pax_global_header00006660000000000000000000000064131401536070014512gustar00rootroot0000000000000052 comment=4121a96458f1f78709411b083655c520a679e49e vinyl-sourcemap-1.1.0/000077500000000000000000000000001314015360700146465ustar00rootroot00000000000000vinyl-sourcemap-1.1.0/.editorconfig000066400000000000000000000003051314015360700173210ustar00rootroot00000000000000# http://editorconfig.org root = true [*] indent_style = space indent_size = 2 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false vinyl-sourcemap-1.1.0/.eslintrc000066400000000000000000000000301314015360700164630ustar00rootroot00000000000000{ "extends": "gulp" } vinyl-sourcemap-1.1.0/.gitignore000066400000000000000000000012721314015360700166400ustar00rootroot00000000000000# Logs logs *.log # Runtime data pids *.pid *.seed # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directory # Commenting this out is preferred by some people, see # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- node_modules jspm_packages # Users Environment Variables .lock-wscript # Garbage files .DS_Store # Generated by integration tests test/fixtures/tmp test/fixtures/out vinyl-sourcemap-1.1.0/.jscsrc000066400000000000000000000000271314015360700161350ustar00rootroot00000000000000{ "preset": "gulp" } vinyl-sourcemap-1.1.0/.travis.yml000066400000000000000000000001711314015360700167560ustar00rootroot00000000000000sudo: false language: node_js node_js: - '6' - '5' - '4' - '0.12' - '0.10' after_script: - npm run coveralls vinyl-sourcemap-1.1.0/LICENSE000066400000000000000000000023461314015360700156600ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2017 Blaine Bublitz , Eric Schoffstall and other contributors (Based on code from gulp-sourcemaps - ISC License - Copyright (c) 2014, Florian Reiterer) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. vinyl-sourcemap-1.1.0/README.md000066400000000000000000000110241314015360700161230ustar00rootroot00000000000000

# vinyl-sourcemap [![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Gitter chat][gitter-image]][gitter-url] Add/write sourcemaps to/from Vinyl files. ## Usage ```js sourcemap.add(file, function(err, updatedFile) { // updatedFile will have a .sourceMap property }); // The 2nd argument can be given as a path string sourcemap.write(file, './maps', function(err, updatedFile, sourcemapFile) { // sourcemapFile will be a Vinyl file to be written to some location // updatedFile will have the .contents property updated with a sourceMappingURL that resolves to sourcemapFile }); // If not defined, the sourcemap is inlined sourcemap.write(file, function(err, updatedFile, sourcemapFile) { // sourcemapFile is undefined // updatedFile will have the .contents property updated with a sourceMappingURL that is an inlined sourcemap }); ``` ## API ### `sourcemap.add(file, callback)` Takes a [Vinyl][vinyl] `file` object and a `callback` function. It attempts to parse an inline sourcemap or load an external sourcemap for the file. If a valid sourcemap is found, the `sources` & `sourcesContent` properties are resolved to actual files (if possible) and a fully resolved sourcemap is attached as `file.sourceMap`. If a sourcemap is not found, a stub sourcemap is generated for the file and attached as `file.sourceMap`. Once all resolution is complete, the `callback(err, updatedFile)` is called with the `updatedFile`. If an error occurs, it will be passed as `err` and `updatedFile` will be undefined. __Note:__ The original file is mutated but `updatedFile` is passed to the callback as a convenience. If the `file` is not a Vinyl object or the contents are streaming, an Error will be passed to the `callback`. If the `file` has a `.sourceMap` property or the contents are null, the `callback` will be called immediately without mutation to the file. All filesystem operations are optional & non-fatal so any errors will not be bubbled to the `callback`. ### `sourcemap.write(file, [outputPath,] callback)` Takes a [Vinyl][vinyl] `file` object, (optionally) an `outputPath` string and a `callback` function. If `outputPath` is not passed, an inline sourcemap will be generated from the `file.sourceMap` property and appended to the `file.contents`. Once the inline sourcemap is appended, the `callback(err, updatedFile)` is called with the `updatedFile`. If an error occurs, it will be passed as `err` and `updatedFile` will be undefined. __Note:__ The original file is mutated but `updatedFile` is passed to the callback as a convenience. If `outputPath` is passed, a new Vinyl file will be generated using `file.cwd` and `file.base` from the original file, the path to the external sourcemap, and the `file.sourceMap` (as contents). The external location will be appended to the `file.contents` of the original file. Once the new file is created and location appended, the `callback(err, updatedFile, sourcemapFile)` is called with the `updatedFile` and the `sourcemapFile`. If an error occurs, it will be passed as `err` and `updatedFile`/`sourcemapFile` will be undefined. __Note:__ The original file is mutated but `updatedFile` is passed to the callback as a convenience. If the `file` is not a Vinyl object or the contents are streaming, an Error will be passed to the `callback`. If the `file` doesn't have a `.sourceMap` property or the contents are null, the `callback` will be called immediately without mutation to the file. ## License MIT [vinyl]: https://github.com/gulpjs/vinyl [downloads-image]: http://img.shields.io/npm/dm/vinyl-sourcemap.svg [npm-url]: https://npmjs.com/package/vinyl-sourcemap [npm-image]: http://img.shields.io/npm/v/vinyl-sourcemap.svg [travis-url]: https://travis-ci.org/gulpjs/vinyl-sourcemap [travis-image]: http://img.shields.io/travis/gulpjs/vinyl-sourcemap.svg?label=travis-ci [appveyor-url]: https://ci.appveyor.com/project/gulpjs/vinyl-sourcemap [appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/vinyl-sourcemap.svg?label=appveyor [coveralls-url]: https://coveralls.io/r/gulpjs/vinyl-sourcemap [coveralls-image]: http://img.shields.io/coveralls/gulpjs/vinyl-sourcemap/master.svg [gitter-url]: https://gitter.im/gulpjs/gulp [gitter-image]: https://badges.gitter.im/gulpjs/gulp.png vinyl-sourcemap-1.1.0/appveyor.yml000066400000000000000000000007211314015360700172360ustar00rootroot00000000000000# http://www.appveyor.com/docs/appveyor-yml # http://www.appveyor.com/docs/lang/nodejs-iojs environment: matrix: # node.js - nodejs_version: "0.10" - nodejs_version: "0.12" - nodejs_version: "4" - nodejs_version: "5" - nodejs_version: "6" install: - ps: Install-Product node $env:nodejs_version - npm install test_script: - node --version - npm --version - cmd: npm test build: off # build version format version: "{build}" vinyl-sourcemap-1.1.0/index.js000066400000000000000000000032441314015360700163160ustar00rootroot00000000000000'use strict'; var File = require('vinyl'); var helpers = require('./lib/helpers'); var PLUGIN_NAME = 'vinyl-sourcemap'; function add(file, callback) { // Bail early an error if the file argument is not a Vinyl file if (!File.isVinyl(file)) { return callback(new Error(PLUGIN_NAME + '-add: Not a vinyl file')); } // Bail early with an error if file has streaming contents if (file.isStream()) { return callback(new Error(PLUGIN_NAME + '-add: Streaming not supported')); } // Bail early successfully if file is null or already has a sourcemap if (file.isNull() || file.sourceMap) { return callback(null, file); } var state = { path: '', // Root path for the sources in the map map: null, content: file.contents.toString(), // TODO: handle this? preExistingComment: null, }; helpers.addSourceMaps(file, state, callback); } function write(file, destPath, callback) { // Check if options or a callback are passed as second argument if (typeof destPath === 'function') { callback = destPath; destPath = undefined; } // Bail early with an error if the file argument is not a Vinyl file if (!File.isVinyl(file)) { return callback(new Error(PLUGIN_NAME + '-write: Not a vinyl file')); } // Bail early with an error if file has streaming contents if (file.isStream()) { return callback(new Error(PLUGIN_NAME + '-write: Streaming not supported')); } // Bail early successfully if file is null or doesn't have sourcemap if (file.isNull() || !file.sourceMap) { return callback(null, file); } helpers.writeSourceMaps(file, destPath, callback); } module.exports = { add: add, write: write, }; vinyl-sourcemap-1.1.0/lib/000077500000000000000000000000001314015360700154145ustar00rootroot00000000000000vinyl-sourcemap-1.1.0/lib/helpers.js000066400000000000000000000133571314015360700174250ustar00rootroot00000000000000'use strict'; var path = require('path'); var fs = require('graceful-fs'); var nal = require('now-and-later'); var File = require('vinyl'); var convert = require('convert-source-map'); var removeBOM = require('remove-bom-buffer'); var appendBuffer = require('append-buffer'); var normalizePath = require('normalize-path'); var urlRegex = /^(https?|webpack(-[^:]+)?):\/\//; function isRemoteSource(source) { return source.match(urlRegex); } function parse(data) { try { return JSON.parse(removeBOM(data)); } catch (err) { // TODO: should this log a debug? } } function loadSourceMap(file, state, callback) { // Try to read inline source map state.map = convert.fromSource(state.content); if (state.map) { state.map = state.map.toObject(); // Sources in map are relative to the source file state.path = file.dirname; state.content = convert.removeComments(state.content); // Remove source map comment from source file.contents = new Buffer(state.content, 'utf8'); return callback(); } // Look for source map comment referencing a source map file var mapComment = convert.mapFileCommentRegex.exec(state.content); var mapFile; if (mapComment) { mapFile = path.resolve(file.dirname, mapComment[1] || mapComment[2]); state.content = convert.removeMapFileComments(state.content); // Remove source map comment from source file.contents = new Buffer(state.content, 'utf8'); } else { // If no comment try map file with same name as source file mapFile = file.path + '.map'; } // Sources in external map are relative to map file state.path = path.dirname(mapFile); fs.readFile(mapFile, onRead); function onRead(err, data) { if (err) { return callback(); } state.map = parse(data); callback(); } } // Fix source paths and sourceContent for imported source map function fixImportedSourceMap(file, state, callback) { if (!state.map) { return callback(); } state.map.sourcesContent = state.map.sourcesContent || []; nal.map(state.map.sources, normalizeSourcesAndContent, callback); function assignSourcesContent(sourceContent, idx) { state.map.sourcesContent[idx] = sourceContent; } function normalizeSourcesAndContent(sourcePath, idx, cb) { var sourceRoot = state.map.sourceRoot || ''; var sourceContent = state.map.sourcesContent[idx] || null; if (isRemoteSource(sourcePath)) { assignSourcesContent(sourceContent, idx); return cb(); } if (state.map.sourcesContent[idx]) { return cb(); } if (sourceRoot && isRemoteSource(sourceRoot)) { assignSourcesContent(sourceContent, idx); return cb(); } var basePath = path.resolve(file.base, sourceRoot); var absPath = path.resolve(state.path, sourceRoot, sourcePath); var relPath = path.relative(basePath, absPath); var unixRelPath = normalizePath(relPath); state.map.sources[idx] = unixRelPath; if (absPath !== file.path) { // Load content from file async return fs.readFile(absPath, onRead); } // If current file: use content assignSourcesContent(state.content, idx); cb(); function onRead(err, data) { if (err) { assignSourcesContent(null, idx); return cb(); } assignSourcesContent(removeBOM(data).toString('utf8'), idx); cb(); } } } function mapsLoaded(file, state, callback) { if (!state.map) { state.map = { version: 3, names: [], mappings: '', sources: [normalizePath(file.relative)], sourcesContent: [state.content], }; } state.map.file = normalizePath(file.relative); file.sourceMap = state.map; callback(); } function addSourceMaps(file, state, callback) { var tasks = [ loadSourceMap, fixImportedSourceMap, mapsLoaded, ]; function apply(fn, key, cb) { fn(file, state, cb); } nal.mapSeries(tasks, apply, done); function done() { callback(null, file); } } /* Write Helpers */ function createSourceMapFile(opts) { return new File({ cwd: opts.cwd, base: opts.base, path: opts.path, contents: new Buffer(JSON.stringify(opts.content)), stat: { isFile: function() { return true; }, isDirectory: function() { return false; }, isBlockDevice: function() { return false; }, isCharacterDevice: function() { return false; }, isSymbolicLink: function() { return false; }, isFIFO: function() { return false; }, isSocket: function() { return false; }, }, }); } var needsMultiline = ['.css']; function getCommentOptions(extname) { var opts = { multiline: (needsMultiline.indexOf(extname) !== -1), }; return opts; } function writeSourceMaps(file, destPath, callback) { var sourceMapFile; var commentOpts = getCommentOptions(file.extname); var comment; if (destPath == null) { // Encode source map into comment comment = convert.fromObject(file.sourceMap).toComment(commentOpts); } else { var mapFile = path.join(destPath, file.relative) + '.map'; var sourceMapPath = path.join(file.base, mapFile); // Create new sourcemap File sourceMapFile = createSourceMapFile({ cwd: file.cwd, base: file.base, path: sourceMapPath, content: file.sourceMap, }); var sourcemapLocation = path.relative(file.dirname, sourceMapPath); sourcemapLocation = normalizePath(sourcemapLocation); comment = convert.generateMapFileComment(sourcemapLocation, commentOpts); } // Append source map comment file.contents = appendBuffer(file.contents, comment); callback(null, file, sourceMapFile); } module.exports = { addSourceMaps: addSourceMaps, writeSourceMaps: writeSourceMaps, }; vinyl-sourcemap-1.1.0/package.json000066400000000000000000000025111314015360700171330ustar00rootroot00000000000000{ "name": "vinyl-sourcemap", "version": "1.1.0", "description": "Add/write sourcemaps to/from Vinyl files.", "author": "Gulp Team (http://gulpjs.com/)", "contributors": [ "Robin Venneman", "Blaine Bublitz " ], "repository": "gulpjs/vinyl-sourcemap", "license": "MIT", "engines": { "node": ">= 0.10" }, "main": "index.js", "files": [ "LICENSE", "index.js", "lib/" ], "scripts": { "lint": "eslint index.js lib/ test/add.js test/write.js && jscs index.js lib/ test/add.js test/write.js", "pretest": "npm run lint", "test": "mocha --async-only", "cover": "istanbul cover _mocha --report lcovonly", "coveralls": "npm run cover && istanbul-coveralls" }, "dependencies": { "append-buffer": "^1.0.2", "convert-source-map": "^1.5.0", "graceful-fs": "^4.1.6", "normalize-path": "^2.1.1", "now-and-later": "^2.0.0", "remove-bom-buffer": "^3.0.0", "vinyl": "^2.0.0" }, "devDependencies": { "eslint": "^1.10.3", "eslint-config-gulp": "^2.0.0", "expect": "^1.20.2", "istanbul": "^0.4.3", "istanbul-coveralls": "^1.0.3", "jscs": "^2.4.0", "jscs-preset-gulp": "^1.0.0", "mississippi": "^1.3.0", "mocha": "^3.2.0" }, "keywords": [ "vinyl", "sourcemap", "gulp" ] } vinyl-sourcemap-1.1.0/test/000077500000000000000000000000001314015360700156255ustar00rootroot00000000000000vinyl-sourcemap-1.1.0/test/.eslintrc000066400000000000000000000000351314015360700174470ustar00rootroot00000000000000{ "extends": "gulp/test" } vinyl-sourcemap-1.1.0/test/add.js000066400000000000000000000311771314015360700167240ustar00rootroot00000000000000'use strict'; var fs = require('fs'); var File = require('vinyl'); var path = require('path'); var expect = require('expect'); var convert = require('convert-source-map'); var miss = require('mississippi'); var sourcemaps = require('..'); var from = miss.from; var sourceContent = fs.readFileSync(path.join(__dirname, 'assets/helloworld.js')); function makeFile() { return new File({ cwd: __dirname, base: path.join(__dirname, 'assets'), path: path.join(__dirname, 'assets', 'helloworld.js'), contents: new Buffer(sourceContent), }); } function makeSourcemap() { return { file: 'all.js', mappings: 'AAAAA,QAAAC,IAAA,YACAD,QAAAC,IAAA,YCDAD,QAAAC,IAAA,YACAD,QAAAC,IAAA', names: ['console', 'log'], sourceRoot: path.join(__dirname, 'assets'), sources: ['test1.js', 'test2.js'], sourcesContent: ['console.log("line 1.1");\nconsole.log("line 1.2");\n', 'console.log("line 2.1");\nconsole.log("line 2.2");'], version: 3, }; } function makeFileWithInlineSourceMap() { var inline = convert.fromObject(makeSourcemap()).toComment(); return new File({ cwd: __dirname, base: path.join(__dirname, 'assets'), path: path.join(__dirname, 'assets', 'all.js'), contents: new Buffer('console.log("line 1.1"),console.log("line 1.2"),console.log("line 2.1"),console.log("line 2.2");\n' + inline), }); } describe('add', function() { it('errors if file argument is undefined', function(done) { sourcemaps.add(undefined, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-add: Not a vinyl file').toExist(); done(); }); }); it('errors if file argument is null', function(done) { sourcemaps.add(null, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-add: Not a vinyl file').toExist(); done(); }); }); it('errors if file argument is a plain object', function(done) { sourcemaps.add({}, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-add: Not a vinyl file').toExist(); done(); }); }); it('does not error if file argument is a Vinyl object with Buffer contents', function(done) { var file = makeFile(); sourcemaps.add(file, function(err) { expect(err).toNotExist(); done(); }); }); it('errors if file argument is a Vinyl object with Stream contents', function(done) { var file = makeFile(); file.contents = from([]); sourcemaps.add(file, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-add: Streaming not supported').toExist(); done(); }); }); it('calls back with the untouched file if file already has a sourcemap', function(done) { var sourceMap = { version: 3, names: [], mappings: '', sources: ['test.js'], sourcesContent: ['testContent'], }; var file = makeFile(); file.sourceMap = sourceMap; sourcemaps.add(file, function(err, data) { expect(data).toExist(); expect(File.isVinyl(data)).toEqual(true); expect(data.sourceMap).toBe(sourceMap); expect(data).toBe(file); done(err); }); }); it('calls back with the untouched file if file contents are null', function(done) { var file = makeFile(); file.contents = null; sourcemaps.add(file, function(err, outFile) { expect(err).toNotExist(); expect(file).toExist(); expect(outFile).toEqual(file); done(err); }); }); it('adds an empty sourceMap if none are found', function(done) { sourcemaps.add(makeFile(), function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.version).toEqual(3); expect(data.sourceMap.sources[0]).toEqual('helloworld.js'); expect(data.sourceMap.sourcesContent[0]).toEqual(sourceContent); expect(data.sourceMap.names).toEqual([]); expect(data.sourceMap.mappings).toEqual(''); done(err); }); }); it('imports an existing inline sourcemap', function(done) { sourcemaps.add(makeFileWithInlineSourceMap(), function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.version).toEqual(3); expect(data.sourceMap.sources).toEqual(['test1.js', 'test2.js']); expect(data.sourceMap.sourcesContent).toEqual(['console.log("line 1.1");\nconsole.log("line 1.2");\n', 'console.log("line 2.1");\nconsole.log("line 2.2");']); expect(data.sourceMap.mappings).toEqual('AAAAA,QAAAC,IAAA,YACAD,QAAAC,IAAA,YCDAD,QAAAC,IAAA,YACAD,QAAAC,IAAA'); done(err); }); }); it('removes an imported inline sourcemap', function(done) { sourcemaps.add(makeFileWithInlineSourceMap(), function(err, data) { expect(/sourceMappingURL/.test(data.contents.toString())).toEqual(false); done(err); }); }); it('loads external sourcemap file from \/\/# comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld2.js.map'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.version).toEqual(3); expect(data.sourceMap.sources).toEqual(['helloworld2.js']); expect(data.sourceMap.sourcesContent).toEqual(['source content from source map']); expect(data.sourceMap.mappings).toEqual(''); done(err); }); }); it('removes an imported sourcemap file \/\/# comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld2.js.map'); sourcemaps.add(file, function(err, data) { expect(/sourceMappingURL/.test(data.contents.toString())).toEqual(false); done(err); }); }); it('loads external sourcemap file from \/\/@ comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//@ sourceMappingURL=helloworld2.js.map'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.version).toEqual(3); expect(data.sourceMap.sources).toEqual(['helloworld2.js']); expect(data.sourceMap.sourcesContent).toEqual(['source content from source map']); expect(data.sourceMap.mappings).toEqual(''); done(err); }); }); it('removes an imported sourcemap file \/\/@ comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//@ sourceMappingURL=helloworld2.js.map'); sourcemaps.add(file, function(err, data) { expect(/sourceMappingURL/.test(data.contents.toString())).toEqual(false); done(err); }); }); it('loads external sourcemap file from \/*# *\/ comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n/*# sourceMappingURL=helloworld2.js.map */'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.version).toEqual(3); expect(data.sourceMap.sources).toEqual(['helloworld2.js']); expect(data.sourceMap.sourcesContent).toEqual(['source content from source map']); expect(data.sourceMap.mappings).toEqual(''); done(err); }); }); it('removes an imported sourcemap file \/*# *\/ comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n/*# sourceMappingURL=helloworld2.js.map */'); sourcemaps.add(file, function(err, data) { expect(/sourceMappingURL/.test(data.contents.toString())).toEqual(false); done(err); }); }); it('loads external sourcemap file from \/*@ *\/ comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n/*@ sourceMappingURL=helloworld2.js.map */'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.version).toEqual(3); expect(data.sourceMap.sources).toEqual(['helloworld2.js']); expect(data.sourceMap.sourcesContent).toEqual(['source content from source map']); expect(data.sourceMap.mappings).toEqual(''); done(err); }); }); it('removes an imported sourcemap file \/*@ *\/ comment', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n/*@ sourceMappingURL=helloworld2.js.map */'); sourcemaps.add(file, function(err, data) { expect(/sourceMappingURL/.test(data.contents.toString())).toEqual(false); done(err); }); }); it('loads external sourcemap by filename if no source mapping comment', function(done) { var file = makeFile(); file.path = file.path.replace('helloworld.js', 'helloworld2.js'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.version).toEqual(3); expect(data.sourceMap.sources).toEqual(['helloworld2.js']); expect(data.sourceMap.sourcesContent).toEqual(['source content from source map']); expect(data.sourceMap.mappings).toEqual(''); done(err); }); }); it('loads sourcesContent if missing', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld3.js.map'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.sourcesContent).toEqual([file.contents.toString(), 'test1\n']); done(err); }); }); it('does not error when source file for sourcesContent not found', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld4.js.map'); sourcemaps.add(file, function(err, data) { expect(err).toNotExist(); expect(data.sourceMap).toExist(); expect(data.sourceMap.sources).toEqual(['helloworld.js', 'missingfile']); expect(data.sourceMap.sourcesContent).toEqual([file.contents.toString(), null]); done(err); }); }); it('uses unix style paths in sourcemap', function(done) { var file = makeFile(); file.base = file.cwd; sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.file).toEqual('assets/helloworld.js'); expect(data.sourceMap.sources).toEqual(['assets/helloworld.js']); done(err); }); }); it('normalizes Windows paths in sources to unix paths', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld8.js.map'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.sources).toEqual(['../helloworld.js', '../test1.js']); done(err); }); }); it('sets file.relative as file property in sourcemap', function(done) { var file = makeFile(); file.stem = 'brandnew'; sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.file).toEqual('brandnew.js'); done(err); }); }); it('normalizes Windows paths in file.relative before using in sourcemap', function(done) { var file = makeFile(); file.stem = 'assets\\\\brandnew'; sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.file).toEqual('assets/brandnew.js'); done(err); }); }); it('uses relative sourceRoot to resolve sources', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld5.js.map'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.sourceRoot).toEqual('test'); expect(data.sourceMap.sourcesContent).toEqual([file.contents.toString(), 'test1\n']); done(err); }); }); it('uses absolute sourceRoot to resolve sources', function(done) { var file = makeFile(); var map = convert.fromObject(makeSourcemap()); delete map.sourcemap.sourcesContent; var inline = map.toComment(); file.contents = new Buffer(sourceContent + '\n' + inline); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.sourceRoot).toEqual(path.join(__dirname, 'assets')); expect(data.sourceMap.sourcesContent).toEqual(['test1\n', 'test2\n']); done(err); }); }); it('does not load sourcesContent when sourceRoot is a url', function(done) { var file = makeFile(); file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld6.js.map'); sourcemaps.add(file, function(err, data) { expect(data.sourceMap).toExist(); expect(data.sourceMap.sourceRoot).toEqual('http://example.com/'); expect(data.sourceMap.sourcesContent).toEqual([null, null]); done(err); }); }); }); vinyl-sourcemap-1.1.0/test/assets/000077500000000000000000000000001314015360700171275ustar00rootroot00000000000000vinyl-sourcemap-1.1.0/test/assets/helloworld.js000066400000000000000000000001071314015360700216360ustar00rootroot00000000000000'use strict'; function helloWorld() { console.log('Hello world!'); } vinyl-sourcemap-1.1.0/test/assets/helloworld2.js.map000066400000000000000000000002351314015360700224760ustar00rootroot00000000000000{ "version":3, "file":"helloworld2.js", "names":[], "mappings":"", "sources":["helloworld2.js"], "sourcesContent":["source content from source map"] } vinyl-sourcemap-1.1.0/test/assets/helloworld3.js.map000066400000000000000000000001661314015360700225020ustar00rootroot00000000000000{ "version": 3, "file": "helloworld.js", "names": [], "mappings": "", "sources": ["helloworld.js", "test1.js"] } vinyl-sourcemap-1.1.0/test/assets/helloworld4.js.map000066400000000000000000000001711314015360700224770ustar00rootroot00000000000000{ "version": 3, "file": "helloworld.js", "names": [], "mappings": "", "sources": ["helloworld.js", "missingfile"] } vinyl-sourcemap-1.1.0/test/assets/helloworld5.js.map000066400000000000000000000002231314015360700224760ustar00rootroot00000000000000{ "version": 3, "file": "helloworld.js", "names": [], "mappings": "", "sources": ["../helloworld.js", "../test1.js"], "sourceRoot": "test" } vinyl-sourcemap-1.1.0/test/assets/helloworld6.js.map000066400000000000000000000002601314015360700225000ustar00rootroot00000000000000{ "version": 3, "file": "helloworld.js", "names": [], "mappings": "", "sources": ["helloworld.js", "http://example2.com/test1.js"], "sourceRoot": "http://example.com/" } vinyl-sourcemap-1.1.0/test/assets/helloworld7.js.map000066400000000000000000000002161314015360700225020ustar00rootroot00000000000000{ "version": 3, "file": "helloworld.js", "names": [], "mappings": "", "sources": ["helloworld.js", "test1.js"], "sourceRoot": "/test" } vinyl-sourcemap-1.1.0/test/assets/helloworld8.js.map000066400000000000000000000002271314015360700225050ustar00rootroot00000000000000{ "version": 3, "file": "helloworld.js", "names": [], "mappings": "", "sources": ["..\\helloworld.js", "..\\test1.js"], "sourceRoot": "" } vinyl-sourcemap-1.1.0/test/assets/test.css000066400000000000000000000000521314015360700206150ustar00rootroot00000000000000body { background: #eee; color: #888; } vinyl-sourcemap-1.1.0/test/assets/test1.js000066400000000000000000000000061314015360700205210ustar00rootroot00000000000000test1 vinyl-sourcemap-1.1.0/test/assets/test2.js000066400000000000000000000000061314015360700205220ustar00rootroot00000000000000test2 vinyl-sourcemap-1.1.0/test/write.js000066400000000000000000000173031314015360700173210ustar00rootroot00000000000000'use strict'; var fs = require('fs'); var path = require('path'); var File = require('vinyl'); var expect = require('expect'); var miss = require('mississippi'); var sourcemaps = require('..'); var from = miss.from; var sourceContent = fs.readFileSync(path.join(__dirname, 'assets/helloworld.js')).toString(); function makeSourceMap() { return { version: 3, file: 'helloworld.js', names: [], mappings: '', sources: ['helloworld.js'], sourcesContent: [sourceContent], }; } function makeFile() { var file = new File({ cwd: __dirname, base: path.join(__dirname, 'assets'), path: path.join(__dirname, 'assets', 'helloworld.js'), contents: new Buffer(sourceContent), sourceMap: makeSourceMap(), }); return file; } function makeNestedFile() { var file = new File({ cwd: __dirname, base: path.join(__dirname, 'assets'), path: path.join(__dirname, 'assets', 'dir1', 'dir2', 'helloworld.js'), contents: new Buffer(sourceContent), }); file.sourceMap = makeSourceMap(); return file; } function base64JSON(object) { return 'data:application/json;charset=utf-8;base64,' + new Buffer(JSON.stringify(object)).toString('base64'); } describe('write', function() { it('errors if file argument is undefined', function(done) { sourcemaps.write(undefined, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-write: Not a vinyl file').toExist(); done(); }); }); it('errors if file argument is null', function(done) { sourcemaps.write(null, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-write: Not a vinyl file').toExist(); done(); }); }); it('errors if file argument is a plain object', function(done) { sourcemaps.write({}, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-write: Not a vinyl file').toExist(); done(); }); }); it('does not error if file argument is a Vinyl object with Buffer contents', function(done) { var file = makeFile(); sourcemaps.write(file, function(err) { expect(err).toNotExist(); done(); }); }); it('errors if file argument is a Vinyl object with Stream contents', function(done) { var file = makeFile(); file.contents = from([]); sourcemaps.write(file, function(err) { expect(err instanceof Error && err.message === 'vinyl-sourcemap-write: Streaming not supported').toExist(); done(); }); }); it('accepts null destPath argument', function(done) { var file = makeFile(); sourcemaps.write(file, null, function(err) { expect(err).toNotExist(); done(err); }); }); it('accepts undefined destPath argument', function(done) { var file = makeFile(); sourcemaps.write(file, undefined, function(err) { expect(err).toNotExist(); done(err); }); }); it('accepts string destPath argument', function(done) { var file = makeFile(); sourcemaps.write(file, 'something', function(err) { expect(err).toNotExist(); done(err); }); }); it('juggles callback if no destPath argument', function(done) { var file = makeFile(); sourcemaps.write(file, function(err) { expect(err).toNotExist(); done(err); }); }); it('calls back with the untouched file if sourceMap property does not exist', function(done) { var file = makeFile(); delete file.sourceMap; sourcemaps.write(file, function(err, outFile) { expect(err).toNotExist(); expect(file).toExist(); expect(outFile).toEqual(file); done(err); }); }); it('calls back with the untouched file if file contents are null', function(done) { var file = makeFile(); file.contents = null; sourcemaps.write(file, function(err, outFile) { expect(err).toNotExist(); expect(file).toExist(); expect(outFile).toEqual(file); done(err); }); }); it('writes an inline sourcemap when no destPath', function(done) { var file = makeFile(); sourcemaps.write(file, function(err, updatedFile, sourceMapFile) { expect(updatedFile).toExist(); expect(sourceMapFile).toNotExist(); expect(File.isVinyl(updatedFile)).toEqual(true); expect(updatedFile).toEqual(file); expect(updatedFile.contents).toEqual(sourceContent + '//# sourceMappingURL=' + base64JSON(updatedFile.sourceMap) + '\n'); done(err); }); }); it('writes /*# */ comment if .css extension', function(done) { var file = makeFile(); file.path = file.path.replace('.js', '.css'); sourcemaps.write(file, function(err, updatedFile) { expect(updatedFile.contents).toEqual(sourceContent + '/*# sourceMappingURL=' + base64JSON(updatedFile.sourceMap) + ' */\n'); done(err); }); }); it('write \/\/# comment if any non-.css extension', function(done) { var file = makeFile(); file.path = file.path.replace('.js', '.txt'); sourcemaps.write(file, function(err, updatedFile) { expect(updatedFile.contents).toEqual(sourceContent + '//# sourceMappingURL=' + base64JSON(updatedFile.sourceMap) + '\n'); done(err); }); }); it('uses \\n or \\r\\n depending on the existing style', function(done) { var file = makeFile(); var customContents = sourceContent.replace(/\n/g, '\r\n'); file.contents = new Buffer(customContents); sourcemaps.write(file, function(err, updatedFile) { expect(updatedFile.contents).toEqual(customContents + '//# sourceMappingURL=' + base64JSON(updatedFile.sourceMap) + '\r\n'); done(err); }); }); it('writes an external sourcemap when given a destPath', function(done) { var file = makeFile(); sourcemaps.write(file, '../maps', function(err, updatedFile, sourceMapFile) { expect(File.isVinyl(updatedFile)).toEqual(true); expect(updatedFile).toEqual(file); expect(updatedFile.contents).toEqual(sourceContent + '//# sourceMappingURL=../maps/helloworld.js.map\n'); expect(File.isVinyl(sourceMapFile)).toEqual(true); expect(sourceMapFile.path).toEqual(path.join(__dirname, 'maps/helloworld.js.map')); expect(JSON.parse(sourceMapFile.contents)).toEqual(updatedFile.sourceMap); expect(sourceMapFile.stat.isFile()).toEqual(true); expect(sourceMapFile.stat.isDirectory()).toEqual(false); expect(sourceMapFile.stat.isBlockDevice()).toEqual(false); expect(sourceMapFile.stat.isCharacterDevice()).toEqual(false); expect(sourceMapFile.stat.isSymbolicLink()).toEqual(false); expect(sourceMapFile.stat.isFIFO()).toEqual(false); expect(sourceMapFile.stat.isSocket()).toEqual(false); done(err); }); }); it('create shortest path to map in file comment', function(done) { var file = makeNestedFile(); sourcemaps.write(file, 'dir1/maps', function(err, updatedFile) { expect(updatedFile.contents).toEqual(sourceContent + '//# sourceMappingURL=../maps/dir1/dir2/helloworld.js.map\n'); done(err); }); }); // TODO: need to figure out this test it.skip('normalizes Windows paths to unix style', function(done) { var file = makeNestedFile(); file.path = file.path.replace(/\//g, '\\\\'); console.log(file.path); sourcemaps.write(file, '..\\\\maps', function(err, updatedFile) { expect(updatedFile.contents).toEqual(sourceContent + '//# sourceMappingURL=../maps/helloworld.js.map\n'); done(err); }); }); // TODO: need to figure out this test it.skip('properly handles remote paths', function(done) { var file = makeNestedFile(); sourcemaps.write(file, 'http://example.com', function(err, updatedFile) { expect(updatedFile.contents).toEqual(sourceContent + '//# sourceMappingURL=http://example.com/dir1/dir2/helloworld.js.map\n'); done(err); }); }); });