From b6d8434d17af056c860882efe7c670b9c6e0ec72 Mon Sep 17 00:00:00 2001 From: Justin Ridgewell Date: Thu, 28 Apr 2022 17:00:43 -0400 Subject: [PATCH] Switch to `@jridgewell/gen-mapping` for sourcemap generation (#14497) --- lib/third-party-libs.js.flow | 35 ------ .../out-files/lib/bar/bar.js | 2 +- .../out-files/lib/foo.js | 2 +- .../out-files/lib/bar/bar.js.map | 2 +- .../out-files/lib/foo.js.map | 2 +- .../stdin --source-maps inline/stdout.txt | 2 +- packages/babel-cli/test/index.js | 10 +- .../src/transformation/file/generate.ts | 24 ++-- .../source-maps/inline/output.js | 2 +- packages/babel-generator/package.json | 5 +- packages/babel-generator/src/buffer.ts | 37 +++--- packages/babel-generator/src/index.ts | 13 +- packages/babel-generator/src/source-map.ts | 113 ++++++++++-------- yarn.lock | 27 +++-- 14 files changed, 141 insertions(+), 135 deletions(-) diff --git a/lib/third-party-libs.js.flow b/lib/third-party-libs.js.flow index c45b2d68c220..11b8368ff1cd 100644 --- a/lib/third-party-libs.js.flow +++ b/lib/third-party-libs.js.flow @@ -51,41 +51,6 @@ declare module "semver" { } } -declare module "source-map" { - declare export type SourceMap = { - version: 3, - file: ?string, - sourceRoot: ?string, - sources: [?string], - sourcesContent: [?string], - names: [?string], - mappings: string, - }; - - declare module.exports: { - SourceMapGenerator: typeof SourceMapGenerator, - } - - declare class SourceMapGenerator { - constructor(?{ - file?: string | null, - sourceRoot?: string | null, - skipValidation?: boolean | null, - }): this; - - addMapping({ - generated: { - line: number, - column: number, - } - }): void; - - setSourceContent(string, string): void; - - toJSON(): SourceMap; - } -} - declare module "convert-source-map" { import type { SourceMap, SourceMapGenerator } from "source-map"; diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/bar/bar.js b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/bar/bar.js index 4887700771ad..6972e60eadda 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/bar/bar.js +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/bar/bar.js @@ -3,4 +3,4 @@ (function () { return 42; }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9iYXIvYmFyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsQ0FBQztBQUFBLFNBQU0sRUFBTjtBQUFBLENBQUQiLCJzb3VyY2VzQ29udGVudCI6WyIoKCkgPT4gNDIpIl19 \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jhci9iYXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiKCgpID0+IDQyKSJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxDQUFDO0FBQUEsU0FBTSxFQUFOO0FBQUEsQ0FBRCJ9 \ No newline at end of file diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/foo.js b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/foo.js index 9b8f51f2f6fc..fb877b64c666 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/foo.js +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps inline/out-files/lib/foo.js @@ -3,4 +3,4 @@ arr.map(function (x) { return x * MULTIPLIER; }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9mb28uanMiXSwibmFtZXMiOlsiYXJyIiwibWFwIiwieCIsIk1VTFRJUExJRVIiXSwibWFwcGluZ3MiOiI7O0FBQUFBLEdBQUcsQ0FBQ0MsR0FBSixDQUFRLFVBQUFDLENBQUM7QUFBQSxTQUFJQSxDQUFDLEdBQUdDLFVBQVI7QUFBQSxDQUFUIiwic291cmNlc0NvbnRlbnQiOlsiYXJyLm1hcCh4ID0+IHggKiBNVUxUSVBMSUVSKTsiXX0= +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhcnIiLCJtYXAiLCJ4IiwiTVVMVElQTElFUiJdLCJzb3VyY2VzIjpbIi4uL3NyYy9mb28uanMiXSwic291cmNlc0NvbnRlbnQiOlsiYXJyLm1hcCh4ID0+IHggKiBNVUxUSVBMSUVSKTsiXSwibWFwcGluZ3MiOiI7O0FBQUFBLEdBQUcsQ0FBQ0MsR0FBSixDQUFRLFVBQUFDLENBQUM7QUFBQSxTQUFJQSxDQUFDLEdBQUdDLFVBQVI7QUFBQSxDQUFUIn0= \ No newline at end of file diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/bar/bar.js.map b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/bar/bar.js.map index b10075c68427..0947e19fc08d 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/bar/bar.js.map +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/bar/bar.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/bar/bar.js"],"names":[],"mappings":";;AAAA,CAAC;AAAA,SAAM,EAAN;AAAA,CAAD","sourcesContent":["(() => 42)"],"file":"bar.js"} \ No newline at end of file +{"version":3,"file":"bar.js","names":[],"sources":["../../src/bar/bar.js"],"sourcesContent":["(() => 42)"],"mappings":";;AAAA,CAAC;AAAA,SAAM,EAAN;AAAA,CAAD"} \ No newline at end of file diff --git a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/foo.js.map b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/foo.js.map index 3caee699c140..60390d68c410 100644 --- a/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/foo.js.map +++ b/packages/babel-cli/test/fixtures/babel/dir --out-dir --source-maps/out-files/lib/foo.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/foo.js"],"names":["arr","map","x","MULTIPLIER"],"mappings":";;AAAAA,GAAG,CAACC,GAAJ,CAAQ,UAAAC,CAAC;AAAA,SAAIA,CAAC,GAAGC,UAAR;AAAA,CAAT","sourcesContent":["arr.map(x => x * MULTIPLIER);"],"file":"foo.js"} +{"version":3,"file":"foo.js","names":["arr","map","x","MULTIPLIER"],"sources":["../src/foo.js"],"sourcesContent":["arr.map(x => x * MULTIPLIER);"],"mappings":";;AAAAA,GAAG,CAACC,GAAJ,CAAQ,UAAAC,CAAC;AAAA,SAAIA,CAAC,GAAGC,UAAR;AAAA,CAAT"} \ No newline at end of file diff --git a/packages/babel-cli/test/fixtures/babel/stdin --source-maps inline/stdout.txt b/packages/babel-cli/test/fixtures/babel/stdin --source-maps inline/stdout.txt index 4f53425171cc..d6a91c7ace1f 100644 --- a/packages/babel-cli/test/fixtures/babel/stdin --source-maps inline/stdout.txt +++ b/packages/babel-cli/test/fixtures/babel/stdin --source-maps inline/stdout.txt @@ -3,6 +3,6 @@ arr.map(function (x) { return x * x; }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbImFyciIsIm1hcCIsIngiXSwibWFwcGluZ3MiOiI7O0FBQUFBLEdBQUcsQ0FBQ0MsR0FBSixDQUFRLFVBQUFDLENBQUM7QUFBQSxTQUFJQSxDQUFDLEdBQUdBLENBQVI7QUFBQSxDQUFUIiwic291cmNlc0NvbnRlbnQiOlsiYXJyLm1hcCh4ID0+IHggKiB4KTsiXX0= +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhcnIiLCJtYXAiLCJ4Il0sInNvdXJjZXMiOlsic3RkaW4iXSwic291cmNlc0NvbnRlbnQiOlsiYXJyLm1hcCh4ID0+IHggKiB4KTsiXSwibWFwcGluZ3MiOiI7O0FBQUFBLEdBQUcsQ0FBQ0MsR0FBSixDQUFRLFVBQUFDLENBQUM7QUFBQSxTQUFJQSxDQUFDLEdBQUdBLENBQVI7QUFBQSxDQUFUIn0= //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Rkb3V0IiwibmFtZXMiOltdLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJtYXBwaW5ncyI6IiJ9 diff --git a/packages/babel-cli/test/index.js b/packages/babel-cli/test/index.js index 1941b84cf81d..43a1499fec1b 100644 --- a/packages/babel-cli/test/index.js +++ b/packages/babel-cli/test/index.js @@ -121,8 +121,13 @@ const assertTest = function (stdout, stderr, opts, cwd) { expect(actual).toBe(expected || ""); } } catch (e) { - e.message += "\n at " + filename; - throw e; + if (!process.env.OVERWRITE) { + e.message += "\n at " + filename; + throw e; + } + const expectedLoc = path.join(opts.testLoc, "out-files", filename); + console.log(`Updated test file: ${expectedLoc}`); + fs.writeFileSync(expectedLoc, actualFiles[filename]); } }); @@ -267,6 +272,7 @@ fs.readdirSync(fixtureLoc).forEach(function (binName) { } }); + opts.testLoc = testLoc; opts.outFiles = readDir(path.join(testLoc, "out-files"), fileFilter); opts.inFiles = readDir(path.join(testLoc, "in-files"), fileFilter); diff --git a/packages/babel-core/src/transformation/file/generate.ts b/packages/babel-core/src/transformation/file/generate.ts index 1b60aa9b1a2f..6be562b1d54a 100644 --- a/packages/babel-core/src/transformation/file/generate.ts +++ b/packages/babel-core/src/transformation/file/generate.ts @@ -46,14 +46,24 @@ export default function generateCode( throw new Error("More than one plugin attempted to override codegen."); } - let { code: outputCode, map: outputMap } = result; + // Decoded maps are faster to merge, so we attempt to get use the decodedMap + // first. But to preserve backwards compat with older Generator, we'll fall + // back to the encoded map. + let { code: outputCode, decodedMap: outputMap = result.map } = result; - if (outputMap && inputMap) { - outputMap = mergeSourceMap( - inputMap.toObject(), - outputMap, - generatorOpts.sourceFileName, - ); + if (outputMap) { + if (inputMap) { + // mergeSourceMap returns an encoded map + outputMap = mergeSourceMap( + inputMap.toObject(), + outputMap, + generatorOpts.sourceFileName, + ); + } else { + // We cannot output a decoded map, so retrieve the encoded form. Because + // the decoded form is free, it's fine to prioritize decoded first. + outputMap = result.map; + } } if (opts.sourceMaps === "inline" || opts.sourceMaps === "both") { diff --git a/packages/babel-core/test/fixtures/transformation/source-maps/inline/output.js b/packages/babel-core/test/fixtures/transformation/source-maps/inline/output.js index 240543408055..3d471519da83 100644 --- a/packages/babel-core/test/fixtures/transformation/source-maps/inline/output.js +++ b/packages/babel-core/test/fixtures/transformation/source-maps/inline/output.js @@ -1,4 +1,4 @@ arr.map(function (x) { return x * x; }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvdXJjZS1tYXBzL2lubGluZS9pbnB1dC5qcyJdLCJuYW1lcyI6WyJhcnIiLCJtYXAiLCJ4Il0sIm1hcHBpbmdzIjoiQUFBQUEsR0FBRyxDQUFDQyxHQUFKLENBQVEsVUFBQUMsQ0FBQztBQUFBLFNBQUlBLENBQUMsR0FBR0EsQ0FBUjtBQUFBLENBQVQiLCJzb3VyY2VzQ29udGVudCI6WyJhcnIubWFwKHggPT4geCAqIHgpOyJdfQ== +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhcnIiLCJtYXAiLCJ4Il0sInNvdXJjZXMiOlsic291cmNlLW1hcHMvaW5saW5lL2lucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImFyci5tYXAoeCA9PiB4ICogeCk7Il0sIm1hcHBpbmdzIjoiQUFBQUEsR0FBRyxDQUFDQyxHQUFKLENBQVEsVUFBQUMsQ0FBQztBQUFBLFNBQUlBLENBQUMsR0FBR0EsQ0FBUjtBQUFBLENBQVQifQ== diff --git a/packages/babel-generator/package.json b/packages/babel-generator/package.json index 62fa7821b50d..dc66e5bb9cc5 100644 --- a/packages/babel-generator/package.json +++ b/packages/babel-generator/package.json @@ -20,15 +20,14 @@ ], "dependencies": { "@babel/types": "workspace:^", - "jsesc": "condition: BABEL_8_BREAKING ? ^3.0.2 : ^2.5.1", - "source-map": "^0.5.0" + "@jridgewell/gen-mapping": "^0.1.0", + "jsesc": "condition: BABEL_8_BREAKING ? ^3.0.2 : ^2.5.1" }, "devDependencies": { "@babel/helper-fixtures": "workspace:^", "@babel/parser": "workspace:^", "@jridgewell/trace-mapping": "^0.3.8", "@types/jsesc": "^2.5.0", - "@types/source-map": "^0.5.0", "charcodes": "^0.2.0" }, "engines": { diff --git a/packages/babel-generator/src/buffer.ts b/packages/babel-generator/src/buffer.ts index cbbaef52e038..a6f6132c2b3f 100644 --- a/packages/babel-generator/src/buffer.ts +++ b/packages/babel-generator/src/buffer.ts @@ -46,25 +46,25 @@ export default class Buffer { // Whatever trim is used here should not execute a regex against the // source string since it may be arbitrarily large after all transformations code: this._buf.trimRight(), - map: null, - rawMappings: map?.getRawMappings(), + // Decoded sourcemap is free to generate. + decodedMap: map?.getDecoded(), + + // Encoding the sourcemap is moderately CPU expensive. + get map() { + return (result.map = map ? map.get() : null); + }, + set map(value) { + Object.defineProperty(result, "map", { value, writable: true }); + }, + // Retrieving the raw mappings is very memory intensive. + get rawMappings() { + return (result.rawMappings = map?.getRawMappings()); + }, + set rawMappings(value) { + Object.defineProperty(result, "rawMappings", { value, writable: true }); + }, }; - if (map) { - // The `.map` property is lazy to allow callers to use the raw mappings - // without any overhead - Object.defineProperty(result, "map", { - configurable: true, - enumerable: true, - get() { - return (this.map = map.get()); - }, - set(value) { - Object.defineProperty(this, "map", { value, writable: true }); - }, - }); - } - return result; } @@ -158,8 +158,7 @@ export default class Buffer { force?: boolean, ): void { this._map?.mark( - this._position.line, - this._position.column, + this._position, line, column, identifierName, diff --git a/packages/babel-generator/src/index.ts b/packages/babel-generator/src/index.ts index 6c449e0413bc..42cdb0b76290 100644 --- a/packages/babel-generator/src/index.ts +++ b/packages/babel-generator/src/index.ts @@ -3,6 +3,7 @@ import Printer from "./printer"; import type * as t from "@babel/types"; import type { Format } from "./printer"; +import type { DecodedSourceMap, Mapping } from "@jridgewell/gen-mapping"; /** * Babel's code generator, turns an ast into code, maintaining sourcemaps, @@ -10,7 +11,15 @@ import type { Format } from "./printer"; */ class Generator extends Printer { - constructor(ast: t.Node, opts: { sourceMaps?: boolean } = {}, code) { + constructor( + ast: t.Node, + opts: { + sourceFileName?: string; + sourceMaps?: boolean; + sourceRoot?: string; + } = {}, + code, + ) { const format = normalizeOptions(code, opts); const map = opts.sourceMaps ? new SourceMap(opts, code) : null; super(format, map); @@ -217,6 +226,8 @@ export interface GeneratorResult { mappings: string; file: string; } | null; + decodedMap: DecodedSourceMap | undefined; + rawMappings: Mapping[] | undefined; } /** diff --git a/packages/babel-generator/src/source-map.ts b/packages/babel-generator/src/source-map.ts index 402c68a6f699..4dcaed846f34 100644 --- a/packages/babel-generator/src/source-map.ts +++ b/packages/babel-generator/src/source-map.ts @@ -1,57 +1,69 @@ -import sourceMap from "source-map"; +import { + GenMapping, + addMapping, + setSourceContent, + allMappings, + encodedMap, + decodedMap, +} from "@jridgewell/gen-mapping"; + +import type { + EncodedSourceMap, + DecodedSourceMap, + Mapping, +} from "@jridgewell/gen-mapping"; /** * Build a sourcemap. */ export default class SourceMap { - private _cachedMap: sourceMap.SourceMapGenerator | null; - private _code: any; - private _opts: any; - private _rawMappings: any[]; - private _lastGenLine: number; - private _lastSourceLine: number; - private _lastSourceColumn: number; - constructor(opts, code) { - this._cachedMap = null; - this._code = code; - this._opts = opts; - this._rawMappings = []; + private _map: GenMapping; + private _rawMappings: Mapping[] | undefined; + private _sourceFileName: string | undefined; + + // Any real line is > 0, so init to 0 is fine. + private _lastGenLine = 0; + private _lastSourceLine = 0; + + // Source columns can be 0, but we ony check in unison with sourceLine, which + // inits to an impossible value. So init to 0 is fine. + private _lastSourceColumn = 0; + + constructor( + opts: { sourceFileName?: string; sourceRoot?: string }, + code: string | { [sourceFileName: string]: string }, + ) { + const map = (this._map = new GenMapping({ sourceRoot: opts.sourceRoot })); + this._sourceFileName = opts.sourceFileName?.replace(/\\/g, "/"); + this._rawMappings = undefined; + + if (typeof code === "string") { + setSourceContent(map, this._sourceFileName, code); + } else if (typeof code === "object") { + Object.keys(code).forEach(sourceFileName => { + setSourceContent( + map, + sourceFileName.replace(/\\/g, "/"), + code[sourceFileName], + ); + }); + } } /** * Get the sourcemap. */ + get(): EncodedSourceMap { + return encodedMap(this._map); + } - get() { - if (!this._cachedMap) { - const map = (this._cachedMap = new sourceMap.SourceMapGenerator({ - sourceRoot: this._opts.sourceRoot, - })); - - const code = this._code; - if (typeof code === "string") { - map.setSourceContent( - this._opts.sourceFileName.replace(/\\/g, "/"), - code, - ); - } else if (typeof code === "object") { - Object.keys(code).forEach(sourceFileName => { - map.setSourceContent( - sourceFileName.replace(/\\/g, "/"), - code[sourceFileName], - ); - }); - } - - this._rawMappings.forEach(mapping => map.addMapping(mapping), map); - } - - return this._cachedMap.toJSON(); + getDecoded(): DecodedSourceMap { + return decodedMap(this._map); } - getRawMappings() { - return this._rawMappings.slice(); + getRawMappings(): Mapping[] { + return (this._rawMappings ||= allMappings(this._map)); } /** @@ -60,14 +72,15 @@ export default class SourceMap { */ mark( - generatedLine: number, - generatedColumn: number, + generated: { line: number; column: number }, line: number, column: number, identifierName?: string | null, filename?: string | null, force?: boolean, ) { + const generatedLine = generated.line; + // Adding an empty mapping at the start of a generated line just clutters the map. if (this._lastGenLine !== generatedLine && line === null) return; @@ -82,24 +95,18 @@ export default class SourceMap { return; } - this._cachedMap = null; + this._rawMappings = undefined; this._lastGenLine = generatedLine; this._lastSourceLine = line; this._lastSourceColumn = column; - // We are deliberately not using the `source-map` library here to allow - // callers to use these mappings without any overhead - this._rawMappings.push({ - // undefined to allow for more compact json serialization - name: identifierName || undefined, - generated: { - line: generatedLine, - column: generatedColumn, - }, + addMapping(this._map, { + name: identifierName, + generated, source: line == null ? undefined - : (filename || this._opts.sourceFileName).replace(/\\/g, "/"), + : filename?.replace(/\\/g, "/") || this._sourceFileName, original: line == null ? undefined diff --git a/yarn.lock b/yarn.lock index 6d02dcb8e5c9..7210da0db71e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -456,12 +456,11 @@ __metadata: "@babel/helper-fixtures": "workspace:^" "@babel/parser": "workspace:^" "@babel/types": "workspace:^" + "@jridgewell/gen-mapping": ^0.1.0 "@jridgewell/trace-mapping": ^0.3.8 "@types/jsesc": ^2.5.0 - "@types/source-map": ^0.5.0 charcodes: ^0.2.0 jsesc: "condition: BABEL_8_BREAKING ? ^3.0.2 : ^2.5.1" - source-map: ^0.5.0 languageName: unknown linkType: soft @@ -4070,6 +4069,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.1.0": + version: 0.1.0 + resolution: "@jridgewell/gen-mapping@npm:0.1.0" + dependencies: + "@jridgewell/set-array": 1.0.0 + "@jridgewell/sourcemap-codec": ^1.4.10 + checksum: 8611de5acbea55fa84bcde0d6f803e006560f7a8ce618ba427e20a76913d18308fc14d5cfb324e30d0051556a96527fbc4e64cf65d68f121170776243387dcce + languageName: node + linkType: hard + "@jridgewell/resolve-uri@npm:^3.0.3": version: 3.0.3 resolution: "@jridgewell/resolve-uri@npm:3.0.3" @@ -4077,6 +4086,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/set-array@npm:1.0.0": + version: 1.0.0 + resolution: "@jridgewell/set-array@npm:1.0.0" + checksum: 35dd48a205099839fa8b9e9b7138d382d1f33457404c4e96c95ad1cd9aea99904737b351d4dea8b21fa17b50fcd0dc2fdbf4c04fc4bcd3c1a42d079217261444 + languageName: node + linkType: hard + "@jridgewell/sourcemap-codec@npm:^1.4.10": version: 1.4.10 resolution: "@jridgewell/sourcemap-codec@npm:1.4.10" @@ -4505,13 +4521,6 @@ __metadata: languageName: node linkType: hard -"@types/source-map@npm:^0.5.0": - version: 0.5.2 - resolution: "@types/source-map@npm:0.5.2" - checksum: e7ff6a13f396fbed6ec9181d6801fee0e466ede4b0e7f00662cd7aca34f0f30d22a7bf00e01a901b374f025a2d7857e19eee29a9dcf6c59af5168bcfc06aa66d - languageName: node - linkType: hard - "@types/stack-utils@npm:^2.0.0": version: 2.0.0 resolution: "@types/stack-utils@npm:2.0.0"