lean-s3 0.6.1 → 0.6.2
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/index.d.ts +18 -12
- package/dist/index.js +24 -26
- package/package.json +5 -6
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,15 @@ type DeleteObjectsOptions = {
|
|
|
45
45
|
bucket?: string;
|
|
46
46
|
signal?: AbortSignal;
|
|
47
47
|
};
|
|
48
|
+
type DeleteObjectsResult = {
|
|
49
|
+
errors: DeleteObjectsError[];
|
|
50
|
+
};
|
|
51
|
+
type DeleteObjectsError = {
|
|
52
|
+
code: string;
|
|
53
|
+
key: string;
|
|
54
|
+
message: string;
|
|
55
|
+
versionId: string;
|
|
56
|
+
};
|
|
48
57
|
interface S3FilePresignOptions {
|
|
49
58
|
contentHash: Buffer;
|
|
50
59
|
/** Seconds. */
|
|
@@ -58,6 +67,7 @@ type ListObjectsOptions = {
|
|
|
58
67
|
bucket?: string;
|
|
59
68
|
prefix?: string;
|
|
60
69
|
maxKeys?: number;
|
|
70
|
+
delimiter?: string;
|
|
61
71
|
startAfter?: string;
|
|
62
72
|
continuationToken?: string;
|
|
63
73
|
signal?: AbortSignal;
|
|
@@ -348,9 +358,7 @@ declare class S3Client {
|
|
|
348
358
|
/**
|
|
349
359
|
* Uses [`DeleteObjects`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) to delete multiple objects in a single request.
|
|
350
360
|
*/
|
|
351
|
-
deleteObjects(objects: readonly S3BucketEntry[] | readonly string[], options?: DeleteObjectsOptions): Promise<
|
|
352
|
-
errors: any;
|
|
353
|
-
} | null>;
|
|
361
|
+
deleteObjects(objects: readonly S3BucketEntry[] | readonly string[], options?: DeleteObjectsOptions): Promise<DeleteObjectsResult>;
|
|
354
362
|
/**
|
|
355
363
|
* Do not use this. This is an internal method.
|
|
356
364
|
* TODO: Maybe move this into a separate free function?
|
|
@@ -379,9 +387,7 @@ declare class S3Stat {
|
|
|
379
387
|
|
|
380
388
|
declare class S3File {
|
|
381
389
|
#private;
|
|
382
|
-
/**
|
|
383
|
-
* @internal
|
|
384
|
-
*/
|
|
390
|
+
/** @internal */
|
|
385
391
|
constructor(client: S3Client, path: ObjectKey, start: number | undefined, end: number | undefined, contentType: string | undefined);
|
|
386
392
|
slice(start?: number | undefined, end?: number | undefined, contentType?: string | undefined): S3File;
|
|
387
393
|
/**
|
|
@@ -391,13 +397,13 @@ declare class S3File {
|
|
|
391
397
|
* @throws {S3Error} If the file does not exist or the server has some other issues.
|
|
392
398
|
* @throws {Error} If the server returns an invalid response.
|
|
393
399
|
*/
|
|
394
|
-
stat(
|
|
400
|
+
stat(options?: Partial<S3StatOptions>): Promise<S3Stat>;
|
|
395
401
|
/**
|
|
396
402
|
* Check if a file exists in the bucket. Uses `HEAD` request to check existence.
|
|
397
403
|
*
|
|
398
404
|
* @remarks Uses [`HeadObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html).
|
|
399
405
|
*/
|
|
400
|
-
exists(
|
|
406
|
+
exists(options?: Partial<S3FileExistsOptions>): Promise<boolean>;
|
|
401
407
|
/**
|
|
402
408
|
* Delete a file from the bucket.
|
|
403
409
|
*
|
|
@@ -409,18 +415,18 @@ declare class S3File {
|
|
|
409
415
|
* @example
|
|
410
416
|
* ```js
|
|
411
417
|
* // Simple delete
|
|
412
|
-
* await client.
|
|
418
|
+
* await client.delete("old-file.txt");
|
|
413
419
|
*
|
|
414
420
|
* // With error handling
|
|
415
421
|
* try {
|
|
416
|
-
* await client.
|
|
422
|
+
* await client.delete("file.dat");
|
|
417
423
|
* console.log("File deleted");
|
|
418
424
|
* } catch (err) {
|
|
419
425
|
* console.error("Delete failed:", err);
|
|
420
426
|
* }
|
|
421
427
|
* ```
|
|
422
428
|
*/
|
|
423
|
-
delete(
|
|
429
|
+
delete(options?: Partial<S3FileDeleteOptions>): Promise<void>;
|
|
424
430
|
toString(): string;
|
|
425
431
|
json(): Promise<unknown>;
|
|
426
432
|
bytes(): Promise<Uint8Array>;
|
|
@@ -484,4 +490,4 @@ type BucketInfo = {
|
|
|
484
490
|
type?: string;
|
|
485
491
|
};
|
|
486
492
|
|
|
487
|
-
export { type AbortMultipartUploadOptions, type Acl, type BucketCreationOptions, type BucketDeletionOptions, type BucketExistsOptions, type BucketInfo, type BucketLocationInfo, type ByteSource, type ChecksumAlgorithm, type ChecksumType, type CompleteMultipartUploadOptions, type CompleteMultipartUploadResult, type CreateFileInstanceOptions, type CreateMultipartUploadOptions, type CreateMultipartUploadResult, type DeleteObjectsOptions, type HttpMethod, type ListMultipartUploadsOptions, type ListMultipartUploadsResult, type ListObjectsIteratingOptions, type ListObjectsOptions, type ListObjectsResult, type ListPartsOptions, type ListPartsResult, type MultipartUpload, type MultipartUploadPart, type OverridableS3ClientOptions, type PresignableHttpMethod, S3BucketEntry, S3Client, type S3ClientOptions, S3Error, type S3ErrorOptions, S3File, type S3FileDeleteOptions, type S3FileExistsOptions, type S3FilePresignOptions, S3Stat, type S3StatOptions, type StorageClass, type UndiciBodyInit, type UploadPartOptions, type UploadPartResult };
|
|
493
|
+
export { type AbortMultipartUploadOptions, type Acl, type BucketCreationOptions, type BucketDeletionOptions, type BucketExistsOptions, type BucketInfo, type BucketLocationInfo, type ByteSource, type ChecksumAlgorithm, type ChecksumType, type CompleteMultipartUploadOptions, type CompleteMultipartUploadResult, type CreateFileInstanceOptions, type CreateMultipartUploadOptions, type CreateMultipartUploadResult, type DeleteObjectsError, type DeleteObjectsOptions, type DeleteObjectsResult, type HttpMethod, type ListMultipartUploadsOptions, type ListMultipartUploadsResult, type ListObjectsIteratingOptions, type ListObjectsOptions, type ListObjectsResult, type ListPartsOptions, type ListPartsResult, type MultipartUpload, type MultipartUploadPart, type OverridableS3ClientOptions, type PresignableHttpMethod, S3BucketEntry, S3Client, type S3ClientOptions, S3Error, type S3ErrorOptions, S3File, type S3FileDeleteOptions, type S3FileExistsOptions, type S3FilePresignOptions, S3Stat, type S3StatOptions, type StorageClass, type UndiciBodyInit, type UploadPartOptions, type UploadPartResult };
|
package/dist/index.js
CHANGED
|
@@ -202,7 +202,7 @@ function buildRequestUrl(endpoint, bucket, region, path) {
|
|
|
202
202
|
const result = new URL(endpointWithBucketAndRegion);
|
|
203
203
|
const pathPrefix = result.pathname.endsWith("/") ? result.pathname : `${result.pathname}/`;
|
|
204
204
|
const pathSuffix = replacedBucket ? normalizePath(path) : `${normalizedBucket}/${normalizePath(path)}`;
|
|
205
|
-
result.pathname = pathPrefix + pathSuffix.replaceAll(":", "%3A").replaceAll("+", "%2B").replaceAll("(", "%28").replaceAll(")", "%29");
|
|
205
|
+
result.pathname = pathPrefix + pathSuffix.replaceAll(":", "%3A").replaceAll("+", "%2B").replaceAll("(", "%28").replaceAll(")", "%29").replaceAll(",", "%2C");
|
|
206
206
|
return result;
|
|
207
207
|
}
|
|
208
208
|
function replaceDomainPlaceholders(endpoint, bucket, region) {
|
|
@@ -721,7 +721,7 @@ var S3Client = class {
|
|
|
721
721
|
options.signal
|
|
722
722
|
);
|
|
723
723
|
if (response.statusCode === 200) {
|
|
724
|
-
|
|
724
|
+
response.body.dump();
|
|
725
725
|
const etag = response.headers.etag;
|
|
726
726
|
if (typeof etag !== "string" || etag.length === 0) {
|
|
727
727
|
throw new S3Error("Unknown", "", {
|
|
@@ -848,7 +848,7 @@ var S3Client = class {
|
|
|
848
848
|
if (400 <= response.statusCode && response.statusCode < 500) {
|
|
849
849
|
throw await getResponseError(response, "");
|
|
850
850
|
}
|
|
851
|
-
|
|
851
|
+
response.body.dump();
|
|
852
852
|
if (response.statusCode === 200) {
|
|
853
853
|
return;
|
|
854
854
|
}
|
|
@@ -876,7 +876,7 @@ var S3Client = class {
|
|
|
876
876
|
if (400 <= response.statusCode && response.statusCode < 500) {
|
|
877
877
|
throw await getResponseError(response, "");
|
|
878
878
|
}
|
|
879
|
-
|
|
879
|
+
response.body.dump();
|
|
880
880
|
if (response.statusCode === 204) {
|
|
881
881
|
return;
|
|
882
882
|
}
|
|
@@ -903,7 +903,7 @@ var S3Client = class {
|
|
|
903
903
|
if (response.statusCode !== 404 && 400 <= response.statusCode && response.statusCode < 500) {
|
|
904
904
|
throw await getResponseError(response, "");
|
|
905
905
|
}
|
|
906
|
-
|
|
906
|
+
response.body.dump();
|
|
907
907
|
if (response.statusCode === 200) {
|
|
908
908
|
return true;
|
|
909
909
|
}
|
|
@@ -956,6 +956,12 @@ var S3Client = class {
|
|
|
956
956
|
}
|
|
957
957
|
query += `&max-keys=${options.maxKeys}`;
|
|
958
958
|
}
|
|
959
|
+
if (typeof options.delimiter !== "undefined") {
|
|
960
|
+
if (typeof options.delimiter !== "string") {
|
|
961
|
+
throw new TypeError("`delimiter` must be a `string`.");
|
|
962
|
+
}
|
|
963
|
+
query += `&delimiter=${options.delimiter === "/" ? "/" : encodeURIComponent(options.delimiter)}`;
|
|
964
|
+
}
|
|
959
965
|
if (options.prefix) {
|
|
960
966
|
if (typeof options.prefix !== "string") {
|
|
961
967
|
throw new TypeError("`prefix` must be a `string`.");
|
|
@@ -1051,7 +1057,7 @@ var S3Client = class {
|
|
|
1051
1057
|
versionId: e.VersionId
|
|
1052
1058
|
})) ?? []
|
|
1053
1059
|
);
|
|
1054
|
-
return
|
|
1060
|
+
return { errors };
|
|
1055
1061
|
}
|
|
1056
1062
|
if (400 <= response.statusCode && response.statusCode < 500) {
|
|
1057
1063
|
throw await getResponseError(response, "");
|
|
@@ -1352,9 +1358,7 @@ var S3File = class _S3File {
|
|
|
1352
1358
|
#start;
|
|
1353
1359
|
#end;
|
|
1354
1360
|
#contentType;
|
|
1355
|
-
/**
|
|
1356
|
-
* @internal
|
|
1357
|
-
*/
|
|
1361
|
+
/** @internal */
|
|
1358
1362
|
constructor(client, path, start, end, contentType) {
|
|
1359
1363
|
if (typeof start === "number" && start < 0) {
|
|
1360
1364
|
throw new Error("Invalid slice `start`.");
|
|
@@ -1385,7 +1389,7 @@ var S3File = class _S3File {
|
|
|
1385
1389
|
* @throws {S3Error} If the file does not exist or the server has some other issues.
|
|
1386
1390
|
* @throws {Error} If the server returns an invalid response.
|
|
1387
1391
|
*/
|
|
1388
|
-
async stat(
|
|
1392
|
+
async stat(options = {}) {
|
|
1389
1393
|
const response = await this.#client[signedRequest](
|
|
1390
1394
|
"HEAD",
|
|
1391
1395
|
this.#path,
|
|
@@ -1395,9 +1399,9 @@ var S3File = class _S3File {
|
|
|
1395
1399
|
void 0,
|
|
1396
1400
|
void 0,
|
|
1397
1401
|
void 0,
|
|
1398
|
-
signal
|
|
1402
|
+
options.signal
|
|
1399
1403
|
);
|
|
1400
|
-
|
|
1404
|
+
response.body.dump();
|
|
1401
1405
|
if (200 <= response.statusCode && response.statusCode < 300) {
|
|
1402
1406
|
const result = S3Stat.tryParseFromHeaders(response.headers);
|
|
1403
1407
|
if (!result) {
|
|
@@ -1416,9 +1420,7 @@ var S3File = class _S3File {
|
|
|
1416
1420
|
*
|
|
1417
1421
|
* @remarks Uses [`HeadObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html).
|
|
1418
1422
|
*/
|
|
1419
|
-
async exists({
|
|
1420
|
-
signal
|
|
1421
|
-
} = {}) {
|
|
1423
|
+
async exists(options = {}) {
|
|
1422
1424
|
const response = await this.#client[signedRequest](
|
|
1423
1425
|
"HEAD",
|
|
1424
1426
|
this.#path,
|
|
@@ -1428,9 +1430,9 @@ var S3File = class _S3File {
|
|
|
1428
1430
|
void 0,
|
|
1429
1431
|
void 0,
|
|
1430
1432
|
void 0,
|
|
1431
|
-
signal
|
|
1433
|
+
options.signal
|
|
1432
1434
|
);
|
|
1433
|
-
|
|
1435
|
+
response.body.dump();
|
|
1434
1436
|
if (200 <= response.statusCode && response.statusCode < 300) {
|
|
1435
1437
|
return true;
|
|
1436
1438
|
}
|
|
@@ -1452,18 +1454,18 @@ var S3File = class _S3File {
|
|
|
1452
1454
|
* @example
|
|
1453
1455
|
* ```js
|
|
1454
1456
|
* // Simple delete
|
|
1455
|
-
* await client.
|
|
1457
|
+
* await client.delete("old-file.txt");
|
|
1456
1458
|
*
|
|
1457
1459
|
* // With error handling
|
|
1458
1460
|
* try {
|
|
1459
|
-
* await client.
|
|
1461
|
+
* await client.delete("file.dat");
|
|
1460
1462
|
* console.log("File deleted");
|
|
1461
1463
|
* } catch (err) {
|
|
1462
1464
|
* console.error("Delete failed:", err);
|
|
1463
1465
|
* }
|
|
1464
1466
|
* ```
|
|
1465
1467
|
*/
|
|
1466
|
-
async delete(
|
|
1468
|
+
async delete(options = {}) {
|
|
1467
1469
|
const response = await this.#client[signedRequest](
|
|
1468
1470
|
"DELETE",
|
|
1469
1471
|
this.#path,
|
|
@@ -1473,10 +1475,10 @@ var S3File = class _S3File {
|
|
|
1473
1475
|
void 0,
|
|
1474
1476
|
void 0,
|
|
1475
1477
|
void 0,
|
|
1476
|
-
signal
|
|
1478
|
+
options.signal
|
|
1477
1479
|
);
|
|
1478
1480
|
if (response.statusCode === 204) {
|
|
1479
|
-
|
|
1481
|
+
response.body.dump();
|
|
1480
1482
|
return;
|
|
1481
1483
|
}
|
|
1482
1484
|
throw await getResponseError(response, this.#path);
|
|
@@ -1556,10 +1558,6 @@ var S3File = class _S3File {
|
|
|
1556
1558
|
}
|
|
1557
1559
|
/*
|
|
1558
1560
|
// Future API?
|
|
1559
|
-
writer(): WritableStream<ArrayBufferLike | ArrayBufferView> {
|
|
1560
|
-
throw new Error("Not implemented");
|
|
1561
|
-
}
|
|
1562
|
-
// Future API?
|
|
1563
1561
|
setTags(): Promise<void> {
|
|
1564
1562
|
throw new Error("Not implemented");
|
|
1565
1563
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "lean-s3",
|
|
3
3
|
"author": "Niklas Mollenhauer",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "0.6.
|
|
5
|
+
"version": "0.6.2",
|
|
6
6
|
"description": "A server-side S3 API for the regular user.",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"s3",
|
|
@@ -44,16 +44,15 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"fast-xml-parser": "^5.2.5",
|
|
47
|
-
"i": "^0.3.7",
|
|
48
47
|
"undici": "^7.10.0"
|
|
49
48
|
},
|
|
50
49
|
"devDependencies": {
|
|
51
|
-
"@biomejs/biome": "2.0.
|
|
50
|
+
"@biomejs/biome": "2.0.5",
|
|
52
51
|
"@testcontainers/localstack": "^11.0.3",
|
|
53
52
|
"@testcontainers/minio": "^11.0.3",
|
|
54
|
-
"@types/node": "^24.0.
|
|
55
|
-
"@typescript/native-preview": "^7.0.0-dev.
|
|
56
|
-
"expect": "^30.0.
|
|
53
|
+
"@types/node": "^24.0.4",
|
|
54
|
+
"@typescript/native-preview": "^7.0.0-dev.20250626.1",
|
|
55
|
+
"expect": "^30.0.3",
|
|
57
56
|
"lefthook": "^1.11.14",
|
|
58
57
|
"tsup": "^8.5.0",
|
|
59
58
|
"tsx": "^4.20.3",
|