diff --git a/.babelrc b/.babelrc index 48f19b72b..7fe9a63a1 100644 --- a/.babelrc +++ b/.babelrc @@ -1,6 +1,7 @@ { "presets": ["@babel/env", ["@babel/typescript", { "jsxPragma": "h" }]], "plugins": [ + "@babel/plugin-transform-nullish-coalescing-operator", [ "@babel/transform-react-jsx", { diff --git a/.github/workflows/ssr-es-check.yml b/.github/workflows/es-check.yml similarity index 57% rename from .github/workflows/ssr-es-check.yml rename to .github/workflows/es-check.yml index 18ad939e5..16e7ebed5 100644 --- a/.github/workflows/ssr-es-check.yml +++ b/.github/workflows/es-check.yml @@ -1,4 +1,4 @@ -name: Server-side rendering and ES5 +name: ES5 support check on: - pull_request @@ -19,8 +19,5 @@ jobs: - run: pnpm install && pnpm build - - name: Run es-check to check if our bundle is ES5 compatible - run: npx es-check@6.1.1 es5 dist/{array,main}.js - - - name: Require module via node - run: cd dist; node -e "require('./main')" + - name: Run es-check to check if our ie11 bundle is ES5 compatible + run: npx es-check@7.2.1 es5 dist/array.full.es5.js diff --git a/CHANGELOG.md b/CHANGELOG.md index cbc9478de..0b5299ff4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.172.0 - 2024-10-17 + +- chore: build an es5 bundle and move main to es6 (#1480) + +## 1.171.0 - 2024-10-17 + +- feat: start session recording on url trigger (#1451) +- chore: babel targets in rollup config (#1479) + ## 1.170.1 - 2024-10-16 - feat: add stack to stacktraceless "exceptions" (#1472) diff --git a/package.json b/package.json index 07cfb083a..e9aa5983d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "posthog-js", - "version": "1.170.1", + "version": "1.172.0", "description": "Posthog-js allows you to automatically capture usage and send events to PostHog.", "repository": "https://github.com/PostHog/posthog-js", "author": "hey@posthog.com", @@ -38,30 +38,33 @@ "react/package.json" ], "dependencies": { + "core-js": "^3.38.1", "fflate": "^0.4.8", "preact": "^10.19.3", - "web-vitals": "^4.0.1" + "web-vitals": "^4.2.0" }, "devDependencies": { "@babel/core": "7.18.9", "@babel/plugin-syntax-decorators": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.8", "@babel/plugin-transform-react-jsx": "^7.23.4", "@babel/preset-env": "7.18.9", "@babel/preset-typescript": "^7.18.6", "@cypress/skip-test": "^2.6.1", "@jest/globals": "^27.5.1", "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^11.1.6", + "@rollup/plugin-typescript": "^12.1.1", "@rrweb/types": "2.0.0-alpha.16", "@sentry/types": "8.7.0", "@testing-library/dom": "^9.3.0", "@testing-library/jest-dom": "^6.5.0", "@testing-library/preact": "^3.2.4", "@types/eslint": "^8.44.6", - "@types/jest": "^27.5.1", + "@types/jest": "^27.5.2", "@types/node": "^22.5.0", "@types/react-dom": "^18.0.10", "@types/sinon": "^17.0.1", @@ -97,9 +100,8 @@ "posthog-js": "link:", "preact-render-to-string": "^6.3.1", "prettier": "^2.7.1", - "rollup": "^4.9.6", - "rollup-plugin-dts": "^6.1.0", - "rollup-plugin-ts": "^3.4.5", + "rollup": "^4.24.0", + "rollup-plugin-dts": "^6.1.1", "rollup-plugin-visualizer": "^5.12.0", "rrweb": "2.0.0-alpha.16", "@rrweb/rrweb-plugin-console-record": "2.0.0-alpha.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8952b472a..6a1182131 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,9 @@ patchedDependencies: path: patches/rrweb@2.0.0-alpha.16.patch dependencies: + core-js: + specifier: ^3.38.1 + version: 3.38.1 fflate: specifier: ^0.4.8 version: 0.4.8 @@ -17,7 +20,7 @@ dependencies: specifier: ^10.19.3 version: 10.19.3 web-vitals: - specifier: ^4.0.1 + specifier: ^4.2.0 version: 4.2.0 devDependencies: @@ -27,6 +30,9 @@ devDependencies: '@babel/plugin-syntax-decorators': specifier: ^7.23.3 version: 7.23.3(@babel/core@7.18.9) + '@babel/plugin-transform-nullish-coalescing-operator': + specifier: ^7.25.8 + version: 7.25.8(@babel/core@7.18.9) '@babel/plugin-transform-react-jsx': specifier: ^7.23.4 version: 7.23.4(@babel/core@7.18.9) @@ -44,19 +50,22 @@ devDependencies: version: 27.5.1 '@rollup/plugin-babel': specifier: ^6.0.4 - version: 6.0.4(@babel/core@7.18.9)(rollup@4.9.6) + version: 6.0.4(@babel/core@7.18.9)(rollup@4.24.0) + '@rollup/plugin-commonjs': + specifier: ^28.0.1 + version: 28.0.1(rollup@4.24.0) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.9.6) + version: 6.1.0(rollup@4.24.0) '@rollup/plugin-node-resolve': - specifier: ^15.2.3 - version: 15.2.3(rollup@4.9.6) + specifier: ^15.3.0 + version: 15.3.0(rollup@4.24.0) '@rollup/plugin-terser': specifier: ^0.4.4 - version: 0.4.4(rollup@4.9.6) + version: 0.4.4(rollup@4.24.0) '@rollup/plugin-typescript': - specifier: ^11.1.6 - version: 11.1.6(rollup@4.9.6)(tslib@2.5.0)(typescript@5.5.4) + specifier: ^12.1.1 + version: 12.1.1(rollup@4.24.0)(tslib@2.5.0)(typescript@5.5.4) '@rrweb/rrweb-plugin-console-record': specifier: 2.0.0-alpha.15 version: 2.0.0-alpha.15(rrweb@2.0.0-alpha.16) @@ -79,7 +88,7 @@ devDependencies: specifier: ^8.44.6 version: 8.44.6 '@types/jest': - specifier: ^27.5.1 + specifier: ^27.5.2 version: 27.5.2 '@types/node': specifier: ^22.5.0 @@ -187,17 +196,14 @@ devDependencies: specifier: ^2.7.1 version: 2.7.1 rollup: - specifier: ^4.9.6 - version: 4.9.6 + specifier: ^4.24.0 + version: 4.24.0 rollup-plugin-dts: - specifier: ^6.1.0 - version: 6.1.0(rollup@4.9.6)(typescript@5.5.4) - rollup-plugin-ts: - specifier: ^3.4.5 - version: 3.4.5(@babel/core@7.18.9)(@babel/preset-env@7.18.9)(@babel/preset-typescript@7.18.6)(rollup@4.9.6)(typescript@5.5.4) + specifier: ^6.1.1 + version: 6.1.1(rollup@4.24.0)(typescript@5.5.4) rollup-plugin-visualizer: specifier: ^5.12.0 - version: 5.12.0(rollup@4.9.6) + version: 5.12.0(rollup@4.24.0) rrweb: specifier: 2.0.0-alpha.16 version: 2.0.0-alpha.16(patch_hash=3ftboblxtwo3qbwixpcnhd7q3i) @@ -261,6 +267,16 @@ packages: chalk: 2.4.2 dev: true + /@babel/code-frame@7.25.7: + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + engines: {node: '>=6.9.0'} + requiresBuild: true + dependencies: + '@babel/highlight': 7.25.7 + picocolors: 1.1.0 + dev: true + optional: true + /@babel/compat-data@7.18.8: resolution: {integrity: sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==} engines: {node: '>=6.9.0'} @@ -461,6 +477,11 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-plugin-utils@7.25.7: + resolution: {integrity: sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-remap-async-to-generator@7.18.9(@babel/core@7.18.9): resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} engines: {node: '>=6.9.0'} @@ -520,6 +541,13 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-identifier@7.25.7: + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + engines: {node: '>=6.9.0'} + requiresBuild: true + dev: true + optional: true + /@babel/helper-validator-option@7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} @@ -567,6 +595,18 @@ packages: js-tokens: 4.0.0 dev: true + /@babel/highlight@7.25.7: + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} + engines: {node: '>=6.9.0'} + requiresBuild: true + dependencies: + '@babel/helper-validator-identifier': 7.25.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.0 + dev: true + optional: true + /@babel/parser@7.23.0: resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} engines: {node: '>=6.0.0'} @@ -1251,6 +1291,16 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true + /@babel/plugin-transform-nullish-coalescing-operator@7.25.8(@babel/core@7.18.9): + resolution: {integrity: sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.18.9 + '@babel/helper-plugin-utils': 7.25.7 + dev: true + /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.18.9): resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} engines: {node: '>=6.9.0'} @@ -2430,6 +2480,10 @@ packages: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true + /@jridgewell/sourcemap-codec@1.5.0: + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + dev: true + /@jridgewell/trace-mapping@0.3.20: resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} dependencies: @@ -2448,10 +2502,6 @@ packages: resolution: {integrity: sha512-jzPrheqEtrnUWWNUS8SFVbQAnoO6rOXetkjiJyzP92UM+BNcyExLD0Qikv9z6TU9D6A9rbXkh3pSmZ5G88d6ew==} dev: true - /@mdn/browser-compat-data@5.5.51: - resolution: {integrity: sha512-17L3+/oqX+sgSyucNKSipri1LkI/d8pwPQI4Vv2ejRVZLZr1WGxcEGBnglqFhdlislQBceJiHAdQnWEE+YJE3A==} - dev: true - /@miherlosev/esm@3.2.26: resolution: {integrity: sha512-TaW4jTGVE1/ln2VGFChnheMh589QCAZy1MVnLvjjSzZ4pEAa4WYAWPwFkDVZbSdPQdLfZy7LuTyZjWRkhX9/Gg==} engines: {node: '>=6'} @@ -2506,7 +2556,7 @@ packages: resolution: {integrity: sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==} dev: true - /@rollup/plugin-babel@6.0.4(@babel/core@7.18.9)(rollup@4.9.6): + /@rollup/plugin-babel@6.0.4(@babel/core@7.18.9)(rollup@4.24.0): resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2521,11 +2571,30 @@ packages: dependencies: '@babel/core': 7.18.9 '@babel/helper-module-imports': 7.22.15 - '@rollup/pluginutils': 5.1.0(rollup@4.9.6) - rollup: 4.9.6 + '@rollup/pluginutils': 5.1.0(rollup@4.24.0) + rollup: 4.24.0 + dev: true + + /@rollup/plugin-commonjs@28.0.1(rollup@4.24.0): + resolution: {integrity: sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.24.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.4.2(picomatch@4.0.2) + is-reference: 1.2.1 + magic-string: 0.30.5 + picomatch: 4.0.2 + rollup: 4.24.0 dev: true - /@rollup/plugin-json@6.1.0(rollup@4.9.6): + /@rollup/plugin-json@6.1.0(rollup@4.24.0): resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2534,12 +2603,12 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.9.6) - rollup: 4.9.6 + '@rollup/pluginutils': 5.1.0(rollup@4.24.0) + rollup: 4.24.0 dev: true - /@rollup/plugin-node-resolve@15.2.3(rollup@4.9.6): - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + /@rollup/plugin-node-resolve@15.3.0(rollup@4.24.0): + resolution: {integrity: sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.78.0||^3.0.0||^4.0.0 @@ -2547,16 +2616,15 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.9.6) + '@rollup/pluginutils': 5.1.0(rollup@4.24.0) '@types/resolve': 1.20.2 deepmerge: 4.2.2 - is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.8 - rollup: 4.9.6 + rollup: 4.24.0 dev: true - /@rollup/plugin-terser@0.4.4(rollup@4.9.6): + /@rollup/plugin-terser@0.4.4(rollup@4.24.0): resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2565,14 +2633,14 @@ packages: rollup: optional: true dependencies: - rollup: 4.9.6 + rollup: 4.24.0 serialize-javascript: 6.0.1 smob: 1.4.1 terser: 5.27.0 dev: true - /@rollup/plugin-typescript@11.1.6(rollup@4.9.6)(tslib@2.5.0)(typescript@5.5.4): - resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + /@rollup/plugin-typescript@12.1.1(rollup@4.24.0)(tslib@2.5.0)(typescript@5.5.4): + resolution: {integrity: sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.14.0||^3.0.0||^4.0.0 @@ -2584,14 +2652,14 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.9.6) + '@rollup/pluginutils': 5.1.0(rollup@4.24.0) resolve: 1.22.8 - rollup: 4.9.6 + rollup: 4.24.0 tslib: 2.5.0 typescript: 5.5.4 dev: true - /@rollup/pluginutils@5.1.0(rollup@4.9.6): + /@rollup/pluginutils@5.1.0(rollup@4.24.0): resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} peerDependencies: @@ -2603,107 +2671,131 @@ packages: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 4.9.6 + rollup: 4.24.0 dev: true - /@rollup/rollup-android-arm-eabi@4.9.6: - resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==} + /@rollup/rollup-android-arm-eabi@4.24.0: + resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} cpu: [arm] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-android-arm64@4.9.6: - resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==} + /@rollup/rollup-android-arm64@4.24.0: + resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} cpu: [arm64] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-arm64@4.9.6: - resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==} + /@rollup/rollup-darwin-arm64@4.24.0: + resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-x64@4.9.6: - resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==} + /@rollup/rollup-darwin-x64@4.24.0: + resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.9.6: - resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==} + /@rollup/rollup-linux-arm-gnueabihf@4.24.0: + resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.9.6: - resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==} + /@rollup/rollup-linux-arm-musleabihf@4.24.0: + resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.24.0: + resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-musl@4.9.6: - resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==} + /@rollup/rollup-linux-arm64-musl@4.24.0: + resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-riscv64-gnu@4.9.6: - resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==} + /@rollup/rollup-linux-powerpc64le-gnu@4.24.0: + resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.24.0: + resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} cpu: [riscv64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-gnu@4.9.6: - resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==} + /@rollup/rollup-linux-s390x-gnu@4.24.0: + resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.24.0: + resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-musl@4.9.6: - resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==} + /@rollup/rollup-linux-x64-musl@4.24.0: + resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.9.6: - resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==} + /@rollup/rollup-win32-arm64-msvc@4.24.0: + resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.9.6: - resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==} + /@rollup/rollup-win32-ia32-msvc@4.24.0: + resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} cpu: [ia32] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-x64-msvc@4.9.6: - resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==} + /@rollup/rollup-win32-x64-msvc@4.24.0: + resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} cpu: [x64] os: [win32] requiresBuild: true @@ -2912,6 +3004,10 @@ packages: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} dev: true + /@types/estree@1.0.6: + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + dev: true + /@types/glob@7.1.3: resolution: {integrity: sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==} dependencies: @@ -2982,20 +3078,12 @@ packages: resolution: {integrity: sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==} dev: true - /@types/node@17.0.45: - resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - dev: true - /@types/node@22.5.0: resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} dependencies: undici-types: 6.19.8 dev: true - /@types/object-path@0.11.4: - resolution: {integrity: sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==} - dev: true - /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} dev: true @@ -3030,10 +3118,6 @@ packages: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} dev: true - /@types/semver@7.5.8: - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - dev: true - /@types/set-cookie-parser@2.4.2: resolution: {integrity: sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==} dependencies: @@ -3062,10 +3146,6 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true - /@types/ua-parser-js@0.7.39: - resolution: {integrity: sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==} - dev: true - /@types/web@0.0.154: resolution: {integrity: sha512-Tc10Nkpbb8AgM3iGnrvpKVb6x8pzrZpMCPqMJe8htXoEdNDKojEevNAkCjxkjCLZF2p1ZB+gknAwdbkypxwxKg==} dev: true @@ -3230,11 +3310,6 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@wessberg/stringutil@1.0.19: - resolution: {integrity: sha512-9AZHVXWlpN8Cn9k5BC/O0Dzb9E9xfEMXzYrNunwvkUTvuK7xgQPVRZpLo+jWCOZ5r8oBa8NIrHuPEu1hzbb6bg==} - engines: {node: '>=8.0.0'} - dev: true - /@xmldom/xmldom@0.8.7: resolution: {integrity: sha512-sI1Ly2cODlWStkINzqGrZ8K6n+MTSbAeQnAipGyL+KZCXuHaRlj2gyyy8B/9MvsFFqN7XHryQnB2QwhzvJXovg==} engines: {node: '>=10.0.0'} @@ -3349,11 +3424,6 @@ packages: engines: {node: '>=6'} dev: true - /ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - dev: true - /ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -3927,22 +3997,6 @@ packages: resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} dev: true - /browserslist-generator@2.3.0: - resolution: {integrity: sha512-NEvS2dNlBKfSL3qDUTM3NkJMfjMAPEjvEGnhMZKql6ZNzJ8asqFpmuTizwOpRQeYA0/VktmOXa+mFPv8nvcIGw==} - engines: {node: '>=16.15.1', npm: '>=7.0.0', pnpm: '>=3.2.0', yarn: '>=1.13'} - dependencies: - '@mdn/browser-compat-data': 5.5.51 - '@types/object-path': 0.11.4 - '@types/semver': 7.5.8 - '@types/ua-parser-js': 0.7.39 - browserslist: 4.23.3 - caniuse-lite: 1.0.30001660 - isbot: 3.8.0 - object-path: 0.11.8 - semver: 7.6.3 - ua-parser-js: 1.0.38 - dev: true - /browserslist@4.21.7: resolution: {integrity: sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -3954,17 +4008,6 @@ packages: update-browserslist-db: 1.0.11(browserslist@4.21.7) dev: true - /browserslist@4.23.3: - resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001660 - electron-to-chromium: 1.5.19 - node-releases: 2.0.18 - update-browserslist-db: 1.1.0(browserslist@4.23.3) - dev: true - /browserstack-local@1.5.1: resolution: {integrity: sha512-T/wxyWDzvBHbDvl7fZKpFU7mYze6nrUkBhNy+d+8bXBqgQX10HTYvajIGO0wb49oGSLCPM0CMZTV/s7e6LF0sA==} dependencies: @@ -4007,11 +4050,6 @@ packages: ieee754: 1.2.1 dev: true - /builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - dev: true - /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -4080,10 +4118,6 @@ packages: resolution: {integrity: sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==} dev: true - /caniuse-lite@1.0.30001660: - resolution: {integrity: sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==} - dev: true - /capture-exit@2.0.0: resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} engines: {node: 6.* || 8.* || >= 10.*} @@ -4352,18 +4386,12 @@ packages: engines: {node: '>=4.0.0'} dev: true - /compare-versions@6.1.0: - resolution: {integrity: sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==} + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} dev: true - /compatfactory@3.0.0(typescript@5.5.4): - resolution: {integrity: sha512-WD5kF7koPwVoyKL8p0LlrmIZtilrD46sQStyzzxzTFinMKN2Dxk1hN+sddLSQU1mGIZvQfU8c+ONSghvvM40jg==} - engines: {node: '>=14.9.0'} - peerDependencies: - typescript: '>=3.x || >= 4.x || >= 5.x' - dependencies: - helpertypes: 0.0.19 - typescript: 5.5.4 + /compare-versions@6.1.0: + resolution: {integrity: sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==} dev: true /component-emitter@1.3.0: @@ -4423,6 +4451,11 @@ packages: semver: 7.0.0 dev: true + /core-js@3.38.1: + resolution: {integrity: sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==} + requiresBuild: true + dev: false + /core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} dev: true @@ -4462,13 +4495,6 @@ packages: which: 2.0.2 dev: true - /crosspath@2.0.0: - resolution: {integrity: sha512-ju88BYCQ2uvjO2bR+SsgLSTwTSctU+6Vp2ePbKPgSCZyy4MWZxYsT738DlKVRE5utUjobjPRm1MkTYKJxCmpTA==} - engines: {node: '>=14.9.0'} - dependencies: - '@types/node': 17.0.45 - dev: true - /crypto-md5@1.0.0: resolution: {integrity: sha512-65Mtei8+EkSIK+5Ie4gpWXoJ/5bgpqPXFknHHXAyhDqKsEAAzUslGd8mOeawbfcuQ8fADNKcF4xQA3fqlZJ8Ig==} engines: {iojs: '>=1.0.0', node: '>=0.5.2'} @@ -4879,10 +4905,6 @@ packages: resolution: {integrity: sha512-1KnpDTS9onwAfMzW50LcpNtyOkMyjd/OLoD2Kx/DDITZqgNYixY71XNszPHNxyQQ/Brh+FDcUnf4BaM041sdWg==} dev: true - /electron-to-chromium@1.5.19: - resolution: {integrity: sha512-kpLJJi3zxTR1U828P+LIUDZ5ohixyo68/IcYOHLqnbTPr/wdgn4i1ECvmALN9E16JPA6cvCG5UG79gVwVdEK5w==} - dev: true - /elegant-spinner@1.0.1: resolution: {integrity: sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ==} engines: {node: '>=0.10.0'} @@ -5011,11 +5033,6 @@ packages: engines: {node: '>=6'} dev: true - /escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - dev: true - /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} dev: true @@ -5559,6 +5576,17 @@ packages: pend: 1.2.0 dev: true + /fdir@6.4.2(picomatch@4.0.2): + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + dependencies: + picomatch: 4.0.2 + dev: true + /fflate@0.4.8: resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} dev: false @@ -6087,11 +6115,6 @@ packages: resolution: {integrity: sha512-tUCGvt191vNSQgttSyJoibR+VO+I6+iCHIUdhzEMJKE+EAL8BwCN7fUOZlY4ofOelNHsK+gEjxB/B+9N3EWtdA==} dev: true - /helpertypes@0.0.19: - resolution: {integrity: sha512-J00e55zffgi3yVnUp0UdbMztNkr2PnizEkOe9URNohnrNhW5X0QpegkuLpOmFQInpi93Nb8MCjQRHAiCDF42NQ==} - engines: {node: '>=10.0.0'} - dev: true - /highlight-es@1.0.3: resolution: {integrity: sha512-s/SIX6yp/5S1p8aC/NRDC1fwEb+myGIfp8/TzZz0rtAv8fzsdX7vGl3Q1TrXCsczFq8DI3CBFBCySPClfBSdbg==} dependencies: @@ -6398,13 +6421,6 @@ packages: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} dev: true - /is-builtin-module@3.2.1: - resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} - engines: {node: '>=6'} - dependencies: - builtin-modules: 3.3.0 - dev: true - /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} @@ -6648,6 +6664,12 @@ packages: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} dev: true + /is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + dependencies: + '@types/estree': 1.0.5 + dev: true + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -6764,11 +6786,6 @@ packages: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} dev: true - /isbot@3.8.0: - resolution: {integrity: sha512-vne1mzQUTR+qsMLeCBL9+/tgnDXRyc2pygLGl/WsgA+EZKIiB5Ehu0CiVTHIIk30zhJ24uGz4M5Ppse37aR0Hg==} - engines: {node: '>=12'} - dev: true - /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -7936,6 +7953,12 @@ packages: hasBin: true dev: true + /magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true + /magic-string@0.30.5: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} @@ -8278,10 +8301,6 @@ packages: resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} dev: true - /node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} - dev: true - /normalize-path@2.1.1: resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} engines: {node: '>=0.10.0'} @@ -8347,11 +8366,6 @@ packages: engines: {node: '>= 0.4'} dev: true - /object-path@0.11.8: - resolution: {integrity: sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==} - engines: {node: '>= 10.12.0'} - dev: true - /object-visit@1.0.1: resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} engines: {node: '>=0.10.0'} @@ -8711,10 +8725,6 @@ packages: resolution: {integrity: sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==} dev: true - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - /picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} dev: true @@ -8724,6 +8734,11 @@ packages: engines: {node: '>=8.6'} dev: true + /picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + dev: true + /pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} @@ -9324,67 +9339,21 @@ packages: glob: 7.1.6 dev: true - /rollup-plugin-dts@6.1.0(rollup@4.9.6)(typescript@5.5.4): - resolution: {integrity: sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==} + /rollup-plugin-dts@6.1.1(rollup@4.24.0)(typescript@5.5.4): + resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} engines: {node: '>=16'} peerDependencies: rollup: ^3.29.4 || ^4 typescript: ^4.5 || ^5.0 dependencies: - magic-string: 0.30.5 - rollup: 4.9.6 + magic-string: 0.30.12 + rollup: 4.24.0 typescript: 5.5.4 optionalDependencies: - '@babel/code-frame': 7.23.5 - dev: true - - /rollup-plugin-ts@3.4.5(@babel/core@7.18.9)(@babel/preset-env@7.18.9)(@babel/preset-typescript@7.18.6)(rollup@4.9.6)(typescript@5.5.4): - resolution: {integrity: sha512-9iCstRJpEZXSRQuXitlSZAzcGlrqTbJg1pE4CMbEi6xYldxVncdPyzA2I+j6vnh73wBymZckerS+Q/iEE/M3Ow==} - engines: {node: '>=16.15.1', npm: '>=7.0.0', pnpm: '>=3.2.0', yarn: '>=1.13'} - peerDependencies: - '@babel/core': '>=7.x' - '@babel/plugin-transform-runtime': '>=7.x' - '@babel/preset-env': '>=7.x' - '@babel/preset-typescript': '>=7.x' - '@babel/runtime': '>=7.x' - '@swc/core': '>=1.x' - '@swc/helpers': '>=0.2' - rollup: '>=1.x || >=2.x || >=3.x' - typescript: '>=3.2.x || >= 4.x || >= 5.x' - peerDependenciesMeta: - '@babel/core': - optional: true - '@babel/plugin-transform-runtime': - optional: true - '@babel/preset-env': - optional: true - '@babel/preset-typescript': - optional: true - '@babel/runtime': - optional: true - '@swc/core': - optional: true - '@swc/helpers': - optional: true - dependencies: - '@babel/core': 7.18.9 - '@babel/preset-env': 7.18.9(@babel/core@7.18.9) - '@babel/preset-typescript': 7.18.6(@babel/core@7.18.9) - '@rollup/pluginutils': 5.1.0(rollup@4.9.6) - '@wessberg/stringutil': 1.0.19 - ansi-colors: 4.1.3 - browserslist: 4.23.3 - browserslist-generator: 2.3.0 - compatfactory: 3.0.0(typescript@5.5.4) - crosspath: 2.0.0 - magic-string: 0.30.5 - rollup: 4.9.6 - ts-clone-node: 3.0.0(typescript@5.5.4) - tslib: 2.7.0 - typescript: 5.5.4 + '@babel/code-frame': 7.25.7 dev: true - /rollup-plugin-visualizer@5.12.0(rollup@4.9.6): + /rollup-plugin-visualizer@5.12.0(rollup@4.24.0): resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} engines: {node: '>=14'} hasBin: true @@ -9396,31 +9365,34 @@ packages: dependencies: open: 8.4.2 picomatch: 2.3.1 - rollup: 4.9.6 + rollup: 4.24.0 source-map: 0.7.4 yargs: 17.7.2 dev: true - /rollup@4.9.6: - resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==} + /rollup@4.24.0: + resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.9.6 - '@rollup/rollup-android-arm64': 4.9.6 - '@rollup/rollup-darwin-arm64': 4.9.6 - '@rollup/rollup-darwin-x64': 4.9.6 - '@rollup/rollup-linux-arm-gnueabihf': 4.9.6 - '@rollup/rollup-linux-arm64-gnu': 4.9.6 - '@rollup/rollup-linux-arm64-musl': 4.9.6 - '@rollup/rollup-linux-riscv64-gnu': 4.9.6 - '@rollup/rollup-linux-x64-gnu': 4.9.6 - '@rollup/rollup-linux-x64-musl': 4.9.6 - '@rollup/rollup-win32-arm64-msvc': 4.9.6 - '@rollup/rollup-win32-ia32-msvc': 4.9.6 - '@rollup/rollup-win32-x64-msvc': 4.9.6 + '@rollup/rollup-android-arm-eabi': 4.24.0 + '@rollup/rollup-android-arm64': 4.24.0 + '@rollup/rollup-darwin-arm64': 4.24.0 + '@rollup/rollup-darwin-x64': 4.24.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 + '@rollup/rollup-linux-arm-musleabihf': 4.24.0 + '@rollup/rollup-linux-arm64-gnu': 4.24.0 + '@rollup/rollup-linux-arm64-musl': 4.24.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 + '@rollup/rollup-linux-riscv64-gnu': 4.24.0 + '@rollup/rollup-linux-s390x-gnu': 4.24.0 + '@rollup/rollup-linux-x64-gnu': 4.24.0 + '@rollup/rollup-linux-x64-musl': 4.24.0 + '@rollup/rollup-win32-arm64-msvc': 4.24.0 + '@rollup/rollup-win32-ia32-msvc': 4.24.0 + '@rollup/rollup-win32-x64-msvc': 4.24.0 fsevents: 2.3.3 dev: true @@ -10490,16 +10462,6 @@ packages: typescript: 5.5.4 dev: true - /ts-clone-node@3.0.0(typescript@5.5.4): - resolution: {integrity: sha512-egavvyHbIoelkgh1IC2agNB1uMNjB8VJgh0g/cn0bg2XXTcrtjrGMzEk4OD3Fi2hocICjP3vMa56nkzIzq0FRg==} - engines: {node: '>=14.9.0'} - peerDependencies: - typescript: ^3.x || ^4.x || ^5.x - dependencies: - compatfactory: 3.0.0(typescript@5.5.4) - typescript: 5.5.4 - dev: true - /ts-node@10.9.2(@types/node@22.5.0)(typescript@5.5.4): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true @@ -10613,10 +10575,6 @@ packages: hasBin: true dev: true - /ua-parser-js@1.0.38: - resolution: {integrity: sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==} - dev: true - /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -10713,17 +10671,6 @@ packages: dependencies: browserslist: 4.21.7 escalade: 3.1.1 - picocolors: 1.0.0 - dev: true - - /update-browserslist-db@1.1.0(browserslist@4.23.3): - resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.23.3 - escalade: 3.2.0 picocolors: 1.1.0 dev: true diff --git a/rollup.config.js b/rollup.config.js index 3bd5afe8c..648cdd8bb 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -5,19 +5,37 @@ import typescript from '@rollup/plugin-typescript' import { dts } from 'rollup-plugin-dts' import terser from '@rollup/plugin-terser' import { visualizer } from 'rollup-plugin-visualizer' +import commonjs from '@rollup/plugin-commonjs' import fs from 'fs' import path from 'path' -const plugins = [ +const plugins = (es5) => [ json(), resolve({ browser: true }), - typescript({ sourceMap: true }), + typescript({ sourceMap: true, outDir: './dist' }), + commonjs(), babel({ extensions: ['.js', '.jsx', '.ts', '.tsx'], babelHelpers: 'bundled', - presets: ['@babel/preset-env'], + plugins: ['@babel/plugin-transform-nullish-coalescing-operator'], + presets: [ + [ + '@babel/preset-env', + { + targets: es5 + ? '>0.5%, last 2 versions, Firefox ESR, not dead, IE 11' + : '>0.5%, last 2 versions, Firefox ESR, not dead', + }, + ], + ], + }), + terser({ + toplevel: true, + compress: { + // 5 is the default if unspecified + ecma: es5 ? 5 : 6, + }, }), - terser({ toplevel: true }), ] const entrypoints = fs.readdirSync('./src/entrypoints') @@ -37,6 +55,8 @@ const entrypointTargets = entrypoints.map((file) => { const fileName = fileParts.join('.') + const pluginsForThisFile = plugins(fileName.includes('es5')) + // we're allowed to console log in this file :) // eslint-disable-next-line no-console console.log(`Building ${fileName} in ${format} format`) @@ -60,7 +80,7 @@ const entrypointTargets = entrypoints.map((file) => { ...(format === 'cjs' ? { exports: 'auto' } : {}), }, ], - plugins: [...plugins, visualizer({ filename: `bundle-stats-${fileName}.html` })], + plugins: [...pluginsForThisFile, visualizer({ filename: `bundle-stats-${fileName}.html` })], } }) diff --git a/src/constants.ts b/src/constants.ts index fc3154879..ac85e6936 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -24,6 +24,8 @@ export const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate' export const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration' export const SESSION_ID = '$sesid' export const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled' +export const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session' +export const SESSION_RECORDING_URL_TRIGGER_STATUS = '$session_recording_url_trigger_status' export const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags' export const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features' export const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties' diff --git a/src/entrypoints/array.full.es5.ts b/src/entrypoints/array.full.es5.ts new file mode 100644 index 000000000..b1a76efc8 --- /dev/null +++ b/src/entrypoints/array.full.es5.ts @@ -0,0 +1,11 @@ +// a straight copy of the array.full.ts entrypoint, +// but will have different config when passed through rollup +// to allow es5/IE11 support + +// it doesn't include recorder which doesn't support IE11, +// and it doesn't include web-vitals which doesn't support IE11 + +import './surveys' +import './exception-autocapture' +import './tracing-headers' +import './array.no-external' diff --git a/src/extensions/replay/sessionrecording.ts b/src/extensions/replay/sessionrecording.ts index 0f0f65bf1..95420aa5f 100644 --- a/src/extensions/replay/sessionrecording.ts +++ b/src/extensions/replay/sessionrecording.ts @@ -6,6 +6,8 @@ import { SESSION_RECORDING_MINIMUM_DURATION, SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE, SESSION_RECORDING_SAMPLE_RATE, + SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION, + SESSION_RECORDING_URL_TRIGGER_STATUS, } from '../../constants' import { estimateSize, @@ -16,7 +18,14 @@ import { truncateLargeConsoleLogs, } from './sessionrecording-utils' import { PostHog } from '../../posthog-core' -import { DecideResponse, FlagVariant, NetworkRecordOptions, NetworkRequest, Properties } from '../../types' +import { + DecideResponse, + FlagVariant, + NetworkRecordOptions, + NetworkRequest, + Properties, + SessionRecordingUrlTrigger, +} from '../../types' import { customEvent, EventType, @@ -44,7 +53,8 @@ type SessionStartReason = const BASE_ENDPOINT = '/s/' -const FIVE_MINUTES = 1000 * 60 * 5 +const ONE_MINUTE = 1000 * 60 +const FIVE_MINUTES = ONE_MINUTE * 5 const TWO_SECONDS = 2000 export const RECORDING_IDLE_THRESHOLD_MS = FIVE_MINUTES const ONE_KB = 1024 @@ -68,6 +78,9 @@ const ACTIVE_SOURCES = [ IncrementalSource.Drag, ] +const TRIGGER_STATUSES = ['trigger_activated', 'trigger_pending', 'trigger_disabled'] as const +type TriggerStatus = typeof TRIGGER_STATUSES[number] + /** * Session recording starts in buffering mode while waiting for decide response * Once the response is received it might be disabled, active or sampled @@ -233,6 +246,8 @@ export class SessionRecording { // then we can manually track href changes private _lastHref?: string + private _urlTriggers: SessionRecordingUrlTrigger[] = [] + // Util to help developers working on this feature manually override _forceAllowLocalhostNetworkCapture = false @@ -258,7 +273,11 @@ export class SessionRecording { } private get fullSnapshotIntervalMillis(): number { - return this.instance.config.session_recording?.full_snapshot_interval_millis || FIVE_MINUTES + if (this.urlTriggerStatus === 'trigger_pending') { + return ONE_MINUTE + } + + return this.instance.config.session_recording?.full_snapshot_interval_millis ?? FIVE_MINUTES } private get isSampled(): boolean | null { @@ -348,6 +367,10 @@ export class SessionRecording { return 'buffering' } + if (this.urlTriggerStatus === 'trigger_pending') { + return 'buffering' + } + if (isBoolean(this.isSampled)) { return this.isSampled ? 'sampled' : 'disabled' } else { @@ -355,6 +378,34 @@ export class SessionRecording { } } + private get urlTriggerStatus(): TriggerStatus { + if (this.receivedDecide && this._urlTriggers.length === 0) { + return 'trigger_disabled' + } + + const currentStatus = this.instance?.get_property(SESSION_RECORDING_URL_TRIGGER_STATUS) + const currentTriggerSession = this.instance?.get_property(SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION) + + if (currentTriggerSession !== this.sessionId) { + this.instance?.persistence?.unregister(SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION) + this.instance?.persistence?.unregister(SESSION_RECORDING_URL_TRIGGER_STATUS) + return 'trigger_pending' + } + + if (TRIGGER_STATUSES.includes(currentStatus)) { + return currentStatus as TriggerStatus + } + + return 'trigger_pending' + } + + private set urlTriggerStatus(status: TriggerStatus) { + this.instance?.persistence?.register({ + [SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION]: this.sessionId, + [SESSION_RECORDING_URL_TRIGGER_STATUS]: status, + }) + } + constructor(private readonly instance: PostHog) { this._captureStarted = false this._endpoint = BASE_ENDPOINT @@ -438,6 +489,9 @@ export class SessionRecording { this._onSessionIdListener = this.sessionManager.onSessionId((sessionId, windowId, changeReason) => { if (changeReason) { this._tryAddCustomEvent('$session_id_change', { sessionId, windowId, changeReason }) + + this.instance?.persistence?.unregister(SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION) + this.instance?.persistence?.unregister(SESSION_RECORDING_URL_TRIGGER_STATUS) } }) } @@ -556,6 +610,10 @@ export class SessionRecording { }) } + if (response.sessionRecording?.urlTriggers) { + this._urlTriggers = response.sessionRecording.urlTriggers + } + this.receivedDecide = true this.startIfEnabledOrStop() } @@ -921,11 +979,19 @@ export class SessionRecording { this._pageViewFallBack() } + // Check if the URL matches any trigger patterns + this._checkUrlTrigger() + // we're processing a full snapshot, so we should reset the timer if (rawEvent.type === EventType.FullSnapshot) { this._scheduleFullSnapshot() } + // Clear the buffer if waiting for a trigger, and only keep data from after the current full snapshot + if (rawEvent.type === EventType.FullSnapshot && this.urlTriggerStatus === 'trigger_pending') { + this.clearBuffer() + } + const throttledEvent = this.mutationRateLimiter ? this.mutationRateLimiter.throttleMutations(rawEvent) : rawEvent @@ -1102,6 +1168,36 @@ export class SessionRecording { }) } + private _checkUrlTrigger() { + if (typeof window === 'undefined' || !window.location.href) { + return + } + + const url = window.location.href + + if ( + this._urlTriggers.some((trigger) => { + switch (trigger.matching) { + case 'regex': + return new RegExp(trigger.url).test(url) + default: + return false + } + }) + ) { + this._activateUrlTrigger() + } + } + + private _activateUrlTrigger() { + if (this.urlTriggerStatus === 'trigger_pending') { + this.urlTriggerStatus = 'trigger_activated' + this._tryAddCustomEvent('url trigger activated', {}) + this._flushBuffer() + logger.info(LOGGER_PREFIX + ' recording triggered by URL pattern match') + } + } + /** * this ignores the linked flag config and causes capture to start * (if recording would have started had the flag been received i.e. it does not override other config). diff --git a/src/types.ts b/src/types.ts index bd28662cf..268265f18 100644 --- a/src/types.ts +++ b/src/types.ts @@ -396,6 +396,7 @@ export interface DecideResponse { canvasQuality?: string | null linkedFlag?: string | FlagVariant | null networkPayloadCapture?: Pick + urlTriggers?: SessionRecordingUrlTrigger[] } surveys?: boolean toolbarParams: ToolbarParams @@ -591,3 +592,27 @@ export type ErrorMetadata = { // but provided as an array of literal types, so we can constrain the level below export const severityLevels = ['fatal', 'error', 'warning', 'log', 'info', 'debug'] as const export declare type SeverityLevel = typeof severityLevels[number] + +export interface ErrorProperties { + $exception_type: string + $exception_message: string + $exception_level: SeverityLevel + $exception_source?: string + $exception_lineno?: number + $exception_colno?: number + $exception_DOMException_code?: string + $exception_is_synthetic?: boolean + $exception_stack_trace_raw?: string + $exception_handled?: boolean + $exception_personURL?: string +} + +export interface ErrorConversions { + errorToProperties: (args: ErrorEventArgs) => ErrorProperties + unhandledRejectionToProperties: (args: [ev: PromiseRejectionEvent]) => ErrorProperties +} + +export interface SessionRecordingUrlTrigger { + url: string + matching: 'regex' +} diff --git a/testcafe/helpers.js b/testcafe/helpers.js index e321dc21c..5f3312298 100644 --- a/testcafe/helpers.js +++ b/testcafe/helpers.js @@ -33,7 +33,10 @@ export const staticFilesMock = RequestMock() .onRequestTo(/array.full.js/) .respond((req, res) => { // eslint-disable-next-line no-undef - const arrayjs = fs.readFileSync(path.resolve(__dirname, '../dist/array.full.js')) + const ENV_BROWSER = process.env.BROWSER + const fileToRead = ENV_BROWSER === 'browserstack:ie' ? '../dist/array.full.es5.js' : '../dist/array.full.js' + // eslint-disable-next-line no-undef + const arrayjs = fs.readFileSync(path.resolve(__dirname, fileToRead)) res.setBody(arrayjs) }) .onRequestTo(/playground/)