Skip to content

Commit

Permalink
feat: upgrade to ipx 2
Browse files Browse the repository at this point in the history
  • Loading branch information
ascorbic committed Oct 30, 2023
1 parent bfffe93 commit 28b1f77
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 30 deletions.
15 changes: 14 additions & 1 deletion example/netlify/functions/ipx.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createIPXHandler } from '@netlify/ipx'

export const handler = createIPXHandler({
const handle = createIPXHandler({
remotePatterns: [
{
protocol: 'https',
Expand All @@ -17,3 +17,16 @@ export const handler = createIPXHandler({
'X-Test': 'foobar'
}
})

export const handler = async (event, context) => {
try {
return await handle(event, context)
} catch (e) {
// eslint-disable-next-line no-console
console.error(e)
return {
statusCode: 500,
body: 'Internal Server Error'
}
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@netlify/functions": "^2.3.0",
"etag": "^1.8.1",
"fs-extra": "^11.0.0",
"ipx": "^1.3.1",
"ipx": "^2.0.0",
"micromatch": "^4.0.5",
"mkdirp": "^3.0.0",
"murmurhash": "^2.0.0",
Expand Down
7 changes: 6 additions & 1 deletion src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,13 @@ const USAGE_TRACKING_KEY = 'usage-tracking'
const trackingLock = new Lock()

async function getTracking (metadataStore: Storage): Promise<UsageTracking> {
return ((await metadataStore.getItem(USAGE_TRACKING_KEY)) ??
const usage = ((await metadataStore.getItem(USAGE_TRACKING_KEY)) ||
{}) as UsageTracking

if (typeof usage !== 'object') {
return {}
}
return usage
}

async function markUsageStart (
Expand Down
48 changes: 33 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { join } from 'path'
import { tmpdir } from 'os'
import { createIPX, handleRequest, IPXOptions } from 'ipx'
import { createIPX, createIPXPlainServer, ipxFSStorage, ipxHttpStorage, IPXOptions } from 'ipx'
import { builder, Handler } from '@netlify/functions'
import { parseURL } from 'ufo'
import etag from 'etag'
Expand Down Expand Up @@ -30,6 +30,10 @@ export interface IPXHandlerOptions extends Partial<IPXOptions> {
* Restrict local image access to a specific prefix
*/
localPrefix?: string
/**
* List of domains to allow for remote images
*/
domains?: string[]
/**
* Patterns used to verify remote image URLs
*/
Expand All @@ -54,9 +58,21 @@ export function createIPXHandler ({
remotePatterns,
responseHeaders,
localPrefix,
domains = [],
...opts
}: IPXHandlerOptions = {}, loadSourceImage = defaultLoadSourceImage) {
const ipx = createIPX({ ...opts, dir: join(cacheDir, 'cache') })
const ipx = createIPX(
{
storage: ipxFSStorage({
dir: join(cacheDir, 'cache')
}),
httpStorage: ipxHttpStorage({
...opts
})
})

const handleRequest = createIPXPlainServer(ipx)

if (!basePath.endsWith('/')) {
basePath = `${basePath}/`
}
Expand All @@ -73,7 +89,7 @@ export function createIPXHandler ({
headers: plainText
}
}
let domains = (opts as IPXOptions).domains || []

const remoteURLPatterns = remotePatterns || []
const requestEtag = event.headers['if-none-match']
const eventPath = event.path.replace(basePath, '')
Expand Down Expand Up @@ -195,19 +211,21 @@ export function createIPXHandler ({

const res = await handleRequest(
{
url: `/${modifiers}/${cacheKey}`,
headers: event.headers
},
ipx
path: `/${modifiers}/${cacheKey}`,
headers: event.headers,
method: 'GET'
}
)

const headers = Object.fromEntries(res.headers)

const body =
typeof res.body === 'string' ? res.body : res.body.toString('base64')
typeof res.body === 'string' ? res.body : (res.body as Buffer).toString('base64')

res.headers.etag = responseEtag || JSON.parse(etag(body))
delete res.headers['Last-Modified']
headers.etag = responseEtag || JSON.parse(etag(body))
delete headers['Last-Modified']

if (requestEtag && requestEtag === res.headers.etag) {
if (requestEtag && requestEtag === headers.etag) {
return {
statusCode: 304,
message: 'Not Modified'
Expand All @@ -216,14 +234,14 @@ export function createIPXHandler ({

if (responseHeaders) {
for (const [header, value] of Object.entries(responseHeaders)) {
res.headers[header] = value
headers[header] = value
}
}

return {
statusCode: res.statusCode,
message: res.statusMessage,
headers: res.headers,
statusCode: res.status,
statusText: res.statusText,
headers,
isBase64Encoded: typeof res.body !== 'string',
body
}
Expand Down
Loading

0 comments on commit 28b1f77

Please sign in to comment.