Skip to content

Commit

Permalink
♻️ Full (verified) api migration from page to app router.
Browse files Browse the repository at this point in the history
  • Loading branch information
KemingHe committed Dec 15, 2024
1 parent 96a76e8 commit 290ebf8
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 88 deletions.
7 changes: 3 additions & 4 deletions pages/api/font.ts → app/api/font/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import type { NextRequest } from 'next/server'

import { FontDetector, languageFontMap } from '@/common/font'

export const config = {
runtime: 'edge',
}
export const runtime = 'edge'

const detector = new FontDetector()

Expand Down Expand Up @@ -37,7 +35,8 @@ function encodeFontInfoAsArrayBuffer(code: string, fontData: ArrayBuffer) {
return buffer
}

export default async function loadGoogleFont(req: NextRequest) {
// export default async function loadGoogleFont(req: NextRequest) {
export async function GET(req: NextRequest) {
if (req.nextUrl.pathname !== '/api/font') return

const { searchParams } = new URL(req.url)
Expand Down
23 changes: 6 additions & 17 deletions pages/api/graphql.ts → app/api/graphql/route.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
import type { NextRequest } from 'next/server'

const API_ENDPOINT: string = 'https://api.github.com/graphql'
import { GITHUB_GRAPHQL_ENDPOINT } from '@/common/constants'

const graphQLEndpoint = async (req: NextRequest) => {
if (req.method !== 'POST') {
return new Response('Method Not Allowed', {
status: 405,
headers: {
'cache-control': 'max-age=0, public',
},
})
}
export const runtime = 'edge'

const response = await fetch(API_ENDPOINT, {
export async function POST(req: NextRequest) {
const response = await fetch(GITHUB_GRAPHQL_ENDPOINT, {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `bearer ${process.env.GITHUB_TOKEN}`,
'content-type': 'application/json',
},
body: req.body,
// @ts-expect-error: 'duplex' is not part of the RequestInit type but required by GraphQL.
duplex: 'half',
})

if (!response.ok) {
Expand All @@ -41,9 +36,3 @@ const graphQLEndpoint = async (req: NextRequest) => {
},
})
}

export const config = {
runtime: 'edge',
}

export default graphQLEndpoint
15 changes: 15 additions & 0 deletions app/api/image/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { isBot } from 'next/dist/server/web/spec-extension/user-agent'
import type { NextRequest, NextResponse } from 'next/server'

import { GET as GETPng } from '@/app/api/png/route'
import { GET as GETSvg } from '@/app/api/svg/route'

export const runtime = 'edge'

export async function GET(req: NextRequest): Promise<NextResponse> {
if (isBot(req.headers.get('user-agent') ?? '')) {
return GETPng(req)
} else {
return GETSvg(req)
}
}
16 changes: 6 additions & 10 deletions pages/api/png.ts → app/api/png/route.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import type { NextRequest } from 'next/server'
import { type NextRequest, NextResponse } from 'next/server'

import renderCardPNG from '@/common/renderPNG'
import type QueryType from '@/common/types/queryType'

const pngEndpoint = async (req: NextRequest) => {
export const runtime = 'edge'

export async function GET(req: NextRequest): Promise<NextResponse> {
const { searchParams } = new URL(req.url)
const query = Object.fromEntries(searchParams) as QueryType

try {
return new Response(await renderCardPNG(query), {
return new NextResponse(await renderCardPNG(query), {
status: 200,
headers: {
'content-type': 'image/png',
Expand All @@ -27,7 +29,7 @@ const pngEndpoint = async (req: NextRequest) => {
}
console.error(errorJSON)

return new Response(JSON.stringify(errorJSON), {
return new NextResponse(JSON.stringify(errorJSON), {
status: 400,
headers: {
'content-type': 'application/json',
Expand All @@ -36,9 +38,3 @@ const pngEndpoint = async (req: NextRequest) => {
})
}
}

export const config = {
runtime: 'edge',
}

export default pngEndpoint
18 changes: 7 additions & 11 deletions pages/api/stats.svg.ts → app/api/stats.svg/route.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { badgen } from 'badgen'
import type { NextRequest } from 'next/server'
import { type NextRequest, NextResponse } from 'next/server'

import statsEndpoint from '@/pages/api/stats'
import { GET as GETStats } from '@/app/api/stats/route'

const statsSvgEndpoint = async (req: NextRequest) => {
export const runtime = 'edge'

export async function GET(req: NextRequest): Promise<NextResponse> {
let totalCount = 0

try {
const apiResponse = await (await statsEndpoint(req)).json()
const apiResponse = await (await GETStats(req)).json()
if (apiResponse.total_count) {
totalCount = apiResponse.total_count
}
Expand All @@ -33,7 +35,7 @@ const statsSvgEndpoint = async (req: NextRequest) => {
style: 'flat',
})

return new Response(svg, {
return new NextResponse(svg, {
status: 200,
headers: {
'content-type': 'image/svg+xml',
Expand All @@ -43,9 +45,3 @@ const statsSvgEndpoint = async (req: NextRequest) => {
},
})
}

export const config = {
runtime: 'edge',
}

export default statsSvgEndpoint
16 changes: 6 additions & 10 deletions pages/api/stats.ts → app/api/stats/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { NextRequest } from 'next/server'
import { type NextRequest, NextResponse } from 'next/server'

const statsEndpoint = async (_req: NextRequest) => {
export const runtime = 'edge'

export async function GET(_req: NextRequest): Promise<NextResponse> {
const response = await fetch(
`https://api.github.com/search/code?per_page=1&q=${encodeURIComponent(
'socialify.git.ci'
Expand All @@ -16,7 +18,7 @@ const statsEndpoint = async (_req: NextRequest) => {
)

if (!response.ok) {
return new Response(await response.text(), {
return new NextResponse(await response.text(), {
status: response.status,
headers: {
'cache-control': 'public, max-age=0',
Expand All @@ -25,7 +27,7 @@ const statsEndpoint = async (_req: NextRequest) => {
}

const json = await response.json()
return new Response(JSON.stringify({ total_count: json.total_count }), {
return new NextResponse(JSON.stringify({ total_count: json.total_count }), {
status: 200,
headers: {
'content-type': 'application/json',
Expand All @@ -35,9 +37,3 @@ const statsEndpoint = async (_req: NextRequest) => {
},
})
}

export const config = {
runtime: 'edge',
}

export default statsEndpoint
16 changes: 6 additions & 10 deletions pages/api/svg.ts → app/api/svg/route.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import type { NextRequest } from 'next/server'
import { type NextRequest, NextResponse } from 'next/server'

import renderCardSVG from '@/common/renderSVG'
import type QueryType from '@/common/types/queryType'

const svgEndpoint = async (req: NextRequest) => {
export const runtime = 'edge'

export async function GET(req: NextRequest): Promise<NextResponse> {
const { searchParams } = new URL(req.url)
const query = Object.fromEntries(searchParams) as QueryType

try {
const svg = await renderCardSVG(query)

return new Response(svg, {
return new NextResponse(svg, {
status: 200,
headers: {
'content-type': 'image/svg+xml',
Expand All @@ -29,7 +31,7 @@ const svgEndpoint = async (req: NextRequest) => {
}
console.error(errorJSON)

return new Response(JSON.stringify(errorJSON), {
return new NextResponse(JSON.stringify(errorJSON), {
status: 400,
headers: {
'content-type': 'application/json',
Expand All @@ -38,9 +40,3 @@ const svgEndpoint = async (req: NextRequest) => {
})
}
}

export const config = {
runtime: 'edge',
}

export default svgEndpoint
7 changes: 7 additions & 0 deletions common/__snapshots__/constants.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`constants matches snapshot 1`] = `
{
"GITHUB_GRAPHQL_ENDPOINT": "https://api.github.com/graphql",
}
`;
7 changes: 7 additions & 0 deletions common/constants.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as constants from './constants'

describe('constants', () => {
test('matches snapshot', () => {
expect(constants).toMatchSnapshot()
})
})
4 changes: 4 additions & 0 deletions common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// GitHub constants.
export const GITHUB_GRAPHQL_ENDPOINT = 'https://api.github.com/graphql'

// Socialify constants.
3 changes: 2 additions & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
19 changes: 0 additions & 19 deletions pages/api/image.ts

This file was deleted.

1 change: 1 addition & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export default defineConfig({
webServer: {
command: 'pnpm build && pnpm start',
url: 'http://127.0.0.1:3000',
timeout: 120 * 1000, // Extend the timeout to 2 minutes due to the build time.
reuseExistingServer: !process.env.CI,
},
})
31 changes: 25 additions & 6 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "es2020",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
Expand All @@ -22,11 +26,26 @@
],
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
"@/*": [
"./*"
]
},
"typeRoots": ["./node_modules/@types", "./common/types"]
"typeRoots": [
"./node_modules/@types",
"./common/types"
]
},
"types": ["@types/jest"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "jest.config.ts"],
"exclude": ["node_modules"]
"types": [
"@types/jest"
],
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
"jest.config.ts",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}

0 comments on commit 290ebf8

Please sign in to comment.