Fix top level return incompatibility (#818)

* Run transformation functions at top level

* changelog
This commit is contained in:
Will Hunt 2023-09-26 13:56:11 +01:00 committed by GitHub
parent 257c93e0e0
commit c3cb131e4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 1 deletions

1
changelog.d/818.bugfix Normal file
View File

@ -0,0 +1 @@
Fix transformation scripts breaking if they include a `return` at the top level

View File

@ -332,7 +332,7 @@ export class GenericHookConnection extends BaseConnection implements IConnection
ctx.runtime.setInterruptHandler(shouldInterruptAfterDeadline(Date.now() + TRANSFORMATION_TIMEOUT_MS));
try {
ctx.setProp(ctx.global, 'HookshotApiVersion', ctx.newString('v2'));
const ctxResult = ctx.evalCode(`const data = ${JSON.stringify(data)};\n\n${this.state.transformationFunction}`);
const ctxResult = ctx.evalCode(`const data = ${JSON.stringify(data)};\n(() => { ${this.state.transformationFunction} })();`);
if (ctxResult.error) {
const e = Error(`Transformation failed to run: ${JSON.stringify(ctx.dump(ctxResult.error))}`);

View File

@ -11,6 +11,7 @@ const ROOM_ID = "!foo:bar";
const V1TFFunction = "result = `The answer to '${data.question}' is ${data.answer}`;";
const V2TFFunction = "result = {plain: `The answer to '${data.question}' is ${data.answer}`, version: 'v2'}";
const V2TFFunctionWithReturn = "result = {plain: `The answer to '${data.question}' is ${data.answer}`, version: 'v2'}; return;";
async function testSimpleWebhook(connection: GenericHookConnection, mq: LocalMQ, testValue: string) {
const webhookData = {simple: testValue};
@ -199,6 +200,29 @@ describe("GenericHookConnection", () => {
type: 'm.room.message',
});
});
it("will handle a hook event with a top-level return", async () => {
const webhookData = {question: 'What is the meaning of life?', answer: 42};
const [connection, mq] = createGenericHook({name: 'test', transformationFunction: V2TFFunctionWithReturn}, {
enabled: true,
urlPrefix: "https://example.com/webhookurl",
allowJsTransformationFunctions: true,
}
);
const messagePromise = handleMessage(mq);
await connection.onGenericHook(webhookData);
expect(await messagePromise).to.deep.equal({
roomId: ROOM_ID,
sender: connection.getUserId(),
content: {
body: "The answer to 'What is the meaning of life?' is 42",
format: "org.matrix.custom.html",
formatted_body: "<p>The answer to 'What is the meaning of life?' is 42</p>",
msgtype: "m.notice",
"uk.half-shot.hookshot.webhook_data": webhookData,
},
type: 'm.room.message',
});
});
it("will fail to handle a webhook with an invalid script", async () => {
const webhookData = {question: 'What is the meaning of life?', answer: 42};
const [connection, mq] = createGenericHook({name: 'test', transformationFunction: "bibble bobble"}, {