diff --git a/README.md b/README.md index c5c0cf3..cad1970 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ Aseteroid Storage Service The `asteroid-storage-service` service is designed to make it easy to upload and download files to various infrastructure providers. **_Special attention has been paid so that methods are streams and pipe-capable._** -To get started with a `asteroid-storage-service` client just create one: +To get started with a `asteroid-storage-service` provider just create one: ``` js - var client = require('asteroid-storage-service').createClient({ + var storageService = require('asteroid-storage-service')({ // // The name of the provider (e.g. "file") // @@ -33,18 +33,18 @@ Each instance of `storage.Client` returned from `storage.createClient` has a set ### Container -* `client.getContainers(function (err, containers) { })` -* `client.createContainer(options, function (err, container) { })` -* `client.destroyContainer(containerName, function (err) { })` -* `client.getContainer(containerName, function (err, container) { })` +* `storageService.getContainers(function (err, containers) { })` +* `storageService.createContainer(options, function (err, container) { })` +* `storageService.destroyContainer(containerName, function (err) { })` +* `storageService.getContainer(containerName, function (err, container) { })` ### File -* `client.upload(options, function (err) { })` -* `client.download(options, function (err) { })` -* `client.getFiles(container, function (err, files) { })` -* `client.getFile(container, file, function (err, server) { })` -* `client.removeFile(container, file, function (err) { })` +* `storageService.upload(options, function (err) { })` +* `storageService.download(options, function (err) { })` +* `storageService.getFiles(container, function (err, files) { })` +* `storageService.getFile(container, file, function (err, server) { })` +* `storageService.removeFile(container, file, function (err) { })` Both the `.upload(options)` and `.download(options)` have had **careful attention paid to make sure they are pipe and stream capable:** @@ -53,12 +53,9 @@ Both the `.upload(options)` and `.download(options)` have had **careful attentio var storage = require('asteroid-storage-service'), fs = require('fs'); - var client = storage.createClient({ /* ... */ }); + var storageService = storage({ /* ... */ }); - fs.createReadStream('a-file.txt').pipe(client.upload({ - container: 'a-container', - remote: 'remote-file-name.txt' - })); + fs.createReadStream('a-file.txt').pipe(storageService.uploadStream('a-container','remote-file-name.txt')); ``` ### Download a File @@ -66,9 +63,9 @@ Both the `.upload(options)` and `.download(options)` have had **careful attentio var storage = require('asteroid-storage-service'), fs = require('fs'); - var client = storage.createClient({ /* ... */ }); + var storageService = storage({ /* ... */ }); - client.download({ + storageService.downloadStream({ container: 'a-container', remote: 'remote-file-name.txt' }).pipe(fs.createWriteStream('a-file.txt')); diff --git a/example/app-asteroid.js b/example/app-asteroid.js new file mode 100644 index 0000000..78e1bb5 --- /dev/null +++ b/example/app-asteroid.js @@ -0,0 +1,73 @@ +var asteroid = require('asteroid') + , app = module.exports = asteroid(); + +var StorageService = require('../'); + +// expose a rest api +app.use(asteroid.rest()); + +app.configure(function () { + app.set('port', process.env.PORT || 3000); +}); + +var handler = new StorageService({provider: 'filesystem', root: '/tmp/storage'}); + +app.service('storage', handler); + +app.get('/', function (req, res, next) { + res.setHeader('Content-Type', 'text/html'); + var form = "

Storage Service Demo

" + + "List all containers

" + + "Upload to container c1:

" + + "

" + + "File to upload:
" + + "Notes about the file:
" + + "
" + + ""; + res.send(form); + res.end(); +}); + +app.post('/upload/:container', function (req, res, next) { + handler.upload(req, res, function (err, result) { + if (!err) { + res.setHeader('Content-Type', 'application/json'); + res.send(200, result); + } else { + res.send(500, err); + } + }); +}); + +app.get('/download', function (req, res, next) { + handler.getContainers(function (err, containers) { + var html = "

Containers

Home

"; + res.send(200, html); + }); +}); + +app.get('/download/:container', function (req, res, next) { + handler.getFiles(req.params.container, function (err, files) { + var html = "

Files in container " + req.params.container + "

Home

"; + res.send(200, html); + }); +}); + +app.get('/download/:container/:file', function (req, res, next) { + handler.download(req, res, function (err, result) { + if (err) { + res.send(500, err); + } + }); +}); + +app.listen(app.get('port')); +console.log('http://127.0.0.1:' + app.get('port')); diff --git a/lib/index.js b/lib/index.js index 22caa57..47ebfb7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -42,8 +42,8 @@ StorageService.prototype.uploadStream = function (container, file, options, cb) options = {}; } options = options || {}; - options.container = container; - options.remote = file; + if(container) options.container = container; + if(file) options.remote = file; return this.provider.upload(options, cb); } @@ -54,8 +54,8 @@ StorageService.prototype.downloadStream = function (container, file, options, cb options = {}; } options = options || {}; - options.container = container; - options.remote = file; + if(container) options.container = container; + if(file) options.remote = file; return this.provider.download(options, cb); } @@ -78,4 +78,69 @@ StorageService.prototype.upload = function (req, res, cb) { StorageService.prototype.download = function (req, res, cb) { return handler.download(this.provider, req, res, cb); -} \ No newline at end of file +} + +StorageService.modelName = 'storage'; + +StorageService.prototype.getContainers.shared = true; +StorageService.prototype.getContainers.accepts = []; +StorageService.prototype.getContainers.returns = {arg: 'containers', type: 'array'}; +StorageService.prototype.getContainers.http = [ + {verb: 'get', path: '/'} +]; + +StorageService.prototype.getContainer.shared = true; +StorageService.prototype.getContainer.accepts = [{arg: 'container', type: 'string'}]; +StorageService.prototype.getContainer.returns = {arg: 'container', type: 'object'}; +StorageService.prototype.getContainer.http = [ + {verb: 'get', path: '/:container'} +]; + +StorageService.prototype.createContainer.shared = true; +StorageService.prototype.createContainer.accepts = [{arg: 'options', type: 'object'}]; +StorageService.prototype.createContainer.returns = {arg: 'container', type: 'object'}; +StorageService.prototype.createContainer.http = [ + {verb: 'post', path: '/'} +]; + +StorageService.prototype.destroyContainer.shared = true; +StorageService.prototype.destroyContainer.accepts = [{arg: 'container', type: 'string'}]; +StorageService.prototype.destroyContainer.returns = {}; +StorageService.prototype.destroyContainer.http = [ + {verb: 'delete', path: '/:container'} +]; + +StorageService.prototype.getFiles.shared = true; +StorageService.prototype.getFiles.accepts = [{arg: 'container', type: 'string'}]; +StorageService.prototype.getFiles.returns = {arg: 'files', type: 'array'}; +StorageService.prototype.getFiles.http = [ + {verb: 'get', path: '/:container/files'} +]; + +StorageService.prototype.getFile.shared = true; +StorageService.prototype.getFile.accepts = [{arg: 'container', type: 'string'}, {arg: 'file', type: 'string'}]; +StorageService.prototype.getFile.returns = {arg: 'file', type: 'object'}; +StorageService.prototype.getFile.http = [ + {verb: 'get', path: '/:container/files/:file'} +]; + +StorageService.prototype.removeFile.shared = true; +StorageService.prototype.removeFile.accepts = [{arg: 'container', type: 'string'}, {arg: 'file', type: 'string'}]; +StorageService.prototype.removeFile.returns = {}; +StorageService.prototype.removeFile.http = [ + {verb: 'delete', path: '/:container/files/:file'} +]; + +StorageService.prototype.upload.shared = true; +StorageService.prototype.upload.accepts = [{arg: 'file', type: 'object', 'http': {source: 'req'}}]; +StorageService.prototype.upload.returns = {arg: 'description', type: 'object'}; +StorageService.prototype.upload.http = [ + {verb: 'post', path: '/:container/upload/:file'} +]; + +StorageService.prototype.download.shared = true; +StorageService.prototype.download.accepts = [{arg: 'file', type: 'object', 'http': {source: 'req'}}]; +StorageService.prototype.download.returns = {arg: 'body', type: 'object'}; +StorageService.prototype.download.http = [ + {verb: 'get', path: '/:container/download/:file'} +]; \ No newline at end of file diff --git a/package.json b/package.json index cff7d96..0ede614 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "devDependencies": { "express": "latest", + "asteroid": "git+ssh://git@github.com/strongloop/asteroid.git", "formidable": "latest", "mocha": "latest", "supertest": "latest"