diff --git a/.vscode/settings.json b/.vscode/settings.json index 9009717..dcde473 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,5 +10,6 @@ "**/.yarn": true, "**/.pnp.*": true }, - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.preferences.importModuleSpecifier": "non-relative" } diff --git a/packages/api/handlers/update-guild.ts b/packages/api/handlers/update-guild.ts new file mode 100644 index 0000000..dc9c309 --- /dev/null +++ b/packages/api/handlers/update-guild.ts @@ -0,0 +1,38 @@ +import { GuildDataUpdate, SessionData, UserGuildPermissions } from '@roleypoly/types'; +import { withSession } from '../utils/api-tools'; +import { getGuildData } from '../utils/guild'; +import { GuildData } from '../utils/kv'; +import { lowPermissions, missingParameters, notFound, ok } from '../utils/responses'; + +export const UpdateGuild = withSession( + (session: SessionData) => async (request: Request): Promise => { + const url = new URL(request.url); + const [, , guildID] = url.pathname.split('/'); + if (!guildID) { + return missingParameters(); + } + + const guildUpdate = (await request.json()) as GuildDataUpdate; + + const guild = session.guilds.find((guild) => guild.id === guildID); + if (!guild) { + return notFound(); + } + + if ( + guild?.permissionLevel !== UserGuildPermissions.Manager && + guild?.permissionLevel !== UserGuildPermissions.Admin + ) { + return lowPermissions(); + } + + const newGuildData = { + ...(await getGuildData(guildID)), + ...guildUpdate, + }; + + await GuildData.put(guildID, newGuildData); + + return ok(); + } +); diff --git a/packages/design-system/atoms/halfsies/Halfsies.tsx b/packages/design-system/atoms/halfsies/Halfsies.tsx index 2727722..864ba8d 100644 --- a/packages/design-system/atoms/halfsies/Halfsies.tsx +++ b/packages/design-system/atoms/halfsies/Halfsies.tsx @@ -1,13 +1,6 @@ import { onTablet } from '@roleypoly/design-system/atoms/breakpoints'; import styled, { css } from 'styled-components'; -export const HalfsiesContainer = styled.div` - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: center; -`; - export const HalfsiesItem = styled.div` box-sizing: border-box; flex: 1 1 100%; @@ -15,3 +8,16 @@ export const HalfsiesItem = styled.div` flex: 1 2 50%; `)} `; + +export const HalfsiesContainer = styled.div<{ center?: boolean }>` + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + + ${({ center }) => + center && + css` + align-content: center; + `} +`; diff --git a/packages/design-system/atoms/tab-view/TabView.styled.ts b/packages/design-system/atoms/tab-view/TabView.styled.ts index e5901d3..4a88799 100644 --- a/packages/design-system/atoms/tab-view/TabView.styled.ts +++ b/packages/design-system/atoms/tab-view/TabView.styled.ts @@ -22,8 +22,9 @@ export const TabTitleRow = styled.div` position: fixed; ${onSmallScreen( css` + width: fit-content; position: unset; - max-width: 100vw; + max-width: 98vw; ` )} `; diff --git a/packages/design-system/atoms/tab-view/TabView.tsx b/packages/design-system/atoms/tab-view/TabView.tsx index 1edd199..01803fe 100644 --- a/packages/design-system/atoms/tab-view/TabView.tsx +++ b/packages/design-system/atoms/tab-view/TabView.tsx @@ -10,6 +10,7 @@ import { export type TabViewProps = { children: React.ReactNode[]; initialTab?: number; + masthead?: React.ReactNode; }; type TabProps = { @@ -39,6 +40,7 @@ export const TabView = (props: TabViewProps) => { return ( + {props.masthead && props.masthead} void; + onReset: () => void; + showSaveReset: boolean; +}; + +const MastheadContainer = styled.div` + display: flex; + flex: 1; + align-items: center; + justify-content: start; + padding-bottom: 0.5em; + ${Text} { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + margin-left: 0.5em; + } + + ${onSmallScreen(css` + display: none; + `)} +`; + +export const EditorMasthead = (props: EditorMastheadProps) => ( + + + {avatarUtils.initialsFromName(props.guild.guild.name)} + + Server Editor + +); diff --git a/packages/design-system/molecules/editor-masthead/index.ts b/packages/design-system/molecules/editor-masthead/index.ts new file mode 100644 index 0000000..1ddc31d --- /dev/null +++ b/packages/design-system/molecules/editor-masthead/index.ts @@ -0,0 +1 @@ +export * from './EditorMasthead'; diff --git a/packages/design-system/molecules/reset-submit/ResetSubmit.stories.tsx b/packages/design-system/molecules/reset-submit/ResetSubmit.stories.tsx index 3879f5b..8d6ecd1 100644 --- a/packages/design-system/molecules/reset-submit/ResetSubmit.stories.tsx +++ b/packages/design-system/molecules/reset-submit/ResetSubmit.stories.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; -import { ResetSubmit } from './ResetSubmit'; +import { InlineResetSubmit, ResetSubmit } from './ResetSubmit'; export default { - title: 'Molecules', + title: 'Molecules/Reset and Submit', component: ResetSubmit, }; -export const ResetAndSubmit = (args) => ; +export const normal = (args) => ; +export const inline = (args) => ; diff --git a/packages/design-system/molecules/reset-submit/ResetSubmit.styled.ts b/packages/design-system/molecules/reset-submit/ResetSubmit.styled.ts deleted file mode 100644 index 215ca73..0000000 --- a/packages/design-system/molecules/reset-submit/ResetSubmit.styled.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { onSmallScreen } from '@roleypoly/design-system/atoms/breakpoints'; -import styled from 'styled-components'; - -export const Buttons = styled.div` - display: flex; - flex-wrap: wrap; -`; - -export const Left = styled.div` - flex: 0; - ${onSmallScreen` - flex: 1 1 100%; - order: 2; - `} -`; - -export const Right = styled.div` - flex: 1; -`; diff --git a/packages/design-system/molecules/reset-submit/ResetSubmit.tsx b/packages/design-system/molecules/reset-submit/ResetSubmit.tsx index d044efa..d94af3b 100644 --- a/packages/design-system/molecules/reset-submit/ResetSubmit.tsx +++ b/packages/design-system/molecules/reset-submit/ResetSubmit.tsx @@ -2,7 +2,7 @@ import { onSmallScreen } from '@roleypoly/design-system/atoms/breakpoints'; import { Button } from '@roleypoly/design-system/atoms/button'; import * as React from 'react'; import { MdRestore } from 'react-icons/md'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; type Props = { onSubmit: () => void; @@ -22,8 +22,14 @@ const Left = styled.div` `} `; -const Right = styled.div` +const Right = styled.div<{ inline?: boolean }>` flex: 1; + + ${(props) => + props.inline && + css` + padding-left: 0.2em; + `} `; export const ResetSubmit = (props: Props) => { @@ -40,3 +46,20 @@ export const ResetSubmit = (props: Props) => { ); }; + +export const InlineResetSubmit = (props: Props) => { + return ( + + + + + + + + + ); +}; diff --git a/packages/design-system/organisms/editor-shell/EditorShell.tsx b/packages/design-system/organisms/editor-shell/EditorShell.tsx index 1398037..2fa3222 100644 --- a/packages/design-system/organisms/editor-shell/EditorShell.tsx +++ b/packages/design-system/organisms/editor-shell/EditorShell.tsx @@ -1,7 +1,10 @@ +import { Space } from '@roleypoly/design-system/atoms/space'; import { Tab, TabView } from '@roleypoly/design-system/atoms/tab-view'; +import { EditorMasthead } from '@roleypoly/design-system/molecules/editor-masthead'; import { EditorCategoriesTab } from '@roleypoly/design-system/organisms/editor-categories-tab'; import { EditorDetailsTab } from '@roleypoly/design-system/organisms/editor-details-tab'; import { Category, PresentableGuild } from '@roleypoly/types'; +import deepEqual from 'deep-equal'; import React from 'react'; export type EditorShellProps = { @@ -34,23 +37,35 @@ export const EditorShell = (props: EditorShellProps) => { }); }; + const hasChanges = React.useMemo(() => !deepEqual(guild.data, props.guild.data), [ + guild.data, + props.guild.data, + ]); + return ( - - - {() => ( - - )} - - - {() => ( - - )} - - {() =>
hi2!
}
-
+
+ + }> + + {() => ( + + )} + + + {() => ( + + )} + + {() =>
hi2!
}
+
+
); }; diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 8cb1f6f..a0d46a9 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -8,6 +8,7 @@ "dependencies": { "@roleypoly/types": "*", "chroma-js": "^2.1.2", + "deep-equal": "^2.0.5", "isomorphic-unfetch": "^3.1.0", "ksuid": "^2.0.0", "lodash": "^4.17.21", @@ -30,6 +31,7 @@ "@storybook/react": "^6.3.2", "@storybook/theming": "^6.3.2", "@types/chroma-js": "^2.1.3", + "@types/deep-equal": "^1.0.1", "@types/node": "^15.12.5", "@types/react": "^17.0.11", "@types/react-custom-scrollbars": "^4.0.7", diff --git a/packages/design-system/templates/editor/Editor.stories.tsx b/packages/design-system/templates/editor/Editor.stories.tsx new file mode 100644 index 0000000..ef1c966 --- /dev/null +++ b/packages/design-system/templates/editor/Editor.stories.tsx @@ -0,0 +1,13 @@ +import { guildEnum, mastheadSlugs, user } from '../../fixtures/storyData'; +import { EditorTemplate } from './Editor'; +export default { + title: 'Templates/Server Editor', + component: EditorTemplate, + args: { + guilds: mastheadSlugs, + user: user, + guild: guildEnum.guilds[0], + }, +}; + +export const serverEditor = (args) => ; diff --git a/packages/design-system/templates/editor/Editor.tsx b/packages/design-system/templates/editor/Editor.tsx new file mode 100644 index 0000000..a412108 --- /dev/null +++ b/packages/design-system/templates/editor/Editor.tsx @@ -0,0 +1,22 @@ +import { AppShell, AppShellProps } from '@roleypoly/design-system/organisms/app-shell'; +import { + EditorShell, + EditorShellProps, +} from '@roleypoly/design-system/organisms/editor-shell'; + +export const EditorTemplate = ( + props: EditorShellProps & Omit +) => { + const { + guild, + onCategoryChange, + onMessageChange, + onGuildChange, + ...appShellProps + } = props; + return ( + + + + ); +}; diff --git a/packages/design-system/templates/editor/index.ts b/packages/design-system/templates/editor/index.ts new file mode 100644 index 0000000..8b7c4c2 --- /dev/null +++ b/packages/design-system/templates/editor/index.ts @@ -0,0 +1 @@ +export * from './Editor'; diff --git a/packages/types/Guild.ts b/packages/types/Guild.ts index 383c09a..9561be7 100644 --- a/packages/types/Guild.ts +++ b/packages/types/Guild.ts @@ -22,6 +22,8 @@ export type GuildData = { features: Features; }; +export type GuildDataUpdate = Omit, 'id'>; + export type PresentableGuild = { id: string; guild: GuildSlug; diff --git a/packages/web/src/app-router/AppRouter.tsx b/packages/web/src/app-router/AppRouter.tsx index 118f2e4..0d947a0 100644 --- a/packages/web/src/app-router/AppRouter.tsx +++ b/packages/web/src/app-router/AppRouter.tsx @@ -7,6 +7,7 @@ import LandingPage from '../pages/landing'; import PickerPage from '../pages/picker'; const ServersPage = React.lazy(() => import('../pages/servers')); +const EditorPage = React.lazy(() => import('../pages/editor')); const MachineryNewSession = React.lazy(() => import('../pages/machinery/new-session')); const MachineryLogout = React.lazy(() => import('../pages/machinery/logout')); @@ -32,6 +33,7 @@ export const AppRouter = () => { + diff --git a/packages/web/src/pages/editor.tsx b/packages/web/src/pages/editor.tsx new file mode 100644 index 0000000..52a884e --- /dev/null +++ b/packages/web/src/pages/editor.tsx @@ -0,0 +1,100 @@ +import { Redirect } from '@reach/router'; +import { EditorTemplate } from '@roleypoly/design-system/templates/editor'; +import { GenericLoadingTemplate } from '@roleypoly/design-system/templates/generic-loading'; +import { + GuildDataUpdate, + PresentableGuild, + UserGuildPermissions, +} from '@roleypoly/types'; +import * as React from 'react'; +import { useAppShellProps } from '../contexts/app-shell/AppShellContext'; +import { useRecentGuilds } from '../contexts/recent-guilds/RecentGuildsContext'; +import { useSessionContext } from '../contexts/session/SessionContext'; +import { Title } from '../utils/metaTitle'; + +type EditorProps = { + serverID: string; + path: string; +}; + +const Editor = (props: EditorProps) => { + const { serverID } = props; + const { session, authedFetch, isAuthenticated } = useSessionContext(); + const { pushRecentGuild } = useRecentGuilds(); + const appShellProps = useAppShellProps(); + + const [guild, setGuild] = React.useState(null); + const [pending, setPending] = React.useState(false); + + React.useEffect(() => { + const fetchGuild = async () => { + const response = await authedFetch(`/get-picker-data/${serverID}`); + const data = await response.json(); + + if (response.status !== 200) { + setGuild(false); + return; + } + + setGuild(data); + }; + + fetchGuild(); + }, [serverID, authedFetch]); + + React.useCallback((serverID) => pushRecentGuild(serverID), [pushRecentGuild])(serverID); + + // If the user is not authenticated, redirect to the login page. + if (!isAuthenticated) { + return ; + } + + // If the user is not an admin, they can't edit the guild + // so we redirect them to the picker + const guildSlug = session?.guilds?.find((guild) => guild.id === serverID); + if (guildSlug && guildSlug?.permissionLevel === UserGuildPermissions.User) { + return ; + } + + // If the guild isn't loaded, render a loading placeholder + if (guild === null) { + return ; + } + + // If the guild is not found, redirect to the picker page + if (guild === false) { + return ; + } + + const onGuildChange = async (guild: PresentableGuild) => { + if (pending) { + return; + } + + setPending(true); + + const updatePayload: GuildDataUpdate = { + message: guild.data.message, + categories: guild.data.categories, + }; + + const response = await authedFetch(`/update-guild/${serverID}`, { + method: 'PATCH', + body: JSON.stringify(updatePayload), + }); + + if (response.status === 200) { + setGuild(guild); + setPending(false); + } + }; + + return ( + <> + + <EditorTemplate {...appShellProps} guild={guild} onGuildChange={onGuildChange} /> + </> + ); +}; + +export default Editor; diff --git a/tsconfig.json b/tsconfig.json index 725c723..cc23a2a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,7 +22,10 @@ "forceConsistentCasingInFileNames": true, "noEmit": true, "resolveJsonModule": true, - "isolatedModules": true + "isolatedModules": true, + "paths": { + "@roleypoly/*": ["./packages/*"] + } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], "exclude": ["node_modules", "**/*.stories.tsx", "packages/api"] diff --git a/yarn.lock b/yarn.lock index c5365b3..95d8105 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3390,6 +3390,11 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/deep-equal@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03" + integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg== + "@types/enzyme@^3.10.8": version "3.10.8" resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.8.tgz#ad7ac9d3af3de6fd0673773123fafbc63db50d42" @@ -4647,6 +4652,11 @@ autoprefixer@^9.6.1, autoprefixer@^9.8.6: postcss "^7.0.32" postcss-value-parser "^4.1.0" +available-typed-arrays@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" + integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -6629,6 +6639,27 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" +deep-equal@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.5.tgz#55cd2fe326d83f9cbf7261ef0e060b3f724c5cb9" + integrity sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw== + dependencies: + call-bind "^1.0.0" + es-get-iterator "^1.1.1" + get-intrinsic "^1.0.1" + is-arguments "^1.0.4" + is-date-object "^1.0.2" + is-regex "^1.1.1" + isarray "^2.0.5" + object-is "^1.1.4" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.3.0" + side-channel "^1.0.3" + which-boxed-primitive "^1.0.1" + which-collection "^1.0.1" + which-typed-array "^1.1.2" + 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" @@ -7341,6 +7372,20 @@ es-get-iterator@^1.0.2: is-string "^1.0.5" isarray "^2.0.5" +es-get-iterator@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.0" + has-symbols "^1.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.5" + isarray "^2.0.5" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -8135,6 +8180,11 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -8352,7 +8402,7 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: +get-intrinsic@^1.0.1, get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -9322,6 +9372,13 @@ is-arguments@^1.0.4: resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== +is-arguments@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -9425,6 +9482,11 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== +is-date-object@^1.0.2: + 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-decimal@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" @@ -9546,6 +9608,11 @@ is-map@^2.0.1: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw== +is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" @@ -9642,6 +9709,14 @@ is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.2: call-bind "^1.0.2" has-symbols "^1.0.1" +is-regex@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.2" + is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -9667,6 +9742,11 @@ is-set@^2.0.1: resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43" integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA== +is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -9701,6 +9781,17 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.1" +is-typed-array@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" + foreach "^2.0.5" + has-symbols "^1.0.1" + is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -9711,6 +9802,16 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakset@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" + integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw== + is-whitespace-character@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" @@ -11936,7 +12037,7 @@ object-inspect@^1.7.0, object-inspect@^1.8.0, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== -object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2: +object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2, object-is@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -17008,11 +17109,34 @@ which-boxed-primitive@^1.0.1: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +which-typed-array@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" + foreach "^2.0.5" + function-bind "^1.1.1" + has-symbols "^1.0.1" + is-typed-array "^1.1.3" + which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"