Skip to content
Snippets Groups Projects
index.js 8.75 MiB
Newer Older
  • Learn to ignore specific revisions
  •     function validate(props, propName, componentName, location, propFullName) {
          var propValue = props[propName];
          if (!isValidElement(propValue)) {
            var propType = getPropType(propValue);
            return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));
          }
          return null;
        }
        return createChainableTypeChecker(validate);
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      function createElementTypeTypeChecker() {
        function validate(props, propName, componentName, location, propFullName) {
          var propValue = props[propName];
          if (!ReactIs.isValidElementType(propValue)) {
            var propType = getPropType(propValue);
            return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.'));
          }
          return null;
        }
        return createChainableTypeChecker(validate);
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      function createInstanceTypeChecker(expectedClass) {
        function validate(props, propName, componentName, location, propFullName) {
          if (!(props[propName] instanceof expectedClass)) {
            var expectedClassName = expectedClass.name || ANONYMOUS;
            var actualClassName = getClassName(props[propName]);
            return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));
          }
          return null;
        }
        return createChainableTypeChecker(validate);
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      function createEnumTypeChecker(expectedValues) {
        if (!Array.isArray(expectedValues)) {
          if (true) {
            if (arguments.length > 1) {
              printWarning(
                'Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' +
                'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).'
              );
            } else {
              printWarning('Invalid argument supplied to oneOf, expected an array.');
    
    Romain CREY's avatar
    Romain CREY committed
            }
          }
    
          return emptyFunctionThatReturnsNull;
    
    Romain CREY's avatar
    Romain CREY committed
        }
    
    
        function validate(props, propName, componentName, location, propFullName) {
          var propValue = props[propName];
          for (var i = 0; i < expectedValues.length; i++) {
            if (is(propValue, expectedValues[i])) {
              return null;
            }
          }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
          var valuesString = JSON.stringify(expectedValues, function replacer(key, value) {
            var type = getPreciseType(value);
            if (type === 'symbol') {
              return String(value);
            }
            return value;
          });
          return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));
        }
        return createChainableTypeChecker(validate);
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      function createObjectOfTypeChecker(typeChecker) {
        function validate(props, propName, componentName, location, propFullName) {
          if (typeof typeChecker !== 'function') {
            return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');
          }
          var propValue = props[propName];
          var propType = getPropType(propValue);
          if (propType !== 'object') {
            return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));
          }
          for (var key in propValue) {
            if (has(propValue, key)) {
              var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
              if (error instanceof Error) {
                return error;
              }
            }
          }
          return null;
        }
        return createChainableTypeChecker(validate);
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      function createUnionTypeChecker(arrayOfTypeCheckers) {
        if (!Array.isArray(arrayOfTypeCheckers)) {
           true ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : undefined;
          return emptyFunctionThatReturnsNull;
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
          var checker = arrayOfTypeCheckers[i];
          if (typeof checker !== 'function') {
            printWarning(
              'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' +
              'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.'
            );
            return emptyFunctionThatReturnsNull;
          }
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        function validate(props, propName, componentName, location, propFullName) {
          for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
            var checker = arrayOfTypeCheckers[i];
            if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) {
              return null;
            }
          }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
          return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.'));
        }
        return createChainableTypeChecker(validate);
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      function createNodeChecker() {
        function validate(props, propName, componentName, location, propFullName) {
          if (!isNode(props[propName])) {
            return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));
          }
          return null;
        }
        return createChainableTypeChecker(validate);
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      function createShapeTypeChecker(shapeTypes) {
        function validate(props, propName, componentName, location, propFullName) {
          var propValue = props[propName];
          var propType = getPropType(propValue);
          if (propType !== 'object') {
            return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
          }
          for (var key in shapeTypes) {
            var checker = shapeTypes[key];
            if (!checker) {
              continue;
            }
            var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
            if (error) {
              return error;
            }
          }
          return null;
        }
        return createChainableTypeChecker(validate);
      }
    
      function createStrictShapeTypeChecker(shapeTypes) {
        function validate(props, propName, componentName, location, propFullName) {
          var propValue = props[propName];
          var propType = getPropType(propValue);
          if (propType !== 'object') {
            return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));
          }
          // We need to check all keys in case some are required but missing from
          // props.
          var allKeys = assign({}, props[propName], shapeTypes);
          for (var key in allKeys) {
            var checker = shapeTypes[key];
            if (!checker) {
              return new PropTypeError(
                'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' +
                '\nBad object: ' + JSON.stringify(props[propName], null, '  ') +
                '\nValid keys: ' +  JSON.stringify(Object.keys(shapeTypes), null, '  ')
              );
            }
            var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);
            if (error) {
              return error;
            }
          }
          return null;
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        return createChainableTypeChecker(validate);
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      function isNode(propValue) {
        switch (typeof propValue) {
          case 'number':
          case 'string':
          case 'undefined':
            return true;
          case 'boolean':
            return !propValue;
          case 'object':
            if (Array.isArray(propValue)) {
              return propValue.every(isNode);
            }
            if (propValue === null || isValidElement(propValue)) {
              return true;
            }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
            var iteratorFn = getIteratorFn(propValue);
            if (iteratorFn) {
              var iterator = iteratorFn.call(propValue);
              var step;
              if (iteratorFn !== propValue.entries) {
                while (!(step = iterator.next()).done) {
                  if (!isNode(step.value)) {
                    return false;
                  }
                }
              } else {
                // Iterator will provide entry [k,v] tuples rather than values.
                while (!(step = iterator.next()).done) {
                  var entry = step.value;
                  if (entry) {
                    if (!isNode(entry[1])) {
                      return false;
                    }
                  }
                }
              }
            } else {
              return false;
            }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      function isSymbol(propType, propValue) {
        // Native Symbol.
        if (propType === 'symbol') {
          return true;
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        // falsy value can't be a Symbol
        if (!propValue) {
          return false;
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
        if (propValue['@@toStringTag'] === 'Symbol') {
          return true;
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        // Fallback for non-spec compliant Symbols which are polyfilled.
        if (typeof Symbol === 'function' && propValue instanceof Symbol) {
          return true;
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      // Equivalent of `typeof` but with special handling for array and regexp.
      function getPropType(propValue) {
        var propType = typeof propValue;
        if (Array.isArray(propValue)) {
          return 'array';
        }
        if (propValue instanceof RegExp) {
          // Old webkits (at least until Android 4.0) return 'function' rather than
          // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
          // passes PropTypes.object.
          return 'object';
    
    Romain CREY's avatar
    Romain CREY committed
        }
    
        if (isSymbol(propType, propValue)) {
          return 'symbol';
        }
        return propType;
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      // This handles more types than `getPropType`. Only used for error messages.
      // See `createPrimitiveTypeChecker`.
      function getPreciseType(propValue) {
        if (typeof propValue === 'undefined' || propValue === null) {
          return '' + propValue;
        }
        var propType = getPropType(propValue);
        if (propType === 'object') {
          if (propValue instanceof Date) {
            return 'date';
          } else if (propValue instanceof RegExp) {
            return 'regexp';
          }
        }
        return propType;
      }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      // Returns a string that is postfixed to a warning about an invalid type.
      // For example, "undefined" or "of type array"
      function getPostfixForTypeWarning(value) {
        var type = getPreciseType(value);
        switch (type) {
          case 'array':
          case 'object':
            return 'an ' + type;
          case 'boolean':
          case 'date':
          case 'regexp':
            return 'a ' + type;
          default:
            return type;
    
    Romain CREY's avatar
    Romain CREY committed
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      // Returns class name of the object, if any.
      function getClassName(propValue) {
        if (!propValue.constructor || !propValue.constructor.name) {
          return ANONYMOUS;
    
    Romain CREY's avatar
    Romain CREY committed
        }
    
        return propValue.constructor.name;
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      ReactPropTypes.checkPropTypes = checkPropTypes;
      ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache;
      ReactPropTypes.PropTypes = ReactPropTypes;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      return ReactPropTypes;
    };
    
    /***/ }),
    /* 1598 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    "use strict";
    /*
    object-assign
    (c) Sindre Sorhus
    @license MIT
    */
    
    /* eslint-disable no-unused-vars */
    var getOwnPropertySymbols = Object.getOwnPropertySymbols;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    var propIsEnumerable = Object.prototype.propertyIsEnumerable;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    function toObject(val) {
    	if (val === null || val === undefined) {
    		throw new TypeError('Object.assign cannot be called with null or undefined');
    	}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    function shouldUseNative() {
    	try {
    		if (!Object.assign) {
    			return false;
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// Detect buggy property enumeration order in older V8 versions.
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// https://bugs.chromium.org/p/v8/issues/detail?id=4118
    		var test1 = new String('abc');  // eslint-disable-line no-new-wrappers
    		test1[5] = 'de';
    		if (Object.getOwnPropertyNames(test1)[0] === '5') {
    			return false;
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// https://bugs.chromium.org/p/v8/issues/detail?id=3056
    		var test2 = {};
    		for (var i = 0; i < 10; i++) {
    			test2['_' + String.fromCharCode(i)] = i;
    		}
    		var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
    			return test2[n];
    		});
    		if (order2.join('') !== '0123456789') {
    			return false;
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		// https://bugs.chromium.org/p/v8/issues/detail?id=3056
    		var test3 = {};
    		'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
    			test3[letter] = letter;
    		});
    		if (Object.keys(Object.assign({}, test3)).join('') !==
    				'abcdefghijklmnopqrst') {
    			return false;
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		return true;
    	} catch (err) {
    		// We don't expect any of the above to throw, but better to be safe.
    		return false;
    	}
    }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = shouldUseNative() ? Object.assign : function (target, source) {
    	var from;
    	var to = toObject(target);
    	var symbols;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    	for (var s = 1; s < arguments.length; s++) {
    		from = Object(arguments[s]);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		for (var key in from) {
    			if (hasOwnProperty.call(from, key)) {
    				to[key] = from[key];
    			}
    		}
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    		if (getOwnPropertySymbols) {
    			symbols = getOwnPropertySymbols(from);
    			for (var i = 0; i < symbols.length; i++) {
    				if (propIsEnumerable.call(from, symbols[i])) {
    					to[symbols[i]] = from[symbols[i]];
    				}
    			}
    		}
    	}
    
    	return to;
    };
    
    /***/ }),
    /* 1599 */
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    Romain CREY's avatar
    Romain CREY committed
    /**
    
     * Copyright (c) 2013-present, Facebook, Inc.
    
    Romain CREY's avatar
    Romain CREY committed
     *
    
     * This source code is licensed under the MIT license found in the
     * LICENSE file in the root directory of this source tree.
    
    Romain CREY's avatar
    Romain CREY committed
     */
    
    
    
    
    var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
    
    module.exports = ReactPropTypesSecret;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    /**
     * Copyright (c) 2013-present, Facebook, Inc.
     *
     * This source code is licensed under the MIT license found in the
     * LICENSE file in the root directory of this source tree.
     */
    
    var printWarning = function() {};
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    if (true) {
      var ReactPropTypesSecret = __webpack_require__(1599);
      var loggedTypeFailures = {};
      var has = Function.call.bind(Object.prototype.hasOwnProperty);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      printWarning = function(text) {
        var message = 'Warning: ' + text;
        if (typeof console !== 'undefined') {
          console.error(message);
        }
        try {
          // --- Welcome to debugging React ---
          // This error was thrown as a convenience so that you can use this stack
          // to find the callsite that caused this warning to fire.
          throw new Error(message);
        } catch (x) {}
      };
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    /**
     * Assert that the values match with the type specs.
     * Error messages are memorized and will only be shown once.
     *
     * @param {object} typeSpecs Map of name to a ReactPropType
     * @param {object} values Runtime values that need to be type-checked
     * @param {string} location e.g. "prop", "context", "child context"
     * @param {string} componentName Name of the component for error messages.
     * @param {?Function} getStack Returns the component stack.
     * @private
     */
    function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
      if (true) {
        for (var typeSpecName in typeSpecs) {
          if (has(typeSpecs, typeSpecName)) {
            var error;
            // Prop type validation may throw. In case they do, we don't want to
            // fail the render phase where it didn't fail before. So we log it.
            // After these have been cleaned up, we'll let them throw.
            try {
              // This is intentionally an invariant that gets caught. It's the same
              // behavior as without this statement except with a better message.
              if (typeof typeSpecs[typeSpecName] !== 'function') {
                var err = Error(
                  (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
                  'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
                );
                err.name = 'Invariant Violation';
                throw err;
              }
              error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
            } catch (ex) {
              error = ex;
            }
            if (error && !(error instanceof Error)) {
              printWarning(
                (componentName || 'React class') + ': type specification of ' +
                location + ' `' + typeSpecName + '` is invalid; the type checker ' +
                'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
                'You may have forgotten to pass an argument to the type checker ' +
                'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
                'shape all require an argument).'
              );
            }
            if (error instanceof Error && !(error.message in loggedTypeFailures)) {
              // Only monitor this failure once because there tends to be a lot of the
              // same error.
              loggedTypeFailures[error.message] = true;
    
              var stack = getStack ? getStack() : '';
    
    Romain CREY's avatar
    Romain CREY committed
    
    
              printWarning(
                'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
              );
            }
          }
        }
      }
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    /**
     * Resets warning cache when testing.
     *
     * @private
     */
    checkPropTypes.resetWarningCache = function() {
      if (true) {
        loggedTypeFailures = {};
      }
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    module.exports = checkPropTypes;
    
    /***/ }),
    /* 1601 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const log = __webpack_require__(2).namespace('doctypes')
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = log
    
    /***/ }),
    /* 1602 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const Document = __webpack_require__(1393)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const APP_DOCTYPE = 'io.cozy.apps'
    const STORE_SLUG = 'store'
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    class Application extends Document {
      /**
       * Return Store URL where an app/konnector can be installed / updated
       * @param  {Array}  [appData=[]]   Apps data, as returned by endpoint /apps/ or
       * /konnectors/
       * @param  {Object} [app={}] AppObject
       * @return {String}                URL as string
       */
      static getStoreInstallationURL(appData = [], app = {}) {
        if (!app.slug) {
          throw new Error('Expected app / konnector with the defined slug')
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        const storeApp = this.isInstalled(appData, { slug: STORE_SLUG })
        if (!storeApp) return null
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        const storeUrl = storeApp.links && storeApp.links.related
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        if (!storeUrl) return null
    
        return `${storeUrl}#/discover/${app.slug}/install`
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      /**
       *
       * @param {Array} apps Array of apps returned by /apps /konnectors
       * @param {Object} wantedApp io.cozy.app with at least a slug
       * @return {Object} The io.cozy.app is installed or undefined if not
       */
      static isInstalled(apps = [], wantedApp = {}) {
        return apps.find(
          app => app.attributes && app.attributes.slug === wantedApp.slug
        )
      }
      /**
       *
       * @param {Object} app io.cozy.app object
       * @return {String} url to the app
       */
      static getUrl(app) {
        return app.links && app.links.related
      }
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    Application.schema = {
      doctype: APP_DOCTYPE,
      attributes: {}
    }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Application.doctype = APP_DOCTYPE
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = Application
    
    /***/ }),
    /* 1603 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const Document = __webpack_require__(1393)
    const BankAccount = __webpack_require__(1604)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    class BalanceHistory extends Document {
      static async getByYearAndAccount(year, accountId) {
        const index = await Document.getIndex(this.doctype, this.idAttributes)
        const options = {
          selector: { year, 'relationships.account.data._id': accountId },
          limit: 1
        }
        const [balance] = await Document.query(index, options)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        if (balance) {
          return balance
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        return this.getEmptyDocument(year, accountId)
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      static getEmptyDocument(year, accountId) {
        return {
          year,
          balances: {},
          metadata: {
            version: this.version
          },
          relationships: {
            account: {
              data: {
                _id: accountId,
                _type: BankAccount.doctype
              }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    BalanceHistory.doctype = 'io.cozy.bank.balancehistories'
    BalanceHistory.idAttributes = ['year', 'relationships.account.data._id']
    BalanceHistory.version = 1
    BalanceHistory.checkedAttributes = ['balances']
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = BalanceHistory
    
    /***/ }),
    /* 1604 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const groupBy = __webpack_require__(1579)
    const get = __webpack_require__(1564)
    const merge = __webpack_require__(1605)
    const Document = __webpack_require__(1393)
    const matching = __webpack_require__(1613)
    const { getSlugFromInstitutionLabel } = __webpack_require__(1615)
    const log = __webpack_require__(2).namespace('BankAccount')
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    class BankAccount extends Document {
      /**
       * Adds _id of existing accounts to fetched accounts
       */
      static reconciliate(fetchedAccounts, localAccounts) {
        const matchings = matching.matchAccounts(fetchedAccounts, localAccounts)
        return matchings.map(matching => {
          log(
            'info',
            matching.match
              ? `${matching.account.label} matched with ${matching.match.label} via ${matching.method}`
              : `${matching.account.label} did not match with an existing account`
          )
          return {
            ...matching.account,
            relationships: merge(
              {},
              matching.match ? matching.match.relationships : null,
              matching.account.relationships
            ),
            _id: matching.match ? matching.match._id : undefined
          }
        })
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      static findDuplicateAccountsWithNoOperations(accounts, operations) {
        const opsByAccountId = groupBy(operations, op => op.account)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        const duplicateAccountGroups = Object.entries(
          groupBy(accounts, x => x.institutionLabel + ' > ' + x.label)
        )
          .map(([, duplicateGroup]) => duplicateGroup)
          .filter(duplicateGroup => duplicateGroup.length > 1)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        const res = []
        for (const duplicateAccounts of duplicateAccountGroups) {
          for (const account of duplicateAccounts) {
            const accountOperations = opsByAccountId[account._id] || []
            if (accountOperations.length === 0) {
              res.push(account)
            }
          }
        }
        return res
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      static hasIncoherentCreatedByApp(account) {
        const predictedSlug = getSlugFromInstitutionLabel(account.institutionLabel)
        const createdByApp =
          account.cozyMetadata && account.cozyMetadata.createdByApp
        return Boolean(
          predictedSlug && createdByApp && predictedSlug !== createdByApp
        )
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
    
      static getUpdatedAt(account) {
        const vendorUpdatedAt = get(account, 'metadata.updatedAt')
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        if (vendorUpdatedAt) {
          return vendorUpdatedAt
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        const cozyUpdatedAt = get(account, 'cozyMetadata.updatedAt')
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        if (cozyUpdatedAt) {
          return cozyUpdatedAt
        }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    BankAccount.normalizeAccountNumber = matching.normalizeAccountNumber
    BankAccount.doctype = 'io.cozy.bank.accounts'
    BankAccount.idAttributes = ['_id']
    BankAccount.version = 1
    BankAccount.checkedAttributes = null
    BankAccount.vendorIdAttr = 'vendorId'
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = BankAccount
    
    /***/ }),
    /* 1605 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    var baseMerge = __webpack_require__(1606),
        createAssigner = __webpack_require__(1612);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /**
     * This method is like `_.assign` except that it recursively merges own and
     * inherited enumerable string keyed properties of source objects into the
     * destination object. Source properties that resolve to `undefined` are
     * skipped if a destination value exists. Array and plain object properties
     * are merged recursively. Other objects and value types are overridden by
     * assignment. Source objects are applied from left to right. Subsequent
     * sources overwrite property assignments of previous sources.
     *
     * **Note:** This method mutates `object`.
     *
     * @static
     * @memberOf _
     * @since 0.5.0
     * @category Object
     * @param {Object} object The destination object.
     * @param {...Object} [sources] The source objects.
     * @returns {Object} Returns `object`.
     * @example
     *
     * var object = {
     *   'a': [{ 'b': 2 }, { 'd': 4 }]
     * };
     *
     * var other = {
     *   'a': [{ 'c': 3 }, { 'e': 5 }]
     * };
     *
     * _.merge(object, other);
     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
     */
    var merge = createAssigner(function(object, source, srcIndex) {
      baseMerge(object, source, srcIndex);
    });
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = merge;
    
    /***/ }),
    /* 1606 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    var Stack = __webpack_require__(1397),
        assignMergeValue = __webpack_require__(1607),
        baseFor = __webpack_require__(1576),
        baseMergeDeep = __webpack_require__(1608),
        isObject = __webpack_require__(1421),
        keysIn = __webpack_require__(1468),
        safeGet = __webpack_require__(1610);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /**
     * The base implementation of `_.merge` without support for multiple sources.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {number} srcIndex The index of `source`.
     * @param {Function} [customizer] The function to customize merged values.
     * @param {Object} [stack] Tracks traversed source values and their merged
     *  counterparts.
     */
    function baseMerge(object, source, srcIndex, customizer, stack) {
      if (object === source) {
        return;
      }
      baseFor(source, function(srcValue, key) {
        stack || (stack = new Stack);
        if (isObject(srcValue)) {
          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
    
    Romain CREY's avatar
    Romain CREY committed
        }
    
        else {
          var newValue = customizer
            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
            : undefined;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
          if (newValue === undefined) {
            newValue = srcValue;
    
    Romain CREY's avatar
    Romain CREY committed
          }
    
          assignMergeValue(object, key, newValue);
        }
      }, keysIn);
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    module.exports = baseMerge;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    
    var baseAssignValue = __webpack_require__(1443),
        eq = __webpack_require__(1402);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /**
     * This function is like `assignValue` except that it doesn't assign
     * `undefined` values.
     *
     * @private
     * @param {Object} object The object to modify.
     * @param {string} key The key of the property to assign.
     * @param {*} value The value to assign.
     */
    function assignMergeValue(object, key, value) {
      if ((value !== undefined && !eq(object[key], value)) ||
          (value === undefined && !(key in object))) {
        baseAssignValue(object, key, value);
      }
    }
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = assignMergeValue;
    
    /***/ }),
    /* 1608 */
    /***/ (function(module, exports, __webpack_require__) {
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    var assignMergeValue = __webpack_require__(1607),
        cloneBuffer = __webpack_require__(1471),
        cloneTypedArray = __webpack_require__(1496),
        copyArray = __webpack_require__(1472),
        initCloneObject = __webpack_require__(1497),
        isArguments = __webpack_require__(1450),
        isArray = __webpack_require__(1453),
        isArrayLikeObject = __webpack_require__(1609),
        isBuffer = __webpack_require__(1454),
        isFunction = __webpack_require__(1414),
        isObject = __webpack_require__(1421),
        isPlainObject = __webpack_require__(1518),
        isTypedArray = __webpack_require__(1457),
        safeGet = __webpack_require__(1610),
        toPlainObject = __webpack_require__(1611);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /**
     * A specialized version of `baseMerge` for arrays and objects which performs
     * deep merges and tracks traversed objects enabling objects with circular
     * references to be merged.
     *
     * @private
     * @param {Object} object The destination object.
     * @param {Object} source The source object.
     * @param {string} key The key of the value to merge.
     * @param {number} srcIndex The index of `source`.
     * @param {Function} mergeFunc The function to merge values.
     * @param {Function} [customizer] The function to customize assigned values.
     * @param {Object} [stack] Tracks traversed source values and their merged
     *  counterparts.
     */
    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
      var objValue = safeGet(object, key),
          srcValue = safeGet(source, key),
          stacked = stack.get(srcValue);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      if (stacked) {
        assignMergeValue(object, key, stacked);
    
    Romain CREY's avatar
    Romain CREY committed
        return;
      }
    
      var newValue = customizer
        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
        : undefined;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      var isCommon = newValue === undefined;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
      if (isCommon) {
        var isArr = isArray(srcValue),
            isBuff = !isArr && isBuffer(srcValue),
            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
        newValue = srcValue;
        if (isArr || isBuff || isTyped) {
          if (isArray(objValue)) {
            newValue = objValue;
          }
          else if (isArrayLikeObject(objValue)) {
            newValue = copyArray(objValue);
          }
          else if (isBuff) {
            isCommon = false;
            newValue = cloneBuffer(srcValue, true);
          }
          else if (isTyped) {
            isCommon = false;
            newValue = cloneTypedArray(srcValue, true);
          }
          else {
            newValue = [];
          }
    
    Romain CREY's avatar
    Romain CREY committed
        }
    
        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
          newValue = objValue;
          if (isArguments(objValue)) {
            newValue = toPlainObject(objValue);
          }
          else if (!isObject(objValue) || isFunction(objValue)) {
            newValue = initCloneObject(srcValue);
          }
        }
        else {
          isCommon = false;
        }
      }
      if (isCommon) {
        // Recursively merge objects and arrays (susceptible to call stack limits).
        stack.set(srcValue, newValue);
        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
        stack['delete'](srcValue);
      }
      assignMergeValue(object, key, newValue);
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    module.exports = baseMergeDeep;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    
    var isArrayLike = __webpack_require__(1466),
        isObjectLike = __webpack_require__(1452);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /**
     * This method is like `_.isArrayLike` except that it also checks if `value`
     * is an object.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.