asset-pipe-sink-fs
Advanced tools
Comparing version 1.0.0-alpha.5 to 1.0.0-beta.1
@@ -9,52 +9,73 @@ 'use strict'; | ||
const fs = require('fs'); | ||
const os = require('os'); | ||
const SinkFs = module.exports = function (fileDir) { | ||
if (!(this instanceof SinkFs)) { return new SinkFs(fileDir); } | ||
assert(fileDir, '"fileDir" must be provided'); | ||
class WriteStream extends stream.PassThrough { | ||
constructor (options = {}, type) { | ||
super(); | ||
this.fileDir = fileDir; | ||
}; | ||
const temp = path.join(os.tmpdir(), common.createTemporaryFilename(type)); | ||
const hasher = (type === 'json') ? new common.SourceHasher() : new common.FileHasher(); | ||
const parser = (type === 'json') ? JSONStream.parse('*') : new stream.PassThrough(); | ||
const fileStream = fs.createWriteStream(temp); | ||
fileStream.on('finish', () => { | ||
const id = hasher.hash; | ||
const file = `${id}.${type}`; | ||
fs.rename(temp, path.join(options.path, file), (error) => { | ||
if (error) { | ||
return this.emit('file not saved'); | ||
} | ||
this.emit('file saved', id, file); | ||
}); | ||
}); | ||
SinkFs.prototype.writer = function (fileType, callback) { | ||
const temp = path.join(this.fileDir, common.createTemporaryFilename(fileType)); | ||
const hasher = (fileType === 'json') ? new common.SourceHasher() : new common.FileHasher(); | ||
const parser = (fileType === 'json') ? JSONStream.parse('*') : new stream.PassThrough(); | ||
const proxy = new stream.PassThrough(); | ||
hasher.on('error', (error) => { | ||
this.emit('error', error); | ||
}); | ||
parser.on('error', (error) => { | ||
this.emit('error', error); | ||
}); | ||
const file = fs.createWriteStream(temp); | ||
file.on('finish', () => { | ||
const id = hasher.hash; | ||
const fileName = `${id}.${fileType}`; | ||
fs.rename(temp, path.join(this.fileDir, fileName), () => { | ||
if (callback) { | ||
callback(id, fileName); | ||
} | ||
fileStream.on('error', (error) => { | ||
this.emit('error', error); | ||
}); | ||
}); | ||
file.on('error', (error) => { | ||
console.log(error); | ||
}); | ||
this.pipe(parser).pipe(hasher); | ||
this.pipe(fileStream); | ||
} | ||
} | ||
proxy.pipe(parser).pipe(hasher); | ||
proxy.pipe(file); | ||
return proxy; | ||
}; | ||
class ReadStream extends fs.createReadStream { | ||
constructor (...args) { | ||
super(...args); | ||
this.on('open', () => { | ||
this.emit('file found'); | ||
}); | ||
this.on('error', (error) => { | ||
if (error.code === 'ENOENT') { | ||
this.emit('file not found'); | ||
} | ||
}); | ||
} | ||
} | ||
SinkFs.prototype.reader = function (fileName, callback) { | ||
const from = this.fileDir + fileName; | ||
const file = fs.createReadStream(from); | ||
module.exports = class SinkFs { | ||
constructor (options = {}) { | ||
assert(options.path, '"options.path" is missing'); | ||
this.options = Object.assign({}, options); | ||
} | ||
file.on('finish', () => { | ||
if (callback) { | ||
callback(); | ||
} | ||
}); | ||
writer (type) { | ||
assert(type, '"type" is missing'); | ||
return new WriteStream(this.options, type); | ||
} | ||
return file; | ||
reader (file) { | ||
assert(file, '"file" is missing'); | ||
return new ReadStream(path.join(this.options.path, file)); | ||
} | ||
}; |
{ | ||
"name": "asset-pipe-sink-fs", | ||
"version": "1.0.0-alpha.5", | ||
"version": "1.0.0-beta.1", | ||
"author": { | ||
@@ -28,14 +28,14 @@ "name": "Trygve Lie", | ||
"dependencies": { | ||
"JSONStream": "1.2.1", | ||
"asset-pipe-common": "1.0.0-alpha.4", | ||
"readable-stream": "2.2.2" | ||
"JSONStream": "1.3.1", | ||
"asset-pipe-common": "1.0.0-beta.2", | ||
"readable-stream": "2.2.6" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^3.15.0", | ||
"eslint": "^3.19.0", | ||
"eslint-config-finn": "^1.0.1", | ||
"tap": "10.0.2" | ||
"tap": "10.3.1" | ||
}, | ||
"scripts": { | ||
"lint": "eslint .", | ||
"test": "tap test/*.js" | ||
"test": "tap --jobs=4 test/*.js" | ||
}, | ||
@@ -42,0 +42,0 @@ "files": [ |
117
README.md
# asset-pipe-sink-fs | ||
A [asset-pipe][asset-pipe] sink for writing to and reading from local file system. | ||
The intention of the [asset-pipe][asset-pipe] sink modules is to use be able to write and read files | ||
to different backends by just swapping modules. By each sink implementing the same public API it is | ||
possible to ex use this module in one environment and another sink module in another environment. | ||
These sinks are normally used by the [asset-pipe-build-server][asset-pipe-build-server]. | ||
## Installation | ||
```bash | ||
$ npm install asset-pipe-sink-fs | ||
``` | ||
## Example | ||
Read an asset feed from disc and serve it on http: | ||
```js | ||
const express = require('express'); | ||
const Sink = require('asset-pipe-sink-fs'); | ||
const app = express(); | ||
const sink = new Sink({ | ||
path: './feeds/', | ||
}); | ||
app.get('/', (req, res, next) => { | ||
const file = sink.reader('feed.json'); | ||
file.on('file not found', () => { | ||
res.status(404).send('File not found'); | ||
}); | ||
file.on('file found', () => { | ||
res.status(200); | ||
file.pipe(res); | ||
}); | ||
}); | ||
app.listen(8000); | ||
``` | ||
## API | ||
This module have the following API: | ||
### constructor(options) | ||
Supported arguments are: | ||
- `options.path` - String - path to where files whould be / are persisted. | ||
### writer(type) | ||
Method for writing a file to disc. Returns a write stream. | ||
Supported arguments are: | ||
- `type` - String - File type of the file to write. Used as extension of the persisted file. - Required | ||
Events: | ||
- `file saved` - When a file have been sucessfully persisted. | ||
- `file not saved` - When a file could not be persisted. | ||
- `error` - When an error occured during persistence. | ||
### reader(file) | ||
Method for reading a file from disc. Returns a read stream. | ||
Supported arguments are: | ||
- `file` - String - File name of the file to read. - Required | ||
Events: | ||
- `file found` - When the file we want to read is found. | ||
- `file not saved` - When the file we want to read is not found. | ||
## License | ||
The MIT License (MIT) | ||
Copyright (c) 2017 - Trygve Lie - post@trygve-lie.com | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
[asset-pipe]: https://github.com/asset-pipe | ||
[asset-pipe-build-server]: https://github.com/asset-pipe/asset-pipe-build-server |
6356
65
119
+ AddedJSONStream@1.3.1(transitive)
+ Addedasset-pipe-common@1.0.0-beta.2(transitive)
+ Addedreadable-stream@2.2.6(transitive)
- RemovedJSONStream@1.2.1(transitive)
- Removedasset-pipe-common@1.0.0-alpha.4(transitive)
- Removedreadable-stream@2.2.2(transitive)
UpdatedJSONStream@1.3.1
Updatedreadable-stream@2.2.6