Skip to content

Commit

Permalink
Enable relative URL in Fastboot mode
Browse files Browse the repository at this point in the history
define fetch module at instance-initializers to get request info
  • Loading branch information
xg-wang committed Nov 10, 2018
1 parent bdf83a8 commit 8629160
Show file tree
Hide file tree
Showing 8 changed files with 1,193 additions and 58 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ember-fetch
# ember-fetch
[![Build Status](https://travis-ci.org/ember-cli/ember-fetch.svg?branch=master)](https://travis-ci.org/ember-cli/ember-fetch)
[![Build status](https://ci.appveyor.com/api/projects/status/u7qcv4pgsvo60sxt?svg=true)](https://ci.appveyor.com/project/embercli/ember-fetch)
[![Ember Observer Score](https://emberobserver.com/badges/ember-fetch.svg)](https://emberobserver.com/addons/ember-fetch)
Expand Down Expand Up @@ -65,7 +65,7 @@ export default {
}
```

For addon authors, if the addon supports Fastboot mode, `ember-fetch` should also be listed as a [peer dependency](https://docs.npmjs.com/files/package.json#peerdependencies).
For addon authors, if the addon supports Fastboot mode, `ember-fetch` should also be listed as a [peer dependency](https://docs.npmjs.com/files/package.json#peerdependencies).
This is because Fastboot only invokes top-level addon's `updateFastBootManifest` ([detail](https://github.com/ember-fastboot/ember-cli-fastboot/issues/597)), thus `ember-fetch` has to be a top-level addon installed by the host app.

### Allow native fetch
Expand Down
14 changes: 7 additions & 7 deletions addon/mixins/adapter-fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import RSVP from 'rsvp';
import fetch from 'fetch';
import mungOptionsForFetch from '../utils/mung-options-for-fetch';
import determineBodyPromise from '../utils/determine-body-promise';

/**
* Helper function to create a plain object from the response's Headers.
* Consumed by the adapter's `handleResponse`.
Expand All @@ -21,14 +22,13 @@ export function headersToObject(headers) {
}

export default Mixin.create({
/**
* @param {String} url
* @param {String} type
* @param {Object} _options
* @returns {Object}
* @override
/**
* @param {String} url
* @param {String} type
* @param {Object} _options
* @returns {Object}
* @override
*/

ajaxOptions(url, type, options = {}) {
options.url = url;
options.type = type;
Expand Down
17 changes: 17 additions & 0 deletions fastboot/instance-initializers/setup-fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import setupFetch from 'fetch/setup';

/**
* To allow relative URLs for Fastboot mode, we need the per request information
* from the fastboot service. Then we re-define the `fetch` amd module.
*/
function patchFetchForRelativeURLs(instance) {
const fastboot = instance.lookup('service:fastboot');
const request = fastboot.get('request');
// host is cp
setupFetch(request.protocol, request.get('host'))();
}

export default {
name: 'fetch',
initialize: patchFetchForRelativeURLs
};
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ module.exports = {
},

//add node version of fetch.js into fastboot package.json manifest vendorFiles array
updateFastBootManifest: function (manifest) {
updateFastBootManifest: function(manifest) {
manifest.vendorFiles.push('ember-fetch/fastboot-fetch.js');
return manifest;
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"ember-cli": "~3.0.2",
"ember-cli-dependency-checker": "^3.0.0",
"ember-cli-eslint": "^4.2.1",
"ember-cli-fastboot": "^2.0.0",
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-inject-live-reload": "^1.4.1",
"ember-cli-pretender": "^3.0.0",
Expand Down
66 changes: 47 additions & 19 deletions public/fastboot-fetch.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,51 @@
/* globals define FastBoot */
(function() {
define('fetch', ['exports'], function(self) {
var AbortControllerPolyfill = FastBoot.require('abortcontroller-polyfill/dist/cjs-ponyfill');
var nodeFetch = FastBoot.require('node-fetch');
var abortableFetch = AbortControllerPolyfill.abortableFetch({
fetch: nodeFetch,
Request: nodeFetch.Request
});
define('fetch/setup', ['exports'], function(self) {
var httpRegex = /^https?:\/\//;
var protocolRelativeRegex = /^\/\//;

self['default'] = abortableFetch.fetch;
self['Request'] = abortableFetch.Request;

self['Headers'] = nodeFetch.Headers;
self['Response'] = nodeFetch.Response;

self['AbortController'] = AbortControllerPolyfill.AbortController;
var AbortControllerPolyfill = FastBoot.require(
'abortcontroller-polyfill/dist/cjs-ponyfill'
);
var nodeFetch = FastBoot.require('node-fetch');
var abortableFetch = AbortControllerPolyfill.abortableFetch({
fetch: nodeFetch,
Request: nodeFetch.Request
});

define('fetch/ajax', ['exports'], function() {
throw new Error('You included `fetch/ajax` but it was renamed to `ember-fetch/ajax`');
});
})();
self['default'] = function(protocol, host) {
return function() {
define('fetch', ['exports'], function(exports) {
/**
* Setup the exported fetch for a given origin so it can handle:
* - protocol-relative URL (//can-be-http-or-https.com/)
* - path-relative URL (/file/under/root)
* @param {String} url
* @param {Object} [options]
*/
exports['default'] = function fetch(url, options) {
if (protocolRelativeRegex.test(url)) {
url = host + url;
} else if (!httpRegex.test(url)) {
if (!host) {
throw new Error(
'You are using using fetch with a path-relative URL, but host is missing from Fastboot request. Please set the hostWhitelist property in your environment.js.'
);
}
url = protocol + '//' + host + url;
}
return abortableFetch.fetch(url, options);
};
exports['Request'] = abortableFetch.Request;
exports['Headers'] = nodeFetch.Headers;
exports['Response'] = nodeFetch.Response;
exports['AbortController'] = AbortControllerPolyfill.AbortController;
});
};
};
});

define('fetch/ajax', ['exports'], function() {
throw new Error(
'You included `fetch/ajax` but it was renamed to `ember-fetch/ajax`'
);
});
4 changes: 4 additions & 0 deletions tests/dummy/config/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ module.exports = function(environment) {
APP: {
// Here you can pass flags/options to your application instance
// when it is created
},

fastboot: {
hostWhitelist: [/^localhost:\d+$/]
}
};

Expand Down
Loading

0 comments on commit 8629160

Please sign in to comment.