diff --git a/apps/chrome-extension/lib/background/index.ts b/apps/chrome-extension/lib/background/index.ts index 2d8a024ed..f2f1617ce 100644 --- a/apps/chrome-extension/lib/background/index.ts +++ b/apps/chrome-extension/lib/background/index.ts @@ -128,7 +128,8 @@ bridge.handle.CREATE_MEMO(async (payload, _sender, sendResponse) => { } catch (error) { sendResponse({ success: false, - error: error instanceof Error ? error.message : "메모 생성에 실패했습니다.", + error: + error instanceof Error ? error.message : "메모 생성에 실패했습니다.", }); } }); diff --git a/apps/chrome-extension/manifest.js b/apps/chrome-extension/manifest.js index 28df1c244..0b907eaeb 100755 --- a/apps/chrome-extension/manifest.js +++ b/apps/chrome-extension/manifest.js @@ -3,8 +3,6 @@ import fs from "node:fs"; import { CONFIG } from "@web-memo/env"; import deepmerge from "deepmerge"; - - const packageJson = JSON.parse(fs.readFileSync("../../package.json", "utf8")); /** @@ -72,7 +70,7 @@ const manifest = deepmerge( side_panel: { default_path: "side-panel/index.html", }, - } + }, ); export default manifest; diff --git a/apps/chrome-extension/turbo.json b/apps/chrome-extension/turbo.json index a4423f927..051950743 100644 --- a/apps/chrome-extension/turbo.json +++ b/apps/chrome-extension/turbo.json @@ -3,7 +3,12 @@ "tags": ["app"], "tasks": { "build": { - "outputs": ["../../dist/**", "!../../dist/side-panel/**", "!../../dist/options/**", "!../../dist/content-ui/**"] + "outputs": [ + "../../dist/**", + "!../../dist/side-panel/**", + "!../../dist/options/**", + "!../../dist/content-ui/**" + ] } } } diff --git a/apps/chrome-extension/utils/plugins/make-manifest-plugin.ts b/apps/chrome-extension/utils/plugins/make-manifest-plugin.ts index 779bf96dd..b80da5acc 100644 --- a/apps/chrome-extension/utils/plugins/make-manifest-plugin.ts +++ b/apps/chrome-extension/utils/plugins/make-manifest-plugin.ts @@ -1,5 +1,5 @@ -import { colorLog, ManifestParser } from "@web-memo/dev-utils"; import * as fs from "node:fs"; +import { colorLog, ManifestParser } from "@web-memo/dev-utils"; import * as path from "path"; import * as process from "process"; import { pathToFileURL } from "url"; diff --git a/apps/chrome-extension/vite.config.mts b/apps/chrome-extension/vite.config.mts index c8184b299..b35d14629 100644 --- a/apps/chrome-extension/vite.config.mts +++ b/apps/chrome-extension/vite.config.mts @@ -7,7 +7,7 @@ import makeManifestPlugin from "./utils/plugins/make-manifest-plugin"; const rootDir = resolve(__dirname); const libDir = resolve(rootDir, "lib"); -const outDir = resolve(rootDir, "..", "..", "dist"); +const outDir = resolve(rootDir, "..", "..", "dist"); export default defineConfig({ resolve: { alias: { diff --git a/biome.json b/biome.json index 8263ded9f..2eec62870 100644 --- a/biome.json +++ b/biome.json @@ -8,17 +8,17 @@ "files": { "ignoreUnknown": false, "includes": [ - "**/src/**/*", - "**/app/**/*", + "**", "!**/ios/**/*", "!**/android/**/*", - "e2e/tests/**/*", "!**/dist/**", "!**/node_modules/**", "!**/.next/**", "!**/.vercel/**", "!**/.expo/**", - "!**/tailwind-output.css" + "!**/tailwind-output.css", + "!.turbo/**", + "!dist-zip/**" ] }, "formatter": { diff --git a/e2e/package.json b/e2e/package.json index 463024b13..66f1e82bc 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -1,17 +1,17 @@ { - "name": "e2e", - "private": true, - "version": "1.10.4", - "scripts": { - "test": "playwright test", - "test:ui": "playwright test --ui", - "install:browsers": "playwright install --with-deps" - }, - "postinstall": "playwright install --with-deps", - "devDependencies": { - "@playwright/test": "^1.47.0" - }, - "dependencies": { - "@web-memo/shared": "workspace:*" - } + "name": "e2e", + "private": true, + "version": "1.10.4", + "scripts": { + "test": "playwright test", + "test:ui": "playwright test --ui", + "install:browsers": "playwright install --with-deps" + }, + "postinstall": "playwright install --with-deps", + "devDependencies": { + "@playwright/test": "^1.47.0" + }, + "dependencies": { + "@web-memo/shared": "workspace:*" + } } diff --git a/packages/supabase-edge-functions/.vscode/extensions.json b/packages/supabase-edge-functions/.vscode/extensions.json index 74baffcc4..35448591a 100644 --- a/packages/supabase-edge-functions/.vscode/extensions.json +++ b/packages/supabase-edge-functions/.vscode/extensions.json @@ -1,3 +1,3 @@ { - "recommendations": ["denoland.vscode-deno"] + "recommendations": ["denoland.vscode-deno"] } diff --git a/packages/supabase-edge-functions/.vscode/settings.json b/packages/supabase-edge-functions/.vscode/settings.json index 5d0c9ed1c..4e8bd0898 100644 --- a/packages/supabase-edge-functions/.vscode/settings.json +++ b/packages/supabase-edge-functions/.vscode/settings.json @@ -1,10 +1,8 @@ { - "deno.enablePaths": [ - "supabase/functions" - ], - "deno.lint": true, - "deno.unstable": true, - "[typescript]": { - "editor.defaultFormatter": "denoland.vscode-deno" - } + "deno.enablePaths": ["supabase/functions"], + "deno.lint": true, + "deno.unstable": true, + "[typescript]": { + "editor.defaultFormatter": "denoland.vscode-deno" + } } diff --git a/packages/supabase-edge-functions/supabase/functions/kakao-auth/index.ts b/packages/supabase-edge-functions/supabase/functions/kakao-auth/index.ts index 620f9599b..4a8d39118 100644 --- a/packages/supabase-edge-functions/supabase/functions/kakao-auth/index.ts +++ b/packages/supabase-edge-functions/supabase/functions/kakao-auth/index.ts @@ -1,137 +1,127 @@ import { createClient } from "https://esm.sh/@supabase/supabase-js@2"; const corsHeaders = { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Headers": - "authorization, x-client-info, apikey, content-type", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": + "authorization, x-client-info, apikey, content-type", }; Deno.serve(async (req) => { - if (req.method === "OPTIONS") { - return new Response("ok", { headers: corsHeaders }); - } - - try { - const { kakao_access_token } = await req.json(); - - if (!kakao_access_token) { - return new Response( - JSON.stringify({ error: "kakao_access_token is required" }), - { - status: 400, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }, - ); - } - - // 1. 카카오 API로 access token 검증 및 사용자 정보 조회 - const kakaoRes = await fetch("https://kapi.kakao.com/v2/user/me", { - headers: { Authorization: `Bearer ${kakao_access_token}` }, - }); - - if (!kakaoRes.ok) { - return new Response( - JSON.stringify({ error: "Invalid Kakao token" }), - { - status: 401, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }, - ); - } - - const kakaoUser = await kakaoRes.json(); - const email = kakaoUser.kakao_account?.email; - - if (!email) { - return new Response( - JSON.stringify({ error: "Email not available from Kakao account" }), - { - status: 400, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }, - ); - } - - // 2. Supabase Admin 클라이언트 생성 - const supabaseAdmin = createClient( - Deno.env.get("SUPABASE_URL")!, - Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, - ); - - // 3. 기존 사용자에 대해 magiclink 토큰 생성 시도 - let { data: linkData, error: linkError } = - await supabaseAdmin.auth.admin.generateLink({ - type: "magiclink", - email, - }); - - // 4. 사용자가 없으면 생성 후 재시도 - if (linkError) { - const nickname = - kakaoUser.properties?.nickname ?? - kakaoUser.kakao_account?.profile?.nickname; - const avatarUrl = - kakaoUser.properties?.profile_image ?? - kakaoUser.kakao_account?.profile?.profile_image_url; - - const { error: createError } = - await supabaseAdmin.auth.admin.createUser({ - email, - email_confirm: true, - user_metadata: { - name: nickname, - avatar_url: avatarUrl, - provider: "kakao", - kakao_id: String(kakaoUser.id), - }, - }); - - if (createError) { - return new Response( - JSON.stringify({ error: createError.message }), - { - status: 500, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }, - ); - } - - const retryResult = await supabaseAdmin.auth.admin.generateLink({ - type: "magiclink", - email, - }); - linkData = retryResult.data; - linkError = retryResult.error; - } - - if (linkError || !linkData) { - return new Response( - JSON.stringify({ - error: linkError?.message ?? "Failed to generate auth link", - }), - { - status: 500, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }, - ); - } - - return new Response( - JSON.stringify({ - email, - token: linkData.properties.hashed_token, - }), - { - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }, - ); - } catch (error) { - return new Response( - JSON.stringify({ error: error.message }), - { - status: 500, - headers: { ...corsHeaders, "Content-Type": "application/json" }, - }, - ); - } + if (req.method === "OPTIONS") { + return new Response("ok", { headers: corsHeaders }); + } + + try { + const { kakao_access_token } = await req.json(); + + if (!kakao_access_token) { + return new Response( + JSON.stringify({ error: "kakao_access_token is required" }), + { + status: 400, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }, + ); + } + + // 1. 카카오 API로 access token 검증 및 사용자 정보 조회 + const kakaoRes = await fetch("https://kapi.kakao.com/v2/user/me", { + headers: { Authorization: `Bearer ${kakao_access_token}` }, + }); + + if (!kakaoRes.ok) { + return new Response(JSON.stringify({ error: "Invalid Kakao token" }), { + status: 401, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + + const kakaoUser = await kakaoRes.json(); + const email = kakaoUser.kakao_account?.email; + + if (!email) { + return new Response( + JSON.stringify({ error: "Email not available from Kakao account" }), + { + status: 400, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }, + ); + } + + // 2. Supabase Admin 클라이언트 생성 + const supabaseAdmin = createClient( + Deno.env.get("SUPABASE_URL")!, + Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, + ); + + // 3. 기존 사용자에 대해 magiclink 토큰 생성 시도 + let { data: linkData, error: linkError } = + await supabaseAdmin.auth.admin.generateLink({ + type: "magiclink", + email, + }); + + // 4. 사용자가 없으면 생성 후 재시도 + if (linkError) { + const nickname = + kakaoUser.properties?.nickname ?? + kakaoUser.kakao_account?.profile?.nickname; + const avatarUrl = + kakaoUser.properties?.profile_image ?? + kakaoUser.kakao_account?.profile?.profile_image_url; + + const { error: createError } = await supabaseAdmin.auth.admin.createUser({ + email, + email_confirm: true, + user_metadata: { + name: nickname, + avatar_url: avatarUrl, + provider: "kakao", + kakao_id: String(kakaoUser.id), + }, + }); + + if (createError) { + return new Response(JSON.stringify({ error: createError.message }), { + status: 500, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + + const retryResult = await supabaseAdmin.auth.admin.generateLink({ + type: "magiclink", + email, + }); + linkData = retryResult.data; + linkError = retryResult.error; + } + + if (linkError || !linkData) { + return new Response( + JSON.stringify({ + error: linkError?.message ?? "Failed to generate auth link", + }), + { + status: 500, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }, + ); + } + + return new Response( + JSON.stringify({ + email, + token: linkData.properties.hashed_token, + }), + { + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }, + ); + } catch (error) { + return new Response(JSON.stringify({ error: error.message }), { + status: 500, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } }); diff --git a/packages/supabase-edge-functions/supabase/functions/send-feedback/index.ts b/packages/supabase-edge-functions/supabase/functions/send-feedback/index.ts index d1b7496ea..e2f208f5a 100644 --- a/packages/supabase-edge-functions/supabase/functions/send-feedback/index.ts +++ b/packages/supabase-edge-functions/supabase/functions/send-feedback/index.ts @@ -1,34 +1,38 @@ import { serve } from "https://deno.land/std@0.177.0/http/server.ts"; -const GATE_API_URL = "https://pbix60v3vk.execute-api.ap-northeast-2.amazonaws.com/send-feedback" +const GATE_API_URL = + "https://pbix60v3vk.execute-api.ap-northeast-2.amazonaws.com/send-feedback"; serve(async (req) => { - const webhookPayload = await req.json(); - - const newRecord = webhookPayload.record; - const content = newRecord.content; - - const targetUrl = new URL(GATE_API_URL); - targetUrl.searchParams.append("content", content); - - console.log("Gate API URL:", targetUrl.toString()); - - try { - const response = await fetch(targetUrl.toString(), { - method: "GET", - }); - - const result = await response.json(); - console.log("Gate API 응답:", result); - - return new Response(JSON.stringify({ status: "success", data: result }), { - headers: { "Content-Type": "application/json" }, - }); - } catch (error) { - console.error("Gate API 요청 중 오류 발생:", error); - return new Response(JSON.stringify({ status: "error", message: error.message }), { - status: 500, - headers: { "Content-Type": "application/json" }, - }); - } -}); \ No newline at end of file + const webhookPayload = await req.json(); + + const newRecord = webhookPayload.record; + const content = newRecord.content; + + const targetUrl = new URL(GATE_API_URL); + targetUrl.searchParams.append("content", content); + + console.log("Gate API URL:", targetUrl.toString()); + + try { + const response = await fetch(targetUrl.toString(), { + method: "GET", + }); + + const result = await response.json(); + console.log("Gate API 응답:", result); + + return new Response(JSON.stringify({ status: "success", data: result }), { + headers: { "Content-Type": "application/json" }, + }); + } catch (error) { + console.error("Gate API 요청 중 오류 발생:", error); + return new Response( + JSON.stringify({ status: "error", message: error.message }), + { + status: 500, + headers: { "Content-Type": "application/json" }, + }, + ); + } +}); diff --git a/packages/ui/global.css b/packages/ui/global.css index b28254e45..cd19b5d3e 100644 --- a/packages/ui/global.css +++ b/packages/ui/global.css @@ -11,15 +11,15 @@ --popover: 0 0% 100%; --popover-foreground: 222.8571 84.0000% 4.9020%; --primary: 221.2121 83.1933% 53.3333%; - --primary-foreground: 210.0000 40.0000% 98.0392%; - --secondary: 210.0000 40.0000% 96.0784%; + --primary-foreground: 210 40.0000% 98.0392%; + --secondary: 210 40.0000% 96.0784%; --secondary-foreground: 222.2222 47.3684% 11.1765%; - --muted: 210.0000 40.0000% 96.0784%; + --muted: 210 40.0000% 96.0784%; --muted-foreground: 215.3846 16.3180% 46.8627%; - --accent: 210.0000 40.0000% 96.0784%; + --accent: 210 40.0000% 96.0784%; --accent-foreground: 222.2222 47.3684% 11.1765%; --destructive: 0 72.2222% 50.5882%; - --destructive-foreground: 210.0000 40.0000% 98.0392%; + --destructive-foreground: 210 40.0000% 98.0392%; --border: 214.2857 31.8182% 91.3725%; --input: 214.2857 31.8182% 91.3725%; --ring: 221.2121 83.1933% 53.3333%; @@ -28,10 +28,10 @@ --chart-3: 20.5405 90.2439% 48.2353%; --chart-4: 262.1229 83.2558% 57.8431%; --chart-5: 333.3333 71.4286% 50.5882%; - --sidebar: 210.0000 40.0000% 98.0392%; + --sidebar: 210 40.0000% 98.0392%; --sidebar-foreground: 215.3846 16.3180% 46.8627%; --sidebar-primary: 221.2121 83.1933% 53.3333%; - --sidebar-primary-foreground: 210.0000 40.0000% 98.0392%; + --sidebar-primary-foreground: 210 40.0000% 98.0392%; --sidebar-accent: 214.2857 31.8182% 91.3725%; --sidebar-accent-foreground: 222.2222 47.3684% 11.1765%; --sidebar-border: 214.2857 31.8182% 91.3725%; @@ -42,11 +42,16 @@ --radius: 0.5rem; --shadow-2xs: 0px 2px 4px 0px hsl(0 0% 0% / 0.03); --shadow-xs: 0px 2px 4px 0px hsl(0 0% 0% / 0.03); - --shadow-sm: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 1px 2px -1px hsl(0 0% 0% / 0.05); - --shadow: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 1px 2px -1px hsl(0 0% 0% / 0.05); - --shadow-md: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 2px 4px -1px hsl(0 0% 0% / 0.05); - --shadow-lg: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 4px 6px -1px hsl(0 0% 0% / 0.05); - --shadow-xl: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 8px 10px -1px hsl(0 0% 0% / 0.05); + --shadow-sm: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 1px 2px -1px + hsl(0 0% 0% / 0.05); + --shadow: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 1px 2px -1px + hsl(0 0% 0% / 0.05); + --shadow-md: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 2px 4px -1px + hsl(0 0% 0% / 0.05); + --shadow-lg: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 4px 6px -1px + hsl(0 0% 0% / 0.05); + --shadow-xl: 0px 2px 4px 0px hsl(0 0% 0% / 0.05), 0px 8px 10px -1px + hsl(0 0% 0% / 0.05); --shadow-2xl: 0px 2px 4px 0px hsl(0 0% 0% / 0.13); --tracking-normal: 0rem; --spacing: 0.25rem; @@ -54,21 +59,21 @@ .dark { --background: 222.8571 84.0000% 4.9020%; - --foreground: 210.0000 40.0000% 98.0392%; + --foreground: 210 40.0000% 98.0392%; --card: 222.8571 84.0000% 4.9020%; - --card-foreground: 210.0000 40.0000% 98.0392%; + --card-foreground: 210 40.0000% 98.0392%; --popover: 222.8571 84.0000% 4.9020%; - --popover-foreground: 210.0000 40.0000% 98.0392%; + --popover-foreground: 210 40.0000% 98.0392%; --primary: 217.2193 91.2195% 59.8039%; - --primary-foreground: 210.0000 40.0000% 98.0392%; + --primary-foreground: 210 40.0000% 98.0392%; --secondary: 217.2414 32.5843% 17.4510%; - --secondary-foreground: 210.0000 40.0000% 98.0392%; + --secondary-foreground: 210 40.0000% 98.0392%; --muted: 217.2414 32.5843% 17.4510%; - --muted-foreground: 215.0000 20.2247% 65.0980%; + --muted-foreground: 215 20.2247% 65.0980%; --accent: 217.2414 32.5843% 17.4510%; - --accent-foreground: 210.0000 40.0000% 98.0392%; + --accent-foreground: 210 40.0000% 98.0392%; --destructive: 0 84.2365% 60.1961%; - --destructive-foreground: 210.0000 40.0000% 98.0392%; + --destructive-foreground: 210 40.0000% 98.0392%; --border: 217.2414 32.5843% 17.4510%; --input: 217.2414 32.5843% 17.4510%; --ring: 217.2193 91.2195% 59.8039%; @@ -78,11 +83,11 @@ --chart-4: 258.3117 89.5349% 66.2745%; --chart-5: 330.3659 81.1881% 60.3922%; --sidebar: 222.2222 47.3684% 11.1765%; - --sidebar-foreground: 215.0000 20.2247% 65.0980%; + --sidebar-foreground: 215 20.2247% 65.0980%; --sidebar-primary: 217.2193 91.2195% 59.8039%; - --sidebar-primary-foreground: 210.0000 40.0000% 98.0392%; + --sidebar-primary-foreground: 210 40.0000% 98.0392%; --sidebar-accent: 217.2414 32.5843% 17.4510%; - --sidebar-accent-foreground: 210.0000 40.0000% 98.0392%; + --sidebar-accent-foreground: 210 40.0000% 98.0392%; --sidebar-border: 217.2414 32.5843% 17.4510%; --sidebar-ring: 217.2193 91.2195% 59.8039%; --font-sans: Inter; @@ -91,17 +96,22 @@ --radius: 0.5rem; --shadow-2xs: 0px 2px 4px 0px hsl(0 0% 0% / 0.05); --shadow-xs: 0px 2px 4px 0px hsl(0 0% 0% / 0.05); - --shadow-sm: 0px 2px 4px 0px hsl(0 0% 0% / 0.10), 0px 1px 2px -1px hsl(0 0% 0% / 0.10); - --shadow: 0px 2px 4px 0px hsl(0 0% 0% / 0.10), 0px 1px 2px -1px hsl(0 0% 0% / 0.10); - --shadow-md: 0px 2px 4px 0px hsl(0 0% 0% / 0.10), 0px 2px 4px -1px hsl(0 0% 0% / 0.10); - --shadow-lg: 0px 2px 4px 0px hsl(0 0% 0% / 0.10), 0px 4px 6px -1px hsl(0 0% 0% / 0.10); - --shadow-xl: 0px 2px 4px 0px hsl(0 0% 0% / 0.10), 0px 8px 10px -1px hsl(0 0% 0% / 0.10); + --shadow-sm: 0px 2px 4px 0px hsl(0 0% 0% / 0.1), 0px 1px 2px -1px + hsl(0 0% 0% / 0.1); + --shadow: 0px 2px 4px 0px hsl(0 0% 0% / 0.1), 0px 1px 2px -1px + hsl(0 0% 0% / 0.1); + --shadow-md: 0px 2px 4px 0px hsl(0 0% 0% / 0.1), 0px 2px 4px -1px + hsl(0 0% 0% / 0.1); + --shadow-lg: 0px 2px 4px 0px hsl(0 0% 0% / 0.1), 0px 4px 6px -1px + hsl(0 0% 0% / 0.1); + --shadow-xl: 0px 2px 4px 0px hsl(0 0% 0% / 0.1), 0px 8px 10px -1px + hsl(0 0% 0% / 0.1); --shadow-2xl: 0px 2px 4px 0px hsl(0 0% 0% / 0.25); } -body { - letter-spacing: var(--tracking-normal); -} + body { + letter-spacing: var(--tracking-normal); + } * { @apply border-border; diff --git a/turbo.jsonc b/turbo.jsonc index 3bc60bf51..19e6b7a30 100644 --- a/turbo.jsonc +++ b/turbo.jsonc @@ -46,7 +46,13 @@ // 프로덕션 빌드 (apps/app|chrome-extension|web, pages/content-ui|options|side-panel) "build": { "dependsOn": ["ready", "^build"], - "inputs": ["$TURBO_DEFAULT$", "!**/*.md", "!**/*.test.*", "!**/*.spec.*", "!**/*.tsbuildinfo"], + "inputs": [ + "$TURBO_DEFAULT$", + "!**/*.md", + "!**/*.test.*", + "!**/*.spec.*", + "!**/*.tsbuildinfo" + ], "outputs": ["dist/**", "build/**", ".next/**", "!.next/cache/**"] }, // 프로덕션 서버 실행 (apps/web) diff --git a/vercel.json b/vercel.json index 212ef1d51..9fa4c1181 100644 --- a/vercel.json +++ b/vercel.json @@ -1,6 +1,6 @@ { - "$schema": "https://openapi.vercel.sh/vercel.json", - "rewrites": [ - { "source": "/api/transcript", "destination": "/api/transcript.py" } - ] + "$schema": "https://openapi.vercel.sh/vercel.json", + "rewrites": [ + { "source": "/api/transcript", "destination": "/api/transcript.py" } + ] }