* only try to pretty print `err.source` if it exists
* fix small typo
* drop unnecessary path resolving
* add `from` and `to` to `run` test helper
* enable all source map tests
* ensure source maps are generated properly
* update annotation values in tests
* handle `map: true`
* add test for `map: { inline: true }`
* force Lightning CSS to handle an inline source map
* base64 encode the test name
This will get rid of special characters that can cause issues /
confusion when debugging tests.
* ensure utilities and components with variants are pointing to the correct source
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* update changelog
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
88 lines
2.5 KiB
JavaScript
88 lines
2.5 KiB
JavaScript
import { SourceMapConsumer } from 'source-map-js'
|
|
|
|
/**
|
|
* Parse the source maps from a PostCSS result
|
|
*
|
|
* @param {import('postcss').Result} result
|
|
*/
|
|
export function parseSourceMaps(result) {
|
|
let map = result.map
|
|
? result.map.toJSON()
|
|
: (() => {
|
|
let css = result.toString()
|
|
let sourceMappingURL = css.match(/\/\*# sourceMappingURL=(.*) \*\//)?.[1]
|
|
let raw = sourceMappingURL
|
|
? Buffer.from(sourceMappingURL.split(',')[1], 'base64').toString()
|
|
: null
|
|
return JSON.parse(raw ?? '{}')
|
|
})()
|
|
|
|
return {
|
|
sources: map.sources,
|
|
annotations: annotatedMappings(map),
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A string annotation that represents a source map
|
|
*
|
|
* It's not meant to be exhaustive just enough to
|
|
* verify that the source map is working and that
|
|
* lines are mapped back to the original source
|
|
*
|
|
* Including when using @apply with multiple classes
|
|
*
|
|
* @param {import('source-map-js').RawSourceMap} map
|
|
*/
|
|
function annotatedMappings(map) {
|
|
const smc = new SourceMapConsumer(map)
|
|
const annotations = {}
|
|
|
|
smc.eachMapping((mapping) => {
|
|
let annotation = (annotations[mapping.generatedLine] = annotations[mapping.generatedLine] || {
|
|
...mapping,
|
|
|
|
original: {
|
|
start: [mapping.originalLine, mapping.originalColumn],
|
|
end: [mapping.originalLine, mapping.originalColumn],
|
|
},
|
|
|
|
generated: {
|
|
start: [mapping.generatedLine, mapping.generatedColumn],
|
|
end: [mapping.generatedLine, mapping.generatedColumn],
|
|
},
|
|
})
|
|
|
|
annotation.generated.end[0] = mapping.generatedLine
|
|
annotation.generated.end[1] = mapping.generatedColumn
|
|
|
|
annotation.original.end[0] = mapping.originalLine
|
|
annotation.original.end[1] = mapping.originalColumn
|
|
})
|
|
|
|
return Object.values(annotations).map((annotation) => {
|
|
return `${formatRange(annotation.original)} -> ${formatRange(annotation.generated)}`
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @param {object} range
|
|
* @param {[number, number]} range.start
|
|
* @param {[number, number]} range.end
|
|
*/
|
|
function formatRange(range) {
|
|
if (range.start[0] === range.end[0]) {
|
|
// This range is on the same line
|
|
// and the columns are the same
|
|
if (range.start[1] === range.end[1]) {
|
|
return `${range.start[0]}:${range.start[1]}`
|
|
}
|
|
|
|
// This range is on the same line
|
|
// but the columns are different
|
|
return `${range.start[0]}:${range.start[1]}-${range.end[1]}`
|
|
}
|
|
|
|
// This range spans multiple lines
|
|
return `${range.start[0]}:${range.start[1]}-${range.end[0]}:${range.end[1]}`
|
|
}
|