GithubHelp home page GithubHelp logo

aginix / nestjs-gcloud-storage Goto Github PK

View Code? Open in Web Editor NEW
21.0 2.0 11.0 1.3 MB

Google Cloud Storage Module for Nest.js Framework

License: MIT License

TypeScript 100.00%
google-cloud-storage nestjs typescript nest-framework

nestjs-gcloud-storage's Introduction

NPM Version Package License NPM Downloads

Description

Google Cloud Storage Module for Nest.js Framework

Installation

$ yarn add @aginix/nestjs-gcloud-storage

Examples

Default import

If you have bucket domain name you can config storageBaseUri.

import { Module } from '@nestjs/common';
import { GCloudStorageModule } from '@aginix/nestjs-gcloud-storage';

@Module({
  imports: [
    GCloudStorageModule.withConfig({
      defaultBucketname: 'bucket.aginix.tech',
      storageBaseUri: 'bucket.aginix.tech',
      predefinedAcl: 'private' // Default is publicRead
    })
  ],
})
export class AppModule {}

Default import with asynchonous

import { Module } from '@nestjs/common';
import { GCloudStorageModule } from '@aginix/nestjs-gcloud-storage';
import { ConfigService } from './config.service';
import { ConfigModule } from './config.module';

@Module({
  imports: [
    GCloudStorageModule.withConfigAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        defaultBucketname: config.get('GCS_BUCKET_NAME'),
        storageBaseUri: config.get('GCS_DOMAIN_NAME'),
      }),
      imports: [ConfigModule],
    })
  ],
})
export class AppModule {}

Using uniform bucket-level access

Set predefinedAcl to null

@Module({
  imports: [
    GCloudStorageModule.withConfig({
      predefinedAcl: null
    })
  ],
})
export class AppModule {}

Store a file using the default config

import {
  Controller,
  Logger,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
  GCloudStorageFileInterceptor,
  UploadedFileMetadata,
} from '@aginix/nestjs-gcloud-storage';

@Controller()
export class AppController {
  
  @Post('gcs/upload')
  @UseInterceptors(
    GCloudStorageFileInterceptor('file'),
  )
  UploadedFilesUsingInterceptor(
    @UploadedFile()
    file: UploadedFileMetadata,
  ) {
    Logger.log(`Storage URL: ${file.storageUrl}`, 'AppController');
  }
}

Store a file using a specific folder/prefix name

import {
  Controller,
  Logger,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
  GCloudStorageFileInterceptor,
  UploadedFileMetadata,
} from '@aginix/nestjs-gcloud-storage';

@Controller()
export class AppController {
  
  @Post('gcs/upload')
  @UseInterceptors(
    GCloudStorageFileInterceptor('file', undefined, { prefix: 'prefix/test' })
  )
  UploadedFilesUsingInterceptor(
    @UploadedFile()
    file: UploadedFileMetadata,
  ) {
    Logger.log(`Storage URL: ${file.storageUrl}`, 'AppController');
  }
}

Store a file using a specific predefined ACL

@Controller()
export class AppController {
  
  @Post('gcs/secret-file')
  @UseInterceptors(
    GCloudStorageFileInterceptor('secret-file', undefined, { predefinedAcl: 'private' })
  )
  UploadedSecretFile(
    @UploadedFile()
    file: UploadedFileMetadata,
  ) {
    Logger.log(`Storage URL: ${file.storageUrl}`, 'AppController');
  }
}

License

MIT © Aginix Technologies Co., Ltd.

nestjs-gcloud-storage's People

Contributors

dependabot-preview[bot] avatar hood avatar n3n avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nestjs-gcloud-storage's Issues

Add a resize functionality for interceptor

If you want to resize the file before the upload, you can pass on the resize property as follows:
@post('upload')
@UseInterceptors(
GCloudStorageFileInterceptor('file', {
resize: { width: 500, height: 400 },
}),
)
uploadFile(@uploadedfile() file) {
console.log(file);
}

You can pass an array of size options to resize a single image into different sizes as follows:
@post('upload')
@UseInterceptors(
GCloudStorageFileInterceptor('file', {
resizeMultiple: [
{ suffix: 'sm', width: 200, height: 200 },
{ suffix: 'md', width: 300, height: 300 },
{ suffix: 'lg', width: 400, height: 400 },
],
}
)
uploadFile(@uploadedfile() file) {
console.log(file);
}

Support for multiple field names

I have a form to upload two images with different names say 'avatar' and 'background'
When i use

GCloudStorageFileInterceptor('background', undefined, {
  prefix: 'background',
  predefinedAcl: 'private'
}),
GCloudStorageFileInterceptor('avatar', undefined, {
  prefix: 'avatar',
  predefinedAcl: 'private'
}),

I get Unexpected field error

@nestjs/platform-express supports has FileFieldsInterceptor which can take multiple fields

@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))

Is there a way to do this with @aginix/nestjs-gcloud-storage ?

Add support for random file naming flag

Hi just want to propose some minor changes if you can support uuid naming out of the box when uploading a file?
For example:
@post('upload')
@UseInterceptors(
GCloudStorageFileInterceptor('file', {
randomFilename: true
}),
)
uploadFile(@uploadedfile() file: UploadedFileMetadata) {
console.log(file);
}

You may want to store the file with an arbitrary name instead of the original file name. You can do this by passing the randomFilename property attribute set to true as follows:

"undefined" storage options when using "withConfigAsync"

Given this way of importing the module:

@Module({
    controllers: [MyController],
    imports: [
        ConfigService,
        GCloudStorageModule.withConfigAsync({
            inject: [ConfigService],
            useFactory: (configService: ConfigService) => ({
                defaultBucketname: configService.get<string>(
                    'gcsConfig.defaultBucketname'
                ),
                credentials: configService.get<IGCloudCredentials>(
                    'gcsConfig.credentials'
                ),
                prefix: configService.get<string>('gcsConfig.prefix'),
                projectId: configService.get<string>('gcsConfig.projectId')
            }),
            imports: [ConfigModule]
        })
    ]
})
export class MyModule {}

I'm getting the following errors:

TypeError: Cannot read property 'defaultBucketname' of undefined
    at new GCloudStorageService (/<PROJECT_PATH>/node_modules/@aginix/nestjs-gcloud-storage/dist/gcloud-storage.service.js:37:41)

as if the storage options are undefined.

Strange this is that if if set defaultBucketname: undefined I then get the following, different, error:

Error: A bucket name is needed to use Cloud Storage.

I've tried hardcoding the configuration directly in the GCloudStorageFileInterceptor parameters and everything works, so I guess it's an issue with withConfigAsync.

I'm currently trying to investigate, but I can't seem to find any apparent reason for this issue to be happening.

Field names other than "file" seem to be broken

Hi. It seems that custom field names don't work correctly with the interceptors. For example:

@UseInterceptors(
  GCloudStorageFileInterceptor('customField')
)

This will always result in the error

Can not intercept field "customField". Did you specify the correct field name in @GCloudStorageFileInterceptor('customField')?

The error originates from here:

const file = request[fieldName];
if (!file) {
Logger.error(
'GCloudStorageFileInterceptor',
`Can not intercept field "${fieldName}". Did you specify the correct field name in @GCloudStorageFileInterceptor('${fieldName}')?`,
);
return;
}

I think the line const file = request[fieldName]; is incorrect, as according to multer docs:

  • Multer adds a body object and a file or files object to the request object

But the interceptor tries to access a property of the request object based on the provided fieldName parameter.
So GCloudStorageFileInterceptor('file') works, but everything else won't.

refresh the lockfile to automatically remove the vulnerability introduced in @aginix/nestjs-gcloud-storage

Hi, @n3n, I have reported a vulnerability issue in package @google-cloud/storage.

As far as I am aware, vulnerability CVE-2020-26289 detected in package date-and-time<0.14.2) is directly referenced by  @google-cloud/[email protected], on which your package @aginix/[email protected] directly depends. As such, this vulnerability can also affect @aginix/[email protected] via the following path:
@aginix/[email protected] ➔ @google-cloud/[email protected][email protected](vulnerable version)

Since @google-cloud/storage has released a new patched version @google-cloud/[email protected] to resolve this issue (@google-cloud/[email protected][email protected](fix version)), then this vulnerability patch can be automatically propagated into your project only if you update your lockfile. The following is your new dependency path :
@aginix/[email protected] ➔ @google-cloud/[email protected][email protected](vulnerability fix version).

dependency path

A warm tip.
Best regards,
^_^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.