Permalink
Browse files

update

  • Loading branch information...
youurayy committed Dec 22, 2011
1 parent b5888f7 commit 7058c4f52de9926dd55c183ac8cd8a7047a49af8
Showing with 205 additions and 25 deletions.
  1. +70 −10 README.md
  2. +1 −1 example/example2.js
  3. +17 −0 example/example3.js
  4. +35 −0 example/example4.js
  5. +80 −13 lib/utilz.js
  6. +2 −1 package.json
View
@@ -13,21 +13,21 @@
Watch the specificed .js file and quit the server to restart if it has changed.
Best used with Supervisord, or Forever (when it matures).
-`fileName`: the file to watch, may be relative to `process.cwd()`.
+* `fileName`: the file to watch, may be relative to `process.cwd()`.
```js
utilz.watchFile(__filename); // watch this .js
utilz.watchFile(__dirname + '/other.js'); // watch some other .js
```
-In production (NODE_ENV === 'production'), this will not restart imediatelly, but rather wait 2 seconds, to allow for all files to be replaced first, in the case of a full update.
+In production `(NODE_ENV === 'production')`, this will not restart imediatelly, but rather wait 2 seconds, to allow for all files to be replaced first, in the case of a full update.
### timeSpan(timespanInMs)
Display time duration in human readable format, from number of days to milliseconds.
-`timespanInMs`: the time interval in milliseconds.
+* `timespanInMs`: the time interval in milliseconds.
```js
var t1 = Date.now();
@@ -43,23 +43,83 @@ This will display an interval in the form of:
### formatNumber(number, fractionDigits)
-Format a number to the number of decimal places specified.
+Format a number to the number of decimal places specified, and add grouping commas.
-`number`: the number to format.
-
-`fractionDigits`: the number of decimal places.
+* `number`: the number to format.
+* `fractionDigits`: the number of decimal places.
```js
-var n = 3.14159265;
+var n = 123456.123456;
console.log(utilz.formatNumber(n, 3));
console.log(utilz.formatNumber(n, 0));
```
This will display:
- 3.142
- 3
+ 123,456.123
+ 123,456
+
+
+### mongodbInitCollections
+
+Initialize mongodb (node-mongodb-native) collections and hook them right onto the db objects to prevent code litter.
+
+* `db`: the DB object
+* cols: array with strings, the names of the collections;
+ optionally, an object where values are names of mongo collections,
+ and keys are aliases under which to store them on the db object
+* `cb`: the callback to call when done
+
+See below for complete example.
+
+
+### mongodbEnsureIndexes
+
+Initialize mongodb (node-mongodb-native) indexes for a specific collection.
+
+* `col`: the initialized collection
+* `indexes`: array with strings, the names of the indexes
+* `cb`: the callback to call when done
+
+Complete example of to open a MongoDB database using `mongodbInitCollections` and `mongodbEnsureIndexes`, plus helpers from `asinc-mini` and `LAEH`.
+
+```js
+var utilz = require('utilz');
+var async = require('async-mini');
+var laeh = require('laeh');
+var mongodb = require('mongodb');
+var _e = laeh._e;
+var _x = laeh._x;
+var db;
+
+async.series([
+ _x(function(cb) {
+ new mongodb.Db('example4', new mongodb.Server('localhost', 27017))
+ .open(_x(function(err, _db) {
+ db = _db;
+ cb();
+ }, cb, true));
+ }),
+ _x(function(cb) {
+ utilz.mongodbInitCollections(db, [ 'col1', 'col2' ], cb);
+ }),
+ _x(function(cb) {
+ utilz.mongodbEnsureIndexes(db.col1, [ [ 'field1' ], [ 'field2' ] ], cb);
+ }),
+ _x(function(cb) {
+ utilz.mongodbEnsureIndexes(db.col2, [ [ 'field3' ], [ 'field4' ] ], cb);
+ })
+],
+function(err) {
+ _e(err);
+ // the collections are now usable at db.col1 and db.col2, e.g.
+ db.col1.find({ field1: 'abc' }).toArray(function(err, arr) {
+ console.log(arr);
+ db.close();
+ });
+});
+```
### More...
View
@@ -2,7 +2,7 @@
var utilz = require('../lib/utilz.js');
-var n = 3.14159265;
+var n = 123456.123456;
console.log(utilz.formatNumber(n, 3));
console.log(utilz.formatNumber(n, 0));
View
@@ -0,0 +1,17 @@
+
+var utilz = require('../lib/utilz.js');
+var laeh = require('../node_modules/laeh');
+var _e = laeh._e;
+var _x = laeh._x;
+
+var obj = { f: 'my func', a: 'data 1', b: 'data 2' };
+
+console.log(obj);
+
+obj.sig = utilz.sign(obj, 'my secret', true);
+
+console.log(obj);
+
+_e(utilz.verify(obj, 'my secret', 5000));
+
+console.log('success');
View
@@ -0,0 +1,35 @@
+
+var utilz = require('../lib/utilz.js');
+var async = require('../node_modules/async-mini');
+var laeh = require('../node_modules/laeh');
+var mongodb = require('../node_modules/mongodb');
+var _e = laeh._e;
+var _x = laeh._x;
+var db;
+
+async.series([
+ _x(function(cb) {
+ new mongodb.Db('example4', new mongodb.Server('localhost', 27017))
+ .open(_x(function(err, _db) {
+ db = _db;
+ cb();
+ }, cb, true));
+ }),
+ _x(function(cb) {
+ utilz.mongodbInitCollections(db, [ 'col1', 'col2' ], cb);
+ }),
+ _x(function(cb) {
+ utilz.mongodbEnsureIndexes(db.col1, [ [ 'field1' ], [ 'field2' ] ], cb);
+ }),
+ _x(function(cb) {
+ utilz.mongodbEnsureIndexes(db.col2, [ [ 'field3' ], [ 'field4' ] ], cb);
+ })
+],
+function(err) {
+ _e(err);
+ // the collections are now usable at db.col1 and db.col2, e.g.
+ db.col1.find({ field1: 'abc' }).toArray(function(err, arr) {
+ console.log(arr);
+ db.close();
+ });
+});
View
@@ -20,7 +20,9 @@
// 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.
+
var fs = require('fs');
+var crypto = require('crypto');
var async = require('async-mini');
var laeh = require('laeh');
var _x = laeh._x;
@@ -49,7 +51,7 @@ exports.watchFile = function(filename) {
// Display time duration in human readable format, from number of days to milliseconds.
// t: the time interval in milliseconds
-exports.timeSpan = function(t) {
+exports.timeSpan = timeSpan = function(t) {
var f = Math.floor;
if(t < 1000)
return t + "ms";
@@ -85,35 +87,100 @@ exports.formatNumber = function(n, fr) {
// Initialize mongodb (node-mongodb-native) collections and hook
// them right onto the db objects to prevent code litter.
// db: the DB object
-// cols: array with string, the names of the collections
+// cols: array with strings, the names of the collections;
+// optionally, an object where values are names of mongo collections,
+// and keys are aliases under which to store them on the db object
// cb: the callback to call when done
exports.mongodbInitCollections = function(db, cols, cb) {
- var aa = [];
+ var aa = [], isobj = !Array.isArray(cols);
_.each(cols, function(v, k) {
aa.push(_x(function(cb) {
- db.collection(v, _ex(function(err, col) {
- db[k] = col;
+ db.collection(v, _x(function(err, col) {
+ db[isobj ? k : v] = col;
cb();
- }, cb));
+ }, cb, true));
}));
});
- async.series(aa, _ex(function(err, res) {
+ async.series(aa, _x(function(err, res) {
cb();
- }, cb));
+ }, cb, true));
};
-//
+// Initialize mongodb (node-mongodb-native) indexes for
+// a specific collection.
+// col: the initialized collection
+// indexes: array with strings, the names of the indexes
+// cb: the callback to call when done
-export.mongodbEnsureIndexes = function(col, arr, cb) {
- var pp = _.map(arr, function(v) {
+exports.mongodbEnsureIndexes = function(col, indexes, cb) {
+ var pp = _.map(indexes, function(v) {
return _x(function(cb) {
v.push(cb);
col.ensureIndex.apply(col, v);
});
});
- async.series(pp, _ex(function(err) {
+ async.series(pp, _x(function(err) {
cb();
- }, cb));
+ }, cb, true));
+};
+
+
+// Sign an object using sha256, optionally add timestamp.
+// `sig` and `ts` are reserved property names in the object.
+// obj: the object to sign
+// secret: the secret key
+// timed: boolean, whether to add timestamp for later checking
+// return: the signature, which needs to be assigned to obj.sig
+
+exports.sign = sign = function(obj, secret, timed) {
+ if(timed)
+ obj.ts = Date.now();
+ var b = [];
+ _.each(_.keys(obj).sort(), function(e) {
+ if(e != 'sig') {
+ b.push(e);
+ var v = obj[e];
+ b.push(Array.isArray(v) ? JSON.stringify(v) : String(v));
+ }
+ });
+ b.push(secret);
+ var s = b.join('|');
+ return crypto.createHash('sha256').update(s).digest('hex');
};
+
+
+// Verify a sha256 signed object, optionally check if timestamp
+// falls into the specified window.
+// obj: the object to verify
+// secret: the secret key
+// timeWindowMs: optional, the time window tolerance for the
+// timestamp, in milliseconds
+// return: error message or null on success
+
+exports.verify = function(obj, secret, timeWindowMs) {
+ if(sign(obj, secret) !== obj.sig)
+ return 'invalid signature';
+
+ if(timeWindowMs) {
+ if(!obj.ts)
+ return 'missing timestamp';
+
+ var half = timeWindowMs / 2;
+ var timestamp = new Date(obj.ts).getTime();
+ var latest = timestamp - timeWindowMs;
+ var earliest = timestamp + timeWindowMs;
+
+ // timespan plus window:
+ // latest -----|timestamp|---- earliest
+
+ var now = Date.now();
+ if(now < latest)
+ return 'timestamp too late by ' + timeSpan(latest - now);
+ if(now > earliest)
+ return 'timestamp too early by ' + timeSpan(now - earliest);
+ }
+
+ return null;
+}
View
@@ -3,7 +3,7 @@
"name": "utilz",
"description": "Various Small Utility Functions for Node.js",
"keywords": [ "utility", "functions" ],
- "version": "0.1.2",
+ "version": "0.1.3",
"homepage": "http://github.com/ypocat/utilz",
"repository": {
"type": "git",
@@ -22,5 +22,6 @@
"underscore": "1.1.7"
},
"devDependencies": {
+ "mongodb": "0.9.7"
}
}

0 comments on commit 7058c4f

Please sign in to comment.