{"version":3,"sources":["jsdelivr-header.js","/npm/gtmetrix@1.3.0/index.js"],"names":[],"mappings":"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","file":"/npm/gtmetrix@1.3.0/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/gtmetrix@1.3.0/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","const { doRequest } = require ('httpreq');\nconst { promisify } = require ('es6-promisify');\n\n\n// Default config\nconst defaults = {\n  email: null,\n  apikey: null,\n  timeout: 5000\n};\n\nlet pkg = {\n  test: {\n    get: null\n  },\n  locations: {},\n  browsers: {},\n  account: {}\n};\n\nlet config = {};\n\n\n/**\n * Get info about resource type\n *\n * @param   {string}  name  The resource name\n * @return  {object}        Resource info object\n */\n\nfunction resourceType (name) {\n  let info = {\n    binary: false,\n    path: name.replace ('_', '-')\n  };\n\n  if (info.path.match (/^(filmstrip|pagespeed-files|report-pdf(-full)?|screenshot|video)$/)) {\n    info.binary = true;\n  }\n\n  if (info.path === 'report-pdf-full') {\n    info.path = 'report-pdf?full=1';\n  }\n\n  return info;\n}\n\n\n/**\n * Make an error\n *\n * @return  {Error}\n *\n * @param   {string}       msg   Error.message\n * @param   {mixed}        err   Error.error\n * @param   {number|null}  code  Error.statusCode\n * @param   {string|null}  type  Error.contentType\n */\n\nfunction doError (msg, err, code, type) {\n  let error = new Error (msg);\n\n  error.error = err;\n  error.statusCode = code;\n  error.contentType = type;\n  return error;\n}\n\n\n/**\n * Process API response\n *\n * @callback  callback\n * @return    {void}\n *\n * @param     {object}      options   httpreq options\n * @param     {Error|null}  err       httpreq Error\n * @param     {object}      res       httpreq response\n * @param     {function}    callback  `(err, data)`\n */\n\nfunction apiResponse (options, err, res, callback) {\n  let type;\n  let size;\n  let code;\n  let data;\n  let error = null;\n\n  if (err) {\n    error = doError ('request failed', err, null, null);\n    callback (error);\n    return;\n  }\n\n  type = String (res.headers ['content-type']) .split (';') [0];\n  size = String (res.headers ['content-length']);\n  code = res.statusCode;\n  data = res.body;\n\n  // Received data, expecting binary\n  if (size && options.binary && type.match (/\\/(pdf|jpeg|tar)$/)) {\n    callback (null, data);\n    return;\n  }\n\n  // Received something else\n  try {\n    data = JSON.parse (data);\n\n    if (data.error) {\n      error = doError ('API error', data.error, code, type);\n      callback (error);\n      return;\n    }\n  } catch (e) {\n    error = doError ('invalid response', e, code, type);\n    callback (error);\n    return;\n  }\n\n  // It's real data\n  callback (null, data);\n}\n\n\n/**\n * Send API request\n *\n * @callback  callback\n * @return    {void}\n *\n * @param     {object}    props\n * @param     {boolean}   [props.binary=false]  Expect binary response\n * @param     {string}    props.method          HTTP method\n * @param     {object}    [props.params]        Method parameters\n * @param     {string}    props.path            Method path\n * @param     {function}  callback              `(err, data)`\n */\n\nfunction apiRequest (props, callback) {\n  const options = {\n    url: 'https://gtmetrix.com/api/0.1/' + props.path,\n    parameters: props.params || null,\n    method: props.method,\n    headers: {\n      'User-Agent': 'gtmetrix.js (https://www.npmjs.com/package/gtmetrix)'\n    },\n    timeout: parseInt (config.timeout, 10) || defaults.timeout,\n    auth: config.email + ':' + config.apikey,\n    binary: props.binary || false\n  };\n\n  doRequest (options, (err, res) => {\n    apiResponse (options, err, res, callback);\n  });\n}\n\n\n/**\n * Create test\n *\n * @callback  callback\n * @return    {Promise<object>}\n *\n * @param     {object}    params\n * @param     {function}  [callback]  `(err, data)`\n */\n\npkg.test.create = promisify ((params, callback) => {\n  const props = {\n    method: 'POST',\n    path: 'test',\n    params: params\n  };\n\n  apiRequest (props, callback);\n});\n\n\n/**\n * Process callback when polling\n *\n * @callback  callback\n * @return    {boolean}               Stop polling? true = yes\n *\n * @param     {object}      props     Request properties\n * @param     {Error|null}  err       Response error\n * @param     {object}      data      Response data\n * @param     {function}    callback  `(err, data)`\n */\n\nfunction pollingCallback (props, err, data, callback) {\n  // API error saying we need to wait\n  if (err && String (err.error).match (/Data not yet available/)) {\n    return false;\n  }\n\n  // Another API error\n  if (err) {\n    callback (err);\n    return true;\n  }\n\n  // No API error, binary expected = ok complete\n  if (props.binary) {\n    callback (null, data);\n    return true;\n  }\n\n  // No error, non-binary, not running = ok complete\n  if (!String (data.state).match (/^(started|queued)$/)) {\n    callback (null, data);\n    return true;\n  }\n\n  // else keep polling\n  return false;\n}\n\n\n/**\n * Process test response\n *\n * @callback  callback\n * @return    {void}\n *\n * @param     {object}      params\n * @param     {bool}        params.polling   Keep polling for updates\n * @param     {string}      params.testId    Test ID\n * @param     {string}      params.resource  Test resource\n * @param     {object}      params.props     Request params\n * @param     {Error|null}  err              Response error\n * @param     {mixed}       data             Response data\n * @param     {function}    callback         `(err, data)`\n */\n\nfunction testResponse (params, err, data, callback) {\n  let retryInterval;\n  let complete;\n\n  if (err && !params.polling) {\n    callback (err);\n    return;\n  }\n\n  if (!params.polling) {\n    callback (null, data);\n    return;\n  }\n\n  if (params.polling === true) {\n    params.polling = 5000;\n  }\n\n  if (typeof params.polling === 'number') {\n    complete = pollingCallback (params.props, err, data, callback);\n\n    if (complete) {\n      return;\n    }\n\n    // Test is still running\n    retryInterval = setInterval (() => {\n      pkg.test.get (params.testId, params.resource, (pErr, pData) => {\n        const pComplete = pollingCallback (params.props, pErr, pData, callback);\n\n        if (pComplete) {\n          clearInterval (retryInterval);\n        }\n      });\n    }, params.polling);\n  }\n}\n\n\n/**\n * Get test result\n *\n * @callback  callback\n * @return    {Promise<object>}\n *\n * @param     {string}    testId      Test ID\n * @param     {string}    [resource]  Resource to get, i.e. `screenshot`\n * @param     {number}    [polling]   Poll state until completion, in ms\n * @param     {function}  [callback]  `(err, data)`\n */\n\npkg.test.get = promisify ((testId, resource, polling, callback) => {\n  let resourceInfo = {};\n  let params = {\n    testId,\n    resource,\n    polling,\n    props: {\n      method: 'GET',\n      path: 'test/' + testId\n    }\n  };\n\n  if (typeof polling === 'function') {\n    callback = polling;\n    params.polling = null;\n  }\n\n  switch (typeof resource) {\n    case 'function':\n      callback = resource;\n      params.resource = null;\n      params.polling = null;\n      break;\n\n    case 'number':\n      params.polling = resource;\n      params.resource = null;\n      break;\n\n    case 'string':\n      resourceInfo = resourceType (resource);\n      params.props.path += '/' + resourceInfo.path;\n      params.props.binary = resourceInfo.binary;\n      break;\n\n    default:\n      break;\n  }\n\n  apiRequest (params.props, (err, data) => {\n    testResponse (params, err, data, callback);\n  });\n});\n\n\n/**\n * List locations\n *\n * @callback  callback\n * @return    {Promise<object>}\n *\n * @param     {function}  [callback]  `(err, data)`\n */\n\npkg.locations.list = promisify ((callback) => {\n  const props = {\n    method: 'GET',\n    path: 'locations'\n  };\n\n  apiRequest (props, callback);\n});\n\n\n/**\n * List browsers\n *\n * @callback  callback\n * @return    {Promise<object>}\n *\n * @param     {function}  [callback]  `(err, data)`\n */\n\npkg.browsers.list = promisify ((callback) => {\n  const props = {\n    method: 'GET',\n    path: 'browsers'\n  };\n\n  apiRequest (props, callback);\n});\n\n\n/**\n * Get browser\n *\n * @callback  callback\n * @return    {Promise<object>}\n *\n * @param     {string}    browserId\n * @param     {function}  [callback]  `(err, data)`\n */\n\npkg.browsers.get = promisify ((browserId, callback) => {\n  const props = {\n    method: 'GET',\n    path: 'browsers/' + browserId\n  };\n\n  apiRequest (props, callback);\n});\n\n\n/**\n * Get account status\n *\n * @callback  callback\n * @return    {Promise<object>}\n *\n * @param     {function}  [callback]  `(err, data)`\n */\n\npkg.account.status = promisify ((callback) => {\n  const props = {\n    method: 'GET',\n    path: 'status'\n  };\n\n  apiRequest (props, callback);\n});\n\n\n/**\n * Module interface\n *\n * @return  {object}                        Methods\n *\n * @param   {object}  props\n * @param   {string}  props.email           API email\n * @param   {string}  props.apikey          API key\n * @param   {number}  [props.timeout=5000]  Request timeut in ms\n */\n\nmodule.exports = (props) => {\n  let key;\n\n  for (key in props) {\n    config [key] = props [key];\n  }\n\n  return pkg;\n};\n"]}