|
| 1 | +import * as Effect from "effect/Effect" |
| 2 | +import * as Layer from "effect/Layer" |
| 3 | +import * as Runtime from "effect/Runtime" |
| 4 | +import * as vscode from "vscode" |
| 5 | +import { configWithDefault, VsCodeContext } from "./VsCode" |
| 6 | + |
| 7 | +export const InjectNodeOptionsInstrumentationLive = Effect.gen(function*() { |
| 8 | + const extension = yield* VsCodeContext |
| 9 | + |
| 10 | + // gets the config if it shuold be injected or not |
| 11 | + const injectNodeOptions = yield* configWithDefault("effect.instrumentation", "injectNodeOptions", false) |
| 12 | + const injectDebugConfigurations = yield* configWithDefault("effect.instrumentation", "injectDebugConfigurations", [ |
| 13 | + "node", |
| 14 | + "node-terminal", |
| 15 | + "pwa-node" |
| 16 | + ]) |
| 17 | + const runtime = yield* Effect.runtime<never>() |
| 18 | + |
| 19 | + yield* Effect.acquireRelease( |
| 20 | + Effect.sync(() => |
| 21 | + vscode.debug.registerDebugConfigurationProvider("*", { |
| 22 | + resolveDebugConfiguration(_folder, config, _token) { |
| 23 | + // if disabled (default) then do nothing |
| 24 | + const shouldInjectBool = Runtime.runSync(runtime, injectNodeOptions.get) |
| 25 | + if (!shouldInjectBool) return config |
| 26 | + |
| 27 | + // abort immediately if the token is cancelled |
| 28 | + if (_token?.isCancellationRequested) return config |
| 29 | + |
| 30 | + // if not supported, then do nothing |
| 31 | + const debugConfigurations = Runtime.runSync(runtime, injectDebugConfigurations.get) |
| 32 | + if ( |
| 33 | + debugConfigurations.map((_) => String(_).toLowerCase()).indexOf(config.type.toLowerCase()) === -1 |
| 34 | + ) return config |
| 35 | + |
| 36 | + // if enabled, then inject the instrumentation in NODE_OPTIONS |
| 37 | + const configEnv = config.env || {} |
| 38 | + const previousNodeOptions = configEnv.NODE_OPTIONS || "${env:NODE_OPTIONS}" |
| 39 | + const instrumentationPath = JSON.stringify(extension.extensionPath + "/out/instrumentation.global.js") |
| 40 | + return { |
| 41 | + ...config, |
| 42 | + env: { |
| 43 | + ...configEnv, |
| 44 | + "NODE_OPTIONS": `--require ${instrumentationPath} ${previousNodeOptions}` |
| 45 | + } |
| 46 | + } |
| 47 | + } |
| 48 | + }) |
| 49 | + ), |
| 50 | + (disposer) => Effect.sync(() => disposer.dispose()) |
| 51 | + ) |
| 52 | +}).pipe(Layer.scopedDiscard) |
0 commit comments