Skip to content

Commit

Permalink
Merge pull request #392 from liaujianjie/liaujianjie/http-call-node-b…
Browse files Browse the repository at this point in the history
…inary-support

feat: add `binary` output port on `HttpCallNode`
  • Loading branch information
abrenneke authored May 8, 2024
2 parents 62da815 + 7f54555 commit f2f289c
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 28 deletions.
9 changes: 8 additions & 1 deletion packages/app/src/components/RenderDataValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,14 @@ const scalarRenderers: {
</div>
);
},
binary: ({ value }) => <>Binary (length {value.value.length.toLocaleString()})</>,
binary: ({ value }) => {
// FIXME: Coercing `value.value` into a `Uint8Array` here because `Uint8Array` gets parsed as an
// object of shape `{ [index: number]: number }` when stringified via `JSON.stringify()`.
// Consider coercing it back to `Uint8Array` at the entrypoints of the boundaries between
// browser and node.js instead.
const coercedValue = new Uint8Array(Object.values(value.value));
return <>Binary (length {coercedValue.length.toLocaleString()})</>;
},
audio: ({ value }) => {
const {
value: { data },
Expand Down
81 changes: 54 additions & 27 deletions packages/core/src/model/nodes/HttpCallNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export type HttpCallNodeData = {
body: string;
useBodyInput?: boolean;

isBinaryOutput?: boolean;

errorOnNon200?: boolean;
};

Expand Down Expand Up @@ -93,17 +95,29 @@ export class HttpCallNodeImpl extends NodeImpl<HttpCallNode> {
}

getOutputDefinitions(): NodeOutputDefinition[] {
return [
{
dataType: 'string',
id: 'res_body' as PortId,
title: 'Body',
},
{
dataType: 'object',
id: 'json' as PortId,
title: 'JSON',
},
const outputDefinitions: NodeOutputDefinition[] = [];
if (this.data.isBinaryOutput) {
outputDefinitions.push({
dataType: 'binary',
id: 'binary' as PortId,
title: 'Binary',
});
} else {
outputDefinitions.push(
{
dataType: 'string',
id: 'res_body' as PortId,
title: 'Body',
},
{
dataType: 'object',
id: 'json' as PortId,
title: 'JSON',
},
);
}

outputDefinitions.push(
{
dataType: 'number',
id: 'statusCode' as PortId,
Expand All @@ -114,7 +128,9 @@ export class HttpCallNodeImpl extends NodeImpl<HttpCallNode> {
id: 'res_headers' as PortId,
title: 'Headers',
},
];
);

return outputDefinitions;
}

getEditors(): EditorDefinition<HttpCallNode>[] {
Expand Down Expand Up @@ -151,6 +167,11 @@ export class HttpCallNodeImpl extends NodeImpl<HttpCallNode> {
useInputToggleDataKey: 'useBodyInput',
language: 'json',
},
{
type: 'toggle',
label: 'Whether response body is expected to be a binary',
dataKey: 'isBinaryOutput',
},
{
type: 'toggle',
label: 'Error on non-200 status code',
Expand Down Expand Up @@ -244,24 +265,30 @@ export class HttpCallNodeImpl extends NodeImpl<HttpCallNode> {
},
};

const responseBody = await response.text();

output['res_body' as PortId] = {
type: 'string',
value: responseBody,
};

if (response.headers.get('content-type')?.includes('application/json')) {
const jsonData = JSON.parse(responseBody);
output['json' as PortId] = {
type: 'object',
value: jsonData,
if (this.data.isBinaryOutput) {
const responseBlob = await response.blob();
output['binary' as PortId] = {
type: 'binary',
value: new Uint8Array(await responseBlob.arrayBuffer()),
};
} else {
output['json' as PortId] = {
type: 'control-flow-excluded',
value: undefined,
const responseText = await response.text();
output['res_body' as PortId] = {
type: 'string',
value: responseText,
};
if (response.headers.get('content-type')?.includes('application/json')) {
const jsonData = JSON.parse(responseText);
output['json' as PortId] = {
type: 'object',
value: jsonData,
};
} else {
output['json' as PortId] = {
type: 'control-flow-excluded',
value: undefined,
};
}
}

return output;
Expand Down

0 comments on commit f2f289c

Please sign in to comment.