Skip to content

Commit 297ff53

Browse files
author
Robert Jackson
committed
Refactor sandboxGlobals -> buildSandboxGlobals
This changes the system from providing default set of shared (and therefore mutable) global properties to using a builder function to generate the set of globals to be used _per visit_. The `buildSandboxGlobals` function will receive the default set of globals that FastBoot creates (currently this is `najax` and `FastBoot`), and whatever the `buildSandboxGlobals` function returns is what will ultimately be used. If `buildSandboxGlobals` is not provided, a default implementation is used (it is essentially `defaultGlobals => defaultGlobals;`). For example, to specify a custom global property named `AwesomeThing` to be accessed within the sandboxed context: ```js let fastboot = new FastBoot({ distPath: 'some/path/here', buildSandboxGlobals(globals) { return Object.assign({}, globals, { AwesomeThing: 'Taco Cat' }); } }); ``` If `sandboxGlobals` is passed (and `buildSandboxGlobals` is not) issue a deprecation and automatically create a `buildSandboxGlobals` of the following: ```js globals => Object.assign({}, globals, options.sandboxGlobals); ```
1 parent 85a3666 commit 297ff53

File tree

4 files changed

+62
-36
lines changed

4 files changed

+62
-36
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,14 @@ let app = new FastBoot({
2828
distPath: 'path/to/dist',
2929
// optional boolean flag when set to true does not reject the promise if there are rendering errors (defaults to false)
3030
resilient: <boolean>,
31-
sandboxGlobals: {...} // optional map of key value pairs to expose in the sandbox
31+
32+
// optional function used to generate the set of global properties available within the sandbox, receives default globals
33+
// and is expected to return an object (the default implementation returns the passed in defaults)
34+
buildSandboxGlobals(defaultGlobals) {
35+
return Object.assign({}, defaultGlobals, {
36+
// additional global properties to define within the sandbox
37+
});
38+
},
3239
});
3340

3441
app.visit('/photos', options)

src/ember-app.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,10 @@ class EmberApp {
2929
* Create a new EmberApp.
3030
* @param {Object} options
3131
* @param {string} options.distPath - path to the built Ember application
32-
* @param {Object} [options.sandboxGlobals] - sandbox variables that can be added or used for overrides in the sandbox.
32+
* @param {Function} [options.buildSandboxGlobals] - the function used to build the final set of global properties accesible within the sandbox
3333
*/
3434
constructor(options) {
35-
// TODO: make these two into builder functions
36-
this.sandboxGlobals = options.sandboxGlobals;
35+
this.buildSandboxGlobals = options.buildSandboxGlobals || defaultBuildSandboxGlobals;
3736

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

8281
function fastbootConfig(key) {
8382
if (!key) {
@@ -92,21 +91,19 @@ class EmberApp {
9291
}
9392
}
9493

95-
// add any additional user provided variables or override the default globals in the sandbox
96-
let globals = Object.assign(
97-
{
98-
najax,
99-
FastBoot: {
100-
require: sandboxRequire,
101-
config: fastbootConfig,
102-
103-
get distPath() {
104-
return distPath;
105-
},
94+
let defaultGlobals = {
95+
najax,
96+
FastBoot: {
97+
require: sandboxRequire,
98+
config: fastbootConfig,
99+
100+
get distPath() {
101+
return distPath;
106102
},
107103
},
108-
sandboxGlobals
109-
);
104+
};
105+
106+
let globals = buildSandboxGlobals(defaultGlobals);
110107

111108
return new Sandbox(globals);
112109
}
@@ -519,4 +516,9 @@ function buildScripts(filePaths) {
519516
return new vm.Script(source, { filename: filePath });
520517
});
521518
}
519+
520+
function defaultBuildSandboxGlobals(defaultGlobals) {
521+
return defaultGlobals;
522+
}
523+
522524
module.exports = EmberApp;

src/index.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,44 @@ const EmberApp = require('./ember-app');
2222
*
2323
* let app = new FastBoot({
2424
* distPath: 'path/to/dist',
25-
* sandboxGlobals: {...}
25+
* buildSandboxGlobals(globals) {
26+
* return Object.assign({}, globals, {
27+
* // custom globals
28+
* });
29+
* },
2630
* });
2731
*
2832
* app.visit('/photos')
2933
* .then(result => result.html())
3034
* .then(html => res.send(html));
3135
*/
32-
3336
class FastBoot {
3437
/**
3538
* Create a new FastBoot instance.
39+
*
3640
* @param {Object} options
3741
* @param {string} options.distPath the path to the built Ember application
3842
* @param {Boolean} [options.resilient=false] if true, errors during rendering won't reject the `visit()` promise but instead resolve to a {@link Result}
39-
* @param {Object} [options.sandboxGlobals={}] any additional sandbox variables that an app server wants to override and/or add in the sandbox
43+
* @param {Function} [options.buildSandboxGlobals] a function used to build the final set of global properties setup within the sandbox
4044
*/
4145
constructor(options = {}) {
42-
let { distPath, sandboxGlobals } = options;
46+
let { distPath, buildSandboxGlobals } = options;
4347

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

4650
this.distPath = distPath;
47-
this.sandboxGlobals = sandboxGlobals || {};
4851

49-
this._buildEmberApp(this.distPath, this.sandboxGlobals);
52+
// deprecate the legacy path, but support it
53+
if (buildSandboxGlobals === undefined && options.sandboxGlobals !== undefined) {
54+
console.warn(
55+
'[DEPRECATION] Instantiating `fastboot` with a `sandboxGlobals` option has been deprecated. Please migrate to specifying `buildSandboxGlobals` instead.'
56+
);
57+
buildSandboxGlobals = globals => Object.assign({}, globals, options.sandboxGlobals);
58+
}
59+
60+
this.buildSandboxGlobals = buildSandboxGlobals;
61+
62+
this._buildEmberApp(this.distPath, this.buildSandboxGlobals);
5063
}
5164

5265
/**
@@ -92,7 +105,7 @@ class FastBoot {
92105
this._buildEmberApp(distPath);
93106
}
94107

95-
_buildEmberApp(distPath = this.distPath, sandboxGlobals = this.sandboxGlobals) {
108+
_buildEmberApp(distPath = this.distPath, buildSandboxGlobals = this.buildSandboxGlobals) {
96109
if (!distPath) {
97110
throw new Error(
98111
'You must instantiate FastBoot with a distPath ' +
@@ -109,7 +122,7 @@ class FastBoot {
109122

110123
this._app = new EmberApp({
111124
distPath,
112-
sandboxGlobals,
125+
buildSandboxGlobals,
113126
});
114127
}
115128
}

test/fastboot-test.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,15 @@ describe('FastBoot', function() {
169169
});
170170
});
171171

172-
it('can render HTML when sandboxGlobals is provided', function() {
172+
it('can render HTML when a custom set of sandbox globals is provided', function() {
173173
var fastboot = new FastBoot({
174174
distPath: fixture('custom-sandbox'),
175-
sandboxGlobals: {
176-
foo: 5,
177-
najax: 'undefined',
178-
myVar: 'undefined',
175+
buildSandboxGlobals(globals) {
176+
return Object.assign({}, globals, {
177+
foo: 5,
178+
najax: 'undefined',
179+
myVar: 'undefined',
180+
});
179181
},
180182
});
181183

@@ -256,13 +258,15 @@ describe('FastBoot', function() {
256258
}
257259
});
258260

259-
it('can reload the app using the same sandboxGlobals', function() {
261+
it('can reload the app using the same buildSandboxGlobals', function() {
260262
var fastboot = new FastBoot({
261263
distPath: fixture('basic-app'),
262-
sandboxGlobals: {
263-
foo: 5,
264-
najax: 'undefined',
265-
myVar: 'undefined',
264+
buildSandboxGlobals(globals) {
265+
return Object.assign({}, globals, {
266+
foo: 5,
267+
najax: 'undefined',
268+
myVar: 'undefined',
269+
});
266270
},
267271
});
268272

0 commit comments

Comments
 (0)