Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

View File

@ -0,0 +1,30 @@
{
"name": "source-map-resolve",
"version": "0.3.1",
"author": "Simon Lydell",
"license": "MIT",
"description": "Resolve the source map and/or sources for a generated file.",
"keywords": [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
"authors": [
"Simon Lydell"
],
"ignore": [
".*"
],
"dependencies": {
"source-map-url": "~0.3.0",
"resolve-url": "~0.2.1"
}
}

View File

@ -0,0 +1,60 @@
### Version 0.3.1 (2014-08-16) ###
- Improved: Updated the source-map-url dependency to 0.3.0.
### Version 0.3.0 (2014-07-02) ###
- Removed: Argument checking. Its not worth it. (Possibly
backwards-incompatible change.)
- Added: The `sourceRoot` property of source maps may now be ignored, which can
be useful when resolving sources outside of the browser.
- Added: It is now possible to resolve only the URLs of sources, without
reading them.
### Version 0.2.0 (2014-06-22) ###
- Changed: The result of `resolveSources` is now an object, not an array. The
old result array is available in the `sourcesContent` property.
(Backwards-incompatible change.)
- Changed: `sources` has been renamed to `sourcesContent` in the result object
of `resolve`. (Backwards-incompatible change.)
- Added: `resolveSources` now also returns all sources fully resolved, in the
`sourcesResolved` property.
- Added: The result object of `resolve` now contains the `sourcesResolved`
property from `resolveSources`.
### Version 0.1.4 (2014-06-16) ###
- Fixed: `sourcesContent` was mis-typed as `sourceContents`, which meant that
the `sourcesContent` property of source maps never was used when resolving
sources.
### Version 0.1.3 (2014-05-06) ###
- Only documentation and meta-data changes.
### Version 0.1.2 (2014-03-23) ###
- Improved: Source maps starting with `)]}'` are now parsed correctly. The spec
allows source maps to start with that character sequence to prevent XSSI
attacks.
### Version 0.1.1 (2014-03-06) ###
- Improved: Make sourceRoot resolving more sensible.
A source root such as `/scripts/subdir` is now treated as `/scripts/subdir/`
— that is, as a directory called “subdir”, not a file called “subdir”.
Pointing to a file as source root does not makes sense.
### Version 0.1.0 (2014-03-03) ###
- Initial release.

View File

@ -0,0 +1,29 @@
{
"name": "source-map-resolve",
"version": "0.3.1",
"author": "Simon Lydell",
"license": "MIT",
"description": "Resolve the source map and/or sources for a generated file.",
"keywords": [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
"repo": "lydell/source-map-resolve",
"main": "source-map-resolve.js",
"scripts": [
"source-map-resolve.js"
],
"dependencies": {
"lydell/source-map-url": "~0.3.0",
"lydell/resolve-url": "~0.2.1"
}
}

View File

@ -0,0 +1,25 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var fs = require("fs")
var template = fs.readFileSync("source-map-resolve.js.template").toString()
var nodeCode = fs.readFileSync("lib/source-map-resolve-node.js").toString()
nodeCode = nodeCode
// Remove leading comments and `require`s.
.replace(/^\s*(?:\/\/.+\s+|var\s+\w+\s*=\s*require\([^)]+\).*\s+)*/, "")
// Remove `urix`.
.replace(/(\w+)\s*=\s*urix\(\1\)\s*/g, "")
// Change `module.exports = {...}` to `return {...}`.
.replace(/module\.exports = (\{[^}]+\})\s*$/, "return $1")
// Indent.
.replace(/^(?!$)/gm, " ")
var code = template.replace(/[ \t]*\{\{source-map-resolve-node.js\}\}/, nodeCode)
fs.writeFileSync("source-map-resolve.js", code)

View File

@ -0,0 +1,12 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var url = require("url")
function resolveUrl(/* ...urls */) {
return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) {
return url.resolve(resolved, nextUrl)
})
}
module.exports = resolveUrl

View File

@ -0,0 +1,215 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var sourceMappingURL = require("source-map-url")
var resolveUrl = require("./resolve-url")
var urix = require("urix")
var atob = require("atob")
function callbackAsync(callback, error, result) {
setImmediate(function() { callback(error, result) })
}
function parseMapToJSON(string) {
return JSON.parse(string.replace(/^\)\]\}'/, ""))
}
function resolveSourceMap(code, codeUrl, read, callback) {
var mapData
try {
mapData = resolveSourceMapHelper(code, codeUrl)
} catch (error) {
return callbackAsync(callback, error)
}
if (!mapData || mapData.map) {
return callbackAsync(callback, null, mapData)
}
read(mapData.url, function(error, result) {
if (error) {
return callback(error)
}
try {
mapData.map = parseMapToJSON(String(result))
} catch (error) {
return callback(error)
}
callback(null, mapData)
})
}
function resolveSourceMapSync(code, codeUrl, read) {
var mapData = resolveSourceMapHelper(code, codeUrl)
if (!mapData || mapData.map) {
return mapData
}
mapData.map = parseMapToJSON(String(read(mapData.url)))
return mapData
}
var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/
var jsonMimeTypeRegex = /^(?:application|text)\/json$/
function resolveSourceMapHelper(code, codeUrl) {
codeUrl = urix(codeUrl)
var url = sourceMappingURL.getFrom(code)
if (!url) {
return null
}
var dataUri = url.match(dataUriRegex)
if (dataUri) {
var mimeType = dataUri[1]
var lastParameter = dataUri[2]
var encoded = dataUri[3]
if (!jsonMimeTypeRegex.test(mimeType)) {
throw new Error("Unuseful data uri mime type: " + (mimeType || "text/plain"))
}
return {
sourceMappingURL: url,
url: null,
sourcesRelativeTo: codeUrl,
map: parseMapToJSON(lastParameter === ";base64" ? atob(encoded) : decodeURIComponent(encoded))
}
}
var mapUrl = resolveUrl(codeUrl, url)
return {
sourceMappingURL: url,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
}
function resolveSources(map, mapUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
var pending = map.sources.length
var errored = false
var result = {
sourcesResolved: [],
sourcesContent: []
}
var done = function(error) {
if (errored) {
return
}
if (error) {
errored = true
return callback(error)
}
pending--
if (pending === 0) {
callback(null, result)
}
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
callbackAsync(done, null)
} else {
read(fullUrl, function(error, source) {
result.sourcesContent[index] = String(source)
done(error)
})
}
})
}
function resolveSourcesSync(map, mapUrl, read, options) {
var result = {
sourcesResolved: [],
sourcesContent: []
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (read !== null) {
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
} else {
result.sourcesContent[index] = String(read(fullUrl))
}
}
})
return result
}
var endingSlash = /\/?$/
function resolveSourcesHelper(map, mapUrl, options, fn) {
options = options || {}
mapUrl = urix(mapUrl)
var fullUrl
var sourceContent
for (var index = 0, len = map.sources.length; index < len; index++) {
if (map.sourceRoot && !options.ignoreSourceRoot) {
// Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes
// `/scripts/subdir/<source>`, not `/scripts/<source>`. Pointing to a file as source root
// does not make sense.
fullUrl = resolveUrl(mapUrl, map.sourceRoot.replace(endingSlash, "/"), map.sources[index])
} else {
fullUrl = resolveUrl(mapUrl, map.sources[index])
}
sourceContent = (map.sourcesContent || [])[index]
fn(fullUrl, sourceContent, index)
}
}
function resolve(code, codeUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
resolveSourceMap(code, codeUrl, read, function(error, mapData) {
if (error) {
return callback(error)
}
if (!mapData) {
return callback(null, null)
}
resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) {
if (error) {
return callback(error)
}
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
callback(null, mapData)
})
})
}
function resolveSync(code, codeUrl, read, options) {
var mapData = resolveSourceMapSync(code, codeUrl, read)
if (!mapData) {
return null
}
var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options)
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
return mapData
}
module.exports = {
resolveSourceMap: resolveSourceMap,
resolveSourceMapSync: resolveSourceMapSync,
resolveSources: resolveSources,
resolveSourcesSync: resolveSourcesSync,
resolve: resolve,
resolveSync: resolveSync
}

View File

@ -0,0 +1,89 @@
{
"_from": "source-map-resolve@^0.3.0",
"_id": "source-map-resolve@0.3.1",
"_inBundle": false,
"_integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=",
"_location": "/source-map-resolve",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "source-map-resolve@^0.3.0",
"name": "source-map-resolve",
"escapedName": "source-map-resolve",
"rawSpec": "^0.3.0",
"saveSpec": null,
"fetchSpec": "^0.3.0"
},
"_requiredBy": [
"/css"
],
"_resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz",
"_shasum": "610f6122a445b8dd51535a2a71b783dfc1248761",
"_spec": "source-map-resolve@^0.3.0",
"_where": "/home/manfred/enviPath/ketcher2/ketcher/node_modules/css",
"author": {
"name": "Simon Lydell"
},
"browser": "source-map-resolve.js",
"bugs": {
"url": "https://github.com/lydell/source-map-resolve/issues"
},
"bundleDependencies": false,
"dependencies": {
"atob": "~1.1.0",
"resolve-url": "~0.2.1",
"source-map-url": "~0.3.0",
"urix": "~0.1.0"
},
"deprecated": false,
"description": "Resolve the source map and/or sources for a generated file.",
"devDependencies": {
"Base64": "~0.2.0",
"jshint": "~2.4.3",
"setimmediate": "~1.0.1",
"simple-asyncify": "~0.1.0",
"tape": "~2.5.0"
},
"homepage": "https://github.com/lydell/source-map-resolve#readme",
"keywords": [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
"license": "MIT",
"main": "lib/source-map-resolve-node.js",
"name": "source-map-resolve",
"repository": {
"type": "git",
"url": "git+https://github.com/lydell/source-map-resolve.git"
},
"scripts": {
"build": "node generate-source-map-resolve.js",
"lint": "jshint lib/ test/",
"test": "npm run lint && npm run unit",
"unit": "node test/source-map-resolve.js && node test/windows.js"
},
"testling": {
"files": "test/source-map-resolve.js",
"browsers": [
"ie/8..latest",
"chrome/latest",
"firefox/latest",
"opera/12",
"opera/latest",
"safari/5",
"iphone/6",
"android-browser/4"
]
},
"version": "0.3.1"
}

View File

@ -0,0 +1,208 @@
Overview [![Build Status](https://travis-ci.org/lydell/source-map-resolve.png?branch=master)](https://travis-ci.org/lydell/source-map-resolve)
========
[![browser support](https://ci.testling.com/lydell/source-map-resolve.png)](https://ci.testling.com/lydell/source-map-resolve)
Resolve the source map and/or sources for a generated file.
```js
var sourceMapResolve = require("source-map-resolve")
var sourceMap = require("source-map")
var code = [
"!function(){...}();",
"/*# sourceMappingURL=foo.js.map */"
].join("\n")
sourceMapResolve.resolveSourceMap(code, "/js/foo.js", fs.readFile, function(error, result) {
if (error) {
return notifyFailure(error)
}
result
// {
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
// url: "/js/foo.js.map",
// sourcesRelativeTo: "/js/foo.js.map",
// sourceMappingURL: "foo.js.map"
// }
sourceMapResolve.resolveSources(result.map, result.sourcesRelativeTo, fs.readFile, function(error, result) {
if (error) {
return notifyFailure(error)
}
result
// {
// sourcesResolved: ["/coffee/foo.coffee"],
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
// }
})
})
sourceMapResolve.resolve(code, "/js/foo.js", fs.readFile, function(error, result) {
if (error) {
return notifyFailure(error)
}
result
// {
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
// url: "/js/foo.js.map",
// sourcesRelativeTo: "/js/foo.js.map",
// sourceMappingURL: "foo.js.map",
// sourcesResolved: ["/coffee/foo.coffee"],
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
// }
result.map.sourcesContent = result.sourcesContent
var map = new sourceMap.sourceMapConsumer(result.map)
map.sourceContentFor("/coffee/foo.coffee")
// "<contents of /coffee/foo.coffee>"
})
```
Installation
============
- `npm install source-map-resolve`
- `bower install source-map-resolve`
- `component install lydell/source-map-resolve`
Works with CommonJS, AMD and browser globals, through UMD.
Note: This module requires `setImmediate` and `atob`.
Use polyfills if needed, such as:
- <https://github.com/NobleJS/setImmediate>
- <https://github.com/davidchambers/Base64.js>
Usage
=====
### `sourceMapResolve.resolveSourceMap(code, codeUrl, read, callback)` ###
- `code` is a string of code that may or may not contain a sourceMappingURL
comment. Such a comment is used to resolve the source map.
- `codeUrl` is the url to the file containing `code`. If the sourceMappingURL
is relative, it is resolved against `codeUrl`.
- `read(url, callback)` is a function that reads `url` and responds using
`callback(error, content)`. In Node.js you might want to use `fs.readFile`,
while in the browser you might want to use an asynchronus `XMLHttpRequest`.
- `callback(error, result)` is a function that is invoked with either an error
or `null` and the result.
The result is an object with the following properties:
- `map`: The source map for `code`, as an object (not a string).
- `url`: The url to the source map. If the source map came from a data uri,
this property is `null`, since then there is no url to it.
- `sourcesRelativeTo`: The url that the sources of the source map are relative
to. Since the sources are relative to the source map, and the url to the
source map is provided as the `url` property, this property might seem
superfluos. However, remember that the `url` property can be `null` if the
source map came from a data uri. If so, the sources are relative to the file
containing the data uri—`codeUrl`. This property will be identical to the
`url` property or `codeUrl`, whichever is appropriate. This way you can
conveniently resolve the sources without having to think about where the
source map came from.
- `sourceMappingURL`: The url of the sourceMappingURL comment in `code`.
If `code` contains no sourceMappingURL, the result is `null`.
### `sourceMapResolve.resolveSources(map, mapUrl, read, [options], callback)` ###
- `map` is a source map, as an object (not a string).
- `mapUrl` is the url to the file containing `map`. Relative sources in the
source map, if any, are resolved against `mapUrl`.
- `read(url, callback)` is a function that reads `url` and responds using
`callback(error, content)`. In Node.js you might want to use `fs.readFile`,
while in the browser you might want to use an asynchronus `XMLHttpRequest`.
- `options` is an optional object with any of the following properties:
- `ignoreSourceRoot`: The `sourceRoot` property of source maps might only be
relevant when resolving sources in the browser. This lets you bypass it
when using the module outside of a browser, if needed. Defaults to `false`.
- `callback(error, result)` is a function that is invoked with either an error
or `null` and the result.
The result is an object with the following properties:
- `sourcesResolved`: The same as `map.sources`, except all the sources are
fully resolved.
- `sourcesContent`: An array with the contents of all sources in `map.sources`,
in the same order as `map.sources`.
### `sourceMapResolve.resolve(code, codeUrl, read, [options], callback)` ###
The arguments are identical to `sourceMapResolve.resolveSourceMap`, except that
you may also provide the same `options` as in
`sourceMapResolve.resolveSources`.
This is simply a convienience method that first resolves the source map and
then its sources. You could also do this by first calling
`sourceMapResolve.resolveSourceMap` and then `sourceMapResolve.resolveSources`.
The result is identical to `sourceMapResolve.resolveSourceMap`, with the
properties from `sourceMapResolve.resolveSources` merged into it.
### `sourceMapResolve.*Sync()` ###
There are also sync versions of the three previous functions. They are identical
to the async versions, except:
- They expect a sync reading function. In Node.js you might want to use
`fs.readFileSync`, while in the browser you might want to use a synchronus
`XMLHttpRequest`.
- They throw errors and return the result instead of using a callback.
`sourceMapResolve.resolveSourcesSync` also accepts `null` as the `read`
parameter. The result is the same as when passing a function as the `read
parameter`, except that the `sourcesContent` property of the result will be an
empty array. In other words, the sources arent read. You only get the
`sourcesResolved` property. (This only supported in the synchronus version, since
there is no point doing it asynchronusly.)
Note
====
This module resolves the source map for a given generated file by looking for a
sourceMappingURL comment. The spec defines yet a way to provide the URL to the
source map: By sending the `SourceMap: <url>` header along with the generated
file. Since this module doesnt retrive the generated code for you (instead
_you_ give the generated code to the module), its up to you to look for such a
header when you retrieve the file (should the need arise).
Development
===========
Tests
-----
First off, run `npm install` to install testing modules and browser polyfills.
`npm test` lints the code and runs the test suite in Node.js.
To run the tests in a browser, run `testling` (`npm install -g testling`) or
`testling -u`.
x-package.json5
---------------
package.json, component.json and bower.json are all generated from
x-package.json5 by using [`xpkg`]. Only edit x-package.json5, and remember to
run `xpkg` before commiting!
[`xpkg`]: https://github.com/kof/node-xpkg
Generating the browser version
------------------------------
source-map-resolve.js is generated from source-map-resolve-node.js and
source-map-resolve-template.js. Only edit the two latter files, _not_
source-map-resolve.js! To generate it, run `npm run build`.
License
=======
[The X11 (“MIT”) License](LICENSE).

View File

@ -0,0 +1,223 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
// Note: source-map-resolve.js is generated from source-map-resolve-node.js and
// source-map-resolve-template.js. Only edit the two latter files, _not_
// source-map-resolve.js!
void (function(root, factory) {
if (typeof define === "function" && define.amd) {
define(["source-map-url", "resolve-url"], factory)
} else if (typeof exports === "object") {
var sourceMappingURL = require("source-map-url")
var resolveUrl = require("resolve-url")
module.exports = factory(sourceMappingURL, resolveUrl)
} else {
root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
}
}(this, function(sourceMappingURL, resolveUrl) {
function callbackAsync(callback, error, result) {
setImmediate(function() { callback(error, result) })
}
function parseMapToJSON(string) {
return JSON.parse(string.replace(/^\)\]\}'/, ""))
}
function resolveSourceMap(code, codeUrl, read, callback) {
var mapData
try {
mapData = resolveSourceMapHelper(code, codeUrl)
} catch (error) {
return callbackAsync(callback, error)
}
if (!mapData || mapData.map) {
return callbackAsync(callback, null, mapData)
}
read(mapData.url, function(error, result) {
if (error) {
return callback(error)
}
try {
mapData.map = parseMapToJSON(String(result))
} catch (error) {
return callback(error)
}
callback(null, mapData)
})
}
function resolveSourceMapSync(code, codeUrl, read) {
var mapData = resolveSourceMapHelper(code, codeUrl)
if (!mapData || mapData.map) {
return mapData
}
mapData.map = parseMapToJSON(String(read(mapData.url)))
return mapData
}
var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/
var jsonMimeTypeRegex = /^(?:application|text)\/json$/
function resolveSourceMapHelper(code, codeUrl) {
var url = sourceMappingURL.getFrom(code)
if (!url) {
return null
}
var dataUri = url.match(dataUriRegex)
if (dataUri) {
var mimeType = dataUri[1]
var lastParameter = dataUri[2]
var encoded = dataUri[3]
if (!jsonMimeTypeRegex.test(mimeType)) {
throw new Error("Unuseful data uri mime type: " + (mimeType || "text/plain"))
}
return {
sourceMappingURL: url,
url: null,
sourcesRelativeTo: codeUrl,
map: parseMapToJSON(lastParameter === ";base64" ? atob(encoded) : decodeURIComponent(encoded))
}
}
var mapUrl = resolveUrl(codeUrl, url)
return {
sourceMappingURL: url,
url: mapUrl,
sourcesRelativeTo: mapUrl,
map: null
}
}
function resolveSources(map, mapUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
var pending = map.sources.length
var errored = false
var result = {
sourcesResolved: [],
sourcesContent: []
}
var done = function(error) {
if (errored) {
return
}
if (error) {
errored = true
return callback(error)
}
pending--
if (pending === 0) {
callback(null, result)
}
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
callbackAsync(done, null)
} else {
read(fullUrl, function(error, source) {
result.sourcesContent[index] = String(source)
done(error)
})
}
})
}
function resolveSourcesSync(map, mapUrl, read, options) {
var result = {
sourcesResolved: [],
sourcesContent: []
}
resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
result.sourcesResolved[index] = fullUrl
if (read !== null) {
if (typeof sourceContent === "string") {
result.sourcesContent[index] = sourceContent
} else {
result.sourcesContent[index] = String(read(fullUrl))
}
}
})
return result
}
var endingSlash = /\/?$/
function resolveSourcesHelper(map, mapUrl, options, fn) {
options = options || {}
var fullUrl
var sourceContent
for (var index = 0, len = map.sources.length; index < len; index++) {
if (map.sourceRoot && !options.ignoreSourceRoot) {
// Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes
// `/scripts/subdir/<source>`, not `/scripts/<source>`. Pointing to a file as source root
// does not make sense.
fullUrl = resolveUrl(mapUrl, map.sourceRoot.replace(endingSlash, "/"), map.sources[index])
} else {
fullUrl = resolveUrl(mapUrl, map.sources[index])
}
sourceContent = (map.sourcesContent || [])[index]
fn(fullUrl, sourceContent, index)
}
}
function resolve(code, codeUrl, read, options, callback) {
if (typeof options === "function") {
callback = options
options = {}
}
resolveSourceMap(code, codeUrl, read, function(error, mapData) {
if (error) {
return callback(error)
}
if (!mapData) {
return callback(null, null)
}
resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) {
if (error) {
return callback(error)
}
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
callback(null, mapData)
})
})
}
function resolveSync(code, codeUrl, read, options) {
var mapData = resolveSourceMapSync(code, codeUrl, read)
if (!mapData) {
return null
}
var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options)
mapData.sourcesResolved = result.sourcesResolved
mapData.sourcesContent = result.sourcesContent
return mapData
}
return {
resolveSourceMap: resolveSourceMap,
resolveSourceMapSync: resolveSourceMapSync,
resolveSources: resolveSources,
resolveSourcesSync: resolveSourcesSync,
resolve: resolve,
resolveSync: resolveSync
}
}));

View File

@ -0,0 +1,22 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
// Note: source-map-resolve.js is generated from source-map-resolve-node.js and
// source-map-resolve-template.js. Only edit the two latter files, _not_
// source-map-resolve.js!
void (function(root, factory) {
if (typeof define === "function" && define.amd) {
define(["source-map-url", "resolve-url"], factory)
} else if (typeof exports === "object") {
var sourceMappingURL = require("source-map-url")
var resolveUrl = require("resolve-url")
module.exports = factory(sourceMappingURL, resolveUrl)
} else {
root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
}
}(this, function(sourceMappingURL, resolveUrl) {
{{source-map-resolve-node.js}}
}));

View File

@ -0,0 +1,27 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
function u(url) {
return "code\n/*# sourceMappingURL=" + url + " */"
}
function read(x) {
return function() {
return x
}
}
function Throws(x) {
throw new Error(x)
}
function identity(x) {
return x
}
module.exports = {
u: u,
read: read,
Throws: Throws,
identity: identity
}

View File

@ -0,0 +1,819 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var test = require("tape")
var asyncify = require("simple-asyncify")
var common = require("./common")
var u = common.u
var read = common.read
var Throws = common.Throws
var identity = common.identity
var sourceMapResolve = require("../")
// Polyfills.
require("setimmediate")
if (typeof window !== "undefined" && !window.atob) {
window.atob = require("Base64").atob
}
"use strict"
var map = {
simple: {
mappings: "AAAA",
sources: ["foo.js"],
names: []
},
sourceRoot: {
mappings: "AAAA",
sourceRoot: "/static/js/app/",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
names: []
},
sourceRootNoSlash: {
mappings: "AAAA",
sourceRoot: "/static/js/app",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
names: []
},
sourcesContent: {
mappings: "AAAA",
sourceRoot: "/static/js/app/",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
sourcesContent: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
names: []
},
mixed: {
mappings: "AAAA",
sources: ["foo.js", "lib/bar.js", "../vendor/dom.js", "/version.js", "//foo.org/baz.js"],
sourcesContent: ["foo.js", null , null , "/version.js", "//foo.org/baz.js"],
names: []
}
}
map.simpleString = JSON.stringify(map.simple)
map.XSSIsafe = ")]}'" + map.simpleString
var code = {
fileRelative: u("foo.js.map"),
domainRelative: u("/foo.js.map"),
schemeRelative: u("//foo.org/foo.js.map"),
absolute: u("https://foo.org/foo.js.map"),
dataUri: u("data:application/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
base64: u("data:application/json;base64," +
"eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119"),
dataUriText: u("data:text/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
dataUriParameter: u("data:application/json;charset=UTF-8;foo=bar," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
dataUriNoMime: u("data:,foo"),
dataUriInvalidMime: u("data:text/html,foo"),
dataUriInvalidJSON: u("data:application/json,foo"),
dataUriXSSIsafe: u("data:application/json," + ")%5D%7D%27" +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D"),
dataUriEmpty: u("data:"),
noMap: ""
}
function testResolveSourceMap(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var codeUrl = "http://example.com/a/b/c/foo.js"
t.plan(1 + 18*3)
t.equal(typeof method, "function", "is a function")
if (sync) {
method = asyncify(method)
}
var next = false
function isAsync() { t.ok(next, "is async") }
method(code.fileRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "http://example.com/a/b/c/foo.js.map",
sourcesRelativeTo: "http://example.com/a/b/c/foo.js.map",
map: map.simple
}, "fileRelative")
isAsync()
})
method(code.domainRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "http://example.com/foo.js.map",
sourcesRelativeTo: "http://example.com/foo.js.map",
map: map.simple
}, "domainRelative")
isAsync()
})
method(code.schemeRelative, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "//foo.org/foo.js.map",
url: "http://foo.org/foo.js.map",
sourcesRelativeTo: "http://foo.org/foo.js.map",
map: map.simple
}, "schemeRelative")
isAsync()
})
method(code.absolute, codeUrl, wrap(read(map.simpleString)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple
}, "absolute")
isAsync()
})
method(code.dataUri, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUri")
isAsync()
})
method(code.base64, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;base64," +
"eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "base64")
isAsync()
})
method(code.dataUriText, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:text/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUriText")
isAsync()
})
method(code.dataUriParameter, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;charset=UTF-8;foo=bar," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUriParameter")
isAsync()
})
method(code.dataUriNoMime, codeUrl, wrap(Throws), function(error, result) {
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriNoMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidMime, codeUrl, wrap(Throws), function(error, result) {
t.ok(error.message.match(/mime type.+text\/html/), "dataUriInvalidMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidJSON, codeUrl, wrap(Throws), function(error, result) {
t.ok(error instanceof SyntaxError && error.message !== "data:application/json,foo",
"dataUriInvalidJSON")
t.notOk(result)
isAsync()
})
method(code.dataUriXSSIsafe, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," + ")%5D%7D%27" +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple
}, "dataUriXSSIsafe")
isAsync()
})
method(code.dataUriEmpty, codeUrl, wrap(Throws), function(error, result) {
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriEmpty")
t.notOk(result)
isAsync()
})
method(code.noMap, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.equal(result, null, "noMap")
isAsync()
})
method(code.absolute, codeUrl, wrap(read([map.simpleString])), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple
}, "read non-string")
isAsync()
})
method(code.absolute, codeUrl, wrap(read("invalid JSON")), function(error, result) {
t.ok(error instanceof SyntaxError, "read invalid JSON")
t.notOk(result)
isAsync()
})
method(code.absolute, codeUrl, wrap(read(map.XSSIsafe)), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple
}, "XSSIsafe map")
isAsync()
})
method(code.absolute, codeUrl, wrap(Throws), function(error, result) {
t.equal(error.message, "https://foo.org/foo.js.map", "read throws")
t.notOk(result)
isAsync()
})
next = true
}
}
test(".resolveSourceMap", testResolveSourceMap(sourceMapResolve.resolveSourceMap, false))
test(".resolveSourceMapSync", testResolveSourceMap(sourceMapResolve.resolveSourceMapSync, true))
function testResolveSources(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var mapUrl = "http://example.com/a/b/c/foo.js.map"
t.plan(1 + 7*3 + 4)
t.equal(typeof method, "function", "is a function")
if (sync) {
method = asyncify(method)
}
var next = false
function isAsync() { t.ok(next, "is async") }
var options
method(map.simple, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "simple")
isAsync()
})
method(map.sourceRoot, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "sourceRoot")
isAsync()
})
options = {ignoreSourceRoot: true}
method(map.sourceRoot, mapUrl, wrap(identity), options, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "ignore sourceRoot")
isAsync()
})
method(map.sourceRootNoSlash, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
]
}, "sourceRootNoSlash")
isAsync()
})
method(map.sourcesContent, mapUrl, wrap(Throws), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"foo.js",
"lib/bar.js",
"../vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
]
}, "sourcesContent")
isAsync()
})
method(map.mixed, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: [
"foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
]
}, "mixed")
isAsync()
})
method(map.simple, mapUrl, wrap(read(["non", "string"])), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["non,string"]
}, "read non-string")
isAsync()
})
var calledBack = false
method(map.mixed, mapUrl, wrap(Throws), function(error, result) {
t.equal(calledBack, false)
calledBack = true
t.equal(error.message, "http://example.com/a/b/c/lib/bar.js", "read throws")
t.notOk(result)
isAsync()
})
next = true
}
}
test(".resolveSources", testResolveSources(sourceMapResolve.resolveSources, false))
test(".resolveSourcesSync", testResolveSources(sourceMapResolve.resolveSourcesSync, true))
test(".resolveSourcesSync no read", function(t) {
t.plan(1)
var mapUrl = "http://example.com/a/b/c/foo.js.map"
var result = sourceMapResolve.resolveSourcesSync(map.mixed, mapUrl, null)
t.deepEqual(result, {
sourcesResolved: [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
],
sourcesContent: []
})
})
function testResolve(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var wrapMap = function(mapFn, fn) {
return wrap(function(url) {
if (/\.map$/.test(url)) {
return mapFn(url)
}
return fn(url)
})
}
var codeUrl = "http://example.com/a/b/c/foo.js"
t.plan(1 + 18*3 + 7*4 + 4)
t.equal(typeof method, "function", "is a function")
if (sync) {
method = asyncify(method)
}
var next = false
function isAsync() { t.ok(next, "is async") }
var readSimple = wrapMap(read(map.simpleString), identity)
method(code.fileRelative, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "http://example.com/a/b/c/foo.js.map",
sourcesRelativeTo: "http://example.com/a/b/c/foo.js.map",
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "fileRelative")
isAsync()
})
method(code.domainRelative, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "http://example.com/foo.js.map",
sourcesRelativeTo: "http://example.com/foo.js.map",
map: map.simple,
sourcesResolved: ["http://example.com/foo.js"],
sourcesContent: ["http://example.com/foo.js"]
}, "domainRelative")
isAsync()
})
method(code.schemeRelative, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "//foo.org/foo.js.map",
url: "http://foo.org/foo.js.map",
sourcesRelativeTo: "http://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["http://foo.org/foo.js"],
sourcesContent: ["http://foo.org/foo.js"]
}, "schemeRelative")
isAsync()
})
method(code.absolute, codeUrl, readSimple, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: ["https://foo.org/foo.js"]
}, "absolute")
isAsync()
})
method(code.dataUri, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUri")
isAsync()
})
method(code.base64, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;base64," +
"eyJtYXBwaW5ncyI6IkFBQUEiLCJzb3VyY2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W119",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "base64")
isAsync()
})
method(code.dataUriText, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:text/json," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUriText")
isAsync()
})
method(code.dataUriParameter, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json;charset=UTF-8;foo=bar," +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUriParameter")
isAsync()
})
method(code.dataUriNoMime, codeUrl, wrap(Throws), function(error, result) {
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriNoMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidMime, codeUrl, wrap(Throws), function(error, result) {
t.ok(error.message.match(/mime type.+text\/html/), "dataUriInvalidMime")
t.notOk(result)
isAsync()
})
method(code.dataUriInvalidJSON, codeUrl, wrap(Throws), function(error, result) {
t.ok(error instanceof SyntaxError && error.message !== "data:application/json,foo",
"dataUriInvalidJSON")
t.notOk(result)
isAsync()
})
method(code.dataUriXSSIsafe, codeUrl, wrapMap(Throws, identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "data:application/json," + ")%5D%7D%27" +
"%7B%22mappings%22%3A%22AAAA%22%2C%22sources%22%3A%5B%22" +
"foo.js%22%5D%2C%22names%22%3A%5B%5D%7D",
url: null,
sourcesRelativeTo: codeUrl,
map: map.simple,
sourcesResolved: ["http://example.com/a/b/c/foo.js"],
sourcesContent: ["http://example.com/a/b/c/foo.js"]
}, "dataUriXSSIsafe")
isAsync()
})
method(code.dataUriEmpty, codeUrl, wrap(Throws), function(error, result) {
t.ok(error.message.match(/mime type.+text\/plain/), "dataUriEmpty")
t.notOk(result)
isAsync()
})
method(code.noMap, codeUrl, wrap(Throws), function(error, result) {
t.error(error)
t.equal(result, null, "noMap")
isAsync()
})
method(code.absolute, codeUrl, wrap(read([map.simpleString])), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: [map.simpleString]
}, "read non-string")
isAsync()
})
method(code.absolute, codeUrl, wrap(read("invalid JSON")), function(error, result) {
t.ok(error instanceof SyntaxError, "read invalid JSON")
t.notOk(result)
isAsync()
})
method(code.absolute, codeUrl, wrapMap(read(map.XSSIsafe), identity), function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "https://foo.org/foo.js.map",
url: "https://foo.org/foo.js.map",
sourcesRelativeTo: "https://foo.org/foo.js.map",
map: map.simple,
sourcesResolved: ["https://foo.org/foo.js"],
sourcesContent: ["https://foo.org/foo.js"]
}, "XSSIsafe map")
isAsync()
})
method(code.absolute, codeUrl, wrap(Throws), function(error, result) {
t.equal(error.message, "https://foo.org/foo.js.map", "read throws")
t.notOk(result)
isAsync()
})
function readMap(what) {
return wrapMap(read(JSON.stringify(what)), identity)
}
var options
method(code.fileRelative, codeUrl, readMap(map.simple), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, ["http://example.com/a/b/c/foo.js"], "simple")
t.deepEqual(result.sourcesContent, ["http://example.com/a/b/c/foo.js"], "simple")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.sourceRoot), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRoot")
t.deepEqual(result.sourcesContent, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRoot")
isAsync()
})
options = {ignoreSourceRoot: true}
method(code.fileRelative, codeUrl, readMap(map.sourceRoot), options, function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRoot")
t.deepEqual(result.sourcesContent, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "ignore sourceRoot")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.sourceRootNoSlash), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRootNoSlash")
t.deepEqual(result.sourcesContent, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourceRootNoSlash")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.sourcesContent), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/static/js/app/foo.js",
"http://example.com/static/js/app/lib/bar.js",
"http://example.com/static/js/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "sourcesContent")
t.deepEqual(result.sourcesContent, [
"foo.js",
"lib/bar.js",
"../vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
], "sourcesContent")
isAsync()
})
method(code.fileRelative, codeUrl, readMap(map.mixed), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, [
"http://example.com/a/b/c/foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"http://example.com/version.js",
"http://foo.org/baz.js"
], "mixed")
t.deepEqual(result.sourcesContent, [
"foo.js",
"http://example.com/a/b/c/lib/bar.js",
"http://example.com/a/b/vendor/dom.js",
"/version.js",
"//foo.org/baz.js"
], "mixed")
isAsync()
})
method(code.fileRelative, codeUrl, wrap(read([map.simpleString])), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, ["http://example.com/a/b/c/foo.js"], "read non-string")
t.deepEqual(result.sourcesContent, [map.simpleString], "read non-string")
isAsync()
})
function ThrowsMap(what) {
return wrapMap(read(JSON.stringify(what)), Throws)
}
var calledBack = false
method(code.fileRelative, codeUrl, ThrowsMap(map.mixed), function(error, result) {
t.equal(calledBack, false)
calledBack = true
t.equal(error.message, "http://example.com/a/b/c/lib/bar.js", "read throws")
t.notOk(result)
isAsync()
})
next = true
}
}
test(".resolve", testResolve(sourceMapResolve.resolve, false))
test(".resolveSync", testResolve(sourceMapResolve.resolveSync, true))

View File

@ -0,0 +1,166 @@
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
var path = require("path")
var test = require("tape")
var asyncify = require("simple-asyncify")
var common = require("./common")
var u = common.u
var read = common.read
var identity = common.identity
var sourceMapResolve = require("../")
path.sep = "\\"
function testResolveSourceMap(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var codeUrl = "c:\\a\\b\\c\\foo.js"
t.plan(3 * 2)
if (sync) {
method = asyncify(method)
}
var map = {}
var readMap = wrap(read(JSON.stringify(map)))
method(u("foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "/a/b/c/foo.js.map",
sourcesRelativeTo: "/a/b/c/foo.js.map",
map: map
})
})
method(u("/foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "/foo.js.map",
sourcesRelativeTo: "/foo.js.map",
map: map
})
})
method(u("../foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "../foo.js.map",
url: "/a/b/foo.js.map",
sourcesRelativeTo: "/a/b/foo.js.map",
map: map
})
})
}
}
test(".resolveSourceMap", testResolveSourceMap(sourceMapResolve.resolveSourceMap, false))
test(".resolveSourceMapSync", testResolveSourceMap(sourceMapResolve.resolveSourceMapSync, true))
function testResolveSources(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var mapUrl = "c:\\a\\b\\c\\foo.js.map"
t.plan(1 * 3)
if (sync) {
method = asyncify(method)
}
var map = {
sources: ["foo.js", "/foo.js", "../foo.js"]
}
method(map, mapUrl, wrap(identity), function(error, result) {
t.error(error)
t.deepEqual(result.sourcesResolved, ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"])
t.deepEqual(result.sourcesContent, ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"])
})
}
}
test(".resolveSources", testResolveSources(sourceMapResolve.resolveSources, false))
test(".resolveSourcesSync", testResolveSources(sourceMapResolve.resolveSourcesSync, true))
function testResolve(method, sync) {
return function(t) {
var wrap = (sync ? identity : asyncify)
var wrapMap = function(mapFn, fn) {
return wrap(function(url) {
if (/\.map$/.test(url)) {
return mapFn(url)
}
return fn(url)
})
}
var codeUrl = "c:\\a\\b\\c\\foo.js"
t.plan(3 * 2)
if (sync) {
method = asyncify(method)
}
var map = {
sources: ["foo.js", "/foo.js", "../foo.js"]
}
var readMap = wrapMap(read(JSON.stringify(map)), identity)
method(u("foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "foo.js.map",
url: "/a/b/c/foo.js.map",
sourcesRelativeTo: "/a/b/c/foo.js.map",
map: map,
sourcesResolved: ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"],
sourcesContent: ["/a/b/c/foo.js", "/foo.js", "/a/b/foo.js"]
})
})
method(u("/foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "/foo.js.map",
url: "/foo.js.map",
sourcesRelativeTo: "/foo.js.map",
map: map,
sourcesResolved: ["/foo.js", "/foo.js", "/foo.js"],
sourcesContent: ["/foo.js", "/foo.js", "/foo.js"]
})
})
method(u("../foo.js.map"), codeUrl, readMap, function(error, result) {
t.error(error)
t.deepEqual(result, {
sourceMappingURL: "../foo.js.map",
url: "/a/b/foo.js.map",
sourcesRelativeTo: "/a/b/foo.js.map",
map: map,
sourcesResolved: ["/a/b/foo.js", "/foo.js", "/a/foo.js"],
sourcesContent: ["/a/b/foo.js", "/foo.js", "/a/foo.js"]
})
})
}
}
test(".resolve", testResolve(sourceMapResolve.resolve, false))
test(".resolveSync", testResolve(sourceMapResolve.resolveSync, true))

View File

@ -0,0 +1,83 @@
{
name: "source-map-resolve",
version: "0.3.1",
author: "Simon Lydell",
license: "MIT",
description: "Resolve the source map and/or sources for a generated file.",
keywords: [
"source map",
"sourcemap",
"source",
"map",
"sourceMappingURL",
"resolve",
"resolver",
"locate",
"locator",
"find",
"finder"
],
overlay: {
npm: {
repository: "lydell/source-map-resolve",
main: "lib/source-map-resolve-node.js",
browser: "source-map-resolve.js",
scripts: {
lint: "jshint lib/ test/",
unit: "node test/source-map-resolve.js && node test/windows.js",
test: "npm run lint && npm run unit",
build: "node generate-source-map-resolve.js"
},
dependencies: {
"source-map-url": "~0.3.0",
"atob": "~1.1.0",
"urix": "~0.1.0",
// resolve-url is a dependency in package.json even though it is not
// needed in Node.js, to allow using npm as a package manager for
// browser projects too.
"resolve-url": "~0.2.1"
},
devDependencies: {
"tape": "~2.5.0",
"jshint": "~2.4.3",
"setimmediate": "~1.0.1",
"Base64": "~0.2.0",
"simple-asyncify": "~0.1.0"
},
testling: {
files: "test/source-map-resolve.js",
browsers: [
"ie/8..latest",
"chrome/latest",
"firefox/latest",
"opera/12",
"opera/latest",
"safari/5",
"iphone/6",
"android-browser/4"
]
}
},
component: {
repo: "lydell/source-map-resolve",
main: "source-map-resolve.js",
scripts: [
"source-map-resolve.js"
],
dependencies: {
"lydell/source-map-url": "~0.3.0",
"lydell/resolve-url": "~0.2.1"
}
},
bower: {
authors: ["Simon Lydell"],
ignore: [
".*"
],
dependencies: {
"source-map-url": "~0.3.0",
"resolve-url": "~0.2.1"
}
}
}
}