Skip to content
Snippets Groups Projects
index.js 6.29 MiB
Newer Older
  • Learn to ignore specific revisions
  • 165001 165002 165003 165004 165005 165006 165007 165008 165009 165010 165011 165012 165013 165014 165015 165016 165017 165018 165019 165020 165021 165022 165023 165024 165025 165026 165027 165028 165029 165030 165031 165032 165033 165034 165035 165036 165037 165038 165039 165040 165041 165042 165043 165044 165045 165046 165047 165048 165049 165050 165051 165052 165053 165054 165055 165056 165057 165058 165059 165060 165061 165062 165063 165064 165065 165066 165067 165068 165069 165070 165071 165072 165073 165074 165075 165076 165077 165078 165079 165080 165081 165082 165083 165084 165085 165086 165087 165088 165089 165090 165091 165092 165093 165094 165095 165096 165097 165098 165099 165100 165101 165102 165103 165104 165105 165106 165107 165108 165109 165110 165111 165112 165113 165114 165115 165116 165117 165118 165119 165120 165121 165122 165123 165124 165125 165126 165127 165128 165129 165130 165131 165132 165133 165134 165135 165136 165137 165138 165139 165140 165141 165142 165143 165144 165145 165146 165147 165148 165149 165150 165151 165152 165153 165154 165155 165156 165157 165158 165159 165160 165161 165162 165163 165164 165165 165166 165167 165168 165169 165170 165171 165172 165173 165174 165175 165176 165177 165178 165179 165180 165181 165182 165183 165184 165185 165186 165187 165188 165189 165190 165191 165192 165193 165194 165195 165196 165197 165198 165199 165200 165201 165202 165203 165204 165205 165206 165207 165208 165209 165210 165211 165212 165213 165214 165215 165216 165217 165218 165219 165220 165221 165222 165223 165224 165225 165226 165227 165228 165229 165230 165231 165232 165233 165234 165235 165236 165237 165238 165239 165240 165241 165242 165243 165244 165245 165246 165247 165248 165249 165250 165251 165252 165253 165254 165255 165256 165257 165258 165259 165260 165261 165262 165263 165264 165265 165266 165267 165268 165269 165270 165271 165272 165273 165274 165275 165276 165277 165278 165279 165280 165281 165282 165283 165284 165285 165286 165287 165288 165289 165290 165291 165292 165293 165294 165295 165296 165297 165298 165299 165300 165301 165302 165303 165304 165305 165306 165307 165308 165309 165310 165311 165312 165313 165314 165315 165316 165317 165318 165319 165320 165321 165322 165323 165324 165325 165326 165327 165328 165329 165330 165331 165332 165333 165334 165335 165336 165337 165338 165339 165340 165341 165342 165343 165344 165345 165346 165347 165348 165349 165350 165351 165352 165353 165354 165355 165356 165357 165358 165359 165360 165361 165362 165363 165364 165365 165366 165367 165368 165369 165370 165371 165372 165373 165374 165375 165376 165377 165378 165379 165380 165381 165382 165383 165384 165385 165386 165387 165388 165389 165390 165391 165392 165393 165394 165395 165396 165397 165398 165399 165400 165401 165402 165403 165404 165405 165406 165407 165408 165409 165410 165411 165412 165413 165414 165415 165416 165417 165418 165419 165420 165421 165422 165423 165424 165425 165426 165427 165428 165429 165430 165431 165432 165433 165434 165435 165436 165437 165438 165439 165440 165441 165442 165443 165444 165445 165446 165447 165448 165449 165450 165451 165452 165453 165454 165455 165456 165457 165458 165459 165460 165461 165462 165463 165464 165465 165466 165467 165468 165469 165470 165471 165472 165473 165474 165475 165476 165477 165478 165479 165480 165481 165482 165483 165484 165485 165486 165487 165488 165489 165490 165491 165492 165493 165494 165495 165496 165497 165498 165499 165500 165501 165502 165503 165504 165505 165506 165507 165508 165509 165510 165511 165512 165513 165514 165515 165516 165517 165518 165519 165520 165521 165522 165523 165524 165525 165526 165527 165528 165529 165530 165531 165532 165533 165534 165535 165536 165537 165538 165539 165540 165541 165542 165543 165544 165545 165546 165547 165548 165549 165550 165551 165552 165553 165554 165555 165556 165557 165558 165559 165560 165561 165562 165563 165564 165565 165566 165567 165568 165569 165570 165571 165572 165573 165574 165575 165576 165577 165578 165579 165580 165581 165582 165583 165584 165585 165586 165587 165588 165589 165590 165591 165592 165593 165594 165595 165596 165597 165598 165599 165600 165601 165602 165603 165604 165605 165606 165607 165608 165609 165610 165611 165612 165613 165614 165615 165616 165617 165618 165619 165620 165621 165622 165623 165624 165625 165626 165627 165628 165629 165630 165631 165632 165633 165634 165635 165636 165637 165638 165639 165640 165641 165642 165643 165644 165645 165646 165647 165648 165649 165650 165651 165652 165653 165654 165655 165656 165657 165658 165659 165660 165661 165662 165663 165664 165665 165666 165667 165668 165669 165670 165671 165672 165673 165674 165675 165676 165677 165678 165679 165680 165681 165682 165683 165684 165685 165686 165687 165688 165689 165690 165691 165692 165693 165694 165695 165696 165697 165698 165699 165700 165701 165702 165703 165704 165705 165706 165707 165708 165709 165710 165711 165712 165713 165714 165715 165716 165717 165718 165719 165720 165721 165722 165723 165724 165725 165726 165727 165728 165729 165730 165731 165732 165733 165734 165735 165736 165737 165738 165739 165740 165741 165742 165743 165744 165745 165746 165747 165748 165749 165750 165751 165752 165753 165754 165755 165756 165757 165758 165759 165760 165761 165762 165763 165764 165765 165766 165767 165768 165769 165770 165771 165772 165773 165774 165775 165776 165777 165778 165779 165780 165781 165782 165783 165784 165785 165786 165787 165788 165789 165790 165791 165792 165793 165794 165795 165796 165797 165798 165799 165800 165801 165802 165803 165804 165805 165806 165807 165808 165809 165810 165811 165812 165813 165814 165815 165816 165817 165818 165819 165820 165821 165822 165823 165824 165825 165826 165827 165828 165829 165830 165831 165832 165833 165834 165835 165836 165837 165838 165839 165840 165841 165842 165843 165844 165845 165846 165847 165848 165849 165850 165851 165852 165853 165854 165855 165856 165857 165858 165859 165860 165861 165862 165863 165864 165865 165866 165867 165868 165869 165870 165871 165872 165873 165874 165875 165876 165877 165878 165879 165880 165881 165882 165883 165884 165885 165886 165887 165888 165889 165890 165891 165892 165893 165894 165895 165896 165897 165898 165899 165900 165901 165902 165903 165904 165905 165906 165907 165908 165909 165910 165911 165912 165913 165914 165915 165916 165917 165918 165919 165920 165921 165922 165923 165924 165925 165926 165927 165928 165929 165930 165931 165932 165933 165934 165935 165936 165937 165938 165939 165940 165941 165942 165943 165944 165945 165946 165947 165948 165949 165950 165951 165952 165953 165954 165955 165956 165957 165958 165959 165960 165961 165962 165963 165964 165965 165966 165967 165968 165969 165970 165971 165972 165973 165974 165975 165976 165977 165978 165979 165980 165981 165982 165983 165984 165985 165986 165987 165988 165989 165990 165991 165992 165993 165994 165995 165996 165997 165998 165999 166000
     * connector.run()
     * ```
     *
     */
    
    class CookieKonnector extends BaseKonnector {
      /**
       * Constructor
       *
       * @param  {Function} requestFactoryOptions    - Option object passed to requestFactory to
       * initialize this.request. It is still possible to change this.request doing :
       *
       * ```javascript
       * this.request = this.requestFactory(...)
       * ```
       *
       * Please not you have to run the connector yourself doing :
       *
       * ```javascript
       * connector.run()
       * ```
       */
      constructor(requestFactoryOptions) {
        super();
    
        if (!this.testSession) {
          throw new Error('Could not find a testSession method. CookieKonnector needs it to test if a session is valid. Please implement it');
        }
    
        this._jar = requestFactory().jar();
        this.request = this.requestFactory(requestFactoryOptions);
      }
      /**
       * Initializes the current connector with data coming from the associated account
       * and also the session
       *
       * @returns {Promise} with the fields as an object
       */
    
    
      async initAttributes(cozyFields, account) {
        await super.initAttributes(cozyFields, account);
        await this.initSession();
      }
      /**
       * Hook called when the connector is ended
       */
    
    
      async end() {
        await this.saveSession();
        return super.end();
      }
      /**
       * Calls cozy-konnector-libs requestFactory forcing this._jar as the cookie
       *
       * @param  {object} options - requestFactory option
       * @returns {object} - The resulting request object
       */
    
    
      requestFactory(options) {
        this._jar = this._jar || requestFactory().jar();
        return requestFactory({ ...options,
          jar: this._jar
        });
      }
      /**
       * Reset cookie session with a new empty session and save it to the associated account
       *
       * @returns {Promise}
       */
    
    
      async resetSession() {
        log('info', 'Reset cookie session...');
        this._jar = requestFactory().jar();
        return this.saveSession();
      }
      /**
       * Get the cookie session from the account if any
       *
       * @returns {Promise} true or false if the session in the account exists or not
       */
    
    
      async initSession() {
        const accountData = this.getAccountData();
    
        try {
          if (this._account.state === 'RESET_SESSION') {
            log('info', 'RESET_SESSION state found');
            await this.resetSession();
            await this.updateAccountAttributes({
              state: null
            });
          }
        } catch (err) {
          log('warn', 'Could not reset the session');
          log('warn', err.message);
        }
    
        try {
          let jar = null;
    
          if (accountData && accountData.auth) {
            jar = JSON.parse(accountData.auth[JAR_ACCOUNT_KEY]);
          }
    
          if (jar) {
            log('info', 'found saved session, using it...');
            this._jar._jar = CookieJar.fromJSON(jar, this._jar._jar.store);
            return true;
          }
        } catch (err) {
          log('info', 'Could not parse session');
        }
    
        log('info', 'Found no session');
        return false;
      }
      /**
       * Saves the current cookie session to the account
       *
       * @returns {Promise}
       */
    
    
      async saveSession(obj) {
        const accountData = { ...this._account.data,
          auth: {}
        };
    
        if (obj && obj.getCookieJar) {
          this._jar._jar = obj.getCookieJar();
        }
    
        accountData.auth[JAR_ACCOUNT_KEY] = JSON.stringify(this._jar._jar.toJSON());
        await this.saveAccountData(accountData);
        log('info', 'saved the session');
      }
      /**
       * This is signin function from cozy-konnector-libs which is forced to use the current cookies
       * and current request from CookieKonnector. It also automatically saves the session after
       * signin if it is a success.
       *
       * @returns {Promise}
       */
    
    
      async signin(options) {
        const result = await super.signin({ ...options,
          requestInstance: this.request
        });
        await this.saveSession();
        return result;
      }
      /**
       * This is saveFiles function from cozy-konnector-libs which is forced to use the current cookies
       * and current request from CookieKonnector.
       *
       * @returns {Promise}
       */
    
    
      saveFiles(entries, fields, options) {
        return super.saveFiles(entries, fields, { ...options,
          requestInstance: this.request
        });
      }
      /**
       * This is saveBills function from cozy-konnector-libs which is forced to use the current cookies
       * and current request from CookieKonnector.
       *
       * @returns {Promise}
       */
    
    
      saveBills(entries, fields, options) {
        return super.saveBills(entries, fields, { ...options,
          requestInstance: this.request
        });
      }
    
    }
    
    module.exports = CookieKonnector;
    
    /***/ }),
    /* 1238 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const {
      URL
    } = __webpack_require__(83);
    
    const computeWidth = $table => {
      let out = 0;
      const tds = $table.find('tr').first().find('td,th');
    
      for (var i = 0; i < tds.length; i++) {
        out += parseInt(tds.eq(i).attr('colspan')) || 1;
      }
    
      return out;
    };
    
    const makeLinkOpts = ($el, opts) => {
      if ($el.attr('href') === undefined) return undefined;
      if ($el.attr('href').indexOf('javascript:') === 0) return undefined;
      if ($el.attr('href').indexOf('#') === 0) return undefined;
      return {
        link: new URL($el.attr('href'), opts.baseURL).toString(),
        color: '0x0000FF'
      };
    };
    
    function htmlToPDF($, frag, $parent, opts) {
      let pdf, helveticaBold, helveticaEm; // pdfjs is an optional dependency, this is why the requires are done in
      // a try/catch. webpack detects this and does not crash when building
      // if requires are done in a try/catch.
    
      try {
        pdf = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
        helveticaBold = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs/font/Helvetica-Bold'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
        helveticaEm = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs/font/Helvetica-Oblique'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
      } catch (err) {
        throw new Error('pdfjs dependency is missing. Please add it in your package.json');
      }
    
      opts = Object.assign({
        baseURL: '',
        filter: () => true,
        txtOpts: {}
      }, opts);
      const children = $parent.contents();
      let text = opts.text;
      let parentDL = null;
    
      const getText = () => {
        if (!text) text = frag.text('', opts.txtOpts);
        return text;
      };
    
      children.each((i, el) => {
        if (el.nodeType === 3 && el.data.trim() !== '') {
          getText().add(el.data);
        } else if (el.nodeType === 1) {
          const $el = $(el);
          if (!opts.filter($el)) return;
    
          switch (el.tagName) {
            case 'a':
              getText().add($el.text(), makeLinkOpts($el, opts));
              break;
    
            case 'strong':
            case 'b':
              getText().add($el.text(), {
                font: helveticaBold
              });
              break;
    
            case 'em':
              getText().add($el.text(), {
                font: helveticaEm
              });
              break;
    
            case 'span':
              htmlToPDF($, frag, $el, Object.assign({}, opts, {
                text: text
              }));
              break;
    
            case 'br':
              getText().br();
              break;
    
            case 'i':
            case 'select':
            case 'input':
            case 'label':
            case 'form':
            case 'fieldset':
            case 'textarea':
            case 'button':
            case 'img':
            case 'script':
            case 'caption':
              // ignore
              break;
    
            case 'table':
              {
                text = null;
                let width = computeWidth($el);
                let tableState = {
                  tableWidth: width
                };
                htmlToPDF($, frag.table({
                  widths: Array.from(Array(width), () => '*'),
                  borderWidth: 1
                }), $el, Object.assign({}, opts, {
                  tableState
                }));
                break;
              }
    
            case 'tr':
              {
                text = null;
                opts.tableState.colRemaining = opts.tableState.tableWidth;
                let row = frag.row();
                htmlToPDF($, row, $el, opts);
    
                if (opts.tableState.colRemaining > 0) {
                  row.cell({
                    colspan: opts.tableState.colRemaining
                  });
                }
    
                break;
              }
    
            case 'dl':
              text = null;
              htmlToPDF($, frag.table({
                widths: [5 * pdf.cm, null],
                borderWidth: 1
              }), $el, { ...opts,
                tableState: {
                  tableWidth: 2,
                  colRemaining: 2
                }
              });
              parentDL = null;
              break;
    
            case 'dt':
              if (!parentDL) {
                parentDL = frag;
              } else {
                frag = parentDL;
              }
    
              frag = frag.row();
            // fall through the rest of the procedure
    
            case 'dd':
            case 'th':
            case 'td':
              {
                text = null;
                const colspan = Math.min(opts.tableState.tableWidth, parseInt($el.attr('colspan')) || 1);
                opts.tableState.colRemaining -= colspan;
                htmlToPDF($, frag.cell({
                  padding: 5,
                  colspan: colspan
                }), $el, opts);
                break;
              }
    
            case 'h1':
            case 'h2':
            case 'h3':
            case 'h4':
            case 'h5':
              text = null;
              htmlToPDF($, frag, //.cell({ paddingTop: 1 * pdf.cm }),
              $el, Object.assign({}, opts, {
                txtOpts: {
                  fontSize: 30 - parseInt(el.tagName.replace('h', '')) * 2
                }
              }));
              break;
    
            case 'div':
            case 'p':
            case 'ul':
              text = null;
              htmlToPDF($, frag.cell(), $el, opts);
              break;
    
            case 'thead':
            case 'tfoot':
            case 'tbody':
            case 'small':
            case 'li':
              text = null;
              htmlToPDF($, frag, $el, opts);
              break;
    
            default:
              text = null;
              htmlToPDF($, frag, $el, opts);
          }
        }
      });
    }
    
    function createCozyPDFDocument(headline, url) {
      let pdf, helveticaBold; // pdfjs is an optional dependency, this is why the requires are done in
      // a try/catch. webpack detects this and does not crash when building
      // if requires are done in a try/catch.
    
      try {
        pdf = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
        helveticaBold = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module 'pdfjs/font/Helvetica-Bold'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
      } catch (err) {
        throw new Error('pdfjs dependency is missing. Please add it in your package.json');
      }
    
      var doc = new pdf.Document();
      const cell = doc.cell({
        paddingBottom: 0.5 * pdf.cm
      }).text();
      cell.add(headline, {
        font: helveticaBold,
        fontSize: 14
      });
      cell.add(url, {
        link: url,
        color: '0x0000FF'
      });
      return doc;
    }
    
    module.exports = {
      htmlToPDF,
      createCozyPDFDocument
    };
    
    /***/ }),
    /* 1239 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const isEqualWith = __webpack_require__(1240);
    
    const omit = __webpack_require__(944);
    
    const maybeToISO = date => {
      try {
        return date.toISOString ? date.toISOString() : date;
      } catch (e) {
        return date;
      }
    };
    
    const looseDates = (val, otherVal) => {
      // Loose equality for dates since when coming from Couch, they
      // are ISO strings whereas just after scraping they are `Date`s.
      if (val instanceof Date) {
        return maybeToISO(val) === maybeToISO(otherVal);
      }
    };
    /**
     * Simple Model for Documents. Allows to specify
     * `shouldSave`, `shouldUpdate` as methods.
     *
     * Has useful `isEqual` method
     *
     */
    
    
    class Document {
      constructor(attrs) {
        if (this.validate) {
          this.validate(attrs);
        }
    
        Object.assign(this, attrs, {
          metadata: {
            version: attrs.metadata && attrs.metadata.version || this.constructor.version
          }
        });
      }
    
      toJSON() {
        return this;
      }
      /**
       * Compares to another document deeply.
       *
       * `_id` and `_rev` are by default ignored in the comparison.
       *
       * By default, will compare dates loosely since you often
       * compare existing documents (dates in ISO string) with documents
       * that just have been scraped where dates are `Date`s.
       */
    
    
      isEqual(other, ignoreAttrs = ['_id', '_rev'], strict = false) {
        return isEqualWith(omit(this, ignoreAttrs), omit(other, ignoreAttrs), !strict && looseDates);
      }
    
    }
    
    module.exports = Document;
    
    /***/ }),
    /* 1240 */
    /***/ (function(module, exports, __webpack_require__) {
    
    var baseIsEqual = __webpack_require__(546);
    
    /**
     * This method is like `_.isEqual` except that it accepts `customizer` which
     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
     * are handled by the method instead. The `customizer` is invoked with up to
     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to compare.
     * @param {*} other The other value to compare.
     * @param {Function} [customizer] The function to customize comparisons.
     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
     * @example
     *
     * function isGreeting(value) {
     *   return /^h(?:i|ello)$/.test(value);
     * }
     *
     * function customizer(objValue, othValue) {
     *   if (isGreeting(objValue) && isGreeting(othValue)) {
     *     return true;
     *   }
     * }
     *
     * var array = ['hello', 'goodbye'];
     * var other = ['hi', 'goodbye'];
     *
     * _.isEqualWith(array, other, customizer);
     * // => true
     */
    function isEqualWith(value, other, customizer) {
      customizer = typeof customizer == 'function' ? customizer : undefined;
      var result = customizer ? customizer(value, other) : undefined;
      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
    }
    
    module.exports = isEqualWith;
    
    
    /***/ }),
    /* 1241 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const log = __webpack_require__(2).namespace('scrape');
    /**
     * Declarative scraping.
     *
     * Describe your items attributes and where to find/parse them
     * instead of imperatively building them.
     *
     * Heavily inspired by [artoo] scraping method.
     *
     * [artoo]: https://medialab.github.io/artoo/
     */
    
    
    const mkSpec = function (spec) {
      if (typeof spec === 'string') {
        return {
          sel: spec
        };
      } else {
        return spec;
      }
    };
    /**
     * Scrape a cheerio object for properties
     *
     * @param  {cheerio} $ - Cheerio node which will be scraped
     * @param  {object|string} spec(s) - Options object describing what you want to scrape
     * @param  {string} [childSelector] -  If passed, scrape will return an array of items
     * @returns {object|Array} - Item(s) scraped
     * @example
     *
     * `scrape` can be used to declaratively extract data :
     *
     * - For one object :
     *
     * ```
     * const item = scrape($('#item'), {
     *   title: '.title',
     *   content: '.content'
     * })
     * ```
     *
     * - For a list of objects :
     *
     * ```
     * const items = scrape($('#content'), {
     *   title: '.title',
     *   content: '.content'
     * }, '.item')
     * ```
     *
     * For more power, you can use `object`s for each retriever :
     *
     * ```
     * const items = scrape($('#content'), {
     *   title: '.title',
     *   content: '.content',
     *   link: {
     *     sel: 'a',
     *     attr: 'href'
     *   },
     * }, '.item')
     * ```
     *
     * Here the `href` attribute of the `a` inside `.item`s would have been
     * put into the `link` attribute of the items returned by `scrape`.
     *
     * Available options :
     *
     * - `sel`: the CSS selector used to target the HTML node from which data will be scraped
     * - `attr`: the HTML attribute from which to extract data
     * - `parse`: function applied to the value extracted (`{ sel: '.price', parse: parseAmount }`)
     * - `fn`: if you need something more complicated than `attr`, you can use this function, it receives
     * the complete DOM node. `{ sel: '.person', fn: $node => $node.attr('data-name') + $node.attr('data-firstname') }`
     */
    
    
    const scrape = ($, specs, childSelector) => {
      // Only one value shorthand
      if (typeof specs === 'string' || specs.sel && typeof specs.sel === 'string') {
        const {
          val
        } = scrape($, {
          val: specs
        });
        return val;
      } // Several items shorthand
    
    
      if (childSelector !== undefined) {
        return Array.from(($.find || $)(childSelector)).map(e => scrape($(e), specs));
      } // Several properties "normal" case
    
    
      const res = {};
      Object.keys(specs).forEach(specName => {
        try {
          const spec = mkSpec(specs[specName]);
          let data = spec.sel ? $.find(spec.sel) : $;
    
          if (spec.index) {
            data = data.get(spec.index);
          }
    
          let val;
    
          if (spec.fn) {
            val = spec.fn(data);
          } else if (spec.attr) {
            val = data.attr(spec.attr);
          } else {
            val = data;
            val = val && val.text();
            val = val && val.trim();
          }
    
          if (spec.parse) {
            val = spec.parse(val);
          }
    
          res[specName] = val;
        } catch (e) {
          log('warn', 'Could not parse for', specName);
          log('warn', e);
        }
      });
      return res;
    };
    
    module.exports = scrape;
    
    /***/ }),
    /* 1242 */
    /***/ (function(module, exports) {
    
    /**
     * Returns the given name, replacing characters that could be an issue when
     * used in a filename with spaces.
     *
     * @module normalizeFilename
     */
    const normalizableCharsRegExp = /[<>:"/\\|?*\0\s]+/g;
    /**
     * Returns the given name, replacing characters that could be an issue when
     * used in a filename with spaces.
     *
     * Replaced characters include:
     *
     * - Those forbidden on one or many popular OS or filesystem: `<>:"/\|?*`
     * - Those forbidden by the cozy-stack `\0`, `\r` and `\n`
     * - Multiple spaces and/or tabs are replaced with a single space
     * - Leading & trailing spaces and/or tabs are removed
     *
     * An exception will be thrown in case there is not any filename-compatible
     * character in the given name.
     *
     * Parameters:
     *
     * - `basename` is whatever string you want to generate the filename from
     * - `ext` is an optional file extension, with or without leading dot
     *
     * ```javascript
     * const { normalizeFilename } = require('cozy-konnector-libs')
     *
     * const filename = normalizeFilename('*foo/bar: <baz> \\"qux"\t???', '.txt')
     * // `filename` === `foo bar baz qux.txt`
     * ```
     *
     * @alias module:normalizeFilename
     */
    
    const normalizeFilename = (basename, ext) => {
      const filename = basename.replace(normalizableCharsRegExp, ' ').trim();
    
      if (filename === '') {
        throw new Error('Cannot find any filename-compatible character in ' + JSON.stringify(filename) + '!');
      }
    
      if (ext == null) ext = '';else if (!ext.startsWith('.')) ext = '.' + ext;
      return filename + ext;
    };
    
    module.exports = normalizeFilename;
    
    /***/ }),
    /* 1243 */
    /***/ (function(module, exports, __webpack_require__) {
    
    /**
     * Use every possible means to solve a captcha. At the moment, Anticaptcha web service is used if
     * any related secret key is found in COZY_PARAMETERS environment variable.
     *
     * @module solveCaptcha
     */
    const log = __webpack_require__(2).namespace('solveCaptcha');
    
    const errors = __webpack_require__(1176);
    
    const request = __webpack_require__(24);
    
    const sleep = __webpack_require__(9).promisify(global.setTimeout);
    
    const connectorStartTime = Date.now();
    const DEFAULT_TIMEOUT = connectorStartTime + 3 * 60 * 1000; // 3 minutes by default to let 1 min to the connector to fetch files
    
    /**
     * Use every possible means to solve a captcha. At the moment, Anticaptcha web service is used if
     * any related secret key is found in COZY_PARAMETERS environment variable.
     * If you do not want to solve the captcha each time the connector is run, please also use
     * CookieKonnector which will help you save the session.
     *
     * Parameters:
     *
     * - `params` is an array of objects with any attributes with some mandatory attributes :
     *   + `type` (String): (default recaptcha) type of captcha to solve. can be "recaptcha" or "image" at the moment
     *   + `timeout` (Number): (default 3 minutes after now) time when the solver should stop trying to
     *   solve the captcha
     *   + `websiteKey` (String): the key you can find on the targeted website (for recaptcha)
     *   + `websiteURL` (String): The URL of the page showing the captcha (for recaptcha)
     *   + `body` (String): The base64 encoded image (for image captcha)
     * Returns: Promise with the solved captcha response as a string
     *
     * @example
     *
     * ```javascript
     * const { solveCaptcha } = require('cozy-konnector-libs')
     *
     * const solvedKey = await solveCaptcha({
     *   websiteKey: 'the key in the webpage',
     *   websiteURL: 'http://quotes.toscrape.com/login',
     * })
     * // now use the solveKey to submit your form
     * ```
     *
     * @alias module:solveCaptcha
     */
    
    const solveCaptcha = async (params = {}) => {
      const defaultParams = {
        type: 'recaptcha',
        timeout: DEFAULT_TIMEOUT
      };
      params = { ...defaultParams,
        ...params
      };
      const secrets = JSON.parse(process.env.COZY_PARAMETERS || '{}').secret;
    
      if (params.type === 'recaptcha') {
        checkMandatoryParams(params, ['websiteKey', 'websiteURL']);
        const {
          websiteKey,
          websiteURL
        } = params;
        return solveWithAntiCaptcha({
          websiteKey,
          websiteURL,
          type: 'NoCaptchaTaskProxyless'
        }, params.timeout, secrets, 'gRecaptchaResponse');
      } else if (params.type === 'recaptchav3') {
        checkMandatoryParams(params, ['websiteKey', 'websiteURL', 'pageAction', 'minScore']);
        const {
          websiteKey,
          websiteURL,
          pageAction,
          minScore
        } = params;
        return solveWithAntiCaptcha({
          websiteKey,
          websiteURL,
          pageAction,
          minScore,
          type: 'RecaptchaV3TaskProxyless'
        }, params.timeout, secrets, 'gRecaptchaResponse');
      } else if (params.type === 'image') {
        checkMandatoryParams(params, ['body']);
        return solveWithAntiCaptcha({
          body: params.body,
          type: 'ImageToTextTask'
        }, params.timeout, secrets, 'text');
      }
    };
    
    function checkMandatoryParams(params = {}, mandatoryParams = []) {
      const keys = Object.keys(params);
      const missingKeys = mandatoryParams.filter(key => !keys.includes(key));
    
      if (missingKeys.length) {
        throw new Error(`${missingKeys.join(', ')} are mandatory to solve the captcha`);
      }
    }
    
    async function solveWithAntiCaptcha(taskParams, timeout = DEFAULT_TIMEOUT, secrets, resultAttribute = 'gRecaptchaResponse') {
      const antiCaptchaApiUrl = 'https://api.anti-captcha.com';
      let gRecaptchaResponse = null;
      const startTime = Date.now(); // we try to solve the captcha with anticaptcha
    
      const clientKey = secrets.antiCaptchaClientKey;
    
      if (clientKey) {
        log('info', '  Creating captcha resolution task...');
        const task = await request.post(`${antiCaptchaApiUrl}/createTask`, {
          body: {
            clientKey,
            task: taskParams
          },
          json: true
        });
    
        if (task && task.taskId) {
          log('info', `    Task id : ${task.taskId}`);
    
          while (!gRecaptchaResponse) {
            const resp = await request.post(`${antiCaptchaApiUrl}/getTaskResult`, {
              body: {
                clientKey,
                taskId: task.taskId
              },
              json: true
            });
    
            if (resp.status === 'ready') {
              if (resp.errorId) {
                log('error', `Anticaptcha error: ${JSON.stringify(resp)}`);
                throw new Error(errors.CAPTCHA_RESOLUTION_FAILED);
              }
    
              log('warn', `  Found Recaptcha response : ${JSON.stringify(resp)}`);
              return resp.solution[resultAttribute];
            } else {
              log('info', `    ${Math.round((Date.now() - startTime) / 1000)}s...`);
    
              if (Date.now() > timeout) {
                log('warn', `  Captcha resolution timeout`);
                throw new Error(errors.CAPTCHA_RESOLUTION_FAILED + '.TIMEOUT');
              }
    
              await sleep(10000);
            }
          }
        } else {
          log('warn', 'Could not create anticaptcha task');
          log('warn', JSON.stringify(task));
        }
      } else {
        log('warn', 'Could not find any anticaptcha secret key');
      }
    
      throw new Error(errors.CAPTCHA_RESOLUTION_FAILED);
    }
    
    module.exports = solveCaptcha;
    
    /***/ }),
    /* 1244 */
    /***/ (function(module, exports, __webpack_require__) {
    
    function getAccountId() {
      try {
        return  false
          ? undefined
          : JSON.parse(process.env.COZY_FIELDS).account
      } catch (err) {
        throw new Error(`You must provide 'account' in COZY_FIELDS: ${err.message}`)
      }
    }
    
    module.exports = getAccountId
    
    
    /***/ }),
    /* 1245 */
    /***/ (function(module, exports, __webpack_require__) {
    
    /* WEBPACK VAR INJECTION */(function(module) {var require;//! moment.js
    //! version : 2.25.3
    //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
    //! license : MIT
    //! momentjs.com
    
    ;(function (global, factory) {
         true ? module.exports = factory() :
        undefined
    }(this, (function () { 'use strict';
    
        var hookCallback;
    
        function hooks() {
            return hookCallback.apply(null, arguments);
        }
    
        // This is done to register the method called with moment()
        // without creating circular dependencies.
        function setHookCallback(callback) {
            hookCallback = callback;
        }
    
        function isArray(input) {
            return (
                input instanceof Array ||
                Object.prototype.toString.call(input) === '[object Array]'
            );
        }
    
        function isObject(input) {
            // IE8 will treat undefined and null as object if it wasn't for
            // input != null
            return (
                input != null &&
                Object.prototype.toString.call(input) === '[object Object]'
            );
        }
    
        function hasOwnProp(a, b) {
            return Object.prototype.hasOwnProperty.call(a, b);
        }
    
        function isObjectEmpty(obj) {
            if (Object.getOwnPropertyNames) {
                return Object.getOwnPropertyNames(obj).length === 0;
            } else {
                var k;
                for (k in obj) {
                    if (hasOwnProp(obj, k)) {
                        return false;
                    }
                }
                return true;
            }
        }
    
        function isUndefined(input) {
            return input === void 0;
        }
    
        function isNumber(input) {
            return (
                typeof input === 'number' ||
                Object.prototype.toString.call(input) === '[object Number]'
            );
        }
    
        function isDate(input) {
            return (
                input instanceof Date ||
                Object.prototype.toString.call(input) === '[object Date]'
            );
        }
    
        function map(arr, fn) {