diff --git a/.dockerignore b/.dockerignore index 1e10d15..868663b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,3 +10,11 @@ cloudbuild.yaml cloudbuild-pr.yaml ./kubernetes .env* +clean-local-database.sh +run-cloud.sh +.prettierrc +./db +.editorconfig +docker-compose* +./.github +./.next \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0daf454..588492d 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ yarn-debug.log* yarn-error.log* # local env files +.env .env.local .env.development.local .env.test.local diff --git a/Dockerfile b/Dockerfile index 2dad939..506e4b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,9 @@ FROM node:alpine AS builder RUN apk add --no-cache libc6-compat WORKDIR /app -COPY . . +COPY package.json yarn.lock ./ RUN yarn +COPY . . RUN yarn build FROM node:alpine @@ -16,6 +17,7 @@ EXPOSE 3000 COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/.next ./.next +COPY --from=builder /app/postgraphile.tags.json5 ./postgraphile.tags.json5 RUN npx next telemetry disable -CMD ["node_modules/.bin/next", "start"] \ No newline at end of file +CMD ["node_modules/.bin/next", "start"] diff --git a/README.md b/README.md index f355ed4..b2efff9 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Contributions for the following are very welcome. - [ ] Edit Links - [x] Redirect Links - [x] Auth + - [x] Can be disabled - [x] Powered by Auth0 - [x] Security - [x] Row Level Security using Auth0 Roles and Permissions @@ -43,6 +44,7 @@ Contributions for the following are very welcome. - [x] Graph: Usage of last 14 days - [ ] Link Ownership - [ ] Link Parameters +- [ ] Link Groups (Folders) - [ ] Private Links - [ ] Temporary Links - [ ] Random Alias @@ -103,6 +105,7 @@ export GOOGLE_CLOUD_REGION= export CLOUDSQL_INSTANCE_NAME= export HOSTNAME=https://go.mydomain.com export LOGONAME=golinks +export AUHT0_ENABLED=true export AUTH0_DOMAIN= export AUTH0_AUDIENCE= export AUTH0_COOKIE_DOMAIN=go.mydomain.com @@ -136,6 +139,12 @@ kubectl apply -f ./kubernetes/istio/destination-rule.yaml This app leverages [Auth0](https://auth0.com) as an Identity provider. Auth0 is used to manage users and their permissions to access and modify data in this application. +### Enable Auth0 + +To enable, make sure you set the `AUTH0_ENABLED` env var as `true`. + +In case this is set to `false`, every other environment variable prefixed with `AUTH0_` can be considered optional. + ### Configuring Auth0 > In the future, these steps will be automated through the Auth0 Provider for Terraform. @@ -193,10 +202,9 @@ GraphQL Type definitions are generated on application startup during development `graphql-let` then is used to generate type definitions in Typescript for development use. -### Local Database with watch mode: +### Local Database without Auth0 in Watch mode: -For development, we use the official `postgres` docker image. This image comes with a feature that initializes the database when provided a folder with scripts. -When started without a volume setup, the image will execute all the `.sql` scripts in the `./database` folder. +For development, we use the official `postgres` docker image. Migrations need to be ran manually using `dbmate` and the SQL scripts provided. Start the database: @@ -204,7 +212,46 @@ Start the database: docker-compose up -d db ``` -Prepare the project and run in development mode: +Run the migrations using [`dbmate`](https://github.com/amacneil/dbmate): + +```sh +export DATABASE_URL=postgres://dev:dev@127.0.0.1:5432/golinks?sslmode=disable +dbmate up +``` + +Regenerate the `./lib/type-defs.graphqls` with: + +```sh +npx postgraphile \ + --connection 'postgres://dev:dev@localhost:5432/golinks' \ + --schema public \ + --export-schema-graphql ./lib/type-defs.graphqls \ + --subscriptions \ + --dynamic-json \ + --no-setof-functions-contain-nulls \ + --no-ignore-rbac \ + --no-ignore-indexes \ + --show-error-stack=json \ + --extended-errors hint,detail,errcode \ + --append-plugins @graphile-contrib/pg-simplify-inflector \ + --enable-query-batching \ + --legacy-relations omit \ + --no-server +``` + +Create an `.env.local` file (with auth0 disabled): + +```sh +cat > ./.env.local < ./.env.local < AUTH0_AUDIENCE= AUTH0_CLIENT_ID= @@ -237,7 +285,7 @@ docker-compose up Access http://localhost:3000 -### Locally, with docker and cloud sql db: +### Locally, with docker, cloud sql db and Auth0: ```sh # Environment Variables for the Application @@ -245,6 +293,7 @@ cat > ./.env.cloud <:@db:5432/golinks DATABASE_SCHEMA=public NODE_ENV=production +AUTH0_ENABLED=true AUTH0_DOMAIN= AUTH0_AUDIENCE= AUTH0_CLIENT_ID= diff --git a/components/LinkCards/index.tsx b/components/LinkCards/index.tsx new file mode 100644 index 0000000..3310e5a --- /dev/null +++ b/components/LinkCards/index.tsx @@ -0,0 +1,103 @@ +import { + Box, + Label, + Text, + Link as FannyLink, + Button, + Set, + Icon, + Stack, + Card, +} from 'bumbag'; +import { GetAllLinksQuery } from '../../lib/queries/getAllLinks.graphql'; +import { LinkMetricUsageGraph } from '../LinkMetricUsageGraph'; + +interface Props { + data: GetAllLinksQuery; + isDeleteEnabled: boolean; + isEditEnabled: boolean; + onDelete: (linkId: string) => void | Promise; + onShare: (linkUrl: string) => void | Promise; + onAnalytics: (linkId: string) => void | Promise; + onEdit: (linkId: string) => void | Promise; + isDeleting: boolean; +} + +export const LinkCards: React.FC = ({ + data, + isDeleteEnabled, + // isEditEnabled, + onDelete, + // onEdit, + onShare, + // onAnalytics, + isDeleting, +}) => { + const links = data?.links; + + if (links?.nodes.length === 0) { + return ( + + There are no golinks available. + + ); + } + + return ( + + {links?.nodes.map((link) => { + return ( + + + {isDeleteEnabled && ( + + )} + + }> + + + + {link.url} + + + + + + + + + ); + })} + + ); +}; + +export default LinkCards; diff --git a/components/CreateLinkForm/index.tsx b/components/LinkForm/index.tsx similarity index 52% rename from components/CreateLinkForm/index.tsx rename to components/LinkForm/index.tsx index 8a20c27..e0fe774 100644 --- a/components/CreateLinkForm/index.tsx +++ b/components/LinkForm/index.tsx @@ -1,4 +1,4 @@ -import { Link, FieldStack, Button, InputField } from 'bumbag'; +import { Link, InputField } from 'bumbag'; import * as Yup from 'yup'; import { Formik, Form, Field, FormikHelpers } from 'formik'; @@ -22,39 +22,46 @@ interface Props { values: Link, helpers: FormikHelpers ) => void | Promise; + initialValues?: Link; } -export const CreateLinkForm: React.FC = ({ onSubmit }) => { +export const Fields = () => { + return ( + <> + + + + + ); +}; + +export const FormWrapper: React.FC = ({ + onSubmit, + children, + initialValues = { + alias: '', + url: '', + }, +}) => { return ( { onSubmit(values, form); }} validationSchema={CreateLinkSchema} - initialValues={{ - alias: '', - url: '', - }}> -
- - - - - - - -
+ initialValues={initialValues}> +
{children}
); }; diff --git a/components/LinkMetricUsageGraph/index.tsx b/components/LinkMetricUsageGraph/index.tsx new file mode 100644 index 0000000..fd36332 --- /dev/null +++ b/components/LinkMetricUsageGraph/index.tsx @@ -0,0 +1,121 @@ +import { Box, Text, useTheme } from 'bumbag'; +import { + Sparkline, + LineSeries, + VerticalReferenceLine, + PatternLines, + WithTooltip, + PointSeries, + // @ts-ignore +} from '@data-ui/sparkline'; +import { compareAsc, eachDayOfInterval, sub } from 'date-fns'; +import { formatWithOptions } from 'date-fns/fp'; +import { nl } from 'date-fns/locale'; +import { LinkUsageMetric } from '../../lib/queries/getAllLinks.graphql'; + +interface Props { + linkUsageMetrics: Pick[]; +} + +const dateToString = formatWithOptions({ locale: nl }, 'dd/MM/yyyy'); + +interface Datum { + count: number; + date: string; +} + +const convertMetricsToLineChartData = ( + linkUsageMetrics: Pick[] +) => { + const now = new Date(); + const days = eachDayOfInterval({ + end: now, + start: sub(now, { + days: 31, + }), + }); + + const dates = [ + ...linkUsageMetrics.map((metric) => new Date(metric.accessedAt)), + ...days, + ].sort(compareAsc); + + const countPerDate = dates.map(dateToString).reduce((acc, date) => { + const accCount = acc[date]?.count; + const count = accCount === undefined ? 0 : accCount + 1; + + return { + ...acc, + [date]: { + date, + count, + }, + }; + }, {} as Record); + + return Object.values(countPerDate); +}; + +const Tooltip: React.FC<{ datum: Datum }> = ({ datum }) => ( + + Date: {datum.date} +
+ Usage: {datum.count} +
+); + +export const LinkMetricUsageGraph: React.FC = ({ + linkUsageMetrics, +}) => { + const { theme } = useTheme(); + const data = convertMetricsToLineChartData(linkUsageMetrics); + + return ( + + {/* @ts-ignore */} + {({ onMouseMove, onMouseLeave, tooltipData }) => ( + datum.count} + onMouseLeave={onMouseLeave} + onMouseMove={onMouseMove}> + + + {tooltipData && [ + , + , + ]} + + )} + + ); +}; diff --git a/components/LinkTable/index.tsx b/components/LinkTable/index.tsx index a00961c..2ba7696 100644 --- a/components/LinkTable/index.tsx +++ b/components/LinkTable/index.tsx @@ -7,14 +7,8 @@ import { DropdownMenu, Icon, } from 'bumbag'; -import { Sparklines, SparklinesLine } from 'react-sparklines'; -import { compareAsc, eachDayOfInterval, sub } from 'date-fns'; -import { formatWithOptions } from 'date-fns/fp'; -import { nl } from 'date-fns/locale'; -import { - GetAllLinksQuery, - LinkUsageMetric, -} from '../../lib/queries/getAllLinks.graphql'; +import { GetAllLinksQuery } from '../../lib/queries/getAllLinks.graphql'; +import { LinkMetricUsageGraph } from '../LinkMetricUsageGraph'; interface Props { data: GetAllLinksQuery; @@ -26,34 +20,6 @@ interface Props { onEdit: (linkId: string) => void | Promise; } -const dateToString = formatWithOptions({ locale: nl }, 'dd/MM/yyyy'); - -const convertMetricsToLineChartData = ( - linkUsageMetrics: Pick[] -) => { - const days = eachDayOfInterval({ - end: new Date(), - start: sub(new Date(), { - days: 14, - }), - }); - - const dates = [ - ...linkUsageMetrics.map((metric) => new Date(metric.accessedAt)), - ...days, - ].sort(compareAsc); - - const countPerDate = dates.map(dateToString).reduce( - (acc, date) => ({ - ...acc, - [date]: (acc[date] || 0) + 1, - }), - {} as Record - ); - - return Object.values(countPerDate); -}; - export const LinkTable: React.FC = ({ data, isDeleteEnabled, @@ -74,13 +40,16 @@ export const LinkTable: React.FC = ({ } return ( - +
Alias Destination - Usage (14 days) + Month Usage + + + Total Usage Actions @@ -104,20 +73,12 @@ export const LinkTable: React.FC = ({ - - - -
- - Total Usage: {link.linkUsageMetrics.totalCount} - + +
+ + {link.linkUsageMetrics.totalCount} = ({
); }; + +export default LinkTable; diff --git a/components/TopNavigation/index.tsx b/components/TopNavigation/index.tsx new file mode 100644 index 0000000..6f4d0ae --- /dev/null +++ b/components/TopNavigation/index.tsx @@ -0,0 +1,48 @@ +import { TopNav, Heading, Button } from 'bumbag'; + +interface Props { + hostname: string; + logoname: string; + isAuthenticated: boolean; + isAuthEnabled: boolean; +} + +export const TopNavigation: React.FC = ({ + hostname, + logoname, + isAuthenticated, + isAuthEnabled, +}) => { + return ( + + + + {logoname} + + + {isAuthEnabled && ( + + + {isAuthenticated ? ( + + ) : ( + + )} + + + )} + + ); +}; diff --git a/database/1-tables.sql b/database/1-tables.sql deleted file mode 100644 index 6d05941..0000000 --- a/database/1-tables.sql +++ /dev/null @@ -1,29 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - -DROP TABLE IF EXISTS public.links CASCADE; -CREATE TABLE public.links ( - id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), - alias VARCHAR ( 50 ) UNIQUE NOT NULL, - url VARCHAR ( 255 ) NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT NOW() -); - -comment on table public.links is 'A link alias posted by an user.'; -comment on column public.links.id is 'The id for a link alias.'; -comment on column public.links.alias is 'The alias for an url. It must be unique.'; -comment on column public.links.url is 'The link alias url.'; -comment on column public.links.created_at is 'The time this link alias was created.'; - -DROP TABLE IF EXISTS public.link_usage_metrics CASCADE; -CREATE TABLE public.link_usage_metrics ( - id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), - link_id uuid NOT NULL REFERENCES public.links ON DELETE CASCADE, - accessed_at TIMESTAMP NOT NULL DEFAULT NOW() -); - -CREATE INDEX ON public.link_usage_metrics (link_id); - -comment on table public.link_usage_metrics is 'A link usage metric posted by the application when a link is accessed.'; -comment on column public.link_usage_metrics.id is 'The id for this metric record.'; -comment on column public.link_usage_metrics.link_id is 'The id of the link being accessed.'; -comment on column public.link_usage_metrics.accessed_at is 'The time this link was accessed.'; diff --git a/database/2-roles.sql b/database/2-roles.sql deleted file mode 100644 index 456b21f..0000000 --- a/database/2-roles.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE ROLE postgraphile; \ No newline at end of file diff --git a/db/migrations/20200927095515_add_extensions.sql b/db/migrations/20200927095515_add_extensions.sql new file mode 100644 index 0000000..49508d9 --- /dev/null +++ b/db/migrations/20200927095515_add_extensions.sql @@ -0,0 +1,5 @@ +-- migrate:up +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +-- migrate:down +DROP EXTENSION "uuid-ossp"; \ No newline at end of file diff --git a/db/migrations/20200927100445_create_links_table.sql b/db/migrations/20200927100445_create_links_table.sql new file mode 100644 index 0000000..46449bb --- /dev/null +++ b/db/migrations/20200927100445_create_links_table.sql @@ -0,0 +1,16 @@ +-- migrate:up +CREATE TABLE public.links ( + id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + alias VARCHAR ( 50 ) UNIQUE NOT NULL, + url VARCHAR ( 255 ) NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT NOW() +); + +comment on table public.links is 'A link alias posted by an user.'; +comment on column public.links.id is 'The id for a link alias.'; +comment on column public.links.alias is 'The alias for an url. It must be unique.'; +comment on column public.links.url is 'The link alias url.'; +comment on column public.links.created_at is 'The time this link alias was created.'; + +-- migrate:down +DROP TABLE public.links CASCADE; \ No newline at end of file diff --git a/db/migrations/20200927100527_create_link_usage_metrics_table.sql b/db/migrations/20200927100527_create_link_usage_metrics_table.sql new file mode 100644 index 0000000..7dd82e5 --- /dev/null +++ b/db/migrations/20200927100527_create_link_usage_metrics_table.sql @@ -0,0 +1,16 @@ +-- migrate:up +CREATE TABLE public.link_usage_metrics ( + id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), + link_id uuid NOT NULL REFERENCES public.links ON DELETE CASCADE, + accessed_at TIMESTAMP NOT NULL DEFAULT NOW() +); + +CREATE INDEX ON public.link_usage_metrics (link_id); + +comment on table public.link_usage_metrics is 'A link usage metric posted by the application when a link is accessed.'; +comment on column public.link_usage_metrics.id is 'The id for this metric record.'; +comment on column public.link_usage_metrics.link_id is 'The id of the link being accessed.'; +comment on column public.link_usage_metrics.accessed_at is 'The time this link was accessed.'; + +-- migrate:down +DROP TABLE public.link_usage_metrics CASCADE; diff --git a/db/migrations/20200927100605_create_postgraphile_role.sql b/db/migrations/20200927100605_create_postgraphile_role.sql new file mode 100644 index 0000000..a7bb494 --- /dev/null +++ b/db/migrations/20200927100605_create_postgraphile_role.sql @@ -0,0 +1,5 @@ +-- migrate:up +CREATE ROLE postgraphile; + +-- migrate:down +DROP ROLE postgraphile; \ No newline at end of file diff --git a/database/3-functions.sql b/db/migrations/20200927100655_create_permission_functions.sql similarity index 75% rename from database/3-functions.sql rename to db/migrations/20200927100655_create_permission_functions.sql index 71d65bd..f1be561 100644 --- a/database/3-functions.sql +++ b/db/migrations/20200927100655_create_permission_functions.sql @@ -1,3 +1,4 @@ +-- migrate:up create function get_current_permissions() returns json as $$ select nullif(current_setting('jwt.claims.permissions', true), '[]')::json; $$ language sql stable SECURITY DEFINER; @@ -10,4 +11,8 @@ create function has_permission(permission text) returns boolean as $$ select count(claims.permissions) > 0 from claims where claims.permissions::jsonb ? permission; -$$ language sql stable SECURITY DEFINER; \ No newline at end of file +$$ language sql stable SECURITY DEFINER; + +-- migrate:down +DROP FUNCTION get_current_permissions; +DROP FUNCTION has_permission; diff --git a/database/4-policies.sql b/db/migrations/20200927100746_create_links_policies.sql similarity index 57% rename from database/4-policies.sql rename to db/migrations/20200927100746_create_links_policies.sql index 9d54bef..b00f5ab 100644 --- a/database/4-policies.sql +++ b/db/migrations/20200927100746_create_links_policies.sql @@ -1,3 +1,4 @@ +-- migrate:up CREATE POLICY read_links ON public.links FOR SELECT @@ -31,26 +32,13 @@ CREATE POLICY delete_links ALTER TABLE public.links ENABLE ROW LEVEL SECURITY; ALTER TABLE public.links FORCE ROW LEVEL SECURITY; - GRANT ALL ON public.links TO postgraphile; -CREATE POLICY read_link_metric - ON public.link_usage_metrics - FOR SELECT - USING ( - has_permission('read:golinks') - ); - -CREATE POLICY create_link_metric - ON public.link_usage_metrics - FOR INSERT - WITH CHECK ( - has_permission('read:golinks') - ); - -ALTER TABLE public.link_usage_metrics ENABLE ROW LEVEL SECURITY; -ALTER TABLE public.link_usage_metrics FORCE ROW LEVEL SECURITY; - -GRANT ALL ON public.link_usage_metrics TO postgraphile; +-- migrate:down +DROP POLICY read_links ON public.links; +DROP POLICY update_links ON public.links; +DROP POLICY create_links ON public.links; +DROP POLICY delete_links ON public.links; -GRANT ALL on schema public TO postgraphile; \ No newline at end of file +ALTER TABLE IF EXISTS public.links DISABLE ROW LEVEL SECURITY; +REVOKE ALL ON public.links FROM postgraphile; \ No newline at end of file diff --git a/db/migrations/20200927101112_create_link_usage_metrics_policies.sql b/db/migrations/20200927101112_create_link_usage_metrics_policies.sql new file mode 100644 index 0000000..1723d53 --- /dev/null +++ b/db/migrations/20200927101112_create_link_usage_metrics_policies.sql @@ -0,0 +1,25 @@ +-- migrate:up +CREATE POLICY read_link_usage_metric + ON public.link_usage_metrics + FOR SELECT + USING ( + has_permission('read:golinks') + ); + +CREATE POLICY create_link_usage_metric + ON public.link_usage_metrics + FOR INSERT + WITH CHECK ( + has_permission('read:golinks') + ); + +ALTER TABLE public.link_usage_metrics ENABLE ROW LEVEL SECURITY; +ALTER TABLE public.link_usage_metrics FORCE ROW LEVEL SECURITY; +GRANT ALL ON public.link_usage_metrics TO postgraphile; + +-- migrate:down +DROP POLICY read_link_usage_metric ON public.link_usage_metrics; +DROP POLICY create_link_usage_metric ON public.link_usage_metrics; + +ALTER TABLE IF EXISTS public.link_usage_metrics DISABLE ROW LEVEL SECURITY; +REVOKE ALL ON public.link_usage_metrics FROM postgraphile; \ No newline at end of file diff --git a/db/migrations/20200927101300_grant_all_public_to_postgraphile.sql b/db/migrations/20200927101300_grant_all_public_to_postgraphile.sql new file mode 100644 index 0000000..5488377 --- /dev/null +++ b/db/migrations/20200927101300_grant_all_public_to_postgraphile.sql @@ -0,0 +1,5 @@ +-- migrate:up +GRANT ALL on schema public TO postgraphile; + +-- migrate:down +REVOKE ALL on schema public FROM postgraphile; diff --git a/db/migrations/20200927232549_add_default_links.sql b/db/migrations/20200927232549_add_default_links.sql new file mode 100644 index 0000000..5e7fe0c --- /dev/null +++ b/db/migrations/20200927232549_add_default_links.sql @@ -0,0 +1,16 @@ +-- migrate:up +set local jwt.claims.permissions to '["create:golinks", "read:golinks"]'; + +-- add insert statements for default links +-- INSERT INTO public.links (id, alias, url, created_at) VALUES ('8f31a121-31af-4e2c-a3be-08bb9274723b', 'github', 'https://github.com/armand1m', '2020-07-28 11:39:06.892521'); + +-- add insert statements for link usage metrics if needed +-- INSERT INTO public.link_usage_metrics (id, link_id, accessed_at) VALUES ('6eb89582-04f8-41ea-9284-bc07c8456304', '8f31a121-31af-4e2c-a3be-08bb9274723b', '2020-08-30 09:24:03.869824'); +-- INSERT INTO public.link_usage_metrics (id, link_id, accessed_at) VALUES ('15891bc1-b807-48b8-ba95-6b809df3ca4e', '8f31a121-31af-4e2c-a3be-08bb9274723b', '2020-08-30 21:24:49.138064'); +-- INSERT INTO public.link_usage_metrics (id, link_id, accessed_at) VALUES ('996c6cc5-3c00-4ce3-9c90-a0d319f07a2f', '8f31a121-31af-4e2c-a3be-08bb9274723b', '2020-08-31 15:38:30.985529'); + +-- migrate:down +set local jwt.claims.permissions to '["delete:golinks", "read:golinks"]'; + +DELETE FROM public.links; +DELETE FROM public.link_usage_metrics; \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql new file mode 100644 index 0000000..cd4ce76 --- /dev/null +++ b/db/schema.sql @@ -0,0 +1,276 @@ +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +-- +-- Name: uuid-ossp; Type: EXTENSION; Schema: -; Owner: - +-- + +CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public; + + +-- +-- Name: EXTENSION "uuid-ossp"; Type: COMMENT; Schema: -; Owner: - +-- + +COMMENT ON EXTENSION "uuid-ossp" IS 'generate universally unique identifiers (UUIDs)'; + + +-- +-- Name: get_current_permissions(); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.get_current_permissions() RETURNS json + LANGUAGE sql STABLE SECURITY DEFINER + AS $$ + select nullif(current_setting('jwt.claims.permissions', true), '[]')::json; +$$; + + +-- +-- Name: has_permission(text); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.has_permission(permission text) RETURNS boolean + LANGUAGE sql STABLE SECURITY DEFINER + AS $$ + with claims as ( + select + get_current_permissions() as permissions + ) + select count(claims.permissions) > 0 + from claims + where claims.permissions::jsonb ? permission; +$$; + + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: link_usage_metrics; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.link_usage_metrics ( + id uuid DEFAULT public.uuid_generate_v4() NOT NULL, + link_id uuid NOT NULL, + accessed_at timestamp without time zone DEFAULT now() NOT NULL +); + +ALTER TABLE ONLY public.link_usage_metrics FORCE ROW LEVEL SECURITY; + + +-- +-- Name: TABLE link_usage_metrics; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON TABLE public.link_usage_metrics IS 'A link usage metric posted by the application when a link is accessed.'; + + +-- +-- Name: COLUMN link_usage_metrics.id; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.link_usage_metrics.id IS 'The id for this metric record.'; + + +-- +-- Name: COLUMN link_usage_metrics.link_id; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.link_usage_metrics.link_id IS 'The id of the link being accessed.'; + + +-- +-- Name: COLUMN link_usage_metrics.accessed_at; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.link_usage_metrics.accessed_at IS 'The time this link was accessed.'; + + +-- +-- Name: links; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.links ( + id uuid DEFAULT public.uuid_generate_v4() NOT NULL, + alias character varying(50) NOT NULL, + url character varying(255) NOT NULL, + created_at timestamp without time zone DEFAULT now() NOT NULL +); + +ALTER TABLE ONLY public.links FORCE ROW LEVEL SECURITY; + + +-- +-- Name: TABLE links; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON TABLE public.links IS 'A link alias posted by an user.'; + + +-- +-- Name: COLUMN links.id; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.links.id IS 'The id for a link alias.'; + + +-- +-- Name: COLUMN links.alias; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.links.alias IS 'The alias for an url. It must be unique.'; + + +-- +-- Name: COLUMN links.url; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.links.url IS 'The link alias url.'; + + +-- +-- Name: COLUMN links.created_at; Type: COMMENT; Schema: public; Owner: - +-- + +COMMENT ON COLUMN public.links.created_at IS 'The time this link alias was created.'; + + +-- +-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.schema_migrations ( + version character varying(255) NOT NULL +); + + +-- +-- Name: link_usage_metrics link_usage_metrics_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.link_usage_metrics + ADD CONSTRAINT link_usage_metrics_pkey PRIMARY KEY (id); + + +-- +-- Name: links links_alias_key; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.links + ADD CONSTRAINT links_alias_key UNIQUE (alias); + + +-- +-- Name: links links_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.links + ADD CONSTRAINT links_pkey PRIMARY KEY (id); + + +-- +-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.schema_migrations + ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); + + +-- +-- Name: link_usage_metrics_link_id_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX link_usage_metrics_link_id_idx ON public.link_usage_metrics USING btree (link_id); + + +-- +-- Name: link_usage_metrics link_usage_metrics_link_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.link_usage_metrics + ADD CONSTRAINT link_usage_metrics_link_id_fkey FOREIGN KEY (link_id) REFERENCES public.links(id) ON DELETE CASCADE; + + +-- +-- Name: link_usage_metrics create_link_usage_metric; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY create_link_usage_metric ON public.link_usage_metrics FOR INSERT WITH CHECK (public.has_permission('read:golinks'::text)); + + +-- +-- Name: links create_links; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY create_links ON public.links FOR INSERT WITH CHECK (public.has_permission('create:golinks'::text)); + + +-- +-- Name: links delete_links; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY delete_links ON public.links FOR DELETE USING (public.has_permission('delete:golinks'::text)); + + +-- +-- Name: link_usage_metrics; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.link_usage_metrics ENABLE ROW LEVEL SECURITY; + +-- +-- Name: links; Type: ROW SECURITY; Schema: public; Owner: - +-- + +ALTER TABLE public.links ENABLE ROW LEVEL SECURITY; + +-- +-- Name: link_usage_metrics read_link_usage_metric; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY read_link_usage_metric ON public.link_usage_metrics FOR SELECT USING (public.has_permission('read:golinks'::text)); + + +-- +-- Name: links read_links; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY read_links ON public.links FOR SELECT USING (public.has_permission('read:golinks'::text)); + + +-- +-- Name: links update_links; Type: POLICY; Schema: public; Owner: - +-- + +CREATE POLICY update_links ON public.links FOR UPDATE USING (public.has_permission('update:golinks'::text)) WITH CHECK (public.has_permission('update:golinks'::text)); + + +-- +-- PostgreSQL database dump complete +-- + + +-- +-- Dbmate schema migrations +-- + +INSERT INTO public.schema_migrations (version) VALUES + ('20200927095515'), + ('20200927100445'), + ('20200927100527'), + ('20200927100605'), + ('20200927100655'), + ('20200927100746'), + ('20200927101112'), + ('20200927101300'), + ('20200927232549'); diff --git a/docker-compose.yml b/docker-compose.yml index d9ee713..22ba06e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,10 +24,6 @@ services: - overlay volumes: - db-data:/var/lib/postgresql/data - - ./database/1-tables.sql:/docker-entrypoint-initdb.d/1-tables.sql - - ./database/2-roles.sql:/docker-entrypoint-initdb.d/2-roles.sql - - ./database/3-functions.sql:/docker-entrypoint-initdb.d/3-functions.sql - - ./database/4-policies.sql:/docker-entrypoint-initdb.d/4-policies.sql ports: - 5432:5432/tcp diff --git a/kubernetes/deployment.yaml b/kubernetes/deployment.yaml index 337f59e..4d6d025 100644 --- a/kubernetes/deployment.yaml +++ b/kubernetes/deployment.yaml @@ -40,7 +40,9 @@ spec: - name: HOSTNAME value: ${HOSTNAME} - name: LOGONAME - value: ${LOGONAME} + value: ${LOGONAME} + - name: AUTH0_ENABLED + value: ${AUTH0_ENABLED} - name: AUTH0_DOMAIN value: ${AUTH0_DOMAIN} - name: AUTH0_AUDIENCE diff --git a/lib/auth.ts b/lib/auth.ts index 4096d87..bd0b420 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -1,29 +1,12 @@ +import { NextApiRequest } from 'next'; import { promisify } from 'util'; import jsonwebtoken from 'jsonwebtoken'; import jwksRsa from 'jwks-rsa'; import { initAuth0 } from '@auth0/nextjs-auth0'; import { ISession } from '@auth0/nextjs-auth0/dist/session/session'; - -const ANONYMOUS_PERMISSIONS = ['read:golinks']; -const ANONYMOUS_ROLES = ['viewer']; - -const DOMAIN = String(process.env.AUTH0_DOMAIN); -const AUDIENCE = String(process.env.AUTH0_AUDIENCE); -const CLIENT_ID = String(process.env.AUTH0_CLIENT_ID); -const CLIENT_SECRET = String(process.env.AUTH0_CLIENT_SECRET); -const COOKIE_DOMAIN = String(process.env.AUTH0_COOKIE_DOMAIN); -const COOKIE_SECRET = String(process.env.AUTH0_COOKIE_SECRET); -const REDIRECT_URL = String(process.env.AUTH0_REDIRECT_URL); -const POST_LOGOUT_REDIRECT_URL = String( - process.env.AUTH0_POST_LOGOUT_REDIRECT_URL -); - -const jwksSecretClient = jwksRsa({ - cache: true, - rateLimit: true, - jwksRequestsPerMinute: 5, - jwksUri: `https://${DOMAIN}/.well-known/jwks.json`, -}); +import { ISignInWithAuth0 } from '@auth0/nextjs-auth0/dist/instance'; +import { Config } from './config'; +import { UserRole, UserPermission } from './permissions'; interface JwtHeader { kid: string; @@ -52,13 +35,18 @@ interface DecodedJwtToken { } export const getPermissionsFromSession = async ( - session?: ISession | null + session: ISession ) => { - if (!session || !session.accessToken) { - return { - permissions: ANONYMOUS_PERMISSIONS, - roles: ANONYMOUS_ROLES, - }; + if (!Config.auth0) { + throw new Error( + "Missing Auth0 parameters. Make sure you've passed correctly all environment variables." + ); + } + + if (!session.accessToken) { + throw new Error( + 'Session is missing an access token. This is an issue with your auth provider.' + ); } const decodedAccessToken = jsonwebtoken.decode( @@ -70,6 +58,13 @@ export const getPermissionsFromSession = async ( throw new Error('Failed to decode token.'); } + const jwksSecretClient = jwksRsa({ + cache: true, + rateLimit: true, + jwksRequestsPerMinute: 5, + jwksUri: `https://${Config.auth0.domain}/.well-known/jwks.json`, + }); + const signingKey = await promisify(jwksSecretClient.getSigningKey)( decodedAccessToken.header.kid ); @@ -78,8 +73,8 @@ export const getPermissionsFromSession = async ( session.accessToken, signingKey.getPublicKey(), { - audience: AUDIENCE, - issuer: new URL(`https://${DOMAIN}`).href, + audience: Config.auth0.audience, + issuer: new URL(`https://${Config.auth0.domain}`).href, algorithms: ['RS256'], } ); @@ -93,35 +88,83 @@ export const getPermissionsFromSession = async ( const jwtToken = token as DecodedJwtToken; return { - permissions: jwtToken.permissions || ANONYMOUS_PERMISSIONS, - roles: jwtToken['https://user/roles'] || ANONYMOUS_ROLES, + permissions: + (jwtToken.permissions as UserPermission[]) || + Config.anonymous.permissions, + roles: + (jwtToken['https://user/roles'] as UserRole[]) || + Config.anonymous.roles, }; }; -export const auth0 = initAuth0({ - domain: DOMAIN, - clientId: CLIENT_ID, - audience: AUDIENCE, - clientSecret: CLIENT_SECRET, - scope: 'openid email profile', - redirectUri: REDIRECT_URL, - postLogoutRedirectUri: POST_LOGOUT_REDIRECT_URL, - session: { - cookieSecret: COOKIE_SECRET, - cookieLifetime: 60 * 60 * 8, - cookieDomain: - process.env.NODE_ENV === 'development' - ? 'localhost' - : COOKIE_DOMAIN, - cookieSameSite: 'lax', - storeIdToken: true, - storeAccessToken: true, - storeRefreshToken: true, - }, - oidcClient: { - httpTimeout: 2500, - clockTolerance: 10000, - }, -}); +export const getUserClaimsFromRequest = async ( + request: NextApiRequest +) => { + if (!Config.features.auth0) { + return { + claims: Config.anonymous, + user: null, + }; + } + + const auth0 = getAuth0(); + const session = await auth0.getSession(request); + + if (!session || !session.accessToken) { + return { + claims: Config.anonymous, + user: null, + }; + } + + const claims = await getPermissionsFromSession(session); + + return { + claims, + user: session.user, + }; +}; + +export let auth0: ISignInWithAuth0 | undefined; + +export const getAuth0 = () => { + if (!Config.features.auth0 || !Config.auth0) { + throw new Error( + 'Auth0 is trying to be instantiated with missing environment variables.' + ); + } + + if (auth0) { + return auth0; + } + + auth0 = initAuth0({ + domain: Config.auth0.domain, + clientId: Config.auth0.clientId, + audience: Config.auth0.audience, + clientSecret: Config.auth0.clientSecret, + scope: 'openid email profile', + redirectUri: Config.auth0.redirectUrl, + postLogoutRedirectUri: Config.auth0.postLogoutRedirectUrl, + session: { + cookieSecret: Config.auth0.cookieSecret, + cookieLifetime: 60 * 60 * 8, + cookieDomain: + Config.environment === 'development' + ? 'localhost' + : Config.auth0.cookieDomain, + cookieSameSite: 'lax', + storeIdToken: true, + storeAccessToken: true, + storeRefreshToken: true, + }, + oidcClient: { + httpTimeout: 2500, + clockTolerance: 10000, + }, + }); + + return auth0; +}; export type { IClaims } from '@auth0/nextjs-auth0/dist/session/session'; diff --git a/lib/config.ts b/lib/config.ts new file mode 100644 index 0000000..36265a3 --- /dev/null +++ b/lib/config.ts @@ -0,0 +1,175 @@ +import * as Yup from 'yup'; +import { UserPermission, UserRole } from './permissions'; + +interface Auth0Props { + domain: string; + audience: string; + clientId: string; + clientSecret: string; + cookieDomain: string; + cookieSecret: string; + redirectUrl: string; + postLogoutRedirectUrl: string; +} + +const createErrorMessageForRequiredEnv = ( + env: string, + possibleValues?: string[] +) => { + const begin = `The "${env}" environment variable is required.`; + + if (!possibleValues || possibleValues.length === 0) { + return begin; + } + + const valuesMsg = `Make sure it is one of the possible values: ${possibleValues.join( + ', ' + )}`; + + return `${begin} ${valuesMsg}`; +}; + +export type ConfigInterface = Yup.InferType; + +const ConfigSchema = Yup.object({ + environment: Yup.string() + .oneOf(['production', 'development']) + .required( + createErrorMessageForRequiredEnv('NODE_ENV', [ + 'production', + 'development', + ]) + ), + metadata: Yup.object({ + logoname: Yup.string().required( + createErrorMessageForRequiredEnv('LOGONAME') + ), + hostname: Yup.string().required( + createErrorMessageForRequiredEnv('HOSTNAME') + ), + }).required(), + anonymous: Yup.object({ + permissions: Yup.array().required(), + roles: Yup.array().required(), + }).required(), + features: Yup.object({ + auth0: Yup.boolean().required( + createErrorMessageForRequiredEnv('AUTH0_ENABLED') + ), + }).required(), + auth0: Yup.object().when('features.auth0', { + is: true, + then: Yup.object({ + domain: Yup.string().required( + createErrorMessageForRequiredEnv('AUTH0_DOMAIN') + ), + audience: Yup.string().required( + createErrorMessageForRequiredEnv('AUTH0_AUDIENCE') + ), + clientId: Yup.string().required( + createErrorMessageForRequiredEnv('AUTH0_CLIENT_ID') + ), + clientSecret: Yup.string().required( + createErrorMessageForRequiredEnv('AUTH0_CLIENT_SECRET') + ), + cookieDomain: Yup.string().required( + createErrorMessageForRequiredEnv('AUTH0_COOKIE_DOMAIN') + ), + cookieSecret: Yup.string().required( + createErrorMessageForRequiredEnv('AUTH0_COOKIE_SECRET') + ), + redirectUrl: Yup.string().required( + createErrorMessageForRequiredEnv('AUTH0_REDIRECT_URL') + ), + postLogoutRedirectUrl: Yup.string().required( + createErrorMessageForRequiredEnv( + 'AUTH0_POST_LOGOUT_REDIRECT_URL' + ) + ), + }).required(), + otherwise: Yup.object().optional(), + }), + database: Yup.object({ + connectionString: Yup.string().required( + createErrorMessageForRequiredEnv('DATABASE_CONNECTION_STRING') + ), + schema: Yup.string().required( + createErrorMessageForRequiredEnv('DATABASE_SCHEMA') + ), + }).required(), +}).required(); + +const createConfig = () => { + const LOGONAME = process.env.LOGONAME; + const HOSTNAME = process.env.HOSTNAME; + const AUTH0_ENABLED = Boolean(process.env.AUTH0_ENABLED); + const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN; + const AUTH0_AUDIENCE = process.env.AUTH0_AUDIENCE; + const AUTH0_CLIENT_ID = process.env.AUTH0_CLIENT_ID; + const AUTH0_CLIENT_SECRET = process.env.AUTH0_CLIENT_SECRET; + const AUTH0_COOKIE_DOMAIN = process.env.AUTH0_COOKIE_DOMAIN; + const AUTH0_COOKIE_SECRET = process.env.AUTH0_COOKIE_SECRET; + const AUTH0_REDIRECT_URL = process.env.AUTH0_REDIRECT_URL; + const AUTH0_POST_LOGOUT_REDIRECT_URL = + process.env.AUTH0_POST_LOGOUT_REDIRECT_URL; + + const DATABASE_CONNECTION_STRING = + process.env.DATABASE_CONNECTION_STRING; + const DATABASE_SCHEMA = process.env.DATABASE_SCHEMA; + const ENVIRONMENT = + process.env.NODE_ENV === 'production' + ? 'production' + : 'development'; + + const ANONYMOUS_PERMISSIONS = AUTH0_ENABLED + ? [UserPermission.ReadLink] + : [ + UserPermission.CreateLink, + UserPermission.ReadLink, + UserPermission.DeleteLink, + UserPermission.UpdateLink, + ]; + + const ANONYMOUS_ROLES = AUTH0_ENABLED + ? [UserRole.Viewer] + : [UserRole.Viewer, UserRole.Editor]; + + const config = { + environment: ENVIRONMENT, + metadata: { + logoname: LOGONAME, + hostname: HOSTNAME, + }, + anonymous: { + permissions: ANONYMOUS_PERMISSIONS, + roles: ANONYMOUS_ROLES, + }, + features: { + auth0: AUTH0_ENABLED, + }, + auth0: AUTH0_ENABLED + ? { + domain: AUTH0_DOMAIN, + audience: AUTH0_AUDIENCE, + clientId: AUTH0_CLIENT_ID, + clientSecret: AUTH0_CLIENT_SECRET, + cookieDomain: AUTH0_COOKIE_DOMAIN, + cookieSecret: AUTH0_COOKIE_SECRET, + redirectUrl: AUTH0_REDIRECT_URL, + postLogoutRedirectUrl: AUTH0_POST_LOGOUT_REDIRECT_URL, + } + : undefined, + database: { + connectionString: DATABASE_CONNECTION_STRING, + schema: DATABASE_SCHEMA, + }, + }; + + const validatedConfig = ConfigSchema.validateSync(config, { + abortEarly: false, + }); + + return validatedConfig; +}; + +export const Config = createConfig(); diff --git a/lib/graphql.ts b/lib/graphql.ts index 4e8bc35..c90633c 100644 --- a/lib/graphql.ts +++ b/lib/graphql.ts @@ -1,6 +1,7 @@ -import { postgraphile, PostGraphileOptions } from 'postgraphile'; -import { auth0, getPermissionsFromSession } from './auth'; import { NextApiRequest } from 'next'; +import { postgraphile, PostGraphileOptions } from 'postgraphile'; +import { getUserClaimsFromRequest } from './auth'; +import { Config } from './config'; const commonProperties: Partial = { subscriptions: true, @@ -8,22 +9,24 @@ const commonProperties: Partial = { setofFunctionsContainNulls: false, ignoreRBAC: false, ignoreIndexes: false, - appendPlugins: [require('@graphile-contrib/pg-simplify-inflector')], + appendPlugins: [ + require('@graphile-contrib/pg-simplify-inflector'), + require('postgraphile/plugins').TagsFilePlugin, + ], graphqlRoute: '/api/graphql', graphiqlRoute: '/api/graphiql', legacyRelations: 'omit', pgSettings: async (req) => { - const settings = {} as Record; - - const session = await auth0.getSession(req as NextApiRequest); - const claims = await getPermissionsFromSession(session); - - settings['role'] = 'postgraphile'; - settings['jwt.claims.roles'] = JSON.stringify(claims.roles); - settings['jwt.claims.permissions'] = JSON.stringify( - claims.permissions + const { claims } = await getUserClaimsFromRequest( + req as NextApiRequest ); + const settings = { + role: 'postgraphile', + 'jwt.claims.roles': JSON.stringify(claims.roles), + 'jwt.claims.permissions': JSON.stringify(claims.permissions), + }; + return settings; }, }; @@ -52,10 +55,9 @@ const productionProperties: PostGraphileOptions = { }; export const graphqlInstance = postgraphile( - process.env.DATABASE_CONNECTION_STRING || - 'postgres://dev:dev@localhost:5432/golinks', - process.env.DATABASE_SCHEMA || 'public', - process.env.NODE_ENV === 'production' + Config.database.connectionString, + Config.database.schema, + Config.environment === 'production' ? productionProperties : devProperties ); diff --git a/lib/permissions.ts b/lib/permissions.ts new file mode 100644 index 0000000..be6fd3b --- /dev/null +++ b/lib/permissions.ts @@ -0,0 +1,11 @@ +export enum UserRole { + Viewer = 'viewer', + Editor = 'editor', +} + +export enum UserPermission { + CreateLink = 'create:golinks', + ReadLink = 'read:golinks', + DeleteLink = 'delete:golinks', + UpdateLink = 'update:golinks', +} diff --git a/package.json b/package.json index 398e674..1091c34 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,28 @@ { - "name": "with-typescript-graphql", + "name": "golinks", "version": "0.1.0", - "author": "", - "license": "ISC", + "author": "Armando Magalhaes ", + "contributors": [], + "repository": "armand1m/golinks", + "homepage": "https://go.d1m.dev/", + "keywords": [ + "golinks", + "application", + "urlshortener", + "web", + "http", + "app", + "api", + "graphql", + "postgresql" + ], + "license": "MIT", "scripts": { "codegen": "graphql-let", - "dev": "yarn codegen && next", - "build": "yarn codegen && next build", + "predev": "yarn codegen", + "dev": "next", + "prebuild": "yarn codegen", + "build": "next build", "start": "next start", "lint": "prettier --check './**/*.{tsx,ts}'", "lint:fix": "prettier --write './**/*.{tsx,ts}'" @@ -17,6 +33,7 @@ "@apollo/react-hooks": "3.1.5", "@auth0/auth0-react": "^1.0.0", "@auth0/nextjs-auth0": "^0.15.0", + "@data-ui/sparkline": "^0.0.84", "@emotion/core": "^10.0.28", "@fortawesome/fontawesome-svg-core": "^1.2.30", "@fortawesome/free-solid-svg-icons": "^5.14.0", @@ -29,8 +46,8 @@ "apollo-link-http": "1.5.17", "apollo-link-schema": "1.2.5", "apollo-utilities": "^1.3.4", - "bumbag": "1.0.0-rc.11", - "bumbag-server": "1.0.0-rc.11", + "bumbag": "^1.3.4", + "bumbag-server": "^1.1.16", "date-fns": "^2.16.1", "emotion": "^10.0.27", "express": "^4.17.1", @@ -49,7 +66,6 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "react-kawaii": "^0.16.0", - "react-sparklines": "^1.7.0", "yup": "^0.29.1" }, "devDependencies": { diff --git a/pages/_app.tsx b/pages/_app.tsx index 45c924d..5efcade 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -3,6 +3,7 @@ import { Provider as ThemeProvider, ToastManager, ThemeConfig, + css, } from 'bumbag'; import { ApolloProvider } from '@apollo/react-hooks'; import { useApollo } from '../lib/apollo'; @@ -16,7 +17,12 @@ import { const theme: ThemeConfig = { modes: { - useSystemColorMode: true, + useSystemColorMode: false, + }, + global: { + styles: { + base: css``, + }, }, Icon: { iconSets: [ @@ -40,7 +46,7 @@ export default function App({ Component, pageProps }: AppProps) { return ( - + diff --git a/pages/_document.tsx b/pages/_document.tsx index 3f52300..4ef3a0f 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -21,6 +21,7 @@ export default class MyDocument extends Document { ), }; } + render() { return ( diff --git a/pages/api/callback.ts b/pages/api/callback.ts index 2ece322..728b75d 100644 --- a/pages/api/callback.ts +++ b/pages/api/callback.ts @@ -1,11 +1,19 @@ -import { auth0 } from '../../lib/auth'; import { NextApiRequest, NextApiResponse } from 'next'; +import { getAuth0 } from '../../lib/auth'; +import { Config } from '../../lib/config'; export default async function callback( req: NextApiRequest, res: NextApiResponse ) { try { + if (!Config.features.auth0) { + return res.status(503).json({ + message: 'Authentication is disabled in this application.', + }); + } + + const auth0 = getAuth0(); await auth0.handleCallback(req, res, { redirectTo: '/' }); } catch (error) { console.error(error); diff --git a/pages/api/login.ts b/pages/api/login.ts index 6bc050a..64f11e3 100644 --- a/pages/api/login.ts +++ b/pages/api/login.ts @@ -1,11 +1,19 @@ -import { auth0 } from '../../lib/auth'; import { NextApiRequest, NextApiResponse } from 'next'; +import { getAuth0 } from '../../lib/auth'; +import { Config } from '../../lib/config'; export default async function login( req: NextApiRequest, res: NextApiResponse ) { try { + if (!Config.features.auth0) { + return res.status(503).json({ + message: 'Authentication is disabled in this application.', + }); + } + + const auth0 = getAuth0(); await auth0.handleLogin(req, res); } catch (error) { console.error(error); diff --git a/pages/api/logout.ts b/pages/api/logout.ts index 3093708..2ae6de2 100644 --- a/pages/api/logout.ts +++ b/pages/api/logout.ts @@ -1,11 +1,19 @@ -import { auth0 } from '../../lib/auth'; import { NextApiRequest, NextApiResponse } from 'next'; +import { getAuth0 } from '../../lib/auth'; +import { Config } from '../../lib/config'; export default async function logout( req: NextApiRequest, res: NextApiResponse ) { try { + if (!Config.features.auth0) { + return res.status(503).json({ + message: 'Authentication is disabled in this application.', + }); + } + + const auth0 = getAuth0(); await auth0.handleLogout(req, res); } catch (error) { console.error(error); diff --git a/pages/api/me.ts b/pages/api/me.ts index 350d526..6962029 100644 --- a/pages/api/me.ts +++ b/pages/api/me.ts @@ -1,11 +1,19 @@ -import { auth0 } from '../../lib/auth'; import { NextApiRequest, NextApiResponse } from 'next'; +import { getAuth0 } from '../../lib/auth'; +import { Config } from '../../lib/config'; export default async function me( req: NextApiRequest, res: NextApiResponse ) { try { + if (!Config.features.auth0) { + return res.status(503).json({ + message: 'Authentication is disabled in this application.', + }); + } + + const auth0 = getAuth0(); await auth0.handleProfile(req, res); } catch (error) { console.error(error); diff --git a/pages/index.tsx b/pages/index.tsx index 094f4df..541fcc4 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,190 +1,218 @@ -import { - GetServerSideProps, - NextApiRequest, - NextApiResponse, -} from 'next'; +import { lazy, Suspense } from 'react'; +import { GetServerSideProps, NextApiRequest } from 'next'; + import { Modal, - Dialog, Flex, - TopNav, + Box, + Dialog, PageWithHeader, - DropdownMenu, - Avatar, - Heading, Spinner, useToasts, Container, + Button, + Stack, + Set, + FieldStack, } from 'bumbag'; -import { IClaims } from '../lib/auth'; -import { LinkTable } from '../components/LinkTable'; -import { CreateLinkForm } from '../components/CreateLinkForm'; -import { useGetAllLinksQuery } from '../lib/queries/getAllLinks.graphql'; +import { TopNavigation } from '../components/TopNavigation'; +import * as LinkForm from '../components/LinkForm'; +import { + Link, + useGetAllLinksQuery, +} from '../lib/queries/getAllLinks.graphql'; import { useCreateLinkMutation } from '../lib/mutations/createLink.graphql'; import { useDeleteLinkMutation } from '../lib/mutations/deleteLink.graphql'; +const LinkTable = lazy(() => import('../components/LinkTable')); + interface Props { logoname: string; hostname: string; - user: IClaims; - grants: { + isAuthEnabled: boolean; + isAuthenticated: boolean; + claims: { permissions: string[]; }; } +const Loader = () => ( + + + +); + const Index: React.FC = ({ - user, logoname, hostname, - grants, + claims, + isAuthEnabled, + isAuthenticated, }) => { - const [createLink] = useCreateLinkMutation(); - const [deleteLink] = useDeleteLinkMutation(); - const { loading, data, refetch } = useGetAllLinksQuery(); - const createLinkModal = Modal.useState(); const toasts = useToasts(); - const canEdit = grants.permissions.includes('update:golinks'); - const canCreate = grants.permissions.includes('create:golinks'); - const canDelete = grants.permissions.includes('delete:golinks'); + const [createLink, createLinkStatus] = useCreateLinkMutation(); + const [deleteLink] = useDeleteLinkMutation(); + const allLinks = useGetAllLinksQuery(); + + const canEdit = claims.permissions.includes('update:golinks'); + const canCreate = claims.permissions.includes('create:golinks'); + const canDelete = claims.permissions.includes('delete:golinks'); + + const onCreateLink = async ( + values: Pick + ) => { + try { + await createLink({ + variables: values, + }); + + await allLinks.refetch(); + + toasts.success({ + title: 'Link Created', + message: 'Link was successfully created.', + }); + } catch (error) { + console.error('Failed to create Link, details: ', error); + toasts.danger({ + title: 'Failed to create Link', + message: 'An unexpected error occurred.', + }); + } + }; + + const onEditLink = async (_linkId: string) => { + /** Open EditLinkForm with data prefilled. */ + }; + + const onViewLinkAnalytics = async (_linkId: string) => { + /** Open Analytics Modal */ + }; + + const onShareLink = async (linkUrl: string) => { + try { + await navigator.clipboard.writeText(linkUrl); + + toasts.success({ + title: 'Link Copied', + message: 'Link is in your clipboard.', + }); + } catch (error) { + console.error('Failed to Copy Link, details: ', error); + toasts.danger({ + title: 'Failed to Copy Link', + message: 'An unexpected error occurred.', + }); + } + }; + + const onDeleteLink = async (linkId: string) => { + try { + await deleteLink({ + variables: { + id: linkId, + }, + }); + + await allLinks.refetch(); + + toasts.success({ + title: 'Link Deleted', + message: 'Link was successfully deleted.', + }); + } catch (error) { + console.error('Failed to delete Link, details: ', error); + toasts.danger({ + title: 'Failed to delete Link', + message: 'An unexpected error occurred.', + }); + } + }; return ( - - - {logoname} - - - Create - - - - - - window.location.replace('/api/logout') - }> - Logout - - - }> - - - - - - + }> - {canCreate && ( - - { - try { - await createLink({ - variables: values, - }); - - toasts.success({ - title: 'Link Created', - message: 'Link was successfully created.', - }); - - createLinkModal.hide(); - form.resetForm(); - refetch(); - } catch (e) { - console.error( - 'Failed to create Link, details: ', - e - ); - toasts.danger({ - title: 'Failed to create Link', - message: 'An unexpected error occurred.', - }); - } - }} - /> - - )} - - {loading && ( - - - - )} - - {data !== undefined && data !== null && ( - { - /** Open EditLinkForm with data prefilled. */ - }} - onShare={async (linkUrl) => { - try { - await navigator.clipboard.writeText(linkUrl); - - toasts.success({ - title: 'Link Copied', - message: 'Link is in your clipboard.', - }); - } catch (e) { - console.error('Failed to Copy Link, details: ', e); - toasts.danger({ - title: 'Failed to Copy Link', - message: 'An unexpected error occurred.', - }); - } - }} - onAnalytics={async (_linkId) => { - /** Open Analytics Modal */ - }} - onDelete={async (linkId) => { - try { - await deleteLink({ - variables: { - id: linkId, - }, - }); - - toasts.success({ - title: 'Link Deleted', - message: 'Link was successfully deleted.', - }); - - refetch(); - } catch (e) { - console.error('Failed to delete Link, details: ', e); - toasts.danger({ - title: 'Failed to delete Link', - message: 'An unexpected error occurred.', - }); - } - }} - /> - )} + + + {canCreate && ( + + {(modal) => ( + <> + + { + await onCreateLink(values); + modal.hide(); + form.resetForm(); + }}> + + + + Create Link + + + + + + + + + + + + + + + + Create + + + )} + + )} + + + {allLinks.loading && } + + {allLinks.data !== undefined && allLinks.data !== null && ( + }> + + + )} + ); @@ -195,34 +223,22 @@ export default Index; export const getServerSideProps: GetServerSideProps = async ( context ) => { - const { auth0, getPermissionsFromSession } = require('../lib/auth'); + const { getUserClaimsFromRequest } = await import('../lib/auth'); + const { Config } = await import("../lib/config"); const request = context?.req as NextApiRequest; - const session = await auth0.getSession(request); - const grants = await getPermissionsFromSession(session); - const user = session?.user; - const logoname = process.env.LOGONAME; - const hostname = process.env.HOSTNAME; - - if (user) { - return { - props: { - user, - grants, - logoname, - hostname, - }, - }; - } - - const response = context?.res as NextApiResponse; - - response.writeHead(302, { - Location: '/api/login', - }); - - response.end(); + const { claims, user } = await getUserClaimsFromRequest(request); + const logoname = Config.metadata.logoname; + const hostname = Config.metadata.hostname; + const isAuthEnabled = Config.features.auth0; + const isAuthenticated = user !== null; return { - props: {}, + props: { + claims, + logoname, + hostname, + isAuthEnabled, + isAuthenticated, + }, }; }; diff --git a/postgraphile.tags.json5 b/postgraphile.tags.json5 new file mode 100644 index 0000000..d0c0715 --- /dev/null +++ b/postgraphile.tags.json5 @@ -0,0 +1,12 @@ +{ + version: 1, + config: { + class: { + schema_migrations: { + tags: { + omit: 'read,update,create,delete,all,many' + } + } + }, + }, +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 9eb56aa..b5c30f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -314,7 +314,7 @@ dependencies: "@babel/types" "^7.10.5" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.8.3": +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== @@ -1081,7 +1081,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.4.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": +"@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2": version "7.11.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== @@ -1139,6 +1139,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.0.0-beta.49": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" + integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@babel/types@^7.10.4": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" @@ -1148,7 +1157,51 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@emotion/cache@^10.0.14", "@emotion/cache@^10.0.27": +"@data-ui/shared@^0.0.84": + version "0.0.84" + resolved "https://registry.yarnpkg.com/@data-ui/shared/-/shared-0.0.84.tgz#42bd025d677f9be2beada3e1a84a53d33ac0eb10" + integrity sha512-MsDLsFzBHFEREr/eF2/RX1o/cXioEg+VQTsM8gViW5ywGQ7Xo5+EqUOaBSrwqKAkvp3e8PaEZVkchPC54IBhrA== + dependencies: + "@data-ui/theme" "^0.0.84" + "@vx/event" "^0.0.165" + "@vx/group" "^0.0.165" + "@vx/shape" "^0.0.168" + "@vx/tooltip" "0.0.165" + d3-array "^1.2.1" + prop-types "^15.5.10" + +"@data-ui/sparkline@^0.0.84": + version "0.0.84" + resolved "https://registry.yarnpkg.com/@data-ui/sparkline/-/sparkline-0.0.84.tgz#be722bcb6fe4844b26905419ecfb3a727b2d206e" + integrity sha512-Ja7T2JjioZtnoy0PEXF72qv/J8xIotu+oS1Z+ygVGZni6aN/DUY35eGpg/DDeemEFDMoifcx+kYa5LU7hQCnJg== + dependencies: + "@data-ui/shared" "^0.0.84" + "@data-ui/theme" "^0.0.8" + "@vx/axis" "^0.0.179" + "@vx/curve" "^0.0.165" + "@vx/event" "^0.0.179" + "@vx/glyph" "^0.0.179" + "@vx/gradient" "^0.0.165" + "@vx/group" "^0.0.170" + "@vx/pattern" "^0.0.179" + "@vx/point" "^0.0.165" + "@vx/responsive" "^0.0.192" + "@vx/scale" "^0.0.179" + "@vx/shape" "^0.0.179" + d3-array "^1.2.0" + prop-types "^15.5.10" + +"@data-ui/theme@^0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@data-ui/theme/-/theme-0.0.8.tgz#3116723d04b99f65c7750f81a500e9608b4837c3" + integrity sha1-MRZyPQS5n2XHdQ+BpQDpYItIN8M= + +"@data-ui/theme@^0.0.84": + version "0.0.84" + resolved "https://registry.yarnpkg.com/@data-ui/theme/-/theme-0.0.84.tgz#b75c23d7f38c582adbb8d2159d0d703159f8e3b2" + integrity sha512-jIoHftC/5c/LVJYF4VSBjjVjrjc0yj4mLkGe8p0eVO7qUYKVvlWx7PrpM7ucyefvuAaKIwlr+Nh2xPGPdADjaA== + +"@emotion/cache@^10.0.27": version "10.0.29" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ== @@ -1158,17 +1211,17 @@ "@emotion/utils" "0.11.3" "@emotion/weak-memoize" "0.2.5" -"@emotion/core@10.0.14": - version "10.0.14" - resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.14.tgz#cac5c334b278d5b7688cfff39e460a5b50abb71c" - integrity sha512-G9FbyxLm3lSnPfLDcag8fcOQBKui/ueXmWOhV+LuEQg9HrqExuWnWaO6gm6S5rNe+AMcqLXVljf8pYgAdFLNSg== +"@emotion/core@^10.0.14": + version "10.0.35" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.35.tgz#513fcf2e22cd4dfe9d3894ed138c9d7a859af9b3" + integrity sha512-sH++vJCdk025fBlRZSAhkRlSUoqSqgCzYf5fMOmqqi3bM6how+sQpg3hkgJonj8GxXM4WbD7dRO+4tegDB9fUw== dependencies: - "@babel/runtime" "^7.4.3" - "@emotion/cache" "^10.0.14" - "@emotion/css" "^10.0.14" - "@emotion/serialize" "^0.11.8" - "@emotion/sheet" "0.9.3" - "@emotion/utils" "0.11.2" + "@babel/runtime" "^7.5.5" + "@emotion/cache" "^10.0.27" + "@emotion/css" "^10.0.27" + "@emotion/serialize" "^0.11.15" + "@emotion/sheet" "0.9.4" + "@emotion/utils" "0.11.3" "@emotion/core@^10.0.28": version "10.0.28" @@ -1182,7 +1235,7 @@ "@emotion/sheet" "0.9.4" "@emotion/utils" "0.11.3" -"@emotion/css@^10.0.14", "@emotion/css@^10.0.27": +"@emotion/css@^10.0.27": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== @@ -1196,31 +1249,19 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== -"@emotion/is-prop-valid@0.8.2": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.2.tgz#b9692080da79041683021fcc32f96b40c54c59dc" - integrity sha512-ZQIMAA2kLUWiUeMZNJDTeCwYRx1l8SQL0kHktze4COT22occKpDML1GDUXP5/sxhOMrZO8vZw773ni4H5Snrsg== - dependencies: - "@emotion/memoize" "0.7.2" - -"@emotion/is-prop-valid@0.8.8": +"@emotion/is-prop-valid@0.8.8", "@emotion/is-prop-valid@^0.8.2": version "0.8.8" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== dependencies: "@emotion/memoize" "0.7.4" -"@emotion/memoize@0.7.2": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.2.tgz#7f4c71b7654068dfcccad29553520f984cc66b30" - integrity sha512-hnHhwQzvPCW1QjBWFyBtsETdllOM92BfrKWbUTmh9aeOlcVOiXvlPsK4104xH8NsaKfg86PTFsWkueQeUfMA/w== - "@emotion/memoize@0.7.4": version "0.7.4" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== -"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16", "@emotion/serialize@^0.11.8": +"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16": version "0.11.16" resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad" integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg== @@ -1231,17 +1272,12 @@ "@emotion/utils" "0.11.3" csstype "^2.5.7" -"@emotion/sheet@0.9.3": - version "0.9.3" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.3.tgz#689f135ecf87d3c650ed0c4f5ddcbe579883564a" - integrity sha512-c3Q6V7Df7jfwSq5AzQWbXHa5soeE4F5cbqi40xn0CzXxWW9/6Mxq48WJEtqfWzbZtW9odZdnRAkwCQwN12ob4A== - "@emotion/sheet@0.9.4": version "0.9.4" resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== -"@emotion/styled-base@^10.0.14": +"@emotion/styled-base@^10.0.27": version "10.0.31" resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.31.tgz#940957ee0aa15c6974adc7d494ff19765a2f742a" integrity sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ== @@ -1251,13 +1287,13 @@ "@emotion/serialize" "^0.11.15" "@emotion/utils" "0.11.3" -"@emotion/styled@10.0.14": - version "10.0.14" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.14.tgz#538bcf0d67bf8f6de946bcfbee53dc7d0187b346" - integrity sha512-Ae8d5N/FmjvZKXjqWcjfhZhjCdkvxZSqD95Q72BYDNQnsOKLHIA4vWlMolLXDNkw1dIxV3l2pp82Z87HXj6eYQ== +"@emotion/styled@^10.0.14": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" + integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== dependencies: - "@emotion/styled-base" "^10.0.14" - babel-plugin-emotion "^10.0.14" + "@emotion/styled-base" "^10.0.27" + babel-plugin-emotion "^10.0.27" "@emotion/stylis@0.8.5": version "0.8.5" @@ -1269,31 +1305,16 @@ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== -"@emotion/utils@0.11.2": - version "0.11.2" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.2.tgz#713056bfdffb396b0a14f1c8f18e7b4d0d200183" - integrity sha512-UHX2XklLl3sIaP6oiMmlVzT0J+2ATTVpf0dHQVyPJHTkOITvXfaSqnRk6mdDhV9pR8T/tHc3cex78IKXssmzrA== - "@emotion/utils@0.11.3": version "0.11.3" resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw== -"@emotion/weak-memoize@0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.3.tgz#dfa0c92efe44a1d1a7974fb49ffeb40ef2da5a27" - integrity sha512-zVgvPwGK7c1aVdUVc9Qv7SqepOGRDrqCw7KZPSZziWGxSlbII3gmvGLPzLX4d0n0BMbamBacUrN22zOMyFFEkQ== - "@emotion/weak-memoize@0.2.5": version "0.2.5" resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@fortawesome/fontawesome-common-types@0.2.29": - version "0.2.29" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.29.tgz#e1a456b643237462d390304cab6975ff3fd68397" - integrity sha512-cY+QfDTbZ7XVxzx7jxbC98Oxr/zc7R2QpTLqTxqlfyXDrAJjzi/xUIqAUsygELB62JIrbsWxtSRhayKFkGI7MA== - "@fortawesome/fontawesome-common-types@^0.2.29", "@fortawesome/fontawesome-common-types@^0.2.30": version "0.2.30" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.30.tgz#2f1cc5b46bd76723be41d0013a8450c9ba92b777" @@ -1306,14 +1327,7 @@ dependencies: "@fortawesome/fontawesome-common-types" "^0.2.30" -"@fortawesome/free-solid-svg-icons@5.13.1": - version "5.13.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.1.tgz#010a846b718a0f110b3cd137d072639b4e8bd41a" - integrity sha512-LQH/0L1p4+rqtoSHa9qFYR84hpuRZKqaQ41cfBQx8b68p21zoWSekTAeA54I/2x9VlCHDLFlG74Nmdg4iTPQOg== - dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.29" - -"@fortawesome/free-solid-svg-icons@^5.14.0": +"@fortawesome/free-solid-svg-icons@^5.13.1", "@fortawesome/free-solid-svg-icons@^5.14.0": version "5.14.0" resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.14.0.tgz#970453f5e8c4915ad57856c3a0252ac63f6fec18" integrity sha512-M933RDM8cecaKMWDSk3FRYdnzWGW7kBBlGNGfvqLVwcwhUPNj9gcw+xZMrqBdRqxnSXdl3zWzTCNNGEtFUq67Q== @@ -1800,10 +1814,10 @@ resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6" integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw== -"@popperjs/core@^2.4.2": - version "2.4.4" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.4.4.tgz#11d5db19bd178936ec89cd84519c4de439574398" - integrity sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg== +"@popperjs/core@^2.4.4": + version "2.5.1" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.5.1.tgz#32b99c0a2b6120d200556fa2d5cd9211ca711881" + integrity sha512-VVOiO4HSzITdcRxUNopcDmI6kE3gNRGq+1Kna1djqx7uCWhaRWpkSl7QxK/i1X3+S5F3dlEQ50qhmBB/JNWubQ== "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" @@ -1839,10 +1853,10 @@ "@types/connect" "*" "@types/node" "*" -"@types/classnames@2.2.9": - version "2.2.9" - resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.9.tgz#d868b6febb02666330410fe7f58f3c4b8258be7b" - integrity sha512-MNl+rT5UmZeilaPxAVs6YaPC2m6aA8rofviZbhbxpPpl61uKodfdQVsBtgJGTqGizEf02oW3tsVe7FYB8kK14A== +"@types/classnames@^2.2.9": + version "2.2.10" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999" + integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ== "@types/color-name@^1.1.1": version "1.1.1" @@ -2073,6 +2087,153 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" integrity sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg== +"@vx/axis@^0.0.179": + version "0.0.179" + resolved "https://registry.yarnpkg.com/@vx/axis/-/axis-0.0.179.tgz#c6cf021d59e42d6fc9a08cd9ecbd45c9889c60d3" + integrity sha512-FtUcdJxejYn5jgixSgSk9AdA96VwP9sCRATVfGvugEL0gtTKWYDbJEgSgqXfKqpeUdsDdf/JT7NVbLMc1hzrZg== + dependencies: + "@vx/group" "0.0.170" + "@vx/point" "0.0.165" + "@vx/shape" "0.0.179" + "@vx/text" "0.0.179" + classnames "^2.2.5" + prop-types "^15.6.0" + +"@vx/bounds@0.0.165": + version "0.0.165" + resolved "https://registry.yarnpkg.com/@vx/bounds/-/bounds-0.0.165.tgz#75f107a6deb58223c6878db5053382eff3174567" + integrity sha512-ZvRb72/4QNs1ZrytZTZxd0hfAb/KKfhsdkcYtIQkmdF6dTsjigMQZ+h2bLvLnbZb/RxyCCoxdiZSGXd+T1c//Q== + dependencies: + prop-types "^15.5.10" + +"@vx/curve@0.0.165", "@vx/curve@^0.0.165": + version "0.0.165" + resolved "https://registry.yarnpkg.com/@vx/curve/-/curve-0.0.165.tgz#330d1512dceae0af43dd3eb4c85523132030a3a0" + integrity sha512-fiQAGrKNGjJbL+eixUckJqIZDWXH/1NtIyyDbSz3J7ksk0QpYr5BgWcNJN76HLNt7wfcLwNzCHeNs4iVYyFGTg== + dependencies: + d3-shape "^1.0.6" + +"@vx/event@^0.0.165": + version "0.0.165" + resolved "https://registry.yarnpkg.com/@vx/event/-/event-0.0.165.tgz#675d89fdfdc08d0c99c36ff1a381ea50fccfba2e" + integrity sha512-FsQiw0f3s5DQB6aBQmBcoWk9e4q65LcDobHIyV8qrmpW2QgV2NvQFM1w0Q300ohpRMgJDzGk68HHHQgFOJvApw== + dependencies: + "@vx/point" "0.0.165" + +"@vx/event@^0.0.179": + version "0.0.179" + resolved "https://registry.yarnpkg.com/@vx/event/-/event-0.0.179.tgz#4474819b5deeb7de313eda4d2f2cc12e2834e38b" + integrity sha512-wEwqKsxrzoRV/A9Va/f/CHPmV9asrTH/kW/f88jCydsVXd5W/nrJZiVpozN2Zr1Ernv0i1gW5896FWo/LHRg0A== + dependencies: + "@vx/point" "0.0.165" + +"@vx/glyph@^0.0.179": + version "0.0.179" + resolved "https://registry.yarnpkg.com/@vx/glyph/-/glyph-0.0.179.tgz#5e03b96c9cc37f2417cf05557d758e9e2c8f1009" + integrity sha512-RO7adwyG+9gGzjFdfmplrojgWCT+gsOnIFcRgJNJjx41+P6hWdI9X4OpsLx8VVqNhp7g+hxBDZWte8AxTvLQGw== + dependencies: + "@vx/group" "0.0.170" + classnames "^2.2.5" + d3-shape "^1.2.0" + prop-types "^15.6.2" + +"@vx/gradient@^0.0.165": + version "0.0.165" + resolved "https://registry.yarnpkg.com/@vx/gradient/-/gradient-0.0.165.tgz#0cc0fe873e6acded4943fa274f68601ad5a50a38" + integrity sha512-FjRXMTmcy7k0TWsfDzWWXw6T9WXKP+6LS/GRgnguq271pab/P+AdOJThsVxtBgUc8ZOAPbub3/2Gggz9d8tocg== + dependencies: + classnames "^2.2.5" + prop-types "^15.5.7" + +"@vx/group@0.0.165", "@vx/group@^0.0.165": + version "0.0.165" + resolved "https://registry.yarnpkg.com/@vx/group/-/group-0.0.165.tgz#2342523225de94859b5be49c3072dc6bb6795e78" + integrity sha512-gi1DSg8AAaVRseyWiq8y4bzyvKiQIXT6vDUYBVRmv2LBcpHocBGaxNiNK0X602RgLG0XmNyRv6qSCWLOaBs3Mg== + dependencies: + classnames "^2.2.5" + +"@vx/group@0.0.170", "@vx/group@^0.0.170": + version "0.0.170" + resolved "https://registry.yarnpkg.com/@vx/group/-/group-0.0.170.tgz#8b30b3ea07c348fe22253812fe7cb6d4200d725d" + integrity sha512-RnDdRoy0YI5hokk+YWXc8t39Kp51i4BdCpiwkDJU4YypGycTYnDFjicam6jigUmZ/6wyMirDf/aQboWviFLt2Q== + dependencies: + classnames "^2.2.5" + +"@vx/pattern@^0.0.179": + version "0.0.179" + resolved "https://registry.yarnpkg.com/@vx/pattern/-/pattern-0.0.179.tgz#8d4723e9ef41930bfdf723582fb2c7d43a91ce01" + integrity sha512-qvJsK07oUnSbuzj9jo7b/1Up13DknIeTlj9FDIhg0UNmz90ikVN2CZIWtdJyc2I1AFDEg0odOqYXzUx9aEBRfg== + dependencies: + classnames "^2.2.5" + prop-types "^15.5.10" + +"@vx/point@0.0.165", "@vx/point@^0.0.165": + version "0.0.165" + resolved "https://registry.yarnpkg.com/@vx/point/-/point-0.0.165.tgz#7ebde5da3d86954fe31a56f923f31550f0b4b867" + integrity sha512-spoHilhjcWNgccrSzBUPw+PXV81tYxeyEWBkgr35aGVU4m7YT86Ywvfemwp7AVVGPn+XJHrhB0ujAhDoyqFPoA== + +"@vx/responsive@^0.0.192": + version "0.0.192" + resolved "https://registry.yarnpkg.com/@vx/responsive/-/responsive-0.0.192.tgz#721d032bec38b9e3ff5fde2e4d5d8ee5a81cc517" + integrity sha512-HaXVwhSJXUfRbzRV+glxsX0ki2Hi1mdpz42iuGArVQgDPJEmBHjkXyoiXU8U6v66M7FAH+OyKgtc5j2bfhyYzA== + dependencies: + lodash "^4.17.10" + prop-types "^15.6.1" + resize-observer-polyfill "1.5.0" + +"@vx/scale@^0.0.179": + version "0.0.179" + resolved "https://registry.yarnpkg.com/@vx/scale/-/scale-0.0.179.tgz#c7f65974ba80ccb7c90a69f639b982f9df9ea7af" + integrity sha512-j40WiGu4VcHZdaSQAl12ig2w5c4Q9EVn7qqYf9PX7uoS5PbxRYNnHeKZ7e5Bf8O6b57iv5jFTfUV7HkpNF4vvg== + dependencies: + d3-scale "^2.0.0" + +"@vx/shape@0.0.179", "@vx/shape@^0.0.179": + version "0.0.179" + resolved "https://registry.yarnpkg.com/@vx/shape/-/shape-0.0.179.tgz#038c449743d1e05b7b2d20151e9ab6e739f73516" + integrity sha512-YHVNx4xGpbjolkW3Lb5pEgJB0+u349vfnLI976DJlinY0hRNa4TZbWXOB4ywLIrYzQEXXPMUR8WtdubNxg6g0w== + dependencies: + "@vx/curve" "0.0.165" + "@vx/group" "0.0.170" + "@vx/point" "0.0.165" + classnames "^2.2.5" + d3-path "^1.0.5" + d3-shape "^1.2.0" + prop-types "^15.5.10" + +"@vx/shape@^0.0.168": + version "0.0.168" + resolved "https://registry.yarnpkg.com/@vx/shape/-/shape-0.0.168.tgz#172bc1cf4dade47076018efd559e0ecc4e959aec" + integrity sha512-urKZkwSafMpPQ0wI/L5FJmufRiAR4UsgYUCKxROjfE1Cf4jWNlK6mlVIIASxCdHlh9CGBbIrRMdl5Yv5lzqhjA== + dependencies: + "@vx/curve" "0.0.165" + "@vx/group" "0.0.165" + "@vx/point" "0.0.165" + classnames "^2.2.5" + d3-path "^1.0.5" + d3-shape "^1.2.0" + prop-types "^15.5.10" + +"@vx/text@0.0.179": + version "0.0.179" + resolved "https://registry.yarnpkg.com/@vx/text/-/text-0.0.179.tgz#820328086c22a83cd9e4a5373f4c7f4223db3a74" + integrity sha512-UD3/8o15+AQfjDI8LQ1Zj3EdQCwA3cfuQMR/M2F/Le4+JXQNMheeWz4xGyF4ZDs6r7c5cUI9Cd1RaPmGhYsX9g== + dependencies: + babel-plugin-lodash "^3.3.2" + classnames "^2.2.5" + lodash "^4.17.4" + prop-types "^15.6.2" + reduce-css-calc "^1.3.0" + +"@vx/tooltip@0.0.165": + version "0.0.165" + resolved "https://registry.yarnpkg.com/@vx/tooltip/-/tooltip-0.0.165.tgz#0d17a1b445a7bc70d7840e36593b780a6e7b40e2" + integrity sha512-/x1NZc67QGQ4e/WNT7Ks5LYRyeLSqp8lG04gX5J6leUS0zscAVzo3aE5u65Qqbc0cnMyMPRZ2Qtb4klWTLg+eQ== + dependencies: + "@vx/bounds" "0.0.165" + classnames "^2.2.5" + prop-types "^15.5.10" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -2350,11 +2511,6 @@ anser@1.4.9: resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== -ansi-colors@^4.1.1: - version "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.1, ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.1" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" @@ -2686,7 +2842,7 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-emotion@^10.0.14, babel-plugin-emotion@^10.0.27: +babel-plugin-emotion@^10.0.27: version "10.0.33" resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz#ce1155dcd1783bbb9286051efee53f4e2be63e03" integrity sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ== @@ -2702,6 +2858,17 @@ babel-plugin-emotion@^10.0.14, babel-plugin-emotion@^10.0.27: find-root "^1.1.0" source-map "^0.5.7" +babel-plugin-lodash@^3.3.2: + version "3.3.4" + resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz#4f6844358a1340baed182adbeffa8df9967bc196" + integrity sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg== + dependencies: + "@babel/helper-module-imports" "^7.0.0-beta.49" + "@babel/types" "^7.0.0-beta.49" + glob "^7.1.1" + lodash "^4.17.10" + require-package-name "^2.0.1" + babel-plugin-macros@^2.0.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" @@ -2772,6 +2939,11 @@ backo2@^1.0.2: resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= +balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -2860,10 +3032,10 @@ body-parser@1.19.0, body-parser@^1.15.2: raw-body "2.4.0" type-is "~1.6.17" -body-scroll-lock@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.0.3.tgz#221d87435bcfb50e27ab5d4508735f622aed11a2" - integrity sha512-EUryImgD6Gv87HOjJB/yB2WIGECiZMhmcUK+DrqVRFDDa64xR+FsK0LgvLPnBxZDTxIl+W80/KJ8i6gp2IwOHQ== +body-scroll-lock@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec" + integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg== boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" @@ -3040,36 +3212,36 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -bumbag-server@1.0.0-rc.11: - version "1.0.0-rc.11" - resolved "https://registry.yarnpkg.com/bumbag-server/-/bumbag-server-1.0.0-rc.11.tgz#f40c5bde0af258cd4a8da8f5a3ba4f9cb9862982" - integrity sha512-7pqdZV3soRbywJTpcWYA3jH9PC78AAEn+HILeHsLHWPeElEFjK87P4BqiHmm0YHu6avzBBqRT/uGvqWwlOQSEg== +bumbag-server@^1.1.16: + version "1.1.16" + resolved "https://registry.yarnpkg.com/bumbag-server/-/bumbag-server-1.1.16.tgz#14a862a1b8f87bbeaaf5a80437cb4f9e4cb76bf1" + integrity sha512-36uHwMcJrgiotYD463OOmJ9fA9/IclwLh/5RCHTr5ADsZvlsey9p2r504i7U0FaU9DR5Z8t5ASlGh9nXBgqxGA== dependencies: - emotion-server "10.0.27" + emotion-server "^10.0.27" -bumbag@1.0.0-rc.11: - version "1.0.0-rc.11" - resolved "https://registry.yarnpkg.com/bumbag/-/bumbag-1.0.0-rc.11.tgz#526eab53570d23f23c3eaf3f3511822effeb8f27" - integrity sha512-xd5fWjhSoXTPixxc8GSXKgEBgwAwOyGpJMAjkfGYmqfIathPEFrULwosDPQdsUIIhobVvVxCzKA5w9hP43uZtw== +bumbag@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bumbag/-/bumbag-1.3.4.tgz#87d23cf94095708702b0e9b9ea1c497ddc6da7fc" + integrity sha512-cICLr4wCUTryZePrdXEGn5q387DUdnfjGaqjqeHGrBMRT/IF6YWF3EGPway31LZKg31kztzcEu4oXKuvuJDF+Q== dependencies: - "@emotion/core" "10.0.14" - "@emotion/is-prop-valid" "0.8.2" - "@emotion/styled" "10.0.14" - "@fortawesome/fontawesome-common-types" "0.2.29" - "@fortawesome/free-solid-svg-icons" "5.13.1" - "@types/classnames" "2.2.9" - classnames "2.2.6" - conditional-wrap "1.0.0" - deepmerge "4.2.2" - emotion "10.0.14" - emotion-theming "10.0.14" - lodash "4.17.19" - react-input-mask "2.0.4" + "@emotion/core" "^10.0.14" + "@emotion/is-prop-valid" "^0.8.2" + "@emotion/styled" "^10.0.14" + "@fortawesome/fontawesome-common-types" "^0.2.29" + "@fortawesome/free-solid-svg-icons" "^5.13.1" + "@types/classnames" "^2.2.9" + capsize "^1.1.0" + classnames "^2.2.6" + conditional-wrap "^1.0.0" + deepmerge "^4.2.2" + emotion "^10.0.14" + emotion-theming "^10.0.14" + lodash "^4.17.19" + react-input-mask "^2.0.4" react-loads-next "npm:react-loads@9.2.3" - reakit "1.1.0" - styled-tools "1.7.1" - tinycolor2 "1.4.1" - use-effect-reducer "0.5.0" + reakit "^1.2.2" + styled-tools "^1.7.1" + tinycolor2 "^1.4.1" bytes@3.1.0: version "3.1.0" @@ -3206,6 +3378,13 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001093: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001107.tgz#809360df7a5b3458f627aa46b0f6ed6d5239da9a" integrity sha512-86rCH+G8onCmdN4VZzJet5uPELII59cUzDphko3thQFgAQG1RNa+sVLDoALIhRYmflo5iSIzWY3vu1XTWtNMQQ== +capsize@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/capsize/-/capsize-1.1.0.tgz#d70f918b5ecadc2390b2a3b3b672ced639907ed6" + integrity sha512-tV0weOXxQ9hsbqewiWfGQBXsGzSN/i/w9IGuH+JVySzGOhscTAzeK3N9ZAM3Kf89bWgYot80Za5fSXKi6ZynvA== + dependencies: + round-to "^4.1.0" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -3316,7 +3495,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@2.2.6: +classnames@2.2.6, classnames@^2.2.5, classnames@^2.2.6: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== @@ -3348,14 +3527,6 @@ cli-truncate@^0.2.1: slice-ansi "0.0.4" string-width "^1.0.1" -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - cli-width@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" @@ -3465,11 +3636,6 @@ commander@^2.19.0, commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc" - integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA== - common-tags@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -3507,10 +3673,10 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" -conditional-wrap@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/conditional-wrap/-/conditional-wrap-1.0.0.tgz#e97ea144b4f5b03819fe0e3c8be2f3d7f37d10ea" - integrity sha512-vjSB8ARvV+b4q5BbdO6aOpPRfjQdfnKEZZN0H5v8F1X+fQ+X1/LV+yWx3CSZaS+rLGiwFD3Xp086bB9qHu0aaw== +conditional-wrap@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/conditional-wrap/-/conditional-wrap-1.0.2.tgz#a993fd402e7747d83d1e36c675175f89852c25e5" + integrity sha512-jaL1qJC7JImOXiWC4/OxrSMjbPSZG+tWj2VmUtdBOOQhJj0gbFoDCF2Y0F5xLgQUpg+CDSymssaTX+Vn+1yM3Q== console-browserify@^1.1.0: version "1.2.0" @@ -3631,17 +3797,6 @@ cosmiconfig@^5.0.0: js-yaml "^3.13.1" parse-json "^4.0.0" -cosmiconfig@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -3660,7 +3815,7 @@ create-emotion-server@10.0.27: multipipe "^1.0.2" through "^2.3.8" -create-emotion@^10.0.14, create-emotion@^10.0.27: +create-emotion@^10.0.27: version "10.0.27" resolved "https://registry.yarnpkg.com/create-emotion/-/create-emotion-10.0.27.tgz#cb4fa2db750f6ca6f9a001a33fbf1f6c46789503" integrity sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg== @@ -3708,15 +3863,6 @@ cross-fetch@3.0.5: dependencies: node-fetch "2.6.0" -cross-spawn@^7.0.0: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -3912,6 +4058,69 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= +d3-array@^1.2.0, d3-array@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + +d3-collection@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" + integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== + +d3-color@1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" + integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== + +d3-format@1: + version "1.4.5" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" + integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== + +d3-interpolate@1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" + integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== + dependencies: + d3-color "1" + +d3-path@1, d3-path@^1.0.5: + version "1.0.9" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +d3-scale@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-2.2.2.tgz#4e880e0b2745acaaddd3ede26a9e908a9e17b81f" + integrity sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw== + dependencies: + d3-array "^1.2.0" + d3-collection "1" + d3-format "1" + d3-interpolate "1" + d3-time "1" + d3-time-format "2" + +d3-shape@^1.0.6, d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +d3-time-format@2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.3.0.tgz#107bdc028667788a8924ba040faf1fbccd5a7850" + integrity sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ== + dependencies: + d3-time "1" + +d3-time@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" + integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== + d@1, d@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" @@ -4004,21 +4213,16 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - -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== - deepmerge@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== +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== + defer-to-connect@^1.0.1: version "1.1.3" resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" @@ -4249,31 +4453,23 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== -emotion-server@10.0.27: +emotion-server@^10.0.27: version "10.0.27" resolved "https://registry.yarnpkg.com/emotion-server/-/emotion-server-10.0.27.tgz#ea654342fdf9f5d8cd1793f5a6594159485a3806" integrity sha512-ypISBMkgZD7dgP6Y0QhZlqazxffpowcEWlZHKLADVazdxY5iXjZbd1UvovdpfDRjbj4EBxwKkltog3NzuSBavA== dependencies: create-emotion-server "10.0.27" -emotion-theming@10.0.14: - version "10.0.14" - resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.14.tgz#e548d388493d07bedbb0d9d3bbe221766174b1f4" - integrity sha512-zMGhPSYz48AAR6DYjQVaZHeO42cYKPq4VyB1XjxzgR62/NmO99679fx8qDDB1QZVYGkRWZtsOe+zJE/e30XdbA== +emotion-theming@^10.0.14: + version "10.0.27" + resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.27.tgz#1887baaec15199862c89b1b984b79806f2b9ab10" + integrity sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw== dependencies: - "@babel/runtime" "^7.4.3" - "@emotion/weak-memoize" "0.2.3" + "@babel/runtime" "^7.5.5" + "@emotion/weak-memoize" "0.2.5" hoist-non-react-statics "^3.3.0" -emotion@10.0.14: - version "10.0.14" - resolved "https://registry.yarnpkg.com/emotion/-/emotion-10.0.14.tgz#d7702a6147de6e8ce863dacde98418a467c5fed4" - integrity sha512-6cTWfwqVGy9UinGSZQKRGyuRsRGkzlT0MaeH2pF4BvL7u6PnyTZeyHj4INwzpaXBLwA9C0JaFqS31J62RWUNNw== - dependencies: - babel-plugin-emotion "^10.0.14" - create-emotion "^10.0.14" - -emotion@^10.0.27: +emotion@^10.0.14, emotion@^10.0.27: version "10.0.27" resolved "https://registry.yarnpkg.com/emotion/-/emotion-10.0.27.tgz#f9ca5df98630980a23c819a56262560562e5d75e" integrity sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g== @@ -4309,13 +4505,6 @@ enhanced-resolve@^4.1.0: memory-fs "^0.5.0" tapable "^1.0.0" -enquirer@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - entities@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" @@ -4472,21 +4661,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -execa@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.3.tgz#0a34dabbad6d66100bd6f2c576c8669403f317f2" - integrity sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -4701,7 +4875,7 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -figures@^3.0.0, figures@^3.2.0: +figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -4967,11 +5141,6 @@ 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-own-enumerable-property-symbols@^3.0.0: - version "3.0.2" - 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-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -4979,7 +5148,7 @@ get-stream@^4.1.0: dependencies: pump "^3.0.0" -get-stream@^5.0.0, get-stream@^5.1.0: +get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== @@ -5418,11 +5587,6 @@ https-proxy-agent@^2.2.1: agent-base "^4.3.0" debug "^3.1.0" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5472,7 +5636,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== @@ -5741,11 +5905,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -5782,11 +5941,6 @@ is-regex@^1.1.0: dependencies: has-symbols "^1.0.1" -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= - is-relative@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" @@ -5804,11 +5958,6 @@ is-stream@^1.0.1, is-stream@^1.1.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-stream@^2.0.0: - version "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-svg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" @@ -5855,11 +6004,6 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -6137,27 +6281,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -lint-staged@^10.1.6: - version "10.2.13" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.2.13.tgz#b9c504683470edfc464b7d3fe3845a5a1efcd814" - integrity sha512-conwlukNV6aL9SiMWjFtDp5exeDnTMekdNPDZsKGnpfQuHcO0E3L3Bbf58lcR+M7vk6LpCilxDAVks/DDVBYlA== - dependencies: - chalk "^4.1.0" - cli-truncate "^2.1.0" - commander "^6.0.0" - cosmiconfig "^7.0.0" - debug "^4.1.1" - dedent "^0.7.0" - enquirer "^2.3.6" - execa "^4.0.3" - listr2 "^2.6.0" - log-symbols "^4.0.0" - micromatch "^4.0.2" - normalize-path "^3.0.0" - please-upgrade-node "^3.2.0" - string-argv "0.3.1" - stringify-object "^3.3.0" - listr-silent-renderer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" @@ -6187,20 +6310,6 @@ listr-verbose-renderer@^0.5.0: date-fns "^1.27.2" figures "^2.0.0" -listr2@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a" - integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== - dependencies: - chalk "^4.1.0" - cli-truncate "^2.1.0" - figures "^3.2.0" - indent-string "^4.0.0" - log-update "^4.0.0" - p-map "^4.0.0" - rxjs "^6.6.2" - through "^2.3.8" - listr@0.14.3: version "0.14.3" resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" @@ -6341,12 +6450,12 @@ lodash@4.17.19, "lodash@>=4 <5", lodash@>=4.17.19, lodash@^4.17.11, lodash@^4.17 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== -lodash@^4.17.19: +lodash@^4.17.10, lodash@^4.17.19: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== -log-symbols@4.0.0, log-symbols@^4.0.0: +log-symbols@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== @@ -6473,6 +6582,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +math-expression-evaluator@^1.2.14: + version "1.2.22" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.22.tgz#c14dcb3d8b4d150e5dcea9c68c8dad80309b0d5e" + integrity sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -6956,13 +7070,6 @@ normalize-url@^4.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== -npm-run-path@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -7210,13 +7317,6 @@ p-map@^3.0.0: dependencies: aggregate-error "^3.0.0" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-some@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/p-some/-/p-some-5.0.0.tgz#8b730c74b4fe5169d7264a240ad010b6ebc686a4" @@ -7351,11 +7451,6 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - 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" @@ -7496,13 +7591,6 @@ platform@1.3.3: resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.3.tgz#646c77011899870b6a0903e75e997e8e51da7461" integrity sha1-ZGx3ARiZhwtqCQPnXpl+jlHadGE= -please-upgrade-node@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" - integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== - dependencies: - semver-compare "^1.0.0" - pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" @@ -8003,7 +8091,7 @@ prop-types-exact@1.2.0: object.assign "^4.1.0" reflect.ownkeys "^0.2.0" -prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, 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" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8170,7 +8258,7 @@ react-fast-compare@^2.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== -react-input-mask@2.0.4: +react-input-mask@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/react-input-mask/-/react-input-mask-2.0.4.tgz#9ade5cf8196f4a856dbf010820fe75a795f3eb14" integrity sha512-1hwzMr/aO9tXfiroiVCx5EtKohKwLk/NT8QlJXHQ4N+yJJFyUuMT+zfTpLBwX/lK3PkuMlievIffncpMZ3HGRQ== @@ -8200,13 +8288,6 @@ 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-sparklines@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/react-sparklines/-/react-sparklines-1.7.0.tgz#9b1d97e8c8610095eeb2ad658d2e1fcf91f91a60" - integrity sha512-bJFt9K4c5Z0k44G8KtxIhbG+iyxrKjBZhdW6afP+R7EnIq+iKjbWbEFISrf3WKNFsda+C46XAfnX0StS5fbDcg== - dependencies: - prop-types "^15.5.10" - react@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" @@ -8264,35 +8345,51 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" -reakit-system@^0.13.0: - version "0.13.1" - resolved "https://registry.yarnpkg.com/reakit-system/-/reakit-system-0.13.1.tgz#e756b9a1b9d6cfe75f9a5e77531e5b0f9eb8227b" - integrity sha512-qglfQ53FsJh5+VSkjMtBg7eZiowj9zXOyfJJxfaXh/XYTVe/5ibzWg6rvGHyvSm6C3D7Q2sg/NPCLmCtYGGvQA== +reakit-system@^0.14.5: + version "0.14.5" + resolved "https://registry.yarnpkg.com/reakit-system/-/reakit-system-0.14.5.tgz#1fd0bf79d50fbf6dc8a2801fd68540ecdb67cdbe" + integrity sha512-zoUjfbNlYpb9GxlVwTiBJco0M7J4zKoJ+anhTUiAfo5OKabnuGUcI8fJ4OTiWgzH7XSdjDSubb2xCfGnwLR8BA== dependencies: - reakit-utils "^0.13.1" + reakit-utils "^0.14.4" -reakit-utils@^0.13.0, reakit-utils@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/reakit-utils/-/reakit-utils-0.13.1.tgz#060b8b2a55eea1170c6d8ff37cd98c10c63ee55c" - integrity sha512-NBKgsot3tU91gZgK5MTInI/PR0T3kIsTmbU5MbGggSOcwU2dG/kbE8IrM2lC6ayCSL2W2QWkijT6kewdrIX7Gw== +reakit-utils@^0.14.4: + version "0.14.4" + resolved "https://registry.yarnpkg.com/reakit-utils/-/reakit-utils-0.14.4.tgz#1ecf035faf58960ba48eac2963f70269596effcf" + integrity sha512-jDEf/NmZVJ6fs10G16ifD+RFhQikSLN7VfjRHu0CPoUj4g6lFXd5PPcRXCY81qiqc9FVHjr2d2fmsw1hs6xUxA== -reakit-warning@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/reakit-warning/-/reakit-warning-0.4.1.tgz#a715302812c5fc7f89f35772d650423f09029b00" - integrity sha512-AgnRN6cf8DYBF/mK2JEMFVL67Sbon8fDbFy1kfm0EDibtGsMOQtsFYfozZL7TwmJ4yg68VMhg8tmPHchVQRrlg== +reakit-warning@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/reakit-warning/-/reakit-warning-0.5.5.tgz#551afcfd9b0c3dc92eab21fcca001fc2ebbc8465" + integrity sha512-OuP1r7rlSSJZsoLuc0CPA2ACPKnWO8HDbFktiiidbT67UjuX6udYV1AUsIgMJ8ado9K5gZGjPj7IB/GDYo9Yjg== dependencies: - reakit-utils "^0.13.1" + reakit-utils "^0.14.4" -reakit@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/reakit/-/reakit-1.1.0.tgz#c30289907722a1fb1aa6a8c4990dac739c60e9c7" - integrity sha512-d/ERtwgBndBPsyPBPUl5jueyfFgsglIfQCnLMKuxM0PaWiIZ6Ys3XsYaNy/AaG8k46Ee5cQPMdRrR30nVcSToQ== +reakit@^1.2.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/reakit/-/reakit-1.2.5.tgz#700cfe25543a2cce6d4c843d7b3d82ff9be3554a" + integrity sha512-i5i11ygjsf2H6p3P6+QSZo08PZe/HdH/3YoXtaozL95tC/47r9J2GPaVF0XZR1dcC7zWXVoiZdnFEowRIVx+Rw== + dependencies: + "@popperjs/core" "^2.4.4" + body-scroll-lock "^3.1.5" + reakit-system "^0.14.5" + reakit-utils "^0.14.4" + reakit-warning "^0.5.5" + +reduce-css-calc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= + dependencies: + balanced-match "^0.4.2" + math-expression-evaluator "^1.2.14" + reduce-function-call "^1.0.1" + +reduce-function-call@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" + integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ== dependencies: - "@popperjs/core" "^2.4.2" - body-scroll-lock "^3.0.2" - reakit-system "^0.13.0" - reakit-utils "^0.13.0" - reakit-warning "^0.4.0" + balanced-match "^1.0.0" reflect.ownkeys@^0.2.0: version "0.2.0" @@ -8456,6 +8553,16 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +require-package-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" + integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk= + +resize-observer-polyfill@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz#660ff1d9712a2382baa2cad450a4716209f9ca69" + integrity sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg== + resolve-from@5.0.0, resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" @@ -8577,6 +8684,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +round-to@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/round-to/-/round-to-4.1.0.tgz#148d768d18b2f127f78e6648cb8b0a5943c416bf" + integrity sha512-H/4z+4QdWS82iMZ23+5St302Mv2jJws0hUvEogrD6gC8NN6Z5TalDtbg51owCrVy4V/4c8ePvwVLNtlhEfPo5g== + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -8601,7 +8713,7 @@ rxjs@^6.3.3: dependencies: tslib "^1.9.0" -rxjs@^6.6.0, rxjs@^6.6.2: +rxjs@^6.6.0: version "6.6.2" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2" integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg== @@ -8693,11 +8805,6 @@ scuid@^1.0.2: resolved "https://registry.yarnpkg.com/scuid/-/scuid-1.1.0.tgz#d3f9f920956e737a60f72d0e4ad280bf324d5dab" integrity sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg== -semver-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= - semver@4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7" @@ -8799,18 +8906,6 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - shell-quote@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" @@ -8843,15 +8938,6 @@ slice-ansi@0.0.4: resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -9060,11 +9146,6 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= -string-argv@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" - integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== - string-env-interpolation@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" @@ -9136,15 +9217,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-object@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - strip-ansi@6.0.0, strip-ansi@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" @@ -9166,11 +9238,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -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" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - style-loader@1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" @@ -9193,10 +9260,10 @@ styled-jsx@3.3.0: stylis "3.5.4" stylis-rule-sheet "0.0.10" -styled-tools@1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/styled-tools/-/styled-tools-1.7.1.tgz#1c9a586f49c8aa85d18aa5ca26ac01250e7fc6c5" - integrity sha512-F0ANrxYgc6rMO5npJmOWu8+jvHDlOuu31JGeWIHBVuPJ2mUCpLLAN5dN+4MC+OBIdJAJ/BpsfFuxKnOWq7YAJQ== +styled-tools@^1.7.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/styled-tools/-/styled-tools-1.7.2.tgz#a8f71198535cf785d7db0927cc1c1b88337c4440" + integrity sha512-IjLxzM20RMwAsx8M1QoRlCG/Kmq8lKzCGyospjtSXt/BTIIcvgTonaxQAsKnBrsZNwhpHzO9ADx5te0h76ILVg== stylehacks@^4.0.0: version "4.0.3" @@ -9359,7 +9426,7 @@ tiny-warning@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== -tinycolor2@1.4.1: +tinycolor2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= @@ -9683,13 +9750,6 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -use-effect-reducer@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/use-effect-reducer/-/use-effect-reducer-0.5.0.tgz#da1387160931915888f9c1a641b5d4306cebad73" - integrity sha512-m2et3PukZ9MKROOcr83Ylg1IARlsMgUwsTO6tDZNXtikUn6vC6J3el1vxOckhf8JlCGtDw8tXKw88n9hegJ11Q== - dependencies: - lint-staged "^10.1.6" - use-subscription@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.4.1.tgz#edcbcc220f1adb2dd4fa0b2f61b6cc308e620069" @@ -9893,13 +9953,6 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -10001,7 +10054,7 @@ yaml-ast-parser@^0.0.40: resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.40.tgz#08536d4e73d322b1c9ce207ab8dd70e04d20ae6e" integrity sha1-CFNtTnPTIrHJziB6uN1w4E0grm4= -yaml@^1.10.0, yaml@^1.7.2: +yaml@^1.7.2: version "1.10.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==