diff --git a/.gitignore b/.gitignore index 2c7d751..15b2fbf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .DS_Store npdfile.js +examples diff --git a/README.md b/README.md index 1842e77..5c94dad 100644 --- a/README.md +++ b/README.md @@ -612,6 +612,54 @@ npd migrate:rollback npm test ``` +## Browser Support +Npdynamodb can be built using browserify or webpack, and pre-built or pre-built with uglified version can be found in the build directory. + +#### Note that, if you use Npdynamodb on any browsers, It has a security issue. Because AccessKey and SecretAccessKey for DynamoDB can be seen from public. We recommend you only using it for private or readonly projects which is not including any privacy informations. + + +### For Browserify or Webpack +```js +var AWS = require('aws-sdk'); +var npdynamodb = require('npdynamodb/build/npdynamodb'); + +var dynamodb = new AWS.DynamoDB({ + apiVersion: '2012-08-10', + accessKeyId: "here is key", + secretAccessKey: "here is secret key", + region: "ap-northeast-1", + sslEnabled: true, +}); + +var npd = npdynamodb.createClient(dynamodb); +npd().table('table_name').where('id', 1).then(function(data){ + console.log(data); +}); +``` + +### For HTML +```html + + + + + +``` + + ## License (The MIT License) diff --git a/build/npdynamodb.js b/build/npdynamodb.js new file mode 100644 index 0000000..427459f --- /dev/null +++ b/build/npdynamodb.js @@ -0,0 +1,2995 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("lodash"), require("bluebird"), require("aws-sdk")); + else if(typeof define === 'function' && define.amd) + define(["lodash", "bluebird", "aws-sdk"], factory); + else if(typeof exports === 'object') + exports["npdynamodb"] = factory(require("lodash"), require("bluebird"), require("aws-sdk")); + else + root["npdynamodb"] = factory(root["_"], root["Promise"], root["AWS"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_8__, __WEBPACK_EXTERNAL_MODULE_15__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + // For Browser + if(typeof(window) === 'object') { + window.npdynamodb = exports; + window.DynamoDBDatatype = __webpack_require__(17).DynamoDBDatatype; + window.DynamoDBFormatter = __webpack_require__(18).DynamoDBFormatter; + } + + exports.version = __webpack_require__(30).version; + + exports.createClient = __webpack_require__(9); + + exports.define = __webpack_require__(1); + + exports.Collection = __webpack_require__(28); + + exports.Model = __webpack_require__(27); + + exports.Migrator = __webpack_require__(31); + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _ = __webpack_require__(2); + var util = __webpack_require__(3); + + var utils = __webpack_require__(7); + var npdynamodb = __webpack_require__(9); + + var BaseModel = __webpack_require__(27); + + module.exports = function(tableName, prototypeProps, staticProps){ + + var reservedProps = ['hashKey', 'rangeKey', 'npdynamodb']; + + function Model(attributes){ + this.tableName = tableName; + + _.extend(this, _.pick.apply(null, [prototypeProps].concat(reservedProps))); + + this._attributes = attributes || {}; + + this._builder = this.npdynamodb().table(tableName); + } + + _.extend(Model.prototype, _.clone(BaseModel.prototype)); + + _.each(_.omit.apply(null, [prototypeProps].concat(reservedProps)), function(val, name){ + if(val.hasOwnProperty('bind')) { + Model.prototype[name] = function(){ + return val.bind(this, _.toArray(arguments)); + }; + }else{ + Model.prototype[name] = val; + } + }); + + _.each([ + 'find', + 'where', + 'query', + 'fetch', + 'save' + ], function(_interface){ + Model[_interface] = function(){ + var model = new Model(); + return model[_interface].apply(model, _.toArray(arguments)); + }; + }); + + _.each(staticProps, function(val, name){ + if(val.hasOwnProperty('bind')) { + Model[name] = val.bind(Model); + }else{ + Model[name] = val; + } + }); + + return Model; + }; + + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_2__; + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. + // + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to permit + // persons to whom the Software is furnished to do so, subject to the + // following conditions: + // + // The above copyright notice and this permission notice shall be included + // in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var formatRegExp = /%[sdj%]/g; + exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; + }; + + + // Mark that a method should not be used. + // Returns a modified function which warns once by default. + // If --no-deprecation is set, then it is a no-op. + exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; + }; + + + var debugs = {}; + var debugEnviron; + exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; + }; + + + /** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ + /* legacy: obj, showHidden, depth, colors*/ + function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); + } + exports.inspect = inspect; + + + // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics + inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] + }; + + // Don't use 'blue' not visible on cmd.exe + inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' + }; + + + function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } + } + + + function stylizeNoColor(str, styleType) { + return str; + } + + + function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; + } + + + function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); + } + + + function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); + } + + + function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; + } + + + function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; + } + + + function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; + } + + + function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { + return Array.isArray(ar); + } + exports.isArray = isArray; + + function isBoolean(arg) { + return typeof arg === 'boolean'; + } + exports.isBoolean = isBoolean; + + function isNull(arg) { + return arg === null; + } + exports.isNull = isNull; + + function isNullOrUndefined(arg) { + return arg == null; + } + exports.isNullOrUndefined = isNullOrUndefined; + + function isNumber(arg) { + return typeof arg === 'number'; + } + exports.isNumber = isNumber; + + function isString(arg) { + return typeof arg === 'string'; + } + exports.isString = isString; + + function isSymbol(arg) { + return typeof arg === 'symbol'; + } + exports.isSymbol = isSymbol; + + function isUndefined(arg) { + return arg === void 0; + } + exports.isUndefined = isUndefined; + + function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; + } + exports.isRegExp = isRegExp; + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + exports.isObject = isObject; + + function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; + } + exports.isDate = isDate; + + function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); + } + exports.isError = isError; + + function isFunction(arg) { + return typeof arg === 'function'; + } + exports.isFunction = isFunction; + + function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; + } + exports.isPrimitive = isPrimitive; + + exports.isBuffer = __webpack_require__(5); + + function objectToString(o) { + return Object.prototype.toString.call(o); + } + + + function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); + } + + + var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + + // 26 Feb 16:19:34 + function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); + } + + + // log is just a thin wrapper to console.log that prepends a timestamp + exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); + }; + + + /** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ + exports.inherits = __webpack_require__(6); + + exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; + }; + + function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(4))) + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + + // shim for using process in browser + + var process = module.exports = {}; + var queue = []; + var draining = false; + var currentQueue; + var queueIndex = -1; + + function cleanUpNextTick() { + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } + } + + function drainQueue() { + if (draining) { + return; + } + var timeout = setTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + currentQueue[queueIndex].run(); + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + clearTimeout(timeout); + } + + process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + setTimeout(drainQueue, 0); + } + }; + + // v8 likes predictible objects + function Item(fun, array) { + this.fun = fun; + this.array = array; + } + Item.prototype.run = function () { + this.fun.apply(null, this.array); + }; + process.title = 'browser'; + process.browser = true; + process.env = {}; + process.argv = []; + process.version = ''; // empty string to avoid regexp issues + process.versions = {}; + + function noop() {} + + process.on = noop; + process.addListener = noop; + process.once = noop; + process.off = noop; + process.removeListener = noop; + process.removeAllListeners = noop; + process.emit = noop; + + process.binding = function (name) { + throw new Error('process.binding is not supported'); + }; + + // TODO(shtylman) + process.cwd = function () { return '/' }; + process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); + }; + process.umask = function() { return 0; }; + + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; + } + +/***/ }, +/* 6 */ +/***/ function(module, exports) { + + if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; + } else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _ = __webpack_require__(2); + var Promise = __webpack_require__(8); + + exports.isEmpty = function(val){ + if(val === null) return true; + if(val === '') return true; + if(_.isArray(val) && val.length === 0) return true; + if(_.isObject(val) && _.keys(val).length === 0) return true; + return false; + }; + + exports.newObject = function(key, val){ + var o = {}; + o[key] = val; + return o; + }; + + exports.toPascalCase = function(string){ + var camelized = string.replace(/_./g, function(str) { + return str.charAt(1).toUpperCase(); + }); + + return camelized.charAt(0).toUpperCase() + camelized.slice(1); + }; + + exports.collectionFlatten = function(collection){ + var newObj = {}; + _.each(collection, function(obj){ + _.extend(newObj, obj); + }); + return newObj; + }; + + + exports.PromiseWaterfall = function(promises){ + + return new Promise(function(resolve, reject){ + var results = []; + + function watefallThen(promise){ + + if(promise && typeof promise.then === 'function') { + promise.then(function(data){ + results.push(data); + watefallThen(promises.shift()); + }).catch(reject); + } else if(promise && typeof promise.then !== 'function') { + + reject(new TypeError("Function return value should be a promise.")); + + } else { + resolve(results); + } + } + + watefallThen(promises.shift()); + }); + + }; + + + exports.lazyPromiseRunner = function(cb) { + return { + then: function(callback){ + return cb().then(callback); + } + }; + }; + + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_8__; + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var QueryBuilder = __webpack_require__(10); + var promisify = __webpack_require__(13); + var DOC = __webpack_require__(14); + + var promisifiedPool = {}; + + function npdynamodb(clients, options){ + var Feature = __webpack_require__(19)("./"+ clients.dynamodb.config.apiVersion +'/feature'); + var qb = new QueryBuilder(new Feature(clients), options); + return qb; + } + + module.exports = function(dynamodb, options){ + var v = dynamodb.config.apiVersion, + api = __webpack_require__(26)("./" + v + '/' + 'api') + ; + + if(!promisifiedPool[v]) { + promisifiedPool[v] = promisify(dynamodb, api.originalApis); + } + + var clients = { + dynamodb: typeof dynamodb.Condition === 'function' ? dynamodb: new DOC.DynamoDB(dynamodb), + promisifidRawClient: promisifiedPool[v] + }; + + return function(){ + return npdynamodb(clients, options); + }; + }; + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var interfaces = __webpack_require__(12); + var _ = __webpack_require__(2); + var Promise = __webpack_require__(8); + var EventEmitter = __webpack_require__(11).EventEmitter; + var util = __webpack_require__(3); + + var utils = __webpack_require__(7); + + module.exports = QueryBuilder; + + function QueryBuilder(feature, options){ + EventEmitter.call(this); + this._feature = feature; + this._options = options || {}; + var self = this; + + _.each(['beforeQuery', 'afterQuery'], function(event){ + self._feature.on(event, function(data){ + self.emit(event, data); + }); + }); + } + util.inherits(QueryBuilder, EventEmitter); + + interfaces.forEach(function(m){ + QueryBuilder.prototype[m] = function(){ + this._feature[m].apply(this._feature, _.toArray(arguments)); + return this; + }; + }); + + QueryBuilder.prototype.tableName = function(){ + return this._feature.conditions.TableName; + }; + + QueryBuilder.prototype.feature = function(cb){ + cb(this._feature); + return this; + }; + + QueryBuilder.prototype.rawClient = function(cb){ + return this._feature.promisifidRawClient; + }; + + _.each([ + 'then', + ], function(promiseInterface){ + QueryBuilder.prototype[promiseInterface] = function(cb){ + var self = this; + var gotResponse = false; + return new Promise(function(resolve, reject){ + var request = self._feature.run(function(err, data){ + gotResponse = true; + if(err) { + return reject(err); + } + resolve(data); + }); + + if(self._options.timeout !== null) { + setTimeout(function(){ + if(!gotResponse) { + request.abort(); + reject(new Error("The connection has timed out.")); + } + }, self._options.timeout || 5000); + } + }) + .then(function(data){ + return cb.bind(self)(data); + }); + }; + }); + + +/***/ }, +/* 11 */ +/***/ function(module, exports) { + + // Copyright Joyent, Inc. and other Node contributors. + // + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to permit + // persons to whom the Software is furnished to do so, subject to the + // following conditions: + // + // The above copyright notice and this permission notice shall be included + // in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; + } + module.exports = EventEmitter; + + // Backwards-compat with node 0.10.x + EventEmitter.EventEmitter = EventEmitter; + + EventEmitter.prototype._events = undefined; + EventEmitter.prototype._maxListeners = undefined; + + // By default EventEmitters will print a warning if more than 10 listeners are + // added to it. This is a useful default which helps finding memory leaks. + EventEmitter.defaultMaxListeners = 10; + + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. + EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; + }; + + EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; + }; + + EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; + }; + + EventEmitter.prototype.on = EventEmitter.prototype.addListener; + + EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; + }; + + // emits a 'removeListener' event iff the listener was removed + EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; + }; + + EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; + }; + + EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; + }; + + EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; + }; + + function isFunction(arg) { + return typeof arg === 'function'; + } + + function isNumber(arg) { + return typeof arg === 'number'; + } + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + + function isUndefined(arg) { + return arg === void 0; + } + + +/***/ }, +/* 12 */ +/***/ function(module, exports) { + + 'use strict'; + + module.exports = [ + 'select', + 'table', + 'count', + 'all', + 'where', + 'first', + 'whereBetween', + 'whereBeginsWith', + 'filterBetween', + 'filterBeginsWith', + 'filter', + 'filterIn', + 'filterNull', + 'filterNotNull', + 'filterContains', + 'filterNotContains', + 'limit', + 'desc', + 'asc', + 'create', + 'update', + 'set', + 'delete', + 'showTables', + 'indexName', + 'describe', + 'createTable', + 'deleteTable', + ]; + + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var Promise = __webpack_require__(8); + + module.exports = function(lib, apis){ + var promisifiedMethods = {}; + + apis.forEach(function(m){ + promisifiedMethods[m] = Promise.promisify(lib[m], lib); + }); + + return promisifiedMethods; + }; + + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + /** + * Create an instance of the DynamoDB Document client. + * + * @constructor + * @class DynamoDB + * @param {AWS.DynamoDB} dynamoDB An instance of the service provided AWS SDK (optional). + * @returns {DynamoDB} Modified version of the service for Document support. + */ + function DynamoDB(dynamoDB) { + var isBrowser = typeof(window) === "undefined"; + var AWS = isBrowser ? __webpack_require__(15) : window.AWS; + + var condition = isBrowser ? __webpack_require__(16).DynamoDBCondition : window.DynamoDBCondition; + + var datatypes = isBrowser ? __webpack_require__(17).DynamoDBDatatype : window.DynamoDBDatatype; + var t = new datatypes(); + + var formatter = isBrowser ? __webpack_require__(18).DynamoDBFormatter : window.DynamoDBFormatter; + var f = new formatter(); + + var service = dynamoDB || new AWS.DynamoDB(); + + var setupLowLevelRequestListeners = service.setupRequestListeners; + service.setupRequestListeners = function(request) { + setupLowLevelRequestListeners.call(this, request); + + request._events.validate.unshift(f.formatInput); + request.on("extractData", f.formatOutput); + }; + + /** + * Utility to create Set Object for requests. + * + * @function Set + * @memberOf DynamoDB# + * @param {array} set An array that contains elements of the same typed as defined by {type}. + * @param {string} type Can only be a [S]tring, [N]umber, or [B]inary type. + * @return {Set} Custom Set object that follow {type}. + * @throws InvalidSetType, InconsistentType + */ + service.__proto__.Set = function(set, type) { + return t.createSet(set, type); + }; + + /** + * Creates an instance of Condition and should be used with the DynamoDB client. + * + * @function Condition + * @memberOf DynamoDB# + * @param {string} key The attribute name being conditioned. + * @param {string} operator The operator in the conditional clause. (See lower level docs for full list of operators) + * @param val1 Potential first element in what would be the AttributeValueList + * @param val2 Potential second element in what would be the AttributeValueList + * @return {Condition} Condition for your DynamoDB request. + */ + service.__proto__.Condition = function(key, operator, val1, val2) { + return condition(key, operator, val1, val2); + }; + + /** + * Utility to convert a String to the necessary Binary object. + * + * @function StrToBin + * @memberOf DynamoDB# + * @param {string} value String value to converted to Binary object. + * @return {object} Return value will be a Buffer or Uint8Array in the browser. + * @throws StrConversionError + */ + service.__proto__.StrToBin = function(value) { + return t.strToBin(value); + }; + /** + * Utility to convert a Binary object into its String equivalent. + * + * @function BinToStr + * @memberOf DynamoDB# + * @param {object} value Binary value (Buffer | Uint8Array) depending on environment. + * @return {string} Return value will be the string representation of the Binary object. + * @throws BinConversionError + */ + service.__proto__.BinToStr = function(value) { + return t.binToStr(value); + }; + + return service; + } + + if (true) { + var exports = module.exports = {}; + exports.DynamoDB = DynamoDB; + } + + +/***/ }, +/* 15 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_15__; + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + /** + * Creates an instance of Condition that is used by the DynamoDB Document client. + * + * @param {string} key The attribute name being conditioned on. + * @param {string} operator The operator in the conditional clause. (See aws sdk docs for full list of operators) + * @param val1 Potential first element in what would be the AttributeValueList + * @param val2 Potential second element in what would be the AttributeValueList + * @return {Condition} Condition for your DynamoDB request. + */ + function DynamoDBCondition(key, operator, val1, val2) { + var datatypes = typeof(window) === "undefined" ? __webpack_require__(17).DynamoDBDatatype + : window.DynamoDBDatatype; + + var t = new datatypes(); + + var CondObj = function Condition(key, operator, val1, val2) { + this.key = key; + this.operator = operator; + this.val1 = val1; + this.val2 = val2; + + this.format = function() { + var formatted = {}; + + var attrValueList = []; + if (this.val1 !== undefined) { + attrValueList.push(t.formatDataType(this.val1)); + } + if (this.val2 !== undefined) { + attrValueList.push(t.formatDataType(this.val2)); + } + if (attrValueList.length > 0) { + formatted.AttributeValueList = attrValueList; + } + formatted.ComparisonOperator = this.operator; + + return formatted; + }; + }; + + var cond = new CondObj(key, operator, val1, val2); + cond.prototype = Object.create(Object.prototype); + cond.prototype.instanceOf = "DynamoDBConditionObject"; + + return cond; + } + + if (true) { + var exports = module.exports = {}; + exports.DynamoDBCondition = DynamoDBCondition; + } + + +/***/ }, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + /** + * @class Creates a DynamoDBDatatype that takes care of all datatype handling. + * + * @name DynamoDBDatatype + */ + function DynamoDBDatatype() { + var AWS = typeof(window) === "undefined" ? __webpack_require__(15) : window.AWS; + var Uint8ArrayError = "Uint8Array can only be used for Binary in Browser."; + var ScalarDatatypeError = "Unrecognized Scalar Datatype to be formatted."; + var GeneralDatatypeError = "Unrecognized Datatype to be formatted."; + var BinConversionError = "Need to pass in Buffer or Uint8Array. "; + var StrConversionError = "Need to pass in string primitive to be converted to binary."; + + function isScalarType(dataType) { + + var type = typeof(dataType); + return type === "number" || + type === "string" || + type === "boolean" || + (dataType instanceof(Uint8Array) && AWS.util.isBrowser()) || + dataType instanceof(AWS.util.Buffer) || + dataType === null; + } + + function isSetType(dataType) { + return dataType.datatype === "SS" || + dataType.datatype === "NS" || + dataType.datatype === "BS"; + } + + function isRecursiveType(dataType) { + + return Array.isArray(dataType) || + typeof(dataType) === "object"; + } + + function formatSetValues(datatype, values) { + if(datatype === "NS") { + return values.map(function (n) { + return n.toString(); + }); + } else { + return values; + } + }; + + function formatRecursiveType(dataType) { + + var recursiveDoc = {}; + + var value = {}; + var type = "M"; + if (Array.isArray(dataType)) { + value = []; + type = "L"; + } + + for (var key in dataType) { + value[key] = this.formatDataType(dataType[key]); + } + + recursiveDoc[type] = value; + return recursiveDoc; + } + + /** @throws Uint8ArrayError, ScalarDatatypeError + * @private */ + function formatScalarType(dataType) { + + if (dataType == null) { + return { "NULL" : true }; + } + + var type = typeof(dataType); + if (type === "string") { + return { "S" : dataType }; + } else if (type === "number") { + return { "N" : String(dataType) }; + } else if (type === "boolean") { + return { "BOOL" : dataType }; + } else if (dataType instanceof(AWS.util.Buffer)) { + return { "B" : dataType }; + } else if (dataType instanceof(Uint8Array)) { + if (AWS.util.isBrowser()) { + return { "B" : dataType }; + } else { + throw new Error(Uint8ArrayError); + } + } else { + throw new Error(ScalarDatatypeError); + } + } + + /** + * Formats Javascript datatypes into DynamoDB wire format. + * + * @name formatDataType + * @function + * @memberOf DynamoDBDatatype# + * @param dataType Javascript datatype (i.e. string, number. For full information, check out the README). + * @return {object} DynamoDB JSON-like wire format. + * @throws GeneralDatatypeError + */ + this.formatDataType = function(dataType) { + + if (isScalarType(dataType)) { + return formatScalarType(dataType); + } else if (isSetType(dataType)) { + return dataType.format(); + } else if (isRecursiveType(dataType)) { + return formatRecursiveType.call(this, dataType); + } else { + throw new Error(GeneralDatatypeError); + } + + }; + + function str2Bin(value) { + if (typeof(value) !== "string") { + throw new Error(StrConversionError); + } + + if (AWS.util.isBrowser()) { + var len = value.length; + var bin = new Uint8Array(new ArrayBuffer(len)); + for (var i = 0; i < len; i++) { + bin[i] = value.charCodeAt(i); + } + return bin; + } else { + return AWS.util.Buffer(value); + } + } + + /** + * Utility to convert a String to a Binary object. + * + * @function strToBin + * @memberOf DynamoDBDatatype# + * @param {string} value String value to converted to Binary object. + * @return {object} (Buffer | Uint8Array) depending on Node or browser. + * @throws StrConversionError + */ + this.strToBin = function(value) { + return str2Bin.call(this, value); + }; + + function bin2Str(value) { + if (!(value instanceof(AWS.util.Buffer)) && !(value instanceof(Uint8Array))) { + throw new Error(BinConversionError); + } + + if (AWS.util.isBrowser()) { + return String.fromCharCode.apply(null, value); + } else { + return value.toString("utf-8").valueOf(); + } + } + + /** + * Utility to convert a Binary object into a decoded String. + * + * @function binToStr + * @memberOf DynamoDBDatatype# + * @param {object} value Binary value (Buffer | Uint8Array) depending on Node or browser. + * @return {string} decoded String in UTF-8 + * @throws BinConversionError + */ + this.binToStr = function(value) { + return bin2Str.call(this, value); + }; + + /** + * Utility to create the DynamoDB Set Datatype. + * + * @function createSet + * @memberOf DynamoDBDatatype# + * @param {array} set An array that contains elements of the same typed as defined by {type}. + * @param {string} type Can only be a [S]tring, [N]umber, or [B]inary type. + * @return {Set} Custom Set object that follow {type}. + * @throws InvalidSetType, InconsistentType + */ + this.createSet = function(set, type) { + if (type !== "N" && type !== "S" && type !== "B") { + throw new Error(type + " is an invalid type for Set"); + } + + var setObj = function Set(set, type) { + this.datatype = type + "S"; + this.contents = {}; + + this.add = function(value) { + if (this.datatype === "SS" && typeof(value) === "string") { + this.contents[value] = value; + } else if (this.datatype === "NS" && typeof(value) === "number") { + this.contents[value] = value; + } else if (this.datatype === "BS" && value instanceof(AWS.util.Buffer)) { + this.contents[bin2Str(value)] = value; + } else if (this.datatype === "BS" && value instanceof(Uint8Array)) { + if (AWS.util.isBrowser()) { + this.contents[bin2Str(value)] = value; + } else { + throw new Error(Uint8ArrayError); + } + } else { + throw new Error("Inconsistent in this " + type + " Set"); + } + }; + + this.contains = function(content) { + var value = content; + if (content instanceof AWS.util.Buffer || content instanceof(Uint8Array)) { + value = bin2Str(content); + } + if (this.contents[value] === undefined) { + return false; + } + return true; + }; + + this.remove = function(content) { + var value = content; + if (content instanceof AWS.util.Buffer || content instanceof(Uint8Array)) { + value = bin2Str(content); + } + delete this.contents[value]; + }; + + this.toArray = function() { + var keys = Object.keys(this.contents); + var arr = []; + + for (var keyIndex in keys) { + var key = keys[keyIndex]; + if (this.contents.hasOwnProperty(key)) { + arr.push(this.contents[key]); + } + } + + return arr; + }; + + this.format = function() { + var values = this.toArray(); + var result = {}; + result[this.datatype] = formatSetValues(this.datatype, values); + return result; + }; + + if (set) { + for (var index in set) { + this.add(set[index]); + } + } + }; + + return new setObj(set, type); + }; + + /** + * Formats DynamoDB wire format into javascript datatypes. + * + * @name formatWireType + * @function + * @memberOf DynamoDBDatatype# + * @param {string} key Key that represents the type of the attribute value + * @param value Javascript datatype of the attribute value produced by DynamoDB + * @throws GeneralDatatypeError + */ + this.formatWireType = function(key, value) { + switch (key) { + case "S": + case "B": + case "BOOL": + return value; + case "N": + return Number(value); + case "NULL": + return null; + case "L": + for (var lIndex = 0; lIndex < value.length; lIndex++) { + var lValue = value[lIndex]; + var lKey = Object.keys(lValue)[0]; + value[lIndex] = this.formatWireType(lKey, lValue[lKey]); + } + return value; + case "M": + for (var mIndex in value) { + var mValue = value[mIndex]; + var mKey = Object.keys(mValue)[0]; + value[mIndex] = this.formatWireType(mKey, mValue[mKey]); + } + return value; + case "SS": + return new this.createSet(value, "S"); + case "NS": + value = value.map(function(each) { return Number(each);}); + return new this.createSet(value, "N"); + case "BS": + return new this.createSet(value, "B"); + default: + throw "Service returned unrecognized datatype " + key; + } + } + } + + if (true) { + var exports = module.exports = {}; + exports.DynamoDBDatatype = DynamoDBDatatype; + } + + +/***/ }, +/* 18 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + /** + * Create an instance of the DynamoDBFormatter. + * @constructor + * @return {DynamoDBFormatter} A Formatter object that provides methods for formatting DynamoDB requests and responses. + */ + function DynamoDBFormatter() { + var datatypes = typeof(window) === "undefined" ? __webpack_require__(17).DynamoDBDatatype : window.DynamoDBDatatype; + var t = new datatypes(); + var EmptyConditionArray = "Need to pass in an array with 1 or more Condition Objects."; + var BadElementInConditionArray = "Only Condition objects are allowed as members of the array."; + var InvalidCondition = "Need to pass in a valid Condition Object."; + + function formatAttrValInput(attrValueMap) { + var attributeValueMap = {}; + for (var attr in attrValueMap) { + var value = attrValueMap[attr]; + attributeValueMap[attr] = t.formatDataType(value); + } + return attributeValueMap; + } + + function formatConditions(conditions) { + if (conditions.prototype && conditions.prototype.instanceOf === "DynamoDBConditionObject") { + conditions = [conditions]; + } else { + if (Array.isArray(conditions)) { + if (conditions.length === 0) { + throw new Error(EmptyConditionArray); + } + for (var index in conditions) { + var condition = conditions[index]; + if (!(condition.prototype) || !(condition.prototype.instanceOf === "DynamoDBConditionObject")) { + throw new Error(BadElementInConditionArray); + } + } + } else { + throw new Error(InvalidCondition); + } + } + + var expected = {}; + for (var index in conditions) { + var condition = conditions[index]; + expected[condition.key] = condition.format(); + } + return expected; + } + + function formatUpdates(updates) { + var attrUpdates = {}; + for (var attr in updates) { + if (updates.hasOwnProperty(attr)) { + var actionValue = {}; + var value = updates[attr].Value; + var action = updates[attr].Action; + + actionValue.Action = action; + actionValue.Value = t.formatDataType(value); + + attrUpdates[attr] = actionValue; + } + } + + return attrUpdates; + } + + function handleWriteRequest(request) { + var requestCopy = {}; + + if (request.DeleteRequest) { + var key = request.DeleteRequest.Key; + requestCopy.DeleteRequest = {}; + requestCopy.DeleteRequest.Key = formatAttrValInput(key); + } else { + var item = request.PutRequest.Item; + requestCopy.PutRequest = {}; + requestCopy.PutRequest.Item = formatAttrValInput(item); + } + + return requestCopy; + } + + function formatRequestItems(requests) { + var requestItems = {}; + + for (var table in requests) { + if (requests.hasOwnProperty(table)) { + requestItems[table] = {}; + + var request = requests[table]; + if (Array.isArray(request)) { + var writeRequests = []; + for (var wIndex in request) { + writeRequests.push(handleWriteRequest(request[wIndex])); + } + requestItems[table] = writeRequests; + } else { + if (request.AttributesToGet) { + requestItems[table].AttributesToGet = request.AttributesToGet; + } + if (request.ConsistentRead) { + requestItems[table].ConsistentRead = request.ConsistentRead; + } + if (request.ProjectionExpression) { + requestItems[table].ProjectionExpression = request.ProjectionExpression; + } + if (request.ExpressionAttributeNames) { + requestItems[table].ExpressionAttributeNames = request.ExpressionAttributeNames; + } + if (request.Keys) { + var keys = []; + for (var gIndex in request.Keys) { + var key = request.Keys[gIndex]; + keys.push(formatAttrValInput(key)); + } + requestItems[table].Keys = keys; + } + } + } + } + + return requestItems; + } + + var inputMap = { "AttributeUpdates": formatUpdates, + "ExclusiveStartKey": formatAttrValInput, + "Expected": formatConditions, + "ExpressionAttributeValues": formatAttrValInput, + "Item": formatAttrValInput, + "Key": formatAttrValInput, + "KeyConditions": formatConditions, + "RequestItems": formatRequestItems, + "ScanFilter": formatConditions, + "QueryFilter": formatConditions}; + + + function formatAttrValOutput(item) { + var attrList = {}; + for (var attribute in item) { + var keys = Object.keys(item[attribute]); + var key = keys[0]; + var value = item[attribute][key]; + + value = t.formatWireType(key, value); + attrList[attribute] = value; + } + + return attrList; + } + + function formatItems(items) { + for (var index in items) { + items[index] = formatAttrValOutput(items[index]); + } + return items; + } + + function handleCollectionKey(metrics) { + var collectionKey = metrics.ItemCollectionKey; + metrics.ItemCollectionKey = formatAttrValOutput(collectionKey); + return metrics; + } + + function handleBatchMetrics(metrics) { + for (var table in metrics) { + if (metrics.hasOwnProperty(table)) { + var listOfKeys = metrics[table]; + for (var index in listOfKeys) { + listOfKeys[index] = handleCollectionKey(listOfKeys[index]); + } + } + } + return metrics; + } + + function formatMetrics(metrics) { + var collectionKey = metrics.ItemCollectionKey; + if (collectionKey) { + metrics = handleCollectionKey(metrics); + } else { + metrics = handleBatchMetrics(metrics); + } + return metrics; + } + + function formatResponses(responses) { + for (var table in responses) { + if (responses.hasOwnProperty(table)) { + var listOfItems = responses[table]; + for (var index in listOfItems) { + listOfItems[index] = formatAttrValOutput(listOfItems[index]); + } + } + } + + return responses; + } + + function formatUnprocessedItems(unprocessedItems) { + for(var table in unprocessedItems) { + if (unprocessedItems.hasOwnProperty(table)) { + var tableInfo = unprocessedItems[table]; + for (var index in tableInfo) { + var request = tableInfo[index]; + if (request.DeleteRequest) { + tableInfo[index].DeleteRequest.Key = formatAttrValOutput(request.DeleteRequest.Key); + } else { + tableInfo[index].PutRequest.Item = formatAttrValOutput(request.PutRequest.Item); + } + } + } + } + return unprocessedItems; + } + + function formatUnprocessedKeys(unprocessedKeys) { + for (var table in unprocessedKeys) { + if (unprocessedKeys.hasOwnProperty(table)) { + var tableInfo = unprocessedKeys[table]; + var listOfKeys = tableInfo.Keys; + for (var index in listOfKeys) { + tableInfo.Keys[index] = formatAttrValOutput(listOfKeys[index]); + } + } + } + + return unprocessedKeys; + } + + /** + * DynamoDBFormatter specifically for wrapping DynamoDB response objects. + * + * @function formatOutput + * @memberOf DynamoDBFormatter# + * @params {object} response Response object directly passed out by the service. + * @returns {object} Wrapped up response object. + */ + this.formatOutput = function(response) { + var outputMap = {"Attributes": formatAttrValOutput, + "Item": formatAttrValOutput, + "Items": formatItems, + "ItemCollectionMetrics": formatMetrics, + "LastEvaluatedKey": formatAttrValOutput, + "Responses": formatResponses, + "UnprocessedKeys": formatUnprocessedKeys, + "UnprocessedItems": formatUnprocessedItems}; + + + var data = response.data; + if (data) { + for (var key in data) { + if (data.hasOwnProperty(key)) { + var formatFunc = outputMap[key]; + if (formatFunc) { + response.data[key] = formatFunc(data[key]); + } + } + } + } + }; + + /** + * DynamoDBFormatter specifically for unwrapping DynamoDB request objects. + * + * @function formatInput + * @memberOf DynamoDBFormatter# + * @params {object} request Request object created by the service. + * @return {object} Returns aws sdk version of the request. + */ + this.formatInput = function (request) { + var paramsCopy = {}; + var params = request.params; + + for (var key in params) { + if (params.hasOwnProperty(key)) { + var param = params[key]; + var formatFunc = inputMap[key]; + if (formatFunc) { + param = formatFunc(param); + } + paramsCopy[key] = param; + } + } + + request.params = paramsCopy; + }; + } + + if (true) { + var exports = module.exports = {}; + exports.DynamoDBFormatter = DynamoDBFormatter; + } + + +/***/ }, +/* 19 */ +/***/ function(module, exports, __webpack_require__) { + + var map = { + "./2012-08-10/feature": 20 + }; + function webpackContext(req) { + return __webpack_require__(webpackContextResolve(req)); + }; + function webpackContextResolve(req) { + return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }()); + }; + webpackContext.keys = function webpackContextKeys() { + return Object.keys(map); + }; + webpackContext.resolve = webpackContextResolve; + module.exports = webpackContext; + webpackContext.id = 19; + + +/***/ }, +/* 20 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _ = __webpack_require__(2); + var util = __webpack_require__(3); + var EventEmitter = __webpack_require__(11).EventEmitter; + var DOC = __webpack_require__(14); + + var utils = __webpack_require__(7); + var api = __webpack_require__(21); + + var clientPools = {}; + + var extraOperators = { + where: [ + 'BEGINS_WITH', + 'BETWEEN' + ], + filter: [ + 'BETWEEN', + 'BEGINS_WITH', + 'NOT_NULL', + 'NULL', + 'CONTAINS', + 'NOT_CONTAINS', + 'IN' + ] + }; + + var availableOperators = api.availableOperators.concat(extraOperators.filter); + + var parameterBuilder = {}; + + parameterBuilder.createTable = parameterBuilder.deleteTable = function(feature){ + return { conditions: feature.params }; + }; + + parameterBuilder.deleteItem = parameterBuilder.getItem = parameterBuilder.updateItem = function(feature){ + var cond = utils.collectionFlatten(_.map(feature.whereConditions, function(param){ + return utils.newObject(param.key, param.values[0]); + })); + + return { conditions: { Key: cond } }; + }; + + parameterBuilder.query = function(feature){ + var obj = {}; + + obj.KeyConditions = feature.toDocClientConditon(feature.whereConditions); + + if(!_.isEmpty(feature.filterConditions)){ + obj.QueryFilter = feature.toDocClientConditon(feature.filterConditions); + } + + return { conditions: obj }; + }; + + parameterBuilder.putItem = function(feature){ + if(_.isArray(feature.params)) { + var items = feature.params.map(function(item){ + return {PutRequest: { Item: item } }; + }); + + var tableName = feature.conditions.TableName; + + return { + beforeQuery: function(){ + this.nonTable(); + }, + nextThen: 'batchWriteItem', + conditions: { + RequestItems: utils.newObject(tableName, items) + } + }; + + }else{ + return {conditions: { Item: feature.params } }; + } + }; + + function Feature(clients){ + EventEmitter.call(this); + + this.client = clients.dynamodb; + + this.promisifidRawClient = clients.promisifidRawClient; + + this.nextThen = undefined; + + this.params = {}; + + this.whereConditions = []; + + this.filterConditions = []; + + this.conditions = {}; + + this.schema = {}; + } + + util.inherits(Feature, EventEmitter); + + _.each(api.operations, function(spec, method){ + _.each(spec.input.members, function(typeSpec, member){ + Feature.prototype[_.camelCase(member)] = function(params){ + this.conditions[member] = params; + return this; + }; + }); + }); + + _.each(api.transformFunctionMap, function(oldM, newM){ + Feature.prototype[newM] = function(params){ + this.nextThen = oldM; + this.params = params; + }; + }); + + Feature.prototype.select = function(){ + this.attributesToGet(_.toArray(arguments)); + }; + + Feature.prototype.table = function(tableName){ + this.tableName(tableName); + }; + + Feature.prototype.count = function(){ + this.conditions.Select = 'COUNT'; + this.nextThen = 'query'; + }; + + _.each([ + 'filter', + 'where' + ], function(operator){ + + Feature.prototype[operator] = function(){ + addConditions.apply(this, [operator].concat(_.toArray(arguments))); + return this; + }; + + _.each(extraOperators[operator], function(_operator){ + Feature.prototype[operator + utils.toPascalCase(_operator.toLowerCase())] = function(){ + var args = _.toArray(arguments); + var newArgs = [operator, args.shift(), _operator].concat(args); + addConditions.apply(this, newArgs); + return this; + }; + }); + }); + + function addConditions(){ + var args = _.toArray(arguments); + var col = args[1], op = args[2], val = args[3]; + if(!_.contains(availableOperators, op)){ + val = op; + op = '='; + } + + this[args[0]+'Conditions'].push({ + key: col, + values: [val].concat(Array.prototype.slice.call(args, 4)), + operator: op + }); + } + + Feature.prototype.toDocClientConditon = function(conditions){ + var self = this; + return conditions.map(function(cond){ + var args = [ + cond.key, + api.transformOperatorMap[cond.operator] || cond.operator + ].concat(cond.values); + return self.client.Condition.apply(null, args); + }); + }; + + Feature.prototype.set = function(key, action, value){ + if(!this.conditions.AttributeUpdates) { + this.conditions.AttributeUpdates = {}; + } + + this.conditions.AttributeUpdates[key] = { + Action: action, + Value: value + }; + + return this; + }; + + Feature.prototype.asc = function(){ + this.scanIndexForward(true); + }; + + Feature.prototype.desc = function(){ + this.scanIndexForward(false); + }; + + Feature.prototype.nonTable = function(){ + this.conditions = _.omit(this.conditions, 'TableName'); + }; + + Feature.prototype.run = function(cb){ + var self = this; + var built = this._buildQuery(); + + self.emit('beforeQuery', built.params); + + return this.client[built.method](built.params, function(err, data){ + if(!err) self.emit('afterQuery', data); + cb(err, data); + }); + }; + + Feature.prototype._buildQuery = function(){ + var nextThen = this.nextThen || 'query'; + var self = this; + + function supplement(builder){ + if(!builder) return undefined; + + return function(){ + var result = builder(self); + if(!result.beforeQuery) result.beforeQuery = function(){}; + if(!result.nextThen) result.nextThen = nextThen; + + return result; + }; + } + + var builder = supplement(parameterBuilder[nextThen]) || function(){ + return { + beforeQuery: function(){}, + conditions: {}, + nextThen: nextThen + }; + }; + + var built = builder(); + built.beforeQuery.call(this); + + this.nextThen = built.nextThen; + this.conditions = _.extend(this.conditions, built.conditions); + + return { + params: this.conditions, + method: this.nextThen + }; + }; + + + module.exports = Feature; + + +/***/ }, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {var _ = __webpack_require__(2); + var utils = __webpack_require__(7); + var fs = __webpack_require__(22); + + function getDynamoDBOperations(){ + // Browser. + if(this.AWS) { + return this.AWS.apiLoader.services.dynamodb['2012-08-10'].operations; + } + + // Node.js + var dynamoApiJsonPath = 'aws-sdk/apis/dynamodb-2012-08-10.min.json'; + + try { + + return __webpack_require__(23)(dynamoApiJsonPath).operations; + + } catch(e) { + var pathFromWorkingDir = process.cwd() + "/node_modules/" + dynamoApiJsonPath; + + if(fs.existsSync(pathFromWorkingDir)){ + return __webpack_require__(23)(pathFromWorkingDir).operations; + } + + throw new TypeError("Module `aws-sdk` is required for npdynamodb"); + } + } + + var operations = getDynamoDBOperations(this); + + //available methods.(api version 2012-08-10) + var apis = [ + { + origin: 'createTable', + transformed: 'createTable' + }, + + { + origin: 'deleteTable', + transformed: 'deleteTable' + }, + + { + origin: 'deleteItem', + transformed: 'delete' + }, + + { + origin: 'describeTable', + transformed: 'describe' + }, + + { + origin: 'listTables', + transformed: 'showTables', + }, + + { + origin: 'putItem', + transformed: 'create' + }, + + { + origin: 'updateItem', + transformed: 'update' + }, + + { + origin: 'getItem', + transformed: 'first' + }, + + { + origin: 'query', + transformed: 'query', + }, + + { + origin: 'scan', + transformed: 'all' + }, + + { + origin: 'updateTable', + transformed: 'alterTable' + }, + + { + origin: 'waitFor', + transformed: 'waitFor' + } + ]; + + var transformOperatorMap = { + '=' : 'EQ', + '!=': 'NE', + '<=': 'LE', + '<': 'LT', + '>=': 'GE', + '>': 'GT', + }; + + module.exports = { + operations: operations, + + originalApis: _.keys(operations).map(function(api){ + return _.camelCase(api); + }).concat(['waitFor']), + + transformFunctionMap: utils.collectionFlatten(apis.map(function(api){ + return utils.newObject(api.transformed, api.origin); + })), + + transformOperatorMap: transformOperatorMap, + + availableOperators: _.keys(transformOperatorMap) + }; + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) + +/***/ }, +/* 22 */ +/***/ function(module, exports) { + + + +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { + + var map = { + "./api": 21, + "./api.js": 21, + "./feature": 20, + "./feature.js": 20, + "./schema": 24, + "./schema.js": 25 + }; + function webpackContext(req) { + return __webpack_require__(webpackContextResolve(req)); + }; + function webpackContextResolve(req) { + return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }()); + }; + webpackContext.keys = function webpackContextKeys() { + return Object.keys(map); + }; + webpackContext.resolve = webpackContextResolve; + module.exports = webpackContext; + webpackContext.id = 23; + + +/***/ }, +/* 24 */ +/***/ function(module, exports) { + + /* (ignored) */ + +/***/ }, +/* 25 */ +/***/ function(module, exports) { + + /* (ignored) */ + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + var map = { + "./2012-08-10/api": 21 + }; + function webpackContext(req) { + return __webpack_require__(webpackContextResolve(req)); + }; + function webpackContextResolve(req) { + return map[req] || (function() { throw new Error("Cannot find module '" + req + "'.") }()); + }; + webpackContext.keys = function webpackContextKeys() { + return Object.keys(map); + }; + webpackContext.resolve = webpackContextResolve; + module.exports = webpackContext; + webpackContext.id = 26; + + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _ = __webpack_require__(2); + var Collection = __webpack_require__(28); + var promiseRunner = __webpack_require__(29); + + module.exports = Model; + + function Runner(query, formatter){ + var self = this; + return promiseRunner(query, function(data){ + self._refreshBuilder(); + return formatter(data); + }) + .bind(this); + } + + function Model(){} + + Model.prototype.where = function(){ + this._builder.where.apply(this._builder, arguments); + return this; + }; + + Model.prototype.query = function(fn){ + if(typeof fn === 'function') { + fn(this._builder); + return this; + } + + return this._builder; + }; + + Model.prototype.find = function(hashKeyVal, rangeKeyVal){ + var self = this; + var query = this._builder.where(this.hashKey, hashKeyVal); + + if(rangeKeyVal) { + query.where(this.rangeKey, rangeKeyVal); + } + + return Runner.bind(this)(query.first(), function(data){ + self._attributes = data.Item; + return self; + }); + }; + + Model.prototype.reload = function(){ + return this.find(this.get(this.hashKey), this.get(this.rangeKey)); + }; + + Model.prototype.fetch = function(){ + var self = this; + + return Runner.bind(this)(this._builder, function(data){ + var models = data.Items.map(function(item){ + return new self.constructor(item); + }); + + return new Collection(models); + }); + }; + + Model.prototype.save = function(item){ + var self = this; + + if(typeof item === 'object'){ + _.extend(this._attributes, item); + } + + return Runner.bind(this)(this._builder.create(this.attributes()), function(){ + return self; + }); + }; + + Model.prototype.destroy = function(item){ + var self = this; + + var query = this._builder.where(this.hashKey, this.get(this.hashKey)); + + if(this.rangeKey) { + query.where(this.rangeKey, this.get(this.rangeKey)); + } + + return Runner.bind(this)(query.delete(), function(){ + self._attributes = {}; + return self; + }); + }; + + Model.prototype.set = function(key, value){ + this._attributes[key] = value; + return this; + }; + + Model.prototype.unset = function(key){ + if(this._attributes[key]) { + delete this._attributes[key]; + } + return this; + }; + + Model.prototype.extend = function(attributes){ + _.extend(this._attributes, attributes); + return this; + }; + + Model.prototype.get = function(key){ + return this._attributes[key]; + }; + + Model.prototype.isEmpty = function(){ + return _.isEmpty(this._attributes); + }; + + Model.prototype.attributes = function(){ + return this._attributes; + }; + + Model.prototype.toJson = function(){ + return JSON.stringify(this._attributes); + }; + + Model.prototype._refreshBuilder = function(){ + this._builder = this.npdynamodb().table(this.tableName); + }; + + _.each([ + 'each', + 'map', + 'includes', + 'contains', + 'keys', + 'pick', + 'values', + ], function(name){ + Model.prototype[name] = function(){ + var args = [this._item].concat(_.map(arguments, function(arg){ return arg; })); + return _[name].apply(_, args); + }; + }); + + +/***/ }, +/* 28 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _ = __webpack_require__(2); + + module.exports = Collection; + + function Collection(items){ + this._items = items; + } + + Collection.prototype.toArray = function(){ + return this._items.map(function(item){ + return item.attributes(); + }); + }; + + Collection.prototype.toJSON = function(){ + return JSON.stringify(this.toArray()); + }; + + Collection.prototype.indexAt = function(index){ + return this._items[index]; + }; + + _.each([ + 'pluck' + ], function(name){ + Collection.prototype[name] = function(){ + var args = [this.toArray()].concat(_.map(arguments, function(arg){ return arg; })); + return _[name].apply(_, args); + }; + }); + + _.each([ + 'each', + 'map', + 'reduce', + 'reduceRight', + 'find', + 'filter', + 'where', + 'findWhere', + 'reject', + 'every', + 'some', + 'invoke', + 'sortBy', + 'groupBy', + 'indexBy', + 'countBy', + 'shuffle', + 'sample', + 'size', + 'partition', + 'first', + 'last', + 'isEmpty' + ], function(name){ + Collection.prototype[name] = function(){ + var args = [this._items].concat(_.map(arguments, function(arg){ return arg; })); + return _[name].apply(_, args); + }; + }); + + +/***/ }, +/* 29 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var Promise = __webpack_require__(8); + + module.exports = function(promsie, formatter) { + var self = this; + return new Promise(function(resolve, reject){ + return promsie.then(function(data){ + if(!formatter) { + formatter = function(data){ return data; }; + } + return resolve(formatter(data)); + }).catch(reject); + }); + }; + + +/***/ }, +/* 30 */ +/***/ function(module, exports) { + + module.exports = { + "name": "npdynamodb", + "version": "0.2.4", + "description": "A Node.js Simple Query Builder and ORM for AWS DynamoDB.", + "main": "index.js", + "scripts": { + "test": "find ./test -name *_spec.js | xargs mocha --reporter spec -t 20000" + }, + "keywords": [ + "dynamodb", + "aws", + "activerecord", + "orm", + "migration" + ], + "bin": { + "npd": "./lib/bin/npd" + }, + "repository": { + "type": "git", + "url": "https://github.com/noppoMan/npdynamodb.git" + }, + "author": "noppoMan (http://miketokyo.com)", + "license": "MIT", + "bugs": { + "url": "https://github.com/noppoMan/npdynamodb/issues" + }, + "homepage": "https://github.com/noppoMan/npdynamodb", + "dependencies": { + "bluebird": "^2.9.24", + "chalk": "^1.0.0", + "commander": "^2.7.1", + "dynamodb-doc": "^1.0.0", + "glob": "^5.0.3", + "interpret": "^0.5.2", + "liftoff": "^2.0.3", + "lodash": "^3.5.0", + "minimist": "^1.1.1", + "readline": "0.0.7", + "v8flags": "^2.0.3" + }, + "devDependencies": { + "aws-sdk": "^2.1.18", + "chai": "^2.2.0" + }, + "browser": { + "./lib/migrate/migrator.js": false, + "./lib/dialects/2012-08-10/schema.js": false, + "aws-sdk": false + } + } + +/***/ }, +/* 31 */ +/***/ function(module, exports) { + + /* (ignored) */ + +/***/ } +/******/ ]) +}); +; \ No newline at end of file diff --git a/build/npdynamodb.min.js b/build/npdynamodb.min.js new file mode 100644 index 0000000..2f92730 --- /dev/null +++ b/build/npdynamodb.min.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("lodash"),require("bluebird"),require("aws-sdk")):"function"==typeof define&&define.amd?define(["lodash","bluebird","aws-sdk"],e):"object"==typeof exports?exports.npdynamodb=e(require("lodash"),require("bluebird"),require("aws-sdk")):t.npdynamodb=e(t._,t.Promise,t.AWS)}(this,function(t,e,n){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";"object"==typeof window&&(window.npdynamodb=e,window.DynamoDBDatatype=n(17).DynamoDBDatatype,window.DynamoDBFormatter=n(18).DynamoDBFormatter),e.version=n(30).version,e.createClient=n(9),e.define=n(1),e.Collection=n(28),e.Model=n(27),e.Migrator=n(31)},function(t,e,n){"use strict";var r=n(2),i=(n(3),n(7),n(9),n(27));t.exports=function(t,e,n){function o(n){this.tableName=t,r.extend(this,r.pick.apply(null,[e].concat(s))),this._attributes=n||{},this._builder=this.npdynamodb().table(t)}var s=["hashKey","rangeKey","npdynamodb"];return r.extend(o.prototype,r.clone(i.prototype)),r.each(r.omit.apply(null,[e].concat(s)),function(t,e){t.hasOwnProperty("bind")?o.prototype[e]=function(){return t.bind(this,r.toArray(arguments))}:o.prototype[e]=t}),r.each(["find","where","query","fetch","save"],function(t){o[t]=function(){var e=new o;return e[t].apply(e,r.toArray(arguments))}}),r.each(n,function(t,e){t.hasOwnProperty("bind")?o[e]=t.bind(o):o[e]=t}),o}},function(e,n){e.exports=t},function(t,e,n){(function(t,r){function i(t,n){var r={seen:[],stylize:s};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&e._extend(r,n),_(r.showHidden)&&(r.showHidden=!1),_(r.depth)&&(r.depth=2),_(r.colors)&&(r.colors=!1),_(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=o),u(r,t,r.depth)}function o(t,e){var n=i.styles[e];return n?"["+i.colors[n][0]+"m"+t+"["+i.colors[n][1]+"m":t}function s(t,e){return t}function a(t){var e={};return t.forEach(function(t,n){e[t]=!0}),e}function u(t,n,r){if(t.customInspect&&n&&E(n.inspect)&&n.inspect!==e.inspect&&(!n.constructor||n.constructor.prototype!==n)){var i=n.inspect(r,t);return g(i)||(i=u(t,i,r)),i}var o=c(t,n);if(o)return o;var s=Object.keys(n),d=a(s);if(t.showHidden&&(s=Object.getOwnPropertyNames(n)),A(n)&&(s.indexOf("message")>=0||s.indexOf("description")>=0))return f(n);if(0===s.length){if(E(n)){var m=n.name?": "+n.name:"";return t.stylize("[Function"+m+"]","special")}if(x(n))return t.stylize(RegExp.prototype.toString.call(n),"regexp");if(O(n))return t.stylize(Date.prototype.toString.call(n),"date");if(A(n))return f(n)}var v="",b=!1,w=["{","}"];if(y(n)&&(b=!0,w=["[","]"]),E(n)){var _=n.name?": "+n.name:"";v=" [Function"+_+"]"}if(x(n)&&(v=" "+RegExp.prototype.toString.call(n)),O(n)&&(v=" "+Date.prototype.toUTCString.call(n)),A(n)&&(v=" "+f(n)),0===s.length&&(!b||0==n.length))return w[0]+v+w[1];if(0>r)return x(n)?t.stylize(RegExp.prototype.toString.call(n),"regexp"):t.stylize("[Object]","special");t.seen.push(n);var D;return D=b?p(t,n,r,d,s):s.map(function(e){return l(t,n,r,d,e,b)}),t.seen.pop(),h(D,v,w)}function c(t,e){if(_(e))return t.stylize("undefined","undefined");if(g(e)){var n="'"+JSON.stringify(e).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return t.stylize(n,"string")}return b(e)?t.stylize(""+e,"number"):d(e)?t.stylize(""+e,"boolean"):m(e)?t.stylize("null","null"):void 0}function f(t){return"["+Error.prototype.toString.call(t)+"]"}function p(t,e,n,r,i){for(var o=[],s=0,a=e.length;a>s;++s)j(e,String(s))?o.push(l(t,e,n,r,String(s),!0)):o.push("");return i.forEach(function(i){i.match(/^\d+$/)||o.push(l(t,e,n,r,i,!0))}),o}function l(t,e,n,r,i,o){var s,a,c;if(c=Object.getOwnPropertyDescriptor(e,i)||{value:e[i]},c.get?a=c.set?t.stylize("[Getter/Setter]","special"):t.stylize("[Getter]","special"):c.set&&(a=t.stylize("[Setter]","special")),j(r,i)||(s="["+i+"]"),a||(t.seen.indexOf(c.value)<0?(a=m(n)?u(t,c.value,null):u(t,c.value,n-1),a.indexOf("\n")>-1&&(a=o?a.split("\n").map(function(t){return" "+t}).join("\n").substr(2):"\n"+a.split("\n").map(function(t){return" "+t}).join("\n"))):a=t.stylize("[Circular]","special")),_(s)){if(o&&i.match(/^\d+$/))return a;s=JSON.stringify(""+i),s.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=t.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=t.stylize(s,"string"))}return s+": "+a}function h(t,e,n){var r=0,i=t.reduce(function(t,e){return r++,e.indexOf("\n")>=0&&r++,t+e.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(""===e?"":e+"\n ")+" "+t.join(",\n ")+" "+n[1]:n[0]+e+" "+t.join(", ")+" "+n[1]}function y(t){return Array.isArray(t)}function d(t){return"boolean"==typeof t}function m(t){return null===t}function v(t){return null==t}function b(t){return"number"==typeof t}function g(t){return"string"==typeof t}function w(t){return"symbol"==typeof t}function _(t){return void 0===t}function x(t){return D(t)&&"[object RegExp]"===T(t)}function D(t){return"object"==typeof t&&null!==t}function O(t){return D(t)&&"[object Date]"===T(t)}function A(t){return D(t)&&("[object Error]"===T(t)||t instanceof Error)}function E(t){return"function"==typeof t}function S(t){return null===t||"boolean"==typeof t||"number"==typeof t||"string"==typeof t||"symbol"==typeof t||"undefined"==typeof t}function T(t){return Object.prototype.toString.call(t)}function B(t){return 10>t?"0"+t.toString(10):t.toString(10)}function C(){var t=new Date,e=[B(t.getHours()),B(t.getMinutes()),B(t.getSeconds())].join(":");return[t.getDate(),I[t.getMonth()],e].join(" ")}function j(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var N=/%[sdj%]/g;e.format=function(t){if(!g(t)){for(var e=[],n=0;n=o)return t;switch(t){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return t}}),a=r[n];o>n;a=r[++n])s+=m(a)||!D(a)?" "+a:" "+i(a);return s},e.deprecate=function(n,i){function o(){if(!s){if(r.throwDeprecation)throw new Error(i);r.traceDeprecation?console.trace(i):console.error(i),s=!0}return n.apply(this,arguments)}if(_(t.process))return function(){return e.deprecate(n,i).apply(this,arguments)};if(r.noDeprecation===!0)return n;var s=!1;return o};var L,k={};e.debuglog=function(t){if(_(L)&&(L=r.env.NODE_DEBUG||""),t=t.toUpperCase(),!k[t])if(new RegExp("\\b"+t+"\\b","i").test(L)){var n=r.pid;k[t]=function(){var r=e.format.apply(e,arguments);console.error("%s %d: %s",t,n,r)}}else k[t]=function(){};return k[t]},e.inspect=i,i.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},i.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},e.isArray=y,e.isBoolean=d,e.isNull=m,e.isNullOrUndefined=v,e.isNumber=b,e.isString=g,e.isSymbol=w,e.isUndefined=_,e.isRegExp=x,e.isObject=D,e.isDate=O,e.isError=A,e.isFunction=E,e.isPrimitive=S,e.isBuffer=n(5);var I=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];e.log=function(){console.log("%s - %s",C(),e.format.apply(e,arguments))},e.inherits=n(6),e._extend=function(t,e){if(!e||!D(e))return t;for(var n=Object.keys(e),r=n.length;r--;)t[n[r]]=e[n[r]];return t}}).call(e,function(){return this}(),n(4))},function(t,e){function n(){c=!1,s.length?u=s.concat(u):f=-1,u.length&&r()}function r(){if(!c){var t=setTimeout(n);c=!0;for(var e=u.length;e;){for(s=u,u=[];++f1)for(var n=1;nt||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},n.prototype.emit=function(t){var e,n,i,a,u,c;if(this._events||(this._events={}),"error"===t&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(e=arguments[1],e instanceof Error)throw e;throw TypeError('Uncaught, unspecified "error" event.')}if(n=this._events[t],s(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:for(i=arguments.length,a=new Array(i-1),u=1;i>u;u++)a[u-1]=arguments[u];n.apply(this,a)}else if(o(n)){for(i=arguments.length,a=new Array(i-1),u=1;i>u;u++)a[u-1]=arguments[u];for(c=n.slice(),i=c.length,u=0;i>u;u++)c[u].apply(this,a)}return!0},n.prototype.addListener=function(t,e){var i;if(!r(e))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",t,r(e.listener)?e.listener:e),this._events[t]?o(this._events[t])?this._events[t].push(e):this._events[t]=[this._events[t],e]:this._events[t]=e,o(this._events[t])&&!this._events[t].warned){var i;i=s(this._maxListeners)?n.defaultMaxListeners:this._maxListeners,i&&i>0&&this._events[t].length>i&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace())}return this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(t,e){function n(){this.removeListener(t,n),i||(i=!0,e.apply(this,arguments))}if(!r(e))throw TypeError("listener must be a function");var i=!1;return n.listener=e,this.on(t,n),this},n.prototype.removeListener=function(t,e){var n,i,s,a;if(!r(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(n=this._events[t],s=n.length,i=-1,n===e||r(n.listener)&&n.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(o(n)){for(a=s;a-->0;)if(n[a]===e||n[a].listener&&n[a].listener===e){i=a;break}if(0>i)return this;1===n.length?(n.length=0,delete this._events[t]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},n.prototype.removeAllListeners=function(t){var e,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[t],r(n))this.removeListener(t,n);else for(;n.length;)this.removeListener(t,n[n.length-1]);return delete this._events[t],this},n.prototype.listeners=function(t){var e;return e=this._events&&this._events[t]?r(this._events[t])?[this._events[t]]:this._events[t].slice():[]},n.listenerCount=function(t,e){var n;return n=t._events&&t._events[e]?r(t._events[e])?1:t._events[e].length:0}},function(t,e){"use strict";t.exports=["select","table","count","all","where","first","whereBetween","whereBeginsWith","filterBetween","filterBeginsWith","filter","filterIn","filterNull","filterNotNull","filterContains","filterNotContains","limit","desc","asc","create","update","set","delete","showTables","indexName","describe","createTable","deleteTable"]},function(t,e,n){"use strict";var r=n(8);t.exports=function(t,e){var n={};return e.forEach(function(e){n[e]=r.promisify(t[e],t)}),n}},function(t,e,n){"use strict";function r(t){var e="undefined"==typeof window,r=e?n(15):window.AWS,i=e?n(16).DynamoDBCondition:window.DynamoDBCondition,o=e?n(17).DynamoDBDatatype:window.DynamoDBDatatype,s=new o,a=e?n(18).DynamoDBFormatter:window.DynamoDBFormatter,u=new a,c=t||new r.DynamoDB,f=c.setupRequestListeners;return c.setupRequestListeners=function(t){f.call(this,t),t._events.validate.unshift(u.formatInput),t.on("extractData",u.formatOutput)},c.__proto__.Set=function(t,e){return s.createSet(t,e)},c.__proto__.Condition=function(t,e,n,r){return i(t,e,n,r)},c.__proto__.StrToBin=function(t){return s.strToBin(t)},c.__proto__.BinToStr=function(t){return s.binToStr(t)},c}var e=t.exports={};e.DynamoDB=r},function(t,e){t.exports=n},function(t,e,n){"use strict";function r(t,e,r,i){var o="undefined"==typeof window?n(17).DynamoDBDatatype:window.DynamoDBDatatype,s=new o,a=function(t,e,n,r){this.key=t,this.operator=e,this.val1=n,this.val2=r,this.format=function(){var t={},e=[];return void 0!==this.val1&&e.push(s.formatDataType(this.val1)),void 0!==this.val2&&e.push(s.formatDataType(this.val2)),e.length>0&&(t.AttributeValueList=e),t.ComparisonOperator=this.operator,t}},u=new a(t,e,r,i);return u.prototype=Object.create(Object.prototype),u.prototype.instanceOf="DynamoDBConditionObject",u}var e=t.exports={};e.DynamoDBCondition=r},function(t,e,n){"use strict";function r(){function t(t){var e=typeof t;return"number"===e||"string"===e||"boolean"===e||t instanceof Uint8Array&&c.util.isBrowser()||t instanceof c.util.Buffer||null===t}function e(t){return"SS"===t.datatype||"NS"===t.datatype||"BS"===t.datatype}function r(t){return Array.isArray(t)||"object"==typeof t}function i(t,e){return"NS"===t?e.map(function(t){return t.toString()}):e}function o(t){var e={},n={},r="M";Array.isArray(t)&&(n=[],r="L");for(var i in t)n[i]=this.formatDataType(t[i]);return e[r]=n,e}function s(t){if(null==t)return{NULL:!0};var e=typeof t;if("string"===e)return{S:t};if("number"===e)return{N:String(t)};if("boolean"===e)return{BOOL:t};if(t instanceof c.util.Buffer)return{B:t};if(t instanceof Uint8Array){if(c.util.isBrowser())return{B:t};throw new Error(f)}throw new Error(p)}function a(t){if("string"!=typeof t)throw new Error(y);if(c.util.isBrowser()){for(var e=t.length,n=new Uint8Array(new ArrayBuffer(e)),r=0;e>r;r++)n[r]=t.charCodeAt(r);return n}return c.util.Buffer(t)}function u(t){if(!(t instanceof c.util.Buffer||t instanceof Uint8Array))throw new Error(h);return c.util.isBrowser()?String.fromCharCode.apply(null,t):t.toString("utf-8").valueOf()}var c="undefined"==typeof window?n(15):window.AWS,f="Uint8Array can only be used for Binary in Browser.",p="Unrecognized Scalar Datatype to be formatted.",l="Unrecognized Datatype to be formatted.",h="Need to pass in Buffer or Uint8Array. ",y="Need to pass in string primitive to be converted to binary.";this.formatDataType=function(n){if(t(n))return s(n);if(e(n))return n.format();if(r(n))return o.call(this,n);throw new Error(l)},this.strToBin=function(t){return a.call(this,t)},this.binToStr=function(t){return u.call(this,t)},this.createSet=function(t,e){if("N"!==e&&"S"!==e&&"B"!==e)throw new Error(e+" is an invalid type for Set");var n=function(t,e){if(this.datatype=e+"S",this.contents={},this.add=function(t){if("SS"===this.datatype&&"string"==typeof t)this.contents[t]=t;else if("NS"===this.datatype&&"number"==typeof t)this.contents[t]=t;else if("BS"===this.datatype&&t instanceof c.util.Buffer)this.contents[u(t)]=t;else{if(!("BS"===this.datatype&&t instanceof Uint8Array))throw new Error("Inconsistent in this "+e+" Set");if(!c.util.isBrowser())throw new Error(f);this.contents[u(t)]=t}},this.contains=function(t){var e=t;return(t instanceof c.util.Buffer||t instanceof Uint8Array)&&(e=u(t)),void 0===this.contents[e]?!1:!0},this.remove=function(t){var e=t;(t instanceof c.util.Buffer||t instanceof Uint8Array)&&(e=u(t)),delete this.contents[e]},this.toArray=function(){var t=Object.keys(this.contents),e=[];for(var n in t){var r=t[n];this.contents.hasOwnProperty(r)&&e.push(this.contents[r])}return e},this.format=function(){var t=this.toArray(),e={};return e[this.datatype]=i(this.datatype,t),e},t)for(var n in t)this.add(t[n])};return new n(t,e)},this.formatWireType=function(t,e){switch(t){case"S":case"B":case"BOOL":return e;case"N":return Number(e);case"NULL":return null;case"L":for(var n=0;n=":"GE",">":"GT"};t.exports={operations:a,originalApis:i.keys(a).map(function(t){return i.camelCase(t)}).concat(["waitFor"]),transformFunctionMap:o.collectionFlatten(u.map(function(t){return o.newObject(t.transformed,t.origin)})),transformOperatorMap:c,availableOperators:i.keys(c)}}).call(e,n(4))},function(t,e){},function(t,e,n){function r(t){return n(i(t))}function i(t){return o[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var o={"./api":21,"./api.js":21,"./feature":20,"./feature.js":20,"./schema":24,"./schema.js":25};r.keys=function(){return Object.keys(o)},r.resolve=i,t.exports=r,r.id=23},function(t,e){},function(t,e){},function(t,e,n){function r(t){return n(i(t))}function i(t){return o[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var o={"./2012-08-10/api":21};r.keys=function(){return Object.keys(o)},r.resolve=i,t.exports=r,r.id=26},function(t,e,n){"use strict";function r(t,e){var n=this;return a(t,function(t){return n._refreshBuilder(),e(t)}).bind(this)}function i(){}var o=n(2),s=n(28),a=n(29);t.exports=i,i.prototype.where=function(){return this._builder.where.apply(this._builder,arguments),this},i.prototype.query=function(t){return"function"==typeof t?(t(this._builder),this):this._builder},i.prototype.find=function(t,e){var n=this,i=this._builder.where(this.hashKey,t);return e&&i.where(this.rangeKey,e),r.bind(this)(i.first(),function(t){return n._attributes=t.Item,n})},i.prototype.reload=function(){return this.find(this.get(this.hashKey),this.get(this.rangeKey))},i.prototype.fetch=function(){var t=this;return r.bind(this)(this._builder,function(e){var n=e.Items.map(function(e){return new t.constructor(e)});return new s(n)})},i.prototype.save=function(t){var e=this;return"object"==typeof t&&o.extend(this._attributes,t),r.bind(this)(this._builder.create(this.attributes()),function(){return e})},i.prototype.destroy=function(t){var e=this,n=this._builder.where(this.hashKey,this.get(this.hashKey));return this.rangeKey&&n.where(this.rangeKey,this.get(this.rangeKey)),r.bind(this)(n["delete"](),function(){return e._attributes={},e})},i.prototype.set=function(t,e){return this._attributes[t]=e,this},i.prototype.unset=function(t){return this._attributes[t]&&delete this._attributes[t],this},i.prototype.extend=function(t){return o.extend(this._attributes,t),this},i.prototype.get=function(t){return this._attributes[t]},i.prototype.isEmpty=function(){return o.isEmpty(this._attributes)},i.prototype.attributes=function(){return this._attributes},i.prototype.toJson=function(){return JSON.stringify(this._attributes)},i.prototype._refreshBuilder=function(){this._builder=this.npdynamodb().table(this.tableName)},o.each(["each","map","includes","contains","keys","pick","values"],function(t){i.prototype[t]=function(){var e=[this._item].concat(o.map(arguments,function(t){return t}));return o[t].apply(o,e)}})},function(t,e,n){"use strict";function r(t){this._items=t}var i=n(2);t.exports=r,r.prototype.toArray=function(){return this._items.map(function(t){return t.attributes()})},r.prototype.toJSON=function(){return JSON.stringify(this.toArray())},r.prototype.indexAt=function(t){return this._items[t]},i.each(["pluck"],function(t){r.prototype[t]=function(){var e=[this.toArray()].concat(i.map(arguments,function(t){return t}));return i[t].apply(i,e)}}),i.each(["each","map","reduce","reduceRight","find","filter","where","findWhere","reject","every","some","invoke","sortBy","groupBy","indexBy","countBy","shuffle","sample","size","partition","first","last","isEmpty"],function(t){r.prototype[t]=function(){var e=[this._items].concat(i.map(arguments,function(t){return t}));return i[t].apply(i,e)}})},function(t,e,n){"use strict";var r=n(8);t.exports=function(t,e){return new r(function(n,r){return t.then(function(t){return e||(e=function(t){return t}),n(e(t))})["catch"](r)})}},function(t,e){t.exports={name:"npdynamodb",version:"0.2.4",description:"A Node.js Simple Query Builder and ORM for AWS DynamoDB.",main:"index.js",scripts:{test:"find ./test -name *_spec.js | xargs mocha --reporter spec -t 20000"},keywords:["dynamodb","aws","activerecord","orm","migration"],bin:{npd:"./lib/bin/npd"},repository:{type:"git",url:"https://github.com/noppoMan/npdynamodb.git"},author:"noppoMan (http://miketokyo.com)", +license:"MIT",bugs:{url:"https://github.com/noppoMan/npdynamodb/issues"},homepage:"https://github.com/noppoMan/npdynamodb",dependencies:{bluebird:"^2.9.24",chalk:"^1.0.0",commander:"^2.7.1","dynamodb-doc":"^1.0.0",glob:"^5.0.3",interpret:"^0.5.2",liftoff:"^2.0.3",lodash:"^3.5.0",minimist:"^1.1.1",readline:"0.0.7",v8flags:"^2.0.3"},devDependencies:{"aws-sdk":"^2.1.18",chai:"^2.2.0"},browser:{"./lib/migrate/migrator.js":!1,"./lib/dialects/2012-08-10/schema.js":!1,"aws-sdk":!1}}},function(t,e){}])}); \ No newline at end of file diff --git a/index.js b/index.js index b4da88e..00dccae 100644 --- a/index.js +++ b/index.js @@ -1,26 +1,17 @@ 'use strict'; -var npdynamodb = require('./lib/npdynamodb'); -var npdynamodbORM = require('./lib/orm/index'); -var promisify = require('./lib/promisify'); -var DOC = require("dynamodb-doc"); +// For Browser +if(typeof(window) === 'object') { + window.npdynamodb = exports; + window.DynamoDBDatatype = require('./node_modules/dynamodb-doc/lib/datatypes').DynamoDBDatatype; + window.DynamoDBFormatter = require('./node_modules/dynamodb-doc/lib/formatter').DynamoDBFormatter; +} exports.version = require('./package.json').version; -exports.createClient = function(dynamodb, options){ - var api = require('./lib/dialects/' + dynamodb.config.apiVersion + '/' + 'api'); - var clients = { - dynamodb: typeof dynamodb.Condition === 'function' ? dynamodb: new DOC.DynamoDB(dynamodb), - promisifidRawClient: promisify(dynamodb, api.originalApis) - }; - return function(){ - return npdynamodb(clients, options); - }; -}; +exports.createClient = require('./lib/npdynamodb'); -exports.define = function(tableName, prototypeProps, staticProps){ - return npdynamodbORM(tableName, prototypeProps, staticProps); -}; +exports.define = require('./lib/orm/index'); exports.Collection = require('./lib/orm/collection'); diff --git a/lib/dialects/2012-08-10/api.js b/lib/dialects/2012-08-10/api.js index 108f408..eb8c3dd 100644 --- a/lib/dialects/2012-08-10/api.js +++ b/lib/dialects/2012-08-10/api.js @@ -1,21 +1,33 @@ var _ = require('lodash'); var utils = require('../../utils'); +var fs = require('fs'); + +function getDynamoDBOperations(){ + // Browser. + if(this.AWS) { + return this.AWS.apiLoader.services.dynamodb['2012-08-10'].operations; + } + + // Node.js + var dynamoApiJsonPath = 'aws-sdk/apis/dynamodb-2012-08-10.min.json'; + + try { + + return require(dynamoApiJsonPath).operations; + + } catch(e) { + var pathFromWorkingDir = process.cwd() + "/node_modules/" + dynamoApiJsonPath; + + if(fs.existsSync(pathFromWorkingDir)){ + return require(pathFromWorkingDir).operations; + } -var operations; -var dynamoApiJsonPath = 'aws-sdk/apis/dynamodb-2012-08-10.min.json'; - -try { - operations = require(dynamoApiJsonPath).operations; -} catch(e) { - var fs = require('fs'); - var pathFromWorkingDir = process.cwd() + "/node_modules/" + dynamoApiJsonPath; - if(fs.existsSync(pathFromWorkingDir)){ - operations = require(pathFromWorkingDir).operations; - }else{ throw new TypeError("Module `aws-sdk` is required for npdynamodb"); } } +var operations = getDynamoDBOperations(this); + //available methods.(api version 2012-08-10) var apis = [ { diff --git a/lib/migrate/migrator.js b/lib/migrate/migrator.js index dad7617..a8f399d 100644 --- a/lib/migrate/migrator.js +++ b/lib/migrate/migrator.js @@ -5,11 +5,11 @@ var Promise = require('bluebird'); var path = require('path'); var glob = require('glob'); var fs = require('fs'); - -var npdynamodb = require('../../index'); var SchemaBuilder = require('../schema/builder'); var utils = require('../utils'); +var npdynamodb = require('../npdynamodb'); + exports.create = function(dynamodb){ return function(){ return new Migrator(dynamodb); @@ -20,7 +20,7 @@ exports.Runner = MigrateRunner; function Migrator(dynamodb){ this.apiVer = dynamodb.config.apiVersion; - this.npd = npdynamodb.createClient(dynamodb); + this.npd = npdynamodb(dynamodb); } Migrator.prototype.createTable = function(tableName, callback){ @@ -42,9 +42,7 @@ Migrator.prototype.deleteTable = function(tableName) { function MigrateRunner(config){ this.config = config; - var npdynamodb = require('../../index'); - - this.npd = npdynamodb.createClient(config.dynamoClient); + this.npd = npdynamodb(config.dynamoClient); this.migrator = exports.create(config.dynamoClient); } diff --git a/lib/npdynamodb.js b/lib/npdynamodb.js index a88ea1d..abc0e8f 100644 --- a/lib/npdynamodb.js +++ b/lib/npdynamodb.js @@ -1,9 +1,32 @@ 'use strict'; var QueryBuilder = require('./query_builder'); +var promisify = require('./promisify'); +var DOC = require("dynamodb-doc"); -module.exports = function(clients, options){ +var promisifiedPool = {}; + +function npdynamodb(clients, options){ var Feature = require('./dialects/'+ clients.dynamodb.config.apiVersion +'/feature'); var qb = new QueryBuilder(new Feature(clients), options); return qb; +} + +module.exports = function(dynamodb, options){ + var v = dynamodb.config.apiVersion, + api = require('./dialects/' + v + '/' + 'api') + ; + + if(!promisifiedPool[v]) { + promisifiedPool[v] = promisify(dynamodb, api.originalApis); + } + + var clients = { + dynamodb: typeof dynamodb.Condition === 'function' ? dynamodb: new DOC.DynamoDB(dynamodb), + promisifidRawClient: promisifiedPool[v] + }; + + return function(){ + return npdynamodb(clients, options); + }; }; diff --git a/package.json b/package.json index ba28e7c..7d1e871 100644 --- a/package.json +++ b/package.json @@ -42,5 +42,10 @@ "devDependencies": { "aws-sdk": "^2.1.18", "chai": "^2.2.0" + }, + "browser": { + "./lib/migrate/migrator.js": false, + "./lib/dialects/2012-08-10/schema.js": false, + "aws-sdk": false } } diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..040c27c --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,15 @@ +#!/bin/bash -e + +npm install webpack@1.10.1 json-loader@0.5.2 uglify-js@2.4.24 + +webpack=node_modules/.bin/webpack +uglifyjs=node_modules/.bin/uglifyjs + +DEST_DIR='./build' + +if [ ! -d "$DEST_DIR" ]; then + mkdir $DEST_DIR +fi + +$webpack --config scripts/webpack.config.js index.js $DEST_DIR/npdynamodb.js +$uglifyjs $DEST_DIR/npdynamodb.js -o $DEST_DIR/npdynamodb.min.js -c -m diff --git a/scripts/webpack.config.js b/scripts/webpack.config.js new file mode 100644 index 0000000..30ef9d3 --- /dev/null +++ b/scripts/webpack.config.js @@ -0,0 +1,54 @@ +'use strict'; + +var webpack = require('webpack'); + +var externals = [ + { + "bluebird": { + root: "Promise", + commonjs2: "bluebird", + commonjs: "bluebird", + amd: "bluebird" + }, + "lodash": { + root: "_", + commonjs2: "lodash", + commonjs: "lodash", + amd: "lodash" + }, + "aws-sdk": { + root: "AWS", + commonjs2: "aws-sdk", + commonjs: "aws-sdk", + amd: "aws-sdk" + } + } +]; + +module.exports = { + + module: { + loaders: [ + { + include: /\.json$/, loaders: ["json-loader"] + } + ], + resolve: { + extensions: ['', '.json', '.js'] + } + }, + + output: { + library: 'npdynamodb', + libraryTarget: 'umd' + }, + + node: { + fs: "empty" + }, + + externals: externals, + + verbose: true + +};