finish trash
This commit is contained in:
parent
9629a04da6
commit
4b70edb947
@ -24,6 +24,7 @@
|
||||
"@push.rocks/smartpromise": "^4.0.3",
|
||||
"@push.rocks/smartrx": "^3.0.7",
|
||||
"@push.rocks/smartstream": "^3.0.44",
|
||||
"@push.rocks/smartstring": "^4.0.15",
|
||||
"@push.rocks/smartunique": "^3.0.9",
|
||||
"@tsclass/tsclass": "^4.0.55",
|
||||
"minio": "^8.0.0"
|
||||
|
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@ -23,6 +23,9 @@ importers:
|
||||
'@push.rocks/smartstream':
|
||||
specifier: ^3.0.44
|
||||
version: 3.0.44
|
||||
'@push.rocks/smartstring':
|
||||
specifier: ^4.0.15
|
||||
version: 4.0.15
|
||||
'@push.rocks/smartunique':
|
||||
specifier: ^3.0.9
|
||||
version: 3.0.9
|
||||
|
@ -4,7 +4,13 @@ import * as interfaces from './interfaces.js';
|
||||
import { SmartBucket } from './classes.smartbucket.js';
|
||||
import { Directory } from './classes.directory.js';
|
||||
import { File } from './classes.file.js';
|
||||
import { Trash } from './classes.trash.js';
|
||||
|
||||
/**
|
||||
* The bucket class exposes the basc functionality of a bucket.
|
||||
* The functions of the bucket alone are enough to
|
||||
* operate in s3 basic fashion on blobs of data.
|
||||
*/
|
||||
export class Bucket {
|
||||
public static async getBucketByName(smartbucketRef: SmartBucket, bucketNameArg: string) {
|
||||
const buckets = await smartbucketRef.minioClient.listBuckets();
|
||||
@ -45,7 +51,17 @@ export class Bucket {
|
||||
return new Directory(this, null, '');
|
||||
}
|
||||
|
||||
public async getDirectoryFromPath(pathDescriptorArg: interfaces.IPathDecriptor): Promise<Directory> {
|
||||
/**
|
||||
* gets the trash directory
|
||||
*/
|
||||
public async getTrash(): Promise<Trash> {
|
||||
const trash = new Trash(this);
|
||||
return trash;
|
||||
}
|
||||
|
||||
public async getDirectoryFromPath(
|
||||
pathDescriptorArg: interfaces.IPathDecriptor
|
||||
): Promise<Directory> {
|
||||
if (!pathDescriptorArg.path && !pathDescriptorArg.directory) {
|
||||
return this.getBaseDirectory();
|
||||
}
|
||||
@ -61,15 +77,12 @@ export class Bucket {
|
||||
/**
|
||||
* store file
|
||||
*/
|
||||
public async fastPut(optionsArg: {
|
||||
path: string;
|
||||
public async fastPut(optionsArg: interfaces.IPathDecriptor & {
|
||||
contents: string | Buffer;
|
||||
overwrite?: boolean;
|
||||
}): Promise<File> {
|
||||
try {
|
||||
const reducedPath = await helpers.reducePathDescriptorToPath({
|
||||
path: optionsArg.path,
|
||||
})
|
||||
const reducedPath = await helpers.reducePathDescriptorToPath(optionsArg);
|
||||
// Check if the object already exists
|
||||
const exists = await this.fastExists({ path: reducedPath });
|
||||
|
||||
@ -77,14 +90,20 @@ export class Bucket {
|
||||
console.error(`Object already exists at path '${reducedPath}' in bucket '${this.name}'.`);
|
||||
return;
|
||||
} else if (exists && optionsArg.overwrite) {
|
||||
console.log(`Overwriting existing object at path '${reducedPath}' in bucket '${this.name}'.`);
|
||||
console.log(
|
||||
`Overwriting existing object at path '${reducedPath}' in bucket '${this.name}'.`
|
||||
);
|
||||
} else {
|
||||
console.log(`Creating new object at path '${reducedPath}' in bucket '${this.name}'.`);
|
||||
}
|
||||
|
||||
// Proceed with putting the object
|
||||
const streamIntake = new plugins.smartstream.StreamIntake();
|
||||
const putPromise = this.smartbucketRef.minioClient.putObject(this.name, reducedPath, streamIntake);
|
||||
const putPromise = this.smartbucketRef.minioClient.putObject(
|
||||
this.name,
|
||||
reducedPath,
|
||||
streamIntake
|
||||
);
|
||||
streamIntake.pushData(optionsArg.contents);
|
||||
streamIntake.signalEnd();
|
||||
await putPromise;
|
||||
@ -98,18 +117,18 @@ export class Bucket {
|
||||
fileName: parsedPath.base,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error storing object at path '${optionsArg.path}' in bucket '${this.name}':`, error);
|
||||
console.error(
|
||||
`Error storing object at path '${optionsArg.path}' in bucket '${this.name}':`,
|
||||
error
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get file
|
||||
*/
|
||||
public async fastGet(optionsArg: {
|
||||
path: string
|
||||
}): Promise<Buffer> {
|
||||
public async fastGet(optionsArg: { path: string }): Promise<Buffer> {
|
||||
const done = plugins.smartpromise.defer();
|
||||
let completeFile: Buffer;
|
||||
const replaySubject = await this.fastGetReplaySubject(optionsArg);
|
||||
@ -154,34 +173,40 @@ export class Bucket {
|
||||
finalFunction: async (cb) => {
|
||||
replaySubject.complete();
|
||||
return;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!fileStream) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const smartstream = new plugins.smartstream.StreamWrapper([
|
||||
fileStream,
|
||||
duplexStream,
|
||||
]);
|
||||
const smartstream = new plugins.smartstream.StreamWrapper([fileStream, duplexStream]);
|
||||
smartstream.run();
|
||||
return replaySubject;
|
||||
}
|
||||
|
||||
public fastGetStream(optionsArg: {
|
||||
public fastGetStream(
|
||||
optionsArg: {
|
||||
path: string;
|
||||
}, typeArg: 'webstream'): Promise<ReadableStream>
|
||||
public async fastGetStream(optionsArg: {
|
||||
},
|
||||
typeArg: 'webstream'
|
||||
): Promise<ReadableStream>;
|
||||
public async fastGetStream(
|
||||
optionsArg: {
|
||||
path: string;
|
||||
}, typeArg: 'nodestream'): Promise<plugins.stream.Readable>
|
||||
},
|
||||
typeArg: 'nodestream'
|
||||
): Promise<plugins.stream.Readable>;
|
||||
|
||||
/**
|
||||
* fastGetStream
|
||||
* @param optionsArg
|
||||
* @returns
|
||||
*/
|
||||
public async fastGetStream(optionsArg: { path: string; }, typeArg: 'webstream' | 'nodestream' = 'nodestream'): Promise<ReadableStream | plugins.stream.Readable>{
|
||||
public async fastGetStream(
|
||||
optionsArg: { path: string },
|
||||
typeArg: 'webstream' | 'nodestream' = 'nodestream'
|
||||
): Promise<ReadableStream | plugins.stream.Readable> {
|
||||
const fileStream = await this.smartbucketRef.minioClient
|
||||
.getObject(this.name, optionsArg.path)
|
||||
.catch((e) => console.log(e));
|
||||
@ -191,21 +216,18 @@ export class Bucket {
|
||||
},
|
||||
finalFunction: async (cb) => {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!fileStream) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const smartstream = new plugins.smartstream.StreamWrapper([
|
||||
fileStream,
|
||||
duplexStream,
|
||||
]);
|
||||
const smartstream = new plugins.smartstream.StreamWrapper([fileStream, duplexStream]);
|
||||
smartstream.run();
|
||||
if (typeArg === 'nodestream') {
|
||||
return duplexStream;
|
||||
};
|
||||
}
|
||||
if (typeArg === 'webstream') {
|
||||
return (await duplexStream.getWebStreams()).readable;
|
||||
}
|
||||
@ -225,15 +247,21 @@ 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}'.`);
|
||||
console.error(
|
||||
`Object already exists at path '${optionsArg.path}' in bucket '${this.name}'.`
|
||||
);
|
||||
return;
|
||||
} else if (exists && optionsArg.overwrite) {
|
||||
console.log(`Overwriting existing object at path '${optionsArg.path}' in bucket '${this.name}'.`);
|
||||
console.log(
|
||||
`Overwriting existing object at path '${optionsArg.path}' in bucket '${this.name}'.`
|
||||
);
|
||||
} else {
|
||||
console.log(`Creating new object at path '${optionsArg.path}' in bucket '${this.name}'.`);
|
||||
}
|
||||
|
||||
const streamIntake = await plugins.smartstream.StreamIntake.fromStream<Uint8Array>(optionsArg.readableStream);
|
||||
const streamIntake = await plugins.smartstream.StreamIntake.fromStream<Uint8Array>(
|
||||
optionsArg.readableStream
|
||||
);
|
||||
|
||||
// Proceed with putting the object
|
||||
await this.smartbucketRef.minioClient.putObject(
|
||||
@ -241,17 +269,21 @@ export class Bucket {
|
||||
optionsArg.path,
|
||||
streamIntake,
|
||||
null,
|
||||
null, // TODO: Add support for custom metadata once proper support is in minio.
|
||||
null // TODO: Add support for custom metadata once proper support is in minio.
|
||||
);
|
||||
|
||||
console.log(`Object '${optionsArg.path}' has been successfully stored in bucket '${this.name}'.`);
|
||||
console.log(
|
||||
`Object '${optionsArg.path}' has been successfully stored in bucket '${this.name}'.`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error storing object at path '${optionsArg.path}' in bucket '${this.name}':`, error);
|
||||
console.error(
|
||||
`Error storing object at path '${optionsArg.path}' in bucket '${this.name}':`,
|
||||
error
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async fastCopy(optionsArg: {
|
||||
sourcePath: string;
|
||||
destinationPath?: string;
|
||||
@ -306,12 +338,18 @@ export class Bucket {
|
||||
const exists = await destinationBucket.fastExists({ path: optionsArg.destinationPath });
|
||||
|
||||
if (exists && !optionsArg.overwrite) {
|
||||
console.error(`Object already exists at destination path '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`);
|
||||
console.error(
|
||||
`Object already exists at destination path '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`
|
||||
);
|
||||
return;
|
||||
} else if (exists && optionsArg.overwrite) {
|
||||
console.log(`Overwriting existing object at destination path '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`);
|
||||
console.log(
|
||||
`Overwriting existing object at destination path '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`
|
||||
);
|
||||
} else {
|
||||
console.log(`Moving object to path '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`);
|
||||
console.log(
|
||||
`Moving object to path '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`
|
||||
);
|
||||
}
|
||||
|
||||
// Proceed with copying the object to the new path
|
||||
@ -320,20 +358,22 @@ export class Bucket {
|
||||
// Remove the original object after successful copy
|
||||
await this.fastRemove({ path: optionsArg.sourcePath });
|
||||
|
||||
console.log(`Object '${optionsArg.sourcePath}' has been successfully moved to '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`);
|
||||
console.log(
|
||||
`Object '${optionsArg.sourcePath}' has been successfully moved to '${optionsArg.destinationPath}' in bucket '${destinationBucket.name}'.`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error moving object from '${optionsArg.sourcePath}' to '${optionsArg.destinationPath}':`, error);
|
||||
console.error(
|
||||
`Error moving object from '${optionsArg.sourcePath}' to '${optionsArg.destinationPath}':`,
|
||||
error
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* removeObject
|
||||
*/
|
||||
public async fastRemove(optionsArg: {
|
||||
path: string;
|
||||
}) {
|
||||
public async fastRemove(optionsArg: { path: string }) {
|
||||
await this.smartbucketRef.minioClient.removeObject(this.name, optionsArg.path);
|
||||
}
|
||||
|
||||
@ -342,9 +382,7 @@ export class Bucket {
|
||||
* @param optionsArg
|
||||
* @returns
|
||||
*/
|
||||
public async fastExists(optionsArg: {
|
||||
path: string;
|
||||
}): Promise<boolean> {
|
||||
public async fastExists(optionsArg: { path: string }): Promise<boolean> {
|
||||
try {
|
||||
await this.smartbucketRef.minioClient.statObject(this.name, optionsArg.path);
|
||||
console.log(`Object '${optionsArg.path}' exists in bucket '${this.name}'.`);
|
||||
@ -394,7 +432,7 @@ export class Bucket {
|
||||
});
|
||||
|
||||
return done.promise;
|
||||
};
|
||||
}
|
||||
|
||||
public async isFile(pathDescriptor: interfaces.IPathDecriptor): Promise<boolean> {
|
||||
let checkPath = await helpers.reducePathDescriptorToPath(pathDescriptor);
|
||||
|
@ -2,6 +2,8 @@ import * as plugins from './plugins.js';
|
||||
import { Bucket } from './classes.bucket.js';
|
||||
import { File } from './classes.file.js';
|
||||
|
||||
import * as helpers from './helpers.js';
|
||||
|
||||
export class Directory {
|
||||
public bucketRef: Bucket;
|
||||
public parentDirectoryRef: Directory;
|
||||
@ -65,11 +67,20 @@ export class Directory {
|
||||
public async getFile(optionsArg: {
|
||||
name: string;
|
||||
createWithContents?: string | Buffer;
|
||||
getFromTrash?: boolean;
|
||||
}): Promise<File> {
|
||||
const pathDescriptor = {
|
||||
directory: this,
|
||||
path: optionsArg.name,
|
||||
};
|
||||
// check wether the file exists
|
||||
const exists = await this.bucketRef.fastExists({
|
||||
path: this.getBasePath() + optionsArg.name,
|
||||
path: await helpers.reducePathDescriptorToPath(pathDescriptor),
|
||||
});
|
||||
if (!exists && optionsArg.getFromTrash) {
|
||||
const trash = await this.bucketRef.getTrash();
|
||||
const trashKey = await trash.getTrashKeyByOriginalBasePath()
|
||||
}
|
||||
if (!exists && !optionsArg.createWithContents) {
|
||||
return null;
|
||||
}
|
||||
|
@ -116,10 +116,10 @@ export class File {
|
||||
originalPath: this.getBasePath(),
|
||||
},
|
||||
});
|
||||
const trashName = plugins.smartunique.uuid4();
|
||||
const trash = await this.parentDirectoryRef.bucketRef.getTrash();
|
||||
await this.move({
|
||||
directory: await this.parentDirectoryRef.bucketRef.getBaseDirectory(),
|
||||
path: plugins.path.join('trash', trashName),
|
||||
directory: await trash.getTrashDir(),
|
||||
path: await trash.getTrashKeyByOriginalBasePath(this.getBasePath()),
|
||||
});
|
||||
}
|
||||
|
||||
|
27
ts/classes.trash.ts
Normal file
27
ts/classes.trash.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import * as interfaces from './interfaces.js';
|
||||
import * as helpers from './helpers.js';
|
||||
import type { Bucket } from './classes.bucket.js';
|
||||
import type { Directory } from './classes.directory.js';
|
||||
import type { File } from './classes.file.js';
|
||||
|
||||
|
||||
export class Trash {
|
||||
public bucketRef: Bucket;
|
||||
|
||||
constructor(bucketRefArg: Bucket) {
|
||||
this.bucketRef = bucketRefArg;
|
||||
}
|
||||
|
||||
public async getTrashDir() {
|
||||
return this.bucketRef.getDirectoryFromPath({ path: '.trash' });
|
||||
}
|
||||
|
||||
public async getTrashedFileByOriginalName(pathDescriptor: interfaces.IPathDecriptor): Promise<File> {
|
||||
|
||||
}
|
||||
|
||||
public async getTrashKeyByOriginalBasePath (originalPath: string): Promise<string> {
|
||||
return plugins.smartstring.base64.encode(originalPath);
|
||||
}
|
||||
}
|
@ -10,9 +10,10 @@ import * as smartpath from '@push.rocks/smartpath';
|
||||
import * as smartpromise from '@push.rocks/smartpromise';
|
||||
import * as smartrx from '@push.rocks/smartrx';
|
||||
import * as smartstream from '@push.rocks/smartstream';
|
||||
import * as smartstring from '@push.rocks/smartstring';
|
||||
import * as smartunique from '@push.rocks/smartunique';
|
||||
|
||||
export { smartmime, smartpath, smartpromise, smartrx, smartstream, smartunique };
|
||||
export { smartmime, smartpath, smartpromise, smartrx, smartstream, smartstring, smartunique };
|
||||
|
||||
// @tsclass
|
||||
import * as tsclass from '@tsclass/tsclass';
|
||||
|
Loading…
Reference in New Issue
Block a user