Skip to content

Commit

Permalink
chore: add ci (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
rqbazan authored Feb 15, 2024
1 parent 436804e commit 628f28b
Show file tree
Hide file tree
Showing 32 changed files with 258 additions and 98 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CI

on: [push]

jobs:
testing:
name: 👀 Testing

runs-on: ubuntu-latest

steps:
- name: 🛑 Cancel Previous Runs
uses: styfle/[email protected]

- name: ⬇️ Checkout repo
uses: actions/checkout@master

- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 18
cache: "yarn"

- name: 📦 Install dependencies
run: yarn install --frozen-lockfile

- name: 🔎 Static testing
run: yarn test:static
12 changes: 11 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib"
"typescript.tsdk": "node_modules\\typescript\\lib",
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
}
}
44 changes: 22 additions & 22 deletions api/resume.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import type { VercelRequest, VercelResponse } from "@vercel/node";
import type { Lang } from "../src/types";
import { getTechProfile, getTechResume } from "../src/lib/airtable.js";
import type { VercelRequest, VercelResponse } from '@vercel/node'
import { getTechProfile, getTechResume } from '../src/lib/airtable.js'
import type { Lang } from '../src/types'

// @ts-ignore
import { renderAppToStream } from "../.lib/server.cjs";
import { renderAppToStream } from '../.lib/server.cjs'

type Query = {
id: string;
lang: Lang;
};
id: string
lang: Lang
}

export default async (req: VercelRequest, res: VercelResponse) => {
const { id, lang = "en" } = req.query as Query;
const { id, lang = 'en' } = req.query as Query

const [techProfile, techResume] = await Promise.all([
getTechProfile(),
getTechResume({ id, lang }),
]);
])

if (!techResume) {
return res.redirect(techProfile.website);
return res.redirect(techProfile.website)
}

const appProps = {
lang,
techProfile,
techResume,
};

if (process.env.NODE_ENV !== "production") {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
res.setHeader("Cache-Control", "max-age=60");
res.json(appProps);
return;
}

const stream = await renderAppToStream(appProps);
res.setHeader("Content-Type", "application/pdf");
stream.pipe(res);
};
if (process.env.NODE_ENV !== 'production') {
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader('Access-Control-Allow-Methods', 'GET,OPTIONS')
res.setHeader('Cache-Control', 'max-age=60')
res.json(appProps)
return
}

const stream = await renderAppToStream(appProps)
res.setHeader('Content-Type', 'application/pdf')
stream.pipe(res)
}
27 changes: 27 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
"organizeImports": {
"enabled": true
},
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true,
"indentStyle": "space"
},
"javascript": {
"formatter": {
"semicolons": "asNeeded",
"quoteStyle": "single"
}
}
}
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
"build:browser": "vite build",
"build:server": "node ./scripts/build.cjs",
"vercel-build": "npm run build:server",
"typecheck": "tsc --noEmit"
"check:types": "tsc --noEmit",
"check:lint": "biome check .",
"test:static": "run-p check:*"
},
"dependencies": {
"@react-pdf/renderer": "2.0.20",
Expand All @@ -19,14 +21,15 @@
"react-dom": "17.0.0"
},
"devDependencies": {
"@biomejs/biome": "^1.5.3",
"@rqbazan/vite-plugin-shim-react-pdf": "1.1.0",
"@types/node": "16.11.6",
"@types/react": "17.0.0",
"@types/react-dom": "17.0.0",
"@vercel/node": "1.12.1",
"@vitejs/plugin-react": "1.0.0",
"esbuild": "^0.20.0",
"npm-run-all": "4.1.5",
"npm-run-all": "^4.1.5",
"typescript": "4.3.2",
"vite": "2.6.4"
}
Expand Down
16 changes: 8 additions & 8 deletions scripts/build.cjs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
require("esbuild").build({
entryPoints: ["./src/server/main.tsx"],
inject: ["./src/server/react-shim.ts"],
require('esbuild').build({
entryPoints: ['./src/server/main.tsx'],
inject: ['./src/server/react-shim.ts'],
bundle: true,
minify: true,
platform: "node",
target: "node18",
outfile: ".lib/server.cjs",
platform: 'node',
target: 'node18',
outfile: '.lib/server.cjs',
loader: {
".ttf": "dataurl",
'.ttf': 'dataurl',
},
});
})
5 changes: 5 additions & 0 deletions src/app/cn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Style } from '~/react-pdf'

export function cn(...styles: (Style | undefined)[]): Style[] {
return styles.filter(Boolean) as Style[]
}
2 changes: 1 addition & 1 deletion src/app/hooks/use-strings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function useContextValue(lang: Lang) {
...strings.defaults,
...strings[lang],
}
}, [lang])
}, [strings[lang]])
}

export function StringsProvider({ lang, children }: StringsProviderProps) {
Expand Down
20 changes: 10 additions & 10 deletions src/app/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { Document, Page, StyleSheet, View } from '~/react-pdf'
import type { Lang, TechProfile, TechResume } from '~/types'
import { Document, View, StyleSheet, Page } from '~/react-pdf'
import { ThemeProvider, StringsProvider, useStrings } from './hooks'
import { StringsProvider, ThemeProvider, useStrings } from './hooks'
import { createTheme } from './theme'
import {
EducationPost,
Heading,
Section,
IconName,
Insight,
Language,
ListItem,
WorkPost,
Resume,
EducationPost,
Language,
Insight,
TechGroup,
Section,
SocialMedia,
TechGroup,
Watermark,
IconName,
WorkPost,
} from './ui'
import { createTheme } from './theme'

export interface AppDocumentProps {
techProfile: TechProfile
Expand Down
4 changes: 2 additions & 2 deletions src/app/ui/date-range/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ export interface DateRangeProps {
endAt?: string
}

export function formatDate(dateString: string, format: string = 'LL/yyyy') {
export function formatDate(dateString: string, format = 'LL/yyyy') {
const formatString = 'yyyy-MM-dd'
const referenceDate = new Date()

return dateFnsFormat(
dateFnsParse(dateString, formatString, referenceDate),
format
format,
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/app/ui/education-post/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react'
import { Style, View } from '~/react-pdf'
import { WorkPost } from '../work-post'
import { IconText } from '../icon-text'
import { DateRange } from '../date-range'
import { IconText } from '../icon-text'
import { WorkPost } from '../work-post'

export interface EducationPostProps {
style?: Style
Expand Down
5 changes: 3 additions & 2 deletions src/app/ui/heading/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cn } from '~/app/cn'
import { useTheme } from '~/app/hooks/use-theme'
import { StyleSheet, Style, Link, View, Text, Image } from '~/react-pdf'
import { Image, Link, Style, StyleSheet, Text, View } from '~/react-pdf'
import { IconText } from '../icon-text'

export interface HeadingProps {
Expand Down Expand Up @@ -63,7 +64,7 @@ export function Heading({
const theme = useTheme()

return (
<View style={[styles.container, style!]}>
<View style={cn(styles.container, style)}>
<View style={{ margin: 1 }}>
<Text style={styles.title}>{title}</Text>
<Text style={[styles.subTitle, { color: theme.colors.primary }]}>
Expand Down
5 changes: 3 additions & 2 deletions src/app/ui/icon-text/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cn } from '~/app/cn'
import { useTheme } from '~/app/hooks/use-theme'
import { Text, View, Style, StyleSheet } from '~/react-pdf'
import { Style, StyleSheet, Text, View } from '~/react-pdf'
import { Icon, IconName } from '../icon'

export interface IconTextProps {
Expand All @@ -24,7 +25,7 @@ export function IconText({ style, text, iconName }: IconTextProps) {
const theme = useTheme()

return (
<View style={[styles.container, style!]}>
<View style={cn(styles.container, style)}>
<Icon size={10} name={iconName} />
<Text style={[styles.text, { color: theme.colors.text }]}>{text}</Text>
</View>
Expand Down
21 changes: 14 additions & 7 deletions src/app/ui/icon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Style, Canvas } from '~/react-pdf'
import { cn } from '~/app/cn'
import { Canvas, Style } from '~/react-pdf'

export interface IconProps {
style?: Style
Expand All @@ -12,15 +13,20 @@ export type IconName = keyof typeof iconPaths

// prettier-ignore
const iconPaths = {
atSymbol: 'M15.6 15.47A4.99 4.99 0 0 1 7 12a5 5 0 0 1 10 0v1.5a1.5 1.5 0 1 0 3 0V12a8 8 0 1 0-4.94 7.4 1 1 0 1 1 .77 1.84A10 10 0 1 1 22 12v1.5a3.5 3.5 0 0 1-6.4 1.97zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
calendar: 'M17 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h2V3a1 1 0 1 1 2 0v1h6V3a1 1 0 0 1 2 0v1zm-2 2H9v1a1 1 0 1 1-2 0V6H5v4h14V6h-2v1a1 1 0 0 1-2 0V6zm4 6H5v8h14v-8z',
atSymbol:
'M15.6 15.47A4.99 4.99 0 0 1 7 12a5 5 0 0 1 10 0v1.5a1.5 1.5 0 1 0 3 0V12a8 8 0 1 0-4.94 7.4 1 1 0 1 1 .77 1.84A10 10 0 1 1 22 12v1.5a3.5 3.5 0 0 1-6.4 1.97zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
calendar:
'M17 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h2V3a1 1 0 1 1 2 0v1h6V3a1 1 0 0 1 2 0v1zm-2 2H9v1a1 1 0 1 1-2 0V6H5v4h14V6h-2v1a1 1 0 0 1-2 0V6zm4 6H5v8h14v-8z',
call: 'M13.04 14.69l1.07-2.14a1 1 0 0 1 1.2-.5l6 2A1 1 0 0 1 22 15v5a2 2 0 0 1-2 2h-2A16 16 0 0 1 2 6V4c0-1.1.9-2 2-2h5a1 1 0 0 1 .95.68l2 6a1 1 0 0 1-.5 1.21L9.3 10.96a10.05 10.05 0 0 0 3.73 3.73zM8.28 4H4v2a14 14 0 0 0 14 14h2v-4.28l-4.5-1.5-1.12 2.26a1 1 0 0 1-1.3.46 12.04 12.04 0 0 1-6.02-6.01 1 1 0 0 1 .46-1.3l2.26-1.14L8.28 4z',
link: 'M19.48 13.03A4 4 0 0 1 16 19h-4a4 4 0 1 1 0-8h1a1 1 0 0 0 0-2h-1a6 6 0 1 0 0 12h4a6 6 0 0 0 5.21-8.98L21.2 12a1 1 0 1 0-1.72 1.03zM4.52 10.97A4 4 0 0 1 8 5h4a4 4 0 1 1 0 8h-1a1 1 0 0 0 0 2h1a6 6 0 1 0 0-12H8a6 6 0 0 0-5.21 8.98l.01.02a1 1 0 1 0 1.72-1.03z',
location: 'M5.64 16.36a9 9 0 1 1 12.72 0l-5.65 5.66a1 1 0 0 1-1.42 0l-5.65-5.66zm11.31-1.41a7 7 0 1 0-9.9 0L12 19.9l4.95-4.95zM12 14a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-2a2 2 0 1 0 0-4 2 2 0 0 0 0 4z',
location:
'M5.64 16.36a9 9 0 1 1 12.72 0l-5.65 5.66a1 1 0 0 1-1.42 0l-5.65-5.66zm11.31-1.41a7 7 0 1 0-9.9 0L12 19.9l4.95-4.95zM12 14a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-2a2 2 0 1 0 0-4 2 2 0 0 0 0 4z',
dot: 'M3,12a9,9 0 1,0 18,0a9,9 0 1,0 -18,0',
search: 'M16.32 14.9l5.39 5.4a1 1 0 0 1-1.42 1.4l-5.38-5.38a8 8 0 1 1 1.41-1.41zM10 16a6 6 0 1 0 0-12 6 6 0 0 0 0 12z',
search:
'M16.32 14.9l5.39 5.4a1 1 0 0 1-1.42 1.4l-5.38-5.38a8 8 0 1 1 1.41-1.41zM10 16a6 6 0 1 0 0-12 6 6 0 0 0 0 12z',
cog: 'M9 4.58V4c0-1.1.9-2 2-2h2a2 2 0 0 1 2 2v.58a8 8 0 0 1 1.92 1.11l.5-.29a2 2 0 0 1 2.74.73l1 1.74a2 2 0 0 1-.73 2.73l-.5.29a8.06 8.06 0 0 1 0 2.22l.5.3a2 2 0 0 1 .73 2.72l-1 1.74a2 2 0 0 1-2.73.73l-.5-.3A8 8 0 0 1 15 19.43V20a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-.58a8 8 0 0 1-1.92-1.11l-.5.29a2 2 0 0 1-2.74-.73l-1-1.74a2 2 0 0 1 .73-2.73l.5-.29a8.06 8.06 0 0 1 0-2.22l-.5-.3a2 2 0 0 1-.73-2.72l1-1.74a2 2 0 0 1 2.73-.73l.5.3A8 8 0 0 1 9 4.57zM7.88 7.64l-.54.51-1.77-1.02-1 1.74 1.76 1.01-.17.73a6.02 6.02 0 0 0 0 2.78l.17.73-1.76 1.01 1 1.74 1.77-1.02.54.51a6 6 0 0 0 2.4 1.4l.72.2V20h2v-2.04l.71-.2a6 6 0 0 0 2.41-1.4l.54-.51 1.77 1.02 1-1.74-1.76-1.01.17-.73a6.02 6.02 0 0 0 0-2.78l-.17-.73 1.76-1.01-1-1.74-1.77 1.02-.54-.51a6 6 0 0 0-2.4-1.4l-.72-.2V4h-2v2.04l-.71.2a6 6 0 0 0-2.41 1.4zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0-2a2 2 0 1 0 0-4 2 2 0 0 0 0 4z',
puzzle: 'M17 22a2 2 0 0 1-2-2v-1a1 1 0 0 0-1-1 1 1 0 0 0-1 1v1a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-3H5a3 3 0 1 1 0-6h1V8c0-1.11.9-2 2-2h3V5a3 3 0 1 1 6 0v1h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-1a1 1 0 0 0-1 1 1 1 0 0 0 1 1h1a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-3zm3-2v-3h-1a3 3 0 1 1 0-6h1V8h-3a2 2 0 0 1-2-2V5a1 1 0 0 0-1-1 1 1 0 0 0-1 1v1a2 2 0 0 1-2 2H8v3a2 2 0 0 1-2 2H5a1 1 0 0 0-1 1 1 1 0 0 0 1 1h1a2 2 0 0 1 2 2v3h3v-1a3 3 0 1 1 6 0v1h3z'
puzzle:
'M17 22a2 2 0 0 1-2-2v-1a1 1 0 0 0-1-1 1 1 0 0 0-1 1v1a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-3H5a3 3 0 1 1 0-6h1V8c0-1.11.9-2 2-2h3V5a3 3 0 1 1 6 0v1h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-1a1 1 0 0 0-1 1 1 1 0 0 0 1 1h1a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-3zm3-2v-3h-1a3 3 0 1 1 0-6h1V8h-3a2 2 0 0 1-2-2V5a1 1 0 0 0-1-1 1 1 0 0 0-1 1v1a2 2 0 0 1-2 2H8v3a2 2 0 0 1-2 2H5a1 1 0 0 0-1 1 1 1 0 0 0 1 1h1a2 2 0 0 1 2 2v3h3v-1a3 3 0 1 1 6 0v1h3z',
}

const defaultSize = 24
Expand All @@ -32,6 +38,7 @@ export function Icon({
debug = false,
color = 'black',
}: IconProps) {
// biome-ignore lint/suspicious/noExplicitAny: I don't know what type `doc` is but it does what I need
function drawIcon(doc: any) {
return doc
.scale(size / defaultSize)
Expand All @@ -43,7 +50,7 @@ export function Icon({
return (
<Canvas
debug={debug}
style={[{ width: size, height: size }, style!]}
style={cn({ width: size, height: size }, style)}
paint={drawIcon}
/>
)
Expand Down
9 changes: 5 additions & 4 deletions src/app/ui/insight/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Text, View, Style, StyleSheet } from '~/react-pdf'
import { RoundedIcon } from '../rounded-icon'
import type { IconName } from '../icon'
import { cn } from '~/app/cn'
import { useTheme } from '~/app/hooks/use-theme'
import { Style, StyleSheet, Text, View } from '~/react-pdf'
import type { IconName } from '../icon'
import { RoundedIcon } from '../rounded-icon'

export interface InsightProps {
style?: Style
Expand Down Expand Up @@ -30,7 +31,7 @@ export function Insight({ style, title, description, iconName }: InsightProps) {
const theme = useTheme()

return (
<View style={[styles.container, style!]}>
<View style={cn(styles.container, style)}>
{iconName && (
<RoundedIcon
size={18}
Expand Down
5 changes: 3 additions & 2 deletions src/app/ui/language/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cn } from '~/app/cn'
import { useTheme } from '~/app/hooks/use-theme'
import { View, Text, Style, StyleSheet } from '~/react-pdf'
import { Style, StyleSheet, Text, View } from '~/react-pdf'
import { Score } from '../score'

export interface LanguageProps {
Expand Down Expand Up @@ -30,7 +31,7 @@ export function Language({ style, name, scoreLabel, score }: LanguageProps) {
const theme = useTheme()

return (
<View style={[styles.container, style!]}>
<View style={cn(styles.container, style)}>
<Text style={styles.name}>{name}</Text>
<Text style={[styles.scoreLabel, { color: theme.colors.text }]}>
{scoreLabel}
Expand Down
5 changes: 3 additions & 2 deletions src/app/ui/list-item/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { cn } from '~/app/cn'
import { useTheme } from '~/app/hooks/use-theme'
import { Text, View, Style, StyleSheet } from '~/react-pdf'
import { Style, StyleSheet, Text, View } from '~/react-pdf'
import { Icon } from '../icon'

export interface ListItemProps {
Expand All @@ -23,7 +24,7 @@ export function ListItem({ style, children }: ListItemProps) {
const theme = useTheme()

return (
<View style={[styles.container, style!]}>
<View style={cn(styles.container, style)}>
<Icon name="dot" size={3.5} style={{ margin: 4, marginRight: 8 }} />
<Text style={[styles.text, { color: theme.colors.text }]}>
{children.replace(/\xa0/g, ' ')}
Expand Down
Loading

0 comments on commit 628f28b

Please sign in to comment.