diff --git a/pages/api/ipfs/index.ts b/pages/api/ipfs/index.ts index 6d5c9b1fe..e77a39815 100644 --- a/pages/api/ipfs/index.ts +++ b/pages/api/ipfs/index.ts @@ -1,8 +1,7 @@ +import { IOMarketMetadata } from "@zeitgeistpm/sdk"; import { create as createIPFSClient } from "ipfs-http-client"; import type { PageConfig } from "next"; import { NextApiRequest, NextApiResponse } from "next"; -import { fromZodError } from "zod-validation-error"; -import { IOMarketMetadata } from "./types"; export const config: PageConfig = { runtime: "nodejs", @@ -17,6 +16,8 @@ export default async function handler( } } +const MAX_METADATA_SIZE_KB = 10; + const POST = async (req: NextApiRequest, res: NextApiResponse) => { const node = createIPFSClient({ url: process.env.NEXT_PUBLIC_IPFS_NODE_URL, @@ -29,28 +30,44 @@ const POST = async (req: NextApiRequest, res: NextApiResponse) => { }, }); - const parsed = IOMarketMetadata.safeParse(req.body); + const [error, metadata] = IOMarketMetadata.validate(req.body); const onlyHash = req.query["only-hash"] === "true" ? true : false; - if (!parsed.success) { - return res.status(400).json({ - message: fromZodError(parsed.error).toString(), - }); + if (error) { + return res + .status(400) + .setHeader("Content-Type", "application/problem+json; charset=utf-8") + .send( + JSON.stringify({ + title: "Invalid Market Metadata", + detail: "The market metadata provided is invalid.", + message: "The market metadata provided is invalid.", + context: { + failures: error.failures(), + }, + }), + ); } - const metadata = { - __meta: "markets", - ...parsed.data, - }; - const content = JSON.stringify(metadata); const kbSize = Buffer.byteLength(content) / 1024; - if (kbSize > 10) { - return res.status(400).json({ - message: "Market metadata is too large. Please keep it under 10kb.", - }); + if (kbSize > MAX_METADATA_SIZE_KB) { + return res + .status(400) + .setHeader("Content-Type", "application/problem+json; charset=utf-8") + .send( + JSON.stringify({ + title: "Invalid Market Metadata", + detail: `Market metadata is too large. Please keep it under ${MAX_METADATA_SIZE_KB}kb.`, + message: `Market metadata is too large. Please keep it under ${MAX_METADATA_SIZE_KB}kb.`, + context: { + maxKb: MAX_METADATA_SIZE_KB, + metadataSizeKb: kbSize, + }, + }), + ); } try { const { cid } = await node.add( @@ -62,10 +79,6 @@ const POST = async (req: NextApiRequest, res: NextApiResponse) => { }, ); - // if (!onlyHash) { - // await node.pin.add(cid); - // } - return res.status(200).json({ message: `Market metadata ${ onlyHash ? "hashed" : "pinned" @@ -78,29 +91,3 @@ const POST = async (req: NextApiRequest, res: NextApiResponse) => { }); } }; - -// const DELETE = async (req: NextRequest) => { -// const { cid } = JSON.parse(await extractBody(req)); - -// try { -// await node.pin.rm(IPFSHTTPClient.CID.parse(cid)); - -// return new Response( -// JSON.stringify({ -// message: `Market metadata(cid: ${cid}) unpinned successfully.`, -// }), -// { -// status: 200, -// }, -// ); -// } catch (error) { -// return new Response( -// JSON.stringify({ -// message: error.message, -// }), -// { -// status: 500, -// }, -// ); -// } -// };