From 08ec2fa6d5bb13b037151e7ed919b6ad0894b8cd Mon Sep 17 00:00:00 2001 From: gloria Date: Wed, 22 Jan 2025 14:38:58 +0100 Subject: [PATCH 01/31] add version 2 --- apps/contact/vercel.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 apps/contact/vercel.json diff --git a/apps/contact/vercel.json b/apps/contact/vercel.json new file mode 100644 index 00000000..26ae9d44 --- /dev/null +++ b/apps/contact/vercel.json @@ -0,0 +1,21 @@ +{ + "version": 2, + "installCommand": "curl -fsSL https://bun.sh/install | bash && ~/.bun/bin/bun install --frozen-lockfile", + "buildCommand": "~/.bun/bin/bun run build", + "functions": { + "index.ts": { + "memory": 256, + "maxDuration": 5, + "runtime": "vercel/bun" + } + }, + "routes": [ + { + "src": "/", + "methods": [ + "POST" + ], + "dest": "index.ts" + } + ] +} \ No newline at end of file From b60c41bd3f3043636461756789e380bcfa20a52a Mon Sep 17 00:00:00 2001 From: gloria Date: Wed, 22 Jan 2025 14:42:39 +0100 Subject: [PATCH 02/31] add bun version --- apps/contact/vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/contact/vercel.json b/apps/contact/vercel.json index 26ae9d44..fa039c18 100644 --- a/apps/contact/vercel.json +++ b/apps/contact/vercel.json @@ -6,7 +6,7 @@ "index.ts": { "memory": 256, "maxDuration": 5, - "runtime": "vercel/bun" + "runtime": "vercel/bun@1.1.45" } }, "routes": [ From 361e93f5c64319e38f6f08538d2e275c13e5efc6 Mon Sep 17 00:00:00 2001 From: gloria Date: Wed, 22 Jan 2025 16:13:57 +0100 Subject: [PATCH 03/31] add api folder --- apps/contact/api/index.ts | 386 ++++++++++++++++++++++++++++++++++++++ apps/contact/vercel.json | 4 +- 2 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 apps/contact/api/index.ts diff --git a/apps/contact/api/index.ts b/apps/contact/api/index.ts new file mode 100644 index 00000000..73248e06 --- /dev/null +++ b/apps/contact/api/index.ts @@ -0,0 +1,386 @@ +import { Client, isFullPage } from "@notionhq/client"; +import { Ratelimit } from "@upstash/ratelimit"; +import { Redis } from "@upstash/redis"; +import { nanoid } from "nanoid"; +import z from "zod"; + +const bodyValidationSchema = z.object({ + name: z + .string() + .min(3, { message: "Name must be at least 3 characters long" }), + email: z + .string() + .min(1, { message: "Required field" }) + .email({ message: "Invalid email adress" }), + message: z.string().min(1, { message: "Required field" }), + hasConsent: z.boolean().optional(), +}); + +type RequestBody = z.infer; + +const { + NOTION_TOKEN, + SLACK_CHANNEL, + SLACK_BOT_TOKEN, + MENTION_EMAILS, + MENTION_IDS, + NOTION_DATABASE_ID, + UPSTASH_REDIS_REST_URL, + UPSTASH_REDIS_REST_TOKEN, + IS_OFFLINE, +} = process.env; + +const notion = new Client({ auth: NOTION_TOKEN }); + +const redis = new Redis({ + url: UPSTASH_REDIS_REST_URL, + token: UPSTASH_REDIS_REST_TOKEN, +}); + +const createPayload = (name: string, email: string, url: string) => ({ + channel: SLACK_CHANNEL, + blocks: [ + { + type: "header", + text: { + type: "plain_text", + text: "We have 1 new message(s).", + emoji: true, + }, + }, + { + type: "section", + text: { + type: "mrkdwn", + text: `We got a new message from _${name}_ (_${email}_).`, + }, + }, + { + type: "divider", + }, + { + type: "section", + text: { + type: "mrkdwn", + text: " ", + }, + accessory: { + type: "button", + text: { + type: "plain_text", + text: "Show me the message", + emoji: true, + }, + value: "new_message_click", + url, + action_id: "button-action", + }, + }, + ], +}); + +const notifyContactCreated = async ( + name: string, + email: string, + url: string, +) => { + const payload = createPayload(name, email, url); + const payloadStringify = JSON.stringify(payload); + + if (IS_OFFLINE) { + console.log(payload); + } else { + try { + const result = await fetch("https://slack.com/api/chat.postMessage", { + method: "POST", + body: payloadStringify, + headers: { + "Content-Type": "application/json; charset=utf-8", + "Content-Length": payloadStringify.length.toString(), + Authorization: `Bearer ${SLACK_BOT_TOKEN}`, + Accept: "application/json", + }, + }); + if (result.status !== 200) { + throw { + statusCode: result.status, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Credentials": true, + }, + }; + } + } catch (error) { + throw error; + } + } +}; + +const mentionPerson = ({ id, email }: { id: string; email: string }) => [ + { + mention: { + user: { + id, + person: { + email, + }, + }, + }, + plain_text: "", + href: null, + }, + { + text: { + content: " ", + }, + }, +]; + +const getMentions = () => { + if (MENTION_EMAILS && MENTION_IDS) { + const emails = MENTION_EMAILS.split(","); + const ids = MENTION_IDS.split(","); + + if (emails.length && ids.length) { + return ids.map((id, i) => ({ + id, + email: emails[i], + })); + } + } + return []; +}; + +const mentionPeople = () => { + return getMentions().flatMap(mentionPerson); +}; + +const createContactObject = ( + id: string, + email: string, + name: string, + content: string, +) => ({ + parent: { + database_id: NOTION_DATABASE_ID || "", + }, + properties: { + id: { + title: [ + { + text: { + content: id, + }, + }, + ], + }, + email: { + email, + }, + name: { + rich_text: [ + { + text: { + content: name, + }, + }, + ], + }, + date: { + date: { + start: new Date().toISOString(), + }, + }, + }, + children: [ + { + paragraph: { + rich_text: [ + { + text: { + content, + }, + }, + ], + }, + }, + { + paragraph: { + rich_text: mentionPeople(), + }, + }, + ], +}); + +const createContact = async ( + id: string, + email: string, + name: string, + content: string, +) => { + try { + const response = await notion.pages.create( + createContactObject(id, email, name, content), + ); + + if (response.id && isFullPage(response)) { + return response.url; + } + throw { + body: { + message: "Failed to create notion page", + }, + }; + } catch (error) { + throw error; + } +}; + +const processContact = async (event: { + id: string; + email: string; + name: string; + message: string; +}) => { + try { + const { id, email, name, message } = event; + + if (!id || !email || !name || !message) { + throw { + body: { + message: "Missing id, email, name or message", + }, + }; + } + + const url = await createContact( + `Message from ${name} (${id})`, + email, + name, + message, + ); + await notifyContactCreated(name, email, url); + } catch (error) { + throw error; + } +}; + +const allowRequest = async (request: Request & { ip?: string }) => { + try { + const ip = request.ip ?? "127.0.0.1"; + + const ratelimit = new Ratelimit({ + limiter: Ratelimit.fixedWindow(1, "30 s"), + /** Use fromEnv() to automatically load connection secrets from your environment + * variables. For instance when using the Vercel integration. + * + * This tries to load `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` from + * your environment using `import.meta.env`. + */ + redis, + }); + + const response = await ratelimit.limit(ip); + return response; + } catch (error) { + throw { + body: { + message: error, + }, + }; + } +}; + +export const POST = async (request: Request) => { + if (request.headers.get("Content-Type") === "application/json") { + try { + const body = (await request.json()) as RequestBody; + const bodyValidationResult = bodyValidationSchema.safeParse(body); + + if (!body || bodyValidationResult.error) { + throw { + statusCode: 400, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Credentials": true, + }, + body: { + message: bodyValidationResult.error?.message || "No body was found", + }, + }; + } + + const { name, email, message, hasConsent } = body; + + if (!hasConsent) { + throw { + statusCode: 403, + body: { + message: "No consent by user", + }, + }; + } + + const { success, limit, reset, remaining } = await allowRequest(request); + + if (!success) { + throw { + statusCode: 429, + body: { + message: "Too many requests. Please try again in a minute", + }, + }; + } + + try { + await processContact({ + id: nanoid(), + email, + name, + message, + }); + } catch (error) { + throw error; + } + + return new Response( + JSON.stringify({ + message: "Success", + }), + { + status: 200, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Credentials": "true", + "X-RateLimit-Limit": limit.toString(), + "X-RateLimit-Remaining": remaining.toString(), + "X-RateLimit-Reset": reset.toString(), + }, + }, + ); + } catch (error) { + const customError = error as Error & { + statusCode?: number; + body?: { + message?: string; + }; + headers?: HeadersInit; + }; + + console.error("Error - api/contacts", customError); + + return new Response( + JSON.stringify({ + message: + customError?.body?.message || "Issue while processing request", + }), + { + status: customError.statusCode || 501, + headers: customError?.headers, + }, + ); + } + } + + return new Response(null, { status: 400 }); +}; diff --git a/apps/contact/vercel.json b/apps/contact/vercel.json index fa039c18..b766ff3c 100644 --- a/apps/contact/vercel.json +++ b/apps/contact/vercel.json @@ -3,7 +3,7 @@ "installCommand": "curl -fsSL https://bun.sh/install | bash && ~/.bun/bin/bun install --frozen-lockfile", "buildCommand": "~/.bun/bin/bun run build", "functions": { - "index.ts": { + "api/index.ts": { "memory": 256, "maxDuration": 5, "runtime": "vercel/bun@1.1.45" @@ -11,7 +11,7 @@ }, "routes": [ { - "src": "/", + "src": "/api/index.ts", "methods": [ "POST" ], From a409a362688523e9331bc12242dffbdabcae46cc Mon Sep 17 00:00:00 2001 From: gloria Date: Wed, 22 Jan 2025 16:30:00 +0100 Subject: [PATCH 04/31] change runtime --- apps/contact/index.ts | 1 + apps/contact/vercel.json | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 apps/contact/index.ts diff --git a/apps/contact/index.ts b/apps/contact/index.ts new file mode 100644 index 00000000..f67b2c64 --- /dev/null +++ b/apps/contact/index.ts @@ -0,0 +1 @@ +console.log("Hello via Bun!"); \ No newline at end of file diff --git a/apps/contact/vercel.json b/apps/contact/vercel.json index b766ff3c..a5648f50 100644 --- a/apps/contact/vercel.json +++ b/apps/contact/vercel.json @@ -5,8 +5,7 @@ "functions": { "api/index.ts": { "memory": 256, - "maxDuration": 5, - "runtime": "vercel/bun@1.1.45" + "maxDuration": 5 } }, "routes": [ From 8dddc913cc2c9d3c1be5f153511eb6f323836ef6 Mon Sep 17 00:00:00 2001 From: gloria Date: Wed, 22 Jan 2025 16:31:40 +0100 Subject: [PATCH 05/31] add build script to package --- apps/contact/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/contact/package.json b/apps/contact/package.json index 02123027..58727064 100644 --- a/apps/contact/package.json +++ b/apps/contact/package.json @@ -24,4 +24,4 @@ "@types/react": "^19", "@types/react-dom": "^19" } -} +} \ No newline at end of file From 4a0918736cb2ffe37135f2554b16288dbd501273 Mon Sep 17 00:00:00 2001 From: gloria Date: Wed, 22 Jan 2025 16:39:18 +0100 Subject: [PATCH 06/31] remove bun --- apps/contact/.gitignore | 41 -------------------------------------- apps/contact/README.md | 36 --------------------------------- apps/contact/index.ts | 1 - apps/contact/tsconfig.json | 23 ++++++++++++++++----- apps/contact/vercel.json | 2 -- 5 files changed, 18 insertions(+), 85 deletions(-) delete mode 100644 apps/contact/.gitignore delete mode 100644 apps/contact/README.md delete mode 100644 apps/contact/index.ts diff --git a/apps/contact/.gitignore b/apps/contact/.gitignore deleted file mode 100644 index 5ef6a520..00000000 --- a/apps/contact/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# env files (can opt-in for committing if needed) -.env* - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/apps/contact/README.md b/apps/contact/README.md deleted file mode 100644 index e215bc4c..00000000 --- a/apps/contact/README.md +++ /dev/null @@ -1,36 +0,0 @@ -This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/apps/contact/index.ts b/apps/contact/index.ts deleted file mode 100644 index f67b2c64..00000000 --- a/apps/contact/index.ts +++ /dev/null @@ -1 +0,0 @@ -console.log("Hello via Bun!"); \ No newline at end of file diff --git a/apps/contact/tsconfig.json b/apps/contact/tsconfig.json index d8b93235..9c7e071f 100644 --- a/apps/contact/tsconfig.json +++ b/apps/contact/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2017", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -19,9 +23,18 @@ } ], "paths": { - "@/*": ["./*"] + "@/*": [ + "./*" + ] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] -} + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/apps/contact/vercel.json b/apps/contact/vercel.json index a5648f50..05ad6168 100644 --- a/apps/contact/vercel.json +++ b/apps/contact/vercel.json @@ -1,7 +1,5 @@ { "version": 2, - "installCommand": "curl -fsSL https://bun.sh/install | bash && ~/.bun/bin/bun install --frozen-lockfile", - "buildCommand": "~/.bun/bin/bun run build", "functions": { "api/index.ts": { "memory": 256, From 929352366d031c28d2f6cd127344ff827342c471 Mon Sep 17 00:00:00 2001 From: gloria Date: Wed, 22 Jan 2025 17:01:35 +0100 Subject: [PATCH 07/31] change runtime --- apps/contact/api/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/contact/api/index.ts b/apps/contact/api/index.ts index 73248e06..d891d8ce 100644 --- a/apps/contact/api/index.ts +++ b/apps/contact/api/index.ts @@ -1,3 +1,5 @@ +export const runtime = 'nodejs'; + import { Client, isFullPage } from "@notionhq/client"; import { Ratelimit } from "@upstash/ratelimit"; import { Redis } from "@upstash/redis"; From 529a3524f0f2e542a32f90b69a05eb853a30186b Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 09:19:10 +0100 Subject: [PATCH 08/31] feat[web-27]: use vercel req and res --- apps/contact/.gitignore | 37 +++++++++ apps/contact/api/index.ts | 159 +++++++++++++++++--------------------- 2 files changed, 109 insertions(+), 87 deletions(-) create mode 100644 apps/contact/.gitignore diff --git a/apps/contact/.gitignore b/apps/contact/.gitignore new file mode 100644 index 00000000..e02215bd --- /dev/null +++ b/apps/contact/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# Dependencies +/node_modules +/.pnp +.pnp.js + +# Testing +/coverage + +# Production +build +dist + +# Misc +.DS_Store +*.pem + +# Debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Local ENV files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Vercel +.vercel + +# Turborepo +.turbo + +# typescript +*.tsbuildinfo \ No newline at end of file diff --git a/apps/contact/api/index.ts b/apps/contact/api/index.ts index d891d8ce..94a0f6da 100644 --- a/apps/contact/api/index.ts +++ b/apps/contact/api/index.ts @@ -1,10 +1,9 @@ -export const runtime = 'nodejs'; - import { Client, isFullPage } from "@notionhq/client"; import { Ratelimit } from "@upstash/ratelimit"; import { Redis } from "@upstash/redis"; import { nanoid } from "nanoid"; import z from "zod"; +import type { VercelRequest, VercelResponse } from "@vercel/node"; const bodyValidationSchema = z.object({ name: z @@ -18,8 +17,6 @@ const bodyValidationSchema = z.object({ hasConsent: z.boolean().optional(), }); -type RequestBody = z.infer; - const { NOTION_TOKEN, SLACK_CHANNEL, @@ -144,7 +141,7 @@ const getMentions = () => { const ids = MENTION_IDS.split(","); if (emails.length && ids.length) { - return ids.map((id, i) => ({ + return ids.map((id: any, i: string | number) => ({ id, email: emails[i], })); @@ -267,7 +264,7 @@ const processContact = async (event: { } }; -const allowRequest = async (request: Request & { ip?: string }) => { +const allowRequest = async (request: VercelRequest & { ip?: string }) => { try { const ip = request.ip ?? "127.0.0.1"; @@ -293,96 +290,84 @@ const allowRequest = async (request: Request & { ip?: string }) => { } }; -export const POST = async (request: Request) => { - if (request.headers.get("Content-Type") === "application/json") { - try { - const body = (await request.json()) as RequestBody; - const bodyValidationResult = bodyValidationSchema.safeParse(body); - - if (!body || bodyValidationResult.error) { - throw { - statusCode: 400, - headers: { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Credentials": true, - }, - body: { - message: bodyValidationResult.error?.message || "No body was found", - }, - }; - } +export default async function handler(req: VercelRequest, res: VercelResponse) { + try { + const body = req.body; + const bodyValidationResult = bodyValidationSchema.safeParse(body); - const { name, email, message, hasConsent } = body; + if (!body || bodyValidationResult.error) { + const headers = new Map([ + ["Access-Control-Allow-Origin", "*"], + ["Access-Control-Allow-Credentials", "true"], + ]); - if (!hasConsent) { - throw { - statusCode: 403, - body: { - message: "No consent by user", - }, - }; - } + throw { + statusCode: 400, + headers: headers, + body: { + message: bodyValidationResult.error?.message || "No body was found", + }, + }; + } - const { success, limit, reset, remaining } = await allowRequest(request); + const { name, email, message, hasConsent } = body; - if (!success) { - throw { - statusCode: 429, - body: { - message: "Too many requests. Please try again in a minute", - }, - }; - } + if (!hasConsent) { + throw { + statusCode: 403, + body: { + message: "No consent by user", + }, + }; + } - try { - await processContact({ - id: nanoid(), - email, - name, - message, - }); - } catch (error) { - throw error; - } + const { success, limit, reset, remaining } = await allowRequest(req); - return new Response( - JSON.stringify({ - message: "Success", - }), - { - status: 200, - headers: { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Credentials": "true", - "X-RateLimit-Limit": limit.toString(), - "X-RateLimit-Remaining": remaining.toString(), - "X-RateLimit-Reset": reset.toString(), - }, + if (!success) { + throw { + statusCode: 429, + body: { + message: "Too many requests. Please try again in a minute", }, - ); + }; + } + + try { + await processContact({ + id: nanoid(), + email, + name, + message, + }); } catch (error) { - const customError = error as Error & { - statusCode?: number; - body?: { - message?: string; - }; - headers?: HeadersInit; + throw error; + } + + const headers = new Map([ + ["Access-Control-Allow-Origin", "*"], + ["Access-Control-Allow-Credentials", "true"], + ["X-RateLimit-Limit", limit.toString()], + ["X-RateLimit-Remaining", remaining.toString()], + ["X-RateLimit-Reset", reset.toString()], + ]); + + return res.status(200).json({ message: "Success" }).setHeaders(headers); + } catch (error) { + const customError = error as Error & { + statusCode?: number; + body?: { + message?: string; }; + headers?: Headers; + }; - console.error("Error - api/contacts", customError); + console.error("Error - api/contacts", customError); - return new Response( - JSON.stringify({ - message: - customError?.body?.message || "Issue while processing request", - }), - { - status: customError.statusCode || 501, - headers: customError?.headers, - }, - ); - } + return res + .status(customError.statusCode || 501) + .json({ + message: customError?.body?.message || "Issue while processing request", + }) + .setHeaders(customError?.headers || new Map()); } - - return new Response(null, { status: 400 }); -}; +} From d91721d5767a08d8342e2fd96841f9a6fc9a15b6 Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 10:03:50 +0100 Subject: [PATCH 09/31] feat[web-27]: fix env and types --- apps/contact/.gitignore | 3 ++- apps/contact/api/index.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/contact/.gitignore b/apps/contact/.gitignore index e02215bd..a093d7d0 100644 --- a/apps/contact/.gitignore +++ b/apps/contact/.gitignore @@ -34,4 +34,5 @@ yarn-error.log* .turbo # typescript -*.tsbuildinfo \ No newline at end of file +*.tsbuildinfo +.env*.local diff --git a/apps/contact/api/index.ts b/apps/contact/api/index.ts index 94a0f6da..2bf115fd 100644 --- a/apps/contact/api/index.ts +++ b/apps/contact/api/index.ts @@ -141,7 +141,7 @@ const getMentions = () => { const ids = MENTION_IDS.split(","); if (emails.length && ids.length) { - return ids.map((id: any, i: string | number) => ({ + return ids.map((id: any, i: number) => ({ id, email: emails[i], })); From 7b6bd06c239202ec4aef35290aebef3c7bf01504 Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 10:10:15 +0100 Subject: [PATCH 10/31] feat[web-27]: fix module --- apps/contact/vercel.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/contact/vercel.json b/apps/contact/vercel.json index 05ad6168..e846a1a1 100644 --- a/apps/contact/vercel.json +++ b/apps/contact/vercel.json @@ -3,7 +3,8 @@ "functions": { "api/index.ts": { "memory": 256, - "maxDuration": 5 + "maxDuration": 5, + "runtime": "nodejs16.x" } }, "routes": [ From f1002912304088b05c9a443003e85783edb1d43f Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 10:21:20 +0100 Subject: [PATCH 11/31] feat[web-27]: remove runtime version --- apps/contact/vercel.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/contact/vercel.json b/apps/contact/vercel.json index e846a1a1..05ad6168 100644 --- a/apps/contact/vercel.json +++ b/apps/contact/vercel.json @@ -3,8 +3,7 @@ "functions": { "api/index.ts": { "memory": 256, - "maxDuration": 5, - "runtime": "nodejs16.x" + "maxDuration": 5 } }, "routes": [ From cd89fe37e52a058349af5f350e32b2b806248fbd Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 10:24:40 +0100 Subject: [PATCH 12/31] feat[web-27]: set headers earlier --- apps/contact/api/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/contact/api/index.ts b/apps/contact/api/index.ts index 2bf115fd..cef51fd2 100644 --- a/apps/contact/api/index.ts +++ b/apps/contact/api/index.ts @@ -351,7 +351,7 @@ export default async function handler(req: VercelRequest, res: VercelResponse) { ["X-RateLimit-Reset", reset.toString()], ]); - return res.status(200).json({ message: "Success" }).setHeaders(headers); + return res.setHeaders(headers).status(200).json({ message: "Success" }); } catch (error) { const customError = error as Error & { statusCode?: number; @@ -364,10 +364,10 @@ export default async function handler(req: VercelRequest, res: VercelResponse) { console.error("Error - api/contacts", customError); return res + .setHeaders(customError?.headers || new Map()) .status(customError.statusCode || 501) .json({ message: customError?.body?.message || "Issue while processing request", - }) - .setHeaders(customError?.headers || new Map()); + }); } } From 282631c86c07423a4cbbe81850f905448e350217 Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 10:38:23 +0100 Subject: [PATCH 13/31] feat[web-27]: change contact url --- apps/website/src/components/ContactUsForm.astro | 2 +- apps/website/src/env.d.ts | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/apps/website/src/components/ContactUsForm.astro b/apps/website/src/components/ContactUsForm.astro index 95bbab26..7a5c7208 100644 --- a/apps/website/src/components/ContactUsForm.astro +++ b/apps/website/src/components/ContactUsForm.astro @@ -176,7 +176,7 @@ import "../styles/loader.css"; } showLoader(); - const response = await fetch("/contact.json", { + const response = await fetch(`${import.meta.env.CONTACT_URL}`, { method: "POST", mode: "cors", headers: { diff --git a/apps/website/src/env.d.ts b/apps/website/src/env.d.ts index ae5f5871..3da9f2ce 100644 --- a/apps/website/src/env.d.ts +++ b/apps/website/src/env.d.ts @@ -2,15 +2,7 @@ /// interface ImportMetaEnv { - readonly NOTION_TOKEN: string; - readonly SLACK_CHANNEL: string; - readonly IS_OFFLINE: string; - readonly SLACK_BOT_TOKEN: string; - readonly MENTION_EMAILS: string; - readonly MENTION_IDS: string; - readonly NOTION_DATABASE_ID: string; - readonly UPSTASH_REDIS_REST_URL: string; - readonly UPSTASH_REDIS_REST_TOKEN: string; + readonly CONTACT_URL: string; } interface ImportMeta { From 6118abdf3774b8503d1c910ddb16291e0986b565 Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 10:44:47 +0100 Subject: [PATCH 14/31] fix[web-27]: console log env --- apps/website/src/components/ContactUsForm.astro | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/website/src/components/ContactUsForm.astro b/apps/website/src/components/ContactUsForm.astro index 7a5c7208..2644eb7b 100644 --- a/apps/website/src/components/ContactUsForm.astro +++ b/apps/website/src/components/ContactUsForm.astro @@ -176,6 +176,7 @@ import "../styles/loader.css"; } showLoader(); + console.log("KAJJJ", import.meta.env.CONTACT_URL); const response = await fetch(`${import.meta.env.CONTACT_URL}`, { method: "POST", mode: "cors", From c5d240a326dcdda5681a5dac17684d2f6ee9a63d Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 11:09:56 +0100 Subject: [PATCH 15/31] fix[web-27]: console log env --- apps/website/src/components/ContactUsForm.astro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/website/src/components/ContactUsForm.astro b/apps/website/src/components/ContactUsForm.astro index 2644eb7b..8dc34936 100644 --- a/apps/website/src/components/ContactUsForm.astro +++ b/apps/website/src/components/ContactUsForm.astro @@ -176,8 +176,8 @@ import "../styles/loader.css"; } showLoader(); - console.log("KAJJJ", import.meta.env.CONTACT_URL); - const response = await fetch(`${import.meta.env.CONTACT_URL}`, { + console.log("KAJJJ", process.env.CONTACT_URL); + const response = await fetch(`${process.env.CONTACT_URL}`, { method: "POST", mode: "cors", headers: { From bea3b989dfbdc4c32e709ef3dbed4ad63868c9f1 Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 11:25:59 +0100 Subject: [PATCH 16/31] fix[web-27]: change env name --- .../src/components/ContactUsForm.astro | 5 +++-- turbo.json | 22 ++++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/website/src/components/ContactUsForm.astro b/apps/website/src/components/ContactUsForm.astro index 8dc34936..04a58bcf 100644 --- a/apps/website/src/components/ContactUsForm.astro +++ b/apps/website/src/components/ContactUsForm.astro @@ -108,6 +108,7 @@ import "../styles/loader.css"; diff --git a/turbo.json b/turbo.json index 85bfc80c..5851a647 100644 --- a/turbo.json +++ b/turbo.json @@ -1,15 +1,24 @@ { "tasks": { "build": { - "dependsOn": ["^build"], - "inputs": ["$TURBO_DEFAULT$", ".env*"], + "dependsOn": [ + "^build" + ], + "inputs": [ + "$TURBO_DEFAULT$", + ".env*" + ], "outputs": [] }, "apps/website#build": { - "outputs": ["apps/website/dist/**"] + "outputs": [ + "apps/website/dist/**" + ] }, "lint": { - "dependsOn": ["^lint"] + "dependsOn": [ + "^lint" + ] }, "dev": { "cache": false, @@ -25,6 +34,7 @@ "NOTION_TOKEN", "SLACK_BOT_TOKEN", "NOTION_DATABASE_ID", - "SITE_URL" + "SITE_URL", + "VITE_CONTACT_URL" ] -} +} \ No newline at end of file From f821c0d351e403dc159ea33866948389278713e7 Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 11:34:26 +0100 Subject: [PATCH 17/31] fix[web-27]: add rewrite --- .../src/components/ContactUsForm.astro | 6 ++-- apps/website/src/env.d.ts | 2 +- apps/website/vercel.json | 32 +++++++++++++++++++ turbo.json | 3 +- 4 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 apps/website/vercel.json diff --git a/apps/website/src/components/ContactUsForm.astro b/apps/website/src/components/ContactUsForm.astro index 04a58bcf..79e5b8a0 100644 --- a/apps/website/src/components/ContactUsForm.astro +++ b/apps/website/src/components/ContactUsForm.astro @@ -108,7 +108,6 @@ import "../styles/loader.css"; diff --git a/apps/website/src/env.d.ts b/apps/website/src/env.d.ts index 3da9f2ce..fe02d0f9 100644 --- a/apps/website/src/env.d.ts +++ b/apps/website/src/env.d.ts @@ -2,7 +2,7 @@ /// interface ImportMetaEnv { - readonly CONTACT_URL: string; + readonly VITE_CONTACT_URL: string; } interface ImportMeta { diff --git a/apps/website/vercel.json b/apps/website/vercel.json new file mode 100644 index 00000000..19aa70aa --- /dev/null +++ b/apps/website/vercel.json @@ -0,0 +1,32 @@ +{ + "rewrites": [ + { + "source": "/images/:path*", + "destination": "https://crocoder-company-blog.vercel.app/images/:path*" + }, + { + "source": "/_vercel/:path*", + "destination": "https://crocoder-company-blog.vercel.app/_vercel/:path*" + }, + { + "source": "/_astro/:path*", + "destination": "https://crocoder-company-blog.vercel.app/_astro/:path*" + }, + { + "source": "/blog/:path*", + "destination": "https://crocoder-company-blog.vercel.app/:path*" + }, + { + "source": "/rss.xml", + "destination": "https://crocoder-company-blog.vercel.app/rss.xml" + }, + { + "source": "/feed", + "destination": "https://crocoder-company-blog.vercel.app/rss.xml" + }, + { + "source": "/api/contact", + "destination": "https://web-contact-gloria-crocoderdev-crocoder.vercel.app/api" + } + ] +} \ No newline at end of file diff --git a/turbo.json b/turbo.json index 5851a647..0171821f 100644 --- a/turbo.json +++ b/turbo.json @@ -34,7 +34,6 @@ "NOTION_TOKEN", "SLACK_BOT_TOKEN", "NOTION_DATABASE_ID", - "SITE_URL", - "VITE_CONTACT_URL" + "SITE_URL" ] } \ No newline at end of file From 428c1100c1a123639cdf6d62bd6eab22599f390a Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 11:44:19 +0100 Subject: [PATCH 18/31] fix[web-27]: add server proxy --- apps/website/astro.config.mjs | 29 +++++++++---------- .../src/components/ContactUsForm.astro | 3 +- apps/website/src/env.d.ts | 8 ----- apps/website/vercel.json | 4 --- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/apps/website/astro.config.mjs b/apps/website/astro.config.mjs index 38f14b53..4c343c5e 100644 --- a/apps/website/astro.config.mjs +++ b/apps/website/astro.config.mjs @@ -1,34 +1,33 @@ -import { defineConfig } from 'astro/config'; -import tailwind from '@astrojs/tailwind'; -import react from '@astrojs/react'; -import vercel from '@astrojs/vercel/static'; -import createRemarkPlugin from '@crocoder-dev/remark-plugin'; +import { defineConfig } from "astro/config"; +import tailwind from "@astrojs/tailwind"; +import react from "@astrojs/react"; +import vercel from "@astrojs/vercel/static"; +import createRemarkPlugin from "@crocoder-dev/remark-plugin"; const classes = { - titleClass: 'font-bold text-[1.25rem] mt-[2.5rem]', - summaryClass: 'cursor-pointer font-bold text-[1.25rem]', - detailsClass: 'mt-[2.5rem]', - iframeClass: 'border-none w-full h-[380px] overflow-y-hidden' -} + titleClass: "font-bold text-[1.25rem] mt-[2.5rem]", + summaryClass: "cursor-pointer font-bold text-[1.25rem]", + detailsClass: "mt-[2.5rem]", + iframeClass: "border-none w-full h-[380px] overflow-y-hidden", +}; const remarkPlugin = createRemarkPlugin(classes); export default defineConfig({ - output: 'static', + output: "static", adapter: vercel({ imageService: true, imagesConfig: { sizes: [640, 936], - domains: ['*'], + domains: ["*"], }, }), redirects: { - '/feed': '/rss.xml', - '/sitemap': '/sitemap.xml' + "/feed": "/rss.xml", + "/sitemap": "/sitemap.xml", }, integrations: [tailwind(), react()], markdown: { remarkPlugins: [remarkPlugin], }, }); - diff --git a/apps/website/src/components/ContactUsForm.astro b/apps/website/src/components/ContactUsForm.astro index 79e5b8a0..fb82651b 100644 --- a/apps/website/src/components/ContactUsForm.astro +++ b/apps/website/src/components/ContactUsForm.astro @@ -176,7 +176,8 @@ import "../styles/loader.css"; } showLoader(); - const response = await fetch("/api/contact", { + + const response = await fetch(`/api`, { method: "POST", mode: "cors", headers: { diff --git a/apps/website/src/env.d.ts b/apps/website/src/env.d.ts index fe02d0f9..acef35f1 100644 --- a/apps/website/src/env.d.ts +++ b/apps/website/src/env.d.ts @@ -1,10 +1,2 @@ /// /// - -interface ImportMetaEnv { - readonly VITE_CONTACT_URL: string; -} - -interface ImportMeta { - readonly env: ImportMetaEnv; -} diff --git a/apps/website/vercel.json b/apps/website/vercel.json index 19aa70aa..ef2b1933 100644 --- a/apps/website/vercel.json +++ b/apps/website/vercel.json @@ -23,10 +23,6 @@ { "source": "/feed", "destination": "https://crocoder-company-blog.vercel.app/rss.xml" - }, - { - "source": "/api/contact", - "destination": "https://web-contact-gloria-crocoderdev-crocoder.vercel.app/api" } ] } \ No newline at end of file From f3619752b94cc242118757f48443fc3ae04f93bb Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 11:58:36 +0100 Subject: [PATCH 19/31] fix[web-27]: add server proxy --- apps/website/vercel.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/website/vercel.json b/apps/website/vercel.json index ef2b1933..4c0765fe 100644 --- a/apps/website/vercel.json +++ b/apps/website/vercel.json @@ -23,6 +23,10 @@ { "source": "/feed", "destination": "https://crocoder-company-blog.vercel.app/rss.xml" + }, + { + "source": "/api", + "destination": "https://web-contact-gloria-crocoderdev-crocoder.vercel.app/api" } ] } \ No newline at end of file From 00071884da9b723e1237df6b01690e43efc612c6 Mon Sep 17 00:00:00 2001 From: gloria Date: Thu, 23 Jan 2025 12:35:32 +0100 Subject: [PATCH 20/31] fix[web-27]: console log env --- apps/website/src/components/ContactUsForm.astro | 4 ++++ apps/website/src/env.d.ts | 8 ++++++++ turbo.json | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/website/src/components/ContactUsForm.astro b/apps/website/src/components/ContactUsForm.astro index fb82651b..5c729ee0 100644 --- a/apps/website/src/components/ContactUsForm.astro +++ b/apps/website/src/components/ContactUsForm.astro @@ -108,6 +108,10 @@ import "../styles/loader.css";