Skip to content

Commit 1907e64

Browse files
author
Noémie TAVIERE
committed
add image as output
1 parent c08043b commit 1907e64

File tree

7 files changed

+663
-10
lines changed

7 files changed

+663
-10
lines changed

src/N8NPropertiesBuilder.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,7 @@ test('enum schema', () => {
753753
},
754754
{
755755
displayName: 'Type',
756+
description: undefined,
756757
name: 'type',
757758
type: 'options',
758759
default: 'type1',

src/OperationsCollector.ts

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ import {OptionsByResourceMap} from "./n8n/OptionsByResourceMap";
88
import {INodeProperties} from "n8n-workflow";
99
import {replacePathVarsToParameter} from "./n8n/utils";
1010
import {IResourceParser} from "./ResourceParser";
11+
import {
12+
BinaryFileType,
13+
INodeExecutionData, INodePropertyRouting,
14+
INodeRequestOutput
15+
} from "n8n-workflow/dist/Interfaces";
16+
import ResponseObject = OpenAPIV3.ResponseObject;
1117

1218
export class BaseOperationsCollector implements OpenAPIVisitor {
1319
public readonly _fields: INodeProperties[]
@@ -131,24 +137,71 @@ export class BaseOperationsCollector implements OpenAPIVisitor {
131137
}
132138

133139
protected parseOperation(operation: OpenAPIV3.OperationObject, context: OperationContext) {
134-
const method = context.method
140+
const method = context.method;
135141
const uri = context.pattern;
136-
const parser = this.operationParser
142+
const parser = this.operationParser;
143+
let returns_raw_data = operation.responses &&
144+
Object.entries(operation.responses)
145+
.filter(([code, data]) =>
146+
code.startsWith("2") && 'content' in data && data.content
147+
)
148+
.map(([_, data]) => (data as ResponseObject).content)
149+
.map((content) => Object.keys(content!))
150+
.flat()
151+
.filter((contentType) => contentType.match(/^(image|audio|video|text)\/[a-z0-9.+-]+$|^application\/pdf$/i))
152+
.length > 0;
153+
let output: INodeRequestOutput | undefined = undefined
154+
if (returns_raw_data) {
155+
let file_type = (type: String): BinaryFileType | undefined => {
156+
if (type.startsWith('image/')) return 'image';
157+
if (type.startsWith('audio/')) return 'audio';
158+
if (type.startsWith('video/')) return 'video';
159+
if (type === 'text/html') return 'html';
160+
if (type.startsWith('text/')) return 'text';
161+
if (type === 'application/pdf') return 'pdf';
162+
return undefined;
163+
};
164+
output = {
165+
postReceive: [async (items, response): Promise<INodeExecutionData[]> => {
166+
let bufferData = Buffer.from(items[0].json as unknown as ArrayBuffer);
167+
const base64Data = bufferData.toString('base64');
168+
return [{
169+
binary: {
170+
data: {
171+
data: base64Data,
172+
mimeType: response.headers['content-type'] as string,
173+
fileSize: bufferData.length.toString(),
174+
fileType: file_type(response.headers['content-type'] as string),
175+
},
176+
},
177+
json: {},
178+
}];
179+
}],
180+
}
181+
}
182+
let routing : INodePropertyRouting = {
183+
request: {
184+
// @ts-ignore
185+
method: method.toUpperCase(),
186+
url: `=${replacePathVarsToParameter(uri)}`,
187+
},
188+
};
189+
if (returns_raw_data) {
190+
routing.output = output;
191+
routing.request!.headers = {
192+
Accept: 'image/*',
193+
};
194+
routing.request!.json = false;
195+
routing.request!.encoding = 'arraybuffer';
196+
}
137197
const option = {
138198
name: parser.name(operation, context),
139199
value: parser.value(operation, context),
140200
action: parser.action(operation, context),
141201
description: parser.description(operation, context),
142-
routing: {
143-
request: {
144-
method: method.toUpperCase(),
145-
url: `=${replacePathVarsToParameter(uri)}`,
146-
},
147-
},
202+
routing,
148203
};
149204
const fields = this.parseFields(operation, context);
150-
151-
152205
return {
153206
option: option,
154207
fields: fields,

0 commit comments

Comments
 (0)