diff --git a/packages/cli/src/lifecycles/serve.js b/packages/cli/src/lifecycles/serve.js index ea8991f2f..b11bcb21c 100644 --- a/packages/cli/src/lifecycles/serve.js +++ b/packages/cli/src/lifecycles/serve.js @@ -307,15 +307,20 @@ async function getHybridServer(compilation) { ctx.body = Readable.from(response.body); ctx.set('Content-Type', 'text/html'); + // TODO should use status from response + // https://github.com/ProjectEvergreen/greenwood/issues/1048 ctx.status = 200; } else if (isApiRoute) { const apiRoute = manifest.apis.get(url.pathname); const { handler } = await import(new URL(`.${apiRoute.path}`, outputDir)); const response = await handler(request); + const { body } = response; + // TODO should use status from response + // https://github.com/ProjectEvergreen/greenwood/issues/1048 + ctx.body = body ? Readable.from(body) : null; ctx.status = 200; ctx.set('Content-Type', response.headers.get('Content-Type')); - ctx.body = Readable.from(response.body); } } catch (e) { ctx.status = 500; diff --git a/packages/cli/src/plugins/resource/plugin-node-modules.js b/packages/cli/src/plugins/resource/plugin-node-modules.js index b12dd3fe0..475efbf18 100644 --- a/packages/cli/src/plugins/resource/plugin-node-modules.js +++ b/packages/cli/src/plugins/resource/plugin-node-modules.js @@ -66,7 +66,7 @@ class NodeModulesResource extends ResourceInterface { } async shouldIntercept(url, request, response) { - return response.headers.get('Content-Type').indexOf('text/html') >= 0; + return response.headers.get('Content-Type')?.indexOf('text/html') >= 0; } async intercept(url, request, response) { diff --git a/packages/cli/src/plugins/server/plugin-livereload.js b/packages/cli/src/plugins/server/plugin-livereload.js index 07d2eb120..e3303e616 100644 --- a/packages/cli/src/plugins/server/plugin-livereload.js +++ b/packages/cli/src/plugins/server/plugin-livereload.js @@ -54,7 +54,7 @@ class LiveReloadResource extends ResourceInterface { async shouldIntercept(url, request, response) { const contentType = response.headers.get('Content-Type'); - return contentType.indexOf('text/html') >= 0 && process.env.__GWD_COMMAND__ === 'develop'; // eslint-disable-line no-underscore-dangle + return contentType?.indexOf('text/html') >= 0 && process.env.__GWD_COMMAND__ === 'develop'; // eslint-disable-line no-underscore-dangle } async intercept(url, request, response) { diff --git a/packages/cli/test/cases/develop.default/develop.default.spec.js b/packages/cli/test/cases/develop.default/develop.default.spec.js index 9735f6fd3..0136a1ce1 100644 --- a/packages/cli/test/cases/develop.default/develop.default.spec.js +++ b/packages/cli/test/cases/develop.default/develop.default.spec.js @@ -19,6 +19,7 @@ * src/ * api/ * greeting.js + * nothing.js * assets/ * data.json * favicon.ico @@ -1348,6 +1349,28 @@ describe('Develop Greenwood With: ', function() { done(); }); }); + + describe('Develop command with API specific behaviors with a minimal response', function() { + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + request.get(`${hostname}:${port}/api/nothing`, (err, res) => { + if (err) { + reject(); + } + + response = res; + resolve(); + }); + }); + }); + + it('should return a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + }); }); after(function() { diff --git a/packages/cli/test/cases/develop.default/src/api/nothing.js b/packages/cli/test/cases/develop.default/src/api/nothing.js new file mode 100644 index 000000000..4f49b7fb3 --- /dev/null +++ b/packages/cli/test/cases/develop.default/src/api/nothing.js @@ -0,0 +1,5 @@ +export async function handler() { + // TODO should support a non 200 status code + // https://github.com/ProjectEvergreen/greenwood/issues/1048 + return new Response(undefined); +} \ No newline at end of file diff --git a/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js b/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js index 9144881e5..c7e88120b 100644 --- a/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js +++ b/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js @@ -37,7 +37,7 @@ describe('Serve Greenwood With: ', function() { this.context = { hostname }; - runner = new Runner(); + runner = new Runner(true); }); describe(LABEL, function() { @@ -129,6 +129,28 @@ describe('Serve Greenwood With: ', function() { }); }); + describe('Serve command with API specific behaviors with a minimal response', function() { + let response = {}; + + before(async function() { + return new Promise((resolve, reject) => { + request.get(`${hostname}/api/nothing`, (err, res) => { + if (err) { + reject(); + } + + response = res; + resolve(); + }); + }); + }); + + it('should return a 200 status', function(done) { + expect(response.statusCode).to.equal(200); + done(); + }); + }); + describe('Serve command with API 404 not found behavior', function() { let response = {}; diff --git a/packages/cli/test/cases/serve.default.api/src/api/nothing.js b/packages/cli/test/cases/serve.default.api/src/api/nothing.js new file mode 100644 index 000000000..4596641aa --- /dev/null +++ b/packages/cli/test/cases/serve.default.api/src/api/nothing.js @@ -0,0 +1,3 @@ +export async function handler() { + return new Response(undefined); +} \ No newline at end of file diff --git a/packages/plugin-google-analytics/src/index.js b/packages/plugin-google-analytics/src/index.js index 455cc8750..d100dd72f 100644 --- a/packages/plugin-google-analytics/src/index.js +++ b/packages/plugin-google-analytics/src/index.js @@ -14,7 +14,7 @@ class GoogleAnalyticsResource extends ResourceInterface { } async shouldIntercept(url, request, response) { - return response.headers.get('Content-Type').indexOf(this.contentType) >= 0; + return response.headers.get('Content-Type')?.indexOf(this.contentType) >= 0; } async intercept(url, request, response) { diff --git a/packages/plugin-graphql/src/index.js b/packages/plugin-graphql/src/index.js index 7edd95642..cf0c4cb00 100644 --- a/packages/plugin-graphql/src/index.js +++ b/packages/plugin-graphql/src/index.js @@ -40,7 +40,7 @@ class GraphQLResource extends ResourceInterface { } async shouldIntercept(url, request, response) { - return response.headers.get('Content-Type').indexOf(this.contentType[1]) >= 0; + return response.headers.get('Content-Type')?.indexOf(this.contentType[1]) >= 0; } async intercept(url, request, response) { diff --git a/packages/plugin-include-html/src/index.js b/packages/plugin-include-html/src/index.js index 12682e661..20160a44f 100644 --- a/packages/plugin-include-html/src/index.js +++ b/packages/plugin-include-html/src/index.js @@ -9,7 +9,7 @@ class IncludeHtmlResource extends ResourceInterface { } async shouldIntercept(url, request, response) { - return response.headers.get('Content-Type').indexOf(this.contentType) >= 0; + return response.headers.get('Content-Type')?.indexOf(this.contentType) >= 0; } async intercept(url, request, response) { diff --git a/packages/plugin-polyfills/src/index.js b/packages/plugin-polyfills/src/index.js index e56252bd5..358a95afc 100644 --- a/packages/plugin-polyfills/src/index.js +++ b/packages/plugin-polyfills/src/index.js @@ -21,7 +21,7 @@ class PolyfillsResource extends ResourceInterface { return isEnabled && protocol.startsWith('http') - && response.headers.get('Content-Type').indexOf(this.contentType) >= 0; + && response.headers.get('Content-Type')?.indexOf(this.contentType) >= 0; } async intercept(url, request, response) { diff --git a/packages/plugin-renderer-puppeteer/src/plugins/resource.js b/packages/plugin-renderer-puppeteer/src/plugins/resource.js index 509f2faaf..4fd97a306 100644 --- a/packages/plugin-renderer-puppeteer/src/plugins/resource.js +++ b/packages/plugin-renderer-puppeteer/src/plugins/resource.js @@ -13,7 +13,7 @@ class PuppeteerResource extends ResourceInterface { return process.env.__GWD_COMMAND__ === 'build' // eslint-disable-line no-underscore-dangle && protocol.startsWith('http') - && response.headers.get('Content-Type').indexOf(this.contentType) >= 0; + && response.headers.get('Content-Type')?.indexOf(this.contentType) >= 0; } async intercept(url, request, response) {