UNPKG

netlify-cli

Version:

Netlify command line tool

154 lines • 7.83 kB
import { Readable } from 'stream'; import { parse as parseContentType } from 'content-type'; import multiparty from 'multiparty'; import getRawBody from 'raw-body'; import { warn } from '../../utils/command-helpers.js'; import { BACKGROUND } from '../../utils/functions/index.js'; import { capitalize } from '../string.js'; export const getFormHandler = function ({ functionsRegistry, logWarning = true, }) { const handlers = ['submission-created', `submission-created${BACKGROUND}`] .map((name) => functionsRegistry.get(name)) .filter((func) => func != null) .map(({ name }) => name); if (handlers.length === 0) { if (logWarning) { warn(`Missing form submission function handler`); } return; } if (handlers.length === 2) { if (logWarning) { warn(`Detected both '${handlers[0]}' and '${handlers[1]}' form submission functions handlers, using ${handlers[0]}`); } } return handlers[0]; }; export const createFormSubmissionHandler = function ({ functionsRegistry, siteUrl, }) { return async function formSubmissionHandler(req, _res, next) { if (req.url.startsWith('/.netlify/') || req.method !== 'POST' || (await functionsRegistry.getFunctionForURLPath(req.url, req.method, () => Promise.resolve(false)))) { next(); return; } const fakeRequest = new Readable({ read() { this.push(req.body); this.push(null); }, }); // @ts-expect-error TS(2339) FIXME: Property 'headers' does not exist on type 'Readabl... Remove this comment to see the full error message fakeRequest.headers = req.headers; const handlerName = getFormHandler({ functionsRegistry }); if (!handlerName) { next(); return; } const originalUrl = new URL(req.url, 'http://localhost'); req.url = `/.netlify/functions/${handlerName}${originalUrl.search}`; const ct = parseContentType(req); let fields = {}; let files = {}; if (ct.type.endsWith('/x-www-form-urlencoded')) { const bodyData = await getRawBody(fakeRequest, { length: req.headers['content-length'], limit: '10mb', encoding: ct.parameters.charset, }); fields = Object.fromEntries(new URLSearchParams(bodyData.toString())); } else if (ct.type === 'multipart/form-data') { try { ; [fields, files] = await new Promise((resolve, reject) => { const form = new multiparty.Form({ encoding: ct.parameters.charset || 'utf8' }); // @ts-expect-error TS(7006) FIXME: Parameter 'err' implicitly has an 'any' type. form.parse(fakeRequest, (err, Fields, Files) => { if (err) { reject(err); return; } Files = Object.entries(Files).reduce((prev, [name, values]) => ({ ...prev, // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'. [name]: values.map((value) => ({ filename: value.originalFilename, size: value.size, type: value.headers?.['content-type'], url: value.path, })), }), {}); resolve([ Object.entries(Fields).reduce( // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'. (prev, [name, values]) => ({ ...prev, [name]: values.length > 1 ? values : values[0] }), {}), Object.entries(Files).reduce( // @ts-expect-error TS(2571) FIXME: Object is of type 'unknown'. (prev, [name, values]) => ({ ...prev, [name]: values.length > 1 ? values : values[0] }), {}), ]); }); }); } catch (error) { // @ts-expect-error TS(2345) FIXME: Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message warn(error); next(); return; } } else { warn('Invalid Content-Type for Netlify Dev forms request'); next(); return; } const data = JSON.stringify({ payload: { company: // @ts-expect-error TS(2538) FIXME: Type 'undefined' cannot be used as an index type. fields[Object.keys(fields).find((name) => ['company', 'business', 'employer'].includes(name.toLowerCase()))], last_name: // @ts-expect-error TS(2538) FIXME: Type 'undefined' cannot be used as an index type. fields[Object.keys(fields).find((name) => ['lastname', 'surname', 'byname'].includes(name.toLowerCase()))], first_name: fields[ // @ts-expect-error TS(2538) FIXME: Type 'undefined' cannot be used as an index type. Object.keys(fields).find((name) => ['firstname', 'givenname', 'forename'].includes(name.toLowerCase()))], // @ts-expect-error TS(2538) FIXME: Type 'undefined' cannot be used as an index type. name: fields[Object.keys(fields).find((name) => ['name', 'fullname'].includes(name.toLowerCase()))], email: fields[ // @ts-expect-error TS(2538) FIXME: Type 'undefined' cannot be used as an index type. Object.keys(fields).find((name) => ['email', 'mail', 'from', 'twitter', 'sender'].includes(name.toLowerCase()))], // @ts-expect-error TS(2538) FIXME: Type 'undefined' cannot be used as an index type. title: fields[Object.keys(fields).find((name) => ['title', 'subject'].includes(name.toLowerCase()))], data: { ...fields, ...files, ip: req.connection.remoteAddress, user_agent: req.headers['user-agent'], referrer: req.headers.referer, }, created_at: new Date().toISOString(), human_fields: Object.entries({ ...fields, // @ts-expect-error TS(2339) FIXME: Property 'url' does not exist on type 'unknown'. ...Object.entries(files).reduce((prev, [name, { url }]) => ({ ...prev, [name]: url }), {}), }).reduce((prev, [key, val]) => ({ ...prev, [capitalize(key)]: val }), {}), ordered_human_fields: Object.entries({ ...fields, // @ts-expect-error TS(2339) FIXME: Property 'url' does not exist on type 'unknown'. ...Object.entries(files).reduce((prev, [name, { url }]) => ({ ...prev, [name]: url }), {}), }).map(([key, val]) => ({ title: capitalize(key), name: key, value: val })), site_url: siteUrl, }, }); req.body = data; req.headers = { ...req.headers, 'content-length': String(data.length), 'content-type': 'application/json', 'x-netlify-original-pathname': originalUrl.pathname, 'x-netlify-original-search': originalUrl.search, }; next(); }; }; //# sourceMappingURL=form-submissions-handler.js.map