From b8b0d47221726b183048faedabc872905211769a Mon Sep 17 00:00:00 2001 From: jreyesr Date: Tue, 11 Jun 2024 22:17:39 -0500 Subject: [PATCH] Add new batchFIle template tag that replaces itself by a file's _contents_ on request send --- main.js | 31 ++++++++++++++++++++++++++++++- tags.js | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index ec4a425..f92d4a4 100644 --- a/main.js +++ b/main.js @@ -3,8 +3,37 @@ import { createRoot } from 'react-dom/client'; import BatchDialog from './components/BatchDialog'; import BatchDialogSettings from './components/BatchDialogSettings'; -import { templateTags } from './tags'; +import { templateTags, MAGIC_FILE_FIELD_PREFIX } from './tags'; + +module.exports.requestHooks = [ + /* + Intercepts outgoing requests, and then: + 1. Finds any fields in the req body whose value starts with %INSOMNIA_PLUGIN_BATCH_REQUESTS% + 2. Force-converts them into File fields (they'll be coming in as Text fields) + 3. The file that will be sent on that field will be the rest of the text value + (i.e. everything that came _after_ %INSOMNIA_PLUGIN_BATCH_REQUESTS%) + + This hook works in concert with the Batch (File) template tag (see tags.js), + which generates values with the requisite magic prefix. + */ + context => { + const body = context.request.getBody(); + if(body.mimeType === "multipart/form-data" && body.params) { + for(let param of body.params) { + if(param.value.startsWith(MAGIC_FILE_FIELD_PREFIX)) { + param.type = "file" + param.fileName = param.value.replace(MAGIC_FILE_FIELD_PREFIX, ""); + } + } + } + context.request.setBody(body); + } +]; + + +// Provides the context menu action that appears when opening the dropdown menu +// for a request, which is the main entrypoint to the plugin's functionality module.exports.requestActions = [{ label: 'Batch Requests', icon: 'fa-repeat', diff --git a/tags.js b/tags.js index c8d3ad9..097154a 100644 --- a/tags.js +++ b/tags.js @@ -1,3 +1,5 @@ +export const MAGIC_FILE_FIELD_PREFIX = "%INSOMNIA_PLUGIN_BATCH_REQUESTS%" + export const templateTags = [{ name: 'batchVariable', displayName: 'Batch', @@ -32,4 +34,48 @@ export const templateTags = [{ return sample; } }, +}, +/* + When set on a Text field in a form body, this template tag will replace itself with the value + "%INSOMNIA_PLUGIN_BATCH_REQUESTS%" + This will be set by Insomnia as the (text) value of the field. + Then, as the request is going out, it'll be intercepted by a Request hook (see main.js), + which will strip the prefix and force the field to be interpreted as a File, rather than pure text, + as if a user had selected a file to begin with, in the Insomnia UI +*/ +{ + name: 'batchFile', + displayName: 'Batch (File)', + liveDisplayName: ([colName, sample]) => (colName.value ? `CSV[${colName.value}] as File: ${sample.value}` : 'Batch'), + description: 'Placeholder for the Batch Requests plugin', + args: [ + { + displayName: 'Name', + description: 'Ensure that this value matches the name of a column in your CSV file', + type: 'string', + validate: (val) => (val ? '' : 'Enter a column name!'), + }, + { + displayName: 'Sample value', + description: 'This value will be used when sending the request manually (outside of Batch Requests)', + type: 'string' + } + ], + async run(context, name, sample) { + // context.renderPurpose is set to 'send' when actually sending the request + if(context.renderPurpose === 'send') { + const extraData = context.context.getExtraInfo("batchExtraData") + if(extraData) { + console.debug('[store.get]', extraData); + // Magic marker so we can later (in a request hook) identify these fields and mangle them + return MAGIC_FILE_FIELD_PREFIX + JSON.parse(extraData)[name]; + } else { + console.error(`Cannot find column ${name} on request extra data! Falling back to sample value.`); + return MAGIC_FILE_FIELD_PREFIX + sample; + } + } else { + // context.renderPurpose is undefined when previewing the template tag's value + return "[File contents of " + sample + "]"; + } + }, }] \ No newline at end of file