{"id":47696281,"url":"https://github.com/tacxou/nestjs_module_factorydrive","last_synced_at":"2026-04-02T16:27:00.201Z","repository":{"id":195541613,"uuid":"692921847","full_name":"tacxou/nestjs_module_factorydrive","owner":"tacxou","description":"Factory drive module for NestJS framework","archived":false,"fork":false,"pushed_at":"2026-03-07T09:52:20.000Z","size":309,"stargazers_count":1,"open_issues_count":11,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-07T09:53:28.758Z","etag":null,"topics":["abstract","abstraction","async","bucket","disk","drive","driver","factory","factorydrive","file","filesystem","nestjs","node","nodejs","npm","promise","spaces","storage"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@tacxou/nestjs_module_factorydrive","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tacxou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-09-18T01:13:44.000Z","updated_at":"2026-03-07T09:52:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"4760a2ca-5c2c-4bf6-b972-2dee43c00fb3","html_url":"https://github.com/tacxou/nestjs_module_factorydrive","commit_stats":{"total_commits":37,"total_committers":2,"mean_commits":18.5,"dds":"0.16216216216216217","last_synced_commit":"11a9e1a4a7cbb83684c33d7de206bf7b64501fa1"},"previous_names":["streamkits/nestjs_module_factorydrive","the-software-compagny/nestjs_module_factorydrive","tacxou/nestjs_module_factorydrive"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/tacxou/nestjs_module_factorydrive","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacxou%2Fnestjs_module_factorydrive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacxou%2Fnestjs_module_factorydrive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacxou%2Fnestjs_module_factorydrive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacxou%2Fnestjs_module_factorydrive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tacxou","download_url":"https://codeload.github.com/tacxou/nestjs_module_factorydrive/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tacxou%2Fnestjs_module_factorydrive/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31309867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abstract","abstraction","async","bucket","disk","drive","driver","factory","factorydrive","file","filesystem","nestjs","node","nodejs","npm","promise","spaces","storage"],"created_at":"2026-04-02T16:26:59.557Z","updated_at":"2026-04-02T16:27:00.185Z","avatar_url":"https://github.com/tacxou.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"http://nestjs.com/\" target=\"blank\"\u003e\n    \u003cimg src=\"https://nestjs.com/img/logo_text.svg\" width=\"320\" alt=\"Nest Logo\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Factory drive module for NestJS framework\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/org/tacxou\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@tacxou/nestjs_module_factorydrive.svg\" alt=\"NPM Version\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/org/tacxou\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/@tacxou/nestjs_module_factorydrive.svg\" alt=\"Package License\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/tacxou/nestjs_module_rcon/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/tacxou/nestjs_module_factorydrive/actions/workflows/ci.yml/badge.svg\" alt=\"Publish Package to npmjs\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/tacxou/nestjs_module_factorydrive\"\u003e\u003cimg src=\"https://codecov.io/gh/tacxou/nestjs_module_factorydrive/graph/badge.svg?token=BX1NdAZ9yj\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/tacxou/nestjs_module_rcon/actions/workflows/release.yml?event=workflow_dispatch\"\u003e\u003cimg alt=\"GitHub contributors\" src=\"https://github.com/tacxou/nestjs_module_rcon/actions/workflows/release.yml/badge.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cbr\u003e\n\n## `@tacxou/nestjs_module_factorydrive`\n\n`nestjs_module_factorydrive` provides a simple storage abstraction for NestJS:\n- configure one or many disks\n- select a default disk\n- use built-in local filesystem driver\n- register custom drivers (S3, Spaces, etc.)\n\n## Maintained Packages\n\nCurrent maintained packages in the Factorydrive ecosystem:\n\n- `local`: [`nestjs_module_factorydrive`](https://github.com/tacxou/nestjs_module_factorydrive/blob/main/src/factorydrive/local-file-system.storage.ts)\n- `s3`: [`nestjs_module_factorydrive-s3`](https://github.com/tacxou/nestjs_module_factorydrive-s3)\n- `sftp`: [`nestjs_module_factorydrive-sftp`](https://github.com/tacxou/nestjs_module_factorydrive-sftp)\n\n## Requirements\n\n- Node.js `\u003e= 22`\n- Bun `\u003e= 1.0.0` (used for build/test in this repository)\n- NestJS `^6` to `^11` (`@nestjs/common` and `@nestjs/core`)\n\n## Installation\n\n```bash\nnpm install @tacxou/nestjs_module_factorydrive\n```\n\nOr with other package managers:\n\n```bash\nyarn add @tacxou/nestjs_module_factorydrive\npnpm add @tacxou/nestjs_module_factorydrive\nbun add @tacxou/nestjs_module_factorydrive\n```\n\n## Quick Start (synchronous config)\n\n```ts\n// app.module.ts\nimport { Module } from '@nestjs/common'\nimport { FactorydriveModule } from '@tacxou/nestjs_module_factorydrive'\n\n@Module({\n  imports: [\n    FactorydriveModule.forRoot({\n      default: 'local',\n      disks: {\n        local: {\n          driver: 'local',\n          config: {\n            root: `${process.cwd()}/storage`,\n          },\n        },\n      },\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n## Async Configuration (`forRootAsync`)\n\n```ts\n// app.module.ts\nimport { Module } from '@nestjs/common'\nimport { ConfigModule, ConfigService } from '@nestjs/config'\nimport { FactorydriveModule } from '@tacxou/nestjs_module_factorydrive'\n\n@Module({\n  imports: [\n    ConfigModule.forRoot({ isGlobal: true }),\n    FactorydriveModule.forRootAsync({\n      imports: [ConfigModule],\n      inject: [ConfigService],\n      useFactory: async (config: ConfigService) =\u003e ({\n        default: config.get\u003cstring\u003e('factorydrive.default', 'local'),\n        disks: {\n          local: {\n            driver: 'local',\n            config: {\n              root: config.get\u003cstring\u003e('factorydrive.localRoot', `${process.cwd()}/storage`),\n            },\n          },\n        },\n      }),\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\n## Usage\n\nInject `FactorydriveService` and interact with a disk instance:\n\n```ts\n// file-storage.service.ts\nimport { Injectable } from '@nestjs/common'\nimport { FactorydriveService } from '@tacxou/nestjs_module_factorydrive'\n\n@Injectable()\nexport class FileStorageService {\n  public constructor(private readonly factorydrive: FactorydriveService) {}\n\n  public async uploadFile(path: string, buffer: Buffer): Promise\u003cvoid\u003e {\n    await this.factorydrive.getDisk('local').put(path, buffer)\n  }\n\n  public async readFile(path: string): Promise\u003cstring\u003e {\n    const { content } = await this.factorydrive.getDisk('local').get(path)\n    return content\n  }\n\n  public async deleteFile(path: string): Promise\u003cboolean | null\u003e {\n    const { wasDeleted } = await this.factorydrive.getDisk('local').delete(path)\n    return wasDeleted\n  }\n}\n```\n\nIf no disk name is provided, the configured `default` disk is used:\n\n```ts\nconst disk = this.factorydrive.getDisk()\n```\n\n## Built-in Local Driver\n\nThe package includes a `local` driver with the following operations:\n\n- `append(location, content)`\n- `copy(src, dest)`\n- `delete(location)`\n- `exists(location)`\n- `get(location, encoding?)`\n- `getBuffer(location)`\n- `getStat(location)`\n- `getStream(location)`\n- `move(src, dest)`\n- `prepend(location, content)`\n- `put(location, content)`\n- `flatList(prefix?)`\n\n`content` for `put` accepts `Buffer | ReadableStream | string`.\n\n## Register a Custom Driver\n\nCustom drivers must extend `AbstractStorage` and implement the methods you need.\n\n```ts\n// aws-s3.storage.ts\nimport { AbstractStorage, DeleteResponse, Response } from '@tacxou/nestjs_module_factorydrive'\n\nexport class AwsS3Storage extends AbstractStorage {\n  public constructor(private readonly config: { bucket: string }) {\n    super()\n  }\n\n  public async put(location: string, content: Buffer | NodeJS.ReadableStream | string): Promise\u003cResponse\u003e {\n    // Upload implementation...\n    return { raw: { location, uploaded: true, contentType: typeof content } }\n  }\n\n  public async delete(location: string): Promise\u003cDeleteResponse\u003e {\n    // Delete implementation...\n    return { raw: { location }, wasDeleted: true }\n  }\n}\n```\n\nThen register it at startup:\n\n```ts\n// app.module.ts\nimport { Module, OnModuleInit } from '@nestjs/common'\nimport { FactorydriveModule, FactorydriveService } from '@tacxou/nestjs_module_factorydrive'\nimport { AwsS3Storage } from './aws-s3.storage'\n\n@Module({\n  imports: [\n    FactorydriveModule.forRoot({\n      default: 's3',\n      disks: {\n        s3: {\n          driver: 's3',\n          config: {\n            bucket: 'example',\n          },\n        },\n      },\n    }),\n  ],\n})\nexport class AppModule implements OnModuleInit {\n  public constructor(private readonly factorydrive: FactorydriveService) {}\n\n  public onModuleInit(): void {\n    this.factorydrive.registerDriver('s3', AwsS3Storage)\n  }\n}\n```\n\n## Exported API\n\nMain exports from this package:\n\n- `FactorydriveModule`\n- `FactorydriveService`\n- `AbstractStorage`\n- `StorageManager`\n- storage config/types from `factorydrive/types`\n- exceptions from `exceptions`\n\n## Error Handling\n\nThe module provides dedicated exceptions (for example):\n- `InvalidConfigException`\n- `DriverNotSupportedException`\n- `FileNotFoundException`\n- `PermissionMissingException`\n- `MethodNotSupportedException`\n\nCatch and map them in your service/controller layers as needed.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftacxou%2Fnestjs_module_factorydrive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftacxou%2Fnestjs_module_factorydrive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftacxou%2Fnestjs_module_factorydrive/lists"}