Skip to content

Commit

Permalink
fix(ssg): preserve binary files as-is (#2275)
Browse files Browse the repository at this point in the history
* fix(ssg): preserve binary files as-is

* denoify

* test(ssg): cleanup

* test(ssg): merge tests for the right content and paths
  • Loading branch information
berlysia authored Feb 26, 2024
1 parent a32482d commit d4db451
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
3 changes: 1 addition & 2 deletions deno_dist/helper/ssg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { replaceUrlParam } from '../../client/utils.ts'
import type { Context } from '../../context.ts'
import type { Hono } from '../../hono.ts'
import type { Env, MiddlewareHandler, Schema } from '../../types.ts'
import { bufferToString } from '../../utils/buffer.ts'
import { getExtension } from '../../utils/mime.ts'
import { joinPaths, dirname, filterStaticGenerateRoutes } from './utils.ts'

Expand Down Expand Up @@ -202,7 +201,7 @@ export const saveContentToFiles = async (
if (typeof content === 'string') {
await fsModule.writeFile(filePath, content)
} else if (content instanceof ArrayBuffer) {
await fsModule.writeFile(filePath, bufferToString(content))
await fsModule.writeFile(filePath, new Uint8Array(content))
}
files.push(filePath)
}
Expand Down
44 changes: 42 additions & 2 deletions src/helper/ssg/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,24 @@ describe('fetchRoutesContent function', () => {
describe('saveContentToFiles function', () => {
let fsMock: FileSystemModule
let htmlMap: Map<string, { content: string | ArrayBuffer; mimeType: string }>
// tar.gz, testdir/test.txt
const gzFileBuffer = Buffer.from(
'H4sIAAAAAAAAA+3SQQrCMBSE4aw9RU6gSc3LO0/FLgqukgj29qZgsQgqCEHE/9vMIoEMTMqQy3FMO9OQq1RkTq/i1rkwPkiMUXWvnXG+U/XGSstSi3MufbLWHIZ0mvLYP7v37vxHldv+c27LpbR4Yx44hvBi/3DfX3zdP0j9Eta1KPPoz/ef+mnz7Q4AAAAAAAAAAAAAAAAAPnMFqt1/BQAoAAA=',
'base64'
)
const gzFileArrayBuffer = gzFileBuffer.buffer.slice(
gzFileBuffer.byteOffset,
gzFileBuffer.byteLength + gzFileBuffer.byteOffset
)
// PNG, red dot (1x1)
const pngFileBuffer = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCCAAAALw',
'base64'
)
const pngFileArrayBuffer = pngFileBuffer.buffer.slice(
pngFileBuffer.byteOffset,
pngFileBuffer.byteLength + pngFileBuffer.byteOffset
)

beforeEach(() => {
fsMock = {
Expand All @@ -297,11 +315,24 @@ describe('saveContentToFiles function', () => {
['/about', { content: 'About Page', mimeType: 'text/html' }],
['/about/', { content: 'About Page', mimeType: 'text/html' }],
['/bravo/index.html', { content: 'About Page', mimeType: 'text/html' }],
['/bravo/index.tar.gz', { content: 'About Page', mimeType: 'application/gzip' }],
['/bravo/release-4.0.0', { content: 'Release 4.0.0', mimeType: 'text/html' }],
['/bravo/2024.02.18-sweet-memories', { content: 'Sweet Memories', mimeType: 'text/html' }],
['/bravo/deep.dive.to.html', { content: 'Deep Dive To HTML', mimeType: 'text/html' }],
['/bravo/alert.js', { content: 'alert("evil content")', mimeType: 'text/html' }],
[
'/bravo/index.tar.gz',
{
content: gzFileArrayBuffer,
mimeType: 'application/gzip',
},
],
[
'/bravo/dot.png',
{
content: pngFileArrayBuffer,
mimeType: 'image/png',
},
],
['/bravo.text/index.html', { content: 'About Page', mimeType: 'text/html' }],
['/bravo.text/', { content: 'Bravo Page', mimeType: 'text/html' }],
])
Expand All @@ -315,7 +346,6 @@ describe('saveContentToFiles function', () => {
expect(fsMock.writeFile).toHaveBeenCalledWith('static/about.html', 'About Page')
expect(fsMock.writeFile).toHaveBeenCalledWith('static/about/index.html', 'About Page')
expect(fsMock.writeFile).toHaveBeenCalledWith('static/bravo/index.html', 'About Page')
expect(fsMock.writeFile).toHaveBeenCalledWith('static/bravo/index.tar.gz', 'About Page')
expect(fsMock.writeFile).toHaveBeenCalledWith(
'static/bravo/release-4.0.0.html',
'Release 4.0.0'
Expand All @@ -334,6 +364,16 @@ describe('saveContentToFiles function', () => {
)
expect(fsMock.writeFile).toHaveBeenCalledWith('static/bravo.text/index.html', 'About Page')
expect(fsMock.writeFile).toHaveBeenCalledWith('static/bravo.text/index.html', 'Bravo Page')

// binary files
expect(fsMock.writeFile).toHaveBeenCalledWith(
'static/bravo/index.tar.gz',
new Uint8Array(gzFileArrayBuffer)
)
expect(fsMock.writeFile).toHaveBeenCalledWith(
'static/bravo/dot.png',
new Uint8Array(pngFileArrayBuffer)
)
})

it('should correctly create directories if they do not exist', async () => {
Expand Down
3 changes: 1 addition & 2 deletions src/helper/ssg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { replaceUrlParam } from '../../client/utils'
import type { Context } from '../../context'
import type { Hono } from '../../hono'
import type { Env, MiddlewareHandler, Schema } from '../../types'
import { bufferToString } from '../../utils/buffer'
import { getExtension } from '../../utils/mime'
import { joinPaths, dirname, filterStaticGenerateRoutes } from './utils'

Expand Down Expand Up @@ -202,7 +201,7 @@ export const saveContentToFiles = async (
if (typeof content === 'string') {
await fsModule.writeFile(filePath, content)
} else if (content instanceof ArrayBuffer) {
await fsModule.writeFile(filePath, bufferToString(content))
await fsModule.writeFile(filePath, new Uint8Array(content))
}
files.push(filePath)
}
Expand Down

0 comments on commit d4db451

Please sign in to comment.