npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@secjs/storage

v1.0.4

Published

Handle your application files in Node.js

Downloads

5

Readme

Storage 🗃️

Handle your application files in Node.js

GitHub followers GitHub stars

The intention behind this repository is to always maintain a Storage class to manipulate files using any driver.

Installation

To use the high potential from this package you need to install first this other packages from SecJS, it keeps as dev dependency because one day @secjs/core will install everything once.

npm install @secjs/env @secjs/utils @secjs/contracts @secjs/exceptions

Then you can install the package using:

npm install @secjs/storage

Usage

Config filesystem template

First you need to create the configuration file filesystem in the config folder on project root path. Is extremely important to use export default in these configurations.

import { Env } from '@secjs/env'
import { Path } from '@secjs/utils'

export default {
  /*
  |--------------------------------------------------------------------------
  | Default Filesystem Disk
  |--------------------------------------------------------------------------
  |
  | Here you may specify the default filesystem disk that should be used
  | by the framework. The "local" disk, as well as a variety of cloud
  | based disks are available to your application.
  |
  */

  default: Env('FILESYSTEM_DISK', 'local'),

  /*
  |--------------------------------------------------------------------------
  | Filesystem Disks
  |--------------------------------------------------------------------------
  |
  | Here you may configure as many filesystem "disks" as you wish, and you
  | may even configure multiple disks of the same driver. Defaults have
  | been setup for each driver as an example of the required options.
  |
  */

  disks: {
    local: {
      driver: 'local',
      root: Path.noBuild().storage('app'),
      url: `${Env('APP_URL', '')}/storage`,
    },
    public: {
      driver: 'local',
      root: Path.noBuild().storage('app/public'),
      url: `${Env('APP_URL', '')}/storage/public`,
    },
    s3: {
      driver: 's3',
      key: Env('AWS_KEY', ''),
      secret: Env('AWS_SECRET', ''),
      region: Env('AWS_REGION', ''),
      bucket: Env('AWS_BUCKET', ''),
      endpoint: Env('AWS_ENDPOINT', '')
    },
    gcs: {
      driver: 'gcs',
      project: Env('GCS_PROJECT', ''),
      secret: Env('GCS_SECRET', ''),
      bucket: Env('GCS_BUCKET', ''),
      endpoint: Env('GCS_ENDPOINT', ''),
    },
  },
}

Storage

With the config/filesystem file created you can use Storage class to start storing your files.

import { Storage } from '@secjs/storage'

const storage = new Storage()

// Storage class will always use the default value set in config/filesystem to store the files, in this case, local.
await storage.put('file.txt', Buffer.from('hello world!'))
// The file will be saved in the root storage/app/file.txt, according to config/filesystem.

// You can use putFile method to create a file "without name", an unique id will be generated for him.
const path = await storage.putFile('folder', 'txt', Buffer.from('hello world!')) // returns the path -> folder/DASdsakdjas912831jhdasnm.txt
// The file will be saved in the root storage/app/folder/DASdsakdjas912831jhdasnm.txt, according to config/filesystem.
// You can use exists and missing too
console.log(await storage.exists('folder/DASdsakdjas912831jhdasnm.txt')) // true
console.log(await storage.missing('folder/DASdsakdjas912831jhdasnm.txt')) // false

// You can get only the content of the file in Buffer using get
await storage.get('folder/DASdsakdjas912831jhdasnm.txt') // Buffer<6c 6c 6c 6c...>
// You can generate an url and a temporaryUrl to your file based on config/filesystem.
await storage.url('folder/DASdsakdjas912831jhdasnm.txt') // https://cdn.secjs.io/storage/folder/DASdsakdjas912831jhdasnm.txt
// 10 minutes = 600000ms
await storage.temporaryUrl('folder/DASdsakdjas912831jhdasnm.txt', 600000) // https://cdn.secjs.io/storage/folder/temp/30219310391sadlksa12039.txt
// You can delete the file using delete
const force = true
// You can use force to not throw exceptions if file does not exist
await storage.delete('folder/DASdsakdjas912831jhdasnm.txt', force)
// You can use copy and move
// In this case folder/DASdsakdjas912831jhdasnm.txt will still exists
await storage.copy('folder/DASdsakdjas912831jhdasnm.txt', 'folder/test/copy.txt')

// In this case folder/DASdsakdjas912831jhdasnm.txt will be removed
await storage.move('folder/DASdsakdjas912831jhdasnm.txt', 'folder/test/move.txt')

Subscribing configs of disks in runtime

You can subscribe the disks configs in runtime using in Storage constructor or disk method

// Using disk method approach
// File created on storage/newAppFolder/file.txt
storage
  .disk('local', { root: Path.noBuild().storage('newAppFolder') })
  .put('file.txt', Buffer.from('Hello World'))

// Using constructor method approach
const newStorage = new Storage({ root: Path.noBuild().storage('newAppFolder') })

// File created on storage/newAppFolder/file2.txt
newStorage.put('file2.txt', Buffer.from('Hello World'))

// You can reset configs using an empty object in the disk method
storage.disk('local', {}) // Clear the runtime configuration

Using S3 or GCS disk

You can use s3 or gcs disk to make all this actions inside buckets

// Saves to S3
storage.disk('s3').put('folder/file.txt', Buffer.from('Hello world!'))
// Saves to GCS
storage.disk('gcs').put('folder/file.txt', Buffer.from('Hello world!'))

Extending disks and drivers

Nowadays, @secjs/storage has only LocalDriver, S3Driver and GCSDriver support, but you can extend the drivers for Storage class if you implement DriverContract interface

import { DriverContract } from '@secjs/storage'

class CustomDriver implements DriverContract {
  private readonly _url: string
  private readonly _root: string
  
  constructor(disk: string) {
    this._url = Config.get(`filesystem.disks.${disk}.url`)
    this._root = Config.get(`filesystem.disks.${disk}.root`)
  }
  
  // all the methods implemented from DriverContract...
}

Constructor is extremely important in your CustomDriver class, it's the constructor that will use the values from config/filesystem disks to manipulate your CustomDriver using disk method from storage. So if you are building a CustomDriver, and you want to use it, you can create a new disk inside config/filesystem disks or change the driver from an existing disk.

// extending disks
// config/filesystem file

export default {
  // default etc...
  
  disks: {
    mydisk: {
      driver: 'custom',
      root: Path.storage('app/mydisk'),
      url: `${Env('APP_URL', '')}/storage/mydisk`,
    }
    // ... other disks
  }
}

Build you new driver using build static method

const name = 'custom'
const driver = CustomDriver

Storage.build(name, driver)

console.log(Storage.drivers) // ['s3', 'local', 'public', 'custom']

Now, if you have implemented your disk in config/filesystem, you can use him inside storage

// Will use CustomDriver to handle the file actions
storage.disk('mydisk').put('file.txt', Buffer.from('my custom driver'))

License

Made with 🖤 by jlenon7 :wave: