Socket
Socket
Sign inDemoInstall

ember-cli-htmlbars

Package Overview
Dependencies
Maintainers
5
Versions
112
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ember-cli-htmlbars - npm Package Compare versions

Comparing version 4.4.1 to 4.5.0

10

CHANGELOG.md

@@ -0,1 +1,11 @@

## v4.5.0 (2021-03-03)
#### :rocket: Enhancement
* [#673](https://github.com/ember-cli/ember-cli-htmlbars/pull/673) Backport template compiler improvements from 5.x ([@rwjblue](https://github.com/rwjblue))
* [#661](https://github.com/ember-cli/ember-cli-htmlbars/pull/661) Remove usage of registerPlugin / unregisterPlugin ([@rwjblue](https://github.com/rwjblue))
* [#660](https://github.com/ember-cli/ember-cli-htmlbars/pull/660) Replace `purgeModule` cache busting with `vm` based sandboxing ([@rwjblue](https://github.com/rwjblue))
#### Committers: 1
- Robert Jackson ([@rwjblue](https://github.com/rwjblue))
## v4.4.1 (2021-02-05)

@@ -2,0 +12,0 @@

52

lib/template-compiler-plugin.js
'use strict';
const fs = require('fs');
const path = require('path');

@@ -43,5 +42,4 @@ const utils = require('./utils');

let { templateCompiler, plugins, EmberENV } = options;
let { templateCompiler, EmberENV } = options;
utils.registerPlugins(templateCompiler, plugins);
utils.initializeEmberENV(templateCompiler, EmberENV);

@@ -54,15 +52,2 @@ }

unregisterPlugins() {
let { templateCompiler, plugins } = this.options;
utils.unregisterPlugins(templateCompiler, plugins);
}
registeredASTPlugins() {
// This is a super obtuse way to get access to the plugins we've registered
// it also returns other plugins that are registered by ember itself.
let options = this.options.templateCompiler.compileOptions();
return (options.plugins && options.plugins.ast) || [];
}
processString(string, relativePath) {

@@ -72,2 +57,13 @@ let srcDir = this.inputPaths[0];

try {
// we have to reverse these for reasons that are a bit bonkers. the initial
// version of this system used `registeredPlugin` from
// `ember-template-compiler.js` to set up these plugins (because Ember ~ 1.13
// only had `registerPlugin`, and there was no way to pass plugins directly
// to the call to `compile`/`precompile`). calling `registerPlugin`
// unfortunately **inverted** the order of plugins (it essentially did
// `PLUGINS = [plugin, ...PLUGINS]`).
//
// sooooooo...... we are forced to maintain that **absolutely bonkers** ordering
let astPlugins = this.options.plugins ? [].concat(this.options.plugins.ast).reverse() : [];
let result =

@@ -82,6 +78,14 @@ 'export default ' +

},
// intentionally not using `plugins: this.options.plugins` here
// because if we do, Ember will mutate the shared plugins object (adding
// all of the built in AST transforms into plugins.ast, which breaks
// persistent caching)
plugins: {
ast: astPlugins,
},
}) +
';';
if (this.options.dependencyInvalidation) {
let plugins = pluginsWithDependencies(this.registeredASTPlugins());
let plugins = pluginsWithDependencies(this.options.plugins.ast);
let dependencies = [];

@@ -112,16 +116,12 @@ for (let i = 0; i < plugins.length; i++) {

_templateCompilerContents() {
if (this.options.templateCompilerPath) {
return fs.readFileSync(this.options.templateCompilerPath, { encoding: 'utf8' });
} else {
return '';
}
}
optionsHash() {
if (!this._optionsHash) {
let templateCompilerCacheKey = utils.getTemplateCompilerCacheKey(
this.options.templateCompilerPath
);
this._optionsHash = crypto
.createHash('md5')
.update(stringify(this._buildOptionsForHash()), 'utf8')
.update(stringify(this._templateCompilerContents()), 'utf8')
.update(templateCompilerCacheKey, 'utf8')
.digest('hex');

@@ -128,0 +128,0 @@ }

'use strict';
const crypto = require('crypto');
const fs = require('fs');

@@ -9,3 +10,6 @@ const path = require('path');

const addDependencyTracker = require('./addDependencyTracker');
const vm = require('vm');
const TemplateCompilerCache = new Map();
const INLINE_PRECOMPILE_MODULES = Object.freeze({

@@ -83,14 +87,6 @@ 'ember-cli-htmlbars': 'hbs',

purgeModule(templateCompilerPath);
// do a full clone of the EmberENV (it is guaranteed to be structured
// cloneable) to prevent ember-template-compiler.js from mutating
// the shared global config
let clonedEmberENV = JSON.parse(JSON.stringify(EmberENV));
global.EmberENV = clonedEmberENV; // Needed for eval time feature flag checks
let htmlbarsOptions = {
isHTMLBars: true,
EmberENV: EmberENV,
templateCompiler: require(templateCompilerPath),
templateCompiler: getTemplateCompiler(templateCompilerPath, EmberENV),
templateCompilerPath: templateCompilerPath,

@@ -107,53 +103,60 @@

purgeModule(templateCompilerPath);
delete global.Ember;
delete global.EmberENV;
return htmlbarsOptions;
}
function purgeModule(templateCompilerPath) {
// ensure we get a fresh templateCompilerModuleInstance per ember-addon
// instance NOTE: this is a quick hack, and will only work as long as
// templateCompilerPath is a single file bundle
//
// (╯°□°)╯︵ ɹǝqɯǝ
//
// we will also fix this in ember for future releases
function getTemplateCompiler(templateCompilerPath, EmberENV = {}) {
let templateCompilerFullPath = require.resolve(templateCompilerPath);
let cacheData = TemplateCompilerCache.get(templateCompilerFullPath);
// Module will be cached in .parent.children as well. So deleting from require.cache alone is not sufficient.
let mod = require.cache[templateCompilerPath];
if (mod && mod.parent) {
let index = mod.parent.children.indexOf(mod);
if (index >= 0) {
mod.parent.children.splice(index, 1);
} else {
throw new TypeError(
`ember-cli-htmlbars attempted to purge '${templateCompilerPath}' but something went wrong.`
);
}
if (cacheData === undefined) {
let templateCompilerContents = fs.readFileSync(templateCompilerFullPath, { encoding: 'utf-8' });
let templateCompilerCacheKey = crypto
.createHash('md5')
.update(templateCompilerContents)
.digest('hex');
cacheData = {
script: new vm.Script(templateCompilerContents, {
filename: templateCompilerPath,
}),
templateCompilerCacheKey,
};
TemplateCompilerCache.set(templateCompilerFullPath, cacheData);
}
delete require.cache[templateCompilerPath];
}
let { script } = cacheData;
function registerPlugins(templateCompiler, plugins) {
if (plugins) {
for (let type in plugins) {
for (let i = 0, l = plugins[type].length; i < l; i++) {
templateCompiler.registerPlugin(type, plugins[type][i]);
}
}
// do a full clone of the EmberENV (it is guaranteed to be structured
// cloneable) to prevent ember-template-compiler.js from mutating
// the shared global config
let clonedEmberENV = JSON.parse(JSON.stringify(EmberENV));
let sandbox = {
EmberENV: clonedEmberENV,
// Older versions of ember-template-compiler (up until ember-source@3.1.0)
// eagerly access `setTimeout` without checking via `typeof` first
setTimeout,
clearTimeout,
// fake the module into thinking we are running inside a Node context
module: { require, exports: {} },
require,
};
// if we are running on a Node version _without_ a globalThis
// we must provide a `global`
//
// this is due to https://git.io/Jtb7s (Ember 3.27+)
if (typeof globalThis === 'undefined') {
sandbox.global = sandbox;
}
}
function unregisterPlugins(templateCompiler, plugins) {
if (plugins) {
for (let type in plugins) {
for (let i = 0, l = plugins[type].length; i < l; i++) {
templateCompiler.unregisterPlugin(type, plugins[type][i]);
}
}
}
let context = vm.createContext(sandbox);
script.runInContext(context);
return context.module.exports;
}

@@ -202,7 +205,18 @@

registerPlugins(templateCompiler, {
ast: pluginInfo.plugins,
});
let templatePrecompile = templateCompiler.precompile;
let { precompile } = templateCompiler;
let precompile = (template, options) => {
let plugins = pluginInfo.plugins || [];
// concat so we ensure we don't mutate the original plugins
// reverse to ensure that original AST plugin ordering is preserved
let astPlugins = [].concat(plugins).reverse();
options = options || {};
options.plugins = {
ast: astPlugins,
};
return templatePrecompile(template, options);
};
precompile.baseDir = () => path.resolve(__dirname, '..');

@@ -227,6 +241,18 @@

function getTemplateCompilerCacheKey(templateCompilerPath) {
let templateCompilerFullPath = require.resolve(templateCompilerPath);
let cacheData = TemplateCompilerCache.get(templateCompilerFullPath);
if (cacheData === undefined) {
getTemplateCompiler(templateCompilerFullPath);
cacheData = TemplateCompilerCache.get(templateCompilerFullPath);
}
return cacheData.templateCompilerCacheKey;
}
function makeCacheKey(templateCompilerPath, pluginInfo, extra) {
let templateCompilerFullPath = require.resolve(templateCompilerPath);
let templateCompilerCacheKey = fs.readFileSync(templateCompilerFullPath, { encoding: 'utf-8' });
let templateCompilerCacheKey = getTemplateCompilerCacheKey(templateCompilerPath);
let cacheItems = [templateCompilerCacheKey, extra].concat(pluginInfo.cacheKeys.sort());
// extra may be undefined

@@ -296,5 +322,2 @@ return cacheItems.filter(Boolean).join('|');

buildOptions,
purgeModule,
registerPlugins,
unregisterPlugins,
initializeEmberENV,

@@ -308,2 +331,4 @@ template,

buildParalleizedBabelPlugin,
getTemplateCompiler,
getTemplateCompilerCacheKey,
};
{
"name": "ember-cli-htmlbars",
"version": "4.4.1",
"version": "4.5.0",
"description": "A library for adding htmlbars to ember CLI",

@@ -5,0 +5,0 @@ "keywords": [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc