Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ let app = new FastBoot({
distPath: 'path/to/dist',
// optional boolean flag when set to true does not reject the promise if there are rendering errors (defaults to false)
resilient: <boolean>,
sandboxGlobals: {...} // optional map of key value pairs to expose in the sandbox

// optional function used to generate the set of global properties available within the sandbox, receives default globals
// and is expected to return an object (the default implementation returns the passed in defaults)
buildSandboxGlobals(defaultGlobals) {
return Object.assign({}, defaultGlobals, {
// additional global properties to define within the sandbox
});
},
});

app.visit('/photos', options)
Expand Down
36 changes: 19 additions & 17 deletions src/ember-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,10 @@ class EmberApp {
* Create a new EmberApp.
* @param {Object} options
* @param {string} options.distPath - path to the built Ember application
* @param {Object} [options.sandboxGlobals] - sandbox variables that can be added or used for overrides in the sandbox.
* @param {Function} [options.buildSandboxGlobals] - the function used to build the final set of global properties accesible within the sandbox
*/
constructor(options) {
// TODO: make these two into builder functions
this.sandboxGlobals = options.sandboxGlobals;
this.buildSandboxGlobals = options.buildSandboxGlobals || defaultBuildSandboxGlobals;

let distPath = (this.distPath = path.resolve(options.distPath));
let config = this.readPackageJSON(distPath);
Expand Down Expand Up @@ -77,7 +76,7 @@ class EmberApp {
* Builds and initializes a new sandbox to run the Ember application in.
*/
buildSandbox() {
const { distPath, sandboxGlobals, config, appName, sandboxRequire } = this;
const { distPath, buildSandboxGlobals, config, appName, sandboxRequire } = this;

function fastbootConfig(key) {
if (!key) {
Expand All @@ -92,21 +91,19 @@ class EmberApp {
}
}

// add any additional user provided variables or override the default globals in the sandbox
let globals = Object.assign(
{
najax,
FastBoot: {
require: sandboxRequire,
config: fastbootConfig,

get distPath() {
return distPath;
},
let defaultGlobals = {
najax,
FastBoot: {
require: sandboxRequire,
config: fastbootConfig,

get distPath() {
return distPath;
},
},
sandboxGlobals
);
};

let globals = buildSandboxGlobals(defaultGlobals);

return new Sandbox(globals);
}
Expand Down Expand Up @@ -519,4 +516,9 @@ function buildScripts(filePaths) {
return new vm.Script(source, { filename: filePath });
});
}

function defaultBuildSandboxGlobals(defaultGlobals) {
return defaultGlobals;
}

module.exports = EmberApp;
29 changes: 21 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,44 @@ const EmberApp = require('./ember-app');
*
* let app = new FastBoot({
* distPath: 'path/to/dist',
* sandboxGlobals: {...}
* buildSandboxGlobals(globals) {
* return Object.assign({}, globals, {
* // custom globals
* });
* },
* });
*
* app.visit('/photos')
* .then(result => result.html())
* .then(html => res.send(html));
*/

class FastBoot {
/**
* Create a new FastBoot instance.
*
* @param {Object} options
* @param {string} options.distPath the path to the built Ember application
* @param {Boolean} [options.resilient=false] if true, errors during rendering won't reject the `visit()` promise but instead resolve to a {@link Result}
* @param {Object} [options.sandboxGlobals={}] any additional sandbox variables that an app server wants to override and/or add in the sandbox
* @param {Function} [options.buildSandboxGlobals] a function used to build the final set of global properties setup within the sandbox
*/
constructor(options = {}) {
let { distPath, sandboxGlobals } = options;
let { distPath, buildSandboxGlobals } = options;

this.resilient = 'resilient' in options ? Boolean(options.resilient) : false;

this.distPath = distPath;
this.sandboxGlobals = sandboxGlobals || {};

this._buildEmberApp(this.distPath, this.sandboxGlobals);
// deprecate the legacy path, but support it
if (buildSandboxGlobals === undefined && options.sandboxGlobals !== undefined) {
console.warn(
'[DEPRECATION] Instantiating `fastboot` with a `sandboxGlobals` option has been deprecated. Please migrate to specifying `buildSandboxGlobals` instead.'
);
buildSandboxGlobals = globals => Object.assign({}, globals, options.sandboxGlobals);
}

this.buildSandboxGlobals = buildSandboxGlobals;

this._buildEmberApp(this.distPath, this.buildSandboxGlobals);
}

/**
Expand Down Expand Up @@ -92,7 +105,7 @@ class FastBoot {
this._buildEmberApp(distPath);
}

_buildEmberApp(distPath = this.distPath, sandboxGlobals = this.sandboxGlobals) {
_buildEmberApp(distPath = this.distPath, buildSandboxGlobals = this.buildSandboxGlobals) {
if (!distPath) {
throw new Error(
'You must instantiate FastBoot with a distPath ' +
Expand All @@ -109,7 +122,7 @@ class FastBoot {

this._app = new EmberApp({
distPath,
sandboxGlobals,
buildSandboxGlobals,
});
}
}
Expand Down
24 changes: 14 additions & 10 deletions test/fastboot-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,15 @@ describe('FastBoot', function() {
});
});

it('can render HTML when sandboxGlobals is provided', function() {
it('can render HTML when a custom set of sandbox globals is provided', function() {
var fastboot = new FastBoot({
distPath: fixture('custom-sandbox'),
sandboxGlobals: {
foo: 5,
najax: 'undefined',
myVar: 'undefined',
buildSandboxGlobals(globals) {
return Object.assign({}, globals, {
foo: 5,
najax: 'undefined',
myVar: 'undefined',
});
},
});

Expand Down Expand Up @@ -256,13 +258,15 @@ describe('FastBoot', function() {
}
});

it('can reload the app using the same sandboxGlobals', function() {
it('can reload the app using the same buildSandboxGlobals', function() {
var fastboot = new FastBoot({
distPath: fixture('basic-app'),
sandboxGlobals: {
foo: 5,
najax: 'undefined',
myVar: 'undefined',
buildSandboxGlobals(globals) {
return Object.assign({}, globals, {
foo: 5,
najax: 'undefined',
myVar: 'undefined',
});
},
});

Expand Down