aboutsummaryrefslogtreecommitdiff
path: root/pages/api
diff options
context:
space:
mode:
authorBobby <[email protected]>2022-11-30 23:16:07 -0500
committerBobby <[email protected]>2022-11-30 23:16:07 -0500
commitdaaa789068cebb5fdfcea6197ade6e663be46e0f (patch)
tree1cd315851b779ac28fe622da332c3c16fe1c433c /pages/api
downloadtcssocialify-daaa789068cebb5fdfcea6197ade6e663be46e0f.tar.xz
tcssocialify-daaa789068cebb5fdfcea6197ade6e663be46e0f.zip
socialify update
Diffstat (limited to 'pages/api')
-rw-r--r--pages/api/graphql.ts49
-rw-r--r--pages/api/image.ts18
-rw-r--r--pages/api/png.ts35
-rw-r--r--pages/api/stats.svg.ts45
-rw-r--r--pages/api/stats.ts42
-rw-r--r--pages/api/svg.ts39
6 files changed, 228 insertions, 0 deletions
diff --git a/pages/api/graphql.ts b/pages/api/graphql.ts
new file mode 100644
index 0000000..92c3eff
--- /dev/null
+++ b/pages/api/graphql.ts
@@ -0,0 +1,49 @@
+import type { NextRequest } from 'next/server'
+
+const API_ENDPOINT = 'https://api.github.com/graphql'
+
+const graphQLEndpoint = async (req: NextRequest) => {
+ if (req.method !== 'POST') {
+ return new Response('Method Not Allowed', {
+ status: 405,
+ headers: {
+ 'cache-control': 'max-age=0, public'
+ }
+ })
+ }
+
+ const response = await fetch(API_ENDPOINT, {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ Authorization: `bearer ${process.env.GITHUB_TOKEN}`,
+ 'content-type': 'application/json'
+ },
+ body: req.body
+ })
+
+ if (!response.ok) {
+ return new Response(await response.text(), {
+ status: response.status,
+ headers: {
+ 'cache-control': 'public, max-age=0'
+ }
+ })
+ }
+
+ const text = await response.text()
+ return new Response(text, {
+ status: 200,
+ headers: {
+ 'content-type': 'application/json',
+ 'cache-control':
+ 'public, immutable, no-transform, max-age=60, s-maxage=600'
+ }
+ })
+}
+
+export const config = {
+ runtime: 'experimental-edge'
+}
+
+export default graphQLEndpoint
diff --git a/pages/api/image.ts b/pages/api/image.ts
new file mode 100644
index 0000000..122599e
--- /dev/null
+++ b/pages/api/image.ts
@@ -0,0 +1,18 @@
+import { isBot } from 'next/dist/server/web/spec-extension/user-agent'
+import type { NextRequest } from 'next/server'
+import pngEndpoint from './png'
+import svgEndpoint from './svg'
+
+const imageEndpoint = async (req: NextRequest) => {
+ if (isBot(req.headers.get('user-agent') ?? '')) {
+ return pngEndpoint(req)
+ } else {
+ return svgEndpoint(req)
+ }
+}
+
+export const config = {
+ runtime: 'experimental-edge'
+}
+
+export default imageEndpoint
diff --git a/pages/api/png.ts b/pages/api/png.ts
new file mode 100644
index 0000000..dc9883b
--- /dev/null
+++ b/pages/api/png.ts
@@ -0,0 +1,35 @@
+import type { NextRequest } from 'next/server'
+
+import QueryType from '../../common/types/queryType'
+import renderCardPNG from '../../common/renderPNG'
+
+const pngEndpoint = async (req: NextRequest) => {
+ const { searchParams } = new URL(req.url)
+ const query = Object.fromEntries(searchParams) as QueryType
+
+ try {
+ return renderCardPNG(query, {
+ headers: {
+ 'cache-control': `public, immutable, no-transform, max-age=0, s-maxage=${
+ searchParams.has('cache') ? searchParams.get('cache') : 3600
+ }`
+ }
+ })
+ } catch (ex) {
+ console.error(ex)
+
+ return new Response(JSON.stringify({ error: ex }), {
+ status: 400,
+ headers: {
+ 'content-type': 'application/json',
+ 'cache-control': 'public, max-age=0'
+ }
+ })
+ }
+}
+
+export const config = {
+ runtime: 'experimental-edge'
+}
+
+export default pngEndpoint
diff --git a/pages/api/stats.svg.ts b/pages/api/stats.svg.ts
new file mode 100644
index 0000000..df95a89
--- /dev/null
+++ b/pages/api/stats.svg.ts
@@ -0,0 +1,45 @@
+import type { NextRequest } from 'next/server'
+import { badgen } from 'badgen'
+import statsEndpoint from './stats'
+
+const statsSvgEndpoint = async (req: NextRequest) => {
+ let totalCount = 0
+
+ try {
+ const apiResponse = await (await statsEndpoint(req)).json()
+ if (apiResponse.total_count) {
+ totalCount = apiResponse.total_count
+ }
+ } catch (ex) {
+ console.error(ex)
+ }
+
+ const svg = totalCount
+ ? badgen({
+ subject: '',
+ status: `${totalCount} repositories`,
+ color: 'black',
+ style: 'flat'
+ })
+ : badgen({
+ subject: '',
+ status: `thousands of repositories`,
+ color: 'black',
+ style: 'flat'
+ })
+
+ return new Response(svg, {
+ status: 200,
+ headers: {
+ 'content-type': 'image/svg+xml',
+ 'cache-control':
+ 'public, immutable, no-transform, max-age=60, s-maxage=86400'
+ }
+ })
+}
+
+export const config = {
+ runtime: 'experimental-edge'
+}
+
+export default statsSvgEndpoint
diff --git a/pages/api/stats.ts b/pages/api/stats.ts
new file mode 100644
index 0000000..d557939
--- /dev/null
+++ b/pages/api/stats.ts
@@ -0,0 +1,42 @@
+import type { NextRequest } from 'next/server'
+
+const statsEndpoint = async (req: NextRequest) => {
+ const response = await fetch(
+ `https://api.github.com/search/code?per_page=1&q=${encodeURIComponent(
+ 'socialify.git.ci'
+ )}`,
+ {
+ method: 'GET',
+ headers: {
+ Accept: 'application/vnd.github.v3+json',
+ Authorization: `bearer ${process.env.GITHUB_TOKEN}`,
+ 'content-type': 'application/json'
+ }
+ }
+ )
+
+ if (!response.ok) {
+ return new Response(await response.text(), {
+ status: response.status,
+ headers: {
+ 'cache-control': 'public, max-age=0'
+ }
+ })
+ }
+
+ const json = await response.json()
+ return new Response(JSON.stringify({ total_count: json.total_count }), {
+ status: 200,
+ headers: {
+ 'content-type': 'application/json',
+ 'cache-control':
+ 'public, immutable, no-transform, max-age=60, s-maxage=86400'
+ }
+ })
+}
+
+export const config = {
+ runtime: 'experimental-edge'
+}
+
+export default statsEndpoint
diff --git a/pages/api/svg.ts b/pages/api/svg.ts
new file mode 100644
index 0000000..a803e9b
--- /dev/null
+++ b/pages/api/svg.ts
@@ -0,0 +1,39 @@
+import type { NextRequest } from 'next/server'
+
+import QueryType from '../../common/types/queryType'
+import renderCardSVG from '../../common/renderSVG'
+
+const svgEndpoint = async (req: NextRequest) => {
+ const { searchParams } = new URL(req.url)
+ const query = Object.fromEntries(searchParams) as QueryType
+
+ try {
+ const svg = await renderCardSVG(query)
+
+ return new Response(svg, {
+ status: 200,
+ headers: {
+ 'content-type': 'image/svg+xml',
+ 'cache-control': `public, immutable, no-transform, max-age=0, s-maxage=${
+ searchParams.has('cache') ? searchParams.get('cache') : 3600
+ }`
+ }
+ })
+ } catch (ex) {
+ console.error(ex)
+
+ return new Response(JSON.stringify({ error: ex }), {
+ status: 400,
+ headers: {
+ 'content-type': 'application/json',
+ 'cache-control': 'public, max-age=0'
+ }
+ })
+ }
+}
+
+export const config = {
+ runtime: 'experimental-edge'
+}
+
+export default svgEndpoint