@glasstrace/sdk 0.2.0 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/adapters/drizzle.cjs +729 -3
  2. package/dist/adapters/drizzle.cjs.map +1 -1
  3. package/dist/adapters/drizzle.js +6 -1
  4. package/dist/adapters/drizzle.js.map +1 -1
  5. package/dist/chunk-CUFIV225.js +14083 -0
  6. package/dist/chunk-CUFIV225.js.map +1 -0
  7. package/dist/chunk-DQ25VOKK.js +1250 -0
  8. package/dist/chunk-DQ25VOKK.js.map +1 -0
  9. package/dist/chunk-PZ5AY32C.js +10 -0
  10. package/dist/chunk-PZ5AY32C.js.map +1 -0
  11. package/dist/chunk-WZXVS2EO.js +9 -0
  12. package/dist/chunk-WZXVS2EO.js.map +1 -0
  13. package/dist/cli/init.cjs +13863 -12
  14. package/dist/cli/init.cjs.map +1 -1
  15. package/dist/cli/init.js +10 -9
  16. package/dist/cli/init.js.map +1 -1
  17. package/dist/esm-POMEQPKL.js +62 -0
  18. package/dist/esm-POMEQPKL.js.map +1 -0
  19. package/dist/getMachineId-bsd-TC3JSTY5.js +29 -0
  20. package/dist/getMachineId-bsd-TC3JSTY5.js.map +1 -0
  21. package/dist/getMachineId-darwin-2SUKQCE6.js +29 -0
  22. package/dist/getMachineId-darwin-2SUKQCE6.js.map +1 -0
  23. package/dist/getMachineId-linux-PNAFHLXH.js +23 -0
  24. package/dist/getMachineId-linux-PNAFHLXH.js.map +1 -0
  25. package/dist/getMachineId-unsupported-L2MNYW3W.js +14 -0
  26. package/dist/getMachineId-unsupported-L2MNYW3W.js.map +1 -0
  27. package/dist/getMachineId-win-D6D42WOQ.js +31 -0
  28. package/dist/getMachineId-win-D6D42WOQ.js.map +1 -0
  29. package/dist/index.cjs +18836 -815
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +131 -5
  32. package/dist/index.d.ts +131 -5
  33. package/dist/index.js +2758 -238
  34. package/dist/index.js.map +1 -1
  35. package/package.json +4 -10
  36. package/dist/chunk-BKMITIEZ.js +0 -169
  37. package/dist/chunk-BKMITIEZ.js.map +0 -1
package/dist/cli/init.js CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildImportGraph
4
- } from "../chunk-BKMITIEZ.js";
4
+ } from "../chunk-CUFIV225.js";
5
+ import "../chunk-PZ5AY32C.js";
5
6
 
6
7
  // src/cli/init.ts
7
8
  import * as fs2 from "fs";
@@ -112,14 +113,14 @@ async function scaffoldEnvLocal(projectRoot) {
112
113
  const filePath = path.join(projectRoot, ".env.local");
113
114
  if (fs.existsSync(filePath)) {
114
115
  const existing = fs.readFileSync(filePath, "utf-8");
115
- if (/^\s*GLASSTRACE_API_KEY\s*=/m.test(existing)) {
116
+ if (/^\s*#?\s*GLASSTRACE_API_KEY\s*=/m.test(existing)) {
116
117
  return false;
117
118
  }
118
119
  const separator = existing.endsWith("\n") ? "" : "\n";
119
- fs.writeFileSync(filePath, existing + separator + "GLASSTRACE_API_KEY=\n", "utf-8");
120
+ fs.writeFileSync(filePath, existing + separator + "# GLASSTRACE_API_KEY=your_key_here\n", "utf-8");
120
121
  return true;
121
122
  }
122
- fs.writeFileSync(filePath, "GLASSTRACE_API_KEY=\n", "utf-8");
123
+ fs.writeFileSync(filePath, "# GLASSTRACE_API_KEY=your_key_here\n", "utf-8");
123
124
  return true;
124
125
  }
125
126
  async function addCoverageMapEnv(projectRoot) {
@@ -235,9 +236,9 @@ async function runInit(options) {
235
236
  try {
236
237
  const envCreated = await scaffoldEnvLocal(projectRoot);
237
238
  if (envCreated) {
238
- summary.push("Updated .env.local with GLASSTRACE_API_KEY placeholder");
239
+ summary.push("Updated .env.local with Glasstrace configuration");
239
240
  } else {
240
- summary.push("Skipped .env.local (GLASSTRACE_API_KEY already present)");
241
+ summary.push("Skipped .env.local (GLASSTRACE_API_KEY already configured)");
241
242
  }
242
243
  } catch (err) {
243
244
  errors.push(`Failed to update .env.local: ${err instanceof Error ? err.message : String(err)}`);
@@ -326,9 +327,9 @@ if (isDirectExecution) {
326
327
  `);
327
328
  }
328
329
  process.stderr.write("\nNext steps:\n");
329
- process.stderr.write(" 1. Set your GLASSTRACE_API_KEY in .env.local\n");
330
- process.stderr.write(" 2. Start your Next.js dev server\n");
331
- process.stderr.write(" 3. Glasstrace will begin capturing traces automatically\n\n");
330
+ process.stderr.write(" 1. Start your Next.js dev server\n");
331
+ process.stderr.write(" 2. Glasstrace works immediately in anonymous mode\n");
332
+ process.stderr.write(" 3. To link to your account, set GLASSTRACE_API_KEY in .env.local\n\n");
332
333
  }
333
334
  process.exit(result.exitCode);
334
335
  }).catch((err) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/init.ts","../../src/cli/scaffolder.ts"],"sourcesContent":["#!/usr/bin/env node\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline\";\nimport {\n scaffoldInstrumentation,\n scaffoldNextConfig,\n scaffoldEnvLocal,\n scaffoldGitignore,\n addCoverageMapEnv,\n} from \"./scaffolder.js\";\nimport { buildImportGraph } from \"../import-graph.js\";\n\n/** Options for the init command (parsed from CLI args or passed programmatically). */\nexport interface InitOptions {\n projectRoot: string;\n yes: boolean;\n coverageMap: boolean;\n}\n\n/** Result of running the init command. */\nexport interface InitResult {\n exitCode: number;\n summary: string[];\n warnings: string[];\n errors: string[];\n}\n\n/**\n * Prompts the user with a yes/no question. Returns true for yes.\n * In non-interactive mode (no TTY), returns the default value.\n */\nasync function promptYesNo(question: string, defaultValue: boolean): Promise<boolean> {\n if (!process.stdin.isTTY) {\n return defaultValue;\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise<boolean>((resolve) => {\n const suffix = defaultValue ? \" [Y/n] \" : \" [y/N] \";\n rl.question(question + suffix, (answer) => {\n rl.close();\n const trimmed = answer.trim().toLowerCase();\n if (trimmed === \"\") {\n resolve(defaultValue);\n return;\n }\n resolve(trimmed === \"y\" || trimmed === \"yes\");\n });\n });\n}\n\n/**\n * Core init logic. Exported for testability — the CLI entry point at the\n * bottom calls this function and translates the result to process.exit().\n */\nexport async function runInit(options: InitOptions): Promise<InitResult> {\n const { projectRoot, yes, coverageMap } = options;\n const summary: string[] = [];\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // Step 1: Detect package.json\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) {\n errors.push(\"No package.json found. Run this command from a Node.js project root.\");\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 2 + 3: Generate instrumentation.ts\n const instrumentationPath = path.join(projectRoot, \"instrumentation.ts\");\n const instrumentationExists = fs.existsSync(instrumentationPath);\n let shouldWriteInstrumentation = true;\n\n if (instrumentationExists && !yes) {\n shouldWriteInstrumentation = await promptYesNo(\n \"instrumentation.ts already exists. Overwrite?\",\n false,\n );\n } else if (instrumentationExists && yes) {\n // Non-interactive: never overwrite (idempotent)\n shouldWriteInstrumentation = false;\n }\n\n try {\n const created = await scaffoldInstrumentation(projectRoot, shouldWriteInstrumentation && instrumentationExists);\n if (created) {\n summary.push(\"Created instrumentation.ts\");\n } else if (instrumentationExists) {\n summary.push(\"Skipped instrumentation.ts (already exists)\");\n }\n } catch (err) {\n errors.push(`Failed to write instrumentation.ts: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 4: Detect and wrap next.config.*\n try {\n const wrapped = await scaffoldNextConfig(projectRoot);\n if (wrapped) {\n summary.push(\"Wrapped next.config with withGlasstraceConfig()\");\n } else {\n // Check if it was skipped because file already wrapped vs not found\n const hasNextConfig = [\"next.config.ts\", \"next.config.js\", \"next.config.mjs\"].some(\n (name) => fs.existsSync(path.join(projectRoot, name)),\n );\n if (hasNextConfig) {\n summary.push(\"Skipped next.config (already contains withGlasstraceConfig)\");\n } else {\n warnings.push(\"No next.config.* found. You may need to create one for Next.js projects.\");\n }\n }\n } catch (err) {\n errors.push(`Failed to modify next.config: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 5: Update .env.local\n try {\n const envCreated = await scaffoldEnvLocal(projectRoot);\n if (envCreated) {\n summary.push(\"Updated .env.local with GLASSTRACE_API_KEY placeholder\");\n } else {\n summary.push(\"Skipped .env.local (GLASSTRACE_API_KEY already present)\");\n }\n } catch (err) {\n errors.push(`Failed to update .env.local: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 6: Update .gitignore\n try {\n const gitignoreUpdated = await scaffoldGitignore(projectRoot);\n if (gitignoreUpdated) {\n summary.push(\"Updated .gitignore with .glasstrace/\");\n } else {\n summary.push(\"Skipped .gitignore (.glasstrace/ already listed)\");\n }\n } catch (err) {\n errors.push(`Failed to update .gitignore: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 7: Coverage map opt-in\n let enableCoverageMap = coverageMap;\n if (!yes && !coverageMap) {\n if (process.stdin.isTTY) {\n enableCoverageMap = await promptYesNo(\n \"Would you like to enable test coverage mapping?\",\n false,\n );\n }\n }\n\n if (enableCoverageMap) {\n try {\n const added = await addCoverageMapEnv(projectRoot);\n if (added) {\n summary.push(\"Added GLASSTRACE_COVERAGE_MAP=true to .env.local\");\n }\n } catch (err) {\n warnings.push(`Failed to add coverage map env: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n // Step 8: Run initial import graph scan\n try {\n await buildImportGraph(projectRoot);\n summary.push(\"Completed initial import graph scan\");\n } catch (err) {\n warnings.push(`Import graph scan failed: ${err instanceof Error ? err.message : String(err)}. You can run it later.`);\n }\n }\n\n return { exitCode: 0, summary, warnings, errors };\n}\n\n/**\n * Parses CLI arguments into InitOptions.\n */\nfunction parseArgs(argv: string[]): InitOptions {\n const args = argv.slice(2); // skip node + script path\n let yes = false;\n let coverageMap = false;\n\n for (const arg of args) {\n if (arg === \"--yes\" || arg === \"-y\") {\n yes = true;\n } else if (arg === \"--coverage-map\") {\n coverageMap = true;\n }\n }\n\n // Auto-detect non-interactive\n if (!process.stdin.isTTY) {\n yes = true;\n }\n\n return {\n projectRoot: process.cwd(),\n yes,\n coverageMap,\n };\n}\n\n/**\n * CLI entry point. Only runs when this module is executed directly\n * (not when imported for testing).\n */\nconst scriptPath =\n typeof process !== \"undefined\" && process.argv[1] !== undefined\n ? process.argv[1].replace(/\\\\/g, \"/\")\n : undefined;\n\nconst scriptBasename = scriptPath !== undefined ? path.basename(scriptPath) : undefined;\n\nconst isDirectExecution =\n scriptPath !== undefined &&\n (scriptPath.endsWith(\"/cli/init.js\") ||\n scriptPath.endsWith(\"/cli/init.ts\") ||\n scriptBasename === \"glasstrace\");\n\nif (isDirectExecution) {\n const options = parseArgs(process.argv);\n\n runInit(options)\n .then((result) => {\n if (result.errors.length > 0) {\n for (const err of result.errors) {\n process.stderr.write(`Error: ${err}\\n`);\n }\n }\n if (result.warnings.length > 0) {\n for (const warn of result.warnings) {\n process.stderr.write(`Warning: ${warn}\\n`);\n }\n }\n if (result.summary.length > 0) {\n process.stderr.write(\"\\nGlasstrace initialized successfully!\\n\\n\");\n for (const line of result.summary) {\n process.stderr.write(` - ${line}\\n`);\n }\n process.stderr.write(\"\\nNext steps:\\n\");\n process.stderr.write(\" 1. Set your GLASSTRACE_API_KEY in .env.local\\n\");\n process.stderr.write(\" 2. Start your Next.js dev server\\n\");\n process.stderr.write(\" 3. Glasstrace will begin capturing traces automatically\\n\\n\");\n }\n process.exit(result.exitCode);\n })\n .catch((err: unknown) => {\n process.stderr.write(`Fatal error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n });\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\n/** Next.js config file names in priority order */\nconst NEXT_CONFIG_NAMES = [\"next.config.ts\", \"next.config.js\", \"next.config.mjs\"] as const;\n\n/**\n * Generates `instrumentation.ts` with a `registerGlasstrace()` call.\n * If the file exists and `force` is false, the file is not overwritten.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @param force - When true, overwrite an existing instrumentation.ts file.\n * @returns True if the file was written, false if it was skipped.\n */\nexport async function scaffoldInstrumentation(\n projectRoot: string,\n force: boolean,\n): Promise<boolean> {\n const filePath = path.join(projectRoot, \"instrumentation.ts\");\n\n if (fs.existsSync(filePath) && !force) {\n return false;\n }\n\n const content = `import { registerGlasstrace } from \"@glasstrace/sdk\";\n\nexport async function register() {\n // Glasstrace must be registered before Prisma instrumentation\n // to ensure all ORM spans are captured correctly.\n // If you use @prisma/instrumentation, import it after this call.\n registerGlasstrace();\n}\n`;\n\n fs.writeFileSync(filePath, content, \"utf-8\");\n return true;\n}\n\n/**\n * Detects `next.config.js`, `next.config.ts`, or `next.config.mjs` and wraps\n * with `withGlasstraceConfig()`. If the config already contains\n * `withGlasstraceConfig`, the file is not modified.\n *\n * For CJS `.js` configs, adds a `require()` call and wraps `module.exports`.\n * The SDK ships dual ESM/CJS builds via tsup + conditional exports, so\n * `require(\"@glasstrace/sdk\")` resolves to the CJS entrypoint natively.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the config file was modified (or created), false if skipped.\n */\nexport async function scaffoldNextConfig(\n projectRoot: string,\n): Promise<boolean> {\n let configPath: string | undefined;\n let configName: string | undefined;\n\n for (const name of NEXT_CONFIG_NAMES) {\n const candidate = path.join(projectRoot, name);\n if (fs.existsSync(candidate)) {\n configPath = candidate;\n configName = name;\n break;\n }\n }\n\n if (configPath === undefined || configName === undefined) {\n return false;\n }\n\n const existing = fs.readFileSync(configPath, \"utf-8\");\n\n // Already wrapped — skip even in force mode to avoid double-wrapping\n if (existing.includes(\"withGlasstraceConfig\")) {\n return false;\n }\n\n const isESM = configName.endsWith(\".ts\") || configName.endsWith(\".mjs\");\n\n if (isESM) {\n // ESM: static import at top of file, wrap the export\n const importLine = 'import { withGlasstraceConfig } from \"@glasstrace/sdk\";\\n';\n const wrapResult = wrapExport(existing);\n if (!wrapResult.wrapped) {\n return false;\n }\n const modified = importLine + \"\\n\" + wrapResult.content;\n fs.writeFileSync(configPath, modified, \"utf-8\");\n return true;\n }\n\n // CJS (.js): require() the SDK (resolves to the CJS dist build) and\n // wrap the module.exports expression in place — no file renaming needed.\n const requireLine = 'const { withGlasstraceConfig } = require(\"@glasstrace/sdk\");\\n';\n const wrapResult = wrapCJSExport(existing);\n if (!wrapResult.wrapped) {\n return false;\n }\n const modified = requireLine + \"\\n\" + wrapResult.content;\n fs.writeFileSync(configPath, modified, \"utf-8\");\n return true;\n}\n\ninterface WrapResult {\n content: string;\n wrapped: boolean;\n}\n\n/**\n * Wraps an ESM `export default` expression with `withGlasstraceConfig()`.\n *\n * Strategy: find the last `export default` in the file. Everything from\n * that statement to EOF is the exported expression. Strip optional trailing\n * semicolons/whitespace and wrap with `withGlasstraceConfig(...)`.\n *\n * @param content - The full file content containing an ESM default export.\n * @returns `{ wrapped: true, content }` on success, or `{ wrapped: false }` if\n * no recognizable export pattern was found (content returned unchanged).\n */\nfunction wrapExport(content: string): WrapResult {\n // Find the last `export default` — use lastIndexOf for robustness\n const marker = \"export default\";\n const idx = content.lastIndexOf(marker);\n if (idx === -1) {\n return { content, wrapped: false };\n }\n\n const preamble = content.slice(0, idx);\n const exprRaw = content.slice(idx + marker.length);\n // Trim leading whitespace; strip trailing semicolon + whitespace\n const expr = exprRaw.trim().replace(/;?\\s*$/, \"\");\n if (expr.length === 0) {\n return { content, wrapped: false };\n }\n\n return {\n content: preamble + `export default withGlasstraceConfig(${expr});\\n`,\n wrapped: true,\n };\n}\n\n/**\n * Wraps a CJS `module.exports = expr` with `withGlasstraceConfig()`.\n *\n * Strategy: find the last `module.exports =` in the file. Everything from\n * that statement to EOF is the exported expression. Strip optional trailing\n * semicolons/whitespace and wrap with `module.exports = withGlasstraceConfig(...)`.\n *\n * @param content - The full CJS file content containing `module.exports = ...`.\n * @returns `{ wrapped: true, content }` on success, or `{ wrapped: false }` if\n * no recognizable `module.exports` pattern was found (content returned unchanged).\n */\nfunction wrapCJSExport(content: string): WrapResult {\n const cjsMarker = \"module.exports\";\n const cjsIdx = content.lastIndexOf(cjsMarker);\n if (cjsIdx === -1) {\n return { content, wrapped: false };\n }\n\n const preamble = content.slice(0, cjsIdx);\n const afterMarker = content.slice(cjsIdx + cjsMarker.length);\n const eqMatch = /^\\s*=\\s*/.exec(afterMarker);\n if (!eqMatch) {\n return { content, wrapped: false };\n }\n\n const exprRaw = afterMarker.slice(eqMatch[0].length);\n const expr = exprRaw.trim().replace(/;?\\s*$/, \"\");\n if (expr.length === 0) {\n return { content, wrapped: false };\n }\n\n return {\n content: preamble + `module.exports = withGlasstraceConfig(${expr});\\n`,\n wrapped: true,\n };\n}\n\n/**\n * Creates `.env.local` with `GLASSTRACE_API_KEY=` placeholder, or appends\n * to an existing file if it does not already contain `GLASSTRACE_API_KEY`.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the file was created or modified, false if already configured.\n */\nexport async function scaffoldEnvLocal(projectRoot: string): Promise<boolean> {\n const filePath = path.join(projectRoot, \".env.local\");\n\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, \"utf-8\");\n if (/^\\s*GLASSTRACE_API_KEY\\s*=/m.test(existing)) {\n return false;\n }\n // Append with a newline separator if needed\n const separator = existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n fs.writeFileSync(filePath, existing + separator + \"GLASSTRACE_API_KEY=\\n\", \"utf-8\");\n return true;\n }\n\n fs.writeFileSync(filePath, \"GLASSTRACE_API_KEY=\\n\", \"utf-8\");\n return true;\n}\n\n/**\n * Adds `GLASSTRACE_COVERAGE_MAP=true` to `.env.local`.\n * Creates the file if it does not exist. If the key is already present\n * with a value other than `true`, it is updated in place.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the file was created or modified, false if already set to `true`.\n */\nexport async function addCoverageMapEnv(projectRoot: string): Promise<boolean> {\n const filePath = path.join(projectRoot, \".env.local\");\n\n if (!fs.existsSync(filePath)) {\n fs.writeFileSync(filePath, \"GLASSTRACE_COVERAGE_MAP=true\\n\", \"utf-8\");\n return true;\n }\n\n const existing = fs.readFileSync(filePath, \"utf-8\");\n const keyRegex = /^(\\s*GLASSTRACE_COVERAGE_MAP\\s*=\\s*)(.*)$/m;\n const keyMatch = keyRegex.exec(existing);\n\n if (keyMatch) {\n const currentValue = keyMatch[2].trim();\n if (currentValue === \"true\") {\n // Already set to true — nothing to do\n return false;\n }\n // Key exists but is not `true` — update in place\n const updated = existing.replace(keyRegex, `${keyMatch[1]}true`);\n fs.writeFileSync(filePath, updated, \"utf-8\");\n return true;\n }\n\n const separator = existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n fs.writeFileSync(filePath, existing + separator + \"GLASSTRACE_COVERAGE_MAP=true\\n\", \"utf-8\");\n return true;\n}\n\n/**\n * Adds `.glasstrace/` to `.gitignore`, or creates `.gitignore` if missing.\n * Does not add duplicate entries.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the file was created or modified, false if already configured.\n */\nexport async function scaffoldGitignore(projectRoot: string): Promise<boolean> {\n const filePath = path.join(projectRoot, \".gitignore\");\n\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, \"utf-8\");\n // Check line-by-line to avoid false positive partial matches\n const lines = existing.split(\"\\n\").map((l) => l.trim());\n if (lines.includes(\".glasstrace/\")) {\n return false;\n }\n const separator = existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n fs.writeFileSync(filePath, existing + separator + \".glasstrace/\\n\", \"utf-8\");\n return true;\n }\n\n fs.writeFileSync(filePath, \".glasstrace/\\n\", \"utf-8\");\n return true;\n}\n"],"mappings":"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","names":["fs","path","wrapResult","modified"]}
1
+ {"version":3,"sources":["../../src/cli/init.ts","../../src/cli/scaffolder.ts"],"sourcesContent":["#!/usr/bin/env node\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline\";\nimport {\n scaffoldInstrumentation,\n scaffoldNextConfig,\n scaffoldEnvLocal,\n scaffoldGitignore,\n addCoverageMapEnv,\n} from \"./scaffolder.js\";\nimport { buildImportGraph } from \"../import-graph.js\";\n\n/** Options for the init command (parsed from CLI args or passed programmatically). */\nexport interface InitOptions {\n projectRoot: string;\n yes: boolean;\n coverageMap: boolean;\n}\n\n/** Result of running the init command. */\nexport interface InitResult {\n exitCode: number;\n summary: string[];\n warnings: string[];\n errors: string[];\n}\n\n/**\n * Prompts the user with a yes/no question. Returns true for yes.\n * In non-interactive mode (no TTY), returns the default value.\n */\nasync function promptYesNo(question: string, defaultValue: boolean): Promise<boolean> {\n if (!process.stdin.isTTY) {\n return defaultValue;\n }\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise<boolean>((resolve) => {\n const suffix = defaultValue ? \" [Y/n] \" : \" [y/N] \";\n rl.question(question + suffix, (answer) => {\n rl.close();\n const trimmed = answer.trim().toLowerCase();\n if (trimmed === \"\") {\n resolve(defaultValue);\n return;\n }\n resolve(trimmed === \"y\" || trimmed === \"yes\");\n });\n });\n}\n\n/**\n * Core init logic. Exported for testability — the CLI entry point at the\n * bottom calls this function and translates the result to process.exit().\n */\nexport async function runInit(options: InitOptions): Promise<InitResult> {\n const { projectRoot, yes, coverageMap } = options;\n const summary: string[] = [];\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // Step 1: Detect package.json\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) {\n errors.push(\"No package.json found. Run this command from a Node.js project root.\");\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 2 + 3: Generate instrumentation.ts\n const instrumentationPath = path.join(projectRoot, \"instrumentation.ts\");\n const instrumentationExists = fs.existsSync(instrumentationPath);\n let shouldWriteInstrumentation = true;\n\n if (instrumentationExists && !yes) {\n shouldWriteInstrumentation = await promptYesNo(\n \"instrumentation.ts already exists. Overwrite?\",\n false,\n );\n } else if (instrumentationExists && yes) {\n // Non-interactive: never overwrite (idempotent)\n shouldWriteInstrumentation = false;\n }\n\n try {\n const created = await scaffoldInstrumentation(projectRoot, shouldWriteInstrumentation && instrumentationExists);\n if (created) {\n summary.push(\"Created instrumentation.ts\");\n } else if (instrumentationExists) {\n summary.push(\"Skipped instrumentation.ts (already exists)\");\n }\n } catch (err) {\n errors.push(`Failed to write instrumentation.ts: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 4: Detect and wrap next.config.*\n try {\n const wrapped = await scaffoldNextConfig(projectRoot);\n if (wrapped) {\n summary.push(\"Wrapped next.config with withGlasstraceConfig()\");\n } else {\n // Check if it was skipped because file already wrapped vs not found\n const hasNextConfig = [\"next.config.ts\", \"next.config.js\", \"next.config.mjs\"].some(\n (name) => fs.existsSync(path.join(projectRoot, name)),\n );\n if (hasNextConfig) {\n summary.push(\"Skipped next.config (already contains withGlasstraceConfig)\");\n } else {\n warnings.push(\"No next.config.* found. You may need to create one for Next.js projects.\");\n }\n }\n } catch (err) {\n errors.push(`Failed to modify next.config: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 5: Update .env.local\n try {\n const envCreated = await scaffoldEnvLocal(projectRoot);\n if (envCreated) {\n summary.push(\"Updated .env.local with Glasstrace configuration\");\n } else {\n summary.push(\"Skipped .env.local (GLASSTRACE_API_KEY already configured)\");\n }\n } catch (err) {\n errors.push(`Failed to update .env.local: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 6: Update .gitignore\n try {\n const gitignoreUpdated = await scaffoldGitignore(projectRoot);\n if (gitignoreUpdated) {\n summary.push(\"Updated .gitignore with .glasstrace/\");\n } else {\n summary.push(\"Skipped .gitignore (.glasstrace/ already listed)\");\n }\n } catch (err) {\n errors.push(`Failed to update .gitignore: ${err instanceof Error ? err.message : String(err)}`);\n return { exitCode: 1, summary, warnings, errors };\n }\n\n // Step 7: Coverage map opt-in\n let enableCoverageMap = coverageMap;\n if (!yes && !coverageMap) {\n if (process.stdin.isTTY) {\n enableCoverageMap = await promptYesNo(\n \"Would you like to enable test coverage mapping?\",\n false,\n );\n }\n }\n\n if (enableCoverageMap) {\n try {\n const added = await addCoverageMapEnv(projectRoot);\n if (added) {\n summary.push(\"Added GLASSTRACE_COVERAGE_MAP=true to .env.local\");\n }\n } catch (err) {\n warnings.push(`Failed to add coverage map env: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n // Step 8: Run initial import graph scan\n try {\n await buildImportGraph(projectRoot);\n summary.push(\"Completed initial import graph scan\");\n } catch (err) {\n warnings.push(`Import graph scan failed: ${err instanceof Error ? err.message : String(err)}. You can run it later.`);\n }\n }\n\n return { exitCode: 0, summary, warnings, errors };\n}\n\n/**\n * Parses CLI arguments into InitOptions.\n */\nfunction parseArgs(argv: string[]): InitOptions {\n const args = argv.slice(2); // skip node + script path\n let yes = false;\n let coverageMap = false;\n\n for (const arg of args) {\n if (arg === \"--yes\" || arg === \"-y\") {\n yes = true;\n } else if (arg === \"--coverage-map\") {\n coverageMap = true;\n }\n }\n\n // Auto-detect non-interactive\n if (!process.stdin.isTTY) {\n yes = true;\n }\n\n return {\n projectRoot: process.cwd(),\n yes,\n coverageMap,\n };\n}\n\n/**\n * CLI entry point. Only runs when this module is executed directly\n * (not when imported for testing).\n */\nconst scriptPath =\n typeof process !== \"undefined\" && process.argv[1] !== undefined\n ? process.argv[1].replace(/\\\\/g, \"/\")\n : undefined;\n\nconst scriptBasename = scriptPath !== undefined ? path.basename(scriptPath) : undefined;\n\nconst isDirectExecution =\n scriptPath !== undefined &&\n (scriptPath.endsWith(\"/cli/init.js\") ||\n scriptPath.endsWith(\"/cli/init.ts\") ||\n scriptBasename === \"glasstrace\");\n\nif (isDirectExecution) {\n const options = parseArgs(process.argv);\n\n runInit(options)\n .then((result) => {\n if (result.errors.length > 0) {\n for (const err of result.errors) {\n process.stderr.write(`Error: ${err}\\n`);\n }\n }\n if (result.warnings.length > 0) {\n for (const warn of result.warnings) {\n process.stderr.write(`Warning: ${warn}\\n`);\n }\n }\n if (result.summary.length > 0) {\n process.stderr.write(\"\\nGlasstrace initialized successfully!\\n\\n\");\n for (const line of result.summary) {\n process.stderr.write(` - ${line}\\n`);\n }\n process.stderr.write(\"\\nNext steps:\\n\");\n process.stderr.write(\" 1. Start your Next.js dev server\\n\");\n process.stderr.write(\" 2. Glasstrace works immediately in anonymous mode\\n\");\n process.stderr.write(\" 3. To link to your account, set GLASSTRACE_API_KEY in .env.local\\n\\n\");\n }\n process.exit(result.exitCode);\n })\n .catch((err: unknown) => {\n process.stderr.write(`Fatal error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n });\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\n/** Next.js config file names in priority order */\nconst NEXT_CONFIG_NAMES = [\"next.config.ts\", \"next.config.js\", \"next.config.mjs\"] as const;\n\n/**\n * Generates `instrumentation.ts` with a `registerGlasstrace()` call.\n * If the file exists and `force` is false, the file is not overwritten.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @param force - When true, overwrite an existing instrumentation.ts file.\n * @returns True if the file was written, false if it was skipped.\n */\nexport async function scaffoldInstrumentation(\n projectRoot: string,\n force: boolean,\n): Promise<boolean> {\n const filePath = path.join(projectRoot, \"instrumentation.ts\");\n\n if (fs.existsSync(filePath) && !force) {\n return false;\n }\n\n const content = `import { registerGlasstrace } from \"@glasstrace/sdk\";\n\nexport async function register() {\n // Glasstrace must be registered before Prisma instrumentation\n // to ensure all ORM spans are captured correctly.\n // If you use @prisma/instrumentation, import it after this call.\n registerGlasstrace();\n}\n`;\n\n fs.writeFileSync(filePath, content, \"utf-8\");\n return true;\n}\n\n/**\n * Detects `next.config.js`, `next.config.ts`, or `next.config.mjs` and wraps\n * with `withGlasstraceConfig()`. If the config already contains\n * `withGlasstraceConfig`, the file is not modified.\n *\n * For CJS `.js` configs, adds a `require()` call and wraps `module.exports`.\n * The SDK ships dual ESM/CJS builds via tsup + conditional exports, so\n * `require(\"@glasstrace/sdk\")` resolves to the CJS entrypoint natively.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the config file was modified (or created), false if skipped.\n */\nexport async function scaffoldNextConfig(\n projectRoot: string,\n): Promise<boolean> {\n let configPath: string | undefined;\n let configName: string | undefined;\n\n for (const name of NEXT_CONFIG_NAMES) {\n const candidate = path.join(projectRoot, name);\n if (fs.existsSync(candidate)) {\n configPath = candidate;\n configName = name;\n break;\n }\n }\n\n if (configPath === undefined || configName === undefined) {\n return false;\n }\n\n const existing = fs.readFileSync(configPath, \"utf-8\");\n\n // Already wrapped — skip even in force mode to avoid double-wrapping\n if (existing.includes(\"withGlasstraceConfig\")) {\n return false;\n }\n\n const isESM = configName.endsWith(\".ts\") || configName.endsWith(\".mjs\");\n\n if (isESM) {\n // ESM: static import at top of file, wrap the export\n const importLine = 'import { withGlasstraceConfig } from \"@glasstrace/sdk\";\\n';\n const wrapResult = wrapExport(existing);\n if (!wrapResult.wrapped) {\n return false;\n }\n const modified = importLine + \"\\n\" + wrapResult.content;\n fs.writeFileSync(configPath, modified, \"utf-8\");\n return true;\n }\n\n // CJS (.js): require() the SDK (resolves to the CJS dist build) and\n // wrap the module.exports expression in place — no file renaming needed.\n const requireLine = 'const { withGlasstraceConfig } = require(\"@glasstrace/sdk\");\\n';\n const wrapResult = wrapCJSExport(existing);\n if (!wrapResult.wrapped) {\n return false;\n }\n const modified = requireLine + \"\\n\" + wrapResult.content;\n fs.writeFileSync(configPath, modified, \"utf-8\");\n return true;\n}\n\ninterface WrapResult {\n content: string;\n wrapped: boolean;\n}\n\n/**\n * Wraps an ESM `export default` expression with `withGlasstraceConfig()`.\n *\n * Strategy: find the last `export default` in the file. Everything from\n * that statement to EOF is the exported expression. Strip optional trailing\n * semicolons/whitespace and wrap with `withGlasstraceConfig(...)`.\n *\n * @param content - The full file content containing an ESM default export.\n * @returns `{ wrapped: true, content }` on success, or `{ wrapped: false }` if\n * no recognizable export pattern was found (content returned unchanged).\n */\nfunction wrapExport(content: string): WrapResult {\n // Find the last `export default` — use lastIndexOf for robustness\n const marker = \"export default\";\n const idx = content.lastIndexOf(marker);\n if (idx === -1) {\n return { content, wrapped: false };\n }\n\n const preamble = content.slice(0, idx);\n const exprRaw = content.slice(idx + marker.length);\n // Trim leading whitespace; strip trailing semicolon + whitespace\n const expr = exprRaw.trim().replace(/;?\\s*$/, \"\");\n if (expr.length === 0) {\n return { content, wrapped: false };\n }\n\n return {\n content: preamble + `export default withGlasstraceConfig(${expr});\\n`,\n wrapped: true,\n };\n}\n\n/**\n * Wraps a CJS `module.exports = expr` with `withGlasstraceConfig()`.\n *\n * Strategy: find the last `module.exports =` in the file. Everything from\n * that statement to EOF is the exported expression. Strip optional trailing\n * semicolons/whitespace and wrap with `module.exports = withGlasstraceConfig(...)`.\n *\n * @param content - The full CJS file content containing `module.exports = ...`.\n * @returns `{ wrapped: true, content }` on success, or `{ wrapped: false }` if\n * no recognizable `module.exports` pattern was found (content returned unchanged).\n */\nfunction wrapCJSExport(content: string): WrapResult {\n const cjsMarker = \"module.exports\";\n const cjsIdx = content.lastIndexOf(cjsMarker);\n if (cjsIdx === -1) {\n return { content, wrapped: false };\n }\n\n const preamble = content.slice(0, cjsIdx);\n const afterMarker = content.slice(cjsIdx + cjsMarker.length);\n const eqMatch = /^\\s*=\\s*/.exec(afterMarker);\n if (!eqMatch) {\n return { content, wrapped: false };\n }\n\n const exprRaw = afterMarker.slice(eqMatch[0].length);\n const expr = exprRaw.trim().replace(/;?\\s*$/, \"\");\n if (expr.length === 0) {\n return { content, wrapped: false };\n }\n\n return {\n content: preamble + `module.exports = withGlasstraceConfig(${expr});\\n`,\n wrapped: true,\n };\n}\n\n/**\n * Creates `.env.local` with `GLASSTRACE_API_KEY=` placeholder, or appends\n * to an existing file if it does not already contain `GLASSTRACE_API_KEY`.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the file was created or modified, false if already configured.\n */\nexport async function scaffoldEnvLocal(projectRoot: string): Promise<boolean> {\n const filePath = path.join(projectRoot, \".env.local\");\n\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, \"utf-8\");\n if (/^\\s*#?\\s*GLASSTRACE_API_KEY\\s*=/m.test(existing)) {\n return false;\n }\n // Append with a newline separator if needed\n const separator = existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n fs.writeFileSync(filePath, existing + separator + \"# GLASSTRACE_API_KEY=your_key_here\\n\", \"utf-8\");\n return true;\n }\n\n fs.writeFileSync(filePath, \"# GLASSTRACE_API_KEY=your_key_here\\n\", \"utf-8\");\n return true;\n}\n\n/**\n * Adds `GLASSTRACE_COVERAGE_MAP=true` to `.env.local`.\n * Creates the file if it does not exist. If the key is already present\n * with a value other than `true`, it is updated in place.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the file was created or modified, false if already set to `true`.\n */\nexport async function addCoverageMapEnv(projectRoot: string): Promise<boolean> {\n const filePath = path.join(projectRoot, \".env.local\");\n\n if (!fs.existsSync(filePath)) {\n fs.writeFileSync(filePath, \"GLASSTRACE_COVERAGE_MAP=true\\n\", \"utf-8\");\n return true;\n }\n\n const existing = fs.readFileSync(filePath, \"utf-8\");\n const keyRegex = /^(\\s*GLASSTRACE_COVERAGE_MAP\\s*=\\s*)(.*)$/m;\n const keyMatch = keyRegex.exec(existing);\n\n if (keyMatch) {\n const currentValue = keyMatch[2].trim();\n if (currentValue === \"true\") {\n // Already set to true — nothing to do\n return false;\n }\n // Key exists but is not `true` — update in place\n const updated = existing.replace(keyRegex, `${keyMatch[1]}true`);\n fs.writeFileSync(filePath, updated, \"utf-8\");\n return true;\n }\n\n const separator = existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n fs.writeFileSync(filePath, existing + separator + \"GLASSTRACE_COVERAGE_MAP=true\\n\", \"utf-8\");\n return true;\n}\n\n/**\n * Adds `.glasstrace/` to `.gitignore`, or creates `.gitignore` if missing.\n * Does not add duplicate entries.\n *\n * @param projectRoot - Absolute path to the project root directory.\n * @returns True if the file was created or modified, false if already configured.\n */\nexport async function scaffoldGitignore(projectRoot: string): Promise<boolean> {\n const filePath = path.join(projectRoot, \".gitignore\");\n\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, \"utf-8\");\n // Check line-by-line to avoid false positive partial matches\n const lines = existing.split(\"\\n\").map((l) => l.trim());\n if (lines.includes(\".glasstrace/\")) {\n return false;\n }\n const separator = existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n fs.writeFileSync(filePath, existing + separator + \".glasstrace/\\n\", \"utf-8\");\n return true;\n }\n\n fs.writeFileSync(filePath, \".glasstrace/\\n\", \"utf-8\");\n return true;\n}\n"],"mappings":";;;;;;;AACA,YAAYA,SAAQ;AACpB,YAAYC,WAAU;AACtB,YAAY,cAAc;;;ACH1B,YAAY,QAAQ;AACpB,YAAY,UAAU;AAGtB,IAAM,oBAAoB,CAAC,kBAAkB,kBAAkB,iBAAiB;AAUhF,eAAsB,wBACpB,aACA,OACkB;AAClB,QAAM,WAAgB,UAAK,aAAa,oBAAoB;AAE5D,MAAO,cAAW,QAAQ,KAAK,CAAC,OAAO;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUhB,EAAG,iBAAc,UAAU,SAAS,OAAO;AAC3C,SAAO;AACT;AAcA,eAAsB,mBACpB,aACkB;AAClB,MAAI;AACJ,MAAI;AAEJ,aAAW,QAAQ,mBAAmB;AACpC,UAAM,YAAiB,UAAK,aAAa,IAAI;AAC7C,QAAO,cAAW,SAAS,GAAG;AAC5B,mBAAa;AACb,mBAAa;AACb;AAAA,IACF;AAAA,EACF;AAEA,MAAI,eAAe,UAAa,eAAe,QAAW;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,WAAc,gBAAa,YAAY,OAAO;AAGpD,MAAI,SAAS,SAAS,sBAAsB,GAAG;AAC7C,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,MAAM;AAEtE,MAAI,OAAO;AAET,UAAM,aAAa;AACnB,UAAMC,cAAa,WAAW,QAAQ;AACtC,QAAI,CAACA,YAAW,SAAS;AACvB,aAAO;AAAA,IACT;AACA,UAAMC,YAAW,aAAa,OAAOD,YAAW;AAChD,IAAG,iBAAc,YAAYC,WAAU,OAAO;AAC9C,WAAO;AAAA,EACT;AAIA,QAAM,cAAc;AACpB,QAAM,aAAa,cAAc,QAAQ;AACzC,MAAI,CAAC,WAAW,SAAS;AACvB,WAAO;AAAA,EACT;AACA,QAAM,WAAW,cAAc,OAAO,WAAW;AACjD,EAAG,iBAAc,YAAY,UAAU,OAAO;AAC9C,SAAO;AACT;AAkBA,SAAS,WAAW,SAA6B;AAE/C,QAAM,SAAS;AACf,QAAM,MAAM,QAAQ,YAAY,MAAM;AACtC,MAAI,QAAQ,IAAI;AACd,WAAO,EAAE,SAAS,SAAS,MAAM;AAAA,EACnC;AAEA,QAAM,WAAW,QAAQ,MAAM,GAAG,GAAG;AACrC,QAAM,UAAU,QAAQ,MAAM,MAAM,OAAO,MAAM;AAEjD,QAAM,OAAO,QAAQ,KAAK,EAAE,QAAQ,UAAU,EAAE;AAChD,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO,EAAE,SAAS,SAAS,MAAM;AAAA,EACnC;AAEA,SAAO;AAAA,IACL,SAAS,WAAW,uCAAuC,IAAI;AAAA;AAAA,IAC/D,SAAS;AAAA,EACX;AACF;AAaA,SAAS,cAAc,SAA6B;AAClD,QAAM,YAAY;AAClB,QAAM,SAAS,QAAQ,YAAY,SAAS;AAC5C,MAAI,WAAW,IAAI;AACjB,WAAO,EAAE,SAAS,SAAS,MAAM;AAAA,EACnC;AAEA,QAAM,WAAW,QAAQ,MAAM,GAAG,MAAM;AACxC,QAAM,cAAc,QAAQ,MAAM,SAAS,UAAU,MAAM;AAC3D,QAAM,UAAU,WAAW,KAAK,WAAW;AAC3C,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,SAAS,SAAS,MAAM;AAAA,EACnC;AAEA,QAAM,UAAU,YAAY,MAAM,QAAQ,CAAC,EAAE,MAAM;AACnD,QAAM,OAAO,QAAQ,KAAK,EAAE,QAAQ,UAAU,EAAE;AAChD,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO,EAAE,SAAS,SAAS,MAAM;AAAA,EACnC;AAEA,SAAO;AAAA,IACL,SAAS,WAAW,yCAAyC,IAAI;AAAA;AAAA,IACjE,SAAS;AAAA,EACX;AACF;AASA,eAAsB,iBAAiB,aAAuC;AAC5E,QAAM,WAAgB,UAAK,aAAa,YAAY;AAEpD,MAAO,cAAW,QAAQ,GAAG;AAC3B,UAAM,WAAc,gBAAa,UAAU,OAAO;AAClD,QAAI,mCAAmC,KAAK,QAAQ,GAAG;AACrD,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,SAAS,SAAS,IAAI,IAAI,KAAK;AACjD,IAAG,iBAAc,UAAU,WAAW,YAAY,wCAAwC,OAAO;AACjG,WAAO;AAAA,EACT;AAEA,EAAG,iBAAc,UAAU,wCAAwC,OAAO;AAC1E,SAAO;AACT;AAUA,eAAsB,kBAAkB,aAAuC;AAC7E,QAAM,WAAgB,UAAK,aAAa,YAAY;AAEpD,MAAI,CAAI,cAAW,QAAQ,GAAG;AAC5B,IAAG,iBAAc,UAAU,kCAAkC,OAAO;AACpE,WAAO;AAAA,EACT;AAEA,QAAM,WAAc,gBAAa,UAAU,OAAO;AAClD,QAAM,WAAW;AACjB,QAAM,WAAW,SAAS,KAAK,QAAQ;AAEvC,MAAI,UAAU;AACZ,UAAM,eAAe,SAAS,CAAC,EAAE,KAAK;AACtC,QAAI,iBAAiB,QAAQ;AAE3B,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,SAAS,QAAQ,UAAU,GAAG,SAAS,CAAC,CAAC,MAAM;AAC/D,IAAG,iBAAc,UAAU,SAAS,OAAO;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,SAAS,SAAS,IAAI,IAAI,KAAK;AACjD,EAAG,iBAAc,UAAU,WAAW,YAAY,kCAAkC,OAAO;AAC3F,SAAO;AACT;AASA,eAAsB,kBAAkB,aAAuC;AAC7E,QAAM,WAAgB,UAAK,aAAa,YAAY;AAEpD,MAAO,cAAW,QAAQ,GAAG;AAC3B,UAAM,WAAc,gBAAa,UAAU,OAAO;AAElD,UAAM,QAAQ,SAAS,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACtD,QAAI,MAAM,SAAS,cAAc,GAAG;AAClC,aAAO;AAAA,IACT;AACA,UAAM,YAAY,SAAS,SAAS,IAAI,IAAI,KAAK;AACjD,IAAG,iBAAc,UAAU,WAAW,YAAY,kBAAkB,OAAO;AAC3E,WAAO;AAAA,EACT;AAEA,EAAG,iBAAc,UAAU,kBAAkB,OAAO;AACpD,SAAO;AACT;;;ADvOA,eAAe,YAAY,UAAkB,cAAyC;AACpF,MAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,KAAc,yBAAgB;AAAA,IAClC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED,SAAO,IAAI,QAAiB,CAAC,YAAY;AACvC,UAAM,SAAS,eAAe,YAAY;AAC1C,OAAG,SAAS,WAAW,QAAQ,CAAC,WAAW;AACzC,SAAG,MAAM;AACT,YAAM,UAAU,OAAO,KAAK,EAAE,YAAY;AAC1C,UAAI,YAAY,IAAI;AAClB,gBAAQ,YAAY;AACpB;AAAA,MACF;AACA,cAAQ,YAAY,OAAO,YAAY,KAAK;AAAA,IAC9C,CAAC;AAAA,EACH,CAAC;AACH;AAMA,eAAsB,QAAQ,SAA2C;AACvE,QAAM,EAAE,aAAa,KAAK,YAAY,IAAI;AAC1C,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAqB,CAAC;AAC5B,QAAM,SAAmB,CAAC;AAG1B,QAAM,kBAAuB,WAAK,aAAa,cAAc;AAC7D,MAAI,CAAI,eAAW,eAAe,GAAG;AACnC,WAAO,KAAK,sEAAsE;AAClF,WAAO,EAAE,UAAU,GAAG,SAAS,UAAU,OAAO;AAAA,EAClD;AAGA,QAAM,sBAA2B,WAAK,aAAa,oBAAoB;AACvE,QAAM,wBAA2B,eAAW,mBAAmB;AAC/D,MAAI,6BAA6B;AAEjC,MAAI,yBAAyB,CAAC,KAAK;AACjC,iCAA6B,MAAM;AAAA,MACjC;AAAA,MACA;AAAA,IACF;AAAA,EACF,WAAW,yBAAyB,KAAK;AAEvC,iCAA6B;AAAA,EAC/B;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,wBAAwB,aAAa,8BAA8B,qBAAqB;AAC9G,QAAI,SAAS;AACX,cAAQ,KAAK,4BAA4B;AAAA,IAC3C,WAAW,uBAAuB;AAChC,cAAQ,KAAK,6CAA6C;AAAA,IAC5D;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,KAAK,uCAAuC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AACrG,WAAO,EAAE,UAAU,GAAG,SAAS,UAAU,OAAO;AAAA,EAClD;AAGA,MAAI;AACF,UAAM,UAAU,MAAM,mBAAmB,WAAW;AACpD,QAAI,SAAS;AACX,cAAQ,KAAK,iDAAiD;AAAA,IAChE,OAAO;AAEL,YAAM,gBAAgB,CAAC,kBAAkB,kBAAkB,iBAAiB,EAAE;AAAA,QAC5E,CAAC,SAAY,eAAgB,WAAK,aAAa,IAAI,CAAC;AAAA,MACtD;AACA,UAAI,eAAe;AACjB,gBAAQ,KAAK,6DAA6D;AAAA,MAC5E,OAAO;AACL,iBAAS,KAAK,0EAA0E;AAAA,MAC1F;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,KAAK,iCAAiC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAC/F,WAAO,EAAE,UAAU,GAAG,SAAS,UAAU,OAAO;AAAA,EAClD;AAGA,MAAI;AACF,UAAM,aAAa,MAAM,iBAAiB,WAAW;AACrD,QAAI,YAAY;AACd,cAAQ,KAAK,kDAAkD;AAAA,IACjE,OAAO;AACL,cAAQ,KAAK,4DAA4D;AAAA,IAC3E;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,KAAK,gCAAgC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAC9F,WAAO,EAAE,UAAU,GAAG,SAAS,UAAU,OAAO;AAAA,EAClD;AAGA,MAAI;AACF,UAAM,mBAAmB,MAAM,kBAAkB,WAAW;AAC5D,QAAI,kBAAkB;AACpB,cAAQ,KAAK,sCAAsC;AAAA,IACrD,OAAO;AACL,cAAQ,KAAK,kDAAkD;AAAA,IACjE;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,KAAK,gCAAgC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAC9F,WAAO,EAAE,UAAU,GAAG,SAAS,UAAU,OAAO;AAAA,EAClD;AAGA,MAAI,oBAAoB;AACxB,MAAI,CAAC,OAAO,CAAC,aAAa;AACxB,QAAI,QAAQ,MAAM,OAAO;AACvB,0BAAoB,MAAM;AAAA,QACxB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,mBAAmB;AACrB,QAAI;AACF,YAAM,QAAQ,MAAM,kBAAkB,WAAW;AACjD,UAAI,OAAO;AACT,gBAAQ,KAAK,kDAAkD;AAAA,MACjE;AAAA,IACF,SAAS,KAAK;AACZ,eAAS,KAAK,mCAAmC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,IACrG;AAGA,QAAI;AACF,YAAM,iBAAiB,WAAW;AAClC,cAAQ,KAAK,qCAAqC;AAAA,IACpD,SAAS,KAAK;AACZ,eAAS,KAAK,6BAA6B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,yBAAyB;AAAA,IACtH;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,GAAG,SAAS,UAAU,OAAO;AAClD;AAKA,SAAS,UAAU,MAA6B;AAC9C,QAAM,OAAO,KAAK,MAAM,CAAC;AACzB,MAAI,MAAM;AACV,MAAI,cAAc;AAElB,aAAW,OAAO,MAAM;AACtB,QAAI,QAAQ,WAAW,QAAQ,MAAM;AACnC,YAAM;AAAA,IACR,WAAW,QAAQ,kBAAkB;AACnC,oBAAc;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,UAAM;AAAA,EACR;AAEA,SAAO;AAAA,IACL,aAAa,QAAQ,IAAI;AAAA,IACzB;AAAA,IACA;AAAA,EACF;AACF;AAMA,IAAM,aACJ,OAAO,YAAY,eAAe,QAAQ,KAAK,CAAC,MAAM,SAClD,QAAQ,KAAK,CAAC,EAAE,QAAQ,OAAO,GAAG,IAClC;AAEN,IAAM,iBAAiB,eAAe,SAAiB,eAAS,UAAU,IAAI;AAE9E,IAAM,oBACJ,eAAe,WACd,WAAW,SAAS,cAAc,KACjC,WAAW,SAAS,cAAc,KAClC,mBAAmB;AAEvB,IAAI,mBAAmB;AACrB,QAAM,UAAU,UAAU,QAAQ,IAAI;AAEtC,UAAQ,OAAO,EACZ,KAAK,CAAC,WAAW;AAChB,QAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,iBAAW,OAAO,OAAO,QAAQ;AAC/B,gBAAQ,OAAO,MAAM,UAAU,GAAG;AAAA,CAAI;AAAA,MACxC;AAAA,IACF;AACA,QAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,iBAAW,QAAQ,OAAO,UAAU;AAClC,gBAAQ,OAAO,MAAM,YAAY,IAAI;AAAA,CAAI;AAAA,MAC3C;AAAA,IACF;AACA,QAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,cAAQ,OAAO,MAAM,4CAA4C;AACjE,iBAAW,QAAQ,OAAO,SAAS;AACjC,gBAAQ,OAAO,MAAM,OAAO,IAAI;AAAA,CAAI;AAAA,MACtC;AACA,cAAQ,OAAO,MAAM,iBAAiB;AACtC,cAAQ,OAAO,MAAM,sCAAsC;AAC3D,cAAQ,OAAO,MAAM,uDAAuD;AAC5E,cAAQ,OAAO,MAAM,wEAAwE;AAAA,IAC/F;AACA,YAAQ,KAAK,OAAO,QAAQ;AAAA,EAC9B,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,YAAQ,OAAO,MAAM,gBAAgB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AACzF,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACL;","names":["fs","path","wrapResult","modified"]}
@@ -0,0 +1,62 @@
1
+ import {
2
+ DiagConsoleLogger,
3
+ DiagLogLevel,
4
+ INVALID_SPANID,
5
+ INVALID_SPAN_CONTEXT,
6
+ INVALID_TRACEID,
7
+ ProxyTracer,
8
+ ProxyTracerProvider,
9
+ ROOT_CONTEXT,
10
+ SamplingDecision,
11
+ SpanKind,
12
+ SpanStatusCode,
13
+ TraceFlags,
14
+ ValueType,
15
+ baggageEntryMetadataFromString,
16
+ context,
17
+ createContextKey,
18
+ createNoopMeter,
19
+ createTraceState,
20
+ defaultTextMapGetter,
21
+ defaultTextMapSetter,
22
+ diag,
23
+ esm_default,
24
+ isSpanContextValid,
25
+ isValidSpanId,
26
+ isValidTraceId,
27
+ metrics,
28
+ propagation,
29
+ trace
30
+ } from "./chunk-DQ25VOKK.js";
31
+ import "./chunk-PZ5AY32C.js";
32
+ export {
33
+ DiagConsoleLogger,
34
+ DiagLogLevel,
35
+ INVALID_SPANID,
36
+ INVALID_SPAN_CONTEXT,
37
+ INVALID_TRACEID,
38
+ ProxyTracer,
39
+ ProxyTracerProvider,
40
+ ROOT_CONTEXT,
41
+ SamplingDecision,
42
+ SpanKind,
43
+ SpanStatusCode,
44
+ TraceFlags,
45
+ ValueType,
46
+ baggageEntryMetadataFromString,
47
+ context,
48
+ createContextKey,
49
+ createNoopMeter,
50
+ createTraceState,
51
+ esm_default as default,
52
+ defaultTextMapGetter,
53
+ defaultTextMapSetter,
54
+ diag,
55
+ isSpanContextValid,
56
+ isValidSpanId,
57
+ isValidTraceId,
58
+ metrics,
59
+ propagation,
60
+ trace
61
+ };
62
+ //# sourceMappingURL=esm-POMEQPKL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,29 @@
1
+ import {
2
+ execAsync
3
+ } from "./chunk-WZXVS2EO.js";
4
+ import {
5
+ diag
6
+ } from "./chunk-DQ25VOKK.js";
7
+ import "./chunk-PZ5AY32C.js";
8
+
9
+ // ../../node_modules/@opentelemetry/resources/build/esm/detectors/platform/node/machine-id/getMachineId-bsd.js
10
+ import { promises as fs } from "fs";
11
+ async function getMachineId() {
12
+ try {
13
+ const result = await fs.readFile("/etc/hostid", { encoding: "utf8" });
14
+ return result.trim();
15
+ } catch (e) {
16
+ diag.debug(`error reading machine id: ${e}`);
17
+ }
18
+ try {
19
+ const result = await execAsync("kenv -q smbios.system.uuid");
20
+ return result.stdout.trim();
21
+ } catch (e) {
22
+ diag.debug(`error reading machine id: ${e}`);
23
+ }
24
+ return void 0;
25
+ }
26
+ export {
27
+ getMachineId
28
+ };
29
+ //# sourceMappingURL=getMachineId-bsd-TC3JSTY5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/@opentelemetry/resources/src/detectors/platform/node/machine-id/getMachineId-bsd.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { promises as fs } from 'fs';\nimport { execAsync } from './execAsync';\nimport { diag } from '@opentelemetry/api';\n\nexport async function getMachineId(): Promise<string | undefined> {\n try {\n const result = await fs.readFile('/etc/hostid', { encoding: 'utf8' });\n return result.trim();\n } catch (e) {\n diag.debug(`error reading machine id: ${e}`);\n }\n\n try {\n const result = await execAsync('kenv -q smbios.system.uuid');\n return result.stdout.trim();\n } catch (e) {\n diag.debug(`error reading machine id: ${e}`);\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;AAKA,SAAS,YAAY,UAAU;AAI/B,eAAsB,eAAY;AAChC,MAAI;AACF,UAAM,SAAS,MAAM,GAAG,SAAS,eAAe,EAAE,UAAU,OAAM,CAAE;AACpE,WAAO,OAAO,KAAI;WACX,GAAG;AACV,SAAK,MAAM,6BAA6B,CAAC,EAAE;;AAG7C,MAAI;AACF,UAAM,SAAS,MAAM,UAAU,4BAA4B;AAC3D,WAAO,OAAO,OAAO,KAAI;WAClB,GAAG;AACV,SAAK,MAAM,6BAA6B,CAAC,EAAE;;AAG7C,SAAO;AACT;","names":[]}
@@ -0,0 +1,29 @@
1
+ import {
2
+ execAsync
3
+ } from "./chunk-WZXVS2EO.js";
4
+ import {
5
+ diag
6
+ } from "./chunk-DQ25VOKK.js";
7
+ import "./chunk-PZ5AY32C.js";
8
+
9
+ // ../../node_modules/@opentelemetry/resources/build/esm/detectors/platform/node/machine-id/getMachineId-darwin.js
10
+ async function getMachineId() {
11
+ try {
12
+ const result = await execAsync('ioreg -rd1 -c "IOPlatformExpertDevice"');
13
+ const idLine = result.stdout.split("\n").find((line) => line.includes("IOPlatformUUID"));
14
+ if (!idLine) {
15
+ return void 0;
16
+ }
17
+ const parts = idLine.split('" = "');
18
+ if (parts.length === 2) {
19
+ return parts[1].slice(0, -1);
20
+ }
21
+ } catch (e) {
22
+ diag.debug(`error reading machine id: ${e}`);
23
+ }
24
+ return void 0;
25
+ }
26
+ export {
27
+ getMachineId
28
+ };
29
+ //# sourceMappingURL=getMachineId-darwin-2SUKQCE6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/@opentelemetry/resources/src/detectors/platform/node/machine-id/getMachineId-darwin.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { execAsync } from './execAsync';\nimport { diag } from '@opentelemetry/api';\n\nexport async function getMachineId(): Promise<string | undefined> {\n try {\n const result = await execAsync('ioreg -rd1 -c \"IOPlatformExpertDevice\"');\n\n const idLine = result.stdout\n .split('\\n')\n .find(line => line.includes('IOPlatformUUID'));\n\n if (!idLine) {\n return undefined;\n }\n\n const parts = idLine.split('\" = \"');\n if (parts.length === 2) {\n return parts[1].slice(0, -1);\n }\n } catch (e) {\n diag.debug(`error reading machine id: ${e}`);\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;AAQA,eAAsB,eAAY;AAChC,MAAI;AACF,UAAM,SAAS,MAAM,UAAU,wCAAwC;AAEvE,UAAM,SAAS,OAAO,OACnB,MAAM,IAAI,EACV,KAAK,UAAQ,KAAK,SAAS,gBAAgB,CAAC;AAE/C,QAAI,CAAC,QAAQ;AACX,aAAO;;AAGT,UAAM,QAAQ,OAAO,MAAM,OAAO;AAClC,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE;;WAEtB,GAAG;AACV,SAAK,MAAM,6BAA6B,CAAC,EAAE;;AAG7C,SAAO;AACT;","names":[]}
@@ -0,0 +1,23 @@
1
+ import {
2
+ diag
3
+ } from "./chunk-DQ25VOKK.js";
4
+ import "./chunk-PZ5AY32C.js";
5
+
6
+ // ../../node_modules/@opentelemetry/resources/build/esm/detectors/platform/node/machine-id/getMachineId-linux.js
7
+ import { promises as fs } from "fs";
8
+ async function getMachineId() {
9
+ const paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
10
+ for (const path of paths) {
11
+ try {
12
+ const result = await fs.readFile(path, { encoding: "utf8" });
13
+ return result.trim();
14
+ } catch (e) {
15
+ diag.debug(`error reading machine id: ${e}`);
16
+ }
17
+ }
18
+ return void 0;
19
+ }
20
+ export {
21
+ getMachineId
22
+ };
23
+ //# sourceMappingURL=getMachineId-linux-PNAFHLXH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/@opentelemetry/resources/src/detectors/platform/node/machine-id/getMachineId-linux.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { promises as fs } from 'fs';\nimport { diag } from '@opentelemetry/api';\n\nexport async function getMachineId(): Promise<string | undefined> {\n const paths = ['/etc/machine-id', '/var/lib/dbus/machine-id'];\n\n for (const path of paths) {\n try {\n const result = await fs.readFile(path, { encoding: 'utf8' });\n return result.trim();\n } catch (e) {\n diag.debug(`error reading machine id: ${e}`);\n }\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;AAIA,SAAS,YAAY,UAAU;AAG/B,eAAsB,eAAY;AAChC,QAAM,QAAQ,CAAC,mBAAmB,0BAA0B;AAE5D,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,SAAS,MAAM,GAAG,SAAS,MAAM,EAAE,UAAU,OAAM,CAAE;AAC3D,aAAO,OAAO,KAAI;aACX,GAAG;AACV,WAAK,MAAM,6BAA6B,CAAC,EAAE;;;AAI/C,SAAO;AACT;","names":[]}
@@ -0,0 +1,14 @@
1
+ import {
2
+ diag
3
+ } from "./chunk-DQ25VOKK.js";
4
+ import "./chunk-PZ5AY32C.js";
5
+
6
+ // ../../node_modules/@opentelemetry/resources/build/esm/detectors/platform/node/machine-id/getMachineId-unsupported.js
7
+ async function getMachineId() {
8
+ diag.debug("could not read machine-id: unsupported platform");
9
+ return void 0;
10
+ }
11
+ export {
12
+ getMachineId
13
+ };
14
+ //# sourceMappingURL=getMachineId-unsupported-L2MNYW3W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/@opentelemetry/resources/src/detectors/platform/node/machine-id/getMachineId-unsupported.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { diag } from '@opentelemetry/api';\n\nexport async function getMachineId(): Promise<string | undefined> {\n diag.debug('could not read machine-id: unsupported platform');\n return undefined;\n}\n"],"mappings":";;;;;;AAOA,eAAsB,eAAY;AAChC,OAAK,MAAM,iDAAiD;AAC5D,SAAO;AACT;","names":[]}
@@ -0,0 +1,31 @@
1
+ import {
2
+ execAsync
3
+ } from "./chunk-WZXVS2EO.js";
4
+ import {
5
+ diag
6
+ } from "./chunk-DQ25VOKK.js";
7
+ import "./chunk-PZ5AY32C.js";
8
+
9
+ // ../../node_modules/@opentelemetry/resources/build/esm/detectors/platform/node/machine-id/getMachineId-win.js
10
+ import * as process from "process";
11
+ async function getMachineId() {
12
+ const args = "QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid";
13
+ let command = "%windir%\\System32\\REG.exe";
14
+ if (process.arch === "ia32" && "PROCESSOR_ARCHITEW6432" in process.env) {
15
+ command = "%windir%\\sysnative\\cmd.exe /c " + command;
16
+ }
17
+ try {
18
+ const result = await execAsync(`${command} ${args}`);
19
+ const parts = result.stdout.split("REG_SZ");
20
+ if (parts.length === 2) {
21
+ return parts[1].trim();
22
+ }
23
+ } catch (e) {
24
+ diag.debug(`error reading machine id: ${e}`);
25
+ }
26
+ return void 0;
27
+ }
28
+ export {
29
+ getMachineId
30
+ };
31
+ //# sourceMappingURL=getMachineId-win-D6D42WOQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/@opentelemetry/resources/src/detectors/platform/node/machine-id/getMachineId-win.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport * as process from 'process';\nimport { execAsync } from './execAsync';\nimport { diag } from '@opentelemetry/api';\n\nexport async function getMachineId(): Promise<string | undefined> {\n const args =\n 'QUERY HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Cryptography /v MachineGuid';\n let command = '%windir%\\\\System32\\\\REG.exe';\n if (process.arch === 'ia32' && 'PROCESSOR_ARCHITEW6432' in process.env) {\n command = '%windir%\\\\sysnative\\\\cmd.exe /c ' + command;\n }\n\n try {\n const result = await execAsync(`${command} ${args}`);\n const parts = result.stdout.split('REG_SZ');\n if (parts.length === 2) {\n return parts[1].trim();\n }\n } catch (e) {\n diag.debug(`error reading machine id: ${e}`);\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;AAKA,YAAY,aAAa;AAIzB,eAAsB,eAAY;AAChC,QAAM,OACJ;AACF,MAAI,UAAU;AACd,MAAY,iBAAS,UAAU,4BAAoC,aAAK;AACtE,cAAU,qCAAqC;;AAGjD,MAAI;AACF,UAAM,SAAS,MAAM,UAAU,GAAG,OAAO,IAAI,IAAI,EAAE;AACnD,UAAM,QAAQ,OAAO,OAAO,MAAM,QAAQ;AAC1C,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,MAAM,CAAC,EAAE,KAAI;;WAEf,GAAG;AACV,SAAK,MAAM,6BAA6B,CAAC,EAAE;;AAG7C,SAAO;AACT;","names":[]}