diff --git a/packages/plugin-adapter-netlify/src/index.js b/packages/plugin-adapter-netlify/src/index.js index c075eacc0..7336f174f 100644 --- a/packages/plugin-adapter-netlify/src/index.js +++ b/packages/plugin-adapter-netlify/src/index.js @@ -171,6 +171,17 @@ async function netlifyAdapter(compilation) { ); } + const ssrApiAssets = (await fs.readdir(new URL('./api/', outputDir))) + .filter(file => new RegExp(/^[\w][\w-]*\.[a-zA-Z0-9]{4,20}\.[\w]{2,4}$/).test(path.basename(file))); + + for (const asset of ssrApiAssets) { + await fs.cp( + new URL(`./${asset}`, new URL('./api/', outputDir)), + new URL(`./${asset}`, outputRoot), + { recursive: true } + ); + } + // NOTE: All functions must live at the top level // https://github.com/netlify/netlify-lambda/issues/90#issuecomment-486047201 await createOutputZip(id, outputType, outputRoot, projectDirectory); diff --git a/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js b/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js index 7b9457929..a51f5c69f 100644 --- a/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js +++ b/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js @@ -23,7 +23,9 @@ * api/ * fragment.js * greeting.js - * submit.js + * search.js + * submit-form-data.js + * submit-json.js * components/ * card.js * pages/ @@ -76,11 +78,11 @@ describe('Build Greenwood With: ', function() { }); it('should output the expected number of serverless function zip files', function() { - expect(zipFiles.length).to.be.equal(6); + expect(zipFiles.length).to.be.equal(7); }); it('should output the expected number of serverless function API zip files', function() { - expect(zipFiles.filter(file => path.basename(file).startsWith('api-')).length).to.be.equal(4); + expect(zipFiles.filter(file => path.basename(file).startsWith('api-')).length).to.be.equal(5); }); it('should output the expected number of serverless function SSR page zip files', function() { diff --git a/packages/plugin-adapter-netlify/test/cases/build.default/src/api/search.js b/packages/plugin-adapter-netlify/test/cases/build.default/src/api/search.js new file mode 100644 index 000000000..959eb2c22 --- /dev/null +++ b/packages/plugin-adapter-netlify/test/cases/build.default/src/api/search.js @@ -0,0 +1,41 @@ +import { renderFromHTML } from 'wc-compiler'; +import { getArtists } from '../services/artists.js'; + +export async function handler(request) { + const formData = await request.formData(); + const term = formData.has('term') ? formData.get('term') : ''; + const artists = (await getArtists()) + .filter((artist) => { + return term !== '' && artist.name.toLowerCase().includes(term.toLowerCase()); + }); + let body = ''; + + if (artists.length === 0) { + body = 'No results found.'; + } else { + const { html } = await renderFromHTML(` + ${ + artists.map((item, idx) => { + const { name, imageUrl } = item; + + return ` + + `; + }).join('') + } + `, [ + new URL('../components/card.js', import.meta.url) + ]); + + body = html; + } + + return new Response(body, { + headers: new Headers({ + 'Content-Type': 'text/html' + }) + }); +} \ No newline at end of file diff --git a/packages/plugin-adapter-vercel/src/index.js b/packages/plugin-adapter-vercel/src/index.js index 8b58d55b4..00ee5798b 100644 --- a/packages/plugin-adapter-vercel/src/index.js +++ b/packages/plugin-adapter-vercel/src/index.js @@ -149,6 +149,17 @@ async function vercelAdapter(compilation) { new URL('./assets/', outputRoot), { recursive: true } ); + + const ssrApiAssets = (await fs.readdir(new URL('./api/', outputDir))) + .filter(file => new RegExp(/^[\w][\w-]*\.[a-zA-Z0-9]{4,20}\.[\w]{2,4}$/).test(path.basename(file))); + + for (const asset of ssrApiAssets) { + await fs.cp( + new URL(`./${asset}`, new URL('./api/', outputDir)), + new URL(`./${asset}`, outputRoot), + { recursive: true } + ); + } } // static assets / build diff --git a/packages/plugin-adapter-vercel/test/cases/build.default/build.default.spec.js b/packages/plugin-adapter-vercel/test/cases/build.default/build.default.spec.js index 77f3d0678..014522efa 100644 --- a/packages/plugin-adapter-vercel/test/cases/build.default/build.default.spec.js +++ b/packages/plugin-adapter-vercel/test/cases/build.default/build.default.spec.js @@ -23,7 +23,9 @@ * api/ * fragment.js * greeting.js - * submit.js + * search.js + * submit-form-data.js + * submit-json.js * components/ * card.js * pages/ @@ -77,7 +79,7 @@ describe('Build Greenwood With: ', function() { }); it('should output the expected number of serverless function output folders', function() { - expect(functionFolders.length).to.be.equal(6); + expect(functionFolders.length).to.be.equal(7); }); it('should output the expected configuration file for the build output', function() { diff --git a/packages/plugin-adapter-vercel/test/cases/build.default/src/api/search.js b/packages/plugin-adapter-vercel/test/cases/build.default/src/api/search.js new file mode 100644 index 000000000..959eb2c22 --- /dev/null +++ b/packages/plugin-adapter-vercel/test/cases/build.default/src/api/search.js @@ -0,0 +1,41 @@ +import { renderFromHTML } from 'wc-compiler'; +import { getArtists } from '../services/artists.js'; + +export async function handler(request) { + const formData = await request.formData(); + const term = formData.has('term') ? formData.get('term') : ''; + const artists = (await getArtists()) + .filter((artist) => { + return term !== '' && artist.name.toLowerCase().includes(term.toLowerCase()); + }); + let body = ''; + + if (artists.length === 0) { + body = 'No results found.'; + } else { + const { html } = await renderFromHTML(` + ${ + artists.map((item, idx) => { + const { name, imageUrl } = item; + + return ` + + `; + }).join('') + } + `, [ + new URL('../components/card.js', import.meta.url) + ]); + + body = html; + } + + return new Response(body, { + headers: new Headers({ + 'Content-Type': 'text/html' + }) + }); +} \ No newline at end of file