{"id":13588754,"url":"https://github.com/Slynova-Org/flydrive","last_synced_at":"2025-04-08T06:32:40.244Z","repository":{"id":44007851,"uuid":"71902592","full_name":"Slynova-Org/flydrive","owner":"Slynova-Org","description":"☁️ Flexible and Fluent framework-agnostic driver based system to manage storage in Node.js","archived":true,"fork":false,"pushed_at":"2021-11-01T04:08:29.000Z","size":758,"stargazers_count":408,"open_issues_count":14,"forks_count":55,"subscribers_count":7,"default_branch":"develop","last_synced_at":"2024-10-18T08:42:19.824Z","etag":null,"topics":["digital-ocean-spaces","driver","filesystem","framework-agnostic","google-cloud-storage","nodejs","s3","storage"],"latest_commit_sha":null,"homepage":"","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/Slynova-Org.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-25T14:00:07.000Z","updated_at":"2024-10-03T12:43:58.000Z","dependencies_parsed_at":"2022-07-09T14:46:24.429Z","dependency_job_id":null,"html_url":"https://github.com/Slynova-Org/flydrive","commit_stats":null,"previous_names":["slynova-org/node-flydrive"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slynova-Org%2Fflydrive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slynova-Org%2Fflydrive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slynova-Org%2Fflydrive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Slynova-Org%2Fflydrive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Slynova-Org","download_url":"https://codeload.github.com/Slynova-Org/flydrive/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247721898,"owners_count":20985084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["digital-ocean-spaces","driver","filesystem","framework-agnostic","google-cloud-storage","nodejs","s3","storage"],"created_at":"2024-08-01T15:06:54.279Z","updated_at":"2025-04-08T06:32:36.031Z","avatar_url":"https://github.com/Slynova-Org.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"https://user-images.githubusercontent.com/2793951/54391096-418f4500-46a4-11e9-8d0c-b00ff7ba4198.png\" alt=\"flydrive\"\u003e\r\n\u003c/p\u003e\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003ca href=\"https://www.npmjs.com/package/@slynova/flydrive\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/@slynova/flydrive.svg?style=flat-square\" alt=\"Download\"\u003e\u003c/a\u003e\r\n  \u003ca href=\"https://www.npmjs.com/package/@slynova/flydrive\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@slynova/flydrive.svg?style=flat-square\" alt=\"Version\"\u003e\u003c/a\u003e\r\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/@slynova/flydrive.svg?style=flat-square\" alt=\"License\"\u003e\u003c/a\u003e\r\n\u003c/p\u003e\r\n\r\n`flydrive` is a framework-agnostic package which provides a powerful wrapper to manage file Storage in [Node.js](https://nodejs.org).\r\n\r\nThere are currently 3 drivers available:\r\n\r\n- `'local'`: Stores files on the local file system.\r\n- `'s3'`: Amazon S3 and other compatible services\r\n  - You need to install the `@slynova/flydrive-s3` package to be able to use this driver.\r\n  - This driver is compatible with DigitalOcean Spaces and Scaleway Object Storage.\r\n- `'gcs'`: Google Cloud Storage\r\n  - You need to install the `@slynova/flydrive-gcs` package to be able to use this driver.\r\n\r\n---\r\n\r\n## Getting Started\r\n\r\nThis package is available in the npm registry.\r\nIt can easily be installed with `npm` or `yarn`.\r\n\r\n```bash\r\n$ npm i @slynova/flydrive\r\n# or\r\n$ yarn add @slynova/flydrive\r\n```\r\n\r\nWhen you require the package in your file, it will give you access to the `StorageManager` class.\r\nThis class is a facade for the package and should be instantiated with a [configuration object](https://github.com/Slynova-Org/flydrive/blob/develop/examples/config.ts).\r\n\r\n```javascript\r\nconst { StorageManager } = require('@slynova/flydrive');\r\nconst storage = new StorageManager(...);\r\n```\r\n\r\nOnce you instantiated the manager, you can use the `StorageManager#disk()` method to retrieve a disk an use it.\r\n\r\n```javascript\r\nstorage.disk(); // Returns the default disk (specified in the config)\r\nstorage.disk('awsCloud'); // Returns the driver for the disk \"s3\"\r\nstorage.disk('awsCloud', customConfig); // Overwrite the default configuration of the disk\r\n```\r\n\r\n## Registering External Driver\r\n\r\nAfter installing any external driver, like `@slynova/flydrive-gcs`, you need to register it inside our manager to be able to use it.\r\n\r\nThe following is done by using the method `storage.registerDriver(name: string, Driver)`.\r\n\r\n```ts\r\nconst { GoogleCloudStorage } = require('@slynova/flydrive-gcs');\r\nconst { StorageManager } = require('@slynova/flydrive');\r\nconst storage = new StorageManager(...);\r\n\r\nstorage.registerDriver('gcs', GoogleCloudStorage);\r\n```\r\n\r\n## Driver's API\r\n\r\nEach driver extends the abstract class [`Storage`](https://github.com/Slynova-Org/flydrive/blob/develop/packages/flydrive/src/Storage.ts). This class will throw an exception for each methods by default. The driver needs to overwrite the methods it supports.\r\n\r\nThe following method doesn't exist on the `LocalFileSystemStorage` driver, therefore, it will throw an exception.\r\n\r\n```javascript\r\n// throws \"E_METHOD_NOT_SUPPORTED: Method getSignedUrl is not supported for the driver LocalFileSystemStorage\"\r\nstorage.disk('local').getSignedUrl();\r\n```\r\n\r\nSince we are using TypeScript, you can make use of casting to get the real interface:\r\n\r\n```typescript\r\nimport { LocalFileSystemStorage } from '@slynova/flydrive';\r\n\r\nstorage.disk\u003cLocalFileSystemStorage\u003e('local');\r\n```\r\n\r\n### Response interface\r\n\r\nAsynchronous methods will always return a Promise which resolves with a `Response`\r\nobject. The response object may contain relevant data in its properties (for\r\nexample, the `ExistsResponse` object for the `exists` method contains a boolean\r\n`exists` property).\r\n\r\nAll responses additionally have a `raw` property which is driver-specific and\r\ncontains the result from the original call made by the driver.\r\n\r\n### Exceptions\r\n\r\nIn case of runtime errors, `flydrive` will try to throw driver-agnostic exceptions.\r\nExceptions also have a `raw` property which contains the original error.\r\n\r\n### Methods\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003eappend(location: string, content: Buffer | Stream | string, options: object): Promise\u0026lt;Response\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will append the content to the file at the location.\r\nIf the file doesn't exist yet, it will be created.\r\n\r\n```javascript\r\n// Supported drivers: \"local\"\r\n\r\nawait storage.disk('local').append('foo.txt', 'bar');\r\n// foo.txt now has the content `${initialContent}bar`\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003ecopy(src: string, dest: string, options: object): Promise\u0026lt;Response\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will copy a file to another location.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nawait storage.disk('local').copy('foo.txt', 'bar.txt');\r\n// foo.txt was copied to bar.txt\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003edelete(location: string): Promise\u0026lt;DeleteResponse\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will delete the file at the given location.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nconst { wasDeleted } = await storage.disk('local').delete('foo.txt');\r\n// If a file named foo.txt has been deleted, wasDeleted is true.\r\n```\r\n\r\nThe value returned by this method will have a `wasDeleted` property that\r\ncan be either a boolean (`true` if a file was deleted, `false` if there was\r\nno file to delete) or `null` (if no information about the file is available).\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003edriver()\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method returns the driver used if you need to do anything specific not supported by default.\r\n\r\n```javascript\r\nstorage.disk('local').driver(); // Returns the \"fs-extra\" module.\r\nstorage.disk('awsCloud').driver(); // Returns an instance of the AWS S3 client.\r\nstorage.disk('googleCloud').driver(); // Returns an instance of the the Google Cloud Storage client.\r\n// ....\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003eexists(location: string): Promise\u0026lt;ExistsResponse\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will determine if a file exists at the given location.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nconst { exists } = await storage.disk('local').exists('foo.txt');\r\n// exists is true or false\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003eget(location: string, encoding: string = 'utf-8'): Promise\u0026lt;ContentResponse\u0026lt;string\u0026gt;\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will return the file's content as a string for the given location.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nconst { content } = await storage.disk('local').get('foo.txt');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003egetBuffer(location: string): Promise\u0026lt;ContentResponse\u0026lt;Buffer\u0026gt;\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will return the file's content as a Buffer for the given location.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nconst buffer = await storage.disk('local').getBuffer('foo.txt');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003egetSignedUrl(location: string, options: SignedUrlOptions = { expiry: 900 }): Promise\u0026lt;SignedUrlResponse\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will return the signed url for an existing file.\r\n\r\n```javascript\r\n// Supported drivers: \"s3\", \"gcs\"\r\n\r\nconst { signedUrl } = await storage.disk('awsCloud').getSignedUrl('foo.txt');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003egetStat(location: string): Promise\u0026lt;StatResponse\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will return the file's size (in bytes) and last modification date.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nconst { size, modified } = await storage.disk('local').getStat('foo.txt');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003egetStream(location: string, options: object | string): Stream\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will return a Node.js readable stream for the given file.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nconst stream = storage.disk('local').getStream('foo.txt');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003egetUrl(location: string): string\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will return a public URL for a given file.\r\n\r\n```javascript\r\n// Supported drivers: \"s3\", \"gcs\"\r\n\r\nconst uri = storage.disk('awsCloud').getUrl('foo.txt');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003emove(src: string, dest: string): Promise\u0026lt;Response\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will move the file to a new location.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nawait storage.disk('local').move('foo.txt', 'newFolder/foo.txt');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003eput(location: string, content: Buffer | Stream | string, options: object): Promise\u0026lt;Response\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will create a new file with the provided content.\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nawait storage.disk('local').put('bar.txt', 'Foobar');\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003eprepend(location: string, content: Buffer | string, options: object): Promise\u0026lt;Response\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will prepend content to a file.\r\n\r\n```javascript\r\n// Supported drivers: \"local\"\r\n\r\nawait storage.disk('local').prepend('foo.txt', 'bar');\r\n// foo.txt now has the content `bar${initialContent}`\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n\u003cdetails\u003e\r\n\u003csummary markdown=\"span\"\u003e\u003ccode\u003eflatList(prefix?: string): AsyncIterable\u0026lt;FileListResponse\u0026gt;\u003c/code\u003e\u003c/summary\u003e\r\n\r\nThis method will return an async iterator over all file names that start with `prefix` (recursive).\r\n\r\n```javascript\r\n// Supported drivers: \"local\", \"s3\", \"gcs\"\r\n\r\nconst disk = storage.disk('local');\r\nfor await (const file of disk.flatList('a/b')) {\r\n  console.log(file.path);\r\n}\r\n```\r\n\r\n\u003c/details\u003e\r\n\r\n## Contribution Guidelines\r\n\r\nAny pull requests or discussions are welcome.\r\nNote that every pull request providing new feature or correcting a bug should be created with appropriate unit tests.\r\n","funding_links":[],"categories":["TypeScript","Packages"],"sub_categories":["Others"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSlynova-Org%2Fflydrive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSlynova-Org%2Fflydrive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSlynova-Org%2Fflydrive/lists"}