Skip to content

Commit 6c9ab35

Browse files
authored
Add forRootAsync (#1)
* feat: add module import for root async method * refactor: storage module options struct refactor * test: add for root async testing * build: move flydrive dependencies to dev dependencies * docs: prettier add print width * docs: add readme.md
1 parent f814d58 commit 6c9ab35

16 files changed

+288
-28
lines changed

.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"trailingComma": "all",
33
"singleQuote": true,
4-
"arrowParens": "avoid"
4+
"arrowParens": "avoid",
5+
"printWidth": 80
56
}

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<p align="center">
2+
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo_text.svg" width="320" alt="Nest Logo" /></a>
3+
</p>
4+
5+
<p align="center">
6+
nestjs-storage is manage file Storage wrapping package flydrive
7+
</p>
8+
<p align="center">
9+
<a href="https://www.npmjs.com/org/codebrew"><img src="https://img.shields.io/npm/v/@codebrew/nestjs-storage.svg" alt="NPM Version" /></a>
10+
<a href="https://www.npmjs.com/org/codebrew"><img src="https://img.shields.io/npm/l/@codebrew/nestjs-storage.svg" alt="Package License" /></a>
11+
<a href="https://www.npmjs.com/org/codebrew"><img src="https://img.shields.io/npm/dm/@codebrew/nestjs-storage.svg" alt="NPM Downloads" /></a>
12+
</p>
13+
14+
## Installation
15+
16+
```bash
17+
$ npm i --save @codebrew/nestjs-storage @slynova/flydrive
18+
19+
# optional with s3 driver
20+
$ npm i --save @slynova/flydrive-s3
21+
22+
# optional with gcs driver
23+
$ npm i --save @slynova/flydrive-gcs
24+
```
25+
26+
## Example
27+
28+
```typescript
29+
// app.module.ts
30+
import { Module } from '@nestjs/common'
31+
import { StorageModule, DriverType } from '@codebrew/nestjs-storage';
32+
33+
@Module({
34+
imports: [StorageModule.forRoot({
35+
module: AppModule,
36+
imports: [
37+
StorageModule.forRoot({
38+
default: 'local',
39+
disks: {
40+
local: {
41+
driver: DriverType.LOCAL,
42+
config: {
43+
root: process.cwd(),
44+
},
45+
},
46+
},
47+
}),
48+
],
49+
})]
50+
})
51+
export class AppModule {
52+
constructor(private storage: StorageServic) {
53+
this.storage.getDisk().put('test.txt', 'text content');
54+
}
55+
}
56+
```
57+
58+
## Support
59+
60+
nestjs-storage is an MIT-licensed open source project. If this library is helpful, please click star to support it.
61+
62+
## Stay in touch
63+
64+
- Author - [David Kwon](https://github.com/tienne)
65+
66+
## License
67+
68+
nestjs-storage is MIT licensed.

lib/interfaces/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export * from './Storage-module-options';
2+
export * from './storage-module-async-options';
3+
export * from './storage-options-factory';
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { ModuleMetadata, Type } from '@nestjs/common';
2+
import { StorageModuleOptions } from './storage-module-options';
3+
import { StorageOptionsFactory } from './storage-options-factory';
4+
5+
export interface StorageModuleAsyncOptions
6+
extends Pick<ModuleMetadata, 'imports'> {
7+
name?: string;
8+
useFactory?: (
9+
...args: any[]
10+
) => Promise<StorageModuleOptions> | StorageModuleOptions;
11+
useClass?: Type<StorageOptionsFactory>;
12+
inject?: any[];
13+
}
Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
11
import { StorageManagerConfig } from '@slynova/flydrive';
2-
import { DiskConfigType, DriverType } from '../types';
2+
import {
3+
DiskConfigType,
4+
DiskGCSConfigType,
5+
DiskLocalConfigType,
6+
DiskS3ConfigType,
7+
DriverType,
8+
DiskType,
9+
} from '../types';
310

411
export interface StorageModuleOptions extends StorageManagerConfig {
5-
isGlobal?: boolean;
612
default: string;
7-
disks: Record<string, StorageDiskConfig>;
13+
disks: Record<string, DiskType>;
814
}
915

1016
export interface StorageDiskConfig {
1117
driver: DriverType | string;
1218
config: DiskConfigType;
1319
}
20+
21+
export interface AwsS3StorageDisk extends StorageDiskConfig {
22+
driver: DriverType.S3 | 's3';
23+
config: DiskS3ConfigType;
24+
}
25+
26+
export interface LocalStorageDisk extends StorageDiskConfig {
27+
driver: DriverType.LOCAL | 'local';
28+
config: DiskLocalConfigType;
29+
}
30+
31+
export interface GoogleGcsStorageDisk extends StorageDiskConfig {
32+
driver: DriverType.GCS | 'gcs';
33+
config: DiskGCSConfigType;
34+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { StorageModuleOptions } from './storage-module-options';
2+
3+
export interface StorageOptionsFactory {
4+
createStorageOptions(): Promise<StorageModuleOptions> | StorageModuleOptions;
5+
}

lib/storage-core.module.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import {
2+
DynamicModule,
3+
Global,
4+
Inject,
5+
Module,
6+
Provider,
7+
Type,
8+
} from '@nestjs/common';
9+
import { StorageService } from './storage.service';
10+
11+
import { STORAGE_MODULE_OPTIONS } from './storage.constants';
12+
import { StorageModuleOptions, StorageOptionsFactory } from './interfaces';
13+
import { ModuleRef } from '@nestjs/core';
14+
import { StorageModuleAsyncOptions } from './interfaces/storage-module-async-options';
15+
@Global()
16+
@Module({})
17+
export class StorageCoreModule {
18+
constructor(
19+
@Inject(STORAGE_MODULE_OPTIONS)
20+
private readonly options: StorageModuleOptions,
21+
private readonly moduleRef: ModuleRef,
22+
) {}
23+
24+
static forRoot(options: StorageModuleOptions): DynamicModule {
25+
const storageModuleOptions: Provider = {
26+
provide: STORAGE_MODULE_OPTIONS,
27+
useValue: options,
28+
};
29+
30+
return {
31+
module: StorageCoreModule,
32+
providers: [storageModuleOptions, StorageService],
33+
exports: [StorageService],
34+
};
35+
}
36+
37+
static forRootAsync(options: StorageModuleAsyncOptions): DynamicModule {
38+
const asyncProviders = this.createAsyncProviders(options);
39+
40+
return {
41+
module: StorageCoreModule,
42+
imports: options.imports,
43+
providers: [...asyncProviders, StorageService],
44+
exports: [StorageService],
45+
};
46+
}
47+
48+
private static createAsyncProviders(
49+
options: StorageModuleAsyncOptions,
50+
): Provider[] {
51+
if (options.useFactory) {
52+
return [this.createAsyncOptionsProvider(options)];
53+
}
54+
const useClass = options.useClass as Type<StorageOptionsFactory>;
55+
return [
56+
this.createAsyncOptionsProvider(options),
57+
{
58+
provide: useClass,
59+
useClass,
60+
},
61+
];
62+
}
63+
64+
private static createAsyncOptionsProvider(
65+
options: StorageModuleAsyncOptions,
66+
): Provider {
67+
if (options.useFactory) {
68+
return {
69+
provide: STORAGE_MODULE_OPTIONS,
70+
useFactory: options.useFactory,
71+
inject: options.inject || [],
72+
};
73+
}
74+
75+
const inject = [options.useClass as Type<StorageOptionsFactory>];
76+
77+
return {
78+
provide: STORAGE_MODULE_OPTIONS,
79+
useFactory: async (optionsFactory: StorageOptionsFactory) =>
80+
optionsFactory.createStorageOptions(),
81+
inject,
82+
};
83+
}
84+
}

lib/storage.constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
* Injection tokens
33
*/
44
export const STORAGE_TOKEN = 'STORAGE_TOKEN';
5+
export const STORAGE_MODULE_OPTIONS = 'STORAGE_MODULE_OPTIONS';

lib/storage.module.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
1-
import { DynamicModule, FactoryProvider, Module } from '@nestjs/common';
2-
import { StorageService } from './storage.service';
1+
import { DynamicModule, Module } from '@nestjs/common';
32

4-
import { STORAGE_TOKEN } from './storage.constants';
53
import { StorageModuleOptions } from './interfaces';
4+
import { StorageCoreModule } from './storage-core.module';
5+
import { StorageModuleAsyncOptions } from './interfaces/storage-module-async-options';
66

7-
@Module({
8-
providers: [StorageService],
9-
exports: [StorageService],
10-
})
7+
@Module({})
118
export class StorageModule {
129
static forRoot(options: StorageModuleOptions): DynamicModule {
1310
return {
1411
module: StorageModule,
15-
global: options.isGlobal,
16-
providers: [
17-
{
18-
provide: STORAGE_TOKEN,
19-
useValue: options,
20-
},
21-
],
22-
exports: [StorageService],
12+
imports: [StorageCoreModule.forRoot(options)],
13+
};
14+
}
15+
16+
static forRootAsync(options: StorageModuleAsyncOptions): DynamicModule {
17+
return {
18+
module: StorageModule,
19+
imports: [StorageCoreModule.forRootAsync(options)],
2320
};
2421
}
2522
}

lib/storage.service.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { Inject, Injectable } from '@nestjs/common';
22
import { Storage, StorageManager } from '@slynova/flydrive';
33

4-
import { STORAGE_TOKEN } from './storage.constants';
4+
import { STORAGE_MODULE_OPTIONS } from './storage.constants';
55
import { StorageModuleOptions } from './interfaces';
66

77
@Injectable()
88
export class StorageService {
99
private storageManager: StorageManager;
1010

11-
constructor(@Inject(STORAGE_TOKEN) private options: StorageModuleOptions) {
11+
constructor(
12+
@Inject(STORAGE_MODULE_OPTIONS) private options: StorageModuleOptions,
13+
) {
1214
this.storageManager = new StorageManager(options);
1315
}
1416

0 commit comments

Comments
 (0)