@@ -8,6 +8,12 @@ import {OptionsByResourceMap} from "./n8n/OptionsByResourceMap";
88import { INodeProperties } from "n8n-workflow" ;
99import { replacePathVarsToParameter } from "./n8n/utils" ;
1010import { IResourceParser } from "./ResourceParser" ;
11+ import {
12+ BinaryFileType ,
13+ INodeExecutionData , INodePropertyRouting ,
14+ INodeRequestOutput
15+ } from "n8n-workflow/dist/Interfaces" ;
16+ import ResponseObject = OpenAPIV3 . ResponseObject ;
1117
1218export 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 ( / ^ ( i m a g e | a u d i o | v i d e o | t e x t ) \/ [ a - z 0 - 9 . + - ] + $ | ^ a p p l i c a t i o n \/ p d f $ / 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