From 03f583b0219a780b55621243eac25f9611d27850 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Mon, 14 Jun 2021 18:53:20 +0000 Subject: [PATCH 01/25] Save WIP --- calendso.yaml | 9 +- components/Schedule.model.tsx | 6 ++ components/modal/DateOverrideModal.tsx | 7 ++ components/modal/SetTimesModal.tsx | 100 +++++++++++++++++ components/ui/Scheduler.tsx | 101 ++++++++++++++++++ components/ui/WeekdaySelect.tsx | 39 +++++++ lib/schedule.model.tsx | 7 ++ pages/api/availability/schedule.ts | 45 ++++++++ pages/api/availability/schedule/[type].ts | 0 .../availability/schedule/[type]/timezone.ts | 18 ++++ pages/api/availability/week.ts | 30 ++++++ pages/availability/event/[type].tsx | 49 +++++++-- prisma/schema.prisma | 17 ++- styles/components/table.css | 4 + styles/globals.css | 20 ++++ 15 files changed, 441 insertions(+), 11 deletions(-) create mode 100644 components/Schedule.model.tsx create mode 100644 components/modal/DateOverrideModal.tsx create mode 100644 components/modal/SetTimesModal.tsx create mode 100644 components/ui/Scheduler.tsx create mode 100644 components/ui/WeekdaySelect.tsx create mode 100644 lib/schedule.model.tsx create mode 100644 pages/api/availability/schedule.ts create mode 100644 pages/api/availability/schedule/[type].ts create mode 100644 pages/api/availability/schedule/[type]/timezone.ts create mode 100644 pages/api/availability/week.ts diff --git a/calendso.yaml b/calendso.yaml index 8f052f877f..bb6d686692 100644 --- a/calendso.yaml +++ b/calendso.yaml @@ -28,6 +28,8 @@ tags: description: Manage integrations - name: User description: Manage the user's profile and settings + - name: Team + description: Group users into teams paths: /api/auth/signin: get: @@ -144,4 +146,9 @@ paths: description: Updates a user's profile. summary: Updates a user's profile tags: - - User \ No newline at end of file + - User + /api/availability/schedule: + path: + description: "Updates a schedule" + tags: + - Availability \ No newline at end of file diff --git a/components/Schedule.model.tsx b/components/Schedule.model.tsx new file mode 100644 index 0000000000..d100f13d26 --- /dev/null +++ b/components/Schedule.model.tsx @@ -0,0 +1,6 @@ +import {Dayjs} from "dayjs"; + +interface Schedule { + startDate: Dayjs; + endDate: Dayjs; +} \ No newline at end of file diff --git a/components/modal/DateOverrideModal.tsx b/components/modal/DateOverrideModal.tsx new file mode 100644 index 0000000000..282f612590 --- /dev/null +++ b/components/modal/DateOverrideModal.tsx @@ -0,0 +1,7 @@ + + +/*export default function DateOverrideModal(props) { + return ( + + ); +}*/ \ No newline at end of file diff --git a/components/modal/SetTimesModal.tsx b/components/modal/SetTimesModal.tsx new file mode 100644 index 0000000000..55a48b5698 --- /dev/null +++ b/components/modal/SetTimesModal.tsx @@ -0,0 +1,100 @@ +import {ClockIcon} from "@heroicons/react/outline"; +import {useRef} from "react"; + +export default function SetTimesModal(props) { + + const isNew = props.isNew || false; + const {startDate, endDate} = props.schedule; + + const startHoursRef = useRef(); + const startMinsRef = useRef(); + const endHoursRef = useRef(); + const endMinsRef = useRef(); + + function updateStartEndTimesHandler(event) { + event.preventDefault(); + + const enteredStartHours = parseInt(startHoursRef.current.value); + const enteredStartMins = parseInt(startMinsRef.current.value); + const enteredEndHours = parseInt(endHoursRef.current.value); + const enteredEndMins = parseInt(endMinsRef.current.value); + + props.onChange({ + startDate: startDate.minute(enteredStartMins).hour(enteredStartHours), + endDate: endDate.minute(enteredEndMins).hour(enteredEndHours), + }); + + props.onExit(0); + } + + return ( +
+
+ + + + +
+
+
+ +
+
+ +
+

+ Set your work schedule +

+
+
+
+
+
+ +
+ + +
+ : +
+ + +
+
+
+ +
+ + +
+ : +
+ + +
+
+
+ + +
+
+
+
+
); +} \ No newline at end of file diff --git a/components/ui/Scheduler.tsx b/components/ui/Scheduler.tsx new file mode 100644 index 0000000000..7e5f73a452 --- /dev/null +++ b/components/ui/Scheduler.tsx @@ -0,0 +1,101 @@ +import React, {useEffect, useState} from "react"; +import TimezoneSelect from "react-timezone-select"; +import {PencilAltIcon, TrashIcon} from "@heroicons/react/outline"; +import {WeekdaySelect} from "./WeekdaySelect"; +import SetTimesModal from "../modal/SetTimesModal"; +import Schedule from '../../lib/schedule.model'; +import dayjs, {Dayjs} from "dayjs"; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; +dayjs.extend(utc); +dayjs.extend(timezone); + +export const Scheduler = (props) => { + + const [ showSetTimesModal, setShowSetTimesModal ]: boolean = useState(false); + const [ schedules, setSchedules ]: Schedule[] = useState( + props.schedules.map( (schedule, idx) => ({ + startDate: dayjs(schedule.startDate), + endDate: dayjs(schedule.startDate).startOf('day').add(schedule.length, 'minutes'), + key: idx + }) ) + ); + + const [ timeZone, setTimeZone ] = useState(props.timeZone); + const [ selectedSchedule, setSelectedSchedule ]: Schedule | null = useState(null); + + const addNewSchedule = () => { + setSelectedSchedule({ + startDate: dayjs().startOf('day').add(0, 'minutes'), + endDate: dayjs().startOf('day').add(1439, 'minutes'), + }); + setShowSetTimesModal(true); + } + + const upsertSchedule = (changed: Schedule) => { + if (changed.key) { + schedules.splice( + schedules.findIndex( (schedule) => changed.key === schedule.key ), 1, changed + ) + setSchedules([].concat(schedules)); // update + } + else { + console.log(changed); + setSchedules(schedules.concat([changed])); // insert + } + } + + const removeSchedule = (toRemove: Schedule) => { + schedules.splice(schedules.findIndex( (schedule) => schedule.key === toRemove.key ), 1); + setSchedules([].concat(schedules)); + }; + + return ( +
+
+
+
+ +
+ +
+
+
    + {schedules.length > 0 && schedules.map( (schedule) => +
  • +
    + + +
    + +
  • )} +
+
+ +
+
+ {/*

Add date overrides

+

+ Add dates when your availability changes from your weekly hours +

+ */} +
+
+ {showSetTimesModal && + setShowSetTimesModal(false)} /> + } + {/*{showDateOverrideModal && + + }*/} +
+ ); +} \ No newline at end of file diff --git a/components/ui/WeekdaySelect.tsx b/components/ui/WeekdaySelect.tsx new file mode 100644 index 0000000000..49e8d9a8cc --- /dev/null +++ b/components/ui/WeekdaySelect.tsx @@ -0,0 +1,39 @@ +import React, {useState} from "react"; + +export const WeekdaySelect = (props) => { + + const [ activeDays, setActiveDays ] = useState([false, true, true, true, true, true, false]); + const days = [ 'S', 'M', 'T', 'W', 'T', 'F', 'S' ]; + + const toggleDay = (e, idx: number) => { + e.preventDefault(); + activeDays[idx] = !activeDays[idx]; + console.log(activeDays); + setActiveDays([].concat(activeDays)); + } + + return ( +
+
+ {days.map( (day, idx) => activeDays[idx] ? + + : + + )} +
+
); +} \ No newline at end of file diff --git a/lib/schedule.model.tsx b/lib/schedule.model.tsx new file mode 100644 index 0000000000..03b3e444a4 --- /dev/null +++ b/lib/schedule.model.tsx @@ -0,0 +1,7 @@ +import {Dayjs} from "dayjs"; + +export default interface Schedule { + key: number; + startDate: Dayjs; + endDate: Dayjs; +} \ No newline at end of file diff --git a/pages/api/availability/schedule.ts b/pages/api/availability/schedule.ts new file mode 100644 index 0000000000..e30b9fff80 --- /dev/null +++ b/pages/api/availability/schedule.ts @@ -0,0 +1,45 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import { getSession } from 'next-auth/client'; +import prisma from '../../../lib/prisma'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const session = await getSession({req: req}); + + if (!session) { + res.status(401).json({message: "Not authenticated"}); + return; + } + + PUT /api/availability/schedule/{id}/timezone + { + "timeZone": "Europe/London" + } + + PATCH /api/availability/schedule { + "schedules": [ + { + + } + ], + "overrides": { + + } + } + + if (req.method == "PATCH") { + const startMins = req.body.start; + const endMins = req.body.end; + + const updateDay = await prisma.schedule.update({ + where: { + id: session.user.id, + }, + data: { + startTime: startMins, + endTime: endMins + }, + }); + + res.status(200).json({message: 'Start and end times updated successfully'}); + } +} \ No newline at end of file diff --git a/pages/api/availability/schedule/[type].ts b/pages/api/availability/schedule/[type].ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pages/api/availability/schedule/[type]/timezone.ts b/pages/api/availability/schedule/[type]/timezone.ts new file mode 100644 index 0000000000..1274c828e4 --- /dev/null +++ b/pages/api/availability/schedule/[type]/timezone.ts @@ -0,0 +1,18 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import prisma from '../../../lib/prisma'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const { user } = req.query + + const schedules = await prisma.schedule.find({ + where: { + eventTypeId: req.query.type, + }, + select: { + credentials: true, + timeZone: true + } + }); + + return res.status(202).send(null); +} diff --git a/pages/api/availability/week.ts b/pages/api/availability/week.ts new file mode 100644 index 0000000000..d52c55d7b7 --- /dev/null +++ b/pages/api/availability/week.ts @@ -0,0 +1,30 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import { getSession } from 'next-auth/client'; +import prisma from '../../../lib/prisma'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const session = await getSession({req: req}); + + if (!session) { + res.status(401).json({message: "Not authenticated"}); + return; + } + + if (req.method == "PATCH") { + + const startMins = req.body.start; + const endMins = req.body.end; + + const updateWeek = await prisma.schedule.update({ + where: { + id: session.user.id, + }, + data: { + startTime: startMins, + endTime: endMins + }, + }); + + res.status(200).json({message: 'Start and end times updated successfully'}); + } +} \ No newline at end of file diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx index ed575f25f1..f0881adc7c 100644 --- a/pages/availability/event/[type].tsx +++ b/pages/availability/event/[type].tsx @@ -7,6 +7,8 @@ import prisma from '../../../lib/prisma'; import { LocationType } from '../../../lib/location'; import Shell from '../../../components/Shell'; import { useSession, getSession } from 'next-auth/client'; +import {Scheduler} from "../../../components/ui/Scheduler"; + import { LocationMarkerIcon, PlusCircleIcon, @@ -14,6 +16,12 @@ import { PhoneIcon, } from '@heroicons/react/outline'; +import dayjs, {Dayjs} from "dayjs"; +import utc from 'dayjs/plugin/utc'; +dayjs.extend(utc); +import timezone from 'dayjs/plugin/timezone'; +dayjs.extend(timezone); + export default function EventType(props) { const router = useRouter(); @@ -32,6 +40,8 @@ export default function EventType(props) { return

Loading...

; } + console.log(props); + async function updateEventTypeHandler(event) { event.preventDefault(); @@ -142,7 +152,7 @@ export default function EventType(props) {
-
+
@@ -232,7 +242,7 @@ export default function EventType(props) {
-
+
- - Cancel +
+
+

How do you want to offer your availability for this event type?

+ +
+ Cancel + +
+
@@ -332,7 +349,10 @@ export async function getServerSideProps(context) { email: session.user.email, }, select: { - username: true + username: true, + timeZone: true, + startTime: true, + endTime: true, } }); @@ -351,10 +371,21 @@ export async function getServerSideProps(context) { } }); + const utcOffset = dayjs().tz(user.timeZone).utcOffset(); + + const schedules = [ + { + key: 0, + startDate: dayjs.utc().startOf('day').add(user.startTime - utcOffset, 'minutes').format(), + length: user.endTime, + } + ]; + return { - props: { - user, - eventType - }, + props: { + user, + eventType, + schedules + }, } } \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 88a8187dda..da60fe971e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,6 +21,7 @@ model EventType { user User? @relation(fields: [userId], references: [id]) userId Int? bookings Booking[] + availability Interval[] } model Credential { @@ -49,6 +50,8 @@ model User { credentials Credential[] teams Membership[] bookings Booking[] + availability Interval[] + @@map(name: "users") } @@ -119,4 +122,16 @@ model Booking { createdAt DateTime @default(now()) updatedAt DateTime? -} \ No newline at end of file +} + +model Interval { + id Int @default(autoincrement()) @id + label String? + user User? @relation(fields: [userId], references: [id]) + userId Int? + eventType EventType? @relation(fields: [eventTypeId], references: [id]) + eventTypeId Int? + startTime DateTime + length Int + isOverride Boolean @default(false) +} diff --git a/styles/components/table.css b/styles/components/table.css index a2d88616a6..29f8c6102c 100644 --- a/styles/components/table.css +++ b/styles/components/table.css @@ -1,4 +1,8 @@ table tbody tr:nth-child(odd) { @apply bg-gray-50; +} + +.highlight-odd > *:nth-child(odd) { + @apply bg-gray-50; } \ No newline at end of file diff --git a/styles/globals.css b/styles/globals.css index 926cc766ad..9dc466a49a 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -24,4 +24,24 @@ body { #timeZone input:focus { box-shadow: none; +} + +.weekdaySelect { + font-family: "Courier New", sans-serif; +} + +.weekdaySelect button.active:first-child { + margin-left: -1px !important; +} + +.weekdaySelect button:not(.active) { + padding-left: calc(0.5rem + 0px); + margin-right: 1px; +} + +.weekdaySelect button.active + button.active { + border-color: rgba(3, 169, 244, var(--tw-border-opacity)) + rgba(3, 169, 244, var(--tw-border-opacity)) + rgba(3, 169, 244, var(--tw-border-opacity)) + white; } \ No newline at end of file From 9d5186f1e3d9e53f81c0aea9ef84c7c47cbf13bb Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 16 Jun 2021 22:27:27 +0000 Subject: [PATCH 02/25] Functionality works, only thing left is a bit of cleaning up and all done --- components/modal/SetTimesModal.tsx | 100 ------------- components/ui/Scheduler.tsx | 83 ++++++----- components/ui/WeekdaySelect.tsx | 9 +- .../{ => ui}/modal/DateOverrideModal.tsx | 0 components/ui/modal/SetTimesModal.tsx | 101 +++++++++++++ lib/schedule.model.tsx | 2 +- pages/api/availability/schedule.ts | 45 ------ .../api/availability/schedule/[eventtype].ts | 69 +++++++++ pages/api/availability/schedule/[type].ts | 0 .../availability/schedule/[type]/timezone.ts | 18 --- pages/availability/event/[type].tsx | 141 +++++++++++------- prisma/schema.prisma | 18 ++- 12 files changed, 317 insertions(+), 269 deletions(-) delete mode 100644 components/modal/SetTimesModal.tsx rename components/{ => ui}/modal/DateOverrideModal.tsx (100%) create mode 100644 components/ui/modal/SetTimesModal.tsx delete mode 100644 pages/api/availability/schedule.ts create mode 100644 pages/api/availability/schedule/[eventtype].ts delete mode 100644 pages/api/availability/schedule/[type].ts delete mode 100644 pages/api/availability/schedule/[type]/timezone.ts diff --git a/components/modal/SetTimesModal.tsx b/components/modal/SetTimesModal.tsx deleted file mode 100644 index 55a48b5698..0000000000 --- a/components/modal/SetTimesModal.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import {ClockIcon} from "@heroicons/react/outline"; -import {useRef} from "react"; - -export default function SetTimesModal(props) { - - const isNew = props.isNew || false; - const {startDate, endDate} = props.schedule; - - const startHoursRef = useRef(); - const startMinsRef = useRef(); - const endHoursRef = useRef(); - const endMinsRef = useRef(); - - function updateStartEndTimesHandler(event) { - event.preventDefault(); - - const enteredStartHours = parseInt(startHoursRef.current.value); - const enteredStartMins = parseInt(startMinsRef.current.value); - const enteredEndHours = parseInt(endHoursRef.current.value); - const enteredEndMins = parseInt(endMinsRef.current.value); - - props.onChange({ - startDate: startDate.minute(enteredStartMins).hour(enteredStartHours), - endDate: endDate.minute(enteredEndMins).hour(enteredEndHours), - }); - - props.onExit(0); - } - - return ( -
-
- - - - -
-
-
- -
-
- -
-

- Set your work schedule -

-
-
-
-
-
- -
- - -
- : -
- - -
-
-
- -
- - -
- : -
- - -
-
-
- - -
-
-
-
-
); -} \ No newline at end of file diff --git a/components/ui/Scheduler.tsx b/components/ui/Scheduler.tsx index 7e5f73a452..9b367d624d 100644 --- a/components/ui/Scheduler.tsx +++ b/components/ui/Scheduler.tsx @@ -1,8 +1,8 @@ import React, {useEffect, useState} from "react"; import TimezoneSelect from "react-timezone-select"; import {PencilAltIcon, TrashIcon} from "@heroicons/react/outline"; -import {WeekdaySelect} from "./WeekdaySelect"; -import SetTimesModal from "../modal/SetTimesModal"; +import {WeekdaySelect, Weekday} from "./WeekdaySelect"; +import SetTimesModal from "./modal/SetTimesModal"; import Schedule from '../../lib/schedule.model'; import dayjs, {Dayjs} from "dayjs"; import utc from 'dayjs/plugin/utc'; @@ -12,44 +12,45 @@ dayjs.extend(timezone); export const Scheduler = (props) => { - const [ showSetTimesModal, setShowSetTimesModal ]: boolean = useState(false); - const [ schedules, setSchedules ]: Schedule[] = useState( - props.schedules.map( (schedule, idx) => ({ - startDate: dayjs(schedule.startDate), - endDate: dayjs(schedule.startDate).startOf('day').add(schedule.length, 'minutes'), - key: idx - }) ) - ); + const [ schedules, setSchedules ]: Schedule[] = useState(props.schedules.map( schedule => { + const startDate = schedule.isOverride ? dayjs(schedule.startDate) : dayjs.utc().startOf('day').add(schedule.startTime, 'minutes') + return ( + { + days: schedule.days, + startDate, + endDate: startDate.add(schedule.length, 'minutes') + } + ) + })); const [ timeZone, setTimeZone ] = useState(props.timeZone); - const [ selectedSchedule, setSelectedSchedule ]: Schedule | null = useState(null); + const [ editSchedule, setEditSchedule ] = useState(-1); - const addNewSchedule = () => { - setSelectedSchedule({ - startDate: dayjs().startOf('day').add(0, 'minutes'), - endDate: dayjs().startOf('day').add(1439, 'minutes'), - }); - setShowSetTimesModal(true); + useEffect( () => { + props.onChange(schedules); + }, [schedules]) + + const addNewSchedule = () => setEditSchedule(schedules.length); + + const applyEditSchedule = (changed: Schedule) => { + const replaceWith = { + ...schedules[editSchedule], + ...changed + }; + schedules.splice(editSchedule, 1, replaceWith); + setSchedules([].concat(schedules)); } - const upsertSchedule = (changed: Schedule) => { - if (changed.key) { - schedules.splice( - schedules.findIndex( (schedule) => changed.key === schedule.key ), 1, changed - ) - setSchedules([].concat(schedules)); // update - } - else { - console.log(changed); - setSchedules(schedules.concat([changed])); // insert - } - } - - const removeSchedule = (toRemove: Schedule) => { - schedules.splice(schedules.findIndex( (schedule) => schedule.key === toRemove.key ), 1); + const removeScheduleAt = (toRemove: number) => { + schedules.splice(toRemove, 1); setSchedules([].concat(schedules)); }; + const setWeekdays = (idx: number, days: number[]) => { + schedules[idx].days = days; + setSchedules([].concat(schedules)); + } + return (
@@ -63,15 +64,15 @@ export const Scheduler = (props) => {
    - {schedules.length > 0 && schedules.map( (schedule) => -
  • + {schedules.map( (schedule, idx) => +
  • - -
    - @@ -88,10 +89,10 @@ export const Scheduler = (props) => { */}
- {showSetTimesModal && - setShowSetTimesModal(false)} /> + {editSchedule >= 0 && + setEditSchedule(-1)} /> } {/*{showDateOverrideModal && diff --git a/components/ui/WeekdaySelect.tsx b/components/ui/WeekdaySelect.tsx index 49e8d9a8cc..6eed8563b3 100644 --- a/components/ui/WeekdaySelect.tsx +++ b/components/ui/WeekdaySelect.tsx @@ -1,14 +1,17 @@ -import React, {useState} from "react"; +import React, {useEffect, useState} from "react"; export const WeekdaySelect = (props) => { - const [ activeDays, setActiveDays ] = useState([false, true, true, true, true, true, false]); + const [ activeDays, setActiveDays ] = useState([1,2,3,4,5,6,7].map( (v) => (props.defaultValue || []).indexOf(v) !== -1)); const days = [ 'S', 'M', 'T', 'W', 'T', 'F', 'S' ]; + useEffect( () => { + props.onSelect(activeDays.map( (isActive, idx) => isActive ? idx + 1 : 0).filter( (v) => 0 !== v )); + }, [activeDays]); + const toggleDay = (e, idx: number) => { e.preventDefault(); activeDays[idx] = !activeDays[idx]; - console.log(activeDays); setActiveDays([].concat(activeDays)); } diff --git a/components/modal/DateOverrideModal.tsx b/components/ui/modal/DateOverrideModal.tsx similarity index 100% rename from components/modal/DateOverrideModal.tsx rename to components/ui/modal/DateOverrideModal.tsx diff --git a/components/ui/modal/SetTimesModal.tsx b/components/ui/modal/SetTimesModal.tsx new file mode 100644 index 0000000000..2a0c1b40a9 --- /dev/null +++ b/components/ui/modal/SetTimesModal.tsx @@ -0,0 +1,101 @@ +import {ClockIcon} from "@heroicons/react/outline"; +import {useRef} from "react"; +import dayjs from "dayjs"; + +export default function SetTimesModal(props) { + + const {startDate, endDate} = props.schedule || { + startDate: dayjs().startOf('day').add(540, 'minutes'), + endDate: dayjs().startOf('day').add(1020, 'minutes'), + }; + + const startHoursRef = useRef(); + const startMinsRef = useRef(); + const endHoursRef = useRef(); + const endMinsRef = useRef(); + + function updateStartEndTimesHandler(event) { + event.preventDefault(); + + const enteredStartHours = parseInt(startHoursRef.current.value); + const enteredStartMins = parseInt(startMinsRef.current.value); + const enteredEndHours = parseInt(endHoursRef.current.value); + const enteredEndMins = parseInt(endMinsRef.current.value); + + props.onChange({ + startDate: startDate.minute(enteredStartMins).hour(enteredStartHours), + endDate: endDate.minute(enteredEndMins).hour(enteredEndHours), + }); + + props.onExit(0); + } + + return ( +
+
+ + + + +
+
+
+ +
+
+ +
+

+ Set your work schedule +

+
+
+
+
+ +
+ + +
+ : +
+ + +
+
+
+ +
+ + +
+ : +
+ + +
+
+
+ + +
+
+
+
); +} \ No newline at end of file diff --git a/lib/schedule.model.tsx b/lib/schedule.model.tsx index 03b3e444a4..7a5f6354cb 100644 --- a/lib/schedule.model.tsx +++ b/lib/schedule.model.tsx @@ -1,7 +1,7 @@ import {Dayjs} from "dayjs"; export default interface Schedule { - key: number; + id: number | null; startDate: Dayjs; endDate: Dayjs; } \ No newline at end of file diff --git a/pages/api/availability/schedule.ts b/pages/api/availability/schedule.ts deleted file mode 100644 index e30b9fff80..0000000000 --- a/pages/api/availability/schedule.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from 'next'; -import { getSession } from 'next-auth/client'; -import prisma from '../../../lib/prisma'; - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const session = await getSession({req: req}); - - if (!session) { - res.status(401).json({message: "Not authenticated"}); - return; - } - - PUT /api/availability/schedule/{id}/timezone - { - "timeZone": "Europe/London" - } - - PATCH /api/availability/schedule { - "schedules": [ - { - - } - ], - "overrides": { - - } - } - - if (req.method == "PATCH") { - const startMins = req.body.start; - const endMins = req.body.end; - - const updateDay = await prisma.schedule.update({ - where: { - id: session.user.id, - }, - data: { - startTime: startMins, - endTime: endMins - }, - }); - - res.status(200).json({message: 'Start and end times updated successfully'}); - } -} \ No newline at end of file diff --git a/pages/api/availability/schedule/[eventtype].ts b/pages/api/availability/schedule/[eventtype].ts new file mode 100644 index 0000000000..9d3a9eb606 --- /dev/null +++ b/pages/api/availability/schedule/[eventtype].ts @@ -0,0 +1,69 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; +import { getSession } from 'next-auth/client'; +import prisma from '../../../../lib/prisma'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + + const session = await getSession({req}); + if (!session) { + res.status(401).json({message: "Not authenticated"}); + return; + } + + if (req.method == "PUT") { + + const openingHours = req.body.openingHours || []; + const overrides = req.body.overrides || []; + + const removeSchedule = await prisma.schedule.deleteMany({ + where: { + eventTypeId: +req.query.eventtype, + } + }) + + const updateSchedule = Promise.all(openingHours.map( (schedule) => prisma.schedule.create({ + data: { + eventTypeId: +req.query.eventtype, + days: schedule.days, + startTime: schedule.startTime, + length: schedule.endTime - schedule.startTime, + }, + }))) + .catch( (error) => { + console.log(error); + }) + } + + res.status(200).json({message: 'Created schedule'}); + + /*if (req.method == "PATCH") { + const openingHours = req.body.openingHours || []; + const overrides = req.body.overrides || []; + + openingHours.forEach( (schedule) => { + const updateSchedule = await prisma.schedule.update({ + where: { + id: req.body.id, + }, + data: { + eventTypeId: req.query.eventtype, + days: req.body.days, + startTime: 333, + endTime: 540 - req.body.startTime, + }, + }); + }); + + overrides.forEach( (schedule) => { + const updateSchedule = await prisma.schedule.update({ + where: { + id: req.body.id, + }, + data: { + eventTypeId: req.query.eventtype, + startDate: req.body.startDate, + length: 540, + }, + }); + });*/ +} diff --git a/pages/api/availability/schedule/[type].ts b/pages/api/availability/schedule/[type].ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pages/api/availability/schedule/[type]/timezone.ts b/pages/api/availability/schedule/[type]/timezone.ts deleted file mode 100644 index 1274c828e4..0000000000 --- a/pages/api/availability/schedule/[type]/timezone.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from 'next'; -import prisma from '../../../lib/prisma'; - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const { user } = req.query - - const schedules = await prisma.schedule.find({ - where: { - eventTypeId: req.query.type, - }, - select: { - credentials: true, - timeZone: true - } - }); - - return res.status(202).send(null); -} diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx index f0881adc7c..acb86ef0d2 100644 --- a/pages/availability/event/[type].tsx +++ b/pages/availability/event/[type].tsx @@ -29,6 +29,7 @@ export default function EventType(props) { const [ showLocationModal, setShowLocationModal ] = useState(false); const [ selectedLocation, setSelectedLocation ] = useState(undefined); const [ locations, setLocations ] = useState(props.eventType.locations || []); + const [ schedule, setSchedule ] = useState(undefined); const titleRef = useRef(); const slugRef = useRef(); @@ -40,8 +41,6 @@ export default function EventType(props) { return

Loading...

; } - console.log(props); - async function updateEventTypeHandler(event) { event.preventDefault(); @@ -60,6 +59,31 @@ export default function EventType(props) { } }); + if (schedule) { + + let schedulePayload = { "overrides": [], "timeZone": props.user.timeZone, "openingHours": [] }; + schedule.forEach( (item) => { + if (item.isOverride) { + delete item.isOverride; + schedulePayload.overrides.push(item); + } else { + schedulePayload.openingHours.push({ + days: item.days, + startTime: item.startDate.hour() * 60 + item.startDate.minute(), + endTime: item.endDate.hour() * 60 + item.endDate.minute() + }); + } + }); + + const response = await fetch('/api/availability/schedule/' + props.eventType.id, { + method: 'PUT', + body: JSON.stringify(schedulePayload), + headers: { + 'Content-Type': 'application/json' + } + }); + } + router.push('/availability'); } @@ -262,16 +286,16 @@ export default function EventType(props) { - -
-
-

How do you want to offer your availability for this event type?

- -
- Cancel - +
+
+

How do you want to offer your availability for this event type?

+ +
+ Cancel + +
-
+
@@ -340,52 +364,63 @@ export default function EventType(props) { } export async function getServerSideProps(context) { - const session = await getSession(context); - if (!session) { - return { redirect: { permanent: false, destination: '/auth/login' } }; + const session = await getSession(context); + if (!session) { + return { redirect: { permanent: false, destination: '/auth/login' } }; + } + const user = await prisma.user.findFirst({ + where: { + email: session.user.email, + }, + select: { + username: true, + timeZone: true, + startTime: true, + endTime: true, } - const user = await prisma.user.findFirst({ - where: { - email: session.user.email, - }, - select: { - username: true, - timeZone: true, - startTime: true, - endTime: true, - } - }); + }); - const eventType = await prisma.eventType.findUnique({ - where: { - id: parseInt(context.query.type), - }, - select: { - id: true, - title: true, - slug: true, - description: true, - length: true, - hidden: true, - locations: true, - } - }); + const eventType = await prisma.eventType.findUnique({ + where: { + id: parseInt(context.query.type), + }, + select: { + id: true, + title: true, + slug: true, + description: true, + length: true, + hidden: true, + locations: true, + } + }); - const utcOffset = dayjs().tz(user.timeZone).utcOffset(); + let schedules = await prisma.schedule.findMany({ + where: { + eventTypeId: parseInt(context.query.type), + }, + }); - const schedules = [ - { - key: 0, - startDate: dayjs.utc().startOf('day').add(user.startTime - utcOffset, 'minutes').format(), - length: user.endTime, - } - ]; - - return { - props: { - user, - eventType, - schedules + if (!schedules.length) { + schedules = await prisma.schedule.findMany({ + where: { + userId: user.id, }, + }); + if (!schedules.length) { + schedules.push({ + days: [ 1, 2, 3, 4, 5, 6, 7 ], + startTime: user.startTime, + length: user.endTime >= 1440 ? 1439 : user.endTime, + }); } + } + + return { + props: { + user, + eventType, + schedules + }, + } } \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index da60fe971e..57f4a90a0c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,7 +21,7 @@ model EventType { user User? @relation(fields: [userId], references: [id]) userId Int? bookings Booking[] - availability Interval[] + availability Schedule[] } model Credential { @@ -50,7 +50,7 @@ model User { credentials Credential[] teams Membership[] bookings Booking[] - availability Interval[] + availability Schedule[] @@map(name: "users") } @@ -124,14 +124,16 @@ model Booking { updatedAt DateTime? } -model Interval { - id Int @default(autoincrement()) @id +model Schedule { + id Int @default(autoincrement()) @id label String? - user User? @relation(fields: [userId], references: [id]) + user User? @relation(fields: [userId], references: [id]) userId Int? - eventType EventType? @relation(fields: [eventTypeId], references: [id]) + eventType EventType? @relation(fields: [eventTypeId], references: [id]) eventTypeId Int? - startTime DateTime + days Int[] + startTime Int? + startDate DateTime? @db.Timestamptz(3) length Int - isOverride Boolean @default(false) + isOverride Boolean @default(false) } From e3dbc5267665a9e6ad0f8ac19bf4911dea6cef08 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 16 Jun 2021 22:50:29 +0000 Subject: [PATCH 03/25] Cleaned up loading the availability schedule --- pages/availability/event/[type].tsx | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx index acb86ef0d2..85d2006cdb 100644 --- a/pages/availability/event/[type].tsx +++ b/pages/availability/event/[type].tsx @@ -377,6 +377,7 @@ export async function getServerSideProps(context) { timeZone: true, startTime: true, endTime: true, + availability: true, } }); @@ -392,29 +393,19 @@ export async function getServerSideProps(context) { length: true, hidden: true, locations: true, + availability: true, } }); - let schedules = await prisma.schedule.findMany({ - where: { - eventTypeId: parseInt(context.query.type), - }, - }); + const getAvailability = (providesAvailability) => ( + providesAvailability.availability && providesAvailability.availability.length + ) ? providesAvailability.availability : null; - if (!schedules.length) { - schedules = await prisma.schedule.findMany({ - where: { - userId: user.id, - }, - }); - if (!schedules.length) { - schedules.push({ - days: [ 1, 2, 3, 4, 5, 6, 7 ], - startTime: user.startTime, - length: user.endTime >= 1440 ? 1439 : user.endTime, - }); - } - } + const schedules = getAvailability(eventType) || getAvailability(user) || [ { + days: [ 1, 2, 3, 4, 5, 6, 7 ], + startTime: user.startTime, + length: user.endTime >= 1440 ? 1439 : user.endTime, + } ]; return { props: { From b423f2894a95bea0e8c089d2b6c31c584dc1b618 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Sat, 19 Jun 2021 22:50:47 +0000 Subject: [PATCH 04/25] WIP to save progress --- components/booking/AvailableTimes.tsx | 97 +++++ components/booking/TimeOptions.tsx | 78 ++++ lib/clock.ts | 43 +++ pages/[user]/[type].tsx | 532 +++++++++----------------- 4 files changed, 406 insertions(+), 344 deletions(-) create mode 100644 components/booking/AvailableTimes.tsx create mode 100644 components/booking/TimeOptions.tsx create mode 100644 lib/clock.ts diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx new file mode 100644 index 0000000000..2b59e59e1b --- /dev/null +++ b/components/booking/AvailableTimes.tsx @@ -0,0 +1,97 @@ +import dayjs, {Dayjs} from "dayjs"; +import isBetween from 'dayjs/plugin/isBetween'; +dayjs.extend(isBetween); +import {useEffect, useMemo, useState} from "react"; +import getSlots from "../../lib/slots"; +import Link from "next/link"; +import {timeZone} from "../../lib/clock"; +import {useRouter} from "next/router"; + +const AvailableTimes = (props) => { + + const router = useRouter(); + const { user, rescheduleUid } = router.query; + const [loading, setLoading] = useState(false); + const [busy, setBusy] = useState([]); + + let availableTimes = []; + + // Handle date change and timezone change + useEffect(() => { + setLoading(true); + fetch(`/api/availability/${user}?dateFrom=${props.date.startOf('day').utc().format()}&dateTo=${props.date.endOf('day').utc().format()}`) + .then( res => res.json()) + .then(setBusy); + }, [props.date]); + + const times = useMemo(() => + getSlots({ + calendarTimeZone: props.user.timeZone, + selectedTimeZone: timeZone(), + eventLength: props.eventType.length, + selectedDate: props.date, + dayStartTime: props.user.startTime, + dayEndTime: props.user.endTime, + }) + , []) + + useEffect(() => { + + // Check for conflicts + for (let i = times.length - 1; i >= 0; i -= 1) { + busy.forEach(busyTime => { + let startTime = dayjs(busyTime.start); + let endTime = dayjs(busyTime.end); + + // Check if start times are the same + if (dayjs(times[i]).format('HH:mm') == startTime.format('HH:mm')) { + times.splice(i, 1); + } + + // Check if time is between start and end times + if (dayjs(times[i]).isBetween(startTime, endTime)) { + times.splice(i, 1); + } + + // Check if slot end time is between start and end time + if (dayjs(times[i]).add(props.eventType.length, 'minutes').isBetween(startTime, endTime)) { + times.splice(i, 1); + } + + // Check if startTime is between slot + if (startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(props.eventType.length, 'minutes'))) { + times.splice(i, 1); + } + }); + } + + // Display available times + availableTimes = times.map((time) => + + ); + + console.log(availableTimes); + + setLoading(false); + + }, [busy]); + + return ( +
+
+ + {props.date.format("dddd DD MMMM YYYY")} + +
+ {!loading ? availableTimes :
} +
+ ); +} + +export default AvailableTimes; \ No newline at end of file diff --git a/components/booking/TimeOptions.tsx b/components/booking/TimeOptions.tsx new file mode 100644 index 0000000000..bf183a82e6 --- /dev/null +++ b/components/booking/TimeOptions.tsx @@ -0,0 +1,78 @@ +import {Switch} from "@headlessui/react"; +import TimezoneSelect from "react-timezone-select"; +import {useEffect, useState} from "react"; +import {timeZone, is24h} from '../../lib/clock'; + +function classNames(...classes) { + return classes.filter(Boolean).join(' ') +} + +const TimeOptions = (props) => { + const [selectedTimeZone, setSelectedTimeZone] = useState(''); + const [is24hClock, setIs24hClock] = useState(false); + const [isReady, setIsReady ] = useState(false); + + useEffect( () => { + setIs24hClock(is24h()); + setSelectedTimeZone(timeZone()); + setIsReady(true); + }, []); + + useEffect( () => { + if (!isReady) { + return; + } + if (selectedTimeZone && selectedTimeZone !== timeZone()) { + props.onSelectTimeZone(selectedTimeZone) + } + if ([true,false].includes(is24h()) && is24hClock !== is24h()) { + props.onToggle24hFormat(is24hClock); + } + }, [is24hClock, selectedTimeZone]); + + return isReady && ( +
+
+
Time Options
+
+ + + am/pm + + + Use setting + + + 24h + + +
+
+ setSelectedTimeZone(tz.value)} + className="mb-2 shadow-sm focus:ring-blue-500 focus:border-blue-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md" + /> +
+ ); +} + +export default TimeOptions; \ No newline at end of file diff --git a/lib/clock.ts b/lib/clock.ts new file mode 100644 index 0000000000..2b065cf485 --- /dev/null +++ b/lib/clock.ts @@ -0,0 +1,43 @@ +// handles logic related to user clock display using 24h display / timeZone options. +import dayjs, {Dayjs} from 'dayjs'; + +interface TimeOptions { is24hClock: boolean, inviteeTimeZone: string }; + +const timeOptions: TimeOptions = { + is24hClock: false, + inviteeTimeZone: '', +} + +const isInitialized: boolean = false; + +const initClock = () => { + if (typeof localStorage === "undefined" || isInitialized) { + return; + } + timeOptions.is24hClock = localStorage.getItem('timeOption.is24hClock') === "true"; + timeOptions.inviteeTimeZone = localStorage.getItem('timeOption.preferredTimeZone') || dayjs.tz.guess(); +} + +const is24h = (is24hClock?: boolean) => { + initClock(); + if(typeof is24hClock !== "undefined") set24hClock(is24hClock); + return timeOptions.is24hClock; +} + +const set24hClock = (is24hClock: boolean) => { + localStorage.setItem('timeOption.is24hClock', is24hClock.toString()); + timeOptions.is24hClock = is24hClock; +} + +function setTimeZone(selectedTimeZone: string) { + localStorage.setItem('timeOption.preferredTimeZone', selectedTimeZone); + timeOptions.inviteeTimeZone = selectedTimeZone; +} + +const timeZone = (selectedTimeZone?: string) => { + initClock(); + if (selectedTimeZone) setTimeZone(selectedTimeZone) + return timeOptions.inviteeTimeZone; +} + +export {is24h, timeZone}; \ No newline at end of file diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 36cc1c79f1..1b95f4b7f6 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -4,369 +4,213 @@ import Link from 'next/link'; import prisma from '../../lib/prisma'; import { useRouter } from 'next/router'; import dayjs, { Dayjs } from 'dayjs'; -import { Switch } from '@headlessui/react'; -import TimezoneSelect from 'react-timezone-select'; import { ClockIcon, GlobeIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid'; import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; -import isBetween from 'dayjs/plugin/isBetween'; import utc from 'dayjs/plugin/utc'; import timezone from 'dayjs/plugin/timezone'; -import Avatar from '../../components/Avatar'; dayjs.extend(isSameOrBefore); -dayjs.extend(isBetween); dayjs.extend(utc); dayjs.extend(timezone); -import getSlots from '../../lib/slots'; import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry"; - -function classNames(...classes) { - return classes.filter(Boolean).join(' ') -} +import AvailableTimes from "../../components/booking/AvailableTimes"; +import TimeOptions from "../../components/booking/TimeOptions" +import Avatar from '../../components/Avatar'; +import {timeZone} from "../../lib/clock"; export default function Type(props) { - // Initialise state - const [selectedDate, setSelectedDate] = useState(); - const [selectedMonth, setSelectedMonth] = useState(dayjs().month()); - const [loading, setLoading] = useState(false); - const [isTimeOptionsOpen, setIsTimeOptionsOpen] = useState(false); - const [is24h, setIs24h] = useState(false); - const [busy, setBusy] = useState([]); - const telemetry = useTelemetry(); - const [selectedTimeZone, setSelectedTimeZone] = useState(''); + // Get router variables + const router = useRouter(); + const { rescheduleUid } = router.query; - function toggleTimeOptions() { - setIsTimeOptionsOpen(!isTimeOptionsOpen); - } + // Initialise state + const [selectedDate, setSelectedDate] = useState(); + const [selectedMonth, setSelectedMonth] = useState(dayjs().month()); + const [isTimeOptionsOpen, setIsTimeOptionsOpen] = useState(false); + const [timeFormat, setTimeFormat] = useState('hh:mm'); + const telemetry = useTelemetry(); - function toggleClockSticky() { - localStorage.setItem('timeOption.is24hClock', (!is24h).toString()); - setIs24h(!is24h); - } + useEffect(() => { + telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())) + }, []); - function setPreferredTimeZoneSticky({ value }: string) { - localStorage.setItem('timeOption.preferredTimeZone', value); - setSelectedTimeZone(value); - } + // Handle month changes + const incrementMonth = () => { + setSelectedMonth(selectedMonth + 1); + } - function initializeTimeOptions() { - setSelectedTimeZone(localStorage.getItem('timeOption.preferredTimeZone') || dayjs.tz.guess()); - setIs24h(!!localStorage.getItem('timeOption.is24hClock')); - } + const decrementMonth = () => { + setSelectedMonth(selectedMonth - 1); + } - useEffect(() => { - telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())) - }); + // Set up calendar + var daysInMonth = dayjs().month(selectedMonth).daysInMonth(); + var days = []; + for (let i = 1; i <= daysInMonth; i++) { + days.push(i); + } - // Handle date change and timezone change - useEffect(() => { - - if ( ! selectedTimeZone ) { - initializeTimeOptions(); - } - - const changeDate = async () => { - if (!selectedDate) { - return - } - - setLoading(true); - const res = await fetch(`/api/availability/${user}?dateFrom=${lowerBound.utc().format()}&dateTo=${upperBound.utc().format()}`); - const busyTimes = await res.json(); - if (busyTimes.length > 0) setBusy(busyTimes); - setLoading(false); - } - changeDate(); - }, [selectedDate, selectedTimeZone]); - - // Get router variables - const router = useRouter(); - const { user, rescheduleUid } = router.query; - - // Handle month changes - const incrementMonth = () => { - setSelectedMonth(selectedMonth + 1); - } - - const decrementMonth = () => { - setSelectedMonth(selectedMonth - 1); - } - - // Need to define the bounds of the 24-hour window - const lowerBound = useMemo(() => { - if(!selectedDate) { - return - } - - return selectedDate.startOf('day') - }, [selectedDate]) - - const upperBound = useMemo(() => { - if(!selectedDate) return - - return selectedDate.endOf('day') - }, [selectedDate]) - - // Set up calendar - var daysInMonth = dayjs().month(selectedMonth).daysInMonth(); - var days = []; - for (let i = 1; i <= daysInMonth; i++) { - days.push(i); - } - - // Create placeholder elements for empty days in first week - let weekdayOfFirst = dayjs().month(selectedMonth).date(1).day(); - if (props.user.weekStart === 'Monday') { - weekdayOfFirst -= 1; - if (weekdayOfFirst < 0) - weekdayOfFirst = 6; - } - const emptyDays = Array(weekdayOfFirst).fill(null).map((day, i) => -
- {null} -
- ); - - // Combine placeholder days with actual days - const calendar = [...emptyDays, ...days.map((day) => - - )]; - - const times = useMemo(() => - getSlots({ - calendarTimeZone: props.user.timeZone, - selectedTimeZone: selectedTimeZone, - eventLength: props.eventType.length, - selectedDate: selectedDate, - dayStartTime: props.user.startTime, - dayEndTime: props.user.endTime, - }) - , [selectedDate, selectedTimeZone]) - - // Check for conflicts - for(let i = times.length - 1; i >= 0; i -= 1) { - busy.forEach(busyTime => { - let startTime = dayjs(busyTime.start); - let endTime = dayjs(busyTime.end); - - // Check if start times are the same - if (dayjs(times[i]).format('HH:mm') == startTime.format('HH:mm')) { - times.splice(i, 1); - } - - // Check if time is between start and end times - if (dayjs(times[i]).isBetween(startTime, endTime)) { - times.splice(i, 1); - } - - // Check if slot end time is between start and end time - if (dayjs(times[i]).add(props.eventType.length, 'minutes').isBetween(startTime, endTime)) { - times.splice(i, 1); - } - - // Check if startTime is between slot - if(startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(props.eventType.length, 'minutes'))) { - times.splice(i, 1); - } - }); - } - - // Display available times - const availableTimes = times.map((time) => - - ); - - return ( -
- - - {rescheduleUid && "Reschedule"} {props.eventType.title} | {props.user.name || props.user.username} | - Calendso - - - -
-
-
-
- -

{props.user.name}

-

- {props.eventType.title} -

-

- - {props.eventType.length} minutes -

- - {isTimeOptionsOpen && ( -
-
-
Time Options
-
- - - am/pm - - - Use setting - - - 24h - - -
-
- -
- )} -

- {props.eventType.description} -

-
-
-
- - {dayjs().month(selectedMonth).format("MMMM YYYY")} - -
- - -
-
-
- {props.user.weekStart !== 'Monday' ? ( -
- Sun -
- ) : null} -
- Mon -
-
- Tue -
-
- Wed -
-
- Thu -
-
- Fri -
-
- Sat -
- {props.user.weekStart === 'Monday' ? ( -
- Sun -
- ) : null} - {calendar} -
-
- {selectedDate && ( -
-
- - {dayjs(selectedDate).format("dddd DD MMMM YYYY")} - -
- {!loading ? availableTimes :
} -
- )} -
-
- {/* note(peer): - you can remove calendso branding here, but we'd also appreciate it, if you don't <3 - */} - -
+ // Create placeholder elements for empty days in first week + let weekdayOfFirst = dayjs().month(selectedMonth).date(1).day(); + if (props.user.weekStart === 'Monday') { + weekdayOfFirst -= 1; + if (weekdayOfFirst < 0) + weekdayOfFirst = 6; + } + const emptyDays = Array(weekdayOfFirst).fill(null).map((day, i) => +
+ {null}
- ); + ); + + const changeDate = (day) => { + telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.dateSelected, collectPageParameters())) + setSelectedDate(dayjs().month(selectedMonth).date(day)) + }; + + // Combine placeholder days with actual days + const calendar = [...emptyDays, ...days.map((day) => + + )]; + + return ( +
+ + + {rescheduleUid && "Reschedule"} {props.eventType.title} | {props.user.name || props.user.username} | + Calendso + + + +
+
+
+
+ +

{props.user.name}

+

+ {props.eventType.title} +

+

+ + {props.eventType.length} minutes +

+ + { + isTimeOptionsOpen && + setSelectedDate(selectedDate.tz(selectedTimeZone))} + onToggle24hFormat={(is24hClock: boolean) => setTimeFormat(is24hClock ? 'HH:mm' : 'h:mma')} + />} +

+ {props.eventType.description} +

+
+
+
+ + {dayjs().month(selectedMonth).format("MMMM YYYY")} + +
+ + +
+
+
+ {props.user.weekStart !== 'Monday' ? ( +
+ Sun +
+ ) : null} +
+ Mon +
+
+ Tue +
+
+ Wed +
+
+ Thu +
+
+ Fri +
+
+ Sat +
+ {props.user.weekStart === 'Monday' ? ( +
+ Sun +
+ ) : null} + {calendar} +
+
+ {selectedDate && } +
+
+ {/* note(peer): + you can remove calendso branding here, but we'd also appreciate it, if you don't <3 + */} + +
+
+ ); } export async function getServerSideProps(context) { From 01eacedde8a5f6600ef9568c079677df2b79adc2 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Sun, 20 Jun 2021 00:08:48 +0000 Subject: [PATCH 05/25] Timezone should never be unless it has no state yet, so used that to simplify TimeOptions --- components/booking/TimeOptions.tsx | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/components/booking/TimeOptions.tsx b/components/booking/TimeOptions.tsx index bf183a82e6..38aafd8bf5 100644 --- a/components/booking/TimeOptions.tsx +++ b/components/booking/TimeOptions.tsx @@ -8,29 +8,24 @@ function classNames(...classes) { } const TimeOptions = (props) => { + const [selectedTimeZone, setSelectedTimeZone] = useState(''); const [is24hClock, setIs24hClock] = useState(false); - const [isReady, setIsReady ] = useState(false); useEffect( () => { setIs24hClock(is24h()); setSelectedTimeZone(timeZone()); - setIsReady(true); }, []); useEffect( () => { - if (!isReady) { - return; - } - if (selectedTimeZone && selectedTimeZone !== timeZone()) { - props.onSelectTimeZone(selectedTimeZone) - } - if ([true,false].includes(is24h()) && is24hClock !== is24h()) { - props.onToggle24hFormat(is24hClock); - } - }, [is24hClock, selectedTimeZone]); + props.onSelectTimeZone(timeZone(selectedTimeZone)); + }, [selectedTimeZone]); - return isReady && ( + useEffect( () => { + props.onToggle24hClock(is24h(is24hClock)); + }, [is24hClock]); + + return selectedTimeZone !== "" && (
Time Options
From d904dd7a00ab8cf2cb46e17aa7b7c53b317121e0 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Sun, 20 Jun 2021 00:10:08 +0000 Subject: [PATCH 06/25] AvailableTimes refactor complete, it all seems much simpler now --- components/booking/AvailableTimes.tsx | 54 ++++++++++++--------------- pages/[user]/[type].tsx | 20 +++++++--- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx index 2b59e59e1b..3acc07a2b3 100644 --- a/components/booking/AvailableTimes.tsx +++ b/components/booking/AvailableTimes.tsx @@ -11,18 +11,7 @@ const AvailableTimes = (props) => { const router = useRouter(); const { user, rescheduleUid } = router.query; - const [loading, setLoading] = useState(false); - const [busy, setBusy] = useState([]); - - let availableTimes = []; - - // Handle date change and timezone change - useEffect(() => { - setLoading(true); - fetch(`/api/availability/${user}?dateFrom=${props.date.startOf('day').utc().format()}&dateTo=${props.date.endOf('day').utc().format()}`) - .then( res => res.json()) - .then(setBusy); - }, [props.date]); + const [loaded, setLoaded] = useState(false); const times = useMemo(() => getSlots({ @@ -35,11 +24,10 @@ const AvailableTimes = (props) => { }) , []) - useEffect(() => { - + const handleAvailableSlots = (busyTimes: []) => { // Check for conflicts for (let i = times.length - 1; i >= 0; i -= 1) { - busy.forEach(busyTime => { + busyTimes.forEach(busyTime => { let startTime = dayjs(busyTime.start); let endTime = dayjs(busyTime.end); @@ -64,23 +52,17 @@ const AvailableTimes = (props) => { } }); } - // Display available times - availableTimes = times.map((time) => - - ); + setLoaded(true); + }; - console.log(availableTimes); - - setLoading(false); - - }, [busy]); + // Re-render only when invitee changes date + useEffect(() => { + setLoaded(false); + fetch(`/api/availability/${user}?dateFrom=${props.date.startOf('day').utc().format()}&dateTo=${props.date.endOf('day').utc().format()}`) + .then( res => res.json()) + .then(handleAvailableSlots); + }, [props.date]); return (
@@ -89,7 +71,17 @@ const AvailableTimes = (props) => { {props.date.format("dddd DD MMMM YYYY")}
- {!loading ? availableTimes :
} + { + loaded ? times.map((time) => + + ) :
+ }
); } diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 1b95f4b7f6..0d5b4c388c 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -76,6 +76,18 @@ export default function Type(props) { )]; + const handleSelectTimeZone = (selectedTimeZone: string) => { + if (selectedDate) { + setSelectedDate(selectedDate.tz(selectedTimeZone)) + } + }; + + const handleToggle24hClock = (is24hClock: boolean) => { + if (selectedDate) { + setTimeFormat(is24hClock ? 'HH:mm' : 'h:mma'); + } + } + return (
@@ -115,12 +127,8 @@ export default function Type(props) { {timeZone()} - { - isTimeOptionsOpen && - setSelectedDate(selectedDate.tz(selectedTimeZone))} - onToggle24hFormat={(is24hClock: boolean) => setTimeFormat(is24hClock ? 'HH:mm' : 'h:mma')} - />} + { isTimeOptionsOpen && }

{props.eventType.description}

From b50fe165663a7918bb90a67e589e563c07e3e072 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Mon, 21 Jun 2021 20:26:04 +0000 Subject: [PATCH 07/25] Moved DatePicker and PoweredByCalendso to seperate components --- components/booking/DatePicker.tsx | 109 ++++++++++++++++++++ components/ui/PoweredByCalendso.tsx | 22 +++++ pages/[user]/[type].tsx | 148 ++++------------------------ 3 files changed, 149 insertions(+), 130 deletions(-) create mode 100644 components/booking/DatePicker.tsx create mode 100644 components/ui/PoweredByCalendso.tsx diff --git a/components/booking/DatePicker.tsx b/components/booking/DatePicker.tsx new file mode 100644 index 0000000000..98a7efe430 --- /dev/null +++ b/components/booking/DatePicker.tsx @@ -0,0 +1,109 @@ +import dayjs from "dayjs"; +import {ChevronLeftIcon, ChevronRightIcon} from "@heroicons/react/solid"; +import {useEffect, useState} from "react"; + +const DatePicker = ({ weekStart, onDatePicked }) => { + + const [selectedMonth, setSelectedMonth] = useState(dayjs().month()); + const [selectedDay, setSelectedDay] = useState(dayjs().date()); + const [hasPickedDate, setHasPickedDate] = useState(false); + + useEffect(() => { + if (hasPickedDate) { + onDatePicked(dayjs().month(selectedMonth).date(selectedDay)); + } + }, [hasPickedDate, selectedDay]); + + // Handle month changes + const incrementMonth = () => { + setSelectedMonth(selectedMonth + 1); + } + + const decrementMonth = () => { + setSelectedMonth(selectedMonth - 1); + } + + // Set up calendar + var daysInMonth = dayjs().month(selectedMonth).daysInMonth(); + var days = []; + for (let i = 1; i <= daysInMonth; i++) { + days.push(i); + } + + // Create placeholder elements for empty days in first week + let weekdayOfFirst = dayjs().month(selectedMonth).date(1).day(); + if (weekStart === 'Monday') { + weekdayOfFirst -= 1; + if (weekdayOfFirst < 0) + weekdayOfFirst = 6; + } + const emptyDays = Array(weekdayOfFirst).fill(null).map((day, i) => +
+ {null} +
+ ); + + // Combine placeholder days with actual days + const calendar = [...emptyDays, ...days.map((day) => + + )]; + + return ( +
+
+ + {dayjs().month(selectedMonth).format("MMMM YYYY")} + +
+ + +
+
+
+ { + ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + .sort( (a, b) => weekStart.startsWith(a) ? -1 : weekStart.startsWith(b) ? 1 : 0 ) + .map( (weekDay) => +
{weekDay}
+ ) + } + {calendar} +
+
+ ); +} + +export default DatePicker; \ No newline at end of file diff --git a/components/ui/PoweredByCalendso.tsx b/components/ui/PoweredByCalendso.tsx new file mode 100644 index 0000000000..2022fa931e --- /dev/null +++ b/components/ui/PoweredByCalendso.tsx @@ -0,0 +1,22 @@ +import Link from "next/link"; + +const PoweredByCalendso = (props) => ( + +); + +export default PoweredByCalendso; \ No newline at end of file diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 1a9d7c47d8..c56b720218 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -2,7 +2,6 @@ import {useEffect, useState, useMemo} from 'react'; import Head from 'next/head'; import Link from 'next/link'; import prisma from '../../lib/prisma'; -import { useRouter } from 'next/router'; import dayjs, { Dayjs } from 'dayjs'; import { ClockIcon, GlobeIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid'; import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; @@ -17,16 +16,16 @@ import AvailableTimes from "../../components/booking/AvailableTimes"; import TimeOptions from "../../components/booking/TimeOptions" import Avatar from '../../components/Avatar'; import {timeZone} from "../../lib/clock"; +import DatePicker from "../../components/booking/DatePicker"; +import PoweredByCalendso from "../../components/ui/PoweredByCalendso"; +import {useRouter} from "next/router"; export default function Type(props) { - // Get router variables const router = useRouter(); const { rescheduleUid } = router.query; - // Initialise state const [selectedDate, setSelectedDate] = useState(); - const [selectedMonth, setSelectedMonth] = useState(dayjs().month()); const [isTimeOptionsOpen, setIsTimeOptionsOpen] = useState(false); const [timeFormat, setTimeFormat] = useState('hh:mm'); const telemetry = useTelemetry(); @@ -35,47 +34,11 @@ export default function Type(props) { telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())) }, []); - // Handle month changes - const incrementMonth = () => { - setSelectedMonth(selectedMonth + 1); - } - - const decrementMonth = () => { - setSelectedMonth(selectedMonth - 1); - } - - // Set up calendar - var daysInMonth = dayjs().month(selectedMonth).daysInMonth(); - var days = []; - for (let i = 1; i <= daysInMonth; i++) { - days.push(i); - } - - // Create placeholder elements for empty days in first week - let weekdayOfFirst = dayjs().month(selectedMonth).date(1).day(); - if (props.user.weekStart === 'Monday') { - weekdayOfFirst -= 1; - if (weekdayOfFirst < 0) - weekdayOfFirst = 6; - } - const emptyDays = Array(weekdayOfFirst).fill(null).map((day, i) => -
- {null} -
- ); - - const changeDate = (day) => { + const changeDate = (date: Dayjs) => { telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.dateSelected, collectPageParameters())) - setSelectedDate(dayjs().month(selectedMonth).date(day)) + setSelectedDate(date); }; - // Combine placeholder days with actual days - const calendar = [...emptyDays, ...days.map((day) => - - )]; - const handleSelectTimeZone = (selectedTimeZone: string) => { if (selectedDate) { setSelectedDate(selectedDate.tz(selectedTimeZone)) @@ -120,102 +83,27 @@ export default function Type(props) { {props.eventType.length} minutes

- { isTimeOptionsOpen && } -

- {props.eventType.description} -

-
-
-
- - {dayjs().month(selectedMonth).format("MMMM YYYY")} - -
- - -
-
-
- {props.user.weekStart !== 'Monday' ? ( -
- Sun -
- ) : null} -
- Mon -
-
- Tue -
-
- Wed -
-
- Thu -
-
- Fri -
-
- Sat -
- {props.user.weekStart === 'Monday' ? ( -
- Sun -
- ) : null} - {calendar} -
-
+ + {timeZone()} + + + { isTimeOptionsOpen && } +

+ {props.eventType.description} +

+
+ {selectedDate && }
{/* note(peer): you can remove calendso branding here, but we'd also appreciate it, if you don't <3 */} - + ); From ef3274d8f3854257c876c962be2126a5182b9639 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Thu, 24 Jun 2021 22:15:18 +0000 Subject: [PATCH 08/25] Working version ready for testing * More tests to be added to verify slots logic * Adds Jest * Implements logic to the booking code to take into account grayed days * Slots take workhours into account TODO: Improve the tests, evaluate the structure, small re-orgs here and there for improved readability / better code --- .eslintrc.json | 6 +- components/booking/AvailableTimes.tsx | 92 +- components/booking/DatePicker.tsx | 134 +- components/booking/Slots.tsx | 66 + components/ui/Scheduler.tsx | 103 +- components/ui/WeekdaySelect.tsx | 59 +- components/ui/modal/SetTimesModal.tsx | 123 +- lib/slots.ts | 174 +-- package.json | 18 + pages/[user]/[type].tsx | 154 ++- pages/availability/event/[type].tsx | 1052 +++++++------- test/lib/slots.test.ts | 39 + tsconfig.json | 5 + yarn.lock | 1839 ++++++++++++++++++++++++- 14 files changed, 2992 insertions(+), 872 deletions(-) create mode 100644 components/booking/Slots.tsx create mode 100644 test/lib/slots.test.ts diff --git a/.eslintrc.json b/.eslintrc.json index 0ea5d0ab21..6b0d79e8ac 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,12 +18,14 @@ "rules": { "prettier/prettier": ["error"], "@typescript-eslint/no-unused-vars": "error", - "react/react-in-jsx-scope": "off" + "react/react-in-jsx-scope": "off", + "react/prop-types": "off" }, "env": { "browser": true, "node": true, - "es6": true + "es6": true, + "jest": true }, "settings": { "react": { diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx index 1d8dc55574..fbf552ab39 100644 --- a/components/booking/AvailableTimes.tsx +++ b/components/booking/AvailableTimes.tsx @@ -1,87 +1,35 @@ -import dayjs, {Dayjs} from "dayjs"; -import isBetween from 'dayjs/plugin/isBetween'; -dayjs.extend(isBetween); -import {useEffect, useMemo, useState} from "react"; -import getSlots from "../../lib/slots"; import Link from "next/link"; -import {timeZone} from "../../lib/clock"; -import {useRouter} from "next/router"; - -const AvailableTimes = (props) => { +import { useRouter } from "next/router"; +import Slots from "./Slots"; +const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeFormat }) => { const router = useRouter(); const { user, rescheduleUid } = router.query; - const [loaded, setLoaded] = useState(false); - - const times = getSlots({ - calendarTimeZone: props.user.timeZone, - selectedTimeZone: timeZone(), - eventLength: props.eventType.length, - selectedDate: props.date, - dayStartTime: props.user.startTime, - dayEndTime: props.user.endTime, - }); - - const handleAvailableSlots = (busyTimes: []) => { - // Check for conflicts - for (let i = times.length - 1; i >= 0; i -= 1) { - busyTimes.forEach(busyTime => { - let startTime = dayjs(busyTime.start); - let endTime = dayjs(busyTime.end); - - // Check if start times are the same - if (dayjs(times[i]).format('HH:mm') == startTime.format('HH:mm')) { - times.splice(i, 1); - } - - // Check if time is between start and end times - if (dayjs(times[i]).isBetween(startTime, endTime)) { - times.splice(i, 1); - } - - // Check if slot end time is between start and end time - if (dayjs(times[i]).add(props.eventType.length, 'minutes').isBetween(startTime, endTime)) { - times.splice(i, 1); - } - - // Check if startTime is between slot - if (startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(props.eventType.length, 'minutes'))) { - times.splice(i, 1); - } - }); - } - // Display available times - setLoaded(true); - }; - - // Re-render only when invitee changes date - useEffect(() => { - setLoaded(false); - fetch(`/api/availability/${user}?dateFrom=${props.date.startOf('day').utc().format()}&dateTo=${props.date.endOf('day').utc().format()}`) - .then( res => res.json()) - .then(handleAvailableSlots); - }, [props.date]); - + const { slots } = Slots({ date, eventLength, workingHours }); return (
- - {props.date.format("dddd DD MMMM YYYY")} - + {date.format("dddd DD MMMM YYYY")}
- { - loaded ? times.map((time) => -
+ {slots.length > 0 ? ( + slots.map((slot) => ( +
- {dayjs(time).tz(timeZone()).format(props.timeFormat)} + href={ + `/${user}/book?date=${slot.utc().format()}&type=${eventTypeId}` + + (rescheduleUid ? "&rescheduleUid=" + rescheduleUid : "") + }> + + {slot.format(timeFormat)} +
- ) :
- } + )) + ) : ( +
+ )}
); -} +}; export default AvailableTimes; diff --git a/components/booking/DatePicker.tsx b/components/booking/DatePicker.tsx index 98a7efe430..b58b6c93ea 100644 --- a/components/booking/DatePicker.tsx +++ b/components/booking/DatePicker.tsx @@ -1,90 +1,90 @@ -import dayjs from "dayjs"; -import {ChevronLeftIcon, ChevronRightIcon} from "@heroicons/react/solid"; -import {useEffect, useState} from "react"; - -const DatePicker = ({ weekStart, onDatePicked }) => { +import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid"; +import { useEffect, useState } from "react"; +import dayjs, { Dayjs } from "dayjs"; +import isToday from "dayjs/plugin/isToday"; +dayjs.extend(isToday); +const DatePicker = ({ weekStart, onDatePicked, workingHours, disableToday }) => { + const workingDays = workingHours.reduce((workingDays: number[], wh) => [...workingDays, ...wh.days], []); const [selectedMonth, setSelectedMonth] = useState(dayjs().month()); - const [selectedDay, setSelectedDay] = useState(dayjs().date()); - const [hasPickedDate, setHasPickedDate] = useState(false); + const [selectedDate, setSelectedDate] = useState(); useEffect(() => { - if (hasPickedDate) { - onDatePicked(dayjs().month(selectedMonth).date(selectedDay)); - } - }, [hasPickedDate, selectedDay]); + if (selectedDate) onDatePicked(selectedDate); + }, [selectedDate, onDatePicked]); // Handle month changes const incrementMonth = () => { setSelectedMonth(selectedMonth + 1); - } + }; const decrementMonth = () => { setSelectedMonth(selectedMonth - 1); - } + }; // Set up calendar - var daysInMonth = dayjs().month(selectedMonth).daysInMonth(); - var days = []; + const daysInMonth = dayjs().month(selectedMonth).daysInMonth(); + const days = []; for (let i = 1; i <= daysInMonth; i++) { days.push(i); } // Create placeholder elements for empty days in first week let weekdayOfFirst = dayjs().month(selectedMonth).date(1).day(); - if (weekStart === 'Monday') { + if (weekStart === "Monday") { weekdayOfFirst -= 1; - if (weekdayOfFirst < 0) - weekdayOfFirst = 6; + if (weekdayOfFirst < 0) weekdayOfFirst = 6; } - const emptyDays = Array(weekdayOfFirst).fill(null).map((day, i) => -
- {null} -
- ); + const emptyDays = Array(weekdayOfFirst) + .fill(null) + .map((day, i) => ( +
+ {null} +
+ )); + + const isDisabled = (day: number) => { + const date: Dayjs = dayjs().month(selectedMonth).date(day); + return ( + date.isBefore(dayjs()) || !workingDays.includes(+date.format("d")) || (date.isToday() && disableToday) + ); + }; // Combine placeholder days with actual days - const calendar = [...emptyDays, ...days.map((day) => - - )]; + const calendar = [ + ...emptyDays, + ...days.map((day) => ( + + )), + ]; return ( -
+
- - {dayjs().month(selectedMonth).format("MMMM YYYY")} - + {dayjs().month(selectedMonth).format("MMMM YYYY")}
- { - ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] - .sort( (a, b) => weekStart.startsWith(a) ? -1 : weekStart.startsWith(b) ? 1 : 0 ) - .map( (weekDay) => -
{weekDay}
- ) - } + {["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] + .sort((a, b) => (weekStart.startsWith(a) ? -1 : weekStart.startsWith(b) ? 1 : 0)) + .map((weekDay) => ( +
+ {weekDay} +
+ ))} {calendar}
); -} +}; -export default DatePicker; \ No newline at end of file +export default DatePicker; diff --git a/components/booking/Slots.tsx b/components/booking/Slots.tsx new file mode 100644 index 0000000000..ea25191b9d --- /dev/null +++ b/components/booking/Slots.tsx @@ -0,0 +1,66 @@ +import { useState, useEffect } from "react"; +import { useRouter } from "next/router"; +import getSlots from "../../lib/slots"; + +const Slots = (props) => { + const router = useRouter(); + const { user } = router.query; + const [slots, setSlots] = useState([]); + + useEffect(() => { + setSlots([]); + fetch( + `/api/availability/${user}?dateFrom=${props.date.startOf("day").utc().format()}&dateTo=${props.date + .endOf("day") + .utc() + .format()}` + ) + .then((res) => res.json()) + .then(handleAvailableSlots); + }, [props.date]); + + const handleAvailableSlots = (busyTimes: []) => { + const times = getSlots({ + frequency: props.eventLength, + inviteeDate: props.date, + workingHours: props.workingHours, + minimumBookingNotice: 0, + }); + + // Check for conflicts + for (let i = times.length - 1; i >= 0; i -= 1) { + busyTimes.forEach((busyTime) => { + const startTime = dayjs(busyTime.start); + const endTime = dayjs(busyTime.end); + + // Check if start times are the same + if (dayjs(times[i]).format("HH:mm") == startTime.format("HH:mm")) { + times.splice(i, 1); + } + + // Check if time is between start and end times + if (dayjs(times[i]).isBetween(startTime, endTime)) { + times.splice(i, 1); + } + + // Check if slot end time is between start and end time + if (dayjs(times[i]).add(props.eventType.length, "minutes").isBetween(startTime, endTime)) { + times.splice(i, 1); + } + + // Check if startTime is between slot + if (startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(props.eventType.length, "minutes"))) { + times.splice(i, 1); + } + }); + } + // Display available times + setSlots(times); + }; + + return { + slots, + }; +}; + +export default Slots; diff --git a/components/ui/Scheduler.tsx b/components/ui/Scheduler.tsx index 9b367d624d..4dea789ef0 100644 --- a/components/ui/Scheduler.tsx +++ b/components/ui/Scheduler.tsx @@ -1,45 +1,48 @@ -import React, {useEffect, useState} from "react"; +import React, { useEffect, useState } from "react"; import TimezoneSelect from "react-timezone-select"; -import {PencilAltIcon, TrashIcon} from "@heroicons/react/outline"; -import {WeekdaySelect, Weekday} from "./WeekdaySelect"; +import { TrashIcon } from "@heroicons/react/outline"; +import { WeekdaySelect } from "./WeekdaySelect"; import SetTimesModal from "./modal/SetTimesModal"; -import Schedule from '../../lib/schedule.model'; -import dayjs, {Dayjs} from "dayjs"; -import utc from 'dayjs/plugin/utc'; -import timezone from 'dayjs/plugin/timezone'; +import Schedule from "../../lib/schedule.model"; +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import timezone from "dayjs/plugin/timezone"; dayjs.extend(utc); dayjs.extend(timezone); export const Scheduler = (props) => { - - const [ schedules, setSchedules ]: Schedule[] = useState(props.schedules.map( schedule => { - const startDate = schedule.isOverride ? dayjs(schedule.startDate) : dayjs.utc().startOf('day').add(schedule.startTime, 'minutes') - return ( - { + const [schedules, setSchedules]: Schedule[] = useState( + props.schedules.map((schedule) => { + const startDate = schedule.isOverride + ? dayjs(schedule.startDate) + : dayjs.utc().startOf("day").add(schedule.startTime, "minutes").tz(props.timeZone); + return { days: schedule.days, startDate, - endDate: startDate.add(schedule.length, 'minutes') - } - ) - })); + endDate: startDate.add(schedule.length, "minutes"), + }; + }) + ); - const [ timeZone, setTimeZone ] = useState(props.timeZone); - const [ editSchedule, setEditSchedule ] = useState(-1); + const [timeZone, setTimeZone] = useState(props.timeZone); + const [editSchedule, setEditSchedule] = useState(-1); - useEffect( () => { + useEffect(() => { props.onChange(schedules); - }, [schedules]) + }, [schedules]); const addNewSchedule = () => setEditSchedule(schedules.length); const applyEditSchedule = (changed: Schedule) => { const replaceWith = { ...schedules[editSchedule], - ...changed + ...changed, }; + schedules.splice(editSchedule, 1, replaceWith); + setSchedules([].concat(schedules)); - } + }; const removeScheduleAt = (toRemove: number) => { schedules.splice(toRemove, 1); @@ -49,7 +52,7 @@ export const Scheduler = (props) => { const setWeekdays = (idx: number, days: number[]) => { schedules[idx].days = days; setSchedules([].concat(schedules)); - } + }; return (
@@ -60,26 +63,40 @@ export const Scheduler = (props) => { Timezone
- +
    - {schedules.map( (schedule, idx) => + {schedules.map((schedule, idx) => (
  • -
    - setWeekdays(idx, days)} /> - +
    + -
- - )} + + ))}
- +
{/*

Add date overrides

@@ -89,14 +106,16 @@ export const Scheduler = (props) => { */}
- {editSchedule >= 0 && - setEditSchedule(-1)} /> - } + {editSchedule >= 0 && ( + setEditSchedule(-1)} + /> + )} {/*{showDateOverrideModal && }*/} ); -} \ No newline at end of file +}; diff --git a/components/ui/WeekdaySelect.tsx b/components/ui/WeekdaySelect.tsx index 6eed8563b3..a9f371d827 100644 --- a/components/ui/WeekdaySelect.tsx +++ b/components/ui/WeekdaySelect.tsx @@ -1,42 +1,53 @@ -import React, {useEffect, useState} from "react"; +import React, { useEffect, useState } from "react"; export const WeekdaySelect = (props) => { + const [activeDays, setActiveDays] = useState( + [...Array(7).keys()].map((v, i) => (props.defaultValue || []).includes(i)) + ); - const [ activeDays, setActiveDays ] = useState([1,2,3,4,5,6,7].map( (v) => (props.defaultValue || []).indexOf(v) !== -1)); - const days = [ 'S', 'M', 'T', 'W', 'T', 'F', 'S' ]; + const days = ["S", "M", "T", "W", "T", "F", "S"]; - useEffect( () => { - props.onSelect(activeDays.map( (isActive, idx) => isActive ? idx + 1 : 0).filter( (v) => 0 !== v )); + useEffect(() => { + props.onSelect(activeDays.map((v, idx) => (v ? idx : -1)).filter((v) => v !== -1)); }, [activeDays]); const toggleDay = (e, idx: number) => { e.preventDefault(); activeDays[idx] = !activeDays[idx]; setActiveDays([].concat(activeDays)); - } + }; return (
- {days.map( (day, idx) => activeDays[idx] ? - - : - + {day} + + ) : ( + + ) )}
-
); -} \ No newline at end of file + + ); +}; diff --git a/components/ui/modal/SetTimesModal.tsx b/components/ui/modal/SetTimesModal.tsx index 2a0c1b40a9..2a9b03a96c 100644 --- a/components/ui/modal/SetTimesModal.tsx +++ b/components/ui/modal/SetTimesModal.tsx @@ -1,14 +1,20 @@ -import {ClockIcon} from "@heroicons/react/outline"; -import {useRef} from "react"; +import { ClockIcon } from "@heroicons/react/outline"; +import { useRef } from "react"; import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import timezone from "dayjs/plugin/utc"; +dayjs.extend(utc); +dayjs.extend(timezone); export default function SetTimesModal(props) { - - const {startDate, endDate} = props.schedule || { - startDate: dayjs().startOf('day').add(540, 'minutes'), - endDate: dayjs().startOf('day').add(1020, 'minutes'), + const { startDate, endDate } = props.schedule || { + startDate: dayjs.utc().startOf("day").add(540, "minutes"), + endDate: dayjs.utc().startOf("day").add(1020, "minutes"), }; + startDate.tz(props.timeZone); + endDate.tz(props.timeZone); + const startHoursRef = useRef(); const startMinsRef = useRef(); const endHoursRef = useRef(); @@ -31,60 +37,108 @@ export default function SetTimesModal(props) { } return ( -
+
- + -
+
-
- +
+
-

- Set your work schedule -

+

Set your work schedule

- - + +
:
- - + +
- - + +
:
- - + +
@@ -97,5 +151,6 @@ export default function SetTimesModal(props) {
-
); -} \ No newline at end of file +
+ ); +} diff --git a/lib/slots.ts b/lib/slots.ts index 157b56a692..00ffc738ab 100644 --- a/lib/slots.ts +++ b/lib/slots.ts @@ -1,94 +1,108 @@ -const dayjs = require("dayjs"); - -const isToday = require("dayjs/plugin/isToday"); -const utc = require("dayjs/plugin/utc"); -const timezone = require("dayjs/plugin/timezone"); - -dayjs.extend(isToday); +import dayjs, { Dayjs } from "dayjs"; +import utc from "dayjs/plugin/utc"; dayjs.extend(utc); -dayjs.extend(timezone); -const getMinutesFromMidnight = (date) => { - return date.hour() * 60 + date.minute(); +interface GetSlotsType { + inviteeDate: Dayjs; + frequency: number; + workingHours: { [WeekDay]: Boundary[] }; + minimumBookingNotice?: number; +} + +interface Boundary { + lowerBound: number; + upperBound: number; +} + +const freqApply: number = (cb, value: number, frequency: number): number => cb(value / frequency) * frequency; + +const intersectBoundary = (a: Boundary, b: Boundary) => { + if (a.upperBound < b.lowerBound || a.lowerBound > b.upperBound) { + return; + } + return { + lowerBound: Math.max(b.lowerBound, a.lowerBound), + upperBound: Math.min(b.upperBound, a.upperBound), + }; }; -const getSlots = ({ - calendarTimeZone, - eventLength, - selectedTimeZone, - selectedDate, - dayStartTime, - dayEndTime -}) => { +// say invitee is -60,1380, and boundary is -120,240 - the overlap is -60,240 +const getOverlaps = (inviteeBoundary: Boundary, boundaries: Boundary[]) => + boundaries.map((boundary) => intersectBoundary(inviteeBoundary, boundary)).filter(Boolean); - if(!selectedDate) return [] - - const lowerBound = selectedDate.tz(selectedTimeZone).startOf("day"); +const organizerBoundaries = (workingHours: [], inviteeDate: Dayjs, inviteeBounds: Boundary): Boundary[] => { + const boundaries: Boundary[] = []; - // Simple case, same timezone - if (calendarTimeZone === selectedTimeZone) { - const slots = []; - const now = dayjs(); - for ( - let minutes = dayStartTime; - minutes <= dayEndTime - eventLength; - minutes += parseInt(eventLength, 10) - ) { - const slot = lowerBound.add(minutes, "minutes"); - if (slot > now) { - slots.push(slot); - } - } - return slots; - } - - const upperBound = selectedDate.tz(selectedTimeZone).endOf("day"); - - // We need to start generating slots from the start of the calendarTimeZone day - const startDateTime = lowerBound - .tz(calendarTimeZone) + const startDay: number = +inviteeDate + .utc() .startOf("day") - .add(dayStartTime, "minutes"); + .add(inviteeBounds.lowerBound, "minutes") + .format("d"); + const endDay: number = +inviteeDate + .utc() + .startOf("day") + .add(inviteeBounds.upperBound, "minutes") + .format("d"); - let phase = 0; - if (startDateTime < lowerBound) { - // Getting minutes of the first event in the day of the chooser - const diff = lowerBound.diff(startDateTime, "minutes"); - - // finding first event - phase = diff + eventLength - (diff % eventLength); - } - - // We can stop as soon as the selectedTimeZone day ends - const endDateTime = upperBound - .tz(calendarTimeZone) - .subtract(eventLength, "minutes"); - - const maxMinutes = endDateTime.diff(startDateTime, "minutes"); - - const slots = []; - const now = dayjs(); - for ( - let minutes = phase; - minutes <= maxMinutes; - minutes += parseInt(eventLength, 10) - ) { - const slot = startDateTime.add(minutes, "minutes"); - - const minutesFromMidnight = getMinutesFromMidnight(slot); - - if ( - minutesFromMidnight < dayStartTime || - minutesFromMidnight > dayEndTime - eventLength || - slot < now - ) { - continue; + workingHours.forEach((item) => { + const lowerBound: number = item.startTime; + const upperBound: number = lowerBound + item.length; + if (startDay !== endDay) { + if (inviteeBounds.lowerBound < 0) { + // lowerBound edges into the previous day + if (item.days.includes(startDay)) { + boundaries.push({ lowerBound: lowerBound - 1440, upperBound: upperBound - 1440 }); + } + if (item.days.includes(endDay)) { + boundaries.push({ lowerBound, upperBound }); + } + } else { + // upperBound edges into the next day + if (item.days.includes(endDay)) { + boundaries.push({ lowerBound: lowerBound + 1440, upperBound: upperBound + 1440 }); + } + if (item.days.includes(startDay)) { + boundaries.push({ lowerBound, upperBound }); + } + } + } else { + boundaries.push({ lowerBound, upperBound }); } + }); + return boundaries; +}; - slots.push(slot.tz(selectedTimeZone)); +const inviteeBoundary = (startTime: number, utcOffset: number, frequency: number): Boundary => { + const upperBound: number = freqApply(Math.floor, 1440 - utcOffset, frequency); + const lowerBound: number = freqApply(Math.ceil, startTime - utcOffset, frequency); + return { + lowerBound, + upperBound, + }; +}; + +const getSlotsBetweenBoundary = (frequency: number, { lowerBound, upperBound }: Boundary) => { + const slots: Dayjs[] = []; + for (let minutes = 0; lowerBound + minutes <= upperBound - frequency; minutes += frequency) { + slots.push( + dayjs + .utc() + .startOf("day") + .add(lowerBound + minutes, "minutes") + ); } - return slots; }; -export default getSlots +const getSlots = ({ inviteeDate, frequency, minimumBookingNotice, workingHours }: GetSlotsType): Dayjs[] => { + const startTime = dayjs.utc().isSame(dayjs(inviteeDate), "day") + ? inviteeDate.hour() * 60 + inviteeDate.minute() + minimumBookingNotice + : 0; + + const inviteeBounds = inviteeBoundary(startTime, inviteeDate.utcOffset(), frequency); + return getOverlaps(inviteeBounds, organizerBoundaries(workingHours, inviteeDate, inviteeBounds)) + .reduce((slots, boundary: Boundary) => [...slots, ...getSlotsBetweenBoundary(frequency, boundary)], []) + .map((slot) => slot.utcOffset(dayjs(inviteeDate).utcOffset())); +}; + +export default getSlots; diff --git a/package.json b/package.json index 31e86ca42c..a81a930bff 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "dev": "next dev", + "test": "node --experimental-vm-modules node_modules/.bin/jest", "build": "next build", "start": "next start", "postinstall": "prisma generate", @@ -36,6 +37,7 @@ "uuid": "^8.3.2" }, "devDependencies": { + "@types/jest": "^26.0.23", "@types/node": "^14.14.33", "@types/react": "^17.0.3", "@typescript-eslint/eslint-plugin": "^4.27.0", @@ -47,7 +49,9 @@ "eslint-plugin-react": "^7.24.0", "eslint-plugin-react-hooks": "^4.2.0", "husky": "^6.0.0", + "jest": "^27.0.5", "lint-staged": "^11.0.0", + "mockdate": "^3.0.5", "postcss": "^8.2.8", "prettier": "^2.3.1", "prisma": "^2.23.0", @@ -59,5 +63,19 @@ "prettier --write", "eslint" ] + }, + "jest": { + "verbose": true, + "extensionsToTreatAsEsm": [ + ".ts" + ], + "moduleFileExtensions": [ + "js", + "ts" + ], + "moduleNameMapper": { + "^@components(.*)$": "/components$1", + "^@lib(.*)$": "/lib$1" + } } } diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index c43199293d..66f3640e75 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -1,58 +1,64 @@ -import {useEffect, useState, useMemo} from 'react'; -import Head from 'next/head'; -import Link from 'next/link'; -import prisma from '../../lib/prisma'; -import dayjs, { Dayjs } from 'dayjs'; -import { ClockIcon, GlobeIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/solid'; -import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; -import utc from 'dayjs/plugin/utc'; -import timezone from 'dayjs/plugin/timezone'; +import { useEffect, useState, useMemo } from "react"; +import Head from "next/head"; +import prisma from "../../lib/prisma"; +import dayjs, { Dayjs } from "dayjs"; +import { ClockIcon, GlobeIcon, ChevronDownIcon } from "@heroicons/react/solid"; +import isSameOrBefore from "dayjs/plugin/isSameOrBefore"; +import utc from "dayjs/plugin/utc"; +import timezone from "dayjs/plugin/timezone"; dayjs.extend(isSameOrBefore); dayjs.extend(utc); dayjs.extend(timezone); -import {collectPageParameters, telemetryEventTypes, useTelemetry} from "../../lib/telemetry"; +import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry"; import AvailableTimes from "../../components/booking/AvailableTimes"; -import TimeOptions from "../../components/booking/TimeOptions" -import Avatar from '../../components/Avatar'; -import {timeZone} from "../../lib/clock"; +import TimeOptions from "../../components/booking/TimeOptions"; +import Avatar from "../../components/Avatar"; +import { timeZone } from "../../lib/clock"; import DatePicker from "../../components/booking/DatePicker"; import PoweredByCalendso from "../../components/ui/PoweredByCalendso"; -import {useRouter} from "next/router"; +import { useRouter } from "next/router"; +import getSlots from "@lib/slots"; export default function Type(props) { - - // Get router variables const router = useRouter(); const { rescheduleUid } = router.query; - // Initialise state const [selectedDate, setSelectedDate] = useState(); - const [selectedMonth, setSelectedMonth] = useState(dayjs().month()); const [isTimeOptionsOpen, setIsTimeOptionsOpen] = useState(false); - const [timeFormat, setTimeFormat] = useState('h:mma'); + const [timeFormat, setTimeFormat] = useState("h:mma"); const telemetry = useTelemetry(); + const today: string = dayjs().utc().format("YYYY-MM-DDTHH:mm"); + const noSlotsToday = useMemo( + () => + getSlots({ + frequency: props.eventType.length, + inviteeDate: dayjs.utc(today) as Dayjs, + workingHours: props.workingHours, + minimumBookingNotice: 0, + }).length === 0, + [today, props.eventType.length, props.workingHours] + ); + useEffect(() => { - telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())) - }, []); + telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())); + }, [telemetry]); const changeDate = (date: Dayjs) => { - telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.dateSelected, collectPageParameters())) + telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.dateSelected, collectPageParameters())); setSelectedDate(date); }; const handleSelectTimeZone = (selectedTimeZone: string) => { if (selectedDate) { - setSelectedDate(selectedDate.tz(selectedTimeZone)) + setSelectedDate(selectedDate.tz(selectedTimeZone)); } }; const handleToggle24hClock = (is24hClock: boolean) => { - if (selectedDate) { - setTimeFormat(is24hClock ? 'HH:mm' : 'h:mma'); - } - } + setTimeFormat(is24hClock ? "HH:mm" : "h:mma"); + }; return (
@@ -67,40 +73,47 @@ export default function Type(props) { className={ "mx-auto my-24 transition-max-width ease-in-out duration-500 " + (selectedDate ? "max-w-6xl" : "max-w-3xl") - } - > + }>
-
+

{props.user.name}

-

- {props.eventType.title} -

+

{props.eventType.title}

{props.eventType.length} minutes

- { isTimeOptionsOpen && } -

- {props.eventType.description} -

-
- - {selectedDate && } + className="text-gray-500 mb-1 px-2 py-1 -ml-2"> + + {timeZone()} + + + {isTimeOptionsOpen && ( + + )} +

{props.eventType.description}

+
+ + {selectedDate && ( + + )}
{/* note(peer): @@ -112,6 +125,14 @@ export default function Type(props) { ); } +interface WorkingHours { + days: number[]; + startTime: number; + length: number; +} + +type Availability = WorkingHours; + export async function getServerSideProps(context) { const user = await prisma.user.findFirst({ where: { @@ -129,13 +150,14 @@ export async function getServerSideProps(context) { timeZone: true, endTime: true, weekStart: true, - } + availability: true, + }, }); if (!user) { return { notFound: true, - } + }; } const eventType = await prisma.eventType.findFirst({ @@ -149,20 +171,38 @@ export async function getServerSideProps(context) { id: true, title: true, description: true, - length: true - } + length: true, + availability: true, + }, }); if (!eventType) { return { notFound: true, - } + }; } + const getWorkingHours = (providesAvailability) => + providesAvailability.availability && providesAvailability.availability.length + ? providesAvailability.availability + : null; + + const workingHours: WorkingHours[] = + getWorkingHours(eventType) || + getWorkingHours(user) || + [ + { + days: [1, 2, 3, 4, 5, 6, 7], + startTime: user.startTime, + length: user.endTime, + }, + ].filter((availability: Availability): boolean => typeof availability["days"] !== "undefined"); + return { props: { user, eventType, + workingHours, }, - } + }; } diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx index 144e80e023..8c203be008 100644 --- a/pages/availability/event/[type].tsx +++ b/pages/availability/event/[type].tsx @@ -1,244 +1,267 @@ -import Head from 'next/head'; -import Link from 'next/link'; -import { useRouter } from 'next/router'; -import { useRef, useState, useEffect } from 'react'; -import Select, { OptionBase } from 'react-select'; -import prisma from '../../../lib/prisma'; -import {LocationType} from '../../../lib/location'; -import Shell from '../../../components/Shell'; -import { useSession, getSession } from 'next-auth/client'; -import {Scheduler} from "../../../components/ui/Scheduler"; +import Head from "next/head"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import { useRef, useState } from "react"; +import Select, { OptionBase } from "react-select"; +import prisma from "../../../lib/prisma"; +import { LocationType } from "../../../lib/location"; +import Shell from "../../../components/Shell"; +import { getSession } from "next-auth/client"; +import { Scheduler } from "../../../components/ui/Scheduler"; -import { - LocationMarkerIcon, - PlusCircleIcon, - XIcon, - PhoneIcon, -} from '@heroicons/react/outline'; -import {EventTypeCustomInput, EventTypeCustomInputType} from "../../../lib/eventTypeInput"; -import {PlusIcon} from "@heroicons/react/solid"; +import { LocationMarkerIcon, PlusCircleIcon, XIcon, PhoneIcon } from "@heroicons/react/outline"; +import { EventTypeCustomInput, EventTypeCustomInputType } from "../../../lib/eventTypeInput"; +import { PlusIcon } from "@heroicons/react/solid"; -import dayjs, {Dayjs} from "dayjs"; -import utc from 'dayjs/plugin/utc'; +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; dayjs.extend(utc); -import timezone from 'dayjs/plugin/timezone'; +import timezone from "dayjs/plugin/timezone"; dayjs.extend(timezone); export default function EventType(props) { - const router = useRouter(); + const router = useRouter(); - const inputOptions: OptionBase[] = [ - { value: EventTypeCustomInputType.Text, label: 'Text' }, - { value: EventTypeCustomInputType.TextLong, label: 'Multiline Text' }, - { value: EventTypeCustomInputType.Number, label: 'Number', }, - { value: EventTypeCustomInputType.Bool, label: 'Checkbox', }, - ] + const inputOptions: OptionBase[] = [ + { value: EventTypeCustomInputType.Text, label: "Text" }, + { value: EventTypeCustomInputType.TextLong, label: "Multiline Text" }, + { value: EventTypeCustomInputType.Number, label: "Number" }, + { value: EventTypeCustomInputType.Bool, label: "Checkbox" }, + ]; - const [ session, loading ] = useSession(); - const [ showLocationModal, setShowLocationModal ] = useState(false); - const [ showAddCustomModal, setShowAddCustomModal ] = useState(false); - const [ selectedLocation, setSelectedLocation ] = useState(undefined); - const [ selectedInputOption, setSelectedInputOption ] = useState(inputOptions[0]); - const [ locations, setLocations ] = useState(props.eventType.locations || []); - const [ schedule, setSchedule ] = useState(undefined); - const [customInputs, setCustomInputs] = useState(props.eventType.customInputs.sort((a, b) => a.id - b.id) || []); - const locationOptions = props.locationOptions + const [showLocationModal, setShowLocationModal] = useState(false); + const [showAddCustomModal, setShowAddCustomModal] = useState(false); + const [selectedLocation, setSelectedLocation] = useState(undefined); + const [selectedInputOption, setSelectedInputOption] = useState(inputOptions[0]); + const [locations, setLocations] = useState(props.eventType.locations || []); + const [schedule, setSchedule] = useState(undefined); + const [customInputs, setCustomInputs] = useState( + props.eventType.customInputs.sort((a, b) => a.id - b.id) || [] + ); + const locationOptions = props.locationOptions; - const titleRef = useRef(); - const slugRef = useRef(); - const descriptionRef = useRef(); - const lengthRef = useRef(); - const isHiddenRef = useRef(); - const eventNameRef = useRef(); + const titleRef = useRef(); + const slugRef = useRef(); + const descriptionRef = useRef(); + const lengthRef = useRef(); + const isHiddenRef = useRef(); + const eventNameRef = useRef(); - if (loading) { - return

Loading...

; - } + async function updateEventTypeHandler(event) { + event.preventDefault(); - async function updateEventTypeHandler(event) { - event.preventDefault(); + const enteredTitle = titleRef.current.value; + const enteredSlug = slugRef.current.value; + const enteredDescription = descriptionRef.current.value; + const enteredLength = lengthRef.current.value; + const enteredIsHidden = isHiddenRef.current.checked; + const enteredEventName = eventNameRef.current.value; + // TODO: Add validation - const enteredTitle = titleRef.current.value; - const enteredSlug = slugRef.current.value; - const enteredDescription = descriptionRef.current.value; - const enteredLength = lengthRef.current.value; - const enteredIsHidden = isHiddenRef.current.checked; - const enteredEventName = eventNameRef.current.value; - // TODO: Add validation + await fetch("/api/availability/eventtype", { + method: "PATCH", + body: JSON.stringify({ + id: props.eventType.id, + title: enteredTitle, + slug: enteredSlug, + description: enteredDescription, + length: enteredLength, + hidden: enteredIsHidden, + locations, + eventName: enteredEventName, + customInputs, + }), + headers: { + "Content-Type": "application/json", + }, + }); - const response = await fetch('/api/availability/eventtype', { - method: 'PATCH', - body: JSON.stringify({id: props.eventType.id, title: enteredTitle, slug: enteredSlug, description: enteredDescription, length: enteredLength, hidden: enteredIsHidden, locations, eventName: enteredEventName, customInputs }), - headers: { - 'Content-Type': 'application/json' - } - }); - - if (schedule) { - - let schedulePayload = { "overrides": [], "timeZone": props.user.timeZone, "openingHours": [] }; - schedule.forEach( (item) => { - if (item.isOverride) { - delete item.isOverride; - schedulePayload.overrides.push(item); - } else { - schedulePayload.openingHours.push({ - days: item.days, - startTime: item.startDate.hour() * 60 + item.startDate.minute(), - endTime: item.endDate.hour() * 60 + item.endDate.minute() - }); - } - }); - - const response = await fetch('/api/availability/schedule/' + props.eventType.id, { - method: 'PUT', - body: JSON.stringify(schedulePayload), - headers: { - 'Content-Type': 'application/json' - } - }); - } - - router.push('/availability'); - } - - async function deleteEventTypeHandler(event) { - event.preventDefault(); - - const response = await fetch('/api/availability/eventtype', { - method: 'DELETE', - body: JSON.stringify({id: props.eventType.id}), - headers: { - 'Content-Type': 'application/json' - } - }); - - router.push('/availability'); - } - - const openLocationModal = (type: LocationType) => { - setSelectedLocation(locationOptions.find( (option) => option.value === type)); - setShowLocationModal(true); - } - - const closeLocationModal = () => { - setSelectedLocation(undefined); - setShowLocationModal(false); - }; - - const closeAddCustomModal = () => { - setSelectedInputOption(inputOptions[0]); - setShowAddCustomModal(false); - }; - - const LocationOptions = () => { - if (!selectedLocation) { - return null; - } - switch (selectedLocation.value) { - case LocationType.InPerson: - const address = locations.find( - (location) => location.type === LocationType.InPerson - )?.address; - return ( -
- -
- -
-
- ) - case LocationType.Phone: - - return ( -

Calendso will ask your invitee to enter a phone number before scheduling.

- ) - case LocationType.GoogleMeet: - return ( -

Calendso will provide a Google Meet location.

- ) - } - return null; - }; - - const updateLocations = (e) => { - e.preventDefault(); - - let details = {}; - if (e.target.location.value === LocationType.InPerson) { - details = { address: e.target.address.value }; - } - - const existingIdx = locations.findIndex( (loc) => e.target.location.value === loc.type ); - if (existingIdx !== -1) { - let copy = locations; - copy[ existingIdx ] = { ...locations[ existingIdx ], ...details }; - setLocations(copy); + if (schedule) { + const schedulePayload = { overrides: [], timeZone: props.user.timeZone, openingHours: [] }; + schedule.forEach((item) => { + if (item.isOverride) { + delete item.isOverride; + schedulePayload.overrides.push(item); } else { - setLocations(locations.concat({ type: e.target.location.value, ...details })); + const endTime = item.endDate.hour() * 60 + item.endDate.minute() || 1440; // also handles 00:00 + schedulePayload.openingHours.push({ + days: item.days, + startTime: item.startDate.hour() * 60 + item.startDate.minute() - item.startDate.utcOffset(), + endTime: endTime - item.endDate.utcOffset(), + }); } + }); - setShowLocationModal(false); + await fetch("/api/availability/schedule/" + props.eventType.id, { + method: "PUT", + body: JSON.stringify(schedulePayload), + headers: { + "Content-Type": "application/json", + }, + }); + } + + router.push("/availability"); + } + + async function deleteEventTypeHandler(event) { + event.preventDefault(); + + await fetch("/api/availability/eventtype", { + method: "DELETE", + body: JSON.stringify({ id: props.eventType.id }), + headers: { + "Content-Type": "application/json", + }, + }); + + router.push("/availability"); + } + + const openLocationModal = (type: LocationType) => { + setSelectedLocation(locationOptions.find((option) => option.value === type)); + setShowLocationModal(true); + }; + + const closeLocationModal = () => { + setSelectedLocation(undefined); + setShowLocationModal(false); + }; + + const closeAddCustomModal = () => { + setSelectedInputOption(inputOptions[0]); + setShowAddCustomModal(false); + }; + + const LocationOptions = () => { + if (!selectedLocation) { + return null; + } + switch (selectedLocation.value) { + case LocationType.InPerson: { + const address = locations.find((location) => location.type === LocationType.InPerson)?.address; + return ( +
+ +
+ +
+
+ ); + } + case LocationType.Phone: + return ( +

Calendso will ask your invitee to enter a phone number before scheduling.

+ ); + case LocationType.GoogleMeet: + return

Calendso will provide a Google Meet location.

; + } + return null; + }; + + const updateLocations = (e) => { + e.preventDefault(); + + let details = {}; + if (e.target.location.value === LocationType.InPerson) { + details = { address: e.target.address.value }; + } + + const existingIdx = locations.findIndex((loc) => e.target.location.value === loc.type); + if (existingIdx !== -1) { + const copy = locations; + copy[existingIdx] = { ...locations[existingIdx], ...details }; + setLocations(copy); + } else { + setLocations(locations.concat({ type: e.target.location.value, ...details })); + } + + setShowLocationModal(false); + }; + + const removeLocation = (selectedLocation) => { + setLocations(locations.filter((location) => location.type !== selectedLocation.type)); + }; + + const updateCustom = (e) => { + e.preventDefault(); + + const customInput: EventTypeCustomInput = { + label: e.target.label.value, + required: e.target.required.checked, + type: e.target.type.value, }; - const removeLocation = (selectedLocation) => { - setLocations(locations.filter( (location) => location.type !== selectedLocation.type )); - }; + setCustomInputs(customInputs.concat(customInput)); - const updateCustom = (e) => { - e.preventDefault(); + setShowAddCustomModal(false); + }; - const customInput: EventTypeCustomInput = { - label: e.target.label.value, - required: e.target.required.checked, - type: e.target.type.value - }; - - setCustomInputs(customInputs.concat(customInput)); - - setShowAddCustomModal(false); - }; - - return ( -
- - {props.eventType.title} | Event Type | Calendso - - - -
-
-
-
-
-
- -
- + return ( +
+ + {props.eventType.title} | Event Type | Calendso + + + +
+
+
+
+ +
+ +
+ +
+
+
+ +
+
+ + {location.hostname}/{props.user.username}/ + +
-
- -
-
- - {location.hostname}/{props.user.username}/ - - -
-
-
-
- - {locations.length === 0 &&
+
+
+ + {locations.length === 0 && ( +
-
- -
- +
+
+ +
+ +
+ minutes
-
- -
- -
- minutes -
-
+
+
+ +
+
-
- -
- -
-
-
- -
    - {customInputs.map( (customInput) => ( -
  • -
    +
    +
    + +
      + {customInputs.map((customInput) => ( +
    • +
      +
      -
      - Label: {customInput.label} -
      -
      - Type: {customInput.type} -
      -
      - {customInput.required ? "Required" : "Optional"} -
      + Label: {customInput.label}
      -
      - - +
      + Type: {customInput.type} +
      +
      + + {customInput.required ? "Required" : "Optional"} +
      -
    • - ))} -
    • - +
      + + +
      +
  • -
-
-
-
-
- -
-
- -

Hide the event type from your page, so it can only be booked through it's URL.

-
+ ))} +
  • + +
  • + +
    +
    +
    +
    + +
    +
    + +

    + Hide the event type from your page, so it can only be booked through it's URL. +

    -
    -
    -

    How do you want to offer your availability for this event type?

    - -
    - Cancel - -
    +
    +
    +
    +

    How do you want to offer your availability for this event type?

    + +
    + + Cancel + +
    - -
    +
    +
    -
    -
    -
    -

    - Delete this event type -

    -
    -

    - Once you delete this event type, it will be permanently removed. -

    -
    -
    - -
    +
    +
    +
    +
    +

    Delete this event type

    +
    +

    Once you delete this event type, it will be permanently removed.

    +
    +
    +
    - {showLocationModal && -
    +
    + {showLocationModal && ( +
    - + - +
    @@ -414,7 +513,9 @@ export default function EventType(props) {
    - +
    @@ -439,87 +540,115 @@ export default function EventType(props) {
    - } - {showAddCustomModal && -
    -
    - - ); + )} + +
    + ); } const validJson = (jsonString: string) => { try { - const o = JSON.parse(jsonString); - if (o && typeof o === "object") { - return o; - } + const o = JSON.parse(jsonString); + if (o && typeof o === "object") { + return o; + } + } catch (e) { + // no longer empty } - catch (e) {} return false; -} +}; export async function getServerSideProps(context) { const session = await getSession(context); if (!session) { - return { redirect: { permanent: false, destination: '/auth/login' } }; + return { redirect: { permanent: false, destination: "/auth/login" } }; } const user = await prisma.user.findFirst({ @@ -532,7 +661,7 @@ export async function getServerSideProps(context) { startTime: true, endTime: true, availability: true, - } + }, }); const eventType = await prisma.eventType.findUnique({ @@ -549,86 +678,79 @@ export async function getServerSideProps(context) { locations: true, eventName: true, availability: true, - customInputs: true - } + customInputs: true, + }, }); - const credentials = await prisma.credential.findMany({ - where: { - userId: user.id, - }, - select: { - id: true, - type: true, - key: true - } - }); + const credentials = await prisma.credential.findMany({ + where: { + userId: user.id, + }, + select: { + id: true, + type: true, + key: true, + }, + }); - const integrations = [ { - installed: !!(process.env.GOOGLE_API_CREDENTIALS && validJson(process.env.GOOGLE_API_CREDENTIALS)), - enabled: credentials.find( (integration) => integration.type === "google_calendar" ) != null, - type: "google_calendar", - title: "Google Calendar", - imageSrc: "integrations/google-calendar.png", - description: "For personal and business accounts", - }, { - installed: !!(process.env.MS_GRAPH_CLIENT_ID && process.env.MS_GRAPH_CLIENT_SECRET), - type: "office365_calendar", - enabled: credentials.find( (integration) => integration.type === "office365_calendar" ) != null, - title: "Office 365 / Outlook.com Calendar", - imageSrc: "integrations/office-365.png", - description: "For personal and business accounts", - } ]; + const integrations = [ + { + installed: !!(process.env.GOOGLE_API_CREDENTIALS && validJson(process.env.GOOGLE_API_CREDENTIALS)), + enabled: credentials.find((integration) => integration.type === "google_calendar") != null, + type: "google_calendar", + title: "Google Calendar", + imageSrc: "integrations/google-calendar.png", + description: "For personal and business accounts", + }, + { + installed: !!(process.env.MS_GRAPH_CLIENT_ID && process.env.MS_GRAPH_CLIENT_SECRET), + type: "office365_calendar", + enabled: credentials.find((integration) => integration.type === "office365_calendar") != null, + title: "Office 365 / Outlook.com Calendar", + imageSrc: "integrations/office-365.png", + description: "For personal and business accounts", + }, + ]; - let locationOptions: OptionBase[] = [ - { value: LocationType.InPerson, label: 'In-person meeting' }, - { value: LocationType.Phone, label: 'Phone call', }, - ]; + const locationOptions: OptionBase[] = [ + { value: LocationType.InPerson, label: "In-person meeting" }, + { value: LocationType.Phone, label: "Phone call" }, + ]; - const hasGoogleCalendarIntegration = integrations.find((i) => i.type === "google_calendar" && i.installed === true && i.enabled) - if (hasGoogleCalendarIntegration) { - locationOptions.push( { value: LocationType.GoogleMeet, label: 'Google Meet' }) - } + const hasGoogleCalendarIntegration = integrations.find( + (i) => i.type === "google_calendar" && i.installed === true && i.enabled + ); + if (hasGoogleCalendarIntegration) { + locationOptions.push({ value: LocationType.GoogleMeet, label: "Google Meet" }); + } - const hasOfficeIntegration = integrations.find((i) => i.type === "office365_calendar" && i.installed === true && i.enabled) - if (hasOfficeIntegration) { - // TODO: Add default meeting option of the office integration. - // Assuming it's Microsoft Teams. - } - - const eventType = await prisma.eventType.findUnique({ - where: { - id: parseInt(context.query.type), - }, - select: { - id: true, - title: true, - slug: true, - description: true, - length: true, - hidden: true, - locations: true, - eventName: true, - customInputs: true, - availability: true, - } - }); + const hasOfficeIntegration = integrations.find( + (i) => i.type === "office365_calendar" && i.installed === true && i.enabled + ); + if (hasOfficeIntegration) { + // TODO: Add default meeting option of the office integration. + // Assuming it's Microsoft Teams. + } if (!eventType) { return { notFound: true, - } + }; } - const getAvailability = (providesAvailability) => ( + const getAvailability = (providesAvailability) => providesAvailability.availability && providesAvailability.availability.length - ) ? providesAvailability.availability : null; + ? providesAvailability.availability + : null; - const schedules = getAvailability(eventType) || getAvailability(user) || [ { - days: [ 1, 2, 3, 4, 5, 6, 7 ], - startTime: user.startTime, - length: user.endTime >= 1440 ? 1439 : user.endTime, - } ]; + const schedules = getAvailability(eventType) || + getAvailability(user) || [ + { + days: [1, 2, 3, 4, 5, 6, 7], + startTime: user.startTime, + length: user.endTime >= 1440 ? 1439 : user.endTime, + }, + ]; return { props: { @@ -637,5 +759,5 @@ export async function getServerSideProps(context) { schedules, locationOptions, }, - } + }; } diff --git a/test/lib/slots.test.ts b/test/lib/slots.test.ts new file mode 100644 index 0000000000..90bec4be3b --- /dev/null +++ b/test/lib/slots.test.ts @@ -0,0 +1,39 @@ +import getSlots from '@lib/slots'; +import {it, expect} from '@jest/globals'; +import MockDate from 'mockdate'; +import dayjs, {Dayjs} from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; +dayjs.extend(utc); +dayjs.extend(timezone); + +MockDate.set('2021-06-20T12:00:00Z'); + +it('can fit 24 hourly slots for an empty day', async () => { + // 24h in a day. + expect(getSlots({ + inviteeDate: dayjs().add(1, 'day'), + length: 60, + })).toHaveLength(24); +}); + +it('has slots that be in the same timezone as the invitee', async() => { + expect(getSlots({ + inviteeDate: dayjs().add(1, 'day'), + length: 60 + })[0].utcOffset()).toBe(-0); + + expect(getSlots({ + inviteeDate: dayjs().tz('Europe/London').add(1, 'day'), + length: 60 + })[0].utcOffset()).toBe(dayjs().tz('Europe/London').utcOffset()); +}) + +it('excludes slots that have already passed when invitee day equals today', async () => { + expect(getSlots({ inviteeDate: dayjs(), length: 60 })).toHaveLength(12); +}); + +it('supports having slots in different utc offset than the invitee', async () => { + expect(getSlots({ inviteeDate: dayjs(), length: 60 })).toHaveLength(12); + expect(getSlots({ inviteeDate: dayjs().tz('Europe/Brussels'), length: 60 })).toHaveLength(14); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 35d51eac90..7d0d28ffdd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,11 @@ "dom.iterable", "esnext" ], + "baseUrl": ".", + "paths": { + "@components/*": ["components/*"], + "@lib/*": ["lib/*"] + }, "allowJs": true, "skipLibCheck": true, "strict": false, diff --git a/yarn.lock b/yarn.lock index fd8a34d290..0311f59fb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,13 +9,145 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== dependencies: "@babel/highlight" "^7.14.5" +"@babel/compat-data@^7.14.5": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" + integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== + +"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab" + integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.5" + "@babel/helper-compilation-targets" "^7.14.5" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helpers" "^7.14.6" + "@babel/parser" "^7.14.6" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.14.5", "@babel/generator@^7.7.2": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" + integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== + dependencies: + "@babel/types" "^7.14.5" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-compilation-targets@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" + integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== + dependencies: + "@babel/compat-data" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + browserslist "^4.16.6" + semver "^6.3.0" + +"@babel/helper-function-name@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" + integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== + dependencies: + "@babel/helper-get-function-arity" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/helper-get-function-arity@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" + integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-hoist-variables@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" + integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-member-expression-to-functions@^7.14.5": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970" + integrity sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-module-imports@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" + integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-module-transforms@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz#7de42f10d789b423eb902ebd24031ca77cb1e10e" + integrity sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA== + dependencies: + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-simple-access" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/helper-optimise-call-expression@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" + integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== + +"@babel/helper-replace-supers@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94" + integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.14.5" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/helper-simple-access@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4" + integrity sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw== + dependencies: + "@babel/types" "^7.14.5" + +"@babel/helper-split-export-declaration@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" + integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== + dependencies: + "@babel/types" "^7.14.5" + "@babel/helper-validator-identifier@^7.14.0": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" @@ -26,6 +158,20 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== +"@babel/helper-validator-option@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" + integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== + +"@babel/helpers@^7.14.6": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.6.tgz#5b58306b95f1b47e2a0199434fa8658fa6c21635" + integrity sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA== + dependencies: + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" + "@babel/highlight@^7.10.4": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" @@ -44,6 +190,102 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7", "@babel/parser@^7.7.2": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" + integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" + integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/runtime@7.12.5": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" @@ -58,6 +300,30 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/template@^7.14.5", "@babel/template@^7.3.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" + integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/parser" "^7.14.5" + "@babel/types" "^7.14.5" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.7.2": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" + integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.5" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/parser" "^7.14.7" + "@babel/types" "^7.14.5" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" @@ -67,6 +333,19 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.0.0", "@babel/types@^7.14.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" + integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@emotion/cache@^11.0.0", "@emotion/cache@^11.1.3": version "11.1.3" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.1.3.tgz#c7683a9484bcd38d5562f2b9947873cf66829afd" @@ -191,6 +470,202 @@ resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.1.tgz#66d25f6441920bd5c2146ea27fd33995885452dd" integrity sha512-uikw2gKCmqnvjVxitecWfFLMOKyL9BTFcU4VM3hHj9OMwpkCr5Ke+MRMyY2/aQVmsYs4VTq7NCFX05MYwAHi3g== +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^27.0.2": + version "27.0.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.2.tgz#b8eeff8f21ac51d224c851e1729d2630c18631e6" + integrity sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w== + dependencies: + "@jest/types" "^27.0.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.0.2" + jest-util "^27.0.2" + slash "^3.0.0" + +"@jest/core@^27.0.5": + version "27.0.5" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.5.tgz#59e9e69e7374d65dbb22e3fc1bd52e80991eae72" + integrity sha512-g73//jF0VwsOIrWUC9Cqg03lU3QoAMFxVjsm6n6yNmwZcQPN/o8w+gLWODw5VfKNFZT38otXHWxc6b8eGDUpEA== + dependencies: + "@jest/console" "^27.0.2" + "@jest/reporters" "^27.0.5" + "@jest/test-result" "^27.0.2" + "@jest/transform" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-changed-files "^27.0.2" + jest-config "^27.0.5" + jest-haste-map "^27.0.5" + jest-message-util "^27.0.2" + jest-regex-util "^27.0.1" + jest-resolve "^27.0.5" + jest-resolve-dependencies "^27.0.5" + jest-runner "^27.0.5" + jest-runtime "^27.0.5" + jest-snapshot "^27.0.5" + jest-util "^27.0.2" + jest-validate "^27.0.2" + jest-watcher "^27.0.2" + micromatch "^4.0.4" + p-each-series "^2.1.0" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^27.0.5": + version "27.0.5" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.5.tgz#a294ad4acda2e250f789fb98dc667aad33d3adc9" + integrity sha512-IAkJPOT7bqn0GiX5LPio6/e1YpcmLbrd8O5EFYpAOZ6V+9xJDsXjdgN2vgv9WOKIs/uA1kf5WeD96HhlBYO+FA== + dependencies: + "@jest/fake-timers" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/node" "*" + jest-mock "^27.0.3" + +"@jest/fake-timers@^27.0.5": + version "27.0.5" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.5.tgz#304d5aedadf4c75cff3696995460b39d6c6e72f6" + integrity sha512-d6Tyf7iDoKqeUdwUKrOBV/GvEZRF67m7lpuWI0+SCD9D3aaejiOQZxAOxwH2EH/W18gnfYaBPLi0VeTGBHtQBg== + dependencies: + "@jest/types" "^27.0.2" + "@sinonjs/fake-timers" "^7.0.2" + "@types/node" "*" + jest-message-util "^27.0.2" + jest-mock "^27.0.3" + jest-util "^27.0.2" + +"@jest/globals@^27.0.5": + version "27.0.5" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.5.tgz#f63b8bfa6ea3716f8df50f6a604b5c15b36ffd20" + integrity sha512-qqKyjDXUaZwDuccpbMMKCCMBftvrbXzigtIsikAH/9ca+kaae8InP2MDf+Y/PdCSMuAsSpHS6q6M25irBBUh+Q== + dependencies: + "@jest/environment" "^27.0.5" + "@jest/types" "^27.0.2" + expect "^27.0.2" + +"@jest/reporters@^27.0.5": + version "27.0.5" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.5.tgz#cd730b77d9667b8ff700ad66d4edc293bb09716a" + integrity sha512-4uNg5+0eIfRafnpgu3jCZws3NNcFzhu5JdRd1mKQ4/53+vkIqwB6vfZ4gn5BdGqOaLtYhlOsPaL5ATkKzyBrJw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.0.2" + "@jest/test-result" "^27.0.2" + "@jest/transform" "^27.0.5" + "@jest/types" "^27.0.2" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.4" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.3" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + jest-haste-map "^27.0.5" + jest-resolve "^27.0.5" + jest-util "^27.0.2" + jest-worker "^27.0.2" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.0.0" + +"@jest/source-map@^27.0.1": + version "27.0.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.1.tgz#2afbf73ddbaddcb920a8e62d0238a0a9e0a8d3e4" + integrity sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.4" + source-map "^0.6.0" + +"@jest/test-result@^27.0.2": + version "27.0.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.2.tgz#0451049e32ceb609b636004ccc27c8fa22263f10" + integrity sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA== + dependencies: + "@jest/console" "^27.0.2" + "@jest/types" "^27.0.2" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^27.0.5": + version "27.0.5" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.5.tgz#c58b21db49afc36c0e3921d7ddf1fb7954abfded" + integrity sha512-opztnGs+cXzZ5txFG2+omBaV5ge/0yuJNKbhE3DREMiXE0YxBuzyEa6pNv3kk2JuucIlH2Xvgmn9kEEHSNt/SA== + dependencies: + "@jest/test-result" "^27.0.2" + graceful-fs "^4.2.4" + jest-haste-map "^27.0.5" + jest-runtime "^27.0.5" + +"@jest/transform@^27.0.5": + version "27.0.5" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.5.tgz#2dcb78953708af713941ac845b06078bc74ed873" + integrity sha512-lBD6OwKXSc6JJECBNk4mVxtSVuJSBsQrJ9WCBisfJs7EZuYq4K6vM9HmoB7hmPiLIDGeyaerw3feBV/bC4z8tg== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.0.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^27.0.5" + jest-regex-util "^27.0.1" + jest-util "^27.0.2" + micromatch "^4.0.4" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@jest/types@^27.0.2": + version "27.0.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.2.tgz#e153d6c46bda0f2589f0702b071f9898c7bbd37e" + integrity sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + "@jitsu/sdk-js@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@jitsu/sdk-js/-/sdk-js-2.0.1.tgz#7b400f314e042236f994f0cac766712320290fe9" @@ -314,6 +789,20 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^7.0.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" + integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sqltools/formatter@^1.2.2": version "1.2.3" resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.3.tgz#1185726610acc37317ddab11c3c7f9066966bd20" @@ -326,6 +815,78 @@ dependencies: mini-svg-data-uri "^1.2.3" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.1.14" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" + integrity sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" + integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.0" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" + integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" + integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^26.0.23": + version "26.0.23" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.23.tgz#a1b7eab3c503b80451d019efb588ec63522ee4e7" + integrity sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA== + dependencies: + jest-diff "^26.0.0" + pretty-format "^26.0.0" + "@types/json-schema@^7.0.7": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" @@ -346,6 +907,11 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/prettier@^2.1.5": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.0.tgz#2e8332cc7363f887d32ec5496b207d26ba8052bb" + integrity sha512-hkc1DATxFLQo4VxPDpMH1gCkPpBbpOoJ/4nhuXw4n63/0R6bCpQECj4+K226UJ4JO/eJQz+1mC2I7JsWanAdQw== + "@types/prop-types@*": version "15.7.3" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" @@ -365,6 +931,30 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== +"@types/stack-utils@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" + integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + +"@types/yargs-parser@*": + version "20.2.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" + integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + +"@types/yargs@^15.0.0": + version "15.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" + integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^16.0.0": + version "16.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.3.tgz#4b6d35bb8e680510a7dc2308518a80ee1ef27e01" + integrity sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ== + dependencies: + "@types/yargs-parser" "*" + "@types/zen-observable@^0.8.2": version "0.8.2" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" @@ -440,6 +1030,11 @@ "@typescript-eslint/types" "4.27.0" eslint-visitor-keys "^2.0.0" +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -447,6 +1042,14 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" @@ -461,16 +1064,21 @@ acorn-node@^1.6.1: acorn-walk "^7.0.0" xtend "^4.0.2" -acorn-walk@^7.0.0: +acorn-walk@^7.0.0, acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.0.0, acorn@^7.4.0: +acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.2.4: + version "8.4.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.0.tgz#af53266e698d7cffa416714b503066a82221be60" + integrity sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -516,7 +1124,7 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^4.3.0: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -552,6 +1160,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + any-base@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" @@ -562,7 +1175,7 @@ any-promise@^1.0.0: resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= -anymatch@~3.1.1: +anymatch@^3.0.3, anymatch@~3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -671,6 +1284,11 @@ async@^3.2.0: resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + autoprefixer@^10.2.5: version "10.2.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.6.tgz#aadd9ec34e1c98d403e01950038049f0eb252949" @@ -690,11 +1308,72 @@ available-typed-arrays@^1.0.2: dependencies: array-filter "^1.0.0" +babel-jest@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.5.tgz#cd34c033ada05d1362211e5152391fd7a88080c8" + integrity sha512-bTMAbpCX7ldtfbca2llYLeSFsDM257aspyAOpsdrdSrBqoLkWCy4HPYTXtXWaSLgFPjrJGACL65rzzr4RFGadw== + dependencies: + "@jest/transform" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^27.0.1" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" + +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^27.0.1: + version "27.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz#a6d10e484c93abff0f4e95f437dad26e5736ea11" + integrity sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + babel-plugin-syntax-jsx@6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^27.0.1: + version "27.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz#7a50c75d16647c23a2cf5158d5bb9eb206b10e20" + integrity sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA== + dependencies: + babel-plugin-jest-hoist "^27.0.1" + babel-preset-current-node-syntax "^1.0.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -755,6 +1434,11 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -838,11 +1522,23 @@ browserslist@^4.16.6: escalade "^3.1.1" node-releases "^1.1.71" +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + buffer-equal-constant-time@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -901,6 +1597,16 @@ camelcase-css@^2.0.1: resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001179, caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219: version "1.0.30001221" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001221.tgz#b916721ddf59066cfbe96c5c9a77cf7ae5c52e65" @@ -947,6 +1653,11 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + chokidar@3.5.1, chokidar@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" @@ -962,6 +1673,11 @@ chokidar@3.5.1, chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.1" +ci-info@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" + integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A== + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -970,6 +1686,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +cjs-module-lexer@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz#2fd46d9906a126965aa541345c499aaa18e8cd73" + integrity sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw== + classnames@2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" @@ -1021,6 +1742,16 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -1066,6 +1797,13 @@ colorette@^1.2.1, colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^6.0.0: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" @@ -1103,6 +1841,13 @@ convert-source-map@1.7.0: dependencies: safe-buffer "~5.1.1" +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1215,6 +1960,23 @@ cssnano-simple@2.0.0: dependencies: cssnano-preset-simple "^2.0.0" +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + csstype@^3.0.2: version "3.0.8" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" @@ -1225,6 +1987,15 @@ data-uri-to-buffer@3.0.1: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + dayjs@^1.10.4: version "1.10.4" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2" @@ -1237,23 +2008,33 @@ debug@2: dependencies: ms "2.0.0" -debug@4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" +decimal.js@^10.2.1: + version "10.3.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.0.tgz#96fd481189818e0d5810c18ac147824b9e4c0026" + integrity sha512-MrQRs2gyD//7NeHi9TtsfClkf+cFAewDz+PZHR8ILKglLmBMyVX3ymQ+oeznE3tjrS7beTN+6JXb2C3JDHm7ug== + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-is@^0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -1266,6 +2047,11 @@ defined@^1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -1279,6 +2065,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + detective@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" @@ -1293,6 +2084,16 @@ didyoumean@^1.2.1: resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== + +diff-sequences@^27.0.1: + version "27.0.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.1.tgz#9c9801d52ed5f576ff0a20e3022a13ee6e297e7c" + integrity sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -1346,6 +2147,13 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + dotenv@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" @@ -1381,6 +2189,11 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -1488,11 +2301,28 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-config-prettier@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" @@ -1614,7 +2444,7 @@ espree@^7.3.0, espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" -esprima@^4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -1686,6 +2516,23 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expect@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.2.tgz#e66ca3a4c9592f1c019fa1d46459a9d2084f3422" + integrity sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w== + dependencies: + "@jest/types" "^27.0.2" + ansi-styles "^5.0.0" + jest-get-type "^27.0.1" + jest-matcher-utils "^27.0.2" + jest-message-util "^27.0.2" + jest-regex-util "^27.0.1" + extend@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -1718,7 +2565,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -1735,6 +2582,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + figlet@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.5.0.tgz#2db4d00a584e5155a96080632db919213c3e003c" @@ -1763,7 +2617,7 @@ find-cache-dir@3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" -find-up@^4.0.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -1789,6 +2643,15 @@ foreach@^2.0.5: resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fraction.js@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.1.tgz#ac4e520473dae67012d618aab91eda09bcb400ff" @@ -1808,7 +2671,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.1: +fsevents@^2.3.2, fsevents@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -1847,6 +2710,11 @@ gcp-metadata@^4.2.0: gaxios "^4.0.0" json-bigint "^1.0.0" +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1873,6 +2741,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -1909,7 +2782,7 @@ glob@^7.0.0, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: +glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -1921,6 +2794,11 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^13.6.0, globals@^13.9.0: version "13.9.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" @@ -2073,6 +2951,18 @@ hoist-non-react-statics@^3.3.1: dependencies: react-is "^16.7.0" +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + html-tags@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" @@ -2089,6 +2979,15 @@ http-errors@1.7.3: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + https-browserify@1.0.0, https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -2171,6 +3070,14 @@ import-from@^3.0.0: dependencies: resolve-from "^5.0.0" +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -2261,6 +3168,13 @@ is-callable@^1.1.4, is-callable@^1.2.3: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== +is-ci@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" + integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== + dependencies: + ci-info "^3.1.1" + is-core-module@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.3.0.tgz#d341652e3408bca69c4671b79a0954a3d349f887" @@ -2283,6 +3197,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + is-generator-function@^1.0.7: version "1.0.8" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b" @@ -2323,6 +3242,11 @@ is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + is-regex@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" @@ -2377,6 +3301,11 @@ is-typed-array@^1.1.3: foreach "^2.0.5" has-symbols "^1.0.1" +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" @@ -2392,6 +3321,453 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== + +istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== + dependencies: + "@babel/core" "^7.7.5" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" + integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" + integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.2.tgz#997253042b4a032950fc5f56abf3c5d1f8560801" + integrity sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw== + dependencies: + "@jest/types" "^27.0.2" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.5.tgz#b5e327f1d6857c8485126f8e364aefa4378debaa" + integrity sha512-p5rO90o1RTh8LPOG6l0Fc9qgp5YGv+8M5CFixhMh7gGHtGSobD1AxX9cjFZujILgY8t30QZ7WVvxlnuG31r8TA== + dependencies: + "@jest/environment" "^27.0.5" + "@jest/test-result" "^27.0.2" + "@jest/types" "^27.0.2" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.0.2" + is-generator-fn "^2.0.0" + jest-each "^27.0.2" + jest-matcher-utils "^27.0.2" + jest-message-util "^27.0.2" + jest-runtime "^27.0.5" + jest-snapshot "^27.0.5" + jest-util "^27.0.2" + pretty-format "^27.0.2" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + +jest-cli@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.5.tgz#f359ba042624cffb96b713010a94bffb7498a37c" + integrity sha512-kZqY020QFOFQKVE2knFHirTBElw3/Q0kUbDc3nMfy/x+RQ7zUY89SUuzpHHJoSX1kX7Lq569ncvjNqU3Td/FCA== + dependencies: + "@jest/core" "^27.0.5" + "@jest/test-result" "^27.0.2" + "@jest/types" "^27.0.2" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.4" + import-local "^3.0.2" + jest-config "^27.0.5" + jest-util "^27.0.2" + jest-validate "^27.0.2" + prompts "^2.0.1" + yargs "^16.0.3" + +jest-config@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.5.tgz#683da3b0d8237675c29c817f6e3aba1481028e19" + integrity sha512-zCUIXag7QIXKEVN4kUKbDBDi9Q53dV5o3eNhGqe+5zAbt1vLs4VE3ceWaYrOub0L4Y7E9pGfM84TX/0ARcE+Qw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^27.0.5" + "@jest/types" "^27.0.2" + babel-jest "^27.0.5" + chalk "^4.0.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.4" + is-ci "^3.0.0" + jest-circus "^27.0.5" + jest-environment-jsdom "^27.0.5" + jest-environment-node "^27.0.5" + jest-get-type "^27.0.1" + jest-jasmine2 "^27.0.5" + jest-regex-util "^27.0.1" + jest-resolve "^27.0.5" + jest-runner "^27.0.5" + jest-util "^27.0.2" + jest-validate "^27.0.2" + micromatch "^4.0.4" + pretty-format "^27.0.2" + +jest-diff@^26.0.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-diff@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.2.tgz#f315b87cee5dc134cf42c2708ab27375cc3f5a7e" + integrity sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.0.1" + jest-get-type "^27.0.1" + pretty-format "^27.0.2" + +jest-docblock@^27.0.1: + version "27.0.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.1.tgz#bd9752819b49fa4fab1a50b73eb58c653b962e8b" + integrity sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA== + dependencies: + detect-newline "^3.0.0" + +jest-each@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.2.tgz#865ddb4367476ced752167926b656fa0dcecd8c7" + integrity sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ== + dependencies: + "@jest/types" "^27.0.2" + chalk "^4.0.0" + jest-get-type "^27.0.1" + jest-util "^27.0.2" + pretty-format "^27.0.2" + +jest-environment-jsdom@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.5.tgz#c36771977cf4490a9216a70473b39161d193c212" + integrity sha512-ToWhViIoTl5738oRaajTMgYhdQL73UWPoV4GqHGk2DPhs+olv8OLq5KoQW8Yf+HtRao52XLqPWvl46dPI88PdA== + dependencies: + "@jest/environment" "^27.0.5" + "@jest/fake-timers" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/node" "*" + jest-mock "^27.0.3" + jest-util "^27.0.2" + jsdom "^16.6.0" + +jest-environment-node@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.5.tgz#b7238fc2b61ef2fb9563a3b7653a95fa009a6a54" + integrity sha512-47qqScV/WMVz5OKF5TWpAeQ1neZKqM3ySwNveEnLyd+yaE/KT6lSMx/0SOx60+ZUcVxPiESYS+Kt2JS9y4PpkQ== + dependencies: + "@jest/environment" "^27.0.5" + "@jest/fake-timers" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/node" "*" + jest-mock "^27.0.3" + jest-util "^27.0.2" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + +jest-get-type@^27.0.1: + version "27.0.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.1.tgz#34951e2b08c8801eb28559d7eb732b04bbcf7815" + integrity sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg== + +jest-haste-map@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.5.tgz#2e1e55073b5328410a2c0d74b334e513d71f3470" + integrity sha512-3LFryGSHxwPFHzKIs6W0BGA2xr6g1MvzSjR3h3D8K8Uqy4vbRm/grpGHzbPtIbOPLC6wFoViRrNEmd116QWSkw== + dependencies: + "@jest/types" "^27.0.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^27.0.1" + jest-serializer "^27.0.1" + jest-util "^27.0.2" + jest-worker "^27.0.2" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + +jest-jasmine2@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.5.tgz#8a6eb2a685cdec3af13881145c77553e4e197776" + integrity sha512-m3TojR19sFmTn79QoaGy1nOHBcLvtLso6Zh7u+gYxZWGcza4rRPVqwk1hciA5ZOWWZIJOukAcore8JRX992FaA== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^27.0.5" + "@jest/source-map" "^27.0.1" + "@jest/test-result" "^27.0.2" + "@jest/types" "^27.0.2" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.0.2" + is-generator-fn "^2.0.0" + jest-each "^27.0.2" + jest-matcher-utils "^27.0.2" + jest-message-util "^27.0.2" + jest-runtime "^27.0.5" + jest-snapshot "^27.0.5" + jest-util "^27.0.2" + pretty-format "^27.0.2" + throat "^6.0.1" + +jest-leak-detector@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz#ce19aa9dbcf7a72a9d58907a970427506f624e69" + integrity sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q== + dependencies: + jest-get-type "^27.0.1" + pretty-format "^27.0.2" + +jest-matcher-utils@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz#f14c060605a95a466cdc759acc546c6f4cbfc4f0" + integrity sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA== + dependencies: + chalk "^4.0.0" + jest-diff "^27.0.2" + jest-get-type "^27.0.1" + pretty-format "^27.0.2" + +jest-message-util@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.2.tgz#181c9b67dff504d8f4ad15cba10d8b80f272048c" + integrity sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.0.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.4" + pretty-format "^27.0.2" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^27.0.3: + version "27.0.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.3.tgz#5591844f9192b3335c0dca38e8e45ed297d4d23d" + integrity sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q== + dependencies: + "@jest/types" "^27.0.2" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^27.0.1: + version "27.0.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.1.tgz#69d4b1bf5b690faa3490113c47486ed85dd45b68" + integrity sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ== + +jest-resolve-dependencies@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.5.tgz#819ccdddd909c65acddb063aac3a49e4ba1ed569" + integrity sha512-xUj2dPoEEd59P+nuih4XwNa4nJ/zRd/g4rMvjHrZPEBWeWRq/aJnnM6mug+B+Nx+ILXGtfWHzQvh7TqNV/WbuA== + dependencies: + "@jest/types" "^27.0.2" + jest-regex-util "^27.0.1" + jest-snapshot "^27.0.5" + +jest-resolve@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.5.tgz#937535a5b481ad58e7121eaea46d1424a1e0c507" + integrity sha512-Md65pngRh8cRuWVdWznXBB5eDt391OJpdBaJMxfjfuXCvOhM3qQBtLMCMTykhuUKiBMmy5BhqCW7AVOKmPrW+Q== + dependencies: + "@jest/types" "^27.0.2" + chalk "^4.0.0" + escalade "^3.1.1" + graceful-fs "^4.2.4" + jest-pnp-resolver "^1.2.2" + jest-util "^27.0.2" + jest-validate "^27.0.2" + resolve "^1.20.0" + slash "^3.0.0" + +jest-runner@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.5.tgz#b6fdc587e1a5056339205914294555c554efc08a" + integrity sha512-HNhOtrhfKPArcECgBTcWOc+8OSL8GoFoa7RsHGnfZR1C1dFohxy9eLtpYBS+koybAHlJLZzNCx2Y/Ic3iEtJpQ== + dependencies: + "@jest/console" "^27.0.2" + "@jest/environment" "^27.0.5" + "@jest/test-result" "^27.0.2" + "@jest/transform" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.4" + jest-docblock "^27.0.1" + jest-environment-jsdom "^27.0.5" + jest-environment-node "^27.0.5" + jest-haste-map "^27.0.5" + jest-leak-detector "^27.0.2" + jest-message-util "^27.0.2" + jest-resolve "^27.0.5" + jest-runtime "^27.0.5" + jest-util "^27.0.2" + jest-worker "^27.0.2" + source-map-support "^0.5.6" + throat "^6.0.1" + +jest-runtime@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.5.tgz#cd5d1aa9754d30ddf9f13038b3cb7b95b46f552d" + integrity sha512-V/w/+VasowPESbmhXn5AsBGPfb35T7jZPGZybYTHxZdP7Gwaa+A0EXE6rx30DshHKA98lVCODbCO8KZpEW3hiQ== + dependencies: + "@jest/console" "^27.0.2" + "@jest/environment" "^27.0.5" + "@jest/fake-timers" "^27.0.5" + "@jest/globals" "^27.0.5" + "@jest/source-map" "^27.0.1" + "@jest/test-result" "^27.0.2" + "@jest/transform" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.4" + jest-haste-map "^27.0.5" + jest-message-util "^27.0.2" + jest-mock "^27.0.3" + jest-regex-util "^27.0.1" + jest-resolve "^27.0.5" + jest-snapshot "^27.0.5" + jest-util "^27.0.2" + jest-validate "^27.0.2" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^16.0.3" + +jest-serializer@^27.0.1: + version "27.0.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.1.tgz#2464d04dcc33fb71dc80b7c82e3c5e8a08cb1020" + integrity sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + +jest-snapshot@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.5.tgz#6e3b9e8e193685372baff771ba34af631fe4d4d5" + integrity sha512-H1yFYdgnL1vXvDqMrnDStH6yHFdMEuzYQYc71SnC/IJnuuhW6J16w8GWG1P+qGd3Ag3sQHjbRr0TcwEo/vGS+g== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/parser" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.0.5" + "@jest/types" "^27.0.2" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.0.2" + graceful-fs "^4.2.4" + jest-diff "^27.0.2" + jest-get-type "^27.0.1" + jest-haste-map "^27.0.5" + jest-matcher-utils "^27.0.2" + jest-message-util "^27.0.2" + jest-resolve "^27.0.5" + jest-util "^27.0.2" + natural-compare "^1.4.0" + pretty-format "^27.0.2" + semver "^7.3.2" + +jest-util@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.2.tgz#fc2c7ace3c75ae561cf1e5fdb643bf685a5be7c7" + integrity sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA== + dependencies: + "@jest/types" "^27.0.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^3.0.0" + picomatch "^2.2.3" + +jest-validate@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.2.tgz#7fe2c100089449cd5cbb47a5b0b6cb7cda5beee5" + integrity sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg== + dependencies: + "@jest/types" "^27.0.2" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.0.1" + leven "^3.1.0" + pretty-format "^27.0.2" + +jest-watcher@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.2.tgz#dab5f9443e2d7f52597186480731a8c6335c5deb" + integrity sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA== + dependencies: + "@jest/test-result" "^27.0.2" + "@jest/types" "^27.0.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.0.2" + string-length "^4.0.1" + jest-worker@27.0.0-next.5: version "27.0.0-next.5" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28" @@ -2401,6 +3777,24 @@ jest-worker@27.0.0-next.5: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.2.tgz#4ebeb56cef48b3e7514552f80d0d80c0129f0b05" + integrity sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.0.5: + version "27.0.5" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.5.tgz#141825e105514a834cc8d6e44670509e8d74c5f2" + integrity sha512-4NlVMS29gE+JOZvgmSAsz3eOjkSsHqjTajlIsah/4MVSmKvf3zFP/TvgcLoWe2UVHiE9KF741sReqhF0p4mqbQ== + dependencies: + "@jest/core" "^27.0.5" + import-local "^3.0.2" + jest-cli "^27.0.5" + joi@^17.1.1: version "17.4.0" resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20" @@ -2439,6 +3833,44 @@ js-yaml@^4.0.0: dependencies: argparse "^2.0.1" +jsdom@^16.6.0: + version "16.6.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" + integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.5" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + json-bigint@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" @@ -2473,6 +3905,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -2540,6 +3979,16 @@ jws@^4.0.0: jwa "^2.0.0" safe-buffer "^5.0.1" +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -2548,6 +3997,14 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + libphonenumber-js@^1.9.17: version "1.9.17" resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.17.tgz#fef2e6fd7a981be69ba358c24495725ee8daf331" @@ -2678,7 +4135,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@^4.17.13, lodash@^4.17.21: +lodash@^4.17.13, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -2715,13 +4172,20 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-dir@^3.0.2: +make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -2762,6 +4226,18 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" +mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== + +mime-types@^2.1.12: + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== + dependencies: + mime-db "1.48.0" + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -2789,7 +4265,7 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.1.1, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -2799,6 +4275,11 @@ mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mockdate@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb" + integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ== + modern-normalize@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.1.0.tgz#da8e80140d9221426bd4f725c6e11283d34f90b7" @@ -2958,6 +4439,11 @@ node-html-parser@1.4.9: dependencies: he "1.2.0" +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" @@ -2987,6 +4473,11 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + node-releases@^1.1.69, node-releases@^1.1.71: version "1.1.71" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" @@ -3019,6 +4510,11 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + oauth@^0.9.15: version "0.9.15" resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" @@ -3109,6 +4605,18 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -3126,6 +4634,11 @@ os-browserify@0.3.0, os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= +p-each-series@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" + integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== + p-limit@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -3204,16 +4717,16 @@ parse5-htmlparser2-tree-adapter@^6.0.0: dependencies: parse5 "^6.0.1" +parse5@6.0.1, parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + parse5@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== -parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - path-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" @@ -3265,12 +4778,19 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + pkce-challenge@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-2.1.0.tgz#90730f839b2ab00a8cbdd6e808bbaecc10e09b1c" integrity sha512-ehrkzg1m5IBJGEAfePkd+nxBl9JrUC7dqkaL2q/BMsiADSRWSCapIEXlzr7rnfr1RtK6PACVJiE1USKm68QkrQ== -pkg-dir@^4.1.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -3381,6 +4901,11 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -3393,6 +4918,26 @@ prettier@^2.3.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + +pretty-format@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.2.tgz#9283ff8c4f581b186b2d4da461617143dca478a4" + integrity sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig== + dependencies: + "@jest/types" "^27.0.2" + ansi-regex "^5.0.0" + ansi-styles "^5.0.0" + react-is "^17.0.1" + pretty-format@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" @@ -3425,6 +4970,14 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +prompts@^2.0.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" + integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -3434,6 +4987,11 @@ prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, p object-assign "^4.1.1" react-is "^16.8.1" +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" @@ -3456,7 +5014,7 @@ punycode@^1.2.4: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -3549,6 +5107,11 @@ react-is@16.13.1, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-phone-number-input@^3.1.21: version "3.1.21" resolved "https://registry.yarnpkg.com/react-phone-number-input/-/react-phone-number-input-3.1.21.tgz#7c6de442d9d2ebd6e757e93c6603698aa008e82b" @@ -3683,6 +5246,13 @@ require_optional@^1.0.1: resolve-from "^2.0.0" semver "^5.1.0" +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" @@ -3776,6 +5346,13 @@ sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + scheduler@^0.20.1: version "0.20.2" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" @@ -3794,12 +5371,12 @@ semver@^5.1.0, semver@^5.6.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.0.0: +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.5: +semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== @@ -3870,6 +5447,11 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -3898,7 +5480,15 @@ source-map-js@^0.6.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -source-map@0.7.3: +source-map-support@^0.5.6: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@0.7.3, source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== @@ -3910,7 +5500,12 @@ source-map@0.8.0-beta.0: dependencies: whatwg-url "^7.0.0" -source-map@^0.6.1: +source-map@^0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -3932,6 +5527,13 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +stack-utils@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" + integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + dependencies: + escape-string-regexp "^2.0.0" + stacktrace-parser@0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" @@ -3998,6 +5600,14 @@ string-hash@1.1.3: resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" @@ -4074,6 +5684,11 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -4125,7 +5740,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -4139,6 +5754,19 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + table@^6.0.9: version "6.7.1" resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" @@ -4193,6 +5821,23 @@ tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -4212,6 +5857,11 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -4231,6 +5881,11 @@ tmp@^0.2.1: dependencies: rimraf "^3.0.0" +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -4253,6 +5908,15 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -4260,6 +5924,13 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -4299,6 +5970,18 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" @@ -4314,6 +5997,13 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typeorm@^0.2.30: version "0.2.32" resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.32.tgz#544dbfdfe0cd0887548d9bcbd28527ea4f4b3c9b" @@ -4352,6 +6042,11 @@ unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -4435,11 +6130,41 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +v8-to-istanbul@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz#4229f2a99e367f3f018fa1d5c2b8ec684667c69c" + integrity sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + vm-browserify@1.1.2, vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +walker@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + watchpack@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" @@ -4453,6 +6178,28 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" @@ -4462,6 +6209,15 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.6.0.tgz#27c0205a4902084b872aecb97cf0f2a7a3011f4c" + integrity sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -4493,7 +6249,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -word-wrap@^1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -4521,6 +6277,26 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.4.5: + version "7.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.0.tgz#0033bafea031fb9df041b2026fc72a571ca44691" + integrity sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + xml2js@^0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" @@ -4534,6 +6310,11 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -4568,7 +6349,7 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== -yargs@^16.0.0, yargs@^16.2.0: +yargs@^16.0.0, yargs@^16.0.3, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== From 28edb86c14dcac32922a6f4623ab20b1801bd83b Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Thu, 24 Jun 2021 22:48:01 +0000 Subject: [PATCH 09/25] Don't render location if there is none for now --- pages/availability/event/[type].tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx index 8c203be008..129be9fcea 100644 --- a/pages/availability/event/[type].tsx +++ b/pages/availability/event/[type].tsx @@ -242,7 +242,7 @@ export default function EventType(props) {
    - {location.hostname}/{props.user.username}/ + {typeof location !== "undefined" ? location.hostname : ""}/{props.user.username}/ Date: Sun, 27 Jun 2021 22:02:27 +0000 Subject: [PATCH 10/25] Re-implemented * is all booked today in Slots() component --- components/booking/AvailableTimes.tsx | 11 +++++--- components/booking/Slots.tsx | 40 +++++++++++++++++++++------ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx index fbf552ab39..66bdc43e92 100644 --- a/components/booking/AvailableTimes.tsx +++ b/components/booking/AvailableTimes.tsx @@ -5,7 +5,7 @@ import Slots from "./Slots"; const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeFormat }) => { const router = useRouter(); const { user, rescheduleUid } = router.query; - const { slots } = Slots({ date, eventLength, workingHours }); + const { slots, isFullyBooked } = Slots({ date, eventLength, workingHours }); return (
    @@ -25,9 +25,12 @@ const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeForm
    )) - ) : ( -
    - )} + ) : isFullyBooked ? +
    +

    {user} is all booked today.

    +
    + :
    + }
    ); }; diff --git a/components/booking/Slots.tsx b/components/booking/Slots.tsx index ea25191b9d..76798e7020 100644 --- a/components/booking/Slots.tsx +++ b/components/booking/Slots.tsx @@ -1,32 +1,49 @@ import { useState, useEffect } from "react"; import { useRouter } from "next/router"; import getSlots from "../../lib/slots"; +import dayjs, {Dayjs} from "dayjs"; +import isBetween from "dayjs/plugin/isBetween"; +dayjs.extend(isBetween); + +type Props = { + eventLength: number; + minimumBookingNotice?: number; + date: Dayjs; +} + +const Slots = ({ eventLength, minimumBookingNotice, date, workingHours }: Props) => { + + minimumBookingNotice = minimumBookingNotice || 0; -const Slots = (props) => { const router = useRouter(); const { user } = router.query; const [slots, setSlots] = useState([]); + const [isFullyBooked, setIsFullyBooked ] = useState(false); useEffect(() => { setSlots([]); + setIsFullyBooked(false); fetch( - `/api/availability/${user}?dateFrom=${props.date.startOf("day").utc().format()}&dateTo=${props.date + `/api/availability/${user}?dateFrom=${date.startOf("day").utc().format()}&dateTo=${date .endOf("day") .utc() .format()}` ) .then((res) => res.json()) .then(handleAvailableSlots); - }, [props.date]); + }, [date]); const handleAvailableSlots = (busyTimes: []) => { + const times = getSlots({ - frequency: props.eventLength, - inviteeDate: props.date, - workingHours: props.workingHours, - minimumBookingNotice: 0, + frequency: eventLength, + inviteeDate: date, + workingHours, + minimumBookingNotice, }); + const timesLengthBeforeConflicts: number = times.length; + // Check for conflicts for (let i = times.length - 1; i >= 0; i -= 1) { busyTimes.forEach((busyTime) => { @@ -44,22 +61,27 @@ const Slots = (props) => { } // Check if slot end time is between start and end time - if (dayjs(times[i]).add(props.eventType.length, "minutes").isBetween(startTime, endTime)) { + if (dayjs(times[i]).add(eventLength, "minutes").isBetween(startTime, endTime)) { times.splice(i, 1); } // Check if startTime is between slot - if (startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(props.eventType.length, "minutes"))) { + if (startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(eventLength, "minutes"))) { times.splice(i, 1); } }); } + + if (times.length === 0 && timesLengthBeforeConflicts !== 0) { + setIsFullyBooked(true); + } // Display available times setSlots(times); }; return { slots, + isFullyBooked, }; }; From 1eba24282070eac545aa7511f592d4b2e63e7d1d Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Sun, 27 Jun 2021 22:30:11 +0000 Subject: [PATCH 11/25] Compare busyTimes in UTC, re-implement hasErrors --- components/booking/AvailableTimes.tsx | 39 ++++++++++---- components/booking/Slots.tsx | 30 +++++++---- lib/slots.ts | 75 ++++++++++++++------------- pages/[user]/[type].tsx | 1 + 4 files changed, 88 insertions(+), 57 deletions(-) diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx index 66bdc43e92..6745ddc52b 100644 --- a/components/booking/AvailableTimes.tsx +++ b/components/booking/AvailableTimes.tsx @@ -1,17 +1,18 @@ import Link from "next/link"; import { useRouter } from "next/router"; import Slots from "./Slots"; +import {ExclamationIcon} from "@heroicons/react/solid"; -const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeFormat }) => { +const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeFormat, user }) => { const router = useRouter(); - const { user, rescheduleUid } = router.query; - const { slots, isFullyBooked } = Slots({ date, eventLength, workingHours }); + const { rescheduleUid } = router.query; + const { slots, isFullyBooked, hasErrors } = Slots({ date, eventLength, workingHours }); return (
    {date.format("dddd DD MMMM YYYY")}
    - {slots.length > 0 ? ( + {slots.length > 0 && ( slots.map((slot) => (
    )) - ) : isFullyBooked ? -
    -

    {user} is all booked today.

    + )} + {isFullyBooked &&
    +

    {user.name} is all booked today.

    +
    } + + {!isFullyBooked && slots.length === 0 && !hasErrors &&
    } + + {hasErrors && ( +
    +
    +
    +
    +
    +

    + Could not load the available time slots.{" "} + + Contact {user.name} via e-mail + +

    +
    - :
    - } +
    + )}
    ); }; diff --git a/components/booking/Slots.tsx b/components/booking/Slots.tsx index 76798e7020..e3091e967d 100644 --- a/components/booking/Slots.tsx +++ b/components/booking/Slots.tsx @@ -3,7 +3,9 @@ import { useRouter } from "next/router"; import getSlots from "../../lib/slots"; import dayjs, {Dayjs} from "dayjs"; import isBetween from "dayjs/plugin/isBetween"; +import utc from "dayjs/plugin/utc"; dayjs.extend(isBetween); +dayjs.extend(utc); type Props = { eventLength: number; @@ -19,18 +21,25 @@ const Slots = ({ eventLength, minimumBookingNotice, date, workingHours }: Props) const { user } = router.query; const [slots, setSlots] = useState([]); const [isFullyBooked, setIsFullyBooked ] = useState(false); + const [hasErrors, setHasErrors ] = useState(false); useEffect(() => { setSlots([]); setIsFullyBooked(false); + setHasErrors(false); fetch( - `/api/availability/${user}?dateFrom=${date.startOf("day").utc().format()}&dateTo=${date + `/api/availability/${user}?dateFrom=${date.startOf("day").utc().startOf('day').format()}&dateTo=${date .endOf("day") .utc() + .endOf('day') .format()}` ) .then((res) => res.json()) - .then(handleAvailableSlots); + .then(handleAvailableSlots) + .catch( e => { + console.error(e); + setHasErrors(true); + }) }, [date]); const handleAvailableSlots = (busyTimes: []) => { @@ -47,26 +56,24 @@ const Slots = ({ eventLength, minimumBookingNotice, date, workingHours }: Props) // Check for conflicts for (let i = times.length - 1; i >= 0; i -= 1) { busyTimes.forEach((busyTime) => { - const startTime = dayjs(busyTime.start); - const endTime = dayjs(busyTime.end); + + const startTime = dayjs(busyTime.start).utc(); + const endTime = dayjs(busyTime.end).utc(); // Check if start times are the same - if (dayjs(times[i]).format("HH:mm") == startTime.format("HH:mm")) { + if (times[i].utc().format("HH:mm") == startTime.format("HH:mm")) { times.splice(i, 1); } - // Check if time is between start and end times - if (dayjs(times[i]).isBetween(startTime, endTime)) { + else if (times[i].utc().isBetween(startTime, endTime)) { times.splice(i, 1); } - // Check if slot end time is between start and end time - if (dayjs(times[i]).add(eventLength, "minutes").isBetween(startTime, endTime)) { + else if (times[i].utc().add(eventLength, "minutes").isBetween(startTime, endTime)) { times.splice(i, 1); } - // Check if startTime is between slot - if (startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(eventLength, "minutes"))) { + else if (startTime.isBetween(times[i].utc(), times[i].utc().add(eventLength, "minutes"))) { times.splice(i, 1); } }); @@ -82,6 +89,7 @@ const Slots = ({ eventLength, minimumBookingNotice, date, workingHours }: Props) return { slots, isFullyBooked, + hasErrors, }; }; diff --git a/lib/slots.ts b/lib/slots.ts index 00ffc738ab..c3dad4b564 100644 --- a/lib/slots.ts +++ b/lib/slots.ts @@ -1,11 +1,11 @@ -import dayjs, { Dayjs } from "dayjs"; +import dayjs, {Dayjs} from "dayjs"; import utc from "dayjs/plugin/utc"; dayjs.extend(utc); interface GetSlotsType { inviteeDate: Dayjs; frequency: number; - workingHours: { [WeekDay]: Boundary[] }; + workingHours: []; minimumBookingNotice?: number; } @@ -17,34 +17,30 @@ interface Boundary { const freqApply: number = (cb, value: number, frequency: number): number => cb(value / frequency) * frequency; const intersectBoundary = (a: Boundary, b: Boundary) => { - if (a.upperBound < b.lowerBound || a.lowerBound > b.upperBound) { + if ( + a.upperBound < b.lowerBound || a.lowerBound > b.upperBound + ) { return; } return { lowerBound: Math.max(b.lowerBound, a.lowerBound), - upperBound: Math.min(b.upperBound, a.upperBound), + upperBound: Math.min(b.upperBound, a.upperBound) }; -}; +} // say invitee is -60,1380, and boundary is -120,240 - the overlap is -60,240 -const getOverlaps = (inviteeBoundary: Boundary, boundaries: Boundary[]) => - boundaries.map((boundary) => intersectBoundary(inviteeBoundary, boundary)).filter(Boolean); +const getOverlaps = (inviteeBoundary: Boundary, boundaries: Boundary[]) => boundaries + .map( + (boundary) => intersectBoundary(inviteeBoundary, boundary) + ).filter(Boolean); const organizerBoundaries = (workingHours: [], inviteeDate: Dayjs, inviteeBounds: Boundary): Boundary[] => { const boundaries: Boundary[] = []; - const startDay: number = +inviteeDate - .utc() - .startOf("day") - .add(inviteeBounds.lowerBound, "minutes") - .format("d"); - const endDay: number = +inviteeDate - .utc() - .startOf("day") - .add(inviteeBounds.upperBound, "minutes") - .format("d"); + const startDay: number = +inviteeDate.utc().startOf('day').add(inviteeBounds.lowerBound, 'minutes').format('d'); + const endDay: number = +inviteeDate.utc().startOf('day').add(inviteeBounds.upperBound, 'minutes').format('d'); - workingHours.forEach((item) => { + workingHours.forEach( (item) => { const lowerBound: number = item.startTime; const upperBound: number = lowerBound + item.length; if (startDay !== endDay) { @@ -66,7 +62,7 @@ const organizerBoundaries = (workingHours: [], inviteeDate: Dayjs, inviteeBounds } } } else { - boundaries.push({ lowerBound, upperBound }); + boundaries.push({lowerBound, upperBound}); } }); return boundaries; @@ -76,33 +72,38 @@ const inviteeBoundary = (startTime: number, utcOffset: number, frequency: number const upperBound: number = freqApply(Math.floor, 1440 - utcOffset, frequency); const lowerBound: number = freqApply(Math.ceil, startTime - utcOffset, frequency); return { - lowerBound, - upperBound, + lowerBound, upperBound, }; }; -const getSlotsBetweenBoundary = (frequency: number, { lowerBound, upperBound }: Boundary) => { +const getSlotsBetweenBoundary = (frequency: number, {lowerBound,upperBound}: Boundary) => { const slots: Dayjs[] = []; - for (let minutes = 0; lowerBound + minutes <= upperBound - frequency; minutes += frequency) { - slots.push( - dayjs - .utc() - .startOf("day") - .add(lowerBound + minutes, "minutes") - ); + for ( + let minutes = 0; + lowerBound + minutes <= upperBound - frequency; + minutes += frequency + ) { + slots.push(dayjs.utc().startOf('day').add(lowerBound + minutes, 'minutes')); } return slots; }; -const getSlots = ({ inviteeDate, frequency, minimumBookingNotice, workingHours }: GetSlotsType): Dayjs[] => { - const startTime = dayjs.utc().isSame(dayjs(inviteeDate), "day") - ? inviteeDate.hour() * 60 + inviteeDate.minute() + minimumBookingNotice - : 0; +const getSlots = ( + { inviteeDate, frequency, minimumBookingNotice, workingHours, }: GetSlotsType +): Dayjs[] => { + + const startTime = ( + dayjs.utc().isSame(dayjs(inviteeDate), 'day') ? inviteeDate.hour() * 60 + inviteeDate.minute() + minimumBookingNotice : 0 + ); const inviteeBounds = inviteeBoundary(startTime, inviteeDate.utcOffset(), frequency); - return getOverlaps(inviteeBounds, organizerBoundaries(workingHours, inviteeDate, inviteeBounds)) - .reduce((slots, boundary: Boundary) => [...slots, ...getSlotsBetweenBoundary(frequency, boundary)], []) - .map((slot) => slot.utcOffset(dayjs(inviteeDate).utcOffset())); -}; + return getOverlaps( + inviteeBounds, organizerBoundaries(workingHours, inviteeDate, inviteeBounds) + ).reduce( + (slots, boundary: Boundary) => [...slots, ...getSlotsBetweenBoundary(frequency, boundary) ], [] + ).map( + (slot) => slot.utcOffset(dayjs(inviteeDate).utcOffset()) + ) +} export default getSlots; diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 973c8d7826..328a2884f9 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -122,6 +122,7 @@ export default function Type(props): Type { eventLength={props.eventType.length} eventTypeId={props.eventType.id} date={selectedDate} + user={props.user} /> )}
    From 52e68b682c74e436f67c7b4e2c9e4714bed063ad Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Mon, 28 Jun 2021 04:24:15 +0000 Subject: [PATCH 12/25] Removed isOverride boolean, renamed 'Schedule' to 'Availability' --- prisma/schema.prisma | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 5fb93fdcea..212912516c 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -21,7 +21,7 @@ model EventType { user User? @relation(fields: [userId], references: [id]) userId Int? bookings Booking[] - availability Schedule[] + availability Availability[] eventName String? customInputs EventTypeCustomInput[] } @@ -53,7 +53,7 @@ model User { credentials Credential[] teams Membership[] bookings Booking[] - availability Schedule[] + availability Availability[] selectedCalendars SelectedCalendar[] @@map(name: "users") @@ -128,7 +128,7 @@ model Booking { updatedAt DateTime? } -model Schedule { +model Availability { id Int @default(autoincrement()) @id label String? user User? @relation(fields: [userId], references: [id]) @@ -136,10 +136,9 @@ model Schedule { eventType EventType? @relation(fields: [eventTypeId], references: [id]) eventTypeId Int? days Int[] - startTime Int? - startDate DateTime? @db.Timestamptz(3) - length Int - isOverride Boolean @default(false) + startTime Int + endTime Int + date DateTime? @db.Date } model SelectedCalendar { @@ -159,11 +158,3 @@ model EventTypeCustomInput { required Boolean } -model ResetPasswordRequest { - id String @id @default(cuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - email String - expires DateTime -} - From 575747bcd3a5356dec3d1e380d601c383f9fa251 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Tue, 29 Jun 2021 01:45:58 +0000 Subject: [PATCH 13/25] Final thing to check is timezones, currently if I am in Kuala Lumpur the time is correct, but it jumps 8 hours due to being out of bound on Seoul. --- components/Schedule.model.tsx | 6 - components/booking/Slots.tsx | 22 +- components/ui/Scheduler.tsx | 120 +++++----- components/ui/modal/SetTimesModal.tsx | 12 +- lib/jsonUtils.ts | 11 + lib/schedule.model.tsx | 7 - lib/slots.ts | 92 +++++--- pages/[user]/[type].tsx | 41 +++- pages/api/availability/eventtype.ts | 176 ++++++++------ .../api/availability/schedule/[eventtype].ts | 69 ------ pages/availability/event/[type].tsx | 217 ++++++++++-------- prisma/schema.prisma | 1 + 12 files changed, 413 insertions(+), 361 deletions(-) delete mode 100644 components/Schedule.model.tsx create mode 100644 lib/jsonUtils.ts delete mode 100644 lib/schedule.model.tsx delete mode 100644 pages/api/availability/schedule/[eventtype].ts diff --git a/components/Schedule.model.tsx b/components/Schedule.model.tsx deleted file mode 100644 index d100f13d26..0000000000 --- a/components/Schedule.model.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import {Dayjs} from "dayjs"; - -interface Schedule { - startDate: Dayjs; - endDate: Dayjs; -} \ No newline at end of file diff --git a/components/booking/Slots.tsx b/components/booking/Slots.tsx index e3091e967d..3c689d5c38 100644 --- a/components/booking/Slots.tsx +++ b/components/booking/Slots.tsx @@ -1,7 +1,7 @@ import { useState, useEffect } from "react"; import { useRouter } from "next/router"; import getSlots from "../../lib/slots"; -import dayjs, {Dayjs} from "dayjs"; +import dayjs, { Dayjs } from "dayjs"; import isBetween from "dayjs/plugin/isBetween"; import utc from "dayjs/plugin/utc"; dayjs.extend(isBetween); @@ -11,44 +11,43 @@ type Props = { eventLength: number; minimumBookingNotice?: number; date: Dayjs; -} - -const Slots = ({ eventLength, minimumBookingNotice, date, workingHours }: Props) => { +}; +const Slots = ({ eventLength, minimumBookingNotice, date, workingHours, organizerUtcOffset }: Props) => { minimumBookingNotice = minimumBookingNotice || 0; const router = useRouter(); const { user } = router.query; const [slots, setSlots] = useState([]); - const [isFullyBooked, setIsFullyBooked ] = useState(false); - const [hasErrors, setHasErrors ] = useState(false); + const [isFullyBooked, setIsFullyBooked] = useState(false); + const [hasErrors, setHasErrors] = useState(false); useEffect(() => { setSlots([]); setIsFullyBooked(false); setHasErrors(false); fetch( - `/api/availability/${user}?dateFrom=${date.startOf("day").utc().startOf('day').format()}&dateTo=${date + `/api/availability/${user}?dateFrom=${date.startOf("day").utc().startOf("day").format()}&dateTo=${date .endOf("day") .utc() - .endOf('day') + .endOf("day") .format()}` ) .then((res) => res.json()) .then(handleAvailableSlots) - .catch( e => { + .catch((e) => { console.error(e); setHasErrors(true); - }) + }); }, [date]); const handleAvailableSlots = (busyTimes: []) => { - const times = getSlots({ frequency: eventLength, inviteeDate: date, workingHours, minimumBookingNotice, + organizerUtcOffset, }); const timesLengthBeforeConflicts: number = times.length; @@ -56,7 +55,6 @@ const Slots = ({ eventLength, minimumBookingNotice, date, workingHours }: Props) // Check for conflicts for (let i = times.length - 1; i >= 0; i -= 1) { busyTimes.forEach((busyTime) => { - const startTime = dayjs(busyTime.start).utc(); const endTime = dayjs(busyTime.end).utc(); diff --git a/components/ui/Scheduler.tsx b/components/ui/Scheduler.tsx index 4dea789ef0..bbe3ad2819 100644 --- a/components/ui/Scheduler.tsx +++ b/components/ui/Scheduler.tsx @@ -3,56 +3,87 @@ import TimezoneSelect from "react-timezone-select"; import { TrashIcon } from "@heroicons/react/outline"; import { WeekdaySelect } from "./WeekdaySelect"; import SetTimesModal from "./modal/SetTimesModal"; -import Schedule from "../../lib/schedule.model"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; import timezone from "dayjs/plugin/timezone"; +import { Availability } from "@prisma/client"; dayjs.extend(utc); dayjs.extend(timezone); -export const Scheduler = (props) => { - const [schedules, setSchedules]: Schedule[] = useState( - props.schedules.map((schedule) => { - const startDate = schedule.isOverride - ? dayjs(schedule.startDate) - : dayjs.utc().startOf("day").add(schedule.startTime, "minutes").tz(props.timeZone); - return { - days: schedule.days, - startDate, - endDate: startDate.add(schedule.length, "minutes"), - }; - }) - ); +type Props = { + timeZone: string; + availability: Availability[]; + setTimeZone: unknown; +}; - const [timeZone, setTimeZone] = useState(props.timeZone); +export const Scheduler = ({ + availability, + setAvailability, + timeZone: selectedTimeZone, + setTimeZone, +}: Props) => { const [editSchedule, setEditSchedule] = useState(-1); + const [dateOverrides, setDateOverrides] = useState([]); + const [openingHours, setOpeningHours] = useState([]); useEffect(() => { - props.onChange(schedules); - }, [schedules]); + setOpeningHours( + availability + .filter((item: Availability) => item.days.length !== 0) + .map((item) => { + item.startDate = dayjs().utc().startOf("day").add(item.startTime, "minutes"); + item.endDate = dayjs().utc().startOf("day").add(item.endTime, "minutes"); + return item; + }) + ); + setDateOverrides(availability.filter((item: Availability) => item.date)); + }, []); - const addNewSchedule = () => setEditSchedule(schedules.length); + // updates availability to how it should be formatted outside this component. + useEffect(() => { + setAvailability({ + dateOverrides: dateOverrides, + openingHours: openingHours, + }); + }, [dateOverrides, openingHours]); - const applyEditSchedule = (changed: Schedule) => { - const replaceWith = { - ...schedules[editSchedule], - ...changed, - }; + const addNewSchedule = () => setEditSchedule(openingHours.length); - schedules.splice(editSchedule, 1, replaceWith); + const applyEditSchedule = (changed) => { + if (!changed.days) { + changed.days = [1, 2, 3, 4, 5]; // Mon - Fri + } - setSchedules([].concat(schedules)); + const replaceWith = { ...openingHours[editSchedule], ...changed }; + openingHours.splice(editSchedule, 1, replaceWith); + setOpeningHours([].concat(openingHours)); }; const removeScheduleAt = (toRemove: number) => { - schedules.splice(toRemove, 1); - setSchedules([].concat(schedules)); + openingHours.splice(toRemove, 1); + setOpeningHours([].concat(openingHours)); }; - const setWeekdays = (idx: number, days: number[]) => { - schedules[idx].days = days; - setSchedules([].concat(schedules)); - }; + const OpeningHours = ({ idx, item }) => ( +
  • +
    + (item.days = selected)} /> + +
    + +
  • + ); + + console.log(selectedTimeZone); return (
    @@ -65,32 +96,15 @@ export const Scheduler = (props) => {
    setTimeZone(tz.value)} className="shadow-sm focus:ring-blue-500 focus:border-blue-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md" />
      - {schedules.map((schedule, idx) => ( -
    • -
      - setWeekdays(idx, days)} - /> - -
      - -
    • + {openingHours.map((item, idx) => ( + ))}

    @@ -108,7 +122,7 @@ export const Scheduler = (props) => {
    {editSchedule >= 0 && ( setEditSchedule(-1)} /> diff --git a/components/ui/modal/SetTimesModal.tsx b/components/ui/modal/SetTimesModal.tsx index 2a9b03a96c..a286780e94 100644 --- a/components/ui/modal/SetTimesModal.tsx +++ b/components/ui/modal/SetTimesModal.tsx @@ -7,9 +7,15 @@ dayjs.extend(utc); dayjs.extend(timezone); export default function SetTimesModal(props) { - const { startDate, endDate } = props.schedule || { - startDate: dayjs.utc().startOf("day").add(540, "minutes"), - endDate: dayjs.utc().startOf("day").add(1020, "minutes"), + const { startDate, endDate } = { + startDate: dayjs + .utc() + .startOf("day") + .add(props.schedule.startTime || 540, "minutes"), + endDate: dayjs + .utc() + .startOf("day") + .add(props.schedule.endTime || 1020, "minutes"), }; startDate.tz(props.timeZone); diff --git a/lib/jsonUtils.ts b/lib/jsonUtils.ts new file mode 100644 index 0000000000..3f617cb0ce --- /dev/null +++ b/lib/jsonUtils.ts @@ -0,0 +1,11 @@ +export const validJson = (jsonString: string) => { + try { + const o = JSON.parse(jsonString); + if (o && typeof o === "object") { + return o; + } + } catch (e) { + console.log("Invalid JSON:", e); + } + return false; +}; diff --git a/lib/schedule.model.tsx b/lib/schedule.model.tsx deleted file mode 100644 index 7a5f6354cb..0000000000 --- a/lib/schedule.model.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import {Dayjs} from "dayjs"; - -export default interface Schedule { - id: number | null; - startDate: Dayjs; - endDate: Dayjs; -} \ No newline at end of file diff --git a/lib/slots.ts b/lib/slots.ts index c3dad4b564..7d3a777373 100644 --- a/lib/slots.ts +++ b/lib/slots.ts @@ -1,12 +1,15 @@ -import dayjs, {Dayjs} from "dayjs"; +import dayjs, { Dayjs } from "dayjs"; import utc from "dayjs/plugin/utc"; +import timezone from "dayjs/plugin/timezone"; dayjs.extend(utc); +dayjs.extend(timezone); interface GetSlotsType { inviteeDate: Dayjs; frequency: number; workingHours: []; minimumBookingNotice?: number; + organizerUtcOffset: number; } interface Boundary { @@ -17,32 +20,41 @@ interface Boundary { const freqApply: number = (cb, value: number, frequency: number): number => cb(value / frequency) * frequency; const intersectBoundary = (a: Boundary, b: Boundary) => { - if ( - a.upperBound < b.lowerBound || a.lowerBound > b.upperBound - ) { + if (a.upperBound < b.lowerBound || a.lowerBound > b.upperBound) { return; } return { lowerBound: Math.max(b.lowerBound, a.lowerBound), - upperBound: Math.min(b.upperBound, a.upperBound) + upperBound: Math.min(b.upperBound, a.upperBound), }; -} +}; // say invitee is -60,1380, and boundary is -120,240 - the overlap is -60,240 -const getOverlaps = (inviteeBoundary: Boundary, boundaries: Boundary[]) => boundaries - .map( - (boundary) => intersectBoundary(inviteeBoundary, boundary) - ).filter(Boolean); +const getOverlaps = (inviteeBoundary: Boundary, boundaries: Boundary[]) => + boundaries.map((boundary) => intersectBoundary(inviteeBoundary, boundary)).filter(Boolean); -const organizerBoundaries = (workingHours: [], inviteeDate: Dayjs, inviteeBounds: Boundary): Boundary[] => { +const organizerBoundaries = ( + workingHours: [], + inviteeDate: Dayjs, + inviteeBounds: Boundary, + organizerTimeZone +): Boundary[] => { const boundaries: Boundary[] = []; - const startDay: number = +inviteeDate.utc().startOf('day').add(inviteeBounds.lowerBound, 'minutes').format('d'); - const endDay: number = +inviteeDate.utc().startOf('day').add(inviteeBounds.upperBound, 'minutes').format('d'); + const startDay: number = +inviteeDate + .utc() + .startOf("day") + .add(inviteeBounds.lowerBound, "minutes") + .format("d"); + const endDay: number = +inviteeDate + .utc() + .startOf("day") + .add(inviteeBounds.upperBound, "minutes") + .format("d"); - workingHours.forEach( (item) => { - const lowerBound: number = item.startTime; - const upperBound: number = lowerBound + item.length; + workingHours.forEach((item) => { + const lowerBound: number = item.startTime - dayjs().tz(organizerTimeZone).utcOffset(); + const upperBound: number = item.endTime - dayjs().tz(organizerTimeZone).utcOffset(); if (startDay !== endDay) { if (inviteeBounds.lowerBound < 0) { // lowerBound edges into the previous day @@ -62,7 +74,7 @@ const organizerBoundaries = (workingHours: [], inviteeDate: Dayjs, inviteeBounds } } } else { - boundaries.push({lowerBound, upperBound}); + boundaries.push({ lowerBound, upperBound }); } }); return boundaries; @@ -72,38 +84,42 @@ const inviteeBoundary = (startTime: number, utcOffset: number, frequency: number const upperBound: number = freqApply(Math.floor, 1440 - utcOffset, frequency); const lowerBound: number = freqApply(Math.ceil, startTime - utcOffset, frequency); return { - lowerBound, upperBound, + lowerBound, + upperBound, }; }; -const getSlotsBetweenBoundary = (frequency: number, {lowerBound,upperBound}: Boundary) => { +const getSlotsBetweenBoundary = (frequency: number, { lowerBound, upperBound }: Boundary) => { const slots: Dayjs[] = []; - for ( - let minutes = 0; - lowerBound + minutes <= upperBound - frequency; - minutes += frequency - ) { - slots.push(dayjs.utc().startOf('day').add(lowerBound + minutes, 'minutes')); + for (let minutes = 0; lowerBound + minutes <= upperBound - frequency; minutes += frequency) { + slots.push( + dayjs + .utc() + .startOf("day") + .add(lowerBound + minutes, "minutes") + ); } return slots; }; -const getSlots = ( - { inviteeDate, frequency, minimumBookingNotice, workingHours, }: GetSlotsType -): Dayjs[] => { - - const startTime = ( - dayjs.utc().isSame(dayjs(inviteeDate), 'day') ? inviteeDate.hour() * 60 + inviteeDate.minute() + minimumBookingNotice : 0 - ); +const getSlots = ({ + inviteeDate, + frequency, + minimumBookingNotice, + workingHours, + organizerTimeZone, +}: GetSlotsType): Dayjs[] => { + const startTime = dayjs.utc().isSame(dayjs(inviteeDate), "day") + ? inviteeDate.hour() * 60 + inviteeDate.minute() + minimumBookingNotice + : 0; const inviteeBounds = inviteeBoundary(startTime, inviteeDate.utcOffset(), frequency); return getOverlaps( - inviteeBounds, organizerBoundaries(workingHours, inviteeDate, inviteeBounds) - ).reduce( - (slots, boundary: Boundary) => [...slots, ...getSlotsBetweenBoundary(frequency, boundary) ], [] - ).map( - (slot) => slot.utcOffset(dayjs(inviteeDate).utcOffset()) + inviteeBounds, + organizerBoundaries(workingHours, inviteeDate, inviteeBounds, organizerTimeZone) ) -} + .reduce((slots, boundary: Boundary) => [...slots, ...getSlotsBetweenBoundary(frequency, boundary)], []) + .map((slot) => slot.utcOffset(dayjs(inviteeDate).utcOffset())); +}; export default getSlots; diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 328a2884f9..42fba5ecff 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -32,6 +32,7 @@ export default function Type(props): Type { frequency: props.eventType.length, inviteeDate: dayjs.utc(today) as Dayjs, workingHours: props.workingHours, + organizerTimeZone: props.eventType.timeZone, minimumBookingNotice: 0, }).length === 0, [today, props.eventType.length, props.workingHours] @@ -63,21 +64,46 @@ export default function Type(props): Type { {rescheduleUid && "Reschedule"} {props.eventType.title} | {props.user.name || props.user.username} | Calendso - + - - - " + props.eventType.description).replace(/'/g, "%27") + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + encodeURIComponent(props.user.avatar)} /> + + + " + props.eventType.description + ).replace(/'/g, "%27") + + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + + encodeURIComponent(props.user.avatar) + } + /> - + - " + props.eventType.description).replace(/'/g, "%27") + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + encodeURIComponent(props.user.avatar)} /> - + " + props.eventType.description + ).replace(/'/g, "%27") + + ".png?md=1&images=https%3A%2F%2Fcalendso.com%2Fcalendso-logo-white.svg&images=" + + encodeURIComponent(props.user.avatar) + } + />
    { description: true, length: true, availability: true, + timeZone: true, }, }); diff --git a/pages/api/availability/eventtype.ts b/pages/api/availability/eventtype.ts index e50fc4abee..dc5709e668 100644 --- a/pages/api/availability/eventtype.ts +++ b/pages/api/availability/eventtype.ts @@ -1,81 +1,111 @@ -import type {NextApiRequest, NextApiResponse} from 'next'; -import {getSession} from 'next-auth/client'; -import prisma from '../../../lib/prisma'; +import type { NextApiRequest, NextApiResponse } from "next"; +import { getSession } from "next-auth/client"; +import prisma from "../../../lib/prisma"; export default async function handler(req: NextApiRequest, res: NextApiResponse) { - const session = await getSession({req: req}); - if (!session) { - res.status(401).json({message: "Not authenticated"}); - return; - } + const session = await getSession({ req: req }); + if (!session) { + res.status(401).json({ message: "Not authenticated" }); + return; + } - if (req.method == "PATCH" || req.method == "POST") { - - const data = { - title: req.body.title, - slug: req.body.slug, - description: req.body.description, - length: parseInt(req.body.length), - hidden: req.body.hidden, - locations: req.body.locations, - eventName: req.body.eventName, - customInputs: !req.body.customInputs - ? undefined - : { - deleteMany: { - eventTypeId: req.body.id, - NOT: { - id: {in: req.body.customInputs.filter(input => !!input.id).map(e => e.id)} - } - }, - createMany: { - data: req.body.customInputs.filter(input => !input.id).map(input => ({ - type: input.type, - label: input.label, - required: input.required - })) - }, - update: req.body.customInputs.filter(input => !!input.id).map(input => ({ - data: { - type: input.type, - label: input.label, - required: input.required - }, - where: { - id: input.id - } - })) + if (req.method == "PATCH" || req.method == "POST") { + const data = { + title: req.body.title, + slug: req.body.slug, + description: req.body.description, + length: parseInt(req.body.length), + hidden: req.body.hidden, + locations: req.body.locations, + eventName: req.body.eventName, + customInputs: !req.body.customInputs + ? undefined + : { + deleteMany: { + eventTypeId: req.body.id, + NOT: { + id: { in: req.body.customInputs.filter((input) => !!input.id).map((e) => e.id) }, }, - }; - - if (req.method == "POST") { - const createEventType = await prisma.eventType.create({ - data: { - userId: session.user.id, - ...data, - }, - }); - res.status(200).json({message: 'Event created successfully'}); - } - else if (req.method == "PATCH") { - const updateEventType = await prisma.eventType.update({ - where: { - id: req.body.id, - }, - data, - }); - res.status(200).json({message: 'Event updated successfully'}); - } - } - - if (req.method == "DELETE") { - - const deleteEventType = await prisma.eventType.delete({ - where: { - id: req.body.id, }, - }); + createMany: { + data: req.body.customInputs + .filter((input) => !input.id) + .map((input) => ({ + type: input.type, + label: input.label, + required: input.required, + })), + }, + update: req.body.customInputs + .filter((input) => !!input.id) + .map((input) => ({ + data: { + type: input.type, + label: input.label, + required: input.required, + }, + where: { + id: input.id, + }, + })), + }, + }; - res.status(200).json({message: 'Event deleted successfully'}); + if (req.method == "POST") { + await prisma.eventType.create({ + data: { + userId: session.user.id, + ...data, + }, + }); + res.status(200).json({ message: "Event created successfully" }); + } else if (req.method == "PATCH") { + if (req.body.timeZone) { + data.timeZone = req.body.timeZone; + } + + if (req.body.availability) { + const openingHours = req.body.availability.openingHours || []; + // const overrides = req.body.availability.dateOverrides || []; + + await prisma.availability.deleteMany({ + where: { + eventTypeId: +req.body.id, + }, + }); + Promise.all( + openingHours.map((schedule) => + prisma.availability.create({ + data: { + eventTypeId: +req.body.id, + days: schedule.days, + startTime: schedule.startTime, + endTime: schedule.endTime, + }, + }) + ) + ).catch((error) => { + console.log(error); + }); + } + + await prisma.eventType.update({ + where: { + id: req.body.id, + }, + data, + }); + res.status(200).json({ message: "Event updated successfully" }); } + } + + if (req.method == "DELETE") { + await prisma.eventType.delete({ + where: { + id: req.body.id, + }, + }); + + res.status(200).json({ message: "Event deleted successfully" }); + } } diff --git a/pages/api/availability/schedule/[eventtype].ts b/pages/api/availability/schedule/[eventtype].ts deleted file mode 100644 index 9d3a9eb606..0000000000 --- a/pages/api/availability/schedule/[eventtype].ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { NextApiRequest, NextApiResponse } from 'next'; -import { getSession } from 'next-auth/client'; -import prisma from '../../../../lib/prisma'; - -export default async function handler(req: NextApiRequest, res: NextApiResponse) { - - const session = await getSession({req}); - if (!session) { - res.status(401).json({message: "Not authenticated"}); - return; - } - - if (req.method == "PUT") { - - const openingHours = req.body.openingHours || []; - const overrides = req.body.overrides || []; - - const removeSchedule = await prisma.schedule.deleteMany({ - where: { - eventTypeId: +req.query.eventtype, - } - }) - - const updateSchedule = Promise.all(openingHours.map( (schedule) => prisma.schedule.create({ - data: { - eventTypeId: +req.query.eventtype, - days: schedule.days, - startTime: schedule.startTime, - length: schedule.endTime - schedule.startTime, - }, - }))) - .catch( (error) => { - console.log(error); - }) - } - - res.status(200).json({message: 'Created schedule'}); - - /*if (req.method == "PATCH") { - const openingHours = req.body.openingHours || []; - const overrides = req.body.overrides || []; - - openingHours.forEach( (schedule) => { - const updateSchedule = await prisma.schedule.update({ - where: { - id: req.body.id, - }, - data: { - eventTypeId: req.query.eventtype, - days: req.body.days, - startTime: 333, - endTime: 540 - req.body.startTime, - }, - }); - }); - - overrides.forEach( (schedule) => { - const updateSchedule = await prisma.schedule.update({ - where: { - id: req.body.id, - }, - data: { - eventTypeId: req.query.eventtype, - startDate: req.body.startDate, - length: 540, - }, - }); - });*/ -} diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx index 4a48b7b10f..2237d065dd 100644 --- a/pages/availability/event/[type].tsx +++ b/pages/availability/event/[type].tsx @@ -1,26 +1,66 @@ +import { GetServerSideProps } from "next"; import Head from "next/head"; import Link from "next/link"; import { useRouter } from "next/router"; -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import Select, { OptionBase } from "react-select"; -import prisma from "../../../lib/prisma"; -import { LocationType } from "../../../lib/location"; -import Shell from "../../../components/Shell"; +import prisma from "@lib/prisma"; +import { LocationType } from "@lib/location"; +import Shell from "@components/Shell"; import { getSession } from "next-auth/client"; -import { Scheduler } from "../../../components/ui/Scheduler"; +import { Scheduler } from "@components/ui/Scheduler"; import { LocationMarkerIcon, PlusCircleIcon, XIcon, PhoneIcon } from "@heroicons/react/outline"; -import { EventTypeCustomInput, EventTypeCustomInputType } from "../../../lib/eventTypeInput"; +import { EventTypeCustomInput, EventTypeCustomInputType } from "@lib/eventTypeInput"; import { PlusIcon } from "@heroicons/react/solid"; import dayjs from "dayjs"; import utc from "dayjs/plugin/utc"; dayjs.extend(utc); import timezone from "dayjs/plugin/timezone"; +import { EventType, User, Availability } from "@prisma/client"; +import { validJson } from "@lib/jsonUtils"; dayjs.extend(timezone); -export default function EventType(props: any): JSX.Element { +type Props = { + user: User; + eventType: EventType; + locationOptions: OptionBase[]; + availability: Availability[]; +}; +type OpeningHours = { + days: number[]; + startTime: number; + endTime: number; +}; + +type DateOverride = { + date: string; + startTime: number; + endTime: number; +}; + +type EventTypeInput = { + id: number; + title: string; + slug: string; + description: string; + length: number; + hidden: boolean; + locations: unknown; + eventName: string; + customInputs: EventTypeCustomInput[]; + timeZone: string; + availability?: { openingHours: OpeningHours[]; dateOverrides: DateOverride[] }; +}; + +export default function EventTypePage({ + user, + eventType, + locationOptions, + availability, +}: Props): JSX.Element { const router = useRouter(); const inputOptions: OptionBase[] = [ @@ -30,17 +70,17 @@ export default function EventType(props: any): JSX.Element { { value: EventTypeCustomInputType.Bool, label: "Checkbox" }, ]; + const [enteredAvailability, setEnteredAvailability] = useState(); const [showLocationModal, setShowLocationModal] = useState(false); const [showAddCustomModal, setShowAddCustomModal] = useState(false); + const [selectedTimeZone, setSelectedTimeZone] = useState(""); const [selectedLocation, setSelectedLocation] = useState(undefined); const [selectedInputOption, setSelectedInputOption] = useState(inputOptions[0]); - const [locations, setLocations] = useState(props.eventType.locations || []); - const [schedule, setSchedule] = useState(undefined); + const [locations, setLocations] = useState(eventType.locations || []); const [selectedCustomInput, setSelectedCustomInput] = useState(undefined); const [customInputs, setCustomInputs] = useState( - props.eventType.customInputs.sort((a, b) => a.id - b.id) || [] + eventType.customInputs.sort((a, b) => a.id - b.id) || [] ); - const locationOptions = props.locationOptions; const titleRef = useRef(); const slugRef = useRef(); @@ -49,60 +89,55 @@ export default function EventType(props: any): JSX.Element { const isHiddenRef = useRef(); const eventNameRef = useRef(); + useEffect(() => { + setSelectedTimeZone(eventType.timeZone || user.timeZone); + }, []); + async function updateEventTypeHandler(event) { event.preventDefault(); - const enteredTitle = titleRef.current.value; - const enteredSlug = slugRef.current.value; - const enteredDescription = descriptionRef.current.value; - const enteredLength = lengthRef.current.value; - const enteredIsHidden = isHiddenRef.current.checked; - const enteredEventName = eventNameRef.current.value; + const enteredTitle: string = titleRef.current.value; + const enteredSlug: string = slugRef.current.value; + const enteredDescription: string = descriptionRef.current.value; + const enteredLength: number = parseInt(lengthRef.current.value); + const enteredIsHidden: boolean = isHiddenRef.current.checked; + const enteredEventName: string = eventNameRef.current.value; // TODO: Add validation + const payload: EventTypeInput = { + id: eventType.id, + title: enteredTitle, + slug: enteredSlug, + description: enteredDescription, + length: enteredLength, + hidden: enteredIsHidden, + locations, + eventName: enteredEventName, + customInputs, + timeZone: selectedTimeZone, + }; + + if (enteredAvailability) { + payload.availability = { + dateOverrides: [], + openingHours: enteredAvailability.openingHours.map((item): OpeningHours => { + item.startTime = item.startDate.hour() * 60 + item.startDate.minute(); + delete item.startDate; + item.endTime = item.endDate.hour() * 60 + item.endDate.minute(); + delete item.endDate; + return item; + }), + }; + } + await fetch("/api/availability/eventtype", { method: "PATCH", - body: JSON.stringify({ - id: props.eventType.id, - title: enteredTitle, - slug: enteredSlug, - description: enteredDescription, - length: enteredLength, - hidden: enteredIsHidden, - locations, - eventName: enteredEventName, - customInputs, - }), + body: JSON.stringify(payload), headers: { "Content-Type": "application/json", }, }); - if (schedule) { - const schedulePayload = { overrides: [], timeZone: props.user.timeZone, openingHours: [] }; - schedule.forEach((item) => { - if (item.isOverride) { - delete item.isOverride; - schedulePayload.overrides.push(item); - } else { - const endTime = item.endDate.hour() * 60 + item.endDate.minute() || 1440; // also handles 00:00 - schedulePayload.openingHours.push({ - days: item.days, - startTime: item.startDate.hour() * 60 + item.startDate.minute() - item.startDate.utcOffset(), - endTime: endTime - item.endDate.utcOffset(), - }); - } - }); - - await fetch("/api/availability/schedule/" + props.eventType.id, { - method: "PUT", - body: JSON.stringify(schedulePayload), - headers: { - "Content-Type": "application/json", - }, - }); - } - router.push("/availability"); } @@ -111,7 +146,7 @@ export default function EventType(props: any): JSX.Element { await fetch("/api/availability/eventtype", { method: "DELETE", - body: JSON.stringify({ id: props.eventType.id }), + body: JSON.stringify({ id: eventType.id }), headers: { "Content-Type": "application/json", }, @@ -237,10 +272,10 @@ export default function EventType(props: any): JSX.Element { return (
    - {props.eventType.title} | Event Type | Calendso + {eventType.title} | Event Type | Calendso - +
    @@ -259,7 +294,7 @@ export default function EventType(props: any): JSX.Element { required className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="Quick Chat" - defaultValue={props.eventType.title} + defaultValue={eventType.title} />
    @@ -270,7 +305,7 @@ export default function EventType(props: any): JSX.Element {
    - {typeof location !== "undefined" ? location.hostname : ""}/{props.user.username}/ + {typeof location !== "undefined" ? location.hostname : ""}/{user.username}/
    @@ -420,7 +455,7 @@ export default function EventType(props: any): JSX.Element { id="description" className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="A quick video meeting." - defaultValue={props.eventType.description}> + defaultValue={eventType.description}>
    @@ -436,7 +471,7 @@ export default function EventType(props: any): JSX.Element { required className="focus:ring-blue-500 focus:border-blue-500 block w-full pr-20 sm:text-sm border-gray-300 rounded-md" placeholder="15" - defaultValue={props.eventType.length} + defaultValue={eventType.length} />
    minutes @@ -455,7 +490,7 @@ export default function EventType(props: any): JSX.Element { id="title" className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="Meeting with {USER}" - defaultValue={props.eventType.eventName} + defaultValue={eventType.eventName} />
    @@ -514,7 +549,7 @@ export default function EventType(props: any): JSX.Element { name="ishidden" type="checkbox" className="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-300 rounded" - defaultChecked={props.eventType.hidden} + defaultChecked={eventType.hidden} />
    @@ -531,9 +566,10 @@ export default function EventType(props: any): JSX.Element {

    How do you want to offer your availability for this event type?

    @@ -709,24 +745,18 @@ export default function EventType(props: any): JSX.Element { ); } -const validJson = (jsonString: string) => { - try { - const o = JSON.parse(jsonString); - if (o && typeof o === "object") { - return o; - } - } catch (e) { - console.log("Invalid JSON:", e); - } - return false; -}; - -export async function getServerSideProps(context) { - const session = await getSession(context); +export const getServerSideProps: GetServerSideProps = async ({ req, query }) => { + const session = await getSession({ req }); if (!session) { - return { redirect: { permanent: false, destination: "/auth/login" } }; + return { + redirect: { + permanent: false, + destination: "/auth/login", + }, + }; } - const user = await prisma.user.findFirst({ + + const user: User = await prisma.user.findFirst({ where: { email: session.user.email, }, @@ -739,9 +769,9 @@ export async function getServerSideProps(context) { }, }); - const eventType = await prisma.eventType.findUnique({ + const eventType: EventType | null = await prisma.eventType.findUnique({ where: { - id: parseInt(context.query.type), + id: parseInt(query.type as string), }, select: { id: true, @@ -754,9 +784,16 @@ export async function getServerSideProps(context) { eventName: true, availability: true, customInputs: true, + timeZone: true, }, }); + if (!eventType) { + return { + notFound: true, + }; + } + const credentials = await prisma.credential.findMany({ where: { userId: user.id, @@ -808,18 +845,12 @@ export async function getServerSideProps(context) { // Assuming it's Microsoft Teams. } - if (!eventType) { - return { - notFound: true, - }; - } - const getAvailability = (providesAvailability) => providesAvailability.availability && providesAvailability.availability.length ? providesAvailability.availability : null; - const schedules = getAvailability(eventType) || + const availability: Availability[] = getAvailability(eventType) || getAvailability(user) || [ { days: [0, 1, 2, 3, 4, 5, 6], @@ -832,8 +863,8 @@ export async function getServerSideProps(context) { props: { user, eventType, - schedules, locationOptions, + availability, }, }; -} +}; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 212912516c..1d4fe82a8a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -24,6 +24,7 @@ model EventType { availability Availability[] eventName String? customInputs EventTypeCustomInput[] + timeZone String? } model Credential { From 5d30586a248b935271f42659a2a163ef30304459 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Tue, 29 Jun 2021 22:00:25 +0000 Subject: [PATCH 14/25] Heavily simplified the startTime and endTime display by removing dayjs from SetTimesModal --- components/ui/Scheduler.tsx | 26 +++++++++++++++------- components/ui/modal/SetTimesModal.tsx | 32 +++++++-------------------- pages/availability/event/[type].tsx | 13 ++--------- 3 files changed, 28 insertions(+), 43 deletions(-) diff --git a/components/ui/Scheduler.tsx b/components/ui/Scheduler.tsx index bbe3ad2819..9f25dcf4cd 100644 --- a/components/ui/Scheduler.tsx +++ b/components/ui/Scheduler.tsx @@ -50,13 +50,16 @@ export const Scheduler = ({ const addNewSchedule = () => setEditSchedule(openingHours.length); const applyEditSchedule = (changed) => { + // new entry if (!changed.days) { changed.days = [1, 2, 3, 4, 5]; // Mon - Fri + setOpeningHours(openingHours.concat(changed)); + } else { + // update + const replaceWith = { ...openingHours[editSchedule], ...changed }; + openingHours.splice(editSchedule, 1, replaceWith); + setOpeningHours([].concat(openingHours)); } - - const replaceWith = { ...openingHours[editSchedule], ...changed }; - openingHours.splice(editSchedule, 1, replaceWith); - setOpeningHours([].concat(openingHours)); }; const removeScheduleAt = (toRemove: number) => { @@ -69,9 +72,15 @@ export const Scheduler = ({
    (item.days = selected)} />
    : @@ -104,7 +88,7 @@ export default function SetTimesModal(props) { id="startMinutes" className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="30" - defaultValue={startDate.format("m")} + defaultValue={startMinutes} />
    @@ -124,7 +108,7 @@ export default function SetTimesModal(props) { id="endHours" className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="17" - defaultValue={endDate.format("H")} + defaultValue={endHours} />
    : @@ -143,7 +127,7 @@ export default function SetTimesModal(props) { id="endMinutes" className="shadow-sm focus:ring-blue-500 focus:border-blue-500 block w-full sm:text-sm border-gray-300 rounded-md" placeholder="30" - defaultValue={endDate.format("m")} + defaultValue={endMinutes} />
    diff --git a/pages/availability/event/[type].tsx b/pages/availability/event/[type].tsx index 2237d065dd..de3e435339 100644 --- a/pages/availability/event/[type].tsx +++ b/pages/availability/event/[type].tsx @@ -118,16 +118,7 @@ export default function EventTypePage({ }; if (enteredAvailability) { - payload.availability = { - dateOverrides: [], - openingHours: enteredAvailability.openingHours.map((item): OpeningHours => { - item.startTime = item.startDate.hour() * 60 + item.startDate.minute(); - delete item.startDate; - item.endTime = item.endDate.hour() * 60 + item.endDate.minute(); - delete item.endDate; - return item; - }), - }; + payload.availability = enteredAvailability; } await fetch("/api/availability/eventtype", { @@ -855,7 +846,7 @@ export const getServerSideProps: GetServerSideProps = async ({ req, query { days: [0, 1, 2, 3, 4, 5, 6], startTime: user.startTime, - length: user.endTime >= 1440 ? 1439 : user.endTime, + endTime: user.endTime, }, ]; From 0da99f0d078a65140ab1a7a94f06d7ee3a0b3eda Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Tue, 29 Jun 2021 22:35:13 +0000 Subject: [PATCH 15/25] Removed code bloat, fixed tests --- .babelrc | 3 +++ components/ui/modal/DateOverrideModal.tsx | 7 ------ lib/slots.ts | 15 +++++++------ test/lib/slots.test.ts | 27 +++++------------------ 4 files changed, 16 insertions(+), 36 deletions(-) create mode 100644 .babelrc delete mode 100644 components/ui/modal/DateOverrideModal.tsx diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000000..e49a7e6569 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["next/babel"] +} \ No newline at end of file diff --git a/components/ui/modal/DateOverrideModal.tsx b/components/ui/modal/DateOverrideModal.tsx deleted file mode 100644 index 282f612590..0000000000 --- a/components/ui/modal/DateOverrideModal.tsx +++ /dev/null @@ -1,7 +0,0 @@ - - -/*export default function DateOverrideModal(props) { - return ( - - ); -}*/ \ No newline at end of file diff --git a/lib/slots.ts b/lib/slots.ts index 7d3a777373..c82913b597 100644 --- a/lib/slots.ts +++ b/lib/slots.ts @@ -4,20 +4,20 @@ import timezone from "dayjs/plugin/timezone"; dayjs.extend(utc); dayjs.extend(timezone); -interface GetSlotsType { +type GetSlots = { inviteeDate: Dayjs; frequency: number; workingHours: []; minimumBookingNotice?: number; - organizerUtcOffset: number; -} + organizerTimeZone: string; +}; -interface Boundary { +type Boundary = { lowerBound: number; upperBound: number; -} +}; -const freqApply: number = (cb, value: number, frequency: number): number => cb(value / frequency) * frequency; +const freqApply = (cb, value: number, frequency: number): number => cb(value / frequency) * frequency; const intersectBoundary = (a: Boundary, b: Boundary) => { if (a.upperBound < b.lowerBound || a.lowerBound > b.upperBound) { @@ -108,12 +108,13 @@ const getSlots = ({ minimumBookingNotice, workingHours, organizerTimeZone, -}: GetSlotsType): Dayjs[] => { +}: GetSlots): Dayjs[] => { const startTime = dayjs.utc().isSame(dayjs(inviteeDate), "day") ? inviteeDate.hour() * 60 + inviteeDate.minute() + minimumBookingNotice : 0; const inviteeBounds = inviteeBoundary(startTime, inviteeDate.utcOffset(), frequency); + return getOverlaps( inviteeBounds, organizerBoundaries(workingHours, inviteeDate, inviteeBounds, organizerTimeZone) diff --git a/test/lib/slots.test.ts b/test/lib/slots.test.ts index 90bec4be3b..8278837173 100644 --- a/test/lib/slots.test.ts +++ b/test/lib/slots.test.ts @@ -13,27 +13,10 @@ it('can fit 24 hourly slots for an empty day', async () => { // 24h in a day. expect(getSlots({ inviteeDate: dayjs().add(1, 'day'), - length: 60, + frequency: 60, + workingHours: [ + { days: [...Array(7).keys()], startTime: 0, endTime: 1440 } + ], + organizerTimeZone: 'Europe/London' })).toHaveLength(24); -}); - -it('has slots that be in the same timezone as the invitee', async() => { - expect(getSlots({ - inviteeDate: dayjs().add(1, 'day'), - length: 60 - })[0].utcOffset()).toBe(-0); - - expect(getSlots({ - inviteeDate: dayjs().tz('Europe/London').add(1, 'day'), - length: 60 - })[0].utcOffset()).toBe(dayjs().tz('Europe/London').utcOffset()); -}) - -it('excludes slots that have already passed when invitee day equals today', async () => { - expect(getSlots({ inviteeDate: dayjs(), length: 60 })).toHaveLength(12); -}); - -it('supports having slots in different utc offset than the invitee', async () => { - expect(getSlots({ inviteeDate: dayjs(), length: 60 })).toHaveLength(12); - expect(getSlots({ inviteeDate: dayjs().tz('Europe/Brussels'), length: 60 })).toHaveLength(14); }); \ No newline at end of file From e78a34e2ced08aae1f34ef4e112a39afbc4bead6 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 01:35:08 +0000 Subject: [PATCH 16/25] Implements slot logic with the DatePicker, more tests for slots --- components/booking/DatePicker.tsx | 138 ++++++++++++++++------------- components/booking/TimeOptions.tsx | 101 +++++++++++---------- components/ui/Scheduler.tsx | 2 - lib/slots.ts | 10 ++- pages/[user]/[type].tsx | 24 ++--- test/lib/slots.test.ts | 36 +++++++- 6 files changed, 177 insertions(+), 134 deletions(-) diff --git a/components/booking/DatePicker.tsx b/components/booking/DatePicker.tsx index ac1a0420cf..0e02940c51 100644 --- a/components/booking/DatePicker.tsx +++ b/components/booking/DatePicker.tsx @@ -1,13 +1,20 @@ import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/solid"; import { useEffect, useState } from "react"; import dayjs, { Dayjs } from "dayjs"; -import isToday from "dayjs/plugin/isToday"; -dayjs.extend(isToday); +import utc from "dayjs/plugin/utc"; +import timezone from "dayjs/plugin/timezone"; +import getSlots from "@lib/slots"; +dayjs.extend(utc); +dayjs.extend(timezone); -const DatePicker = ({ weekStart, onDatePicked, workingHours, disableToday }) => { - const workingDays = workingHours.reduce((workingDays: number[], wh) => [...workingDays, ...wh.days], []); - const [selectedMonth, setSelectedMonth] = useState(dayjs().month()); - const [selectedDate, setSelectedDate] = useState(); +const DatePicker = ({ weekStart, onDatePicked, workingHours, organizerTimeZone, inviteeTimeZone }) => { + const [calendar, setCalendar] = useState([]); + const [selectedMonth, setSelectedMonth]: number = useState(); + const [selectedDate, setSelectedDate]: Dayjs = useState(); + + useEffect(() => { + setSelectedMonth(dayjs().tz(inviteeTimeZone).month()); + }, []); useEffect(() => { if (selectedDate) onDatePicked(selectedDate); @@ -22,69 +29,80 @@ const DatePicker = ({ weekStart, onDatePicked, workingHours, disableToday }) => setSelectedMonth(selectedMonth - 1); }; - // Set up calendar - const daysInMonth = dayjs().month(selectedMonth).daysInMonth(); - const days = []; - for (let i = 1; i <= daysInMonth; i++) { - days.push(i); - } + useEffect(() => { + if (!selectedMonth) { + // wish next had a way of dealing with this magically; + return; + } - // Create placeholder elements for empty days in first week - let weekdayOfFirst = dayjs().month(selectedMonth).date(1).day(); - if (weekStart === "Monday") { - weekdayOfFirst -= 1; - if (weekdayOfFirst < 0) weekdayOfFirst = 6; - } - const emptyDays = Array(weekdayOfFirst) - .fill(null) - .map((day, i) => ( -
    - {null} -
    - )); + const inviteeDate = dayjs().tz(inviteeTimeZone).month(selectedMonth); - const isDisabled = (day: number) => { - const date: Dayjs = dayjs().month(selectedMonth).date(day); - return ( - date.isBefore(dayjs()) || !workingDays.includes(+date.format("d")) || (date.isToday() && disableToday) - ); - }; + const isDisabled = (day: number) => { + const date: Dayjs = inviteeDate.date(day); + return ( + date.endOf("day").isBefore(dayjs().tz(inviteeTimeZone)) || + !getSlots({ + inviteeDate: date, + frequency: 30, + workingHours, + organizerTimeZone, + }).length + ); + }; - // Combine placeholder days with actual days - const calendar = [ - ...emptyDays, - ...days.map((day) => ( - - )), - ]; + // Set up calendar + const daysInMonth = inviteeDate.daysInMonth(); + const days = []; + for (let i = 1; i <= daysInMonth; i++) { + days.push(i); + } - return ( + // Create placeholder elements for empty days in first week + let weekdayOfFirst = inviteeDate.date(1).day(); + if (weekStart === "Monday") { + weekdayOfFirst -= 1; + if (weekdayOfFirst < 0) weekdayOfFirst = 6; + } + const emptyDays = Array(weekdayOfFirst) + .fill(null) + .map((day, i) => ( +
    + {null} +
    + )); + + // Combine placeholder days with actual days + setCalendar([ + ...emptyDays, + ...days.map((day) => ( + + )), + ]); + }, [selectedMonth, inviteeTimeZone]); + + return selectedMonth ? (
    {dayjs().month(selectedMonth).format("MMMM YYYY")}
    - ); + ) : null; }; export default DatePicker; diff --git a/components/booking/TimeOptions.tsx b/components/booking/TimeOptions.tsx index 38aafd8bf5..580e174e4b 100644 --- a/components/booking/TimeOptions.tsx +++ b/components/booking/TimeOptions.tsx @@ -1,73 +1,72 @@ -import {Switch} from "@headlessui/react"; +import { Switch } from "@headlessui/react"; import TimezoneSelect from "react-timezone-select"; -import {useEffect, useState} from "react"; -import {timeZone, is24h} from '../../lib/clock'; +import { useEffect, useState } from "react"; +import { timeZone, is24h } from "../../lib/clock"; function classNames(...classes) { - return classes.filter(Boolean).join(' ') + return classes.filter(Boolean).join(" "); } const TimeOptions = (props) => { - - const [selectedTimeZone, setSelectedTimeZone] = useState(''); + const [selectedTimeZone, setSelectedTimeZone] = useState(""); const [is24hClock, setIs24hClock] = useState(false); - useEffect( () => { + useEffect(() => { setIs24hClock(is24h()); setSelectedTimeZone(timeZone()); }, []); - useEffect( () => { - props.onSelectTimeZone(timeZone(selectedTimeZone)); + useEffect(() => { + if (selectedTimeZone && timeZone() && selectedTimeZone !== timeZone()) { + props.onSelectTimeZone(timeZone(selectedTimeZone)); + } }, [selectedTimeZone]); - useEffect( () => { + useEffect(() => { props.onToggle24hClock(is24h(is24hClock)); }, [is24hClock]); - return selectedTimeZone !== "" && ( -
    -
    -
    Time Options
    -
    - - - am/pm - - - Use setting -
    - setSelectedTimeZone(tz.value)} - className="mb-2 shadow-sm focus:ring-blue-500 focus:border-blue-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md" - /> -
    + ) ); -} +}; -export default TimeOptions; \ No newline at end of file +export default TimeOptions; diff --git a/components/ui/Scheduler.tsx b/components/ui/Scheduler.tsx index 9f25dcf4cd..045c726d20 100644 --- a/components/ui/Scheduler.tsx +++ b/components/ui/Scheduler.tsx @@ -92,8 +92,6 @@ export const Scheduler = ({ ); - console.log(selectedTimeZone); - return (
    diff --git a/lib/slots.ts b/lib/slots.ts index c82913b597..35d06a65a1 100644 --- a/lib/slots.ts +++ b/lib/slots.ts @@ -4,10 +4,16 @@ import timezone from "dayjs/plugin/timezone"; dayjs.extend(utc); dayjs.extend(timezone); +type WorkingHour = { + days: number[]; + startTime: number; + endTime: number; +}; + type GetSlots = { inviteeDate: Dayjs; frequency: number; - workingHours: []; + workingHours: WorkingHour[]; minimumBookingNotice?: number; organizerTimeZone: string; }; @@ -110,7 +116,7 @@ const getSlots = ({ organizerTimeZone, }: GetSlots): Dayjs[] => { const startTime = dayjs.utc().isSame(dayjs(inviteeDate), "day") - ? inviteeDate.hour() * 60 + inviteeDate.minute() + minimumBookingNotice + ? inviteeDate.hour() * 60 + inviteeDate.minute() + (minimumBookingNotice || 0) : 0; const inviteeBounds = inviteeBoundary(startTime, inviteeDate.utcOffset(), frequency); diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 42fba5ecff..1bda7a5098 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -1,10 +1,10 @@ -import { useEffect, useState, useMemo } from "react"; +import { useEffect, useState } from "react"; import { GetServerSideProps } from "next"; import Head from "next/head"; import { ClockIcon, GlobeIcon, ChevronDownIcon } from "@heroicons/react/solid"; import prisma from "../../lib/prisma"; import { useRouter } from "next/router"; -import dayjs, { Dayjs } from "dayjs"; +import { Dayjs } from "dayjs"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry"; import AvailableTimes from "../../components/booking/AvailableTimes"; @@ -13,7 +13,6 @@ import Avatar from "../../components/Avatar"; import { timeZone } from "../../lib/clock"; import DatePicker from "../../components/booking/DatePicker"; import PoweredByCalendso from "../../components/ui/PoweredByCalendso"; -import getSlots from "@lib/slots"; export default function Type(props): Type { // Get router variables @@ -25,32 +24,20 @@ export default function Type(props): Type { const [timeFormat, setTimeFormat] = useState("h:mma"); const telemetry = useTelemetry(); - const today: string = dayjs().utc().format("YYYY-MM-DDTHH:mm"); - const noSlotsToday = useMemo( - () => - getSlots({ - frequency: props.eventType.length, - inviteeDate: dayjs.utc(today) as Dayjs, - workingHours: props.workingHours, - organizerTimeZone: props.eventType.timeZone, - minimumBookingNotice: 0, - }).length === 0, - [today, props.eventType.length, props.workingHours] - ); - useEffect(() => { telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.pageView, collectPageParameters())); }, [telemetry]); const changeDate = (date: Dayjs) => { telemetry.withJitsu((jitsu) => jitsu.track(telemetryEventTypes.dateSelected, collectPageParameters())); - setSelectedDate(date.tz(timeZone())); + setSelectedDate(date); }; const handleSelectTimeZone = (selectedTimeZone: string): void => { if (selectedDate) { setSelectedDate(selectedDate.tz(selectedTimeZone)); } + setIsTimeOptionsOpen(false); }; const handleToggle24hClock = (is24hClock: boolean) => { @@ -136,10 +123,11 @@ export default function Type(props): Type {

    {props.eventType.description}

    {selectedDate && ( { // 24h in a day. @@ -19,4 +19,38 @@ it('can fit 24 hourly slots for an empty day', async () => { ], organizerTimeZone: 'Europe/London' })).toHaveLength(24); +}); + +it('only shows future booking slots on the same day', async () => { + // The mock date is 1s to midday, so 12 slots should be open given 0 booking notice. + expect(getSlots({ + inviteeDate: dayjs(), + frequency: 60, + workingHours: [ + { days: [...Array(7).keys()], startTime: 0, endTime: 1440 } + ], + organizerTimeZone: 'GMT' + })).toHaveLength(12); +}); + +it('can cut off dates that due to invitee timezone differences fall on the next day', async () => { + expect(getSlots({ + inviteeDate: dayjs().tz('Europe/Amsterdam').startOf('day'), // time translation +01:00 + frequency: 60, + workingHours: [ + { days: [0], startTime: 1380, endTime: 1440 } + ], + organizerTimeZone: 'Europe/London' + })).toHaveLength(0); +}); + +it('can cut off dates that due to invitee timezone differences fall on the previous day', async () => { + expect(getSlots({ + inviteeDate: dayjs().startOf('day'), // time translation -01:00 + frequency: 60, + workingHours: [ + { days: [0], startTime: 0, endTime: 60 } + ], + organizerTimeZone: 'Europe/London' + })).toHaveLength(0); }); \ No newline at end of file From ee603a0a27fbbcfad51baeb71b3c34a8a61abfc9 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 01:48:23 +0000 Subject: [PATCH 17/25] Added migration for Availability and related --- .../migration.sql | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 prisma/migrations/20210630014738_schedule_availability/migration.sql diff --git a/prisma/migrations/20210630014738_schedule_availability/migration.sql b/prisma/migrations/20210630014738_schedule_availability/migration.sql new file mode 100644 index 0000000000..a5099595e9 --- /dev/null +++ b/prisma/migrations/20210630014738_schedule_availability/migration.sql @@ -0,0 +1,31 @@ +/* + Warnings: + + - You are about to drop the `ResetPasswordRequest` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- AlterTable +ALTER TABLE "EventType" ADD COLUMN "timeZone" TEXT; + +-- DropTable +DROP TABLE "ResetPasswordRequest"; + +-- CreateTable +CREATE TABLE "Availability" ( + "id" SERIAL NOT NULL, + "label" TEXT, + "userId" INTEGER, + "eventTypeId" INTEGER, + "days" INTEGER[], + "startTime" INTEGER NOT NULL, + "endTime" INTEGER NOT NULL, + "date" DATE, + + PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Availability" ADD FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Availability" ADD FOREIGN KEY ("eventTypeId") REFERENCES "EventType"("id") ON DELETE SET NULL ON UPDATE CASCADE; From fdee619fbf80a977e836b93ee878068deef5ed4b Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 01:49:35 +0000 Subject: [PATCH 18/25] Removed changes to calendso.yaml --- calendso.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/calendso.yaml b/calendso.yaml index 69adf6164d..d45d0f7d2b 100644 --- a/calendso.yaml +++ b/calendso.yaml @@ -28,8 +28,6 @@ tags: description: Manage integrations - name: User description: Manage the user's profile and settings - - name: Team - description: Group users into teams paths: /api/auth/signin: get: @@ -158,9 +156,3 @@ paths: summary: Updates a user's profile tags: - User - - /api/availability/schedule: - path: - description: "Updates a schedule" - tags: - - Availability From 90e4091b0619c9aab978b0314feb1f373d1d3c09 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 01:55:06 +0000 Subject: [PATCH 19/25] Rehydrated yarn.lock file --- yarn.lock | 1607 +++++++++++++++++++++++++---------------------------- 1 file changed, 765 insertions(+), 842 deletions(-) diff --git a/yarn.lock b/yarn.lock index ffcaf0d899..5448eb4f02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -148,11 +148,6 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-validator-identifier@^7.14.0": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" - integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== - "@babel/helper-validator-identifier@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" @@ -172,16 +167,7 @@ "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/highlight@^7.10.4": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" - integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== - dependencies: - "@babel/helper-validator-identifier" "^7.14.0" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/highlight@^7.14.5": +"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== @@ -293,10 +279,10 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.12.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7": - version "7.14.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" - integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== +"@babel/runtime@^7.10.5", "@babel/runtime@^7.12.0", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== dependencies: regenerator-runtime "^0.13.4" @@ -346,10 +332,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@emotion/cache@^11.0.0", "@emotion/cache@^11.1.3": - version "11.1.3" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.1.3.tgz#c7683a9484bcd38d5562f2b9947873cf66829afd" - integrity sha512-n4OWinUPJVaP6fXxWZD9OUeQ0lY7DvtmtSuqtRWT0Ofo/sBLCVSgb4/Oa0Q5eFxcwablRKjUXqXtNZVyEwCAuA== +"@emotion/cache@^11.4.0": + version "11.4.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.4.0.tgz#293fc9d9a7a38b9aad8e9337e5014366c3b09ac0" + integrity sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g== dependencies: "@emotion/memoize" "^0.7.4" "@emotion/sheet" "^1.0.0" @@ -368,19 +354,19 @@ integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== "@emotion/react@^11.1.1": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.1.5.tgz#15e78f9822894cdc296e6f4e0688bac8120dfe66" - integrity sha512-xfnZ9NJEv9SU9K2sxXM06lzjK245xSeHRpUh67eARBm3PBHjjKIZlfWZ7UQvD0Obvw6ZKjlC79uHrlzFYpOB/Q== + version "11.4.0" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.4.0.tgz#2465ad7b073a691409b88dfd96dc17097ddad9b7" + integrity sha512-4XklWsl9BdtatLoJpSjusXhpKv9YVteYKh9hPKP1Sxl+mswEFoUe0WtmtWjxEjkA51DQ2QRMCNOvKcSlCQ7ivg== dependencies: - "@babel/runtime" "^7.7.2" - "@emotion/cache" "^11.1.3" - "@emotion/serialize" "^1.0.0" + "@babel/runtime" "^7.13.10" + "@emotion/cache" "^11.4.0" + "@emotion/serialize" "^1.0.2" "@emotion/sheet" "^1.0.1" "@emotion/utils" "^1.0.0" "@emotion/weak-memoize" "^0.2.5" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.0.0": +"@emotion/serialize@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.2.tgz#77cb21a0571c9f68eb66087754a65fa97bfcd965" integrity sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A== @@ -433,10 +419,10 @@ dependencies: purgecss "^4.0.3" -"@hapi/accept@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.1.tgz#068553e867f0f63225a506ed74e899441af53e10" - integrity sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q== +"@hapi/accept@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.2.tgz#ab7043b037e68b722f93f376afb05e85c0699523" + integrity sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw== dependencies: "@hapi/boom" "9.x.x" "@hapi/hoek" "9.x.x" @@ -448,22 +434,15 @@ dependencies: "@hapi/hoek" "9.x.x" -"@hapi/hoek@9.x.x", "@hapi/hoek@^9.0.0": +"@hapi/hoek@9.x.x": version "9.2.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== -"@hapi/topo@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" - integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw== - dependencies: - "@hapi/hoek" "^9.0.0" - "@headlessui/react@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.1.1.tgz#71ecb3444eb21947ceefe768a25efaba4f8eceb0" - integrity sha512-fxNKxRrjNXdNYNMhAVrv1nz0gIMX3JhFizTA9lNrEC8+aY3JR00GZTPhuG785RZGvnHXCdYCGHeAhqw9uRNRrA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.3.0.tgz#62287c92604923e5dfb394483e5ec2463e1baea6" + integrity sha512-2gqTO6BQ3Jr8vDX1B67n1gl6MGKTt6DBmR+H0qxwj0gTMnR2+Qpktj8alRWxsZBODyOiBb77QSQpE/6gG3MX4Q== "@heroicons/react@^1.0.1": version "1.0.1" @@ -486,94 +465,94 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.2.tgz#b8eeff8f21ac51d224c851e1729d2630c18631e6" - integrity sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w== +"@jest/console@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.6.tgz#3eb72ea80897495c3d73dd97aab7f26770e2260f" + integrity sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^27.0.2" - jest-util "^27.0.2" + jest-message-util "^27.0.6" + jest-util "^27.0.6" slash "^3.0.0" -"@jest/core@^27.0.5": - version "27.0.5" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.5.tgz#59e9e69e7374d65dbb22e3fc1bd52e80991eae72" - integrity sha512-g73//jF0VwsOIrWUC9Cqg03lU3QoAMFxVjsm6n6yNmwZcQPN/o8w+gLWODw5VfKNFZT38otXHWxc6b8eGDUpEA== +"@jest/core@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.6.tgz#c5f642727a0b3bf0f37c4b46c675372d0978d4a1" + integrity sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow== dependencies: - "@jest/console" "^27.0.2" - "@jest/reporters" "^27.0.5" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/reporters" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^27.0.2" - jest-config "^27.0.5" - jest-haste-map "^27.0.5" - jest-message-util "^27.0.2" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.5" - jest-resolve-dependencies "^27.0.5" - jest-runner "^27.0.5" - jest-runtime "^27.0.5" - jest-snapshot "^27.0.5" - jest-util "^27.0.2" - jest-validate "^27.0.2" - jest-watcher "^27.0.2" + jest-changed-files "^27.0.6" + jest-config "^27.0.6" + jest-haste-map "^27.0.6" + jest-message-util "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-resolve-dependencies "^27.0.6" + jest-runner "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" + jest-watcher "^27.0.6" micromatch "^4.0.4" p-each-series "^2.1.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.0.5": - version "27.0.5" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.5.tgz#a294ad4acda2e250f789fb98dc667aad33d3adc9" - integrity sha512-IAkJPOT7bqn0GiX5LPio6/e1YpcmLbrd8O5EFYpAOZ6V+9xJDsXjdgN2vgv9WOKIs/uA1kf5WeD96HhlBYO+FA== +"@jest/environment@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.6.tgz#ee293fe996db01d7d663b8108fa0e1ff436219d2" + integrity sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg== dependencies: - "@jest/fake-timers" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" - jest-mock "^27.0.3" + jest-mock "^27.0.6" -"@jest/fake-timers@^27.0.5": - version "27.0.5" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.5.tgz#304d5aedadf4c75cff3696995460b39d6c6e72f6" - integrity sha512-d6Tyf7iDoKqeUdwUKrOBV/GvEZRF67m7lpuWI0+SCD9D3aaejiOQZxAOxwH2EH/W18gnfYaBPLi0VeTGBHtQBg== +"@jest/fake-timers@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.6.tgz#cbad52f3fe6abe30e7acb8cd5fa3466b9588e3df" + integrity sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@sinonjs/fake-timers" "^7.0.2" "@types/node" "*" - jest-message-util "^27.0.2" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-message-util "^27.0.6" + jest-mock "^27.0.6" + jest-util "^27.0.6" -"@jest/globals@^27.0.5": - version "27.0.5" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.5.tgz#f63b8bfa6ea3716f8df50f6a604b5c15b36ffd20" - integrity sha512-qqKyjDXUaZwDuccpbMMKCCMBftvrbXzigtIsikAH/9ca+kaae8InP2MDf+Y/PdCSMuAsSpHS6q6M25irBBUh+Q== +"@jest/globals@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.6.tgz#48e3903f99a4650673d8657334d13c9caf0e8f82" + integrity sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw== dependencies: - "@jest/environment" "^27.0.5" - "@jest/types" "^27.0.2" - expect "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/types" "^27.0.6" + expect "^27.0.6" -"@jest/reporters@^27.0.5": - version "27.0.5" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.5.tgz#cd730b77d9667b8ff700ad66d4edc293bb09716a" - integrity sha512-4uNg5+0eIfRafnpgu3jCZws3NNcFzhu5JdRd1mKQ4/53+vkIqwB6vfZ4gn5BdGqOaLtYhlOsPaL5ATkKzyBrJw== +"@jest/reporters@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.6.tgz#91e7f2d98c002ad5df94d5b5167c1eb0b9fd5b00" + integrity sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.0.2" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -584,60 +563,60 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^27.0.5" - jest-resolve "^27.0.5" - jest-util "^27.0.2" - jest-worker "^27.0.2" + jest-haste-map "^27.0.6" + jest-resolve "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" v8-to-istanbul "^8.0.0" -"@jest/source-map@^27.0.1": - version "27.0.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.1.tgz#2afbf73ddbaddcb920a8e62d0238a0a9e0a8d3e4" - integrity sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A== +"@jest/source-map@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f" + integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g== dependencies: callsites "^3.0.0" graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.2.tgz#0451049e32ceb609b636004ccc27c8fa22263f10" - integrity sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA== +"@jest/test-result@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.6.tgz#3fa42015a14e4fdede6acd042ce98c7f36627051" + integrity sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w== dependencies: - "@jest/console" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/types" "^27.0.6" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.0.5": - version "27.0.5" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.5.tgz#c58b21db49afc36c0e3921d7ddf1fb7954abfded" - integrity sha512-opztnGs+cXzZ5txFG2+omBaV5ge/0yuJNKbhE3DREMiXE0YxBuzyEa6pNv3kk2JuucIlH2Xvgmn9kEEHSNt/SA== +"@jest/test-sequencer@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz#80a913ed7a1130545b1cd777ff2735dd3af5d34b" + integrity sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA== dependencies: - "@jest/test-result" "^27.0.2" + "@jest/test-result" "^27.0.6" graceful-fs "^4.2.4" - jest-haste-map "^27.0.5" - jest-runtime "^27.0.5" + jest-haste-map "^27.0.6" + jest-runtime "^27.0.6" -"@jest/transform@^27.0.5": - version "27.0.5" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.5.tgz#2dcb78953708af713941ac845b06078bc74ed873" - integrity sha512-lBD6OwKXSc6JJECBNk4mVxtSVuJSBsQrJ9WCBisfJs7EZuYq4K6vM9HmoB7hmPiLIDGeyaerw3feBV/bC4z8tg== +"@jest/transform@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.6.tgz#189ad7107413208f7600f4719f81dd2f7278cc95" + integrity sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" babel-plugin-istanbul "^6.0.0" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.4" - jest-haste-map "^27.0.5" - jest-regex-util "^27.0.1" - jest-util "^27.0.2" + jest-haste-map "^27.0.6" + jest-regex-util "^27.0.6" + jest-util "^27.0.6" micromatch "^4.0.4" pirates "^4.0.1" slash "^3.0.0" @@ -655,10 +634,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jest/types@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.2.tgz#e153d6c46bda0f2589f0702b071f9898c7bbd37e" - integrity sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg== +"@jest/types@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.6.tgz#9a992bc517e0c49f035938b8549719c2de40706b" + integrity sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -667,38 +646,40 @@ chalk "^4.0.0" "@jitsu/sdk-js@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@jitsu/sdk-js/-/sdk-js-2.0.1.tgz#7b400f314e042236f994f0cac766712320290fe9" - integrity sha512-PPtbNZosEGZ+rWefYodstAA69eJSHMgWfufqZ1ATiYUrobpbGQsLQBKxI0fJ+YvO1oryfYLlJqgJe0X12vNraQ== + version "2.2.2" + resolved "https://registry.yarnpkg.com/@jitsu/sdk-js/-/sdk-js-2.2.2.tgz#f272a1efe8e61dbe2effab735e9e2b819f553227" + integrity sha512-jvYo7oukIF+gfMkWS2zl7FD1PXkRniBJjxTV7FQJdQ0R3vyF0u+NkLDUcS1iKLl5yeXcuX9+LyDEeIMZiRVUHQ== -"@next-auth/prisma-legacy-adapter@canary": - version "0.0.1-canary.115" - resolved "https://registry.yarnpkg.com/@next-auth/prisma-legacy-adapter/-/prisma-legacy-adapter-0.0.1-canary.115.tgz#ef291c865f1ce9d85f660c85b0b0be16bd89c641" - integrity sha512-rIIisYBvVtxDbY9Lbm+HOLbZyOaaEmtGc9wDN3tJLDUu3sLJOXNN7Pz29ThS+gf2lpMxXnfvk587hxGrnhCghQ== - -"@next-auth/typeorm-legacy-adapter@canary": - version "0.0.2-canary.117" - resolved "https://registry.yarnpkg.com/@next-auth/typeorm-legacy-adapter/-/typeorm-legacy-adapter-0.0.2-canary.117.tgz#c71f7e5f3b474e8b292acaa8ad69d2a4537f93ba" - integrity sha512-sYJZPWMsM1ZTJcl749UojYDF4q8+ZiYcrR7rM4SACc0qiA9VBdOYUUMUMpQoazKOiwo1rWDKu4wHPt6CdV0ctQ== +"@next-auth/prisma-legacy-adapter@0.0.1-canary.127": + version "0.0.1-canary.127" + resolved "https://registry.yarnpkg.com/@next-auth/prisma-legacy-adapter/-/prisma-legacy-adapter-0.0.1-canary.127.tgz#09223de6d0350e53afc4bd0dda056a2fde27d8d3" + integrity sha512-Pd2Y8b1ibDywrndbj3751VNKv1mVcg2w0uNIi01EBVkm5pqA1X+VnKWbPeHfh4arLYw93RPCvfLbWBZS7J1gZQ== dependencies: - crypto-js "^4.0.0" + "@babel/runtime" "^7.14.0" + +"@next-auth/typeorm-legacy-adapter@0.0.2-canary.129": + version "0.0.2-canary.129" + resolved "https://registry.yarnpkg.com/@next-auth/typeorm-legacy-adapter/-/typeorm-legacy-adapter-0.0.2-canary.129.tgz#ec17c4561155281bd1504b5b38542234b4b162b1" + integrity sha512-xEGz3TzBzz+5nXQ6BnC++KGfxTOAgztL32ZRLq47UKz9M0kFBP6pCMJjTszltsBHYUI/Wac2IG2egMTpHtppiQ== + dependencies: + "@babel/runtime" "^7.14.0" require_optional "^1.0.1" typeorm "^0.2.30" -"@next/env@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@next/env/-/env-10.2.0.tgz#154dbce2efa3ad067ebd20b7d0aa9aed775e7c97" - integrity sha512-tsWBsn1Rb6hXRaHc/pWMCpZ4Ipkf3OCbZ54ef5ukgIyEvzzGdGFXQshPP2AF7yb+8yMpunWs7vOMZW3e8oPF6A== +"@next/env@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@next/env/-/env-10.2.3.tgz#ede3bbe68cec9939c37168ea2077f9adbc68334e" + integrity sha512-uBOjRBjsWC4C8X3DfmWWP6ekwLnf2JCCwQX9KVnJtJkqfDsv1yQPakdOEwvJzXQc3JC/v5KKffYPVmV2wHXCgQ== -"@next/polyfill-module@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.2.0.tgz#61f41110c4b465cc26d113e2054e205df61c3594" - integrity sha512-Nl3GexIUXsmuggkUqrRFyE/2k7UI44JaVzSywtXEyHzxpZm2a5bdMaWuC89pgLiFDDOqmbqyLAbtwm5lNxa7Eg== +"@next/polyfill-module@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.2.3.tgz#5a29f50c3ce3a56b8268d3b8331c691d8039467a" + integrity sha512-OkeY4cLhzfYbXxM4fd+6V4s5pTPuyfKSlavItfNRA6PpS7t1/R6YjO7S7rB8tu1pbTGuDHGIdE1ioDv15bAbDQ== -"@next/react-dev-overlay@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.2.0.tgz#4220121abac7e3404cbaf467784aeecca8be46cf" - integrity sha512-PRIAoWog41hLN4iJ8dChKp4ysOX0Q8yiNQ/cwzyqEd3EjugkDV5OiKl3mumGKaApJaIra1MX6j1wgQRuLhuWMA== +"@next/react-dev-overlay@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.2.3.tgz#95313d10a8848f6c7b9e31ae3bd2a3627d136841" + integrity sha512-E6g2jws4YW94l0lMMopBVKIZK2mEHfSBvM0d9dmzKG9L/A/kEq6LZCB4SiwGJbNsAdlk2y3USDa0oNbpA+m5Kw== dependencies: "@babel/code-frame" "7.12.11" anser "1.4.9" @@ -712,30 +693,30 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@10.2.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.2.0.tgz#55953b697769c6647f371bc6bcd865a24e1a22e9" - integrity sha512-3I31K9B4hEQRl7yQ44Umyz+szHtuMJrNdwsgJGhoEnUCXSBRHp5wv5Zv8eDa2NewSbe53b2C0oOpivrzmdBakw== +"@next/react-refresh-utils@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.2.3.tgz#2f3e42fe6680798f276e3621345c2886b231348b" + integrity sha512-qtBF56vPC6d6a8p7LYd0iRjW89fhY80kAIzmj+VonvIGjK/nymBjcFUhbKiMFqlhsarCksnhwX+Zmn95Dw9qvA== -"@nodelib/fs.scandir@2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" - integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: - "@nodelib/fs.stat" "2.0.4" + "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" - integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" - integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" + integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== dependencies: - "@nodelib/fs.scandir" "2.1.4" + "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" "@opentelemetry/api@0.14.0": @@ -756,38 +737,21 @@ integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw== "@prisma/client@^2.23.0": - version "2.23.0" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-2.23.0.tgz#4bf16ab19b140873ba79bd159da86842b1746e0a" - integrity sha512-xsHdo3+wIH0hJVGfKHYTEKtifStjKH0b5t8t7hV32Fypq6+3uxhAi3F25yxuI4XSHXg21nb7Ha82lNwU/0TERA== + version "2.26.0" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-2.26.0.tgz#a23a83bc5c931243ee20b78d9ded423e158aa4c1" + integrity sha512-iwhjdUV/MEQZ7RzTEcZ/D+ewxx/pGExWJ2LypfHioJIvEMyK0saPiR0tjMvMT2I2SVzrIM5dXGhBHWi2JksWrQ== dependencies: - "@prisma/engines-version" "2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b" + "@prisma/engines-version" "2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d" -"@prisma/engines-version@2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b": - version "2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b.tgz#c813279bbea48dedad039b0bc3b044117d2dbaa1" - integrity sha512-VNgnOe+oPQKmy3HOtWi/Q1fvcKZUQkf1OfTD1pzrLBx9tJPejyxt1Mq54L+OOAuYvfrua6bmfojFVLh7uXuWVw== +"@prisma/engines-version@2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d": + version "2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d.tgz#aa707f4496ab92ef1eaf17758274f63b86d2ff9f" + integrity sha512-8tygPkPxag3myF5fgNQ60zwnNSZzFf4J+DXGKykXaBLLt9W2FLkaE5sVL8/OqAGhLAnVsKj83CqPms35bKrTKw== -"@prisma/engines@2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b": - version "2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b.tgz#440abe0ebef44b6e1bdaf2b4d14fcde9fe74f18c" - integrity sha512-Tgk3kggO5B9IT6mimJAw6HSxbFoDAuDKL3sHHSS41EnQm76j/nf4uhGZFPzOQwZWOLeT5ZLO2khr4/FCA9Nkhw== - -"@sideway/address@^4.1.0": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d" - integrity sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@sideway/formula@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" - integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== - -"@sideway/pinpoint@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" - integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@prisma/engines@2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d": + version "2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d.tgz#cfdacfad3acc0f3bf1d7710aa8f3852fd85ac6d9" + integrity sha512-a0jIhLvw9rFh6nZTr5Y3uzP28I2xNDu3pqxANvwMNnmIoYr1wYEcO1pMXn/36BGXldDdAWMmAbhfloHA3IB8DA== "@sinonjs/commons@^1.7.0": version "1.8.3" @@ -847,9 +811,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" - integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.0.tgz#a34277cf8acbd3185ea74129e1f100491eb1da7f" + integrity sha512-IilJZ1hJBUZwMOVDNTdflOOLzJB/ZtljYVa7k3gEZN/jqIJIPkWHC6dvbX+DD2CwZDHB9wAKzZPzzqMIkW37/w== dependencies: "@babel/types" "^7.3.0" @@ -892,15 +856,20 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== +"@types/lodash@^4.14.165": + version "4.14.170" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" + integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q== + "@types/node@*": - version "15.0.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" - integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== + version "15.12.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.5.tgz#9a78318a45d75c9523d2396131bd3cca54b2d185" + integrity sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg== "@types/node@^14.14.33": - version "14.14.44" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.44.tgz#df7503e6002847b834371c004b372529f3f85215" - integrity sha512-+gaugz6Oce6ZInfI/tK4Pq5wIIkJMEJUu92RB3Eu93mtj4wjjjz9EB5mLp5s1pSsLXdC/CPut/xF20ZzAQJbTA== + version "14.17.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.4.tgz#218712242446fc868d0e007af29a4408c7765bc0" + integrity sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A== "@types/nodemailer@^6.4.2": version "6.4.2" @@ -925,9 +894,9 @@ integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== "@types/react@^17.0.3": - version "17.0.5" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.5.tgz#3d887570c4489011f75a3fc8f965bf87d09a1bea" - integrity sha512-bj4biDB9ZJmGAYTWSKJly6bMr4BLUiBrx9ujiJEoP9XIDY9CTaPGxE5QWN/1WjpPLzYF7/jRNnV2nNxNe970sw== + version "17.0.11" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" + integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -968,73 +937,72 @@ integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== "@typescript-eslint/eslint-plugin@^4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.27.0.tgz#0b7fc974e8bc9b2b5eb98ed51427b0be529b4ad0" - integrity sha512-DsLqxeUfLVNp3AO7PC3JyaddmEHTtI9qTSAs+RB6ja27QvIM0TA8Cizn1qcS6vOu+WDLFJzkwkgweiyFhssDdQ== + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.1.tgz#c045e440196ae45464e08e20c38aff5c3a825947" + integrity sha512-9yfcNpDaNGQ6/LQOX/KhUFTR1sCKH+PBr234k6hI9XJ0VP5UqGxap0AnNwBnWFk1MNyWBylJH9ZkzBXC+5akZQ== dependencies: - "@typescript-eslint/experimental-utils" "4.27.0" - "@typescript-eslint/scope-manager" "4.27.0" + "@typescript-eslint/experimental-utils" "4.28.1" + "@typescript-eslint/scope-manager" "4.28.1" debug "^4.3.1" functional-red-black-tree "^1.0.1" - lodash "^4.17.21" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.27.0.tgz#78192a616472d199f084eab8f10f962c0757cd1c" - integrity sha512-n5NlbnmzT2MXlyT+Y0Jf0gsmAQzCnQSWXKy4RGSXVStjDvS5we9IWbh7qRVKdGcxT0WYlgcCYUK/HRg7xFhvjQ== +"@typescript-eslint/experimental-utils@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.1.tgz#3869489dcca3c18523c46018b8996e15948dbadc" + integrity sha512-n8/ggadrZ+uyrfrSEchx3jgODdmcx7MzVM2sI3cTpI/YlfSm0+9HEUaWw3aQn2urL2KYlWYMDgn45iLfjDYB+Q== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.27.0" - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/typescript-estree" "4.27.0" + "@typescript-eslint/scope-manager" "4.28.1" + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/typescript-estree" "4.28.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" "@typescript-eslint/parser@^4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.27.0.tgz#85447e573364bce4c46c7f64abaa4985aadf5a94" - integrity sha512-XpbxL+M+gClmJcJ5kHnUpBGmlGdgNvy6cehgR6ufyxkEJMGP25tZKCaKyC0W/JVpuhU3VU1RBn7SYUPKSMqQvQ== + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.1.tgz#5181b81658414f47291452c15bf6cd44a32f85bd" + integrity sha512-UjrMsgnhQIIK82hXGaD+MCN8IfORS1CbMdu7VlZbYa8LCZtbZjJA26De4IPQB7XYZbL8gJ99KWNj0l6WD0guJg== dependencies: - "@typescript-eslint/scope-manager" "4.27.0" - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/typescript-estree" "4.27.0" + "@typescript-eslint/scope-manager" "4.28.1" + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/typescript-estree" "4.28.1" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.27.0.tgz#b0b1de2b35aaf7f532e89c8e81d0fa298cae327d" - integrity sha512-DY73jK6SEH6UDdzc6maF19AHQJBFVRf6fgAXHPXCGEmpqD4vYgPEzqpFz1lf/daSbOcMpPPj9tyXXDPW2XReAw== +"@typescript-eslint/scope-manager@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.1.tgz#fd3c20627cdc12933f6d98b386940d8d0ce8a991" + integrity sha512-o95bvGKfss6705x7jFGDyS7trAORTy57lwJ+VsYwil/lOUxKQ9tA7Suuq+ciMhJc/1qPwB3XE2DKh9wubW8YYA== dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/visitor-keys" "4.28.1" -"@typescript-eslint/types@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.27.0.tgz#712b408519ed699baff69086bc59cd2fc13df8d8" - integrity sha512-I4ps3SCPFCKclRcvnsVA/7sWzh7naaM/b4pBO2hVxnM3wrU51Lveybdw5WoIktU/V4KfXrTt94V9b065b/0+wA== +"@typescript-eslint/types@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.1.tgz#d0f2ecbef3684634db357b9bbfc97b94b828f83f" + integrity sha512-4z+knEihcyX7blAGi7O3Fm3O6YRCP+r56NJFMNGsmtdw+NCdpG5SgNz427LS9nQkRVTswZLhz484hakQwB8RRg== -"@typescript-eslint/typescript-estree@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.27.0.tgz#189a7b9f1d0717d5cccdcc17247692dedf7a09da" - integrity sha512-KH03GUsUj41sRLLEy2JHstnezgpS5VNhrJouRdmh6yNdQ+yl8w5LrSwBkExM+jWwCJa7Ct2c8yl8NdtNRyQO6g== +"@typescript-eslint/typescript-estree@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.1.tgz#af882ae41740d1f268e38b4d0fad21e7e8d86a81" + integrity sha512-GhKxmC4sHXxHGJv8e8egAZeTZ6HI4mLU6S7FUzvFOtsk7ZIDN1ksA9r9DyOgNqowA9yAtZXV0Uiap61bIO81FQ== dependencies: - "@typescript-eslint/types" "4.27.0" - "@typescript-eslint/visitor-keys" "4.27.0" + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/visitor-keys" "4.28.1" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.27.0": - version "4.27.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.27.0.tgz#f56138b993ec822793e7ebcfac6ffdce0a60cb81" - integrity sha512-es0GRYNZp0ieckZ938cEANfEhsfHrzuLrePukLKtY3/KPXcq1Xd555Mno9/GOgXhKzn0QfkDLVgqWO3dGY80bg== +"@typescript-eslint/visitor-keys@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.1.tgz#162a515ee255f18a6068edc26df793cdc1ec9157" + integrity sha512-K4HMrdFqr9PFquPu178SaSb92CaWe2yErXyPumc8cYWxFmhgJsNY9eSePmO05j0JhBvf2Cdhptd6E6Yv9HVHcg== dependencies: - "@typescript-eslint/types" "4.27.0" + "@typescript-eslint/types" "4.28.1" eslint-visitor-keys "^2.0.0" abab@^2.0.3, abab@^2.0.5: @@ -1082,9 +1050,9 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.2.4: - version "8.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.0.tgz#af53266e698d7cffa416714b503066a82221be60" - integrity sha512-ULr0LDaEqQrMFGyQ3bhJkLsbtrQ8QibAseGZeaSUiT/6zb9IvIkomWHJIvgvwad+hinRAgsI51JcWk2yvwyL+w== + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== agent-base@6: version "6.0.2" @@ -1182,7 +1150,7 @@ any-promise@^1.0.0: resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= -anymatch@^3.0.3, anymatch@~3.1.1: +anymatch@^3.0.3, anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -1212,11 +1180,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - array-includes@^3.1.2, array-includes@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" @@ -1309,22 +1272,20 @@ autoprefixer@^10.2.5: postcss-value-parser "^4.1.0" available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" + version "1.0.4" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" + integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== -babel-jest@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.5.tgz#cd34c033ada05d1362211e5152391fd7a88080c8" - integrity sha512-bTMAbpCX7ldtfbca2llYLeSFsDM257aspyAOpsdrdSrBqoLkWCy4HPYTXtXWaSLgFPjrJGACL65rzzr4RFGadw== +babel-jest@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8" + integrity sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA== dependencies: - "@jest/transform" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^27.0.1" + babel-preset-jest "^27.0.6" chalk "^4.0.0" graceful-fs "^4.2.4" slash "^3.0.0" @@ -1340,10 +1301,10 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz#a6d10e484c93abff0f4e95f437dad26e5736ea11" - integrity sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ== +babel-plugin-jest-hoist@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456" + integrity sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -1373,12 +1334,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz#7a50c75d16647c23a2cf5158d5bb9eb206b10e20" - integrity sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA== +babel-preset-jest@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d" + integrity sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw== dependencies: - babel-plugin-jest-hoist "^27.0.1" + babel-plugin-jest-hoist "^27.0.6" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -1507,18 +1468,7 @@ browserify-zlib@0.2.0, browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@4.16.1: - version "4.16.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766" - integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA== - dependencies: - caniuse-lite "^1.0.30001173" - colorette "^1.2.1" - electron-to-chromium "^1.3.634" - escalade "^3.1.1" - node-releases "^1.1.69" - -browserslist@^4.16.6: +browserslist@4.16.6, browserslist@^4.16.6: version "4.16.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== @@ -1614,15 +1564,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -caniuse-lite@^1.0.30001173, caniuse-lite@^1.0.30001179, caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219: - version "1.0.30001221" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001221.tgz#b916721ddf59066cfbe96c5c9a77cf7ae5c52e65" - integrity sha512-b9TOZfND3uGSLjMOrLh8XxSQ41x8mX+9MLJYDM4AAHLfaZHttrLNPrScWjVnBITRZbY5sPpCt7X85n7VSLZ+/g== - -caniuse-lite@^1.0.30001230: - version "1.0.30001239" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001239.tgz#66e8669985bb2cb84ccb10f68c25ce6dd3e4d2b8" - integrity sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ== +caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228, caniuse-lite@^1.0.30001230: + version "1.0.30001241" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz#cd3fae47eb3d7691692b406568d7a3e5b23c7598" + integrity sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ== chalk@2.4.2, chalk@^2.0.0: version "2.4.2" @@ -1665,7 +1610,7 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chokidar@3.5.1, chokidar@^3.5.1: +chokidar@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== @@ -1680,6 +1625,21 @@ chokidar@3.5.1, chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.1" +chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + ci-info@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6" @@ -1799,7 +1759,7 @@ color@^3.1.3: color-convert "^1.9.1" color-string "^1.5.4" -colorette@^1.2.1, colorette@^1.2.2: +colorette@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== @@ -1933,11 +1893,6 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -crypto-js@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.0.0.tgz#2904ab2677a9d042856a2ea2ef80de92e4a36dcc" - integrity sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg== - css-unit-converter@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" @@ -2004,9 +1959,9 @@ data-urls@^2.0.0: whatwg-url "^8.0.0" dayjs@^1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2" - integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw== + version "1.10.5" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986" + integrity sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g== debug@2: version "2.6.9" @@ -2023,9 +1978,9 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: ms "2.1.2" decimal.js@^10.2.1: - version "10.3.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.0.tgz#96fd481189818e0d5810c18ac147824b9e4c0026" - integrity sha512-MrQRs2gyD//7NeHi9TtsfClkf+cFAewDz+PZHR8ILKglLmBMyVX3ymQ+oeznE3tjrS7beTN+6JXb2C3JDHm7ug== + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== dedent@^0.7.0: version "0.7.0" @@ -2087,19 +2042,19 @@ detective@^5.2.0: minimist "^1.1.1" didyoumean@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" - integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== diff-sequences@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== -diff-sequences@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.1.tgz#9c9801d52ed5f576ff0a20e3022a13ee6e297e7c" - integrity sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg== +diff-sequences@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723" + integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ== diffie-hellman@^5.0.0: version "5.0.3" @@ -2162,9 +2117,9 @@ domexception@^2.0.1: webidl-conversions "^5.0.0" dotenv@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: version "1.0.11" @@ -2178,10 +2133,10 @@ efrt-unpack@2.2.0: resolved "https://registry.yarnpkg.com/efrt-unpack/-/efrt-unpack-2.2.0.tgz#b05dbec0fb8cb346a27840e00c969df9c72fee52" integrity sha512-9xUSSj7qcUxz+0r4X3+bwUNttEfGfK5AH+LVa1aTpqdAfrN5VhROYCfcF+up4hp5OL7IUKcZJJrzAGipQRDoiQ== -electron-to-chromium@^1.3.634, electron-to-chromium@^1.3.723: - version "1.3.726" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.726.tgz#6d3c577e5f5a48904ba891464740896c05e3bdb1" - integrity sha512-dw7WmrSu/JwtACiBzth8cuKf62NKL1xVJuNvyOg0jvruN/n4NLtGYoTzciQquCPNaS2eR+BT5GrxHbslfc/w1w== +electron-to-chromium@^1.3.723: + version "1.3.762" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.762.tgz#3fa4e3bcbda539b50e3aa23041627063a5cffe61" + integrity sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA== elliptic@^6.5.3: version "6.5.4" @@ -2219,9 +2174,9 @@ encoding@0.1.13: iconv-lite "^0.6.2" enhanced-resolve@^5.7.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz#d9deae58f9d3773b6a111a5a46831da5be5c9ac0" - integrity sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ== + version "5.8.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" + integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -2240,29 +2195,7 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: - version "1.18.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" - integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.2" - is-callable "^1.2.3" - is-negative-zero "^2.0.1" - is-regex "^1.1.2" - is-string "^1.0.5" - object-inspect "^1.9.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.0" - -es-abstract@^1.18.2: +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: version "1.18.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== @@ -2528,17 +2461,17 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -expect@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.2.tgz#e66ca3a4c9592f1c019fa1d46459a9d2084f3422" - integrity sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w== +expect@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.6.tgz#a4d74fbe27222c718fff68ef49d78e26a8fd4c05" + integrity sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" ansi-styles "^5.0.0" - jest-get-type "^27.0.1" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-regex-util "^27.0.1" + jest-get-type "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-regex-util "^27.0.6" extend@^3.0.2: version "3.0.2" @@ -2556,16 +2489,15 @@ fast-diff@^1.1.2: integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== fast-glob@^3.1.1, fast-glob@^3.2.5: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + version "3.2.6" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.6.tgz#434dd9529845176ea049acc9343e8282765c6e1a" + integrity sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -2678,7 +2610,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.3.2, fsevents@~2.3.1: +fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -2699,9 +2631,9 @@ futoin-hkdf@^1.3.2: integrity sha512-oR75fYk3B3X9/B02Y6vusrBKucrpC6VjxhRL+C6B7FwUpuSRHbhBNG3AZbcE/xPyJmEQWsyqUFp3VeNNbA3S7A== gaxios@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-4.2.1.tgz#7463d3a06f56ddbffa745a242d2b4933b88b2ada" - integrity sha512-s+rTywpw6CmfB8r9TXYkpix7YFeuRjnR/AqhaJrQqsNhsAqej+IAiCc3hadzQH3gHyWth30tvYjxH8EVjQt/8Q== + version "4.3.0" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-4.3.0.tgz#ad4814d89061f85b97ef52aed888c5dbec32f774" + integrity sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg== dependencies: abort-controller "^3.0.0" extend "^3.0.2" @@ -2710,9 +2642,9 @@ gaxios@^4.0.0: node-fetch "^2.3.0" gcp-metadata@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-4.2.1.tgz#31849fbcf9025ef34c2297c32a89a1e7e9f2cd62" - integrity sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw== + version "4.3.0" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-4.3.0.tgz#0423d06becdbfb9cbb8762eaacf14d5324997900" + integrity sha512-L9XQUpvKJCM76YRSmcxrR4mFPzPGsgZUH+GgHMxAET8qc6+BhRJq63RLhWakgEO2KKVgeSDVfyiNjkGSADwNTA== dependencies: gaxios "^4.0.0" json-bigint "^1.0.0" @@ -2758,7 +2690,7 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -2777,19 +2709,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.0.0, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - 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" - -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -2826,9 +2746,9 @@ globby@^11.0.3: slash "^3.0.0" google-auth-library@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-7.0.4.tgz#610cb010de71435dca47dfbe8dc7fbff23055d2c" - integrity sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q== + version "7.1.2" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-7.1.2.tgz#29fc0fe8b6d5a59b93b7cb561b1a28bcc93360b7" + integrity sha512-FMipHgfe2u1LzWsf2n9zEB9KsJ8M3n8OYTHbHtlkzPCyo7IknXQR5X99nfvwUHGuX+iEpihUZxDuPm7+qBYeXg== dependencies: arrify "^2.0.0" base64-js "^1.3.0" @@ -2841,9 +2761,9 @@ google-auth-library@^7.0.2: lru-cache "^6.0.0" google-p12-pem@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.0.3.tgz#673ac3a75d3903a87f05878f3c75e06fc151669e" - integrity sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.1.0.tgz#a1421b432fcc926812e3835289807170768a9885" + integrity sha512-JUtEHXL4DY/N+xhlm7TC3qL797RPAtk0ZGXNs3/gWyiDHYoA/8Rjes0pztkda+sZv4ej1EoO2KhWgW5V9KTrSQ== dependencies: node-forge "^0.10.0" @@ -2873,9 +2793,9 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== gtoken@^5.0.4: - version "5.2.1" - resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.2.1.tgz#4dae1fea17270f457954b4a45234bba5fc796d16" - integrity sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw== + version "5.3.0" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.3.0.tgz#6536eb2880d9829f0b9d78f756795d4d9064b217" + integrity sha512-mCcISYiaRZrJpfqOs0QWa6lfEM/C1V9ASkzFmuz43XBb5s1Vynh+CZy1ECeeJXVGx2PRByjYzb4Y4/zr1byr0w== dependencies: gaxios "^4.0.0" google-p12-pem "^3.0.3" @@ -2950,9 +2870,9 @@ he@1.2.0: integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== highlight.js@^10.7.1: - version "10.7.2" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360" - integrity sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg== + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== hmac-drbg@^1.0.1: version "1.0.1" @@ -3038,19 +2958,19 @@ iconv-lite@0.4.24: safer-buffer ">= 2.1.2 < 3" iconv-lite@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" - integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" ics@^2.27.0: - version "2.27.0" - resolved "https://registry.yarnpkg.com/ics/-/ics-2.27.0.tgz#0279323e2489777b98ef9d8fbe7143275bf666f4" - integrity sha512-Qgf59OEE38EYX/tVPbo+4bsk0+91Io7jTfp37N3o8BbW/CBYHPdw3GcBov8u2ywjg35xNk8o2b+4UmFwdKOP8A== + version "2.29.0" + resolved "https://registry.yarnpkg.com/ics/-/ics-2.29.0.tgz#85d3bef5d17c5c3b9ee2e8986042549d8dcd1834" + integrity sha512-8483825h0tqTRb3nY/ASXL6QIgdlpOJyODOHF6UolSzw7R2JgjxJOpVMvBjheF63gS9Nbdj4SScZWHmDFqxuKg== dependencies: - joi "^17.1.1" uuid "^3.3.3" + yup "^0.32.9" ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" @@ -3176,11 +3096,11 @@ is-binary-path@~2.1.0: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" - integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" is-callable@^1.1.4, is-callable@^1.2.3: version "1.2.3" @@ -3195,16 +3115,16 @@ is-ci@^3.0.0: ci-info "^3.1.1" is-core-module@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.3.0.tgz#d341652e3408bca69c4671b79a0954a3d349f887" - integrity sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw== + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== is-extglob@^2.1.1: version "2.1.1" @@ -3222,9 +3142,9 @@ is-generator-fn@^2.0.0: integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-generator-function@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b" - integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== + version "1.0.9" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.9.tgz#e5f82c2323673e7fcad3d12858c83c4039f6399c" + integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" @@ -3247,9 +3167,9 @@ is-negative-zero@^2.0.1: integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-number-object@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== is-number@^7.0.0: version "7.0.0" @@ -3266,14 +3186,6 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-regex@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" - integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== - dependencies: - call-bind "^1.0.2" - has-symbols "^1.0.1" - is-regex@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" @@ -3292,22 +3204,17 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-string@^1.0.6: +is-string@^1.0.5, is-string@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: - has-symbols "^1.0.1" + has-symbols "^1.0.2" is-typed-array@^1.1.3: version "1.1.5" @@ -3381,84 +3288,84 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.2.tgz#997253042b4a032950fc5f56abf3c5d1f8560801" - integrity sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw== +jest-changed-files@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.6.tgz#bed6183fcdea8a285482e3b50a9a7712d49a7a8b" + integrity sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" execa "^5.0.0" throat "^6.0.1" -jest-circus@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.5.tgz#b5e327f1d6857c8485126f8e364aefa4378debaa" - integrity sha512-p5rO90o1RTh8LPOG6l0Fc9qgp5YGv+8M5CFixhMh7gGHtGSobD1AxX9cjFZujILgY8t30QZ7WVvxlnuG31r8TA== +jest-circus@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.6.tgz#dd4df17c4697db6a2c232aaad4e9cec666926668" + integrity sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q== dependencies: - "@jest/environment" "^27.0.5" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" - expect "^27.0.2" + expect "^27.0.6" is-generator-fn "^2.0.0" - jest-each "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-runtime "^27.0.5" - jest-snapshot "^27.0.5" - jest-util "^27.0.2" - pretty-format "^27.0.2" + jest-each "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" slash "^3.0.0" stack-utils "^2.0.3" throat "^6.0.1" -jest-cli@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.5.tgz#f359ba042624cffb96b713010a94bffb7498a37c" - integrity sha512-kZqY020QFOFQKVE2knFHirTBElw3/Q0kUbDc3nMfy/x+RQ7zUY89SUuzpHHJoSX1kX7Lq569ncvjNqU3Td/FCA== +jest-cli@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.6.tgz#d021e5f4d86d6a212450d4c7b86cb219f1e6864f" + integrity sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg== dependencies: - "@jest/core" "^27.0.5" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/core" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" - jest-config "^27.0.5" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-config "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" prompts "^2.0.1" yargs "^16.0.3" -jest-config@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.5.tgz#683da3b0d8237675c29c817f6e3aba1481028e19" - integrity sha512-zCUIXag7QIXKEVN4kUKbDBDi9Q53dV5o3eNhGqe+5zAbt1vLs4VE3ceWaYrOub0L4Y7E9pGfM84TX/0ARcE+Qw== +jest-config@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.6.tgz#119fb10f149ba63d9c50621baa4f1f179500277f" + integrity sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^27.0.5" - "@jest/types" "^27.0.2" - babel-jest "^27.0.5" + "@jest/test-sequencer" "^27.0.6" + "@jest/types" "^27.0.6" + babel-jest "^27.0.6" chalk "^4.0.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" is-ci "^3.0.0" - jest-circus "^27.0.5" - jest-environment-jsdom "^27.0.5" - jest-environment-node "^27.0.5" - jest-get-type "^27.0.1" - jest-jasmine2 "^27.0.5" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.5" - jest-runner "^27.0.5" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-circus "^27.0.6" + jest-environment-jsdom "^27.0.6" + jest-environment-node "^27.0.6" + jest-get-type "^27.0.6" + jest-jasmine2 "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-runner "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" micromatch "^4.0.4" - pretty-format "^27.0.2" + pretty-format "^27.0.6" jest-diff@^26.0.0: version "26.6.2" @@ -3470,152 +3377,152 @@ jest-diff@^26.0.0: jest-get-type "^26.3.0" pretty-format "^26.6.2" -jest-diff@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.2.tgz#f315b87cee5dc134cf42c2708ab27375cc3f5a7e" - integrity sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw== +jest-diff@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e" + integrity sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg== dependencies: chalk "^4.0.0" - diff-sequences "^27.0.1" - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + diff-sequences "^27.0.6" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" -jest-docblock@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.1.tgz#bd9752819b49fa4fab1a50b73eb58c653b962e8b" - integrity sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA== +jest-docblock@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3" + integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA== dependencies: detect-newline "^3.0.0" -jest-each@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.2.tgz#865ddb4367476ced752167926b656fa0dcecd8c7" - integrity sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ== +jest-each@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.6.tgz#cee117071b04060158dc8d9a66dc50ad40ef453b" + integrity sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" chalk "^4.0.0" - jest-get-type "^27.0.1" - jest-util "^27.0.2" - pretty-format "^27.0.2" + jest-get-type "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" -jest-environment-jsdom@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.5.tgz#c36771977cf4490a9216a70473b39161d193c212" - integrity sha512-ToWhViIoTl5738oRaajTMgYhdQL73UWPoV4GqHGk2DPhs+olv8OLq5KoQW8Yf+HtRao52XLqPWvl46dPI88PdA== +jest-environment-jsdom@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz#f66426c4c9950807d0a9f209c590ce544f73291f" + integrity sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw== dependencies: - "@jest/environment" "^27.0.5" - "@jest/fake-timers" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-mock "^27.0.6" + jest-util "^27.0.6" jsdom "^16.6.0" -jest-environment-node@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.5.tgz#b7238fc2b61ef2fb9563a3b7653a95fa009a6a54" - integrity sha512-47qqScV/WMVz5OKF5TWpAeQ1neZKqM3ySwNveEnLyd+yaE/KT6lSMx/0SOx60+ZUcVxPiESYS+Kt2JS9y4PpkQ== +jest-environment-node@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.6.tgz#a6699b7ceb52e8d68138b9808b0c404e505f3e07" + integrity sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w== dependencies: - "@jest/environment" "^27.0.5" - "@jest/fake-timers" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-mock "^27.0.6" + jest-util "^27.0.6" jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-get-type@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.1.tgz#34951e2b08c8801eb28559d7eb732b04bbcf7815" - integrity sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg== +jest-get-type@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe" + integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg== -jest-haste-map@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.5.tgz#2e1e55073b5328410a2c0d74b334e513d71f3470" - integrity sha512-3LFryGSHxwPFHzKIs6W0BGA2xr6g1MvzSjR3h3D8K8Uqy4vbRm/grpGHzbPtIbOPLC6wFoViRrNEmd116QWSkw== +jest-haste-map@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.6.tgz#4683a4e68f6ecaa74231679dca237279562c8dc7" + integrity sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/graceful-fs" "^4.1.2" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.4" - jest-regex-util "^27.0.1" - jest-serializer "^27.0.1" - jest-util "^27.0.2" - jest-worker "^27.0.2" + jest-regex-util "^27.0.6" + jest-serializer "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" micromatch "^4.0.4" walker "^1.0.7" optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.5.tgz#8a6eb2a685cdec3af13881145c77553e4e197776" - integrity sha512-m3TojR19sFmTn79QoaGy1nOHBcLvtLso6Zh7u+gYxZWGcza4rRPVqwk1hciA5ZOWWZIJOukAcore8JRX992FaA== +jest-jasmine2@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz#fd509a9ed3d92bd6edb68a779f4738b100655b37" + integrity sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.0.5" - "@jest/source-map" "^27.0.1" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^27.0.2" + expect "^27.0.6" is-generator-fn "^2.0.0" - jest-each "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-runtime "^27.0.5" - jest-snapshot "^27.0.5" - jest-util "^27.0.2" - pretty-format "^27.0.2" + jest-each "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" throat "^6.0.1" -jest-leak-detector@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz#ce19aa9dbcf7a72a9d58907a970427506f624e69" - integrity sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q== +jest-leak-detector@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz#545854275f85450d4ef4b8fe305ca2a26450450f" + integrity sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ== dependencies: - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" -jest-matcher-utils@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz#f14c060605a95a466cdc759acc546c6f4cbfc4f0" - integrity sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA== +jest-matcher-utils@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz#2a8da1e86c620b39459f4352eaa255f0d43e39a9" + integrity sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA== dependencies: chalk "^4.0.0" - jest-diff "^27.0.2" - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + jest-diff "^27.0.6" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" -jest-message-util@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.2.tgz#181c9b67dff504d8f4ad15cba10d8b80f272048c" - integrity sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw== +jest-message-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.6.tgz#158bcdf4785706492d164a39abca6a14da5ab8b5" + integrity sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.4" micromatch "^4.0.4" - pretty-format "^27.0.2" + pretty-format "^27.0.6" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.3.tgz#5591844f9192b3335c0dca38e8e45ed297d4d23d" - integrity sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q== +jest-mock@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.6.tgz#0efdd40851398307ba16778728f6d34d583e3467" + integrity sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -3623,76 +3530,76 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.1.tgz#69d4b1bf5b690faa3490113c47486ed85dd45b68" - integrity sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ== +jest-regex-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" + integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== -jest-resolve-dependencies@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.5.tgz#819ccdddd909c65acddb063aac3a49e4ba1ed569" - integrity sha512-xUj2dPoEEd59P+nuih4XwNa4nJ/zRd/g4rMvjHrZPEBWeWRq/aJnnM6mug+B+Nx+ILXGtfWHzQvh7TqNV/WbuA== +jest-resolve-dependencies@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz#3e619e0ef391c3ecfcf6ef4056207a3d2be3269f" + integrity sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA== dependencies: - "@jest/types" "^27.0.2" - jest-regex-util "^27.0.1" - jest-snapshot "^27.0.5" + "@jest/types" "^27.0.6" + jest-regex-util "^27.0.6" + jest-snapshot "^27.0.6" -jest-resolve@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.5.tgz#937535a5b481ad58e7121eaea46d1424a1e0c507" - integrity sha512-Md65pngRh8cRuWVdWznXBB5eDt391OJpdBaJMxfjfuXCvOhM3qQBtLMCMTykhuUKiBMmy5BhqCW7AVOKmPrW+Q== +jest-resolve@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.6.tgz#e90f436dd4f8fbf53f58a91c42344864f8e55bff" + integrity sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" chalk "^4.0.0" escalade "^3.1.1" graceful-fs "^4.2.4" jest-pnp-resolver "^1.2.2" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-util "^27.0.6" + jest-validate "^27.0.6" resolve "^1.20.0" slash "^3.0.0" -jest-runner@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.5.tgz#b6fdc587e1a5056339205914294555c554efc08a" - integrity sha512-HNhOtrhfKPArcECgBTcWOc+8OSL8GoFoa7RsHGnfZR1C1dFohxy9eLtpYBS+koybAHlJLZzNCx2Y/Ic3iEtJpQ== +jest-runner@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.6.tgz#1325f45055539222bbc7256a6976e993ad2f9520" + integrity sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ== dependencies: - "@jest/console" "^27.0.2" - "@jest/environment" "^27.0.5" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/environment" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-docblock "^27.0.1" - jest-environment-jsdom "^27.0.5" - jest-environment-node "^27.0.5" - jest-haste-map "^27.0.5" - jest-leak-detector "^27.0.2" - jest-message-util "^27.0.2" - jest-resolve "^27.0.5" - jest-runtime "^27.0.5" - jest-util "^27.0.2" - jest-worker "^27.0.2" + jest-docblock "^27.0.6" + jest-environment-jsdom "^27.0.6" + jest-environment-node "^27.0.6" + jest-haste-map "^27.0.6" + jest-leak-detector "^27.0.6" + jest-message-util "^27.0.6" + jest-resolve "^27.0.6" + jest-runtime "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" source-map-support "^0.5.6" throat "^6.0.1" -jest-runtime@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.5.tgz#cd5d1aa9754d30ddf9f13038b3cb7b95b46f552d" - integrity sha512-V/w/+VasowPESbmhXn5AsBGPfb35T7jZPGZybYTHxZdP7Gwaa+A0EXE6rx30DshHKA98lVCODbCO8KZpEW3hiQ== +jest-runtime@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.6.tgz#45877cfcd386afdd4f317def551fc369794c27c9" + integrity sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q== dependencies: - "@jest/console" "^27.0.2" - "@jest/environment" "^27.0.5" - "@jest/fake-timers" "^27.0.5" - "@jest/globals" "^27.0.5" - "@jest/source-map" "^27.0.1" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/globals" "^27.0.6" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/yargs" "^16.0.0" chalk "^4.0.0" cjs-module-lexer "^1.0.0" @@ -3700,30 +3607,30 @@ jest-runtime@^27.0.5: exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-haste-map "^27.0.5" - jest-message-util "^27.0.2" - jest-mock "^27.0.3" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.5" - jest-snapshot "^27.0.5" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-haste-map "^27.0.6" + jest-message-util "^27.0.6" + jest-mock "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" slash "^3.0.0" strip-bom "^4.0.0" yargs "^16.0.3" -jest-serializer@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.1.tgz#2464d04dcc33fb71dc80b7c82e3c5e8a08cb1020" - integrity sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ== +jest-serializer@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1" + integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA== dependencies: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.5.tgz#6e3b9e8e193685372baff771ba34af631fe4d4d5" - integrity sha512-H1yFYdgnL1vXvDqMrnDStH6yHFdMEuzYQYc71SnC/IJnuuhW6J16w8GWG1P+qGd3Ag3sQHjbRr0TcwEo/vGS+g== +jest-snapshot@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.6.tgz#f4e6b208bd2e92e888344d78f0f650bcff05a4bf" + integrity sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A== dependencies: "@babel/core" "^7.7.2" "@babel/generator" "^7.7.2" @@ -3731,60 +3638,60 @@ jest-snapshot@^27.0.5: "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.0.0" - "@jest/transform" "^27.0.5" - "@jest/types" "^27.0.2" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^27.0.2" + expect "^27.0.6" graceful-fs "^4.2.4" - jest-diff "^27.0.2" - jest-get-type "^27.0.1" - jest-haste-map "^27.0.5" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-resolve "^27.0.5" - jest-util "^27.0.2" + jest-diff "^27.0.6" + jest-get-type "^27.0.6" + jest-haste-map "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-resolve "^27.0.6" + jest-util "^27.0.6" natural-compare "^1.4.0" - pretty-format "^27.0.2" + pretty-format "^27.0.6" semver "^7.3.2" -jest-util@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.2.tgz#fc2c7ace3c75ae561cf1e5fdb643bf685a5be7c7" - integrity sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA== +jest-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.6.tgz#e8e04eec159de2f4d5f57f795df9cdc091e50297" + integrity sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" graceful-fs "^4.2.4" is-ci "^3.0.0" picomatch "^2.2.3" -jest-validate@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.2.tgz#7fe2c100089449cd5cbb47a5b0b6cb7cda5beee5" - integrity sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg== +jest-validate@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.6.tgz#930a527c7a951927df269f43b2dc23262457e2a6" + integrity sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^27.0.1" + jest-get-type "^27.0.6" leven "^3.1.0" - pretty-format "^27.0.2" + pretty-format "^27.0.6" -jest-watcher@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.2.tgz#dab5f9443e2d7f52597186480731a8c6335c5deb" - integrity sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA== +jest-watcher@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.6.tgz#89526f7f9edf1eac4e4be989bcb6dec6b8878d9c" + integrity sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ== dependencies: - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^27.0.2" + jest-util "^27.0.6" string-length "^4.0.1" jest-worker@27.0.0-next.5: @@ -3796,34 +3703,23 @@ jest-worker@27.0.0-next.5: merge-stream "^2.0.0" supports-color "^8.0.0" -jest-worker@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.2.tgz#4ebeb56cef48b3e7514552f80d0d80c0129f0b05" - integrity sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg== +jest-worker@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" + integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" jest@^27.0.5: - version "27.0.5" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.5.tgz#141825e105514a834cc8d6e44670509e8d74c5f2" - integrity sha512-4NlVMS29gE+JOZvgmSAsz3eOjkSsHqjTajlIsah/4MVSmKvf3zFP/TvgcLoWe2UVHiE9KF741sReqhF0p4mqbQ== + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.6.tgz#10517b2a628f0409087fbf473db44777d7a04505" + integrity sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA== dependencies: - "@jest/core" "^27.0.5" + "@jest/core" "^27.0.6" import-local "^3.0.2" - jest-cli "^27.0.5" - -joi@^17.1.1: - version "17.4.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20" - integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg== - dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.0" - "@sideway/formula" "^3.0.0" - "@sideway/pinpoint" "^2.0.0" + jest-cli "^27.0.6" jose@^1.27.2: version "1.28.1" @@ -4024,10 +3920,10 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libphonenumber-js@^1.9.17: - version "1.9.17" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.17.tgz#fef2e6fd7a981be69ba358c24495725ee8daf331" - integrity sha512-ElJki901OynMg1l+evooPH1VyHrECuLqpgc12z2BkK25dFU5lUKTuMHEYV2jXxvtns/PIuJax56cBeoSK7ANow== +libphonenumber-js@^1.9.19: + version "1.9.20" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.20.tgz#b9c84c56b3a574e4bf4323181b11f424deea1eca" + integrity sha512-fZw/XGE19SdRtcmAa5mEUjhGuFrVsT6x3V07TLt36psLbJnZiAdI0i/h4JSufKGXFCyreYM7gP98julXfO1XNA== lilconfig@^2.0.3: version "2.0.3" @@ -4089,6 +3985,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash-es@^4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -4159,7 +4060,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@^4.17.13, lodash@^4.17.21, lodash@^4.7.0: +lodash@^4.17.13, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4234,7 +4135,7 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== @@ -4268,9 +4169,9 @@ mimic-fn@^2.1.0: integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mini-svg-data-uri@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz#e16baa92ad55ddaa1c2c135759129f41910bc39f" - integrity sha512-zd6KCAyXgmq6FV1mR10oKXYtvmA9vRoB6xPSTUJTbFApCtkefDnYueVR1gkof3KcdLZo1Y8mjF2DFmQMIxsHNQ== + version "1.3.3" + resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.3.3.tgz#91d2c09f45e056e5e1043340b8b37ba7b50f4fac" + integrity sha512-+fA2oRcR1dJI/7ITmeQJDrYWks0wodlOz0pAEhKYJ2IVc1z0AnwJUsKY2fzFmPAM3Jo9J0rBx8JAA9QQSJ5PuA== minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" @@ -4333,12 +4234,12 @@ mz@^2.4.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nanoid@^3.1.22: - version "3.1.22" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" - integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== +nanoclone@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" + integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== -nanoid@^3.1.23: +nanoid@^3.1.22, nanoid@^3.1.23: version "3.1.23" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== @@ -4361,13 +4262,13 @@ neo-async@^2.6.0: integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== next-auth@^3.13.2: - version "3.19.8" - resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-3.19.8.tgz#32331f33dd73b46ec5c774735a9db78f9dbba3c7" - integrity sha512-BB3h3JedZrQ/usB5JFdJSxQcSsMopT8/RfboGAVIASfH7Lyu2PddZnlM1YlmqDZ90lHeFd2AfrxxCYX7HdDcKg== + version "3.27.1" + resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-3.27.1.tgz#8158b88516bb4dd0916b73c3809e7fca86ef370e" + integrity sha512-uTAVwKypvvsZA5SSfdjRmpL2ZPnXciGcOZVZ3IJPeRdUte/IZKckL7vAS+4pSr5euhn2E4OyJ1FecYutBz/WGw== dependencies: - "@next-auth/prisma-legacy-adapter" canary - "@next-auth/typeorm-legacy-adapter" canary - crypto-js "^4.0.0" + "@babel/runtime" "^7.14.0" + "@next-auth/prisma-legacy-adapter" "0.0.1-canary.127" + "@next-auth/typeorm-legacy-adapter" "0.0.2-canary.129" futoin-hkdf "^1.3.2" jose "^1.27.2" jsonwebtoken "^8.5.1" @@ -4377,35 +4278,33 @@ next-auth@^3.13.2: preact "^10.4.1" preact-render-to-string "^5.1.14" querystring "^0.2.0" - require_optional "^1.0.1" - typeorm "^0.2.30" next-transpile-modules@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/next-transpile-modules/-/next-transpile-modules-7.0.0.tgz#5a48988cede89bc5920defb15378093d0d8562eb" - integrity sha512-HgVczU5ajXKvE7HO3ZLmBmxXj79aq8jSZNYpCttim+MZ+b0GIsdk7AV2w7Ax/tIM1/dJA+vV/6loXCRYlbsGGA== + version "7.3.0" + resolved "https://registry.yarnpkg.com/next-transpile-modules/-/next-transpile-modules-7.3.0.tgz#088bfc2baeff7624991d4b510558c7a9d4a82d73" + integrity sha512-1iIiXEL/tyqd9LS3ge8nhPLgYByaFxLSBqbaQZZBedTgFVVnULrcdGDBVqWzivkcxDIqBpdeou+FKqo87IUyVw== dependencies: enhanced-resolve "^5.7.0" escalade "^3.1.1" next@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/next/-/next-10.2.0.tgz#6654cc925d8abcb15474fa062fc6b3ee527dd6dc" - integrity sha512-PKDKCSF7s82xudu3kQhOEaokxggpbLEWouEUtzP6OqV0YqKYHF+Ff+BFLycEem8ixtTM2M6ElN0VRJcskJfxPQ== + version "10.2.3" + resolved "https://registry.yarnpkg.com/next/-/next-10.2.3.tgz#5aa058a63626338cea91c198fda8f2715c058394" + integrity sha512-dkM1mIfnORtGyzw/Yme8RdqNxlCMZyi4Lqj56F01/yHbe1ZtOaJ0cyqqRB4RGiPhjGGh0319f8ddjDyO1605Ow== dependencies: "@babel/runtime" "7.12.5" - "@hapi/accept" "5.0.1" - "@next/env" "10.2.0" - "@next/polyfill-module" "10.2.0" - "@next/react-dev-overlay" "10.2.0" - "@next/react-refresh-utils" "10.2.0" + "@hapi/accept" "5.0.2" + "@next/env" "10.2.3" + "@next/polyfill-module" "10.2.3" + "@next/react-dev-overlay" "10.2.3" + "@next/react-refresh-utils" "10.2.3" "@opentelemetry/api" "0.14.0" assert "2.0.0" ast-types "0.13.2" browserify-zlib "0.2.0" - browserslist "4.16.1" + browserslist "4.16.6" buffer "5.6.0" - caniuse-lite "^1.0.30001179" + caniuse-lite "^1.0.30001228" chalk "2.4.2" chokidar "3.5.1" constants-browserify "1.0.0" @@ -4507,20 +4406,15 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-releases@^1.1.69, node-releases@^1.1.71: - version "1.1.71" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" - integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== +node-releases@^1.1.71: + version "1.1.73" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" + integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== -nodemailer@^6.4.16: - version "6.6.0" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.0.tgz#ed47bb572b48d9d0dca3913fdc156203f438f427" - integrity sha512-ikSMDU1nZqpo2WUPE0wTTw/NGGImTkwpJKDIFPZT+YvvR9Sj+ze5wzu95JHkBMglQLoG2ITxU21WukCC/XsFkg== - -nodemailer@^6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.1.tgz#2a05fbf205b897d71bf43884167b5d4d3bd01b99" - integrity sha512-1xzFN3gqv+/qJ6YRyxBxfTYstLNt0FCtZaFRvf4Sg9wxNGWbwFmGXVpfSi6ThGK6aRxAo+KjHtYSW8NvCsNSAg== +nodemailer@^6.4.16, nodemailer@^6.6.1: + version "6.6.2" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.2.tgz#e184c9ed5bee245a3e0bcabc7255866385757114" + integrity sha512-YSzu7TLbI+bsjCis/TZlAXBoM4y93HhlIgo0P5oiA2ua9Z4k+E2Fod//ybIzdJxOlXGRcHIh/WaeCBehvxZb/Q== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -4559,16 +4453,11 @@ object-hash@^2.2.0: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== -object-inspect@^1.10.3: +object-inspect@^1.10.3, object-inspect@^1.9.0: version "1.10.3" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== -object-inspect@^1.9.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.2.tgz#b6385a3e2b7cae0b5eafcf90cddf85d128767f30" - integrity sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA== - object-is@^1.0.1: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" @@ -4782,9 +4671,9 @@ path-key@^3.0.0, path-key@^3.1.0: integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^4.0.0: version "4.0.0" @@ -4803,9 +4692,9 @@ pbkdf2@^3.0.3: sha.js "^2.4.8" picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" - integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== pirates@^4.0.1: version "4.0.1" @@ -4815,9 +4704,9 @@ pirates@^4.0.1: node-modules-regexp "^1.0.0" pkce-challenge@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-2.1.0.tgz#90730f839b2ab00a8cbdd6e808bbaecc10e09b1c" - integrity sha512-ehrkzg1m5IBJGEAfePkd+nxBl9JrUC7dqkaL2q/BMsiADSRWSCapIEXlzr7rnfr1RtK6PACVJiE1USKm68QkrQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-2.2.0.tgz#02622e0498b82aab248c8c7dbf6507e8bbe20abf" + integrity sha512-Ly0Y0OwhtG2N1ynk5ruqoyJxkrWhAPmvdRk0teiLh9Dp2+J4URKpv1JSKWD0j1Sd+QCeiwO9lTl0EjmrB2jWeA== pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" @@ -4853,7 +4742,7 @@ postcss-js@^3.0.3: camelcase-css "^2.0.1" postcss "^8.1.6" -postcss-load-config@^3.0.1: +postcss-load-config@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.0.tgz#d39c47091c4aec37f50272373a6a648ef5e97829" integrity sha512-ipM8Ds01ZUophjDTQYSVP70slFSYg3T0/zyfII5vzhN6V57YSxMgG5syXuwi5VtS8wSf3iL30v0uBdoIVx4Q0g== @@ -4869,15 +4758,7 @@ postcss-nested@5.0.5: dependencies: postcss-selector-parser "^6.0.4" -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.5" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz#042d74e137db83e6f294712096cb413f5aa612c4" - integrity sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-selector-parser@^6.0.6: +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.6: version "6.0.6" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== @@ -4895,7 +4776,7 @@ postcss-value-parser@^4.1.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss@8.2.13, postcss@^8.1.6, postcss@^8.2.1: +postcss@8.2.13: version "8.2.13" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.13.tgz#dbe043e26e3c068e45113b1ed6375d2d37e2129f" integrity sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ== @@ -4904,7 +4785,7 @@ postcss@8.2.13, postcss@^8.1.6, postcss@^8.2.1: nanoid "^3.1.22" source-map "^0.6.1" -postcss@^8.2.8: +postcss@^8.1.6, postcss@^8.2.1, postcss@^8.2.8: version "8.3.5" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== @@ -4943,9 +4824,9 @@ prettier-linter-helpers@^1.0.0: fast-diff "^1.1.2" prettier@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" - integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" @@ -4957,12 +4838,12 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.2.tgz#9283ff8c4f581b186b2d4da461617143dca478a4" - integrity sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig== +pretty-format@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.6.tgz#ab770c47b2c6f893a21aefc57b75da63ef49a11f" + integrity sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" ansi-regex "^5.0.0" ansi-styles "^5.0.0" react-is "^17.0.1" @@ -4978,11 +4859,11 @@ pretty-hrtime@^1.0.3: integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= prisma@^2.23.0: - version "2.23.0" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-2.23.0.tgz#6464cca0e085ed23b1815013a67c868eff07a7d2" - integrity sha512-3c/lmDy8nsPcEsfCufvCTJUEuwmAcTPbeGg9fL1qjlvS314duLUA/k2nm3n1rq4ImKqzeC5uaKfvI2IoAfwrJA== + version "2.26.0" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-2.26.0.tgz#48f7b8fa166900ae20f2383da711ac8712a56b86" + integrity sha512-MXTQlF8X9mabkdTRb9x5nF6jvo1kT85d9hqIpYjLLZy+5tlvEaCaLBj+ok8GINdfYBS7gwQERZ9MHx0tb5dCdg== dependencies: - "@prisma/engines" "2.23.0-36.adf5e8cba3daf12d456d911d72b6e9418681b28b" + "@prisma/engines" "2.26.0-23.9b816b3aa13cc270074f172f30d6eda8a8ce867d" process-nextick-args@~2.0.0: version "2.0.1" @@ -5016,6 +4897,11 @@ prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, p object-assign "^4.1.1" react-is "^16.8.1" +property-expr@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.4.tgz#37b925478e58965031bb612ec5b3260f8241e910" + integrity sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg== + psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -5142,14 +5028,14 @@ react-is@^17.0.1: integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-phone-number-input@^3.1.21: - version "3.1.21" - resolved "https://registry.yarnpkg.com/react-phone-number-input/-/react-phone-number-input-3.1.21.tgz#7c6de442d9d2ebd6e757e93c6603698aa008e82b" - integrity sha512-Q1CS7RKFE+DyiZxEKrs00wf7geQ4qBJpOflCVNtTXnO0a2iXG42HFF7gtUpKQpro8THr7ejNy8H+zm2zD+EgvQ== + version "3.1.23" + resolved "https://registry.yarnpkg.com/react-phone-number-input/-/react-phone-number-input-3.1.23.tgz#8e8d2b7fb98d94514721d05ca5c58bd31f8d06e1" + integrity sha512-UuIRC4UIwjuC7itrLKH0slq7f6ZDulQt9TB6clPhoevYeu/0yB86bQLKoHaTWCxxY1rYUPGctzR1OzNgBngP/Q== dependencies: classnames "^2.2.5" country-flag-icons "^1.0.2" input-format "^0.3.6" - libphonenumber-js "^1.9.17" + libphonenumber-js "^1.9.19" prop-types "^15.7.2" react-refresh@0.8.3: @@ -5157,13 +5043,13 @@ react-refresh@0.8.3: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== -react-select@^4.2.1, react-select@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.0.tgz#6bde634ae7a378b49f3833c85c126f533483fa2e" - integrity sha512-SBPD1a3TJqE9zoI/jfOLCAoLr/neluaeokjOixr3zZ1vHezkom8K0A9J4QG9IWDqIDE9K/Mv+0y1GjidC2PDtQ== +react-select@^4.3.0, react-select@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.1.tgz#389fc07c9bc7cf7d3c377b7a05ea18cd7399cb81" + integrity sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q== dependencies: "@babel/runtime" "^7.12.0" - "@emotion/cache" "^11.0.0" + "@emotion/cache" "^11.4.0" "@emotion/react" "^11.1.1" memoize-one "^5.0.0" prop-types "^15.6.0" @@ -5171,18 +5057,18 @@ react-select@^4.2.1, react-select@^4.3.0: react-transition-group "^4.3.0" react-timezone-select@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/react-timezone-select/-/react-timezone-select-1.0.2.tgz#37e6d99bc15372bd3f9ebc7541bda6f3a10c852b" - integrity sha512-MDv4rmDkop3nZcIH27tLwIuIVovJE6ushmr9r0kR1SSzVErdydV01vI1ch8u4JAAFpnR5lYDt5PBqQW/lUS+Jg== + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-timezone-select/-/react-timezone-select-1.0.4.tgz#66664f508f927e9f9c0f051aea51fd3196534401" + integrity sha512-tb6wuXKm9djyJ4R6SqvTs7LdxHPHQBAAzL0qDvptPUHilR4ooClF7jwx3OVwg65Of22X/MbNv4xxIaax9PEKsA== dependencies: - react-select "^4.2.1" - spacetime "^6.14.0" + react-select "^4.3.1" + spacetime "^6.16.2" spacetime-informal "^0.6.1" react-transition-group@^4.3.0: - version "4.4.1" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" - integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== + version "4.4.2" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" + integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg== dependencies: "@babel/runtime" "^7.5.5" dom-helpers "^5.0.1" @@ -5226,6 +5112,13 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + reduce-css-calc@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" @@ -5546,10 +5439,10 @@ spacetime-informal@^0.6.1: dependencies: efrt-unpack "2.2.0" -spacetime@^6.14.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/spacetime/-/spacetime-6.16.0.tgz#f213963392eafc380716c3857b23251de87db97f" - integrity sha512-mkuniNOp6ssfPyJidj81tb54zKxK4vEKPTmcUsC/NEGIF8S07ppoSotdg6numT1/26rthQYmdxMY/M5a9WeJVQ== +spacetime@^6.16.2: + version "6.16.2" + resolved "https://registry.yarnpkg.com/spacetime/-/spacetime-6.16.2.tgz#f2e268a6f7b3f35ba822f513d34934a2569d791a" + integrity sha512-Oko/pwiYvkdoLSVjS1LcxkQ3FYIck5TbKttEpfulwdK4SzBB8m9z/S0kKu4HN+W2pHXZRFsiBXzwTtvB1IgfDA== sprintf-js@~1.0.2: version "1.0.3" @@ -5809,15 +5702,15 @@ table@^6.0.9: strip-ansi "^6.0.0" tailwindcss@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.2.2.tgz#28a99c87b5a6b2bf6298a77d88dc0590e84fa8ee" - integrity sha512-OzFWhlnfrO3JXZKHQiqZcb0Wwl3oJSmQ7PvT2jdIgCjV5iUoAyql9bb9ZLCSBI5TYXmawujXAoNxXVfP5Auy/Q== + version "2.2.4" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.2.4.tgz#6a2e259b1e26125aeaa7cdc479963fd217c308b0" + integrity sha512-OdBCPgazNNsknSP+JfrPzkay9aqKjhKtFhbhgxHgvEFdHy/GuRPo2SCJ4w1SFTN8H6FPI4m6qD/Jj20NWY1GkA== dependencies: "@fullhuman/postcss-purgecss" "^4.0.3" arg "^5.0.0" bytes "^3.0.0" chalk "^4.1.1" - chokidar "^3.5.1" + chokidar "^3.5.2" color "^3.1.3" cosmiconfig "^7.0.0" detective "^5.2.0" @@ -5835,7 +5728,7 @@ tailwindcss@^2.2.2: normalize-path "^3.0.0" object-hash "^2.2.0" postcss-js "^3.0.3" - postcss-load-config "^3.0.1" + postcss-load-config "^3.1.0" postcss-nested "5.0.5" postcss-selector-parser "^6.0.6" postcss-value-parser "^4.1.0" @@ -5937,6 +5830,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -5971,9 +5869,9 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== tsutils@^3.21.0: version "3.21.0" @@ -6034,9 +5932,9 @@ typedarray-to-buffer@^3.1.5: is-typedarray "^1.0.0" typeorm@^0.2.30: - version "0.2.32" - resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.32.tgz#544dbfdfe0cd0887548d9bcbd28527ea4f4b3c9b" - integrity sha512-LOBZKZ9As3f8KRMPCUT2H0JZbZfWfkcUnO3w/1BFAbL/X9+cADTF6bczDGGaKVENJ3P8SaKheKmBgpt5h1x+EQ== + version "0.2.34" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.34.tgz#637b3cec2de54ee7f423012b813a2022c0aacc8b" + integrity sha512-FZAeEGGdSGq7uTH3FWRQq67JjKu0mgANsSZ04j3kvDYNgy9KwBl/6RFgMVgiSgjf7Rqd7NrhC2KxVT7I80qf7w== dependencies: "@sqltools/formatter" "^1.2.2" app-root-path "^3.0.0" @@ -6057,16 +5955,16 @@ typeorm@^0.2.30: zen-observable-ts "^1.0.0" typescript@^4.2.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== + version "4.3.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc" + integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew== uglify-js@^3.1.4: - version "3.13.9" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.9.tgz#4d8d21dcd497f29cfd8e9378b9df123ad025999b" - integrity sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g== + version "3.13.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.10.tgz#a6bd0d28d38f592c3adb6b180ea6e07e1e540a8d" + integrity sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg== -unbox-primitive@^1.0.0, unbox-primitive@^1.0.1: +unbox-primitive@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== @@ -6130,7 +6028,7 @@ util@0.10.3: dependencies: inherits "2.0.1" -util@0.12.3, util@^0.12.0: +util@0.12.3: version "0.12.3" resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== @@ -6149,6 +6047,18 @@ util@^0.11.0: dependencies: inherits "2.0.3" +util@^0.12.0: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + uuid@^3.3.3: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -6244,9 +6154,9 @@ whatwg-url@^7.0.0: webidl-conversions "^4.0.2" whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.6.0.tgz#27c0205a4902084b872aecb97cf0f2a7a3011f4c" - integrity sha512-os0KkeeqUOl7ccdDT1qqUcS4KH4tcBTSKK5Nl5WKb2lyxInIZ/CpjkqKa1Ss12mjfdcRX9mHmPPs7/SxG1Hbdw== + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: lodash "^4.7.0" tr46 "^2.1.0" @@ -6327,9 +6237,9 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@^7.4.5: - version "7.5.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.0.tgz#0033bafea031fb9df041b2026fc72a571ca44691" - integrity sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw== + version "7.5.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.1.tgz#44fc000d87edb1d9c53e51fbc69a0ac1f6871d66" + integrity sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow== xml-name-validator@^3.0.0: version "3.0.0" @@ -6384,9 +6294,9 @@ yargonaut@^1.1.4: parent-require "^1.0.0" yargs-parser@^20.2.2: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs@^16.0.0, yargs@^16.0.3, yargs@^16.2.0: version "16.2.0" @@ -6406,6 +6316,19 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yup@^0.32.9: + version "0.32.9" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.9.tgz#9367bec6b1b0e39211ecbca598702e106019d872" + integrity sha512-Ci1qN+i2H0XpY7syDQ0k5zKQ/DoxO0LzPg8PAR/X4Mpj6DqaeCoIYEEjDJwhArh3Fa7GWbQQVDZKeXYlSH4JMg== + dependencies: + "@babel/runtime" "^7.10.5" + "@types/lodash" "^4.14.165" + lodash "^4.17.20" + lodash-es "^4.17.15" + nanoclone "^0.2.1" + property-expr "^2.0.4" + toposort "^2.0.2" + zen-observable-ts@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.0.0.tgz#30d1202b81d8ba4c489e3781e8ca09abf0075e70" From f7f5e2cc179bf7954824585299441d5ae9719b74 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 02:01:29 +0000 Subject: [PATCH 20/25] Re-instated ResetPasswordRequest, almost oops --- .../20210630014738_schedule_availability/migration.sql | 9 --------- prisma/schema.prisma | 7 +++++++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/prisma/migrations/20210630014738_schedule_availability/migration.sql b/prisma/migrations/20210630014738_schedule_availability/migration.sql index a5099595e9..a89bf58cf9 100644 --- a/prisma/migrations/20210630014738_schedule_availability/migration.sql +++ b/prisma/migrations/20210630014738_schedule_availability/migration.sql @@ -1,15 +1,6 @@ -/* - Warnings: - - - You are about to drop the `ResetPasswordRequest` table. If the table is not empty, all the data it contains will be lost. - -*/ -- AlterTable ALTER TABLE "EventType" ADD COLUMN "timeZone" TEXT; --- DropTable -DROP TABLE "ResetPasswordRequest"; - -- CreateTable CREATE TABLE "Availability" ( "id" SERIAL NOT NULL, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1e8f8efb6e..ddaf7d8133 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -160,3 +160,10 @@ model EventTypeCustomInput { required Boolean } +model ResetPasswordRequest { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + email String + expires DateTime +} From 9fe11ea10d34cc00a383e49d239da721d822bc89 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 02:41:22 +0000 Subject: [PATCH 21/25] Make sure the currently selected date is active --- components/booking/DatePicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/booking/DatePicker.tsx b/components/booking/DatePicker.tsx index 0e02940c51..86fda25922 100644 --- a/components/booking/DatePicker.tsx +++ b/components/booking/DatePicker.tsx @@ -92,7 +92,7 @@ const DatePicker = ({ weekStart, onDatePicked, workingHours, organizerTimeZone, )), ]); - }, [selectedMonth, inviteeTimeZone]); + }, [selectedMonth, inviteeTimeZone, selectedDate]); return selectedMonth ? (
    From bfc7cce6888382b5bbccc04b316d15b5bc11deba Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 15:27:49 +0000 Subject: [PATCH 22/25] Make sure the slots equal the month and date of the invitee so we can check isSame with freebusy --- components/booking/Slots.tsx | 8 +++++--- lib/slots.ts | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/components/booking/Slots.tsx b/components/booking/Slots.tsx index 3c689d5c38..8f92aaeb14 100644 --- a/components/booking/Slots.tsx +++ b/components/booking/Slots.tsx @@ -54,12 +54,11 @@ const Slots = ({ eventLength, minimumBookingNotice, date, workingHours, organize // Check for conflicts for (let i = times.length - 1; i >= 0; i -= 1) { - busyTimes.forEach((busyTime) => { + busyTimes.every((busyTime): boolean => { const startTime = dayjs(busyTime.start).utc(); const endTime = dayjs(busyTime.end).utc(); - // Check if start times are the same - if (times[i].utc().format("HH:mm") == startTime.format("HH:mm")) { + if (times[i].utc().isSame(startTime)) { times.splice(i, 1); } // Check if time is between start and end times @@ -73,7 +72,10 @@ const Slots = ({ eventLength, minimumBookingNotice, date, workingHours, organize // Check if startTime is between slot else if (startTime.isBetween(times[i].utc(), times[i].utc().add(eventLength, "minutes"))) { times.splice(i, 1); + } else { + return true; } + return false; }); } diff --git a/lib/slots.ts b/lib/slots.ts index 35d06a65a1..5beeb9f8af 100644 --- a/lib/slots.ts +++ b/lib/slots.ts @@ -126,7 +126,9 @@ const getSlots = ({ organizerBoundaries(workingHours, inviteeDate, inviteeBounds, organizerTimeZone) ) .reduce((slots, boundary: Boundary) => [...slots, ...getSlotsBetweenBoundary(frequency, boundary)], []) - .map((slot) => slot.utcOffset(dayjs(inviteeDate).utcOffset())); + .map((slot) => + slot.month(inviteeDate.month()).date(inviteeDate.date()).utcOffset(inviteeDate.utcOffset()) + ); }; export default getSlots; From a28cb455f16e8814d83e076dd640111d7d399136 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 30 Jun 2021 15:41:38 +0000 Subject: [PATCH 23/25] Fixed bug that kept the date enabled when the time slot was less than 30m --- components/booking/DatePicker.tsx | 11 +++++++++-- pages/[user]/[type].tsx | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/components/booking/DatePicker.tsx b/components/booking/DatePicker.tsx index 86fda25922..1bea6caf65 100644 --- a/components/booking/DatePicker.tsx +++ b/components/booking/DatePicker.tsx @@ -7,7 +7,14 @@ import getSlots from "@lib/slots"; dayjs.extend(utc); dayjs.extend(timezone); -const DatePicker = ({ weekStart, onDatePicked, workingHours, organizerTimeZone, inviteeTimeZone }) => { +const DatePicker = ({ + weekStart, + onDatePicked, + workingHours, + organizerTimeZone, + inviteeTimeZone, + eventLength, +}) => { const [calendar, setCalendar] = useState([]); const [selectedMonth, setSelectedMonth]: number = useState(); const [selectedDate, setSelectedDate]: Dayjs = useState(); @@ -43,7 +50,7 @@ const DatePicker = ({ weekStart, onDatePicked, workingHours, organizerTimeZone, date.endOf("day").isBefore(dayjs().tz(inviteeTimeZone)) || !getSlots({ inviteeDate: date, - frequency: 30, + frequency: eventLength, workingHours, organizerTimeZone, }).length diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index 1a8b670a6b..e56ed4c609 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -128,6 +128,7 @@ export default function Type(props): Type { workingHours={props.workingHours} organizerTimeZone={props.eventType.timeZone || props.user.timeZone} inviteeTimeZone={timeZone()} + eventLength={props.eventType.length} /> {selectedDate && ( Date: Wed, 30 Jun 2021 15:56:06 +0000 Subject: [PATCH 24/25] If no availability set, default to user prefs --- pages/[user]/[type].tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pages/[user]/[type].tsx b/pages/[user]/[type].tsx index e56ed4c609..fd81a9c516 100644 --- a/pages/[user]/[type].tsx +++ b/pages/[user]/[type].tsx @@ -148,14 +148,6 @@ export default function Type(props): Type { ); } -interface WorkingHours { - days: number[]; - startTime: number; - length: number; -} - -type Availability = WorkingHours; - export const getServerSideProps: GetServerSideProps = async (context) => { const user = await prisma.user.findFirst({ where: { @@ -212,16 +204,16 @@ export const getServerSideProps: GetServerSideProps = async (context) => { ? providesAvailability.availability : null; - const workingHours: WorkingHours[] = + const workingHours: [] = getWorkingHours(eventType) || getWorkingHours(user) || [ { days: [0, 1, 2, 3, 4, 5, 6], startTime: user.startTime, - length: user.endTime, + endTime: user.endTime, }, - ].filter((availability: Availability): boolean => typeof availability["days"] !== "undefined"); + ].filter((availability): boolean => typeof availability["days"] !== "undefined"); return { props: { From a7173a32a038f390b553de41fa98a1d6d4c081e3 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Thu, 1 Jul 2021 10:31:38 +0000 Subject: [PATCH 25/25] Updated booking link to proper username --- components/booking/AvailableTimes.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/components/booking/AvailableTimes.tsx b/components/booking/AvailableTimes.tsx index 6745ddc52b..bfa4a0cfd3 100644 --- a/components/booking/AvailableTimes.tsx +++ b/components/booking/AvailableTimes.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; import { useRouter } from "next/router"; import Slots from "./Slots"; -import {ExclamationIcon} from "@heroicons/react/solid"; +import { ExclamationIcon } from "@heroicons/react/solid"; const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeFormat, user }) => { const router = useRouter(); @@ -12,12 +12,12 @@ const AvailableTimes = ({ date, eventLength, eventTypeId, workingHours, timeForm
    {date.format("dddd DD MMMM YYYY")}
    - {slots.length > 0 && ( + {slots.length > 0 && slots.map((slot) => ( - )) + ))} + {isFullyBooked && ( +
    +

    {user.name} is all booked today.

    +
    )} - {isFullyBooked &&
    -

    {user.name} is all booked today.

    -
    } {!isFullyBooked && slots.length === 0 && !hasErrors &&
    }