Comparing version 0.3.0 to 0.4.0
156
lib/blob.js
@@ -7,6 +7,7 @@ /*! | ||
var crypto = require('crypto'); | ||
var dateFormat = require('dateformat'); | ||
var sax = require('sax'); | ||
var MemoryStream = require('memorystream'); | ||
var BlobReadStream = require('./blobReadStream'); | ||
var BlobWriteStream = require('./blobWriteStream'); | ||
var u_ = require('underscore'); | ||
var mime = require('mime'); | ||
@@ -172,57 +173,95 @@ var skyutil = require("./util"); | ||
Container.prototype.put = function(name) { | ||
var that = this; | ||
var s = new MemoryStream(null, {readable: false}); | ||
var s = new BlobWriteStream({ | ||
name: name, | ||
onBlock: function(opts,callback) { | ||
var saxStream = sax.createStream(true); | ||
var isError = 0; | ||
var contentType = mime.lookup(opts.name); | ||
saxStream.on('opentag', function(tag) { | ||
if (tag.name === 'error') { | ||
isError++; | ||
} else if ((tag.name === "code") && (isError === 1)) { | ||
isError++; | ||
} | ||
}); | ||
var req = { | ||
'host' : that.options.account + '.blob.core.windows.net', | ||
'path' : that.name + '/' + opts.name, | ||
'account' : that.options.account, | ||
'key' : that.options.key, | ||
'contentType' : contentType, | ||
'body' : opts.block, | ||
'enhancedAuth' : true, | ||
'responseStream' : getResponseStream(callback), | ||
'headers' : {} | ||
}; | ||
saxStream.on('text', function(s) { | ||
if (isError === 2) { | ||
isError = 0; | ||
s.emit("error",new Error(s)); | ||
s.destroy(); | ||
} | ||
}); | ||
if (opts.id) { | ||
// This is a single block of a larger blob | ||
req.queryString = 'comp=block&blockid=' + opts.id; | ||
} else { | ||
// Single blob put, so add properties & metadata here | ||
req.headers['x-ms-blob-content-type'] = contentType; | ||
req.headers['x-ms-blob-type'] = 'BlockBlob'; | ||
u_.each(u_.keys(opts.properties), function(prop) { | ||
req.headers['x-ms-blob-' + prop] = opts.properties[prop]; | ||
}); | ||
if (opts.metadata) { | ||
req.metaData = opts.metadata; | ||
} | ||
} | ||
saxStream.on('error', function(err) { | ||
skyutil.doPut(req); | ||
}, | ||
onCommit: function(opts,callback) { | ||
var message = '<?xml version="1.0" encoding="utf-8"?><BlockList>' + | ||
u_.map(opts.guids, function(id) { return '<Uncommitted>' + id + '</Uncommitted>'}).join('') + | ||
'</BlockList>'; | ||
}); | ||
var req = { | ||
'host' : that.options.account + '.blob.core.windows.net', | ||
'path' : that.name + '/' + opts.name, | ||
'queryString' : 'comp=blocklist', | ||
'account' : that.options.account, | ||
'key' : that.options.key, | ||
'body' : message, | ||
'enhancedAuth' : true, | ||
'responseStream' : getResponseStream(callback), | ||
'headers' : {} | ||
}; | ||
s.on('end', function() { | ||
// Put blob properties & metadata here | ||
req.headers['x-ms-blob-content-type'] = mime.lookup(opts.name); | ||
u_.each(u_.keys(opts.properties), function(prop) { | ||
req.headers['x-ms-blob-' + prop] = opts.properties[prop]; | ||
}); | ||
skyutil.doPut({ | ||
'host' : that.options.account + '.blob.core.windows.net', | ||
'path' : that.name + '/' + name, | ||
'account' : that.options.account, | ||
'key' : that.options.key, | ||
'body' : s.getAll(), | ||
'enhancedAuth' : true, | ||
'responseStream' : saxStream, | ||
'headers' : { | ||
'x-ms-blob-type' : 'BlockBlob' | ||
if (opts.metadata) { | ||
req.metaData = opts.metadata; | ||
} | ||
}); | ||
skyutil.doPut(req); | ||
} | ||
}); | ||
return(s); | ||
}; | ||
Container.prototype.get = function(name) { | ||
} | ||
var getStream = null; | ||
Container.prototype.get = function(name, callback) { | ||
var blobReadStream = new BlobReadStream(); | ||
var getStream; | ||
var onResponse = function(error,response) { | ||
if (response.statusCode !== 200) { | ||
getStream.emit("error",new Error(response.statusCode)); | ||
callback(new Error(response.statusCode)); | ||
} else { | ||
u_.keys(response.headers).forEach(function(key) { | ||
if (key.indexOf('x-ms-meta') === 0) { | ||
blobReadStream.metadata[key.substring(10)] = response.headers[key]; | ||
} else if (key.indexOf('x-ms-blob') === 0) { | ||
blobReadStream.properties[key.substring(5)] = response.headers[key]; | ||
} | ||
}); | ||
callback(null,getStream.pipe(blobReadStream)); | ||
} | ||
@@ -240,4 +279,2 @@ }; | ||
return(getStream); | ||
}; | ||
@@ -263,2 +300,37 @@ | ||
var getResponseStream = function(callback) { | ||
var saxStream = sax.createStream(true); | ||
var isError = 0; | ||
var errorOccurred = false; | ||
saxStream.on('opentag', function(tag) { | ||
if (tag.name === 'Error') { | ||
isError++; | ||
} else if ((tag.name === "Code") && (isError === 1)) { | ||
isError++; | ||
} | ||
}); | ||
saxStream.on('text', function(s) { | ||
if (isError === 2) { | ||
isError = 0; | ||
errorOccurred = true; | ||
callback(new Error(s)); | ||
} | ||
}); | ||
saxStream.on('error', function(err) { | ||
// callback(err); | ||
}); | ||
saxStream.on('end', function() { | ||
if (!errorOccurred) { | ||
callback(null,true); | ||
} | ||
}); | ||
return saxStream; | ||
} | ||
module.exports = Container; |
@@ -11,2 +11,3 @@ /*! | ||
var sax = require('sax'); | ||
var u_ = require('underscore'); | ||
@@ -168,3 +169,3 @@ var msversion = '2011-08-18'; | ||
message = options.body; | ||
contentType = 'application/atom+xml'; | ||
contentType = options.contentType || 'application/atom+xml'; | ||
} | ||
@@ -178,5 +179,12 @@ | ||
'key' : options.key, | ||
// 'path' : path + queryString | ||
'path' : path | ||
'path' : (queryString.indexOf('comp=') === -1) ? path : path + queryString | ||
// Really?!? | ||
// For some reason, 'PUT's to blob storage need query string for creating blob blocks, but not containers | ||
}; | ||
// BUT ... with PUT'ing blob blocks, don't include the block id in the auth path | ||
authParams.path = authParams.path.replace(/&blockid=\S+$/,''); | ||
var tempHeaders = {}; | ||
authParams.headers = {}; | ||
@@ -188,24 +196,26 @@ if (options.enhancedAuth === true) { | ||
authParams.contentType = contentType; | ||
// Note: Auth headers must be in alpha order | ||
authParams.headers = []; | ||
// This is a hack | ||
if (options.headers && options.headers['x-ms-blob-type']) { | ||
authParams.headers['x-ms-blob-type'] = options.headers['x-ms-blob-type']; | ||
if (options.headers) { | ||
u_.map(options.headers, function(value, key) { | ||
if (key.indexOf('x-ms-blob') !== -1) { | ||
tempHeaders[key.toLowerCase()] = value; | ||
} | ||
}); | ||
} | ||
authParams.headers['x-ms-date'] = now; | ||
tempHeaders['x-ms-date'] = now; | ||
if (options.metaData) { | ||
var m; | ||
for (m in options.metaData) { | ||
if (options.metaData.hasOwnProperty(m)) { | ||
authParams.headers['x-ms-meta-' + m.toLowerCase()] = options.metaData[m]; | ||
} | ||
} | ||
u_.map(options.metaData, function(value, key) { | ||
tempHeaders['x-ms-meta-' + key.toLowerCase()] = value; | ||
}); | ||
} | ||
authParams.headers['x-ms-version'] = msversion; | ||
tempHeaders['x-ms-version'] = msversion; | ||
// Auth headers must be in alphabetical order... | ||
u_.each(u_.keys(tempHeaders).sort(), function(header) { | ||
authParams.headers[header] = tempHeaders[header]; | ||
}); | ||
} | ||
@@ -212,0 +222,0 @@ |
@@ -7,13 +7,24 @@ { | ||
"homepage": "https://github.com/pofallon/node-bluesky", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/pofallon/node-bluesky.git" | ||
}, | ||
"scripts": { | ||
"test": "nodeunit test" | ||
}, | ||
"dependencies": { | ||
"request": "2.2.x", | ||
"dateformat": "1.0.x", | ||
"sax": "0.3.x", | ||
"memorystream": "0.0.x" | ||
"request": "2.x.x", | ||
"dateformat": "1.x.x", | ||
"sax": "0.x.x", | ||
"mime": "1.x.x", | ||
"node-uuid": "1.x.x", | ||
"underscore": "1.x.x" | ||
}, | ||
"devDependencies": { | ||
"nodeunit": "0.5.x" | ||
"nodeunit": "0.x.x", | ||
"memorystream" : "0.0.x", | ||
"loremipstream" : "0.0.x" | ||
}, | ||
"engine": "node >= 0.4.1", | ||
"version": "0.3.0", | ||
"engine": "node >= 0.6.0", | ||
"version": "0.4.0", | ||
"files": [ | ||
@@ -26,3 +37,4 @@ "index.js", | ||
], | ||
"main": "index" | ||
"main": "index", | ||
"license": "MIT" | ||
} |
# node-bluesky | ||
A node.js library for accessing the Windows Azure REST API's. | ||
A lightweight, high-performance node.js library for accessing Windows Azure | ||
@@ -19,3 +19,5 @@ ## Usage | ||
var c2 = s.container('old'); | ||
c1.get('readme.txt').pipe(c2.put('archive.txt')); | ||
c1.get('readme.txt', function(err, readme) { | ||
readme.pipe(c2.put('archive.txt')); | ||
}); | ||
@@ -28,3 +30,2 @@ // and tables, oh my! | ||
// * Note that blob support is only preliminary and still needs work | ||
``` | ||
@@ -48,8 +49,15 @@ | ||
* [mikeal/request](https://github.com/mikeal/request) | ||
* [felixge/node-dateformat](https://github.com/felixge/node-dateformat) | ||
* [isaacs/sax-js](https://github.com/isaacs/sax-js) | ||
* [JSBizon/memorystream](https://github.com/JSBizon/memorystream) | ||
* [caolan/nodeunit](https://github.com/caolan/nodeunit) (for unit tests) | ||
* [bentomas/node-mime](/bentomas/node-mime) | ||
* [broofa/node-uuid](/broofa/node-uuid) | ||
* [documentcloud/underscore](/documentcloud/underscore) | ||
* [felixge/node-dateformat](/felixge/node-dateformat) | ||
* [isaacs/sax-js](/isaacs/sax-js) | ||
* [mikeal/request](/mikeal/request) | ||
... and for unit tests: | ||
* [caolan/nodeunit](/caolan/nodeunit) | ||
* [JSBizon/memorystream](/JSBizon/memorystream) | ||
* [pofallon/loremipstream](/pofallon/loremipstream) | ||
## Special Thanks | ||
@@ -56,0 +64,0 @@ |
@@ -9,2 +9,4 @@ /*! | ||
var MemoryStream = require('memorystream'); | ||
var LoremIpStream = require('loremipstream'); | ||
var testCase = require('nodeunit').testCase; | ||
@@ -50,3 +52,3 @@ | ||
var s = c.put('blob.txt'); | ||
s.on('end', function() { | ||
s.on('close', function() { | ||
test.done(); | ||
@@ -74,15 +76,17 @@ }); | ||
var c = storage.container(that.containerName); | ||
var s = c.get('blob.txt'); | ||
test.notEqual(s,null); | ||
if (s) { | ||
s.on("error", function(error) { | ||
test.equals(error,null,"Stream emitted an error event."); | ||
test.done(); | ||
}); | ||
s.on("end", function() { | ||
test.equals(memStream.getAll(),'This is a text blob'); | ||
test.done(); | ||
}); | ||
s.pipe(memStream); | ||
} | ||
c.get('blob.txt', function(err,s) { | ||
test.equals(err,null); | ||
test.notEqual(s,null); | ||
if (s) { | ||
s.on("error", function(error) { | ||
test.equals(error,null,"Stream emitted an error event."); | ||
test.done(); | ||
}); | ||
s.on("end", function() { | ||
test.equals(memStream.getAll(),'This is a text blob'); | ||
test.done(); | ||
}); | ||
s.pipe(memStream); | ||
} | ||
}); | ||
}, 1000); | ||
@@ -97,26 +101,74 @@ | ||
var s = c.put('blob2.txt'); | ||
s.on('end', function() { | ||
s.on('close', function() { | ||
var m1 = new MemoryStream(null, {readable: false}); | ||
var s1 = c.get('blob.txt'); | ||
s1.on("end", function() { | ||
setTimeout(function() { | ||
var m2 = new MemoryStream(null, {readable: false}); | ||
var s2 = c.get('blob2.txt'); | ||
s2.on("end", function() { | ||
test.equals(m1.getAll(), m2.getAll()); | ||
test.done(); | ||
}); | ||
s2.pipe(m2); | ||
}, 1000); | ||
c.get('blob.txt', function(err,s1) { | ||
test.equals(err,null); | ||
test.notEqual(s1,null); | ||
s1.on("end", function() { | ||
setTimeout(function() { | ||
var m2 = new MemoryStream(null, {readable: false}); | ||
c.get('blob2.txt', function(err,s2) { | ||
test.equals(err,null); | ||
test.notEqual(s2,null); | ||
s2.on("end", function() { | ||
test.equals(m1.getAll(), m2.getAll()); | ||
test.done(); | ||
}); | ||
s2.pipe(m2); | ||
}); | ||
}, 1000); | ||
}); | ||
s1.pipe(m1); | ||
}); | ||
s1.pipe(m1); | ||
}); | ||
s.on('error', function(err) { | ||
test.equals(err,null,"Stream emitted an error event."); | ||
test.equals(err,null,'writeStream emitted an error:' + err.message); | ||
test.done(); | ||
}); | ||
c.get('blob.txt').pipe(s); | ||
c.get('blob.txt', function(err,b) { | ||
test.equals(err,null); | ||
test.notEqual(b,null); | ||
b.pipe(s); | ||
}); | ||
}, | ||
/* blobPutSmallImage: function(test) { | ||
var c = storage.container(this.containerName); | ||
var imageStream = fs.createReadStream('test/node.png'); | ||
var s = c.put('node.png'); | ||
s.on('end', function() { | ||
test.done(); | ||
}); | ||
s.on('error', function(err) { | ||
test.equals(err,null,'writeStream emitted an error:' + err.message); | ||
test.done(); | ||
}); | ||
imageStream.pipe(s); | ||
}, */ | ||
blobPutLargeStream: function(test) { | ||
var c = storage.container(this.containerName); | ||
var lorem = new LoremIpStream(750*1024); | ||
var s = c.put('lorem.txt'); | ||
s.on('end', function() { | ||
test.done(); | ||
}); | ||
s.on('error', function(err) { | ||
test.equals(err,null,'writeStream emitted an error: ' + err.message); | ||
test.done(); | ||
}); | ||
lorem.pipe(s); | ||
}, | ||
removeContainer: function (test) { | ||
@@ -123,0 +175,0 @@ storage.removeContainer(this.containerName, function(err) { |
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
63315
15
1980
69
12
6
3
+ Addedmime@1.x.x
+ Addednode-uuid@1.x.x
+ Addedunderscore@1.x.x
+ Addedajv@6.12.6(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@1.0.0(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedaws-sign2@0.7.0(transitive)
+ Addedaws4@1.13.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@2.3.3(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjson-stringify-safe@5.0.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedmime@1.6.0(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addednode-uuid@1.4.8(transitive)
+ Addedoauth-sign@0.9.0(transitive)
+ Addedperformance-now@2.1.0(transitive)
+ Addedpsl@1.15.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedqs@6.5.3(transitive)
+ Addedrequest@2.88.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsax@0.6.1(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedtough-cookie@2.5.0(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addedunderscore@1.13.7(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedverror@1.10.0(transitive)
- Removedmemorystream@0.0.x
- Removedmemorystream@0.0.5(transitive)
- Removedrequest@2.2.9(transitive)
- Removedsax@0.3.5(transitive)
Updateddateformat@1.x.x
Updatedrequest@2.x.x
Updatedsax@0.x.x