2022-08-30 14:42:49 +02:00
import {
Integration ,
QueryType ,
IntegrationBase ,
DatasourceFieldType ,
} from "@budibase/types"
2021-06-24 19:16:48 +02:00
module S3Module {
const AWS = require ( "aws-sdk" )
2022-08-30 14:42:49 +02:00
const csv = require ( "csvtojson" )
2021-06-24 19:16:48 +02:00
interface S3Config {
2021-06-24 19:17:26 +02:00
region : string
accessKeyId : string
secretAccessKey : string
2021-12-31 17:15:49 +01:00
s3ForcePathStyle : boolean
endpoint? : string
2021-06-24 19:16:48 +02:00
}
const SCHEMA : Integration = {
docs : "https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html" ,
description :
"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance." ,
friendlyName : "Amazon S3" ,
2022-06-23 12:35:57 +02:00
type : "Object store" ,
2021-06-24 19:16:48 +02:00
datasource : {
region : {
type : "string" ,
2021-12-31 17:15:49 +01:00
required : false ,
2021-06-24 19:16:48 +02:00
default : "us-east-1" ,
} ,
accessKeyId : {
type : "password" ,
required : true ,
} ,
secretAccessKey : {
type : "password" ,
required : true ,
} ,
2021-12-30 18:44:27 +01:00
endpoint : {
type : "string" ,
required : false ,
} ,
signatureVersion : {
type : "string" ,
required : false ,
2022-01-13 18:24:52 +01:00
default : "v4" ,
2021-12-30 18:44:27 +01:00
} ,
2021-06-24 19:16:48 +02:00
} ,
query : {
read : {
2022-08-11 14:50:05 +02:00
type : QueryType . FIELDS ,
2021-06-24 19:16:48 +02:00
fields : {
bucket : {
2022-08-30 12:17:11 +02:00
type : DatasourceFieldType . STRING ,
2021-06-24 19:16:48 +02:00
required : true ,
} ,
2022-08-30 12:17:11 +02:00
delimiter : {
type : DatasourceFieldType . STRING ,
} ,
marker : {
type : DatasourceFieldType . STRING ,
} ,
maxKeys : {
type : DatasourceFieldType . NUMBER ,
display : "Max Keys" ,
} ,
prefix : {
type : DatasourceFieldType . STRING ,
} ,
2021-06-24 19:16:48 +02:00
} ,
2022-08-30 14:42:49 +02:00
} ,
readCsv : {
displayName : "Read CSV" ,
type : QueryType . FIELDS ,
fields : {
bucket : {
type : DatasourceFieldType . STRING ,
required : true ,
} ,
key : {
type : DatasourceFieldType . STRING ,
required : true ,
} ,
} ,
} ,
} ,
2021-06-24 19:16:48 +02:00
}
2021-11-10 20:35:09 +01:00
class S3Integration implements IntegrationBase {
2021-06-24 19:16:48 +02:00
private readonly config : S3Config
private client : any
constructor ( config : S3Config ) {
this . config = config
2021-12-31 17:15:49 +01:00
if ( this . config . endpoint ) {
this . config . s3ForcePathStyle = true
} else {
delete this . config . endpoint
}
2021-06-24 19:16:48 +02:00
2021-12-31 17:15:49 +01:00
this . client = new AWS . S3 ( this . config )
2021-06-24 19:16:48 +02:00
}
2022-08-30 14:42:49 +02:00
async read ( query : {
bucket : string
delimiter : string
expectedBucketOwner : string
marker : string
maxKeys : number
prefix : string
2022-08-30 12:17:11 +02:00
} ) {
2021-06-24 19:16:48 +02:00
const response = await this . client
. listObjects ( {
Bucket : query.bucket ,
2022-08-30 12:17:11 +02:00
Delimiter : query.delimiter ,
Marker : query.marker ,
MaxKeys : query.maxKeys ,
Prefix : query.prefix ,
2021-06-24 19:16:48 +02:00
} )
. promise ( )
return response . Contents
}
2022-08-30 14:42:49 +02:00
async readCsv ( query : { bucket : string ; key : string } ) {
const stream = this . client
. getObject ( {
Bucket : query.bucket ,
Key : query.key ,
} )
. createReadStream ( )
2022-08-30 16:18:44 +02:00
let csvError = false
return new Promise ( async ( resolve , reject ) = > {
stream . on ( "error" , ( err : Error ) = > {
reject ( err )
} )
const response = csv ( )
. fromStream ( stream )
. on ( "error" , ( ) = > {
csvError = true
2022-08-30 14:55:55 +02:00
} )
2022-08-30 16:18:44 +02:00
stream . on ( "finish" , ( ) = > {
resolve ( response )
} )
} ) . catch ( err = > {
if ( csvError ) {
throw new Error ( "Could not read CSV" )
} else {
throw err
}
2022-08-30 14:55:55 +02:00
} )
2022-08-30 14:42:49 +02:00
}
2021-06-24 19:16:48 +02:00
}
module .exports = {
schema : SCHEMA ,
integration : S3Integration ,
}
}