https://github.com/compulim/azure-storage-fs
A drop-in "fs" replacement for accessing Azure Storage with Node.js "fs" API
https://github.com/compulim/azure-storage-fs
Last synced: about 1 month ago
JSON representation
A drop-in "fs" replacement for accessing Azure Storage with Node.js "fs" API
- Host: GitHub
- URL: https://github.com/compulim/azure-storage-fs
- Owner: compulim
- License: mit
- Created: 2016-08-10T21:14:18.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2020-07-09T20:10:05.000Z (almost 5 years ago)
- Last Synced: 2025-03-24T16:03:14.023Z (about 2 months ago)
- Language: JavaScript
- Homepage:
- Size: 165 KB
- Stars: 10
- Watchers: 2
- Forks: 7
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
azure-storage-fs
================[](https://badge.fury.io/js/azure-storage-fs) [](https://travis-ci.org/compulim/azure-storage-fs) [](https://david-dm.org/compulim/azure-storage-fs) [](https://img.shields.io/npm/dm/azure-storage-fs.svg)
A drop-in "fs" replacement for accessing Azure Storage with Node.js "fs" API.
This package is designed to support [ftpd](https://www.npmjs.com/package/ftpd).
## How to use
`azure-storage-fs` is designed to replace Node.js "fs" package and integrate with [`ftpd`](https://www.npmjs.com/package/ftpd) package.
### Replace Node.js "fs" package
```js
const fs = require('azure-storage-fs').blob(accountName, secret, container);fs.readFile('helloworld.txt', (err, data) => {
console.log(err || data);
});
```#### Go advanced mode
If you want to bring your own `BlobService` and prefer a Promise interface like [`mz/fs`](https://npmjs.com/packages/mz).
```js
const { createBlobService } = require('azure-storage');
const fs = require('azure-storage-fs').blob(createBlobService(), container).promise;
const data = await fs.readFile('helloworld.txt');console.log(data);
```### Integration with ftpd
[`ftpd`](https://www.npmjs.com/package/ftpd) supports custom "fs" implementation and `azure-storage-fs` is designed to be a "fs" provider for `ftpd`.
To use a custom "fs" implementation, in your `ftpd` authorization code (`command:pass` event), add `require('azure-storage-fs').blob(accountName, secret, container)` to the `success` callback. For example,
```js
connection.on('command:pass', (password, success, failure) => {
if (auth(username, password)) {
success(username, require('azure-storage-fs').blob(accountName, secret, container));
} else {
failure();
}
});
```#### Some ideas for ftpd
* Use different container for each user
* Username/password can be stored as container metadata, always salt and hash the password
* Trigger webhook when a file is uploaded to FTP#### Some caveats for ftpd
* Azure Storage is eventually consistent, changes may not happen right away
* After uploaded a file, it may not appear in the file list immediately
* When listing files, `ftpd` will call `fs.readdir()` first, then `fs.stat()` for every file
* Listing a folder with 10 files will result in 11 requests to Azure
* Calling `fs.stat()` on a directory will result in 2 calls to Azure## Supported APIs
### Path normalization
Paths will be normalized with the following rules:
1. Turn backslashes (Windows style) into slashes, then
2. Remove leading slashesFor example, `\Users\Documents\HelloWorld.txt` will become `Users/Documents/HelloWorld.txt`.
### Blob service
Since Blob service is flat natively, it does not support directory tree. It use delimiter `/` to provides a hierarchical view of its flat structure. A hidden empty blob named `$$$.$$$` is used to represent empty directory.
Only block blob is supported and is the default blob type when creating a new blob.
* `createReadStream`
* Only default options are supported
* `encoding` is not supported
* New `snapshot` options for specifying ID of the snapshot to read
* `createWriteStream`
* Only default options are supported
* Append is not supported
* `encoding` is not supported
* New `metadata` option to specify blob metadata
* `mkdir`
* Throw `EEXIST` if the directory already exists
* Will create a hidden blob under the new folder, named `$$$.$$$`
* `open`
* Supported mode: `r`, `w`, and `wx`
* Only default options are supported
* New `snapshot` options for specifying ID of the snapshot to open
* `readdir`
* `readFile`
* Implemented using `createReadStream`
* Only default options are supported
* `encoding` is not supported
* New `snapshot` options for specifying ID of the snapshot to read
* `rename`
* Implemented as copy-and-delete
* Because rename is not natively supported, snapshots will be lost after rename
* Metadata will be retained
* `rmdir`
* Will delete hidden blob `$$$.$$$` if exists
* Checks if the directory is emptied, throw `ENOTEMPTY` if not
* `sas(path, options)` (New)
* Will create a Shared Access Signature token for a blob synchronously
* Options can be passed
* `flag` (optional)
* [Permission level](https://msdn.microsoft.com/library/dn140255.aspx) of the blob: `r`, `a`, `c`, `w`, `d`
* `start` (optional)
* Start time of the token
* `expiry` (optional)
* Expiry time of the token
* `setMetadata(metadata, options)` (New)
* Will modify metadata on existing blob
* Options can be passed
* `snapshot` (optional)
* The snapshot ID to modify the metadata on
* `snapshot(path, options)` (New)
* Will create a new snapshot based on existing blob
* Will return the new snapshot ID
* Options can be passed
* `snapshot` (optional)
* The snapshot ID to base the new snapshot on
* `stat(path, options)`
* Only report the following properties
* `isDirectory()`
* `mode` always equals to `R_OK | W_OK`
* `mtime`
* `size`
* `0` for directory
* New `url` for the actual URL (not support Shared Access Signature yet)
* Options can be passed as the second argument
* `metadata` (default set to `false`)
* When set to `true`, the call will also return metadata
* When paired with `snapshot` options, the call will also return metadata for snapshots
* `snapshot` (default set to `false`)
* When set to `true`, the call will also return an array named `snapshots`, each with the following properties
* `id` is the snapshot ID
* `mtime`
* `size`
* `url`
* When set to a string, the call will target the specified snapshot ID
* Otherwise, will target the default (i.e. most recent) blob
* `unlink(pathname, options)`
* Options can be passed as the second argument
* `snapshot` (default set to `true`)
* `true` will delete all snapshots associated with the blob
* Otherwise, it will be treated as a string to specify the ID of the snapshot to delete
* `writeFile`
* Implemented using `createWriteStream`
* Only default options are supported
* Append is not supported
* `encoding` is not supported
* New `metadata` option to specify blob metadata#### Snapshot
Snapshot is supported and snapshot ID can be specified for most read APIs. `stat` can also set to return snapshot information. By default this is disabled to save transaction cost.
### File service
In future, we plan to support Azure Storage File, which is another file storage service accessible thru HTTP interface and SMB on Azure.
## Contributions
Like us? [Star](https://github.com/compulim/azure-storage-fs/stargazers) us.
Doesn't work as expected? File us an [issue](https://github.com/compulim/azure-storage-fs/issues) with minimal code for bug repro.