diff --git a/functions/all-projects.js b/functions/all-projects.js
new file mode 100644
index 0000000..019370e
--- /dev/null
+++ b/functions/all-projects.js
@@ -0,0 +1,36 @@
+import {
+ getFauna,
+ getProjectPreviewData,
+ withErrorWrapper,
+} from './utils/fauna';
+
+exports.handler = withErrorWrapper(async (event, context) => {
+ const { before, after, size = 24 } = event.queryStringParameters;
+ const { q, client } = getFauna();
+ const result = await client.query(
+ q.Paginate(q.Match(q.Index('all_projects_sorted_by_date_created')), {
+ size,
+ after: after ? parseInt(after) : undefined,
+ before: before ? parseInt(before) : undefined,
+ })
+ );
+ const getAllprojectDataQuery = result.data.map(ref => q.Get(ref[1]));
+ const allProjects = await client.query(getAllprojectDataQuery);
+
+ return {
+ statusCode: 200,
+ body: JSON.stringify({
+ after: result.after,
+ before: result.before,
+ data: allProjects.map(({ ref, data, ts }, i) => {
+ return {
+ ref,
+ ts,
+ _id: ref.id,
+ index: i,
+ ...getProjectPreviewData(data),
+ };
+ }),
+ }),
+ };
+});
diff --git a/functions/my-projects.js b/functions/my-projects.js
new file mode 100644
index 0000000..c594de5
--- /dev/null
+++ b/functions/my-projects.js
@@ -0,0 +1,46 @@
+import {
+ getFauna,
+ getProjectPreviewData,
+ withErrorWrapper,
+} from './utils/fauna';
+
+exports.handler = withErrorWrapper(async (event, context) => {
+ const { user } = context.clientContext;
+ if (!user) {
+ return { statusCode: 401, body: 'Not logged in' };
+ }
+
+ // const { before, after, size = 24 } = event.queryStringParameters;
+ const { q, client } = getFauna();
+ console.log('USER', user);
+ const result = await client.query(
+ q.Paginate(
+ q.Match(q.Index('projectsByUserId'), user.sub)
+ // {
+ // size,
+ // after: after ? [parseInt(after)] : undefined,
+ // before: before ? [parseInt(before)] : undefined,
+ // }
+ )
+ );
+
+ const getAllprojectDataQuery = result.data.map(ref => q.Get(ref));
+ const allProjects = await client.query(getAllprojectDataQuery);
+
+ return {
+ statusCode: 200,
+ body: JSON.stringify({
+ after: result.after,
+ before: result.before,
+ data: allProjects.map(({ ref, data, ts }, i) => {
+ return {
+ ref,
+ ts,
+ _id: ref.id,
+ index: i,
+ ...getProjectPreviewData(data),
+ };
+ }),
+ }),
+ };
+});
diff --git a/functions/project.js b/functions/project.js
new file mode 100644
index 0000000..55ee73c
--- /dev/null
+++ b/functions/project.js
@@ -0,0 +1,80 @@
+import { getFauna, getId, withErrorWrapper } from './utils/fauna';
+
+exports.handler = withErrorWrapper(async (event, context) => {
+ const method = event.httpMethod;
+ const { q, client } = getFauna();
+ const id = getId(event.path);
+ const { user } = context.clientContext;
+ if (!id) return { statusCode: 400, body: 'invalid request' };
+
+ console.log(`Function 'project' invoked. Method: ${method}, Read id: ${id}`);
+ const projectIdPath = `classes/Project/${id}`;
+
+ const verifyProjectOwner = async (id, user) => {
+ if (!user) {
+ throw new Error('Not logged in');
+ }
+ const project = await client.query(q.Get(q.Ref(projectIdPath)));
+ if (!project) {
+ throw new Error('Project not found');
+ }
+ const { userId } = project.data;
+ if (userId !== user.sub) {
+ throw new Error('Unauthorized');
+ }
+ };
+
+ switch (method) {
+ case 'GET': {
+ const response = await client.query(q.Get(q.Ref(projectIdPath)));
+ return { statusCode: 200, body: JSON.stringify(response) };
+ }
+
+ case 'POST': {
+ if (!user) {
+ return { statusCode: 401, body: 'Not logged in' };
+ }
+ const userId = user.sub;
+ const userName = user.user_metadata.full_name;
+ const dateCreated = Date.now() * 1000;
+ const data = JSON.parse(event.body);
+ const response = await client.query(
+ q.Create(q.Ref('classes/Project'), {
+ data: { ...data, userId, userName, dateCreated },
+ })
+ );
+ return {
+ statusCode: 200,
+ body: JSON.stringify({
+ data: { ...response.data, _id: response.ref.id },
+ }),
+ };
+ }
+
+ case 'PATCH': {
+ try {
+ await verifyProjectOwner(id, user);
+ } catch (err) {
+ return { statusCode: 401, body: JSON.stringify(err) };
+ }
+ const data = JSON.parse(event.body);
+ const response = await client.query(
+ q.Update(q.Ref(projectIdPath), { data })
+ );
+ return { statusCode: 200, body: JSON.stringify(response) };
+ }
+
+ case 'DELETE': {
+ try {
+ await verifyProjectOwner(id, user);
+ } catch (err) {
+ return { statusCode: 401, body: JSON.stringify(err) };
+ }
+ const response = await client.query(q.Delete(q.Ref(projectIdPath)));
+ return { statusCode: 200, body: JSON.stringify(response) };
+ }
+
+ default:
+ return { statusCode: 400, body: 'invalid method' };
+ }
+});
diff --git a/functions/utils/errors.js b/functions/utils/errors.js
index 5925f5c..580aca3 100644
--- a/functions/utils/errors.js
+++ b/functions/utils/errors.js
@@ -9,6 +9,13 @@ export const initSentry = () => {
});
};
+export const captureError = (error, context) => {
+ Sentry.withScope(scope => {
+ scope.setExtra('context', context);
+ Sentry.captureException(error);
+ });
+};
+
export const objectMap = (object, mapper) =>
Object.entries(object).reduce(
(acc, [key, value]) => ({
diff --git a/functions/utils/fauna.js b/functions/utils/fauna.js
new file mode 100644
index 0000000..2446810
--- /dev/null
+++ b/functions/utils/fauna.js
@@ -0,0 +1,51 @@
+import faunadb from 'faunadb';
+import * as Sentry from '@sentry/node';
+import { initSentry, captureError } from './errors';
+
+initSentry();
+
+export const getFauna = () => ({
+ q: faunadb.query,
+ client: new faunadb.Client({
+ secret: process.env.FAUNADB_SERVER_SECRET,
+ }),
+});
+
+export const getId = urlPath => urlPath.match(/([^\/]*)\/*$/)[0];
+export const getUserName = user => user && user.user_metadata.full_name;
+
+export const getProjectPreviewData = ({
+ name,
+ userName,
+ shapesList,
+ dateCreated,
+}) => {
+ return {
+ name,
+ userName,
+ dateCreated,
+ shapesList,
+ };
+};
+
+export const withErrorWrapper = callback => async (event, context) => {
+ try {
+ return await callback(event, context);
+ } catch (err) {
+ console.log('GOT ERROR', err.name);
+ console.log('ERROR MESSAGE:', err.message);
+
+ captureError(err, context);
+ try {
+ return {
+ statusCode: err.requestResult.statusCode,
+ body: JSON.stringify(err),
+ };
+ } catch (err) {
+ return {
+ statusCode: 500,
+ body: JSON.stringify(err),
+ };
+ }
+ }
+};
diff --git a/package.json b/package.json
index b477d9a..d49ef4e 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"color": "^2.0.1",
"craco-antd": "^1.19.0",
"date-fns": "^2.0.1",
+ "faunadb": "2.6.1",
"file-saver": "2.0.0",
"graphql": "^14.5.8",
"graphql-request": "^1.8.2",
@@ -64,7 +65,7 @@
"upload-schema": "yarn checkForFaunaKey && curl -u $FAUNADB_SERVER_SECRET: https://graphql.fauna.com/import --data-binary \"@schema.gql\"",
"start:server": "yarn upload-schema && netlify-lambda serve functions -c ./webpack.config.js",
"start:devserver": "NODE_ENV=development yarn start:server",
- "build": "npm-run-all --parallel build:**",
+ "build": "CI=false npm-run-all --parallel build:**",
"build:app": "craco build",
"build:functions": "netlify-lambda build functions -c ./webpack.config.js",
"test": "craco test --env=jsdom",
diff --git a/src/utils/middleware.js b/src/utils/middleware.js
new file mode 100644
index 0000000..5c3d94b
--- /dev/null
+++ b/src/utils/middleware.js
@@ -0,0 +1,58 @@
+import netlifyIdentity from 'netlify-identity-widget';
+const API_URL = `/.netlify/functions`;
+
+export const apiDeleteProject = async id => {
+ const url = `${API_URL}/project/${id}`;
+ return fetcher(url, { method: 'DELETE' });
+};
+
+export const apiPatchProject = async (id, data) => {
+ const url = `${API_URL}/project/${id}`;
+ return fetcher(url, {
+ method: 'PATCH',
+ body: JSON.stringify(data),
+ });
+};
+
+export const apiPostProject = async data => {
+ const url = `${API_URL}/project`;
+ return fetcher(url, {
+ method: 'POST',
+ body: JSON.stringify(data),
+ });
+};
+
+export const fetchProject = async id => {
+ const url = `${API_URL}/project/${id}`;
+ return fetcher(url);
+};
+
+export const fetchAllProjects = async pagination => {
+ const queryParams = new URLSearchParams(pagination);
+ const url = `${API_URL}/all-projects?${queryParams}`;
+ return fetcher(url);
+};
+
+export const fetchMyProjects = async pagination => {
+ const queryParams = new URLSearchParams(pagination);
+ const url = `${API_URL}/my-projects?${queryParams}`;
+ return fetcher(url);
+};
+
+export const fetcher = async (url, opts) => {
+ const currentUser = netlifyIdentity.currentUser();
+ let token;
+ if (currentUser) {
+ token = await currentUser.jwt();
+ }
+ const res = await fetch(url, {
+ headers: {
+ authorization: token ? `Bearer ${token}` : '',
+ },
+ ...opts,
+ });
+ if (!res.ok) {
+ throw new Error(res.statusText);
+ }
+ return res.json();
+};
diff --git a/src/views/DiscoverGQL/index.js b/src/views/DiscoverGQL/index.js
index e87e5dc..5af3af0 100644
--- a/src/views/DiscoverGQL/index.js
+++ b/src/views/DiscoverGQL/index.js
@@ -1,34 +1,37 @@
-import React, { useState } from 'react';
-import { useQuery } from '@apollo/react-hooks';
-
+import React, { useEffect, useState } from 'react';
import ProjectList from 'components/ProjectList';
import Loading from 'components/Loading';
import PageContainer from 'components/PageContainer';
-import { GET_ALL_PROJECTS_SORTED_BY_DATE_CREATED } from 'graphql/queries';
import ErrorMessage from 'components/ErrorMessage';
+import { fetchAllProjects } from 'utils/middleware';
function DiscoverGQLContainer() {
- const pageSize = 24;
- const [cursor, setCursor] = useState(null);
- const { loading, error, data } = useQuery(
- GET_ALL_PROJECTS_SORTED_BY_DATE_CREATED,
- { variables: { _size: pageSize, _cursor: cursor } }
- );
+ const [pagination, setPagination] = useState({});
+ const [{ loading, error, data }, setResult] = useState({ loading: true });
+
+ useEffect(() => {
+ setResult({ loading: true });
+ const fetchData = async () => {
+ try {
+ const result = await fetchAllProjects(pagination);
+ setResult({ loading: false, data: result });
+ } catch (error) {
+ setResult({ loading: false, error });
+ }
+ };
+ fetchData();
+ }, [pagination]);
- if (loading) return ;
if (error) return ;
+ if (!data || loading) return ;
- const {
- before,
- after,
- data: projectsData,
- } = data.allProjectsSortedByDateCreated;
+ const { before, after, data: projectsData } = data;
const onNextPageClick = () => {
- setCursor(after);
+ setPagination({ after });
};
const onPrevPageClick = () => {
- setCursor(before);
+ setPagination({ before });
};
return (
diff --git a/src/views/ProjectCreate/index.jsx b/src/views/ProjectCreate/index.jsx
index 52aea29..7c396cb 100644
--- a/src/views/ProjectCreate/index.jsx
+++ b/src/views/ProjectCreate/index.jsx
@@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import { withRouter } from 'react-router';
-import { useMutation } from '@apollo/react-hooks';
+// import { useMutation } from '@apollo/react-hooks';
import { DEFAULT_PROJECT, getProjectSaveData } from 'utils/project';
import { CurrentUserContext } from 'context/CurrentUserContext/CurrentUserContextProvider';
@@ -11,31 +11,14 @@ import {
showSuccessMessage,
} from 'utils/message';
import ProjectContainer from 'components/Project';
-import { CREATE_PROJECT } from 'graphql/mutations';
-import { GET_ALL_PROJECTS, GET_MY_PROJECTS } from 'graphql/queries';
import { ROUTES } from 'Routes';
+import { apiPostProject } from 'utils/middleware';
function ProjectCreate(props) {
const { user: currentUser, authenticate } = useContext(CurrentUserContext);
const { history } = props;
- const [createProjectMutation] = useMutation(CREATE_PROJECT, {
- refetchQueries: () => [
- { query: GET_ALL_PROJECTS },
- { query: GET_MY_PROJECTS },
- ],
- onError: showErrorMessage,
- onCompleted: ({ createProject }) => {
- const { _id, name } = createProject;
- showSuccessMessage(`Saved "${name}"`);
- history.push({
- pathname: `${ROUTES.PROJECT}/${_id}`,
- state: { projectData: createProject },
- });
- },
- });
-
- const saveProject = project => {
+ const saveProject = async project => {
/* TODO: Automatically save on user login success */
if (!currentUser) {
authenticate();
@@ -44,11 +27,18 @@ function ProjectCreate(props) {
showLoadingMessage('Saving...');
const projectSaveData = getProjectSaveData(project);
- createProjectMutation({
- variables: {
- data: projectSaveData,
- },
- });
+ try {
+ const { data: savedProject } = await apiPostProject(projectSaveData);
+ console.log({ savedProject });
+ showSuccessMessage(`Saved "${savedProject.name}"`);
+ history.push({
+ pathname: `${ROUTES.PROJECT}/${savedProject._id}`,
+ state: { projectData: savedProject },
+ });
+ } catch (error) {
+ showErrorMessage(error);
+ return;
+ }
};
const projectProps = {
diff --git a/src/views/ProjectEdit/index.jsx b/src/views/ProjectEdit/index.jsx
index 771eb13..f1faabb 100644
--- a/src/views/ProjectEdit/index.jsx
+++ b/src/views/ProjectEdit/index.jsx
@@ -1,6 +1,6 @@
-import React, { useContext } from 'react';
+import React from 'react';
+import { useContext, useEffect, useState } from 'react';
import { CurrentUserContext } from 'context/CurrentUserContext/CurrentUserContextProvider';
-import { useQuery, useMutation } from '@apollo/react-hooks';
import { withRouter } from 'react-router';
import Loading from 'components/Loading';
@@ -14,13 +14,12 @@ import {
import { DEFAULT_SYNTHS } from 'utils/synths';
import { ROUTES } from 'Routes';
-import {
- GET_PROJECT,
- GET_ALL_PROJECTS,
- GET_MY_PROJECTS,
-} from 'graphql/queries';
-import { UPDATE_PROJECT, DELETE_PROJECT } from 'graphql/mutations';
import ErrorMessage from 'components/ErrorMessage';
+import {
+ apiDeleteProject,
+ apiPatchProject,
+ fetchProject,
+} from 'utils/middleware';
function ProjectEdit(props) {
const {
@@ -33,40 +32,27 @@ function ProjectEdit(props) {
console.log('ProjectEdit render. projectId:', projectId);
- const { loading, data, error } = useQuery(GET_PROJECT, {
- skip: !!projectData,
- variables: { id: projectId },
- });
-
- const [saveProjectMutation] = useMutation(UPDATE_PROJECT, {
- onError: showErrorMessage,
- onCompleted: ({ updateProject }) => {
- const { name } = updateProject;
- showSuccessMessage(`Saved "${name}"`);
- // Update local state that may contain old data
- history.push({
- state: { projectData: updateProject },
- });
- },
- });
-
- const [deleteProjectMutation] = useMutation(DELETE_PROJECT, {
- refetchQueries: () => [
- { query: GET_ALL_PROJECTS },
- { query: GET_MY_PROJECTS },
- ],
- onError: showErrorMessage,
- onCompleted: ({ deleteProject }) => {
- const { name } = deleteProject;
- showSuccessMessage(`Deleted "${name}"`);
- history.push(ROUTES.INDEX);
- },
- });
+ const [{ loading, data, error }, setResult] = useState({ loading: true });
+
+ useEffect(() => {
+ setResult({ loading: true });
+ const fetchData = async () => {
+ try {
+ const result = await fetchProject(projectId);
+ console.log({ result });
+ setResult({ loading: false, data: result });
+ } catch (error) {
+ setResult({ loading: false, error });
+ }
+ };
+ fetchData();
+ }, [projectId]);
if (loading) return ;
if (error) return ;
- const project = projectData || data.findProjectByID;
+ const project = projectData || data.data;
+ console.log({ project });
const { shapesList, selectedSynths } = project;
const newSelectedSynths =
@@ -82,21 +68,30 @@ function ProjectEdit(props) {
})),
};
- const saveProject = project => {
+ const saveProject = async project => {
showLoadingMessage('Saving...');
const projectSaveData = getProjectSaveData(project);
- console.log('project save data', projectSaveData);
- saveProjectMutation({
- variables: {
- id: projectId,
- data: projectSaveData,
- },
- });
+ try {
+ const updatedProject = await apiPatchProject(projectId, projectSaveData);
+ showSuccessMessage(`Saved "${updatedProject.data.name}"`);
+ history.push({
+ state: { projectData: updatedProject.data },
+ });
+ } catch (error) {
+ showErrorMessage(error.message);
+ }
};
- const deleteProject = () => {
+ const deleteProject = async () => {
showLoadingMessage('Deleting...');
- deleteProjectMutation({ variables: { id: newProjectData._id } });
+ try {
+ const { data: deletedProject } = await apiDeleteProject(projectId);
+ showSuccessMessage(`Deleted "${deletedProject.name}"`);
+ history.push(ROUTES.INDEX);
+ } catch (error) {
+ showErrorMessage(error.message);
+ }
+ // deleteProjectMutation({ variables: { id: newProjectData._id } });
};
const userIsProjectAuthor =
diff --git a/src/views/UserProjects/index.js b/src/views/UserProjects/index.js
index 3ae0f03..8a2a30d 100644
--- a/src/views/UserProjects/index.js
+++ b/src/views/UserProjects/index.js
@@ -1,5 +1,4 @@
-import React, { useContext } from 'react';
-import { useQuery } from '@apollo/react-hooks';
+import React, { useContext, useEffect, useState } from 'react';
import { Alert } from 'antd';
import PageContainer from 'components/PageContainer';
@@ -7,12 +6,41 @@ import ProjectList from 'components/ProjectList';
import Loading from 'components/Loading';
import { CurrentUserContext } from 'context/CurrentUserContext/CurrentUserContextProvider';
import { getUserName } from 'utils/user';
-import { GET_MY_PROJECTS } from 'graphql/queries';
import ErrorMessage from 'components/ErrorMessage';
+import { fetchMyProjects } from 'utils/middleware';
function UserProjects() {
const { user } = useContext(CurrentUserContext);
- const { loading, error, data } = useQuery(GET_MY_PROJECTS, { skip: !user });
+ const [pagination, setPagination] = useState({});
+ const [{ loading, error, data }, setResult] = useState({ loading: true });
+
+ useEffect(() => {
+ setResult({ loading: true });
+ const fetchData = async () => {
+ try {
+ const result = await fetchMyProjects(pagination);
+ setResult({ loading: false, data: result });
+ } catch (error) {
+ setResult({ loading: false, error });
+ }
+ };
+ fetchData();
+ }, [pagination]);
+
+ if (error) return ;
+ if (!data || loading) return ;
+
+ const {
+ // before, after,
+ data: projectsData,
+ } = data;
+
+ // const onNextPageClick = () => {
+ // setPagination({ after });
+ // };
+ // const onPrevPageClick = () => {
+ // setPagination({ before });
+ // };
if (!user)
return (
@@ -31,7 +59,11 @@ function UserProjects() {
);
diff --git a/yarn.lock b/yarn.lock
index 71cf129..8132d37 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3949,6 +3949,11 @@ base64-js@^1.0.2:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
+base64-js@^1.2.0:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
+ integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+
base@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@@ -4181,6 +4186,11 @@ bser@^2.0.0:
dependencies:
node-int64 "^0.4.0"
+btoa-lite@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337"
+ integrity sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==
+
buffer-from@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
@@ -4302,6 +4312,17 @@ call-bind@^1.0.0:
function-bind "^1.1.1"
get-intrinsic "^1.0.0"
+call-bind@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
+ integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.4"
+ set-function-length "^1.2.1"
+
call-me-maybe@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
@@ -4665,6 +4686,11 @@ component-classes@^1.2.5:
dependencies:
component-indexof "0.0.3"
+component-emitter@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17"
+ integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==
+
component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
@@ -4798,6 +4824,11 @@ cookie@^0.3.1:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
+cookiejar@^2.1.0:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b"
+ integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==
+
copy-concurrently@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
@@ -5288,6 +5319,13 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "^2.1.1"
+debug@^3.1.0:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
+ integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
+ dependencies:
+ ms "^2.1.1"
+
debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@@ -5335,6 +5373,15 @@ default-gateway@^4.2.0:
execa "^1.0.0"
ip-regex "^2.1.0"
+define-data-property@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
+ integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ gopd "^1.0.1"
+
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -5782,6 +5829,18 @@ es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1:
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
+es-define-property@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
+ integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
+ dependencies:
+ get-intrinsic "^1.2.4"
+
+es-errors@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
+ integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
+
es-to-primitive@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
@@ -5818,6 +5877,11 @@ es6-iterator@2.0.3, es6-iterator@~2.0.3:
es5-ext "^0.10.35"
es6-symbol "^3.1.1"
+es6-promise@^4.1.1:
+ version "4.2.8"
+ resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
+ integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
+
es6-symbol@^3.1.1, es6-symbol@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
@@ -6242,7 +6306,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
assign-symbols "^1.0.0"
is-extendable "^1.0.1"
-extend@~3.0.2:
+extend@^3.0.0, extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@@ -6335,6 +6399,19 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.0"
+faunadb@2.6.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/faunadb/-/faunadb-2.6.1.tgz#90783b32da13dd5500a873aca2629543eaa8d51f"
+ integrity sha512-n/aRPDqrE7Sor7qzNDvZHmM7nEw0wERZZPjXRx1sBS3+9mJAscFa4zOQMgbh+pTz8M3r6Djd3vxl11JLn3eSMA==
+ dependencies:
+ base64-js "^1.2.0"
+ btoa-lite "^1.0.0"
+ es6-promise "^4.1.1"
+ fn-annotate "^1.1.3"
+ object-assign "^4.1.0"
+ superagent "^3.8.1"
+ util-deprecate "^1.0.2"
+
faye-websocket@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
@@ -6525,6 +6602,11 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
+fn-annotate@^1.1.3:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/fn-annotate/-/fn-annotate-1.2.0.tgz#28da000117dea61842fe61f353f41cf4c93a7a7e"
+ integrity sha512-j2gv2wkRhQgkJNf1ygdca8ynP3tK+a87bowc+RG81iWTye3yKIOeAkrKYv0Kqyh8yCeSyljOk3ZFelfXUFpirA==
+
follow-redirects@^1.0.0:
version "1.14.8"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
@@ -6566,6 +6648,15 @@ fork-ts-checker-webpack-plugin@3.1.1:
tapable "^1.0.0"
worker-rpc "^0.1.0"
+form-data@^2.3.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
+ integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.6"
+ mime-types "^2.1.12"
+
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
@@ -6575,6 +6666,11 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
+formidable@^1.2.0:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168"
+ integrity sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==
+
forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
@@ -6696,6 +6792,11 @@ function-bind@^1.0.2, function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+function-bind@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+
functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
@@ -6734,6 +6835,17 @@ get-intrinsic@^1.0.0:
has "^1.0.3"
has-symbols "^1.0.1"
+get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
+ integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
+ dependencies:
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ has-proto "^1.0.1"
+ has-symbols "^1.0.3"
+ hasown "^2.0.0"
+
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz#6f7764f88ea11e0b514bd9bd860a132259992ca4"
@@ -6875,6 +6987,13 @@ globby@^6.1.0:
pify "^2.0.0"
pinkie-promise "^2.0.0"
+gopd@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
+ integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+ dependencies:
+ get-intrinsic "^1.1.3"
+
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
@@ -6992,6 +7111,18 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+has-property-descriptors@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
+ integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
+ dependencies:
+ es-define-property "^1.0.0"
+
+has-proto@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
+ integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
+
has-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
@@ -7002,6 +7133,11 @@ has-symbols@^1.0.1:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
+has-symbols@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
+ integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -7061,6 +7197,13 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"
+hasown@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
+ integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
+ dependencies:
+ function-bind "^1.1.2"
+
he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
@@ -9011,7 +9154,7 @@ merge2@^1.2.3, merge2@^1.3.0:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
-methods@~1.1.2:
+methods@^1.1.1, methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
@@ -9628,6 +9771,11 @@ object-hash@^2.0.1:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea"
integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg==
+object-inspect@^1.13.1:
+ version "1.13.1"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2"
+ integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
+
object-inspect@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
@@ -11111,6 +11259,13 @@ qs@6.7.0:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
+qs@^6.5.1:
+ version "6.12.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.0.tgz#edd40c3b823995946a8a0b1f208669c7a200db77"
+ integrity sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==
+ dependencies:
+ side-channel "^1.0.6"
+
qs@~6.5.2:
version "6.5.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
@@ -11975,6 +12130,19 @@ read-pkg@^3.0.0:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
+readable-stream@^2.3.5:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
readable-stream@^3.0.6, readable-stream@^3.1.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc"
@@ -12605,6 +12773,18 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
+set-function-length@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
+ integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
+ dependencies:
+ define-data-property "^1.1.4"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.4"
+ gopd "^1.0.1"
+ has-property-descriptors "^1.0.2"
+
set-immediate-shim@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
@@ -12714,6 +12894,16 @@ side-channel@^1.0.2:
es-abstract "^1.18.0-next.0"
object-inspect "^1.8.0"
+side-channel@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
+ integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==
+ dependencies:
+ call-bind "^1.0.7"
+ es-errors "^1.3.0"
+ get-intrinsic "^1.2.4"
+ object-inspect "^1.13.1"
+
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@@ -13231,6 +13421,22 @@ subscriptions-transport-ws@^0.9.11:
symbol-observable "^1.0.4"
ws "^5.2.0"
+superagent@^3.8.1:
+ version "3.8.3"
+ resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128"
+ integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==
+ dependencies:
+ component-emitter "^1.2.0"
+ cookiejar "^2.1.0"
+ debug "^3.1.0"
+ extend "^3.0.0"
+ form-data "^2.3.1"
+ formidable "^1.2.0"
+ methods "^1.1.1"
+ mime "^1.4.1"
+ qs "^6.5.1"
+ readable-stream "^2.3.5"
+
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"