fix(smarts3): Use filesystem store for bucket creation and remove smartbucket runtime dependency
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-11-23 - 3.0.4 - fix(smarts3)
|
||||
Use filesystem store for bucket creation and remove smartbucket runtime dependency
|
||||
|
||||
- Switched createBucket to call the internal FilesystemStore.createBucket instead of using @push.rocks/smartbucket
|
||||
- Made Smarts3Server.store public so Smarts3 can access the filesystem store directly
|
||||
- Removed runtime import/export of @push.rocks/smartbucket from plugins and moved @push.rocks/smartbucket to devDependencies in package.json
|
||||
- Updated createBucket to return a simple { name } object after creating the bucket via the filesystem store
|
||||
|
||||
## 2025-11-23 - 3.0.3 - fix(filesystem)
|
||||
Migrate filesystem implementation to @push.rocks/smartfs and add Web Streams handling
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"@git.zone/tsbundle": "^2.5.2",
|
||||
"@git.zone/tsrun": "^2.0.0",
|
||||
"@git.zone/tstest": "^3.1.0",
|
||||
"@push.rocks/smartbucket": "^4.3.0",
|
||||
"@types/node": "^22.9.0"
|
||||
},
|
||||
"browserslist": [
|
||||
@@ -37,7 +38,6 @@
|
||||
"readme.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"@push.rocks/smartbucket": "^4.3.0",
|
||||
"@push.rocks/smartfs": "^1.1.0",
|
||||
"@push.rocks/smartpath": "^6.0.0",
|
||||
"@push.rocks/smartxml": "^2.0.0",
|
||||
|
||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -8,9 +8,6 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@push.rocks/smartbucket':
|
||||
specifier: ^4.3.0
|
||||
version: 4.3.0
|
||||
'@push.rocks/smartfs':
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
@@ -39,6 +36,9 @@ importers:
|
||||
'@git.zone/tstest':
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.0(socks@2.8.7)(typescript@5.9.3)
|
||||
'@push.rocks/smartbucket':
|
||||
specifier: ^4.3.0
|
||||
version: 4.3.0
|
||||
'@types/node':
|
||||
specifier: ^22.9.0
|
||||
version: 22.19.1
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smarts3',
|
||||
version: '3.0.3',
|
||||
version: '3.0.4',
|
||||
description: 'A Node.js TypeScript package to create a local S3 endpoint for simulating AWS S3 operations using mapped local directories for development and testing purposes.'
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export class Smarts3Server {
|
||||
private httpServer?: plugins.http.Server;
|
||||
private router: S3Router;
|
||||
private middlewares: MiddlewareStack;
|
||||
private store: FilesystemStore;
|
||||
public store: FilesystemStore; // Made public for direct access from Smarts3 class
|
||||
private options: Required<ISmarts3ServerOptions>;
|
||||
|
||||
constructor(options: ISmarts3ServerOptions = {}) {
|
||||
|
||||
182
ts/index.ts
182
ts/index.ts
@@ -2,39 +2,185 @@ import * as plugins from './plugins.js';
|
||||
import * as paths from './paths.js';
|
||||
import { Smarts3Server } from './classes/smarts3-server.js';
|
||||
|
||||
export interface ISmarts3ContructorOptions {
|
||||
/**
|
||||
* 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 {
|
||||
port?: number;
|
||||
address?: string;
|
||||
silent?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Storage configuration
|
||||
*/
|
||||
export interface IStorageConfig {
|
||||
directory?: string;
|
||||
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
|
||||
*/
|
||||
export class Smarts3 {
|
||||
// STATIC
|
||||
public static async createAndStart(
|
||||
optionsArg: ConstructorParameters<typeof Smarts3>[0],
|
||||
) {
|
||||
const smartS3Instance = new Smarts3(optionsArg);
|
||||
public static async createAndStart(configArg: ISmarts3Config = {}) {
|
||||
const smartS3Instance = new Smarts3(configArg);
|
||||
await smartS3Instance.start();
|
||||
return smartS3Instance;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
public options: ISmarts3ContructorOptions;
|
||||
public config: Required<ISmarts3Config>;
|
||||
public s3Instance: Smarts3Server;
|
||||
|
||||
constructor(optionsArg: ISmarts3ContructorOptions) {
|
||||
this.options = optionsArg;
|
||||
constructor(configArg: ISmarts3Config = {}) {
|
||||
this.config = mergeConfig(configArg);
|
||||
}
|
||||
|
||||
public async start() {
|
||||
this.s3Instance = new Smarts3Server({
|
||||
port: this.options.port || 3000,
|
||||
address: '0.0.0.0',
|
||||
directory: paths.bucketsDir,
|
||||
cleanSlate: this.options.cleanSlate || false,
|
||||
silent: false,
|
||||
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();
|
||||
console.log('s3 server is running');
|
||||
|
||||
if (!this.config.server.silent) {
|
||||
console.log('s3 server is running');
|
||||
}
|
||||
}
|
||||
|
||||
public async getS3Descriptor(
|
||||
@@ -48,11 +194,9 @@ export class Smarts3 {
|
||||
}
|
||||
|
||||
public async createBucket(bucketNameArg: string) {
|
||||
const smartbucketInstance = new plugins.smartbucket.SmartBucket(
|
||||
await this.getS3Descriptor(),
|
||||
);
|
||||
const bucket = await smartbucketInstance.createBucket(bucketNameArg);
|
||||
return bucket;
|
||||
// Call the filesystem store directly instead of using the client library
|
||||
await this.s3Instance.store.createBucket(bucketNameArg);
|
||||
return { name: bucketNameArg };
|
||||
}
|
||||
|
||||
public async stop() {
|
||||
|
||||
@@ -7,7 +7,6 @@ import * as url from 'url';
|
||||
export { path, http, crypto, url };
|
||||
|
||||
// @push.rocks scope
|
||||
import * as smartbucket from '@push.rocks/smartbucket';
|
||||
import { SmartFs, SmartFsProviderNode } from '@push.rocks/smartfs';
|
||||
import * as smartpath from '@push.rocks/smartpath';
|
||||
import { SmartXml } from '@push.rocks/smartxml';
|
||||
@@ -15,7 +14,7 @@ import { SmartXml } from '@push.rocks/smartxml';
|
||||
// Create SmartFs instance with Node.js provider
|
||||
export const smartfs = new SmartFs(new SmartFsProviderNode());
|
||||
|
||||
export { smartbucket, smartpath, SmartXml };
|
||||
export { smartpath, SmartXml };
|
||||
|
||||
// @tsclass scope
|
||||
import * as tsclass from '@tsclass/tsclass';
|
||||
|
||||
Reference in New Issue
Block a user