{"action":"created","comment":{"url":"https://api.github.com/repos/thlorenz/exorcist/pulls/comments/28117890","id":28117890,"diff_hunk":"@@ -1,63 +1,61 @@\n 'use strict';\n \n-var convert = require('convert-source-map')\n+var mold = require('mold-source-map')\n   , path = require('path')\n-  , fs = require('fs')\n-  , through = require('through2');\n+  , fs = require('fs');\n \n-function separate(src, file, root, url) {\n-  var inlined = convert.fromSource(src);\n-\n-  if (!inlined) return null;\n+function separate(src, file, root, base, url) {\n+  src.sourceRoot(root || '');\n+  if (base) {\n+    src.mapSources(mold.mapPathRelativeTo(base));\n+  }\n \n-  var json = inlined\n-    .setProperty('sourceRoot', root || '')\n-    .toJSON(2);\n+  var json = src.toJSON(2);\n \n   url = url || path.basename(file);\n-\n-  var newSrc = convert.removeComments(src);\n   var comment = '//# sourceMappingURL=' + url;\n \n-  return { json: json, src: newSrc + '\\n' + comment }\n+  return { json: json, comment: comment }\n }\n \n var go = module.exports = \n \n /**\n- * Transforms the incoming stream of code by removing the inlined source map and writing it to an external map file.\n- * Additionally it adds a source map url that points to the extracted map file.\n  *\n- * #### Events (other than all stream events like `error`)\n+ * Externalizes the source map of the file streamed in.\n+ *\n+ * The source map is written as JSON to `file`, and the original file is streamed out with its\n+ * `sourceMappingURL` set to the path of `file` (or to the value of `url`).\n+ *\n+ * #### Events (in addition to stream events)\n+ *\n+ * - `missing-map` emitted if no map was found in the stream\n+ *   (the src is still piped through in this case, but no map file is written)\n  *\n- *  - `missing-map` emitted if no map was found in the stream (the src still is piped through in this case, but no map file is written)\n- * \n  * @name exorcist\n  * @function\n  * @param {String} file full path to the map file to which to write the extracted source map\n- * @param {String=} url  allows overriding the url at which the map file is found (default: name of map file)\n- * @param {String=} root allows adjusting the source maps `sourceRoot` field (default: '')\n+ * @param {String=} url full URL to the map file, set as `sourceMappingURL` in the streaming output (default: file)\n+ * @param {String=} root root URL for loading relative source paths, set as `sourceRoot` in the source map (default: '')\n+ * @param {String=} base base path for calculating relative source paths (default: use absolute paths)\n  * @return {TransformStream} transform stream into which to pipe the code containing the source map\n  */\n-function exorcist(file, url, root) {\n-  var src = '';\n-\n-  function ondata(d, _, cb) { src += d; cb(); }\n-  function onend(cb) {\n-    var self = this;\n-    var separated = separate(src, file, root, url);\n-    if (!separated) {\n-      self.emit(\n-          'missing-map'\n+function exorcist(file, url, root, base) {\n+  var stream = mold.transform(function(src, write) {\n+    if (!src.sourcemap) {\n+      stream.emit(\n+        'missing-map'\n         ,   'The code that you piped into exorcist contains no source map!\\n'\n           + 'Therefore it was piped through as is and no external map file generated.'\n       );\n-      self.push(src);\n-      return cb(); \n+      return write(src.source);","path":"index.js","position":83,"original_position":83,"commit_id":"d2eeee89e1285f30c2b5a68ee7dc5918ea291ca5","original_commit_id":"d2eeee89e1285f30c2b5a68ee7dc5918ea291ca5","user":{"login":"jamesreggio","id":822205,"avatar_url":"https://avatars.githubusercontent.com/u/822205?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesreggio","html_url":"https://github.com/jamesreggio","followers_url":"https://api.github.com/users/jamesreggio/followers","following_url":"https://api.github.com/users/jamesreggio/following{/other_user}","gists_url":"https://api.github.com/users/jamesreggio/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesreggio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesreggio/subscriptions","organizations_url":"https://api.github.com/users/jamesreggio/orgs","repos_url":"https://api.github.com/users/jamesreggio/repos","events_url":"https://api.github.com/users/jamesreggio/events{/privacy}","received_events_url":"https://api.github.com/users/jamesreggio/received_events","type":"User","site_admin":false},"body":"Line 45 and this line reference specific components of the `SourceMolder` object, which may not be part of the formally public interface. If you have concern about this, I could add getter functions, though I'm generally adverse to writing simple getters in JavaScript. Your call.","created_at":"2015-04-10T01:40:07Z","updated_at":"2015-04-10T01:40:07Z","html_url":"https://github.com/thlorenz/exorcist/pull/12#discussion_r28117890","pull_request_url":"https://api.github.com/repos/thlorenz/exorcist/pulls/12","_links":{"self":{"href":"https://api.github.com/repos/thlorenz/exorcist/pulls/comments/28117890"},"html":{"href":"https://github.com/thlorenz/exorcist/pull/12#discussion_r28117890"},"pull_request":{"href":"https://api.github.com/repos/thlorenz/exorcist/pulls/12"}}},"pull_request":{"url":"https://api.github.com/repos/thlorenz/exorcist/pulls/12","id":30341027,"html_url":"https://github.com/thlorenz/exorcist/pull/12","diff_url":"https://github.com/thlorenz/exorcist/pull/12.diff","patch_url":"https://github.com/thlorenz/exorcist/pull/12.patch","issue_url":"https://api.github.com/repos/thlorenz/exorcist/issues/12","number":12,"state":"open","locked":false,"title":"Support base-relative sources","user":{"login":"jamesreggio","id":822205,"avatar_url":"https://avatars.githubusercontent.com/u/822205?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesreggio","html_url":"https://github.com/jamesreggio","followers_url":"https://api.github.com/users/jamesreggio/followers","following_url":"https://api.github.com/users/jamesreggio/following{/other_user}","gists_url":"https://api.github.com/users/jamesreggio/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesreggio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesreggio/subscriptions","organizations_url":"https://api.github.com/users/jamesreggio/orgs","repos_url":"https://api.github.com/users/jamesreggio/repos","events_url":"https://api.github.com/users/jamesreggio/events{/privacy}","received_events_url":"https://api.github.com/users/jamesreggio/received_events","type":"User","site_admin":false},"body":"Browserify is overly simple with its handling of source maps: it always passes the full, absolute path of files to transformers, which results in source maps filled with absolute paths.\r\n\r\nExorcist seems like a reasonable place to re-relative-ize the source paths against a consistent base directory. This works in conjunction with `--root` to indicate the URL to use to look up source files.\r\n\r\nFor example:\r\n\r\n```\r\nInput source map contains:\r\n{ ...\r\n  sources: ['/Users/jamesreggio/project/src/foo.js']\r\n  ... }\r\n\r\nWe execute this:\r\n... | exorcist --base /Users/jamesreggio/project --root http://internal.myapp.com/maps output.js.map > output.js\r\n\r\noutput.js.map contains:\r\n{ ...\r\n  sourceRoot: 'http://internal.myapp.com/maps',\r\n  sources: ['src/foo.js']\r\n  ... }\r\n\r\nIn the browser, it will try to resolve the source file at:\r\nhttp://internal.myapp.com/maps/src/foo.js\r\n\r\n...which is correct!\r\n```\r\n\r\nI added this feature with documentation and tests. (I also did some housekeeping in the documentation since the `--url` and `--root` options were a little confusing.)\r\n\r\nLet me know if you'd like any clarification.","created_at":"2015-03-03T02:17:44Z","updated_at":"2015-04-10T01:40:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"137b602566ebb32e2b526be6105d64769d34f55b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/thlorenz/exorcist/pulls/12/commits","review_comments_url":"https://api.github.com/repos/thlorenz/exorcist/pulls/12/comments","review_comment_url":"https://api.github.com/repos/thlorenz/exorcist/pulls/comments{/number}","comments_url":"https://api.github.com/repos/thlorenz/exorcist/issues/12/comments","statuses_url":"https://api.github.com/repos/thlorenz/exorcist/statuses/d2eeee89e1285f30c2b5a68ee7dc5918ea291ca5","head":{"label":"jamesreggio:base-relative","ref":"base-relative","sha":"d2eeee89e1285f30c2b5a68ee7dc5918ea291ca5","user":{"login":"jamesreggio","id":822205,"avatar_url":"https://avatars.githubusercontent.com/u/822205?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesreggio","html_url":"https://github.com/jamesreggio","followers_url":"https://api.github.com/users/jamesreggio/followers","following_url":"https://api.github.com/users/jamesreggio/following{/other_user}","gists_url":"https://api.github.com/users/jamesreggio/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesreggio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesreggio/subscriptions","organizations_url":"https://api.github.com/users/jamesreggio/orgs","repos_url":"https://api.github.com/users/jamesreggio/repos","events_url":"https://api.github.com/users/jamesreggio/events{/privacy}","received_events_url":"https://api.github.com/users/jamesreggio/received_events","type":"User","site_admin":false},"repo":{"id":31572808,"name":"exorcist","full_name":"jamesreggio/exorcist","owner":{"login":"jamesreggio","id":822205,"avatar_url":"https://avatars.githubusercontent.com/u/822205?v=3","gravatar_id":"","url":"https://api.github.com/users/jamesreggio","html_url":"https://github.com/jamesreggio","followers_url":"https://api.github.com/users/jamesreggio/followers","following_url":"https://api.github.com/users/jamesreggio/following{/other_user}","gists_url":"https://api.github.com/users/jamesreggio/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesreggio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesreggio/subscriptions","organizations_url":"https://api.github.com/users/jamesreggio/orgs","repos_url":"https://api.github.com/users/jamesreggio/repos","events_url":"https://api.github.com/users/jamesreggio/events{/privacy}","received_events_url":"https://api.github.com/users/jamesreggio/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jamesreggio/exorcist","description":"CLI to extract inline sourcemaps","fork":true,"url":"https://api.github.com/repos/jamesreggio/exorcist","forks_url":"https://api.github.com/repos/jamesreggio/exorcist/forks","keys_url":"https://api.github.com/repos/jamesreggio/exorcist/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jamesreggio/exorcist/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jamesreggio/exorcist/teams","hooks_url":"https://api.github.com/repos/jamesreggio/exorcist/hooks","issue_events_url":"https://api.github.com/repos/jamesreggio/exorcist/issues/events{/number}","events_url":"https://api.github.com/repos/jamesreggio/exorcist/events","assignees_url":"https://api.github.com/repos/jamesreggio/exorcist/assignees{/user}","branches_url":"https://api.github.com/repos/jamesreggio/exorcist/branches{/branch}","tags_url":"https://api.github.com/repos/jamesreggio/exorcist/tags","blobs_url":"https://api.github.com/repos/jamesreggio/exorcist/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jamesreggio/exorcist/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jamesreggio/exorcist/git/refs{/sha}","trees_url":"https://api.github.com/repos/jamesreggio/exorcist/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jamesreggio/exorcist/statuses/{sha}","languages_url":"https://api.github.com/repos/jamesreggio/exorcist/languages","stargazers_url":"https://api.github.com/repos/jamesreggio/exorcist/stargazers","contributors_url":"https://api.github.com/repos/jamesreggio/exorcist/contributors","subscribers_url":"https://api.github.com/repos/jamesreggio/exorcist/subscribers","subscription_url":"https://api.github.com/repos/jamesreggio/exorcist/subscription","commits_url":"https://api.github.com/repos/jamesreggio/exorcist/commits{/sha}","git_commits_url":"https://api.github.com/repos/jamesreggio/exorcist/git/commits{/sha}","comments_url":"https://api.github.com/repos/jamesreggio/exorcist/comments{/number}","issue_comment_url":"https://api.github.com/repos/jamesreggio/exorcist/issues/comments{/number}","contents_url":"https://api.github.com/repos/jamesreggio/exorcist/contents/{+path}","compare_url":"https://api.github.com/repos/jamesreggio/exorcist/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jamesreggio/exorcist/merges","archive_url":"https://api.github.com/repos/jamesreggio/exorcist/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jamesreggio/exorcist/downloads","issues_url":"https://api.github.com/repos/jamesreggio/exorcist/issues{/number}","pulls_url":"https://api.github.com/repos/jamesreggio/exorcist/pulls{/number}","milestones_url":"https://api.github.com/repos/jamesreggio/exorcist/milestones{/number}","notifications_url":"https://api.github.com/repos/jamesreggio/exorcist/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jamesreggio/exorcist/labels{/name}","releases_url":"https://api.github.com/repos/jamesreggio/exorcist/releases{/id}","created_at":"2015-03-03T01:19:51Z","updated_at":"2015-03-03T19:30:07Z","pushed_at":"2015-04-10T01:32:24Z","git_url":"git://github.com/jamesreggio/exorcist.git","ssh_url":"git@github.com:jamesreggio/exorcist.git","clone_url":"https://github.com/jamesreggio/exorcist.git","svn_url":"https://github.com/jamesreggio/exorcist","homepage":"","size":131,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"thlorenz:master","ref":"master","sha":"9059d0f4e4065934bb09a4c27e7dfb9c1e476242","user":{"login":"thlorenz","id":192891,"avatar_url":"https://avatars.githubusercontent.com/u/192891?v=3","gravatar_id":"","url":"https://api.github.com/users/thlorenz","html_url":"https://github.com/thlorenz","followers_url":"https://api.github.com/users/thlorenz/followers","following_url":"https://api.github.com/users/thlorenz/following{/other_user}","gists_url":"https://api.github.com/users/thlorenz/gists{/gist_id}","starred_url":"https://api.github.com/users/thlorenz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thlorenz/subscriptions","organizations_url":"https://api.github.com/users/thlorenz/orgs","repos_url":"https://api.github.com/users/thlorenz/repos","events_url":"https://api.github.com/users/thlorenz/events{/privacy}","received_events_url":"https://api.github.com/users/thlorenz/received_events","type":"User","site_admin":false},"repo":{"id":15978688,"name":"exorcist","full_name":"thlorenz/exorcist","owner":{"login":"thlorenz","id":192891,"avatar_url":"https://avatars.githubusercontent.com/u/192891?v=3","gravatar_id":"","url":"https://api.github.com/users/thlorenz","html_url":"https://github.com/thlorenz","followers_url":"https://api.github.com/users/thlorenz/followers","following_url":"https://api.github.com/users/thlorenz/following{/other_user}","gists_url":"https://api.github.com/users/thlorenz/gists{/gist_id}","starred_url":"https://api.github.com/users/thlorenz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thlorenz/subscriptions","organizations_url":"https://api.github.com/users/thlorenz/orgs","repos_url":"https://api.github.com/users/thlorenz/repos","events_url":"https://api.github.com/users/thlorenz/events{/privacy}","received_events_url":"https://api.github.com/users/thlorenz/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/thlorenz/exorcist","description":"Externalizes the source map found inside a stream to an external .js.map file","fork":false,"url":"https://api.github.com/repos/thlorenz/exorcist","forks_url":"https://api.github.com/repos/thlorenz/exorcist/forks","keys_url":"https://api.github.com/repos/thlorenz/exorcist/keys{/key_id}","collaborators_url":"https://api.github.com/repos/thlorenz/exorcist/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/thlorenz/exorcist/teams","hooks_url":"https://api.github.com/repos/thlorenz/exorcist/hooks","issue_events_url":"https://api.github.com/repos/thlorenz/exorcist/issues/events{/number}","events_url":"https://api.github.com/repos/thlorenz/exorcist/events","assignees_url":"https://api.github.com/repos/thlorenz/exorcist/assignees{/user}","branches_url":"https://api.github.com/repos/thlorenz/exorcist/branches{/branch}","tags_url":"https://api.github.com/repos/thlorenz/exorcist/tags","blobs_url":"https://api.github.com/repos/thlorenz/exorcist/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/thlorenz/exorcist/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/thlorenz/exorcist/git/refs{/sha}","trees_url":"https://api.github.com/repos/thlorenz/exorcist/git/trees{/sha}","statuses_url":"https://api.github.com/repos/thlorenz/exorcist/statuses/{sha}","languages_url":"https://api.github.com/repos/thlorenz/exorcist/languages","stargazers_url":"https://api.github.com/repos/thlorenz/exorcist/stargazers","contributors_url":"https://api.github.com/repos/thlorenz/exorcist/contributors","subscribers_url":"https://api.github.com/repos/thlorenz/exorcist/subscribers","subscription_url":"https://api.github.com/repos/thlorenz/exorcist/subscription","commits_url":"https://api.github.com/repos/thlorenz/exorcist/commits{/sha}","git_commits_url":"https://api.github.com/repos/thlorenz/exorcist/git/commits{/sha}","comments_url":"https://api.github.com/repos/thlorenz/exorcist/comments{/number}","issue_comment_url":"https://api.github.com/repos/thlorenz/exorcist/issues/comments{/number}","contents_url":"https://api.github.com/repos/thlorenz/exorcist/contents/{+path}","compare_url":"https://api.github.com/repos/thlorenz/exorcist/compare/{base}...{head}","merges_url":"https://api.github.com/repos/thlorenz/exorcist/merges","archive_url":"https://api.github.com/repos/thlorenz/exorcist/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/thlorenz/exorcist/downloads","issues_url":"https://api.github.com/repos/thlorenz/exorcist/issues{/number}","pulls_url":"https://api.github.com/repos/thlorenz/exorcist/pulls{/number}","milestones_url":"https://api.github.com/repos/thlorenz/exorcist/milestones{/number}","notifications_url":"https://api.github.com/repos/thlorenz/exorcist/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/thlorenz/exorcist/labels{/name}","releases_url":"https://api.github.com/repos/thlorenz/exorcist/releases{/id}","created_at":"2014-01-16T19:32:38Z","updated_at":"2015-04-08T07:52:04Z","pushed_at":"2015-04-10T01:32:25Z","git_url":"git://github.com/thlorenz/exorcist.git","ssh_url":"git@github.com:thlorenz/exorcist.git","clone_url":"https://github.com/thlorenz/exorcist.git","svn_url":"https://github.com/thlorenz/exorcist","homepage":"","size":520,"stargazers_count":120,"watchers_count":120,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":8,"forks":9,"open_issues":8,"watchers":120,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/thlorenz/exorcist/pulls/12"},"html":{"href":"https://github.com/thlorenz/exorcist/pull/12"},"issue":{"href":"https://api.github.com/repos/thlorenz/exorcist/issues/12"},"comments":{"href":"https://api.github.com/repos/thlorenz/exorcist/issues/12/comments"},"review_comments":{"href":"https://api.github.com/repos/thlorenz/exorcist/pulls/12/comments"},"review_comment":{"href":"https://api.github.com/repos/thlorenz/exorcist/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/thlorenz/exorcist/pulls/12/commits"},"statuses":{"href":"https://api.github.com/repos/thlorenz/exorcist/statuses/d2eeee89e1285f30c2b5a68ee7dc5918ea291ca5"}}}}