feat: support template in all code blocks

This commit is contained in:
Morten Olsen
2025-05-18 20:31:23 +02:00
parent 1cb885bb32
commit 1b2d345420
5 changed files with 132 additions and 88 deletions

View File

@@ -0,0 +1,34 @@
import Handlebars from "handlebars";
import { ExecutionHandler } from "../execution.js";
const codeHandler: ExecutionHandler = ({
node,
addStep,
}) => {
if (node.type !== 'code' || node.lang === 'http') {
return;
}
const optionParts = node.meta?.split(',') || [];
const options = Object.fromEntries(
optionParts.filter(Boolean).map((option) => {
const [key, value] = option.split('=');
return [key.trim(), value?.trim() || true];
})
);
addStep({
type: 'code',
node,
action: async ({ context }) => {
node.meta = undefined;
if (options['no-tmpl'] === true) {
return;
}
const template = Handlebars.compile(node.value);
const content = template(context);
node.value = content;
},
});
};
export { codeHandler };

View File

@@ -6,85 +6,82 @@ const httpHandler: ExecutionHandler = ({
node,
addStep,
}) => {
if (node.type === 'code') {
if (node.lang !== 'http') {
return;
}
const optionParts = node.meta?.split(',') || [];
const options = Object.fromEntries(
optionParts.filter(Boolean).map((option) => {
const [key, value] = option.split('=');
return [key.trim(), value?.trim() || true];
})
);
addStep({
type: 'http',
node,
action: async ({ context }) => {
if (options.disable === true) {
return;
}
const template = Handlebars.compile(node.value);
const content = template(context);
const [head, body] = content.split('\n\n');
const [top, ...headerItems] = head.split('\n');
const [method, url] = top.split(' ');
const headers = Object.fromEntries(
headerItems.map((header) => {
const [key, value] = header.split(':');
return [key.trim(), value?.trim() || ''];
})
);
let parsedBody = body;
if (options.format === 'yaml') {
try {
const parsed = YAML.parse(body);
parsedBody = JSON.stringify(parsed);
} catch (error) {
parsedBody = `Error parsing YAML: ${error}`;
}
}
const response = await fetch(url, {
method,
headers,
body
});
let responseText = await response.text();
if (options.json) {
try {
responseText = JSON.parse(responseText);
} catch (e) {
responseText = `Error parsing JSON: ${e}`;
}
}
node.value = content;
node.meta = undefined;
context.addRequest({
id: options.id?.toString(),
request: {
method,
url,
headers,
body,
},
response: {
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries(response.headers.entries()),
body: responseText,
},
});
},
});
if (node.type !== 'code' || node.lang !== 'http') {
return;
}
const optionParts = node.meta?.split(',') || [];
const options = Object.fromEntries(
optionParts.filter(Boolean).map((option) => {
const [key, value] = option.split('=');
return [key.trim(), value?.trim() || true];
})
);
addStep({
type: 'http',
node,
action: async ({ context }) => {
if (options.disable === true) {
return;
}
const template = Handlebars.compile(node.value);
const content = template(context);
const [head, body] = content.split('\n\n');
const [top, ...headerItems] = head.split('\n');
const [method, url] = top.split(' ');
const headers = Object.fromEntries(
headerItems.map((header) => {
const [key, value] = header.split(':');
return [key.trim(), value?.trim() || ''];
})
);
let parsedBody = body;
if (options.format === 'yaml') {
try {
const parsed = YAML.parse(body);
parsedBody = JSON.stringify(parsed);
} catch (error) {
parsedBody = `Error parsing YAML: ${error}`;
}
}
const response = await fetch(url, {
method,
headers,
body
});
let responseText = await response.text();
if (options.json) {
try {
responseText = JSON.parse(responseText);
} catch (e) {
responseText = `Error parsing JSON: ${e}`;
}
}
node.value = content;
node.meta = undefined;
context.addRequest({
id: options.id?.toString(),
request: {
method,
url,
headers,
body,
},
response: {
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries(response.headers.entries()),
body: responseText,
},
});
},
});
};
export { httpHandler };

View File

@@ -1,10 +1,11 @@
import { ExecutionHandler } from "../execution.js";
import { fileHandler } from "./handlers.file.js";
import { fileHandler } from "./handlers.md.js";
import { httpHandler } from "./handlers.http.js";
import { inputHandler } from "./handlers.input.js";
import { rawMdHandler } from "./handlers.raw-md.js";
import { responseHandler } from "./handlers.response.js";
import { textHandler } from "./handlers.text.js";
import { codeHandler } from "./handlers.code.js";
const handlers = [
fileHandler,
@@ -13,6 +14,7 @@ const handlers = [
textHandler,
inputHandler,
rawMdHandler,
codeHandler,
] satisfies ExecutionHandler[];
export { handlers };