Skip to content
Snippets Groups Projects
index.js 7.33 MiB
Newer Older
  • Learn to ignore specific revisions
  • Romain CREY's avatar
    Romain CREY committed
    /******/ (function(modules) { // webpackBootstrap
    /******/ 	// The module cache
    /******/ 	var installedModules = {};
    /******/
    /******/ 	// The require function
    /******/ 	function __webpack_require__(moduleId) {
    /******/
    /******/ 		// Check if module is in cache
    /******/ 		if(installedModules[moduleId]) {
    /******/ 			return installedModules[moduleId].exports;
    /******/ 		}
    /******/ 		// Create a new module (and put it into the cache)
    /******/ 		var module = installedModules[moduleId] = {
    /******/ 			i: moduleId,
    /******/ 			l: false,
    /******/ 			exports: {}
    /******/ 		};
    /******/
    /******/ 		// Execute the module function
    /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    /******/
    /******/ 		// Flag the module as loaded
    /******/ 		module.l = true;
    /******/
    /******/ 		// Return the exports of the module
    /******/ 		return module.exports;
    /******/ 	}
    /******/
    /******/
    /******/ 	// expose the modules object (__webpack_modules__)
    /******/ 	__webpack_require__.m = modules;
    /******/
    /******/ 	// expose the module cache
    /******/ 	__webpack_require__.c = installedModules;
    /******/
    /******/ 	// define getter function for harmony exports
    /******/ 	__webpack_require__.d = function(exports, name, getter) {
    /******/ 		if(!__webpack_require__.o(exports, name)) {
    /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
    /******/ 		}
    /******/ 	};
    /******/
    /******/ 	// define __esModule on exports
    /******/ 	__webpack_require__.r = function(exports) {
    /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
    /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
    /******/ 		}
    /******/ 		Object.defineProperty(exports, '__esModule', { value: true });
    /******/ 	};
    /******/
    /******/ 	// create a fake namespace object
    /******/ 	// mode & 1: value is a module id, require it
    /******/ 	// mode & 2: merge all properties of value into the ns
    /******/ 	// mode & 4: return value when already ns object
    /******/ 	// mode & 8|1: behave like require
    /******/ 	__webpack_require__.t = function(value, mode) {
    /******/ 		if(mode & 1) value = __webpack_require__(value);
    /******/ 		if(mode & 8) return value;
    /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
    /******/ 		var ns = Object.create(null);
    /******/ 		__webpack_require__.r(ns);
    /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
    /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
    /******/ 		return ns;
    /******/ 	};
    /******/
    /******/ 	// getDefaultExport function for compatibility with non-harmony modules
    /******/ 	__webpack_require__.n = function(module) {
    /******/ 		var getter = module && module.__esModule ?
    /******/ 			function getDefault() { return module['default']; } :
    /******/ 			function getModuleExports() { return module; };
    /******/ 		__webpack_require__.d(getter, 'a', getter);
    /******/ 		return getter;
    /******/ 	};
    /******/
    /******/ 	// Object.prototype.hasOwnProperty.call
    /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    /******/
    /******/ 	// __webpack_public_path__
    /******/ 	__webpack_require__.p = "";
    /******/
    /******/
    /******/ 	// Load entry module and return exports
    /******/ 	return __webpack_require__(__webpack_require__.s = 0);
    /******/ })
    /************************************************************************/
    /******/ ([
    /* 0 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const {
      BaseKonnector,
      log,
      errors,
      addData,
      hydrateAndFilter,
      cozyClient
    
    } = __webpack_require__(1)
    
    const rp = __webpack_require__(24)
    const moment = __webpack_require__(1492)
    __webpack_require__(1630)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    moment.locale('fr') // set the language
    moment.tz.setDefault('Europe/Paris') // set the timezone
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const manualExecution =
      process.env.COZY_JOB_MANUAL_EXECUTION === 'true' ? true : false
    
    
    const startDate = manualExecution
    
      ? moment()
          .startOf('year')
          .subtract(1, 'year')
          .format('MM/DD/YYYY')
      : moment()
          .startOf('year')
          .subtract(3, 'year')
          .format('MM/DD/YYYY')
    
    const endDate = moment().format('MM/DD/YYYY')
    // const timeRange = ['day', 'month', 'year']
    
    const rangeDate = {
      day: {
    
        doctype: 'com.grandlyon.egl.day',
        keys: ['year', 'month', 'day']
    
        doctype: 'com.grandlyon.egl.month',
        keys: ['year', 'month']
    
        doctype: 'com.grandlyon.egl.year',
        keys: ['year']
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    module.exports = new BaseKonnector(start)
    
    Romain CREY's avatar
    Romain CREY committed
    
    // The start function is run by the BaseKonnector instance only when it got all the account
    // information (fields). When you run this connector yourself in "standalone" mode or "dev" mode,
    // the account information come from ./konnector-dev-config.json file
    async function start(fields, cozyParameters) {
      try {
        // resetting data for demo only
        // await resetData()
    
        const baseUrl = cozyParameters.secret.eglBaseURL
        const apiAuthKey = cozyParameters.secret.eglAPIAuthKey
        log('info', 'Authenticating ...')
    
    Romain CREY's avatar
    Romain CREY committed
        const response = await authenticate(
          fields.login,
          fields.password,
          baseUrl,
          apiAuthKey
    
        )
        log('info', 'Successfully logged in')
    
        const eglData = await getData(response, baseUrl, apiAuthKey)
        if (eglData) {
          log('debug', 'Process egl daily data')
          const processedLoadData = await processData(
            eglData,
            rangeDate.day.doctype,
            rangeDate.day.keys
    
          log('debug', 'Agregate egl load data for month and year')
          await agregateMonthAndYearData(processedLoadData)
        } else {
          log('debug', 'No data found')
        }
    
    Romain CREY's avatar
    Romain CREY committed
      } catch (error) {
    
        throw new Error(error.message)
    
    Romain CREY's avatar
    Romain CREY committed
      }
    }
    
    
    /**
     * Parse data
     * Remove existing data from DB using hydrateAndFilter
     * Store filtered data
     * Return the list of filtered data
     */
    async function processData(data, doctype, filterKeys) {
      // const formatedData = await formateData(data)
      log('debug', 'processData - data formated')
      // Remove data for existing days into the DB
      const filteredData = await hydrateAndFilter(data, doctype, {
        keys: filterKeys
      })
      log('debug', 'processData - data filtered')
      // Store new day data
      await storeData(filteredData, doctype, filterKeys)
      return filteredData
    }
    
    /**
     * Agregate data from daily data to monthly and yearly data
     */
    async function agregateMonthAndYearData(data) {
      // Sum year and month values into object with year or year-month as keys
      if (data && data.length !== 0) {
        let monthData = {}
        let yearData = {}
    
        data.forEach(element => {
          element.year + '-' + element.month in monthData
            ? (monthData[element.year + '-' + element.month] += element.load)
            : (monthData[element.year + '-' + element.month] = element.load)
          element.year in yearData
            ? (yearData[element.year] += element.load)
            : (yearData[element.year] = element.load)
        })
        // Agregation for Month data
        const agregatedMonthData = await buildAgregatedData(
          monthData,
          'com.grandlyon.egl.month'
        )
        await storeData(agregatedMonthData, 'com.grandlyon.egl.month', [
          'year',
          'month'
        ])
        // Agregation for Year data
        const agregatedYearData = await buildAgregatedData(
          yearData,
          'com.grandlyon.egl.year'
        )
        await storeData(agregatedYearData, 'com.grandlyon.egl.year', ['year'])
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    /**
     * Retrieve and remove old data for a specific doctype
     * Return an Array of agregated data
     */
    async function buildAgregatedData(data, doctype) {
    
    git-directory-deploy's avatar
    git-directory-deploy committed
      log('info', 'entering buildAgregatedData')
    
      let agregatedData = []
      for (let [key, value] of Object.entries(data)) {
        const data = await buildDataFromKey(doctype, key, value)
        const oldValue = await resetInProgressAggregatedData(data, doctype)
    
    git-directory-deploy's avatar
    git-directory-deploy committed
        log('info', 'Dataload + oldvalue is ' + data.load + ' + ' + oldValue)
    
        data.load += oldValue
        agregatedData.push(data)
      }
      return agregatedData
    }
    
    // async function processData(timeStep, response, baseUrl, apiAuthKey) {
    //   const doctype = rangeDate[timeStep].doctype;
    //   const loadProfile = await getData(response, baseUrl, apiAuthKey);
    //   log("info", "Saving data to Cozy");
    //   if (doctype === rangeDate.day.doctype) {
    //     await storeData(loadProfile, rangeDate.day.doctype, rangeDate.day.keys);
    //   } else if (doctype === rangeDate.month.doctype) {
    //     await resetInProgressAggregatedData(rangeDate.month.doctype);
    //     const monthlyData = processMonthlyAggregation(loadProfile, rangeDate.month);
    //     log("info", "Saving monthly data");
    //     await storeData(monthlyData, rangeDate.month.doctype, rangeDate.month.keys);
    //   } else if (doctype === rangeDate.year.doctype) {
    //     await resetInProgressAggregatedData(rangeDate.year.doctype);
    //     const yearlyData = processYearAggregation(
    //       loadProfile,
    //       rangeDate.year.doctype
    //     );
    //     log("info", "Saving yearly data");
    //     await storeData(yearlyData, rangeDate.year.doctype, rangeDate.year.keys);
    //   } else {
    //     throw new Error("Unkonw range type: " + doctype);
    //   }
    // }
    
    
    Romain CREY's avatar
    Romain CREY committed
    async function authenticate(login, password, baseUrl, apiAuthKey) {
      const authRequest = {
    
        method: 'POST',
        uri: baseUrl + '/connect.aspx',
    
    Romain CREY's avatar
    Romain CREY committed
        headers: {
          AuthKey: apiAuthKey,
    
          'Content-Type': 'application/x-www-form-urlencoded'
    
    Romain CREY's avatar
    Romain CREY committed
        },
        form: {
          login: login,
          pass: password
        },
        json: true
    
      }
      const response = await rp(authRequest)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      if (response.codeRetour === 100) {
    
        return response
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      } else {
    
        throw new Error(errors.LOGIN_FAILED)
    
    Romain CREY's avatar
    Romain CREY committed
      }
    }
    
    async function getData(response, baseUrl, apiAuthKey) {
    
      log('debug', 'Start date : ' + startDate)
      log('debug', 'End date : ' + endDate)
    
    Romain CREY's avatar
    Romain CREY committed
      const dataRequest = {
    
        method: 'POST',
        uri: baseUrl + '/getAllAgregatsByAbonnement.aspx',
    
    Romain CREY's avatar
    Romain CREY committed
        headers: {
          AuthKey: apiAuthKey,
    
          'Content-Type': 'application/x-www-form-urlencoded'
    
    Romain CREY's avatar
    Romain CREY committed
        },
        form: {
          token: response.resultatRetour.token,
          num_abt: response.resultatRetour.num_abt,
          date_debut: startDate,
          date_fin: endDate
        },
        json: true
    
    Romain CREY's avatar
    Romain CREY committed
      try {
    
        const responseEgl = await rp(dataRequest)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
        switch (responseEgl.codeRetour) {
    
    Romain CREY's avatar
    Romain CREY committed
          case 100:
    
            return format(responseEgl)
    
    Romain CREY's avatar
    Romain CREY committed
          case -2:
    
            throw new Error(errors.LOGIN_FAILED)
    
    Romain CREY's avatar
    Romain CREY committed
          case -1:
    
            throw new Error(errors.VENDOR_DOWN)
    
    Romain CREY's avatar
    Romain CREY committed
          default:
    
            throw new Error(errors.UNKNOWN_ERROR)
    
    Romain CREY's avatar
    Romain CREY committed
        }
      } catch (error) {
    
        throw new Error(errors.VENDOR_DOWN)
    
    Romain CREY's avatar
    Romain CREY committed
      }
    }
    
    function format(response) {
    
      log('info', 'origin response size is : ' + response.resultatRetour.length)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      const data = response.resultatRetour
        .slice(1)
    
        .filter(value => value.ValeurIndex)
      const dataLen = data.length
      log('info', 'filtered size is : ' + dataLen)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
      const mapData = data.map((value, index) => {
    
        const time = moment(value.DateReleve, moment.ISO_8601)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
        if (index + 1 < dataLen) {
    
    Yoan VALLET's avatar
    Yoan VALLET committed
          return {
    
    Yoan VALLET's avatar
    Yoan VALLET committed
            load: data[index + 1].ValeurIndex - value.ValeurIndex,
    
            year: parseInt(time.format('YYYY')),
            month: parseInt(time.format('M')),
            day: parseInt(time.format('D')),
    
    Yoan VALLET's avatar
    Yoan VALLET committed
            hour: 0,
            minute: 0,
            type: value.TypeAgregat
    
    Yoan VALLET's avatar
    Yoan VALLET committed
        } else {
    
          log('info', 'end of data - date is : ' + value.DateReleve)
    
    Yoan VALLET's avatar
    Yoan VALLET committed
          return {
            load: null,
    
            year: parseInt(time.format('YYYY')),
            month: parseInt(time.format('M')),
            day: parseInt(time.format('D')),
    
    Yoan VALLET's avatar
    Yoan VALLET committed
            hour: 0,
            minute: 0,
            type: value.TypeAgregat
    
    Yoan VALLET's avatar
    Yoan VALLET committed
        }
    
      })
      return mapData
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    // function processYearAggregation(data, doctype) {
    //   log("info", "Start aggregation for : " + doctype);
    //   const grouped = data.reduce(reduceYearFunction, {});
    //   return Object.values(grouped);
    // }
    
    // function processMonthlyAggregation(data, range) {
    //   log("info", "Start aggregation for : " + range.doctype);
    //   // Filter by year
    //   const tmpData = groupBy(data, "year");
    //   const keys = Object.keys(tmpData);
    //   var dataToStore = [];
    //   // Monthly aggregation
    //   for (const index in keys) {
    //     // Get daily data of a year
    //     var monthlyData = tmpData[keys[index]];
    //     // Monthly aggregation
    //     var aggregatedData = monthlyData.reduce(reduceMonthFunction, {});
    //     // Store it
    //     dataToStore = dataToStore.concat(Object.values(aggregatedData));
    //   }
    //   return dataToStore;
    // }
    
    // function groupBy(xs, key) {
    //   return xs.reduce(function(rv, x) {
    //     (rv[x[key]] = rv[x[key]] || []).push(x);
    //     return rv;
    //   }, {});
    // }
    
    // function reduceYearFunction(acc, x) {
    //   var id = acc[x.year];
    //   if (id) {
    //     id.load += x.load;
    //   } else {
    //     acc[x.year] = x;
    //   }
    //   return acc;
    // }
    
    // function reduceMonthFunction(acc, x) {
    //   var id = acc[x.month];
    //   if (id) {
    //     id.load += x.load;
    //   } else {
    //     acc[x.month] = x;
    //   }
    //   return acc;
    // }
    
    /**
     * Save data in the right doctype db and prevent duplicated keys
     */
    async function storeData(data, doctype, filterKeys) {
    
      log('debug', 'Store into ' + doctype)
      log('debug', 'Store into keys : ' + filterKeys)
    
      // data.map(v => {
      //   log("info", "Saving data " + v.load + " for " + v.day + "/" + v.month + "/" + v.year);
      // });
    
      const filteredDocuments = await hydrateAndFilter(data, doctype, {
        keys: filterKeys
      })
      return await addData(filteredDocuments, doctype)
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    /**
     * Format an entry for DB storage
     * using key and value
     * For year doctype: key = "YYYY"
     * For month doctype: key = "YYYY-MM"
     */
    async function buildDataFromKey(doctype, key, value) {
      let year, month, day, hour
      if (doctype === 'com.grandlyon.egl.year') {
        year = key
        month = 1
        day = 0
        hour = 0
      } else if (doctype === 'com.grandlyon.egl.month') {
        const split = key.split('-')
        year = split[0]
        month = split[1]
        day = 0
        hour = 0
      } else {
        const split = key.split('-')
        year = split[0]
        month = split[1]
        day = split[2]
        hour = split[3]
      }
      return {
        load: Math.round(value * 10000) / 10000,
        year: parseInt(year),
        month: parseInt(month),
        day: parseInt(day),
        hour: parseInt(hour),
        minute: 0
      }
    }
    
    
    /**
     * Function handling special case.
     * The temporary aggregated data need to be remove in order for the most recent one te be saved.
    
    Yoan VALLET's avatar
    Yoan VALLET committed
     * ex for com.grandlyon.egl.month :
    
     * { load: 76.712, month: 2020, ... } need to be replace by
    
     * { load: 82.212, month: 2020, ... } after egl data reprocess
    
    async function resetInProgressAggregatedData(data, doctype) {
    
      // /!\ Warning: cannot use mongo queries because not supported for dev by cozy-konnectors-libs
    
      log('debug', 'Remove aggregated data for ' + doctype)
      const result = await cozyClient.data.findAll(doctype)
      if (result && result.length > 0) {
    
        // Filter data to remove
    
        var filtered = []
        if (doctype === 'com.grandlyon.egl.year') {
    
          // Yearly case
          filtered = result.filter(function(el) {
    
            return el.year == data.year
          })
        } else if (doctype === 'com.grandlyon.egl.month') {
    
          // Monthly case
    
          filtered = result.filter(function(el) {
            return el.year == data.year && el.month == data.month
          })
        } else {
          // Hourly case
    
          filtered = result.filter(function(el) {
            return (
    
              el.year == data.year &&
              el.month == data.month &&
              el.day == data.day &&
              el.hour == data.hour
            )
          })
    
        }
        // Remove data
    
        let sum = 0.0
    
        for (const doc of filtered) {
    
          sum += doc.load
          log('debug', 'Removing this entry for ' + doc.load)
          await cozyClient.data.delete(doctype, doc)
    
        return sum
    
    Romain CREY's avatar
    Romain CREY committed
      }
    
      return 0.0
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    /***/ }),
    /* 1 */
    /***/ (function(module, exports, __webpack_require__) {
    
    
    const log = __webpack_require__(2).namespace('cozy-konnector-libs');
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const requestFactory = __webpack_require__(22);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const hydrateAndFilter = __webpack_require__(371);
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const categorization = __webpack_require__(1130);
    
    Romain CREY's avatar
    Romain CREY committed
    
    module.exports = {
    
      BaseKonnector: __webpack_require__(1402),
      CookieKonnector: __webpack_require__(1485),
      cozyClient: __webpack_require__(487),
      errors: __webpack_require__(1408),
    
    Romain CREY's avatar
    Romain CREY committed
      log,
    
      saveFiles: __webpack_require__(1404),
      saveBills: __webpack_require__(1403),
      saveIdentity: __webpack_require__(1451),
      linkBankOperations: __webpack_require__(1425),
      addData: __webpack_require__(1424),
    
    Romain CREY's avatar
    Romain CREY committed
      hydrateAndFilter,
    
      htmlToPDF: __webpack_require__(1486).htmlToPDF,
      createCozyPDFDocument: __webpack_require__(1486).createCozyPDFDocument,
    
    Romain CREY's avatar
    Romain CREY committed
      filterData: deprecate(hydrateAndFilter, 'Use hydrateAndFilter now. filterData will be removed in cozy-konnector-libs@4'),
    
      updateOrCreate: __webpack_require__(1450),
    
    Romain CREY's avatar
    Romain CREY committed
      request: deprecate(requestFactory, 'Use requestFactory instead of request. It will be removed in cozy-konnector-libs@4'),
      requestFactory,
    
      retry: __webpack_require__(1405),
      wrapIfSentrySetUp: __webpack_require__(1452).wrapIfSentrySetUp,
      Document: __webpack_require__(1487),
      signin: __webpack_require__(1447),
      submitForm: __webpack_require__(1447),
      scrape: __webpack_require__(1489),
      mkdirp: __webpack_require__(1407),
      normalizeFilename: __webpack_require__(1490),
      utils: __webpack_require__(486),
      solveCaptcha: __webpack_require__(1491),
    
    Romain CREY's avatar
    Romain CREY committed
      createCategorizer: categorization.createCategorizer,
      categorize: categorization.categorize,
    
      manifest: __webpack_require__(845)
    
    Romain CREY's avatar
    Romain CREY committed
    };
    
    function deprecate(wrapped, message) {
      return function () {
        log('warn', message);
        return wrapped.apply(this, arguments);
      };
    }
    
    /***/ }),
    /* 2 */
    /***/ (function(module, exports, __webpack_require__) {
    
    
    const { filterLevel, filterSecrets } = __webpack_require__(3)
    const Secret = __webpack_require__(4)
    const { LOG_LEVEL } = process.env
    
    Romain CREY's avatar
    Romain CREY committed
    let level = LOG_LEVEL || 'debug'
    
    const format = __webpack_require__(5)
    
    Romain CREY's avatar
    Romain CREY committed
    const filters = [filterLevel, filterSecrets]
    
    const filterOut = function() {
      for (const filter of filters) {
        if (filter.apply(null, arguments) === false) {
          return true
        }
      }
      return false
    }
    
    /**
     * Use it to log messages in your konnector. Typical types are
     *
     * - `debug`
     * - `warning`
     * - `info`
     * - `error`
     * - `ok`
     *
     *
     * @example
     *
     * They will be colored in development mode. In production mode, those logs are formatted in JSON to be interpreted by the stack and possibly sent to the client. `error` will stop the konnector.
     *
     * ```js
     * logger = log('my-namespace')
     * logger('debug', '365 bills')
     * // my-namespace : debug : 365 bills
     * logger('info', 'Page fetched')
     * // my-namespace : info : Page fetched
     * ```
     * @param  {string} type
     * @param  {string} message
     * @param  {string} label
     * @param  {string} namespace
     */
    function log(type, message, label, namespace) {
      if (filterOut(level, type, message, label, namespace)) {
        return
      }
      // eslint-disable-next-line no-console
      console.log(format(type, message, label, namespace))
    }
    
    log.addFilter = function(filter) {
      return filters.push(filter)
    }
    
    log.setLevel = function(lvl) {
      level = lvl
    }
    
    // Short-hands
    const methods = ['debug', 'info', 'warn', 'error', 'ok', 'critical']
    methods.forEach(level => {
      log[level] = function(message, label, namespace) {
        return log(level, message, label, namespace)
      }
    })
    
    module.exports = log
    
    log.setNoRetry = obj => {
      if (obj) obj.no_retry = true
      else obj = { no_retry: true }
      return obj.no_retry
    }
    log.Secret = Secret
    log.namespace = function(namespace) {
      return function(type, message, label, ns = namespace) {
        log(type, message, label, ns)
      }
    }
    
    
    /***/ }),
    /* 3 */
    /***/ (function(module, exports, __webpack_require__) {
    
    
    const levels = {
      secret: 0,
      debug: 10,
      info: 20,
      warn: 30,
      error: 40,
      ok: 50,
      critical: 50
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    const Secret = __webpack_require__(4)
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const filterSecrets = function(level, type, message) {
      if (type !== 'secret' && message instanceof Secret) {
        throw new Error('You should log a secret with log.secret')
      }
    }
    
    const filterLevel = function(level, type) {
      return levels[type] >= levels[level]
    }
    
    module.exports = {
      filterSecrets,
      filterLevel
    }
    
    
    /***/ }),
    /* 4 */
    /***/ (function(module, exports) {
    
    const Secret = function(data) {
      Object.assign(this, data)
      return this
    }
    
    Secret.prototype.toString = function() {
      throw new Error('Cannot convert Secret to string')
    }
    
    module.exports = Secret
    
    
    /***/ }),
    /* 5 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const prodFormat = __webpack_require__(6)
    const devFormat = __webpack_require__(8)
    
    switch ("none") {
      case 'production':
        module.exports = prodFormat
        break
      case 'development':
        module.exports = devFormat
        break
      case 'standalone':
        module.exports = devFormat
        break
      case 'test':
        module.exports = devFormat
        break
      default:
        module.exports = prodFormat
    
    Romain CREY's avatar
    Romain CREY committed
    }
    
    
    
    /***/ }),
    /* 6 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const stringify = __webpack_require__(7)
    
    const LOG_LENGTH_LIMIT = 64 * 1024 - 1
    
    
    Romain CREY's avatar
    Romain CREY committed
    function prodFormat(type, message, label, namespace) {
      const log = { time: new Date(), type, label, namespace }
    
      if (typeof message === 'object') {
        if (message && message.no_retry) {
          log.no_retry = message.no_retry
        }
        if (message && message.message) {
          log.message = message.message
        }
      } else {
        log.message = message
      }
    
      // properly display error messages
      if (log.message && log.message.stack) {
        log.message = log.message.stack
      }
    
      // cut the string to avoid a fail in the stack
      let result = log
      try {
        result = stringify(log).substr(0, LOG_LENGTH_LIMIT)
      } catch (err) {
        // eslint-disable-next-line no-console
        console.log(err.message, 'cozy-logger: Failed to convert message to JSON')
      }
      return result
    }
    
    
    module.exports = prodFormat
    
    
    /***/ }),
    /* 7 */
    /***/ (function(module, exports) {
    
    exports = module.exports = stringify
    exports.getSerialize = serializer
    
    function stringify(obj, replacer, spaces, cycleReplacer) {
      return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
    }
    
    function serializer(replacer, cycleReplacer) {
      var stack = [], keys = []
    
      if (cycleReplacer == null) cycleReplacer = function(key, value) {
        if (stack[0] === value) return "[Circular ~]"
        return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]"
      }
    
      return function(key, value) {
        if (stack.length > 0) {
          var thisPos = stack.indexOf(this)
          ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
          ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
          if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value)
        }
        else stack.push(value)
    
        return replacer == null ? value : replacer.call(this, key, value)
      }
    }
    
    
    /***/ }),
    /* 8 */
    /***/ (function(module, exports, __webpack_require__) {
    
    const util = __webpack_require__(9)
    const chalk = __webpack_require__(10)
    
    if (util && util.inspect && util.inspect.defaultOptions) {
      util.inspect.defaultOptions.maxArrayLength = null
      util.inspect.defaultOptions.depth = 2
      util.inspect.defaultOptions.colors = true
    }
    
    const type2color = {
      debug: 'cyan',
      warn: 'yellow',
      info: 'blue',
      error: 'red',
      ok: 'green',
      secret: 'red',
      critical: 'red'
    }
    
    
    Romain CREY's avatar
    Romain CREY committed
    function devFormat(type, message, label, namespace) {
      let formatmessage = message
    
      if (typeof formatmessage !== 'string') {
        formatmessage = util.inspect(formatmessage)
      }
    
      let formatlabel = label ? ` : "${label}" ` : ''
      let formatnamespace = namespace ? chalk.magenta(`${namespace}: `) : ''
    
      let color = type2color[type]
      let formattype = color ? chalk[color](type) : type
    
      return `${formatnamespace}${formattype}${formatlabel} : ${formatmessage}`
    }
    
    
    module.exports = devFormat
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    
    /***/ }),
    /* 9 */
    /***/ (function(module, exports) {
    
    module.exports = require("util");
    
    Romain CREY's avatar
    Romain CREY committed
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    
    const escapeStringRegexp = __webpack_require__(11);
    const ansiStyles = __webpack_require__(12);
    const stdoutColor = __webpack_require__(18).stdout;
    
    Romain CREY's avatar
    Romain CREY committed
    
    
    const template = __webpack_require__(21);
    
    Romain CREY's avatar
    Romain CREY committed
    
    const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
    
    // `supportsColor.level` → `ansiStyles.color[name]` mapping
    const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
    
    // `color-convert` models to exclude from the Chalk API due to conflicts and such
    const skipModels = new Set(['gray']);
    
    const styles = Object.create(null);
    
    function applyOptions(obj, options) {
    	options = options || {};
    
    	// Detect level if not set manually
    	const scLevel = stdoutColor ? stdoutColor.level : 0;
    	obj.level = options.level === undefined ? scLevel : options.level;
    	obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
    }
    
    function Chalk(options) {
    	// We check for this.template here since calling `chalk.constructor()`
    	// by itself will have a `this` of a previously constructed chalk object
    	if (!this || !(this instanceof Chalk) || this.template) {
    		const chalk = {};
    		applyOptions(chalk, options);
    
    		chalk.template = function () {
    			const args = [].slice.call(arguments);
    			return chalkTag.apply(null, [chalk.template].concat(args));
    		};
    
    		Object.setPrototypeOf(chalk, Chalk.prototype);
    		Object.setPrototypeOf(chalk.template, chalk);
    
    		chalk.template.constructor = Chalk;
    
    		return chalk.template;
    	}
    
    	applyOptions(this, options);
    }
    
    // Use bright blue on Windows as the normal blue color is illegible
    if (isSimpleWindowsTerm) {
    	ansiStyles.blue.open = '\u001B[94m';
    }
    
    for (const key of Object.keys(ansiStyles)) {
    	ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
    
    	styles[key] = {
    		get() {
    			const codes = ansiStyles[key];
    			return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
    		}
    	};
    }
    
    styles.visible = {
    	get() {
    		return build.call(this, this._styles || [], true, 'visible');
    	}
    };
    
    ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
    for (const model of Object.keys(ansiStyles.color.ansi)) {
    	if (skipModels.has(model)) {
    		continue;
    	}
    
    	styles[model] = {
    		get() {
    			const level = this.level;
    			return function () {
    				const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
    				const codes = {
    					open,
    					close: ansiStyles.color.close,
    					closeRe: ansiStyles.color.closeRe
    				};
    				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
    			};
    		}
    	};
    }
    
    ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
    for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
    	if (skipModels.has(model)) {
    		continue;
    	}
    
    	const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
    	styles[bgModel] = {
    		get() {
    			const level = this.level;
    			return function () {
    				const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
    				const codes = {
    					open,
    					close: ansiStyles.bgColor.close,
    					closeRe: ansiStyles.bgColor.closeRe
    				};
    				return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
    			};
    		}
    	};
    }
    
    const proto = Object.defineProperties(() => {}, styles);
    
    function build(_styles, _empty, key) {
    	const builder = function () {
    		return applyStyle.apply(builder, arguments);
    	};
    
    	builder._styles = _styles;
    	builder._empty = _empty;
    
    	const self = this;
    
    	Object.defineProperty(builder, 'level', {
    		enumerable: true,
    		get() {
    			return self.level;
    		},
    		set(level) {
    			self.level = level;
    		}
    	});
    
    	Object.defineProperty(builder, 'enabled', {
    		enumerable: true,
    		get() {
    			return self.enabled;
    		},
    		set(enabled) {
    			self.enabled = enabled;
    		}
    	});
    
    	// See below for fix regarding invisible grey/dim combination on Windows
    	builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
    
    	// `__proto__` is used because we must return a function, but there is