Skip to content

Commit

Permalink
feat: finish link shortener
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonappah committed Oct 18, 2021
1 parent 5644f63 commit 3950fcd
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 81 deletions.
27 changes: 27 additions & 0 deletions lib/server/getLinks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { AirtablePlusPlus, AirtablePlusPlusRecord } from "airtable-plusplus";

export async function getLinks(): Promise<Record<string, ILink>> {
const airtable = new AirtablePlusPlus({
apiKey: process.env.AIRTABLE_KEY,
baseId: process.env.AIRTABLE_BASE_ID,
tableName: "Table 1"
});
const links = (await airtable.read({
filterByFormula: "{Active}"
})) as unknown as AirtablePlusPlusRecord<ILink>[];

const yeah = {};
for (const record in links) {
yeah[links[record].fields.Slug] = links[record].fields;
}

return yeah;
}
interface ILink {
"Friendly Name": string;
Slug: string;
"Redirect URL": string;
Description: string;
Active: boolean;
Public: boolean;
}
6 changes: 6 additions & 0 deletions next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
"format": "prettier --write \"./**/*.{js,ts,tsx,jsx}\""
},
"dependencies": {
"airtable-plusplus": "^0.3.2",
"next": "11.1.0",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"eslint": "^8.0.1",
"@types/react": "^17.0.30",
"eslint": "7",
"eslint-config-next": "11.1.2",
"prettier": "^2.4.1"
"prettier": "^2.4.1",
"typescript": "^4.4.4"
}
}
31 changes: 24 additions & 7 deletions pages/api/link.js → pages/api/link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,38 @@
// logs of what links were accessed when and where which wasn't an option previously.
// also stale while revalidate is pretty pog, see https://vercel.com/docs/concepts/functions/edge-caching

// idk how to handle 404s yet but that shouldn't be too painful i hope - if i return a 404 does it
// serve the 404 page for me? then i can style that and make it all nice
import path from "path"
import type {NextApiRequest, NextApiResponse} from "next"
import { getLinks } from "../../lib/server/getLinks"

export default async (req, res) => {
const link = async (req: NextApiRequest, res: NextApiResponse) => {
const ALLOWED_METHODS = ["GET", "HEAD"]
const DEFAULT = "https://jasonaa.me"
if (!ALLOWED_METHODS.includes(req.method)) {
return res.send("Only GET and HEAD methods are supported.")
}

if (req.cookies["_vercel_no_cache"] === 1 || req.query["?_vercel_no_cache"] === 1 || req.headers["Authorization"] || req.headers["Range"]) {
if (
req.cookies["_vercel_no_cache"] === "1" ||
req.query["?_vercel_no_cache"] === "1" ||
req.headers["Authorization"] ||
req.headers["Range"]
) {
return res.send("sorry, we must get that cash!")
}

// TODO: Airtable stuff

res.setHeader("Cache-Control", "s-maxage=10, stale-while-revalidate")
return res.redirect(308, "https://jasonaa.me")

if (!req.query.slug) {
// for vercel to cache the response it has to be a 308 redirect
return res.redirect(308, DEFAULT)
}
const slug = path.format(path.parse(req.query.slug as string))

const links = await getLinks()
const url = links[slug]["Redirect URL"] || DEFAULT

return res.redirect(308, url)
}

export default link
29 changes: 29 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
Loading

1 comment on commit 3950fcd

@vercel
Copy link

@vercel vercel bot commented on 3950fcd Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.