{"version":3,"file":"alpha.modern.js","sources":["../src/pendoStub.ts","../src/index.ts"],"sourcesContent":["import { Pendo, PendoAgentValidationError, PendoInitializeParams, Window } from './types'\nimport { toHex, JSONWithRegex } from './utils'\n\ndeclare const window: Window & typeof globalThis\n\n// Parses Pendo agent source and verifies that its embedded configuration does not conflict with our overrides\nexport async function parsePendoAgent(\n src: string,\n expectedPendoOptions: Record,\n expectedInnerAgentDigest: string\n) {\n if (typeof src !== 'string') throw new PendoAgentValidationError('src is not a string')\n if (typeof expectedPendoOptions !== 'object')\n throw new PendoAgentValidationError('expectedConfig is not an object')\n if (typeof expectedInnerAgentDigest !== 'string')\n throw new PendoAgentValidationError('expectedInnerAgentDigest is not a string')\n\n const lines = src.split('\\n')\n const innerAgentLines = []\n const config: Record = {}\n const expectLine = (regex: RegExp, last = false) => {\n if (lines.length === 0) throw new PendoAgentValidationError('expected line missing')\n const line = last ? lines.pop() : lines.shift()\n if (line === undefined || !regex.test(line)) throw new PendoAgentValidationError('line does not match expectations')\n return line\n }\n const expectLastLine = (regex: RegExp) => expectLine(regex, true)\n expectLine(/^\\/\\/ Pendo Agent Wrapper$/)\n expectLine(/^\\/\\/ Environment:\\s+(production|staging)$/)\n expectLine(/^\\/\\/ Agent Version:\\s+(\\d+\\.)*\\d+$/)\n expectLine(/^\\/\\/ Installed:\\s+\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/)\n expectLine(/^\\(function \\(PendoConfig\\) \\{$/)\n while (lines.length > 0 && !/^\\}\\)\\(\\{$/.test(lines[0])) {\n innerAgentLines.push(lines.shift())\n }\n expectLine(/^\\}\\)\\(\\{$/)\n expectLastLine(/^\\}\\);$/)\n\n const regexCookie = toHex(await window.crypto.getRandomValues(new Uint8Array(16)))\n const jsonWithRegex = new JSONWithRegex(regexCookie)\n while (lines.length > 0) {\n const line = lines.shift()!\n const result = /^\\s*([a-zA-Z][a-zA-Z0-9]*)\\s*:\\s*(.*)\\s*,?\\s*$/.exec(line)\n if (!result) throw new PendoAgentValidationError('configuration line unparsable')\n const [, name, value] = result\n config[name] = (() => {\n try {\n return JSON.parse(value)\n } catch {\n // swallow error\n }\n value.replace(/\\/((?:\\\\\\/|[^/])*)\\/([a-z]*)/g, (x) => `${regexCookie}${JSON.stringify(x)}`)\n return jsonWithRegex.parse(value)\n })()\n }\n\n for (const [k, v] of Object.entries(config)) {\n if (k in expectedPendoOptions) {\n const expected = expectedPendoOptions[k]\n if (jsonWithRegex.stringify(v) !== jsonWithRegex.stringify(expected)) {\n throw new PendoAgentValidationError(\n `configuration parameter ${k} (${v}) does not match expected value (${expected})`\n )\n }\n }\n }\n\n const innerAgentSrc = innerAgentLines.join('\\n')\n const innerAgentDigest = toHex(\n new Uint8Array(\n await window.crypto.subtle.digest('SHA-256', new TextEncoder().encode(innerAgentSrc))\n )\n )\n\n if (innerAgentDigest !== expectedInnerAgentDigest) {\n throw new PendoAgentValidationError(\n `innerAgentDigest (${innerAgentDigest}) does not match expected value (${expectedInnerAgentDigest})`\n )\n }\n\n return config\n}\n\n// Prepare Pendo stub. This queues actions to be taken by the agent once it's loaded, and is equivalent\n// to the official minified Pendo installation snippet.\nexport function installPendoStub() {\n window.pendo ||= {} as Pendo\n window.pendo._q ||= []\n window.pendo.initialize ||= (...args: any[]) => window.pendo!._q.unshift(['initialize', ...args])\n window.pendo.identify ||= (...args: any[]) => window.pendo!._q.push(['identify', ...args])\n window.pendo.updateOptions ||= (...args: any[]) => window.pendo!._q.push(['updateOptions', ...args])\n window.pendo.pageLoad ||= (...args: any[]) => window.pendo!._q.push(['pageLoad', ...args])\n window.pendo.track ||= (...args: any[]) => window.pendo!._q.push(['track', ...args])\n}\n\nexport function loadPendoAgent(agentIntegrity: string, pendoOptions: Record, pendoInitializeParams: PendoInitializeParams) {\n window.pendo_options = pendoOptions\n installPendoStub()\n window.pendo!.initialize(pendoInitializeParams)\n\n const agentScriptNode = document.createElement('script')\n agentScriptNode.async = true\n agentScriptNode.src =\n 'https://cdn.pendo.io/agent/static/' + pendoOptions.apiKey + '/pendo.js'\n // TODO: add serviceworker-based validation of the agent script using parsePendoAgent?\n agentScriptNode.integrity = agentIntegrity\n agentScriptNode.crossOrigin = 'anonymous'\n // const firstScriptNode = document.getElementsByTagName('script')[0]\n // firstScriptNode.parentNode.insertBefore(agentScriptNode, firstScriptNode)\n document.body.appendChild(agentScriptNode)\n}\n","import { loadPendoAgent } from './pendoStub'\n\n// globalThis.navigator?.serviceWorker?.register(require('./serviceWorker'))\n\nloadPendoAgent(\n \"sha256-5HTd4/q1dqz5q9IXMH8iAXgKTZhK6VxryPypqws4/jA=\",\n {\n environmentName: 'production',\n blockAgentMetadata: false, // double-check\n blockLogRemoteAddress: true,\n dataHost: 'data.pendo.io',\n // stagingServers: [/^.*\\.web-29e\\.pages\\.dev$/, 'localhost:3000'],\n stagingAgentUrl:\n 'https://pendo-io-static.storage.googleapis.com/agent/static/67c2f326-a6c2-4aa2-4559-08a53b679e93/pendo-staging.js',\n allowedOriginServers: ['https://pendo-static-6047664892149760.storage.googleapis.com'],\n allowCrossOriginFrames: false,\n disableCookies: true,\n disableFeedbackAutoInit: false, // double-check\n disableGlobalCSS: true,\n disablePersistence: true,\n excludeAllText: true,\n guideValidation: true,\n localStorageOnly: true,\n preferBroadcastChannel: true,\n preferMutationObserver: true,\n preventCodeInjection: true,\n requireHTTPS: true,\n restrictP1Access: true,\n xhrTimings: false,\n xhrWhitelist: null,\n htmlAttributeBlacklist: null,\n htmlAttributes: /^(tabindex)$/i,\n apiKey: '67c2f326-a6c2-4aa2-4559-08a53b679e93',\n // hack to stop SameSite cookie warnings while disableCookies is set\n cookieDomain: window.location.hostname\n }, {\n // visitor: {\n // id: 'test_visitor'\n // },\n sanitizeUrl: (x) => {\n console.debug('PendoConfig:sanitizeUrl', x)\n return x\n },\n events: {\n ready: () => {\n console.debug('PendoConfig:ready')\n },\n deliverablesLoaded: () => {\n console.debug('PendoConfig:deliverablesLoaded')\n },\n guidesFailed: () => {\n console.debug('PendoConfig:guidesFailed')\n },\n guidesLoaded: () => {\n console.debug('PendoConfig:guidesLoaded')\n },\n validateGuide: async (signatureString) => {\n console.debug('PendoConfig:validateGuide', signatureString)\n return true\n },\n validateLauncher: async (signatureString) => {\n console.debug('PendoConfig:validateLauncher', signatureString)\n return true\n },\n validateGlobalScript: async (data) => {\n console.debug('PendoConfig:validateGlobalScript', data)\n return true\n }\n }\n }\n)\n"],"names":["loadPendoAgent","agentIntegrity","pendoOptions","pendoInitializeParams","window","pendo_options","pendo","_window","_window$pendo","_q","initialize","args","unshift","identify","push","updateOptions","pageLoad","_window$pendo6","track","agentScriptNode","document","createElement","async","src","apiKey","integrity","crossOrigin","body","appendChild","environmentName","blockAgentMetadata","blockLogRemoteAddress","dataHost","stagingAgentUrl","allowedOriginServers","allowCrossOriginFrames","disableCookies","disableFeedbackAutoInit","disableGlobalCSS","disablePersistence","excludeAllText","guideValidation","localStorageOnly","preferBroadcastChannel","preferMutationObserver","preventCodeInjection","requireHTTPS","restrictP1Access","xhrTimings","xhrWhitelist","htmlAttributeBlacklist","htmlAttributes","cookieDomain","location","hostname","sanitizeUrl","x","console","debug","events","ready","deliverablesLoaded","guidesFailed","guidesLoaded","validateGuide","signatureString","validateLauncher","validateGlobalScript","data"],"mappings":"CA+FgBA,SAAeC,EAAwBC,EAAuCC,qBAC5FC,OAAOC,cAAgBH,GAVvBE,EAAAA,QAAOE,QAAPC,EAAOD,MAAU,KACjBE,EAAAJ,OAAOE,OAAMG,KAAbD,EAAaC,GAAO,KACpBL,EAAAA,OAAOE,OAAMI,aAAAA,EAAAA,WAAe,IAAIC,IAAgBP,OAAOE,MAAOG,GAAGG,QAAQ,CAAC,gBAAiBD,QAC3FP,OAAOE,OAAMO,WAAAA,EAAAA,SAAa,IAAIF,IAAgBP,OAAOE,MAAOG,GAAGK,KAAK,CAAC,cAAeH,QACpFP,OAAOE,OAAMS,kBAAAA,cAAkB,IAAIJ,IAAgBP,OAAOE,MAAOG,GAAGK,KAAK,CAAC,mBAAoBH,QAC9FP,OAAOE,OAAMU,aAAAA,SAAa,IAAIL,IAAgBP,OAAOE,MAAOG,GAAGK,KAAK,CAAC,cAAeH,MACpFM,EAAAb,OAAOE,OAAMY,QAAbD,EAAaC,MAAU,IAAIP,IAAgBP,OAAOE,MAAOG,GAAGK,KAAK,CAAC,WAAYH,KAM9EP,OAAOE,MAAOI,WAAWP,GAEzB,MAAMgB,EAAkBC,SAASC,cAAc,UAC/CF,EAAgBG,OAAQ,EACxBH,EAAgBI,IACd,qCAAuCrB,EAAasB,OAAS,YAE/DL,EAAgBM,UCpGhB,sDDqGAN,EAAgBO,YAAc,YAG9BN,SAASO,KAAKC,YAAYT,GCzG5BnB,CACE,EACA,CACE6B,gBAAiB,aACjBC,oBAAoB,EACpBC,uBAAuB,EACvBC,SAAU,gBAEVC,gBACE,oHACFC,qBAAsB,CAAC,gEACvBC,wBAAwB,EACxBC,gBAAgB,EAChBC,yBAAyB,EACzBC,kBAAkB,EAClBC,oBAAoB,EACpBC,gBAAgB,EAChBC,iBAAiB,EACjBC,kBAAkB,EAClBC,wBAAwB,EACxBC,wBAAwB,EACxBC,sBAAsB,EACtBC,cAAc,EACdC,kBAAkB,EAClBC,YAAY,EACZC,aAAc,KACdC,uBAAwB,KACxBC,eAAgB,gBAChB3B,OAAQ,uCAER4B,aAAchD,OAAOiD,SAASC,UAC7B,CAIDC,YAAcC,IACZC,QAAQC,MAAM,0BAA2BF,GAClCA,GAETG,OAAQ,CACNC,MAAO,KACLH,QAAQC,MAAM,sBAEhBG,mBAAoB,KAClBJ,QAAQC,MAAM,mCAEhBI,aAAc,KACZL,QAAQC,MAAM,6BAEhBK,aAAc,KACZN,QAAQC,MAAM,6BAEhBM,cAAe1C,MAAAA,IACbmC,QAAQC,MAAM,4BAA6BO,IACpC,GAETC,iBAAkB5C,MAAAA,IAChBmC,QAAQC,MAAM,+BAAgCO,IACvC,GAETE,qBAAsB7C,MAAAA,IACpBmC,QAAQC,MAAM,mCAAoCU,IAEnD"}