Compare commits
33 Commits
Author | SHA1 | Date |
---|---|---|
|
3b1b432b13 | |
|
11a3caf2d3 | |
|
479800e419 | |
|
3ada3ddf4e | |
|
5668fe31f4 | |
|
c8f3b24141 | |
|
fd1a2527f2 | |
|
d020a178c4 | |
|
6a18af7774 | |
|
fee0855137 | |
|
02569bd3b5 | |
|
60963c4415 | |
|
963f334ee7 | |
|
9205c9f079 | |
|
5608021675 | |
|
351c3e8ebb | |
|
5c10529445 | |
|
6ff4f2b234 | |
|
3516cf642d | |
|
609b63c474 | |
|
d2352bdc4c | |
|
1dc5a4dc81 | |
|
a3c8509adf | |
|
6f8e4284f5 | |
|
d8b7ebcd14 | |
|
4eaec69fce | |
|
30e8ee0a09 | |
|
00092b5129 | |
|
83a28273d4 | |
|
e76d571a8c | |
|
47002dceff | |
|
7b4cf0b236 | |
|
0562cd03d4 |
|
@ -1,37 +0,0 @@
|
||||||
<!--
|
|
||||||
Questions:
|
|
||||||
https://groups.google.com/forum/#!forum/loopbackjs
|
|
||||||
https://gitter.im/strongloop/loopback
|
|
||||||
Immediate support:
|
|
||||||
https://strongloop.com/api-connect-faqs/
|
|
||||||
https://strongloop.com/node-js/subscription-plans/
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Description/Steps to reproduce
|
|
||||||
|
|
||||||
<!--
|
|
||||||
If feature: A description of the feature
|
|
||||||
If bug: Steps to reproduce
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Link to reproduction sandbox
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Link to an app sandbox for reproduction
|
|
||||||
|
|
||||||
Note: Failure to provide a sandbox application for reproduction purposes will result in the issue being closed.
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Expected result
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Also include actual results if bug
|
|
||||||
-->
|
|
||||||
|
|
||||||
# Additional information
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Copy+paste the output of these two commands:
|
|
||||||
node -e 'console.log(process.platform, process.arch, process.versions.node)'
|
|
||||||
npm ls --prod --depth 0 | grep loopback
|
|
||||||
-->
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
labels: bug
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
|
||||||
|
|
||||||
|
HELP US HELP YOU, PLEASE
|
||||||
|
- Do a quick search to avoid duplicate issues
|
||||||
|
- Provide as much information as possible (reproduction sandbox, use case for features, etc.)
|
||||||
|
- Consider using a more suitable venue for questions such as Stack Overflow, Gitter, etc.
|
||||||
|
|
||||||
|
Please fill in the *entire* template below.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Steps to reproduce
|
||||||
|
|
||||||
|
<!-- Describe how to reproduce the issue -->
|
||||||
|
|
||||||
|
## Current Behavior
|
||||||
|
|
||||||
|
<!-- Describe the observed result -->
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
|
||||||
|
<!-- Describe what did you expect instead, what is the desired outcome? -->
|
||||||
|
|
||||||
|
## Link to reproduction sandbox
|
||||||
|
|
||||||
|
<!--
|
||||||
|
See https://loopback.io/doc/en/contrib/Reporting-issues.html#loopback-3x-bugs
|
||||||
|
Note: Failure to provide a sandbox application for reproduction purposes will result in the issue being closed.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Copy+paste the output of these two commands:
|
||||||
|
node -e 'console.log(process.platform, process.arch, process.versions.node)'
|
||||||
|
npm ls --prod --depth 0 | grep loopback
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Related Issues
|
||||||
|
|
||||||
|
<!-- Did you find other bugs that looked similar? -->
|
||||||
|
|
||||||
|
_See [Reporting Issues](http://loopback.io/doc/en/contrib/Reporting-issues.html) for more tips on writing good issues_
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
labels: feature
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Suggestion
|
||||||
|
|
||||||
|
<!-- A summary of what you'd like to see added or changed -->
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
<!--
|
||||||
|
What do you want to use this for?
|
||||||
|
What shortcomings exist with current approaches?
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<!-- Show how this would be used and what the behavior would be -->
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
TBD - will be filled by the team.
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
name: Question
|
||||||
|
about: The issue tracker is not for questions. Please use Stack Overflow or other resources for help.
|
||||||
|
labels: question
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- 🚨 STOP 🚨 STOP 🚨 STOP 🚨
|
||||||
|
|
||||||
|
THE ISSUE TRACKER IS NOT FOR QUESTIONS.
|
||||||
|
|
||||||
|
DO NOT CREATE A NEW ISSUE TO ASK A QUESTION.
|
||||||
|
|
||||||
|
Please use one of the following resources for help:
|
||||||
|
|
||||||
|
**Questions**
|
||||||
|
|
||||||
|
- https://stackoverflow.com/tags/loopbackjs
|
||||||
|
- https://groups.google.com/forum/#!forum/loopbackjs
|
||||||
|
- https://gitter.im/strongloop/loopback
|
||||||
|
|
||||||
|
**Immediate support**
|
||||||
|
|
||||||
|
- https://strongloop.com/api-connect-faqs/
|
||||||
|
- https://strongloop.com/node-js/subscription-plans/
|
||||||
|
|
||||||
|
-->
|
|
@ -0,0 +1,11 @@
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Report a security vulnerability
|
||||||
|
url: https://loopback.io/doc/en/contrib/Reporting-issues.html#security-issues
|
||||||
|
about: Do not report security vulnerabilities using GitHub issues. Please send an email to `reachsl@us.ibm.com` instead.
|
||||||
|
- name: Get help on StackOverflow
|
||||||
|
url: https://stackoverflow.com/tags/loopbackjs
|
||||||
|
about: Please ask and answer questions on StackOverflow.
|
||||||
|
- name: Join our mailing list
|
||||||
|
url: https://groups.google.com/forum/#!forum/loopbackjs
|
||||||
|
about: You can also post your question to our mailing list.
|
|
@ -1,25 +1,18 @@
|
||||||
### Description
|
|
||||||
|
|
||||||
|
|
||||||
#### Related issues
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Please use the following link syntaxes:
|
Please provide a high-level description of the changes made by your pull request.
|
||||||
|
|
||||||
- connect to #49 (to reference issues in the current repository)
|
Include references to all related GitHub issues and other pull requests, for example:
|
||||||
- connect to strongloop/loopback#49 (to reference issues in another repository)
|
|
||||||
|
Fixes #123
|
||||||
|
Implements #254
|
||||||
|
See also #23
|
||||||
-->
|
-->
|
||||||
|
|
||||||
- connect to <link_to_referenced_issue>
|
## Checklist
|
||||||
|
|
||||||
### Checklist
|
👉 [Read and sign the CLA (Contributor License Agreement)](https://cla.strongloop.com/agreements/strongloop/loopback-component-storage) 👈
|
||||||
|
|
||||||
<!--
|
|
||||||
- Please mark your choice with an "x" (i.e. [x], see
|
|
||||||
https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments)
|
|
||||||
- PR's without test coverage will be closed.
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
- [ ] `npm test` passes on your machine
|
||||||
- [ ] New tests added or existing tests modified to cover all changes
|
- [ ] New tests added or existing tests modified to cover all changes
|
||||||
- [ ] Code conforms with the [style
|
- [ ] Code conforms with the [style guide](https://loopback.io/doc/en/contrib/style-guide-es6.html)
|
||||||
guide](http://loopback.io/doc/en/contrib/style-guide.html)
|
- [ ] Commit messages are following our [guidelines](https://loopback.io/doc/en/contrib/git-commit-messages.html)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "6"
|
|
||||||
- "8"
|
- "8"
|
||||||
- "10"
|
- "10"
|
||||||
|
- "12"
|
||||||
|
|
50
CHANGES.md
50
CHANGES.md
|
@ -1,4 +1,52 @@
|
||||||
2018-07-10, Version 3.5.0
|
2020-03-06, Version 3.7.0
|
||||||
|
=========================
|
||||||
|
|
||||||
|
* Update LTS status in README (Miroslav Bajtoš)
|
||||||
|
|
||||||
|
* chore: update copyright year (Diana Lau)
|
||||||
|
|
||||||
|
* Update README.md (Shaun)
|
||||||
|
|
||||||
|
* chore: improve issue and PR templates (Nora)
|
||||||
|
|
||||||
|
* chore: drop Node.js 6 and add Node.js 12 to travis (Nora)
|
||||||
|
|
||||||
|
|
||||||
|
2019-07-25, Version 3.6.3
|
||||||
|
=========================
|
||||||
|
|
||||||
|
* Rannig from other paths. Property files to array. (Diego A. Zapata Häntsch)
|
||||||
|
|
||||||
|
|
||||||
|
2019-07-12, Version 3.6.2
|
||||||
|
=========================
|
||||||
|
|
||||||
|
* chore: update CODEOWNERS (Diana Lau)
|
||||||
|
|
||||||
|
* Upgrade pkgcloud version (Diego A. Zapata Häntsch)
|
||||||
|
|
||||||
|
|
||||||
|
2019-05-23, Version 3.6.1
|
||||||
|
=========================
|
||||||
|
|
||||||
|
* update pkgcloud and use version 2.x (Anis)
|
||||||
|
|
||||||
|
* chore: update copyrights years (Agnes Lin)
|
||||||
|
|
||||||
|
|
||||||
|
2019-03-28, Version 3.6.0
|
||||||
|
=========================
|
||||||
|
|
||||||
|
* Pass through AWS/S3 specific options (Alex Owen)
|
||||||
|
|
||||||
|
* add support to promise (Matteo Padovano)
|
||||||
|
|
||||||
|
* style: fix linting (virkt25)
|
||||||
|
|
||||||
|
* {download,upload}Stream: removed callback from doc (Youcef Mammar)
|
||||||
|
|
||||||
|
|
||||||
|
2018-07-09, Version 3.5.0
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
* [WebFM] cs/pl/ru translation (candytangnb)
|
* [WebFM] cs/pl/ru translation (candytangnb)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Lines starting with '#' are comments.
|
# Lines starting with '#' are comments.
|
||||||
# Each line is a file pattern followed by one or more owners,
|
# Each line is a file pattern followed by one or more owners,
|
||||||
# the last matching pattern has the most precendence.
|
# the last matching pattern has the most precedence.
|
||||||
|
|
||||||
|
# Alumni members
|
||||||
|
# @kjdelisle @loay @ssh24 @virkt25
|
||||||
|
|
||||||
# Core team members from IBM
|
# Core team members from IBM
|
||||||
* @kjdelisle @jannyHou @loay @b-admike @ssh24 @virkt25 @dhmlau
|
* @jannyHou @b-admike @dhmlau @hacksparrow
|
||||||
|
|
25
README.md
25
README.md
|
@ -1,6 +1,15 @@
|
||||||
# LoopBack Storage Component
|
# LoopBack Storage Component
|
||||||
|
|
||||||
**NOTE: The loopback-component-storage module supersedes [loopback-storage-service](https://www.npmjs.org/package/loopback-storage-service). Please update your package.json accordingly.**
|
**⚠️ LoopBack 3 is in Maintenance LTS mode, only critical bugs and critical
|
||||||
|
security fixes will be provided. (See
|
||||||
|
[Module Long Term Support Policy](#module-long-term-support-policy) below.)**
|
||||||
|
|
||||||
|
We urge all LoopBack 3 users to migrate their applications to LoopBack 4 as
|
||||||
|
soon as possible. Refer to our
|
||||||
|
[Migration Guide](https://loopback.io/doc/en/lb4/migration-overview.html)
|
||||||
|
for more information on how to upgrade.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
LoopBack storage component provides Node.js and REST APIs to manage binary file contents
|
LoopBack storage component provides Node.js and REST APIs to manage binary file contents
|
||||||
using pluggable storage providers, such as local file systems, Amazon S3, or
|
using pluggable storage providers, such as local file systems, Amazon S3, or
|
||||||
|
@ -13,10 +22,22 @@ storage services including:
|
||||||
- Openstack
|
- Openstack
|
||||||
- Rackspace
|
- Rackspace
|
||||||
|
|
||||||
> Please see the [Storage Service Documentaion](http://loopback.io/doc/en/lb3/Storage-component.html).
|
> Please see the [Storage Service Documentation](http://loopback.io/doc/en/lb3/Storage-component.html).
|
||||||
|
|
||||||
For more details on the architecture of the module, please see the introduction section of the [blog post](https://strongloop.com/strongblog/managing-nodejs-loopback-storage-service-provider/).
|
For more details on the architecture of the module, please see the introduction section of the [blog post](https://strongloop.com/strongblog/managing-nodejs-loopback-storage-service-provider/).
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
See https://github.com/strongloop/loopback-example-storage.
|
See https://github.com/strongloop/loopback-example-storage.
|
||||||
|
|
||||||
|
## Module Long Term Support Policy
|
||||||
|
|
||||||
|
This module adopts the [
|
||||||
|
Module Long Term Support (LTS)](http://github.com/CloudNativeJS/ModuleLTS) policy,
|
||||||
|
with the following End Of Life (EOL) dates:
|
||||||
|
|
||||||
|
| Version | Status | Published | EOL |
|
||||||
|
| ------- | --------------- | --------- | -------- |
|
||||||
|
| 3.x | Maintenance LTS | Dec 2016 | Dec 2020 |
|
||||||
|
|
||||||
|
Learn more about our LTS plan in [docs](https://loopback.io/doc/en/contrib/Long-term-support.html).
|
||||||
|
|
3
index.js
3
index.js
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
|
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var SG = require('strong-globalize');
|
var SG = require('strong-globalize');
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2014. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var pkgcloud = require('pkgcloud');
|
var pkgcloud = require('pkgcloud');
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2014. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var base = require('pkgcloud').storage;
|
var base = require('pkgcloud').storage;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2014. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var base = require('pkgcloud').storage;
|
var base = require('pkgcloud').storage;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2015. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Globalization
|
// Globalization
|
||||||
|
@ -18,6 +19,8 @@ var fs = require('fs'),
|
||||||
File = require('./file').File,
|
File = require('./file').File,
|
||||||
Container = require('./container').Container;
|
Container = require('./container').Container;
|
||||||
|
|
||||||
|
var utils = require('./../../utils');
|
||||||
|
|
||||||
module.exports.storage = module.exports; // To make it consistent with pkgcloud
|
module.exports.storage = module.exports; // To make it consistent with pkgcloud
|
||||||
|
|
||||||
module.exports.File = File;
|
module.exports.File = File;
|
||||||
|
@ -29,6 +32,12 @@ module.exports.createClient = function(options) {
|
||||||
|
|
||||||
function FileSystemProvider(options) {
|
function FileSystemProvider(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
|
if (!path.isAbsolute(options.root)) {
|
||||||
|
var basePath = path.dirname(path.dirname(require.main.filename));
|
||||||
|
options.root = path.join(basePath, options.root);
|
||||||
|
}
|
||||||
|
|
||||||
this.root = options.root;
|
this.root = options.root;
|
||||||
var exists = fs.existsSync(this.root);
|
var exists = fs.existsSync(this.root);
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
|
@ -95,10 +104,17 @@ function populateMetadata(stat, props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystemProvider.prototype.getContainers = function(cb) {
|
FileSystemProvider.prototype.getContainers = function(cb) {
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
fs.readdir(self.root, function(err, files) {
|
fs.readdir(self.root, function(err, files) {
|
||||||
var containers = [];
|
var containers = [];
|
||||||
var tasks = [];
|
var tasks = [];
|
||||||
|
|
||||||
|
if (!files) {
|
||||||
|
files = [];
|
||||||
|
}
|
||||||
|
|
||||||
files.forEach(function(f) {
|
files.forEach(function(f) {
|
||||||
tasks.push(fs.stat.bind(fs, path.join(self.root, f)));
|
tasks.push(fs.stat.bind(fs, path.join(self.root, f)));
|
||||||
});
|
});
|
||||||
|
@ -119,15 +135,20 @@ FileSystemProvider.prototype.getContainers = function(cb) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.createContainer = function(options, cb) {
|
FileSystemProvider.prototype.createContainer = function(options, cb) {
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var name = options.name;
|
var name = options.name;
|
||||||
var dir = path.join(this.root, name);
|
var dir = path.join(this.root, name);
|
||||||
validateName(name, cb) && fs.mkdir(dir, options, function(err) {
|
validateName(name, cb) && fs.mkdir(dir, options, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb && cb(err);
|
cb && cb(err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
fs.stat(dir, function(err, stat) {
|
fs.stat(dir, function(err, stat) {
|
||||||
var container = null;
|
var container = null;
|
||||||
|
@ -139,9 +160,13 @@ FileSystemProvider.prototype.createContainer = function(options, cb) {
|
||||||
cb && cb(err, container);
|
cb && cb(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.destroyContainer = function(containerName, cb) {
|
FileSystemProvider.prototype.destroyContainer = function(containerName, cb) {
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
if (!validateName(containerName, cb)) return;
|
if (!validateName(containerName, cb)) return;
|
||||||
|
|
||||||
var dir = path.join(this.root, containerName);
|
var dir = path.join(this.root, containerName);
|
||||||
|
@ -160,9 +185,13 @@ FileSystemProvider.prototype.destroyContainer = function(containerName, cb) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.getContainer = function(containerName, cb) {
|
FileSystemProvider.prototype.getContainer = function(containerName, cb) {
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!validateName(containerName, cb)) return;
|
if (!validateName(containerName, cb)) return;
|
||||||
var dir = path.join(this.root, containerName);
|
var dir = path.join(this.root, containerName);
|
||||||
|
@ -175,6 +204,8 @@ FileSystemProvider.prototype.getContainer = function(containerName, cb) {
|
||||||
}
|
}
|
||||||
cb && cb(err, container);
|
cb && cb(err, container);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
// File related functions
|
// File related functions
|
||||||
|
@ -252,6 +283,9 @@ FileSystemProvider.prototype.getFiles = function(container, options, cb) {
|
||||||
cb = options;
|
cb = options;
|
||||||
options = false;
|
options = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
var dir = path.join(this.root, container);
|
var dir = path.join(this.root, container);
|
||||||
|
@ -278,9 +312,13 @@ FileSystemProvider.prototype.getFiles = function(container, options, cb) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.getFile = function(container, file, cb) {
|
FileSystemProvider.prototype.getFile = function(container, file, cb) {
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
if (!validateName(file, cb)) return;
|
if (!validateName(file, cb)) return;
|
||||||
|
@ -294,6 +332,8 @@ FileSystemProvider.prototype.getFile = function(container, file, cb) {
|
||||||
}
|
}
|
||||||
cb && cb(err, f);
|
cb && cb(err, f);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.getUrl = function(options) {
|
FileSystemProvider.prototype.getUrl = function(options) {
|
||||||
|
@ -303,9 +343,13 @@ FileSystemProvider.prototype.getUrl = function(options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
FileSystemProvider.prototype.removeFile = function(container, file, cb) {
|
FileSystemProvider.prototype.removeFile = function(container, file, cb) {
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
if (!validateName(container, cb)) return;
|
if (!validateName(container, cb)) return;
|
||||||
if (!validateName(file, cb)) return;
|
if (!validateName(file, cb)) return;
|
||||||
|
|
||||||
var filePath = path.join(this.root, container, file);
|
var filePath = path.join(this.root, container, file);
|
||||||
fs.unlink(filePath, cb);
|
fs.unlink(filePath, cb);
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2014. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var StorageService = require('./storage-service');
|
var StorageService = require('./storage-service');
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2015. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Globalization
|
// Globalization
|
||||||
|
@ -52,9 +53,11 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
self._fieldsSize += buffer.length;
|
self._fieldsSize += buffer.length;
|
||||||
if (self._fieldsSize > self.maxFieldsSize) {
|
if (self._fieldsSize > self.maxFieldsSize) {
|
||||||
self._error(new Error(
|
self._error(new Error(
|
||||||
g.f('{{maxFieldsSize}} exceeded, received %s bytes of field data',
|
g.f(
|
||||||
|
'{{maxFieldsSize}} exceeded, received %s bytes of field data',
|
||||||
self._fieldsSize
|
self._fieldsSize
|
||||||
)));
|
)
|
||||||
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value += decoder.write(buffer);
|
value += decoder.write(buffer);
|
||||||
|
@ -104,10 +107,12 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
if (Array.isArray(allowedContentTypes) && allowedContentTypes.length !== 0) {
|
if (Array.isArray(allowedContentTypes) && allowedContentTypes.length !== 0) {
|
||||||
if (allowedContentTypes.indexOf(file.type) === -1) {
|
if (allowedContentTypes.indexOf(file.type) === -1) {
|
||||||
self._error(new Error(
|
self._error(new Error(
|
||||||
g.f('{{contentType}} "%s" is not allowed (Must be in [%s])',
|
g.f(
|
||||||
|
'{{contentType}} "%s" is not allowed (Must be in [%s])',
|
||||||
file.type,
|
file.type,
|
||||||
allowedContentTypes.join(', ')
|
allowedContentTypes.join(', ')
|
||||||
)));
|
)
|
||||||
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,28 +148,21 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
uploadParams.acl = file.acl;
|
uploadParams.acl = file.acl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add AWS specific options
|
// AWS specific options
|
||||||
// See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
|
// See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
|
||||||
if (options.StorageClass) {
|
const awsOptionNames = [
|
||||||
uploadParams.StorageClass = options.StorageClass;
|
'StorageClass',
|
||||||
|
'CacheControl',
|
||||||
|
'ServerSideEncryption',
|
||||||
|
'SSEKMSKeyId',
|
||||||
|
'SSECustomerAlgorithm',
|
||||||
|
'SSECustomerKey',
|
||||||
|
'SSECustomerKeyMD5',
|
||||||
|
];
|
||||||
|
for (const awsOption of awsOptionNames) {
|
||||||
|
if (typeof options[awsOption] !== 'undefined') {
|
||||||
|
uploadParams[awsOption] = options[awsOption];
|
||||||
}
|
}
|
||||||
if (options.CacheControl) {
|
|
||||||
uploadParams.CacheControl = options.CacheControl;
|
|
||||||
}
|
|
||||||
if (options.ServerSideEncryption) {
|
|
||||||
uploadParams.ServerSideEncryption = options.ServerSideEncryption;
|
|
||||||
}
|
|
||||||
if (options.SSEKMSKeyId) {
|
|
||||||
uploadParams.SSEKMSKeyId = options.SSEKMSKeyId;
|
|
||||||
}
|
|
||||||
if (options.SSECustomerAlgorithm) {
|
|
||||||
uploadParams.SSECustomerAlgorithm = options.SSECustomerAlgorithm;
|
|
||||||
}
|
|
||||||
if (options.SSECustomerKey) {
|
|
||||||
uploadParams.SSECustomerKey = options.SSECustomerKey;
|
|
||||||
}
|
|
||||||
if (options.SSECustomerKeyMD5) {
|
|
||||||
uploadParams.SSECustomerKeyMD5 = options.SSECustomerKeyMD5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var writer = provider.upload(uploadParams);
|
var writer = provider.upload(uploadParams);
|
||||||
|
@ -203,10 +201,12 @@ exports.upload = function(provider, req, res, options, cb) {
|
||||||
// - s3-upload-stream doesn't provide a way to do this in it's public interface
|
// - s3-upload-stream doesn't provide a way to do this in it's public interface
|
||||||
// - We could call provider.delete file but it would not delete multipart data
|
// - We could call provider.delete file but it would not delete multipart data
|
||||||
self._error(new Error(
|
self._error(new Error(
|
||||||
g.f('{{maxFileSize}} exceeded, received %s bytes of field data (max is %s)',
|
g.f(
|
||||||
|
'{{maxFileSize}} exceeded, received %s bytes of field data (max is %s)',
|
||||||
fileSize,
|
fileSize,
|
||||||
maxFileSize
|
maxFileSize
|
||||||
)));
|
)
|
||||||
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
|
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var factory = require('./factory');
|
var factory = require('./factory');
|
||||||
var handler = require('./storage-handler');
|
var handler = require('./storage-handler');
|
||||||
|
var utils = require('./utils');
|
||||||
|
|
||||||
var storage = require('pkgcloud').storage;
|
var storage = require('pkgcloud').storage;
|
||||||
var debug = require('debug')('loopback:storage:service');
|
var debug = require('debug')('loopback:storage:service');
|
||||||
|
@ -53,6 +55,22 @@ function StorageService(options) {
|
||||||
if (options.maxFieldsSize) {
|
if (options.maxFieldsSize) {
|
||||||
this.maxFieldsSize = options.maxFieldsSize;
|
this.maxFieldsSize = options.maxFieldsSize;
|
||||||
}
|
}
|
||||||
|
// AWS specific options
|
||||||
|
// See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
|
||||||
|
const awsOptionNames = [
|
||||||
|
'StorageClass',
|
||||||
|
'CacheControl',
|
||||||
|
'ServerSideEncryption',
|
||||||
|
'SSEKMSKeyId',
|
||||||
|
'SSECustomerAlgorithm',
|
||||||
|
'SSECustomerKey',
|
||||||
|
'SSECustomerKeyMD5',
|
||||||
|
];
|
||||||
|
for (const awsOption of awsOptionNames) {
|
||||||
|
if (typeof options[awsOption] !== 'undefined') {
|
||||||
|
this[awsOption] = options[awsOption];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function map(obj) {
|
function map(obj) {
|
||||||
|
@ -64,8 +82,11 @@ function map(obj) {
|
||||||
* @callback {Function} callback Callback function
|
* @callback {Function} callback Callback function
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object[]} containers An array of container metadata objects
|
* @param {Object[]} containers An array of container metadata objects
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getContainers = function(cb) {
|
StorageService.prototype.getContainers = function(cb) {
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
this.client.getContainers(function(err, containers) {
|
this.client.getContainers(function(err, containers) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb(err, containers);
|
cb(err, containers);
|
||||||
|
@ -75,6 +96,8 @@ StorageService.prototype.getContainers = function(cb) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,19 +108,24 @@ StorageService.prototype.getContainers = function(cb) {
|
||||||
* @callback {Function} cb Callback function
|
* @callback {Function} cb Callback function
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object} container Container metadata object
|
* @param {Object} container Container metadata object
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
StorageService.prototype.createContainer = function(options, cb) {
|
StorageService.prototype.createContainer = function(options, cb) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
if ('object' === typeof options && !(options instanceof storage.Container)) {
|
if ('object' === typeof options && !(options instanceof storage.Container)) {
|
||||||
options.Name = options.name; // Amazon expects Name
|
options.Name = options.name; // Amazon expects Name
|
||||||
var Container = factory.getProvider(this.provider).storage.Container;
|
var Container = factory.getProvider(this.provider).storage.Container;
|
||||||
options = new Container(this.client, options);
|
options = new Container(this.client, options);
|
||||||
}
|
}
|
||||||
debug('Creating container with options %o', options);
|
debug('Creating container with options %o', options);
|
||||||
return this.client.createContainer(options, function(err, container) {
|
this.client.createContainer(options, function(err, container) {
|
||||||
return cb(err, map(container));
|
return cb(err, map(container));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,9 +133,13 @@ StorageService.prototype.createContainer = function(options, cb) {
|
||||||
* @param {String} container Container name.
|
* @param {String} container Container name.
|
||||||
* @callback {Function} callback Callback function.
|
* @callback {Function} callback Callback function.
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.destroyContainer = function(container, cb) {
|
StorageService.prototype.destroyContainer = function(container, cb) {
|
||||||
return this.client.destroyContainer(container, cb);
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
|
this.client.destroyContainer(container, cb);
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,15 +148,20 @@ StorageService.prototype.destroyContainer = function(container, cb) {
|
||||||
* @callback {Function} callback Callback function.
|
* @callback {Function} callback Callback function.
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object} container Container metadata object
|
* @param {Object} container Container metadata object
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getContainer = function(container, cb) {
|
StorageService.prototype.getContainer = function(container, cb) {
|
||||||
return this.client.getContainer(container, function(err, container) {
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
|
this.client.getContainer(container, function(err, container) {
|
||||||
if (err && err.code === 'ENOENT') {
|
if (err && err.code === 'ENOENT') {
|
||||||
err.statusCode = err.status = 404;
|
err.statusCode = err.status = 404;
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
return cb(err, map(container));
|
return cb(err, map(container));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,8 +169,6 @@ StorageService.prototype.getContainer = function(container, cb) {
|
||||||
* @param {String} container Container name
|
* @param {String} container Container name
|
||||||
* @param {String} file File name
|
* @param {String} file File name
|
||||||
* @options {Object} [options] Options for uploading
|
* @options {Object} [options] Options for uploading
|
||||||
* @callback callback Callback function
|
|
||||||
* @param {String|Object} err Error string or object
|
|
||||||
* @returns {Stream} Stream for uploading
|
* @returns {Stream} Stream for uploading
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.uploadStream = function(container, file, options) {
|
StorageService.prototype.uploadStream = function(container, file, options) {
|
||||||
|
@ -156,8 +191,6 @@ StorageService.prototype.uploadStream = function(container, file, options) {
|
||||||
* @param {String} container Container name.
|
* @param {String} container Container name.
|
||||||
* @param {String} file File name.
|
* @param {String} file File name.
|
||||||
* @options {Object} options Options for downloading
|
* @options {Object} options Options for downloading
|
||||||
* @callback {Function} callback Callback function
|
|
||||||
* @param {String|Object} err Error string or object
|
|
||||||
* @returns {Stream} Stream for downloading
|
* @returns {Stream} Stream for downloading
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.downloadStream = function(container, file, options) {
|
StorageService.prototype.downloadStream = function(container, file, options) {
|
||||||
|
@ -182,6 +215,7 @@ StorageService.prototype.downloadStream = function(container, file, options) {
|
||||||
* @callback {Function} cb Callback function
|
* @callback {Function} cb Callback function
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object[]} files An array of file metadata objects
|
* @param {Object[]} files An array of file metadata objects
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getFiles = function(container, options, cb) {
|
StorageService.prototype.getFiles = function(container, options, cb) {
|
||||||
if (typeof options === 'function' && !cb) {
|
if (typeof options === 'function' && !cb) {
|
||||||
|
@ -189,7 +223,10 @@ StorageService.prototype.getFiles = function(container, options, cb) {
|
||||||
cb = options;
|
cb = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
return this.client.getFiles(container, options, function(err, files) {
|
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
|
this.client.getFiles(container, options, function(err, files) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb(err, files);
|
cb(err, files);
|
||||||
} else {
|
} else {
|
||||||
|
@ -198,6 +235,8 @@ StorageService.prototype.getFiles = function(container, options, cb) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,15 +246,20 @@ StorageService.prototype.getFiles = function(container, options, cb) {
|
||||||
* @callback {Function} cb Callback function
|
* @callback {Function} cb Callback function
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
* @param {Object} file File metadata object
|
* @param {Object} file File metadata object
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.getFile = function(container, file, cb) {
|
StorageService.prototype.getFile = function(container, file, cb) {
|
||||||
return this.client.getFile(container, file, function(err, f) {
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
|
this.client.getFile(container, file, function(err, f) {
|
||||||
if (err && err.code === 'ENOENT') {
|
if (err && err.code === 'ENOENT') {
|
||||||
err.statusCode = err.status = 404;
|
err.statusCode = err.status = 404;
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
return cb(err, map(f));
|
return cb(err, map(f));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -224,9 +268,13 @@ StorageService.prototype.getFile = function(container, file, cb) {
|
||||||
* @param {String} file File name
|
* @param {String} file File name
|
||||||
* @callback {Function} cb Callback function
|
* @callback {Function} cb Callback function
|
||||||
* @param {Object|String} err Error string or object
|
* @param {Object|String} err Error string or object
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.removeFile = function(container, file, cb) {
|
StorageService.prototype.removeFile = function(container, file, cb) {
|
||||||
return this.client.removeFile(container, file, cb);
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
|
this.client.removeFile(container, file, cb);
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -236,6 +284,7 @@ StorageService.prototype.removeFile = function(container, file, cb) {
|
||||||
* @param {Response} res Response object
|
* @param {Response} res Response object
|
||||||
* @param {Object} [options] Options for upload
|
* @param {Object} [options] Options for upload
|
||||||
* @param {Function} cb Callback function
|
* @param {Function} cb Callback function
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.upload = function(container, req, res, options, cb) {
|
StorageService.prototype.upload = function(container, req, res, options, cb) {
|
||||||
debug('Configuring upload with options %o', options);
|
debug('Configuring upload with options %o', options);
|
||||||
|
@ -251,6 +300,9 @@ StorageService.prototype.upload = function(container, req, res, options, cb) {
|
||||||
cb = options;
|
cb = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
if (this.getFilename && !options.getFilename) {
|
if (this.getFilename && !options.getFilename) {
|
||||||
options.getFilename = this.getFilename;
|
options.getFilename = this.getFilename;
|
||||||
}
|
}
|
||||||
|
@ -269,11 +321,32 @@ StorageService.prototype.upload = function(container, req, res, options, cb) {
|
||||||
if (this.maxFieldsSize && !options.maxFieldsSize) {
|
if (this.maxFieldsSize && !options.maxFieldsSize) {
|
||||||
options.maxFieldsSize = this.maxFieldsSize;
|
options.maxFieldsSize = this.maxFieldsSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AWS specific options
|
||||||
|
// See http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
|
||||||
|
const awsOptionNames = [
|
||||||
|
'StorageClass',
|
||||||
|
'CacheControl',
|
||||||
|
'ServerSideEncryption',
|
||||||
|
'SSEKMSKeyId',
|
||||||
|
'SSECustomerAlgorithm',
|
||||||
|
'SSECustomerKey',
|
||||||
|
'SSECustomerKeyMD5',
|
||||||
|
];
|
||||||
|
for (const awsOption of awsOptionNames) {
|
||||||
|
if (this[awsOption] && !options[awsOption]) {
|
||||||
|
options[awsOption] = this[awsOption];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof container === 'string') {
|
if (typeof container === 'string') {
|
||||||
options.container = container;
|
options.container = container;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug('Upload configured with options %o', options);
|
debug('Upload configured with options %o', options);
|
||||||
return handler.upload(this.client, req, res, options, cb);
|
|
||||||
|
handler.upload(this.client, req, res, options, cb);
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -283,9 +356,13 @@ StorageService.prototype.upload = function(container, req, res, options, cb) {
|
||||||
* @param {Request} req HTTP request
|
* @param {Request} req HTTP request
|
||||||
* @param {Response} res HTTP response
|
* @param {Response} res HTTP response
|
||||||
* @param {Function} cb Callback function
|
* @param {Function} cb Callback function
|
||||||
|
* @promise
|
||||||
*/
|
*/
|
||||||
StorageService.prototype.download = function(container, file, req, res, cb) {
|
StorageService.prototype.download = function(container, file, req, res, cb) {
|
||||||
return handler.download(this.client, req, res, container, file, cb);
|
cb = cb || utils.createPromiseCallback();
|
||||||
|
|
||||||
|
handler.download(this.client, req, res, container, file, cb);
|
||||||
|
return cb.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
StorageService.modelName = 'storage';
|
StorageService.modelName = 'storage';
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright IBM Corp. 2018,2019. All Rights Reserved.
|
||||||
|
// Node module: loopback-component-storage
|
||||||
|
// This file is licensed under the Artistic License 2.0.
|
||||||
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
exports.createPromiseCallback = createPromiseCallback;
|
||||||
|
|
||||||
|
function createPromiseCallback() {
|
||||||
|
var cb;
|
||||||
|
var promise = new Promise(function(resolve, reject) {
|
||||||
|
cb = function(err, data) {
|
||||||
|
if (err) return reject(err);
|
||||||
|
return resolve(data);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
cb.promise = promise;
|
||||||
|
return cb;
|
||||||
|
}
|
15
package.json
15
package.json
|
@ -2,9 +2,9 @@
|
||||||
"name": "loopback-component-storage",
|
"name": "loopback-component-storage",
|
||||||
"description": "Loopback Storage Service",
|
"description": "Loopback Storage Service",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=8"
|
||||||
},
|
},
|
||||||
"version": "3.5.0",
|
"version": "3.7.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
|
@ -15,15 +15,15 @@
|
||||||
"async": "^2.6.1",
|
"async": "^2.6.1",
|
||||||
"debug": "^3.1.0",
|
"debug": "^3.1.0",
|
||||||
"formidable": "^1.2.1",
|
"formidable": "^1.2.1",
|
||||||
"pkgcloud": "^1.5.0",
|
"pkgcloud": "^2.1.1",
|
||||||
"strong-globalize": "^4.1.1",
|
"strong-globalize": "^4.1.1",
|
||||||
"uuid": "^3.2.1"
|
"uuid": "^3.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^4.19.1",
|
"eslint": "^5.4.0",
|
||||||
"eslint-config-loopback": "^10.0.0",
|
"eslint-config-loopback": "^11.0.0",
|
||||||
"express": "^4.16.3",
|
"express": "^4.16.3",
|
||||||
"loopback": "^3.20.0",
|
"loopback": "^3.22.1",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"supertest": "^3.1.0",
|
"supertest": "^3.1.0",
|
||||||
|
@ -33,5 +33,6 @@
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/strongloop/loopback-component-storage.git"
|
"url": "https://github.com/strongloop/loopback-component-storage.git"
|
||||||
},
|
},
|
||||||
"license": "Artistic-2.0"
|
"license": "Artistic-2.0",
|
||||||
|
"author": "IBM Corp."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2016. All Rights Reserved.
|
// Copyright IBM Corp. 2016,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var loopback = require('loopback');
|
var loopback = require('loopback');
|
||||||
|
|
122
test/fs.test.js
122
test/fs.test.js
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2014. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var FileSystemProvider = require('../lib/providers/filesystem/index.js').Client;
|
var FileSystemProvider = require('../lib/providers/filesystem/index.js').Client;
|
||||||
|
@ -30,6 +31,21 @@ describe('FileSystem based storage provider', function() {
|
||||||
process.nextTick(done);
|
process.nextTick(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should work even it is ran from other path', function(done) {
|
||||||
|
process.chdir('../../../');
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(`running from ${process.cwd()}`);
|
||||||
|
client = new FileSystemProvider({
|
||||||
|
root: path.join(__dirname, 'storage'),
|
||||||
|
});
|
||||||
|
|
||||||
|
process.nextTick(done);
|
||||||
|
} catch (error) {
|
||||||
|
process.nextTick(done(error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('should complain if the root directory doesn\'t exist', function(done) {
|
it('should complain if the root directory doesn\'t exist', function(done) {
|
||||||
try {
|
try {
|
||||||
client = new FileSystemProvider({
|
client = new FileSystemProvider({
|
||||||
|
@ -45,11 +61,20 @@ describe('FileSystem based storage provider', function() {
|
||||||
it('should return an empty list of containers', function(done) {
|
it('should return an empty list of containers', function(done) {
|
||||||
client.getContainers(function(err, containers) {
|
client.getContainers(function(err, containers) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, containers.length);
|
assert.equal(containers.length, 0);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return an empty list of containers - promise', function(done) {
|
||||||
|
client.getContainers()
|
||||||
|
.then(function(containers) {
|
||||||
|
assert.equal(containers.length, 0);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should create a new container', function(done) {
|
it('should create a new container', function(done) {
|
||||||
client.createContainer({name: 'c1'}, function(err, container) {
|
client.createContainer({name: 'c1'}, function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -58,6 +83,15 @@ describe('FileSystem based storage provider', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create a new container - promise', function(done) {
|
||||||
|
client.createContainer({name: 'c3'})
|
||||||
|
.then(function(container) {
|
||||||
|
verifyMetadata(container, 'c3');
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should get a container c1', function(done) {
|
it('should get a container c1', function(done) {
|
||||||
client.getContainer('c1', function(err, container) {
|
client.getContainer('c1', function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -66,6 +100,15 @@ describe('FileSystem based storage provider', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get a container c1 - promise', function(done) {
|
||||||
|
client.getContainer('c1')
|
||||||
|
.then(function(container) {
|
||||||
|
verifyMetadata(container, 'c1');
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not get a container c2', function(done) {
|
it('should not get a container c2', function(done) {
|
||||||
client.getContainer('c2', function(err, container) {
|
client.getContainer('c2', function(err, container) {
|
||||||
assert(err);
|
assert(err);
|
||||||
|
@ -73,10 +116,18 @@ describe('FileSystem based storage provider', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should destroy a container c3 - promise', function(done) {
|
||||||
|
client.destroyContainer('c3')
|
||||||
|
.then(function(container) {
|
||||||
|
done(null, container);
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return one container', function(done) {
|
it('should return one container', function(done) {
|
||||||
client.getContainers(function(err, containers) {
|
client.getContainers(function(err, containers) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, containers.length);
|
assert.equal(containers.length, 1);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -167,11 +218,20 @@ describe('FileSystem based storage provider', function() {
|
||||||
it('should get files for a container', function(done) {
|
it('should get files for a container', function(done) {
|
||||||
client.getFiles('c1', function(err, files) {
|
client.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, files.length);
|
assert.equal(files.length, 1);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get files for a container - promise', function(done) {
|
||||||
|
client.getFiles('c1')
|
||||||
|
.then(function(files) {
|
||||||
|
assert.equal(files.length, 1);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should get a file', function(done) {
|
it('should get a file', function(done) {
|
||||||
client.getFile('c1', 'f1.txt', function(err, f) {
|
client.getFile('c1', 'f1.txt', function(err, f) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -181,6 +241,16 @@ describe('FileSystem based storage provider', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get a file - promise', function(done) {
|
||||||
|
client.getFile('c1', 'f1.txt')
|
||||||
|
.then(function(f) {
|
||||||
|
assert.ok(f);
|
||||||
|
verifyMetadata(f, 'f1.txt');
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should remove a file', function(done) {
|
it('should remove a file', function(done) {
|
||||||
client.removeFile('c1', 'f1.txt', function(err) {
|
client.removeFile('c1', 'f1.txt', function(err) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -188,29 +258,67 @@ describe('FileSystem based storage provider', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should remove a file - promise', function(done) {
|
||||||
|
createFile('c1', 'f1.txt').then(function() {
|
||||||
|
return client.removeFile('c1', 'f1.txt')
|
||||||
|
.then(function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should get no files from a container', function(done) {
|
it('should get no files from a container', function(done) {
|
||||||
client.getFiles('c1', function(err, files) {
|
client.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, files.length);
|
assert.equal(files.length, 0);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get no files from a container - promise', function(done) {
|
||||||
|
client.getFiles('c1')
|
||||||
|
.then(function(files) {
|
||||||
|
assert.equal(files.length, 0);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not get a file from a container', function(done) {
|
it('should not get a file from a container', function(done) {
|
||||||
client.getFile('c1', 'f2.txt', function(err, f) {
|
client.getFile('c1', 'f2.txt', function(err, f) {
|
||||||
assert(err);
|
assert(err);
|
||||||
assert.equal('ENOENT', err.code);
|
assert.equal(err.code, 'ENOENT');
|
||||||
assert(!f);
|
assert(!f);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not get a file from a container - promise', function(done) {
|
||||||
|
client.getFile('c1', 'f2.txt')
|
||||||
|
.then(function() {
|
||||||
|
throw new Error('should not be throw');
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
assert.equal(err.code, 'ENOENT');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should destroy a container c1', function(done) {
|
it('should destroy a container c1', function(done) {
|
||||||
client.destroyContainer('c1', function(err, container) {
|
client.destroyContainer('c1', function(err, container) {
|
||||||
// console.error(err);
|
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function createFile(container, file) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var writer = client.upload({container: container, remote: file});
|
||||||
|
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
||||||
|
writer.on('finish', resolve);
|
||||||
|
writer.on('error', reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2013,2015. All Rights Reserved.
|
// Copyright IBM Corp. 2013,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var StorageService = require('../lib/storage-service.js');
|
var StorageService = require('../lib/storage-service.js');
|
||||||
|
@ -19,11 +20,20 @@ describe('Storage service', function() {
|
||||||
it('should return an empty list of containers', function(done) {
|
it('should return an empty list of containers', function(done) {
|
||||||
storageService.getContainers(function(err, containers) {
|
storageService.getContainers(function(err, containers) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, containers.length);
|
assert.equal(containers.length, 0);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return an empty list of containers - promise', function(done) {
|
||||||
|
storageService.getContainers()
|
||||||
|
.then(function(containers) {
|
||||||
|
assert.equal(containers.length, 0);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should create a new container', function(done) {
|
it('should create a new container', function(done) {
|
||||||
storageService.createContainer({name: 'c1'}, function(err, container) {
|
storageService.createContainer({name: 'c1'}, function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -32,6 +42,15 @@ describe('Storage service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create a new container - promise', function(done) {
|
||||||
|
storageService.createContainer({name: 'c3'})
|
||||||
|
.then(function(container) {
|
||||||
|
assert(container.getMetadata());
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should get a container c1', function(done) {
|
it('should get a container c1', function(done) {
|
||||||
storageService.getContainer('c1', function(err, container) {
|
storageService.getContainer('c1', function(err, container) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -40,6 +59,15 @@ describe('Storage service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get a container c1 - promise', function(done) {
|
||||||
|
storageService.getContainer('c1')
|
||||||
|
.then(function(container) {
|
||||||
|
assert(container.getMetadata());
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not get a container c2', function(done) {
|
it('should not get a container c2', function(done) {
|
||||||
storageService.getContainer('c2', function(err, container) {
|
storageService.getContainer('c2', function(err, container) {
|
||||||
assert(err);
|
assert(err);
|
||||||
|
@ -47,10 +75,18 @@ describe('Storage service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should destroy a container c3 - promise', function(done) {
|
||||||
|
storageService.destroyContainer('c3')
|
||||||
|
.then(function(container) {
|
||||||
|
done(null, container);
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should return one container', function(done) {
|
it('should return one container', function(done) {
|
||||||
storageService.getContainers(function(err, containers) {
|
storageService.getContainers(function(err, containers) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, containers.length);
|
assert.equal(containers.length, 1);
|
||||||
done(err, containers);
|
done(err, containers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -104,11 +140,20 @@ describe('Storage service', function() {
|
||||||
it('should get files for a container', function(done) {
|
it('should get files for a container', function(done) {
|
||||||
storageService.getFiles('c1', function(err, files) {
|
storageService.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(1, files.length);
|
assert.equal(files.length, 1);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get files for a container - promise', function(done) {
|
||||||
|
storageService.getFiles('c1')
|
||||||
|
.then(function(files) {
|
||||||
|
assert.equal(files.length, 1);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should get a file', function(done) {
|
it('should get a file', function(done) {
|
||||||
storageService.getFile('c1', 'f1.txt', function(err, f) {
|
storageService.getFile('c1', 'f1.txt', function(err, f) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -118,6 +163,16 @@ describe('Storage service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should get a file - promise', function(done) {
|
||||||
|
storageService.getFile('c1', 'f1.txt')
|
||||||
|
.then(function(f) {
|
||||||
|
assert.ok(f);
|
||||||
|
assert(f.getMetadata());
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should remove a file', function(done) {
|
it('should remove a file', function(done) {
|
||||||
storageService.removeFile('c1', 'f1.txt', function(err) {
|
storageService.removeFile('c1', 'f1.txt', function(err) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
@ -125,10 +180,21 @@ describe('Storage service', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should remove a file - promise', function(done) {
|
||||||
|
createFile('c1', 'f1.txt')
|
||||||
|
.then(function() {
|
||||||
|
return storageService.removeFile('c1', 'f1.txt')
|
||||||
|
.then(function() {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
it('should get no files from a container', function(done) {
|
it('should get no files from a container', function(done) {
|
||||||
storageService.getFiles('c1', function(err, files) {
|
storageService.getFiles('c1', function(err, files) {
|
||||||
assert(!err);
|
assert(!err);
|
||||||
assert.equal(0, files.length);
|
assert.equal(files.length, 0);
|
||||||
done(err, files);
|
done(err, files);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -136,19 +202,39 @@ describe('Storage service', function() {
|
||||||
it('should not get a file from a container', function(done) {
|
it('should not get a file from a container', function(done) {
|
||||||
storageService.getFile('c1', 'f1.txt', function(err, f) {
|
storageService.getFile('c1', 'f1.txt', function(err, f) {
|
||||||
assert(err);
|
assert(err);
|
||||||
assert.equal('ENOENT', err.code);
|
assert.equal(err.code, 'ENOENT');
|
||||||
assert.equal(404, err.status);
|
assert.equal(err.status, 404);
|
||||||
assert(!f);
|
assert(!f);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not get a file from a container - promise', function(done) {
|
||||||
|
storageService.getFile('c1', 'f1.txt')
|
||||||
|
.then(function() {
|
||||||
|
throw new Error('should not be throw');
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
assert.equal(err.code, 'ENOENT');
|
||||||
|
assert.equal(err.status, 404);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should destroy a container c1', function(done) {
|
it('should destroy a container c1', function(done) {
|
||||||
storageService.destroyContainer('c1', function(err, container) {
|
storageService.destroyContainer('c1', function(err, container) {
|
||||||
// console.error(err);
|
|
||||||
assert(!err);
|
assert(!err);
|
||||||
done(err, container);
|
done(err, container);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function createFile(container, file) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var writer = storageService.uploadStream(container, file);
|
||||||
|
fs.createReadStream(path.join(__dirname, 'files/f1.txt')).pipe(writer);
|
||||||
|
writer.on('finish', resolve);
|
||||||
|
writer.on('error', reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// Copyright IBM Corp. 2014,2016. All Rights Reserved.
|
// Copyright IBM Corp. 2014,2019. All Rights Reserved.
|
||||||
// Node module: loopback-component-storage
|
// Node module: loopback-component-storage
|
||||||
// This file is licensed under the Artistic License 2.0.
|
// This file is licensed under the Artistic License 2.0.
|
||||||
// License text available at https://opensource.org/licenses/Artistic-2.0
|
// License text available at https://opensource.org/licenses/Artistic-2.0
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var request = require('supertest');
|
var request = require('supertest');
|
||||||
|
|
Loading…
Reference in New Issue