From 2819f984608fa6e18e542e3dcd15424b42364c78 Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Mon, 28 Sep 2020 12:22:14 +0200 Subject: [PATCH 1/3] add option decodeMappings to remapping --- src/remapping.ts | 17 +++++++++++------ test/unit/remapping.ts | 27 ++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/remapping.ts b/src/remapping.ts index 48658c3..d6bfd71 100644 --- a/src/remapping.ts +++ b/src/remapping.ts @@ -16,7 +16,7 @@ import buildSourceMapTree from './build-source-map-tree'; import SourceMap from './source-map'; -import { SourceMapInput, SourceMapLoader } from './types'; +import { DecodedSourceMap, SourceMapInput, SourceMapLoader } from './types'; /** * Traces through all the mappings in the root sourcemap, through the sources @@ -27,14 +27,19 @@ import { SourceMapInput, SourceMapLoader } from './types'; * it returns a falsey value, that source file is treated as an original, * unmodified source file. * - * Pass `excludeContent` content to exclude any self-containing source file - * content from the output sourcemap. + * Pass `excludeContent` to exclude any self-containing source file content + * from the output sourcemap. + * + * Pass `decodeMappings` to get a sourcemap with decoded mappings. */ export default function remapping( input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader, - excludeContent?: boolean -): SourceMap { + excludeContent?: boolean, + decodeMappings?: boolean +): SourceMap | DecodedSourceMap { const graph = buildSourceMapTree(input, loader); - return new SourceMap(graph.traceMappings(), !!excludeContent); + return decodeMappings + ? graph.traceMappings() + : new SourceMap(graph.traceMappings(), !!excludeContent); } diff --git a/test/unit/remapping.ts b/test/unit/remapping.ts index d72276a..07a702b 100644 --- a/test/unit/remapping.ts +++ b/test/unit/remapping.ts @@ -15,7 +15,7 @@ */ import remapping from '../../src/remapping'; -import { RawSourceMap } from '../../src/types'; +import { DecodedSourceMap, RawSourceMap } from '../../src/types'; describe('remapping', () => { const rawMap: RawSourceMap = { @@ -49,6 +49,16 @@ describe('remapping', () => { sourcesContent: ['\n\n 1 + 1;'], version: 3, }; + const decodedMap: DecodedSourceMap = { + file: 'transpiled.min.js', + mappings: [[[0, 0, 2, 2, 0]]], + names: ['add'], + // TODO: support sourceRoot + // sourceRoot: '', + sources: ['helloworld.js'], + sourcesContent: ['\n\n 1 + 1;'], + version: 3, + }; test('does not alter a lone sourcemap', () => { const map = remapping(rawMap, () => null); @@ -155,4 +165,19 @@ describe('remapping', () => { expect(map).not.toHaveProperty('sourcesContent'); }); + + test('returns decoded mappings if `decodeMappings` is set', () => { + const map = remapping( + rawMap, + (name: string) => { + if (name === 'transpiled.js') { + return transpiledMap; + } + }, + false, + true + ); + + expect(map).toEqual(decodedMap); + }); }); From 4c25d9c287b2dde59e9cc4327713c3276c9a69d3 Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Mon, 28 Sep 2020 20:57:45 +0200 Subject: [PATCH 2/3] add option segmentsAreSorted --- src/build-source-map-tree.ts | 5 +- src/decode-source-map.ts | 14 +++-- src/remapping.ts | 5 +- test/unit/remapping.ts | 111 ++++++++++++++++++++++++++++------- 4 files changed, 105 insertions(+), 30 deletions(-) diff --git a/src/build-source-map-tree.ts b/src/build-source-map-tree.ts index bd49841..52de627 100644 --- a/src/build-source-map-tree.ts +++ b/src/build-source-map-tree.ts @@ -40,9 +40,10 @@ function asArray(value: T | T[]): T[] { export default function buildSourceMapTree( input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader, - relativeRoot?: string + relativeRoot?: string, + segmentsAreSorted?: boolean ): SourceMapTree { - const maps = asArray(input).map(decodeSourceMap); + const maps = asArray(input).map((map: SourceMapInput): DecodedSourceMap => decodeSourceMap(map, segmentsAreSorted)) as DecodedSourceMap[]; const map = maps.pop()!; for (let i = 0; i < maps.length; i++) { diff --git a/src/decode-source-map.ts b/src/decode-source-map.ts index a521350..b9ecad0 100644 --- a/src/decode-source-map.ts +++ b/src/decode-source-map.ts @@ -24,7 +24,7 @@ import { DecodedSourceMap, RawSourceMap, SourceMapInput, SourceMapSegment } from * Valid input maps include a `DecodedSourceMap`, a `RawSourceMap`, or JSON * representations of either type. */ -export default function decodeSourceMap(map: SourceMapInput): DecodedSourceMap { +export default function decodeSourceMap(map: SourceMapInput, segmentsAreSorted?: boolean): DecodedSourceMap { if (typeof map === 'string') { map = JSON.parse(map) as DecodedSourceMap | RawSourceMap; } @@ -32,15 +32,17 @@ export default function decodeSourceMap(map: SourceMapInput): DecodedSourceMap { let { mappings } = map; if (typeof mappings === 'string') { mappings = decode(mappings); - } else { + } else if (!segmentsAreSorted) { // Clone the Line so that we can sort it. We don't want to mutate an array // that we don't own directly. mappings = mappings.map(cloneSegmentLine); } - // Sort each Line's segments. There's no guarantee that segments are sorted for us, - // and even Chrome's implementation sorts: - // https://cs.chromium.org/chromium/src/third_party/devtools-frontend/src/front_end/sdk/SourceMap.js?l=507-508&rcl=109232bcf479c8f4ef8ead3cf56c49eb25f8c2f0 - mappings.forEach(sortSegments); + if (!segmentsAreSorted) { + // Sort each Line's segments. There's no guarantee that segments are sorted for us, + // and even Chrome's implementation sorts: + // https://cs.chromium.org/chromium/src/third_party/devtools-frontend/src/front_end/sdk/SourceMap.js?l=507-508&rcl=109232bcf479c8f4ef8ead3cf56c49eb25f8c2f0 + mappings.forEach(sortSegments); + } return defaults({ mappings }, map); } diff --git a/src/remapping.ts b/src/remapping.ts index d6bfd71..8bb4d0a 100644 --- a/src/remapping.ts +++ b/src/remapping.ts @@ -36,9 +36,10 @@ export default function remapping( input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader, excludeContent?: boolean, - decodeMappings?: boolean + decodeMappings?: boolean, + segmentsAreSorted?: boolean ): SourceMap | DecodedSourceMap { - const graph = buildSourceMapTree(input, loader); + const graph = buildSourceMapTree(input, loader, '', !!segmentsAreSorted); return decodeMappings ? graph.traceMappings() : new SourceMap(graph.traceMappings(), !!excludeContent); diff --git a/test/unit/remapping.ts b/test/unit/remapping.ts index 07a702b..d216a9f 100644 --- a/test/unit/remapping.ts +++ b/test/unit/remapping.ts @@ -18,20 +18,31 @@ import remapping from '../../src/remapping'; import { DecodedSourceMap, RawSourceMap } from '../../src/types'; describe('remapping', () => { + + // transform chain: + // 1+1 \n 1+1 \n\n 1 + 1; + // line 0 column 0 < line 1 column 1 < line 2 column 2 + // transpiled.min.js < transpiled.js < helloworld.js + // v v + // rawMap transpiledMap + // v + // translatedMap + + // segment = output_column [, source, line, column [, name]] + // all decoded numbers are zero-based + const rawMap: RawSourceMap = { file: 'transpiled.min.js', - // 0th column of 1st line of output file translates into the 1st source - // file, line 2, column 1, using 1st name. - mappings: 'AACCA', + // line 0, column 0 <- source 0, line 1, column 1, name 0 + mappings: 'AACCA', // [[[ 0, 0, 1, 1, 0 ]]] names: ['add'], sources: ['transpiled.js'], - sourcesContent: ['1+1'], + sourcesContent: ['\n 1+1'], version: 3, }; const transpiledMap: RawSourceMap = { - // 1st column of 2nd line of output file translates into the 1st source - // file, line 3, column 2 - mappings: ';CAEE', + // line 1, column 1 <- source 0, line 2, column 2 + mappings: ';CAEE', // [ [], [[ 1, 0, 2, 2 ]] ] names: [], sources: ['helloworld.js'], sourcesContent: ['\n\n 1 + 1;'], @@ -39,9 +50,8 @@ describe('remapping', () => { }; const translatedMap: RawSourceMap = { file: 'transpiled.min.js', - // 0th column of 1st line of output file translates into the 1st source - // file, line 3, column 2, using first name - mappings: 'AAEEA', + // line 0, column 0 <- source 0, line 2, column 2, name 0 + mappings: 'AAEEA', // [[[ 0, 0, 2, 2, 0 ]]] names: ['add'], // TODO: support sourceRoot // sourceRoot: '', @@ -49,16 +59,48 @@ describe('remapping', () => { sourcesContent: ['\n\n 1 + 1;'], version: 3, }; - const decodedMap: DecodedSourceMap = { - file: 'transpiled.min.js', - mappings: [[[0, 0, 2, 2, 0]]], - names: ['add'], - // TODO: support sourceRoot - // sourceRoot: '', - sources: ['helloworld.js'], - sourcesContent: ['\n\n 1 + 1;'], - version: 3, + + const rawMapDecoded: DecodedSourceMap = { + ...rawMap, + mappings: [[[ 0, 0, 1, 1, 0 ]]], + }; + const transpiledMapDecoded: DecodedSourceMap = { + ...transpiledMap, + mappings: [ [], [[ 1, 0, 2, 2 ]] ], + }; + const translatedMapDecoded: DecodedSourceMap = { + ...translatedMap, + mappings: [[[ 0, 0, 2, 2, 0 ]]], + }; + + // segments in reverse order to test `segmentsAreSorted` option + // sort order is preserved in result + // transform chain: + // line 0 column 0 < line 1 column 1 < line 2 column 2 + // line 0 column 1 < line 1 column 2 < line 2 column 1 + // transpiled.min.js < transpiled.js < helloworld.js + // v v + // rawMap transpiledMap + const rawMapDecodedReversed: DecodedSourceMap = { + ...rawMap, + // line 0, column 1 <- source 0, line 1, column 2, name 0 + // line 0, column 0 <- source 0, line 1, column 1 + mappings: [[ [ 1, 0, 1, 2, 0 ], [ 0, 0, 1, 1 ] ]], }; + const transpiledMapDecodedReversed: DecodedSourceMap = { + ...transpiledMap, + // line 1, column 2 <- source 0, line 2, column 1 + // line 1, column 1 <- source 0, line 2, column 2 + mappings: [ [], [ [ 2, 0, 2, 1 ], [ 1, 0, 2, 2 ] ] ], + }; + const translatedMapDecodedReversed: DecodedSourceMap = { + ...translatedMap, + // line 0, column 1 <- source 0, line 2, column 1, name 0 + // line 0, column 0 <- source 0, line 2, column 2 + mappings: [[ [ 1, 0, 2, 1, 0 ], [ 0, 0, 2, 2 ] ]], + }; + + test('does not alter a lone sourcemap', () => { const map = remapping(rawMap, () => null); @@ -178,6 +220,35 @@ describe('remapping', () => { true ); - expect(map).toEqual(decodedMap); + expect(map).toEqual(translatedMapDecoded); + }); + + test('accepts decoded mappings as input', () => { + const map = remapping( + rawMapDecoded, + (name: string) => { + if (name === 'transpiled.js') { + return transpiledMapDecoded; + } + } + ); + + expect(map).toEqual(translatedMap); + }); + + test('skips sorting of segments if `segmentsAreSorted` is set', () => { + const map = remapping( + rawMapDecodedReversed, + (name: string) => { + if (name === 'transpiled.js') { + return transpiledMapDecodedReversed; + } + }, + false, + true, + true + ); + + expect(map).toEqual(translatedMapDecodedReversed); }); }); From fbc7722cac4f8868ccc0c604fbbba1c0f47297ef Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Mon, 5 Oct 2020 14:16:08 +0200 Subject: [PATCH 3/3] rename decodeMappings to skipEncodeMappings, refactor --- src/build-source-map-tree.ts | 11 +++-- src/decode-source-map.ts | 5 ++- src/remapping.ts | 37 ++++++++++++----- src/source-map.ts | 10 ++--- src/types.ts | 4 ++ test/unit/remapping.ts | 79 +++++++++++++++++++++++++----------- test/unit/source-map.ts | 20 +++++---- 7 files changed, 116 insertions(+), 50 deletions(-) diff --git a/src/build-source-map-tree.ts b/src/build-source-map-tree.ts index 52de627..748083c 100644 --- a/src/build-source-map-tree.ts +++ b/src/build-source-map-tree.ts @@ -19,7 +19,7 @@ import OriginalSource from './original-source'; import resolve from './resolve'; import SourceMapTree from './source-map-tree'; import stripFilename from './strip-filename'; -import { SourceMapInput, SourceMapLoader } from './types'; +import { DecodedSourceMap, SourceMapInput, SourceMapLoader } from './types'; function asArray(value: T | T[]): T[] { if (Array.isArray(value)) return value; @@ -43,7 +43,12 @@ export default function buildSourceMapTree( relativeRoot?: string, segmentsAreSorted?: boolean ): SourceMapTree { - const maps = asArray(input).map((map: SourceMapInput): DecodedSourceMap => decodeSourceMap(map, segmentsAreSorted)) as DecodedSourceMap[]; + const maps = asArray(input).map( + (map: SourceMapInput): DecodedSourceMap => { + return decodeSourceMap(map, segmentsAreSorted); + } + ); + // as DecodedSourceMap[]; const map = maps.pop()!; for (let i = 0; i < maps.length; i++) { @@ -79,7 +84,7 @@ export default function buildSourceMapTree( // Else, it's a real sourcemap, and we need to recurse into it to load its // source files. - return buildSourceMapTree(decodeSourceMap(sourceMap), loader, uri); + return buildSourceMapTree(decodeSourceMap(sourceMap, segmentsAreSorted), loader, uri); }); let tree = new SourceMapTree(map, children); diff --git a/src/decode-source-map.ts b/src/decode-source-map.ts index b9ecad0..a244ac9 100644 --- a/src/decode-source-map.ts +++ b/src/decode-source-map.ts @@ -24,7 +24,10 @@ import { DecodedSourceMap, RawSourceMap, SourceMapInput, SourceMapSegment } from * Valid input maps include a `DecodedSourceMap`, a `RawSourceMap`, or JSON * representations of either type. */ -export default function decodeSourceMap(map: SourceMapInput, segmentsAreSorted?: boolean): DecodedSourceMap { +export default function decodeSourceMap( + map: SourceMapInput, + segmentsAreSorted?: boolean +): DecodedSourceMap { if (typeof map === 'string') { map = JSON.parse(map) as DecodedSourceMap | RawSourceMap; } diff --git a/src/remapping.ts b/src/remapping.ts index 8bb4d0a..5513564 100644 --- a/src/remapping.ts +++ b/src/remapping.ts @@ -16,7 +16,13 @@ import buildSourceMapTree from './build-source-map-tree'; import SourceMap from './source-map'; -import { DecodedSourceMap, SourceMapInput, SourceMapLoader } from './types'; +import { + DecodedSourceMap, + RawOrDecodedSourceMap, + RawSourceMap, + SourceMapInput, + SourceMapLoader, +} from './types'; /** * Traces through all the mappings in the root sourcemap, through the sources @@ -30,17 +36,28 @@ import { DecodedSourceMap, SourceMapInput, SourceMapLoader } from './types'; * Pass `excludeContent` to exclude any self-containing source file content * from the output sourcemap. * - * Pass `decodeMappings` to get a sourcemap with decoded mappings. + * Pass `skipEncodeMappings` to get a sourcemap with decoded mappings. + * + * Pass `segmentsAreSorted` to skip sorting of segments. Only use when segments + * are guaranteed to be sorted, otherwise mappings will be wrong. */ export default function remapping( input: SourceMapInput | SourceMapInput[], loader: SourceMapLoader, - excludeContent?: boolean, - decodeMappings?: boolean, - segmentsAreSorted?: boolean -): SourceMap | DecodedSourceMap { - const graph = buildSourceMapTree(input, loader, '', !!segmentsAreSorted); - return decodeMappings - ? graph.traceMappings() - : new SourceMap(graph.traceMappings(), !!excludeContent); + options?: { + excludeContent?: boolean; + skipEncodeMappings?: boolean; + segmentsAreSorted?: boolean; + } +): RawOrDecodedSourceMap { + // TODO remove in future + // tslint:disable-next-line:strict-type-predicates + if (typeof options === 'boolean') throw new Error('Please use the new API'); + + const graph = buildSourceMapTree(input, loader, '', !!(options && options.segmentsAreSorted)); + return new SourceMap( + graph.traceMappings(), + !!(options && options.excludeContent), + !!(options && options.skipEncodeMappings) + ); } diff --git a/src/source-map.ts b/src/source-map.ts index 07369d0..dbca1e0 100644 --- a/src/source-map.ts +++ b/src/source-map.ts @@ -15,25 +15,25 @@ */ import { encode } from 'sourcemap-codec'; -import { DecodedSourceMap, RawSourceMap } from './types'; +import { DecodedSourceMap, RawOrDecodedSourceMap, SourceMapSegment } from './types'; /** * A SourceMap v3 compatible sourcemap, which only includes fields that were * provided to it. */ -export default class SourceMap implements RawSourceMap { +export default class SourceMap implements RawOrDecodedSourceMap { file?: string | null; - mappings: string; + mappings: string | SourceMapSegment[][]; sourceRoot?: string; names: string[]; sources: (string | null)[]; sourcesContent?: (string | null)[]; version: 3; - constructor(map: DecodedSourceMap, excludeContent: boolean) { + constructor(map: DecodedSourceMap, excludeContent: boolean, skipEncodeMappings: boolean) { this.version = 3; // SourceMap spec says this should be first. if ('file' in map) this.file = map.file; - this.mappings = encode(map.mappings); + this.mappings = skipEncodeMappings ? map.mappings : encode(map.mappings); this.names = map.names; // TODO: We first need to make all source URIs relative to the sourceRoot diff --git a/src/types.ts b/src/types.ts index c5286d4..27488df 100644 --- a/src/types.ts +++ b/src/types.ts @@ -42,6 +42,10 @@ export interface DecodedSourceMap extends SourceMapV3 { mappings: SourceMapSegment[][]; } +export interface RawOrDecodedSourceMap extends SourceMapV3 { + mappings: string | SourceMapSegment[][]; +} + export interface SourceMapSegmentObject { column: number; line: number; diff --git a/test/unit/remapping.ts b/test/unit/remapping.ts index d216a9f..fd17276 100644 --- a/test/unit/remapping.ts +++ b/test/unit/remapping.ts @@ -18,7 +18,6 @@ import remapping from '../../src/remapping'; import { DecodedSourceMap, RawSourceMap } from '../../src/types'; describe('remapping', () => { - // transform chain: // 1+1 \n 1+1 \n\n 1 + 1; // line 0 column 0 < line 1 column 1 < line 2 column 2 @@ -62,15 +61,15 @@ describe('remapping', () => { const rawMapDecoded: DecodedSourceMap = { ...rawMap, - mappings: [[[ 0, 0, 1, 1, 0 ]]], + mappings: [[[0, 0, 1, 1, 0]]], }; const transpiledMapDecoded: DecodedSourceMap = { ...transpiledMap, - mappings: [ [], [[ 1, 0, 2, 2 ]] ], + mappings: [[], [[1, 0, 2, 2]]], }; const translatedMapDecoded: DecodedSourceMap = { ...translatedMap, - mappings: [[[ 0, 0, 2, 2, 0 ]]], + mappings: [[[0, 0, 2, 2, 0]]], }; // segments in reverse order to test `segmentsAreSorted` option @@ -85,23 +84,37 @@ describe('remapping', () => { ...rawMap, // line 0, column 1 <- source 0, line 1, column 2, name 0 // line 0, column 0 <- source 0, line 1, column 1 - mappings: [[ [ 1, 0, 1, 2, 0 ], [ 0, 0, 1, 1 ] ]], + mappings: [ + [ + [1, 0, 1, 2, 0], + [0, 0, 1, 1], + ], + ], }; const transpiledMapDecodedReversed: DecodedSourceMap = { ...transpiledMap, // line 1, column 2 <- source 0, line 2, column 1 // line 1, column 1 <- source 0, line 2, column 2 - mappings: [ [], [ [ 2, 0, 2, 1 ], [ 1, 0, 2, 2 ] ] ], + mappings: [ + [], + [ + [2, 0, 2, 1], + [1, 0, 2, 2], + ], + ], }; const translatedMapDecodedReversed: DecodedSourceMap = { ...translatedMap, // line 0, column 1 <- source 0, line 2, column 1, name 0 // line 0, column 0 <- source 0, line 2, column 2 - mappings: [[ [ 1, 0, 2, 1, 0 ], [ 0, 0, 2, 2 ] ]], + mappings: [ + [ + [1, 0, 2, 1, 0], + [0, 0, 2, 2], + ], + ], }; - - test('does not alter a lone sourcemap', () => { const map = remapping(rawMap, () => null); expect(map).toEqual(rawMap); @@ -202,13 +215,15 @@ describe('remapping', () => { return transpiledMap; } }, - true + { + excludeContent: true, + } ); expect(map).not.toHaveProperty('sourcesContent'); }); - test('returns decoded mappings if `decodeMappings` is set', () => { + test('returns decoded mappings if `skipEncodeMappings` is set', () => { const map = remapping( rawMap, (name: string) => { @@ -216,22 +231,20 @@ describe('remapping', () => { return transpiledMap; } }, - false, - true + { + skipEncodeMappings: true, + } ); expect(map).toEqual(translatedMapDecoded); }); test('accepts decoded mappings as input', () => { - const map = remapping( - rawMapDecoded, - (name: string) => { - if (name === 'transpiled.js') { - return transpiledMapDecoded; - } + const map = remapping(rawMapDecoded, (name: string) => { + if (name === 'transpiled.js') { + return transpiledMapDecoded; } - ); + }); expect(map).toEqual(translatedMap); }); @@ -244,11 +257,29 @@ describe('remapping', () => { return transpiledMapDecodedReversed; } }, - false, - true, - true + { + skipEncodeMappings: true, + segmentsAreSorted: true, + } ); - expect(map).toEqual(translatedMapDecodedReversed); }); + + test('throws error when old API is used', () => { + try { + remapping( + rawMapDecoded, + (name: string) => { + if (name === 'transpiled.js') { + return transpiledMapDecoded; + } + }, + true as any // old API + ); + // fail + expect(1).toEqual(0); + } catch (error) { + expect(error.message).toEqual('Please use the new API'); + } + }); }); diff --git a/test/unit/source-map.ts b/test/unit/source-map.ts index e4c4c3c..c4adb6a 100644 --- a/test/unit/source-map.ts +++ b/test/unit/source-map.ts @@ -26,7 +26,7 @@ describe('SourceMap', () => { }; test('it is a compliant, v3 sourcemap', () => { - const map = new SourceMap(decoded, false); + const map = new SourceMap(decoded, false, false); expect(map).toHaveProperty('mappings', 'AAAA'); expect(map).toHaveProperty('names', decoded.names); expect(map).toHaveProperty('sources', decoded.sources); @@ -34,7 +34,7 @@ describe('SourceMap', () => { }); test('it does not include properties missing from input', () => { - const map = new SourceMap(decoded, false); + const map = new SourceMap(decoded, false, false); expect(map).not.toHaveProperty('file'); expect(map).not.toHaveProperty('sourceRoot'); expect(map).not.toHaveProperty('sourcesContent'); @@ -42,32 +42,38 @@ describe('SourceMap', () => { test('it can include a file', () => { const file = 'foobar.js'; - const map = new SourceMap({ ...decoded, file }, false); + const map = new SourceMap({ ...decoded, file }, false, false); expect(map).toHaveProperty('file', file); }); // TODO: support sourceRoot test.skip('it can include a sourceRoot', () => { const sourceRoot = 'https://foo.com/'; - const map = new SourceMap({ ...decoded, sourceRoot }, false); + const map = new SourceMap({ ...decoded, sourceRoot }, false, false); expect(map).toHaveProperty('sourceRoot', sourceRoot); }); test('it can include a sourcesContent', () => { const sourcesContent = ['1 + 1']; - const map = new SourceMap({ ...decoded, sourcesContent }, false); + const map = new SourceMap({ ...decoded, sourcesContent }, false, false); expect(map).toHaveProperty('sourcesContent', sourcesContent); }); test('sourcesContent can be manually excluded', () => { const sourcesContent = ['1 + 1']; - const map = new SourceMap({ ...decoded, sourcesContent }, true); + const map = new SourceMap({ ...decoded, sourcesContent }, true, false); expect(map).not.toHaveProperty('sourcesContent'); }); + test('can return decoded mappings', () => { + const sourcesContent = ['1 + 1']; + const map = new SourceMap({ ...decoded, sourcesContent }, false, true); + expect(map).toHaveProperty('mappings', [[[0, 0, 0, 0]]]); + }); + describe('toString()', () => { test('returns the sourcemap in JSON', () => { - const map = new SourceMap(decoded, false); + const map = new SourceMap(decoded, false, false); expect(JSON.parse(map.toString())).toEqual(map); }); });