Skip to content
This repository has been archived by the owner on Dec 8, 2024. It is now read-only.

Commit

Permalink
Merge pull request #75 from rwjblue/accept-options
Browse files Browse the repository at this point in the history
Add ability to pass static options to transpilation.
  • Loading branch information
rwjblue authored Aug 30, 2019
2 parents cbe5718 + cb5e610 commit c47570a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 16 deletions.
63 changes: 51 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,37 @@ const parseModuleName = require('./lib/parse-module-name');
module.exports = function(babel) {
let t = babel.types;

function compileTemplate(precompile, template) {
let options = {
contents: template
}
function compileTemplate(precompile, template, _options) {
let options = Object.assign({ contents: template }, _options);

let compiledTemplateString = `Ember.HTMLBars.template(${precompile(template, options)})`;

return compiledTemplateString;
}

function parseObjectExpression(buildError, node) {
let result = {};

node.properties.forEach(property => {
if (property.computed || property.key.type !== "Identifier") {
throw buildError("hbs can only accept static options");
}

let value;
if (property.value.type === "ObjectExpression") {
value = parseObjectExpression(buildError, property.value);
} else if (["StringLiteral", "NumericLiteral", "BooleanLiteral"].indexOf(property.value.type) > -1) {
value = property.value.value;
} else {
throw buildError("hbs can only accept static options");
}

result[property.key.name] = value;
});

return result;
}

return {
visitor: {
ImportDeclaration(path, state) {
Expand Down Expand Up @@ -63,7 +84,7 @@ module.exports = function(babel) {
options.meta.moduleName = moduleName;
}

path.replaceWithSourceString(compileTemplate(state.opts.precompile, template, state.file.opts.filename));
path.replaceWithSourceString(compileTemplate(state.opts.precompile, template));
},

CallExpression(path, state) {
Expand All @@ -74,17 +95,35 @@ module.exports = function(babel) {
return;
}

let argumentErrorMsg = "hbs should be invoked with a single argument: the template string";
if (path.node.arguments.length !== 1) {
throw path.buildCodeFrameError(argumentErrorMsg);
let options;

let template = path.node.arguments[0];
if (template === undefined || typeof template.value !== "string") {
throw path.buildCodeFrameError("hbs should be invoked with at least a single argument: the template string");
}

let template = path.node.arguments[0].value;
if (typeof template !== "string") {
throw path.buildCodeFrameError(argumentErrorMsg);
switch (path.node.arguments.length) {
case 0:
throw path.buildCodeFrameError("hbs should be invoked with at least a single argument: the template string");
case 1:
break;
case 2: {
let astOptions = path.node.arguments[1];
if (astOptions.type !== "ObjectExpression") {
throw path.buildCodeFrameError("hbs can only be invoked with 2 arguments: the template string, and any static options");
}

options = parseObjectExpression(path.buildCodeFrameError.bind(path), astOptions);

break;
}
default:
throw path.buildCodeFrameError("hbs can only be invoked with 2 arguments: the template string, and any static options");
}

path.replaceWithSourceString(compileTemplate(state.opts.precompile, template, state.file.opts.filename));
let { precompile } = state.opts;

path.replaceWithSourceString(compileTemplate(precompile, template.value, options));
},
}
};
Expand Down
21 changes: 17 additions & 4 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ describe("htmlbars-inline-precompile", function() {
});
});

it('allows static userland options when used as a call expression', function() {
let source = 'hello';
transform(`import hbs from 'htmlbars-inline-precompile';\nvar compiled = hbs('${source}', { parseOptions: { srcName: 'bar.hbs' }, moduleName: 'foo/bar.hbs', xyz: 123, qux: true });`);

expect(optionsReceived).toEqual({
contents: source,
parseOptions: { srcName: 'bar.hbs' },
moduleName: 'foo/bar.hbs',
xyz: 123,
qux: true
});
});

it('passes options when used as a tagged template string', function() {
let source = 'hello';
transform(`import hbs from 'htmlbars-inline-precompile';\nvar compiled = hbs\`${source}\`;`);
Expand Down Expand Up @@ -138,19 +151,19 @@ describe("htmlbars-inline-precompile", function() {
expect(transformed).toEqual("var compiled = Ember.HTMLBars.template(precompiled(hello));", "tagged template is replaced");
});

it("warns when more than one argument is passed", function() {
it("warns when the second argument is not an object", function() {
expect(() => transform("import hbs from 'htmlbars-inline-precompile';\nvar compiled = hbs('first', 'second');"))
.toThrow(/hbs should be invoked with a single argument: the template string/);
.toThrow(/hbs can only be invoked with 2 arguments: the template string, and any static options/);
});

it("warns when argument is not a string", function() {
expect(() => transform("import hbs from 'htmlbars-inline-precompile';\nvar compiled = hbs(123);"))
.toThrow(/hbs should be invoked with a single argument: the template string/);
.toThrow(/hbs should be invoked with at least a single argument: the template string/);
});

it("warns when no argument is passed", function() {
expect(() => transform("import hbs from 'htmlbars-inline-precompile';\nvar compiled = hbs();"))
.toThrow(/hbs should be invoked with a single argument: the template string/);
.toThrow(/hbs should be invoked with at least a single argument: the template string/);
});
});
});

0 comments on commit c47570a

Please sign in to comment.