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