diff --git a/lib/precompiler.js b/lib/precompiler.js index 2b3fb69d..1fb0093d 100644 --- a/lib/precompiler.js +++ b/lib/precompiler.js @@ -153,7 +153,8 @@ function loadFiles(opts, callback) { ); } -module.exports.cli = function (opts) { +module.exports.cli = async function (opts) { + // TODO what implications does this have? if (opts.version) { console.log(Handlebars.VERSION); return; @@ -222,7 +223,7 @@ module.exports.cli = function (opts) { output.add('{};\n'); } - opts.templates.forEach(function (template) { + for (const template of opts.templates) { let options = { knownHelpers: known, knownHelpersOnly: opts.o, @@ -239,11 +240,12 @@ module.exports.cli = function (opts) { // If we are generating a source map, we have to reconstruct the SourceNode object if (opts.map) { - let consumer = new SourceMapConsumer(precompiled.map); + let consumer = await new SourceMapConsumer(precompiled.map); precompiled = SourceNode.fromStringWithSourceMap( precompiled.code, consumer ); + consumer.destroy(); } if (opts.simple) { @@ -265,7 +267,7 @@ module.exports.cli = function (opts) { ');\n', ]); } - }); + } // Output the content if (!opts.simple) { diff --git a/package-lock.json b/package-lock.json index 35076066..22120e49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@handlebars/parser": "^2.1.0", "neo-async": "^2.6.2", - "source-map": "^0.6.1", + "source-map": "^0.7.4", "yargs": "^16.2.0" }, "bin": { @@ -8230,6 +8230,15 @@ "ms": "^2.1.1" } }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/istanbul-reports": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", @@ -9559,6 +9568,15 @@ "source-map": "^0.6.1" } }, + "node_modules/merge-source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -12897,11 +12915,11 @@ "dev": true }, "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, "node_modules/source-map-resolve": { @@ -13798,6 +13816,15 @@ "node": ">=0.8.0" } }, + "node_modules/uglify-js/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/uglify-to-browserify": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", @@ -21169,6 +21196,12 @@ "requires": { "ms": "^2.1.1" } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -22223,6 +22256,14 @@ "dev": true, "requires": { "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "merge-stream": { @@ -24943,9 +24984,9 @@ "dev": true }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" }, "source-map-resolve": { "version": "0.5.3", @@ -25663,6 +25704,14 @@ "requires": { "commander": "~2.20.3", "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "uglify-to-browserify": { diff --git a/package.json b/package.json index 8d732c21..9e921f81 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "dependencies": { "@handlebars/parser": "^2.1.0", "neo-async": "^2.6.2", - "source-map": "^0.6.1", + "source-map": "^0.7.4", "yargs": "^16.2.0" }, "peerDependencies": { diff --git a/spec/precompiler.js b/spec/precompiler.js index 857f64e2..976f51d6 100644 --- a/spec/precompiler.js +++ b/spec/precompiler.js @@ -83,14 +83,15 @@ describe('precompiler', function () { console.error = errorLogFunction; }); - it('should output version', function () { - Precompiler.cli({ templates: [], version: true }); + it('should output version', async function () { + // TODO do this for all other tests + await Precompiler.cli({ templates: [], version: true }); equals(log, Handlebars.VERSION); }); it('should throw if lacking templates', function () { shouldThrow( - function () { - Precompiler.cli({ templates: [] }); + async function () { + await Precompiler.cli({ templates: [] }); }, Handlebars.Exception, 'Must define at least one template or directory.' diff --git a/spec/source-map.js b/spec/source-map.js index 5eb10967..81274245 100644 --- a/spec/source-map.js +++ b/spec/source-map.js @@ -21,7 +21,7 @@ describe('source-map', function () { equal(!!template.code, true); equal(!!template.map, !CompilerContext.browser); }); - it('should map source properly', function () { + it('should map source properly', async function () { var templateSource = ' b{{hello}} \n {{bar}}a {{#block arg hash=(subex 1 subval)}}{{/block}}', template = Handlebars.precompile(templateSource, { @@ -30,13 +30,15 @@ describe('source-map', function () { }); if (template.map) { - var consumer = new SourceMapConsumer(template.map), + var consumer = await new SourceMapConsumer(template.map), lines = template.code.split('\n'), srcLines = templateSource.split('\n'), generated = grepLine('" b"', lines), source = grepLine(' b', srcLines); var mapped = consumer.originalPositionFor(generated); + consumer.destroy(); + equal(mapped.line, source.line); equal(mapped.column, source.column); } diff --git a/tests/print-script.js b/tests/print-script.js index c8d9ddbb..e92b0e2a 100755 --- a/tests/print-script.js +++ b/tests/print-script.js @@ -1,114 +1,119 @@ /* eslint-disable no-console, no-var */ // Util script for debugging source code generation issues +// Example: `node tests/print-script.js "Test: {{ foo }}" -v` -var script = process.argv[2].replace(/\\n/g, '\n'), - verbose = process.argv[3] === '-v'; +const Handlebars = require('./../lib'); +const SourceMap = require('source-map'); +const SourceMapConsumer = SourceMap.SourceMapConsumer; -var Handlebars = require('./../lib'), - SourceMap = require('source-map'), - SourceMapConsumer = SourceMap.SourceMapConsumer; +const script = process.argv[2].replace(/\\n/g, '\n'); +const verbose = process.argv[3] === '-v'; -var template = Handlebars.precompile(script, { - srcName: 'input.hbs', - destName: 'output.js', +async function generateSourceCode(script, verbose) { + var template = Handlebars.precompile(script, { + srcName: 'input.hbs', + destName: 'output.js', - assumeObjects: true, - compat: false, - strict: true, - trackIds: true, - knownHelpersOnly: false, -}); + assumeObjects: true, + compat: false, + strict: true, + knownHelpersOnly: false, + }); -if (!verbose) { - console.log(template); -} else { - var consumer = new SourceMapConsumer(template.map), - lines = template.code.split('\n'), - srcLines = script.split('\n'); + if (!verbose) { + console.log(template); + } else { + const consumer = await new SourceMapConsumer(template.map); + let lines = template.code.split('\n'); + let srcLines = script.split('\n'); - console.log(); - console.log('Source:'); - srcLines.forEach(function (source, index) { - console.log(index + 1, source); - }); - console.log(); - console.log('Generated:'); - console.log(template.code); - lines.forEach(function (source, index) { - console.log(index + 1, source); - }); - console.log(); - console.log('Map:'); - console.log(template.map); - console.log(); + console.log(); + console.log('Source:'); + srcLines.forEach(function (source, index) { + console.log(index + 1, source); + }); + console.log(); + console.log('Generated:'); + console.log(template.code); + lines.forEach(function (source, index) { + console.log(index + 1, source); + }); + console.log(); + console.log('Map:'); + console.log(template.map); + console.log(); - // eslint-disable-next-line no-inner-declarations - function collectSource(lines, lineName, colName, order) { - var ret = {}, - ordered = [], - last; + // eslint-disable-next-line no-inner-declarations + function collectSource(lines, lineName, colName, order) { + var ret = {}, + ordered = [], + last; - function collect(current) { - if (last) { - var mapLines = lines.slice( - last[lineName] - 1, - current && current[lineName] - ); - if (mapLines.length) { - if (current) { - mapLines[mapLines.length - 1] = mapLines[mapLines.length - 1].slice( - 0, - current[colName] - ); + function collect(current) { + if (last) { + var mapLines = lines.slice( + last[lineName] - 1, + current && current[lineName] + ); + if (mapLines.length) { + if (current) { + mapLines[mapLines.length - 1] = mapLines[ + mapLines.length - 1 + ].slice(0, current[colName]); + } + mapLines[0] = mapLines[0].slice(last[colName]); } - mapLines[0] = mapLines[0].slice(last[colName]); + ret[last[lineName] + ':' + last[colName]] = mapLines.join('\n'); + ordered.push({ + startLine: last[lineName], + startCol: last[colName], + endLine: current && current[lineName], + }); } - ret[last[lineName] + ':' + last[colName]] = mapLines.join('\n'); - ordered.push({ - startLine: last[lineName], - startCol: last[colName], - endLine: current && current[lineName], - }); + last = current; } - last = current; - } - consumer.eachMapping(collect, undefined, order); - collect(); + consumer.eachMapping(collect, undefined, order); + collect(); - return ret; - } + return ret; + } - srcLines = collectSource( - srcLines, - 'originalLine', - 'originalColumn', - SourceMapConsumer.ORIGINAL_ORDER - ); - lines = collectSource(lines, 'generatedLine', 'generatedColumn'); + srcLines = collectSource( + srcLines, + 'originalLine', + 'originalColumn', + SourceMapConsumer.ORIGINAL_ORDER + ); + lines = collectSource(lines, 'generatedLine', 'generatedColumn'); - consumer.eachMapping(function (mapping) { - var originalSrc = - srcLines[mapping.originalLine + ':' + mapping.originalColumn], - generatedSrc = - lines[mapping.generatedLine + ':' + mapping.generatedColumn]; + consumer.eachMapping(function (mapping) { + var originalSrc = + srcLines[mapping.originalLine + ':' + mapping.originalColumn], + generatedSrc = + lines[mapping.generatedLine + ':' + mapping.generatedColumn]; - if (!mapping.originalLine) { - console.log( - 'generated', - mapping.generatedLine + ':' + mapping.generatedColumn, - generatedSrc - ); - } else { - console.log( - 'map', - mapping.source, - mapping.originalLine + ':' + mapping.originalColumn, - originalSrc, - '->', - mapping.generatedLine + ':' + mapping.generatedColumn, - generatedSrc - ); - } - }); + if (!mapping.originalLine) { + console.log( + 'generated', + mapping.generatedLine + ':' + mapping.generatedColumn, + generatedSrc + ); + } else { + console.log( + 'map', + mapping.source, + mapping.originalLine + ':' + mapping.originalColumn, + originalSrc, + '->', + mapping.generatedLine + ':' + mapping.generatedColumn, + generatedSrc + ); + } + }); + + consumer.destroy(); + } } + +generateSourceCode(script, verbose);