convert-source-map
Advanced tools
Comparing version 1.9.0 to 2.0.0
104
index.js
'use strict'; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
Object.defineProperty(exports, 'commentRegex', { | ||
get: function getCommentRegex () { | ||
return /^\s*\/(?:\/|\*)[@#]\s+sourceMappingURL=data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(?:.*)$/mg; | ||
// Groups: 1: media type, 2: MIME type, 3: charset, 4: encoding, 5: data. | ||
return /^\s*?\/[\/\*][@#]\s+?sourceMappingURL=data:(((?:application|text)\/json)(?:;charset=([^;,]+?)?)?)?(?:;(base64))?,(.*?)$/mg; | ||
} | ||
}); | ||
Object.defineProperty(exports, 'mapFileCommentRegex', { | ||
get: function getMapFileCommentRegex () { | ||
// Matches sourceMappingURL in either // or /* comment styles. | ||
return /(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"`]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^\*]+?)[ \t]*(?:\*\/){1}[ \t]*$)/mg; | ||
return /(?:\/\/[@#][ \t]+?sourceMappingURL=([^\s'"`]+?)[ \t]*?$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^*]+?)[ \t]*?(?:\*\/){1}[ \t]*?$)/mg; | ||
} | ||
@@ -48,16 +48,21 @@ }); | ||
function readFromFileMap(sm, dir) { | ||
// NOTE: this will only work on the server since it attempts to read the map file | ||
function readFromFileMap(sm, read) { | ||
var r = exports.mapFileCommentRegex.exec(sm); | ||
// for some odd reason //# .. captures in 1 and /* .. */ in 2 | ||
var filename = r[1] || r[2]; | ||
var filepath = path.resolve(dir, filename); | ||
try { | ||
return fs.readFileSync(filepath, 'utf8'); | ||
var sm = read(filename); | ||
if (sm != null && typeof sm.catch === 'function') { | ||
return sm.catch(throwError); | ||
} else { | ||
return sm; | ||
} | ||
} catch (e) { | ||
throw new Error('An error occurred while trying to read the map file at ' + filepath + '\n' + e); | ||
throwError(e); | ||
} | ||
function throwError(e) { | ||
throw new Error('An error occurred while trying to read the map file at ' + filename + '\n' + e.stack); | ||
} | ||
} | ||
@@ -68,7 +73,16 @@ | ||
if (opts.isFileComment) sm = readFromFileMap(sm, opts.commentFileDir); | ||
if (opts.hasComment) sm = stripComment(sm); | ||
if (opts.isEncoded) sm = decodeBase64(sm); | ||
if (opts.isJSON || opts.isEncoded) sm = JSON.parse(sm); | ||
if (opts.hasComment) { | ||
sm = stripComment(sm); | ||
} | ||
if (opts.encoding === 'base64') { | ||
sm = decodeBase64(sm); | ||
} else if (opts.encoding === 'uri') { | ||
sm = decodeURIComponent(sm); | ||
} | ||
if (opts.isJSON || opts.encoding) { | ||
sm = JSON.parse(sm); | ||
} | ||
this.sourcemap = sm; | ||
@@ -109,6 +123,18 @@ } | ||
Converter.prototype.toURI = function () { | ||
var json = this.toJSON(); | ||
return encodeURIComponent(json); | ||
}; | ||
Converter.prototype.toComment = function (options) { | ||
var base64 = this.toBase64(); | ||
var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; | ||
return options && options.multiline ? '/*# ' + data + ' */' : '//# ' + data; | ||
var encoding, content, data; | ||
if (options != null && options.encoding === 'uri') { | ||
encoding = ''; | ||
content = this.toURI(); | ||
} else { | ||
encoding = ';base64'; | ||
content = this.toBase64(); | ||
} | ||
data = 'sourceMappingURL=data:application/json;charset=utf-8' + encoding + ',' + content; | ||
return options != null && options.multiline ? '/*# ' + data + ' */' : '//# ' + data; | ||
}; | ||
@@ -143,16 +169,38 @@ | ||
exports.fromURI = function (uri) { | ||
return new Converter(uri, { encoding: 'uri' }); | ||
}; | ||
exports.fromBase64 = function (base64) { | ||
return new Converter(base64, { isEncoded: true }); | ||
return new Converter(base64, { encoding: 'base64' }); | ||
}; | ||
exports.fromComment = function (comment) { | ||
var m, encoding; | ||
comment = comment | ||
.replace(/^\/\*/g, '//') | ||
.replace(/\*\/$/g, ''); | ||
return new Converter(comment, { isEncoded: true, hasComment: true }); | ||
m = exports.commentRegex.exec(comment); | ||
encoding = m && m[4] || 'uri'; | ||
return new Converter(comment, { encoding: encoding, hasComment: true }); | ||
}; | ||
exports.fromMapFileComment = function (comment, dir) { | ||
return new Converter(comment, { commentFileDir: dir, isFileComment: true, isJSON: true }); | ||
function makeConverter(sm) { | ||
return new Converter(sm, { isJSON: true }); | ||
} | ||
exports.fromMapFileComment = function (comment, read) { | ||
if (typeof read === 'string') { | ||
throw new Error( | ||
'String directory paths are no longer supported with `fromMapFileComment`\n' + | ||
'Please review the Upgrading documentation at https://github.com/thlorenz/convert-source-map#upgrading' | ||
) | ||
} | ||
var sm = readFromFileMap(comment, read); | ||
if (sm != null && typeof sm.then === 'function') { | ||
return sm.then(makeConverter); | ||
} else { | ||
return makeConverter(sm); | ||
} | ||
}; | ||
@@ -167,5 +215,11 @@ | ||
// Finds last sourcemap comment in file or returns null if none was found | ||
exports.fromMapFileSource = function (content, dir) { | ||
exports.fromMapFileSource = function (content, read) { | ||
if (typeof read === 'string') { | ||
throw new Error( | ||
'String directory paths are no longer supported with `fromMapFileSource`\n' + | ||
'Please review the Upgrading documentation at https://github.com/thlorenz/convert-source-map#upgrading' | ||
) | ||
} | ||
var m = content.match(exports.mapFileCommentRegex); | ||
return m ? exports.fromMapFileComment(m.pop(), dir) : null; | ||
return m ? exports.fromMapFileComment(m.pop(), read) : null; | ||
}; | ||
@@ -172,0 +226,0 @@ |
{ | ||
"name": "convert-source-map", | ||
"version": "1.9.0", | ||
"version": "2.0.0", | ||
"description": "Converts a source-map from/to different formats and allows adding/changing properties.", | ||
@@ -33,10 +33,7 @@ "main": "index.js", | ||
"engine": { | ||
"node": ">=0.6" | ||
"node": ">=4" | ||
}, | ||
"files": [ | ||
"index.js" | ||
], | ||
"browser": { | ||
"fs": false | ||
} | ||
] | ||
} |
103
README.md
@@ -26,2 +26,19 @@ # convert-source-map [![Build Status][ci-image]][ci-url] | ||
## Upgrading | ||
Prior to v2.0.0, the `fromMapFileComment` and `fromMapFileSource` functions took a String directory path and used that to resolve & read the source map file from the filesystem. However, this made the library limited to nodejs environments and broke on sources with querystrings. | ||
In v2.0.0, you now need to pass a function that does the file reading. It will receive the source filename as a String that you can resolve to a filesystem path, URL, or anything else. | ||
If you are using `convert-source-map` in nodejs and want the previous behavior, you'll use a function like such: | ||
```diff | ||
+ var fs = require('fs'); // Import the fs module to read a file | ||
+ var path = require('path'); // Import the path module to resolve a path against your directory | ||
- var conv = convert.fromMapFileSource(css, '../my-dir'); | ||
+ var conv = convert.fromMapFileSource(css, function (filename) { | ||
+ return fs.readFileSync(path.resolve('../my-dir', filename), 'utf-8'); | ||
+ }); | ||
``` | ||
## API | ||
@@ -37,2 +54,6 @@ | ||
### fromURI(uri) | ||
Returns source map converter from given uri encoded json string. | ||
### fromBase64(base64) | ||
@@ -44,23 +65,77 @@ | ||
Returns source map converter from given base64 encoded json string prefixed with `//# sourceMappingURL=...`. | ||
Returns source map converter from given base64 or uri encoded json string prefixed with `//# sourceMappingURL=...`. | ||
### fromMapFileComment(comment, mapFileDir) | ||
### fromMapFileComment(comment, readMap) | ||
Returns source map converter from given `filename` by parsing `//# sourceMappingURL=filename`. | ||
`filename` must point to a file that is found inside the `mapFileDir`. Most tools store this file right next to the | ||
generated file, i.e. the one containing the source map. | ||
`readMap` must be a function which receives the source map filename and returns either a String or Buffer of the source map (if read synchronously), or a `Promise` containing a String or Buffer of the source map (if read asynchronously). | ||
If `readMap` doesn't return a `Promise`, `fromMapFileComment` will return a source map converter synchronously. | ||
If `readMap` returns a `Promise`, `fromMapFileComment` will also return `Promise`. The `Promise` will be either resolved with the source map converter or rejected with an error. | ||
#### Examples | ||
**Synchronous read in Node.js:** | ||
```js | ||
var convert = require('convert-source-map'); | ||
var fs = require('fs'); | ||
function readMap(filename) { | ||
return fs.readFileSync(filename, 'utf8'); | ||
} | ||
var json = convert | ||
.fromMapFileComment('//# sourceMappingURL=map-file-comment.css.map', readMap) | ||
.toJSON(); | ||
console.log(json); | ||
``` | ||
**Asynchronous read in Node.js:** | ||
```js | ||
var convert = require('convert-source-map'); | ||
var { promises: fs } = require('fs'); // Notice the `promises` import | ||
function readMap(filename) { | ||
return fs.readFile(filename, 'utf8'); | ||
} | ||
var converter = await convert.fromMapFileComment('//# sourceMappingURL=map-file-comment.css.map', readMap) | ||
var json = converter.toJSON(); | ||
console.log(json); | ||
``` | ||
**Asynchronous read in the browser:** | ||
```js | ||
var convert = require('convert-source-map'); | ||
async function readMap(url) { | ||
const res = await fetch(url); | ||
return res.text(); | ||
} | ||
const converter = await convert.fromMapFileComment('//# sourceMappingURL=map-file-comment.css.map', readMap) | ||
var json = converter.toJSON(); | ||
console.log(json); | ||
``` | ||
### fromSource(source) | ||
Finds last sourcemap comment in file and returns source map converter or returns null if no source map comment was found. | ||
Finds last sourcemap comment in file and returns source map converter or returns `null` if no source map comment was found. | ||
### fromMapFileSource(source, mapFileDir) | ||
### fromMapFileSource(source, readMap) | ||
Finds last sourcemap comment in file and returns source map converter or returns null if no source map comment was | ||
found. | ||
Finds last sourcemap comment in file and returns source map converter or returns `null` if no source map comment was found. | ||
The sourcemap will be read from the map file found by parsing `# sourceMappingURL=file` comment. For more info see | ||
fromMapFileComment. | ||
`readMap` must be a function which receives the source map filename and returns either a String or Buffer of the source map (if read synchronously), or a `Promise` containing a String or Buffer of the source map (if read asynchronously). | ||
If `readMap` doesn't return a `Promise`, `fromMapFileSource` will return a source map converter synchronously. | ||
If `readMap` returns a `Promise`, `fromMapFileSource` will also return `Promise`. The `Promise` will be either resolved with the source map converter or rejected with an error. | ||
### toObject() | ||
@@ -76,2 +151,6 @@ | ||
### toURI() | ||
Converts source map to uri encoded json string. | ||
### toBase64() | ||
@@ -88,2 +167,4 @@ | ||
When `options.encoding == 'uri'`, the data will be uri encoded, otherwise they will be base64 encoded. | ||
When `options.multiline == true`, the comment is formatted like: `/*# sourceMappingURL=... */`, which you would find in a CSS source file. | ||
@@ -115,2 +196,4 @@ | ||
Breaks down a source map comment into groups: Groups: 1: media type, 2: MIME type, 3: charset, 4: encoding, 5: data. | ||
### mapFileCommentRegex | ||
@@ -117,0 +200,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
15854
193
207
0
1