Skip to content

Commit 28b1f77

Browse files
committed
feat: upgrade to ipx 2
1 parent bfffe93 commit 28b1f77

File tree

5 files changed

+215
-30
lines changed

5 files changed

+215
-30
lines changed

example/netlify/functions/ipx.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createIPXHandler } from '@netlify/ipx'
22

3-
export const handler = createIPXHandler({
3+
const handle = createIPXHandler({
44
remotePatterns: [
55
{
66
protocol: 'https',
@@ -17,3 +17,16 @@ export const handler = createIPXHandler({
1717
'X-Test': 'foobar'
1818
}
1919
})
20+
21+
export const handler = async (event, context) => {
22+
try {
23+
return await handle(event, context)
24+
} catch (e) {
25+
// eslint-disable-next-line no-console
26+
console.error(e)
27+
return {
28+
statusCode: 500,
29+
body: 'Internal Server Error'
30+
}
31+
}
32+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"@netlify/functions": "^2.3.0",
2121
"etag": "^1.8.1",
2222
"fs-extra": "^11.0.0",
23-
"ipx": "^1.3.1",
23+
"ipx": "^2.0.0",
2424
"micromatch": "^4.0.5",
2525
"mkdirp": "^3.0.0",
2626
"murmurhash": "^2.0.0",

src/http.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,13 @@ const USAGE_TRACKING_KEY = 'usage-tracking'
5656
const trackingLock = new Lock()
5757

5858
async function getTracking (metadataStore: Storage): Promise<UsageTracking> {
59-
return ((await metadataStore.getItem(USAGE_TRACKING_KEY)) ??
59+
const usage = ((await metadataStore.getItem(USAGE_TRACKING_KEY)) ||
6060
{}) as UsageTracking
61+
62+
if (typeof usage !== 'object') {
63+
return {}
64+
}
65+
return usage
6166
}
6267

6368
async function markUsageStart (

src/index.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { join } from 'path'
22
import { tmpdir } from 'os'
3-
import { createIPX, handleRequest, IPXOptions } from 'ipx'
3+
import { createIPX, createIPXPlainServer, ipxFSStorage, ipxHttpStorage, IPXOptions } from 'ipx'
44
import { builder, Handler } from '@netlify/functions'
55
import { parseURL } from 'ufo'
66
import etag from 'etag'
@@ -30,6 +30,10 @@ export interface IPXHandlerOptions extends Partial<IPXOptions> {
3030
* Restrict local image access to a specific prefix
3131
*/
3232
localPrefix?: string
33+
/**
34+
* List of domains to allow for remote images
35+
*/
36+
domains?: string[]
3337
/**
3438
* Patterns used to verify remote image URLs
3539
*/
@@ -54,9 +58,21 @@ export function createIPXHandler ({
5458
remotePatterns,
5559
responseHeaders,
5660
localPrefix,
61+
domains = [],
5762
...opts
5863
}: IPXHandlerOptions = {}, loadSourceImage = defaultLoadSourceImage) {
59-
const ipx = createIPX({ ...opts, dir: join(cacheDir, 'cache') })
64+
const ipx = createIPX(
65+
{
66+
storage: ipxFSStorage({
67+
dir: join(cacheDir, 'cache')
68+
}),
69+
httpStorage: ipxHttpStorage({
70+
...opts
71+
})
72+
})
73+
74+
const handleRequest = createIPXPlainServer(ipx)
75+
6076
if (!basePath.endsWith('/')) {
6177
basePath = `${basePath}/`
6278
}
@@ -73,7 +89,7 @@ export function createIPXHandler ({
7389
headers: plainText
7490
}
7591
}
76-
let domains = (opts as IPXOptions).domains || []
92+
7793
const remoteURLPatterns = remotePatterns || []
7894
const requestEtag = event.headers['if-none-match']
7995
const eventPath = event.path.replace(basePath, '')
@@ -195,19 +211,21 @@ export function createIPXHandler ({
195211

196212
const res = await handleRequest(
197213
{
198-
url: `/${modifiers}/${cacheKey}`,
199-
headers: event.headers
200-
},
201-
ipx
214+
path: `/${modifiers}/${cacheKey}`,
215+
headers: event.headers,
216+
method: 'GET'
217+
}
202218
)
203219

220+
const headers = Object.fromEntries(res.headers)
221+
204222
const body =
205-
typeof res.body === 'string' ? res.body : res.body.toString('base64')
223+
typeof res.body === 'string' ? res.body : (res.body as Buffer).toString('base64')
206224

207-
res.headers.etag = responseEtag || JSON.parse(etag(body))
208-
delete res.headers['Last-Modified']
225+
headers.etag = responseEtag || JSON.parse(etag(body))
226+
delete headers['Last-Modified']
209227

210-
if (requestEtag && requestEtag === res.headers.etag) {
228+
if (requestEtag && requestEtag === headers.etag) {
211229
return {
212230
statusCode: 304,
213231
message: 'Not Modified'
@@ -216,14 +234,14 @@ export function createIPXHandler ({
216234

217235
if (responseHeaders) {
218236
for (const [header, value] of Object.entries(responseHeaders)) {
219-
res.headers[header] = value
237+
headers[header] = value
220238
}
221239
}
222240

223241
return {
224-
statusCode: res.statusCode,
225-
message: res.statusMessage,
226-
headers: res.headers,
242+
statusCode: res.status,
243+
statusText: res.statusText,
244+
headers,
227245
isBase64Encoded: typeof res.body !== 'string',
228246
body
229247
}

0 commit comments

Comments
 (0)