Skip to content
Snippets Groups Projects
index.js 7.56 MiB
Newer Older
Hugo NOUTS's avatar
Hugo NOUTS committed
/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ([
/* 0 */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

// @ts-check
const {
  BaseKonnector,
  log,
  hydrateAndFilter,
  addData,
Hugo NOUTS's avatar
Hugo NOUTS committed
} = __webpack_require__(1)
const soapRequest = __webpack_require__(1331)
const moment = __webpack_require__(1373)
__webpack_require__(1510)
const xml2js = __webpack_require__(1513)
const { buildAgregatedData } = __webpack_require__(1554)
Hugo NOUTS's avatar
Hugo NOUTS committed
const {
  parseSgeXmlData,
  formateDataForDoctype,
  parseTags,
  parseValue,
} = __webpack_require__(1555)
build-token's avatar
build-token committed
const {
  consultationMesuresDetailleesMaxPower,
  consultationMesuresDetaillees,
} = __webpack_require__(1556)
  updateBoConsent,
  createBoConsent,
  getBoConsent,
  deleteBoConsent,
} = __webpack_require__(1557)
build-token's avatar
build-token committed
const {
  verifyUserIdentity,
  activateContract,
  verifyContract,
  terminateContract,
  getContractStartDate,
} = __webpack_require__(1595)
const { getAccount, saveAccountData } = __webpack_require__(1604)
const { isLocal } = __webpack_require__(1605)
Hugo NOUTS's avatar
Hugo NOUTS committed
moment.locale('fr') // set the language
moment.tz.setDefault('Europe/Paris') // set the timezone

/*** Connector Constants ***/
const manualExecution =
  process.env.COZY_JOB_MANUAL_EXECUTION === 'true' ? true : false
let startDailyDate = manualExecution
  ? moment().subtract(12, 'month')
  : moment().subtract(6, 'month')
let startDailyDateString = startDailyDate.format('YYYY-MM-DD')
const startLoadDate = moment().subtract(7, 'day')
const endDate = moment()
const endDateString = endDate.format('YYYY-MM-DD')
const ACCOUNT_ID = isLocal() ? 'default_account_id' : 'enedis-sge-grandlyon'
Hugo NOUTS's avatar
Hugo NOUTS committed

module.exports = new BaseKonnector(start)

Hugo SUBTIL's avatar
Hugo SUBTIL 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
 * cozyParameters are static parameters, independents from the account. Most often, it can be a
 * secret api key.
 * @param {fields} fields
 * @param {{secret: fields}} cozyParameters
 */
Hugo NOUTS's avatar
Hugo NOUTS committed
async function start(fields, cozyParameters) {
  log('info', 'Konnector configuration ...')
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  const pointId = parseInt(fields.pointId)
Hugo NOUTS's avatar
Hugo NOUTS committed
  let baseUrl = fields.wso2BaseUrl
  let apiAuthKey = fields.apiToken
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  let contractId = fields.contractId
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  let sgeLogin = fields.sgeLogin
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  let boToken = fields.boToken
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  let boBaseUrl = fields.boBaseUrl
Hugo NOUTS's avatar
Hugo NOUTS committed
  if (cozyParameters && Object.keys(cozyParameters).length !== 0) {
    log('debug', 'Found COZY_PARAMETERS')
    baseUrl = cozyParameters.secret.wso2BaseUrl
    apiAuthKey = cozyParameters.secret.apiToken
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    contractId = cozyParameters.secret.contractId
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    sgeLogin = cozyParameters.secret.sgeLogin
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    boBaseUrl = cozyParameters.secret.boBaseUrl
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    boToken = cozyParameters.secret.boToken
Hugo NOUTS's avatar
Hugo NOUTS committed
  }
  // Prevent missing configuration
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  if (
    !baseUrl ||
    !apiAuthKey ||
    !contractId ||
    !sgeLogin ||
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    !boToken ||
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    !boBaseUrl
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  ) {
    log('error', `Missing configuration secrets`)
    throw errors.VENDOR_DOWN
  }

  /**
   * If it's first start we have to do the following operations:
   * - verify pdl are matching
   * - BO: create backoffice consent
   * - get contract start date and store it
   * - activate half-hour
   * - BO: update consent with service ID
   */
  log('info', 'User Logging...')

build-token's avatar
build-token committed
  if (isFirstStart(await getAccount(ACCOUNT_ID))) {
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    const user = await verifyUserIdentity(fields, baseUrl, apiAuthKey, sgeLogin)

    let consent = await createBoConsent(
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      boBaseUrl,
      boToken,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      pointId,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      user.lastname,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      user.firstname,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      user.address,
      user.postalCode,
      user.inseeCode
    )
Hugo SUBTIL's avatar
Hugo SUBTIL committed

    // handle user contract start date in order to preperly request data
    const userContractstartDate = await getContractStartDate(
      baseUrl,
      apiAuthKey,
      sgeLogin,
      pointId
    )
    startDailyDate = moment(userContractstartDate, 'YYYY-MM-DD')
    startDailyDateString = startDailyDate.format('YYYY-MM-DD')
Hugo SUBTIL's avatar
Hugo SUBTIL committed

    const contractStartDate = moment().format('YYYY-MM-DD')
    const contractEndDate = moment()
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      .add(1, 'year') // SGE force 1 year duration
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      .format('YYYY-MM-DD')

    let serviceId = await verifyContract(
      baseUrl,
      apiAuthKey,
      sgeLogin,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      contractId,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      user.pointId
    )
    if (!serviceId) {
      serviceId = await activateContract(
        baseUrl,
        apiAuthKey,
        sgeLogin,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
        contractId,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
        user.lastname,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
        user.pointId,
        contractStartDate,
        contractEndDate
      )
    }
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    consent = await updateBoConsent(
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      boBaseUrl,
      boToken,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      consent,
      serviceId.toString()
    )
    console.log(consent)
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    // Save bo id into account
    const accountData = await getAccount(ACCOUNT_ID)

    await saveAccountData(this.accountId, {
      ...accountData.data,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      consentId: consent.ID,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    // AlternateStart
    const accountData = await getAccount(ACCOUNT_ID)
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    const userConsent = await getBoConsent(
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      boBaseUrl,
      boToken,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      accountData.data.consentId
    )
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    const user = await verifyUserIdentity(
      fields,
      baseUrl,
      apiAuthKey,
      sgeLogin,
      true
    )
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    if (!userConsent) {
      log('error', 'No user consent found')
      throw errors.VENDOR_DOWN
    }

    const consentEndDate = Date.parse(userConsent.endDate)
    const today = Date.now()
    if (
      user.lastname.toLocaleUpperCase() !==
        userConsent.lastname.toLocaleUpperCase() ||
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      !user ||
      consentEndDate < today
Hugo SUBTIL's avatar
Hugo SUBTIL committed
      await deleteConsent(
        userConsent,
        baseUrl,
        apiAuthKey,
        sgeLogin,
        contractId,
        pointId,
        boBaseUrl,
        boToken
      )
Hugo NOUTS's avatar
Hugo NOUTS committed
  log('info', 'Successfully logged in')

  await gatherData(baseUrl, apiAuthKey, sgeLogin, pointId)
Hugo SUBTIL's avatar
Hugo SUBTIL committed
/**
 * Delete User Consent
 * @param {Consent} userConsent
 * @param {string} baseUrl
 * @param {string} apiAuthKey
 * @param {string} sgeLogin
 * @param {string} contractId
 * @param {number} pointId
 * @param {string} boBaseUrl
 * @param {string} boToken
 */
async function deleteConsent(
  userConsent,
  baseUrl,
  apiAuthKey,
  sgeLogin,
  contractId,
  pointId,
  boBaseUrl,
  boToken
) {
  log('error', `Invalid or not found consent for user`)
  if (userConsent.serviceID) {
    await terminateContract(
      baseUrl,
      apiAuthKey,
      sgeLogin,
      contractId,
      pointId,
      userConsent.serviceID
    )
build-token's avatar
build-token committed
    await deleteBoConsent(boBaseUrl, boToken, userConsent.ID || 0)
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  } else {
    log('error', `No service id retrieved from BO`)
    throw errors.VENDOR_DOWN
  }
  throw errors.TERMS_VERSION_MISMATCH
}

/**
 * Main method for gathering data
 * @param {string} baseUrl
 * @param {string} apiAuthKey
Hugo SUBTIL's avatar
Hugo SUBTIL committed
 * @param {string} sgeLogin
 * @param {number} pointId
 */
Hugo SUBTIL's avatar
Hugo SUBTIL committed
async function gatherData(baseUrl, apiAuthKey, sgeLogin, pointId) {
Hugo NOUTS's avatar
Hugo NOUTS committed
  log('info', 'Querying data...')
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  await getContractStartDate(baseUrl, apiAuthKey, sgeLogin, pointId)
Hugo NOUTS's avatar
Hugo NOUTS committed
  await getData(
    `${baseUrl}/enedis_SGE_ConsultationMesuresDetaillees/1.0`,
    apiAuthKey,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    sgeLogin,
Hugo NOUTS's avatar
Hugo NOUTS committed
  )
  await getMaxPowerData(
    `${baseUrl}/enedis_SGE_ConsultationMesuresDetaillees/1.0`,
    apiAuthKey,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    sgeLogin,
Hugo NOUTS's avatar
Hugo NOUTS committed
  )
  await getDataHalfHour(
    `${baseUrl}/enedis_SGE_ConsultationMesuresDetaillees/1.0`,
    apiAuthKey,
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    sgeLogin,
Hugo NOUTS's avatar
Hugo NOUTS committed
  )
  log('info', 'Querying data: done')
}
Hugo NOUTS's avatar
Hugo NOUTS committed
/**
 * Get hour data
 * @param {string} url
 * @param {string} apiAuthKey
 * @param {string} userLogin
 * @param {number} pointId
 */
async function getData(url, apiAuthKey, userLogin, pointId) {
  log('info', 'Fetching data')
Hugo NOUTS's avatar
Hugo NOUTS committed
    'Content-Type': 'text/xml;charset=UTF-8',
    apikey: apiAuthKey,
  }

  setStartDate()

  const { response } = await soapRequest({
    url: url,
    xml: consultationMesuresDetaillees(
Hugo NOUTS's avatar
Hugo NOUTS committed
      pointId,
      userLogin,
      startDailyDateString,
Hugo NOUTS's avatar
Hugo NOUTS committed
    ),
  }).catch(err => {
    log('error', 'consultationMesuresDetaillees')
Hugo NOUTS's avatar
Hugo NOUTS committed
    log('error', err)
    return err
  })

  xml2js.parseString(
    response.body,
    {
      tagNameProcessors: [parseTags],
      valueProcessors: [parseValue],
      explicitArray: false,
    },
    processData()
  )
}

/**
 * Get Max power data
 * @param {string} url
 * @param {string} apiAuthKey
 * @param {string} userLogin
 * @param {number} pointId
 */
async function getMaxPowerData(url, apiAuthKey, userLogin, pointId) {
  log('info', 'Fetching Max Power data')
Hugo NOUTS's avatar
Hugo NOUTS committed
    'Content-Type': 'text/xml;charset=UTF-8',
    apikey: apiAuthKey,
  }

  setStartDate()

  const { response } = await soapRequest({
    url: url,
    xml: consultationMesuresDetailleesMaxPower(
      pointId,
      userLogin,
      startDailyDateString,
      endDateString
    ),
Hugo NOUTS's avatar
Hugo NOUTS committed
  }).catch(err => {
    log('error', 'getMaxPowerData')
    log('error', err)
    return err
  })

  xml2js.parseString(
    response.body,
    {
      tagNameProcessors: [parseTags],
      valueProcessors: [parseValue],
      explicitArray: false,
    },
    processData('com.grandlyon.enedis.maxpower')
  )
}

/**
 * If start date exceed the maximum amount of data we can get with one query
 * get only 36 month
 */
function setStartDate() {
  if (moment(endDate).diff(startDailyDate, 'months', true) > 36) {
    log(
      'info',
      'Start date exceed 36 month, setting start date to current date minus 36 month'
    )
    startDailyDate = moment(endDate).subtract(36, 'month')
    startDailyDateString = startDailyDate.format('YYYY-MM-DD')
  }
}

/**
 * Get half-hour data
 * @param {string} url
 * @param {string} apiAuthKey
 * @param {string} userLogin
 * @param {number} pointId
 */
async function getDataHalfHour(url, apiAuthKey, userLogin, pointId) {
  log('info', 'Fetching data')
Hugo NOUTS's avatar
Hugo NOUTS committed
    'Content-Type': 'text/xml;charset=UTF-8',
    apikey: apiAuthKey,
  }

  let MAX_HISTO = 4
  // If manual execution, retrieve only 1 week
  if (manualExecution) {
    MAX_HISTO = 1
  }
  for (var i = 0; i < MAX_HISTO; i++) {
    log('info', 'launch process with history')
    const increamentedStartDateString = moment(startLoadDate)
      .subtract(7 * i, 'day')
      .format('YYYY-MM-DD')
    const incrementedEndDateString = moment(endDate)
      .subtract(7 * i, 'day')
      .format('YYYY-MM-DD')
Hugo NOUTS's avatar
Hugo NOUTS committed
    const { response } = await soapRequest({
      url: url,
      xml: consultationMesuresDetaillees(
Hugo NOUTS's avatar
Hugo NOUTS committed
        pointId,
        userLogin,
        increamentedStartDateString,
        incrementedEndDateString,
        'COURBE',
        'PA'
      ),
    }).catch(err => {
      log('error', 'consultationMesuresDetaillees half-hour')
Hugo NOUTS's avatar
Hugo NOUTS committed
      log('error', err)
      return err
    })

    xml2js.parseString(
      response.body,
      {
        tagNameProcessors: [parseTags],
        valueProcessors: [parseValue],
        explicitArray: false,
      },
      processData('com.grandlyon.enedis.minute')
    )
  }
}

/**
 * Parse data
 * @param {string} doctype
 * @returns
 */
function processData(doctype = 'com.grandlyon.enedis.day') {
  return async (err, result) => {
    if (err) {
      log('error', err)
      throw err
    }
    // Return only needed part of info
    log('info', doctype)
    try {
      const data = parseSgeXmlData(result)
      const processedDailyData = await storeData(
        await formateDataForDoctype(data),
        doctype,
        ['year', 'month', 'day', 'hour', 'minute']
      )
Hugo NOUTS's avatar
Hugo NOUTS committed

      log('info', 'Agregate enedis daily data for month and year')
      if (doctype === 'com.grandlyon.enedis.day') {
        log('info', 'Agregating...')
        await agregateMonthAndYearData(processedDailyData)
      }
    } catch (e) {
      if (doctype === 'com.grandlyon.enedis.minute') {
Hugo SUBTIL's avatar
Hugo SUBTIL committed
        log(
          'warn',
          `No half-hour activated. Issue: ${result.Envelope.Body.Fault.faultstring}`
        )
      } else {
        log('error', `Unkown error ${e}`)
      }
Hugo NOUTS's avatar
Hugo NOUTS committed
    }
  }
}

/**
 * Save data in the right doctype db and prevent duplicated keys
 * @param {EnedisKonnectorData[]} data
 * @param {string} doctype
 * @param {string[]} filterKeys
 * @returns {Promise<*>}
 */
async function storeData(data, doctype, filterKeys) {
  log('debug', doctype, 'Store into')
  const filteredDocuments = await hydrateAndFilter(data, doctype, {
    keys: filterKeys,
  })
  await addData(filteredDocuments, doctype)
  return filteredDocuments
}

/**
 * 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.enedis.month'
    )
    await storeData(agregatedMonthData, 'com.grandlyon.enedis.month', [
      'year',
      'month',
    ])
    // Agregation for Year data
    const agregatedYearData = await buildAgregatedData(
      yearData,
      'com.grandlyon.enedis.year'
    )
    await storeData(agregatedYearData, 'com.grandlyon.enedis.year', ['year'])
  }
}

/**
 * @returns {boolean}
 */
Hugo SUBTIL's avatar
Hugo SUBTIL committed
function isFirstStart(account) {
build-token's avatar
build-token committed
  if (account && account.data && account.data.consentId) {
Hugo SUBTIL's avatar
Hugo SUBTIL committed
    log('info', 'Konnector not first start')
    return false
Hugo SUBTIL's avatar
Hugo SUBTIL committed
  log('info', 'Konnector first start')
  return true
Hugo NOUTS's avatar
Hugo NOUTS committed

/***/ }),
/* 1 */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const requestFactory = __webpack_require__(2);

const hydrateAndFilter = __webpack_require__(353);
Hugo NOUTS's avatar
Hugo NOUTS committed

const categorization = __webpack_require__(1226);
Hugo NOUTS's avatar
Hugo NOUTS committed

const log = __webpack_require__(1243);
Hugo NOUTS's avatar
Hugo NOUTS committed

module.exports = {
  BaseKonnector: __webpack_require__(1244),
  CookieKonnector: __webpack_require__(1324),
  cozyClient: __webpack_require__(485),
  errors: __webpack_require__(1250),
Hugo NOUTS's avatar
Hugo NOUTS committed
  log,
  saveFiles: __webpack_require__(1246),
  saveBills: __webpack_require__(1245),
  saveIdentity: __webpack_require__(1290),
  linkBankOperations: __webpack_require__(1267),
  addData: __webpack_require__(1266),
Hugo NOUTS's avatar
Hugo NOUTS committed
  hydrateAndFilter,
  htmlToPDF: (__webpack_require__(1325).htmlToPDF),
  createCozyPDFDocument: (__webpack_require__(1325).createCozyPDFDocument),
Hugo NOUTS's avatar
Hugo NOUTS committed
  filterData: deprecate(hydrateAndFilter, 'Use hydrateAndFilter now. filterData will be removed in cozy-konnector-libs@4'),
  updateOrCreate: __webpack_require__(1289),
Hugo NOUTS's avatar
Hugo NOUTS committed
  request: deprecate(requestFactory, 'Use requestFactory instead of request. It will be removed in cozy-konnector-libs@4'),
  requestFactory,
  retry: __webpack_require__(1247),
  wrapIfSentrySetUp: (__webpack_require__(1291).wrapIfSentrySetUp),
  Document: __webpack_require__(1326),
  signin: __webpack_require__(1286),
  submitForm: __webpack_require__(1286),
  scrape: __webpack_require__(1328),
  mkdirp: __webpack_require__(1249),
  normalizeFilename: __webpack_require__(1329),
  solveCaptcha: __webpack_require__(1330),
Hugo NOUTS's avatar
Hugo NOUTS committed
  createCategorizer: categorization.createCategorizer,
  categorize: categorization.categorize,
  manifest: __webpack_require__(909)
Hugo NOUTS's avatar
Hugo NOUTS committed
};

function deprecate(wrapped, message) {
  return function () {
    log('warn', message);
    return wrapped.apply(this, arguments);
  };
}

/***/ }),
/* 2 */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(3)["default"];

/***/ }),
/* 3 */
/***/ ((module, exports, __webpack_require__) => {

/**
 * This is a function which returns an instance of
 * [request-promise](https://www.npmjs.com/package/request-promise) initialized with
 * defaults often used in connector development.
 *
 * ```js
 * // Showing defaults
 * req = requestFactory({
 *   cheerio: false,
 *   jar: true,
 *   json: true
 * })
 * ```
 *
 * Options :
 *
 * - `cheerio`:  will parse automatically the `response.body` in a cheerio instance
 *
 * ```javascript
 * req = requestFactory({ cheerio: true })
 * req('http://github.com', $ => {
 *   const repos = $('#repo_listing .repo')
 * })
 * ```
 *
 * - `jar`: is passed to `request` options. Remembers cookies for future use.
 * - `json`: will parse the `response.body` as JSON
 * - `resolveWithFullResponse`: The full response will be return in the promise. It is compatible
 *   with cheerio and json options.
 *
 * ```javascript
 * req = requestFactory({
 *    resolveWithFullResponse: true,
 *    cheerio: true
 * })
 * req('http://github.com', response => {
 *   console.log(response.statusCode)
 *   const $ = response.body
 *   const repos = $('#repo_listing .repo')
 * })
 * ```
 * - `debug`: will display request and responses details in error output. Possible values :
 *   true : display request and response in normal request-debug json format
 *   'json' : display request and response in full json format
 *   'simple' : display main information about each request and response
 *   ```
 *   GET -> http://books.toscrape.com/media/cache/26/0c/260c6ae16bce31c8f8c95daddd9f4a1c.jpg
 *   <- 200  Content-Length: 7095
 *   ```
 *   'full' : display comple information about each request and response
 *   ```
 *   GET -> http://quotes.toscrape.com/login
 *
 *   BEGIN HEADERS
 *   host: quotes.toscrape.com
 *   END HEADERS
 *
 *   <- 200  Content-Length: 1869
 *
 *   BEGIN HEADERS
 *   server: nginx/1.12.1
 *   ...
 *   END HEADERS
 *
 *   BEGIN BODY
 *   <html>....
 *   END BODY
 *   ```
 *
 * You can find the full list of available options in [request-promise](https://github.com/request/request-promise) and [request](https://github.com/request/request) documentations.
 *
 * @module requestFactory
 */
let request = __webpack_require__(4);

const requestdebug = __webpack_require__(254); // Quickly found more UserAgent here
Hugo NOUTS's avatar
Hugo NOUTS committed
// https://www.whatismybrowser.com/guides/the-latest-user-agent/


const AGENTS_LIST = ['Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11.1; rv:84.0) Gecko/20100101 Firefox/84.0', 'Mozilla/5.0 (X11; Linux i686; rv:84.0) Gecko/20100101 Firefox/84.0', 'Mozilla/5.0 (Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0', 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:84.0) Gecko/20100101 Firefox/84.0', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Edg/87.0.664.75', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Edg/87.0.664.75'];
const DEFAULT_USER_AGENT = AGENTS_LIST[Math.floor(Math.random() * AGENTS_LIST.length)];
exports = module.exports = {
  default: requestFactory,
  mergeDefaultOptions,
  transformWithCheerio,
  getRequestOptions,
  DEFAULT_USER_AGENT
};

function requestFactory({
  debug,
  ...options
} = {
  debug: false
}) {
  const logFn = setDebugFunction(debug);
  debug && requestdebug(request, logFn);
  return request.defaults(getRequestOptions(mergeDefaultOptions(options)));
}

function setDebugFunction(debug) {
  /* eslint no-console: off */
  if (debug === 'simple') {
    return (type, data) => console.error(requestToStrings(type, data).oneline);
  } else if (debug === 'json') {
    return (type, data) => console.error(JSON.stringify({
      type,
      data
    }));
  } else if (debug === 'full') {
    return (type, data) => {
      const {
        oneline,
        headers,
        body
      } = requestToStrings(type, data);
      console.error(`${oneline}

BEGIN HEADERS
${headers}
END HEADERS

` + (body ? `BEGIN BODY
${body}
END BODY

` : ''));
    };
  } else if (typeof debug === 'function') {
    return (type, data, resp) => debug({
      strings: requestToStrings(type, data),
      type,
      data,
      resp
    });
  }
}

function requestToStrings(type, data) {
  const result = {};

  if (type === 'request') {
    result.oneline = `${data.method} -> ${data.uri} ${data.headers['content-length'] ? 'Content-Length: ' + data.headers['content-length'] : ''}`;
  } else if (type === 'response') {
    result.oneline = `<- ${data.statusCode}  ${data.headers['content-length'] ? 'Content-Length: ' + data.headers['content-length'] : ''}`;
  } else {
    result.oneline = `<- ${data.statusCode} ${data.uri}`;
  }

  result.headers = Object.keys(data.headers).map(key => `${key}: ${data.headers[key]}`).join('\n');
  result.body = data.body;
  return result;
}

function mergeDefaultOptions(options = {}) {
  const defaultOptions = {
    debug: false,
    json: true,
    cheerio: false,
    headers: {},
    followAllRedirects: true
  };

  if (options.cheerio === true) {
    options.json = false;
  }

  return { ...defaultOptions,
    ...options
  };
}

function transformWithCheerio(body, response, resolveWithFullResponse) {
  const result = (__webpack_require__(256).load)(body);
Hugo NOUTS's avatar
Hugo NOUTS committed

  if (resolveWithFullResponse) {
    return { ...response,
      body: result
    };
  }

  return result;
}

function getRequestOptions({
  cheerio,
  userAgent,
  ...options
}) {
  const userAgentOption = options.headers['User-Agent'];
  return cheerio ? { ...options,
    transform: transformWithCheerio,
    headers: { ...options.headers,
      'User-Agent': userAgentOption ? userAgentOption : userAgent === false ? undefined : DEFAULT_USER_AGENT
    }
  } : { ...options,
    headers: { ...options.headers,
      'User-Agent': userAgent ? DEFAULT_USER_AGENT : options.headers['User-Agent']
    }
  };
}

/***/ }),
/* 4 */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";
/* module decorator */ module = __webpack_require__.nmd(module);


var Bluebird = (__webpack_require__(5).getNewLibraryCopy)(),
    configure = __webpack_require__(42),
    stealthyRequire = __webpack_require__(57);

try {

    // Load Request freshly - so that users can require an unaltered request instance!
    var request = stealthyRequire(__webpack_require__.c, function () {
        return __webpack_require__(58);
    },
    function () {
        __webpack_require__(61);
    }, module);

} catch (err) {
    /* istanbul ignore next */
    var EOL = (__webpack_require__(253).EOL);
Hugo NOUTS's avatar
Hugo NOUTS committed
    /* istanbul ignore next */
    console.error(EOL + '###' + EOL + '### The "request" library is not installed automatically anymore.' + EOL + '### But is a dependency of "request-promise".' + EOL + '### Please install it with:' + EOL + '### npm install request --save' + EOL + '###' + EOL);
    /* istanbul ignore next */
    throw err;
}

Bluebird.config({cancellation: true});

configure({
    request: request,
    PromiseImpl: Bluebird,
    expose: [
        'then',
        'catch',
        'finally',
        'cancel',
        'promise'
        // Would you like to expose more Bluebird methods? Try e.g. `rp(...).promise().tap(...)` first. `.promise()` returns the full-fledged Bluebird promise.
    ],
    constructorMixin: function (resolve, reject, onCancel) {
        var self = this;
        onCancel(function () {
            self.abort();
        });
    }
});

request.bindCLS = function RP$bindCLS() {
    throw new Error('CLS support was dropped. To get it back read: https://github.com/request/request-promise/wiki/Getting-Back-Support-for-Continuation-Local-Storage');
};


module.exports = request;


/***/ }),
/* 5 */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var old;
if (typeof Promise !== "undefined") old = Promise;
function noConflict() {
    try { if (Promise === bluebird) Promise = old; }
    catch (e) {}
    return bluebird;
}
var bluebird = __webpack_require__(6)();
bluebird.noConflict = noConflict;
module.exports = bluebird;


/***/ }),
/* 6 */
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

module.exports = function() {
var makeSelfResolutionError = function () {
    return new TypeError("circular promise resolution chain\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
};
var reflectHandler = function() {
    return new Promise.PromiseInspection(this._target());
};
var apiRejection = function(msg) {
    return Promise.reject(new TypeError(msg));
};
function Proxyable() {}
var UNDEFINED_BINDING = {};
var util = __webpack_require__(7);
util.setReflectHandler(reflectHandler);

var getDomain = function() {
    var domain = process.domain;
    if (domain === undefined) {
        return null;
    }
    return domain;
};
var getContextDefault = function() {
    return null;
};
var getContextDomain = function() {
    return {
        domain: getDomain(),
        async: null
    };
};
var AsyncResource = util.isNode && util.nodeSupportsAsyncResource ?
    (__webpack_require__(9).AsyncResource) : null;
var getContextAsyncHooks = function() {
    return {
        domain: getDomain(),
        async: new AsyncResource("Bluebird::Promise")
    };
};
var getContext = util.isNode ? getContextDomain : getContextDefault;
util.notEnumerableProp(Promise, "_getContext", getContext);
var enableAsyncHooks = function() {
    getContext = getContextAsyncHooks;
    util.notEnumerableProp(Promise, "_getContext", getContextAsyncHooks);
};
var disableAsyncHooks = function() {
    getContext = getContextDomain;
    util.notEnumerableProp(Promise, "_getContext", getContextDomain);
};

var es5 = __webpack_require__(8);
var Async = __webpack_require__(10);
var async = new Async();
es5.defineProperty(Promise, "_async", {value: async});
var errors = __webpack_require__(13);
var TypeError = Promise.TypeError = errors.TypeError;
Promise.RangeError = errors.RangeError;
var CancellationError = Promise.CancellationError = errors.CancellationError;
Promise.TimeoutError = errors.TimeoutError;
Promise.OperationalError = errors.OperationalError;
Promise.RejectionError = errors.OperationalError;
Promise.AggregateError = errors.AggregateError;
var INTERNAL = function(){};
var APPLY = {};
var NEXT_FILTER = {};
var tryConvertToPromise = __webpack_require__(14)(Promise, INTERNAL);
var PromiseArray =
    __webpack_require__(15)(Promise, INTERNAL,
                               tryConvertToPromise, apiRejection, Proxyable);
var Context = __webpack_require__(16)(Promise);
 /*jshint unused:false*/
var createContext = Context.create;

var debug = __webpack_require__(17)(Promise, Context,
    enableAsyncHooks, disableAsyncHooks);
var CapturedTrace = debug.CapturedTrace;
var PassThroughHandlerContext =
    __webpack_require__(18)(Promise, tryConvertToPromise, NEXT_FILTER);
var catchFilter = __webpack_require__(19)(NEXT_FILTER);
var nodebackForPromise = __webpack_require__(20);
var errorObj = util.errorObj;
var tryCatch = util.tryCatch;
function check(self, executor) {
    if (self == null || self.constructor !== Promise) {
        throw new TypeError("the promise constructor cannot be invoked directly\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
    }
    if (typeof executor !== "function") {
        throw new TypeError("expecting a function but got " + util.classString(executor));
    }

}

function Promise(executor) {
    if (executor !== INTERNAL) {
        check(this, executor);
    }
    this._bitField = 0;
    this._fulfillmentHandler0 = undefined;
    this._rejectionHandler0 = undefined;
    this._promise0 = undefined;
    this._receiver0 = undefined;