@replayio/puppeteer
Advanced tools
Comparing version 0.0.0-pr624-20240710193747 to 0.0.0-pr628-20241211184008
# @replayio/puppeteer | ||
## 0.0.0-pr624-20240710193747 | ||
## 0.0.0-pr628-20241211184008 | ||
### Patch Changes | ||
- [#624](https://github.com/replayio/replay-cli/pull/624) [`1d79fbf`](https://github.com/replayio/replay-cli/commit/1d79fbfa9208698cf2afa121554e9191f4e84b20) Thanks [@bvaughn](https://github.com/bvaughn)! - Improve async initialization and teardown logic | ||
- [#624](https://github.com/replayio/replay-cli/pull/624) [`82852c2`](https://github.com/replayio/replay-cli/commit/82852c2d1e9f58c7036a8c0ab5b50e8ef79efa3e) Thanks [@bvaughn](https://github.com/bvaughn)! - Improve async initialization and teardown logic | ||
@@ -9,0 +9,0 @@ ## 0.2.11 |
@@ -16,7 +16,3 @@ 'use strict'; | ||
} | ||
function isTimeoutResult(result) { | ||
return result != null && typeof result === "object" && "timedOutAfter" in result; | ||
} | ||
exports.isTimeoutResult = isTimeoutResult; | ||
exports.timeoutAfter = timeoutAfter; |
@@ -9,3 +9,3 @@ 'use strict'; | ||
async function fetchAuthInfoFromGraphQL(accessToken) { | ||
logger.logger.debug("Fetching auth info from GraphQL"); | ||
logger.logDebug("Fetching auth info from GraphQL"); | ||
const { data, errors } = await queryGraphQL.queryGraphQL( | ||
@@ -12,0 +12,0 @@ "AuthInfo", |
@@ -25,6 +25,6 @@ 'use strict'; | ||
} | ||
logger.logger.debug("Querying graphql endpoint", { name, replayApiServer: config.replayApiServer }); | ||
logger.logDebug("Querying graphql endpoint", { name, replayApiServer: config.replayApiServer }); | ||
const result = await undici.fetch(`${config.replayApiServer}/v1/graphql`, options); | ||
const json = await result.json(); | ||
logger.logger.debug("GraphQL Response", { json }); | ||
logger.logDebug("GraphQL Response", { json }); | ||
return json; | ||
@@ -31,0 +31,0 @@ } |
@@ -9,3 +9,3 @@ 'use strict'; | ||
var getDeviceId = require('./getDeviceId.js'); | ||
var AuthenticatedTaskQueue = require('./session/AuthenticatedTaskQueue.js'); | ||
var createTaskQueue = require('./session/createTaskQueue.js'); | ||
@@ -24,46 +24,33 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } | ||
const stackUtils = new StackUtils__default.default({ cwd: process.cwd(), internals: StackUtils__default.default.nodeInternals() }); | ||
function anonymizeStackTrace(stack) { | ||
return stack.split("\n").map((line) => { | ||
const frame = stackUtils.parseLine(line); | ||
if (frame && frame.file) { | ||
const relativePath = frame.file.includes("node_modules") ? frame.file.substring(frame.file.indexOf("node_modules")) : frame.file; | ||
return line.replace(frame.file, relativePath); | ||
} | ||
return line; | ||
}).join("\n"); | ||
} | ||
class Logger extends AuthenticatedTaskQueue.AuthenticatedTaskQueue { | ||
deviceId; | ||
grafana = null; | ||
localDebugger; | ||
sessionId; | ||
constructor() { | ||
super(); | ||
this.localDebugger = dbg__default.default("replay"); | ||
this.deviceId = getDeviceId.getDeviceId(); | ||
this.sessionId = crypto.randomUUID(); | ||
} | ||
onAuthenticate() { | ||
} | ||
async onFinalize() { | ||
const deviceId = getDeviceId.getDeviceId(); | ||
const localDebugger = dbg__default.default("replay"); | ||
const sessionId = crypto.randomUUID(); | ||
let grafana = null; | ||
const taskQueue = createTaskQueue.createTaskQueue({ | ||
onDestroy: async () => { | ||
if (process.env.REPLAY_TELEMETRY_DISABLED) { | ||
return; | ||
} | ||
if (this.grafana) { | ||
await this.grafana.close(); | ||
if (grafana) { | ||
await grafana.close(); | ||
} | ||
} | ||
onInitialize({ packageName, packageVersion }) { | ||
}, | ||
onInitialize: ({ packageInfo: { packageName, packageVersion } }) => { | ||
const lokiTransport = new LokiTransport__default.default({ | ||
basicAuth: GRAFANA_BASIC_AUTH, | ||
format: winston__default.default.format.json(), | ||
gracefulShutdown: true, | ||
host: HOST, | ||
json: true, | ||
labels: { app: packageName, version: packageVersion }, | ||
json: true, | ||
basicAuth: GRAFANA_BASIC_AUTH, | ||
format: winston__default.default.format.json(), | ||
onConnectionError: (err) => localDebugger("Grafana connection error", err), | ||
replaceTimestamp: true, | ||
timeout: 5e3, | ||
onConnectionError: (err) => this.localDebugger("Grafana connection error", err), | ||
gracefulShutdown: true | ||
timeout: 5e3 | ||
}); | ||
this.grafana = { | ||
grafana = { | ||
close: async () => { | ||
await lokiTransport.flush().catch(() => { | ||
}); | ||
lokiTransport.close?.(); | ||
}, | ||
logger: winston__default.default.createLogger({ | ||
@@ -74,75 +61,78 @@ // Levels greater than or equal to "info" ("info", "warn", "error") will be logged. | ||
transports: [lokiTransport] | ||
}), | ||
close: async () => { | ||
await lokiTransport.flush().catch(() => { | ||
}); | ||
lokiTransport.close?.(); | ||
} | ||
}) | ||
}; | ||
} | ||
log(message, level, tags) { | ||
super.addToQueue((authInfo) => { | ||
const formattedTags = this.formatTags(tags); | ||
this.localDebugger(message, formattedTags); | ||
if (process.env.REPLAY_TELEMETRY_DISABLED) { | ||
return; | ||
} | ||
const entry = { | ||
level, | ||
message, | ||
...formattedTags, | ||
deviceId: this.deviceId, | ||
sessionId: this.sessionId | ||
}; | ||
if (authInfo) { | ||
switch (authInfo.type) { | ||
case "user": { | ||
entry.userId = authInfo.id; | ||
break; | ||
} | ||
case "workspace": { | ||
entry.workspaceId = authInfo.id; | ||
break; | ||
} | ||
}); | ||
async function flushLog() { | ||
await taskQueue.flushAndClose(); | ||
} | ||
function logDebug(message, tags) { | ||
log(message, "debug", tags); | ||
} | ||
function logError(message, tags) { | ||
log(message, "error", tags); | ||
} | ||
function anonymizeStackTrace(stack) { | ||
return stack.split("\n").map((line) => { | ||
const frame = stackUtils.parseLine(line); | ||
if (frame && frame.file) { | ||
const relativePath = frame.file.includes("node_modules") ? frame.file.substring(frame.file.indexOf("node_modules")) : frame.file; | ||
return line.replace(frame.file, relativePath); | ||
} | ||
return line; | ||
}).join("\n"); | ||
} | ||
function log(message, level, tags) { | ||
taskQueue.push((authInfo) => { | ||
const formattedTags = formatTags(tags); | ||
localDebugger(message, formattedTags); | ||
if (process.env.REPLAY_TELEMETRY_DISABLED) { | ||
return; | ||
} | ||
const entry = { | ||
level, | ||
message, | ||
...formattedTags, | ||
deviceId, | ||
sessionId | ||
}; | ||
if (authInfo) { | ||
switch (authInfo.type) { | ||
case "user": { | ||
entry.userId = authInfo.id; | ||
break; | ||
} | ||
case "workspace": { | ||
entry.workspaceId = authInfo.id; | ||
break; | ||
} | ||
} | ||
if (this.grafana) { | ||
this.grafana.logger.log(entry); | ||
} | ||
}); | ||
} | ||
if (grafana) { | ||
grafana.logger.log(entry); | ||
} | ||
}); | ||
} | ||
function formatTags(tags) { | ||
if (!tags) { | ||
return; | ||
} | ||
formatTags(tags) { | ||
if (!tags) { | ||
return; | ||
return Object.entries(tags).reduce((result, [key, value]) => { | ||
if (value instanceof Error) { | ||
result[key] = { | ||
// Intentionally keeping this for any extra properties attached in `Error` | ||
...value, | ||
errorName: value.name, | ||
errorMessage: value.message, | ||
errorStack: anonymizeStackTrace(value.stack ?? "") | ||
}; | ||
} else { | ||
result[key] = value; | ||
} | ||
return Object.entries(tags).reduce((result, [key, value]) => { | ||
if (value instanceof Error) { | ||
result[key] = { | ||
// Intentionally keeping this for any extra properties attached in `Error` | ||
...value, | ||
errorName: value.name, | ||
errorMessage: value.message, | ||
errorStack: anonymizeStackTrace(value.stack ?? "") | ||
}; | ||
} else { | ||
result[key] = value; | ||
} | ||
return result; | ||
}, {}); | ||
} | ||
debug(message, tags) { | ||
this.log(message, "debug", tags); | ||
} | ||
error(message, tags) { | ||
this.log(message, "error", tags); | ||
} | ||
info(message, tags) { | ||
this.log(message, "info", tags); | ||
} | ||
warn(message, tags) { | ||
this.log(message, "warn", tags); | ||
} | ||
return result; | ||
}, {}); | ||
} | ||
const logger = new Logger(); | ||
exports.logger = logger; | ||
exports.flushLog = flushLog; | ||
exports.logDebug = logDebug; | ||
exports.logError = logError; |
@@ -5,89 +5,20 @@ 'use strict'; | ||
var config = require('./config.js'); | ||
var logger = require('./logger.js'); | ||
var AuthenticatedTaskQueue = require('./session/AuthenticatedTaskQueue.js'); | ||
require('./logger.js'); | ||
var createTaskQueue = require('./session/createTaskQueue.js'); | ||
class MixpanelClient extends AuthenticatedTaskQueue.AuthenticatedTaskQueue { | ||
_additionalProperties = {}; | ||
_mixpanelClient; | ||
_packageName; | ||
_packageVersion; | ||
constructor() { | ||
super(); | ||
if (!config.disableMixpanel) { | ||
this._mixpanelClient = mixpanel.init(config.mixpanelToken); | ||
} | ||
if (!config.disableMixpanel) { | ||
mixpanel.init(config.mixpanelToken); | ||
} | ||
const taskQueue = createTaskQueue.createTaskQueue({ | ||
onDestroy: () => { | ||
}, | ||
onInitialize: ({ packageInfo }) => { | ||
packageInfo.packageName; | ||
packageInfo.packageVersion; | ||
} | ||
onAuthenticate() { | ||
} | ||
async onFinalize() { | ||
} | ||
async onInitialize({ packageName, packageVersion }) { | ||
this._packageName = packageName; | ||
this._packageVersion = packageVersion; | ||
} | ||
appendAdditionalProperties(additionalProperties) { | ||
Object.assign(this._additionalProperties, additionalProperties); | ||
} | ||
mockForTests(mock) { | ||
this._mixpanelClient = mock; | ||
} | ||
createAsyncFunctionWithTracking(createPromise, eventName, properties) { | ||
return (...args) => this.trackAsyncEvent(createPromise(...args), eventName, properties); | ||
} | ||
async trackAsyncEvent(promise, eventName, properties = {}) { | ||
logger.logger.debug(`Waiting to log Mixpanel event "${eventName}" (awaiting promise)`, { | ||
eventName, | ||
properties | ||
}); | ||
const startTime = Date.now(); | ||
let result = void 0; | ||
let succeeded = false; | ||
let thrown = void 0; | ||
try { | ||
result = await promise; | ||
succeeded = true; | ||
} catch (error) { | ||
thrown = error; | ||
} | ||
const endTime = Date.now(); | ||
this.trackEvent(eventName, { | ||
...typeof properties === "function" ? properties(result, thrown) : properties, | ||
duration: endTime - startTime, | ||
succeeded | ||
}); | ||
if (succeeded) { | ||
return result; | ||
} else { | ||
throw thrown; | ||
} | ||
} | ||
trackEvent(eventName, properties = {}) { | ||
if (this._packageName) { | ||
const prefix = `${this._packageName}.`; | ||
if (!eventName.startsWith(prefix)) { | ||
eventName = prefix + eventName; | ||
} | ||
} | ||
super.addToQueue(async (authInfo) => { | ||
logger.logger.debug("MixpanelClient:AddToQueue:SendMessage", { eventName, properties }); | ||
this._mixpanelClient?.track( | ||
eventName, | ||
{ | ||
...properties, | ||
...this._additionalProperties, | ||
distinct_id: authInfo?.id, | ||
packageName: this._packageName, | ||
packageVersion: this._packageVersion | ||
}, | ||
(error) => { | ||
if (error) { | ||
logger.logger.error("MixpanelClient:AddToQueue:Failed", { eventName, error, properties }); | ||
} else { | ||
logger.logger.debug("MixpanelClient:AddToQueue:Success", { eventName, properties }); | ||
} | ||
} | ||
); | ||
}); | ||
} | ||
}); | ||
async function closeMixpanel() { | ||
await taskQueue.flushAndClose(); | ||
} | ||
new MixpanelClient(); | ||
exports.closeMixpanel = closeMixpanel; |
@@ -15,3 +15,3 @@ 'use strict'; | ||
async function getLatestRuntimeRelease() { | ||
logger.logger.debug("Fetching release metadata"); | ||
logger.logDebug("Fetching release metadata"); | ||
const response = await undici.fetch(`${config.replayAppHost}/api/releases`); | ||
@@ -22,3 +22,3 @@ const json = await response.json(); | ||
); | ||
logger.logger.debug("Latest release", { latestRelease }); | ||
logger.logDebug("Latest release", { latestRelease }); | ||
assert__default.default(latestRelease, `No release found for ${platform}:${runtime}`); | ||
@@ -25,0 +25,0 @@ return latestRelease; |
@@ -11,3 +11,3 @@ 'use strict'; | ||
if (overridePath) { | ||
logger.logger.debug(`Using executable override for chromium: ${overridePath}`); | ||
logger.logDebug(`Using executable override for chromium: ${overridePath}`); | ||
return overridePath; | ||
@@ -14,0 +14,0 @@ } |
@@ -23,9 +23,9 @@ 'use strict'; | ||
}); | ||
logger.logger.debug(`Removing previous installation at ${runtimePath}`); | ||
logger.logDebug(`Removing previous installation at ${runtimePath}`); | ||
fsExtra.rmSync(runtimePath, { force: true, recursive: true }); | ||
fsExtra.ensureDirSync(config.runtimeBasePath); | ||
logger.logger.debug(`Writing downloaded file data to ${downloadFilePath}`); | ||
logger.logDebug(`Writing downloaded file data to ${downloadFilePath}`); | ||
fsExtra.writeFileSync(downloadFilePath, buffers); | ||
extractBrowserArchive(config.runtimeBasePath, runtimePath); | ||
logger.logger.debug(`Deleting downloaded file ${downloadFilePath}`); | ||
logger.logDebug(`Deleting downloaded file ${downloadFilePath}`); | ||
fsExtra.unlinkSync(downloadFilePath); | ||
@@ -41,3 +41,3 @@ if (config.runtimeMetadata.sourceName !== config.runtimeMetadata.destinationName) { | ||
const latestVersion = latestRelease.version; | ||
logger.logger.debug(`Saving release metadata to ${config.metadataPath}`); | ||
logger.logDebug(`Saving release metadata to ${config.metadataPath}`); | ||
cache.writeToCache(config.metadataPath, { | ||
@@ -55,3 +55,3 @@ chromium: { | ||
} catch (error) { | ||
logger.logger.debug("Browser installation failed", { error }); | ||
logger.logDebug("Browser installation failed", { error }); | ||
} | ||
@@ -72,3 +72,3 @@ } | ||
if (response.statusCode != 200) { | ||
logger.logger.debug(`Download received status code ${response.statusCode}, retrying...`); | ||
logger.logDebug(`Download received status code ${response.statusCode}, retrying...`); | ||
request.destroy(); | ||
@@ -83,3 +83,3 @@ resolve(null); | ||
request.on("error", (error) => { | ||
logger.logger.debug("Download error; retrying ...", { error }); | ||
logger.logDebug("Download error; retrying ...", { error }); | ||
request.destroy(); | ||
@@ -96,3 +96,3 @@ resolve(null); | ||
async function extractBrowserArchive(runtimeBasePath2, downloadFilePath) { | ||
logger.logger.debug(`Extracting archived file at ${downloadFilePath}`); | ||
logger.logDebug(`Extracting archived file at ${downloadFilePath}`); | ||
const tarResult = child_process.spawnSync("tar", ["xf", config.runtimeMetadata.downloadFileName], { | ||
@@ -102,3 +102,3 @@ cwd: runtimeBasePath2 | ||
if (tarResult.status !== 0) { | ||
logger.logger.debug(`Failed to extract ${downloadFilePath}`, { stderr: String(tarResult.stderr) }); | ||
logger.logDebug(`Failed to extract ${downloadFilePath}`, { stderr: String(tarResult.stderr) }); | ||
throw new Error("Unable to extract browser archive"); | ||
@@ -105,0 +105,0 @@ } |
'use strict'; | ||
var deferred = require('./deferred.js'); | ||
var waitForPackageInfo = require('./waitForPackageInfo.js'); | ||
async function getUserAgent() { | ||
const { packageName, packageVersion } = await deferred.deferredPackageInfo.promise; | ||
const { packageName, packageVersion } = await waitForPackageInfo.waitForPackageInfo(); | ||
return `${packageName}/${packageVersion}`; | ||
@@ -8,0 +8,0 @@ } |
'use strict'; | ||
var createDeferred = require('../async/createDeferred.js'); | ||
var getAuthInfo = require('../authentication/getAuthInfo.js'); | ||
var deferred = require('./deferred.js'); | ||
var initializeAuthInfo = require('./initializeAuthInfo.js'); | ||
var initializePackageInfo = require('./initializePackageInfo.js'); | ||
@@ -12,13 +11,6 @@ async function initializeSession({ | ||
}) { | ||
if (deferred.deferredPackageInfo.status === createDeferred.STATUS_RESOLVED) { | ||
return; | ||
} | ||
deferred.deferredPackageInfo.resolve({ packageName, packageVersion }); | ||
let authInfo = void 0; | ||
if (accessToken) { | ||
authInfo = await getAuthInfo.getAuthInfo(accessToken); | ||
} | ||
deferred.deferredAuthInfo.resolve(authInfo); | ||
await initializePackageInfo.initializePackageInfo({ packageName, packageVersion }); | ||
await initializeAuthInfo.initializeAuthInfo({ accessToken }); | ||
} | ||
exports.initializeSession = initializeSession; |
'use strict'; | ||
var logger = require('../../@replay-cli/shared/logger.js'); | ||
function getAccessToken(config) { | ||
return config?.apiKey || process.env.REPLAY_API_KEY || process.env.RECORD_REPLAY_API_KEY; | ||
if (process.env.REPLAY_API_KEY) { | ||
logger.logDebug("Using token from env (REPLAY_API_KEY)"); | ||
return process.env.REPLAY_API_KEY; | ||
} else if (process.env.RECORD_REPLAY_API_KEY) { | ||
logger.logDebug("Using token from env (RECORD_REPLAY_API_KEY)"); | ||
return process.env.RECORD_REPLAY_API_KEY; | ||
} | ||
} | ||
exports.getAccessToken = getAccessToken; |
'use strict'; | ||
var getReplayPath = require('../../@replay-cli/shared/getReplayPath.js'); | ||
var logger = require('../../@replay-cli/shared/logger.js'); | ||
var fs = require('fs'); | ||
var logging = require('./logging.js'); | ||
var logger = require('../../@replay-cli/shared/logger.js'); | ||
@@ -19,3 +19,3 @@ function getMetadataFilePath(base, workerIndex = 0) { | ||
logging.warn(`Failed to initialize metadata file${path ? ` at ${path}` : ""}`, error); | ||
logger.logger.error("InitMetadataFile:Failed", { | ||
logger.logError("InitMetadataFile:Failed", { | ||
path, | ||
@@ -22,0 +22,0 @@ error |
'use strict'; | ||
var getRuntimePath = require('./_bundled/@replay-cli/shared/runtime/getRuntimePath.js'); | ||
require('./_bundled/@replay-cli/shared/logger.js'); | ||
require('node-fetch'); | ||
require('./_bundled/@replay-cli/shared/logger.js'); | ||
var metadata = require('./_bundled/@replayio/test-utils/metadata.js'); | ||
@@ -10,8 +10,12 @@ require('node:os'); | ||
require('./_bundled/@replay-cli/shared/config.js'); | ||
require('./_bundled/@replay-cli/shared/session/deferred.js'); | ||
require('./_bundled/@replay-cli/shared/session/waitForPackageInfo.js'); | ||
require('./_bundled/@replay-cli/shared/mixpanelClient.js'); | ||
require('fs-extra'); | ||
require('node:assert/strict'); | ||
require('path'); | ||
require('./_bundled/@replay-cli/shared/recording/config.js'); | ||
require('./_bundled/@replay-cli/shared/recording/readRecordingLog.js'); | ||
require('node:path'); | ||
require('node:fs'); | ||
require('os'); | ||
require('path'); | ||
require('fs'); | ||
@@ -21,14 +25,9 @@ require('superstruct'); | ||
require('./_bundled/@replay-cli/shared/recording/metadata/legacy/test/v2.js'); | ||
require('./_bundled/@replay-cli/shared/launchDarklylient.js'); | ||
require('ws'); | ||
require('fs/promises'); | ||
require('crypto'); | ||
require('child_process'); | ||
require('node:assert/strict'); | ||
require('uuid'); | ||
require('http'); | ||
require('https'); | ||
require('p-map'); | ||
require('jsonata'); | ||
require('ws'); | ||
require('launchdarkly-node-client-sdk'); | ||
require('./_bundled/@replay-cli/shared/recording/config.js'); | ||
require('crypto'); | ||
require('worker_threads'); | ||
require('sha-1'); | ||
@@ -35,0 +34,0 @@ |
@@ -6,2 +6,3 @@ 'use strict'; | ||
var logger = require('./_bundled/@replay-cli/shared/logger.js'); | ||
var waitForExitTasks = require('./_bundled/@replay-cli/shared/process/waitForExitTasks.js'); | ||
var installLatestRuntimeRelease = require('./_bundled/@replay-cli/shared/runtime/installLatestRuntimeRelease.js'); | ||
@@ -17,4 +18,8 @@ var initializeSession = require('./_bundled/@replay-cli/shared/session/initializeSession.js'); | ||
require('./_bundled/@replay-cli/shared/config.js'); | ||
require('./_bundled/@replay-cli/shared/session/deferred.js'); | ||
require('./_bundled/@replay-cli/shared/session/waitForPackageInfo.js'); | ||
require('./_bundled/@replay-cli/shared/mixpanelClient.js'); | ||
require('fs-extra'); | ||
require('node:assert/strict'); | ||
require('./_bundled/@replay-cli/shared/recording/config.js'); | ||
require('./_bundled/@replay-cli/shared/recording/readRecordingLog.js'); | ||
require('node:path'); | ||
@@ -25,14 +30,9 @@ require('node:fs'); | ||
require('./_bundled/@replay-cli/shared/recording/metadata/legacy/test/v2.js'); | ||
require('./_bundled/@replay-cli/shared/launchDarklylient.js'); | ||
require('ws'); | ||
require('fs/promises'); | ||
require('crypto'); | ||
require('child_process'); | ||
require('node:assert/strict'); | ||
require('uuid'); | ||
require('http'); | ||
require('https'); | ||
require('p-map'); | ||
require('jsonata'); | ||
require('ws'); | ||
require('launchdarkly-node-client-sdk'); | ||
require('./_bundled/@replay-cli/shared/recording/config.js'); | ||
require('crypto'); | ||
require('worker_threads'); | ||
require('sha-1'); | ||
@@ -43,3 +43,3 @@ var _package = require('./package.json.js'); | ||
try { | ||
initializeSession.initializeSession({ | ||
await initializeSession.initializeSession({ | ||
accessToken: getAccessToken.getAccessToken(), | ||
@@ -50,3 +50,3 @@ packageName: _package.name, | ||
} catch (error) { | ||
logger.logger.error("Failed to identify for logger", { error }); | ||
logger.logError("Failed to identify for logger", { error }); | ||
} | ||
@@ -56,3 +56,3 @@ try { | ||
} finally { | ||
await logger.logger.close(); | ||
await waitForExitTasks.waitForExitTasks(); | ||
} | ||
@@ -59,0 +59,0 @@ } |
'use strict'; | ||
var name = "@replayio/puppeteer"; | ||
var version = "0.0.0-pr624-20240710193747"; | ||
var version = "0.0.0-pr628-20241211184008"; | ||
exports.name = name; | ||
exports.version = version; |
{ | ||
"name": "@replayio/puppeteer", | ||
"version": "0.0.0-pr624-20240710193747", | ||
"version": "0.0.0-pr628-20241211184008", | ||
"description": "Configuration utilities for using the Replay browsers with puppeteer", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
50869
54
1348
4
32