Demo for query storing
Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/value-or-function/index.js b/node_modules/value-or-function/index.js
new file mode 100644
index 0000000..1be06dc
--- /dev/null
+++ b/node_modules/value-or-function/index.js
@@ -0,0 +1,113 @@
+'use strict';
+
+// Built-in types
+var types = [
+ 'object',
+ 'number',
+ 'string',
+ 'symbol',
+ 'boolean',
+ 'date',
+ 'function', // Weird to expose this
+];
+
+
+function normalize(coercer, value) {
+ if (typeof value === 'function') {
+ if (coercer === 'function') {
+ return value;
+ }
+ value = value.apply(this, slice(arguments, 2));
+ }
+ return coerce(this, coercer, value);
+}
+
+
+function coerce(ctx, coercer, value) {
+
+ // Handle built-in types
+ if (typeof coercer === 'string') {
+ if (coerce[coercer]) {
+ return coerce[coercer].call(ctx, value);
+ }
+ return typeOf(coercer, value);
+ }
+
+ // Handle custom coercer
+ if (typeof coercer === 'function') {
+ return coercer.call(ctx, value);
+ }
+
+ // Array of coercers, try in order until one returns a non-null value
+ var result;
+ coercer.some(function(coercer) {
+ result = coerce(ctx, coercer, value);
+ return result != null;
+ });
+
+ return result;
+}
+
+
+coerce.string = function(value) {
+ if (value != null &&
+ typeof value === 'object' &&
+ typeof value.toString === 'function') {
+
+ value = value.toString();
+ }
+ return typeOf('string', primitive(value));
+};
+
+
+coerce.number = function(value) {
+ return typeOf('number', primitive(value));
+};
+
+
+coerce.boolean = function(value) {
+ return typeOf('boolean', primitive(value));
+};
+
+
+coerce.date = function(value) {
+ value = primitive(value);
+ if (typeof value === 'number' && !isNaN(value) && isFinite(value)) {
+ return new Date(value);
+ }
+};
+
+
+function typeOf(type, value) {
+ if (typeof value === type) {
+ return value;
+ }
+}
+
+
+function primitive(value) {
+ if (value != null &&
+ typeof value === 'object' &&
+ typeof value.valueOf === 'function') {
+
+ value = value.valueOf();
+ }
+ return value;
+}
+
+function slice(value, from) {
+ return Array.prototype.slice.call(value, from);
+}
+
+// Add methods for each type
+types.forEach(function(type) {
+ // Make it an array for easier concat
+ var typeArg = [type];
+
+ normalize[type] = function() {
+ var args = slice(arguments);
+ return normalize.apply(this, typeArg.concat(args));
+ };
+});
+
+module.exports = normalize;