pax_global_header00006660000000000000000000000064132200435720014510gustar00rootroot0000000000000052 comment=987790721c7e3a36175f39de32bf060987200cc4 merge-source-map-1.1.0/000077500000000000000000000000001322004357200146575ustar00rootroot00000000000000merge-source-map-1.1.0/.eslintignore000066400000000000000000000000161322004357200173570ustar00rootroot00000000000000test/fixtures merge-source-map-1.1.0/.eslintrc.js000066400000000000000000000003271322004357200171200ustar00rootroot00000000000000module.exports = { "parserOptions": { "sourceType": "module", "ecmaVersion": 6 }, "env": { "es6": true, "node": true }, "rules": { "semi": [2, "never"], "no-unused-vars": [2] } } merge-source-map-1.1.0/.gitignore000066400000000000000000000000471322004357200166500ustar00rootroot00000000000000node_modules npm-debug.log .nyc_output merge-source-map-1.1.0/.prettierrc000066400000000000000000000000361322004357200170420ustar00rootroot00000000000000semi: false singleQuote: true merge-source-map-1.1.0/.travis.yml000066400000000000000000000003271322004357200167720ustar00rootroot00000000000000language: node_js node_js: - '0.12' - '4' - '5' - '6' sudo: false cache: directories: - node_modules after_success: npm i coveralls && $(npm bin)/nyc report --reporter=text-lcov | $(npm bin)/coveralls merge-source-map-1.1.0/LICENSE000066400000000000000000000020771322004357200156720ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) keik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. merge-source-map-1.1.0/README.md000066400000000000000000000043331322004357200161410ustar00rootroot00000000000000# merge-source-map [![npm-version](https://img.shields.io/npm/v/merge-source-map.svg?style=flat-square)](https://npmjs.org/package/merge-source-map) [![downloads](http://img.shields.io/npm/dm/merge-source-map.svg?style=flat-square)](https://npmjs.org/package/merge-source-map) [![travis-ci](https://img.shields.io/travis/keik/merge-source-map.svg?style=flat-square)](https://travis-ci.org/keik/merge-source-map) [![Coverage Status](https://img.shields.io/coveralls/keik/merge-source-map.svg?style=flat-square)](https://coveralls.io/github/keik/merge-source-map) Merge old source map and new source map in multi-transform flow # API ```javascript var merge = require('merge-source-map') ``` ## `merge(oldMap, newMap)` Merge old source map and new source map and return merged. If old or new source map value is falsy, return another one as it is.
oldMap : object|undefined
old source map object
newmap : object|undefined
new source map object
# Example ```javascript var esprima = require('esprima'), estraverse = require('estraverse'), escodegen = require('escodegen'), convert = require('convert-source-map'), merge = require('merge-source-map') const CODE = 'a = 1', FILEPATH = 'a.js' // create AST of original code var ast = esprima.parse(CODE, {sourceType: 'module', loc: true}) // transform AST of original code estraverse.replace(ast, { enter: function(node, parent) { /* change AST */ }, leave: function(node, parent) { /* change AST */ } }) // generate code and source map from transformed AST var gen = escodegen.generate(ast, { sourceMap: FILEPATH, sourceMapWithCode: true, sourceContent: CODE }) // merge old source map and new source map var oldMap = convert.fromSource(CODE) && convert.fromSource(CODE).toObject(), newMap = JSON.parse(gen.map.toString()), mergedMap = merge(oldMap, newMap), mapComment = convert.fromObject(mergedMap).toComment() // attach merge source map to transformed code var transformed = gen.code + '\n' + mapComment console.log(transformed); ``` # Test ``` % npm install % npm test ``` # License MIT (c) keik merge-source-map-1.1.0/index.js000066400000000000000000000040771322004357200163340ustar00rootroot00000000000000var sourceMap = require('source-map') var SourceMapConsumer = sourceMap.SourceMapConsumer var SourceMapGenerator = sourceMap.SourceMapGenerator module.exports = merge /** * Merge old source map and new source map and return merged. * If old or new source map value is falsy, return another one as it is. * * @param {object|string} [oldMap] old source map object * @param {object|string} [newmap] new source map object * @return {object|undefined} merged source map object, or undefined when both old and new source map are undefined */ function merge(oldMap, newMap) { if (!oldMap) return newMap if (!newMap) return oldMap var oldMapConsumer = new SourceMapConsumer(oldMap) var newMapConsumer = new SourceMapConsumer(newMap) var mergedMapGenerator = new SourceMapGenerator() // iterate on new map and overwrite original position of new map with one of old map newMapConsumer.eachMapping(function(m) { // pass when `originalLine` is null. // It occurs in case that the node does not have origin in original code. if (m.originalLine == null) return var origPosInOldMap = oldMapConsumer.originalPositionFor({ line: m.originalLine, column: m.originalColumn }) if (origPosInOldMap.source == null) return mergedMapGenerator.addMapping({ original: { line: origPosInOldMap.line, column: origPosInOldMap.column }, generated: { line: m.generatedLine, column: m.generatedColumn }, source: origPosInOldMap.source, name: origPosInOldMap.name }) }) var consumers = [oldMapConsumer, newMapConsumer] consumers.forEach(function(consumer) { consumer.sources.forEach(function(sourceFile) { mergedMapGenerator._sources.add(sourceFile) var sourceContent = consumer.sourceContentFor(sourceFile) if (sourceContent != null) { mergedMapGenerator.setSourceContent(sourceFile, sourceContent) } }) }) mergedMapGenerator._sourceRoot = oldMap.sourceRoot mergedMapGenerator._file = oldMap.file return JSON.parse(mergedMapGenerator.toString()) } merge-source-map-1.1.0/package.json000066400000000000000000000021401322004357200171420ustar00rootroot00000000000000{ "name": "merge-source-map", "version": "1.1.0", "description": "Merge old source map and new source map in multi-transform flow", "main": "index.js", "scripts": { "test": "nyc tape test/*.js", "lint": "eslint index.js 'test/**/*.js'", "version": "npm run lint && npm run test" }, "repository": { "type": "git", "url": "git+https://github.com/keik/merge-source-map.git" }, "author": "keik ", "license": "MIT", "bugs": { "url": "https://github.com/keik/merge-source-map/issues" }, "keywords": [ "sourcemap", "source-map" ], "dependencies": { "source-map": "^0.6.1" }, "devDependencies": { "babel-core": "^6.25.0", "babel-plugin-syntax-object-rest-spread": "^6.13.0", "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", "babel-plugin-transform-es2015-spread": "^6.22.0", "coffee-script": "^1.12.6", "convert-source-map": "^1.5.0", "escodegen": "^1.8.1", "eslint": "^3.19.0", "esprima": "^3.1.3", "estraverse": "^4.2.0", "nyc": "^8.4.0", "tape": "^4.6.3" }, "files": [] } merge-source-map-1.1.0/test/000077500000000000000000000000001322004357200156365ustar00rootroot00000000000000merge-source-map-1.1.0/test/fixtures/000077500000000000000000000000001322004357200175075ustar00rootroot00000000000000merge-source-map-1.1.0/test/fixtures/coffee-script/000077500000000000000000000000001322004357200222405ustar00rootroot00000000000000merge-source-map-1.1.0/test/fixtures/coffee-script/actual.js000066400000000000000000000013171322004357200240510ustar00rootroot00000000000000(function () { var a, b; a = 1; a = 1; b = function (arg1, arg2) { console.log(arg1); console.log(arg1); console.log(arg2); console.log(arg2); }; b = function (arg1, arg2) { console.log(arg1); console.log(arg1); console.log(arg2); console.log(arg2); }; }.call(this)); (function () { var a, b; a = 1; a = 1; b = function (arg1, arg2) { console.log(arg1); console.log(arg1); console.log(arg2); console.log(arg2); }; b = function (arg1, arg2) { console.log(arg1); console.log(arg1); console.log(arg2); console.log(arg2); }; }.call(this));merge-source-map-1.1.0/test/fixtures/coffee-script/expected.coffee000066400000000000000000000001251322004357200252100ustar00rootroot00000000000000a = 1 b = (arg1, arg2) -> console.log arg1 # comment console.log arg2 return merge-source-map-1.1.0/test/fixtures/coffee-script/expected.js000066400000000000000000000003171322004357200244000ustar00rootroot00000000000000// Generated by CoffeeScript 1.12.6 (function() { var a, b; a = 1; b = function(arg1, arg2) { console.log(arg1); console.log(arg2); }; }).call(this); //# sourceMappingURL=expected.js.map merge-source-map-1.1.0/test/fixtures/coffee-script/expected.js.map000066400000000000000000000004671322004357200251620ustar00rootroot00000000000000{ "version": 3, "file": "expected.js", "sourceRoot": "../../..", "sources": [ "test/fixtures/coffee-script/expected.coffee" ], "names": [], "mappings": ";AAAA;AAAA,MAAA;;EAAA,CAAA,GAAI;;EACJ,CAAA,GAAI,SAAC,IAAD,EAAO,IAAP;IACF,OAAO,CAAC,GAAR,CAAY,IAAZ;IAEA,OAAO,CAAC,GAAR,CAAY,IAAZ;EAHE;AADJ" }merge-source-map-1.1.0/test/fixtures/es2015/000077500000000000000000000000001322004357200204265ustar00rootroot00000000000000merge-source-map-1.1.0/test/fixtures/es2015/actual.js000066400000000000000000000005001322004357200222300ustar00rootroot00000000000000function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } var concatFooBar = function (args) { const f = 'foo'; const b = 'bar'; return [f, b].concat(_toConsumableArray(args)); };merge-source-map-1.1.0/test/fixtures/es2015/expected.js000066400000000000000000000001361322004357200225650ustar00rootroot00000000000000var concatFooBar = (args) => { const f = 'foo' const b = 'bar' return [f, b, ...args] } merge-source-map-1.1.0/test/test.js000066400000000000000000000231431322004357200171560ustar00rootroot00000000000000const test = require('tape') const merge = require('../') const fs = require('fs') const resolve = require('path').resolve const babel = require('babel-core') const SourceMapConsumer = require('source-map').SourceMapConsumer const doubleLineTransform = require('./transforms/tr-double-line') const insertEmptyStatementTransform = require('./transforms/tr-insert-empty-statement') test('undefined args should not effect results', function(t) { const code = 'y = x => x * 2' const transformed = babel.transform(code, { filename: 'source.js', plugins: ['transform-es2015-spread'], sourceMaps: true }) const map = transformed.map t.equal(map, merge(undefined, map)) t.equal(map, merge(map, undefined)) t.end() }) test('multi transform with CoffeeScript and doubleLineTransform', function(t) { // first transform from CofeeeScript to JavaScript (assumed pre-processed) const coffeeCompiledCode = fs.readFileSync(resolve(__dirname, './fixtures/coffee-script/expected.js'), 'utf-8') const coffeeCompiledMap = fs.readFileSync(resolve(__dirname, './fixtures/coffee-script/expected.js.map'), 'utf-8') // second transform with `doubleLineTransform` const doubleLineTransformed = doubleLineTransform(coffeeCompiledCode, 'coffeeCompiled.js') // exercise: merge maps of `coffeeCompiled` and `doubleLineTransformed` const mergedMap = merge(coffeeCompiledMap, doubleLineTransformed.map.toJSON()) // logging... // console.log('# 1') // new SourceMapConsumer(coffeeCompiledMap).eachMapping(m => console.log(JSON.stringify(m))) // console.log('# 2') // new SourceMapConsumer(doubleLineTransformed.map.toJSON()).eachMapping(m => console.log(JSON.stringify(m))) // console.log('# 3') // new SourceMapConsumer(mergedMap).eachMapping(m => console.log(JSON.stringify(m))) // verify t.equal(doubleLineTransformed.code, fs.readFileSync(resolve(__dirname, './fixtures/coffee-script/actual.js'), 'utf-8')) const con = new SourceMapConsumer(mergedMap) for (var i = 0; i < 2; i++) { const offset = i * 17 t.deepEqual( con.originalPositionFor({ line: 2 + offset, column: 8 }), { column: 0, line: 1, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `var *a* = b`' ) t.deepEqual( con.originalPositionFor({ line: 2 + offset, column: 11 }), { column: 0, line: 1, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `var *a* = b`' ) t.deepEqual( con.originalPositionFor({ line: 3 + offset, column: 4 }), { column: 0, line: 1, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `var *a* = b`' ) t.deepEqual( con.originalPositionFor({ line: 4 + offset, column: 4 }), { column: 0, line: 1, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `var *a* = b`' ) t.deepEqual( con.originalPositionFor({ line: 5 + offset, column: 4 }), { column: 0, line: 2, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*b* = function (arg1, arg2)`' ) t.deepEqual( con.originalPositionFor({ line: 5 + offset, column: 18 }), { column: 5, line: 2, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `b = function (*arg1*, arg2)`' ) t.deepEqual( con.originalPositionFor({ line: 6 + offset, column: 8 }), { column: 2, line: 3, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) t.deepEqual( con.originalPositionFor({ line: 6 + offset, column: 20 }), { column: 14, line: 3, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) t.deepEqual( con.originalPositionFor({ line: 7 + offset, column: 8 }), { column: 2, line: 3, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) t.deepEqual( con.originalPositionFor({ line: 7 + offset, column: 20 }), { column: 14, line: 3, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) t.deepEqual( con.originalPositionFor({ line: 8 + offset, column: 8 }), { column: 2, line: 5, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) t.deepEqual( con.originalPositionFor({ line: 8 + offset, column: 20 }), { column: 14, line: 5, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) t.deepEqual( con.originalPositionFor({ line: 9 + offset, column: 8 }), { column: 2, line: 5, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) t.deepEqual( con.originalPositionFor({ line: 9 + offset, column: 20 }), { column: 14, line: 5, name: null, source: '../../../test/fixtures/coffee-script/expected.coffee' }, 'pos of `*console*.log(arg1)`' ) } t.end() }) test('multi transform with es2015-arrow and es2015-spread on babel', function(t) { // source.js -> resultOfArrow.js const resultOfArrow = babel.transform(fs.readFileSync(resolve(__dirname, './fixtures/es2015/expected.js')), { filename: 'source.js', plugins: ['transform-es2015-arrow-functions'], sourceMaps: true, }) // logging... // console.log('# arrow') // const arrowMapConsumer = new SourceMapConsumer(resultOfArrow.map) // arrowMapConsumer.eachMapping(m => console.log(JSON.stringify(m))) // console.log(resultOfArrow.code) // resultOfArrow.js -> resultOfAdditionalSpread.js const resultOfAdditionalSpread = babel.transform(resultOfArrow.code, { filename: 'resultOfArrow.js', plugins: ['transform-es2015-spread'], sourceMaps: true }) // logging... // console.log('# additionalSpread') // const additionalSpreadMapConsumer = new SourceMapConsumer(resultOfAdditionalSpread.map) // additionalSpreadMapConsumer.eachMapping(m => console.log(JSON.stringify(m))) // console.log(resultOfAdditionalSpread.code) // exercise: merge maps of `resultOfArrow` and `resultOfAdditionalSpread const mergedMap = merge(resultOfArrow.map, resultOfAdditionalSpread.map) const mergedMapConsumer = new SourceMapConsumer(mergedMap) // logging... // console.log('# merged') // mergedMapConsumer.eachMapping(m => console.log(JSON.stringify(m))) // actual map with babel in same time transform const resultOfArrowAndSpreadAtSameTime = babel.transform(fs.readFileSync(resolve(__dirname, './fixtures/es2015/expected.js')), { filename: 'source.js', plugins: ['transform-es2015-arrow-functions', 'transform-es2015-spread'], sourceMaps: true }) const sameTimeMapConsumer = new SourceMapConsumer(resultOfArrowAndSpreadAtSameTime.map) // logging... // console.log('# actual with babel') // sameTimeMapConsumer.eachMapping(m => console.log(JSON.stringify(m))) // console.log(resultOfArrowAndSpreadAtSameTime.code) // verify const actualCode = fs.readFileSync(resolve(__dirname, './fixtures/es2015/actual.js'), 'utf-8') t.equal(resultOfAdditionalSpread.code, actualCode) t.equal(resultOfArrowAndSpreadAtSameTime.code, actualCode) // mappings by merge-soource-source-map, filtered by having `name` property const mergedMappings = [] mergedMapConsumer.eachMapping(function(m) { m.name && mergedMappings.push(m) }) // mappings by babel, filtered by having `name` property const sameTimeMappings = [] sameTimeMapConsumer.eachMapping(function(m) { m.name && sameTimeMappings.push(m) }) t.deepEqual(mergedMappings, sameTimeMappings) t.end() }) test('handle original position of code that does not have an origin', function(t) { const origCode = 'a = b' // transform to insert empty statement const transformed1 = insertEmptyStatementTransform(origCode, 'source.js') t.equal(transformed1.code, 'a = b;\n;') // transform to insert empty statement (x2) const transformed2 = insertEmptyStatementTransform(transformed1.code, 'transformed1.js') t.equal(transformed2.code, 'a = b;\n;\n;') // verify const mergedMap = merge(transformed1.map.toJSON(), transformed2.map.toJSON()) const con = new SourceMapConsumer(mergedMap) var origPos // pos for variable `a` origPos = con.originalPositionFor({line: 1, column: 0}) t.deepEqual(origPos, {line: 1, column: 0, name: 'a', source: 'source.js'}) // pos for variable `b` origPos = con.originalPositionFor({line: 1, column: 4}) t.deepEqual(origPos, {line: 1, column: 4, name: 'b', source: 'source.js'}) t.end() }) test('handle original position of code that does not have an origin (with compact format)', function(t) { const origCode = 'a = b' // transform to insert empty statement const transformed1 = insertEmptyStatementTransform(origCode, 'source.js', true) t.equal(transformed1.code, 'a=b;;') // transform to insert empty statement (x2) const transformed2 = insertEmptyStatementTransform(transformed1.code, 'transformed1.js', true) t.equal(transformed2.code, 'a=b;;;') const mergedMap = merge(transformed1.map.toJSON(), transformed2.map.toJSON()) const con = new SourceMapConsumer(mergedMap) var origPos // pos for variable `a` origPos = con.originalPositionFor({line: 1, column: 0}) t.deepEqual(origPos, {line: 1, column: 0, name: 'a', source: 'source.js'}) // pos for variable `b` origPos = con.originalPositionFor({line: 1, column: 2}) t.deepEqual(origPos, {line: 1, column: 4, name: 'b', source: 'source.js'}) t.end() }) merge-source-map-1.1.0/test/transforms/000077500000000000000000000000001322004357200200345ustar00rootroot00000000000000merge-source-map-1.1.0/test/transforms/tr-double-line.js000066400000000000000000000010771322004357200232210ustar00rootroot00000000000000const esprima = require('esprima') const estraverse = require('estraverse') const escodegen = require('escodegen') module.exports = function(code, filepath) { const ast = esprima.parse(code, {sourceType: 'module', loc: true}) estraverse.replace(ast, { enter: function(node, parent) { if (node.type === 'ExpressionStatement') { parent.body.splice(parent.body.indexOf(node), 0, node) } }, leave: function() {} }) return escodegen.generate(ast, { sourceMap: filepath, sourceMapWithCode: true, sourceContent: code }) } merge-source-map-1.1.0/test/transforms/tr-insert-empty-statement.js000066400000000000000000000012441322004357200254600ustar00rootroot00000000000000const esprima = require('esprima') const estraverse = require('estraverse') const escodegen = require('escodegen') module.exports = function insertEmptyStatementTransform(code, filepath, compact) { const emptyStatement = esprima.parse(';').body[0] const ast = esprima.parse(code, {sourceType: 'module', loc: true}) estraverse.replace(ast, { enter: function(node, parent) { if (node.type === 'ExpressionStatement') { parent.body.push(emptyStatement) } }, leave: function() {} }) return escodegen.generate(ast, { sourceMap: filepath, sourceMapWithCode: true, sourceContent: code, format: {compact: compact} }) }