Skip to content
This repository has been archived by the owner on Jan 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #41 from bugsnag/transform-relative-paths
Browse files Browse the repository at this point in the history
feat: Transform relative "sources" paths in source map
  • Loading branch information
bengourley authored May 22, 2019
2 parents aca2088 + 48c143f commit da781d3
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 6 deletions.
19 changes: 13 additions & 6 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,23 @@ function transformSourcesMap (options) {
return (
readFileJSON(options.sourceMap)
.then(sourceMap => (
mapSources(sourceMap, path => {
const relativePath = stripProjectRoot(options.projectRoot, path)
return doesFileExist(path).then(exists => {
mapSources(sourceMap, p => {
// resolve a relative path in the sources array if it begins with a ".." e.g. "../../src/index.js"
const resolvedPath = /^\.\./.test(p)
? path.resolve(path.dirname(options.sourceMap), p)
: p

// then make it relative to the project root
const relativePath = stripProjectRoot(options.projectRoot, resolvedPath)

return doesFileExist(p).then(exists => {
if (exists && options.uploadSources) {
if (path.indexOf('node_modules') !== -1) {
if (p.indexOf('node_modules') !== -1) {
if (options.uploadNodeModules) {
options.sources[relativePath] = path
options.sources[relativePath] = p
}
} else {
options.sources[relativePath] = path
options.sources[relativePath] = p
}
}
return relativePath
Expand Down
13 changes: 13 additions & 0 deletions test/fixtures/multi-relative/lib/app.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixtures/multi-relative/lib/app.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions test/fixtures/multi-relative/lib/services/bugsnag.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixtures/multi-relative/lib/services/bugsnag.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions test/fixtures/multi-relative/lib/services/logger.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixtures/multi-relative/lib/services/logger.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions test/fixtures/multi-relative/lib/services/widget.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixtures/multi-relative/lib/services/widget.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions test/fixtures/multi-relative/src/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const logger = require('./services/logger')
const Widget = require('./services/widget')
const bugsnagClient = require('./services/bugsnag')

logger.debug('app is booting')

const widget = new Widget()
logger.debug('Created a widget', widget.getCreated())
widget.update()
logger.debug('Updated a widget', widget.getUpdated())
bugsnagClient.notify(new Error('errororor'))
6 changes: 6 additions & 0 deletions test/fixtures/multi-relative/src/services/bugsnag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const bugsnag = require('@bugsnag/js')
const bugsnagClient = bugsnag({
apiKey: 'YOUR_API_KEY',
appVersion: require('../../package.json').version
})
module.exports = bugsnagClient
15 changes: 15 additions & 0 deletions test/fixtures/multi-relative/src/services/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
exports.debug = function () {
console.debug(new Date(), arguments)
}

exports.info = function () {
console.info(new Date(), arguments)
}

exports.warn = function () {
console.warn(new Date(), arguments)
}

exports.error = function () {
console.error(new Date(), arguments)
}
24 changes: 24 additions & 0 deletions test/fixtures/multi-relative/src/services/widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class Widget {
constructor () {
this.created = new Date()
this.updated = new Date()
}

getCreated () {
return this.created
}

getUpdated () {
return this.updated
}

isWidget () {
return true
}

update () {
this.updated = new Date()
}
}

module.exports = Widget
73 changes: 73 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const path = require('path')
const concat = require('concat-stream')

afterEach(() => jest.resetModules())

Expand Down Expand Up @@ -74,3 +75,75 @@ test('multiple uploads', () => {
])
})
})

test('multiple uploads (resolving relative source paths inside map)', () => {
let mockCalled = 0
let mockCalledWith = []
const mockConcat = concat
jest.mock('../lib/request', () => {
return (endpoint, makePayload, onSuccess, onError) => {
mockCalled++
const payload = makePayload()
payload.sourceMap.pipe(mockConcat(data => {
payload.sourceMapData = JSON.parse(data)
mockCalledWith.push(payload)
onSuccess()
}))
}
})

const upload = require('../').upload
return upload({
apiKey: 'API_KEY',
projectRoot: `${__dirname}/fixtures/multi-relative`,
directory: true
}).then(() => {
expect(mockCalled).toBe(4)

const uploads = mockCalledWith.reduce((accum, payload) => {
return accum.concat({
minifiedUrl: payload.minifiedUrl,
minifiedFile: payload.minifiedFile.path,
sourceMap: path.basename(payload.sourceMap.path),
sourceMapData: payload.sourceMapData
})
}, []).sort((a, b) => a.minifiedUrl > b.minifiedUrl)

const orderedSourceMapContent = uploads.map(u => {
const data = u.sourceMapData
// bad mutating this array in an iterator but needs must
delete u.sourceMapData
return data
})

expect(uploads).toEqual([
{
minifiedUrl: 'lib/app.js',
minifiedFile: `${__dirname}/fixtures/multi-relative/lib/app.js`,
sourceMap: 'app.js.map'
},
{
minifiedUrl: 'lib/services/bugsnag.js',
minifiedFile: `${__dirname}/fixtures/multi-relative/lib/services/bugsnag.js`,
sourceMap: 'bugsnag.js.map'
},
{
minifiedUrl: 'lib/services/logger.js',
minifiedFile: `${__dirname}/fixtures/multi-relative/lib/services/logger.js`,
sourceMap: 'logger.js.map'
},
{
minifiedUrl: 'lib/services/widget.js',
minifiedFile: `${__dirname}/fixtures/multi-relative/lib/services/widget.js`,
sourceMap: 'widget.js.map'
}
])

expect(orderedSourceMapContent.map(map => map.sources[0])).toEqual([
'src/app.js',
'src/services/bugsnag.js',
'src/services/logger.js',
'src/services/widget.js'
])
})
})

0 comments on commit da781d3

Please sign in to comment.