@budibase/server 3.23.10 → 3.23.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builder/assets/{easymde-92d28041.js → easymde-ad68176c.js} +1 -1
- package/builder/assets/{index-25de6765.css → index-68c7076a.css} +1 -1
- package/builder/assets/{index-200c1478.js → index-d2c74196.js} +3 -3
- package/builder/index.html +2 -2
- package/dist/automation.js +1 -1
- package/dist/automation.js.map +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/query.js +1 -1
- package/dist/query.js.map +2 -2
- package/package.json +2 -2
- package/src/integrations/rest.ts +31 -49
- package/src/integrations/tests/rest.spec.ts +44 -1
package/dist/index.js
CHANGED
|
@@ -917,7 +917,7 @@ Example: return $("Score") + $("Weight")
|
|
|
917
917
|
CONSTRAINT [PK_${a}] PRIMARY KEY (${u})`),c+=`
|
|
918
918
|
);`,r.push(c)}return r.join(`
|
|
919
919
|
`)}},sme={schema:bXr,integration:ame}});var Mxt,Bxt,jxt,wXr,ume,cme,qxt=v(()=>{"use strict";V();Mxt=require("@aws-sdk/client-s3"),Bxt=te(require("csvtojson")),jxt=te(require("stream")),wXr={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",type:"Object store",features:{connection:!0},datasource:{region:{type:"string",required:!1,default:"us-east-1"},accessKeyId:{type:"password",required:!0},secretAccessKey:{type:"password",required:!0},endpoint:{type:"string",required:!1},signatureVersion:{type:"string",required:!1,default:"v4"}},query:{create:{type:"fields",fields:{bucket:{display:"New Bucket",type:"string",required:!0},location:{required:!0,default:"us-east-1",type:"string"},grantFullControl:{display:"Grant full control",type:"string"},grantRead:{display:"Grant read",type:"string"},grantReadAcp:{display:"Grant read ACP",type:"string"},grantWrite:{display:"Grant write",type:"string"},grantWriteAcp:{display:"Grant write ACP",type:"string"}}},read:{type:"fields",fields:{bucket:{type:"string",required:!0},delimiter:{type:"string"},marker:{type:"string"},maxKeys:{type:"number",display:"Max Keys"},prefix:{type:"string"}}},readCsv:{displayName:"Read CSV",type:"fields",readable:!0,fields:{bucket:{type:"string",required:!0},key:{type:"string",required:!0}}},delete:{type:"fields",fields:{bucket:{type:"string",required:!0},delete:{type:"json",required:!0}}}},extra:{acl:{required:!1,displayName:"ACL",type:"list",data:{create:["private","public-read","public-read-write","authenticated-read"]}}}},ume=class{static{o(this,"S3Integration")}constructor(t){this.config={forcePathStyle:t.s3ForcePathStyle||!0,credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey},region:t.region,endpoint:t.endpoint},t.endpoint?(this.config.requestChecksumCalculation="WHEN_REQUIRED",this.config.responseChecksumValidation="WHEN_REQUIRED",this.config.forcePathStyle=!0):delete this.config.endpoint,this.client=new Mxt.S3(this.config)}async testConnection(){let t={connected:!1};try{await this.client.listBuckets({MaxBuckets:1}),t.connected=!0}catch(r){t.error=r.message}return t}async create(t){let r={Bucket:t.bucket,ACL:t.extra?.acl,GrantFullControl:t.grantFullControl,GrantRead:t.grantRead,GrantReadACP:t.grantReadAcp,GrantWrite:t.grantWrite,GrantWriteACP:t.grantWriteAcp};return t.location&&(r.CreateBucketConfiguration={LocationConstraint:t.location}),await this.client.createBucket(r)}async read(t){return(await this.client.listObjects({Bucket:t.bucket,Delimiter:t.delimiter,Marker:t.marker,MaxKeys:t.maxKeys,Prefix:t.prefix})).Contents}async readCsv(t){let n=(await this.client.getObject({Bucket:t.bucket,Key:t.key})).Body?.transformToWebStream();if(!n||!(n instanceof jxt.default.Readable))throw new Error("Unable to retrieve CSV - invalid stream");let i=!1;return new Promise((a,s)=>{n.on("error",c=>{s(c)});let u=(0,Bxt.default)().fromStream(n).on("error",()=>{i=!0});n.on("end",()=>{a(u)})}).catch(a=>{throw i?new Error("Could not read CSV"):a})}async delete(t){return await this.client.deleteObjects({Bucket:t.bucket,Delete:JSON.parse(t.delete)})}},cme={schema:wXr,integration:ume}});var $xt,_Xr,lme,pme,Wxt=v(()=>{"use strict";V();$xt=te(require("airtable")),_Xr={docs:"https://airtable.com/api",description:"Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.",friendlyName:"Airtable",type:"Spreadsheet",features:{connection:!0},datasource:{apiKey:{type:"password",default:"enter api key",required:!0},base:{type:"string",default:"mybase",required:!0}},query:{create:{type:"fields",customisable:!0,fields:{table:{type:"string",required:!0}}},read:{type:"fields",fields:{table:{type:"string",required:!0},view:{type:"string",required:!0},numRecords:{type:"number",default:10}}},update:{type:"fields",customisable:!0,fields:{id:{display:"Record ID",type:"string",required:!0},table:{type:"string",required:!0}}},delete:{type:"json"}}},lme=class{static{o(this,"AirtableIntegration")}constructor(t){this.config=t,this.client=new $xt.default(t).base(t.base)}async testConnection(){let t=Date.now().toString();try{return await this.client.makeRequest({path:`/${t}`}),{connected:!0}}catch(r){return r.message===`Could not find table ${t} in application ${this.config.base}`?{connected:!0}:{connected:!1,error:r.message}}}async create(t){let{table:r,json:n}=t;try{return await this.client(r).create([{fields:n}])}catch(i){throw console.error("Error writing to airtable",i),i}}async read(t){try{return(await this.client(t.table).select({maxRecords:t.numRecords||10,view:t.view}).firstPage()).map(({fields:n})=>n)}catch(r){return console.error("Error writing to airtable",r),[]}}async update(t){let{table:r,id:n,json:i}=t;try{return await this.client(r).update([{id:n,fields:i}])}catch(a){throw console.error("Error writing to airtable",a),a}}async delete(t){try{return await this.client(t.table).destroy(t.ids)}catch(r){throw console.error("Error writing to airtable",r),r}}},pme={schema:_Xr,integration:lme}});function AXr(e){for(let t=0;t<e.length;t++){let r=e[t];if(typeof r!="string")continue;let n=r.match(bEt);if(n&&n[0]!==""&&!isNaN(Number(n[0])))e[t]=parseFloat(r);else if(vEt(r)){let i;i=new Date(r),isNaN(i)&&(i=r),e[t]=i}}return e}var Gxt,EXr,SXr,xXr,fme,dme,zxt=v(()=>{"use strict";V();tn();As();f6();X();Gxt=te(require("mysql2/promise")),EXr=cr.Sql,SXr={docs:"https://github.com/sidorares/node-mysql2",plus:!0,friendlyName:"MySQL",type:"Relational",description:"MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",features:{connection:!0,fetch_table_names:!0,export_schema:!0},datasource:{host:{type:"string",default:Rs,required:!0},port:{type:"number",default:3306,required:!1},user:{type:"string",default:"root",required:!0},password:{type:"password",default:"root",required:!0},database:{type:"string",required:!0},ssl:{type:"object",required:!1},rejectUnauthorized:{type:"boolean",default:!0,required:!1}},query:{create:{type:"sql"},read:{type:"sql"},update:{type:"sql"},delete:{type:"sql"}}},xXr=o(function(e,t){return e.type=="DATETIME"||e.type==="DATE"||e.type==="TIMESTAMP"||e.type==="LONGLONG"?e.string():e.type==="BIT"&&e.length===1?e.buffer()?.[0]:t()},"defaultTypeCasting");o(AXr,"bindingTypeCoerce");fme=class extends EXr{constructor(r){super("mysql2");this.config=r,r.ssl&&Object.keys(r.ssl).length===0&&delete r.ssl,r.rejectUnauthorized!=null&&!r.rejectUnauthorized&&r.ssl&&typeof r.ssl!="string"&&(r.ssl.rejectUnauthorized=r.rejectUnauthorized),delete r.rejectUnauthorized,this.config={...r,typeCast:xXr,multipleStatements:!0,timezone:"Z"}}static{o(this,"MySQLIntegration")}async testConnection(){let r={connected:!1};try{let[n]=await this.internalQuery({sql:"SELECT 1+1 AS checkRes"},{connect:!0});r.connected=n?.checkRes==2}catch(n){let i=Zw("MYSQL",n.errno);i?r.error=i:r.error=n.message}return r}getBindingIdentifier(){return"?"}getStringConcat(r){return`concat(${r.join(", ")})`}defineTypeCastingFromSchema(r){r&&(this.config.typeCast=function(n,i){if(r[n.name]?.name===n.name&&["LONGLONG","NEWDECIMAL","DECIMAL"].includes(n.type))if(r[n.name]?.type==="number"){let a=n.string();return a?Number(a):null}else return n.string();return n.type=="DATETIME"||n.type==="DATE"||n.type==="TIMESTAMP"?n.string():n.type==="BIT"&&n.length===1?n.buffer()?.[0]:i()})}async connect(){this.client=await Gxt.default.createConnection(this.config),(await this.internalQuery({sql:"SELECT VERSION();"},{connect:!1}))?.[0]?.["VERSION()"]?.toLowerCase().includes("mariadb")&&this.setExtendedSqlClient("mariadb")}async disconnect(){await this.client.end()}async internalQuery(r,n={connect:!0,disableCoercion:!1}){try{n?.connect&&await this.connect();let i=r.bindings||[],a=n?.disableCoercion?i:AXr(i);return this.log(r.sql,a),(await this.client.query(r.sql,a))[0]}catch(i){let a=Zw("MYSQL",i.errno);throw a?new Error(a,{cause:i}):i}finally{n?.connect&&this.client&&await this.disconnect()}}async buildSchema(r,n){let i={};await this.connect();try{let u=await this.queryTableNames();for(let c of u){let l=[],p={},f=await this.internalQuery({sql:`DESCRIBE \`${c}\`;`},{connect:!1});for(let d of f){let m=d.Field;d.Key==="PRI"&&l.indexOf(d.Key)===-1&&l.push(m);let h=d.Default!=null,g=typeof d.Extra=="string"&&(d.Extra==="auto_increment"||d.Extra.toLowerCase().includes("generated")),y=d.Null!=="YES";p[m]=wy({name:m,autocolumn:g,presence:y&&!g&&!h,externalType:d.Type,options:d.Type.startsWith("enum")?d.Type.substring(6,d.Type.length-2).split("','"):void 0})}i[c]||(i[c]={type:"table",_id:Au(r,c),sourceId:r,sourceType:"external",primary:l,name:c,schema:p})}}finally{await this.disconnect()}let a=td(i,n),s=rd(i);return{tables:a,errors:s}}async queryTableNames(){return(await this.internalQuery({sql:"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_TYPE = 'BASE TABLE'"},{connect:!1})).map(n=>n.TABLE_NAME)}async getTableNames(){await this.connect();try{return this.queryTableNames()}finally{await this.disconnect()}}async queryViewNames(){return(await this.internalQuery({sql:"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA = DATABASE()"},{connect:!1})).map(n=>n.TABLE_NAME)}async getViewNames(){await this.connect();try{return this.queryViewNames()}finally{await this.disconnect()}}async create(r){let n=await this.internalQuery(Ao(r));return n.length?n:[{created:!0}]}async read(r){return this.internalQuery(Ao(r))}async update(r){let n=await this.internalQuery(Ao(r));return n.length?n:[{updated:!0}]}async delete(r){let n=await this.internalQuery(Ao(r));return n.length?n:[{deleted:!0}]}async query(r){await this.connect();try{let n=o(a=>this.internalQuery(a,{connect:!1,disableCoercion:!0}),"queryFn"),i=o(a=>Array.isArray(a)?this.convertJsonStringColumns(r.table,a,r.tableAliases):a,"processFn");return await this.queryWithReturning(r,n,i)}finally{await this.disconnect()}}async getExternalSchema(){try{let[r]=await this.internalQuery({sql:`SHOW CREATE DATABASE IF NOT EXISTS \`${this.config.database}\``}),n=[r["Create Database"]],i=await this.internalQuery({sql:"SHOW TABLES"});for(let a of i){let s=a[`Tables_in_${this.config.database}`],c=(await this.internalQuery({sql:`SHOW CREATE TABLE \`${s}\``}))[0]["Create Table"];n.push(c)}return n.join(`;
|
|
920
|
-
`)+";"}finally{this.disconnect()}}},dme={schema:SXr,integration:fme}});var g6,TXr,mme,hme,Vxt=v(()=>{"use strict";V();g6=require("arangojs"),TXr={docs:"https://github.com/arangodb/arangojs",friendlyName:"ArangoDB",type:"Non-relational",description:"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ",features:{connection:!0},datasource:{url:{type:"string",default:"http://localhost:8529",required:!0},username:{type:"string",default:"root",required:!0},password:{type:"password",required:!0},databaseName:{type:"string",default:"_system",required:!0},collection:{type:"string",required:!0}},query:{read:{type:"sql"},create:{type:"json"}}},mme=class{static{o(this,"ArangoDBIntegration")}constructor(t){let r={url:t.url,databaseName:t.databaseName,auth:{username:t.username,password:t.password}};this.config=t,this.client=new g6.Database(r)}async testConnection(){let t={connected:!1};try{await this.client.get(),t.connected=!0}catch(r){t.error=r.message}return t}async read(t){try{return(await this.client.query(t.sql)).all()}catch(r){throw console.error("Error querying arangodb",r.message),r}finally{this.client.close()}}async create(t){let r=this.client.collection(this.config.collection);try{return(await this.client.query(g6.aql`INSERT ${t.json} INTO ${r} RETURN NEW`)).all()}catch(n){throw console.error("Error querying arangodb",n.message),n}finally{this.client.close()}}},hme={schema:TXr,integration:mme}});function Hxt(e,t){let r=e.get("content-type")||"",n=e.get("content-disposition")||"";if(n){let i=/"(?:[^"\\]|\\.)*"|;/g,a=null,s=!1;for(;(a=i.exec(n))!==null;)a[0]===";"&&(s=!0);if(!s)return{contentDisposition:`attachment; ${n}`,contentType:r}}else if(t?.downloadImages&&r.startsWith("image/"))return{contentDisposition:`attachment; filename="image.${r.split("/")[1]}"`,contentType:r};return{contentDisposition:n,contentType:r}}var Kxt=v(()=>{"use strict";o(Hxt,"getAttachmentHeaders")});var Qxt,gme,y6,yme,Yxt,Jxt,Xxt,Ey,HP,IXr,bme,OXr,vme,wme,Zxt=v(()=>{"use strict";V();Qxt=te(require("lodash/get")),gme=te(require("querystring"));As();y6=require("perf_hooks"),yme=require("url");X();tn();Yxt=require("content-disposition"),Jxt=te(require("path")),Xxt=require("xml2js");Kxt();Xe();$e();As();Ey=require("undici");Bt();HP={path:{type:"string",display:"URL"},queryString:{type:"string"},headers:{type:"object"},enabledHeaders:{type:"object"},requestBody:{type:"json"},bodyType:{type:"string",enum:Object.values(MG)},pagination:{type:"object"}},IXr={docs:"https://github.com/node-fetch/node-fetch",description:"With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.",friendlyName:"REST API",type:"API",datasource:{url:{type:"string",default:"",required:!1,deprecated:!0},defaultHeaders:{type:"object",required:!1,default:{}},rejectUnauthorized:{display:"Reject Unauthorized",type:"boolean",default:!0,required:!1},downloadImages:{display:"Download images",type:"boolean",default:!0,required:!1}},query:{create:{readable:!0,displayName:"POST",type:"fields",fields:HP},read:{displayName:"GET",readable:!0,type:"fields",fields:HP},update:{displayName:"PUT",readable:!0,type:"fields",fields:HP},patch:{displayName:"PATCH",readable:!0,type:"fields",fields:HP},delete:{displayName:"DELETE",type:"fields",fields:HP}}},bme=o(e=>Object.prototype.toString.call(e)==="[object Object]","isPlainRecord"),OXr=o(e=>{if(e==null)return{bodyString:"",bodyObject:{},jsonValue:void 0};if(typeof e=="string")try{let t=JSON.parse(e);return bme(t)?{bodyString:e,bodyObject:t,jsonValue:t}:{bodyString:e,bodyObject:{},jsonValue:t}}catch(t){return{bodyString:e,bodyObject:{},parseError:t}}return Buffer.isBuffer(e)?{bodyString:e.toString(),bodyObject:{},jsonValue:e.toString()}:e instanceof Uint8Array?{bodyString:Buffer.from(e).toString(),bodyObject:{},jsonValue:Buffer.from(e).toString()}:bme(e)?{bodyString:JSON.stringify(e),bodyObject:e,jsonValue:e}:Array.isArray(e)?{bodyString:JSON.stringify(e),bodyObject:{},jsonValue:e}:{bodyString:JSON.stringify(e),bodyObject:{},jsonValue:void 0}},"normaliseBody"),vme=class{constructor(t){this.headers={};this.startTimeMs=y6.performance.now();this.config=t}static{o(this,"RestIntegration")}async parseResponse(t,r){let n,i,a={},s,{contentType:u,contentDisposition:c}=Hxt(t.headers,{downloadImages:this.config.downloadImages}),l=t.headers.get("content-length"),p=t.status>=200&&t.status<300;(c.includes("filename")||c.includes("attachment")||c.includes("form-data"))&&p&&(s=Jxt.default.basename((0,Yxt.parse)(c).parameters?.filename)||"");let f=!1,d;try{if(s)return oSt(t,s,this.startTimeMs);{d=t.text?await t.text():"",!l&&d&&(l=Buffer.byteLength(d,"utf8").toString());let y=l&&parseInt(l)>0||d.length>0;if(t.status===204)n=[],i="";else if(y&&u.includes("application/json"))f=!0,n=JSON.parse(d),i=d;else if(y&&u.includes("text/xml")||u.includes("application/xml")){f=!0;let b=await iSt(d);n=b.data,i=b.rawXml}else n=d,i=d}}catch(y){if(f)n=d,i=d;else throw new Error(`Failed to parse response body: ${y}`)}let m=UW(l||"0"),h=`${Math.round(y6.performance.now()-this.startTimeMs)}ms`;for(let[y,b]of t.headers.entries())a[y]=b;let g;return r?.responseParam&&(g=(0,Qxt.default)(n,r.responseParam)),{data:n,info:{code:t.status,size:m,time:h},extra:{raw:i,headers:a},pagination:{cursor:g}}}getUrl(t,r,n,i){if(n?.location==="query"&&i){let{pageParam:u,sizeParam:c}=n,l=new yme.URLSearchParams;u&&i.page!=null&&l.append(u,i.page),c&&i.limit!=null&&l.append(c,String(i.limit));let p=l.toString();p&&(r=`${p}&${r}`)}if(r){let u=gme.default.decode(r),c={};for(let[l,p]of Object.entries(u))p!==""&&p!=null&&(c[l]=p);Object.keys(c).length>0?r="?"+gme.default.encode(c):r=""}let a=`${t}${r}`,s=a;return this.config.url&&!a.startsWith("http")&&(s=this.config.url?`${this.config.url}/${a}`:a),s.startsWith("http")||(s=`http://${s}`),s}addBody(t,r,n,i,a){if(n.headers||(n.headers={}),t==="none")return n;let s,u={},c="",l;if(r!=null){let{bodyString:f,bodyObject:d,parseError:m,jsonValue:h}=OXr(r);c=f,u=d,s=m,l=h}let p=o(f=>{i?.location==="body"&&(i?.pageParam&&a?.page!=null&&f(i.pageParam,a.page),i?.sizeParam&&a?.limit!=null&&f(i.sizeParam,a.limit))},"addPaginationToBody");switch(t){case"text":n.body=c;break;case"encoded":{let f=new yme.URLSearchParams;for(let[d,m]of Object.entries(u))f.append(d,String(m));p((d,m)=>{m!=null&&f.append(d,String(m))}),n.body=f;break}case"form":{let f=new Ey.FormData,d=o((g,y)=>{if(y==null){f.append(g,"");return}if(typeof y=="string"){f.append(g,y);return}if(y instanceof Blob){f.append(g,y);return}if(Buffer.isBuffer(y)){f.append(g,Buffer.from(y).toString());return}if(y instanceof Uint8Array){f.append(g,Buffer.from(y).toString());return}f.append(g,String(y))},"appendFormValue");for(let[g,y]of Object.entries(u))d(g,y);p((g,y)=>{y!=null&&d(g,y)});let h=f.getHeaders?.();if(h){let y=o(()=>{if(!n.headers){let b={};return n.headers=b,b}if(Array.isArray(n.headers)){let b=n.headers.reduce((w,[E,A])=>(w[E]=A,w),{});return n.headers=b,b}if(n.headers instanceof Ey.Headers){let b={};return n.headers.forEach((w,E)=>{b[E]=w}),n.headers=b,b}return n.headers},"ensureHeaderObject")();for(let[b,w]of Object.entries(h)){let E=b.toLowerCase();if(Object.keys(y).find(O=>O.toLowerCase()===E)||typeof w>"u"||w===null)continue;let T=Array.isArray(w)?w.join(", "):String(w);y[b]=T}}n.body=f;break}case"xml":u!=null&&Object.keys(u).length&&(c=new Xxt.Builder().buildObject(u)),n.body=c,n.headers["Content-Type"]="application/xml";break;case"json":{if(s)throw"Invalid JSON for request body";let f;if(typeof l<"u")f=l;else if(c)try{f=JSON.parse(c)}catch{f=u}else f=u;if(i?.location==="body"&&bme(f)){let d={...f};i.pageParam&&a?.page!=null&&(d[i.pageParam]=a.page),i.sizeParam&&a?.limit!=null&&(d[i.sizeParam]=a.limit),f=d}else if(i?.location==="body"){let d={...u};i.pageParam&&a?.page!=null&&(d[i.pageParam]=a.page),i.sizeParam&&a?.limit!=null&&(d[i.sizeParam]=a.limit),Object.keys(d).length>0&&(f=d)}n.body=typeof f=="string"?f:JSON.stringify(f),n.headers["Content-Type"]="application/json";break}}return n}async getAuthHeaders(t,r){if(!t)return{};if(r==="oauth2")return{Authorization:await k.oauth2.getToken(t)};if(!this.config.authConfigs)return{};let n={},i=this.config.authConfigs.filter(a=>a._id===t)[0];if(i){let{type:a,config:s}=i;switch(a){case"basic":n.Authorization=`Basic ${Buffer.from(`${s.username}:${s.password}`).toString("base64")}`;break;case"bearer":n.Authorization=`Bearer ${s.token}`;break;default:throw Kt.unreachable(a)}}return n}async _req(t,r=!0){let{path:n="",queryString:i="",headers:a={},method:s="GET",disabledHeaders:u,bodyType:c="none",requestBody:l,authConfigId:p,authConfigType:f,pagination:d,paginationValues:m}=t,h=await this.getAuthHeaders(p,f);if(this.headers={...this.config.defaultHeaders||{},...a,...h},u)for(let A of Object.keys(this.headers))u[A]&&delete this.headers[A];let g={method:s,headers:this.headers};g=this.addBody(c,l,g,d,m),this.config.legacyHttpParser&&(g.extraHttpOptions={insecureHTTPParser:!0}),this.startTimeMs=y6.performance.now();let y=this.getUrl(n,i,d,m);if(await p4.isBlacklisted(y))throw new Error("Cannot connect to URL.");let b=!!ce.REST_REJECT_UNAUTHORIZED,w=mEt({rejectUnauthorized:b});if(w)console.log("[rest integration] Using proxy for request",{url:y,hasDispatcher:!0,isHttpsUrl:y.startsWith("https://"),rejectUnauthorized:b,configRejectUnauthorized:this.config.rejectUnauthorized,proxyUri:process.env.GLOBAL_AGENT_HTTPS_PROXY||process.env.GLOBAL_AGENT_HTTP_PROXY||process.env.HTTPS_PROXY||process.env.HTTP_PROXY}),g.dispatcher=w;else if(b){let A=new Ey.Agent({connect:{rejectUnauthorized:!1}});g.dispatcher=A}let E;try{E=await(0,Ey.fetch)(y,g)}catch(A){let T=A;throw console.log("[rest integration] Fetch error details",{url:y,error:T.message,cause:T.cause?.message,code:T.cause?.code,hasDispatcher:!!g.dispatcher,isHttpsUrl:y.startsWith("https://"),rejectUnauthorized:b}),T.cause?.code==="UNABLE_TO_VERIFY_LEAF_SIGNATURE"||T.cause?.code==="CERT_UNTRUSTED"||T.cause?.code==="SELF_SIGNED_CERT_IN_CHAIN"?new Error(`SSL certificate verification failed for ${y}. Consider setting rejectUnauthorized to false if using self-signed certificates. Original error: ${T.message}`):T.cause?.code==="ECONNREFUSED"&&g.dispatcher?new Error(`Connection refused when using proxy. Check proxy configuration and ensure the proxy server is accessible. Original error: ${T.message}`):T}return E.status===401&&f==="oauth2"&&r?(await k.oauth2.cleanStoredToken(p),await this._req(t,!1)):await this.parseResponse(E,d)}async create(t){return this._req({...t,method:"POST"})}async read(t){return this._req({...t,method:"GET"})}async update(t){return this._req({...t,method:"PUT"})}async patch(t){return this._req({...t,method:"PATCH"})}async delete(t){return this._req({...t,method:"DELETE"})}},wme={schema:IXr,integration:vme}});async function Eme(e){if(e.continueSetupId){let t=L.getWorkspaceId(),r=await It.get(`datasource:creation:${t}:google:${e.continueSetupId}`);e.auth=r.tokens,delete e.continueSetupId}}var eAt,tAt,rAt,nAt,CXr,kXr,DXr,_me,Sme,xme=v(()=>{"use strict";X();Xe();V();eAt=te(require("dd-trace")),tAt=require("google-auth-library"),rAt=require("google-spreadsheet"),nAt=te(require("node-fetch"));Sa();tn();CXr={string:!0,formula:!0,ai:!0,number:!0,longform:!0,datetime:!0,options:!0,boolean:!0,barcodeqr:!0,bb_reference:!0,bb_reference_single:!0,array:!1,attachment:!1,attachment_single:!1,link:!1,auto:!1,json:!1,internal:!1,bigint:!1,signature_single:!1},kXr=Object.entries(CXr).filter(([e,t])=>t).map(([e])=>e),DXr={plus:!0,auth:{type:"google"},relationships:!1,docs:"https://developers.google.com/sheets/api/quickstart/nodejs",description:"Create and collaborate on online spreadsheets in real-time and from any device.",friendlyName:"Google Sheets",type:"Spreadsheet",features:{connection:!0,fetch_table_names:!0},datasource:{spreadsheetId:{display:"Spreadsheet URL",type:"string",required:!0}},query:{create:{type:"fields",fields:{sheet:{type:"string",required:!0},row:{type:"json",required:!0}}},read:{type:"fields",fields:{sheet:{type:"string",required:!0}}},update:{type:"fields",fields:{sheet:{type:"string",required:!0},rowIndex:{type:"string",required:!0},row:{type:"json",required:!0}}},delete:{type:"fields",fields:{sheet:{type:"string",required:!0},rowIndex:{type:"number",required:!0}}}}},_me=class{constructor(t){this.client=void 0;this.config=t,this.spreadsheetId=this.cleanSpreadsheetUrl(this.config.spreadsheetId)}static{o(this,"GoogleSheetsIntegration")}async testConnection(){try{return await this.connect(),{connected:!0}}catch(t){return{connected:!1,error:t.message}}}getBindingIdentifier(){return""}getStringConcat(t){return""}cleanSpreadsheetUrl(t){if(!t)throw new Error("You must set a spreadsheet ID in your configuration to fetch tables.");let r=t.split("/");return r.length>5?r[5]:t}async fetchAccessToken(t){let r=await(0,nAt.default)("https://www.googleapis.com/oauth2/v4/token",{method:"POST",body:JSON.stringify({...t,grant_type:"refresh_token"}),headers:{"Content-Type":"application/json"}}),n=await r.json();if(r.status!==200)throw new Error(`Error authenticating with google sheets. ${n.error_description}`);return n}async connect(){try{let t=L.getCurrentContext(),r=t?.googleSheets?.oauthClient;if(!r){await Eme(this.config);let i=await xn.getGoogleDatasourceConfig();if(!i)throw new _e("Google config not found",400);r=new tAt.OAuth2Client({clientId:i.clientID,clientSecret:i.clientSecret});let a=await this.fetchAccessToken({client_id:i.clientID,client_secret:i.clientSecret,refresh_token:this.config.auth.refreshToken});r.setCredentials({refresh_token:this.config.auth.refreshToken,access_token:a.access_token}),t&&!t.googleSheets&&(t.googleSheets={oauthClient:r,clients:{}},t.cleanup=t.cleanup||[])}let n=t?.googleSheets?.clients[this.spreadsheetId];n||(n=new rAt.GoogleSpreadsheet(this.spreadsheetId,r),await n.loadInfo(),t?.googleSheets?.clients&&(t.googleSheets.clients[this.spreadsheetId]=n)),this.client=n}catch(t){throw t.message?.includes("operation is not supported")&&(t.message="This operation is not supported - XLSX sheets must be converted."),console.error("Error connecting to google sheets",t),t}}async getTableNames(){return await this.connect(),this.client.sheetsByIndex.map(r=>r.title)}getTableSchema(t,r,n,i){let a={type:"table",name:t,primary:[Vk],schema:{},sourceId:n,sourceType:"external"};i&&(a._id=i);for(let s of r)a.schema[s]={name:s,type:"string"};return a}async buildSchema(t,r,n){if(!this.config.auth)return{tables:{},errors:{}};await this.connect();let i=this.client.sheetsByIndex.filter(c=>!n||n.includes(c.title)),a={},s={};await Kt.parallelForeach(i,async c=>{try{await c.getRows({limit:1})}catch(l){if(!(l instanceof Error))throw l;if(l.message.startsWith("No values in the header row")||l.message.startsWith("All your header cells are blank")){s[c.title]=`Failed to find a header row in sheet "${c.title}", is the first row blank?`;return}throw l}},10);for(let c of i){let l=Au(t,c.title);a[c.title]=this.getTableSchema(c.title,c.headerValues,t,l)}let u=td(a,r);return s={...s,...rd(u)},{tables:u,errors:s}}async query(t){let r=t.table.name;switch(t.operation){case"CREATE":return this.create({sheet:r,row:t.body});case"BULK_CREATE":return this.createBulk({sheet:r,rows:t.body});case"BULK_UPSERT":return this.createBulk({sheet:r,rows:t.body});case"READ":return this.read({...t,sheet:r});case"UPDATE":return this.update({rowIndex:t.extra?.idFilter?.equal?.rowNumber,sheet:r,row:t.body,table:t.table});case"DELETE":return this.delete({rowIndex:t.extra?.idFilter?.equal?.rowNumber,sheet:r});case"CREATE_TABLE":if(!t.table)throw new Error("attempted to create a table without specifying the table to create");return this.createTable(t.table);case"UPDATE_TABLE":if(!t.table)throw new Error("attempted to create a table without specifying the table to create");return this.updateTable(t.table);case"DELETE_TABLE":return this.deleteTable(t?.table?.name);default:throw new Error(`GSheets integration does not support "${t.operation}".`)}}buildRowObject(t,r,n){let i={rowNumber:n,_id:n.toString()};for(let a=0;a<t.length;a++)i[t[a]]=r[t[a]];return i}async createTable(t){try{await this.connect(),await this.client.addSheet({title:t.name,headerValues:Object.keys(t.schema)})}catch(r){throw console.error("Error creating new table in google sheets",r),r}}async updateTable(t){await this.connect();let r=this.client.sheetsByTitle[t.name];if(await r.loadHeaderRow(),t._rename){let n=[];for(let i of r.headerValues)i===t._rename.old?n.push(t._rename.updated):n.push(i);try{await r.setHeaderRow(n)}catch(i){throw console.error("Error updating column name in google sheets",i),i}}else{let n=[...r.headerValues];for(let[i,a]of Object.entries(t.schema)){if(!kXr.includes(a.type))throw new Error(`Column type: ${a.type} not allowed for GSheets integration.`);!r.headerValues.includes(i)&&a.type!=="formula"&&a.type!=="ai"&&n.push(i)}try{n.length>r.gridProperties.columnCount&&(await r.resize({rowCount:r.rowCount,columnCount:n.length}),this.client.resetLocalCache(),await this.client.loadInfo(),r=this.client.sheetsByTitle[t.name],await r.loadHeaderRow()),await r.setHeaderRow(n)}catch(i){throw console.error("Error updating table in google sheets",i),i}}}async deleteTable(t){try{await this.connect(),await this.client.sheetsByTitle[t].delete()}catch(r){throw console.error("Error deleting table in google sheets",r),r}}async create(t){try{await this.connect();let r=this.client.sheetsByTitle[t.sheet],n=typeof t.row=="string"?JSON.parse(t.row):t.row,i=await r.addRow(n);return[this.buildRowObject(r.headerValues,i.toObject(),i.rowNumber)]}catch(r){throw console.error("Error writing to google sheets",r),r}}async createBulk(t){try{await this.connect();let r=this.client.sheetsByTitle[t.sheet],n=[];for(let a of t.rows)n.push(typeof a=="string"?JSON.parse(a):a);return(await r.addRows(n)).map(a=>this.buildRowObject(r.headerValues,a.toObject(),a.rowNumber))}catch(r){throw console.error("Error bulk writing to google sheets",r),r}}async read(t){return await eAt.default.trace("googlesheets.read",async r=>{r.addTags({sheet:t.sheet,filters:t.filters,sort:t.sort,paginate:t.paginate}),await this.connect();let n=Jr.hasFilters(t.filters),i=t.paginate?.limit||100,a=t.paginate?.offset||0;r.addTags({hasFilters:n,limit:i,offset:a});let s=t.paginate?.page;typeof s=="string"&&(s=parseInt(s)),s!==void 0&&(a=s*i);let u=this.client.sheetsByTitle[t.sheet];r.addTags({rowCount:u.rowCount});let c=[];t.paginate&&!n?c=await u.getRows({limit:i,offset:a}):c=await u.getRows(),r.addTags({totalRowsRead:c.length});let l=c.map(p=>this.buildRowObject(u.headerValues,p.toObject(),p.rowNumber));if(l=Jr.runQuery(l,t.filters||{}),n&&t.paginate&&(l=l.slice(a,a+i)),t.sort){Object.keys(t.sort).length!==1&&console.warn("Googlesheets does not support multiple sorting",{sortInfo:t.sort});let[p,f]=Object.entries(t.sort)[0];l=Jr.sort(l,p,f.direction,f.type)}return r.addTags({totalRowsReturned:l.length}),l})}async getRowByIndex(t,r){let n=this.client.sheetsByTitle[t],a=(await n.getRows())[r-2];return{sheet:n,row:a}}async update(t){try{await this.connect();let{sheet:r,row:n}=await this.getRowByIndex(t.sheet,t.rowIndex);if(n){let i=typeof t.row=="string"?JSON.parse(t.row):t.row;for(let a in i)if(n.set(a,i[a]),n.get(a)===null&&n.set(a,""),t.table){let{type:s,subtype:u,constraints:c}=t.table.schema[a];s==="bb_reference"&&u==="user"&&c?.type!=="array"&&Array.isArray(n.get(a))&&n.set(a,n.get(a)[0])}return await n.save(),[this.buildRowObject(r.headerValues,n.toObject(),n.rowNumber)]}else throw new Error("Row does not exist.")}catch(r){throw console.error("Error reading from google sheets",r),r}}async delete(t){await this.connect();let{row:r}=await this.getRowByIndex(t.sheet,t.rowIndex);if(r)return await r.delete(),[{deleted:t.rowIndex,[Vk]:t.rowIndex}];throw new Error("Row does not exist.")}};o(Eme,"setupCreationAuth");Sme={schema:DXr,integration:_me}});var iAt,PXr,Ame,Tme,oAt=v(()=>{"use strict";V();iAt=require("@google-cloud/firestore"),PXr={docs:"https://firebase.google.com/docs/firestore/quickstart",friendlyName:"Firestore",type:"Non-relational",description:"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",features:{connection:!0},datasource:{email:{type:"string",required:!0},privateKey:{type:"string",display:"Private Key",required:!0},projectId:{type:"string",display:"Project ID",required:!0},databaseId:{type:"string",display:"Database ID",required:!1,default:"(default)",placeholder:"(default)"}},query:{create:{type:"json"},read:{type:"json"},update:{type:"json"},delete:{type:"json"}},extra:{collection:{displayName:"Collection",type:"string",required:!0},filterField:{displayName:"Filter field",type:"string",required:!1},filter:{displayName:"Filter comparison",type:"list",required:!1,data:{read:["==","<","<=","!=",">=",">","array-contains","in","not-in","array-contains-any"]}},filterValue:{displayName:"Filter value",type:"string",required:!1}}},Ame=class{static{o(this,"FirebaseIntegration")}constructor(t){this.config=t,this.client=new iAt.Firestore({projectId:t.projectId,databaseId:t.databaseId||"(default)",credentials:{client_email:t.email,private_key:t.privateKey?.replace(/\\n/g,`
|
|
920
|
+
`)+";"}finally{this.disconnect()}}},dme={schema:SXr,integration:fme}});var g6,TXr,mme,hme,Vxt=v(()=>{"use strict";V();g6=require("arangojs"),TXr={docs:"https://github.com/arangodb/arangojs",friendlyName:"ArangoDB",type:"Non-relational",description:"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ",features:{connection:!0},datasource:{url:{type:"string",default:"http://localhost:8529",required:!0},username:{type:"string",default:"root",required:!0},password:{type:"password",required:!0},databaseName:{type:"string",default:"_system",required:!0},collection:{type:"string",required:!0}},query:{read:{type:"sql"},create:{type:"json"}}},mme=class{static{o(this,"ArangoDBIntegration")}constructor(t){let r={url:t.url,databaseName:t.databaseName,auth:{username:t.username,password:t.password}};this.config=t,this.client=new g6.Database(r)}async testConnection(){let t={connected:!1};try{await this.client.get(),t.connected=!0}catch(r){t.error=r.message}return t}async read(t){try{return(await this.client.query(t.sql)).all()}catch(r){throw console.error("Error querying arangodb",r.message),r}finally{this.client.close()}}async create(t){let r=this.client.collection(this.config.collection);try{return(await this.client.query(g6.aql`INSERT ${t.json} INTO ${r} RETURN NEW`)).all()}catch(n){throw console.error("Error querying arangodb",n.message),n}finally{this.client.close()}}},hme={schema:TXr,integration:mme}});function Hxt(e,t){let r=e.get("content-type")||"",n=e.get("content-disposition")||"";if(n){let i=/"(?:[^"\\]|\\.)*"|;/g,a=null,s=!1;for(;(a=i.exec(n))!==null;)a[0]===";"&&(s=!0);if(!s)return{contentDisposition:`attachment; ${n}`,contentType:r}}else if(t?.downloadImages&&r.startsWith("image/"))return{contentDisposition:`attachment; filename="image.${r.split("/")[1]}"`,contentType:r};return{contentDisposition:n,contentType:r}}var Kxt=v(()=>{"use strict";o(Hxt,"getAttachmentHeaders")});var Qxt,gme,y6,yme,Yxt,Jxt,Xxt,Ey,HP,IXr,bme,OXr,vme,wme,Zxt=v(()=>{"use strict";V();Qxt=te(require("lodash/get")),gme=te(require("querystring"));As();y6=require("perf_hooks"),yme=require("url");X();tn();Yxt=require("content-disposition"),Jxt=te(require("path")),Xxt=require("xml2js");Kxt();Xe();$e();As();Ey=require("undici");Bt();HP={path:{type:"string",display:"URL"},queryString:{type:"string"},headers:{type:"object"},enabledHeaders:{type:"object"},requestBody:{type:"json"},bodyType:{type:"string",enum:Object.values(MG)},pagination:{type:"object"}},IXr={docs:"https://github.com/node-fetch/node-fetch",description:"With the REST API datasource, you can connect, query and pull data from multiple REST APIs. You can then use the retrieved data to build apps.",friendlyName:"REST API",type:"API",datasource:{url:{type:"string",default:"",required:!1,deprecated:!0},defaultHeaders:{type:"object",required:!1,default:{}},rejectUnauthorized:{display:"Reject Unauthorized",type:"boolean",default:!0,required:!1},downloadImages:{display:"Download images",type:"boolean",default:!0,required:!1}},query:{create:{readable:!0,displayName:"POST",type:"fields",fields:HP},read:{displayName:"GET",readable:!0,type:"fields",fields:HP},update:{displayName:"PUT",readable:!0,type:"fields",fields:HP},patch:{displayName:"PATCH",readable:!0,type:"fields",fields:HP},delete:{displayName:"DELETE",type:"fields",fields:HP}}},bme=o(e=>Object.prototype.toString.call(e)==="[object Object]","isPlainRecord"),OXr=o(e=>{if(e==null)return{bodyString:"",bodyObject:{},jsonValue:void 0};if(typeof e=="string")try{let t=JSON.parse(e);return bme(t)?{bodyString:e,bodyObject:t,jsonValue:t}:{bodyString:e,bodyObject:{},jsonValue:t}}catch(t){return{bodyString:e,bodyObject:{},parseError:t}}return Buffer.isBuffer(e)?{bodyString:e.toString(),bodyObject:{},jsonValue:e.toString()}:e instanceof Uint8Array?{bodyString:Buffer.from(e).toString(),bodyObject:{},jsonValue:Buffer.from(e).toString()}:bme(e)?{bodyString:JSON.stringify(e),bodyObject:e,jsonValue:e}:Array.isArray(e)?{bodyString:JSON.stringify(e),bodyObject:{},jsonValue:e}:{bodyString:JSON.stringify(e),bodyObject:{},jsonValue:void 0}},"normaliseBody"),vme=class{constructor(t){this.headers={};this.startTimeMs=y6.performance.now();this.config=t}static{o(this,"RestIntegration")}async parseResponse(t,r){let n,i,a={},s,{contentType:u,contentDisposition:c}=Hxt(t.headers,{downloadImages:this.config.downloadImages}),l=t.headers.get("content-length"),p=t.status>=200&&t.status<300;(c.includes("filename")||c.includes("attachment")||c.includes("form-data"))&&p&&(s=Jxt.default.basename((0,Yxt.parse)(c).parameters?.filename)||"");let f=!1,d;try{if(s)return oSt(t,s,this.startTimeMs);{d=t.text?await t.text():"",!l&&d&&(l=Buffer.byteLength(d,"utf8").toString());let y=l&&parseInt(l)>0||d.length>0;if(t.status===204)n=[],i="";else if(y&&u.includes("application/json"))f=!0,n=JSON.parse(d),i=d;else if(y&&u.includes("text/xml")||u.includes("application/xml")){f=!0;let b=await iSt(d);n=b.data,i=b.rawXml}else n=d,i=d}}catch(y){if(f)n=d,i=d;else throw new Error(`Failed to parse response body: ${y}`)}let m=UW(l||"0"),h=`${Math.round(y6.performance.now()-this.startTimeMs)}ms`;for(let[y,b]of t.headers.entries())a[y]=b;let g;return r?.responseParam&&(g=(0,Qxt.default)(n,r.responseParam)),{data:n,info:{code:t.status,size:m,time:h},extra:{raw:i,headers:a},pagination:{cursor:g}}}getUrl(t,r,n,i){if(n?.location==="query"&&i){let{pageParam:u,sizeParam:c}=n,l=new yme.URLSearchParams;u&&i.page!=null&&l.append(u,i.page),c&&i.limit!=null&&l.append(c,String(i.limit));let p=l.toString();p&&(r=`${p}&${r}`)}if(r){let u=gme.default.decode(r),c={};for(let[l,p]of Object.entries(u))p!==""&&p!=null&&(c[l]=p);Object.keys(c).length>0?r="?"+gme.default.encode(c):r=""}let a=`${t}${r}`,s=a;return this.config.url&&!a.startsWith("http")&&(s=this.config.url?`${this.config.url}/${a}`:a),s.startsWith("http")||(s=`http://${s}`),s}addBody(t,r,n,i,a){if(n.headers||(n.headers={}),t==="none")return n;let s,u={},c="",l;if(r!=null){let{bodyString:f,bodyObject:d,parseError:m,jsonValue:h}=OXr(r);c=f,u=d,s=m,l=h}let p=o(f=>{i?.location==="body"&&(i?.pageParam&&a?.page!=null&&f(i.pageParam,a.page),i?.sizeParam&&a?.limit!=null&&f(i.sizeParam,a.limit))},"addPaginationToBody");switch(t){case"text":n.body=c;break;case"encoded":{let f=new yme.URLSearchParams;for(let[d,m]of Object.entries(u))f.append(d,String(m));p((d,m)=>{m!=null&&f.append(d,String(m))}),n.body=f;break}case"form":{let f=new Ey.FormData,d=o((y,b)=>{if(b==null){f.append(y,"");return}if(typeof b=="string"){f.append(y,b);return}if(b instanceof Blob){f.append(y,b);return}if(Buffer.isBuffer(b)){f.append(y,Buffer.from(b).toString());return}if(b instanceof Uint8Array){f.append(y,Buffer.from(b).toString());return}f.append(y,String(b))},"appendFormValue");for(let[y,b]of Object.entries(u))d(y,b);p((y,b)=>{b!=null&&d(y,b)});let h=o(()=>n.headers?Array.isArray(n.headers)?n.headers.reduce((b,[w,E])=>(b[w]=E,b),{}):n.headers instanceof Ey.Headers?Object.fromEntries(n.headers):n.headers:{},"ensureHeaderObject")(),g=Object.keys(h).find(y=>y.toLowerCase()==="content-type");g&&delete h[g],n.headers=h,n.body=f;break}case"xml":u!=null&&Object.keys(u).length&&(c=new Xxt.Builder().buildObject(u)),n.body=c,n.headers["Content-Type"]="application/xml";break;case"json":{if(s)throw"Invalid JSON for request body";let f;if(typeof l<"u")f=l;else if(c)try{f=JSON.parse(c)}catch{f=u}else f=u;if(i?.location==="body"&&bme(f)){let d={...f};i.pageParam&&a?.page!=null&&(d[i.pageParam]=a.page),i.sizeParam&&a?.limit!=null&&(d[i.sizeParam]=a.limit),f=d}else if(i?.location==="body"){let d={...u};i.pageParam&&a?.page!=null&&(d[i.pageParam]=a.page),i.sizeParam&&a?.limit!=null&&(d[i.sizeParam]=a.limit),Object.keys(d).length>0&&(f=d)}n.body=typeof f=="string"?f:JSON.stringify(f),n.headers["Content-Type"]="application/json";break}}return n}async getAuthHeaders(t,r){if(!t)return{};if(r==="oauth2")return{Authorization:await k.oauth2.getToken(t)};if(!this.config.authConfigs)return{};let n={},i=this.config.authConfigs.filter(a=>a._id===t)[0];if(i){let{type:a,config:s}=i;switch(a){case"basic":n.Authorization=`Basic ${Buffer.from(`${s.username}:${s.password}`).toString("base64")}`;break;case"bearer":n.Authorization=`Bearer ${s.token}`;break;default:throw Kt.unreachable(a)}}return n}async _req(t,r=!0){let{path:n="",queryString:i="",headers:a={},method:s="GET",disabledHeaders:u,bodyType:c="none",requestBody:l,authConfigId:p,authConfigType:f,pagination:d,paginationValues:m}=t,h=await this.getAuthHeaders(p,f);if(this.headers={...this.config.defaultHeaders||{},...a,...h},u)for(let A of Object.keys(this.headers))u[A]&&delete this.headers[A];let g={method:s,headers:this.headers};g=this.addBody(c,l,g,d,m),this.config.legacyHttpParser&&(g.extraHttpOptions={insecureHTTPParser:!0}),this.startTimeMs=y6.performance.now();let y=this.getUrl(n,i,d,m);if(await p4.isBlacklisted(y))throw new Error("Cannot connect to URL.");let b=!!ce.REST_REJECT_UNAUTHORIZED,w=mEt({rejectUnauthorized:b});if(w)console.log("[rest integration] Using proxy for request",{url:y,hasDispatcher:!0,isHttpsUrl:y.startsWith("https://"),rejectUnauthorized:b,configRejectUnauthorized:this.config.rejectUnauthorized,proxyUri:process.env.GLOBAL_AGENT_HTTPS_PROXY||process.env.GLOBAL_AGENT_HTTP_PROXY||process.env.HTTPS_PROXY||process.env.HTTP_PROXY}),g.dispatcher=w;else if(b){let A=new Ey.Agent({connect:{rejectUnauthorized:!1}});g.dispatcher=A}let E;try{E=await(0,Ey.fetch)(y,g)}catch(A){let T=A;throw console.log("[rest integration] Fetch error details",{url:y,error:T.message,cause:T.cause?.message,code:T.cause?.code,hasDispatcher:!!g.dispatcher,isHttpsUrl:y.startsWith("https://"),rejectUnauthorized:b}),T.cause?.code==="UNABLE_TO_VERIFY_LEAF_SIGNATURE"||T.cause?.code==="CERT_UNTRUSTED"||T.cause?.code==="SELF_SIGNED_CERT_IN_CHAIN"?new Error(`SSL certificate verification failed for ${y}. Consider setting rejectUnauthorized to false if using self-signed certificates. Original error: ${T.message}`):T.cause?.code==="ECONNREFUSED"&&g.dispatcher?new Error(`Connection refused when using proxy. Check proxy configuration and ensure the proxy server is accessible. Original error: ${T.message}`):T}return E.status===401&&f==="oauth2"&&r?(await k.oauth2.cleanStoredToken(p),await this._req(t,!1)):await this.parseResponse(E,d)}async create(t){return this._req({...t,method:"POST"})}async read(t){return this._req({...t,method:"GET"})}async update(t){return this._req({...t,method:"PUT"})}async patch(t){return this._req({...t,method:"PATCH"})}async delete(t){return this._req({...t,method:"DELETE"})}},wme={schema:IXr,integration:vme}});async function Eme(e){if(e.continueSetupId){let t=L.getWorkspaceId(),r=await It.get(`datasource:creation:${t}:google:${e.continueSetupId}`);e.auth=r.tokens,delete e.continueSetupId}}var eAt,tAt,rAt,nAt,CXr,kXr,DXr,_me,Sme,xme=v(()=>{"use strict";X();Xe();V();eAt=te(require("dd-trace")),tAt=require("google-auth-library"),rAt=require("google-spreadsheet"),nAt=te(require("node-fetch"));Sa();tn();CXr={string:!0,formula:!0,ai:!0,number:!0,longform:!0,datetime:!0,options:!0,boolean:!0,barcodeqr:!0,bb_reference:!0,bb_reference_single:!0,array:!1,attachment:!1,attachment_single:!1,link:!1,auto:!1,json:!1,internal:!1,bigint:!1,signature_single:!1},kXr=Object.entries(CXr).filter(([e,t])=>t).map(([e])=>e),DXr={plus:!0,auth:{type:"google"},relationships:!1,docs:"https://developers.google.com/sheets/api/quickstart/nodejs",description:"Create and collaborate on online spreadsheets in real-time and from any device.",friendlyName:"Google Sheets",type:"Spreadsheet",features:{connection:!0,fetch_table_names:!0},datasource:{spreadsheetId:{display:"Spreadsheet URL",type:"string",required:!0}},query:{create:{type:"fields",fields:{sheet:{type:"string",required:!0},row:{type:"json",required:!0}}},read:{type:"fields",fields:{sheet:{type:"string",required:!0}}},update:{type:"fields",fields:{sheet:{type:"string",required:!0},rowIndex:{type:"string",required:!0},row:{type:"json",required:!0}}},delete:{type:"fields",fields:{sheet:{type:"string",required:!0},rowIndex:{type:"number",required:!0}}}}},_me=class{constructor(t){this.client=void 0;this.config=t,this.spreadsheetId=this.cleanSpreadsheetUrl(this.config.spreadsheetId)}static{o(this,"GoogleSheetsIntegration")}async testConnection(){try{return await this.connect(),{connected:!0}}catch(t){return{connected:!1,error:t.message}}}getBindingIdentifier(){return""}getStringConcat(t){return""}cleanSpreadsheetUrl(t){if(!t)throw new Error("You must set a spreadsheet ID in your configuration to fetch tables.");let r=t.split("/");return r.length>5?r[5]:t}async fetchAccessToken(t){let r=await(0,nAt.default)("https://www.googleapis.com/oauth2/v4/token",{method:"POST",body:JSON.stringify({...t,grant_type:"refresh_token"}),headers:{"Content-Type":"application/json"}}),n=await r.json();if(r.status!==200)throw new Error(`Error authenticating with google sheets. ${n.error_description}`);return n}async connect(){try{let t=L.getCurrentContext(),r=t?.googleSheets?.oauthClient;if(!r){await Eme(this.config);let i=await xn.getGoogleDatasourceConfig();if(!i)throw new _e("Google config not found",400);r=new tAt.OAuth2Client({clientId:i.clientID,clientSecret:i.clientSecret});let a=await this.fetchAccessToken({client_id:i.clientID,client_secret:i.clientSecret,refresh_token:this.config.auth.refreshToken});r.setCredentials({refresh_token:this.config.auth.refreshToken,access_token:a.access_token}),t&&!t.googleSheets&&(t.googleSheets={oauthClient:r,clients:{}},t.cleanup=t.cleanup||[])}let n=t?.googleSheets?.clients[this.spreadsheetId];n||(n=new rAt.GoogleSpreadsheet(this.spreadsheetId,r),await n.loadInfo(),t?.googleSheets?.clients&&(t.googleSheets.clients[this.spreadsheetId]=n)),this.client=n}catch(t){throw t.message?.includes("operation is not supported")&&(t.message="This operation is not supported - XLSX sheets must be converted."),console.error("Error connecting to google sheets",t),t}}async getTableNames(){return await this.connect(),this.client.sheetsByIndex.map(r=>r.title)}getTableSchema(t,r,n,i){let a={type:"table",name:t,primary:[Vk],schema:{},sourceId:n,sourceType:"external"};i&&(a._id=i);for(let s of r)a.schema[s]={name:s,type:"string"};return a}async buildSchema(t,r,n){if(!this.config.auth)return{tables:{},errors:{}};await this.connect();let i=this.client.sheetsByIndex.filter(c=>!n||n.includes(c.title)),a={},s={};await Kt.parallelForeach(i,async c=>{try{await c.getRows({limit:1})}catch(l){if(!(l instanceof Error))throw l;if(l.message.startsWith("No values in the header row")||l.message.startsWith("All your header cells are blank")){s[c.title]=`Failed to find a header row in sheet "${c.title}", is the first row blank?`;return}throw l}},10);for(let c of i){let l=Au(t,c.title);a[c.title]=this.getTableSchema(c.title,c.headerValues,t,l)}let u=td(a,r);return s={...s,...rd(u)},{tables:u,errors:s}}async query(t){let r=t.table.name;switch(t.operation){case"CREATE":return this.create({sheet:r,row:t.body});case"BULK_CREATE":return this.createBulk({sheet:r,rows:t.body});case"BULK_UPSERT":return this.createBulk({sheet:r,rows:t.body});case"READ":return this.read({...t,sheet:r});case"UPDATE":return this.update({rowIndex:t.extra?.idFilter?.equal?.rowNumber,sheet:r,row:t.body,table:t.table});case"DELETE":return this.delete({rowIndex:t.extra?.idFilter?.equal?.rowNumber,sheet:r});case"CREATE_TABLE":if(!t.table)throw new Error("attempted to create a table without specifying the table to create");return this.createTable(t.table);case"UPDATE_TABLE":if(!t.table)throw new Error("attempted to create a table without specifying the table to create");return this.updateTable(t.table);case"DELETE_TABLE":return this.deleteTable(t?.table?.name);default:throw new Error(`GSheets integration does not support "${t.operation}".`)}}buildRowObject(t,r,n){let i={rowNumber:n,_id:n.toString()};for(let a=0;a<t.length;a++)i[t[a]]=r[t[a]];return i}async createTable(t){try{await this.connect(),await this.client.addSheet({title:t.name,headerValues:Object.keys(t.schema)})}catch(r){throw console.error("Error creating new table in google sheets",r),r}}async updateTable(t){await this.connect();let r=this.client.sheetsByTitle[t.name];if(await r.loadHeaderRow(),t._rename){let n=[];for(let i of r.headerValues)i===t._rename.old?n.push(t._rename.updated):n.push(i);try{await r.setHeaderRow(n)}catch(i){throw console.error("Error updating column name in google sheets",i),i}}else{let n=[...r.headerValues];for(let[i,a]of Object.entries(t.schema)){if(!kXr.includes(a.type))throw new Error(`Column type: ${a.type} not allowed for GSheets integration.`);!r.headerValues.includes(i)&&a.type!=="formula"&&a.type!=="ai"&&n.push(i)}try{n.length>r.gridProperties.columnCount&&(await r.resize({rowCount:r.rowCount,columnCount:n.length}),this.client.resetLocalCache(),await this.client.loadInfo(),r=this.client.sheetsByTitle[t.name],await r.loadHeaderRow()),await r.setHeaderRow(n)}catch(i){throw console.error("Error updating table in google sheets",i),i}}}async deleteTable(t){try{await this.connect(),await this.client.sheetsByTitle[t].delete()}catch(r){throw console.error("Error deleting table in google sheets",r),r}}async create(t){try{await this.connect();let r=this.client.sheetsByTitle[t.sheet],n=typeof t.row=="string"?JSON.parse(t.row):t.row,i=await r.addRow(n);return[this.buildRowObject(r.headerValues,i.toObject(),i.rowNumber)]}catch(r){throw console.error("Error writing to google sheets",r),r}}async createBulk(t){try{await this.connect();let r=this.client.sheetsByTitle[t.sheet],n=[];for(let a of t.rows)n.push(typeof a=="string"?JSON.parse(a):a);return(await r.addRows(n)).map(a=>this.buildRowObject(r.headerValues,a.toObject(),a.rowNumber))}catch(r){throw console.error("Error bulk writing to google sheets",r),r}}async read(t){return await eAt.default.trace("googlesheets.read",async r=>{r.addTags({sheet:t.sheet,filters:t.filters,sort:t.sort,paginate:t.paginate}),await this.connect();let n=Jr.hasFilters(t.filters),i=t.paginate?.limit||100,a=t.paginate?.offset||0;r.addTags({hasFilters:n,limit:i,offset:a});let s=t.paginate?.page;typeof s=="string"&&(s=parseInt(s)),s!==void 0&&(a=s*i);let u=this.client.sheetsByTitle[t.sheet];r.addTags({rowCount:u.rowCount});let c=[];t.paginate&&!n?c=await u.getRows({limit:i,offset:a}):c=await u.getRows(),r.addTags({totalRowsRead:c.length});let l=c.map(p=>this.buildRowObject(u.headerValues,p.toObject(),p.rowNumber));if(l=Jr.runQuery(l,t.filters||{}),n&&t.paginate&&(l=l.slice(a,a+i)),t.sort){Object.keys(t.sort).length!==1&&console.warn("Googlesheets does not support multiple sorting",{sortInfo:t.sort});let[p,f]=Object.entries(t.sort)[0];l=Jr.sort(l,p,f.direction,f.type)}return r.addTags({totalRowsReturned:l.length}),l})}async getRowByIndex(t,r){let n=this.client.sheetsByTitle[t],a=(await n.getRows())[r-2];return{sheet:n,row:a}}async update(t){try{await this.connect();let{sheet:r,row:n}=await this.getRowByIndex(t.sheet,t.rowIndex);if(n){let i=typeof t.row=="string"?JSON.parse(t.row):t.row;for(let a in i)if(n.set(a,i[a]),n.get(a)===null&&n.set(a,""),t.table){let{type:s,subtype:u,constraints:c}=t.table.schema[a];s==="bb_reference"&&u==="user"&&c?.type!=="array"&&Array.isArray(n.get(a))&&n.set(a,n.get(a)[0])}return await n.save(),[this.buildRowObject(r.headerValues,n.toObject(),n.rowNumber)]}else throw new Error("Row does not exist.")}catch(r){throw console.error("Error reading from google sheets",r),r}}async delete(t){await this.connect();let{row:r}=await this.getRowByIndex(t.sheet,t.rowIndex);if(r)return await r.delete(),[{deleted:t.rowIndex,[Vk]:t.rowIndex}];throw new Error("Row does not exist.")}};o(Eme,"setupCreationAuth");Sme={schema:DXr,integration:_me}});var iAt,PXr,Ame,Tme,oAt=v(()=>{"use strict";V();iAt=require("@google-cloud/firestore"),PXr={docs:"https://firebase.google.com/docs/firestore/quickstart",friendlyName:"Firestore",type:"Non-relational",description:"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",features:{connection:!0},datasource:{email:{type:"string",required:!0},privateKey:{type:"string",display:"Private Key",required:!0},projectId:{type:"string",display:"Project ID",required:!0},databaseId:{type:"string",display:"Database ID",required:!1,default:"(default)",placeholder:"(default)"}},query:{create:{type:"json"},read:{type:"json"},update:{type:"json"},delete:{type:"json"}},extra:{collection:{displayName:"Collection",type:"string",required:!0},filterField:{displayName:"Filter field",type:"string",required:!1},filter:{displayName:"Filter comparison",type:"list",required:!1,data:{read:["==","<","<=","!=",">=",">","array-contains","in","not-in","array-contains-any"]}},filterValue:{displayName:"Filter value",type:"string",required:!1}}},Ame=class{static{o(this,"FirebaseIntegration")}constructor(t){this.config=t,this.client=new iAt.Firestore({projectId:t.projectId,databaseId:t.databaseId||"(default)",credentials:{client_email:t.email,private_key:t.privateKey?.replace(/\\n/g,`
|
|
921
921
|
`)}})}async testConnection(){try{return await this.client.listCollections(),{connected:!0}}catch(t){return{connected:!1,error:t.message}}}async create(t){try{let r=this.client.collection(t.extra.collection).doc();return await r.set({...t.json,id:r.id}),(await r.get()).data()}catch(r){throw console.error("Error writing to Firestore",r),r}}async read(t){try{let r,n=this.client.collection(t.extra.collection);t.extra.filterField&&t.extra.filter&&t.extra.filterValue?r=await n.where(t.extra.filterField,t.extra.filter,t.extra.filterValue).get():r=await n.get();let i=[];return r.forEach(a=>i.push(a.data())),i}catch(r){throw console.error("Error querying Firestore",r),r}}async update(t){try{return await this.client.collection(t.extra.collection).doc(t.json.id).update(t.json),(await this.client.collection(t.extra.collection).doc(t.json.id).get()).data()}catch(r){throw console.error("Error writing to Firestore",r),r}}async delete(t){try{return await this.client.collection(t.extra.collection).doc(t.json.id).delete(),!0}catch(r){throw console.error("Error deleting from Firestore",r),r}}},Tme={schema:PXr,integration:Ame}});var aAt,NXr,Rme,Ime,sAt=v(()=>{"use strict";V();aAt=te(require("ioredis"));tn();NXr={docs:"https://redis.io/docs/",description:"Redis is a caching tool, providing powerful key-value store capabilities.",friendlyName:"Redis",type:"Non-relational",features:{connection:!0},datasource:{host:{type:"string",required:!0,default:Rs},port:{type:"number",required:!0,default:6379},username:{type:"string",required:!1},password:{type:"password",required:!1},db:{type:"number",required:!1,display:"DB",default:0}},query:{create:{type:"fields",fields:{key:{type:"string",required:!0},value:{type:"string",required:!0},ttl:{type:"number"}}},read:{readable:!0,type:"fields",fields:{key:{type:"string",required:!0}}},delete:{type:"fields",fields:{key:{type:"string",required:!0}}},command:{readable:!0,displayName:"Redis Command",type:"json"}}},Rme=class{static{o(this,"RedisIntegration")}constructor(t){this.config=t,this.client=new aAt.default({host:this.config.host,port:this.config.port,username:this.config.username,password:this.config.password,db:this.config.db})}async testConnection(){let t={connected:!1};try{await this.client.ping(),t.connected=!0}catch(r){t.error=r.message}finally{await this.disconnect()}return t}async disconnect(){return this.client.quit()}async redisContext(t){try{return await t()}catch(r){throw new Error(`Redis error: ${r}`)}finally{await this.disconnect()}}async create(t){return this.redisContext(async()=>{let r=await this.client.set(t.key,t.value);return t.ttl&&await this.client.expire(t.key,t.ttl),r})}async read(t){return this.redisContext(async()=>await this.client.get(t.key))}async delete(t){return this.redisContext(async()=>await this.client.del(t.key))}async command(t){return this.redisContext(async()=>{let r=t.json.trim().split(`
|
|
922
922
|
`),n=[],i;for(let u of r){let c=u.trim().match(/".*"/);c?.[0]?i=[...u.substring(0,u.indexOf(c[0])-1).trim().split(" "),c?.[0]]:i=u.trim().split(" "),i[0]=i[0].toLowerCase(),n.push(i)}return(await this.client.pipeline(n).exec())?.map(u=>{if(typeof u=="string")return u;if(Array.isArray(u))return u[1]})})}},Ime={schema:NXr,integration:Rme}});var uAt,cAt,LXr,Ome,Cme,kme,lAt=v(()=>{"use strict";V();uAt=te(require("snowflake-sdk")),cAt=require("util"),LXr={docs:"https://developers.snowflake.com/",description:"Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.",friendlyName:"Snowflake",type:"Relational",features:{connection:!0},datasource:{account:{type:"string",required:!0},username:{type:"string",required:!0},password:{type:"password",required:!0},role:{type:"string"},warehouse:{type:"string",required:!0},database:{type:"string",required:!0},schema:{type:"string",required:!0}},query:{create:{type:"sql"},read:{type:"sql"},update:{type:"sql"},delete:{type:"sql"}}},Ome=class{static{o(this,"SnowflakePromise")}constructor(t){this.config=t}async connect(){return this.client?.isUp()?void 0:(this.client=uAt.default.createConnection(this.config),(0,cAt.promisify)(this.client.connect.bind(this.client))())}async execute(t){return new Promise((r,n)=>{if(!this.client)throw Error("No snowflake client present to execute query. Run connect() first to initialise.");this.client.execute({sqlText:t,complete:function(i,a,s){if(i)return n(i);r(s)}})})}},Cme=class{static{o(this,"SnowflakeIntegration")}constructor(t){this.client=new Ome(t)}async testConnection(){try{return await this.client.connect(),{connected:!0}}catch(t){return{connected:!1,error:t.message}}}async internalQuery(t){await this.client.connect();try{return await this.client.execute(t.sql)}catch(r){throw r?.message.split(":")[1]||r?.message}}async create(t){return this.internalQuery(t)}async read(t){return this.internalQuery(t)}async update(t){return this.internalQuery(t)}async delete(t){return this.internalQuery(t)}},kme={schema:LXr,integration:Cme}});var pAt=v(()=>{"use strict"});var Sy,UXr,FXr,MXr,Dme,Pme,Nme,fAt=v(()=>{"use strict";V();tn();Sy=te(require("oracledb"));pAt();X();UXr=cr.Sql;Sy.default.outFormat=Sy.default.OUT_FORMAT_OBJECT;FXr={docs:"https://github.com/oracle/node-oracledb",plus:!0,friendlyName:"Oracle",type:"Relational",description:"Oracle Database is an object-relational database management system developed by Oracle Corporation",features:{connection:!0,fetch_table_names:!0},datasource:{host:{type:"string",default:Rs,required:!0},port:{type:"number",required:!0,default:1521},database:{type:"string",required:!0,display:"Service Name"},user:{type:"string",required:!0},password:{type:"password",required:!0}},query:{create:{type:"sql"},read:{type:"sql"},update:{type:"sql"},delete:{type:"sql"}}},MXr=["BLOB","NCLOB"],Dme={PRIMARY:"P",NOT_NULL_OR_CHECK:"C",FOREIGN_KEY:"R",UNIQUE:"U"},Pme=class e extends UXr{constructor(r){super("oracledb");this.index=1;this.getConnection=async()=>{let r=`${this.config.host}:${this.config.port||1521}/${this.config.database}`,n={user:this.config.user,password:this.config.password,connectString:r},i=Intl.DateTimeFormat().resolvedOptions().timeZone,a=await Sy.default.getConnection(n);return await a.execute(`ALTER SESSION SET TIME_ZONE = '${i}'`),a};this.config=r}static{o(this,"OracleIntegration")}static{this.COLUMNS_SQL=`
|
|
923
923
|
SELECT
|