UNPKG

181 kBJavaScriptView Raw
1/*!
2 * Fortune.js
3 * Version 5.5.13
4 * MIT License
5 * http://fortune.js.org
6 */
7(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
8(function (Buffer){
9'use strict'
10
11var deepEqual = require('../../common/deep_equal')
12var message = require('../../common/message')
13var find = require('../../common/array/find')
14var generateId = require('../../common/generate_id')
15
16var errors = require('../../common/errors')
17var BadRequestError = errors.BadRequestError
18
19var keys = require('../../common/keys')
20var primaryKey = keys.primary
21var typeKey = keys.type
22var isArrayKey = keys.isArray
23
24// For complex types.
25var matchCheck = [
26 [ Date, function (a, b) { return a.getTime() === b.getTime() } ],
27 [ Buffer, function (a, b) { return a.equals(b) } ],
28 [ Object, function (a, b) { return deepEqual(a, b) } ]
29]
30
31// For comparing sort order.
32var comparisons = [
33 [ Number, function (a, b) { return a - b } ],
34 [ String, function (a, b) { return a === b ? 0 : a > b ? 1 : -1 } ],
35 [ Boolean, function (a, b) { return a === b ? 0 : a ? 1 : -1 } ],
36 [ Date, function (a, b) { return a.getTime() - b.getTime() } ],
37 [ Buffer, Buffer.compare ],
38
39 // There is no comparison here that makes sense, so this should simply be a
40 // no-op by default.
41 [ Object, function () { return 0 } ]
42]
43
44
45// Browser-safe ID generation.
46exports.generateId = generateId
47
48
49exports.applyOptions = function (fields, records, options, meta) {
50 var count, record, field, isInclude, isExclude, language, memoizedRecords
51 var i, j
52
53 if (!options) options = {}
54 if (!meta) meta = {}
55
56 language = meta.language
57
58 // Apply filters.
59 if (options) {
60 memoizedRecords = records
61 records = []
62 for (i = 0, j = memoizedRecords.length; i < j; i++) {
63 record = memoizedRecords[i]
64 if (match(fields, options, record))
65 records.push(record)
66 }
67 }
68
69 count = records.length
70
71 if ('fields' in options) {
72 isInclude = !find(Object.keys(options.fields),
73 function (field) { return !options.fields[field] })
74 isExclude = !find(Object.keys(options.fields),
75 function (field) { return options.fields[field] })
76
77 if (!isInclude && !isExclude)
78 throw new BadRequestError(message('FieldsFormat', language))
79
80 for (i = 0, j = records.length; i < j; i++) {
81 record = records[i]
82 for (field in record) {
83 if (field === primaryKey) continue
84 if ((isInclude && !(options.fields.hasOwnProperty(field))) ||
85 (isExclude && options.fields.hasOwnProperty(field)))
86 delete record[field]
87 }
88 }
89 }
90
91 if ('sort' in options)
92 records = records.sort(compare(fields, options.sort))
93
94 if ('limit' in options || 'offset' in options)
95 records = records.slice(options.offset, options.limit ?
96 (options.offset || 0) + options.limit : records.length)
97
98 records.count = count
99
100 return records
101}
102
103
104function check (type, a, b) {
105 var matcher
106
107 if (b === null) return a === null
108 if (!type) return a === b
109 if (type.compare) return type.compare(a, b) === 0
110
111 matcher = find(matchCheck, findByType(type))
112
113 if (matcher) return matcher[1](a, b)
114
115 return a === b
116}
117
118
119function checkValue (fieldDefinition, a) {
120 return function (b) {
121 return fieldDefinition[isArrayKey] ?
122 find(a, function (a) {
123 return check(fieldDefinition[typeKey], b, a)
124 }) : check(fieldDefinition[typeKey], b, a)
125 }
126}
127
128function match (fields, options, record) {
129 var key
130
131 for (key in options)
132 switch (key) {
133 case 'and':
134 if (!matchByLogicalAnd(fields, options[key], record)) return false
135 break
136 case 'or':
137 if (!matchByLogicalOr(fields, options[key], record)) return false
138 break
139 case 'not':
140 if (match(fields, options[key], record)) return false
141 break
142 case 'range':
143 if (!matchByRange(fields, options[key], record)) return false
144 break
145 case 'match':
146 if (!matchByField(fields, options[key], record)) return false
147 break
148 case 'exists':
149 if (!matchByExistence(fields, options[key], record)) return false
150 break
151 default:
152 }
153
154 return true
155}
156
157function matchByLogicalAnd (fields, clauses, record) {
158 var i
159
160 for (i = 0; i < clauses.length; i++)
161 if (!match(fields, clauses[i], record)) return false
162
163 return true
164}
165
166function matchByLogicalOr (fields, clauses, record) {
167 var i
168
169 for (i = 0; i < clauses.length; i++)
170 if (match(fields, clauses[i], record)) return true
171
172 return false
173}
174
175function matchByField (fields, match, record) {
176 var field, matches
177
178 for (field in match) {
179 matches = match[field]
180 if (!Array.isArray(matches)) matches = [ matches ]
181 if (find(matches, checkValue(fields[field], record[field])) === void 0)
182 return false
183 }
184
185 return true
186}
187
188
189function matchByExistence (fields, exists, record) {
190 var field, value, isArray
191
192 for (field in exists) {
193 value = record[field]
194 isArray = fields[field][isArrayKey]
195 if (exists[field]) {
196 if (!value) return false
197 if (isArray && !value.length) return false
198 }
199 else {
200 if (value && !isArray) return false
201 if (isArray && value.length) return false
202 }
203 }
204
205 return true
206}
207
208
209function matchByRange (fields, ranges, record) {
210 var compare = {}
211 var field, fieldDefinition, fieldType, fieldIsArray, range, value
212
213 for (field in ranges) {
214 fieldDefinition = fields[field]
215 fieldType = fieldDefinition[typeKey]
216 fieldIsArray = fieldDefinition[isArrayKey]
217
218 // Skip for singular link fields.
219 if (!fieldType && !fieldIsArray) continue
220
221 range = ranges[field]
222 value = record[field]
223
224 if (value == null) return false
225 if (fieldIsArray) value = value ? value.length : 0
226
227 if (!compare[field])
228 compare[field] = !fieldIsArray ? fieldType.compare ||
229 find(comparisons, findByType(fieldType))[1] :
230 find(comparisons, findByType(Number))[1]
231
232 if (range[0] !== null && compare[field](value, range[0]) < 0)
233 return false
234
235 if (range[1] !== null && compare[field](range[1], value) < 0)
236 return false
237 }
238
239 return true
240}
241
242
243function findByType (type) {
244 return function (pair) {
245 var hasMatch = type === pair[0] ||
246 type.name === pair[0].name
247
248 // In case this errors due to security sandboxing, just skip this check.
249 if (!hasMatch)
250 try {
251 hasMatch = pair[0] === type.prototype.constructor
252 }
253 catch (e) {
254 // Swallow this error.
255 }
256
257 return hasMatch
258 }
259}
260
261
262function compare (fields, sort) {
263 var field, compare, a, b, isAscending,
264 fieldDefinition, fieldIsArray, fieldType, result
265
266 return function (x, y) {
267 for (field in sort) {
268 a = x[field]
269 b = y[field]
270 isAscending = sort[field]
271 fieldDefinition = fields[field]
272 fieldIsArray = fieldDefinition[isArrayKey]
273 fieldType = fieldDefinition[typeKey]
274
275 if (a === null) return 1
276 if (b === null) return -1
277
278 result = 0
279
280 if (fieldIsArray) result = a.length - b.length
281 else if (fieldType) {
282 compare = fieldType.compare ||
283 find(comparisons, findByType(fieldType))[1]
284 if (!compare) throw new Error('Missing "compare" function.')
285 result = compare(a, b)
286 }
287
288 if (result === 0) continue
289
290 return isAscending ? result : -result
291 }
292
293 return 0
294 }
295}
296
297}).call(this,require("buffer").Buffer)
298},{"../../common/array/find":8,"../../common/deep_equal":19,"../../common/errors":20,"../../common/generate_id":22,"../../common/keys":24,"../../common/message":25,"buffer":47}],2:[function(require,module,exports){
299'use strict'
300
301var common = require('../common')
302var generateId = common.generateId
303
304
305exports.inputRecord = function (type, record) {
306 var recordTypes = this.recordTypes
307 var primaryKey = this.keys.primary
308 var isArrayKey = this.keys.isArray
309 var fields = recordTypes[type]
310 var fieldsArray = Object.getOwnPropertyNames(fields)
311 var result = {}
312 var i, j, field
313
314 // Ensure that ID exists on the record.
315 result[primaryKey] = primaryKey in record ?
316 record[primaryKey] : generateId()
317
318 for (i = 0, j = fieldsArray.length; i < j; i++) {
319 field = fieldsArray[i]
320 if (!record.hasOwnProperty(field)) {
321 result[field] = fields[field][isArrayKey] ? [] : null
322 continue
323 }
324
325 result[field] = record[field]
326 }
327
328 return result
329}
330
331
332exports.outputRecord = function (type, record) {
333 var recordTypes = this.recordTypes
334 var primaryKey = this.keys.primary
335 var isArrayKey = this.keys.isArray
336 var denormalizedInverseKey = this.keys.denormalizedInverse
337 var fields = recordTypes[type]
338 var fieldsArray = Object.getOwnPropertyNames(fields)
339 var result = {}
340 var i, j, field, hasField, value
341
342 // Ensure that ID exists on the record.
343 result[primaryKey] = record[primaryKey]
344
345 for (i = 0, j = fieldsArray.length; i < j; i++) {
346 field = fieldsArray[i]
347 hasField = record.hasOwnProperty(field)
348 value = hasField ? record[field] :
349 fields[field][isArrayKey] ? [] : null
350
351 // Do not enumerate denormalized fields.
352 if (fields[field][denormalizedInverseKey]) {
353 Object.defineProperty(result, field, {
354 configurable: true, writable: true, value: value
355 })
356 continue
357 }
358
359 if (hasField) result[field] = value
360 }
361
362 return result
363}
364
365},{"../common":1}],3:[function(require,module,exports){
366'use strict'
367
368var applyUpdate = require('../../../common/apply_update')
369var map = require('../../../common/array/map')
370var promise = require('../../../common/promise')
371
372var common = require('../common')
373var applyOptions = common.applyOptions
374
375var helpers = require('./helpers')
376var inputRecord = helpers.inputRecord
377var outputRecord = helpers.outputRecord
378
379
380/**
381 * Memory adapter.
382 */
383module.exports = function (Adapter) {
384 function MemoryAdapter (properties) {
385 Adapter.call(this, properties)
386 if (!this.options) this.options = {}
387 if (!('recordsPerType' in this.options))
388 this.options.recordsPerType = 1000
389 }
390
391 MemoryAdapter.prototype = new Adapter()
392
393 MemoryAdapter.prototype.connect = function () {
394 var Promise = promise.Promise
395 var recordTypes = this.recordTypes
396 var type
397
398 this.db = {}
399
400 for (type in recordTypes)
401 this.db[type] = {}
402
403 return Promise.resolve()
404 }
405
406
407 MemoryAdapter.prototype.disconnect = function () {
408 var Promise = promise.Promise
409
410 delete this.db
411 return Promise.resolve()
412 }
413
414
415 MemoryAdapter.prototype.find = function (type, ids, options, meta) {
416 var Promise = promise.Promise
417 var self = this
418 var recordTypes = self.recordTypes
419 var fields = recordTypes[type]
420 var collection = self.db[type]
421 var records = []
422 var i, j, id, record
423
424 if (ids && !ids.length) return Adapter.prototype.find.call(self)
425
426 if (ids) for (i = 0, j = ids.length; i < j; i++) {
427 id = ids[i]
428 if (collection.hasOwnProperty(id)) {
429 record = collection[id]
430
431 // LRU update.
432 delete collection[id]
433 collection[id] = record
434
435 records.push(outputRecord.call(self, type, record))
436 }
437 }
438
439 else for (id in collection)
440 records.push(outputRecord.call(self, type, collection[id]))
441
442 return Promise.resolve(applyOptions(fields, records, options, meta))
443 }
444
445
446 MemoryAdapter.prototype.create = function (type, records, meta) {
447 var Promise = promise.Promise
448 var self = this
449 var message = self.message
450 var recordsPerType = self.options.recordsPerType
451 var primaryKey = self.keys.primary
452 var ConflictError = self.errors.ConflictError
453 var collection = self.db[type]
454 var i, j, record, id, ids, language
455
456 if (!meta) meta = {}
457 language = meta.language
458
459 records = map(records, function (record) {
460 return inputRecord.call(self, type, record)
461 })
462
463 // First check for collisions.
464 for (i = 0, j = records.length; i < j; i++) {
465 record = records[i]
466 id = record[primaryKey]
467
468 if (collection.hasOwnProperty(id))
469 return Promise.reject(new ConflictError(
470 message('RecordExists', language, { id: id })))
471 }
472
473 // Then save it to memory.
474 for (i = 0, j = records.length; i < j; i++) {
475 record = records[i]
476 collection[record[primaryKey]] = record
477 }
478
479 // Clear least recently used records.
480 if (recordsPerType) {
481 ids = Object.keys(collection)
482
483 if (ids.length > recordsPerType) {
484 ids = ids.slice(0, ids.length - recordsPerType)
485
486 for (i = 0, j = ids.length; i < j; i++)
487 delete collection[ids[i]]
488 }
489 }
490
491 return Promise.resolve(map(records, function (record) {
492 return outputRecord.call(self, type, record)
493 }))
494 }
495
496
497 MemoryAdapter.prototype.update = function (type, updates) {
498 var Promise = promise.Promise
499 var self = this
500 var primaryKey = self.keys.primary
501 var collection = self.db[type]
502 var count = 0
503 var i, j, update, id, record
504
505 if (!updates.length) return Adapter.prototype.update.call(self)
506
507 for (i = 0, j = updates.length; i < j; i++) {
508 update = updates[i]
509 id = update[primaryKey]
510 record = collection[id]
511
512 if (!record) continue
513
514 count++
515 record = outputRecord.call(self, type, record)
516
517 applyUpdate(record, update)
518
519 // LRU update.
520 delete collection[id]
521
522 collection[id] = inputRecord.call(self, type, record)
523 }
524
525 return Promise.resolve(count)
526 }
527
528
529 MemoryAdapter.prototype.delete = function (type, ids) {
530 var Promise = promise.Promise
531 var collection = this.db[type]
532 var count = 0
533 var i, j, id
534
535 if (ids && !ids.length) return Adapter.prototype.delete.call(this)
536
537 if (ids) for (i = 0, j = ids.length; i < j; i++) {
538 id = ids[i]
539 if (collection[id]) {
540 delete collection[id]
541 count++
542 }
543 }
544
545 else for (id in collection) {
546 delete collection[id]
547 count++
548 }
549
550 return Promise.resolve(count)
551 }
552
553 // Expose utility functions.
554 MemoryAdapter.common = common
555
556 // Expose features for introspection.
557 MemoryAdapter.features = {
558 logicalOperators: true
559 }
560
561 return MemoryAdapter
562}
563
564},{"../../../common/apply_update":6,"../../../common/array/map":10,"../../../common/promise":28,"../common":1,"./helpers":2}],4:[function(require,module,exports){
565'use strict'
566
567var assign = require('../common/assign')
568var promise = require('../common/promise')
569var memoryAdapter = require('./adapters/memory')
570
571
572/**
573 * Adapter is an abstract base class containing methods to be implemented. All
574 * records returned by the adapter must have the primary key `id`. The primary
575 * key **MUST** be a string or a number.
576 *
577 * It has one static property, `defaultAdapter` which is a reference to the
578 * memory adapter.
579 */
580function Adapter (properties) {
581 assign(this, properties)
582}
583
584
585/**
586 * The Adapter should not be instantiated directly, since the constructor
587 * function accepts dependencies. The keys which are injected are:
588 *
589 * - `recordTypes`: an object which enumerates record types and their
590 * definitions.
591 * - `options`: the options passed to the adapter.
592 * - `common`: an object containing all internal utilities.
593 * - `errors`: same as static property on Fortune class.
594 * - `keys`: an object which enumerates reserved constants for record type
595 * - `message`: a function with the signature (`id`, `language`, `data`).
596 *
597 * These keys are accessible on the instance (`this`).
598 *
599 * An adapter may expose a `features` static property, which is an object
600 * that can contain boolean flags. These are used mainly for checking which
601 * additional features may be tested.
602 *
603 * - `logicalOperators`: whether or not `and` and `or` queries are supported.
604 */
605Adapter.prototype.constructor = function () {
606 // This exists here only for documentation purposes.
607}
608
609delete Adapter.prototype.constructor
610
611
612/**
613 * The responsibility of this method is to ensure that the record types
614 * defined are consistent with the backing data store. If there is any
615 * mismatch it should either try to reconcile differences or fail.
616 * This method **SHOULD NOT** be called manually, and it should not accept
617 * any parameters. This is the time to do setup tasks like create tables,
618 * ensure indexes, etc. On successful completion, it should resolve to no
619 * value.
620 *
621 * @return {Promise}
622 */
623Adapter.prototype.connect = function () {
624 var Promise = promise.Promise
625 return Promise.resolve()
626}
627
628
629/**
630 * Close the database connection.
631 *
632 * @return {Promise}
633 */
634Adapter.prototype.disconnect = function () {
635 var Promise = promise.Promise
636 return Promise.resolve()
637}
638
639
640/**
641 * Create records. A successful response resolves to the newly created
642 * records.
643 *
644 * **IMPORTANT**: the record must have initial values for each field defined
645 * in the record type. For non-array fields, it should be `null`, and for
646 * array fields it should be `[]` (empty array). Note that not all fields in
647 * the record type may be enumerable, such as denormalized inverse fields, so
648 * it may be necessary to iterate over fields using
649 * `Object.getOwnPropertyNames`.
650 *
651 * @param {String} type
652 * @param {Object[]} records
653 * @param {Object} [meta]
654 * @return {Promise}
655 */
656Adapter.prototype.create = function () {
657 var Promise = promise.Promise
658 return Promise.resolve([])
659}
660
661
662/**
663 * Find records by IDs and options. If IDs is undefined, it should try to
664 * return all records. However, if IDs is an empty array, it should be a
665 * no-op. The format of the options may be as follows:
666 *
667 * ```js
668 * {
669 * sort: { ... },
670 * fields: { ... },
671 * exists: { ... },
672 * match: { ... },
673 * range: { ... },
674 *
675 * // Limit results to this number. Zero means no limit.
676 * limit: 0,
677 *
678 * // Offset results by this much from the beginning.
679 * offset: 0,
680 *
681 * // The logical operator "and", may be nested. Optional feature.
682 * and: { ... },
683 *
684 * // The logical operator "or", may be nested. Optional feature.
685 * or: { ... },
686 *
687 * // Reserved field for custom querying.
688 * query: null
689 * }
690 * ```
691 *
692 * For the fields `exists`, `match`, and `range`, the logical operator should
693 * be "and". The `query` field may be used on a per adapter basis to provide
694 * custom querying functionality.
695 *
696 * The syntax of the `sort` object is as follows:
697 *
698 * ```js
699 * {
700 * age: false, // descending
701 * name: true // ascending
702 * }
703 * ```
704 *
705 * Fields can be specified to be either included or omitted, but not both.
706 * Use the values `true` to include, or `false` to omit. The syntax of the
707 * `fields` object is as follows:
708 *
709 * ```js
710 * {
711 * name: true, // include this field
712 * age: true // also include this field
713 * }
714 * ```
715 *
716 * The `exists` object specifies if a field should exist or not (`true` or
717 * `false`). For array fields, it should check for non-zero length.
718 *
719 * ```js
720 * {
721 * name: true, // check if this fields exists
722 * age: false // check if this field doesn't exist
723 * }
724 * ```
725 *
726 * The syntax of the `match` object is straightforward:
727 *
728 * ```js
729 * {
730 * name: 'value', // exact match or containment if array
731 * friends: [ 'joe', 'bob' ] // match any one of these values
732 * }
733 * ```
734 *
735 * The `range` object is used to filter between lower and upper bounds. It
736 * should take precedence over `match`. For array fields, it should apply on
737 * the length of the array. For singular link fields, it should not apply.
738 *
739 * ```js
740 * {
741 * range: { // Ranges should be inclusive.
742 * age: [ 18, null ], // From 18 and above.
743 * name: [ 'a', 'd' ], // Starting with letters A through C.
744 * createdAt: [ null, new Date(2016, 0) ] // Dates until 2016.
745 * }
746 * }
747 * ```
748 *
749 * The return value of the promise should be an array, and the array **MUST**
750 * have a `count` property that is the total number of records without limit
751 * and offset.
752 *
753 * @param {String} type
754 * @param {String[]|Number[]} [ids]
755 * @param {Object} [options]
756 * @param {Object} [meta]
757 * @return {Promise}
758 */
759Adapter.prototype.find = function () {
760 var Promise = promise.Promise
761 var results = []
762 results.count = 0
763 return Promise.resolve(results)
764}
765
766
767/**
768 * Update records by IDs. Success should resolve to the number of records
769 * updated. The `updates` parameter should be an array of objects that
770 * correspond to updates by IDs. Each update object must be as follows:
771 *
772 * ```js
773 * {
774 * // ID to update. Required.
775 * id: 1,
776 *
777 * // Replace a value of a field. Use a `null` value to unset a field.
778 * replace: { name: 'Bob' },
779 *
780 * // Append values to an array field. If the value is an array, all of
781 * // the values should be pushed.
782 * push: { pets: 1 },
783 *
784 * // Remove values from an array field. If the value is an array, all of
785 * // the values should be removed.
786 * pull: { friends: [ 2, 3 ] },
787 *
788 * // The `operate` field is specific to the adapter. This should take
789 * // precedence over all of the above. Warning: using this may bypass
790 * // field definitions and referential integrity. Use at your own risk.
791 * operate: null
792 * }
793 * ```
794 *
795 * Things to consider:
796 *
797 * - `push` and `pull` can not be applied to non-arrays.
798 * - The same value in the same field should not exist in both `push` and
799 * `pull`.
800 *
801 * @param {String} type
802 * @param {Object[]} updates
803 * @param {Object} [meta]
804 * @return {Promise}
805 */
806Adapter.prototype.update = function () {
807 var Promise = promise.Promise
808 return Promise.resolve(0)
809}
810
811
812/**
813 * Delete records by IDs, or delete the entire collection if IDs are
814 * undefined or empty. Success should resolve to the number of records
815 * deleted.
816 *
817 * @param {String} type
818 * @param {String[]|Number[]} [ids]
819 * @param {Object} [meta]
820 * @return {Promise}
821 */
822Adapter.prototype.delete = function () {
823 var Promise = promise.Promise
824 return Promise.resolve(0)
825}
826
827
828/**
829 * Begin a transaction to write to the data store. This method is optional
830 * to implement, but useful for ACID. It should resolve to an object
831 * containing all of the adapter methods.
832 *
833 * @return {Promise}
834 */
835Adapter.prototype.beginTransaction = function () {
836 var Promise = promise.Promise
837 return Promise.resolve(this)
838}
839
840
841/**
842 * End a transaction. This method is optional to implement.
843 * It should return a Promise with no value if the transaction is
844 * completed successfully, or reject the promise if it failed.
845 *
846 * @param {Error} [error] - If an error is passed, roll back the transaction.
847 * @return {Promise}
848 */
849Adapter.prototype.endTransaction = function () {
850 var Promise = promise.Promise
851 return Promise.resolve()
852}
853
854
855/**
856 * Apply operators on a record, then return the record. If you make use of
857 * update operators, you should implement this method so that the internal
858 * implementation of update requests get records in the correct state. This
859 * method is optional to implement.
860 *
861 * @param {Object} record
862 * @param {Object} operators - The `operate` field on an `update` object.
863 * @return {Object}
864 */
865Adapter.prototype.applyOperators = function (record) {
866 return record
867}
868
869
870// Expose the default adapter.
871Adapter.DefaultAdapter = memoryAdapter(Adapter)
872
873// Expose features object.
874Adapter.features = {}
875
876module.exports = Adapter
877
878},{"../common/assign":14,"../common/promise":28,"./adapters/memory":3}],5:[function(require,module,exports){
879'use strict'
880
881var Adapter = require('./')
882var common = require('../common')
883var errors = require('../common/errors')
884var keys = require('../common/keys')
885var promise = require('../common/promise')
886
887
888/**
889 * A singleton for the adapter. For internal use.
890 */
891function AdapterSingleton (properties) {
892 var CustomAdapter, input
893
894 input = Array.isArray(properties.adapter) ?
895 properties.adapter : [ properties.adapter ]
896
897 if (typeof input[0] !== 'function')
898 throw new TypeError('The adapter must be a function.')
899
900 CustomAdapter = Adapter.prototype
901 .isPrototypeOf(input[0].prototype) ? input[0] : input[0](Adapter)
902
903 if (!Adapter.prototype.isPrototypeOf(CustomAdapter.prototype))
904 throw new TypeError('The adapter must inherit the Adapter class.')
905
906 return new CustomAdapter({
907 options: input[1] || {},
908 recordTypes: properties.recordTypes,
909 features: CustomAdapter.features,
910 common: common,
911 errors: errors,
912 keys: keys,
913 message: properties.message,
914 Promise: promise.Promise
915 })
916}
917
918
919module.exports = AdapterSingleton
920
921},{"../common":23,"../common/errors":20,"../common/keys":24,"../common/promise":28,"./":4}],6:[function(require,module,exports){
922'use strict'
923
924var pull = require('./array/pull')
925
926
927/**
928 * Given a record and an update object, apply the update on the record. Note
929 * that the `operate` object is unapplied here.
930 *
931 * @param {Object} record
932 * @param {Object} update
933 */
934module.exports = function applyUpdate (record, update) {
935 var field
936
937 for (field in update.replace)
938 record[field] = update.replace[field]
939
940 for (field in update.push)
941 record[field] = record[field] ?
942 record[field].concat(update.push[field]) :
943 [].concat(update.push[field])
944
945 for (field in update.pull)
946 record[field] = record[field] ?
947 pull(record[field], update.pull[field]) : []
948}
949
950},{"./array/pull":11}],7:[function(require,module,exports){
951'use strict'
952
953/**
954 * A more performant `Array.prototype.filter`.
955 *
956 * @param {*[]} array
957 * @param {Function} fn
958 * @return {Boolean}
959 */
960module.exports = function filter (array, fn) {
961 var i, j, k = [], l = 0
962
963 for (i = 0, j = array.length; i < j; i++)
964 if (fn(array[i], i, array))
965 k[l++] = array[i]
966
967 return k
968}
969
970},{}],8:[function(require,module,exports){
971'use strict'
972
973/**
974 * A more performant `Array.prototype.find`.
975 *
976 * @param {*[]} array
977 * @param {Function} fn
978 * @return {*}
979 */
980module.exports = function find (array, fn) {
981 var i, j, value, result
982
983 for (i = 0, j = array.length; i < j; i++) {
984 value = array[i]
985 result = fn(value)
986 if (result) return value
987 }
988
989 return void 0
990}
991
992},{}],9:[function(require,module,exports){
993'use strict'
994
995/**
996 * A more performant `Array.prototype.includes`.
997 *
998 * @param {*[]} array
999 * @param {*} value
1000 * @return {Boolean}
1001 */
1002module.exports = function includes (array, value) {
1003 var i, j
1004
1005 for (i = 0, j = array.length; i < j; i++)
1006 if (array[i] === value) return true
1007
1008 return false
1009}
1010
1011},{}],10:[function(require,module,exports){
1012'use strict'
1013
1014/**
1015 * A more performant `Array.prototype.map`.
1016 *
1017 * @param {*[]} array
1018 * @param {Function} fn
1019 * @return {Boolean}
1020 */
1021module.exports = function map (array, fn) {
1022 var i, j, k = [], l = 0
1023
1024 for (i = 0, j = array.length; i < j; i++)
1025 k[l++] = fn(array[i], i, array)
1026
1027 return k
1028}
1029
1030},{}],11:[function(require,module,exports){
1031'use strict'
1032
1033
1034/**
1035 * Pull primitive values from an array.
1036 *
1037 * @param {*[]} array
1038 * @param {*|*[]} values
1039 * @return {*[]}
1040 */
1041module.exports = function pull (array, values) {
1042 var hash = {}, clone = [], value
1043 var i, j
1044
1045 if (Array.isArray(values))
1046 for (i = 0, j = values.length; i < j; i++)
1047 hash[values[i]] = true
1048 else hash[values] = true
1049
1050 // Need to iterate backwards.
1051 for (i = array.length; i--;) {
1052 value = array[i]
1053 if (!hash.hasOwnProperty(value))
1054 // Unshift because it is iterating backwards.
1055 clone.unshift(value)
1056 }
1057
1058 return clone
1059}
1060
1061},{}],12:[function(require,module,exports){
1062'use strict'
1063
1064/**
1065 * A more performant `Array.prototype.reduce`.
1066 *
1067 * @param {*[]} array
1068 * @param {Function} fn
1069 * @param {*} [initialValue]
1070 * @return {Boolean}
1071 */
1072module.exports = function reduce (array, fn, initialValue) {
1073 var i, j, k = initialValue
1074
1075 for (i = 0, j = array.length; i < j; i++)
1076 k = fn(k, array[i], i, array)
1077
1078 return k
1079}
1080
1081},{}],13:[function(require,module,exports){
1082'use strict'
1083
1084/**
1085 * Return an array with unique values. Values must be primitive, and the array
1086 * may not be sparse.
1087 *
1088 * @param {Array}
1089 * @return {Array}
1090 */
1091module.exports = function unique (a) {
1092 var seen = {}
1093 var result = []
1094 var i, j, k
1095
1096 for (i = 0, j = a.length; i < j; i++) {
1097 k = a[i]
1098 if (seen.hasOwnProperty(k)) continue
1099 result.push(k)
1100 seen[k] = true
1101 }
1102
1103 return result
1104}
1105
1106},{}],14:[function(require,module,exports){
1107'use strict'
1108
1109/**
1110 * Like `Object.assign`, but faster and more restricted in what it does.
1111 *
1112 * @param {Object} target
1113 * @return {Object}
1114 */
1115module.exports = function assign (target) {
1116 var i, j, key, source
1117
1118 for (i = 1, j = arguments.length; i < j; i++) {
1119 source = arguments[i]
1120
1121 if (source == null) continue
1122
1123 for (key in source)
1124 target[key] = source[key]
1125 }
1126
1127 return target
1128}
1129
1130},{}],15:[function(require,module,exports){
1131'use strict'
1132
1133module.exports = function castToNumber (id) {
1134 // Stolen from jQuery source code:
1135 // https://api.jquery.com/jQuery.isNumeric/
1136 var float = Number.parseFloat(id)
1137 return id - float + 1 >= 0 ? float : id
1138}
1139
1140},{}],16:[function(require,module,exports){
1141(function (Buffer){
1142'use strict'
1143
1144var errors = require('./errors')
1145var message = require('./message')
1146var castToNumber = require('./cast_to_number')
1147var BadRequestError = errors.BadRequestError
1148var buffer = Buffer.from || function (input, encoding) {
1149 return new Buffer(input, encoding)
1150}
1151
1152
1153var castByType = [
1154 [ Number, function (x) { return parseFloat(x) } ],
1155
1156 [ Date, function (x, options) {
1157 if (typeof x === 'string') {
1158 x = Date.parse(x)
1159 if (Number.isNaN(x)) throw new BadRequestError(
1160 message('DateISO8601', options.language))
1161 }
1162
1163 x = new Date(x)
1164 if (Number.isNaN(x.getTime())) throw new BadRequestError(
1165 message('DateInvalid', options.language))
1166
1167 return x
1168 } ],
1169
1170 [ Buffer, function (x, options) {
1171 var bufferEncoding = options && options.bufferEncoding ?
1172 options.bufferEncoding : 'base64'
1173
1174 if (typeof x !== 'string') throw new BadRequestError(
1175 message('BufferEncoding', options.language, {
1176 bufferEncoding: bufferEncoding
1177 }))
1178
1179 return buffer(x, bufferEncoding)
1180 } ],
1181
1182 [ Boolean, function (x) {
1183 if (typeof x === 'string')
1184 return (/^(?:true|1|yes|t|y)$/i).test(x)
1185 return Boolean(x)
1186 } ],
1187
1188 [ Object, function (x, options) {
1189 if (typeof x === 'string') return JSON.parse(x)
1190 if (typeof x === 'object') return x
1191 throw new BadRequestError(message('JSONParse', options.language))
1192 } ],
1193
1194 [ String, function (x) { return '' + x } ]
1195]
1196
1197
1198/**
1199 * Cast a value to the given type. Skip if type is missing or value is null.
1200 *
1201 * @param {*} value
1202 * @param {Function} type - Constructor function.
1203 * @param {Object} [options]
1204 * @return {*}
1205 */
1206module.exports = function castValue (value, type, options) {
1207 var i, j, pair, hasMatch, cast
1208
1209 // Special case for empty string: it should be null.
1210 if (value === '') return null
1211
1212 if (type)
1213 for (i = 0, j = castByType.length; i < j; i++) {
1214 pair = castByType[i]
1215 hasMatch = pair[0] === type || pair[0].name === type.name
1216
1217 if (!hasMatch)
1218 try {
1219 hasMatch = pair[0] === type.prototype.constructor
1220 }
1221 catch (e) {
1222 // Swallow this error.
1223 }
1224
1225 if (hasMatch) {
1226 cast = pair[1]
1227 break
1228 }
1229 }
1230 else return castToNumber(value)
1231
1232 return cast && value !== null ? cast(value, options) : value
1233}
1234
1235}).call(this,require("buffer").Buffer)
1236},{"./cast_to_number":15,"./errors":20,"./message":25,"buffer":47}],17:[function(require,module,exports){
1237'use strict'
1238
1239/**
1240 * A fast deep clone function, which covers mostly serializable objects.
1241 *
1242 * @param {*}
1243 * @return {*}
1244 */
1245module.exports = function clone (input) {
1246 var output, key, value, isArray
1247
1248 if (Array.isArray(input)) isArray = true
1249 else if (input == null || Object.getPrototypeOf(input) !== Object.prototype)
1250 return input
1251
1252 output = isArray ? [] : {}
1253
1254 for (key in input) {
1255 value = input[key]
1256 output[key] = value !== null && value !== undefined &&
1257 Object.getPrototypeOf(value) === Object.prototype ||
1258 Array.isArray(value) ? clone(value) : value
1259 }
1260
1261 return output
1262}
1263
1264},{}],18:[function(require,module,exports){
1265'use strict'
1266
1267var hasSymbol = typeof Symbol === 'function'
1268var i, j, key
1269var privateKeys = [
1270 // This is set on the field definition object internally if it is an
1271 // automatically generated denormalized field.
1272 'denormalizedInverse',
1273
1274 // Used to map update objects to records.
1275 'updateRecord',
1276
1277 // Used to map update objects to a hash of linked records.
1278 'linkedHash'
1279]
1280
1281// The primary key that must exist per record, can not be user defined.
1282exports.primary = 'id'
1283
1284// The names of certain reserved keys per field definition.
1285exports.type = 'type'
1286exports.link = 'link'
1287exports.inverse = 'inverse'
1288exports.isArray = 'isArray'
1289
1290// Should be reserved for private use.
1291for (i = 0, j = privateKeys.length; i < j; i++) {
1292 key = privateKeys[i]
1293 exports[key] = hasSymbol ? Symbol(key) : '__' + key + '__'
1294}
1295
1296// Events.
1297exports.change = 'change'
1298exports.sync = 'sync'
1299exports.connect = 'connect'
1300exports.disconnect = 'disconnect'
1301exports.failure = 'failure'
1302
1303// Methods.
1304exports.find = 'find'
1305exports.create = 'create'
1306exports.update = 'update'
1307exports.delete = 'delete'
1308
1309},{}],19:[function(require,module,exports){
1310(function (Buffer){
1311'use strict'
1312
1313/**
1314 * A fast recursive equality check, which covers limited use cases.
1315 *
1316 * @param {Object}
1317 * @param {Object}
1318 * @return {Boolean}
1319 */
1320function deepEqual (a, b) {
1321 var key, value, compare, aLength = 0, bLength = 0
1322
1323 // If they are the same object, don't need to go further.
1324 if (a === b) return true
1325
1326 // Both objects must be defined.
1327 if (!a || !b) return false
1328
1329 // Objects must be of the same type.
1330 if (a.prototype !== b.prototype) return false
1331
1332 for (key in a) {
1333 aLength++
1334 value = a[key]
1335 compare = b[key]
1336
1337 if (typeof value === 'object') {
1338 if (typeof compare !== 'object' || !deepEqual(value, compare))
1339 return false
1340 continue
1341 }
1342
1343 if (Buffer.isBuffer(value)) {
1344 if (!Buffer.isBuffer(compare) || !value.equals(compare))
1345 return false
1346 continue
1347 }
1348
1349 if (value && typeof value.getTime === 'function') {
1350 if (!compare || typeof compare.getTime !== 'function' ||
1351 value.getTime() !== compare.getTime())
1352 return false
1353 continue
1354 }
1355
1356 if (value !== compare) return false
1357 }
1358
1359 for (key in b) bLength++
1360
1361 // Keys must be of same length.
1362 return aLength === bLength
1363}
1364
1365
1366module.exports = deepEqual
1367
1368}).call(this,{"isBuffer":require("../../node_modules/is-buffer/index.js")})
1369},{"../../node_modules/is-buffer/index.js":51}],20:[function(require,module,exports){
1370'use strict'
1371
1372var responseClass = require('./response_classes')
1373
1374exports.BadRequestError = responseClass.BadRequestError
1375exports.UnauthorizedError = responseClass.UnauthorizedError
1376exports.ForbiddenError = responseClass.ForbiddenError
1377exports.NotFoundError = responseClass.NotFoundError
1378exports.MethodError = responseClass.MethodError
1379exports.NotAcceptableError = responseClass.NotAcceptableError
1380exports.ConflictError = responseClass.ConflictError
1381exports.UnsupportedError = responseClass.UnsupportedError
1382exports.UnprocessableError = responseClass.UnprocessableError
1383exports.nativeErrors = responseClass.nativeErrors
1384
1385},{"./response_classes":29}],21:[function(require,module,exports){
1386'use strict'
1387
1388var constants = require('./constants')
1389
1390exports.change = constants.change
1391exports.sync = constants.sync
1392exports.connect = constants.connect
1393exports.disconnect = constants.disconnect
1394exports.failure = constants.failure
1395
1396},{"./constants":18}],22:[function(require,module,exports){
1397'use strict'
1398
1399// Modified base64 with "+" as "-" and "/" as "_".
1400var charset =
1401 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
1402 'abcdefghijklmnopqrstuvwxyz' +
1403 '0123456789-_'
1404
1405var charsetLength = charset.length
1406
1407// Should be a multiple of 3 to avoid padding characters.
1408var keyLength = 3 * 5
1409
1410module.exports = function generateId () {
1411 var i, array = []
1412
1413 for (i = 0; i < keyLength; i++)
1414 array.push(charset.charAt(Math.floor(Math.random() * charsetLength)))
1415
1416 return array.join('')
1417}
1418
1419},{}],23:[function(require,module,exports){
1420'use strict'
1421
1422module.exports = {
1423 // Keys
1424 constants: require('./constants'),
1425 keys: require('./keys'),
1426 events: require('./events'),
1427 methods: require('./methods'),
1428
1429 // Utility functions
1430 assign: require('./assign'),
1431 castToNumber: require('./cast_to_number'),
1432 castValue: require('./cast_value'),
1433 clone: require('./clone'),
1434 deepEqual: require('./deep_equal'),
1435 generateId: require('./generate_id'),
1436 applyUpdate: require('./apply_update'),
1437
1438 // i18n
1439 message: require('./message'),
1440
1441 // Typed responses
1442 responses: require('./response_classes'),
1443 errors: require('./errors'),
1444 successes: require('./success'),
1445
1446 // Arrays
1447 filter: require('./array/filter'),
1448 find: require('./array/find'),
1449 includes: require('./array/includes'),
1450 map: require('./array/map'),
1451 pull: require('./array/pull'),
1452 reduce: require('./array/reduce'),
1453 unique: require('./array/unique')
1454}
1455
1456},{"./apply_update":6,"./array/filter":7,"./array/find":8,"./array/includes":9,"./array/map":10,"./array/pull":11,"./array/reduce":12,"./array/unique":13,"./assign":14,"./cast_to_number":15,"./cast_value":16,"./clone":17,"./constants":18,"./deep_equal":19,"./errors":20,"./events":21,"./generate_id":22,"./keys":24,"./message":25,"./methods":27,"./response_classes":29,"./success":30}],24:[function(require,module,exports){
1457'use strict'
1458
1459var constants = require('./constants')
1460
1461exports.primary = constants.primary
1462exports.type = constants.type
1463exports.link = constants.link
1464exports.isArray = constants.isArray
1465exports.inverse = constants.inverse
1466exports.denormalizedInverse = constants.denormalizedInverse
1467
1468},{"./constants":18}],25:[function(require,module,exports){
1469'use strict'
1470
1471var languages = {
1472 en: require('./messages/en')
1473}
1474
1475var key
1476for (key in languages)
1477 message[key] = languages[key]
1478
1479module.exports = message
1480
1481
1482/**
1483 * Message function for i18n.
1484 *
1485 * @param {String} id
1486 * @param {String} language
1487 * @param {Object} [data]
1488 * @return {String}
1489 */
1490function message (id, language, data) {
1491 var genericMessage = 'GenericError'
1492 var self = this || message
1493 var str, key, subtag
1494
1495 if (!self.hasOwnProperty(language)) {
1496 subtag = language && language.match(/.+?(?=-)/)
1497 if (subtag) subtag = subtag[0]
1498 if (self.hasOwnProperty(subtag)) language = subtag
1499 else language = self.defaultLanguage
1500 }
1501
1502 str = self[language].hasOwnProperty(id) ?
1503 self[language][id] :
1504 self[language][genericMessage] || self.en[genericMessage]
1505
1506 if (typeof str === 'string')
1507 for (key in data)
1508 str = str.replace('{' + key + '}', data[key])
1509
1510 if (typeof str === 'function')
1511 str = str(data)
1512
1513 return str
1514}
1515
1516// Assign fallback language to "en".
1517Object.defineProperty(message, 'defaultLanguage', {
1518 value: 'en', writable: true
1519})
1520
1521},{"./messages/en":26}],26:[function(require,module,exports){
1522
1523module.exports = {
1524 GenericError: function(d) { return "An internal error occurred."; },
1525 MalformedRequest: function(d) { return "The request was malformed."; },
1526 InvalidBody: function(d) { return "The request body is invalid."; },
1527 SerializerNotFound: function(d) { return "The serializer for \"" + d.id + "\" does not exist."; },
1528 InputOnly: function(d) { return "Input only."; },
1529 InvalidID: function(d) { return "An ID is invalid."; },
1530 DateISO8601: function(d) { return "Date string must be an ISO 8601 formatted string."; },
1531 DateInvalid: function(d) { return "Date value is invalid."; },
1532 BufferEncoding: function(d) { return "Buffer value must be a " + d.bufferEncoding + "-encoded string."; },
1533 JSONParse: function(d) { return "Could not parse value as JSON."; },
1534 MissingPayload: function(d) { return "Payload is missing."; },
1535 SpecifiedIDs: function(d) { return "IDs should not be specified."; },
1536 InvalidURL: function(d) { return "Invalid URL."; },
1537 RelatedRecordNotFound: function(d) { return "A related record for the field \"" + d.field + "\" was not found."; },
1538 CreateRecordsInvalid: function(d) { return "There are no valid records to be created."; },
1539 CreateRecordsFail: function(d) { return "Records could not be created."; },
1540 CreateRecordMissingID: function(d) { return "An ID on a created record is missing."; },
1541 DeleteRecordsMissingID: function(d) { return "IDs are required for deleting records."; },
1542 DeleteRecordsInvalid: function(d) { return "A record to be deleted could not be found."; },
1543 DeleteRecordsFail: function(d) { return "Not all records specified could be deleted."; },
1544 UnspecifiedType: function(d) { return "The type is unspecified."; },
1545 InvalidType: function(d) { return "The requested type \"" + d.type + "\" is not a valid type."; },
1546 InvalidLink: function(d) { return "The field \"" + d.field + "\" does not define a link."; },
1547 InvalidMethod: function(d) { return "The method \"" + d.method + "\" is unrecognized."; },
1548 CollisionToOne: function(d) { return "Multiple records can not have the same to-one link value on the field \"" + d.field + "\"."; },
1549 CollisionDuplicate: function(d) { return "Duplicate ID \"" + d.id + "\" in the field \"" + d.field + "\"."; },
1550 UpdateRecordMissing: function(d) { return "A record to be updated could not be found."; },
1551 UpdateRecordsInvalid: function(d) { return "There are no valid updates."; },
1552 UpdateRecordMissingID: function(d) { return "An ID on an update is missing."; },
1553 EnforceArrayType: function(d) { return "The value of \"" + d.key + "\" is invalid, it must be an array with values of type \"" + d.type + "\"."; },
1554 EnforceArray: function(d) { return "The value of \"" + d.key + "\" is invalid, it must be an array."; },
1555 EnforceSameID: function(d) { return "An ID of \"" + d.key + "\" is invalid, it cannot be the same ID of the record."; },
1556 EnforceSingular: function(d) { return "The value of \"" + d.key + "\" can not be an array, it must be a singular value."; },
1557 EnforceValue: function(d) { return "The value of \"" + d.key + "\" is invalid, it must be a \"" + d.type + "\"."; },
1558 EnforceValueArray: function(d) { return "A value in the array of \"" + d.key + "\" is invalid, it must be a \"" + d.type + "\"."; },
1559 FieldsFormat: function(d) { return "Fields format is invalid. It may either be inclusive or exclusive, but not both."; },
1560 RecordExists: function(d) { return "A record with ID \"" + d.id + "\" already exists."; }
1561}
1562
1563},{}],27:[function(require,module,exports){
1564'use strict'
1565
1566var constants = require('./constants')
1567
1568exports.find = constants.find
1569exports.create = constants.create
1570exports.update = constants.update
1571exports.delete = constants.delete
1572
1573},{"./constants":18}],28:[function(require,module,exports){
1574'use strict'
1575
1576// This object exists as a container for the Promise implementation. By
1577// default, it's the native one.
1578exports.Promise = Promise
1579
1580},{}],29:[function(require,module,exports){
1581'use strict'
1582
1583var errorClass = require('error-class')
1584var assign = require('./assign')
1585
1586
1587// Successes.
1588exports.OK = function OK (hash) { assign(this, hash) }
1589exports.Created = function Created (hash) { assign(this, hash) }
1590exports.Empty = function Empty (hash) { assign(this, hash) }
1591
1592
1593// Errors.
1594exports.BadRequestError = errorClass('BadRequestError')
1595exports.UnauthorizedError = errorClass('UnauthorizedError')
1596exports.ForbiddenError = errorClass('ForbiddenError')
1597exports.NotFoundError = errorClass('NotFoundError')
1598exports.MethodError = errorClass('MethodError')
1599exports.NotAcceptableError = errorClass('NotAcceptableError')
1600exports.ConflictError = errorClass('ConflictError')
1601exports.UnsupportedError = errorClass('UnsupportedError')
1602exports.UnprocessableError = errorClass('UnprocessableError')
1603
1604
1605// White-list native error types. The list is gathered from here:
1606// https://developer.mozilla.org/en-US/docs/Web/JavaScript/
1607// Reference/Global_Objects/Error
1608exports.nativeErrors = [
1609 Error, TypeError, ReferenceError, RangeError,
1610 SyntaxError, EvalError, URIError
1611]
1612
1613},{"./assign":14,"error-class":48}],30:[function(require,module,exports){
1614'use strict'
1615
1616var responseClass = require('./response_classes')
1617
1618exports.OK = responseClass.OK
1619exports.Created = responseClass.Created
1620exports.Empty = responseClass.Empty
1621
1622},{"./response_classes":29}],31:[function(require,module,exports){
1623'use strict'
1624
1625window.fortune = require('./')
1626
1627},{"./":32}],32:[function(require,module,exports){
1628'use strict'
1629
1630var EventLite = require('event-lite')
1631
1632// Local modules.
1633var memoryAdapter = require('./adapter/adapters/memory')
1634var AdapterSingleton = require('./adapter/singleton')
1635var validate = require('./record_type/validate')
1636var ensureTypes = require('./record_type/ensure_types')
1637var promise = require('./common/promise')
1638var internalRequest = require('./request')
1639var middlewares = internalRequest.middlewares
1640
1641// Static re-exports.
1642var Adapter = require('./adapter')
1643var common = require('./common')
1644var assign = common.assign
1645var methods = common.methods
1646var events = common.events
1647
1648
1649/**
1650 * This is the default export of the `fortune` package. It implements a
1651 * [subset of `EventEmitter`](https://www.npmjs.com/package/event-lite), and it
1652 * has a few static properties attached to it that may be useful to access:
1653 *
1654 * - `Adapter`: abstract base class for the Adapter.
1655 * - `adapters`: included adapters, defaults to memory adapter.
1656 * - `errors`: custom error types, useful for throwing errors in I/O hooks.
1657 * - `methods`: a hash that maps to string constants. Available are: `find`,
1658 * `create`, `update`, and `delete`.
1659 * - `events`: names for events on the Fortune instance. Available are:
1660 * `change`, `sync`, `connect`, `disconnect`, `failure`.
1661 * - `message`: a function which accepts the arguments (`id`, `language`,
1662 * `data`). It has properties keyed by two-letter language codes, which by
1663 * default includes only `en`.
1664 * - `Promise`: assign this to set the Promise implementation that Fortune
1665 * will use.
1666 */
1667function Fortune (recordTypes, options) {
1668 if (!(this instanceof Fortune))
1669 return new Fortune(recordTypes, options)
1670
1671 this.constructor(recordTypes, options)
1672}
1673
1674
1675// Inherit from EventLite class.
1676Fortune.prototype = new EventLite()
1677
1678
1679/**
1680 * Create a new instance, the only required input is record type definitions.
1681 * The first argument must be an object keyed by name, valued by definition
1682 * objects.
1683 *
1684 * Here are some example field definitions:
1685 *
1686 * ```js
1687 * {
1688 * // Top level keys are names of record types.
1689 * person: {
1690 * // Data types may be singular or plural.
1691 * name: String, // Singular string value.
1692 * luckyNumbers: Array(Number), // Array of numbers.
1693 *
1694 * // Relationships may be singular or plural. They must specify which
1695 * // record type it refers to, and may also specify an inverse field
1696 * // which is optional but recommended.
1697 * pets: [ Array('animal'), 'owner' ], // Has many.
1698 * employer: [ 'organization', 'employees' ], // Belongs to.
1699 * likes: Array('thing'), // Has many (no inverse).
1700 * doing: 'activity', // Belongs to (no inverse).
1701 *
1702 * // Reflexive relationships are relationships in which the record type,
1703 * // the first position, is of the same type.
1704 * following: [ Array('person'), 'followers' ],
1705 * followers: [ Array('person'), 'following' ],
1706 *
1707 * // Mutual relationships are relationships in which the inverse,
1708 * // the second position, is defined to be the same field on the same
1709 * // record type.
1710 * friends: [ Array('person'), 'friends' ],
1711 * spouse: [ 'person', 'spouse' ]
1712 * }
1713 * }
1714 * ```
1715 *
1716 * The above shows the shorthand which will be transformed internally to a
1717 * more verbose data structure. The internal structure is as follows:
1718 *
1719 * ```js
1720 * {
1721 * person: {
1722 * // A singular value.
1723 * name: { type: String },
1724 *
1725 * // An array containing values of a single type.
1726 * luckyNumbers: { type: Number, isArray: true },
1727 *
1728 * // Creates a to-many link to `animal` record type. If the field `owner`
1729 * // on the `animal` record type is not an array, this is a many-to-one
1730 * // relationship, otherwise it is many-to-many.
1731 * pets: { link: 'animal', isArray: true, inverse: 'owner' },
1732 *
1733 * // The `min` and `max` keys are open to interpretation by the specific
1734 * // adapter, which may introspect the field definition.
1735 * thing: { type: Number, min: 0, max: 100 },
1736 *
1737 * // Nested field definitions are invalid. Use `Object` type instead.
1738 * nested: { thing: { ... } } // Will throw an error.
1739 * }
1740 * }
1741 * ```
1742 *
1743 * The allowed native types are `String`, `Number`, `Boolean`, `Date`,
1744 * `Object`, and `Buffer`. Note that the `Object` type should be a JSON
1745 * serializable object that may be persisted. The only other allowed type is
1746 * a `Function`, which may be used to define custom types.
1747 *
1748 * A custom type function should accept one argument, the value, and return a
1749 * boolean based on whether the value is valid for the type or not. It may
1750 * optionally have a method `compare`, used for sorting in the built-in
1751 * adapters. The `compare` method should have the same signature as the native
1752 * `Array.prototype.sort`.
1753 *
1754 * A custom type function must inherit one of the allowed native types. For
1755 * example:
1756 *
1757 * ```js
1758 * function Integer (x) { return (x | 0) === x }
1759 * Integer.prototype = new Number()
1760 * ```
1761 *
1762 * The options object may contain the following keys:
1763 *
1764 * - `adapter`: configuration array for the adapter. The default type is the
1765 * memory adapter. If the value is not an array, its settings will be
1766 * considered omitted.
1767 *
1768 * ```js
1769 * {
1770 * adapter: [
1771 * // Must be a class that extends `Fortune.Adapter`, or a function
1772 * // that accepts the Adapter class and returns a subclass. Required.
1773 * Adapter => { ... },
1774 *
1775 * // An options object that is specific to the adapter. Optional.
1776 * { ... }
1777 * ]
1778 * }
1779 * ```
1780 *
1781 * - `hooks`: keyed by type name, valued by an array containing an `input`
1782 * and/or `output` function at indices `0` and `1` respectively.
1783 *
1784 * A hook function takes at least two arguments, the internal `context`
1785 * object and a single `record`. A special case is the `update` argument for
1786 * the `update` method.
1787 *
1788 * There are only two kinds of hooks, before a record is written (input),
1789 * and after a record is read (output), both are optional. If an error occurs
1790 * within a hook function, it will be forwarded to the response. Use typed
1791 * errors to provide the appropriate feedback.
1792 *
1793 * For a create request, the input hook may return the second argument
1794 * `record` either synchronously, or asynchronously as a Promise. The return
1795 * value of a delete request is inconsequential, but it may return a value or
1796 * a Promise. The `update` method accepts a `update` object as a third
1797 * parameter, which may be returned synchronously or as a Promise.
1798 *
1799 * An example hook to apply a timestamp on a record before creation, and
1800 * displaying the timestamp in the server's locale:
1801 *
1802 * ```js
1803 * {
1804 * recordType: [
1805 * (context, record, update) => {
1806 * switch (context.request.method) {
1807 * case 'create':
1808 * record.timestamp = new Date()
1809 * return record
1810 * case 'update': return update
1811 * case 'delete': return null
1812 * }
1813 * },
1814 * (context, record) => {
1815 * record.timestamp = record.timestamp.toLocaleString()
1816 * return record
1817 * }
1818 * ]
1819 * }
1820 * ```
1821 *
1822 * Requests to update a record will **NOT** have the updates already applied
1823 * to the record.
1824 *
1825 * Another feature of the input hook is that it will have access to a
1826 * temporary field `context.transaction`. This is useful for ensuring that
1827 * bulk write operations are all or nothing. Each request is treated as a
1828 * single transaction.
1829 *
1830 * - `documentation`: an object mapping names to descriptions. Note that there
1831 * is only one namepspace, so field names can only have one description.
1832 * This is optional, but useful for the HTML serializer, which also emits
1833 * this information as micro-data.
1834 *
1835 * ```js
1836 * {
1837 * documentation: {
1838 * recordType: 'Description of a type.',
1839 * fieldName: 'Description of a field.',
1840 * anotherFieldName: {
1841 * en: 'Two letter language code indicates localized description.'
1842 * }
1843 * }
1844 * }
1845 * ```
1846 *
1847 * - `settings`: internal settings to configure.
1848 *
1849 * ```js
1850 * {
1851 * settings: {
1852 * // Whether or not to enforce referential integrity. This may be
1853 * // useful to disable on the client-side.
1854 * enforceLinks: true,
1855 *
1856 * // Name of the application used for display purposes.
1857 * name: 'My Awesome Application',
1858 *
1859 * // Description of the application used for display purposes.
1860 * description: 'media type "application/vnd.micro+json"'
1861 * }
1862 * }
1863 * ```
1864 *
1865 * The return value of the constructor is the instance itself.
1866 *
1867 * @param {Object} [recordTypes]
1868 * @param {Object} [options]
1869 * @return {Fortune}
1870 */
1871Fortune.prototype.constructor = function Fortune (recordTypes, options) {
1872 var self = this
1873 var plainObject = {}
1874 var message = common.message
1875 var adapter, method, stack, flows, type, hooks, i, j
1876
1877 if (recordTypes === void 0) recordTypes = {}
1878 if (options === void 0) options = {}
1879
1880 if (!('adapter' in options)) options.adapter = [ memoryAdapter(Adapter) ]
1881 if (!('settings' in options)) options.settings = {}
1882 if (!('hooks' in options)) options.hooks = {}
1883 if (!('enforceLinks' in options.settings))
1884 options.settings.enforceLinks = true
1885
1886 // Bind middleware methods to instance.
1887 flows = {}
1888 for (method in methods) {
1889 stack = [ middlewares[method], middlewares.include, middlewares.end ]
1890
1891 for (i = 0, j = stack.length; i < j; i++)
1892 stack[i] = bindMiddleware(self, stack[i])
1893
1894 flows[methods[method]] = stack
1895 }
1896
1897 hooks = options.hooks
1898
1899 // Validate hooks.
1900 for (type in hooks) {
1901 if (!recordTypes.hasOwnProperty(type)) throw new Error(
1902 'Attempted to define hook on "' + type + '" type ' +
1903 'which does not exist.')
1904 if (!Array.isArray(hooks[type]))
1905 throw new TypeError('Hook value for "' + type + '" type ' +
1906 'must be an array.')
1907 }
1908
1909 // Validate record types.
1910 for (type in recordTypes) {
1911 if (type in plainObject)
1912 throw new Error('Can not define type name "' + type +
1913 '" which is in Object.prototype.')
1914
1915 validate(recordTypes[type])
1916 if (!hooks.hasOwnProperty(type)) hooks[type] = []
1917 }
1918
1919 /*!
1920 * Adapter singleton that is coupled to the Fortune instance.
1921 *
1922 * @type {Adapter}
1923 */
1924 adapter = new AdapterSingleton({
1925 adapter: options.adapter,
1926 recordTypes: recordTypes,
1927 hooks: hooks,
1928 message: message
1929 })
1930
1931 self.options = options
1932 self.hooks = hooks
1933 self.recordTypes = recordTypes
1934 self.adapter = adapter
1935
1936 // Internal properties.
1937 Object.defineProperties(self, {
1938 // 0 = not started, 1 = started, 2 = done.
1939 connectionStatus: { value: 0, writable: true },
1940
1941 message: { value: message },
1942 flows: { value: flows }
1943 })
1944}
1945
1946
1947/**
1948 * This is the primary method for initiating a request. The options object
1949 * may contain the following keys:
1950 *
1951 * - `method`: The method is a either a function or a constant, which is keyed
1952 * under `Fortune.common.methods` and may be one of `find`, `create`,
1953 * `update`, or `delete`. Default: `find`.
1954 *
1955 * - `type`: Name of a type. **Required**.
1956 *
1957 * - `ids`: An array of IDs. Used for `find` and `delete` methods only. This is
1958 * optional for the `find` method.
1959 *
1960 * - `include`: A 3-dimensional array specifying links to include. The first
1961 * dimension is a list, the second dimension is depth, and the third
1962 * dimension is an optional tuple with field and query options. For example:
1963 * `[['comments'], ['comments', ['author', { ... }]]]`.
1964 *
1965 * - `options`: Exactly the same as the [`find` method](#adapter-find)
1966 * options in the adapter. These options do not apply on methods other than
1967 * `find`, and do not affect the records returned from `include`. Optional.
1968 *
1969 * - `meta`: Meta-information object of the request. Optional.
1970 *
1971 * - `payload`: Payload of the request. **Required** for `create` and `update`
1972 * methods only, and must be an array of objects. The objects must be the
1973 * records to create, or update objects as expected by the Adapter.
1974 *
1975 * - `transaction`: if an existing transaction should be re-used, this may
1976 * optionally be passed in. This must be ended manually.
1977 *
1978 * The response object may contain the following keys:
1979 *
1980 * - `meta`: Meta-info of the response.
1981 *
1982 * - `payload`: An object containing the following keys:
1983 * - `records`: An array of records returned.
1984 * - `count`: Total number of records without options applied (only for
1985 * responses to the `find` method).
1986 * - `include`: An object keyed by type, valued by arrays of included
1987 * records.
1988 *
1989 * The resolved response object should always be an instance of a response
1990 * type.
1991 *
1992 * @param {Object} options
1993 * @return {Promise}
1994 */
1995Fortune.prototype.request = function (options) {
1996 var self = this
1997 var connectionStatus = self.connectionStatus
1998 var Promise = promise.Promise
1999
2000 if (connectionStatus === 0)
2001 return self.connect()
2002 .then(function () { return internalRequest.call(self, options) })
2003
2004 else if (connectionStatus === 1)
2005 return new Promise(function (resolve, reject) {
2006 // Wait for changes to connection status.
2007 self.once(events.failure, function () {
2008 reject(new Error('Connection failed.'))
2009 })
2010 self.once(events.connect, function () {
2011 resolve(internalRequest.call(self, options))
2012 })
2013 })
2014
2015 return internalRequest.call(self, options)
2016}
2017
2018
2019/**
2020 * The `find` method retrieves record by type given IDs, querying options,
2021 * or both. This is a convenience method that wraps around the `request`
2022 * method, see the `request` method for documentation on its arguments.
2023 *
2024 * @param {String} type
2025 * @param {*|*[]} [ids]
2026 * @param {Object} [options]
2027 * @param {Array[]} [include]
2028 * @param {Object} [meta]
2029 * @return {Promise}
2030 */
2031Fortune.prototype.find = function (type, ids, options, include, meta) {
2032 var obj = { method: methods.find, type: type }
2033
2034 if (ids) obj.ids = Array.isArray(ids) ? ids : [ ids ]
2035 if (options) obj.options = options
2036 if (include) obj.include = include
2037 if (meta) obj.meta = meta
2038
2039 return this.request(obj)
2040}
2041
2042
2043/**
2044 * The `create` method creates records by type given records to create. This
2045 * is a convenience method that wraps around the `request` method, see the
2046 * request `method` for documentation on its arguments.
2047 *
2048 * @param {String} type
2049 * @param {Object|Object[]} records
2050 * @param {Array[]} [include]
2051 * @param {Object} [meta]
2052 * @return {Promise}
2053 */
2054Fortune.prototype.create = function (type, records, include, meta) {
2055 var options = { method: methods.create, type: type,
2056 payload: Array.isArray(records) ? records : [ records ] }
2057
2058 if (include) options.include = include
2059 if (meta) options.meta = meta
2060
2061 return this.request(options)
2062}
2063
2064
2065/**
2066 * The `update` method updates records by type given update objects. See the
2067 * [Adapter.update](#adapter-update) method for the format of the update
2068 * objects. This is a convenience method that wraps around the `request`
2069 * method, see the `request` method for documentation on its arguments.
2070 *
2071 * @param {String} type
2072 * @param {Object|Object[]} updates
2073 * @param {Array[]} [include]
2074 * @param {Object} [meta]
2075 * @return {Promise}
2076 */
2077Fortune.prototype.update = function (type, updates, include, meta) {
2078 var options = { method: methods.update, type: type,
2079 payload: Array.isArray(updates) ? updates : [ updates ] }
2080
2081 if (include) options.include = include
2082 if (meta) options.meta = meta
2083
2084 return this.request(options)
2085}
2086
2087
2088/**
2089 * The `delete` method deletes records by type given IDs (optional). This is a
2090 * convenience method that wraps around the `request` method, see the `request`
2091 * method for documentation on its arguments.
2092 *
2093 * @param {String} type
2094 * @param {*|*[]} [ids]
2095 * @param {Array[]} [include]
2096 * @param {Object} [meta]
2097 * @return {Promise}
2098 */
2099Fortune.prototype.delete = function (type, ids, include, meta) {
2100 var options = { method: methods.delete, type: type }
2101
2102 if (ids) options.ids = Array.isArray(ids) ? ids : [ ids ]
2103 if (include) options.include = include
2104 if (meta) options.meta = meta
2105
2106 return this.request(options)
2107}
2108
2109
2110/**
2111 * This method does not need to be called manually, it is automatically called
2112 * upon the first request if it is not connected already. However, it may be
2113 * useful if manually reconnect is needed. The resolved value is the instance
2114 * itself.
2115 *
2116 * @return {Promise}
2117 */
2118Fortune.prototype.connect = function () {
2119 var self = this
2120 var Promise = promise.Promise
2121
2122 if (self.connectionStatus === 1)
2123 return Promise.reject(new Error('Connection is in progress.'))
2124
2125 else if (self.connectionStatus === 2)
2126 return Promise.reject(new Error('Connection is already done.'))
2127
2128 self.connectionStatus = 1
2129
2130 return new Promise(function (resolve, reject) {
2131 Object.defineProperty(self, 'denormalizedFields', {
2132 value: ensureTypes(self.recordTypes),
2133 writable: true,
2134 configurable: true
2135 })
2136
2137 self.adapter.connect().then(function () {
2138 self.connectionStatus = 2
2139 self.emit(events.connect)
2140 return resolve(self)
2141 }, function (error) {
2142 self.connectionStatus = 0
2143 self.emit(events.failure)
2144 return reject(error)
2145 })
2146 })
2147}
2148
2149
2150/**
2151 * Close adapter connection, and reset connection state. The resolved value is
2152 * the instance itself.
2153 *
2154 * @return {Promise}
2155 */
2156Fortune.prototype.disconnect = function () {
2157 var self = this
2158 var Promise = promise.Promise
2159
2160 if (self.connectionStatus !== 2)
2161 return Promise.reject(new Error('Instance has not been connected.'))
2162
2163 self.connectionStatus = 1
2164
2165 return new Promise(function (resolve, reject) {
2166 return self.adapter.disconnect().then(function () {
2167 self.connectionStatus = 0
2168 self.emit(events.disconnect)
2169 return resolve(self)
2170 }, function (error) {
2171 self.connectionStatus = 2
2172 self.emit(events.failure)
2173 return reject(error)
2174 })
2175 })
2176}
2177
2178
2179// Useful for dependency injection. All instances of Fortune have the same
2180// common internal dependencies.
2181Fortune.prototype.common = common
2182
2183
2184// Assign useful static properties to the default export.
2185assign(Fortune, {
2186 Adapter: Adapter,
2187 adapters: {
2188 memory: memoryAdapter(Adapter)
2189 },
2190 errors: common.errors,
2191 message: common.message,
2192 methods: methods,
2193 events: events
2194})
2195
2196
2197// Set the `Promise` property.
2198Object.defineProperty(Fortune, 'Promise', {
2199 enumerable: true,
2200 get: function () {
2201 return promise.Promise
2202 },
2203 set: function (value) {
2204 promise.Promise = value
2205 }
2206})
2207
2208
2209// Internal helper function.
2210function bindMiddleware (scope, method) {
2211 return function (x) {
2212 return method.call(scope, x)
2213 }
2214}
2215
2216
2217module.exports = Fortune
2218
2219},{"./adapter":4,"./adapter/adapters/memory":3,"./adapter/singleton":5,"./common":23,"./common/promise":28,"./record_type/ensure_types":34,"./record_type/validate":35,"./request":42,"event-lite":49}],33:[function(require,module,exports){
2220(function (Buffer){
2221'use strict'
2222
2223var message = require('../common/message')
2224var find = require('../common/array/find')
2225
2226var errors = require('../common/errors')
2227var BadRequestError = errors.BadRequestError
2228
2229var keys = require('../common/keys')
2230var primaryKey = keys.primary
2231var typeKey = keys.type
2232var linkKey = keys.link
2233var isArrayKey = keys.isArray
2234
2235
2236// Check input values.
2237var checkInput = [
2238 [ String, function (value) {
2239 return typeof value === 'string'
2240 } ],
2241 [ Number, function (value) {
2242 return typeof value === 'number'
2243 } ],
2244 [ Boolean, function (value) {
2245 return typeof value === 'boolean'
2246 } ],
2247 [ Date, function (value) {
2248 return value && typeof value.getTime === 'function' &&
2249 !Number.isNaN(value.getTime())
2250 } ],
2251 [ Object, function (value) {
2252 return value !== null && typeof value === 'object'
2253 } ],
2254 [ Buffer, function (value) {
2255 return Buffer.isBuffer(value)
2256 } ]
2257]
2258
2259
2260/**
2261 * Throw errors for mismatched types on a record.
2262 *
2263 * @param {String} type
2264 * @param {Object} record
2265 * @param {Object} fields
2266 * @param {Object} meta
2267 * @return {Object}
2268 */
2269module.exports = function enforce (type, record, fields, meta) {
2270 var i, j, key, value, fieldDefinition, language
2271
2272 if (!meta) meta = {}
2273 language = meta.language
2274
2275 for (key in record) {
2276 fieldDefinition = fields[key]
2277
2278 if (!fieldDefinition) {
2279 if (key !== primaryKey) delete record[key]
2280 continue
2281 }
2282
2283 value = record[key]
2284
2285 if (fieldDefinition[typeKey]) {
2286 if (fieldDefinition[isArrayKey]) {
2287 // If the field is defined as an array but the value is not,
2288 // then throw an error.
2289 if (!Array.isArray(value))
2290 throw new BadRequestError(message('EnforceArrayType', language, {
2291 key: key, type: fieldDefinition[typeKey].name
2292 }))
2293
2294 for (i = 0, j = value.length; i < j; i++)
2295 checkValue(fieldDefinition, key, value[i], meta)
2296 }
2297 else checkValue(fieldDefinition, key, value, meta)
2298
2299 continue
2300 }
2301
2302 if (fieldDefinition[linkKey]) {
2303 if (fieldDefinition[isArrayKey]) {
2304 if (!Array.isArray(value))
2305 throw new BadRequestError(
2306 message('EnforceArray', language, { key: key }))
2307
2308 if (type === fieldDefinition[linkKey] &&
2309 find(value, matchId(record[primaryKey])))
2310 throw new BadRequestError(
2311 message('EnforceSameID', language, { key: key }))
2312
2313 continue
2314 }
2315
2316 if (Array.isArray(value))
2317 throw new BadRequestError(
2318 message('EnforceSingular', language, { key: key }))
2319
2320 if (type === fieldDefinition[linkKey] && record[primaryKey] === value)
2321 throw new BadRequestError(
2322 message('EnforceSameID', language, { key: key }))
2323
2324 continue
2325 }
2326 }
2327
2328 return record
2329}
2330
2331
2332function checkValue (field, key, value, meta) {
2333 var language = meta.language
2334 var check
2335 var type = field[typeKey]
2336
2337 // Skip `null` case.
2338 if (value === null) return
2339
2340 check = find(checkInput, function (pair) {
2341 return pair[0] === type
2342 })
2343 if (check) check = check[1]
2344 else check = type
2345
2346 // Fields may be nullable, but if they're defined, then they must be defined
2347 // properly.
2348 if (!check(value)) throw new BadRequestError(
2349 message(field[isArrayKey] ? 'EnforceValueArray' : 'EnforceValue',
2350 language, { key: key, type: type.displayName || type.name }))
2351}
2352
2353
2354function matchId (a) {
2355 return function (b) {
2356 return a === b
2357 }
2358}
2359
2360}).call(this,require("buffer").Buffer)
2361},{"../common/array/find":8,"../common/errors":20,"../common/keys":24,"../common/message":25,"buffer":47}],34:[function(require,module,exports){
2362'use strict'
2363
2364var keys = require('../common/keys')
2365var linkKey = keys.link
2366var inverseKey = keys.inverse
2367var isArrayKey = keys.isArray
2368var denormalizedInverseKey = keys.denormalizedInverse
2369
2370
2371// Generate denormalized inverse field name.
2372var denormalizedPrefix = '__'
2373var denormalizedDelimiter = '_'
2374var denormalizedPostfix = '_inverse'
2375
2376
2377/**
2378 * Analyze the `types` object to see if `link` and `inverse` values are
2379 * valid. Also assign denormalized inverse fields.
2380 *
2381 * @param {Object} types
2382 * @return {Object}
2383 */
2384module.exports = function ensureTypes (types) {
2385 var denormalizedFields = {}
2386 var type, field, definition, linkedFields,
2387 denormalizedField, denormalizedDefinition
2388
2389 for (type in types)
2390 for (field in types[type]) {
2391 definition = types[type][field]
2392
2393 if (!(linkKey in definition)) continue
2394
2395 if (!types.hasOwnProperty(definition[linkKey]))
2396 throw new Error('The value for "' + linkKey + '" on "' + field +
2397 '" in type "' + type +
2398 '" is invalid, the record type does not exist.')
2399
2400 linkedFields = types[definition[linkKey]]
2401
2402 if (inverseKey in definition) {
2403 if (!linkedFields.hasOwnProperty(definition[inverseKey]))
2404 throw new Error('The value for "' + inverseKey + '" on "' + field +
2405 '" in type "' + type + '" is invalid, the field does not exist.')
2406
2407 if (linkedFields[definition[inverseKey]][inverseKey] !== field)
2408 throw new Error('The value for "' + inverseKey + '" on "' + field +
2409 '" in type "' + type +
2410 '" is invalid, the inversely related field must define its ' +
2411 'inverse as "' + field + '".')
2412
2413 if (linkedFields[definition[inverseKey]][linkKey] !== type)
2414 throw new Error('The value for "' + linkKey + '" on "' + field +
2415 '" in type "' + type +
2416 '" is invalid, the inversely related field must define its link ' +
2417 'as "' + type + '".')
2418
2419 continue
2420 }
2421
2422 // Need to assign denormalized inverse. The denormalized inverse field
2423 // is basically an automatically assigned inverse field that should
2424 // not be visible to the client, but exists in the data store.
2425 denormalizedField = denormalizedPrefix + type +
2426 denormalizedDelimiter + field + denormalizedPostfix
2427
2428 denormalizedFields[denormalizedField] = true
2429
2430 Object.defineProperty(definition, inverseKey, {
2431 value: denormalizedField
2432 })
2433
2434 denormalizedDefinition = {}
2435 denormalizedDefinition[linkKey] = type
2436 denormalizedDefinition[inverseKey] = field
2437 denormalizedDefinition[isArrayKey] = true
2438 denormalizedDefinition[denormalizedInverseKey] = true
2439
2440 Object.defineProperty(linkedFields, denormalizedField, {
2441 value: denormalizedDefinition
2442 })
2443 }
2444
2445 return denormalizedFields
2446}
2447
2448},{"../common/keys":24}],35:[function(require,module,exports){
2449(function (Buffer){
2450'use strict'
2451
2452var find = require('../common/array/find')
2453var map = require('../common/array/map')
2454
2455var keys = require('../common/keys')
2456var primaryKey = keys.primary
2457var typeKey = keys.type
2458var linkKey = keys.link
2459var inverseKey = keys.inverse
2460var isArrayKey = keys.isArray
2461
2462var plainObject = {}
2463var nativeTypes = [ String, Number, Boolean, Date, Object, Buffer ]
2464var stringifiedTypes = map(nativeTypes, function (nativeType) {
2465 return nativeType.name.toLowerCase()
2466})
2467
2468
2469/**
2470 * Given a hash of field definitions, validate that the definitions are in the
2471 * correct format.
2472 *
2473 * @param {Object} fields
2474 * @return {Object}
2475 */
2476module.exports = function validate (fields) {
2477 var key
2478
2479 if (typeof fields !== 'object')
2480 throw new TypeError('Type definition must be an object.')
2481
2482 for (key in fields) validateField(fields, key)
2483
2484 return fields
2485}
2486
2487
2488/**
2489 * Parse a field definition.
2490 *
2491 * @param {Object} fields
2492 * @param {String} key
2493 */
2494function validateField (fields, key) {
2495 var value = fields[key] = castShorthand(fields[key])
2496
2497 if (typeof value !== 'object')
2498 throw new TypeError('The definition of "' + key + '" must be an object.')
2499
2500 if (key === primaryKey)
2501 throw new Error('Can not define primary key "' + primaryKey + '".')
2502
2503 if (key in plainObject)
2504 throw new Error('Can not define field name "' + key +
2505 '" which is in Object.prototype.')
2506
2507 if (!value[typeKey] && !value[linkKey])
2508 throw new Error('The definition of "' + key + '" must contain either ' +
2509 'the "' + typeKey + '" or "' + linkKey + '" property.')
2510
2511 if (value[typeKey] && value[linkKey])
2512 throw new Error('Can not define both "' + typeKey + '" and "' + linkKey +
2513 '" on "' + key + '".')
2514
2515 if (value[typeKey]) {
2516 if (typeof value[typeKey] === 'string')
2517 value[typeKey] = nativeTypes[
2518 stringifiedTypes.indexOf(value[typeKey].toLowerCase())]
2519
2520 if (typeof value[typeKey] !== 'function')
2521 throw new Error('The "' + typeKey + '" on "' + key +
2522 '" must be a function.')
2523
2524 if (!find(nativeTypes, function (type) {
2525 var hasMatch = type === value[typeKey] ||
2526 type.name === value[typeKey].name
2527
2528 // In case this errors due to security sandboxing, just skip this check.
2529 if (!hasMatch)
2530 try {
2531 hasMatch = Object.create(value[typeKey]) instanceof type
2532 }
2533 catch (e) {
2534 hasMatch = true
2535 }
2536
2537 return hasMatch
2538 }))
2539 throw new Error('The "' + typeKey + '" on "' + key + '" must be or ' +
2540 'inherit from a valid native type.')
2541
2542 if (value[inverseKey])
2543 throw new Error('The field "' + inverseKey + '" may not be defined ' +
2544 'on "' + key + '".')
2545 }
2546
2547 if (value[linkKey]) {
2548 if (typeof value[linkKey] !== 'string')
2549 throw new TypeError('The "' + linkKey + '" on "' + key +
2550 '" must be a string.')
2551
2552 if (value[inverseKey] && typeof value[inverseKey] !== 'string')
2553 throw new TypeError('The "' + inverseKey + '" on "' + key + '" ' +
2554 'must be a string.')
2555 }
2556
2557 if (value[isArrayKey] && typeof value[isArrayKey] !== 'boolean')
2558 throw new TypeError('The key "' + isArrayKey + '" on "' + key + '" ' +
2559 'must be a boolean.')
2560}
2561
2562
2563/**
2564 * Cast shorthand definition to standard definition.
2565 *
2566 * @param {*} value
2567 * @return {Object}
2568 */
2569function castShorthand (value) {
2570 var obj
2571
2572 if (typeof value === 'string') obj = { link: value }
2573 else if (typeof value === 'function') obj = { type: value }
2574 else if (Array.isArray(value)) {
2575 obj = {}
2576
2577 if (value[1]) obj.inverse = value[1]
2578 else obj.isArray = true
2579
2580 // Extract type or link.
2581 if (Array.isArray(value[0])) {
2582 obj.isArray = true
2583 value = value[0][0]
2584 }
2585 else value = value[0]
2586
2587 if (typeof value === 'string') obj.link = value
2588 else if (typeof value === 'function') obj.type = value
2589 }
2590 else return value
2591
2592 return obj
2593}
2594
2595}).call(this,require("buffer").Buffer)
2596},{"../common/array/find":8,"../common/array/map":10,"../common/keys":24,"buffer":47}],36:[function(require,module,exports){
2597'use strict'
2598
2599var message = require('../common/message')
2600var promise = require('../common/promise')
2601var unique = require('../common/array/unique')
2602var map = require('../common/array/map')
2603var includes = require('../common/array/includes')
2604
2605var errors = require('../common/errors')
2606var BadRequestError = errors.BadRequestError
2607
2608var keys = require('../common/keys')
2609var primaryKey = keys.primary
2610var linkKey = keys.link
2611var isArrayKey = keys.isArray
2612var inverseKey = keys.inverse
2613
2614module.exports = checkLinks
2615
2616
2617/**
2618 * Ensure referential integrity by checking if related records exist.
2619 *
2620 * @param {Object} transaction
2621 * @param {Object} record
2622 * @param {Object} fields
2623 * @param {String[]} links - An array of strings indicating which fields are
2624 * links. Need to pass this so that it doesn't get computed each time.
2625 * @param {Object} [meta]
2626 * @return {Promise}
2627 */
2628function checkLinks (transaction, record, fields, links, meta) {
2629 var Promise = promise.Promise
2630 var enforceLinks = this.options.settings.enforceLinks
2631
2632 return Promise.all(map(links, function (field) {
2633 var ids = Array.isArray(record[field]) ? record[field] :
2634 !record.hasOwnProperty(field) || record[field] === null ?
2635 [] : [ record[field] ]
2636 var fieldLink = fields[field][linkKey]
2637 var fieldInverse = fields[field][inverseKey]
2638 var findOptions = { fields: {} }
2639
2640 // Don't need the entire records.
2641 findOptions.fields[fieldInverse] = true
2642
2643 return new Promise(function (resolve, reject) {
2644 if (!ids.length) return resolve()
2645
2646 return transaction.find(fieldLink, ids, findOptions, meta)
2647
2648 .then(function (records) {
2649 var recordIds, i, j
2650
2651 if (enforceLinks) {
2652 recordIds = unique(map(records, function (record) {
2653 return record[primaryKey]
2654 }))
2655
2656 for (i = 0, j = ids.length; i < j; i++)
2657 if (!includes(recordIds, ids[i]))
2658 return reject(new BadRequestError(
2659 message('RelatedRecordNotFound', meta.language,
2660 { field: field })
2661 ))
2662 }
2663
2664 return resolve(records)
2665 })
2666 })
2667 }))
2668
2669 .then(function (partialRecords) {
2670 var object = {}, records, i, j
2671
2672 for (i = 0, j = partialRecords.length; i < j; i++) {
2673 records = partialRecords[i]
2674
2675 if (records) object[links[i]] =
2676 fields[links[i]][isArrayKey] ? records : records[0]
2677 }
2678
2679 return object
2680 })
2681}
2682
2683},{"../common/array/includes":9,"../common/array/map":10,"../common/array/unique":13,"../common/errors":20,"../common/keys":24,"../common/message":25,"../common/promise":28}],37:[function(require,module,exports){
2684'use strict'
2685
2686var validateRecords = require('./validate_records')
2687var checkLinks = require('./check_links')
2688var enforce = require('../record_type/enforce')
2689var message = require('../common/message')
2690var promise = require('../common/promise')
2691var map = require('../common/array/map')
2692
2693var errors = require('../common/errors')
2694var BadRequestError = errors.BadRequestError
2695
2696var updateHelpers = require('./update_helpers')
2697var scrubDenormalizedUpdates = updateHelpers.scrubDenormalizedUpdates
2698var getUpdate = updateHelpers.getUpdate
2699var addId = updateHelpers.addId
2700var removeId = updateHelpers.removeId
2701
2702var constants = require('../common/constants')
2703var changeEvent = constants.change
2704var createMethod = constants.create
2705var updateMethod = constants.update
2706var primaryKey = constants.primary
2707var linkKey = constants.link
2708var inverseKey = constants.inverse
2709var isArrayKey = constants.isArray
2710var denormalizedInverseKey = constants.denormalizedInverse
2711
2712
2713/**
2714 * Extend context so that it includes the parsed records and create them.
2715 * This mutates the response object.
2716 *
2717 * @return {Promise}
2718 */
2719module.exports = function (context) {
2720 var Promise = promise.Promise
2721 var self = this
2722 var denormalizedFields = self.denormalizedFields
2723 var recordTypes = self.recordTypes
2724 var hooks = self.hooks
2725 var updates = {}
2726 var links = []
2727 var recordsLinked = []
2728 var transaction, records, type, meta, hook, fields, language
2729
2730 // Start a promise chain.
2731 return Promise.resolve(context.request.payload)
2732
2733 .then(function (payload) {
2734 var i, j, field
2735
2736 records = payload
2737
2738 if (!records || !records.length)
2739 throw new BadRequestError(
2740 message('CreateRecordsInvalid', language))
2741
2742 type = context.request.type
2743 meta = context.request.meta
2744 transaction = context.transaction
2745 language = meta.language
2746
2747 hook = hooks[type]
2748 fields = recordTypes[type]
2749
2750 for (field in fields) {
2751 if (linkKey in fields[field])
2752 links.push(field)
2753
2754 // Delete denormalized inverse fields.
2755 if (denormalizedInverseKey in fields[field])
2756 for (i = 0, j = records.length; i < j; i++)
2757 delete records[i][field]
2758 }
2759
2760 return typeof hook[0] === 'function' ?
2761 Promise.all(map(records, function (record) {
2762 return hook[0](context, record)
2763 })) : records
2764 })
2765
2766 .then(function (results) {
2767 return Promise.all(map(results, function (record, i) {
2768 if (record && typeof record === 'object') records[i] = record
2769 else record = records[i]
2770
2771 // Enforce the fields.
2772 enforce(type, record, fields, meta)
2773
2774 // Ensure referential integrity.
2775 return checkLinks.call(self, transaction, record, fields, links, meta)
2776 .then(function (linked) {
2777 // The created records should come back in the same order.
2778 recordsLinked.push(linked)
2779 return record
2780 })
2781 }))
2782 })
2783
2784 .then(function () {
2785 validateRecords.call(self, records, fields, links, meta)
2786 return transaction.create(type, records, meta)
2787 })
2788
2789 .then(function (createdRecords) {
2790 var record, field, inverseField, fieldIsArray,
2791 linked, linkedType, linkedIsArray, linkedIds, id,
2792 partialRecord, partialRecords
2793 var i, j, k, l, m, n, o, p
2794
2795 // Update inversely linked records on created records.
2796 // Trying to batch updates to be as few as possible.
2797 var idCache = {}
2798
2799 // Adapter must return something.
2800 if (!createdRecords.length)
2801 throw new BadRequestError(
2802 message('CreateRecordsFail', language))
2803
2804 records = createdRecords
2805
2806 Object.defineProperty(context.response, 'records', {
2807 configurable: true,
2808 value: records
2809 })
2810
2811 // Iterate over each record to generate updates object.
2812 for (i = 0, j = records.length; i < j; i++) {
2813 record = records[i]
2814 linked = recordsLinked[i]
2815
2816 // Each created record must have an ID.
2817 if (!(primaryKey in record))
2818 throw new Error(
2819 message('CreateRecordMissingID', language))
2820
2821 for (k = 0, l = links.length; k < l; k++) {
2822 field = links[k]
2823 inverseField = fields[field][inverseKey]
2824
2825 if (!record.hasOwnProperty(field) || !inverseField) continue
2826
2827 linkedType = fields[field][linkKey]
2828 linkedIsArray =
2829 recordTypes[linkedType][inverseField][isArrayKey]
2830 fieldIsArray = fields[field][isArrayKey]
2831 linkedIds = fieldIsArray ?
2832 record[field] : [ record[field] ]
2833
2834 // Do some initialization.
2835 if (!updates[linkedType]) updates[linkedType] = []
2836 if (!idCache[linkedType]) idCache[linkedType] = {}
2837
2838 for (m = 0, n = linkedIds.length; m < n; m++) {
2839 id = linkedIds[m]
2840
2841 // Set related field.
2842 if (id !== null)
2843 addId(record[primaryKey],
2844 getUpdate(linkedType, id, updates, idCache),
2845 inverseField, linkedIsArray)
2846
2847 // Unset 2nd degree related record for one-to-one case.
2848 if (!fieldIsArray &&
2849 linked[field] &&
2850 linked[field][inverseField] !== null &&
2851 !linkedIsArray &&
2852 linked[field][inverseField] !== record[primaryKey])
2853 removeId(id,
2854 getUpdate(
2855 type, linked[field][inverseField], updates, idCache),
2856 field, linkedIsArray)
2857 }
2858
2859 // Unset from 2nd degree related records for many-to-one case.
2860 if (fieldIsArray &&
2861 linked[field] && !linkedIsArray) {
2862 partialRecords = Array.isArray(linked[field]) ?
2863 linked[field] : [ linked[field] ]
2864
2865 for (o = 0, p = partialRecords.length; o < p; o++) {
2866 partialRecord = partialRecords[o]
2867
2868 if (partialRecord[inverseField] === record[primaryKey])
2869 continue
2870
2871 removeId(partialRecord[primaryKey],
2872 getUpdate(
2873 type, partialRecord[inverseField],
2874 updates, idCache),
2875 field, fieldIsArray)
2876 }
2877 }
2878 }
2879 }
2880
2881 return Promise.all(map(Object.keys(updates), function (type) {
2882 return updates[type].length ?
2883 transaction.update(type, updates[type], meta) :
2884 null
2885 }))
2886 })
2887
2888 .then(function () {
2889 var eventData = {}, currentType
2890
2891 eventData[createMethod] = {}
2892 eventData[createMethod][type] = records
2893
2894 for (currentType in updates) {
2895 scrubDenormalizedUpdates(updates[currentType], denormalizedFields)
2896
2897 if (!updates[currentType].length) continue
2898
2899 if (!(updateMethod in eventData)) eventData[updateMethod] = {}
2900 eventData[updateMethod][currentType] = updates[currentType]
2901 }
2902
2903 // Summarize changes during the lifecycle of the request.
2904 self.emit(changeEvent, eventData)
2905
2906 return context
2907 })
2908}
2909
2910},{"../common/array/map":10,"../common/constants":18,"../common/errors":20,"../common/message":25,"../common/promise":28,"../record_type/enforce":33,"./check_links":36,"./update_helpers":44,"./validate_records":45}],38:[function(require,module,exports){
2911'use strict'
2912
2913var message = require('../common/message')
2914var promise = require('../common/promise')
2915var map = require('../common/array/map')
2916
2917var errors = require('../common/errors')
2918var NotFoundError = errors.NotFoundError
2919
2920var updateHelpers = require('./update_helpers')
2921var scrubDenormalizedUpdates = updateHelpers.scrubDenormalizedUpdates
2922var getUpdate = updateHelpers.getUpdate
2923var removeId = updateHelpers.removeId
2924
2925var constants = require('../common/constants')
2926var changeEvent = constants.change
2927var deleteMethod = constants.delete
2928var updateMethod = constants.update
2929var primaryKey = constants.primary
2930var linkKey = constants.link
2931var inverseKey = constants.inverse
2932var isArrayKey = constants.isArray
2933
2934
2935/**
2936 * Delete records. This does not mutate context.
2937 *
2938 * @return {Promise}
2939 */
2940module.exports = function (context) {
2941 var Promise = promise.Promise
2942 var self = this
2943 var denormalizedFields = self.denormalizedFields
2944 var request = context.request
2945 var type = request.type
2946 var ids = request.ids
2947 var meta = request.meta
2948 var language = meta.language
2949 var recordTypes = self.recordTypes
2950 var hooks = self.hooks
2951 var updates = {}
2952 var fields = recordTypes[type]
2953 var hook = hooks[type]
2954 var links = []
2955 var transaction, field, records
2956
2957 transaction = context.transaction
2958
2959 for (field in fields)
2960 if (linkKey in fields[field]) links.push(field)
2961
2962 if (!ids || !ids.length)
2963 throw new NotFoundError(message('DeleteRecordsMissingID', language))
2964
2965 return transaction.find(type, ids, null, meta)
2966
2967 .then(function (foundRecords) {
2968 records = foundRecords
2969
2970 if (records.length < ids.length)
2971 throw new NotFoundError(message('DeleteRecordsInvalid', language))
2972
2973 Object.defineProperty(context.response, 'records', {
2974 configurable: true,
2975 value: records
2976 })
2977
2978 return typeof hook[0] === 'function' ?
2979 Promise.all(map(records, function (record) {
2980 return hook[0](context, record)
2981 })) : records
2982 })
2983
2984 .then(function () {
2985 return transaction.delete(type, ids, meta)
2986 })
2987
2988 .then(function (count) {
2989 var i, j, k, l, m, n, record, field, id, inverseField,
2990 linkedType, linkedIsArray, linkedIds
2991
2992 // Remove all instances of the deleted IDs in all records.
2993 var idCache = {}
2994
2995 // Sanity check.
2996 if (count < ids.length)
2997 throw new Error(message('DeleteRecordsFail', language))
2998
2999 // Loop over each record to generate updates object.
3000 for (i = 0, j = records.length; i < j; i++) {
3001 record = records[i]
3002 for (k = 0, l = links.length; k < l; k++) {
3003 field = links[k]
3004 inverseField = fields[field][inverseKey]
3005
3006 if (!record.hasOwnProperty(field) || !inverseField) continue
3007
3008 linkedType = fields[field][linkKey]
3009 linkedIsArray = recordTypes[linkedType][inverseField][isArrayKey]
3010 linkedIds = Array.isArray(record[field]) ?
3011 record[field] : [ record[field] ]
3012
3013 // Do some initialization.
3014 if (!updates[linkedType]) updates[linkedType] = []
3015 if (!idCache[linkedType]) idCache[linkedType] = {}
3016
3017 for (m = 0, n = linkedIds.length; m < n; m++) {
3018 id = linkedIds[m]
3019 if (id !== null)
3020 removeId(record[primaryKey],
3021 getUpdate(linkedType, id, updates, idCache),
3022 inverseField, linkedIsArray)
3023 }
3024 }
3025 }
3026
3027 return Promise.all(map(Object.keys(updates), function (type) {
3028 return updates[type].length ?
3029 transaction.update(type, updates[type], meta) :
3030 null
3031 }))
3032 })
3033
3034 .then(function () {
3035 var eventData = {}, currentType
3036
3037 eventData[deleteMethod] = {}
3038 eventData[deleteMethod][type] = ids
3039
3040 for (currentType in updates) {
3041 scrubDenormalizedUpdates(updates[currentType], denormalizedFields)
3042
3043 if (!updates[currentType].length) continue
3044
3045 if (!(updateMethod in eventData)) eventData[updateMethod] = {}
3046 eventData[updateMethod][currentType] = updates[currentType]
3047 }
3048
3049 // Summarize changes during the lifecycle of the request.
3050 self.emit(changeEvent, eventData)
3051
3052 return context
3053 })
3054}
3055
3056},{"../common/array/map":10,"../common/constants":18,"../common/errors":20,"../common/message":25,"../common/promise":28,"./update_helpers":44}],39:[function(require,module,exports){
3057'use strict'
3058
3059var map = require('../common/array/map')
3060var promise = require('../common/promise')
3061
3062
3063/**
3064 * Apply `output` hook per record, this mutates `context.response`.
3065 *
3066 * @return {Promise}
3067 */
3068module.exports = function (context) {
3069 var Promise = promise.Promise
3070 var hooks = this.hooks
3071 var request = context.request
3072 var response = context.response
3073 var type = request.type
3074 var hook = hooks[type]
3075 var records = response.records
3076 var include = response.include
3077
3078 // Run hooks on primary type.
3079 return (records ? Promise.all(map(records, function (record) {
3080 return Promise.resolve(typeof hook[1] === 'function' ?
3081 hook[1](context, record) : record)
3082 }))
3083
3084 .then(function (updatedRecords) {
3085 var includeTypes
3086 var i, j
3087
3088 for (i = 0, j = updatedRecords.length; i < j; i++)
3089 if (updatedRecords[i]) records[i] = updatedRecords[i]
3090
3091 if (!include) return void 0
3092
3093 // The order of the keys and their corresponding indices matter.
3094 includeTypes = Object.keys(include)
3095
3096 // Run output hooks per include type.
3097 return Promise.all(map(includeTypes, function (includeType) {
3098 // This is useful for output hooks to know which type that the current
3099 // record belongs to. It is temporary and gets deleted later.
3100 request.includeType = includeType
3101
3102 return Promise.all(map(include[includeType], function (record) {
3103 return Promise.resolve(
3104 typeof hooks[includeType][1] === 'function' ?
3105 hooks[includeType][1](context, record) : record)
3106 }))
3107 }))
3108
3109 .then(function (types) {
3110 var i, j, k, l
3111
3112 // Don't need this anymore.
3113 delete request.includeType
3114
3115 // Assign results of output hooks on includes.
3116 for (i = 0, j = types.length; i < j; i++)
3117 for (k = 0, l = types[i].length; k < l; k++)
3118 if (types[i][k]) include[includeTypes[i]][k] = types[i][k]
3119 })
3120 }) : Promise.resolve())
3121
3122 .then(function () {
3123 // Delete temporary keys, these should not be serialized.
3124 delete response.records
3125 delete response.include
3126
3127 context.response.payload = {
3128 records: records
3129 }
3130
3131 if (include) context.response.payload.include = include
3132
3133 // Expose the "count" property so that it is serializable.
3134 if (records && 'count' in records)
3135 context.response.payload.count = records.count
3136
3137 return context
3138 })
3139}
3140
3141},{"../common/array/map":10,"../common/promise":28}],40:[function(require,module,exports){
3142'use strict'
3143
3144/**
3145 * Fetch the primary records. This mutates `context.response`
3146 * for the next method.
3147 *
3148 * @return {Promise}
3149 */
3150module.exports = function (context) {
3151 var transaction = context.transaction
3152 var request = context.request
3153 var type = request.type
3154 var ids = request.ids
3155 var options = request.options
3156 var meta = request.meta
3157
3158 if (!type) return context
3159
3160 return transaction.find(type, ids, options, meta)
3161 .then(function (records) {
3162 Object.defineProperty(context.response, 'records', {
3163 configurable: true,
3164 value: records
3165 })
3166
3167 return context
3168 })
3169}
3170
3171},{}],41:[function(require,module,exports){
3172'use strict'
3173
3174var promise = require('../common/promise')
3175var map = require('../common/array/map')
3176var find = require('../common/array/find')
3177var reduce = require('../common/array/reduce')
3178var message = require('../common/message')
3179
3180var errors = require('../common/errors')
3181var BadRequestError = errors.BadRequestError
3182
3183var keys = require('../common/keys')
3184var primaryKey = keys.primary
3185var linkKey = keys.link
3186
3187
3188/**
3189 * Fetch included records. This mutates `context.response`
3190 * for the next method.
3191 *
3192 * @return {Promise}
3193 */
3194module.exports = function include (context) {
3195 var Promise = promise.Promise
3196 var request = context.request
3197 var type = request.type
3198 var ids = request.ids || []
3199 var include = request.include
3200 var meta = request.meta
3201 var language = meta.language
3202 var response = context.response
3203 var transaction = context.transaction
3204 var records = response.records
3205 var recordTypes = this.recordTypes
3206 var hasField = true
3207 var idCache = {}
3208 var i, j, record, id
3209
3210 // Skip if there's nothing to be done.
3211 if (!type || !include || !records) return context
3212
3213 // This cache is used to keep unique IDs per type.
3214 idCache[type] = {}
3215 for (i = 0, j = ids.length; i < j; i++)
3216 idCache[type][ids[i]] = true
3217
3218 // It's necessary to iterate over primary records if no IDs were
3219 // provided initially.
3220 if (!ids.length)
3221 for (i = 0, j = records.length; i < j; i++) {
3222 record = records[i]
3223 id = record[primaryKey]
3224 if (!idCache[type][id]) idCache[type][id] = true
3225 }
3226
3227 // Cast `include` into an array if it's using shorthand.
3228 if (include.length && !Array.isArray(include[0]))
3229 include = [ include ]
3230
3231 return Promise.all(map(include, function (fields) {
3232 return new Promise(function (resolve, reject) {
3233 var currentType = type
3234 var includeOptions = []
3235 var currentCache, currentIds, currentOptions, currentField
3236 var i, j, ensureFields
3237
3238 // Cast `fields` into an array if it's using shorthand.
3239 if (!Array.isArray(fields) ||
3240 (!Array.isArray(fields[1]) && typeof fields[1] === 'object'))
3241 fields = [ fields ]
3242
3243 for (i = 0, j = fields.length; i < j; i++)
3244 if (Array.isArray(fields[i])) {
3245 includeOptions[i] = fields[i][1]
3246 fields[i] = fields[i][0]
3247 }
3248
3249 // Check if first level field in in each record.
3250 for (i = 0, j = records.length; i < j; i++)
3251 if (!(fields[0] in records[i])) {
3252 hasField = false
3253 break
3254 }
3255
3256 // Ensure that the first level field is in each record.
3257 if (hasField)
3258 ensureFields = Promise.resolve(records)
3259 else {
3260 currentOptions = { fields: {} }
3261 currentOptions.fields[fields[0]] = true
3262 currentIds = []
3263 for (i = 0, j = records.length; i < j; i++)
3264 currentIds.push(records[i][primaryKey])
3265 ensureFields = transaction.find(
3266 type, currentIds, currentOptions, meta)
3267 }
3268
3269 return ensureFields
3270 .then(function (records) {
3271 return reduce(fields, function (records, field, index) {
3272 // `cursor` refers to the current collection of records.
3273 return records.then(function (cursor) {
3274 currentField = recordTypes[currentType][field]
3275
3276 if (!currentType || !currentField) return []
3277 if (!(linkKey in currentField))
3278 throw new BadRequestError(
3279 message('InvalidLink', language, { field: field }))
3280
3281 currentCache = {}
3282 currentType = currentField[linkKey]
3283 currentIds = reduce(cursor, function (ids, record) {
3284 var linkedIds = Array.isArray(record[field]) ?
3285 record[field] : [ record[field] ]
3286 var i, j, id
3287
3288 for (i = 0, j = linkedIds.length; i < j; i++) {
3289 id = linkedIds[i]
3290 if (id && !currentCache[id]) {
3291 currentCache[id] = true
3292 ids.push(id)
3293 }
3294 }
3295
3296 return ids
3297 }, [])
3298
3299 if (index in includeOptions)
3300 currentOptions = includeOptions[index]
3301 else if (index < fields.length - 1) {
3302 currentOptions = { fields: {} }
3303 currentOptions.fields[fields[index + 1]] = true
3304 }
3305 else currentOptions = null
3306
3307 return currentIds.length ?
3308 transaction.find(
3309 currentType, currentIds, currentOptions, meta) :
3310 []
3311 })
3312 }, Promise.resolve(records))
3313 })
3314
3315 .then(function (records) {
3316 return resolve({
3317 type: currentType,
3318 ids: currentIds,
3319 records: records
3320 })
3321 }, function (error) {
3322 return reject(error)
3323 })
3324 })
3325 }))
3326
3327 .then(function (containers) {
3328 var include = reduce(containers, function (include, container) {
3329 var i, j, id, record
3330
3331 if (!container.ids.length) return include
3332
3333 if (!include[container.type])
3334 include[container.type] = []
3335
3336 // Only include unique IDs per type.
3337 if (!idCache[container.type])
3338 idCache[container.type] = {}
3339
3340 for (i = 0, j = container.ids.length; i < j; i++) {
3341 id = container.ids[i]
3342
3343 if (idCache[container.type][id]) continue
3344
3345 record = find(container.records, matchId(id))
3346
3347 if (record) {
3348 idCache[container.type][id] = true
3349 include[container.type].push(record)
3350 }
3351 }
3352
3353 // If nothing so far, delete the type from include.
3354 if (!include[container.type].length)
3355 delete include[container.type]
3356
3357 return include
3358 }, {})
3359
3360 if (Object.keys(include).length)
3361 Object.defineProperty(context.response, 'include', {
3362 configurable: true,
3363 value: include
3364 })
3365
3366 return context
3367 })
3368}
3369
3370
3371function matchId (id) {
3372 return function (record) {
3373 return record[primaryKey] === id
3374 }
3375}
3376
3377},{"../common/array/find":8,"../common/array/map":10,"../common/array/reduce":12,"../common/errors":20,"../common/keys":24,"../common/message":25,"../common/promise":28}],42:[function(require,module,exports){
3378'use strict'
3379
3380var promise = require('../common/promise')
3381var assign = require('../common/assign')
3382var unique = require('../common/array/unique')
3383var message = require('../common/message')
3384
3385var responseClass = require('../common/response_classes')
3386var BadRequestError = responseClass.BadRequestError
3387var NotFoundError = responseClass.NotFoundError
3388var MethodError = responseClass.MethodError
3389var OK = responseClass.OK
3390var Empty = responseClass.Empty
3391var Created = responseClass.Created
3392
3393var methods = require('../common/methods')
3394var findMethod = methods.find
3395var createMethod = methods.create
3396
3397
3398/*!
3399 * Internal function to send a request. Must be called in the context of
3400 * the Fortune instance.
3401 *
3402 * @param {Object} options
3403 * @return {Promise}
3404 */
3405function internalRequest (options) {
3406 var Promise = promise.Promise
3407 var flows = this.flows
3408 var recordTypes = this.recordTypes
3409 var adapter = this.adapter
3410
3411 var context = setDefaults(options)
3412 var method = context.request.method
3413 var hasTransaction = 'transaction' in options
3414
3415 // Start a promise chain.
3416 return Promise.resolve(context)
3417
3418 .then(function (context) {
3419 var type = context.request.type
3420 var ids = context.request.ids
3421 var language = context.request.meta.language
3422 var error
3423
3424 // Make sure that IDs are an array of unique values.
3425 if (ids) context.request.ids = unique(ids)
3426
3427 // If a type is unspecified, block the request.
3428 if (type === null) {
3429 error = new BadRequestError(message('UnspecifiedType', language))
3430 error.isTypeUnspecified = true
3431 throw error
3432 }
3433
3434 // If a type is specified and it doesn't exist, block the request.
3435 if (!recordTypes.hasOwnProperty(type))
3436 throw new NotFoundError(
3437 message('InvalidType', language, { type: type }))
3438
3439 // Block invalid method.
3440 if (!(method in flows))
3441 throw new MethodError(
3442 message('InvalidMethod', language, { method: method }))
3443
3444 return hasTransaction ?
3445 Promise.resolve(options.transaction) :
3446 adapter.beginTransaction()
3447 })
3448
3449 .then(function (transaction) {
3450 var chain, flow, i, j
3451
3452 context.transaction = transaction
3453 chain = Promise.resolve(context)
3454 flow = flows[method]
3455
3456 for (i = 0, j = flow.length; i < j; i++)
3457 chain = chain.then(flow[i])
3458
3459 return chain
3460 })
3461
3462 .then(function (context) {
3463 return hasTransaction ?
3464 Promise.resolve() : context.transaction.endTransaction()
3465 .then(function () {
3466 var method = context.request.method
3467 var response = context.response
3468 var payload = response.payload
3469
3470 if (!payload) return new Empty(response)
3471 if (method === createMethod) return new Created(response)
3472
3473 return new OK(response)
3474 })
3475 })
3476
3477 // This makes sure to call `endTransaction` before re-throwing the error.
3478 .catch(function (error) {
3479 return 'transaction' in context && !hasTransaction ?
3480 context.transaction.endTransaction(error)
3481 .then(throwError, throwError) :
3482 throwError()
3483
3484 function throwError () {
3485 throw assign(error, context.response)
3486 }
3487 })
3488}
3489
3490
3491// Re-exporting internal middlewares.
3492internalRequest.middlewares = {
3493 create: require('./create'),
3494 'delete': require('./delete'),
3495 update: require('./update'),
3496 find: require('./find'),
3497 include: require('./include'),
3498 end: require('./end')
3499}
3500
3501
3502/*!
3503 * Set default options on a context's request. For internal use.
3504 *
3505 * @param {Object} [options]
3506 * @return {Object}
3507 */
3508function setDefaults (options) {
3509 var context = {
3510 request: {
3511 method: findMethod,
3512 type: null,
3513 ids: null,
3514 options: {},
3515 include: [],
3516 meta: {},
3517 payload: null
3518 },
3519 response: {
3520 meta: {},
3521 payload: null
3522 }
3523 }
3524
3525 assign(context.request, options)
3526
3527 return context
3528}
3529
3530
3531module.exports = internalRequest
3532
3533},{"../common/array/unique":13,"../common/assign":14,"../common/message":25,"../common/methods":27,"../common/promise":28,"../common/response_classes":29,"./create":37,"./delete":38,"./end":39,"./find":40,"./include":41,"./update":43}],43:[function(require,module,exports){
3534'use strict'
3535
3536var deepEqual = require('../common/deep_equal')
3537var promise = require('../common/promise')
3538var assign = require('../common/assign')
3539var clone = require('../common/clone')
3540var validateRecords = require('./validate_records')
3541var checkLinks = require('./check_links')
3542var enforce = require('../record_type/enforce')
3543var message = require('../common/message')
3544var applyUpdate = require('../common/apply_update')
3545
3546var updateHelpers = require('./update_helpers')
3547var scrubDenormalizedUpdates = updateHelpers.scrubDenormalizedUpdates
3548var getUpdate = updateHelpers.getUpdate
3549var addId = updateHelpers.addId
3550var removeId = updateHelpers.removeId
3551
3552var errors = require('../common/errors')
3553var NotFoundError = errors.NotFoundError
3554var BadRequestError = errors.BadRequestError
3555
3556var find = require('../common/array/find')
3557var includes = require('../common/array/includes')
3558var map = require('../common/array/map')
3559
3560var constants = require('../common/constants')
3561var changeEvent = constants.change
3562var updateMethod = constants.update
3563var primaryKey = constants.primary
3564var linkKey = constants.link
3565var inverseKey = constants.inverse
3566var isArrayKey = constants.isArray
3567var denormalizedInverseKey = constants.denormalizedInverse
3568var updateRecordKey = constants.updateRecord
3569var linkedHashKey = constants.linkedHash
3570
3571
3572/**
3573 * Do updates. First, it must find the records to update, then run hooks
3574 * and validation, then apply the update as well as links on related records.
3575 *
3576 * @return {Promise}
3577 */
3578module.exports = function (context) {
3579 var Promise = promise.Promise
3580 var self = this
3581 var denormalizedFields = self.denormalizedFields
3582 var adapter = self.adapter
3583 var recordTypes = self.recordTypes
3584 var hooks = self.hooks
3585
3586 var relatedUpdates = {}
3587 var hookedUpdates = []
3588
3589 var links = []
3590 var transaction, updates, fields, hook, type, meta, language
3591
3592 // Start a promise chain.
3593 return Promise.resolve(context.request.payload)
3594
3595 .then(function (payload) {
3596 var i, j, update, field
3597
3598 updates = payload
3599 validateUpdates(updates, context.request.meta)
3600
3601 type = context.request.type
3602 meta = context.request.meta
3603 transaction = context.transaction
3604 language = meta.language
3605
3606 fields = recordTypes[type]
3607 hook = hooks[type]
3608
3609 // Delete denormalized inverse fields, can't be updated.
3610 for (field in fields) {
3611 if (linkKey in fields[field]) links.push(field)
3612 if (denormalizedInverseKey in fields[field])
3613 for (i = 0, j = updates.length; i < j; i++) {
3614 update = updates[i]
3615 if (update.replace) delete update.replace[field]
3616 if (update.pull) delete update.pull[field]
3617 if (update.push) delete update.push[field]
3618 }
3619 }
3620
3621 return transaction.find(type, map(updates, function (update) {
3622 return update[primaryKey]
3623 }), null, meta)
3624 })
3625
3626 .then(function (records) {
3627 if (records.length < updates.length)
3628 throw new NotFoundError(message('UpdateRecordMissing', language))
3629
3630 return Promise.all(map(records, function (record) {
3631 var update, cloneUpdate
3632 var hasHook = typeof hook[0] === 'function'
3633 var id = record[primaryKey]
3634
3635 update = find(updates, function (update) {
3636 return update[primaryKey] === id
3637 })
3638
3639 if (!update) throw new NotFoundError(
3640 message('UpdateRecordMissing', language))
3641
3642 if (hasHook) cloneUpdate = clone(update)
3643
3644 return Promise.resolve(hasHook ?
3645 hook[0](context, record, update) : update)
3646 .then(function (result) {
3647 if (result && typeof result === 'object') update = result
3648
3649 if (hasHook) {
3650 // Check if the update has been modified or not.
3651 if (!deepEqual(update, cloneUpdate))
3652 context.response.meta.updateModified = true
3653
3654 // Runtime safety check: primary key must be the same.
3655 if (update[primaryKey] !== id) throw new BadRequestError(
3656 message('InvalidID', language))
3657 }
3658
3659 hookedUpdates.push(update)
3660 Object.defineProperty(update, updateRecordKey, { value: record })
3661
3662 // Shallow clone the record.
3663 record = assign({}, record)
3664
3665 // Apply updates to record.
3666 applyUpdate(record, update)
3667
3668 // Apply operators to record.
3669 if (update.operate)
3670 record = adapter.applyOperators(record, update.operate)
3671
3672 // Enforce the fields.
3673 enforce(type, record, fields, meta)
3674
3675 // Ensure referential integrity.
3676 return checkLinks.call(
3677 self, transaction, record, fields, links, meta)
3678 .then(function (linked) {
3679 Object.defineProperty(update, linkedHashKey, { value: linked })
3680 return record
3681 })
3682 })
3683 }))
3684 })
3685
3686 .then(function (records) {
3687 var i, j
3688
3689 validateRecords.call(self, records, fields, links, meta)
3690
3691 Object.defineProperty(context.response, 'records', {
3692 configurable: true,
3693 value: records
3694 })
3695
3696 // Drop fields in the updates that aren't defined in the record type
3697 // before doing the update.
3698 for (i = 0, j = hookedUpdates.length; i < j; i++)
3699 dropFields(hookedUpdates[i], fields)
3700
3701 return transaction.update(type, hookedUpdates, meta)
3702 })
3703
3704 .then(function () {
3705 var inverseField, isArray, linkedType, linkedIsArray, linked, record,
3706 partialRecord, partialRecords, ids, id, push, pull, update, field
3707 var i, j, k, l, m, n
3708
3709 // Build up related updates based on update objects.
3710 var idCache = {}
3711
3712 // Iterate over each update to generate related updates.
3713 for (i = 0, j = hookedUpdates.length; i < j; i++) {
3714 update = hookedUpdates[i]
3715
3716 for (k = 0, l = links.length; k < l; k++) {
3717 field = links[k]
3718 inverseField = fields[field][inverseKey]
3719
3720 if (!inverseField) continue
3721
3722 isArray = fields[field][isArrayKey]
3723 linkedType = fields[field][linkKey]
3724 linkedIsArray =
3725 recordTypes[linkedType][inverseField][isArrayKey]
3726
3727 // Do some initialization.
3728 if (!relatedUpdates[linkedType]) relatedUpdates[linkedType] = []
3729 if (!idCache[linkedType]) idCache[linkedType] = {}
3730
3731 record = update[updateRecordKey]
3732 linked = update[linkedHashKey]
3733
3734 // Replacing a link field is pretty complicated.
3735 if (update.replace && update.replace.hasOwnProperty(field)) {
3736 id = update.replace[field]
3737
3738 if (!Array.isArray(id)) {
3739 // Don't need to worry about inverse updates if the value does not
3740 // change.
3741 if (id === record[field]) continue
3742
3743 // Set related field.
3744 if (id !== null)
3745 addId(update[primaryKey],
3746 getUpdate(linkedType, id, relatedUpdates, idCache),
3747 inverseField, linkedIsArray)
3748
3749 // Unset 2nd degree related record.
3750 if (linked[field] &&
3751 linked[field][inverseField] !== null &&
3752 !linkedIsArray &&
3753 linked[field][inverseField] !== update[primaryKey])
3754 removeId(id,
3755 getUpdate(
3756 type, linked[field][inverseField],
3757 relatedUpdates, idCache),
3758 field, linkedIsArray)
3759
3760 // For unsetting, remove ID from related record.
3761 if (record[field] !== null &&
3762 record[field] !== update[field] &&
3763 record[field] !== id)
3764 removeId(update[primaryKey],
3765 getUpdate(
3766 linkedType, record[field], relatedUpdates, idCache),
3767 inverseField, linkedIsArray)
3768
3769 // After this point, there's no need to go over push/pull.
3770 continue
3771 }
3772
3773 ids = id
3774
3775 // Compute differences for pull, and mutate the update.
3776 for (m = 0, n = record[field].length; m < n; m++) {
3777 id = record[field][m]
3778 if (!includes(ids, id)) {
3779 if (!('pull' in update)) update.pull = {}
3780 if (update.pull.hasOwnProperty(field)) {
3781 if (Array.isArray(update.pull[field])) {
3782 update.pull[field].push(id)
3783 continue
3784 }
3785 update.pull[field] = [ update.pull[field], id ]
3786 continue
3787 }
3788 update.pull[field] = [ id ]
3789 }
3790 }
3791
3792 // Compute differences for push, and mutate the update.
3793 for (m = 0, n = ids.length; m < n; m++) {
3794 id = ids[m]
3795 if (!includes(record[field], id)) {
3796 if (!('push' in update)) update.push = {}
3797 if (update.push.hasOwnProperty(field)) {
3798 if (Array.isArray(update.push[field])) {
3799 update.push[field].push(id)
3800 continue
3801 }
3802 update.push[field] = [ update.push[field], id ]
3803 continue
3804 }
3805 update.push[field] = [ id ]
3806 }
3807 }
3808
3809 // Delete the original replace, since it is no longer valid.
3810 delete update.replace[field]
3811 }
3812
3813 if (update.pull && update.pull[field]) {
3814 pull = Array.isArray(update.pull[field]) ?
3815 update.pull[field] : [ update.pull[field] ]
3816
3817 for (m = 0, n = pull.length; m < n; m++) {
3818 id = pull[m]
3819 if (id !== null)
3820 removeId(update[primaryKey],
3821 getUpdate(linkedType, id, relatedUpdates, idCache),
3822 inverseField, linkedIsArray)
3823 }
3824 }
3825
3826 if (update.push && update.push[field]) {
3827 push = Array.isArray(update.push[field]) ?
3828 update.push[field] : [ update.push[field] ]
3829
3830 for (m = 0, n = push.length; m < n; m++) {
3831 id = push[m]
3832 if (id !== null)
3833 addId(update[primaryKey],
3834 getUpdate(linkedType, id, relatedUpdates, idCache),
3835 inverseField, linkedIsArray)
3836 }
3837 }
3838
3839 // Unset from 2nd degree related records.
3840 if (linked[field] && !linkedIsArray) {
3841 partialRecords = Array.isArray(linked[field]) ?
3842 linked[field] : [ linked[field] ]
3843
3844 for (m = 0, n = partialRecords.length; m < n; m++) {
3845 partialRecord = partialRecords[m]
3846
3847 if (partialRecord[inverseField] === update[primaryKey])
3848 continue
3849
3850 removeId(partialRecord[primaryKey],
3851 getUpdate(
3852 type, partialRecord[inverseField],
3853 relatedUpdates, idCache),
3854 field, isArray)
3855 }
3856 }
3857 }
3858 }
3859
3860 return Promise.all(map(Object.keys(relatedUpdates), function (type) {
3861 return relatedUpdates[type].length ?
3862 transaction.update(type, relatedUpdates[type], meta) :
3863 null
3864 }))
3865 })
3866
3867 .then(function () {
3868 var eventData = {}, linkedType
3869
3870 eventData[updateMethod] = {}
3871 eventData[updateMethod][type] = hookedUpdates
3872
3873 for (linkedType in relatedUpdates) {
3874 scrubDenormalizedUpdates(
3875 relatedUpdates[linkedType], denormalizedFields)
3876
3877 if (!relatedUpdates[linkedType].length) continue
3878
3879 if (linkedType !== type)
3880 eventData[updateMethod][linkedType] = relatedUpdates[linkedType]
3881
3882 // Get the union of update IDs.
3883 else eventData[updateMethod][type] =
3884 eventData[updateMethod][type].concat(relatedUpdates[type])
3885 }
3886
3887 // Summarize changes during the lifecycle of the request.
3888 self.emit(changeEvent, eventData)
3889
3890 return context
3891 })
3892}
3893
3894
3895// Validate updates.
3896function validateUpdates (updates, meta) {
3897 var language = meta.language
3898 var i, j, update
3899
3900 if (!updates || !updates.length)
3901 throw new BadRequestError(
3902 message('UpdateRecordsInvalid', language))
3903
3904 for (i = 0, j = updates.length; i < j; i++) {
3905 update = updates[i]
3906 if (!update[primaryKey])
3907 throw new BadRequestError(
3908 message('UpdateRecordMissingID', language))
3909 }
3910}
3911
3912
3913function dropFields (update, fields) {
3914 var field
3915
3916 for (field in update.replace)
3917 if (!fields.hasOwnProperty(field)) delete update.replace[field]
3918
3919 for (field in update.pull)
3920 if (!fields.hasOwnProperty(field)) delete update.pull[field]
3921
3922 for (field in update.push)
3923 if (!fields.hasOwnProperty(field)) delete update.push[field]
3924}
3925
3926},{"../common/apply_update":6,"../common/array/find":8,"../common/array/includes":9,"../common/array/map":10,"../common/assign":14,"../common/clone":17,"../common/constants":18,"../common/deep_equal":19,"../common/errors":20,"../common/message":25,"../common/promise":28,"../record_type/enforce":33,"./check_links":36,"./update_helpers":44,"./validate_records":45}],44:[function(require,module,exports){
3927'use strict'
3928
3929var find = require('../common/array/find')
3930
3931var keys = require('../common/keys')
3932var primaryKey = keys.primary
3933
3934
3935// Get a related update object by ID, or return a new one if not found.
3936exports.getUpdate = function (type, id, updates, cache) {
3937 var update
3938
3939 if (cache[type] && cache[type][id])
3940 return find(updates[type],
3941 function (update) {
3942 return update[primaryKey] === id
3943 })
3944
3945 update = { id: id }
3946 if (!updates[type]) updates[type] = []
3947 updates[type].push(update)
3948 cache[type] = {}
3949 cache[type][id] = true
3950 return update
3951}
3952
3953
3954// Add an ID to an update object.
3955exports.addId = function (id, update, field, isArray) {
3956 if (isArray) {
3957 if (!update.push) update.push = {}
3958 if (!update.push[field]) update.push[field] = []
3959 update.push[field].push(id)
3960 return
3961 }
3962
3963 if (!update.replace) update.replace = {}
3964 update.replace[field] = id
3965}
3966
3967
3968// Remove an ID from an update object.
3969exports.removeId = function (id, update, field, isArray) {
3970 if (isArray) {
3971 if (!update.pull) update.pull = {}
3972 if (!update.pull[field]) update.pull[field] = []
3973 update.pull[field].push(id)
3974 return
3975 }
3976
3977 if (!update.replace) update.replace = {}
3978 update.replace[field] = null
3979}
3980
3981
3982// Remove denormalized fields from appearing in updates on change events.
3983exports.scrubDenormalizedUpdates = function (updates, denormalizedFields) {
3984 var i, update, operation, field
3985
3986 // Iterate in reverse, so we can easily remove indices in the array.
3987 for (i = updates.length; i--;) {
3988 update = updates[i]
3989
3990 for (operation in update) {
3991 if (operation === primaryKey) continue
3992
3993 for (field in update[operation])
3994 if (field in denormalizedFields)
3995 delete update[operation][field]
3996
3997 if (!Object.keys(update[operation]).length)
3998 delete update[operation]
3999 }
4000
4001 // If only the primary key is present, then remove the entire update.
4002 if (Object.keys(update).length === 1) updates.splice(i, 1)
4003 }
4004}
4005
4006},{"../common/array/find":8,"../common/keys":24}],45:[function(require,module,exports){
4007'use strict'
4008
4009var message = require('../common/message')
4010
4011var errors = require('../common/errors')
4012var ConflictError = errors.ConflictError
4013
4014var keys = require('../common/keys')
4015var linkKey = keys.link
4016var isArrayKey = keys.isArray
4017var inverseKey = keys.inverse
4018
4019/**
4020 * Do some validation on records to be created or updated to determine
4021 * if there are any records which have overlapping to-one relationships,
4022 * or non-unique array relationships.
4023 *
4024 * @param {Object[]} records
4025 * @param {Object} fields
4026 * @param {Object} links
4027 * @param {Object} meta
4028 */
4029module.exports = function validateRecords (records, fields, links, meta) {
4030 var recordTypes = this.recordTypes
4031 var language = meta.language
4032 var toOneMap = {}
4033 var i, j, k, l, m, n, value, field, record, id, ids, seen,
4034 fieldLink, fieldInverse, fieldIsArray, inverseIsArray
4035
4036 for (i = 0, j = links.length; i < j; i++) {
4037 field = links[i]
4038 fieldLink = fields[field][linkKey]
4039 fieldInverse = fields[field][inverseKey]
4040 fieldIsArray = fields[field][isArrayKey]
4041 inverseIsArray = recordTypes[fieldLink][fieldInverse][isArrayKey]
4042
4043 if (fieldIsArray)
4044 for (k = 0, l = records.length; k < l; k++) {
4045 record = records[k]
4046 if (!Array.isArray(record[field])) continue
4047 ids = record[field]
4048 seen = {}
4049
4050 for (m = 0, n = ids.length; m < n; m++) {
4051 id = ids[m]
4052 if (seen.hasOwnProperty(id)) throw new ConflictError(
4053 message('CollisionDuplicate', language, { id: id, field: field }))
4054 else seen[id] = true
4055 }
4056 }
4057
4058 if (!inverseIsArray) {
4059 toOneMap[field] = {}
4060
4061 for (k = 0, l = records.length; k < l; k++) {
4062 record = records[k]
4063 value = record[field]
4064 ids = Array.isArray(value) ? value : value ? [ value ] : []
4065
4066 for (m = 0, n = ids.length; m < n; m++) {
4067 id = ids[m]
4068 if (!toOneMap[field].hasOwnProperty(id)) toOneMap[field][id] = true
4069 else throw new ConflictError(
4070 message('CollisionToOne', language, { field: field }))
4071 }
4072 }
4073 }
4074 }
4075}
4076
4077},{"../common/errors":20,"../common/keys":24,"../common/message":25}],46:[function(require,module,exports){
4078'use strict'
4079
4080exports.byteLength = byteLength
4081exports.toByteArray = toByteArray
4082exports.fromByteArray = fromByteArray
4083
4084var lookup = []
4085var revLookup = []
4086var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
4087
4088var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
4089for (var i = 0, len = code.length; i < len; ++i) {
4090 lookup[i] = code[i]
4091 revLookup[code.charCodeAt(i)] = i
4092}
4093
4094// Support decoding URL-safe base64 strings, as Node.js does.
4095// See: https://en.wikipedia.org/wiki/Base64#URL_applications
4096revLookup['-'.charCodeAt(0)] = 62
4097revLookup['_'.charCodeAt(0)] = 63
4098
4099function getLens (b64) {
4100 var len = b64.length
4101
4102 if (len % 4 > 0) {
4103 throw new Error('Invalid string. Length must be a multiple of 4')
4104 }
4105
4106 // Trim off extra bytes after placeholder bytes are found
4107 // See: https://github.com/beatgammit/base64-js/issues/42
4108 var validLen = b64.indexOf('=')
4109 if (validLen === -1) validLen = len
4110
4111 var placeHoldersLen = validLen === len
4112 ? 0
4113 : 4 - (validLen % 4)
4114
4115 return [validLen, placeHoldersLen]
4116}
4117
4118// base64 is 4/3 + up to two characters of the original data
4119function byteLength (b64) {
4120 var lens = getLens(b64)
4121 var validLen = lens[0]
4122 var placeHoldersLen = lens[1]
4123 return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
4124}
4125
4126function _byteLength (b64, validLen, placeHoldersLen) {
4127 return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
4128}
4129
4130function toByteArray (b64) {
4131 var tmp
4132 var lens = getLens(b64)
4133 var validLen = lens[0]
4134 var placeHoldersLen = lens[1]
4135
4136 var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
4137
4138 var curByte = 0
4139
4140 // if there are placeholders, only get up to the last complete 4 chars
4141 var len = placeHoldersLen > 0
4142 ? validLen - 4
4143 : validLen
4144
4145 for (var i = 0; i < len; i += 4) {
4146 tmp =
4147 (revLookup[b64.charCodeAt(i)] << 18) |
4148 (revLookup[b64.charCodeAt(i + 1)] << 12) |
4149 (revLookup[b64.charCodeAt(i + 2)] << 6) |
4150 revLookup[b64.charCodeAt(i + 3)]
4151 arr[curByte++] = (tmp >> 16) & 0xFF
4152 arr[curByte++] = (tmp >> 8) & 0xFF
4153 arr[curByte++] = tmp & 0xFF
4154 }
4155
4156 if (placeHoldersLen === 2) {
4157 tmp =
4158 (revLookup[b64.charCodeAt(i)] << 2) |
4159 (revLookup[b64.charCodeAt(i + 1)] >> 4)
4160 arr[curByte++] = tmp & 0xFF
4161 }
4162
4163 if (placeHoldersLen === 1) {
4164 tmp =
4165 (revLookup[b64.charCodeAt(i)] << 10) |
4166 (revLookup[b64.charCodeAt(i + 1)] << 4) |
4167 (revLookup[b64.charCodeAt(i + 2)] >> 2)
4168 arr[curByte++] = (tmp >> 8) & 0xFF
4169 arr[curByte++] = tmp & 0xFF
4170 }
4171
4172 return arr
4173}
4174
4175function tripletToBase64 (num) {
4176 return lookup[num >> 18 & 0x3F] +
4177 lookup[num >> 12 & 0x3F] +
4178 lookup[num >> 6 & 0x3F] +
4179 lookup[num & 0x3F]
4180}
4181
4182function encodeChunk (uint8, start, end) {
4183 var tmp
4184 var output = []
4185 for (var i = start; i < end; i += 3) {
4186 tmp =
4187 ((uint8[i] << 16) & 0xFF0000) +
4188 ((uint8[i + 1] << 8) & 0xFF00) +
4189 (uint8[i + 2] & 0xFF)
4190 output.push(tripletToBase64(tmp))
4191 }
4192 return output.join('')
4193}
4194
4195function fromByteArray (uint8) {
4196 var tmp
4197 var len = uint8.length
4198 var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
4199 var parts = []
4200 var maxChunkLength = 16383 // must be multiple of 3
4201
4202 // go through the array every three bytes, we'll deal with trailing stuff later
4203 for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
4204 parts.push(encodeChunk(
4205 uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
4206 ))
4207 }
4208
4209 // pad the end with zeros, but make sure to not forget the extra bytes
4210 if (extraBytes === 1) {
4211 tmp = uint8[len - 1]
4212 parts.push(
4213 lookup[tmp >> 2] +
4214 lookup[(tmp << 4) & 0x3F] +
4215 '=='
4216 )
4217 } else if (extraBytes === 2) {
4218 tmp = (uint8[len - 2] << 8) + uint8[len - 1]
4219 parts.push(
4220 lookup[tmp >> 10] +
4221 lookup[(tmp >> 4) & 0x3F] +
4222 lookup[(tmp << 2) & 0x3F] +
4223 '='
4224 )
4225 }
4226
4227 return parts.join('')
4228}
4229
4230},{}],47:[function(require,module,exports){
4231/*!
4232 * The buffer module from node.js, for the browser.
4233 *
4234 * @author Feross Aboukhadijeh <https://feross.org>
4235 * @license MIT
4236 */
4237/* eslint-disable no-proto */
4238
4239'use strict'
4240
4241var base64 = require('base64-js')
4242var ieee754 = require('ieee754')
4243
4244exports.Buffer = Buffer
4245exports.SlowBuffer = SlowBuffer
4246exports.INSPECT_MAX_BYTES = 50
4247
4248var K_MAX_LENGTH = 0x7fffffff
4249exports.kMaxLength = K_MAX_LENGTH
4250
4251/**
4252 * If `Buffer.TYPED_ARRAY_SUPPORT`:
4253 * === true Use Uint8Array implementation (fastest)
4254 * === false Print warning and recommend using `buffer` v4.x which has an Object
4255 * implementation (most compatible, even IE6)
4256 *
4257 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
4258 * Opera 11.6+, iOS 4.2+.
4259 *
4260 * We report that the browser does not support typed arrays if the are not subclassable
4261 * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
4262 * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
4263 * for __proto__ and has a buggy typed array implementation.
4264 */
4265Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
4266
4267if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
4268 typeof console.error === 'function') {
4269 console.error(
4270 'This browser lacks typed array (Uint8Array) support which is required by ' +
4271 '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
4272 )
4273}
4274
4275function typedArraySupport () {
4276 // Can typed array instances can be augmented?
4277 try {
4278 var arr = new Uint8Array(1)
4279 arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
4280 return arr.foo() === 42
4281 } catch (e) {
4282 return false
4283 }
4284}
4285
4286Object.defineProperty(Buffer.prototype, 'parent', {
4287 enumerable: true,
4288 get: function () {
4289 if (!Buffer.isBuffer(this)) return undefined
4290 return this.buffer
4291 }
4292})
4293
4294Object.defineProperty(Buffer.prototype, 'offset', {
4295 enumerable: true,
4296 get: function () {
4297 if (!Buffer.isBuffer(this)) return undefined
4298 return this.byteOffset
4299 }
4300})
4301
4302function createBuffer (length) {
4303 if (length > K_MAX_LENGTH) {
4304 throw new RangeError('The value "' + length + '" is invalid for option "size"')
4305 }
4306 // Return an augmented `Uint8Array` instance
4307 var buf = new Uint8Array(length)
4308 buf.__proto__ = Buffer.prototype
4309 return buf
4310}
4311
4312/**
4313 * The Buffer constructor returns instances of `Uint8Array` that have their
4314 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
4315 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
4316 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
4317 * returns a single octet.
4318 *
4319 * The `Uint8Array` prototype remains unmodified.
4320 */
4321
4322function Buffer (arg, encodingOrOffset, length) {
4323 // Common case.
4324 if (typeof arg === 'number') {
4325 if (typeof encodingOrOffset === 'string') {
4326 throw new TypeError(
4327 'The "string" argument must be of type string. Received type number'
4328 )
4329 }
4330 return allocUnsafe(arg)
4331 }
4332 return from(arg, encodingOrOffset, length)
4333}
4334
4335// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
4336if (typeof Symbol !== 'undefined' && Symbol.species != null &&
4337 Buffer[Symbol.species] === Buffer) {
4338 Object.defineProperty(Buffer, Symbol.species, {
4339 value: null,
4340 configurable: true,
4341 enumerable: false,
4342 writable: false
4343 })
4344}
4345
4346Buffer.poolSize = 8192 // not used by this implementation
4347
4348function from (value, encodingOrOffset, length) {
4349 if (typeof value === 'string') {
4350 return fromString(value, encodingOrOffset)
4351 }
4352
4353 if (ArrayBuffer.isView(value)) {
4354 return fromArrayLike(value)
4355 }
4356
4357 if (value == null) {
4358 throw TypeError(
4359 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
4360 'or Array-like Object. Received type ' + (typeof value)
4361 )
4362 }
4363
4364 if (isInstance(value, ArrayBuffer) ||
4365 (value && isInstance(value.buffer, ArrayBuffer))) {
4366 return fromArrayBuffer(value, encodingOrOffset, length)
4367 }
4368
4369 if (typeof value === 'number') {
4370 throw new TypeError(
4371 'The "value" argument must not be of type number. Received type number'
4372 )
4373 }
4374
4375 var valueOf = value.valueOf && value.valueOf()
4376 if (valueOf != null && valueOf !== value) {
4377 return Buffer.from(valueOf, encodingOrOffset, length)
4378 }
4379
4380 var b = fromObject(value)
4381 if (b) return b
4382
4383 if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
4384 typeof value[Symbol.toPrimitive] === 'function') {
4385 return Buffer.from(
4386 value[Symbol.toPrimitive]('string'), encodingOrOffset, length
4387 )
4388 }
4389
4390 throw new TypeError(
4391 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
4392 'or Array-like Object. Received type ' + (typeof value)
4393 )
4394}
4395
4396/**
4397 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
4398 * if value is a number.
4399 * Buffer.from(str[, encoding])
4400 * Buffer.from(array)
4401 * Buffer.from(buffer)
4402 * Buffer.from(arrayBuffer[, byteOffset[, length]])
4403 **/
4404Buffer.from = function (value, encodingOrOffset, length) {
4405 return from(value, encodingOrOffset, length)
4406}
4407
4408// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
4409// https://github.com/feross/buffer/pull/148
4410Buffer.prototype.__proto__ = Uint8Array.prototype
4411Buffer.__proto__ = Uint8Array
4412
4413function assertSize (size) {
4414 if (typeof size !== 'number') {
4415 throw new TypeError('"size" argument must be of type number')
4416 } else if (size < 0) {
4417 throw new RangeError('The value "' + size + '" is invalid for option "size"')
4418 }
4419}
4420
4421function alloc (size, fill, encoding) {
4422 assertSize(size)
4423 if (size <= 0) {
4424 return createBuffer(size)
4425 }
4426 if (fill !== undefined) {
4427 // Only pay attention to encoding if it's a string. This
4428 // prevents accidentally sending in a number that would
4429 // be interpretted as a start offset.
4430 return typeof encoding === 'string'
4431 ? createBuffer(size).fill(fill, encoding)
4432 : createBuffer(size).fill(fill)
4433 }
4434 return createBuffer(size)
4435}
4436
4437/**
4438 * Creates a new filled Buffer instance.
4439 * alloc(size[, fill[, encoding]])
4440 **/
4441Buffer.alloc = function (size, fill, encoding) {
4442 return alloc(size, fill, encoding)
4443}
4444
4445function allocUnsafe (size) {
4446 assertSize(size)
4447 return createBuffer(size < 0 ? 0 : checked(size) | 0)
4448}
4449
4450/**
4451 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
4452 * */
4453Buffer.allocUnsafe = function (size) {
4454 return allocUnsafe(size)
4455}
4456/**
4457 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
4458 */
4459Buffer.allocUnsafeSlow = function (size) {
4460 return allocUnsafe(size)
4461}
4462
4463function fromString (string, encoding) {
4464 if (typeof encoding !== 'string' || encoding === '') {
4465 encoding = 'utf8'
4466 }
4467
4468 if (!Buffer.isEncoding(encoding)) {
4469 throw new TypeError('Unknown encoding: ' + encoding)
4470 }
4471
4472 var length = byteLength(string, encoding) | 0
4473 var buf = createBuffer(length)
4474
4475 var actual = buf.write(string, encoding)
4476
4477 if (actual !== length) {
4478 // Writing a hex string, for example, that contains invalid characters will
4479 // cause everything after the first invalid character to be ignored. (e.g.
4480 // 'abxxcd' will be treated as 'ab')
4481 buf = buf.slice(0, actual)
4482 }
4483
4484 return buf
4485}
4486
4487function fromArrayLike (array) {
4488 var length = array.length < 0 ? 0 : checked(array.length) | 0
4489 var buf = createBuffer(length)
4490 for (var i = 0; i < length; i += 1) {
4491 buf[i] = array[i] & 255
4492 }
4493 return buf
4494}
4495
4496function fromArrayBuffer (array, byteOffset, length) {
4497 if (byteOffset < 0 || array.byteLength < byteOffset) {
4498 throw new RangeError('"offset" is outside of buffer bounds')
4499 }
4500
4501 if (array.byteLength < byteOffset + (length || 0)) {
4502 throw new RangeError('"length" is outside of buffer bounds')
4503 }
4504
4505 var buf
4506 if (byteOffset === undefined && length === undefined) {
4507 buf = new Uint8Array(array)
4508 } else if (length === undefined) {
4509 buf = new Uint8Array(array, byteOffset)
4510 } else {
4511 buf = new Uint8Array(array, byteOffset, length)
4512 }
4513
4514 // Return an augmented `Uint8Array` instance
4515 buf.__proto__ = Buffer.prototype
4516 return buf
4517}
4518
4519function fromObject (obj) {
4520 if (Buffer.isBuffer(obj)) {
4521 var len = checked(obj.length) | 0
4522 var buf = createBuffer(len)
4523
4524 if (buf.length === 0) {
4525 return buf
4526 }
4527
4528 obj.copy(buf, 0, 0, len)
4529 return buf
4530 }
4531
4532 if (obj.length !== undefined) {
4533 if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
4534 return createBuffer(0)
4535 }
4536 return fromArrayLike(obj)
4537 }
4538
4539 if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
4540 return fromArrayLike(obj.data)
4541 }
4542}
4543
4544function checked (length) {
4545 // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
4546 // length is NaN (which is otherwise coerced to zero.)
4547 if (length >= K_MAX_LENGTH) {
4548 throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
4549 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
4550 }
4551 return length | 0
4552}
4553
4554function SlowBuffer (length) {
4555 if (+length != length) { // eslint-disable-line eqeqeq
4556 length = 0
4557 }
4558 return Buffer.alloc(+length)
4559}
4560
4561Buffer.isBuffer = function isBuffer (b) {
4562 return b != null && b._isBuffer === true &&
4563 b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
4564}
4565
4566Buffer.compare = function compare (a, b) {
4567 if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
4568 if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
4569 if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
4570 throw new TypeError(
4571 'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
4572 )
4573 }
4574
4575 if (a === b) return 0
4576
4577 var x = a.length
4578 var y = b.length
4579
4580 for (var i = 0, len = Math.min(x, y); i < len; ++i) {
4581 if (a[i] !== b[i]) {
4582 x = a[i]
4583 y = b[i]
4584 break
4585 }
4586 }
4587
4588 if (x < y) return -1
4589 if (y < x) return 1
4590 return 0
4591}
4592
4593Buffer.isEncoding = function isEncoding (encoding) {
4594 switch (String(encoding).toLowerCase()) {
4595 case 'hex':
4596 case 'utf8':
4597 case 'utf-8':
4598 case 'ascii':
4599 case 'latin1':
4600 case 'binary':
4601 case 'base64':
4602 case 'ucs2':
4603 case 'ucs-2':
4604 case 'utf16le':
4605 case 'utf-16le':
4606 return true
4607 default:
4608 return false
4609 }
4610}
4611
4612Buffer.concat = function concat (list, length) {
4613 if (!Array.isArray(list)) {
4614 throw new TypeError('"list" argument must be an Array of Buffers')
4615 }
4616
4617 if (list.length === 0) {
4618 return Buffer.alloc(0)
4619 }
4620
4621 var i
4622 if (length === undefined) {
4623 length = 0
4624 for (i = 0; i < list.length; ++i) {
4625 length += list[i].length
4626 }
4627 }
4628
4629 var buffer = Buffer.allocUnsafe(length)
4630 var pos = 0
4631 for (i = 0; i < list.length; ++i) {
4632 var buf = list[i]
4633 if (isInstance(buf, Uint8Array)) {
4634 buf = Buffer.from(buf)
4635 }
4636 if (!Buffer.isBuffer(buf)) {
4637 throw new TypeError('"list" argument must be an Array of Buffers')
4638 }
4639 buf.copy(buffer, pos)
4640 pos += buf.length
4641 }
4642 return buffer
4643}
4644
4645function byteLength (string, encoding) {
4646 if (Buffer.isBuffer(string)) {
4647 return string.length
4648 }
4649 if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
4650 return string.byteLength
4651 }
4652 if (typeof string !== 'string') {
4653 throw new TypeError(
4654 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
4655 'Received type ' + typeof string
4656 )
4657 }
4658
4659 var len = string.length
4660 var mustMatch = (arguments.length > 2 && arguments[2] === true)
4661 if (!mustMatch && len === 0) return 0
4662
4663 // Use a for loop to avoid recursion
4664 var loweredCase = false
4665 for (;;) {
4666 switch (encoding) {
4667 case 'ascii':
4668 case 'latin1':
4669 case 'binary':
4670 return len
4671 case 'utf8':
4672 case 'utf-8':
4673 return utf8ToBytes(string).length
4674 case 'ucs2':
4675 case 'ucs-2':
4676 case 'utf16le':
4677 case 'utf-16le':
4678 return len * 2
4679 case 'hex':
4680 return len >>> 1
4681 case 'base64':
4682 return base64ToBytes(string).length
4683 default:
4684 if (loweredCase) {
4685 return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
4686 }
4687 encoding = ('' + encoding).toLowerCase()
4688 loweredCase = true
4689 }
4690 }
4691}
4692Buffer.byteLength = byteLength
4693
4694function slowToString (encoding, start, end) {
4695 var loweredCase = false
4696
4697 // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
4698 // property of a typed array.
4699
4700 // This behaves neither like String nor Uint8Array in that we set start/end
4701 // to their upper/lower bounds if the value passed is out of range.
4702 // undefined is handled specially as per ECMA-262 6th Edition,
4703 // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
4704 if (start === undefined || start < 0) {
4705 start = 0
4706 }
4707 // Return early if start > this.length. Done here to prevent potential uint32
4708 // coercion fail below.
4709 if (start > this.length) {
4710 return ''
4711 }
4712
4713 if (end === undefined || end > this.length) {
4714 end = this.length
4715 }
4716
4717 if (end <= 0) {
4718 return ''
4719 }
4720
4721 // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
4722 end >>>= 0
4723 start >>>= 0
4724
4725 if (end <= start) {
4726 return ''
4727 }
4728
4729 if (!encoding) encoding = 'utf8'
4730
4731 while (true) {
4732 switch (encoding) {
4733 case 'hex':
4734 return hexSlice(this, start, end)
4735
4736 case 'utf8':
4737 case 'utf-8':
4738 return utf8Slice(this, start, end)
4739
4740 case 'ascii':
4741 return asciiSlice(this, start, end)
4742
4743 case 'latin1':
4744 case 'binary':
4745 return latin1Slice(this, start, end)
4746
4747 case 'base64':
4748 return base64Slice(this, start, end)
4749
4750 case 'ucs2':
4751 case 'ucs-2':
4752 case 'utf16le':
4753 case 'utf-16le':
4754 return utf16leSlice(this, start, end)
4755
4756 default:
4757 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
4758 encoding = (encoding + '').toLowerCase()
4759 loweredCase = true
4760 }
4761 }
4762}
4763
4764// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
4765// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
4766// reliably in a browserify context because there could be multiple different
4767// copies of the 'buffer' package in use. This method works even for Buffer
4768// instances that were created from another copy of the `buffer` package.
4769// See: https://github.com/feross/buffer/issues/154
4770Buffer.prototype._isBuffer = true
4771
4772function swap (b, n, m) {
4773 var i = b[n]
4774 b[n] = b[m]
4775 b[m] = i
4776}
4777
4778Buffer.prototype.swap16 = function swap16 () {
4779 var len = this.length
4780 if (len % 2 !== 0) {
4781 throw new RangeError('Buffer size must be a multiple of 16-bits')
4782 }
4783 for (var i = 0; i < len; i += 2) {
4784 swap(this, i, i + 1)
4785 }
4786 return this
4787}
4788
4789Buffer.prototype.swap32 = function swap32 () {
4790 var len = this.length
4791 if (len % 4 !== 0) {
4792 throw new RangeError('Buffer size must be a multiple of 32-bits')
4793 }
4794 for (var i = 0; i < len; i += 4) {
4795 swap(this, i, i + 3)
4796 swap(this, i + 1, i + 2)
4797 }
4798 return this
4799}
4800
4801Buffer.prototype.swap64 = function swap64 () {
4802 var len = this.length
4803 if (len % 8 !== 0) {
4804 throw new RangeError('Buffer size must be a multiple of 64-bits')
4805 }
4806 for (var i = 0; i < len; i += 8) {
4807 swap(this, i, i + 7)
4808 swap(this, i + 1, i + 6)
4809 swap(this, i + 2, i + 5)
4810 swap(this, i + 3, i + 4)
4811 }
4812 return this
4813}
4814
4815Buffer.prototype.toString = function toString () {
4816 var length = this.length
4817 if (length === 0) return ''
4818 if (arguments.length === 0) return utf8Slice(this, 0, length)
4819 return slowToString.apply(this, arguments)
4820}
4821
4822Buffer.prototype.toLocaleString = Buffer.prototype.toString
4823
4824Buffer.prototype.equals = function equals (b) {
4825 if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
4826 if (this === b) return true
4827 return Buffer.compare(this, b) === 0
4828}
4829
4830Buffer.prototype.inspect = function inspect () {
4831 var str = ''
4832 var max = exports.INSPECT_MAX_BYTES
4833 str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
4834 if (this.length > max) str += ' ... '
4835 return '<Buffer ' + str + '>'
4836}
4837
4838Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
4839 if (isInstance(target, Uint8Array)) {
4840 target = Buffer.from(target, target.offset, target.byteLength)
4841 }
4842 if (!Buffer.isBuffer(target)) {
4843 throw new TypeError(
4844 'The "target" argument must be one of type Buffer or Uint8Array. ' +
4845 'Received type ' + (typeof target)
4846 )
4847 }
4848
4849 if (start === undefined) {
4850 start = 0
4851 }
4852 if (end === undefined) {
4853 end = target ? target.length : 0
4854 }
4855 if (thisStart === undefined) {
4856 thisStart = 0
4857 }
4858 if (thisEnd === undefined) {
4859 thisEnd = this.length
4860 }
4861
4862 if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
4863 throw new RangeError('out of range index')
4864 }
4865
4866 if (thisStart >= thisEnd && start >= end) {
4867 return 0
4868 }
4869 if (thisStart >= thisEnd) {
4870 return -1
4871 }
4872 if (start >= end) {
4873 return 1
4874 }
4875
4876 start >>>= 0
4877 end >>>= 0
4878 thisStart >>>= 0
4879 thisEnd >>>= 0
4880
4881 if (this === target) return 0
4882
4883 var x = thisEnd - thisStart
4884 var y = end - start
4885 var len = Math.min(x, y)
4886
4887 var thisCopy = this.slice(thisStart, thisEnd)
4888 var targetCopy = target.slice(start, end)
4889
4890 for (var i = 0; i < len; ++i) {
4891 if (thisCopy[i] !== targetCopy[i]) {
4892 x = thisCopy[i]
4893 y = targetCopy[i]
4894 break
4895 }
4896 }
4897
4898 if (x < y) return -1
4899 if (y < x) return 1
4900 return 0
4901}
4902
4903// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
4904// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
4905//
4906// Arguments:
4907// - buffer - a Buffer to search
4908// - val - a string, Buffer, or number
4909// - byteOffset - an index into `buffer`; will be clamped to an int32
4910// - encoding - an optional encoding, relevant is val is a string
4911// - dir - true for indexOf, false for lastIndexOf
4912function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
4913 // Empty buffer means no match
4914 if (buffer.length === 0) return -1
4915
4916 // Normalize byteOffset
4917 if (typeof byteOffset === 'string') {
4918 encoding = byteOffset
4919 byteOffset = 0
4920 } else if (byteOffset > 0x7fffffff) {
4921 byteOffset = 0x7fffffff
4922 } else if (byteOffset < -0x80000000) {
4923 byteOffset = -0x80000000
4924 }
4925 byteOffset = +byteOffset // Coerce to Number.
4926 if (numberIsNaN(byteOffset)) {
4927 // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
4928 byteOffset = dir ? 0 : (buffer.length - 1)
4929 }
4930
4931 // Normalize byteOffset: negative offsets start from the end of the buffer
4932 if (byteOffset < 0) byteOffset = buffer.length + byteOffset
4933 if (byteOffset >= buffer.length) {
4934 if (dir) return -1
4935 else byteOffset = buffer.length - 1
4936 } else if (byteOffset < 0) {
4937 if (dir) byteOffset = 0
4938 else return -1
4939 }
4940
4941 // Normalize val
4942 if (typeof val === 'string') {
4943 val = Buffer.from(val, encoding)
4944 }
4945
4946 // Finally, search either indexOf (if dir is true) or lastIndexOf
4947 if (Buffer.isBuffer(val)) {
4948 // Special case: looking for empty string/buffer always fails
4949 if (val.length === 0) {
4950 return -1
4951 }
4952 return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
4953 } else if (typeof val === 'number') {
4954 val = val & 0xFF // Search for a byte value [0-255]
4955 if (typeof Uint8Array.prototype.indexOf === 'function') {
4956 if (dir) {
4957 return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
4958 } else {
4959 return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
4960 }
4961 }
4962 return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
4963 }
4964
4965 throw new TypeError('val must be string, number or Buffer')
4966}
4967
4968function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
4969 var indexSize = 1
4970 var arrLength = arr.length
4971 var valLength = val.length
4972
4973 if (encoding !== undefined) {
4974 encoding = String(encoding).toLowerCase()
4975 if (encoding === 'ucs2' || encoding === 'ucs-2' ||
4976 encoding === 'utf16le' || encoding === 'utf-16le') {
4977 if (arr.length < 2 || val.length < 2) {
4978 return -1
4979 }
4980 indexSize = 2
4981 arrLength /= 2
4982 valLength /= 2
4983 byteOffset /= 2
4984 }
4985 }
4986
4987 function read (buf, i) {
4988 if (indexSize === 1) {
4989 return buf[i]
4990 } else {
4991 return buf.readUInt16BE(i * indexSize)
4992 }
4993 }
4994
4995 var i
4996 if (dir) {
4997 var foundIndex = -1
4998 for (i = byteOffset; i < arrLength; i++) {
4999 if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
5000 if (foundIndex === -1) foundIndex = i
5001 if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
5002 } else {
5003 if (foundIndex !== -1) i -= i - foundIndex
5004 foundIndex = -1
5005 }
5006 }
5007 } else {
5008 if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
5009 for (i = byteOffset; i >= 0; i--) {
5010 var found = true
5011 for (var j = 0; j < valLength; j++) {
5012 if (read(arr, i + j) !== read(val, j)) {
5013 found = false
5014 break
5015 }
5016 }
5017 if (found) return i
5018 }
5019 }
5020
5021 return -1
5022}
5023
5024Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
5025 return this.indexOf(val, byteOffset, encoding) !== -1
5026}
5027
5028Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
5029 return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
5030}
5031
5032Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
5033 return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
5034}
5035
5036function hexWrite (buf, string, offset, length) {
5037 offset = Number(offset) || 0
5038 var remaining = buf.length - offset
5039 if (!length) {
5040 length = remaining
5041 } else {
5042 length = Number(length)
5043 if (length > remaining) {
5044 length = remaining
5045 }
5046 }
5047
5048 var strLen = string.length
5049
5050 if (length > strLen / 2) {
5051 length = strLen / 2
5052 }
5053 for (var i = 0; i < length; ++i) {
5054 var parsed = parseInt(string.substr(i * 2, 2), 16)
5055 if (numberIsNaN(parsed)) return i
5056 buf[offset + i] = parsed
5057 }
5058 return i
5059}
5060
5061function utf8Write (buf, string, offset, length) {
5062 return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
5063}
5064
5065function asciiWrite (buf, string, offset, length) {
5066 return blitBuffer(asciiToBytes(string), buf, offset, length)
5067}
5068
5069function latin1Write (buf, string, offset, length) {
5070 return asciiWrite(buf, string, offset, length)
5071}
5072
5073function base64Write (buf, string, offset, length) {
5074 return blitBuffer(base64ToBytes(string), buf, offset, length)
5075}
5076
5077function ucs2Write (buf, string, offset, length) {
5078 return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
5079}
5080
5081Buffer.prototype.write = function write (string, offset, length, encoding) {
5082 // Buffer#write(string)
5083 if (offset === undefined) {
5084 encoding = 'utf8'
5085 length = this.length
5086 offset = 0
5087 // Buffer#write(string, encoding)
5088 } else if (length === undefined && typeof offset === 'string') {
5089 encoding = offset
5090 length = this.length
5091 offset = 0
5092 // Buffer#write(string, offset[, length][, encoding])
5093 } else if (isFinite(offset)) {
5094 offset = offset >>> 0
5095 if (isFinite(length)) {
5096 length = length >>> 0
5097 if (encoding === undefined) encoding = 'utf8'
5098 } else {
5099 encoding = length
5100 length = undefined
5101 }
5102 } else {
5103 throw new Error(
5104 'Buffer.write(string, encoding, offset[, length]) is no longer supported'
5105 )
5106 }
5107
5108 var remaining = this.length - offset
5109 if (length === undefined || length > remaining) length = remaining
5110
5111 if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
5112 throw new RangeError('Attempt to write outside buffer bounds')
5113 }
5114
5115 if (!encoding) encoding = 'utf8'
5116
5117 var loweredCase = false
5118 for (;;) {
5119 switch (encoding) {
5120 case 'hex':
5121 return hexWrite(this, string, offset, length)
5122
5123 case 'utf8':
5124 case 'utf-8':
5125 return utf8Write(this, string, offset, length)
5126
5127 case 'ascii':
5128 return asciiWrite(this, string, offset, length)
5129
5130 case 'latin1':
5131 case 'binary':
5132 return latin1Write(this, string, offset, length)
5133
5134 case 'base64':
5135 // Warning: maxLength not taken into account in base64Write
5136 return base64Write(this, string, offset, length)
5137
5138 case 'ucs2':
5139 case 'ucs-2':
5140 case 'utf16le':
5141 case 'utf-16le':
5142 return ucs2Write(this, string, offset, length)
5143
5144 default:
5145 if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
5146 encoding = ('' + encoding).toLowerCase()
5147 loweredCase = true
5148 }
5149 }
5150}
5151
5152Buffer.prototype.toJSON = function toJSON () {
5153 return {
5154 type: 'Buffer',
5155 data: Array.prototype.slice.call(this._arr || this, 0)
5156 }
5157}
5158
5159function base64Slice (buf, start, end) {
5160 if (start === 0 && end === buf.length) {
5161 return base64.fromByteArray(buf)
5162 } else {
5163 return base64.fromByteArray(buf.slice(start, end))
5164 }
5165}
5166
5167function utf8Slice (buf, start, end) {
5168 end = Math.min(buf.length, end)
5169 var res = []
5170
5171 var i = start
5172 while (i < end) {
5173 var firstByte = buf[i]
5174 var codePoint = null
5175 var bytesPerSequence = (firstByte > 0xEF) ? 4
5176 : (firstByte > 0xDF) ? 3
5177 : (firstByte > 0xBF) ? 2
5178 : 1
5179
5180 if (i + bytesPerSequence <= end) {
5181 var secondByte, thirdByte, fourthByte, tempCodePoint
5182
5183 switch (bytesPerSequence) {
5184 case 1:
5185 if (firstByte < 0x80) {
5186 codePoint = firstByte
5187 }
5188 break
5189 case 2:
5190 secondByte = buf[i + 1]
5191 if ((secondByte & 0xC0) === 0x80) {
5192 tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
5193 if (tempCodePoint > 0x7F) {
5194 codePoint = tempCodePoint
5195 }
5196 }
5197 break
5198 case 3:
5199 secondByte = buf[i + 1]
5200 thirdByte = buf[i + 2]
5201 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
5202 tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
5203 if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
5204 codePoint = tempCodePoint
5205 }
5206 }
5207 break
5208 case 4:
5209 secondByte = buf[i + 1]
5210 thirdByte = buf[i + 2]
5211 fourthByte = buf[i + 3]
5212 if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
5213 tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
5214 if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
5215 codePoint = tempCodePoint
5216 }
5217 }
5218 }
5219 }
5220
5221 if (codePoint === null) {
5222 // we did not generate a valid codePoint so insert a
5223 // replacement char (U+FFFD) and advance only 1 byte
5224 codePoint = 0xFFFD
5225 bytesPerSequence = 1
5226 } else if (codePoint > 0xFFFF) {
5227 // encode to utf16 (surrogate pair dance)
5228 codePoint -= 0x10000
5229 res.push(codePoint >>> 10 & 0x3FF | 0xD800)
5230 codePoint = 0xDC00 | codePoint & 0x3FF
5231 }
5232
5233 res.push(codePoint)
5234 i += bytesPerSequence
5235 }
5236
5237 return decodeCodePointsArray(res)
5238}
5239
5240// Based on http://stackoverflow.com/a/22747272/680742, the browser with
5241// the lowest limit is Chrome, with 0x10000 args.
5242// We go 1 magnitude less, for safety
5243var MAX_ARGUMENTS_LENGTH = 0x1000
5244
5245function decodeCodePointsArray (codePoints) {
5246 var len = codePoints.length
5247 if (len <= MAX_ARGUMENTS_LENGTH) {
5248 return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
5249 }
5250
5251 // Decode in chunks to avoid "call stack size exceeded".
5252 var res = ''
5253 var i = 0
5254 while (i < len) {
5255 res += String.fromCharCode.apply(
5256 String,
5257 codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
5258 )
5259 }
5260 return res
5261}
5262
5263function asciiSlice (buf, start, end) {
5264 var ret = ''
5265 end = Math.min(buf.length, end)
5266
5267 for (var i = start; i < end; ++i) {
5268 ret += String.fromCharCode(buf[i] & 0x7F)
5269 }
5270 return ret
5271}
5272
5273function latin1Slice (buf, start, end) {
5274 var ret = ''
5275 end = Math.min(buf.length, end)
5276
5277 for (var i = start; i < end; ++i) {
5278 ret += String.fromCharCode(buf[i])
5279 }
5280 return ret
5281}
5282
5283function hexSlice (buf, start, end) {
5284 var len = buf.length
5285
5286 if (!start || start < 0) start = 0
5287 if (!end || end < 0 || end > len) end = len
5288
5289 var out = ''
5290 for (var i = start; i < end; ++i) {
5291 out += toHex(buf[i])
5292 }
5293 return out
5294}
5295
5296function utf16leSlice (buf, start, end) {
5297 var bytes = buf.slice(start, end)
5298 var res = ''
5299 for (var i = 0; i < bytes.length; i += 2) {
5300 res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
5301 }
5302 return res
5303}
5304
5305Buffer.prototype.slice = function slice (start, end) {
5306 var len = this.length
5307 start = ~~start
5308 end = end === undefined ? len : ~~end
5309
5310 if (start < 0) {
5311 start += len
5312 if (start < 0) start = 0
5313 } else if (start > len) {
5314 start = len
5315 }
5316
5317 if (end < 0) {
5318 end += len
5319 if (end < 0) end = 0
5320 } else if (end > len) {
5321 end = len
5322 }
5323
5324 if (end < start) end = start
5325
5326 var newBuf = this.subarray(start, end)
5327 // Return an augmented `Uint8Array` instance
5328 newBuf.__proto__ = Buffer.prototype
5329 return newBuf
5330}
5331
5332/*
5333 * Need to make sure that buffer isn't trying to write out of bounds.
5334 */
5335function checkOffset (offset, ext, length) {
5336 if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
5337 if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
5338}
5339
5340Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
5341 offset = offset >>> 0
5342 byteLength = byteLength >>> 0
5343 if (!noAssert) checkOffset(offset, byteLength, this.length)
5344
5345 var val = this[offset]
5346 var mul = 1
5347 var i = 0
5348 while (++i < byteLength && (mul *= 0x100)) {
5349 val += this[offset + i] * mul
5350 }
5351
5352 return val
5353}
5354
5355Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
5356 offset = offset >>> 0
5357 byteLength = byteLength >>> 0
5358 if (!noAssert) {
5359 checkOffset(offset, byteLength, this.length)
5360 }
5361
5362 var val = this[offset + --byteLength]
5363 var mul = 1
5364 while (byteLength > 0 && (mul *= 0x100)) {
5365 val += this[offset + --byteLength] * mul
5366 }
5367
5368 return val
5369}
5370
5371Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
5372 offset = offset >>> 0
5373 if (!noAssert) checkOffset(offset, 1, this.length)
5374 return this[offset]
5375}
5376
5377Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
5378 offset = offset >>> 0
5379 if (!noAssert) checkOffset(offset, 2, this.length)
5380 return this[offset] | (this[offset + 1] << 8)
5381}
5382
5383Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
5384 offset = offset >>> 0
5385 if (!noAssert) checkOffset(offset, 2, this.length)
5386 return (this[offset] << 8) | this[offset + 1]
5387}
5388
5389Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
5390 offset = offset >>> 0
5391 if (!noAssert) checkOffset(offset, 4, this.length)
5392
5393 return ((this[offset]) |
5394 (this[offset + 1] << 8) |
5395 (this[offset + 2] << 16)) +
5396 (this[offset + 3] * 0x1000000)
5397}
5398
5399Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
5400 offset = offset >>> 0
5401 if (!noAssert) checkOffset(offset, 4, this.length)
5402
5403 return (this[offset] * 0x1000000) +
5404 ((this[offset + 1] << 16) |
5405 (this[offset + 2] << 8) |
5406 this[offset + 3])
5407}
5408
5409Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
5410 offset = offset >>> 0
5411 byteLength = byteLength >>> 0
5412 if (!noAssert) checkOffset(offset, byteLength, this.length)
5413
5414 var val = this[offset]
5415 var mul = 1
5416 var i = 0
5417 while (++i < byteLength && (mul *= 0x100)) {
5418 val += this[offset + i] * mul
5419 }
5420 mul *= 0x80
5421
5422 if (val >= mul) val -= Math.pow(2, 8 * byteLength)
5423
5424 return val
5425}
5426
5427Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
5428 offset = offset >>> 0
5429 byteLength = byteLength >>> 0
5430 if (!noAssert) checkOffset(offset, byteLength, this.length)
5431
5432 var i = byteLength
5433 var mul = 1
5434 var val = this[offset + --i]
5435 while (i > 0 && (mul *= 0x100)) {
5436 val += this[offset + --i] * mul
5437 }
5438 mul *= 0x80
5439
5440 if (val >= mul) val -= Math.pow(2, 8 * byteLength)
5441
5442 return val
5443}
5444
5445Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
5446 offset = offset >>> 0
5447 if (!noAssert) checkOffset(offset, 1, this.length)
5448 if (!(this[offset] & 0x80)) return (this[offset])
5449 return ((0xff - this[offset] + 1) * -1)
5450}
5451
5452Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
5453 offset = offset >>> 0
5454 if (!noAssert) checkOffset(offset, 2, this.length)
5455 var val = this[offset] | (this[offset + 1] << 8)
5456 return (val & 0x8000) ? val | 0xFFFF0000 : val
5457}
5458
5459Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
5460 offset = offset >>> 0
5461 if (!noAssert) checkOffset(offset, 2, this.length)
5462 var val = this[offset + 1] | (this[offset] << 8)
5463 return (val & 0x8000) ? val | 0xFFFF0000 : val
5464}
5465
5466Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
5467 offset = offset >>> 0
5468 if (!noAssert) checkOffset(offset, 4, this.length)
5469
5470 return (this[offset]) |
5471 (this[offset + 1] << 8) |
5472 (this[offset + 2] << 16) |
5473 (this[offset + 3] << 24)
5474}
5475
5476Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
5477 offset = offset >>> 0
5478 if (!noAssert) checkOffset(offset, 4, this.length)
5479
5480 return (this[offset] << 24) |
5481 (this[offset + 1] << 16) |
5482 (this[offset + 2] << 8) |
5483 (this[offset + 3])
5484}
5485
5486Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
5487 offset = offset >>> 0
5488 if (!noAssert) checkOffset(offset, 4, this.length)
5489 return ieee754.read(this, offset, true, 23, 4)
5490}
5491
5492Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
5493 offset = offset >>> 0
5494 if (!noAssert) checkOffset(offset, 4, this.length)
5495 return ieee754.read(this, offset, false, 23, 4)
5496}
5497
5498Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
5499 offset = offset >>> 0
5500 if (!noAssert) checkOffset(offset, 8, this.length)
5501 return ieee754.read(this, offset, true, 52, 8)
5502}
5503
5504Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
5505 offset = offset >>> 0
5506 if (!noAssert) checkOffset(offset, 8, this.length)
5507 return ieee754.read(this, offset, false, 52, 8)
5508}
5509
5510function checkInt (buf, value, offset, ext, max, min) {
5511 if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
5512 if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
5513 if (offset + ext > buf.length) throw new RangeError('Index out of range')
5514}
5515
5516Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
5517 value = +value
5518 offset = offset >>> 0
5519 byteLength = byteLength >>> 0
5520 if (!noAssert) {
5521 var maxBytes = Math.pow(2, 8 * byteLength) - 1
5522 checkInt(this, value, offset, byteLength, maxBytes, 0)
5523 }
5524
5525 var mul = 1
5526 var i = 0
5527 this[offset] = value & 0xFF
5528 while (++i < byteLength && (mul *= 0x100)) {
5529 this[offset + i] = (value / mul) & 0xFF
5530 }
5531
5532 return offset + byteLength
5533}
5534
5535Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
5536 value = +value
5537 offset = offset >>> 0
5538 byteLength = byteLength >>> 0
5539 if (!noAssert) {
5540 var maxBytes = Math.pow(2, 8 * byteLength) - 1
5541 checkInt(this, value, offset, byteLength, maxBytes, 0)
5542 }
5543
5544 var i = byteLength - 1
5545 var mul = 1
5546 this[offset + i] = value & 0xFF
5547 while (--i >= 0 && (mul *= 0x100)) {
5548 this[offset + i] = (value / mul) & 0xFF
5549 }
5550
5551 return offset + byteLength
5552}
5553
5554Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
5555 value = +value
5556 offset = offset >>> 0
5557 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
5558 this[offset] = (value & 0xff)
5559 return offset + 1
5560}
5561
5562Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
5563 value = +value
5564 offset = offset >>> 0
5565 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
5566 this[offset] = (value & 0xff)
5567 this[offset + 1] = (value >>> 8)
5568 return offset + 2
5569}
5570
5571Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
5572 value = +value
5573 offset = offset >>> 0
5574 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
5575 this[offset] = (value >>> 8)
5576 this[offset + 1] = (value & 0xff)
5577 return offset + 2
5578}
5579
5580Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
5581 value = +value
5582 offset = offset >>> 0
5583 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
5584 this[offset + 3] = (value >>> 24)
5585 this[offset + 2] = (value >>> 16)
5586 this[offset + 1] = (value >>> 8)
5587 this[offset] = (value & 0xff)
5588 return offset + 4
5589}
5590
5591Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
5592 value = +value
5593 offset = offset >>> 0
5594 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
5595 this[offset] = (value >>> 24)
5596 this[offset + 1] = (value >>> 16)
5597 this[offset + 2] = (value >>> 8)
5598 this[offset + 3] = (value & 0xff)
5599 return offset + 4
5600}
5601
5602Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
5603 value = +value
5604 offset = offset >>> 0
5605 if (!noAssert) {
5606 var limit = Math.pow(2, (8 * byteLength) - 1)
5607
5608 checkInt(this, value, offset, byteLength, limit - 1, -limit)
5609 }
5610
5611 var i = 0
5612 var mul = 1
5613 var sub = 0
5614 this[offset] = value & 0xFF
5615 while (++i < byteLength && (mul *= 0x100)) {
5616 if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
5617 sub = 1
5618 }
5619 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
5620 }
5621
5622 return offset + byteLength
5623}
5624
5625Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
5626 value = +value
5627 offset = offset >>> 0
5628 if (!noAssert) {
5629 var limit = Math.pow(2, (8 * byteLength) - 1)
5630
5631 checkInt(this, value, offset, byteLength, limit - 1, -limit)
5632 }
5633
5634 var i = byteLength - 1
5635 var mul = 1
5636 var sub = 0
5637 this[offset + i] = value & 0xFF
5638 while (--i >= 0 && (mul *= 0x100)) {
5639 if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
5640 sub = 1
5641 }
5642 this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
5643 }
5644
5645 return offset + byteLength
5646}
5647
5648Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
5649 value = +value
5650 offset = offset >>> 0
5651 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
5652 if (value < 0) value = 0xff + value + 1
5653 this[offset] = (value & 0xff)
5654 return offset + 1
5655}
5656
5657Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
5658 value = +value
5659 offset = offset >>> 0
5660 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
5661 this[offset] = (value & 0xff)
5662 this[offset + 1] = (value >>> 8)
5663 return offset + 2
5664}
5665
5666Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
5667 value = +value
5668 offset = offset >>> 0
5669 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
5670 this[offset] = (value >>> 8)
5671 this[offset + 1] = (value & 0xff)
5672 return offset + 2
5673}
5674
5675Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
5676 value = +value
5677 offset = offset >>> 0
5678 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
5679 this[offset] = (value & 0xff)
5680 this[offset + 1] = (value >>> 8)
5681 this[offset + 2] = (value >>> 16)
5682 this[offset + 3] = (value >>> 24)
5683 return offset + 4
5684}
5685
5686Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
5687 value = +value
5688 offset = offset >>> 0
5689 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
5690 if (value < 0) value = 0xffffffff + value + 1
5691 this[offset] = (value >>> 24)
5692 this[offset + 1] = (value >>> 16)
5693 this[offset + 2] = (value >>> 8)
5694 this[offset + 3] = (value & 0xff)
5695 return offset + 4
5696}
5697
5698function checkIEEE754 (buf, value, offset, ext, max, min) {
5699 if (offset + ext > buf.length) throw new RangeError('Index out of range')
5700 if (offset < 0) throw new RangeError('Index out of range')
5701}
5702
5703function writeFloat (buf, value, offset, littleEndian, noAssert) {
5704 value = +value
5705 offset = offset >>> 0
5706 if (!noAssert) {
5707 checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
5708 }
5709 ieee754.write(buf, value, offset, littleEndian, 23, 4)
5710 return offset + 4
5711}
5712
5713Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
5714 return writeFloat(this, value, offset, true, noAssert)
5715}
5716
5717Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
5718 return writeFloat(this, value, offset, false, noAssert)
5719}
5720
5721function writeDouble (buf, value, offset, littleEndian, noAssert) {
5722 value = +value
5723 offset = offset >>> 0
5724 if (!noAssert) {
5725 checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
5726 }
5727 ieee754.write(buf, value, offset, littleEndian, 52, 8)
5728 return offset + 8
5729}
5730
5731Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
5732 return writeDouble(this, value, offset, true, noAssert)
5733}
5734
5735Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
5736 return writeDouble(this, value, offset, false, noAssert)
5737}
5738
5739// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
5740Buffer.prototype.copy = function copy (target, targetStart, start, end) {
5741 if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
5742 if (!start) start = 0
5743 if (!end && end !== 0) end = this.length
5744 if (targetStart >= target.length) targetStart = target.length
5745 if (!targetStart) targetStart = 0
5746 if (end > 0 && end < start) end = start
5747
5748 // Copy 0 bytes; we're done
5749 if (end === start) return 0
5750 if (target.length === 0 || this.length === 0) return 0
5751
5752 // Fatal error conditions
5753 if (targetStart < 0) {
5754 throw new RangeError('targetStart out of bounds')
5755 }
5756 if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
5757 if (end < 0) throw new RangeError('sourceEnd out of bounds')
5758
5759 // Are we oob?
5760 if (end > this.length) end = this.length
5761 if (target.length - targetStart < end - start) {
5762 end = target.length - targetStart + start
5763 }
5764
5765 var len = end - start
5766
5767 if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
5768 // Use built-in when available, missing from IE11
5769 this.copyWithin(targetStart, start, end)
5770 } else if (this === target && start < targetStart && targetStart < end) {
5771 // descending copy from end
5772 for (var i = len - 1; i >= 0; --i) {
5773 target[i + targetStart] = this[i + start]
5774 }
5775 } else {
5776 Uint8Array.prototype.set.call(
5777 target,
5778 this.subarray(start, end),
5779 targetStart
5780 )
5781 }
5782
5783 return len
5784}
5785
5786// Usage:
5787// buffer.fill(number[, offset[, end]])
5788// buffer.fill(buffer[, offset[, end]])
5789// buffer.fill(string[, offset[, end]][, encoding])
5790Buffer.prototype.fill = function fill (val, start, end, encoding) {
5791 // Handle string cases:
5792 if (typeof val === 'string') {
5793 if (typeof start === 'string') {
5794 encoding = start
5795 start = 0
5796 end = this.length
5797 } else if (typeof end === 'string') {
5798 encoding = end
5799 end = this.length
5800 }
5801 if (encoding !== undefined && typeof encoding !== 'string') {
5802 throw new TypeError('encoding must be a string')
5803 }
5804 if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
5805 throw new TypeError('Unknown encoding: ' + encoding)
5806 }
5807 if (val.length === 1) {
5808 var code = val.charCodeAt(0)
5809 if ((encoding === 'utf8' && code < 128) ||
5810 encoding === 'latin1') {
5811 // Fast path: If `val` fits into a single byte, use that numeric value.
5812 val = code
5813 }
5814 }
5815 } else if (typeof val === 'number') {
5816 val = val & 255
5817 }
5818
5819 // Invalid ranges are not set to a default, so can range check early.
5820 if (start < 0 || this.length < start || this.length < end) {
5821 throw new RangeError('Out of range index')
5822 }
5823
5824 if (end <= start) {
5825 return this
5826 }
5827
5828 start = start >>> 0
5829 end = end === undefined ? this.length : end >>> 0
5830
5831 if (!val) val = 0
5832
5833 var i
5834 if (typeof val === 'number') {
5835 for (i = start; i < end; ++i) {
5836 this[i] = val
5837 }
5838 } else {
5839 var bytes = Buffer.isBuffer(val)
5840 ? val
5841 : Buffer.from(val, encoding)
5842 var len = bytes.length
5843 if (len === 0) {
5844 throw new TypeError('The value "' + val +
5845 '" is invalid for argument "value"')
5846 }
5847 for (i = 0; i < end - start; ++i) {
5848 this[i + start] = bytes[i % len]
5849 }
5850 }
5851
5852 return this
5853}
5854
5855// HELPER FUNCTIONS
5856// ================
5857
5858var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
5859
5860function base64clean (str) {
5861 // Node takes equal signs as end of the Base64 encoding
5862 str = str.split('=')[0]
5863 // Node strips out invalid characters like \n and \t from the string, base64-js does not
5864 str = str.trim().replace(INVALID_BASE64_RE, '')
5865 // Node converts strings with length < 2 to ''
5866 if (str.length < 2) return ''
5867 // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
5868 while (str.length % 4 !== 0) {
5869 str = str + '='
5870 }
5871 return str
5872}
5873
5874function toHex (n) {
5875 if (n < 16) return '0' + n.toString(16)
5876 return n.toString(16)
5877}
5878
5879function utf8ToBytes (string, units) {
5880 units = units || Infinity
5881 var codePoint
5882 var length = string.length
5883 var leadSurrogate = null
5884 var bytes = []
5885
5886 for (var i = 0; i < length; ++i) {
5887 codePoint = string.charCodeAt(i)
5888
5889 // is surrogate component
5890 if (codePoint > 0xD7FF && codePoint < 0xE000) {
5891 // last char was a lead
5892 if (!leadSurrogate) {
5893 // no lead yet
5894 if (codePoint > 0xDBFF) {
5895 // unexpected trail
5896 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
5897 continue
5898 } else if (i + 1 === length) {
5899 // unpaired lead
5900 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
5901 continue
5902 }
5903
5904 // valid lead
5905 leadSurrogate = codePoint
5906
5907 continue
5908 }
5909
5910 // 2 leads in a row
5911 if (codePoint < 0xDC00) {
5912 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
5913 leadSurrogate = codePoint
5914 continue
5915 }
5916
5917 // valid surrogate pair
5918 codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
5919 } else if (leadSurrogate) {
5920 // valid bmp char, but last char was a lead
5921 if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
5922 }
5923
5924 leadSurrogate = null
5925
5926 // encode utf8
5927 if (codePoint < 0x80) {
5928 if ((units -= 1) < 0) break
5929 bytes.push(codePoint)
5930 } else if (codePoint < 0x800) {
5931 if ((units -= 2) < 0) break
5932 bytes.push(
5933 codePoint >> 0x6 | 0xC0,
5934 codePoint & 0x3F | 0x80
5935 )
5936 } else if (codePoint < 0x10000) {
5937 if ((units -= 3) < 0) break
5938 bytes.push(
5939 codePoint >> 0xC | 0xE0,
5940 codePoint >> 0x6 & 0x3F | 0x80,
5941 codePoint & 0x3F | 0x80
5942 )
5943 } else if (codePoint < 0x110000) {
5944 if ((units -= 4) < 0) break
5945 bytes.push(
5946 codePoint >> 0x12 | 0xF0,
5947 codePoint >> 0xC & 0x3F | 0x80,
5948 codePoint >> 0x6 & 0x3F | 0x80,
5949 codePoint & 0x3F | 0x80
5950 )
5951 } else {
5952 throw new Error('Invalid code point')
5953 }
5954 }
5955
5956 return bytes
5957}
5958
5959function asciiToBytes (str) {
5960 var byteArray = []
5961 for (var i = 0; i < str.length; ++i) {
5962 // Node's code seems to be doing this and not & 0x7F..
5963 byteArray.push(str.charCodeAt(i) & 0xFF)
5964 }
5965 return byteArray
5966}
5967
5968function utf16leToBytes (str, units) {
5969 var c, hi, lo
5970 var byteArray = []
5971 for (var i = 0; i < str.length; ++i) {
5972 if ((units -= 2) < 0) break
5973
5974 c = str.charCodeAt(i)
5975 hi = c >> 8
5976 lo = c % 256
5977 byteArray.push(lo)
5978 byteArray.push(hi)
5979 }
5980
5981 return byteArray
5982}
5983
5984function base64ToBytes (str) {
5985 return base64.toByteArray(base64clean(str))
5986}
5987
5988function blitBuffer (src, dst, offset, length) {
5989 for (var i = 0; i < length; ++i) {
5990 if ((i + offset >= dst.length) || (i >= src.length)) break
5991 dst[i + offset] = src[i]
5992 }
5993 return i
5994}
5995
5996// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
5997// the `instanceof` check but they should be treated as of that type.
5998// See: https://github.com/feross/buffer/issues/166
5999function isInstance (obj, type) {
6000 return obj instanceof type ||
6001 (obj != null && obj.constructor != null && obj.constructor.name != null &&
6002 obj.constructor.name === type.name)
6003}
6004function numberIsNaN (obj) {
6005 // For IE11 support
6006 return obj !== obj // eslint-disable-line no-self-compare
6007}
6008
6009},{"base64-js":46,"ieee754":50}],48:[function(require,module,exports){
6010'use strict'
6011
6012var hasCaptureStackTrace = 'captureStackTrace' in Error
6013
6014module.exports = errorClass
6015
6016
6017function errorClass (name) {
6018 var ErrorClass
6019
6020 if (!name || typeof name !== 'string')
6021 throw new TypeError('Argument "name" must be a non-empty string.')
6022
6023 // This is basically `eval`, there's no other way to dynamically define a
6024 // function name.
6025 ErrorClass = function CustomError () {
6026 if (!(this instanceof CustomError))
6027 return new (CustomError.bind.apply(CustomError,
6028 Array.prototype.concat.apply([ null ], arguments)))
6029 setupError.apply(this, arguments)
6030 }
6031
6032 ErrorClass.prototype = Object.create(Error.prototype, {
6033 constructor: nonEnumerableProperty(ErrorClass),
6034 name: nonEnumerableProperty(name)
6035 })
6036
6037 return ErrorClass
6038}
6039
6040
6041// Internal function to set up an error.
6042function setupError (message) {
6043 if (hasCaptureStackTrace)
6044 // V8 specific method.
6045 Error.captureStackTrace(this, this.constructor)
6046 else
6047 // Generic way to set the error stack trace.
6048 Object.defineProperty(this, 'stack',
6049 nonEnumerableProperty(Error(message).stack))
6050
6051 // Use the `+` operator with an empty string to implicitly type cast the
6052 // `message` argument into a string.
6053 Object.defineProperty(this, 'message',
6054 nonEnumerableProperty(message !== void 0 ? '' + message : ''))
6055}
6056
6057
6058function nonEnumerableProperty (value) {
6059 // The field `enumerable` is `false` by default.
6060 return {
6061 value: value,
6062 writable: true,
6063 configurable: true
6064 }
6065}
6066
6067},{}],49:[function(require,module,exports){
6068/**
6069 * event-lite.js - Light-weight EventEmitter (less than 1KB when gzipped)
6070 *
6071 * @copyright Yusuke Kawasaki
6072 * @license MIT
6073 * @constructor
6074 * @see https://github.com/kawanet/event-lite
6075 * @see http://kawanet.github.io/event-lite/EventLite.html
6076 * @example
6077 * var EventLite = require("event-lite");
6078 *
6079 * function MyClass() {...} // your class
6080 *
6081 * EventLite.mixin(MyClass.prototype); // import event methods
6082 *
6083 * var obj = new MyClass();
6084 * obj.on("foo", function() {...}); // add event listener
6085 * obj.once("bar", function() {...}); // add one-time event listener
6086 * obj.emit("foo"); // dispatch event
6087 * obj.emit("bar"); // dispatch another event
6088 * obj.off("foo"); // remove event listener
6089 */
6090
6091function EventLite() {
6092 if (!(this instanceof EventLite)) return new EventLite();
6093}
6094
6095(function(EventLite) {
6096 // export the class for node.js
6097 if ("undefined" !== typeof module) module.exports = EventLite;
6098
6099 // property name to hold listeners
6100 var LISTENERS = "listeners";
6101
6102 // methods to export
6103 var methods = {
6104 on: on,
6105 once: once,
6106 off: off,
6107 emit: emit
6108 };
6109
6110 // mixin to self
6111 mixin(EventLite.prototype);
6112
6113 // export mixin function
6114 EventLite.mixin = mixin;
6115
6116 /**
6117 * Import on(), once(), off() and emit() methods into target object.
6118 *
6119 * @function EventLite.mixin
6120 * @param target {Prototype}
6121 */
6122
6123 function mixin(target) {
6124 for (var key in methods) {
6125 target[key] = methods[key];
6126 }
6127 return target;
6128 }
6129
6130 /**
6131 * Add an event listener.
6132 *
6133 * @function EventLite.prototype.on
6134 * @param type {string}
6135 * @param func {Function}
6136 * @returns {EventLite} Self for method chaining
6137 */
6138
6139 function on(type, func) {
6140 getListeners(this, type).push(func);
6141 return this;
6142 }
6143
6144 /**
6145 * Add one-time event listener.
6146 *
6147 * @function EventLite.prototype.once
6148 * @param type {string}
6149 * @param func {Function}
6150 * @returns {EventLite} Self for method chaining
6151 */
6152
6153 function once(type, func) {
6154 var that = this;
6155 wrap.originalListener = func;
6156 getListeners(that, type).push(wrap);
6157 return that;
6158
6159 function wrap() {
6160 off.call(that, type, wrap);
6161 func.apply(this, arguments);
6162 }
6163 }
6164
6165 /**
6166 * Remove an event listener.
6167 *
6168 * @function EventLite.prototype.off
6169 * @param [type] {string}
6170 * @param [func] {Function}
6171 * @returns {EventLite} Self for method chaining
6172 */
6173
6174 function off(type, func) {
6175 var that = this;
6176 var listners;
6177 if (!arguments.length) {
6178 delete that[LISTENERS];
6179 } else if (!func) {
6180 listners = that[LISTENERS];
6181 if (listners) {
6182 delete listners[type];
6183 if (!Object.keys(listners).length) return off.call(that);
6184 }
6185 } else {
6186 listners = getListeners(that, type, true);
6187 if (listners) {
6188 listners = listners.filter(ne);
6189 if (!listners.length) return off.call(that, type);
6190 that[LISTENERS][type] = listners;
6191 }
6192 }
6193 return that;
6194
6195 function ne(test) {
6196 return test !== func && test.originalListener !== func;
6197 }
6198 }
6199
6200 /**
6201 * Dispatch (trigger) an event.
6202 *
6203 * @function EventLite.prototype.emit
6204 * @param type {string}
6205 * @param [value] {*}
6206 * @returns {boolean} True when a listener received the event
6207 */
6208
6209 function emit(type, value) {
6210 var that = this;
6211 var listeners = getListeners(that, type, true);
6212 if (!listeners) return false;
6213 var arglen = arguments.length;
6214 if (arglen === 1) {
6215 listeners.forEach(zeroarg);
6216 } else if (arglen === 2) {
6217 listeners.forEach(onearg);
6218 } else {
6219 var args = Array.prototype.slice.call(arguments, 1);
6220 listeners.forEach(moreargs);
6221 }
6222 return !!listeners.length;
6223
6224 function zeroarg(func) {
6225 func.call(that);
6226 }
6227
6228 function onearg(func) {
6229 func.call(that, value);
6230 }
6231
6232 function moreargs(func) {
6233 func.apply(that, args);
6234 }
6235 }
6236
6237 /**
6238 * @ignore
6239 */
6240
6241 function getListeners(that, type, readonly) {
6242 if (readonly && !that[LISTENERS]) return;
6243 var listeners = that[LISTENERS] || (that[LISTENERS] = {});
6244 return listeners[type] || (listeners[type] = []);
6245 }
6246
6247})(EventLite);
6248
6249},{}],50:[function(require,module,exports){
6250exports.read = function (buffer, offset, isLE, mLen, nBytes) {
6251 var e, m
6252 var eLen = nBytes * 8 - mLen - 1
6253 var eMax = (1 << eLen) - 1
6254 var eBias = eMax >> 1
6255 var nBits = -7
6256 var i = isLE ? (nBytes - 1) : 0
6257 var d = isLE ? -1 : 1
6258 var s = buffer[offset + i]
6259
6260 i += d
6261
6262 e = s & ((1 << (-nBits)) - 1)
6263 s >>= (-nBits)
6264 nBits += eLen
6265 for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
6266
6267 m = e & ((1 << (-nBits)) - 1)
6268 e >>= (-nBits)
6269 nBits += mLen
6270 for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
6271
6272 if (e === 0) {
6273 e = 1 - eBias
6274 } else if (e === eMax) {
6275 return m ? NaN : ((s ? -1 : 1) * Infinity)
6276 } else {
6277 m = m + Math.pow(2, mLen)
6278 e = e - eBias
6279 }
6280 return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
6281}
6282
6283exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
6284 var e, m, c
6285 var eLen = nBytes * 8 - mLen - 1
6286 var eMax = (1 << eLen) - 1
6287 var eBias = eMax >> 1
6288 var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
6289 var i = isLE ? 0 : (nBytes - 1)
6290 var d = isLE ? 1 : -1
6291 var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
6292
6293 value = Math.abs(value)
6294
6295 if (isNaN(value) || value === Infinity) {
6296 m = isNaN(value) ? 1 : 0
6297 e = eMax
6298 } else {
6299 e = Math.floor(Math.log(value) / Math.LN2)
6300 if (value * (c = Math.pow(2, -e)) < 1) {
6301 e--
6302 c *= 2
6303 }
6304 if (e + eBias >= 1) {
6305 value += rt / c
6306 } else {
6307 value += rt * Math.pow(2, 1 - eBias)
6308 }
6309 if (value * c >= 2) {
6310 e++
6311 c /= 2
6312 }
6313
6314 if (e + eBias >= eMax) {
6315 m = 0
6316 e = eMax
6317 } else if (e + eBias >= 1) {
6318 m = (value * c - 1) * Math.pow(2, mLen)
6319 e = e + eBias
6320 } else {
6321 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
6322 e = 0
6323 }
6324 }
6325
6326 for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
6327
6328 e = (e << mLen) | m
6329 eLen += mLen
6330 for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
6331
6332 buffer[offset + i - d] |= s * 128
6333}
6334
6335},{}],51:[function(require,module,exports){
6336/*!
6337 * Determine if an object is a Buffer
6338 *
6339 * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
6340 * @license MIT
6341 */
6342
6343// The _isBuffer check is for Safari 5-7 support, because it's missing
6344// Object.prototype.constructor. Remove this eventually
6345module.exports = function (obj) {
6346 return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
6347}
6348
6349function isBuffer (obj) {
6350 return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
6351}
6352
6353// For Node v0.10 support. Remove this eventually.
6354function isSlowBuffer (obj) {
6355 return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
6356}
6357
6358},{}]},{},[31]);