BREAKING CHANGE(core): Make API strict-by-default: remove *Strict variants, throw on not-found/exists conflicts, add explicit exists() methods, update docs/tests and bump deps

This commit is contained in:
2025-11-20 13:20:19 +00:00
parent 0c631383e1
commit 5889396134
15 changed files with 2644 additions and 1562 deletions

View File

@@ -14,7 +14,7 @@ import { Trash } from './classes.trash.js';
* operate in S3 basic fashion on blobs of data.
*/
export class Bucket {
public static async getBucketByName(smartbucketRef: SmartBucket, bucketNameArg: string) {
public static async getBucketByName(smartbucketRef: SmartBucket, bucketNameArg: string): Promise<Bucket> {
const command = new plugins.s3.ListBucketsCommand({});
const buckets = await smartbucketRef.s3Client.send(command);
const foundBucket = buckets.Buckets!.find((bucket) => bucket.Name === bucketNameArg);
@@ -24,8 +24,7 @@ export class Bucket {
console.log(`Taking this as base for new Bucket instance`);
return new this(smartbucketRef, bucketNameArg);
} else {
console.log(`did not find bucket by name: ${bucketNameArg}`);
return null;
throw new Error(`Bucket '${bucketNameArg}' not found.`);
}
}
@@ -71,7 +70,7 @@ export class Bucket {
}
const checkPath = await helpers.reducePathDescriptorToPath(pathDescriptorArg);
const baseDirectory = await this.getBaseDirectory();
return await baseDirectory.getSubDirectoryByNameStrict(checkPath, {
return await baseDirectory.getSubDirectoryByName(checkPath, {
getEmptyDirectory: true,
});
}
@@ -88,15 +87,16 @@ export class Bucket {
contents: string | Buffer;
overwrite?: boolean;
}
): Promise<File | null> {
): Promise<File> {
try {
const reducedPath = await helpers.reducePathDescriptorToPath(optionsArg);
const exists = await this.fastExists({ path: reducedPath });
if (exists && !optionsArg.overwrite) {
const errorText = `Object already exists at path '${reducedPath}' in bucket '${this.name}'.`;
console.error(errorText);
return null;
throw new Error(
`Object already exists at path '${reducedPath}' in bucket '${this.name}'. ` +
`Set overwrite:true to replace it.`
);
} else if (exists && optionsArg.overwrite) {
console.log(
`Overwriting existing object at path '${reducedPath}' in bucket '${this.name}'.`
@@ -129,13 +129,6 @@ export class Bucket {
}
}
public async fastPutStrict(...args: Parameters<Bucket['fastPut']>) {
const file = await this.fastPut(...args);
if (!file) {
throw new Error(`File not stored at path '${args[0].path}'`);
}
return file;
}
/**
* get file
@@ -259,10 +252,10 @@ export class Bucket {
const exists = await this.fastExists({ path: optionsArg.path });
if (exists && !optionsArg.overwrite) {
console.error(
`Object already exists at path '${optionsArg.path}' in bucket '${this.name}'.`
throw new Error(
`Object already exists at path '${optionsArg.path}' in bucket '${this.name}'. ` +
`Set overwrite:true to replace it.`
);
return;
} else if (exists && optionsArg.overwrite) {
console.log(
`Overwriting existing object at path '${optionsArg.path}' in bucket '${this.name}'.`
@@ -460,7 +453,7 @@ export class Bucket {
Range: `bytes=0-${optionsArg.length - 1}`,
});
const response = await this.smartbucketRef.s3Client.send(command);
const chunks = [];
const chunks: Buffer[] = [];
const stream = response.Body as any; // SdkStreamMixin includes readable stream
for await (const chunk of stream) {