-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(blob): allow client uploads in web workers (#817)
* fix(blob): allow client uploads in web workers Before this commit, we had guards so client uploads could only be used in browser environments, this prevented customers to use Vercel Blob in Web Workers, sometimes React Native or in general anywhere window is not really what we think it is. * changeset * actually remove this code * remove * update * debug * remove console.logs * ensure random tests * update
- Loading branch information
Showing
10 changed files
with
149 additions
and
21 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 |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
'@vercel/blob': patch | ||
--- | ||
|
||
fix(blob): allow client uploads in web workers | ||
|
||
Before this change, we had guards so client uploads could only be used in | ||
browser environments, this prevented customers to use Vercel Blob in Web | ||
Workers, sometimes React Native or in general anywhere window is not really what | ||
we think it is. |
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
62 changes: 62 additions & 0 deletions
62
test/next/src/app/vercel/blob/app/client-webworker/page.tsx
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,62 @@ | ||
/* eslint-disable -- I gave up making TS and ESLint happy here for now */ | ||
|
||
'use client'; | ||
import { useEffect, useRef, useCallback, useState } from 'react'; | ||
import { useSearchParams } from 'next/navigation'; | ||
|
||
export default function Index() { | ||
const workerRef = useRef<Worker | null>(null); | ||
const [blobUrl, setBlobUrl] = useState<string | null>(null); | ||
const searchParams = useSearchParams(); | ||
|
||
useEffect(() => { | ||
workerRef.current = new Worker( | ||
new URL('../../../../worker.ts', import.meta.url), | ||
); | ||
workerRef.current.onmessage = (event: MessageEvent<string>) => { | ||
if (event.data.startsWith('Error:')) { | ||
alert(event.data); | ||
} else { | ||
setBlobUrl(event.data); | ||
} | ||
}; | ||
return () => { | ||
workerRef.current?.terminate(); | ||
}; | ||
}, []); | ||
|
||
function handleUpload() { | ||
const fileName = searchParams?.get('fileName'); | ||
const fileContent = searchParams?.get('fileContent'); | ||
if (fileName && fileContent) { | ||
workerRef.current?.postMessage({ fileName, fileContent }); | ||
} else { | ||
alert('Missing fileName or fileContent in search params'); | ||
} | ||
} | ||
|
||
return ( | ||
<> | ||
<h1 className="text-xl mb-4"> | ||
App Router Client Upload using a Web Worker | ||
</h1> | ||
|
||
<button onClick={handleUpload}>Upload from WebWorker</button> | ||
{blobUrl && ( | ||
<div> | ||
<p> | ||
Blob URL:{' '} | ||
<a | ||
id="test-result" | ||
href={blobUrl} | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
{blobUrl} | ||
</a> | ||
</p> | ||
</div> | ||
)} | ||
</> | ||
); | ||
} |
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,13 @@ | ||
import { upload } from '@vercel/blob/client'; | ||
|
||
addEventListener( | ||
'message', | ||
async (event: MessageEvent<{ fileName: string; fileContent: string }>) => { | ||
const { fileName, fileContent } = event.data; | ||
const blob = await upload(fileName, fileContent, { | ||
access: 'public', | ||
handleUploadUrl: `/vercel/blob/api/app/handle-blob-upload/serverless`, | ||
}); | ||
postMessage(blob.url); | ||
}, | ||
); |
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,49 @@ | ||
import crypto from 'node:crypto'; | ||
import { test, expect } from '@playwright/test'; | ||
|
||
const prefix = | ||
process.env.GITHUB_PR_NUMBER || crypto.randomBytes(10).toString('hex'); | ||
|
||
test('web worker upload', async ({ browser }) => { | ||
const browserContext = await browser.newContext(); | ||
await browserContext.addCookies([ | ||
{ | ||
name: 'clientUpload', | ||
value: process.env.BLOB_UPLOAD_SECRET ?? 'YOYOYOYO', | ||
path: '/', | ||
domain: (process.env.PLAYWRIGHT_TEST_BASE_URL ?? 'localhost').replace( | ||
'https://', | ||
'', | ||
), | ||
}, | ||
]); | ||
|
||
const page = await browserContext.newPage(); | ||
|
||
const random = Math.floor(Math.random() * 10000) + 1; | ||
const fileName = `${prefix}-webworker-test${random}`; | ||
const fileContent = `created from a webworker${random}`; | ||
|
||
// Load the page with the specified search params | ||
await page.goto( | ||
`vercel/blob/app/client-webworker?fileName=${fileName}&fileContent=${fileContent}`, | ||
); | ||
|
||
// Click the upload button | ||
await page.click('button:has-text("Upload from WebWorker")'); | ||
|
||
// Wait for the blob URL to appear | ||
const blobUrlElement = await page.waitForSelector('a#test-result'); | ||
const blobUrl = await blobUrlElement.getAttribute('href'); | ||
expect(blobUrl).toBeDefined(); | ||
|
||
// fetch the blob URL from the test, not the page, and verify its content | ||
const res = await fetch(blobUrl!); | ||
const response = await res.text(); | ||
expect(response).toBe(fileContent); | ||
}); | ||
|
||
test.afterAll(async ({ request }) => { | ||
// cleanup all files | ||
await request.delete(`vercel/blob/api/app/clean?prefix=${prefix}`); | ||
}); |
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