From 248910c71988ed4dc8e95b7f498b7d2a28a3a048 Mon Sep 17 00:00:00 2001 From: Dominique Pfister Date: Wed, 17 Apr 2024 11:14:28 +0200 Subject: [PATCH] feat: suppot YAML in body data (if enabled) (#929) --- package-lock.json | 3 + packages/helix-shared-body-data/package.json | 3 + .../src/body-data-wrapper.d.ts | 5 ++ .../src/body-data-wrapper.js | 7 +- .../test/body-data-wrapper.test.js | 64 +++++++++++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c3319d41..d53c22da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15946,6 +15946,9 @@ "@adobe/fetch": "^4.0.1", "@adobe/helix-shared-wrap": "^1.0.5" }, + "devDependencies": { + "yaml": "2.4.1" + }, "optionalDependencies": { "@adobe/helix-universal": "^4.0.0" } diff --git a/packages/helix-shared-body-data/package.json b/packages/helix-shared-body-data/package.json index ebb13f19..09155941 100644 --- a/packages/helix-shared-body-data/package.json +++ b/packages/helix-shared-body-data/package.json @@ -36,5 +36,8 @@ }, "optionalDependencies": { "@adobe/helix-universal": "^4.0.0" + }, + "devDependencies": { + "yaml": "2.4.1" } } diff --git a/packages/helix-shared-body-data/src/body-data-wrapper.d.ts b/packages/helix-shared-body-data/src/body-data-wrapper.d.ts index a8759e89..ac72c49b 100644 --- a/packages/helix-shared-body-data/src/body-data-wrapper.d.ts +++ b/packages/helix-shared-body-data/src/body-data-wrapper.d.ts @@ -31,6 +31,11 @@ export declare interface BodyDataOptions { * Flag that coerces number strings to numbers. */ coerceNumber?:boolean; + + /** + * Support YAML in the POST body. + */ + supportYAML?:boolean; } /** diff --git a/packages/helix-shared-body-data/src/body-data-wrapper.js b/packages/helix-shared-body-data/src/body-data-wrapper.js index 8081559a..bf9d9c31 100644 --- a/packages/helix-shared-body-data/src/body-data-wrapper.js +++ b/packages/helix-shared-body-data/src/body-data-wrapper.js @@ -22,7 +22,7 @@ const BODY_METHODS = ['POST', 'PUT', 'PATCH']; * available. * * @param {Request} request The universal request - * @param {BodyDataOptions} [opts] Options + * @param {import('./body-data-wrapper').BodyDataOptions} [opts] Options * @returns {Promise} the parsed data object. */ async function getData(request, opts) { @@ -31,6 +31,11 @@ async function getData(request, opts) { return request.json(); } + const { supportYAML } = opts; + if (supportYAML && /\/yaml/.test(contentType) && BODY_METHODS.includes(request.method)) { + return request.text(); + } + let data; if (/^application\/x-www-form-urlencoded/.test(contentType) && BODY_METHODS.includes(request.method)) { data = new URLSearchParams(await request.text()); diff --git a/packages/helix-shared-body-data/test/body-data-wrapper.test.js b/packages/helix-shared-body-data/test/body-data-wrapper.test.js index f41a637c..6b339ae5 100644 --- a/packages/helix-shared-body-data/test/body-data-wrapper.test.js +++ b/packages/helix-shared-body-data/test/body-data-wrapper.test.js @@ -14,6 +14,7 @@ /* eslint-env mocha */ import assert from 'assert'; +import YAML from 'yaml'; import { Request, Response } from '@adobe/fetch'; import wrap from '@adobe/helix-shared-wrap'; @@ -267,3 +268,66 @@ describe('Body Data Wrapper Unit Tests (Form Data)', () => { assert.strictEqual(response.status, 200, 'universal function should be executed'); }); }); + +describe('Body Data Wrapper Unit Tests (YAML Body)', () => { + const contents = { indices: [] }; + + ['POST', 'post', 'PUT', 'PATCH'].forEach((method) => { + it(`Loads YAML (${method})`, async () => { + const universalfunct = async (request, context) => { + const yaml = YAML.parse(context.data); + assert.deepStrictEqual(yaml, contents); + return new Response('ok'); + }; + + const actualfunct = wrap(universalfunct).with(bodyData, { supportYAML: true }); + const response = await actualfunct(new Request('http://localhost', { + body: YAML.stringify(contents), + method, + headers: { + 'content-type': 'text/yaml', + }, + }), { + log, + }); + assert.strictEqual(response.status, 200, 'universal function should be executed'); + }); + }); + + it('Ignores body for GET requests.', async () => { + const universalfunct = async (request, context) => { + assert.deepEqual(context.data, { }); + return new Response('ok'); + }; + + const actualfunct = wrap(universalfunct).with(bodyData, { supportYAML: true }); + const response = await actualfunct(new Request('http://localhost', { + method: 'GET', + headers: { + 'content-type': 'text/yaml', + }, + }), { + log, + }); + assert.strictEqual(response.status, 200); + }); + + it('Ignores body when support YAML is not enabled.', async () => { + const universalfunct = async (request, context) => { + assert.deepEqual(context.data, { }); + return new Response('ok'); + }; + + const actualfunct = wrap(universalfunct).with(bodyData); + const response = await actualfunct(new Request('http://localhost', { + body: YAML.stringify(contents), + method: 'POST', + headers: { + 'content-type': 'text/yaml', + }, + }), { + log, + }); + assert.strictEqual(response.status, 200); + }); +});