Files
smarts3/ts/index.ts

209 lines
4.5 KiB
TypeScript
Raw Normal View History

import * as plugins from './plugins.js';
2022-04-14 10:36:24 +02:00
import * as paths from './paths.js';
import { Smarts3Server } from './classes/smarts3-server.js';
2021-12-18 01:41:50 +01:00
/**
* Authentication configuration
*/
export interface IAuthConfig {
enabled: boolean;
credentials: Array<{
accessKeyId: string;
secretAccessKey: string;
}>;
}
/**
* CORS configuration
*/
export interface ICorsConfig {
enabled: boolean;
allowedOrigins?: string[];
allowedMethods?: string[];
allowedHeaders?: string[];
exposedHeaders?: string[];
maxAge?: number;
allowCredentials?: boolean;
}
/**
* Logging configuration
*/
export interface ILoggingConfig {
level?: 'error' | 'warn' | 'info' | 'debug';
format?: 'text' | 'json';
enabled?: boolean;
}
/**
* Request limits configuration
*/
export interface ILimitsConfig {
maxObjectSize?: number;
maxMetadataSize?: number;
requestTimeout?: number;
}
/**
* Server configuration
*/
export interface IServerConfig {
2021-12-18 01:41:50 +01:00
port?: number;
address?: string;
silent?: boolean;
}
/**
* Storage configuration
*/
export interface IStorageConfig {
directory?: string;
2021-12-18 01:41:50 +01:00
cleanSlate?: boolean;
}
/**
* Complete smarts3 configuration
*/
export interface ISmarts3Config {
server?: IServerConfig;
storage?: IStorageConfig;
auth?: IAuthConfig;
cors?: ICorsConfig;
logging?: ILoggingConfig;
limits?: ILimitsConfig;
}
/**
* Default configuration values
*/
const DEFAULT_CONFIG: ISmarts3Config = {
server: {
port: 3000,
address: '0.0.0.0',
silent: false,
},
storage: {
directory: paths.bucketsDir,
cleanSlate: false,
},
auth: {
enabled: false,
credentials: [
{
accessKeyId: 'S3RVER',
secretAccessKey: 'S3RVER',
},
],
},
cors: {
enabled: false,
allowedOrigins: ['*'],
allowedMethods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'],
allowedHeaders: ['*'],
exposedHeaders: ['ETag', 'x-amz-request-id', 'x-amz-version-id'],
maxAge: 86400,
allowCredentials: false,
},
logging: {
level: 'info',
format: 'text',
enabled: true,
},
limits: {
maxObjectSize: 5 * 1024 * 1024 * 1024, // 5GB
maxMetadataSize: 2048,
requestTimeout: 300000, // 5 minutes
},
};
/**
* Merge user config with defaults (deep merge)
*/
function mergeConfig(userConfig: ISmarts3Config): Required<ISmarts3Config> {
return {
server: {
...DEFAULT_CONFIG.server!,
...(userConfig.server || {}),
},
storage: {
...DEFAULT_CONFIG.storage!,
...(userConfig.storage || {}),
},
auth: {
...DEFAULT_CONFIG.auth!,
...(userConfig.auth || {}),
},
cors: {
...DEFAULT_CONFIG.cors!,
...(userConfig.cors || {}),
},
logging: {
...DEFAULT_CONFIG.logging!,
...(userConfig.logging || {}),
},
limits: {
...DEFAULT_CONFIG.limits!,
...(userConfig.limits || {}),
},
};
}
/**
* Main Smarts3 class - production-ready S3-compatible server
*/
2021-12-18 01:41:50 +01:00
export class Smarts3 {
2021-12-20 17:06:42 +01:00
// STATIC
public static async createAndStart(configArg: ISmarts3Config | ILegacySmarts3Config = {}) {
const smartS3Instance = new Smarts3(configArg);
2021-12-20 17:06:42 +01:00
await smartS3Instance.start();
return smartS3Instance;
}
// INSTANCE
public config: Required<ISmarts3Config>;
public s3Instance: Smarts3Server;
2021-12-18 01:41:50 +01:00
constructor(configArg: ISmarts3Config | ILegacySmarts3Config = {}) {
this.config = mergeConfig(configArg);
2021-12-18 01:41:50 +01:00
}
public async start() {
this.s3Instance = new Smarts3Server({
port: this.config.server.port,
address: this.config.server.address,
directory: this.config.storage.directory,
cleanSlate: this.config.storage.cleanSlate,
silent: this.config.server.silent,
config: this.config, // Pass full config to server
});
await this.s3Instance.start();
if (!this.config.server.silent) {
console.log('s3 server is running');
}
2021-12-18 01:41:50 +01:00
}
public async getS3Descriptor(
optionsArg?: Partial<plugins.tsclass.storage.IS3Descriptor>,
): Promise<plugins.tsclass.storage.IS3Descriptor> {
const descriptor = this.s3Instance.getS3Descriptor();
2021-12-20 16:33:13 +01:00
return {
...descriptor,
...(optionsArg ? optionsArg : {}),
2022-04-14 10:38:14 +02:00
};
2021-12-20 16:33:13 +01:00
}
2021-12-20 19:36:54 +01:00
public async createBucket(bucketNameArg: string) {
// Call the filesystem store directly instead of using the client library
await this.s3Instance.store.createBucket(bucketNameArg);
return { name: bucketNameArg };
2021-12-20 19:36:54 +01:00
}
2021-12-18 01:41:50 +01:00
public async stop() {
await this.s3Instance.stop();
2021-12-18 01:41:50 +01:00
}
2022-04-14 10:38:14 +02:00
}
// Export the custom server class for direct use
export { Smarts3Server } from './classes/smarts3-server.js';