@vercel/blob
Advanced tools
Comparing version 0.8.1 to 0.8.2
@@ -38,4 +38,4 @@ import { Readable } from 'node:stream'; | ||
declare function put(pathname: string, body: string | Readable | Blob | ArrayBuffer | FormData | ReadableStream, options: PutCommandOptions): Promise<BlobResult>; | ||
declare function del(url: string, options?: BlobCommandOptions): Promise<BlobResult | null>; | ||
declare function del(url: string[], options?: BlobCommandOptions): Promise<(BlobResult | null)[]>; | ||
type BlobDelResult<T extends string | string[]> = T extends string ? BlobResult | null : (BlobResult | null)[]; | ||
declare function del<T extends string | string[]>(url: T, options?: BlobCommandOptions): Promise<BlobDelResult<T>>; | ||
declare function head(url: string, options?: BlobCommandOptions): Promise<BlobResult | null>; | ||
@@ -42,0 +42,0 @@ declare function list(options?: ListCommandOptions): Promise<ListBlobResult>; |
@@ -1,1 +0,1 @@ | ||
import{fetch as l}from"undici";var i=class extends Error{constructor(r){super(`Vercel Blob: ${r}`)}},o=class extends Error{constructor(){super("Vercel Blob: Access denied, please provide a valid token for this resource")}},a=class extends Error{constructor(){super("Vercel Blob: Unknown error, please contact support@vercel.com")}};async function m(e,r,t){if(!e)throw new i("pathname is required");if(!r)throw new i("body is required");if(!t||t.access!=="public")throw new i('access must be "public"');let s={authorization:`Bearer ${c(t)}`};t.contentType&&(s["x-content-type"]=t.contentType);let n=await l(`${u()}/${e}`,{method:"PUT",body:r,headers:s,duplex:"half"});if(n.status!==200)throw n.status===403?new o:new a;return n.json()}async function b(e,r){let t=await l(`${u()}/delete`,{method:"POST",headers:{authorization:`Bearer ${c(r)}`,"content-type":"application/json"},body:JSON.stringify({urls:Array.isArray(e)?e:[e]})});if(t.status!==200)throw t.status===403?new o:new a;let s=await t.json();return Array.isArray(e)?s:s[0]}async function p(e,r){let t=new URL(u());t.searchParams.set("url",e);let s=await l(t,{method:"GET",headers:{authorization:`Bearer ${c(r)}`}});if(s.status===404)return null;if(s.status!==200)throw s.status===403?new o:new a;let n=await s.json();return{...n,uploadedAt:new Date(n.uploadedAt)}}async function f(e){let r=new URL(u());e!=null&&e.limit&&r.searchParams.set("limit",e.limit.toString()),e!=null&&e.prefix&&r.searchParams.set("prefix",e.prefix),e!=null&&e.cursor&&r.searchParams.set("cursor",e.cursor);let t=await l(r,{method:"GET",headers:{authorization:`Bearer ${c(e)}`}});if(t.status!==200)throw t.status===403?new o:new a;let s=await t.json();return{...s,blobs:s.blobs.map(n=>({...n,uploadedAt:new Date(n.uploadedAt)}))}}function u(){return process.env.VERCEL_BLOB_API_URL||"https://blob.vercel-storage.com"}function c(e){if(e!=null&&e.token)return e.token;if(!process.env.BLOB_READ_WRITE_TOKEN)throw new Error("BLOB_READ_WRITE_TOKEN environment variable is not set. Please set it to your write token.");return process.env.BLOB_READ_WRITE_TOKEN}export{o as BlobAccessError,i as BlobError,a as BlobUnknownError,b as del,p as head,f as list,m as put}; | ||
import{fetch as u}from"undici";var i=class extends Error{constructor(s){super(`Vercel Blob: ${s}`)}},a=class extends Error{constructor(){super("Vercel Blob: Access denied, please provide a valid token for this resource")}},o=class extends Error{constructor(){super("Vercel Blob: Unknown error, please contact support@vercel.com")}};async function p(e,s,t){if(!e)throw new i("pathname is required");if(!s)throw new i("body is required");if(!t||t.access!=="public")throw new i('access must be "public"');let r={authorization:`Bearer ${d(t)}`};t.contentType&&(r["x-content-type"]=t.contentType);let n=await u(`${c()}/${e}`,{method:"PUT",body:s,headers:r,duplex:"half"});if(n.status!==200)throw n.status===403?new a:new o;let b=await n.json();return l(b)}async function f(e,s){let t=await u(`${c()}/delete`,{method:"POST",headers:{authorization:`Bearer ${d(s)}`,"content-type":"application/json"},body:JSON.stringify({urls:Array.isArray(e)?e:[e]})});if(t.status!==200)throw t.status===403?new a:new o;let r=await t.json();return Array.isArray(e)?r.map(n=>n?l(n):null):r[0]?l(r[0]):null}async function B(e,s){let t=new URL(c());t.searchParams.set("url",e);let r=await u(t,{method:"GET",headers:{authorization:`Bearer ${d(s)}`}});if(r.status===404)return null;if(r.status!==200)throw r.status===403?new a:new o;let n=await r.json();return l(n)}async function R(e){let s=new URL(c());e!=null&&e.limit&&s.searchParams.set("limit",e.limit.toString()),e!=null&&e.prefix&&s.searchParams.set("prefix",e.prefix),e!=null&&e.cursor&&s.searchParams.set("cursor",e.cursor);let t=await u(s,{method:"GET",headers:{authorization:`Bearer ${d(e)}`}});if(t.status!==200)throw t.status===403?new a:new o;let r=await t.json();return{...r,blobs:r.blobs.map(l)}}function c(){return process.env.VERCEL_BLOB_API_URL||"https://blob.vercel-storage.com"}function d(e){if(e!=null&&e.token)return e.token;if(!process.env.BLOB_READ_WRITE_TOKEN)throw new Error("BLOB_READ_WRITE_TOKEN environment variable is not set. Please set it to your write token.");return process.env.BLOB_READ_WRITE_TOKEN}function l(e){return{...e,uploadedAt:new Date(e.uploadedAt)}}export{a as BlobAccessError,i as BlobError,o as BlobUnknownError,f as del,B as head,R as list,p as put}; |
{ | ||
"name": "@vercel/blob", | ||
"version": "0.8.1", | ||
"version": "0.8.2", | ||
"description": "The Vercel Blob JavaScript API client", | ||
@@ -35,2 +35,6 @@ "homepage": "https://vercel.com/blob", | ||
], | ||
"jest": { | ||
"preset": "ts-jest", | ||
"testEnvironment": "node" | ||
}, | ||
"dependencies": { | ||
@@ -40,3 +44,12 @@ "undici": "5.22.0" | ||
"devDependencies": { | ||
"tsup": "6.7.0" | ||
"@edge-runtime/jest-environment": "2.1.0", | ||
"@edge-runtime/types": "2.0.8", | ||
"@types/jest": "29.5.1", | ||
"@types/node": "18.16.3", | ||
"eslint": "8.25.0", | ||
"jest": "29.2.1", | ||
"ts-jest": "29.0.3", | ||
"tsup": "6.7.0", | ||
"eslint-config-custom": "0.0.0", | ||
"tsconfig": "0.0.0" | ||
}, | ||
@@ -48,4 +61,9 @@ "engines": { | ||
"build": "tsup && cp src/undici-browser.js dist/undici-browser.js", | ||
"dev": "cp src/undici-browser.js dist/undici-browser.js && tsup --watch --clean=false" | ||
"dev": "cp src/undici-browser.js dist/undici-browser.js && tsup --watch --clean=false", | ||
"lint": "eslint --max-warnings=0 .", | ||
"prettier-check": "prettier --check .", | ||
"publint": "npx publint", | ||
"test": "jest", | ||
"type-check": "tsc --noEmit" | ||
} | ||
} |
@@ -133,4 +133,4 @@ # 🍙 @vercel/blob | ||
- [Next.js App Router examples](./example/app/) | ||
- [https.get, axios, and got](./example/script.ts) | ||
- [Next.js App Router examples](../../test/next/src/app/vercel/blob/) | ||
- [https.get, axios, and got](../../test/next/src/app/vercel/blob/script.ts) | ||
@@ -146,7 +146,7 @@ ### Next.js App Router example | ||
import type { PutBlobResult } from '@vercel/blob'; | ||
import type { BlobResult } from '@vercel/blob'; | ||
import { useState } from 'react'; | ||
export default function UploadForm() { | ||
const [blob, setBlob] = useState<PutBlobResult | null>(null); | ||
const [blob, setBlob] = useState<BlobResult | null>(null); | ||
@@ -167,3 +167,3 @@ return ( | ||
}); | ||
const blob = (await response.json()) as PutBlobResult; | ||
const blob = (await response.json()) as BlobResult; | ||
setBlob(blob); | ||
@@ -272,1 +272,45 @@ }} | ||
- for Vercel contributors, link on how to run the API locally (edge-functions readme link, wrangler dev, pnpm dev for module) | ||
## A note for Vite users | ||
`@vercel/blob` reads the token from the environment variables on `process.env`. In general, `process.env` is automatically populated from your `.env` file during development, which is created when you run `vc env pull`. However, Vite does not expose the `.env` variables on `process.env.` | ||
You can fix this in **one** of following two ways: | ||
1. You can populate `process.env` yourself using something like `dotenv-expand`: | ||
```shell | ||
pnpm install --save-dev dotenv dotenv-expand | ||
``` | ||
```js | ||
// vite.config.js | ||
import dotenvExpand from 'dotenv-expand'; | ||
import { loadEnv, defineConfig } from 'vite'; | ||
export default defineConfig(({ mode }) => { | ||
// This check is important! | ||
if (mode === 'development') { | ||
const env = loadEnv(mode, process.cwd(), ''); | ||
dotenvExpand.expand({ parsed: env }); | ||
} | ||
return { | ||
... | ||
}; | ||
}); | ||
``` | ||
2. You can provide the credentials explicitly, instead of relying on a zero-config setup. For example, this is how you could create a client in SvelteKit, which makes private environment variables available via `$env/static/private`: | ||
```diff | ||
import { put } from '@vercel/blob'; | ||
+ import { BLOB_TOKEN } from '$env/static/private'; | ||
const kv = await head("filepath", { | ||
- token: '<token>', | ||
+ token: BLOB_TOKEN, | ||
}); | ||
await kv.set('key', 'value'); | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18642
313
39
10
7