Browse files

Adding commonjs-utils

  • Loading branch information...
1 parent 8a9712a commit 160c5054e05fb31fc1bdc1d9ef7055f916f1e722 Jonas Galvez committed Aug 29, 2010
View
5 lib/commonjs-utils/README.md
@@ -0,0 +1,5 @@
+CommonJS Utils is a collection of various CommonJS modules.
+
+CommonJS Utils is part of the Persevere project, and therefore is licensed under the
+AFL or BSD license. The Persevere project is administered under the Dojo foundation,
+and all contributions require a Dojo CLA.
View
27 lib/commonjs-utils/engines/rhino/lib/mail/smtp.js
@@ -0,0 +1,27 @@
+/**
+* Send emails
+* Use like this:
+* send({
+* from: "john@mydomain.com",
+* recipient: "bill@yourdomain.com",
+* subject: "hi",
+* message: "message text"
+* });
+* User should define a settings module that provides a MAIL export with the host
+*/
+var config = require("settings").mail;
+exports.send = function(email){
+ var props = new java.util.Properties();
+ props.put("mail.smtp.host", config.host);
+ props.put("mail.smtp.port", config.port || 25);
+ var session = javax.mail.Session.getDefaultInstance(props);
+ var msg = new javax.mail.internet.MimeMessage(session);
+ var from = new javax.mail.internet.InternetAddress(email.from || config.defaultFrom);
+ msg.setFrom(from);
+ var to = new javax.mail.internet.InternetAddress(email.recipient);
+ msg.setRecipients(javax.mail.Message.RecipientType.TO, to);
+ msg.setSubject(email.subject)
+ msg.setText(email.message);
+ //session.getTransport().Transport(msg);
+ javax.mail.Transport.send(msg);
+};
View
72 lib/commonjs-utils/lib/async.js
@@ -0,0 +1,72 @@
+/**
+ * A library for leveraging generator syntax to making promises easier to work with.
+ * This is not a core dependency of Pintura.
+ * Example usage:
+ *
+var async = require("./async").async;
+
+sleep = function(time){
+ var future = new Future();
+ setTimeout(future.fulfill, time);
+ return future;
+};
+
+// some examples
+sleepAndAdd4 = async(function(num){
+ yield sleep(1000);
+ returns = num + 4;
+});
+
+add5 = async(function(num){
+ var sum = yield sleepAndAdd4(num + 1);
+ console.log("sum " + sum);
+ returns = sum;
+});
+
+var add5Promise = add5(10);
+
+sleepAndAdd4(10).addCallback(function(value){
+ console.log("callback the manual way " + value);
+});
+
+ */
+
+var Promise = require("./promise").Promise;
+ // the async library
+exports.async = function(generatorFunction){
+ return function(){
+ var generator;
+ var future = new Future();
+ function finish(value){
+ finished = true;
+ callbacks.forEach(function(callback){
+ callback(returnValue);
+ });
+ }
+ function executeUntilYield(value){
+ try{
+ while(true){
+ returns = undefined;
+ value = generator[value === undefined ? "next" : "send"](value);
+ if(value instanceof Promise){
+ value.addCallback(function(next){
+ return executeUntilYield(next);
+ });
+ break;
+ }
+ }
+ }
+ catch(e if StopIteration){
+ future.fulfill(returns);
+ }
+
+ }
+ generator = generatorFunction.apply(this, arguments);
+ if(Object.prototype.toString.call(generator) == "[object Generator]"){
+ executeUntilYield();
+ }else{
+ future.fulfill(generator);
+ }
+ return future.promise;
+ }
+};
View
101 lib/commonjs-utils/lib/base64.js
@@ -0,0 +1,101 @@
+/* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
+ * Version: 1.0
+ * LastModified: Dec 25 1999
+ * This library is free. You can redistribute it and/or modify it.
+ */
+
+
+var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var base64DecodeChars = new Array(
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
+
+exports.encode = function(str) {
+ var out, i, len;
+ var c1, c2, c3;
+
+ len = str.length;
+ i = 0;
+ out = "";
+ while(i < len) {
+ c1 = str.charCodeAt(i++) & 0xff;
+ if(i == len)
+ {
+ out += base64EncodeChars.charAt(c1 >> 2);
+ out += base64EncodeChars.charAt((c1 & 0x3) << 4);
+ out += "==";
+ break;
+ }
+ c2 = str.charCodeAt(i++);
+ if(i == len)
+ {
+ out += base64EncodeChars.charAt(c1 >> 2);
+ out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
+ out += base64EncodeChars.charAt((c2 & 0xF) << 2);
+ out += "=";
+ break;
+ }
+ c3 = str.charCodeAt(i++);
+ out += base64EncodeChars.charAt(c1 >> 2);
+ out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
+ out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
+ out += base64EncodeChars.charAt(c3 & 0x3F);
+ }
+ return out;
+}
+
+exports.decode = function(str) {
+ var c1, c2, c3, c4;
+ var i, len, out;
+
+ len = str.length;
+ i = 0;
+ out = "";
+ while(i < len) {
+ /* c1 */
+ do {
+ c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+ } while(i < len && c1 == -1);
+ if(c1 == -1)
+ break;
+
+ /* c2 */
+ do {
+ c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
+ } while(i < len && c2 == -1);
+ if(c2 == -1)
+ break;
+
+ out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
+
+ /* c3 */
+ do {
+ c3 = str.charCodeAt(i++) & 0xff;
+ if(c3 == 61)
+ return out;
+ c3 = base64DecodeChars[c3];
+ } while(i < len && c3 == -1);
+ if(c3 == -1)
+ break;
+
+ out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
+
+ /* c4 */
+ do {
+ c4 = str.charCodeAt(i++) & 0xff;
+ if(c4 == 61)
+ return out;
+ c4 = base64DecodeChars[c4];
+ } while(i < len && c4 == -1);
+ if(c4 == -1)
+ break;
+ out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
+ }
+ return out;
+}
View
26 lib/commonjs-utils/lib/copy.js
@@ -0,0 +1,26 @@
+exports.deepCopy = function deepCopy(source, target, overwrite){
+ for(var i in source){
+ if(source.hasOwnProperty(i)){
+ if(typeof source[i] === "object" && typeof target[i] === "object"){
+ deepCopy(source[i], target[i], overwrite);
+ }
+ else if(overwrite || !target.hasOwnProperty(i)){
+ target[i] = source[i];
+ }
+ }
+ }
+ return target;
+};
+
+//TODO: should branch to using Object.keys if a native version is available. The
+// native version is slightly faster than doing a for-in loop (but a simulated version
+// wouldn't be) for rhino (but not v8). We could also have a branch for java-based copier that would
+// certainly be much faster
+exports.copy = function(source, target){
+ for(var i in source){
+ if(source.hasOwnProperty(i)){
+ target[i] = source[i];
+ }
+ }
+ return target;
+}
View
73 lib/commonjs-utils/lib/es5-helper.js
@@ -0,0 +1,73 @@
+/**
+ * Various global cleanup operations
+ */
+// the problem with the narwhal es5 shim is that it throws when you set a property
+// that can't be handled by the VM. We want to be able to set enumerable: false
+// and other functions if possible, but not trigger errors
+exports.defineProperties = Object.defineProperties && Object.defineProperties.toString().match(/native code/) ?
+ Object.defineProperties :
+ function(target, props){
+ for(var i in props){
+ var def = props[i];
+ if(def.get){
+ target.__defineGetter__(i, def.get);
+ }
+ if(def.set){
+ target.__defineSetter__(i, def.set);
+ }
+ else if ("value" in def){
+ target[i] = def.value;
+ }
+ }
+
+ };
+exports.defineProperty = Object.defineProperty && Object.defineProperty.toString().match(/native code/) ?
+ Object.defineProperty :
+ function(target, property, def){
+ if(def.get){
+ target.__defineGetter__(property, def.get);
+ }
+ if(def.set){
+ target.__defineSetter__(property, def.set);
+ }
+ else if ("value" in def){
+ target[property] = def.value;
+ }
+ };
+
+/*(function(){
+ var secureRandom = new java.security.SecureRandom();
+ Math.random = function(){
+ return secureRandom.nextDouble();
+ };
+/* should be handled by Narwhal's global function
+ if(!Object.defineProperty){
+ Object.defineProperty = function(target, property, def){
+ if(def.get || def.set){
+ target.__defineGetter__(property, def.get);
+ target.__defineSetter__(property, def.set);
+ }
+ else if ("value" in def){
+ target[property] = def.value;
+ }
+ };
+ }
+ if(!Object.defineProperties){
+ Object.defineProperties = function(target, props){
+ for(var i in props){
+ Object.defineProperty(target, i, props[i]);
+ }
+ };
+ }
+ if(!Object.create){
+ Object.create = function(proto, properties){
+ // classic beget/delegate function (albiet with the function declared inside for thread safety)
+ function temp(){}
+ temp.prototype = proto;
+ var instance = new temp;
+ Object.defineProperties(instance, properties);
+ return instance;
+ }
+ }
+})();*/
+
View
16 lib/commonjs-utils/lib/extend-error.js
@@ -0,0 +1,16 @@
+// Creates a custom error that extends JS's Error
+exports.ErrorConstructor = function(name, superError){
+ superError = superError || Error;
+ function ExtendedError(message){
+ var e = new Error(message);
+ e.name = name;
+ var ee = Object.create(ExtendedError.prototype);
+ for(var i in e){
+ ee[i] = e[i];
+ }
+ return ee;
+ }
+ ExtendedError.prototype = Object.create(superError.prototype);
+ ExtendedError.prototype.name = name;
+ return ExtendedError;
+};
View
51 lib/commonjs-utils/lib/jsgi-client.js
@@ -0,0 +1,51 @@
+/**
+* HTTP Client using the JSGI standard objects
+*/
+var defer = require("promised-io/promise").defer;
+
+exports.request = function(request){
+ var xhr = new XMLHttpRequest();
+ xhr.open(request.method || "GET",
+ request.uri || // allow request.uri to shortcut creating a URL from all the various parts
+ (request.scheme + "://" + request.serverName + ":" + request.serverPort + request.pathInfo + (request.queryString ? '?' + request.queryString : '')), true);
+ for(var i in request.headers){
+ xhr.setRequestHeader(i, request.headers[i]);
+ }
+ var deferred = defer();
+ var response;
+ var lastUpdate;
+ xhr.onreadystatechange = function(){
+ if(xhr.readyState == 4 || xhr.readyState == 3){
+ if(!response){
+ response = {
+ body: [xhr.responseText],
+ status: xhr.status,
+ headers: {}
+ };
+ lastUpdate = xhr.responseText.length;
+ var headers = xhr.getAllResponseHeaders();
+ headers = headers.split(/\n/);
+ for(var i = 0; i < headers.length; i++){
+ var nameValue = headers[i].split(": ", 2);
+ if(nameValue){
+ var name = nameValue[0];
+ response.headers[name.toLowerCase()] = xhr.getResponseHeader(name);
+ }
+ }
+ }
+ else{
+ response.body = [xhr.responseText];
+ lastUpdate = xhr.responseText.length;
+ }
+ if(xhr.readyState == 4){
+ deferred.resolve(response);
+ }
+ else{
+ deferred.progress(response);
+ }
+ }
+ }
+ xhr.send(request.body && request.body.toString());
+ return deferred.promise;
+}
+
View
101 lib/commonjs-utils/lib/jsgi-worker.js
@@ -0,0 +1,101 @@
+/**
+ * Module for interacting with a WebWorker through JSON-RPC.
+ * You can make a module accessible through JSON-RPC as easily as:
+ * some-module.js:
+ * require("./json-rpc-worker").server(exports);
+ *
+ * And to create this worker and fire it off:
+ * var Worker = require("worker"),
+ * client = require("./json-rpc-worker").client;
+ * var workerInterface = client(new Worker("some-module"));
+ * workerInterface.call("foo", [1, 3]).then(function(result){
+ * ... do something with the result ...
+ * });
+ *
+ */
+var observe = require("./observe").observe,
+ defer = require("./promise").defer;
+// Takes a JSGI 0.3 app.
+// Messages are communicated between workers using the JSGI 0.3 object structure
+// serialized in JSON format.
+exports.server = function(app){
+ if (global.onmessage) // dedicated worker
+ observe(global, "onmessage", handleMessage);
+ else // shared worker
+ observe(global, "onconnect", function (e) { observe(e.port, "onmessage", handleMessage); });
+
+ function handleMessage(event){
+ var request = event.data;
+ if(request.method){
+ var response = app(request);
+ response.url = request.url;
+ postMessage(response);
+ }
+ }
+};
+
+var nextId = 1;
+exports.client = function(worker){
+ if(worker.port){
+ worker = worker.port;
+ }
+ var requestsWaiting = {};
+ observe(worker, "onmessage", function(event){
+ var data = event.data;
+ if(requestsWaiting[data.id]){
+ if(data.error === null){
+ requestsWaiting[data.id].resolve(data.result);
+ }
+ else{
+ requestsWaiting[data.id].reject(data.error);
+ }
+ delete requestsWaiting[data.id];
+ }
+ });
+ return function(object){
+ var id = nextId++;
+ object.id = id;
+ worker.postMessage(object);
+ var deferred = defer();
+ requestsWaiting[id] = deferred;
+ return deferred.promise;
+ };
+};
+
+exports.rpcClient = function(worker){
+ var client = exports.client(worker);
+ return function(method, params){
+ return client({
+ method: method,
+ params: params
+ });
+ }
+}
+/*
+exports.JSFile = function(filename){
+ var worker = new SharedWorker("store/js-file-worker", filename);
+ worker.port.postMessage({start: filename});
+ var promises = [];
+ worker.port.onmessage = function(response){
+ for(var i = 0;i < promises;){
+ var promise = promises[i];
+ if(promise.url == response.url){
+ promise.resolve(response);
+ promises.splice(i,1);
+ }
+ }
+ }
+ jsgiWorker = function(request){
+ print("request " + request.toSource());
+ worker.port.postMessage(request);
+ var promise = new Promise();
+ promise.url = request.url;
+ promises.push(promise);
+ var response;
+ promise.then(function(value){
+ response = value;
+ });
+ // return synchronously
+ wait(promise);
+ return response;
+ };*/
View
28 lib/commonjs-utils/lib/jsgi/parse-header.js
@@ -0,0 +1,28 @@
+/**
+ * Provides parsers for various HTTP headers
+ */
+
+exports["content-range"] = function(contentRange, pageSize) {
+ if (!contentRange) return;
+ var parts = contentRange.match(/(\d+)\-(\d+)\/(\d+)/);
+ if (!parts) return;
+ var r = {};
+ r.start = parseInt(parts[1], 10);
+ r.end = parseInt(parts[2], 10);
+ r.total = parseInt(parts[3], 10);
+
+ if (!pageSize) return r;
+ if (r.start) {
+ r.prev = {};
+ r.prev.start = r.start - pageSize;
+ if (r.prev.start < 0) r.prev.start = 0;
+ r.prev.end = r.start - 1;
+ }
+ if (r.total - r.end > 1) {
+ r.next = {};
+ r.next.start = r.end + 1;
+ r.next.end = r.end + pageSize;
+ if (r.next.end >= r.total) r.next.end = r.total - 1;
+ }
+ return r;
+};
View
318 lib/commonjs-utils/lib/json-ext.js
@@ -0,0 +1,318 @@
+/**
+* Declarative subset of JavaScript with a few extras beyond JSON, including
+* dates, non-finite numbers, etc.
+* Derived from and uses:
+http://www.JSON.org/json2.js
+ 2008-11-19
+
+ Public Domain.
+
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+ */
+
+if(typeof JSON === "undefined"){
+ require("json");
+}
+
+var nativeJson = !!JSON.parse.toString().match(/native code/);
+exports.parse = function (text) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+ var j;
+
+ function walk(value) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+ var k;
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ var v = value[k];
+ if (typeof v === 'string') {
+ var a =
+ /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(v);
+ if (a) {
+ value[k] = new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+ +a[5], +a[6]));
+ }
+ }
+ else if (typeof v === 'object') {
+ walk(v);
+ }
+ }
+ }
+ }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' +
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+var backSlashRemoved = text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
+ if (/^[\],:{}\s]*$/.
+test(backSlashRemoved.
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+ // it is pure JSON
+ if(nativeJson){
+ // use the native parser if available
+ j = JSON.parse(text);
+ }
+ else{
+ // revert to eval
+ j = eval('(' + text + ')');
+ }
+ walk(j);
+ return j;
+ }
+ else if (/^[\],:{}\s]*$/.
+test(backSlashRemoved.
+replace(/"[^"\\\n\r]*"|'[^'\\\n\r]*'|\(?new +Date\([0-9]*\)+|[\w$]+\s*:(?:\s*\[)*|true|false|null|undefined|-?Infinity|NaN|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,|&&)(?:\s*\[)+/g, ''))) {
+ // not pure JSON, but safe declarative JavaScript
+ j = eval('(' + text + ')');
+ walk(j);
+ return j;
+ }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+ throw new SyntaxError('JSON.parse');
+};
+
+var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+
+
+var nativeConstructors = {"String":String, "Object":Object, "Number":Number, "Boolean":Boolean, "Array":Array, "Date":Date};
+exports.stringify = ({}).toSource ?
+ // we will use toSource if it is available
+ (function(){
+ Object.keys(nativeConstructors).forEach(function(name){
+ global[name].toSource = function(){
+ return name;
+ };
+ });
+ return function(value){
+ if(value && typeof value == "object" || typeof value == "function"){
+ var source = value.toSource();
+ if(source.charAt(0) == "("){
+ // remove the surrounding paranthesis that are produced
+ source = source.substring(1, source.length - 1);
+ }
+ return source;
+ }
+ if(typeof value === "number" && !isFinite(value)){
+ return value.toString();
+ }
+ if(typeof value === "undefined"){
+ return "undefined";
+ }
+ return JSON.stringify(value);
+ };
+ })() :
+ (function(){
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+ escapable.lastIndex = 0;
+ return escapable.test(string) ?
+ '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+// Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+// What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'function':
+ if(nativeConstructors[value.name] === value){
+ return value.name;
+ }
+ value = value.toString();
+
+ case 'string':
+ return quote(value);
+
+ case 'number':
+ case 'boolean':
+ case 'undefined':
+ case 'null':
+
+ return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+ case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+// Is the value an array?
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+ if (value instanceof Date){
+ return "new Date(" + value.getTime() + ")";
+ }
+
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+ return function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+ return str('', {'': value});
+ };
+
+})();
View
280 lib/commonjs-utils/lib/json-schema.js
@@ -0,0 +1,280 @@
+/**
+ * JSONSchema Validator - Validates JavaScript objects using JSON Schemas
+ * (http://www.json.com/json-schema-proposal/)
+ *
+ * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com)
+ * Licensed under the MIT (MIT-LICENSE.txt) license.
+To use the validator call JSONSchema.validate with an instance object and an optional schema object.
+If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
+that schema will be used to validate and the schema parameter is not necessary (if both exist,
+both validations will occur).
+The validate method will return an array of validation errors. If there are no errors, then an
+empty list will be returned. A validation error will have two properties:
+"property" which indicates which property had the error
+"message" which indicates what the error was
+ */
+
+// setup primitive classes to be JSON Schema types
+String.type = "string";
+Boolean.type = "boolean";
+Number.type = "number";
+exports.Integer = {type:"integer"};
+Object.type = "object";
+Array.type = "array";
+Date.type = "date";
+
+exports.validate = function(/*Any*/instance,/*Object*/schema) {
+ // Summary:
+ // To use the validator call JSONSchema.validate with an instance object and an optional schema object.
+ // If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
+ // that schema will be used to validate and the schema parameter is not necessary (if both exist,
+ // both validations will occur).
+ // The validate method will return an object with two properties:
+ // valid: A boolean indicating if the instance is valid by the schema
+ // errors: An array of validation errors. If there are no errors, then an
+ // empty list will be returned. A validation error will have two properties:
+ // property: which indicates which property had the error
+ // message: which indicates what the error was
+ //
+ return validate(instance,schema,false);
+ };
+exports.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/ property) {
+ // Summary:
+ // The checkPropertyChange method will check to see if an value can legally be in property with the given schema
+ // This is slightly different than the validate method in that it will fail if the schema is readonly and it will
+ // not check for self-validation, it is assumed that the passed in value is already internally valid.
+ // The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for
+ // information.
+ //
+ return validate(value,schema, property || "property");
+ };
+var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*Boolean*/ _changing) {
+
+ var errors = [];
+ // validate a value against a property definition
+ function checkProp(value, schema, path,i){
+ var l;
+ path += path ? typeof i == 'number' ? '[' + i + ']' : typeof i == 'undefined' ? '' : '.' + i : i;
+ function addError(message){
+ errors.push({property:path,message:message});
+ }
+
+ if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function') && !(schema && schema.type)){
+ if(typeof schema == 'function'){
+ if(!(value instanceof schema)){
+ addError("is not an instance of the class/constructor " + schema.name);
+ }
+ }else if(schema){
+ addError("Invalid schema/property definition " + schema);
+ }
+ return null;
+ }
+ if(_changing && schema.readonly){
+ addError("is a readonly field, it can not be changed");
+ }
+ if(schema['extends']){ // if it extends another schema, it must pass that schema as well
+ checkProp(value,schema['extends'],path,i);
+ }
+ // validate a value against a type definition
+ function checkType(type,value){
+ if(type){
+ if(typeof type == 'string' && type != 'any' &&
+ (type == 'null' ? value !== null : typeof value != type) &&
+ !(value instanceof Array && type == 'array') &&
+ !(value instanceof Date && type == 'date') &&
+ !(type == 'integer' && value%1===0)){
+ return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}];
+ }
+ if(type instanceof Array){
+ var unionErrors=[];
+ for(var j = 0; j < type.length; j++){ // a union type
+ if(!(unionErrors=checkType(type[j],value)).length){
+ break;
+ }
+ }
+ if(unionErrors.length){
+ return unionErrors;
+ }
+ }else if(typeof type == 'object'){
+ var priorErrors = errors;
+ errors = [];
+ checkProp(value,type,path);
+ var theseErrors = errors;
+ errors = priorErrors;
+ return theseErrors;
+ }
+ }
+ return [];
+ }
+ if(value === undefined){
+ if(!schema.optional && !schema.get){
+ addError("is missing and it is not optional");
+ }
+ }else{
+ errors = errors.concat(checkType(schema.type,value));
+ if(schema.disallow && !checkType(schema.disallow,value).length){
+ addError(" disallowed value was matched");
+ }
+ if(value !== null){
+ if(value instanceof Array){
+ if(schema.items){
+ if(schema.items instanceof Array){
+ for(i=0,l=value.length; i<l; i++){
+ errors.concat(checkProp(value[i],schema.items[i],path,i));
+ }
+ }else{
+ for(i=0,l=value.length; i<l; i++){
+ errors.concat(checkProp(value[i],schema.items,path,i));
+ }
+ }
+ }
+ if(schema.minItems && value.length < schema.minItems){
+ addError("There must be a minimum of " + schema.minItems + " in the array");
+ }
+ if(schema.maxItems && value.length > schema.maxItems){
+ addError("There must be a maximum of " + schema.maxItems + " in the array");
+ }
+ }else if(schema.properties || schema.additionalProperties){
+ errors.concat(checkObj(value, schema.properties, path, schema.additionalProperties));
+ }
+ if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){
+ addError("does not match the regex pattern " + schema.pattern);
+ }
+ if(schema.maxLength && typeof value == 'string' && value.length > schema.maxLength){
+ addError("may only be " + schema.maxLength + " characters long");
+ }
+ if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){
+ addError("must be at least " + schema.minLength + " characters long");
+ }
+ if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum &&
+ schema.minimum > value){
+ addError("must have a minimum value of " + schema.minimum);
+ }
+ if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum &&
+ schema.maximum < value){
+ addError("must have a maximum value of " + schema.maximum);
+ }
+ if(schema['enum']){
+ var enumer = schema['enum'];
+ l = enumer.length;
+ var found;
+ for(var j = 0; j < l; j++){
+ if(enumer[j]===value){
+ found=1;
+ break;
+ }
+ }
+ if(!found){
+ addError("does not have a value in the enumeration " + enumer.join(", "));
+ }
+ }
+ if(typeof schema.maxDecimal == 'number' &&
+ (value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){
+ addError("may only have " + schema.maxDecimal + " digits of decimal places");
+ }
+ }
+ }
+ return null;
+ }
+ // validate an object against a schema
+ function checkObj(instance,objTypeDef,path,additionalProp){
+
+ if(typeof objTypeDef =='object'){
+ if(typeof instance != 'object' || instance instanceof Array){
+ errors.push({property:path,message:"an object is required"});
+ }
+
+ for(var i in objTypeDef){
+ if(objTypeDef.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_')){
+ var value = instance[i];
+ var propDef = objTypeDef[i];
+ // set default
+ if(value === undefined && propDef["default"]){
+ value = instance[i] = propDef["default"];
+ }
+ checkProp(value,propDef,path,i);
+ }
+ }
+ }
+ for(i in instance){
+ if(instance.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_') && objTypeDef && !objTypeDef[i] && additionalProp===false){
+ errors.push({property:path,message:(typeof value) + "The property " + i +
+ " is not defined in the schema and the schema does not allow additional properties"});
+ }
+ var requires = objTypeDef && objTypeDef[i] && objTypeDef[i].requires;
+ if(requires && !(requires in instance)){
+ errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"});
+ }
+ value = instance[i];
+ if(additionalProp && (!(objTypeDef && typeof objTypeDef == 'object') || !(i in objTypeDef))){
+ checkProp(value,additionalProp,path,i);
+ }
+ if(!_changing && value && value.$schema){
+ errors = errors.concat(checkProp(value,value.$schema,path,i));
+ }
+ }
+ return errors;
+ }
+ if(schema){
+ checkProp(instance,schema,'',_changing || '');
+ }
+ if(!_changing && instance && instance.$schema){
+ checkProp(instance,instance.$schema,'','');
+ }
+ return {valid:!errors.length,errors:errors};
+};
+exports.mustBeValid = function(result){
+ // summary:
+ // This checks to ensure that the result is valid and will throw an appropriate error message if it is not
+ // result: the result returned from checkPropertyChange or validate
+ if(!result.valid){
+ throw new TypeError(result.errors.map(function(error){return "for property " + error.property + ': ' + error.message;}).join(", \n"));
+ }
+}
+ /* will add this later
+ newFromSchema : function() {
+ }
+*/
+
+exports.cacheLinks = true;
+exports.getLink = function(relation, instance, schema){
+ // gets the URI of the link for the given relation based on the instance and schema
+ // for example:
+ // getLink(
+ // "brother",
+ // {"brother_id":33},
+ // {links:[{rel:"brother", href:"Brother/{brother_id}"}]}) ->
+ // "Brother/33"
+ var links = schema.__linkTemplates;
+ if(!links){
+ links = {};
+ var schemaLinks = schema.links;
+ if(schemaLinks && schemaLinks instanceof Array){
+ schemaLinks.forEach(function(link){
+ /* // TODO: allow for multiple same-name relations
+ if(links[link.rel]){
+ if(!(links[link.rel] instanceof Array)){
+ links[link.rel] = [links[link.rel]];
+ }
+ }*/
+ links[link.rel] = link.href;
+ });
+ }
+ if(exports.cacheLinks){
+ schema.__linkTemplates = links;
+ }
+ }
+ var linkTemplate = links[relation];
+ return linkTemplate && exports.substitute(linkTemplate, instance);
+};
+
+exports.substitute = function(linkTemplate, instance){
+ return linkTemplate.replace(/\{([^\}]*)\}/g, function(t, property){
+ var value = instance[decodeURIComponent(property)];
+ if(value instanceof Array){
+ // the value is an array, it should produce a URI like /Table/(4,5,8) and store.get() should handle that as an array of values
+ return '(' + value.join(',') + ')';
+ }
+ return value;
+ });
+};
View
131 lib/commonjs-utils/lib/json.js
@@ -0,0 +1,131 @@
+/**
+ * This is a port of Dojo's JSON module
+ */
+
+if(typeof JSON === "undefined"){
+exports.parse = function(/*String*/ json){
+ // summary:
+ // Parses a [JSON](http://json.org) string to return a JavaScript object.
+ // description:
+ // Throws for invalid JSON strings, but it does not use a strict JSON parser. It
+ // delegates to eval().
+ // json:
+ // a string literal of a JSON item, for instance:
+ // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
+
+ return eval("(" + json + ")"); // Object
+}
+
+function escapeString(/*String*/str){
+ //summary:
+ // Adds escape sequences for non-visual characters, double quote and
+ // backslash and surrounds with double quotes to form a valid string
+ // literal.
+ return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
+ replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
+ replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
+}
+
+exports.toJsonIndentStr = "\t";
+exports.stringify = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
+ // summary:
+ // Returns a [JSON](http://json.org) serialization of an object.
+ // description:
+ // Returns a [JSON](http://json.org) serialization of an object.
+ // Note that this doesn't check for infinite recursion, so don't do that!
+ // it:
+ // an object to be serialized. Objects may define their own
+ // serialization via a special "__json__" or "json" function
+ // property. If a specialized serializer has been defined, it will
+ // be used as a fallback.
+ // prettyPrint:
+ // if true, we indent objects and arrays to make the output prettier.
+ // The variable `toJsonIndentStr` is used as the indent string --
+ // to use something other than the default (tab), change that variable
+ // before calling stringify().
+ // _indentStr:
+ // private variable for recursive calls when pretty printing, do not use.
+ // example:
+ // simple serialization of a trivial object
+ // | var jsonStr = require("commonjs-utils/json").stringify({ howdy: "stranger!", isStrange: true });
+
+ if(it === undefined){
+ return "undefined";
+ }
+ var objtype = typeof it;
+ if(objtype == "number" || objtype == "boolean"){
+ return it + "";
+ }
+ if(it === null){
+ return "null";
+ }
+ if(typeof it == "string"){
+ return escapeString(it);
+ }
+ // recurse
+ var recurse = arguments.callee;
+ // short-circuit for objects that support "json" serialization
+ // if they return "self" then just pass-through...
+ var newObj;
+ _indentStr = _indentStr || "";
+ var nextIndent = prettyPrint ? _indentStr + exports.toJsonIndentStr : "";
+ var tf = it.__json__||it.json;
+ if(typeof tf == "function"){
+ newObj = tf.call(it);
+ if(it !== newObj){
+ return recurse(newObj, prettyPrint, nextIndent);
+ }
+ }
+ if(it.nodeType && it.cloneNode){ // isNode
+ // we can't seriailize DOM nodes as regular objects because they have cycles
+ // DOM nodes could be serialized with something like outerHTML, but
+ // that can be provided by users in the form of .json or .__json__ function.
+ throw new Error("Can't serialize DOM nodes");
+ }
+
+ var sep = prettyPrint ? " " : "";
+ var newLine = prettyPrint ? "\n" : "";
+
+ // array
+ if(it instanceof Array){
+ var res = [];
+ for(var i = 0, l = it.length; i < l; i++){
+ var val = recurse(it[i], prettyPrint, nextIndent);
+ if(typeof val != "string"){
+ val = "undefined";
+ }
+ res.push(newLine + nextIndent + val);
+ }
+ return "[" + res.join("," + sep) + newLine + _indentStr + "]";
+ }
+ if(objtype == "function"){
+ return null; // null
+ }
+ // generic object code path
+ var output = [], key;
+ for(key in it){
+ var keyStr, val;
+ if(typeof key == "number"){
+ keyStr = '"' + key + '"';
+ }else if(typeof key == "string"){
+ keyStr = escapeString(key);
+ }else{
+ // skip non-string or number keys
+ continue;
+ }
+ val = recurse(it[key], prettyPrint, nextIndent);
+ if(typeof val != "string"){
+ // skip non-serializable values
+ continue;
+ }
+ // FIXME: use += on Moz!!
+ // MOW NOTE: using += is a pain because you have to account for the dangling comma...
+ output.push(newLine + nextIndent + keyStr + ":" + sep + val);
+ }
+ return "{" + output.join("," + sep) + newLine + _indentStr + "}"; // String
+}
+}
+else{
+ exports.parse = JSON.parse;
+ exports.stringify = JSON.stringify;
+}
View
151 lib/commonjs-utils/lib/lazy-array.js
@@ -0,0 +1,151 @@
+try{
+ var when = require("./promise").when;
+}catch(e){
+ when = function(value, callback){
+ return callback(value);
+ }
+}
+exports.LazyArray = function(hasSomeAndLength){
+ return new SomeWrapper(hasSomeAndLength);
+};
+exports.first = function(array){
+ return exports.get(array, 0);
+};
+exports.last = function(array){
+ return exports.get(array, array.length-1);
+};
+exports.get = function(array, index){
+ var result, i = 0;
+ return when(array.some(function(item){
+ if(i == index){
+ result = item;
+ return true;
+ }
+ i++;
+ }),
+ function(){
+ return result;
+ });
+};
+
+
+var testProto = {};
+var testProto2 = testProto.__proto__ = testProto2;
+var mutableProto = testProto.__proto__ === testProto2;
+function SomeWrapper(hasSomeAndLength){
+ if(mutableProto){
+ hasSomeAndLength.source = hasSomeAndLength;
+ hasSomeAndLength.__proto__ = SomeWrapper.prototype;
+ return hasSomeAndLength;
+ }
+ this.source = hasSomeAndLength;
+ if(hasSomeAndLength.length){
+ this.length = hasSomeAndLength.length;
+ }
+ this.totalCount = hasSomeAndLength.totalCount;
+}
+exports.LazyArray.prototype = SomeWrapper.prototype = [];
+SomeWrapper.prototype.some = function(callback){
+ this.source.some(callback);
+}
+SomeWrapper.prototype.filter = function(fn, thisObj){
+ var result = [];
+ return when(this.source.some(function(item){
+ if(fn.call(thisObj, item)){
+ results.push(item);
+ }
+ }), function(){
+ return results;
+ });
+};
+
+SomeWrapper.prototype.every = function(fn, thisObj){
+ return when(this.source.some(function(item){
+ if(!fn.call(thisObj, item)){
+ return true;
+ }
+ }), function(result){return !result;});
+};
+SomeWrapper.prototype.forEach= function(fn, thisObj){
+ return this.source.some(function(item){
+ fn.call(thisObj, item);
+ });
+};
+SomeWrapper.prototype.concat = function(someOther){
+ var source = this.source;
+ return new SomeWrapper({
+ length : source.length + someOther.length,
+ some : function(fn,thisObj){
+ return when(source.some(fn,thisObj), function(result){
+ return result || someOther.some(fn,thisObj);
+ });
+ }
+ });
+};
+SomeWrapper.prototype.map = function(mapFn, mapThisObj){
+ var source = this.source;
+ return new SomeWrapper({
+ length : source.length,
+ some : function(fn,thisObj){
+ return source.some(function(item){
+ return fn.call(thisObj, mapFn.call(mapThisObj, item));
+ });
+ }
+ });
+};
+SomeWrapper.prototype.toRealArray= function(mapFn, mapThisObj){
+ var array = [];
+ return when(this.source.some(function(item){
+ array.push(item);
+ }), function(){
+ return array;
+ });
+};
+SomeWrapper.prototype.join = function(){
+ var args = arguments;
+ return when(this.toRealArray(), function(realArray){
+ return Array.prototype.join.apply(realArray, args);
+ });
+};
+SomeWrapper.prototype.sort = function(){
+ var args = arguments;
+ return when(this.toRealArray(), function(realArray){
+ return Array.prototype.sort.apply(realArray, args);
+ });
+};
+SomeWrapper.prototype.reverse = function(){
+ var args = arguments;
+ return when(this.toRealArray(), function(realArray){
+ return Array.prototype.reverse.apply(realArray, args);
+ });
+};
+SomeWrapper.prototype.get = SomeWrapper.prototype.item = function(index){
+ var result, i = 0;
+ return when(this.source.some(function(item){
+ if(i == index){
+ result = item;
+ return true;
+ }
+ i++;
+ }), function(){
+ return result;
+ });
+};
+
+
+SomeWrapper.prototype.toSource = function(){
+ var serializedParts = [];
+ return when(this.source.some(function(item){
+ serializedParts.push(item && item.toSource());
+ }), function(){
+ return '[' + serializedParts.join(",") + ']';
+ });
+};
+SomeWrapper.prototype.toJSON = function(){
+ var loadedParts = [];
+ return when(this.source.some(function(item){
+ loadedParts.push(item);
+ }), function(){
+ return loadedParts;
+ });
+};
View
94 lib/commonjs-utils/lib/observe.js
@@ -0,0 +1,94 @@
+/**
+ * AOP style event handling, for listening for method calls. Very similar to dojo.connect
+
+/* Add a listener for the execution of the given function slot on the given object.
+ *
+ * When object[eventName]() is executed the handler is called.
+ * The optional before parameter can be used to indicate if the listener
+ * should be fired before or after the default action (default is after)
+ */
+exports.observe = function(object, eventName, listener, before) {
+ if(!listener){
+ throw new Error("No listener provided");
+ }
+ if(typeof object.observe === "function"){
+ // CommonJS observable object
+ return object.observe(eventName, listener);
+ }
+ var listenerProxy = function(that, args){//make sure we have unique function so we can remove it
+ try{
+ listener.apply(that, args);
+ }catch(e){
+ require("./sys").print(e);
+ }
+ };
+ if(typeof object.addListener === "function"){
+ // NodeJS EventEmitter
+ object.addListener(eventName, listener);
+ return {
+ observe: function(listener){
+ return exports.observe(object, eventName, listener);
+ },
+ emit: function(event){
+ object.emit(eventName, event);
+ },
+ dismiss: function(){
+ object.removeListener(eventName, listener);
+ }
+ };
+ }
+ var afters, befores,
+ main = object[eventName];
+ if(typeof main != "function"){
+ main = function(){};
+ }
+ if(main._afters){
+ afters = main._afters;
+ befores = main._befores;
+ }
+ else{
+ befores = [];
+ afters = [];
+ var newFunc = object[eventName] = function(){
+ for(var i = 0; i < befores.length; i++){
+ befores[i](this, arguments);
+ }
+ try{
+ return main.apply(this, arguments);
+ }
+ finally{
+ for(var i = 0; i < afters.length; i++){
+ afters[i](this, arguments);
+ }
+ }
+ };
+ newFunc._befores = befores;
+ newFunc._afters = afters;
+ }
+ if(before){
+ befores.push(listenerProxy);
+ }
+ else{
+ afters.push(listenerProxy);
+ }
+ return createSignal();
+ function createSignal(){
+ var observers;
+ return {
+ observe: function(listener){
+ afters.push(listener);
+ },
+ emit: function(){
+ main.apply(object, arguments);
+ },
+ dismiss: function(){
+ if(before){
+ befores.splice(befores.indexOf(listenerProxy), 1);
+ }
+ else{
+ afters.splice(afters.indexOf(listenerProxy), 1);
+ }
+ }
+ };
+ };
+};
View
14 lib/commonjs-utils/lib/settings.js
@@ -0,0 +1,14 @@
+try{
+ var read = require("fs").readFileSync;
+}catch(e){
+ read = require("file").read;
+}
+try{
+ var settings = JSON.parse(read("local.json").toString("utf8"));
+ for(var i in settings){
+ exports[i] = settings[i];
+ }
+}catch(e){
+ e.message += " trying to load local.json, make sure local.json is in your current working directory";
+ throw e;
+}
View
330 lib/commonjs-utils/lib/sha1.js
@@ -0,0 +1,330 @@
+/*
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS 180-1
+ * Version 2.2 Copyright Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+exports.hex_sha1 = function(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
+exports.b64_sha1 = function(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
+exports.any_sha1 = function (s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
+exports.hex_hmac_sha1 = function (k, d)
+ { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+exports.b64_hmac_sha1 = function(k, d)
+ { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+exports.any_hmac_sha1 = function(k, d, e)
+ { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha1_vm_test()
+{
+ return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
+}
+
+/*
+ * Calculate the SHA1 of a raw string
+ */
+function rstr_sha1(s)
+{
+ return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
+}
+
+/*
+ * Calculate the HMAC-SHA1 of a key and some data (raw strings)
+ */
+function rstr_hmac_sha1(key, data)
+{
+ var bkey = rstr2binb(key);
+ if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
+ return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
+}
+
+/*
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+ try { hexcase } catch(e) { hexcase=0; }
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var output = "";
+ var x;
+ for(var i = 0; i < input.length; i++)
+ {
+ x = input.charCodeAt(i);
+ output += hex_tab.charAt((x >>> 4) & 0x0F)
+ + hex_tab.charAt( x & 0x0F);
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+ try { b64pad } catch(e) { b64pad=''; }
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var output = "";
+ var len = input.length;
+ for(var i = 0; i < len; i += 3)
+ {
+ var triplet = (input.charCodeAt(i) << 16)
+ | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+ | (i + 2 < len ? input.charCodeAt(i+2) : 0);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+ else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+ }
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+ var divisor = encoding.length;
+ var remainders = Array();
+ var i, q, x, quotient;
+
+ /* Convert to an array of 16-bit big-endian values, forming the dividend */
+ var dividend = Array(Math.ceil(input.length / 2));
+ for(i = 0; i < dividend.length; i++)
+ {
+ dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+ }
+
+ /*
+ * Repeatedly perform a long division. The binary array forms the dividend,
+ * the length of the encoding is the divisor. Once computed, the quotient
+ * forms the dividend for the next step. We stop when the dividend is zero.
+ * All remainders are stored for later use.
+ */
+ while(dividend.length > 0)
+ {
+ quotient = Array();
+ x = 0;
+ for(i = 0; i < dividend.length; i++)
+ {
+ x = (x << 16) + dividend[i];
+ q = Math.floor(x / divisor);
+ x -= q * divisor;
+ if(quotient.length > 0 || q > 0)
+ quotient[quotient.length] = q;
+ }
+ remainders[remainders.length] = x;
+ dividend = quotient;
+ }
+
+ /* Convert the remainders to the output string */
+ var output = "";
+ for(i = remainders.length - 1; i >= 0; i--)
+ output += encoding.charAt(remainders[i]);
+
+ /* Append leading zero equivalents */
+ var full_length = Math.ceil(input.length * 8 /
+ (Math.log(encoding.length) / Math.log(2)))
+ for(i = output.length; i < full_length; i++)
+ output = encoding[0] + output;
+
+ return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+ var output = "";
+ var i = -1;
+ var x, y;
+
+ while(++i < input.length)
+ {
+ /* Decode utf-16 surrogate pairs */
+ x = input.charCodeAt(i);
+ y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+ if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+ {
+ x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+ i++;
+ }
+
+ /* Encode output as utf-8 */
+ if(x <= 0x7F)
+ output += String.fromCharCode(x);
+ else if(x <= 0x7FF)
+ output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0xFFFF)
+ output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0x1FFFFF)
+ output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+ 0x80 | ((x >>> 12) & 0x3F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ }
+ return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length; i++)
+ output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
+ (input.charCodeAt(i) >>> 8) & 0xFF);
+ return output;
+}
+
+function str2rstr_utf16be(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length; i++)
+ output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+ input.charCodeAt(i) & 0xFF);
+ return output;
+}
+
+/*
+ * Convert a raw string to an array of big-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binb(input)
+{
+ var output = Array(input.length >> 2);
+ for(var i = 0; i < output.length; i++)
+ output[i] = 0;
+ for(var i = 0; i < input.length * 8; i += 8)
+ output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
+ return output;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+function binb2rstr(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length * 32; i += 8)
+ output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
+ return output;
+}
+
+/*
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
+ */
+function binb_sha1(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << (24 - len % 32);
+ x[((len + 64 >> 9) << 4) + 15] = len;
+
+ var w = Array(80);
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+ var e = -1009589776;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+ var olde = e;
+
+ for(var j = 0; j < 80; j++)
+ {
+ if(j < 16) w[j] = x[i + j];
+ else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
+ var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
+ safe_add(safe_add(e, w[j]), sha1_kt(j)));
+ e = d;
+ d = c;
+ c = bit_rol(b, 30);
+ b = a;
+ a = t;
+ }
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ e = safe_add(e, olde);
+ }
+ return Array(a, b, c, d, e);
+
+}
+
+/*
+ * Perform the appropriate triplet combination function for the current
+ * iteration
+ */
+function sha1_ft(t, b, c, d)
+{
+ if(t < 20) return (b & c) | ((~b) & d);
+ if(t < 40) return b ^ c ^ d;
+ if(t < 60) return (b & c) | (b & d) | (c & d);
+ return b ^ c ^ d;
+}
+
+/*
+ * Determine the appropriate additive constant for the current iteration
+ */
+function sha1_kt(t)
+{
+ return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
+ (t < 60) ? -1894007588 : -899497514;
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
View
109 lib/commonjs-utils/lib/xml-rpc.js
@@ -0,0 +1,109 @@
+var XMLHttpRequest = require("browser/xhr").XMLHttpRequest;
+exports.XmlRpc = function(target){
+ return function(methodName, params){
+ var xml = '<?xml version="1.0"?><methodCall><methodName>' + methodName +
+ '</methodName><params>' +
+ params.map(function(param){
+ return '<param>' + valueToXml(param) + '</param>';
+ }).join("") + '</params></methodCall>\n\n';
+
+ var xhr = new XMLHttpRequest();
+ xhr.open("POST", target, false);
+ xhr.setRequestHeader("Content-Type", "application/xml");
+ xhr.send(xml);
+ if(xhr.status >= 300){
+ throw new Error(xhr.responseText);
+ }
+ var xml = xhr.responseXML;
+ var fault = xml.getElementsByTagName("fault").item(0);
+ if(fault){
+ fault = xmlToValue(fault.firstChild);
+ throw new Error(fault.faultString + " code: " + fault.faultCode);
+ }
+ var param = xml.getElementsByTagName("param").item(0);
+ return xmlToValue(param.firstChild);
+ };
+ function valueToXml(value){
+ var valueString = "<value>";
+ switch(typeof value){
+ case "number" :
+ if(value % 1 == 0){
+ valueString += '<i4>' + value + '</i4>';
+ }
+ else{
+ valueString += '<double>' + value + '</double>';
+ }
+ break;
+ case "string" :
+ valueString += '<string>' + value + '</string>';
+ break;
+ case "boolean" :
+ valueString += '<boolean>' + (value ? 1 : 0) + '</boolean>';
+ break;
+ case "object" :
+ if(value instanceof Date){
+ // must be doing something wrong here, can't seem to get that to be handled by a server
+ //valueString += '<dateTime.iso8601>' + JSON.parse(JSON.stringify(value)) + '</dateTime.iso8601>';
+ }
+ else if (value instanceof Array){
+ valueString += '<array><data>';
+ for(var i = 0; i < value.length; i++){
+ valueString += valueToXml(value[i]);
+ }
+ valueString += '</data></array>';
+ }
+ else{
+ valueString += '<struct>';
+ for(var i in value){
+ valueString += '<member><name>' + i + '</name>' + valueToXml(value[i]) + '</member>';
+ }
+ valueString += '</struct>';
+ }
+ }
+ return valueString + "</value>";
+ }
+ function xmlToValue(node){
+ var value = node.firstChild;
+ if(!value){
+ return value;
+ }
+ if(value.nodeType == 3){
+ return value.nodeValue;
+ }
+ switch(value.tagName){
+ case "string":
+ return value.textContent;
+ case "i4": case "int":
+ return parseInt(value.textContent, 10);
+ case "double":
+ return parseFloat(value.textContent, 10);
+ case "boolean":
+ return !!parseInt(value.textContent,10);
+ case "struct":
+ var members = value.childNodes;
+ var object = {};
+ for(var i = 0; i < members.length; i++){
+ var member = members.item(i);
+ var name = childElementByTagName(member, "name").textContent;
+ var memberValue = childElementByTagName(member, "value");
+ object[name] = xmlToValue(memberValue);
+ }
+ return object;
+ case "array":
+ var members = value.firstChild.childNodes;
+ var array = [];
+ for(var i = 0; i < members.length; i++){
+ array[i] = xmlToValue(members.item(i));
+ }
+ return array;
+ }
+ };
+ function childElementByTagName(parent, tagName){
+ var children = parent.childNodes;
+ for(var i = 0; i < children.length; i++){
+ if(children.item(i).tagName == tagName){
+ return children.item(i);
+ }
+ }
+ }
+}
View
15 lib/commonjs-utils/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "commonjs-utils",
+ "author": "Kris Zyp",
+ "dependencies": [],
+ "contributors": [],
+ "keywords": [
+ "json",
+ "schema",
+ "query"
+ ],
+ "engines": {"node":">=0.1.30", "rhino": true},
+ "githubName": "commonjs-utils",
+ "type": "zip",
+ "location": "http://github.com/kriszyp/commonjs-utils/zipball/master"
+}
View
4 support.js
@@ -4,6 +4,8 @@ require.paths.unshift(
, './lib/express/lib'
, './lib/ejs/lib'
, './lib/socket.io/lib'
+ , './lib/commonjs-utils/lib'
);
-express = require('express');
+express = require('express');
+JSON = require('json');

0 comments on commit 160c505

Please sign in to comment.