@nebutra/uploads 2.0.0 → 3.0.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/factory.d.ts.map +1 -1
- package/dist/factory.js +2 -17
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -6
- package/dist/providers/blob.d.ts +0 -28
- package/dist/providers/blob.d.ts.map +0 -1
- package/dist/providers/blob.js +0 -88
package/dist/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAIlF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,cAAc,CAM5E;AAmFD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAOxF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAkB1D"}
|
package/dist/factory.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
* Upload provider factory with auto-detection
|
|
3
3
|
*/
|
|
4
4
|
import { logger } from "@nebutra/logger";
|
|
5
|
-
import { createVercelBlobProvider, VercelBlobProvider } from "./providers/blob";
|
|
6
5
|
import { createLocalProvider, LocalUploadProvider } from "./providers/local";
|
|
7
6
|
import { createS3Provider, S3UploadProvider } from "./providers/s3";
|
|
8
7
|
let instance = null;
|
|
@@ -25,9 +24,6 @@ function createUploadProviderByType(type, config) {
|
|
|
25
24
|
}
|
|
26
25
|
return new S3UploadProvider(config.s3);
|
|
27
26
|
}
|
|
28
|
-
if (type === "blob") {
|
|
29
|
-
return createVercelBlobProvider();
|
|
30
|
-
}
|
|
31
27
|
if (type === "local") {
|
|
32
28
|
if (!config?.local) {
|
|
33
29
|
return createLocalProvider();
|
|
@@ -57,12 +53,7 @@ function autoDetectProvider(config) {
|
|
|
57
53
|
logger.info("Using explicit upload provider", { provider: explicitProvider });
|
|
58
54
|
return createUploadProviderByType(explicitProvider, config);
|
|
59
55
|
}
|
|
60
|
-
// Priority 2: Check for
|
|
61
|
-
if (process.env.BLOB_READ_WRITE_TOKEN) {
|
|
62
|
-
logger.info("Auto-detected Vercel Blob token, using Blob provider");
|
|
63
|
-
return createVercelBlobProvider();
|
|
64
|
-
}
|
|
65
|
-
// Priority 3: Check for R2 credentials
|
|
56
|
+
// Priority 2: Check for R2 credentials
|
|
66
57
|
if (process.env.R2_ACCESS_KEY_ID || process.env.R2_SECRET_ACCESS_KEY) {
|
|
67
58
|
logger.info("Auto-detected R2 credentials, using S3 provider");
|
|
68
59
|
return new S3UploadProvider({
|
|
@@ -78,7 +69,7 @@ function autoDetectProvider(config) {
|
|
|
78
69
|
logger.info("Auto-detected AWS credentials, using S3 provider");
|
|
79
70
|
return createS3Provider();
|
|
80
71
|
}
|
|
81
|
-
// Priority 4: Check for custom S3 endpoint (Minio, etc.)
|
|
72
|
+
// Priority 4: Check for custom S3 endpoint (Minio, Aliyun OSS, etc.)
|
|
82
73
|
if (process.env.S3_ENDPOINT) {
|
|
83
74
|
logger.info("Using custom S3 endpoint", { endpoint: process.env.S3_ENDPOINT });
|
|
84
75
|
return new S3UploadProvider({
|
|
@@ -121,15 +112,9 @@ export function getActiveProviderType() {
|
|
|
121
112
|
if (instance instanceof S3UploadProvider) {
|
|
122
113
|
return "s3";
|
|
123
114
|
}
|
|
124
|
-
if (instance instanceof VercelBlobProvider) {
|
|
125
|
-
return "blob";
|
|
126
|
-
}
|
|
127
115
|
if (instance instanceof LocalUploadProvider) {
|
|
128
116
|
return "local";
|
|
129
117
|
}
|
|
130
|
-
if (process.env.UPLOAD_PROVIDER === "blob" || process.env.BLOB_READ_WRITE_TOKEN) {
|
|
131
|
-
return "blob";
|
|
132
|
-
}
|
|
133
118
|
if (process.env.UPLOAD_PROVIDER === "s3" ||
|
|
134
119
|
process.env.R2_ACCESS_KEY_ID ||
|
|
135
120
|
process.env.AWS_ACCESS_KEY_ID ||
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Handles presigned, multipart, and Tus protocol uploads
|
|
4
4
|
*/
|
|
5
5
|
export { createUploadProvider, getActiveProviderType, getUploadProvider, resetUploadProvider, } from "./factory";
|
|
6
|
-
export { createVercelBlobProvider, VercelBlobProvider } from "./providers/blob";
|
|
7
6
|
export { createLocalProvider, LocalUploadProvider } from "./providers/local";
|
|
8
7
|
export { createS3Provider, S3UploadProvider } from "./providers/s3";
|
|
9
8
|
export type { ACLType, CompletePart, LocalProviderConfig, MultipartUpload, PresignedUpload, ProviderConfig, S3ProviderConfig, TusUploadConfig, UploadComplete, UploadMethod, UploadPart, UploadProvider, UploadProviderType, UploadTarget, ValidationRules, } from "./types";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,YAAY,EACV,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,YAAY,EACZ,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,kBAAkB,EAClB,KAAK,eAAe,EACpB,uBAAuB,EACvB,cAAc,GACf,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// Factory
|
|
6
6
|
export { createUploadProvider, getActiveProviderType, getUploadProvider, resetUploadProvider, } from "./factory";
|
|
7
7
|
// Providers
|
|
8
|
-
export { createVercelBlobProvider, VercelBlobProvider } from "./providers/blob";
|
|
9
8
|
export { createLocalProvider, LocalUploadProvider } from "./providers/local";
|
|
10
9
|
export { createS3Provider, S3UploadProvider } from "./providers/s3";
|
|
11
10
|
// Validation
|
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebutra/uploads",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,16 +44,12 @@
|
|
|
44
44
|
"@aws-sdk/client-s3": "^3.700.0",
|
|
45
45
|
"@aws-sdk/s3-request-presigner": "^3.700.0",
|
|
46
46
|
"zod": "^4.3.6",
|
|
47
|
-
"@nebutra/logger": "
|
|
47
|
+
"@nebutra/logger": "3.0.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@vercel/blob": ">=0.23.0",
|
|
51
50
|
"tus-js-client": "^4.2.0"
|
|
52
51
|
},
|
|
53
52
|
"peerDependenciesMeta": {
|
|
54
|
-
"@vercel/blob": {
|
|
55
|
-
"optional": true
|
|
56
|
-
},
|
|
57
53
|
"tus-js-client": {
|
|
58
54
|
"optional": true
|
|
59
55
|
}
|
package/dist/providers/blob.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vercel Blob upload provider — zero-config file uploads on Vercel.
|
|
3
|
-
*
|
|
4
|
-
* Uses @vercel/blob for server-side uploads with public URLs.
|
|
5
|
-
* Requires BLOB_READ_WRITE_TOKEN env var (auto-provisioned on Vercel).
|
|
6
|
-
*
|
|
7
|
-
* Note: Vercel Blob doesn't support true multipart uploads or Tus protocol.
|
|
8
|
-
* For files > 500MB, use the S3 provider instead.
|
|
9
|
-
*/
|
|
10
|
-
import type { CompletePart, MultipartUpload, PresignedUpload, TusUploadConfig, UploadComplete, UploadProvider, UploadTarget } from "../types";
|
|
11
|
-
export interface VercelBlobConfig {
|
|
12
|
-
token?: string;
|
|
13
|
-
}
|
|
14
|
-
export declare class VercelBlobProvider implements UploadProvider {
|
|
15
|
-
private token;
|
|
16
|
-
constructor(config?: VercelBlobConfig);
|
|
17
|
-
private buildPathname;
|
|
18
|
-
createPresignedUpload(target: UploadTarget): Promise<PresignedUpload>;
|
|
19
|
-
createMultipartUpload(target: UploadTarget, _partCount: number): Promise<MultipartUpload>;
|
|
20
|
-
completeMultipartUpload(_uploadId: string, key: string, _parts: CompletePart[]): Promise<UploadComplete>;
|
|
21
|
-
abortMultipartUpload(_uploadId: string, key: string): Promise<void>;
|
|
22
|
-
getTusEndpoint(_target: UploadTarget): Promise<TusUploadConfig>;
|
|
23
|
-
deleteFile(_bucket: string, key: string): Promise<void>;
|
|
24
|
-
getDownloadUrl(_bucket: string, key: string, _expiresInSec?: number): Promise<string>;
|
|
25
|
-
close(): Promise<void>;
|
|
26
|
-
}
|
|
27
|
-
export declare function createVercelBlobProvider(config?: VercelBlobConfig): VercelBlobProvider;
|
|
28
|
-
//# sourceMappingURL=blob.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../../src/providers/blob.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACb,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,GAAE,gBAAqB;IAIzC,OAAO,CAAC,aAAa;IAKf,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAyBrE,qBAAqB,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAazF,uBAAuB,CAC3B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,YAAY,EAAE,GACrB,OAAO,CAAC,cAAc,CAAC;IAWpB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnE,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAM/D,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQrF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,wBAAgB,wBAAwB,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,kBAAkB,CAEtF"}
|
package/dist/providers/blob.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vercel Blob upload provider — zero-config file uploads on Vercel.
|
|
3
|
-
*
|
|
4
|
-
* Uses @vercel/blob for server-side uploads with public URLs.
|
|
5
|
-
* Requires BLOB_READ_WRITE_TOKEN env var (auto-provisioned on Vercel).
|
|
6
|
-
*
|
|
7
|
-
* Note: Vercel Blob doesn't support true multipart uploads or Tus protocol.
|
|
8
|
-
* For files > 500MB, use the S3 provider instead.
|
|
9
|
-
*/
|
|
10
|
-
export class VercelBlobProvider {
|
|
11
|
-
token;
|
|
12
|
-
constructor(config = {}) {
|
|
13
|
-
this.token = config.token ?? process.env.BLOB_READ_WRITE_TOKEN ?? "";
|
|
14
|
-
}
|
|
15
|
-
buildPathname(target) {
|
|
16
|
-
const prefix = target.tenantId ? `${target.tenantId}/` : "";
|
|
17
|
-
return `${prefix}${target.key}`;
|
|
18
|
-
}
|
|
19
|
-
async createPresignedUpload(target) {
|
|
20
|
-
// Vercel Blob uses server-side put() — we generate a URL that the client
|
|
21
|
-
// can PUT to via the handleUpload client helper, or we return the blob URL
|
|
22
|
-
// after server-side upload.
|
|
23
|
-
const blob = await import("@vercel/blob");
|
|
24
|
-
const pathname = this.buildPathname(target);
|
|
25
|
-
const result = await blob.put(pathname, "", {
|
|
26
|
-
access: "public",
|
|
27
|
-
contentType: target.contentType,
|
|
28
|
-
token: this.token,
|
|
29
|
-
addRandomSuffix: true,
|
|
30
|
-
});
|
|
31
|
-
return {
|
|
32
|
-
url: result.url,
|
|
33
|
-
method: "PUT",
|
|
34
|
-
headers: {
|
|
35
|
-
"Content-Type": target.contentType,
|
|
36
|
-
"x-vercel-blob-token": this.token,
|
|
37
|
-
},
|
|
38
|
-
expiresAt: new Date(Date.now() + 3600 * 1000), // 1 hour
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
async createMultipartUpload(target, _partCount) {
|
|
42
|
-
// Vercel Blob handles large files internally — no client-side multipart needed
|
|
43
|
-
// We simulate the interface for compatibility
|
|
44
|
-
const presigned = await this.createPresignedUpload(target);
|
|
45
|
-
return {
|
|
46
|
-
uploadId: `blob_${Date.now()}`,
|
|
47
|
-
key: this.buildPathname(target),
|
|
48
|
-
bucket: target.bucket,
|
|
49
|
-
parts: [{ partNumber: 1, presignedUrl: presigned.url }],
|
|
50
|
-
completeUrl: presigned.url,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
async completeMultipartUpload(_uploadId, key, _parts) {
|
|
54
|
-
// Vercel Blob uploads are atomic — no completion step needed
|
|
55
|
-
return {
|
|
56
|
-
key,
|
|
57
|
-
bucket: "vercel-blob",
|
|
58
|
-
url: `https://blob.vercel-storage.com/${key}`,
|
|
59
|
-
size: 0,
|
|
60
|
-
contentType: "application/octet-stream",
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
async abortMultipartUpload(_uploadId, key) {
|
|
64
|
-
// Clean up the blob if partially uploaded
|
|
65
|
-
await this.deleteFile("vercel-blob", key);
|
|
66
|
-
}
|
|
67
|
-
async getTusEndpoint(_target) {
|
|
68
|
-
throw new Error("Vercel Blob does not support Tus protocol. Use S3 provider for resumable uploads.");
|
|
69
|
-
}
|
|
70
|
-
async deleteFile(_bucket, key) {
|
|
71
|
-
const blob = await import("@vercel/blob");
|
|
72
|
-
const url = key.startsWith("http") ? key : `https://blob.vercel-storage.com/${key}`;
|
|
73
|
-
await blob.del(url, { token: this.token });
|
|
74
|
-
}
|
|
75
|
-
async getDownloadUrl(_bucket, key, _expiresInSec) {
|
|
76
|
-
// Vercel Blob URLs are public by default — no signed URL needed
|
|
77
|
-
const blob = await import("@vercel/blob");
|
|
78
|
-
const url = key.startsWith("http") ? key : `https://blob.vercel-storage.com/${key}`;
|
|
79
|
-
const meta = await blob.head(url, { token: this.token });
|
|
80
|
-
return meta.url;
|
|
81
|
-
}
|
|
82
|
-
async close() {
|
|
83
|
-
// No-op — Vercel Blob has no persistent connections
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
export function createVercelBlobProvider(config) {
|
|
87
|
-
return new VercelBlobProvider(config);
|
|
88
|
-
}
|