@mantajs/adapter-file-vercel-blob 0.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter.d.ts +18 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +80 -0
- package/dist/adapter.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +23 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IFilePort } from '@mantajs/core';
|
|
2
|
+
export interface VercelBlobOptions {
|
|
3
|
+
token?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class VercelBlobAdapter implements IFilePort {
|
|
6
|
+
private _token;
|
|
7
|
+
constructor(options?: VercelBlobOptions);
|
|
8
|
+
upload(key: string, data: Buffer | ReadableStream, contentType?: string): Promise<{
|
|
9
|
+
key: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}>;
|
|
12
|
+
delete(key: string | string[]): Promise<void>;
|
|
13
|
+
getPresignedDownloadUrl(key: string): Promise<string>;
|
|
14
|
+
getDownloadStream(key: string): Promise<ReadableStream>;
|
|
15
|
+
getAsBuffer(key: string): Promise<Buffer>;
|
|
16
|
+
list(prefix?: string): Promise<string[]>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAI9C,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,qBAAa,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,MAAM,CAAQ;gBAEV,OAAO,GAAE,iBAAsB;IAWrC,MAAM,CACV,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GAAG,cAAc,EAC7B,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAUlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7C,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASrD,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IASvD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASzC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAmB/C"}
|
package/dist/adapter.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// SPEC-065/080/081 — VercelBlobAdapter implements IFilePort
|
|
2
|
+
import { MantaError } from '@mantajs/core';
|
|
3
|
+
import { del, list, put } from '@vercel/blob';
|
|
4
|
+
export class VercelBlobAdapter {
|
|
5
|
+
_token;
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
const token = options.token ?? process.env.BLOB_READ_WRITE_TOKEN;
|
|
8
|
+
if (!token) {
|
|
9
|
+
throw new MantaError('INVALID_DATA', 'VercelBlobAdapter requires BLOB_READ_WRITE_TOKEN (env or constructor options)');
|
|
10
|
+
}
|
|
11
|
+
this._token = token;
|
|
12
|
+
}
|
|
13
|
+
async upload(key, data, contentType) {
|
|
14
|
+
const blob = await put(key, data, {
|
|
15
|
+
access: 'public',
|
|
16
|
+
contentType,
|
|
17
|
+
addRandomSuffix: false,
|
|
18
|
+
token: this._token,
|
|
19
|
+
});
|
|
20
|
+
return { key, url: blob.url };
|
|
21
|
+
}
|
|
22
|
+
async delete(key) {
|
|
23
|
+
const keys = Array.isArray(key) ? key : [key];
|
|
24
|
+
// Vercel Blob del() requires full URLs. Look up each key's URL.
|
|
25
|
+
const urls = [];
|
|
26
|
+
for (const k of keys) {
|
|
27
|
+
const result = await list({ prefix: k, token: this._token, limit: 1 });
|
|
28
|
+
for (const blob of result.blobs) {
|
|
29
|
+
if (blob.pathname === k) {
|
|
30
|
+
urls.push(blob.url);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (urls.length > 0) {
|
|
35
|
+
await del(urls, { token: this._token });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async getPresignedDownloadUrl(key) {
|
|
39
|
+
const result = await list({ prefix: key, token: this._token, limit: 1 });
|
|
40
|
+
const blob = result.blobs.find((b) => b.pathname === key);
|
|
41
|
+
if (!blob) {
|
|
42
|
+
throw new MantaError('NOT_FOUND', `File "${key}" not found in Vercel Blob`);
|
|
43
|
+
}
|
|
44
|
+
return blob.url;
|
|
45
|
+
}
|
|
46
|
+
async getDownloadStream(key) {
|
|
47
|
+
const url = await this.getPresignedDownloadUrl(key);
|
|
48
|
+
const response = await fetch(url);
|
|
49
|
+
if (!response.ok || !response.body) {
|
|
50
|
+
throw new MantaError('NOT_FOUND', `Failed to download file "${key}" from Vercel Blob`);
|
|
51
|
+
}
|
|
52
|
+
return response.body;
|
|
53
|
+
}
|
|
54
|
+
async getAsBuffer(key) {
|
|
55
|
+
const url = await this.getPresignedDownloadUrl(key);
|
|
56
|
+
const response = await fetch(url);
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
throw new MantaError('NOT_FOUND', `Failed to download file "${key}" from Vercel Blob`);
|
|
59
|
+
}
|
|
60
|
+
return Buffer.from(await response.arrayBuffer());
|
|
61
|
+
}
|
|
62
|
+
async list(prefix) {
|
|
63
|
+
const allPaths = [];
|
|
64
|
+
let cursor;
|
|
65
|
+
do {
|
|
66
|
+
const result = await list({
|
|
67
|
+
prefix: prefix ?? '',
|
|
68
|
+
token: this._token,
|
|
69
|
+
limit: 1000,
|
|
70
|
+
cursor,
|
|
71
|
+
});
|
|
72
|
+
for (const blob of result.blobs) {
|
|
73
|
+
allPaths.push(blob.pathname);
|
|
74
|
+
}
|
|
75
|
+
cursor = result.cursor ?? undefined;
|
|
76
|
+
} while (cursor);
|
|
77
|
+
return allPaths;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAGrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mantajs/adapter-file-vercel-blob",
|
|
3
|
+
"version": "0.2.0-beta.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@vercel/blob": "^0.27.0"
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@mantajs/core": "0.2.0-beta.0"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
]
|
|
23
|
+
}
|