From 3c82785940a8fd187cf9fec436230c39e85ccf21 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Mon, 21 Nov 2022 21:44:52 -0500 Subject: [PATCH 01/20] API Routes --- packages/cli/src/lifecycles/context.js | 2 + .../src/plugins/resource/plugin-api-routes.js | 37 +++++++++++++++++++ www/api/greeting.js | 5 +++ www/pages/index.html | 8 ++++ 4 files changed, 52 insertions(+) create mode 100644 packages/cli/src/plugins/resource/plugin-api-routes.js create mode 100644 www/api/greeting.js diff --git a/packages/cli/src/lifecycles/context.js b/packages/cli/src/lifecycles/context.js index 18589faa9..d52a3ccee 100644 --- a/packages/cli/src/lifecycles/context.js +++ b/packages/cli/src/lifecycles/context.js @@ -11,6 +11,7 @@ const initContext = async({ config }) => { try { const projectDirectory = process.cwd(); const userWorkspace = path.join(config.workspace); + const apisDir = path.join(userWorkspace, 'api/'); const pagesDir = path.join(userWorkspace, `${config.pagesDirectory}/`); const userTemplatesDir = path.join(userWorkspace, `${config.templatesDirectory}/`); @@ -18,6 +19,7 @@ const initContext = async({ config }) => { dataDir, outputDir, userWorkspace, + apisDir, pagesDir, userTemplatesDir, scratchDir, diff --git a/packages/cli/src/plugins/resource/plugin-api-routes.js b/packages/cli/src/plugins/resource/plugin-api-routes.js new file mode 100644 index 000000000..86533ecd9 --- /dev/null +++ b/packages/cli/src/plugins/resource/plugin-api-routes.js @@ -0,0 +1,37 @@ +/* + * + * Manages routing to API routes. + * + */ +import path from 'path'; +import { pathToFileURL } from 'url'; +import { ResourceInterface } from '../../lib/resource-interface.js'; + +class DevProxyResource extends ResourceInterface { + constructor(compilation, options) { + super(compilation, options); + } + + async shouldServe(url) { + // TODO check it exists first + return url.startsWith('/api'); + } + + async serve(url) { + console.debug('SERVING API => ', { url }); + // TODO stop using path! + const { handler } = await import(pathToFileURL(`${path.join(this.compilation.context.apisDir, url.replace('/api', ''))}.js`)); + + return { + body: await handler() + }; + } +} + +const greenwoodApiRoutesPlugin = { + type: 'resource', + name: 'plugin-api-routes', + provider: (compilation, options) => new DevProxyResource(compilation, options) +}; + +export { greenwoodApiRoutesPlugin }; \ No newline at end of file diff --git a/www/api/greeting.js b/www/api/greeting.js new file mode 100644 index 000000000..73416dac0 --- /dev/null +++ b/www/api/greeting.js @@ -0,0 +1,5 @@ +export async function handler(request, response) { + console.debug({ request, response }); + + return { message: 'Greenwood' }; +} \ No newline at end of file diff --git a/www/pages/index.html b/www/pages/index.html index 099510595..0b3732a02 100644 --- a/www/pages/index.html +++ b/www/pages/index.html @@ -10,10 +10,18 @@ + +
+

From 0c0af05bbfdbfca2b9f09de57f5e26e4989db6ca Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Mon, 21 Nov 2022 21:47:05 -0500 Subject: [PATCH 02/20] rename ApiRoutes resource class --- packages/cli/src/plugins/resource/plugin-api-routes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/plugins/resource/plugin-api-routes.js b/packages/cli/src/plugins/resource/plugin-api-routes.js index 86533ecd9..54409f06a 100644 --- a/packages/cli/src/plugins/resource/plugin-api-routes.js +++ b/packages/cli/src/plugins/resource/plugin-api-routes.js @@ -7,7 +7,7 @@ import path from 'path'; import { pathToFileURL } from 'url'; import { ResourceInterface } from '../../lib/resource-interface.js'; -class DevProxyResource extends ResourceInterface { +class ApiRoutesResource extends ResourceInterface { constructor(compilation, options) { super(compilation, options); } @@ -31,7 +31,7 @@ class DevProxyResource extends ResourceInterface { const greenwoodApiRoutesPlugin = { type: 'resource', name: 'plugin-api-routes', - provider: (compilation, options) => new DevProxyResource(compilation, options) + provider: (compilation, options) => new ApiRoutesResource(compilation, options) }; export { greenwoodApiRoutesPlugin }; \ No newline at end of file From 72764df82e3fc4b889457e397e261777d26c5b1e Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Tue, 22 Nov 2022 13:51:47 -0500 Subject: [PATCH 03/20] add skeleton Request support to handler signature --- packages/cli/src/plugins/resource/plugin-api-routes.js | 7 ++++--- www/api/greeting.js | 8 +++++++- www/pages/index.html | 6 ++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/plugins/resource/plugin-api-routes.js b/packages/cli/src/plugins/resource/plugin-api-routes.js index 54409f06a..4ba846401 100644 --- a/packages/cli/src/plugins/resource/plugin-api-routes.js +++ b/packages/cli/src/plugins/resource/plugin-api-routes.js @@ -19,11 +19,12 @@ class ApiRoutesResource extends ResourceInterface { async serve(url) { console.debug('SERVING API => ', { url }); - // TODO stop using path! - const { handler } = await import(pathToFileURL(`${path.join(this.compilation.context.apisDir, url.replace('/api', ''))}.js`)); + // TODO stop using path / url helpers! + const { handler } = await import(pathToFileURL(`${path.join(this.compilation.context.apisDir, this.getBareUrlPath(url).replace('/api', ''))}.js`)); + const req = new Request(new URL(`https://localhost:1984${url}`)); return { - body: await handler() + body: await handler(req) }; } } diff --git a/www/api/greeting.js b/www/api/greeting.js index 73416dac0..1ad28a4d8 100644 --- a/www/api/greeting.js +++ b/www/api/greeting.js @@ -1,5 +1,11 @@ export async function handler(request, response) { console.debug({ request, response }); + const params = new URLSearchParams(request.url.slice(request.url.indexOf('?'))); + const name = params.has('name') ? params.get('name') : 'Greenwood'; - return { message: 'Greenwood' }; + console.debug({ params }); + console.debug({ name }); + + // TODO use Response + return { message: `Hello ${name}!!!` }; } \ No newline at end of file diff --git a/www/pages/index.html b/www/pages/index.html index 0b3732a02..64c4eb22f 100644 --- a/www/pages/index.html +++ b/www/pages/index.html @@ -12,10 +12,12 @@ From 799abea487089ed1f2e766da583018473100f7c4 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Tue, 22 Nov 2022 14:39:15 -0500 Subject: [PATCH 04/20] Response example from API route --- packages/cli/src/plugins/resource/plugin-api-routes.js | 8 ++++++-- www/api/greeting.js | 10 +++------- www/pages/index.html | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/plugins/resource/plugin-api-routes.js b/packages/cli/src/plugins/resource/plugin-api-routes.js index 4ba846401..d0af50a8d 100644 --- a/packages/cli/src/plugins/resource/plugin-api-routes.js +++ b/packages/cli/src/plugins/resource/plugin-api-routes.js @@ -21,10 +21,14 @@ class ApiRoutesResource extends ResourceInterface { console.debug('SERVING API => ', { url }); // TODO stop using path / url helpers! const { handler } = await import(pathToFileURL(`${path.join(this.compilation.context.apisDir, this.getBareUrlPath(url).replace('/api', ''))}.js`)); - const req = new Request(new URL(`https://localhost:1984${url}`)); + const req = new Request(new URL(`https://localhost:1984${url}`)); // TODO can we assume localhost? + const resp = await handler(req); + const body = await resp.json(); // TODO assumes JSON + + console.debug({ body }); return { - body: await handler(req) + body }; } } diff --git a/www/api/greeting.js b/www/api/greeting.js index 1ad28a4d8..c0d422dd5 100644 --- a/www/api/greeting.js +++ b/www/api/greeting.js @@ -1,11 +1,7 @@ -export async function handler(request, response) { - console.debug({ request, response }); +export async function handler(request) { const params = new URLSearchParams(request.url.slice(request.url.indexOf('?'))); const name = params.has('name') ? params.get('name') : 'Greenwood'; + const body = { message: `Hello ${name}!!!` }; - console.debug({ params }); - console.debug({ name }); - - // TODO use Response - return { message: `Hello ${name}!!!` }; + return new Response(JSON.stringify(body)); } \ No newline at end of file diff --git a/www/pages/index.html b/www/pages/index.html index 64c4eb22f..8962d35a0 100644 --- a/www/pages/index.html +++ b/www/pages/index.html @@ -13,8 +13,8 @@
-

From 87216d71c2a02dd9e37959e6f92f1c7ff4a44a06 Mon Sep 17 00:00:00 2001 From: Owen Buckley Date: Sat, 17 Dec 2022 12:41:08 -0500 Subject: [PATCH 20/20] app exists check for API routes --- packages/cli/src/plugins/resource/plugin-api-routes.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/plugins/resource/plugin-api-routes.js b/packages/cli/src/plugins/resource/plugin-api-routes.js index 038fc68b1..cd4f1c85c 100644 --- a/packages/cli/src/plugins/resource/plugin-api-routes.js +++ b/packages/cli/src/plugins/resource/plugin-api-routes.js @@ -3,6 +3,7 @@ * Manages routing to API routes. * */ +import fs from 'fs'; import { ResourceInterface } from '../../lib/resource-interface.js'; class ApiRoutesResource extends ResourceInterface { @@ -11,8 +12,9 @@ class ApiRoutesResource extends ResourceInterface { } async shouldServe(url) { - // TODO check it exists first. Could this come from the graph? - return url.startsWith('/api'); + // TODO Could this existance check be derived from the graph instead? + // https://github.com/ProjectEvergreen/greenwood/issues/946 + return url.startsWith('/api') && fs.existsSync(this.compilation.context.apisDir, url); } async serve(url) {