-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* remove reliance on fauna GQL API. revert to older CRUD style API * add my projects endpoint * add CI=false * add date created to preview
- Loading branch information
Showing
12 changed files
with
604 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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), | ||
}; | ||
}), | ||
}), | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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), | ||
}; | ||
}), | ||
}), | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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' }; | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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), | ||
}; | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.