From 9f67942c040f973a05057e8a775c3d22a5a93ceb Mon Sep 17 00:00:00 2001 From: Christopher Rogers Date: Wed, 7 May 2014 11:20:17 -0700 Subject: [PATCH] Adds component tracking and pins components Switches querystring components node-querystring is stable enough and contains needed features without having to maintain yet another querystring module Signed-off-by: Christopher Rogers --- .gitignore | 1 - component.json | 39 +- .../chrissrogers-promise/component.json | 17 + components/chrissrogers-promise/core.js | 105 +++++ components/chrissrogers-promise/index.js | 180 +++++++++ components/component-bind/component.json | 14 + components/component-bind/index.js | 24 ++ components/component-clone/component.json | 15 + components/component-clone/index.js | 57 +++ components/component-each/component.json | 21 + components/component-each/index.js | 84 ++++ components/component-emitter/component.json | 14 + components/component-emitter/index.js | 164 ++++++++ components/component-event/component.json | 13 + components/component-event/index.js | 35 ++ components/component-find/component.json | 18 + components/component-find/index.js | 45 +++ components/component-indexof/component.json | 18 + components/component-indexof/index.js | 7 + components/component-json/component.json | 17 + components/component-json/index.js | 4 + components/component-map/component.json | 18 + components/component-map/index.js | 24 ++ components/component-props/component.json | 18 + components/component-props/index.js | 85 ++++ .../component-to-function/component.json | 17 + components/component-to-function/index.js | 128 ++++++ components/component-type/component.json | 18 + components/component-type/index.js | 30 ++ .../danmilon-object.keys-shim/component.json | 17 + components/danmilon-object.keys-shim/index.js | 44 +++ components/johntron-asap/asap.js | 128 ++++++ components/johntron-asap/component.json | 18 + components/kewah-mixin/component.json | 14 + components/kewah-mixin/index.js | 15 + components/learnboost-jsonp/component.json | 13 + components/learnboost-jsonp/index.js | 84 ++++ components/pluma-par/component.json | 24 ++ components/pluma-par/dist/par.js | 27 ++ components/visionmedia-debug/component.json | 16 + components/visionmedia-debug/debug.js | 137 +++++++ .../component.json | 15 + .../visionmedia-node-querystring/index.js | 366 ++++++++++++++++++ components/yields-merge/component.json | 17 + components/yields-merge/index.js | 19 + 45 files changed, 2163 insertions(+), 21 deletions(-) create mode 100644 components/chrissrogers-promise/component.json create mode 100644 components/chrissrogers-promise/core.js create mode 100644 components/chrissrogers-promise/index.js create mode 100644 components/component-bind/component.json create mode 100644 components/component-bind/index.js create mode 100644 components/component-clone/component.json create mode 100644 components/component-clone/index.js create mode 100644 components/component-each/component.json create mode 100644 components/component-each/index.js create mode 100644 components/component-emitter/component.json create mode 100644 components/component-emitter/index.js create mode 100644 components/component-event/component.json create mode 100644 components/component-event/index.js create mode 100644 components/component-find/component.json create mode 100644 components/component-find/index.js create mode 100644 components/component-indexof/component.json create mode 100644 components/component-indexof/index.js create mode 100644 components/component-json/component.json create mode 100644 components/component-json/index.js create mode 100644 components/component-map/component.json create mode 100644 components/component-map/index.js create mode 100644 components/component-props/component.json create mode 100644 components/component-props/index.js create mode 100644 components/component-to-function/component.json create mode 100644 components/component-to-function/index.js create mode 100644 components/component-type/component.json create mode 100644 components/component-type/index.js create mode 100644 components/danmilon-object.keys-shim/component.json create mode 100644 components/danmilon-object.keys-shim/index.js create mode 100644 components/johntron-asap/asap.js create mode 100644 components/johntron-asap/component.json create mode 100644 components/kewah-mixin/component.json create mode 100644 components/kewah-mixin/index.js create mode 100644 components/learnboost-jsonp/component.json create mode 100644 components/learnboost-jsonp/index.js create mode 100644 components/pluma-par/component.json create mode 100644 components/pluma-par/dist/par.js create mode 100644 components/visionmedia-debug/component.json create mode 100644 components/visionmedia-debug/debug.js create mode 100644 components/visionmedia-node-querystring/component.json create mode 100644 components/visionmedia-node-querystring/index.js create mode 100644 components/yields-merge/component.json create mode 100644 components/yields-merge/index.js diff --git a/.gitignore b/.gitignore index 814e6faa6..2ce3e8a1e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ node_modules npm-debug.log build -components test/server/pid.txt diff --git a/component.json b/component.json index 7185a323d..4551f0957 100644 --- a/component.json +++ b/component.json @@ -1,6 +1,6 @@ { "name": "recurly", - "repo": "recurly/recurly-js", + "repository": "recurly/recurly-js", "description": "Official Recurly JavaScript client for the browser.", "version": "3.0.0-beta", "keywords": [ @@ -10,23 +10,23 @@ "main": "lib/index.js", "dependencies": { "danmilon/object.keys-shim": "*", - "chrissrogers/querystring": "*", - "component/emitter": "*", - "component/indexof": "*", - "component/event": "*", - "component/clone": "*", - "component/bind": "*", - "component/each": "*", - "component/find": "*", - "component/json": "*", - "component/type": "*", - "component/map": "*", - "yields/merge": "*", - "learnboost/jsonp": "*", - "visionmedia/debug": "*", - "chrissrogers/promise": "*", - "kewah/mixin": "*", - "pluma/par": "*" + "visionmedia/node-querystring": "0.6.6", + "component/emitter": "1.1.2", + "component/indexof": "0.0.3", + "component/event": "0.1.3", + "component/clone": "0.2.2", + "component/bind": "0.0.1", + "component/each": "0.2.3", + "component/find": "0.0.1", + "component/json": "0.0.2", + "component/type": "1.0.0", + "component/map": "0.0.1", + "yields/merge": "1.0.0", + "learnboost/jsonp": "0.0.4", + "visionmedia/debug": "0.8.1", + "chrissrogers/promise": "5.0.0-p1", + "kewah/mixin": "0.1.0", + "pluma/par": "0.3.0" }, "scripts": [ "lib/index.js", @@ -45,6 +45,5 @@ "lib/mixins/pricing/promise.js", "lib/mixins/pricing/calculations.js", "lib/mixins/pricing/attach.js" - ], - "remotes": [] + ] } diff --git a/components/chrissrogers-promise/component.json b/components/chrissrogers-promise/component.json new file mode 100644 index 000000000..462b5d9b7 --- /dev/null +++ b/components/chrissrogers-promise/component.json @@ -0,0 +1,17 @@ +{ + "name": "promise", + "repo": "chrissrogers/promise", + "description": "Bare bones Promises/A+ implementation", + "version": "5.0.0-p0", + "keywords": [], + "dependencies": { + "johntron/asap": "*" + }, + "development": {}, + "license": "MIT", + "scripts": [ + "index.js", + "core.js" + ], + "twitter": "@ForbesLindesay" +} \ No newline at end of file diff --git a/components/chrissrogers-promise/core.js b/components/chrissrogers-promise/core.js new file mode 100644 index 000000000..416020ef3 --- /dev/null +++ b/components/chrissrogers-promise/core.js @@ -0,0 +1,105 @@ +'use strict'; + +var asap = require('asap') + +module.exports = Promise +function Promise(fn) { + if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new') + if (typeof fn !== 'function') throw new TypeError('not a function') + var state = null + var value = null + var deferreds = [] + var self = this + + this.then = function(onFulfilled, onRejected) { + return new self.constructor(function(resolve, reject) { + handle(new Handler(onFulfilled, onRejected, resolve, reject)) + }) + } + + function handle(deferred) { + if (state === null) { + deferreds.push(deferred) + return + } + asap(function() { + var cb = state ? deferred.onFulfilled : deferred.onRejected + if (cb === null) { + (state ? deferred.resolve : deferred.reject)(value) + return + } + var ret + try { + ret = cb(value) + } + catch (e) { + deferred.reject(e) + return + } + deferred.resolve(ret) + }) + } + + function resolve(newValue) { + try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.') + if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { + var then = newValue.then + if (typeof then === 'function') { + doResolve(then.bind(newValue), resolve, reject) + return + } + } + state = true + value = newValue + finale() + } catch (e) { reject(e) } + } + + function reject(newValue) { + state = false + value = newValue + finale() + } + + function finale() { + for (var i = 0, len = deferreds.length; i < len; i++) + handle(deferreds[i]) + deferreds = null + } + + doResolve(fn, resolve, reject) +} + + +function Handler(onFulfilled, onRejected, resolve, reject){ + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null + this.onRejected = typeof onRejected === 'function' ? onRejected : null + this.resolve = resolve + this.reject = reject +} + +/** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ +function doResolve(fn, onFulfilled, onRejected) { + var done = false; + try { + fn(function (value) { + if (done) return + done = true + onFulfilled(value) + }, function (reason) { + if (done) return + done = true + onRejected(reason) + }) + } catch (ex) { + if (done) return + done = true + onRejected(ex) + } +} diff --git a/components/chrissrogers-promise/index.js b/components/chrissrogers-promise/index.js new file mode 100644 index 000000000..d96b7fce6 --- /dev/null +++ b/components/chrissrogers-promise/index.js @@ -0,0 +1,180 @@ +'use strict'; + +//This file contains then/promise specific extensions to the core promise API + +var Promise = require('./core.js') +var asap = require('asap') + +module.exports = Promise + +/* Static Functions */ + +function ValuePromise(value) { + this.then = function (onFulfilled) { + if (typeof onFulfilled !== 'function') return this + return new Promise(function (resolve, reject) { + asap(function () { + try { + resolve(onFulfilled(value)) + } catch (ex) { + reject(ex); + } + }) + }) + } +} +ValuePromise.prototype = Object.create(Promise.prototype) + +var TRUE = new ValuePromise(true) +var FALSE = new ValuePromise(false) +var NULL = new ValuePromise(null) +var UNDEFINED = new ValuePromise(undefined) +var ZERO = new ValuePromise(0) +var EMPTYSTRING = new ValuePromise('') + +Promise.resolve = function (value) { + if (value instanceof Promise) return value + + if (value === null) return NULL + if (value === undefined) return UNDEFINED + if (value === true) return TRUE + if (value === false) return FALSE + if (value === 0) return ZERO + if (value === '') return EMPTYSTRING + + if (typeof value === 'object' || typeof value === 'function') { + try { + var then = value.then + if (typeof then === 'function') { + return new Promise(then.bind(value)) + } + } catch (ex) { + return new Promise(function (resolve, reject) { + reject(ex) + }) + } + } + + return new ValuePromise(value) +} + +Promise.from = Promise.cast = function (value) { + var err = new Error('Promise.from and Promise.cast are deprecated, use Promise.resolve instead') + err.name = 'Warning' + console.warn(err.stack) + return Promise.resolve(value) +} + +Promise.denodeify = function (fn, argumentCount) { + argumentCount = argumentCount || Infinity + return function () { + var self = this + var args = Array.prototype.slice.call(arguments) + return new Promise(function (resolve, reject) { + while (args.length && args.length > argumentCount) { + args.pop() + } + args.push(function (err, res) { + if (err) reject(err) + else resolve(res) + }) + fn.apply(self, args) + }) + } +} +Promise.nodeify = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments) + var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null + try { + return fn.apply(this, arguments).nodeify(callback) + } catch (ex) { + if (callback === null || typeof callback == 'undefined') { + return new Promise(function (resolve, reject) { reject(ex) }) + } else { + asap(function () { + callback(ex) + }) + } + } + } +} + +Promise.all = function () { + var calledWithArray = arguments.length === 1 && Array.isArray(arguments[0]) + var args = Array.prototype.slice.call(calledWithArray ? arguments[0] : arguments) + + if (!calledWithArray) { + var err = new Error('Promise.all should be called with a single array, calling it with multiple arguments is deprecated') + err.name = 'Warning' + console.warn(err.stack) + } + + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]) + var remaining = args.length + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then + if (typeof then === 'function') { + then.call(val, function (val) { res(i, val) }, reject) + return + } + } + args[i] = val + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex) + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]) + } + }) +} + +Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); +} + +Promise.race = function (values) { + return new Promise(function (resolve, reject) { + values.forEach(function(value){ + Promise.resolve(value).then(resolve, reject); + }) + }); +} + +/* Prototype Methods */ + +Promise.prototype.done = function (onFulfilled, onRejected) { + var self = arguments.length ? this.then.apply(this, arguments) : this + self.then(null, function (err) { + asap(function () { + throw err + }) + }) +} + +Promise.prototype.nodeify = function (callback) { + if (typeof callback != 'function') return this + + this.then(function (value) { + asap(function () { + callback(null, value) + }) + }, function (err) { + asap(function () { + callback(err) + }) + }) +} + +Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); +} diff --git a/components/component-bind/component.json b/components/component-bind/component.json new file mode 100644 index 000000000..495962226 --- /dev/null +++ b/components/component-bind/component.json @@ -0,0 +1,14 @@ +{ + "name": "bind", + "version": "0.0.1", + "description": "function binding utility", + "keywords": [ + "bind", + "utility" + ], + "dependencies": {}, + "scripts": [ + "index.js" + ], + "repo": "https://raw.githubusercontent.com/component/bind" +} \ No newline at end of file diff --git a/components/component-bind/index.js b/components/component-bind/index.js new file mode 100644 index 000000000..9808fc06b --- /dev/null +++ b/components/component-bind/index.js @@ -0,0 +1,24 @@ + +/** + * Slice reference. + */ + +var slice = [].slice; + +/** + * Bind `obj` to `fn`. + * + * @param {Object} obj + * @param {Function|String} fn or string + * @return {Function} + * @api public + */ + +module.exports = function(obj, fn){ + if ('string' == typeof fn) fn = obj[fn]; + if ('function' != typeof fn) throw new Error('bind() requires a function'); + var args = [].slice.call(arguments, 2); + return function(){ + return fn.apply(obj, args.concat(slice.call(arguments))); + } +}; diff --git a/components/component-clone/component.json b/components/component-clone/component.json new file mode 100644 index 000000000..c1d50d506 --- /dev/null +++ b/components/component-clone/component.json @@ -0,0 +1,15 @@ +{ + "name": "clone", + "repo": "component/clone", + "version": "0.2.2", + "dependencies": { + "component/type": "*" + }, + "devDependencies": { + "visionmedia/mocha": "*", + "guille/expect.js": "*" + }, + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-clone/index.js b/components/component-clone/index.js new file mode 100644 index 000000000..a74bc22bd --- /dev/null +++ b/components/component-clone/index.js @@ -0,0 +1,57 @@ +/** + * Module dependencies. + */ + +var type; +try { + type = require('component-type'); +} catch (_) { + type = require('type'); +} + +/** + * Module exports. + */ + +module.exports = clone; + +/** + * Clones objects. + * + * @param {Mixed} any object + * @api public + */ + +function clone(obj){ + switch (type(obj)) { + case 'object': + var copy = {}; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + copy[key] = clone(obj[key]); + } + } + return copy; + + case 'array': + var copy = new Array(obj.length); + for (var i = 0, l = obj.length; i < l; i++) { + copy[i] = clone(obj[i]); + } + return copy; + + case 'regexp': + // from millermedeiros/amd-utils - MIT + var flags = ''; + flags += obj.multiline ? 'm' : ''; + flags += obj.global ? 'g' : ''; + flags += obj.ignoreCase ? 'i' : ''; + return new RegExp(obj.source, flags); + + case 'date': + return new Date(obj.getTime()); + + default: // string, number, boolean, … + return obj; + } +} diff --git a/components/component-each/component.json b/components/component-each/component.json new file mode 100644 index 000000000..ff894c626 --- /dev/null +++ b/components/component-each/component.json @@ -0,0 +1,21 @@ +{ + "name": "each", + "repo": "component/each", + "description": "Array / object / string iteration utility", + "version": "0.2.3", + "keywords": [ + "object", + "string", + "array", + "each", + "utility" + ], + "dependencies": { + "component/to-function": "2.0.0", + "component/type": "1.0.0" + }, + "development": {}, + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-each/index.js b/components/component-each/index.js new file mode 100644 index 000000000..1d0b0e647 --- /dev/null +++ b/components/component-each/index.js @@ -0,0 +1,84 @@ + +/** + * Module dependencies. + */ + +var type = require('type'); +var toFunction = require('to-function'); + +/** + * HOP reference. + */ + +var has = Object.prototype.hasOwnProperty; + +/** + * Iterate the given `obj` and invoke `fn(val, i)` + * in optional context `ctx`. + * + * @param {String|Array|Object} obj + * @param {Function} fn + * @param {Object} [ctx] + * @api public + */ + +module.exports = function(obj, fn, ctx){ + fn = toFunction(fn); + ctx = ctx || this; + switch (type(obj)) { + case 'array': + return array(obj, fn, ctx); + case 'object': + if ('number' == typeof obj.length) return array(obj, fn, ctx); + return object(obj, fn, ctx); + case 'string': + return string(obj, fn, ctx); + } +}; + +/** + * Iterate string chars. + * + * @param {String} obj + * @param {Function} fn + * @param {Object} ctx + * @api private + */ + +function string(obj, fn, ctx) { + for (var i = 0; i < obj.length; ++i) { + fn.call(ctx, obj.charAt(i), i); + } +} + +/** + * Iterate object keys. + * + * @param {Object} obj + * @param {Function} fn + * @param {Object} ctx + * @api private + */ + +function object(obj, fn, ctx) { + for (var key in obj) { + if (has.call(obj, key)) { + fn.call(ctx, key, obj[key]); + } + } +} + +/** + * Iterate array-ish. + * + * @param {Array|Object} obj + * @param {Function} fn + * @param {Object} ctx + * @api private + */ + +function array(obj, fn, ctx) { + for (var i = 0; i < obj.length; ++i) { + fn.call(ctx, obj[i], i); + } +} diff --git a/components/component-emitter/component.json b/components/component-emitter/component.json new file mode 100644 index 000000000..9a4ba9f1a --- /dev/null +++ b/components/component-emitter/component.json @@ -0,0 +1,14 @@ +{ + "name": "emitter", + "repo": "component/emitter", + "description": "Event emitter", + "keywords": [ + "emitter", + "events" + ], + "version": "1.1.2", + "scripts": [ + "index.js" + ], + "license": "MIT" +} \ No newline at end of file diff --git a/components/component-emitter/index.js b/components/component-emitter/index.js new file mode 100644 index 000000000..ad711633a --- /dev/null +++ b/components/component-emitter/index.js @@ -0,0 +1,164 @@ + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; diff --git a/components/component-event/component.json b/components/component-event/component.json new file mode 100644 index 000000000..889f8010e --- /dev/null +++ b/components/component-event/component.json @@ -0,0 +1,13 @@ +{ + "name": "event", + "repo": "component/event", + "description": "Event binding component", + "version": "0.1.3", + "keywords": [ + "event", + "events" + ], + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-event/index.js b/components/component-event/index.js new file mode 100644 index 000000000..ef05d5c4e --- /dev/null +++ b/components/component-event/index.js @@ -0,0 +1,35 @@ +var bind = window.addEventListener ? 'addEventListener' : 'attachEvent', + unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent', + prefix = bind !== 'addEventListener' ? 'on' : ''; + +/** + * Bind `el` event `type` to `fn`. + * + * @param {Element} el + * @param {String} type + * @param {Function} fn + * @param {Boolean} capture + * @return {Function} + * @api public + */ + +exports.bind = function(el, type, fn, capture){ + el[bind](prefix + type, fn, capture || false); + return fn; +}; + +/** + * Unbind `el` event `type`'s callback `fn`. + * + * @param {Element} el + * @param {String} type + * @param {Function} fn + * @param {Boolean} capture + * @return {Function} + * @api public + */ + +exports.unbind = function(el, type, fn, capture){ + el[unbind](prefix + type, fn, capture || false); + return fn; +}; \ No newline at end of file diff --git a/components/component-find/component.json b/components/component-find/component.json new file mode 100644 index 000000000..ae228084c --- /dev/null +++ b/components/component-find/component.json @@ -0,0 +1,18 @@ +{ + "name": "find", + "repo": "component/find", + "description": "Array find first value utility", + "version": "0.0.1", + "keywords": [ + "array", + "find", + "utility" + ], + "dependencies": { + "component/to-function": "*" + }, + "development": {}, + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-find/index.js b/components/component-find/index.js new file mode 100644 index 000000000..ffdeeba69 --- /dev/null +++ b/components/component-find/index.js @@ -0,0 +1,45 @@ + +/** + * Module dependencies. + */ + +var toFunction = require('to-function'); + +/** + * Find the first value in `arr` with when `fn(val, i)` is truthy. + * + * @param {Array} arr + * @param {Function} fn + * @return {Array} + * @api public + */ + +module.exports = function(arr, fn){ + // callback + if ('function' != typeof fn) { + if (Object(fn) === fn) fn = objectToFunction(fn); + else fn = toFunction(fn); + } + + // filter + for (var i = 0, len = arr.length; i < len; ++i) { + if (fn(arr[i], i)) return arr[i]; + } +}; + +/** + * Convert `obj` into a match function. + * + * @param {Object} obj + * @return {Function} + * @api private + */ + +function objectToFunction(obj) { + return function(o){ + for (var key in obj) { + if (o[key] != obj[key]) return false; + } + return true; + } +} \ No newline at end of file diff --git a/components/component-indexof/component.json b/components/component-indexof/component.json new file mode 100644 index 000000000..1a5f796b7 --- /dev/null +++ b/components/component-indexof/component.json @@ -0,0 +1,18 @@ +{ + "name": "indexof", + "description": "Microsoft sucks", + "version": "0.0.3", + "keywords": [ + "index", + "array", + "indexOf" + ], + "dependencies": {}, + "development": { + "component/assert": "*" + }, + "scripts": [ + "index.js" + ], + "repo": "https://raw.githubusercontent.com/component/indexof" +} \ No newline at end of file diff --git a/components/component-indexof/index.js b/components/component-indexof/index.js new file mode 100644 index 000000000..7f6005cce --- /dev/null +++ b/components/component-indexof/index.js @@ -0,0 +1,7 @@ +module.exports = function(arr, obj){ + if (arr.indexOf) return arr.indexOf(obj); + for (var i = 0; i < arr.length; ++i) { + if (arr[i] === obj) return i; + } + return -1; +}; \ No newline at end of file diff --git a/components/component-json/component.json b/components/component-json/component.json new file mode 100644 index 000000000..003b22f05 --- /dev/null +++ b/components/component-json/component.json @@ -0,0 +1,17 @@ +{ + "name": "json", + "repo": "component/json", + "description": "JSON parser / stringifier", + "version": "0.0.2", + "keywords": [ + "json" + ], + "dependencies": {}, + "development": {}, + "optional": { + "component/json-fallback": "*" + }, + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-json/index.js b/components/component-json/index.js new file mode 100644 index 000000000..11e0732ab --- /dev/null +++ b/components/component-json/index.js @@ -0,0 +1,4 @@ + +module.exports = 'undefined' == typeof JSON + ? require('component-json-fallback') + : JSON; diff --git a/components/component-map/component.json b/components/component-map/component.json new file mode 100644 index 000000000..c99837114 --- /dev/null +++ b/components/component-map/component.json @@ -0,0 +1,18 @@ +{ + "name": "map", + "repo": "component/map", + "description": "Array map utility", + "version": "0.0.1", + "keywords": [ + "array", + "map", + "utility" + ], + "dependencies": { + "component/to-function": "*" + }, + "development": {}, + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-map/index.js b/components/component-map/index.js new file mode 100644 index 000000000..875a6d178 --- /dev/null +++ b/components/component-map/index.js @@ -0,0 +1,24 @@ + +/** + * Module dependencies. + */ + +var toFunction = require('to-function'); + +/** + * Map the given `arr` with callback `fn(val, i)`. + * + * @param {Array} arr + * @param {Function} fn + * @return {Array} + * @api public + */ + +module.exports = function(arr, fn){ + var ret = []; + fn = toFunction(fn); + for (var i = 0; i < arr.length; ++i) { + ret.push(fn(arr[i], i)); + } + return ret; +}; \ No newline at end of file diff --git a/components/component-props/component.json b/components/component-props/component.json new file mode 100644 index 000000000..e6c2219b8 --- /dev/null +++ b/components/component-props/component.json @@ -0,0 +1,18 @@ +{ + "name": "props", + "repo": "component/props", + "description": "Parse immediate identifiers from a js expression", + "version": "1.1.1", + "keywords": [ + "template", + "engine", + "parse", + "parser" + ], + "dependencies": {}, + "development": {}, + "license": "MIT", + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-props/index.js b/components/component-props/index.js new file mode 100644 index 000000000..3bf657d31 --- /dev/null +++ b/components/component-props/index.js @@ -0,0 +1,85 @@ +/** + * Global Names + */ + +var globals = /\b(this|Array|Date|Object|Math|JSON)\b/g; + +/** + * Return immediate identifiers parsed from `str`. + * + * @param {String} str + * @param {String|Function} map function or prefix + * @return {Array} + * @api public + */ + +module.exports = function(str, fn){ + var p = unique(props(str)); + if (fn && 'string' == typeof fn) fn = prefixed(fn); + if (fn) return map(str, p, fn); + return p; +}; + +/** + * Return immediate identifiers in `str`. + * + * @param {String} str + * @return {Array} + * @api private + */ + +function props(str) { + return str + .replace(/\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\//g, '') + .replace(globals, '') + .match(/[$a-zA-Z_]\w*/g) + || []; +} + +/** + * Return `str` with `props` mapped with `fn`. + * + * @param {String} str + * @param {Array} props + * @param {Function} fn + * @return {String} + * @api private + */ + +function map(str, props, fn) { + var re = /\.\w+|\w+ *\(|"[^"]*"|'[^']*'|\/([^/]+)\/|[a-zA-Z_]\w*/g; + return str.replace(re, function(_){ + if ('(' == _[_.length - 1]) return fn(_); + if (!~props.indexOf(_)) return _; + return fn(_); + }); +} + +/** + * Return unique array. + * + * @param {Array} arr + * @return {Array} + * @api private + */ + +function unique(arr) { + var ret = []; + + for (var i = 0; i < arr.length; i++) { + if (~ret.indexOf(arr[i])) continue; + ret.push(arr[i]); + } + + return ret; +} + +/** + * Map with prefix `str`. + */ + +function prefixed(str) { + return function(_){ + return str + _; + }; +} diff --git a/components/component-to-function/component.json b/components/component-to-function/component.json new file mode 100644 index 000000000..df0ae0e0e --- /dev/null +++ b/components/component-to-function/component.json @@ -0,0 +1,17 @@ +{ + "name": "to-function", + "repo": "component/to-function", + "description": "Convert property access strings into functions", + "version": "2.0.2", + "keywords": [ + "utility", + "function" + ], + "dependencies": { + "component/props": "*" + }, + "development": {}, + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/component-to-function/index.js b/components/component-to-function/index.js new file mode 100644 index 000000000..e9ca93e09 --- /dev/null +++ b/components/component-to-function/index.js @@ -0,0 +1,128 @@ +/** + * Module Dependencies + */ +try { + var expr = require('props'); +} catch(e) { + var expr = require('component-props'); +} + +/** + * Expose `toFunction()`. + */ + +module.exports = toFunction; + +/** + * Convert `obj` to a `Function`. + * + * @param {Mixed} obj + * @return {Function} + * @api private + */ + +function toFunction(obj) { + switch ({}.toString.call(obj)) { + case '[object Object]': + return objectToFunction(obj); + case '[object Function]': + return obj; + case '[object String]': + return stringToFunction(obj); + case '[object RegExp]': + return regexpToFunction(obj); + default: + return defaultToFunction(obj); + } +} + +/** + * Default to strict equality. + * + * @param {Mixed} val + * @return {Function} + * @api private + */ + +function defaultToFunction(val) { + return function(obj){ + return val === obj; + } +} + +/** + * Convert `re` to a function. + * + * @param {RegExp} re + * @return {Function} + * @api private + */ + +function regexpToFunction(re) { + return function(obj){ + return re.test(obj); + } +} + +/** + * Convert property `str` to a function. + * + * @param {String} str + * @return {Function} + * @api private + */ + +function stringToFunction(str) { + // immediate such as "> 20" + if (/^ *\W+/.test(str)) return new Function('_', 'return _ ' + str); + + // properties such as "name.first" or "age > 18" or "age > 18 && age < 36" + return new Function('_', 'return ' + get(str)); +} + +/** + * Convert `object` to a function. + * + * @param {Object} object + * @return {Function} + * @api private + */ + +function objectToFunction(obj) { + var match = {} + for (var key in obj) { + match[key] = typeof obj[key] === 'string' + ? defaultToFunction(obj[key]) + : toFunction(obj[key]) + } + return function(val){ + if (typeof val !== 'object') return false; + for (var key in match) { + if (!(key in val)) return false; + if (!match[key](val[key])) return false; + } + return true; + } +} + +/** + * Built the getter function. Supports getter style functions + * + * @param {String} str + * @return {String} + * @api private + */ + +function get(str) { + var props = expr(str); + if (!props.length) return '_.' + str; + + var val; + for(var i = 0, prop; prop = props[i]; i++) { + val = '_.' + prop; + val = "('function' == typeof " + val + " ? " + val + "() : " + val + ")"; + str = str.replace(new RegExp(prop, 'g'), val); + } + + return str; +} diff --git a/components/component-type/component.json b/components/component-type/component.json new file mode 100644 index 000000000..f186f0634 --- /dev/null +++ b/components/component-type/component.json @@ -0,0 +1,18 @@ +{ + "name": "type", + "description": "Cross-browser type assertions (less broken typeof)", + "version": "1.0.0", + "keywords": [ + "typeof", + "type", + "utility" + ], + "dependencies": {}, + "development": { + "component/assert": "*" + }, + "scripts": [ + "index.js" + ], + "repo": "https://raw.githubusercontent.com/component/type" +} \ No newline at end of file diff --git a/components/component-type/index.js b/components/component-type/index.js new file mode 100644 index 000000000..40998e430 --- /dev/null +++ b/components/component-type/index.js @@ -0,0 +1,30 @@ +/** + * toString ref. + */ + +var toString = Object.prototype.toString; + +/** + * Return the type of `val`. + * + * @param {Mixed} val + * @return {String} + * @api public + */ + +module.exports = function(val){ + switch (toString.call(val)) { + case '[object Date]': return 'date'; + case '[object RegExp]': return 'regexp'; + case '[object Arguments]': return 'arguments'; + case '[object Array]': return 'array'; + case '[object Error]': return 'error'; + } + + if (val === null) return 'null'; + if (val === undefined) return 'undefined'; + if (val !== val) return 'nan'; + if (val && val.nodeType === 1) return 'element'; + + return typeof val.valueOf(); +}; diff --git a/components/danmilon-object.keys-shim/component.json b/components/danmilon-object.keys-shim/component.json new file mode 100644 index 000000000..45f614945 --- /dev/null +++ b/components/danmilon-object.keys-shim/component.json @@ -0,0 +1,17 @@ +{ + "name": "object.keys-shim", + "repo": "danmilon/object.keys-shim", + "description": "Object.keys shim", + "version": "0.0.1", + "keywords": [ + "object", + "keys", + "shim" + ], + "main": "index.js", + "scripts": [ + "index.js" + ], + "dependencies": {}, + "license": "MIT" +} \ No newline at end of file diff --git a/components/danmilon-object.keys-shim/index.js b/components/danmilon-object.keys-shim/index.js new file mode 100644 index 000000000..38e6fe198 --- /dev/null +++ b/components/danmilon-object.keys-shim/index.js @@ -0,0 +1,44 @@ +// grabbed from https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys +if (!Object.keys) { + Object.keys = (function () { + var has = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString') + + var dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ] + + var dontEnumsLength = dontEnums.length; + + return function (obj) { + if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) { + throw new TypeError('Object.keys called on non-object'); + } + + var result = []; + + for (var prop in obj) { + if (has.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (var i = 0; i < dontEnumsLength; i++) { + if (has.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } + } + return result; + } + })() +} + +module.exports = Object.keys diff --git a/components/johntron-asap/asap.js b/components/johntron-asap/asap.js new file mode 100644 index 000000000..20bae8931 --- /dev/null +++ b/components/johntron-asap/asap.js @@ -0,0 +1,128 @@ +"use strict"; + +// Use the fastest possible means to execute a task in a future turn +// of the event loop. + +// linked list of tasks (single, with head node) +var head = {task: void 0, next: null}; +var tail = head; +var flushing = false; +var requestFlush = void 0; +var hasSetImmediate = typeof setImmediate === "function"; +var domain; + +if (typeof global != 'undefined') { + // Avoid shims from browserify. + // The existence of `global` in browsers is guaranteed by browserify. + var process = global.process; +} + +// Note that some fake-Node environments, +// like the Mocha test runner, introduce a `process` global. +var isNodeJS = !!process && ({}).toString.call(process) === "[object process]"; + +function flush() { + /* jshint loopfunc: true */ + + while (head.next) { + head = head.next; + var task = head.task; + head.task = void 0; + + try { + task(); + + } catch (e) { + if (isNodeJS) { + // In node, uncaught exceptions are considered fatal errors. + // Re-throw them to interrupt flushing! + + // Ensure continuation if an uncaught exception is suppressed + // listening process.on("uncaughtException") or domain("error"). + requestFlush(); + + throw e; + + } else { + // In browsers, uncaught exceptions are not fatal. + // Re-throw them asynchronously to avoid slow-downs. + setTimeout(function () { + throw e; + }, 0); + } + } + } + + flushing = false; +} + +if (isNodeJS) { + // Node.js + requestFlush = function () { + // Ensure flushing is not bound to any domain. + var currentDomain = process.domain; + if (currentDomain) { + domain = domain || (1,require)("domain"); + domain.active = process.domain = null; + } + + // Avoid tick recursion - use setImmediate if it exists. + if (flushing && hasSetImmediate) { + setImmediate(flush); + } else { + process.nextTick(flush); + } + + if (currentDomain) { + domain.active = process.domain = currentDomain; + } + }; + +} else if (hasSetImmediate) { + // In IE10, or https://github.com/NobleJS/setImmediate + requestFlush = function () { + setImmediate(flush); + }; + +} else if (typeof MessageChannel !== "undefined") { + // modern browsers + // http://www.nonblocking.io/2011/06/windownexttick.html + var channel = new MessageChannel(); + // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create + // working message ports the first time a page loads. + channel.port1.onmessage = function () { + requestFlush = requestPortFlush; + channel.port1.onmessage = flush; + flush(); + }; + var requestPortFlush = function () { + // Opera requires us to provide a message payload, regardless of + // whether we use it. + channel.port2.postMessage(0); + }; + requestFlush = function () { + setTimeout(flush, 0); + requestPortFlush(); + }; + +} else { + // old browsers + requestFlush = function () { + setTimeout(flush, 0); + }; +} + +function asap(task) { + if (isNodeJS && process.domain) { + task = process.domain.bind(task); + } + + tail = tail.next = {task: task, next: null}; + + if (!flushing) { + requestFlush(); + flushing = true; + } +}; + +module.exports = asap; diff --git a/components/johntron-asap/component.json b/components/johntron-asap/component.json new file mode 100644 index 000000000..6b3d49acc --- /dev/null +++ b/components/johntron-asap/component.json @@ -0,0 +1,18 @@ +{ + "name": "asap", + "repo": "kriskowal/asap", + "description": "High-priority task queue for Node.js and browsers", + "version": "1.0.0", + "keywords": [ + "event", + "task", + "queue" + ], + "dependencies": {}, + "development": {}, + "license": "MIT", + "main": "asap.js", + "scripts": [ + "asap.js" + ] +} \ No newline at end of file diff --git a/components/kewah-mixin/component.json b/components/kewah-mixin/component.json new file mode 100644 index 000000000..220b072b1 --- /dev/null +++ b/components/kewah-mixin/component.json @@ -0,0 +1,14 @@ +{ + "name": "mixin", + "repo": "kewah/mixin", + "description": "ES5 compatible mixin", + "version": "0.1.0", + "keywords": [], + "dependencies": {}, + "development": {}, + "license": "MIT", + "main": "index.js", + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/kewah-mixin/index.js b/components/kewah-mixin/index.js new file mode 100644 index 000000000..d60fba66d --- /dev/null +++ b/components/kewah-mixin/index.js @@ -0,0 +1,15 @@ +if (typeof Object.keys === 'function') { + module.exports = function(to, from) { + Object.keys(from).forEach(function(property) { + Object.defineProperty(to, property, Object.getOwnPropertyDescriptor(from, property)); + }); + }; +} else { + module.exports = function(to, from) { + for (var property in from) { + if (from.hasOwnProperty(property)) { + to[property] = from[property]; + } + } + }; +} diff --git a/components/learnboost-jsonp/component.json b/components/learnboost-jsonp/component.json new file mode 100644 index 000000000..03eca566b --- /dev/null +++ b/components/learnboost-jsonp/component.json @@ -0,0 +1,13 @@ +{ + "name": "jsonp", + "repo": "learnboost/jsonp", + "description": "A sane JSONP implementation.", + "version": "0.0.4", + "dependencies": { + "visionmedia/debug": "*" + }, + "scripts": [ + "index.js" + ], + "main": "index.js" +} \ No newline at end of file diff --git a/components/learnboost-jsonp/index.js b/components/learnboost-jsonp/index.js new file mode 100644 index 000000000..159052b4b --- /dev/null +++ b/components/learnboost-jsonp/index.js @@ -0,0 +1,84 @@ +/** + * Module dependencies + */ + +var debug = require('debug')('jsonp'); + +/** + * Module exports. + */ + +module.exports = jsonp; + +/** + * Callback index. + */ + +var count = 0; + +/** + * Noop function. + */ + +function noop(){} + +/** + * JSONP handler + * + * Options: + * - param {String} qs parameter (`callback`) + * - timeout {Number} how long after a timeout error is emitted (`60000`) + * + * @param {String} url + * @param {Object|Function} optional options / callback + * @param {Function} optional callback + */ + +function jsonp(url, opts, fn){ + if ('function' == typeof opts) { + fn = opts; + opts = {}; + } + if (!opts) opts = {}; + + var prefix = opts.prefix || '__jp'; + var param = opts.param || 'callback'; + var timeout = null != opts.timeout ? opts.timeout : 60000; + var enc = encodeURIComponent; + var target = document.getElementsByTagName('script')[0] || document.head; + var script; + var timer; + + // generate a unique id for this request + var id = prefix + (count++); + + if (timeout) { + timer = setTimeout(function(){ + cleanup(); + if (fn) fn(new Error('Timeout')); + }, timeout); + } + + function cleanup(){ + script.parentNode.removeChild(script); + window[id] = noop; + } + + window[id] = function(data){ + debug('jsonp got', data); + if (timer) clearTimeout(timer); + cleanup(); + if (fn) fn(null, data); + }; + + // add qs component + url += (~url.indexOf('?') ? '&' : '?') + param + '=' + enc(id); + url = url.replace('?&', '?'); + + debug('jsonp req "%s"', url); + + // create script + script = document.createElement('script'); + script.src = url; + target.parentNode.insertBefore(script, target); +} diff --git a/components/pluma-par/component.json b/components/pluma-par/component.json new file mode 100644 index 000000000..e6a239e94 --- /dev/null +++ b/components/pluma-par/component.json @@ -0,0 +1,24 @@ +{ + "name": "par", + "repo": "pluma/par", + "description": "Simple partial function application.", + "keywords": [ + "partial", + "partial function application", + "curry" + ], + "version": "0.3.0", + "dependencies": {}, + "devDependencies": {}, + "scripts": [ + "dist/par.js" + ], + "main": "./dist/par.js", + "ignore": [ + "**/.*", + "build", + "components", + "node_modules" + ], + "license": "UNLICENSE" +} \ No newline at end of file diff --git a/components/pluma-par/dist/par.js b/components/pluma-par/dist/par.js new file mode 100644 index 000000000..669d6ff89 --- /dev/null +++ b/components/pluma-par/dist/par.js @@ -0,0 +1,27 @@ +/*! par 0.3.0 Original author Alan Plum . Released into the Public Domain under the UNLICENSE. @preserve */ +var slice = Array.prototype.slice; + +function par(fn) { + var args0 = slice.call(arguments, 1); + return function() { + var argsN = slice.call(arguments, 0), + args = []; + args.push.apply(args, args0); + args.push.apply(args, argsN); + return fn.apply(this, args); + }; +} + +function rpartial(fn) { + var argsN = slice.call(arguments, 1); + return function() { + var args = slice.call(arguments, 0); + args.push.apply(args, argsN); + return fn.apply(this, args); + }; +} + +par.rpartial = rpartial; +par.lpartial = par; + +module.exports = par; diff --git a/components/visionmedia-debug/component.json b/components/visionmedia-debug/component.json new file mode 100644 index 000000000..071ba8380 --- /dev/null +++ b/components/visionmedia-debug/component.json @@ -0,0 +1,16 @@ +{ + "name": "debug", + "repo": "visionmedia/debug", + "description": "small debugging utility", + "version": "0.7.4", + "keywords": [ + "debug", + "log", + "debugger" + ], + "main": "debug.js", + "scripts": [ + "debug.js" + ], + "dependencies": {} +} \ No newline at end of file diff --git a/components/visionmedia-debug/debug.js b/components/visionmedia-debug/debug.js new file mode 100644 index 000000000..509dc0ded --- /dev/null +++ b/components/visionmedia-debug/debug.js @@ -0,0 +1,137 @@ + +/** + * Expose `debug()` as the module. + */ + +module.exports = debug; + +/** + * Create a debugger with the given `name`. + * + * @param {String} name + * @return {Type} + * @api public + */ + +function debug(name) { + if (!debug.enabled(name)) return function(){}; + + return function(fmt){ + fmt = coerce(fmt); + + var curr = new Date; + var ms = curr - (debug[name] || curr); + debug[name] = curr; + + fmt = name + + ' ' + + fmt + + ' +' + debug.humanize(ms); + + // This hackery is required for IE8 + // where `console.log` doesn't have 'apply' + window.console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); + } +} + +/** + * The currently active debug mode names. + */ + +debug.names = []; +debug.skips = []; + +/** + * Enables a debug mode by name. This can include modes + * separated by a colon and wildcards. + * + * @param {String} name + * @api public + */ + +debug.enable = function(name) { + try { + localStorage.debug = name; + } catch(e){} + + var split = (name || '').split(/[\s,]+/) + , len = split.length; + + for (var i = 0; i < len; i++) { + name = split[i].replace('*', '.*?'); + if (name[0] === '-') { + debug.skips.push(new RegExp('^' + name.substr(1) + '$')); + } + else { + debug.names.push(new RegExp('^' + name + '$')); + } + } +}; + +/** + * Disable debug output. + * + * @api public + */ + +debug.disable = function(){ + debug.enable(''); +}; + +/** + * Humanize the given `ms`. + * + * @param {Number} m + * @return {String} + * @api private + */ + +debug.humanize = function(ms) { + var sec = 1000 + , min = 60 * 1000 + , hour = 60 * min; + + if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; + if (ms >= min) return (ms / min).toFixed(1) + 'm'; + if (ms >= sec) return (ms / sec | 0) + 's'; + return ms + 'ms'; +}; + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +debug.enabled = function(name) { + for (var i = 0, len = debug.skips.length; i < len; i++) { + if (debug.skips[i].test(name)) { + return false; + } + } + for (var i = 0, len = debug.names.length; i < len; i++) { + if (debug.names[i].test(name)) { + return true; + } + } + return false; +}; + +/** + * Coerce `val`. + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +// persist + +try { + if (window.localStorage) debug.enable(localStorage.debug); +} catch(e){} diff --git a/components/visionmedia-node-querystring/component.json b/components/visionmedia-node-querystring/component.json new file mode 100644 index 000000000..2aafb39ac --- /dev/null +++ b/components/visionmedia-node-querystring/component.json @@ -0,0 +1,15 @@ +{ + "name": "querystring", + "repo": "visionmedia/node-querystring", + "description": "query-string parser / stringifier with nesting support", + "version": "0.6.6", + "keywords": [ + "querystring", + "query", + "parser" + ], + "scripts": [ + "index.js" + ], + "license": "MIT" +} \ No newline at end of file diff --git a/components/visionmedia-node-querystring/index.js b/components/visionmedia-node-querystring/index.js new file mode 100644 index 000000000..b05938acc --- /dev/null +++ b/components/visionmedia-node-querystring/index.js @@ -0,0 +1,366 @@ +/** + * Object#toString() ref for stringify(). + */ + +var toString = Object.prototype.toString; + +/** + * Object#hasOwnProperty ref + */ + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Array#indexOf shim. + */ + +var indexOf = typeof Array.prototype.indexOf === 'function' + ? function(arr, el) { return arr.indexOf(el); } + : function(arr, el) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === el) return i; + } + return -1; + }; + +/** + * Array.isArray shim. + */ + +var isArray = Array.isArray || function(arr) { + return toString.call(arr) == '[object Array]'; +}; + +/** + * Object.keys shim. + */ + +var objectKeys = Object.keys || function(obj) { + var ret = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + ret.push(key); + } + } + return ret; +}; + +/** + * Array#forEach shim. + */ + +var forEach = typeof Array.prototype.forEach === 'function' + ? function(arr, fn) { return arr.forEach(fn); } + : function(arr, fn) { + for (var i = 0; i < arr.length; i++) fn(arr[i]); + }; + +/** + * Array#reduce shim. + */ + +var reduce = function(arr, fn, initial) { + if (typeof arr.reduce === 'function') return arr.reduce(fn, initial); + var res = initial; + for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]); + return res; +}; + +/** + * Cache non-integer test regexp. + */ + +var isint = /^[0-9]+$/; + +function promote(parent, key) { + if (parent[key].length == 0) return parent[key] = {} + var t = {}; + for (var i in parent[key]) { + if (hasOwnProperty.call(parent[key], i)) { + t[i] = parent[key][i]; + } + } + parent[key] = t; + return t; +} + +function parse(parts, parent, key, val) { + var part = parts.shift(); + + // illegal + if (Object.getOwnPropertyDescriptor(Object.prototype, key)) return; + + // end + if (!part) { + if (isArray(parent[key])) { + parent[key].push(val); + } else if ('object' == typeof parent[key]) { + parent[key] = val; + } else if ('undefined' == typeof parent[key]) { + parent[key] = val; + } else { + parent[key] = [parent[key], val]; + } + // array + } else { + var obj = parent[key] = parent[key] || []; + if (']' == part) { + if (isArray(obj)) { + if ('' != val) obj.push(val); + } else if ('object' == typeof obj) { + obj[objectKeys(obj).length] = val; + } else { + obj = parent[key] = [parent[key], val]; + } + // prop + } else if (~indexOf(part, ']')) { + part = part.substr(0, part.length - 1); + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + // key + } else { + if (!isint.test(part) && isArray(obj)) obj = promote(parent, key); + parse(parts, obj, part, val); + } + } +} + +/** + * Merge parent key/val pair. + */ + +function merge(parent, key, val){ + if (~indexOf(key, ']')) { + var parts = key.split('[') + , len = parts.length + , last = len - 1; + parse(parts, parent, 'base', val); + // optimize + } else { + if (!isint.test(key) && isArray(parent.base)) { + var t = {}; + for (var k in parent.base) t[k] = parent.base[k]; + parent.base = t; + } + set(parent.base, key, val); + } + + return parent; +} + +/** + * Compact sparse arrays. + */ + +function compact(obj) { + if ('object' != typeof obj) return obj; + + if (isArray(obj)) { + var ret = []; + + for (var i in obj) { + if (hasOwnProperty.call(obj, i)) { + ret.push(obj[i]); + } + } + + return ret; + } + + for (var key in obj) { + obj[key] = compact(obj[key]); + } + + return obj; +} + +/** + * Parse the given obj. + */ + +function parseObject(obj){ + var ret = { base: {} }; + + forEach(objectKeys(obj), function(name){ + merge(ret, name, obj[name]); + }); + + return compact(ret.base); +} + +/** + * Parse the given str. + */ + +function parseString(str){ + var ret = reduce(String(str).split('&'), function(ret, pair){ + var eql = indexOf(pair, '=') + , brace = lastBraceInKey(pair) + , key = pair.substr(0, brace || eql) + , val = pair.substr(brace || eql, pair.length) + , val = val.substr(indexOf(val, '=') + 1, val.length); + + // ?foo + if ('' == key) key = pair, val = ''; + if ('' == key) return ret; + + return merge(ret, decode(key), decode(val)); + }, { base: {} }).base; + + return compact(ret); +} + +/** + * Parse the given query `str` or `obj`, returning an object. + * + * @param {String} str | {Object} obj + * @return {Object} + * @api public + */ + +exports.parse = function(str){ + if (null == str || '' == str) return {}; + return 'object' == typeof str + ? parseObject(str) + : parseString(str); +}; + +/** + * Turn the given `obj` into a query string + * + * @param {Object} obj + * @return {String} + * @api public + */ + +var stringify = exports.stringify = function(obj, prefix) { + if (isArray(obj)) { + return stringifyArray(obj, prefix); + } else if ('[object Object]' == toString.call(obj)) { + return stringifyObject(obj, prefix); + } else if ('string' == typeof obj) { + return stringifyString(obj, prefix); + } else { + return prefix + '=' + encodeURIComponent(String(obj)); + } +}; + +/** + * Stringify the given `str`. + * + * @param {String} str + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyString(str, prefix) { + if (!prefix) throw new TypeError('stringify expects an object'); + return prefix + '=' + encodeURIComponent(str); +} + +/** + * Stringify the given `arr`. + * + * @param {Array} arr + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyArray(arr, prefix) { + var ret = []; + if (!prefix) throw new TypeError('stringify expects an object'); + for (var i = 0; i < arr.length; i++) { + ret.push(stringify(arr[i], prefix + '[' + i + ']')); + } + return ret.join('&'); +} + +/** + * Stringify the given `obj`. + * + * @param {Object} obj + * @param {String} prefix + * @return {String} + * @api private + */ + +function stringifyObject(obj, prefix) { + var ret = [] + , keys = objectKeys(obj) + , key; + + for (var i = 0, len = keys.length; i < len; ++i) { + key = keys[i]; + if ('' == key) continue; + if (null == obj[key]) { + ret.push(encodeURIComponent(key) + '='); + } else { + ret.push(stringify(obj[key], prefix + ? prefix + '[' + encodeURIComponent(key) + ']' + : encodeURIComponent(key))); + } + } + + return ret.join('&'); +} + +/** + * Set `obj`'s `key` to `val` respecting + * the weird and wonderful syntax of a qs, + * where "foo=bar&foo=baz" becomes an array. + * + * @param {Object} obj + * @param {String} key + * @param {String} val + * @api private + */ + +function set(obj, key, val) { + var v = obj[key]; + if (Object.getOwnPropertyDescriptor(Object.prototype, key)) return; + if (undefined === v) { + obj[key] = val; + } else if (isArray(v)) { + v.push(val); + } else { + obj[key] = [v, val]; + } +} + +/** + * Locate last brace in `str` within the key. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function lastBraceInKey(str) { + var len = str.length + , brace + , c; + for (var i = 0; i < len; ++i) { + c = str[i]; + if (']' == c) brace = false; + if ('[' == c) brace = true; + if ('=' == c && !brace) return i; + } +} + +/** + * Decode `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function decode(str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (err) { + return str; + } +} diff --git a/components/yields-merge/component.json b/components/yields-merge/component.json new file mode 100644 index 000000000..7c528a509 --- /dev/null +++ b/components/yields-merge/component.json @@ -0,0 +1,17 @@ +{ + "name": "merge", + "repo": "yields/merge", + "description": "merge two objects", + "version": "1.0.0", + "keywords": [ + "merge", + "inherit", + "extend" + ], + "dependencies": {}, + "license": "MIT", + "development": {}, + "scripts": [ + "index.js" + ] +} \ No newline at end of file diff --git a/components/yields-merge/index.js b/components/yields-merge/index.js new file mode 100644 index 000000000..bf9d777c6 --- /dev/null +++ b/components/yields-merge/index.js @@ -0,0 +1,19 @@ + +/** + * merge `b`'s properties with `a`'s. + * + * example: + * + * var user = {}; + * merge(user, console); + * // > { log: fn, dir: fn ..} + * + * @param {Object} a + * @param {Object} b + * @return {Object} + */ + +module.exports = function (a, b) { + for (var k in b) a[k] = b[k]; + return a; +};