Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
ffaf0fc97a | |||
2a0425ff54 | |||
9adcdee0a0 | |||
786f8d4365 | |||
67244ba5cf | |||
a9bb31c2a2 |
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@push.rocks/smartbucket",
|
"name": "@push.rocks/smartbucket",
|
||||||
"version": "3.0.16",
|
"version": "3.0.19",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@push.rocks/smartbucket",
|
"name": "@push.rocks/smartbucket",
|
||||||
"version": "3.0.16",
|
"version": "3.0.19",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@push.rocks/smartpath": "^5.0.18",
|
"@push.rocks/smartpath": "^5.0.18",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@push.rocks/smartbucket",
|
"name": "@push.rocks/smartbucket",
|
||||||
"version": "3.0.16",
|
"version": "3.0.19",
|
||||||
"description": "A TypeScript library offering simple and cloud-agnostic object storage with advanced features like bucket creation, file and directory management, and data streaming.",
|
"description": "A TypeScript library offering simple and cloud-agnostic object storage with advanced features like bucket creation, file and directory management, and data streaming.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist_ts/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
|
24
test/test.trash.ts
Normal file
24
test/test.trash.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { expect, expectAsync, tap } from '@push.rocks/tapbundle';
|
||||||
|
import { Qenv } from '@push.rocks/qenv';
|
||||||
|
|
||||||
|
import * as smartbucket from '../ts/index.js';
|
||||||
|
|
||||||
|
const testQenv = new Qenv('./', './.nogit/');
|
||||||
|
|
||||||
|
let testSmartbucket: smartbucket.SmartBucket;
|
||||||
|
let myBucket: smartbucket.Bucket;
|
||||||
|
let baseDirectory: smartbucket.Directory;
|
||||||
|
|
||||||
|
tap.test('should create a valid smartbucket', async () => {
|
||||||
|
testSmartbucket = new smartbucket.SmartBucket({
|
||||||
|
accessKey: await testQenv.getEnvVarOnDemand('S3_KEY'),
|
||||||
|
accessSecret: await testQenv.getEnvVarOnDemand('S3_SECRET'),
|
||||||
|
endpoint: 's3.eu-central-1.wasabisys.com',
|
||||||
|
});
|
||||||
|
expect(testSmartbucket).toBeInstanceOf(smartbucket.SmartBucket);
|
||||||
|
myBucket = await testSmartbucket.getBucketByName('testzone');
|
||||||
|
expect(myBucket).toBeInstanceOf(smartbucket.Bucket);
|
||||||
|
expect(myBucket.name).toEqual('testzone');
|
||||||
|
});
|
||||||
|
|
||||||
|
export default tap.start();
|
20
test/test.ts
20
test/test.ts
@ -15,22 +15,20 @@ tap.test('should create a valid smartbucket', async () => {
|
|||||||
accessSecret: await testQenv.getEnvVarOnDemand('S3_SECRET'),
|
accessSecret: await testQenv.getEnvVarOnDemand('S3_SECRET'),
|
||||||
endpoint: 's3.eu-central-1.wasabisys.com',
|
endpoint: 's3.eu-central-1.wasabisys.com',
|
||||||
});
|
});
|
||||||
});
|
expect(testSmartbucket).toBeInstanceOf(smartbucket.SmartBucket);
|
||||||
|
|
||||||
tap.skip.test('should create testbucket', async () => {
|
|
||||||
// await testSmartbucket.createBucket('testzone');
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.skip.test('should remove testbucket', async () => {
|
|
||||||
// await testSmartbucket.removeBucket('testzone');
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.test('should get a bucket', async () => {
|
|
||||||
myBucket = await testSmartbucket.getBucketByName('testzone');
|
myBucket = await testSmartbucket.getBucketByName('testzone');
|
||||||
expect(myBucket).toBeInstanceOf(smartbucket.Bucket);
|
expect(myBucket).toBeInstanceOf(smartbucket.Bucket);
|
||||||
expect(myBucket.name).toEqual('testzone');
|
expect(myBucket.name).toEqual('testzone');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.skip.test('should create testbucket', async () => {
|
||||||
|
// await testSmartbucket.createBucket('testzone2');
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.skip.test('should remove testbucket', async () => {
|
||||||
|
// await testSmartbucket.removeBucket('testzone2');
|
||||||
|
});
|
||||||
|
|
||||||
// Fast operations
|
// Fast operations
|
||||||
tap.test('should store data in bucket fast', async () => {
|
tap.test('should store data in bucket fast', async () => {
|
||||||
await myBucket.fastPut({
|
await myBucket.fastPut({
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartbucket',
|
name: '@push.rocks/smartbucket',
|
||||||
version: '3.0.16',
|
version: '3.0.19',
|
||||||
description: 'A TypeScript library offering simple and cloud-agnostic object storage with advanced features like bucket creation, file and directory management, and data streaming.'
|
description: 'A TypeScript library offering simple and cloud-agnostic object storage with advanced features like bucket creation, file and directory management, and data streaming.'
|
||||||
}
|
}
|
||||||
|
@ -66,13 +66,13 @@ export class Directory {
|
|||||||
* gets a file by name
|
* gets a file by name
|
||||||
*/
|
*/
|
||||||
public async getFile(optionsArg: {
|
public async getFile(optionsArg: {
|
||||||
name: string;
|
path: string;
|
||||||
createWithContents?: string | Buffer;
|
createWithContents?: string | Buffer;
|
||||||
getFromTrash?: boolean;
|
getFromTrash?: boolean;
|
||||||
}): Promise<File> {
|
}): Promise<File> {
|
||||||
const pathDescriptor = {
|
const pathDescriptor = {
|
||||||
directory: this,
|
directory: this,
|
||||||
path: optionsArg.name,
|
path: optionsArg.path,
|
||||||
};
|
};
|
||||||
const exists = await this.bucketRef.fastExists({
|
const exists = await this.bucketRef.fastExists({
|
||||||
path: await helpers.reducePathDescriptorToPath(pathDescriptor),
|
path: await helpers.reducePathDescriptorToPath(pathDescriptor),
|
||||||
@ -88,13 +88,13 @@ export class Directory {
|
|||||||
if (!exists && optionsArg.createWithContents) {
|
if (!exists && optionsArg.createWithContents) {
|
||||||
await File.create({
|
await File.create({
|
||||||
directory: this,
|
directory: this,
|
||||||
name: optionsArg.name,
|
name: optionsArg.path,
|
||||||
contents: optionsArg.createWithContents,
|
contents: optionsArg.createWithContents,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new File({
|
return new File({
|
||||||
directoryRefArg: this,
|
directoryRefArg: this,
|
||||||
fileName: optionsArg.name,
|
fileName: optionsArg.path,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,19 +283,30 @@ export class Directory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* removes a file within the directory
|
* removes a file within the directory
|
||||||
|
* uses file class to make sure effects for metadata etc. are handled correctly
|
||||||
* @param optionsArg
|
* @param optionsArg
|
||||||
*/
|
*/
|
||||||
public async fastRemove(optionsArg: { path: string }) {
|
public async fastRemove(optionsArg: {
|
||||||
const path = plugins.path.join(this.getBasePath(), optionsArg.path);
|
path: string
|
||||||
await this.bucketRef.fastRemove({
|
/**
|
||||||
path,
|
* wether the file should be placed into trash. Default is false.
|
||||||
|
*/
|
||||||
|
mode?: 'permanent' | 'trash';
|
||||||
|
}) {
|
||||||
|
const file = await this.getFile({
|
||||||
|
path: optionsArg.path,
|
||||||
|
});
|
||||||
|
await file.delete({
|
||||||
|
mode: optionsArg.mode ? optionsArg.mode : 'permanent',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deletes the directory with all its contents
|
* deletes the directory with all its contents
|
||||||
*/
|
*/
|
||||||
public async delete() {
|
public async delete(optionsArg: {
|
||||||
|
mode?: 'permanent' | 'trash';
|
||||||
|
}) {
|
||||||
const deleteDirectory = async (directoryArg: Directory) => {
|
const deleteDirectory = async (directoryArg: Directory) => {
|
||||||
const childDirectories = await directoryArg.listDirectories();
|
const childDirectories = await directoryArg.listDirectories();
|
||||||
if (childDirectories.length === 0) {
|
if (childDirectories.length === 0) {
|
||||||
@ -307,9 +318,9 @@ export class Directory {
|
|||||||
}
|
}
|
||||||
const files = await directoryArg.listFiles();
|
const files = await directoryArg.listFiles();
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
await directoryArg.fastRemove({
|
await file.delete({
|
||||||
path: file.name,
|
mode: optionsArg.mode ? optionsArg.mode : 'permanent',
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
await deleteDirectory(this);
|
await deleteDirectory(this);
|
||||||
|
@ -10,7 +10,7 @@ export class MetaData {
|
|||||||
|
|
||||||
// lets find the existing metadata file
|
// lets find the existing metadata file
|
||||||
metaData.metadataFile = await metaData.fileRef.parentDirectoryRef.getFile({
|
metaData.metadataFile = await metaData.fileRef.parentDirectoryRef.getFile({
|
||||||
name: metaData.fileRef.name + '.metadata',
|
path: metaData.fileRef.name + '.metadata',
|
||||||
createWithContents: '{}',
|
createWithContents: '{}',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,16 +16,17 @@ export class SmartBucket {
|
|||||||
*/
|
*/
|
||||||
constructor(configArg: plugins.tsclass.storage.IS3Descriptor) {
|
constructor(configArg: plugins.tsclass.storage.IS3Descriptor) {
|
||||||
this.config = configArg;
|
this.config = configArg;
|
||||||
const endpoint = this.config.endpoint.startsWith('http://') || this.config.endpoint.startsWith('https://')
|
|
||||||
? this.config.endpoint
|
const protocol = configArg.useSsl === false ? 'http' : 'https';
|
||||||
: `https://${this.config.endpoint}`;
|
const port = configArg.port ? `:${configArg.port}` : '';
|
||||||
|
const endpoint = `${protocol}://${configArg.endpoint}${port}`;
|
||||||
|
|
||||||
this.s3Client = new plugins.s3.S3Client({
|
this.s3Client = new plugins.s3.S3Client({
|
||||||
endpoint,
|
endpoint,
|
||||||
region: this.config.region || 'us-east-1',
|
region: configArg.region || 'us-east-1',
|
||||||
credentials: {
|
credentials: {
|
||||||
accessKeyId: this.config.accessKey,
|
accessKeyId: configArg.accessKey,
|
||||||
secretAccessKey: this.config.accessSecret,
|
secretAccessKey: configArg.accessSecret,
|
||||||
},
|
},
|
||||||
forcePathStyle: true, // Necessary for S3-compatible storage like MinIO or Wasabi
|
forcePathStyle: true, // Necessary for S3-compatible storage like MinIO or Wasabi
|
||||||
});
|
});
|
||||||
@ -43,4 +44,4 @@ export class SmartBucket {
|
|||||||
public async getBucketByName(bucketName: string) {
|
public async getBucketByName(bucketName: string) {
|
||||||
return Bucket.getBucketByName(this, bucketName);
|
return Bucket.getBucketByName(this, bucketName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ export class Trash {
|
|||||||
const trashDir = await this.getTrashDir();
|
const trashDir = await this.getTrashDir();
|
||||||
const originalPath = await helpers.reducePathDescriptorToPath(pathDescriptor);
|
const originalPath = await helpers.reducePathDescriptorToPath(pathDescriptor);
|
||||||
const trashKey = await this.getTrashKeyByOriginalBasePath(originalPath);
|
const trashKey = await this.getTrashKeyByOriginalBasePath(originalPath);
|
||||||
return trashDir.getFile({ name: trashKey });
|
return trashDir.getFile({ path: trashKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getTrashKeyByOriginalBasePath (originalPath: string): Promise<string> {
|
public async getTrashKeyByOriginalBasePath (originalPath: string): Promise<string> {
|
||||||
|
Reference in New Issue
Block a user