-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: dynamic
og:image
generation (#85)
- Loading branch information
1 parent
1198275
commit c1f7549
Showing
18 changed files
with
164 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,16 @@ | ||
import { cn } from "@/lib/utils" | ||
import { cn } from '@/lib/utils'; | ||
|
||
describe('check classnames (twMerge)', () => { | ||
it('normal checks', () => { | ||
expect(cn("w-full", "h-full")).toBe("w-full h-full"); | ||
expect(cn("md:max-h-[1vw]", "md:hover:max-h-[10vw]")).toBe( | ||
"md:max-h-[1vw] md:hover:max-h-[10vw]" | ||
expect(cn('w-full', 'h-full')).toBe('w-full h-full'); | ||
expect(cn('md:max-h-[1vw]', 'md:hover:max-h-[10vw]')).toBe( | ||
'md:max-h-[1vw] md:hover:max-h-[10vw]', | ||
); | ||
}) | ||
}); | ||
|
||
it('whitespace check', () => { | ||
expect(cn(" w-full", "h-full ")).toBe( | ||
"w-full h-full" | ||
expect(cn(' w-full', 'h-full ')).toBe( | ||
'w-full h-full', | ||
); | ||
}) | ||
}) | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,17 @@ | ||
import { escapeText } from "@/lib/utils" | ||
import { escapeText } from '@/lib/utils'; | ||
|
||
describe('escape text', () => { | ||
it('should return lower case of plainText', () => { | ||
expect(escapeText('plainText')).toBe('plaintext'); | ||
}) | ||
}); | ||
|
||
it('should return sluggified version of text', () => { | ||
expect(escapeText('Hello World')).toBe('hello-world'); | ||
expect(escapeText('Moonlit@grace')).toBe('moonlit-grace'); | ||
}) | ||
}); | ||
|
||
it('should handle multiplte special characters', () => { | ||
expect(escapeText('hello-----world')).toBe('hello-world'); | ||
expect(escapeText('moon&&&lit***grace')).toBe('moon-lit-grace') | ||
}) | ||
}) | ||
expect(escapeText('moon&&&lit***grace')).toBe('moon-lit-grace'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { formatDate } from "@/lib/utils"; | ||
import { formatDate } from '@/lib/utils'; | ||
|
||
test('check formated date', () => { | ||
const date = new Date("2023-03-11T02:37:40.790Z"); | ||
expect(formatDate(date)).toBe("Mar 11, 2023"); | ||
}) | ||
const date = new Date('2023-03-11T02:37:40.790Z'); | ||
expect(formatDate(date)).toBe('Mar 11, 2023'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
import { stripHtmlTags } from "@/lib/utils" | ||
import { stripHtmlTags } from '@/lib/utils'; | ||
|
||
describe('stripe html tags', () => { | ||
it('should return plaintext itself', () => { | ||
expect(stripHtmlTags('plain-text')).toBe('plain-text') | ||
}) | ||
expect(stripHtmlTags('plain-text')).toBe('plain-text'); | ||
}); | ||
|
||
it('should return content inside', () => { | ||
expect(stripHtmlTags('<strong>Moonlitgrace</strong>')).toBe('Moonlitgrace') | ||
expect(stripHtmlTags('<h1><italic>Hello World</italic></h1>')).toBe('Hello World') | ||
}) | ||
}) | ||
expect(stripHtmlTags('<strong>Moonlitgrace</strong>')).toBe('Moonlitgrace'); | ||
expect(stripHtmlTags('<h1><italic>Hello World</italic></h1>')).toBe('Hello World'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
import { truncate } from "@/lib/utils" | ||
import { truncate } from '@/lib/utils'; | ||
|
||
describe('truncate char', () => { | ||
const exampleStr = 'Step into Moonlitgrace' | ||
const exampleStr = 'Step into Moonlitgrace'; | ||
|
||
it('shouldn"t truncate char shorter than n', () => { | ||
expect(truncate(exampleStr, 25)).toBe(exampleStr) | ||
}) | ||
expect(truncate(exampleStr, 25)).toBe(exampleStr); | ||
}); | ||
|
||
it('shouldn truncate char larger than n', () => { | ||
expect(truncate(exampleStr, 20)).toBe('Step into Moonlit...') | ||
}) | ||
}) | ||
expect(truncate(exampleStr, 20)).toBe('Step into Moonlit...'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,27 @@ | ||
import { validateFile } from "@/lib/utils"; | ||
import { validateFile } from '@/lib/utils'; | ||
|
||
describe('check File validation', () => { | ||
it('should return true if File is valid', () => { | ||
const file = new File(['content'], 'test.txt', { type: 'text/plain' }); | ||
expect(validateFile(file)).toBeTruthy(); | ||
}) | ||
}); | ||
|
||
it('should return false if File is invalid', () => { | ||
const file = {} as File; | ||
expect(validateFile(file)).toBeFalsy(); | ||
}) | ||
}); | ||
|
||
it('should return false if File name is invalid', () => { | ||
const file = new File(['content'], '', { type: 'text/plain' }); | ||
expect(validateFile(file)).toBeFalsy(); | ||
}) | ||
}); | ||
|
||
it('should return false if File size is invalid', () => { | ||
const file = new File(['content'], 'test.txt', { type: 'text/plain' }); | ||
// force set size property | ||
Object.defineProperty(file, 'size', { | ||
value: 0 | ||
}) | ||
value: 0, | ||
}); | ||
expect(validateFile(file)).toBeFalsy(); | ||
}) | ||
}) | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* eslint-disable @next/next/no-img-element */ | ||
/* eslint-disable jsx-a11y/alt-text */ | ||
import { arrayBufferToBase64 } from '@/lib/utils'; | ||
import { ImageResponse } from 'next/og'; | ||
|
||
export const runtime = 'edge'; | ||
|
||
export async function GET(request: Request) { | ||
try { | ||
const { searchParams } = new URL(request.url); | ||
|
||
const title = searchParams.get('title'); | ||
const description = searchParams.get('description'); | ||
const tag = searchParams.get('tag'); | ||
const createdAt = searchParams.get('createdAt'); | ||
const cover = searchParams.get('cover'); | ||
|
||
const DM_sans_Black_fontdata = await fetch( | ||
new URL('../../../assets/fonts/dm-sans/dm-sans-900-normal.ttf', import.meta.url), | ||
).then((res) => res.arrayBuffer()); | ||
const DM_sans_Regular_fontdata = await fetch( | ||
new URL('../../../assets/fonts/dm-sans/dm-sans-400-normal.ttf', import.meta.url), | ||
).then((res) => res.arrayBuffer()); | ||
|
||
const altCoverData = await fetch(new URL('../../../assets/images/icon.png', import.meta.url)) | ||
.then((res) => res.arrayBuffer()) | ||
.then((buffer) => `data:image/png;base64,${arrayBufferToBase64(buffer)}`); | ||
|
||
return new ImageResponse( | ||
( | ||
<div tw="bg-[#030712] w-full h-full flex items-center p-20"> | ||
<div tw="flex flex-col flex-1 mr-10"> | ||
<div tw="flex items-center"> | ||
<span | ||
style={{ fontFamily: 'DM_sans_Black' }} | ||
tw="bg-[#6D28D9] text-[#F9FAFB] p-1 px-3 rounded-full capitalize" | ||
> | ||
{tag} | ||
</span> | ||
<span style={{ fontFamily: 'DM_sans_Black' }} tw="ml-3 text-[#F9FAFB]/75 uppercase"> | ||
{createdAt} | ||
</span> | ||
</div> | ||
<h1 style={{ fontFamily: 'DM_sans_Black' }} tw="text-[#F9FAFB] text-6xl"> | ||
{title} | ||
</h1> | ||
<p style={{ fontFamily: 'DM_sans_Regular' }} tw="text-[#F9FAFB]/75 text-2xl"> | ||
{description} | ||
</p>{' '} | ||
</div> | ||
<img | ||
tw="w-[300px] h-[300px] rounded-3xl" | ||
style={{ objectFit: 'cover' }} | ||
src={cover ?? altCoverData} | ||
/> | ||
</div> | ||
), | ||
{ | ||
fonts: [ | ||
{ | ||
name: 'DM_sans_Black', | ||
data: DM_sans_Black_fontdata, | ||
style: 'normal', | ||
}, | ||
{ | ||
name: 'DM_sans_Regular', | ||
data: DM_sans_Regular_fontdata, | ||
style: 'normal', | ||
}, | ||
], | ||
}, | ||
); | ||
} catch (err) { | ||
return new Response('Failed to generate OG image' + err, { status: 500 }); | ||
} | ||
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters