@stackone/olap 1.36.0 → 1.37.0

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/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- var e=Object.create,t=Object.defineProperty,__name=(e,n)=>t(e,`name`,{value:n,configurable:!0}),n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,__copyProps=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},__toESM=(n,r,a)=>(a=n==null?{}:e(i(n)),__copyProps(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let o=require(`@stackone/utils`),s=require(`@stackone/redaction`),c=require(`@aws-sdk/client-s3`),l=require(`zod`),u=require(`node:http`);u=__toESM(u);let d=require(`@stackone/transport`);const f={Action:`action`,Step:`step`,Unified:`unified`,Provider:`provider`},p={ConnectorKey:`connector_key`,Success:`success`,ActionType:`action_type`,Mode:`mode`,Service:`service`,Resource:`resource`,ActionId:`action_id`,HttpMethod:`http_method`,AccountSecureId:`account_secure_id`,SourceType:`source_type`,StatusCode:`status_code`,OriginOwnerId:`origin_owner_id`,SourceId:`source_id`,IsBackground:`is_background`},m=[`refresh_authentication`,`data_sync`,`test_action`,`webhook_setup`],h=[`TOKEN_REFRESH`,`VALIDATE_CREDENTIALS`,`DATA_SYNC`,`NATIVE_WEBHOOK_SETUP_WORKER`],g=[`data_sync`],_=[`DATA_SYNC`];function isBackgroundLog(e,t){return!!(e&&m.includes(e)||t&&h.includes(t))}function isDataSync(e,t){return!!(e&&g.includes(e)||t&&_.includes(t))}const safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},v=[`x-datadog-parent-id`,`x-datadog-sampling-priority`,`x-datadog-tags`,`x-datadog-trace-id`,`x-forwarded-proto`,`x-forwarded-port`,`x-forwarded-for`,`x-amzn-trace-id`,`traceparent`,`tracestate`,`x-request-nonce`,`x-signing-method`,`x-signature`,`host`,`via`],y=[`application/octet-stream`,`application/pdf`,`application/msword`,`application/vnd.openxmlformats-officedocument.wordprocessingml.document`,`application/vnd.ms-excel`,`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,`application/zip`,`application/x-zip-compressed`],b=[`image/`,`audio/`,`video/`,`application/vnd.`,`binary`],x=10*1024*1024;var AdvancedSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, advanced sink will not function`,category:`AdvancedSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled,errorsOnly:t?.errorsOnly,includeBackground:t?.includeBackground,ttl:t?.ttl}}}),!t?.enabled){this.#t?.debug({message:`Advanced sink is disabled, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(isDataSync(r.mode,r.sourceType)){this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(t.errorsOnly&&i.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${r.mode||`action`}`,category:`AdvancedSink`}),n.push(null);continue}if(isBackgroundLog(r.mode,r.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${r.mode}`,category:`AdvancedSink`}),n.push(null);continue}let e=this.createActionS3(r,i,t?.ttl),a=await this.send(e,t?.ttl);n.push(a)}return n}async sendStep(e,t,n){if(this.#t?.debug({message:`Advanced sink called to send step`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,success:t.success,options:{enabled:n?.enabled,errorsOnly:n?.errorsOnly,includeBackground:n?.includeBackground,ttl:n?.ttl}}}),!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`}),null;if(isDataSync(e.actionMode))return this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending step to advanced sink`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null;if(n.errorsOnly&&e.actionSuccess===!0)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${e.actionMode||`action`}`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.actionMode)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${e.actionMode}`,category:`AdvancedSink`}),null;let r=this.createStepS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send step to advanced sink`,error:t,code:`AdvancedStepWriteError`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null}}async sendSteps(e,t){let n=[];for(let{input:r,result:i}of e){let e=await this.sendStep(r,i,t);n.push(e)}return n}async sendUnified(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending unified to advanced sink`,category:`AdvancedSink`}),null;if(n.errorsOnly&&t.success)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful unified request`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.mode,e.sourceType)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping unified with mode ${e.mode}`,category:`AdvancedSink`}),null;this.#t?.info({message:`Sending unified to advanced sink`,category:`AdvancedSink`});let r=this.createUnifiedS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send unified to advanced sink`,error:t,code:`AdvancedUnifiedWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async sendProvider(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending provider to advanced sink`,category:`AdvancedSink`}),null;this.#t?.info({message:`Sending provider to advanced sink`,category:`AdvancedSink`});let r=this.createProviderS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send provider to advanced sink`,error:t,code:`AdvancedProviderWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new c.GetObjectCommand({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for actionRunId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for actionRunId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for actionRunId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getStep(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get step log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new c.GetObjectCommand({Bucket:i,Key:`${e}/${t}/${n}/steps/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Step log not found in S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting step log from S3 for actionRunId ${n} stepIndex ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getUnified(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get unified log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new c.GetObjectCommand({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get unified log from S3 for requestId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for requestId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for requestId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for requestId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getProvider(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get provider log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new c.GetObjectCommand({Bucket:i,Key:`${e}/${t}/${n}/provider/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Provider log not found in S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting provider log from S3 for requestId ${n} id ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async send(e,t){if(!this.#e)throw Error(`No s3 client available, cannot send to advanced sink`);let n=process.env.ADVANCED_LOGS_BUCKET;if(!n)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);let r=`ttl=30d`;typeof t==`number`&&(t===1?r=`ttl=1d`:t===7&&(r=`ttl=7d`));let i=Math.floor(Date.now()/1e3)+(t??30)*24*60*60,a=new Date(i*1e3);this.#t?.debug({message:`Storing advanced log in S3 bucket ${n} with ttl of ${r}`,category:`AdvancedSink`,context:{bucket:n,key:e.Key,ttlTag:r,expiresAt:a.toISOString()}});try{return await this.#e.send(new c.PutObjectCommand({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:a,Tagging:r})),{expiresAt:a}}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}async getObjectExpiry(e){if(!this.#e)return this.#t?.warning({message:`No s3 client available, cannot check object expiry`,category:`AdvancedSink`}),{exists:!1};let t=process.env.ADVANCED_LOGS_BUCKET;if(!t)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{return{exists:!0,expiresAt:(await this.#e.send(new c.HeadObjectCommand({Bucket:t,Key:e}))).Expires}}catch(t){let n=t;if(n.name===`NotFound`||n.$metadata?.httpStatusCode===404)return this.#t?.debug({message:`Object not found in S3 for key ${e}`,category:`AdvancedSink`}),{exists:!1};throw this.#t?.error({message:`Error when checking object expiry in S3 for key ${e}`,error:t,code:`AdvancedLogHeadError`,category:`AdvancedSink`}),t}}async hasAction(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}async hasUnified(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}createActionS3(e,t,n){let r=`${t.organizationId}/${t.projectSecureId}/${t.actionRunId}/${t.actionRunId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeActionResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}createStepS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.actionRunId}/steps/${e.stepIndex}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeStepResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}createUnifiedS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/${e.requestId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeUnifiedResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}createProviderS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/provider/${e.id}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeProviderResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let i=(0,s.redactObject)({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.CensorType.PARTIAL),a=i.req?.headers,o=i.res?.headers,c=(0,s.redactFields)(e.body,s.CensorType.PARTIAL,!0),l=(0,s.redactFields)(t.body,s.CensorType.PARTIAL,!0),u=this.processContent(a,c,`upload`),d=this.processContent(o,l,`download`),f=e.isBackground??isBackgroundLog(e.mode,e.sourceType),p=e.url,m={};if(e.url)try{p=(0,s.redactUrl)(e.url,s.CensorType.PARTIAL);let t=new URL(p);m=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in action request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{actionRunId:t.actionRunId,actionId:t.actionId}})}let h={data:{request:{actionRunId:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(a),url:{url:p,path:e.pathParams,queryParams:m},body:u},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:d},...f?{isBackgroundLog:!0}:{}},metadata:{...f?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(h,r)}serializeStepResult(e,t,n,r){let i={data:{actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,input:e.inputs,outputs:t.outputs,errors:t.errors},metadata:{expirationTime:n}};return this.serializeAndLimit(i,r)}serializeUnifiedResult(e,t,n,r){let i=(0,s.redactObject)({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.CensorType.PARTIAL),a=i.req?.headers,o=i.res?.headers,c=(0,s.redactFields)(e.body,s.CensorType.PARTIAL,!0),l=(0,s.redactFields)(t.body,s.CensorType.PARTIAL,!0),u=this.processContent(a,c,`upload`),d=this.processContent(o,l,`download`),f=e.isBackground??isBackgroundLog(e.mode,e.sourceType),p=`/`,m=e.url,h={};if(e.url)try{m=(0,s.redactUrl)(e.url,s.CensorType.PARTIAL);let t=new URL(m);p=t.pathname,h=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in unified request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId}})}let g={data:{request:{id:e.requestId,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:m,path:p,queryParams:h},body:u},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:d}},metadata:{...f?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(g,r)}serializeProviderResult(e,t,n,r){let i=(0,s.redactObject)({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.CensorType.PARTIAL),a=i.req?.headers,o=i.res?.headers,c=(0,s.redactFields)(e.body,s.CensorType.PARTIAL,!0),l=(0,s.redactFields)(t.body,s.CensorType.PARTIAL,!0),u=this.processContent(a,c,`upload`),d=this.processContent(o,l,`download`),f,p=``,m=`/`,h={};if(e.url)try{f=(0,s.redactUrl)(e.url,s.CensorType.PARTIAL);let t=new URL(f);p=t.hostname,m=t.pathname,h=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in provider request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId,id:e.id}})}let g={data:{request:{id:e.id,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:f,hostname:p,path:m,queryParams:h},body:u},response:{statusCode:t.statusCode,headers:this.filterHeaders(o),body:d}},metadata:{expirationTime:n}};return this.serializeAndLimit(g,r)}serializeAndLimit(e,t){if((0,o.exceedsSize)(e,t)){let t={...e,data:{outputs:{error:`Error.TOO_LARGE`}}};return JSON.stringify(t)}return JSON.stringify(e)}filterHeaders(e){if(!e)return;let t={},n=v.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}processContent(e,t,n){let r=this.getContentType(e);if(!r)return this.parseJsonSafely(t);let i=r.toLowerCase().split(`;`)[0].trim();return y.includes(i)||b.some(e=>i.startsWith(e))?{type:`binary`,action:n,contentType:r}:this.parseJsonSafely(t)}parseJsonSafely(e){if(!(0,o.isMissing)(e)){if(!(0,o.isString)(e))return e;try{return JSON.parse(e)}catch{return e}}}getContentType(e){if(!e)return;let t=[`content-type`,`contenttype`];return Object.entries(e).find(([e])=>t.includes(e.toLowerCase()))?.[1]?.toString()}},DatasetsSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, datasets sink will not function`,category:`DatasetsSink`});return}}async sendAction(e,t,n){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Datasets sink called to send action`,category:`DatasetsSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Datasets sink is disabled, skipping sending action to datasets sink`,category:`DatasetsSink`});continue}if((0,o.isMissing)(n.body)&&(0,o.isMissing)(r.body)){this.#t?.debug({message:`No body in action result, skipping sending action to datasets sink`,category:`DatasetsSink`,context:{actionRunId:r.actionRunId}});continue}if(isBackgroundLog(n.mode,n.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Datasets sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`DatasetsSink`});continue}let e=this.createDatasetS3Items(n,r);await this.send(e)}}async send(e){let t=this.#e;if(!t)throw Error(`No s3 client available, cannot send to datasets sink`);let n=process.env.DATASETS_LOGS_BUCKET;if(!n)throw Error(`DATASETS_LOGS_BUCKET environment variable is not set`);let r=Math.floor(Date.now()/1e3)+365*24*60*60,i=new Date(r*1e3),a=`ttl=365d`;this.#t?.debug({message:`Storing datasets log in S3 bucket ${n} with 1-year TTL`,category:`DatasetsSink`,context:{bucket:n,keys:e.map(e=>e.Key),ttlTag:a,expiresAt:i.toISOString()}});try{await Promise.all(e.map(e=>t.send(new c.PutObjectCommand({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:i,Tagging:a}))))}catch(e){throw this.#t?.error({message:`Failed to write dataset logs to S3`,error:e,code:`DatasetLogWriteError`,category:`DatasetsSink`}),e}}generateS3Path(e,t,n){return`${e}/${t}/${n}`}createDatasetS3Items(e,t){let n=t.organizationId,r=t.projectSecureId,i=this.generateS3Path(n,r,t.actionRunId),a=[],s=this.createSchemaLog(e,t);if((0,o.notMissing)(s)){let e=`${i}/schemas.json`;this.#t?.debug({message:`Extracted schema from action result, storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId,schemas:s.schemas}}),a.push({Key:e,Body:JSON.stringify(s),ContentType:`application/json`})}else this.#t?.debug({message:`No schema extracted from action result, skipping storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId}});return a}createSchemaLog(e,t){let n;(0,o.notMissing)(e.body)&&(n=(0,o.extractSchema)(e.body));let r;if((0,o.notMissing)(t.body)&&(r=(0,o.extractSchema)(t.body)),(0,o.notMissing)(n)||(0,o.notMissing)(r)){let e={};return(0,o.notMissing)(n)&&(e.input=n),(0,o.notMissing)(r)&&(e.result=r),{organizationId:t.organizationId,projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,actionId:t.actionId,schemas:e}}}},DefenderSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, defender sink will not function`,category:`DefenderSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),n.push(null);continue}if((0,o.isMissing)(i.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:i.actionRunId}}),n.push(null);continue}let e=this.createDefenderS3(i),a=await this.send(e);n.push(a)}return n}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from defender sink`,category:`DefenderSink`});return}let r=process.env.DEFENDER_LOGS_BUCKET;if(!r)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);try{let i=new c.GetObjectCommand({Bucket:r,Key:this.generateS3Key(e,t,n)}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`DefenderSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved defender log from S3 for actionRunId ${n}`,category:`DefenderSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Defender log not found in S3 for actionRunId ${n}`,category:`DefenderSink`});return}throw this.#t?.error({message:`Error when getting defender log from S3 for actionRunId ${n}`,error:e,code:`DefenderLogReadError`,category:`DefenderSink`}),e}}async send(e){if(!this.#e)throw Error(`No s3 client available, cannot send to defender sink`);let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);let n=Math.floor(Date.now()/1e3)+365*24*60*60,r=new Date(n*1e3),i=`ttl=365d`;this.#t?.debug({message:`Storing defender log in S3 bucket ${t} with 1-year TTL`,category:`DefenderSink`,context:{bucket:t,key:e.Key,ttlTag:i,expiresAt:r.toISOString()}});try{return await this.#e.send(new c.PutObjectCommand({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:r,Tagging:i})),{expiresAt:r}}catch(t){throw this.#t?.error({message:`Failed to write defender logs to S3 at ${e.Key}`,error:t,code:`DefenderLogWriteError`,category:`DefenderSink`}),t}}generateS3Key(e,t,n){return`${e}/${t}/${n}/defender.json`}createDefenderS3(e){let t=e.organizationId,n=e.projectSecureId;return{Key:this.generateS3Key(t,n,e.actionRunId),Body:JSON.stringify(e.defenderContext),ContentType:`application/json`}}};const hasTimezone=e=>/Z$|[+-]\d{2}:\d{2}$|[+-]\d{4}$/.test(e),utcDateTransform=e=>{if(hasTimezone(e))return e;let t=e.replace(` `,`T`);return new Date(t+`Z`).toISOString()},S=l.z.preprocess(e=>{if(e instanceof Date)return e;if(typeof e==`string`&&e.length>0)try{return new Date(utcDateTransform(e))}catch(e){throw new l.z.ZodError([{code:l.z.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},l.z.coerce.date()),C=l.z.object({logType:l.z.enum([`action`,`step`,`unified`,`provider`]),eventTime:S,startTime:S,endTime:S.optional().nullable().transform(e=>e??void 0),durationMs:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:l.z.coerce.string(),projectSecureId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0)}),w=C.extend({logType:l.z.literal(`action`),actionRunId:l.z.coerce.string(),actionId:l.z.coerce.string(),connectorKey:l.z.coerce.string(),connectorVersion:l.z.coerce.string(),connectorOwner:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),connectorProfileId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),actionType:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),mode:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),category:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:S.optional().nullable().transform(e=>e??void 0),defenderExpiresAt:S.optional().nullable().transform(e=>e??void 0)}),T=C.extend({logType:l.z.literal(`step`),actionRunId:l.z.coerce.string(),stepIndex:l.z.coerce.number(),stepId:l.z.coerce.string(),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),skipped:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),message:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionVersion:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),stepIterations:l.z.coerce.number().optional().nullable().transform(e=>e??void 0)}),E=C.extend({logType:l.z.literal(`unified`),requestId:l.z.coerce.string(),connectorKey:l.z.coerce.string(),connectorVersion:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),mode:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),path:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:S.optional().nullable().transform(e=>e??void 0),duration:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:S.optional().nullable().transform(e=>e??void 0)}),D=C.extend({logType:l.z.literal(`provider`),requestId:l.z.coerce.string(),id:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:l.z.coerce.string(),mode:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:l.z.coerce.string(),originOwnerId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:l.z.coerce.string(),path:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:l.z.coerce.string(),connectorVersion:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),status:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:S.optional().nullable().transform(e=>e??void 0),duration:l.z.coerce.number().optional().nullable().transform(e=>e??void 0)}),O=l.z.discriminatedUnion(`logType`,[w,T,E,D]);var SchemaValidationError=class extends Error{constructor(e,t){super(e),this.name=`SchemaValidationError`,this.cause=t}},TinybirdClient=class{#e;#t;#n;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async query(e){try{let t=await this.#o(e.endpoint,e.params);return this.#a(t.data,e.schema)}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryWithPagination(e){try{let t=await this.#o(e.endpoint,e.params),n=this.#a(t.data,e.schema);return{data:n,total:t.rows_before_limit_at_least??t.rows??n.length,pageNumber:e.pageNumber??1,pageSize:e.pageSize??n.length}}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryRaw(e){try{let t=await this.#o(e.endpoint,e.params);return t.data=this.#a(t.data,e.schema),t}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}isReady(){return!!(this.#e&&this.#t?.token)}#r(){return new u.default.Agent({})}#i(){if(!this.#e)throw this.#n?.error({message:`HTTP client not initialized, cannot perform Tinybird query`,category:`TinybirdClient`,code:`HttpClientNotReady`}),Error(`HTTP client is not initialized`);if(!this.#t?.token)throw this.#n?.warning({message:`Missing OLAP token, cannot perform Tinybird query`,category:`TinybirdClient`}),Error(`TinybirdClient - Missing token`)}#a(e,t){if(!t)return e;try{let n=e.map(e=>t.parse(e));return this.#n?.debug({message:`Schema validation passed for ${n.length} rows`,category:`TinybirdClient`}),n}catch(e){let t=e instanceof Error?e.message:String(e);throw this.#n?.error({message:`Schema validation failed: ${t}`,category:`TinybirdClient`,code:`SchemaValidationError`,error:e}),new SchemaValidationError(t,e)}}async#o(e,t){this.#i();let n=this.#e,r=this.#t;if(!n||!r)throw Error(`Client validation failed`);let i=new URL(`/v0/pipes/${e}`,r.baseUrl);this.#n?.debug({message:`Querying Tinybird endpoint: ${e}`,category:`TinybirdClient`,context:{endpoint:e,params:t}});let a=await n.request({method:`post`,url:i.toString(),payload:t,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r.token}`},...r.allowHttp&&{httpAgent:this.#r()}});return this.#n?.debug({message:`Tinybird query returned ${a.data.data.length} rows`,category:`TinybirdClient`,context:{endpoint:e,rows:a.data.rows,statistics:a.data.statistics}}),a.data}};const k=`project_logs.json`,A=`project_action_logs.json`,j=`project_step_logs.json`,M=`project_unified_logs.json`,N=`project_provider_logs.json`,P=`project_logs_aggregation.json`,F=`project_logs_dimensions.json`,I=`project_source_usage.json`;var LogsSink=class{#e;#t;#n;constructor(e,t,n,r){this.#e=e,this.#n=r,this.#t=new TinybirdClient(t,n,r)}async initialize(){if(!this.#e){this.#n?.warning({message:`No kafka producer provided, logs sink cannot be initialized`,category:`LogsSink`});return}this.#t?.isReady()||this.#n?.warning({message:`Tinybird client is not ready (missing HTTP client or Tinybird config/token), logs sink will not be able to query`,category:`LogsSink`}),this.#n?.info({message:`Logs sink kafka producer initialized`,category:`LogsSink`})}async sendAction(e,t,n,r){await this.sendActions([{input:e,result:t,metadata:n}],r)}async sendActions(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} actions to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t,metadata:n})=>this.buildActionLog(e,t,n));await this.send(`actions`,n)}async sendStep(e,t,n){await this.sendSteps([{input:e,result:t}],n)}async sendSteps(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} steps to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t})=>this.buildStepLog(e,t));await this.send(`steps`,n)}async sendUnified(e,t,n,r){if(!r?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending unified to log sink`,category:`LogsSink`});return}this.#n?.info({message:`Sending unified to log sink (topic: unified_requests)`,category:`LogsSink`});let i=this.buildUnifiedLog(e,t,n);await this.send(`unified_requests`,[i])}async sendProvider(e,t,n){if(!n?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending provider to log sink`,category:`LogsSink`});return}this.#n?.info({message:`Sending provider to log sink (topic: provider_requests)`,category:`LogsSink`});let r=this.buildProviderLog(e,t);await this.send(`provider_requests`,[r])}async getLogs(e){try{this.#n?.info({message:`Querying logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{logs:this.validateLogs(t.data),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getActions(e){try{this.#n?.info({message:`Querying action logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_action_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} action logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{actionLogs:this.validateLogsWithSchema(t.data,w),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for action logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getAction(e,t,n){return(await this.getActions({organizationId:e,projectSecureId:t,actionRunId:n})).actionLogs[0]}async getSteps(e){try{this.#n?.info({message:`Querying step logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_step_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} step logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{stepLogs:this.validateLogsWithSchema(t.data,T),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getStep(e,t,n,r){return(await this.getSteps({organizationId:e,projectSecureId:t,actionRunId:n,stepIndex:r})).stepLogs[0]}async getUnifiedLogs(e){try{this.#n?.info({message:`Querying unified logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_unified_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} unified logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{unifiedLogs:this.validateLogsWithSchema(t.data,E),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for unified logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getUnifiedLog(e,t,n){return(await this.getUnifiedLogs({organizationId:e,projectSecureId:t,requestId:n})).unifiedLogs[0]}async getProviderLogs(e){try{this.#n?.info({message:`Querying provider logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_provider_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} provider logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{providerLogs:this.validateLogsWithSchema(t.data,D),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for provider logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getProviderLog(e,t,n,r){return(await this.getProviderLogs({organizationId:e,projectSecureId:t,requestId:n,id:r})).providerLogs[0]}async getAggregate(e,t,n){try{this.#n?.info({message:`Querying logs stats aggregate from Tinybird`,category:`LogsSink`,context:{query:n}});let{dimensions:r,startTime:i,endTime:a,...s}=n,c={organizationId:e,projectSecureId:t,...s,...r&&r.length>0&&{dimensions:r.map(o.snakeToCamel).join(`,`)},...i&&{startTime:i.toISOString()},...a&&{endTime:a.toISOString()}},l=await this.#t?.query({endpoint:`project_logs_aggregation.json`,params:c});if(!l)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{data:[]};this.#n?.info({message:`Successfully retrieved ${l.length} aggregated data points from Tinybird`,category:`LogsSink`});let u=l.map(e=>(0,o.convertKeysToSnakeCase)(e,!0)),d=[`success`,`is_worker`,`is_background`,`skipped`];return{data:u.map(e=>{let t={...e};for(let e of d)e in t&&typeof t[e]==`number`&&(t[e]=t[e]===1);return t})}}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats aggregate, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{data:[]}}}async getDimensions(e,t,n){try{this.#n?.info({message:`Querying logs stats dimensions from Tinybird`,category:`LogsSink`,context:{query:n}});let{dimensions:r,startTime:i,endTime:a,maxValues:s,...c}=n,l={organizationId:e,projectSecureId:t,...c,dimensions:r.map(o.snakeToCamel).join(`,`),...i&&{startTime:i.toISOString()},...a&&{endTime:a.toISOString()},...s&&{maxValuesPerDim:s}},u=await this.#t?.query({endpoint:`project_logs_dimensions.json`,params:l});if(!u)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{};this.#n?.info({message:`Successfully retrieved ${u.length} dimension facets from Tinybird`,category:`LogsSink`});let d=[`success`,`is_worker`,`is_background`,`skipped`],f={};for(let e of u){let t=(0,o.camelToSnake)(e.dimension);d.includes((0,o.camelToSnake)(e.dimension))?f[t]=e.values.map(e=>({value:e.value===`1`?`true`:e.value===`0`?`false`:e.value,count:e.count})):f[t]=e.values}return f}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats dimensions, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{}}}async getSourceUsage(e,t,n){try{this.#n?.info({message:`Querying logs stats source usage from Tinybird`,category:`LogsSink`,context:{query:n}});let{startTime:r,endTime:i,sourceType:a}=n,o={organizationId:e,projectSecureId:t,...a&&{sourceType:Array.isArray(a)?a.join(`,`):a},...r&&{startTime:r.toISOString()},...i&&{endTime:i.toISOString()}},s=await this.#t?.query({endpoint:`project_source_usage.json`,params:o});return s?(this.#n?.info({message:`Successfully retrieved ${s.length} source usage records from Tinybird`,category:`LogsSink`}),s.map(e=>({sourceId:e.sourceId,sourceType:e.sourceType,requestCount:e.request_count,lastRequest:e.last_request}))):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),[])}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats source usage, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),[]}}async send(e,t){if(!this.#e)throw this.#n?.error({message:`Kafka not initialized, dropping message for topic ${e}`,category:`KafkaSink`,code:`KafkaNotReady`}),Error(`Kafka producer is not initialized`);let n=this.validateLogsBeforeSend(t);if(n.length===0){this.#n?.warning({message:`All ${t.length} log(s) failed validation, nothing to send to topic ${e}`,category:`LogsSink`,code:`AllLogsInvalid`});return}n.length<t.length&&this.#n?.warning({message:`${t.length-n.length} of ${t.length} log(s) failed validation and were dropped`,category:`LogsSink`,code:`SomeLogsInvalid`});let r=Date.now(),i=n.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${i.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:i,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${i.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-r,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${i.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-r,topic:e,messageCount:i.length}}),t}}buildActionLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`action`,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,actionRunId:t.actionRunId,actionId:t.actionId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,...t.connectorOwner&&{connectorOwner:t.connectorOwner},...t.connectorProfileId&&{connectorProfileId:t.connectorProfileId},...i!==void 0&&{durationMs:i},...e.mode&&{mode:e.mode},...t.actionType&&{actionType:t.actionType},...t.category&&{category:t.category},...t.originOwnerId&&{originOwnerId:t.originOwnerId},...t.originOwnerName&&{originOwnerName:t.originOwnerName},...t.httpMethod&&{httpMethod:t.httpMethod},...t.url&&{url:t.url},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.defenderContext?.result?.riskLevel&&{riskLevel:t.defenderContext.result.riskLevel},...t.defenderContext?.result?.tier2Score!==void 0&&{tier2Score:t.defenderContext.result.tier2Score},startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,isBackground:e.isBackground,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt},...n?.defenderExpiresAt&&{defenderExpiresAt:n.defenderExpiresAt}}}buildStepLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:e.startTime??n,organizationId:String(e.organizationId),projectSecureId:String(e.projectSecureId),accountSecureId:String(e.accountSecureId),actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,...t.endTime&&{endTime:t.endTime},...r!==void 0&&{durationMs:r},...t.skipped!==void 0&&{skipped:t.skipped},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.message&&{message:t.message},...e.stepFunctionName&&{stepFunctionName:e.stepFunctionName},...e.stepFunctionVersion&&{stepFunctionVersion:e.stepFunctionVersion},...e.stepIterations!==void 0&&{stepIterations:e.stepIterations}}}buildUnifiedLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`unified`,requestId:e.requestId,connectorKey:e.connectorKey,connectorVersion:`2`,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},...e.mode&&{mode:e.mode},...e.httpMethod&&{httpMethod:e.httpMethod},...e.url&&{url:e.url},...e.path&&{path:e.path},...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...e.action&&{action:e.action},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.success!==void 0&&{success:t.success},isBackground:e.isBackground,durationMs:i,startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:r,duration:i,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt}}}buildProviderLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`provider`,requestId:e.requestId,id:e.id,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},action:e.action,...e.mode&&{mode:e.mode},httpMethod:e.httpMethod,url:e.url,...e.path&&{path:e.path},connectorKey:e.connectorKey,connectorVersion:`2`,...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},durationMs:r,startTime:e.startTime??n,...t.endTime&&{endTime:t.endTime},eventTime:n,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:n,duration:r}}calculateDurationMs(e,t){if(!(e instanceof Date)||!(t instanceof Date))return;let n=e.getTime(),r=t.getTime();if(!(Number.isNaN(n)||Number.isNaN(r)||r<n))return r-n}validateLogsWithSchema(e,t){return e.map(e=>{try{return t.parse(e)}catch(t){if(t instanceof l.ZodError){let n=`unknown`;if(typeof e==`object`&&e&&`logType`in e){let t=e;n=typeof t.logType==`string`?t.logType:`unknown`}throw this.#n?.error({message:`Failed to validate ${n} log from Tinybird`,category:`LogsSink`,code:`LogParsingTypeError`,context:{validationErrors:t.errors,log:safeSerialize(e)}}),Error(`Tinybird data validation failed for ${n} log: ${t.message}`)}throw t}})}validateLogs(e){return this.validateLogsWithSchema(e,O)}validateLogsBeforeSend(e){let t=[];for(let n of e)try{let e=this.getSchemaForLogType(n.logType).parse(n);t.push(e)}catch(e){e instanceof l.ZodError?this.#n?.warning({message:`Log validation failed before sending to Tinybird, dropping ${n.logType} log`,category:`LogsSink`,code:`PreWriteValidationFailed`,context:{logType:n.logType,validationErrors:e.errors,log:safeSerialize(n)}}):this.#n?.warning({message:`Unexpected error validating ${n.logType} log before send, dropping log`,category:`LogsSink`,code:`PreWriteValidationError`,error:e})}return t}getSchemaForLogType(e){switch(e){case`action`:return w;case`step`:return T;case`unified`:return E;case`provider`:return D}}};const L={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0},datasets:{enabled:!0,includeBackground:!1}};function resolveOlapOptions(e){return{logs:{...L.logs,...e?.logs},advanced:{...L.advanced,...e?.advanced},defender:{...L.defender,...e?.defender},datasets:{...L.datasets,...e?.datasets}}}const buildHttpClient=e=>{try{return new d.HttpClient({logger:e})}catch(t){let n=t;e?.error({message:`Error building http client: ${n.message}`,error:n,code:`BuildHttpClientError`,category:`buildHttpClient`});return}},buildKafkaClient=async(e,t)=>{if(e)try{let{Producer:t,stringSerializers:n}=await import(`@platformatic/kafka`);return new t({...e,serializers:n})??void 0}catch(e){let n=e;t?.error({message:`Error building kafka producer: ${n.message}`,error:n,code:`BuildKafkaProducerError`,category:`buildKafkaClient`});return}},buildS3Client=(e,t)=>{try{return new c.S3Client(e)??void 0}catch(e){let n=e;t?.error({message:`Error building s3 client: ${n.message}`,error:n,code:`BuildS3ClientError`,category:`buildS3Client`});return}};var R=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#c=e,this.#l=r,this.#u=a,this.#t=t(o),this.#n=n(i,o),this.#r=o}static async create({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){let s=new OlapClient({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});return await s.initialize(),s}async initialize(){this.#e=await this.#c(this.#l,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#u,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),this.#s=new DatasetsSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#s?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){await this.recordActions([{input:e,result:t}],n)}async recordActions(e,t){let{logs:n,advanced:r,defender:i,datasets:a}=resolveOlapOptions(t);this.#r?.debug({message:`Olap client called to record ${e.length} action(s)`,category:`OlapClient`,context:{options:t,resolvedOptions:{logs:n,advanced:r,defender:i,datasets:a}}});for(let t of e)(0,o.isMissing)(t.input.isBackground)&&(t.input.isBackground=isBackgroundLog(t.input.mode,t.input.sourceType));let s=a?.enabled&&this.#s?this.#s.sendActions(e,a).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to datasets sink: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve(),[c,l]=await Promise.all([r?.enabled&&this.#a?this.#a.sendActions(e,r).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null)),i?.enabled&&this.#o?this.#o.sendActions(e,i).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null))]),u=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:c[t]?.expiresAt,defenderExpiresAt:l[t]?.expiresAt}})),d=n?.enabled&&this.#i?this.#i.sendActions(u,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve();await Promise.all([s,d])}async recordStep(e,t,n){await this.recordSteps([{input:e,result:t}],n)}async recordSteps(e,t){let{logs:n,advanced:r}=resolveOlapOptions(t),i=[];n?.enabled&&this.#i&&i.push(this.#i.sendSteps(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&i.push(this.#a.sendSteps(e,r).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}async recordUnified(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record unified`,category:`OlapClient`,context:{mode:e.mode,requestId:e.requestId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:i}}}),(0,o.isMissing)(e.isBackground)&&(e.isBackground=isBackgroundLog(e.mode,e.sourceType));let a={advancedExpiresAt:(i?.enabled&&this.#a?await this.#a.sendUnified(e,t,i).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):null)?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendUnified(e,t,a,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordProvider(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendProvider(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&a.push(this.#a.sendProvider(e,t,i).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}async getLogs(e,t,n){return this.#r?.debug({message:`Querying logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query logs, returning empty result`,category:`OlapClient`}),{logs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLogs(e,t,n){return this.#r?.debug({message:`Querying action logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getActions({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query action logs, returning empty result`,category:`OlapClient`}),{actionLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLog(e,t,n){let r=await this.#i?.getAction(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve action log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepLogs(e,t,n){return this.#r?.debug({message:`Querying step logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSteps({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query step logs, returning empty result`,category:`OlapClient`}),{stepLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getStepLog(e,t,n,r){let i=await this.#i?.getStep(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedLogs(e,t,n){return this.#r?.debug({message:`Querying unified logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getUnifiedLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query unified logs, returning empty result`,category:`OlapClient`}),{unifiedLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getUnifiedLog(e,t,n){let r=await this.#i?.getUnifiedLog(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve unified log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderLogs(e,t,n){return this.#r?.debug({message:`Querying provider logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getProviderLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query provider logs, returning empty result`,category:`OlapClient`}),{providerLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getProviderLog(e,t,n,r){let i=await this.#i?.getProviderLog(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve provider log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getActionAdvancedLog(e,t,n){let r=await this.#a?.getAction(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve action advanced log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepAdvancedLog(e,t,n,r){let i=await this.#a?.getStep(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedAdvancedLog(e,t,n){let r=await this.#a?.getUnified(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve unified advanced log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderAdvancedLog(e,t,n,r){let i=await this.#a?.getProvider(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve provider advanced log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getDefenderLog(e,t,n){let r=await this.#o?.getAction(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve defender log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getLogsStatsAggregate(e,t,n){return this.#r?.debug({message:`Querying logs stats aggregate`,category:`OlapClient`,context:{query:n}}),await this.#i?.getAggregate(e,t,n)??{data:[]}}async getLogsStatsDimensions(e,t,n){return this.#r?.debug({message:`Querying logs stats dimensions`,category:`OlapClient`,context:{query:n}}),await this.#i?.getDimensions(e,t,n)??{}}async getSourceUsage(e,t,n){return this.#r?.debug({message:`Querying source usage`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSourceUsage(e,t,n)??[]}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>R.create({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});var OlapClientManager=class{static{this.olapClientPromise=null}static getInstance({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o,getOlapClient:s=buildOlapClientInstance}={}){return this.olapClientPromise||=s({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}),this.olapClientPromise}static resetInstance(){this.olapClientPromise=null}};exports.Dimension=p,exports.LogType=f,exports.OlapClient=R,exports.OlapClientManager=OlapClientManager;
1
+ var e=Object.create,t=Object.defineProperty,__name=(e,n)=>t(e,`name`,{value:n,configurable:!0}),n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,__copyProps=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},__toESM=(n,r,a)=>(a=n==null?{}:e(i(n)),__copyProps(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let o=require(`@stackone/utils`),s=require(`@stackone/redaction`),c=require(`@aws-sdk/client-s3`),l=require(`zod`),u=require(`node:http`);u=__toESM(u);let d=require(`@stackone/transport`);const f={Action:`action`,Step:`step`,Unified:`unified`,Provider:`provider`},p={ConnectorKey:`connector_key`,Success:`success`,ActionType:`action_type`,Mode:`mode`,Service:`service`,Resource:`resource`,ActionId:`action_id`,HttpMethod:`http_method`,AccountSecureId:`account_secure_id`,SourceType:`source_type`,StatusCode:`status_code`,OriginOwnerId:`origin_owner_id`,SourceId:`source_id`,IsBackground:`is_background`},m=[`refresh_authentication`,`data_sync`,`test_action`,`webhook_setup`],h=[`TOKEN_REFRESH`,`VALIDATE_CREDENTIALS`,`DATA_SYNC`,`NATIVE_WEBHOOK_SETUP_WORKER`],g=[`data_sync`],_=[`DATA_SYNC`];function isBackgroundLog(e,t){return!!(e&&m.includes(e)||t&&h.includes(t))}function isDataSync(e,t){return!!(e&&g.includes(e)||t&&_.includes(t))}const safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},v=[`x-datadog-parent-id`,`x-datadog-sampling-priority`,`x-datadog-tags`,`x-datadog-trace-id`,`x-forwarded-proto`,`x-forwarded-port`,`x-forwarded-for`,`x-amzn-trace-id`,`traceparent`,`tracestate`,`x-request-nonce`,`x-signing-method`,`x-signature`,`host`,`via`],y=[`application/octet-stream`,`application/pdf`,`application/msword`,`application/vnd.openxmlformats-officedocument.wordprocessingml.document`,`application/vnd.ms-excel`,`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,`application/zip`,`application/x-zip-compressed`],b=[`image/`,`audio/`,`video/`,`application/vnd.`,`binary`],x=10*1024*1024;var AdvancedSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, advanced sink will not function`,category:`AdvancedSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled,errorsOnly:t?.errorsOnly,includeBackground:t?.includeBackground,ttl:t?.ttl}}}),!t?.enabled){this.#t?.debug({message:`Advanced sink is disabled, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(isDataSync(r.mode,r.sourceType)){this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(t.errorsOnly&&i.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${r.mode||`action`}`,category:`AdvancedSink`}),n.push(null);continue}if(isBackgroundLog(r.mode,r.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${r.mode}`,category:`AdvancedSink`}),n.push(null);continue}let e=this.createActionS3(r,i,t?.ttl),a=await this.send(e,t?.ttl);n.push(a)}return n}async sendStep(e,t,n){if(this.#t?.debug({message:`Advanced sink called to send step`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,success:t.success,options:{enabled:n?.enabled,errorsOnly:n?.errorsOnly,includeBackground:n?.includeBackground,ttl:n?.ttl}}}),!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`}),null;if(isDataSync(e.actionMode))return this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending step to advanced sink`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null;if(n.errorsOnly&&e.actionSuccess===!0)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${e.actionMode||`action`}`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.actionMode)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${e.actionMode}`,category:`AdvancedSink`}),null;let r=this.createStepS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send step to advanced sink`,error:t,code:`AdvancedStepWriteError`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null}}async sendSteps(e,t){let n=[];for(let{input:r,result:i}of e){let e=await this.sendStep(r,i,t);n.push(e)}return n}async sendUnified(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending unified to advanced sink`,category:`AdvancedSink`}),null;if(n.errorsOnly&&t.success)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful unified request`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.mode,e.sourceType)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping unified with mode ${e.mode}`,category:`AdvancedSink`}),null;this.#t?.debug({message:`Sending unified to advanced sink`,category:`AdvancedSink`});let r=this.createUnifiedS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send unified to advanced sink`,error:t,code:`AdvancedUnifiedWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async sendProvider(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending provider to advanced sink`,category:`AdvancedSink`}),null;this.#t?.debug({message:`Sending provider to advanced sink`,category:`AdvancedSink`});let r=this.createProviderS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send provider to advanced sink`,error:t,code:`AdvancedProviderWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new c.GetObjectCommand({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for actionRunId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for actionRunId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for actionRunId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getStep(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get step log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new c.GetObjectCommand({Bucket:i,Key:`${e}/${t}/${n}/steps/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Step log not found in S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting step log from S3 for actionRunId ${n} stepIndex ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getUnified(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get unified log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new c.GetObjectCommand({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get unified log from S3 for requestId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for requestId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for requestId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for requestId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getProvider(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get provider log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new c.GetObjectCommand({Bucket:i,Key:`${e}/${t}/${n}/provider/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Provider log not found in S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting provider log from S3 for requestId ${n} id ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async send(e,t){if(!this.#e)throw Error(`No s3 client available, cannot send to advanced sink`);let n=process.env.ADVANCED_LOGS_BUCKET;if(!n)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);let r=`ttl=30d`;typeof t==`number`&&(t===1?r=`ttl=1d`:t===7&&(r=`ttl=7d`));let i=Math.floor(Date.now()/1e3)+(t??30)*24*60*60,a=new Date(i*1e3);this.#t?.debug({message:`Storing advanced log in S3 bucket ${n} with ttl of ${r}`,category:`AdvancedSink`,context:{bucket:n,key:e.Key,ttlTag:r,expiresAt:a.toISOString()}});try{return await this.#e.send(new c.PutObjectCommand({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:a,Tagging:r})),{expiresAt:a}}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}async getObjectExpiry(e){if(!this.#e)return this.#t?.warning({message:`No s3 client available, cannot check object expiry`,category:`AdvancedSink`}),{exists:!1};let t=process.env.ADVANCED_LOGS_BUCKET;if(!t)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{return{exists:!0,expiresAt:(await this.#e.send(new c.HeadObjectCommand({Bucket:t,Key:e}))).Expires}}catch(t){let n=t;if(n.name===`NotFound`||n.$metadata?.httpStatusCode===404)return this.#t?.debug({message:`Object not found in S3 for key ${e}`,category:`AdvancedSink`}),{exists:!1};throw this.#t?.error({message:`Error when checking object expiry in S3 for key ${e}`,error:t,code:`AdvancedLogHeadError`,category:`AdvancedSink`}),t}}async hasAction(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}async hasUnified(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}createActionS3(e,t,n){let r=`${t.organizationId}/${t.projectSecureId}/${t.actionRunId}/${t.actionRunId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeActionResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}createStepS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.actionRunId}/steps/${e.stepIndex}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeStepResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}createUnifiedS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/${e.requestId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeUnifiedResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}createProviderS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/provider/${e.id}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeProviderResult(e,t,i,x),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let i=(0,s.redactObject)({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.CensorType.PARTIAL),a=i.req?.headers,o=i.res?.headers,c=(0,s.redactFields)(e.body,s.CensorType.PARTIAL,!0),l=(0,s.redactFields)(t.body,s.CensorType.PARTIAL,!0),u=this.processContent(a,c,`upload`),d=this.processContent(o,l,`download`),f=e.isBackground??isBackgroundLog(e.mode,e.sourceType),p=e.url,m={};if(e.url)try{p=(0,s.redactUrl)(e.url,s.CensorType.PARTIAL);let t=new URL(p);m=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in action request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{actionRunId:t.actionRunId,actionId:t.actionId}})}let h={data:{request:{actionRunId:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(a),url:{url:p,path:e.pathParams,queryParams:m},body:u},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:d},...f?{isBackgroundLog:!0}:{}},metadata:{...f?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(h,r)}serializeStepResult(e,t,n,r){let i={data:{actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,input:e.inputs,outputs:t.outputs,errors:t.errors},metadata:{expirationTime:n}};return this.serializeAndLimit(i,r)}serializeUnifiedResult(e,t,n,r){let i=(0,s.redactObject)({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.CensorType.PARTIAL),a=i.req?.headers,o=i.res?.headers,c=(0,s.redactFields)(e.body,s.CensorType.PARTIAL,!0),l=(0,s.redactFields)(t.body,s.CensorType.PARTIAL,!0),u=this.processContent(a,c,`upload`),d=this.processContent(o,l,`download`),f=e.isBackground??isBackgroundLog(e.mode,e.sourceType),p=`/`,m=e.url,h={};if(e.url)try{m=(0,s.redactUrl)(e.url,s.CensorType.PARTIAL);let t=new URL(m);p=t.pathname,h=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in unified request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId}})}let g={data:{request:{id:e.requestId,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:m,path:p,queryParams:h},body:u},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:d}},metadata:{...f?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(g,r)}serializeProviderResult(e,t,n,r){let i=(0,s.redactObject)({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.CensorType.PARTIAL),a=i.req?.headers,o=i.res?.headers,c=(0,s.redactFields)(e.body,s.CensorType.PARTIAL,!0),l=(0,s.redactFields)(t.body,s.CensorType.PARTIAL,!0),u=this.processContent(a,c,`upload`),d=this.processContent(o,l,`download`),f,p=``,m=`/`,h={};if(e.url)try{f=(0,s.redactUrl)(e.url,s.CensorType.PARTIAL);let t=new URL(f);p=t.hostname,m=t.pathname,h=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in provider request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId,id:e.id}})}let g={data:{request:{id:e.id,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:f,hostname:p,path:m,queryParams:h},body:u},response:{statusCode:t.statusCode,headers:this.filterHeaders(o),body:d}},metadata:{expirationTime:n}};return this.serializeAndLimit(g,r)}serializeAndLimit(e,t){if((0,o.exceedsSize)(e,t)){let t={...e,data:{outputs:{error:`Error.TOO_LARGE`}}};return JSON.stringify(t)}return JSON.stringify(e)}filterHeaders(e){if(!e)return;let t={},n=v.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}processContent(e,t,n){let r=this.getContentType(e);if(!r)return this.parseJsonSafely(t);let i=r.toLowerCase().split(`;`)[0].trim();return y.includes(i)||b.some(e=>i.startsWith(e))?{type:`binary`,action:n,contentType:r}:this.parseJsonSafely(t)}parseJsonSafely(e){if(!(0,o.isMissing)(e)){if(!(0,o.isString)(e))return e;try{return JSON.parse(e)}catch{return e}}}getContentType(e){if(!e)return;let t=[`content-type`,`contenttype`];return Object.entries(e).find(([e])=>t.includes(e.toLowerCase()))?.[1]?.toString()}},DatasetsSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, datasets sink will not function`,category:`DatasetsSink`});return}}async sendAction(e,t,n){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Datasets sink called to send action`,category:`DatasetsSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Datasets sink is disabled, skipping sending action to datasets sink`,category:`DatasetsSink`});continue}if((0,o.isMissing)(n.body)&&(0,o.isMissing)(r.body)){this.#t?.debug({message:`No body in action result, skipping sending action to datasets sink`,category:`DatasetsSink`,context:{actionRunId:r.actionRunId}});continue}if(isBackgroundLog(n.mode,n.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Datasets sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`DatasetsSink`});continue}let e=this.createDatasetS3Items(n,r);await this.send(e)}}async send(e){let t=this.#e;if(!t)throw Error(`No s3 client available, cannot send to datasets sink`);let n=process.env.DATASETS_LOGS_BUCKET;if(!n)throw Error(`DATASETS_LOGS_BUCKET environment variable is not set`);let r=Math.floor(Date.now()/1e3)+365*24*60*60,i=new Date(r*1e3),a=`ttl=365d`;this.#t?.debug({message:`Storing datasets log in S3 bucket ${n} with 1-year TTL`,category:`DatasetsSink`,context:{bucket:n,keys:e.map(e=>e.Key),ttlTag:a,expiresAt:i.toISOString()}});try{await Promise.all(e.map(e=>t.send(new c.PutObjectCommand({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:i,Tagging:a}))))}catch(e){throw this.#t?.error({message:`Failed to write dataset logs to S3`,error:e,code:`DatasetLogWriteError`,category:`DatasetsSink`}),e}}generateS3Path(e,t,n){return`${e}/${t}/${n}`}createDatasetS3Items(e,t){let n=t.organizationId,r=t.projectSecureId,i=this.generateS3Path(n,r,t.actionRunId),a=[],s=this.createSchemaLog(e,t);if((0,o.notMissing)(s)){let e=`${i}/schemas.json`;this.#t?.debug({message:`Extracted schema from action result, storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId,schemas:s.schemas}}),a.push({Key:e,Body:JSON.stringify(s),ContentType:`application/json`})}else this.#t?.debug({message:`No schema extracted from action result, skipping storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId}});return a}createSchemaLog(e,t){let n;(0,o.notMissing)(e.body)&&(n=(0,o.extractSchema)(e.body));let r;if((0,o.notMissing)(t.body)&&(r=(0,o.extractSchema)(t.body)),(0,o.notMissing)(n)||(0,o.notMissing)(r)){let e={};return(0,o.notMissing)(n)&&(e.input=n),(0,o.notMissing)(r)&&(e.result=r),{organizationId:t.organizationId,projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,actionId:t.actionId,schemas:e}}}},DefenderSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, defender sink will not function`,category:`DefenderSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),n.push(null);continue}if((0,o.isMissing)(i.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:i.actionRunId}}),n.push(null);continue}let e=this.createDefenderS3(i),a=await this.send(e);n.push(a)}return n}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from defender sink`,category:`DefenderSink`});return}let r=process.env.DEFENDER_LOGS_BUCKET;if(!r)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);try{let i=new c.GetObjectCommand({Bucket:r,Key:this.generateS3Key(e,t,n)}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`DefenderSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved defender log from S3 for actionRunId ${n}`,category:`DefenderSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Defender log not found in S3 for actionRunId ${n}`,category:`DefenderSink`});return}throw this.#t?.error({message:`Error when getting defender log from S3 for actionRunId ${n}`,error:e,code:`DefenderLogReadError`,category:`DefenderSink`}),e}}async send(e){if(!this.#e)throw Error(`No s3 client available, cannot send to defender sink`);let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);let n=Math.floor(Date.now()/1e3)+365*24*60*60,r=new Date(n*1e3),i=`ttl=365d`;this.#t?.debug({message:`Storing defender log in S3 bucket ${t} with 1-year TTL`,category:`DefenderSink`,context:{bucket:t,key:e.Key,ttlTag:i,expiresAt:r.toISOString()}});try{return await this.#e.send(new c.PutObjectCommand({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:r,Tagging:i})),{expiresAt:r}}catch(t){throw this.#t?.error({message:`Failed to write defender logs to S3 at ${e.Key}`,error:t,code:`DefenderLogWriteError`,category:`DefenderSink`}),t}}generateS3Key(e,t,n){return`${e}/${t}/${n}/defender.json`}createDefenderS3(e){let t=e.organizationId,n=e.projectSecureId;return{Key:this.generateS3Key(t,n,e.actionRunId),Body:JSON.stringify(e.defenderContext),ContentType:`application/json`}}};const hasTimezone=e=>/Z$|[+-]\d{2}:\d{2}$|[+-]\d{4}$/.test(e),utcDateTransform=e=>{if(hasTimezone(e))return e;let t=e.replace(` `,`T`);return new Date(t+`Z`).toISOString()},S=l.z.preprocess(e=>{if(e instanceof Date)return e;if(typeof e==`string`&&e.length>0)try{return new Date(utcDateTransform(e))}catch(e){throw new l.z.ZodError([{code:l.z.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},l.z.coerce.date()),C=l.z.object({logType:l.z.enum([`action`,`step`,`unified`,`provider`]),eventTime:S,startTime:S,endTime:S.optional().nullable().transform(e=>e??void 0),durationMs:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:l.z.coerce.string(),projectSecureId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0)}),w=C.extend({logType:l.z.literal(`action`),actionRunId:l.z.coerce.string(),actionId:l.z.coerce.string(),connectorKey:l.z.coerce.string(),connectorVersion:l.z.coerce.string(),connectorOwner:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),connectorProfileId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),actionType:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),mode:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),category:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:S.optional().nullable().transform(e=>e??void 0),defenderExpiresAt:S.optional().nullable().transform(e=>e??void 0)}),T=C.extend({logType:l.z.literal(`step`),actionRunId:l.z.coerce.string(),stepIndex:l.z.coerce.number(),stepId:l.z.coerce.string(),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),skipped:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),message:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionVersion:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),stepIterations:l.z.coerce.number().optional().nullable().transform(e=>e??void 0)}),E=C.extend({logType:l.z.literal(`unified`),requestId:l.z.coerce.string(),connectorKey:l.z.coerce.string(),connectorVersion:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),mode:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),path:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:S.optional().nullable().transform(e=>e??void 0),duration:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:S.optional().nullable().transform(e=>e??void 0)}),D=C.extend({logType:l.z.literal(`provider`),requestId:l.z.coerce.string(),id:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:l.z.coerce.string(),mode:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:l.z.coerce.string(),originOwnerId:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:l.z.coerce.string(),path:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:l.z.coerce.string(),connectorVersion:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:l.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:l.z.coerce.string(),accountSecureId:l.z.coerce.string(),status:l.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:l.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:S.optional().nullable().transform(e=>e??void 0),duration:l.z.coerce.number().optional().nullable().transform(e=>e??void 0)}),O=l.z.discriminatedUnion(`logType`,[w,T,E,D]);var SchemaValidationError=class extends Error{constructor(e,t){super(e),this.name=`SchemaValidationError`,this.cause=t}},TinybirdClient=class{#e;#t;#n;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async query(e){try{let t=await this.#o(e.endpoint,e.params);return this.#a(t.data,e.schema)}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryWithPagination(e){try{let t=await this.#o(e.endpoint,e.params),n=this.#a(t.data,e.schema);return{data:n,total:t.rows_before_limit_at_least??t.rows??n.length,pageNumber:e.pageNumber??1,pageSize:e.pageSize??n.length}}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryRaw(e){try{let t=await this.#o(e.endpoint,e.params);return t.data=this.#a(t.data,e.schema),t}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}isReady(){return!!(this.#e&&this.#t?.token)}#r(){return new u.default.Agent({})}#i(){if(!this.#e)throw this.#n?.error({message:`HTTP client not initialized, cannot perform Tinybird query`,category:`TinybirdClient`,code:`HttpClientNotReady`}),Error(`HTTP client is not initialized`);if(!this.#t?.token)throw this.#n?.warning({message:`Missing OLAP token, cannot perform Tinybird query`,category:`TinybirdClient`}),Error(`TinybirdClient - Missing token`)}#a(e,t){if(!t)return e;try{let n=e.map(e=>t.parse(e));return this.#n?.debug({message:`Schema validation passed for ${n.length} rows`,category:`TinybirdClient`}),n}catch(e){let t=e instanceof Error?e.message:String(e);throw this.#n?.error({message:`Schema validation failed: ${t}`,category:`TinybirdClient`,code:`SchemaValidationError`,error:e}),new SchemaValidationError(t,e)}}async#o(e,t){this.#i();let n=this.#e,r=this.#t;if(!n||!r)throw Error(`Client validation failed`);let i=new URL(`/v0/pipes/${e}`,r.baseUrl);this.#n?.debug({message:`Querying Tinybird endpoint: ${e}`,category:`TinybirdClient`,context:{endpoint:e,params:t}});let a=await n.request({method:`post`,url:i.toString(),payload:t,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r.token}`},...r.allowHttp&&{httpAgent:this.#r()}});return this.#n?.debug({message:`Tinybird query returned ${a.data.data.length} rows`,category:`TinybirdClient`,context:{endpoint:e,rows:a.data.rows,statistics:a.data.statistics}}),a.data}};const k=`project_logs.json`,A=`project_action_logs.json`,j=`project_step_logs.json`,M=`project_unified_logs.json`,N=`project_provider_logs.json`,P=`project_logs_aggregation.json`,F=`project_logs_dimensions.json`,I=`project_source_usage.json`;var LogsSink=class{#e;#t;#n;constructor(e,t,n,r){this.#e=e,this.#n=r,this.#t=new TinybirdClient(t,n,r)}async initialize(){if(!this.#e){this.#n?.warning({message:`No kafka producer provided, logs sink cannot be initialized`,category:`LogsSink`});return}this.#t?.isReady()||this.#n?.warning({message:`Tinybird client is not ready (missing HTTP client or Tinybird config/token), logs sink will not be able to query`,category:`LogsSink`}),this.#n?.info({message:`Logs sink kafka producer initialized`,category:`LogsSink`})}async sendAction(e,t,n,r){await this.sendActions([{input:e,result:t,metadata:n}],r)}async sendActions(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} actions to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t,metadata:n})=>this.buildActionLog(e,t,n));await this.send(`actions`,n)}async sendStep(e,t,n){await this.sendSteps([{input:e,result:t}],n)}async sendSteps(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} steps to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t})=>this.buildStepLog(e,t));await this.send(`steps`,n)}async sendUnified(e,t,n,r){if(!r?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending unified to log sink`,category:`LogsSink`});return}this.#n?.debug({message:`Sending unified to log sink (topic: unified_requests)`,category:`LogsSink`});let i=this.buildUnifiedLog(e,t,n);await this.send(`unified_requests`,[i])}async sendProvider(e,t,n){if(!n?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending provider to log sink`,category:`LogsSink`});return}this.#n?.debug({message:`Sending provider to log sink (topic: provider_requests)`,category:`LogsSink`});let r=this.buildProviderLog(e,t);await this.send(`provider_requests`,[r])}async getLogs(e){try{this.#n?.info({message:`Querying logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{logs:this.validateLogs(t.data),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getActions(e){try{this.#n?.info({message:`Querying action logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_action_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} action logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{actionLogs:this.validateLogsWithSchema(t.data,w),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for action logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getAction(e,t,n){return(await this.getActions({organizationId:e,projectSecureId:t,actionRunId:n})).actionLogs[0]}async getSteps(e){try{this.#n?.info({message:`Querying step logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_step_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} step logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{stepLogs:this.validateLogsWithSchema(t.data,T),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getStep(e,t,n,r){return(await this.getSteps({organizationId:e,projectSecureId:t,actionRunId:n,stepIndex:r})).stepLogs[0]}async getUnifiedLogs(e){try{this.#n?.info({message:`Querying unified logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_unified_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} unified logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{unifiedLogs:this.validateLogsWithSchema(t.data,E),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for unified logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getUnifiedLog(e,t,n){return(await this.getUnifiedLogs({organizationId:e,projectSecureId:t,requestId:n})).unifiedLogs[0]}async getProviderLogs(e){try{this.#n?.info({message:`Querying provider logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_provider_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} provider logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{providerLogs:this.validateLogsWithSchema(t.data,D),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for provider logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getProviderLog(e,t,n,r){return(await this.getProviderLogs({organizationId:e,projectSecureId:t,requestId:n,id:r})).providerLogs[0]}async getAggregate(e,t,n){try{this.#n?.info({message:`Querying logs stats aggregate from Tinybird`,category:`LogsSink`,context:{query:n}});let{dimensions:r,startTime:i,endTime:a,...s}=n,c={organizationId:e,projectSecureId:t,...s,...r&&r.length>0&&{dimensions:r.map(o.snakeToCamel).join(`,`)},...i&&{startTime:i.toISOString()},...a&&{endTime:a.toISOString()}},l=await this.#t?.query({endpoint:`project_logs_aggregation.json`,params:c});if(!l)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{data:[]};this.#n?.info({message:`Successfully retrieved ${l.length} aggregated data points from Tinybird`,category:`LogsSink`});let u=l.map(e=>(0,o.convertKeysToSnakeCase)(e,!0)),d=[`success`,`is_worker`,`is_background`,`skipped`];return{data:u.map(e=>{let t={...e};for(let e of d)e in t&&typeof t[e]==`number`&&(t[e]=t[e]===1);return t})}}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats aggregate, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{data:[]}}}async getDimensions(e,t,n){try{this.#n?.info({message:`Querying logs stats dimensions from Tinybird`,category:`LogsSink`,context:{query:n}});let{dimensions:r,startTime:i,endTime:a,maxValues:s,...c}=n,l={organizationId:e,projectSecureId:t,...c,dimensions:r.map(o.snakeToCamel).join(`,`),...i&&{startTime:i.toISOString()},...a&&{endTime:a.toISOString()},...s&&{maxValuesPerDim:s}},u=await this.#t?.query({endpoint:`project_logs_dimensions.json`,params:l});if(!u)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{};this.#n?.info({message:`Successfully retrieved ${u.length} dimension facets from Tinybird`,category:`LogsSink`});let d=[`success`,`is_worker`,`is_background`,`skipped`],f={};for(let e of u){let t=(0,o.camelToSnake)(e.dimension);d.includes((0,o.camelToSnake)(e.dimension))?f[t]=e.values.map(e=>({value:e.value===`1`?`true`:e.value===`0`?`false`:e.value,count:e.count})):f[t]=e.values}return f}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats dimensions, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{}}}async getSourceUsage(e,t,n){try{this.#n?.info({message:`Querying logs stats source usage from Tinybird`,category:`LogsSink`,context:{query:n}});let{startTime:r,endTime:i,sourceType:a}=n,o={organizationId:e,projectSecureId:t,...a&&{sourceType:Array.isArray(a)?a.join(`,`):a},...r&&{startTime:r.toISOString()},...i&&{endTime:i.toISOString()}},s=await this.#t?.query({endpoint:`project_source_usage.json`,params:o});return s?(this.#n?.info({message:`Successfully retrieved ${s.length} source usage records from Tinybird`,category:`LogsSink`}),s.map(e=>({sourceId:e.sourceId,sourceType:e.sourceType,requestCount:e.request_count,lastRequest:e.last_request}))):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),[])}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats source usage, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),[]}}async send(e,t){if(!this.#e)throw this.#n?.error({message:`Kafka not initialized, dropping message for topic ${e}`,category:`KafkaSink`,code:`KafkaNotReady`}),Error(`Kafka producer is not initialized`);let n=this.validateLogsBeforeSend(t);if(n.length===0){this.#n?.warning({message:`All ${t.length} log(s) failed validation, nothing to send to topic ${e}`,category:`LogsSink`,code:`AllLogsInvalid`});return}n.length<t.length&&this.#n?.warning({message:`${t.length-n.length} of ${t.length} log(s) failed validation and were dropped`,category:`LogsSink`,code:`SomeLogsInvalid`});let r=Date.now(),i=n.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${i.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:i,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${i.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-r,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${i.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-r,topic:e,messageCount:i.length}}),t}}buildActionLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`action`,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,actionRunId:t.actionRunId,actionId:t.actionId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,...t.connectorOwner&&{connectorOwner:t.connectorOwner},...t.connectorProfileId&&{connectorProfileId:t.connectorProfileId},...i!==void 0&&{durationMs:i},...e.mode&&{mode:e.mode},...t.actionType&&{actionType:t.actionType},...t.category&&{category:t.category},...t.originOwnerId&&{originOwnerId:t.originOwnerId},...t.originOwnerName&&{originOwnerName:t.originOwnerName},...t.httpMethod&&{httpMethod:t.httpMethod},...t.url&&{url:t.url},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.defenderContext?.result?.riskLevel&&{riskLevel:t.defenderContext.result.riskLevel},...t.defenderContext?.result?.tier2Score!==void 0&&{tier2Score:t.defenderContext.result.tier2Score},startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,isBackground:e.isBackground,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt},...n?.defenderExpiresAt&&{defenderExpiresAt:n.defenderExpiresAt}}}buildStepLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:e.startTime??n,organizationId:String(e.organizationId),projectSecureId:String(e.projectSecureId),accountSecureId:String(e.accountSecureId),actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,...t.endTime&&{endTime:t.endTime},...r!==void 0&&{durationMs:r},...t.skipped!==void 0&&{skipped:t.skipped},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.message&&{message:t.message},...e.stepFunctionName&&{stepFunctionName:e.stepFunctionName},...e.stepFunctionVersion&&{stepFunctionVersion:e.stepFunctionVersion},...e.stepIterations!==void 0&&{stepIterations:e.stepIterations}}}buildUnifiedLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`unified`,requestId:e.requestId,connectorKey:e.connectorKey,connectorVersion:`2`,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},...e.mode&&{mode:e.mode},...e.httpMethod&&{httpMethod:e.httpMethod},...e.url&&{url:e.url},...e.path&&{path:e.path},...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...e.action&&{action:e.action},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.success!==void 0&&{success:t.success},isBackground:e.isBackground,durationMs:i,startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:r,duration:i,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt}}}buildProviderLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`provider`,requestId:e.requestId,id:e.id,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},action:e.action,...e.mode&&{mode:e.mode},httpMethod:e.httpMethod,url:e.url,...e.path&&{path:e.path},connectorKey:e.connectorKey,connectorVersion:`2`,...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},durationMs:r,startTime:e.startTime??n,...t.endTime&&{endTime:t.endTime},eventTime:n,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:n,duration:r}}calculateDurationMs(e,t){if(!(e instanceof Date)||!(t instanceof Date))return;let n=e.getTime(),r=t.getTime();if(!(Number.isNaN(n)||Number.isNaN(r)||r<n))return r-n}validateLogsWithSchema(e,t){return e.map(e=>{try{return t.parse(e)}catch(t){if(t instanceof l.ZodError){let n=`unknown`;if(typeof e==`object`&&e&&`logType`in e){let t=e;n=typeof t.logType==`string`?t.logType:`unknown`}throw this.#n?.error({message:`Failed to validate ${n} log from Tinybird`,category:`LogsSink`,code:`LogParsingTypeError`,context:{validationErrors:t.errors,log:safeSerialize(e)}}),Error(`Tinybird data validation failed for ${n} log: ${t.message}`)}throw t}})}validateLogs(e){return this.validateLogsWithSchema(e,O)}validateLogsBeforeSend(e){let t=[];for(let n of e)try{let e=this.getSchemaForLogType(n.logType).parse(n);t.push(e)}catch(e){e instanceof l.ZodError?this.#n?.warning({message:`Log validation failed before sending to Tinybird, dropping ${n.logType} log`,category:`LogsSink`,code:`PreWriteValidationFailed`,context:{logType:n.logType,validationErrors:e.errors,log:safeSerialize(n)}}):this.#n?.warning({message:`Unexpected error validating ${n.logType} log before send, dropping log`,category:`LogsSink`,code:`PreWriteValidationError`,error:e})}return t}getSchemaForLogType(e){switch(e){case`action`:return w;case`step`:return T;case`unified`:return E;case`provider`:return D}}};const L={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0},datasets:{enabled:!0,includeBackground:!1}};function resolveOlapOptions(e){return{logs:{...L.logs,...e?.logs},advanced:{...L.advanced,...e?.advanced},defender:{...L.defender,...e?.defender},datasets:{...L.datasets,...e?.datasets}}}const buildHttpClient=e=>{try{return new d.HttpClient({logger:e})}catch(t){let n=t;e?.error({message:`Error building http client: ${n.message}`,error:n,code:`BuildHttpClientError`,category:`buildHttpClient`});return}},buildKafkaClient=async(e,t)=>{if(e)try{let{Producer:t,stringSerializers:n}=await import(`@platformatic/kafka`);return new t({...e,serializers:n})??void 0}catch(e){let n=e;t?.error({message:`Error building kafka producer: ${n.message}`,error:n,code:`BuildKafkaProducerError`,category:`buildKafkaClient`});return}},buildS3Client=(e,t)=>{try{return new c.S3Client(e)??void 0}catch(e){let n=e;t?.error({message:`Error building s3 client: ${n.message}`,error:n,code:`BuildS3ClientError`,category:`buildS3Client`});return}};var R=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#c=e,this.#l=r,this.#u=a,this.#t=t(o),this.#n=n(i,o),this.#r=o}static async create({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){let s=new OlapClient({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});return await s.initialize(),s}async initialize(){this.#e=await this.#c(this.#l,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#u,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),this.#s=new DatasetsSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#s?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){await this.recordActions([{input:e,result:t}],n)}async recordActions(e,t){let{logs:n,advanced:r,defender:i,datasets:a}=resolveOlapOptions(t);this.#r?.debug({message:`Olap client called to record ${e.length} action(s)`,category:`OlapClient`,context:{options:t,resolvedOptions:{logs:n,advanced:r,defender:i,datasets:a}}});for(let t of e)(0,o.isMissing)(t.input.isBackground)&&(t.input.isBackground=isBackgroundLog(t.input.mode,t.input.sourceType));let s=a?.enabled&&this.#s?this.#s.sendActions(e,a).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to datasets sink: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve(),[c,l]=await Promise.all([r?.enabled&&this.#a?this.#a.sendActions(e,r).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null)),i?.enabled&&this.#o?this.#o.sendActions(e,i).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null))]),u=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:c[t]?.expiresAt,defenderExpiresAt:l[t]?.expiresAt}})),d=n?.enabled&&this.#i?this.#i.sendActions(u,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve();await Promise.all([s,d])}async recordStep(e,t,n){await this.recordSteps([{input:e,result:t}],n)}async recordSteps(e,t){let{logs:n,advanced:r}=resolveOlapOptions(t),i=[];n?.enabled&&this.#i&&i.push(this.#i.sendSteps(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&i.push(this.#a.sendSteps(e,r).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}async recordUnified(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record unified`,category:`OlapClient`,context:{mode:e.mode,requestId:e.requestId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:i}}}),(0,o.isMissing)(e.isBackground)&&(e.isBackground=isBackgroundLog(e.mode,e.sourceType));let a={advancedExpiresAt:(i?.enabled&&this.#a?await this.#a.sendUnified(e,t,i).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):null)?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendUnified(e,t,a,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordProvider(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendProvider(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&a.push(this.#a.sendProvider(e,t,i).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}async getLogs(e,t,n){return this.#r?.debug({message:`Querying logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query logs, returning empty result`,category:`OlapClient`}),{logs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLogs(e,t,n){return this.#r?.debug({message:`Querying action logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getActions({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query action logs, returning empty result`,category:`OlapClient`}),{actionLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLog(e,t,n){let r=await this.#i?.getAction(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve action log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepLogs(e,t,n){return this.#r?.debug({message:`Querying step logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSteps({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query step logs, returning empty result`,category:`OlapClient`}),{stepLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getStepLog(e,t,n,r){let i=await this.#i?.getStep(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedLogs(e,t,n){return this.#r?.debug({message:`Querying unified logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getUnifiedLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query unified logs, returning empty result`,category:`OlapClient`}),{unifiedLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getUnifiedLog(e,t,n){let r=await this.#i?.getUnifiedLog(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve unified log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderLogs(e,t,n){return this.#r?.debug({message:`Querying provider logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getProviderLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query provider logs, returning empty result`,category:`OlapClient`}),{providerLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getProviderLog(e,t,n,r){let i=await this.#i?.getProviderLog(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve provider log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getActionAdvancedLog(e,t,n){let r=await this.#a?.getAction(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve action advanced log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepAdvancedLog(e,t,n,r){let i=await this.#a?.getStep(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedAdvancedLog(e,t,n){let r=await this.#a?.getUnified(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve unified advanced log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderAdvancedLog(e,t,n,r){let i=await this.#a?.getProvider(e,t,n,r);if((0,o.isMissing)(i)){this.#r?.debug({message:`Failed to retrieve provider advanced log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getDefenderLog(e,t,n){let r=await this.#o?.getAction(e,t,n);if((0,o.isMissing)(r)){this.#r?.debug({message:`Failed to retrieve defender log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getLogsStatsAggregate(e,t,n){return this.#r?.debug({message:`Querying logs stats aggregate`,category:`OlapClient`,context:{query:n}}),await this.#i?.getAggregate(e,t,n)??{data:[]}}async getLogsStatsDimensions(e,t,n){return this.#r?.debug({message:`Querying logs stats dimensions`,category:`OlapClient`,context:{query:n}}),await this.#i?.getDimensions(e,t,n)??{}}async getSourceUsage(e,t,n){return this.#r?.debug({message:`Querying source usage`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSourceUsage(e,t,n)??[]}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>R.create({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});var OlapClientManager=class{static{this.olapClientPromise=null}static getInstance({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o,getOlapClient:s=buildOlapClientInstance}={}){return this.olapClientPromise||=s({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}),this.olapClientPromise}static resetInstance(){this.olapClientPromise=null}};exports.Dimension=p,exports.LogType=f,exports.OlapClient=R,exports.OlapClientManager=OlapClientManager;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./chunk-Cfxk5zVN.mjs";import{camelToSnake as t,convertKeysToSnakeCase as n,exceedsSize as r,extractSchema as i,isMissing as a,isString as o,notMissing as s,snakeToCamel as c}from"@stackone/utils";import{CensorType as l,redactFields as u,redactObject as d,redactUrl as f}from"@stackone/redaction";import{GetObjectCommand as p,HeadObjectCommand as m,PutObjectCommand as h,S3Client as g}from"@aws-sdk/client-s3";import{ZodError as _,z as v}from"zod";import y from"node:http";import{HttpClient as b}from"@stackone/transport";const x={Action:`action`,Step:`step`,Unified:`unified`,Provider:`provider`},S={ConnectorKey:`connector_key`,Success:`success`,ActionType:`action_type`,Mode:`mode`,Service:`service`,Resource:`resource`,ActionId:`action_id`,HttpMethod:`http_method`,AccountSecureId:`account_secure_id`,SourceType:`source_type`,StatusCode:`status_code`,OriginOwnerId:`origin_owner_id`,SourceId:`source_id`,IsBackground:`is_background`},C=[`refresh_authentication`,`data_sync`,`test_action`,`webhook_setup`],w=[`TOKEN_REFRESH`,`VALIDATE_CREDENTIALS`,`DATA_SYNC`,`NATIVE_WEBHOOK_SETUP_WORKER`],T=[`data_sync`],E=[`DATA_SYNC`];function isBackgroundLog(e,t){return!!(e&&C.includes(e)||t&&w.includes(t))}function isDataSync(e,t){return!!(e&&T.includes(e)||t&&E.includes(t))}const safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},D=[`x-datadog-parent-id`,`x-datadog-sampling-priority`,`x-datadog-tags`,`x-datadog-trace-id`,`x-forwarded-proto`,`x-forwarded-port`,`x-forwarded-for`,`x-amzn-trace-id`,`traceparent`,`tracestate`,`x-request-nonce`,`x-signing-method`,`x-signature`,`host`,`via`],O=[`application/octet-stream`,`application/pdf`,`application/msword`,`application/vnd.openxmlformats-officedocument.wordprocessingml.document`,`application/vnd.ms-excel`,`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,`application/zip`,`application/x-zip-compressed`],k=[`image/`,`audio/`,`video/`,`application/vnd.`,`binary`],A=10*1024*1024;var AdvancedSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, advanced sink will not function`,category:`AdvancedSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled,errorsOnly:t?.errorsOnly,includeBackground:t?.includeBackground,ttl:t?.ttl}}}),!t?.enabled){this.#t?.debug({message:`Advanced sink is disabled, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(isDataSync(r.mode,r.sourceType)){this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(t.errorsOnly&&i.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${r.mode||`action`}`,category:`AdvancedSink`}),n.push(null);continue}if(isBackgroundLog(r.mode,r.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${r.mode}`,category:`AdvancedSink`}),n.push(null);continue}let e=this.createActionS3(r,i,t?.ttl),a=await this.send(e,t?.ttl);n.push(a)}return n}async sendStep(e,t,n){if(this.#t?.debug({message:`Advanced sink called to send step`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,success:t.success,options:{enabled:n?.enabled,errorsOnly:n?.errorsOnly,includeBackground:n?.includeBackground,ttl:n?.ttl}}}),!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`}),null;if(isDataSync(e.actionMode))return this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending step to advanced sink`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null;if(n.errorsOnly&&e.actionSuccess===!0)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${e.actionMode||`action`}`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.actionMode)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${e.actionMode}`,category:`AdvancedSink`}),null;let r=this.createStepS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send step to advanced sink`,error:t,code:`AdvancedStepWriteError`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null}}async sendSteps(e,t){let n=[];for(let{input:r,result:i}of e){let e=await this.sendStep(r,i,t);n.push(e)}return n}async sendUnified(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending unified to advanced sink`,category:`AdvancedSink`}),null;if(n.errorsOnly&&t.success)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful unified request`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.mode,e.sourceType)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping unified with mode ${e.mode}`,category:`AdvancedSink`}),null;this.#t?.info({message:`Sending unified to advanced sink`,category:`AdvancedSink`});let r=this.createUnifiedS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send unified to advanced sink`,error:t,code:`AdvancedUnifiedWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async sendProvider(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending provider to advanced sink`,category:`AdvancedSink`}),null;this.#t?.info({message:`Sending provider to advanced sink`,category:`AdvancedSink`});let r=this.createProviderS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send provider to advanced sink`,error:t,code:`AdvancedProviderWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new p({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for actionRunId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for actionRunId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for actionRunId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getStep(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get step log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new p({Bucket:i,Key:`${e}/${t}/${n}/steps/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Step log not found in S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting step log from S3 for actionRunId ${n} stepIndex ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getUnified(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get unified log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new p({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get unified log from S3 for requestId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for requestId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for requestId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for requestId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getProvider(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get provider log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new p({Bucket:i,Key:`${e}/${t}/${n}/provider/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Provider log not found in S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting provider log from S3 for requestId ${n} id ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async send(e,t){if(!this.#e)throw Error(`No s3 client available, cannot send to advanced sink`);let n=process.env.ADVANCED_LOGS_BUCKET;if(!n)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);let r=`ttl=30d`;typeof t==`number`&&(t===1?r=`ttl=1d`:t===7&&(r=`ttl=7d`));let i=Math.floor(Date.now()/1e3)+(t??30)*24*60*60,a=new Date(i*1e3);this.#t?.debug({message:`Storing advanced log in S3 bucket ${n} with ttl of ${r}`,category:`AdvancedSink`,context:{bucket:n,key:e.Key,ttlTag:r,expiresAt:a.toISOString()}});try{return await this.#e.send(new h({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:a,Tagging:r})),{expiresAt:a}}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}async getObjectExpiry(e){if(!this.#e)return this.#t?.warning({message:`No s3 client available, cannot check object expiry`,category:`AdvancedSink`}),{exists:!1};let t=process.env.ADVANCED_LOGS_BUCKET;if(!t)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{return{exists:!0,expiresAt:(await this.#e.send(new m({Bucket:t,Key:e}))).Expires}}catch(t){let n=t;if(n.name===`NotFound`||n.$metadata?.httpStatusCode===404)return this.#t?.debug({message:`Object not found in S3 for key ${e}`,category:`AdvancedSink`}),{exists:!1};throw this.#t?.error({message:`Error when checking object expiry in S3 for key ${e}`,error:t,code:`AdvancedLogHeadError`,category:`AdvancedSink`}),t}}async hasAction(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}async hasUnified(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}createActionS3(e,t,n){let r=`${t.organizationId}/${t.projectSecureId}/${t.actionRunId}/${t.actionRunId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeActionResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}createStepS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.actionRunId}/steps/${e.stepIndex}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeStepResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}createUnifiedS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/${e.requestId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeUnifiedResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}createProviderS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/provider/${e.id}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeProviderResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let i=d({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},l.PARTIAL),a=i.req?.headers,o=i.res?.headers,s=u(e.body,l.PARTIAL,!0),c=u(t.body,l.PARTIAL,!0),p=this.processContent(a,s,`upload`),m=this.processContent(o,c,`download`),h=e.isBackground??isBackgroundLog(e.mode,e.sourceType),g=e.url,_={};if(e.url)try{g=f(e.url,l.PARTIAL);let t=new URL(g);_=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in action request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{actionRunId:t.actionRunId,actionId:t.actionId}})}let v={data:{request:{actionRunId:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(a),url:{url:g,path:e.pathParams,queryParams:_},body:p},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:m},...h?{isBackgroundLog:!0}:{}},metadata:{...h?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(v,r)}serializeStepResult(e,t,n,r){let i={data:{actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,input:e.inputs,outputs:t.outputs,errors:t.errors},metadata:{expirationTime:n}};return this.serializeAndLimit(i,r)}serializeUnifiedResult(e,t,n,r){let i=d({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},l.PARTIAL),a=i.req?.headers,o=i.res?.headers,s=u(e.body,l.PARTIAL,!0),c=u(t.body,l.PARTIAL,!0),p=this.processContent(a,s,`upload`),m=this.processContent(o,c,`download`),h=e.isBackground??isBackgroundLog(e.mode,e.sourceType),g=`/`,_=e.url,v={};if(e.url)try{_=f(e.url,l.PARTIAL);let t=new URL(_);g=t.pathname,v=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in unified request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId}})}let y={data:{request:{id:e.requestId,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:_,path:g,queryParams:v},body:p},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:m}},metadata:{...h?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(y,r)}serializeProviderResult(e,t,n,r){let i=d({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},l.PARTIAL),a=i.req?.headers,o=i.res?.headers,s=u(e.body,l.PARTIAL,!0),c=u(t.body,l.PARTIAL,!0),p=this.processContent(a,s,`upload`),m=this.processContent(o,c,`download`),h,g=``,_=`/`,v={};if(e.url)try{h=f(e.url,l.PARTIAL);let t=new URL(h);g=t.hostname,_=t.pathname,v=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in provider request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId,id:e.id}})}let y={data:{request:{id:e.id,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:h,hostname:g,path:_,queryParams:v},body:p},response:{statusCode:t.statusCode,headers:this.filterHeaders(o),body:m}},metadata:{expirationTime:n}};return this.serializeAndLimit(y,r)}serializeAndLimit(e,t){if(r(e,t)){let t={...e,data:{outputs:{error:`Error.TOO_LARGE`}}};return JSON.stringify(t)}return JSON.stringify(e)}filterHeaders(e){if(!e)return;let t={},n=D.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}processContent(e,t,n){let r=this.getContentType(e);if(!r)return this.parseJsonSafely(t);let i=r.toLowerCase().split(`;`)[0].trim();return O.includes(i)||k.some(e=>i.startsWith(e))?{type:`binary`,action:n,contentType:r}:this.parseJsonSafely(t)}parseJsonSafely(e){if(!a(e)){if(!o(e))return e;try{return JSON.parse(e)}catch{return e}}}getContentType(e){if(!e)return;let t=[`content-type`,`contenttype`];return Object.entries(e).find(([e])=>t.includes(e.toLowerCase()))?.[1]?.toString()}},DatasetsSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, datasets sink will not function`,category:`DatasetsSink`});return}}async sendAction(e,t,n){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Datasets sink called to send action`,category:`DatasetsSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Datasets sink is disabled, skipping sending action to datasets sink`,category:`DatasetsSink`});continue}if(a(n.body)&&a(r.body)){this.#t?.debug({message:`No body in action result, skipping sending action to datasets sink`,category:`DatasetsSink`,context:{actionRunId:r.actionRunId}});continue}if(isBackgroundLog(n.mode,n.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Datasets sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`DatasetsSink`});continue}let e=this.createDatasetS3Items(n,r);await this.send(e)}}async send(e){let t=this.#e;if(!t)throw Error(`No s3 client available, cannot send to datasets sink`);let n=process.env.DATASETS_LOGS_BUCKET;if(!n)throw Error(`DATASETS_LOGS_BUCKET environment variable is not set`);let r=Math.floor(Date.now()/1e3)+365*24*60*60,i=new Date(r*1e3),a=`ttl=365d`;this.#t?.debug({message:`Storing datasets log in S3 bucket ${n} with 1-year TTL`,category:`DatasetsSink`,context:{bucket:n,keys:e.map(e=>e.Key),ttlTag:a,expiresAt:i.toISOString()}});try{await Promise.all(e.map(e=>t.send(new h({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:i,Tagging:a}))))}catch(e){throw this.#t?.error({message:`Failed to write dataset logs to S3`,error:e,code:`DatasetLogWriteError`,category:`DatasetsSink`}),e}}generateS3Path(e,t,n){return`${e}/${t}/${n}`}createDatasetS3Items(e,t){let n=t.organizationId,r=t.projectSecureId,i=this.generateS3Path(n,r,t.actionRunId),a=[],o=this.createSchemaLog(e,t);if(s(o)){let e=`${i}/schemas.json`;this.#t?.debug({message:`Extracted schema from action result, storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId,schemas:o.schemas}}),a.push({Key:e,Body:JSON.stringify(o),ContentType:`application/json`})}else this.#t?.debug({message:`No schema extracted from action result, skipping storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId}});return a}createSchemaLog(e,t){let n;s(e.body)&&(n=i(e.body));let r;if(s(t.body)&&(r=i(t.body)),s(n)||s(r)){let e={};return s(n)&&(e.input=n),s(r)&&(e.result=r),{organizationId:t.organizationId,projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,actionId:t.actionId,schemas:e}}}},DefenderSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, defender sink will not function`,category:`DefenderSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),n.push(null);continue}if(a(i.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:i.actionRunId}}),n.push(null);continue}let e=this.createDefenderS3(i),o=await this.send(e);n.push(o)}return n}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from defender sink`,category:`DefenderSink`});return}let r=process.env.DEFENDER_LOGS_BUCKET;if(!r)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);try{let i=new p({Bucket:r,Key:this.generateS3Key(e,t,n)}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`DefenderSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved defender log from S3 for actionRunId ${n}`,category:`DefenderSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Defender log not found in S3 for actionRunId ${n}`,category:`DefenderSink`});return}throw this.#t?.error({message:`Error when getting defender log from S3 for actionRunId ${n}`,error:e,code:`DefenderLogReadError`,category:`DefenderSink`}),e}}async send(e){if(!this.#e)throw Error(`No s3 client available, cannot send to defender sink`);let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);let n=Math.floor(Date.now()/1e3)+365*24*60*60,r=new Date(n*1e3),i=`ttl=365d`;this.#t?.debug({message:`Storing defender log in S3 bucket ${t} with 1-year TTL`,category:`DefenderSink`,context:{bucket:t,key:e.Key,ttlTag:i,expiresAt:r.toISOString()}});try{return await this.#e.send(new h({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:r,Tagging:i})),{expiresAt:r}}catch(t){throw this.#t?.error({message:`Failed to write defender logs to S3 at ${e.Key}`,error:t,code:`DefenderLogWriteError`,category:`DefenderSink`}),t}}generateS3Key(e,t,n){return`${e}/${t}/${n}/defender.json`}createDefenderS3(e){let t=e.organizationId,n=e.projectSecureId;return{Key:this.generateS3Key(t,n,e.actionRunId),Body:JSON.stringify(e.defenderContext),ContentType:`application/json`}}};const hasTimezone=e=>/Z$|[+-]\d{2}:\d{2}$|[+-]\d{4}$/.test(e),utcDateTransform=e=>{if(hasTimezone(e))return e;let t=e.replace(` `,`T`);return new Date(t+`Z`).toISOString()},j=v.preprocess(e=>{if(e instanceof Date)return e;if(typeof e==`string`&&e.length>0)try{return new Date(utcDateTransform(e))}catch(e){throw new v.ZodError([{code:v.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},v.coerce.date()),M=v.object({logType:v.enum([`action`,`step`,`unified`,`provider`]),eventTime:j,startTime:j,endTime:j.optional().nullable().transform(e=>e??void 0),durationMs:v.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:v.coerce.string(),projectSecureId:v.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:v.coerce.string().optional().nullable().transform(e=>e??void 0)}),N=M.extend({logType:v.literal(`action`),actionRunId:v.coerce.string(),actionId:v.coerce.string(),connectorKey:v.coerce.string(),connectorVersion:v.coerce.string(),connectorOwner:v.coerce.string().optional().nullable().transform(e=>e??void 0),connectorProfileId:v.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),actionType:v.coerce.string().optional().nullable().transform(e=>e??void 0),mode:v.coerce.string().optional().nullable().transform(e=>e??void 0),category:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:v.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:v.coerce.string().optional().nullable().transform(e=>e??void 0),url:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:v.coerce.string().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:v.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:v.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:j.optional().nullable().transform(e=>e??void 0),defenderExpiresAt:j.optional().nullable().transform(e=>e??void 0)}),P=M.extend({logType:v.literal(`step`),actionRunId:v.coerce.string(),stepIndex:v.coerce.number(),stepId:v.coerce.string(),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),skipped:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),message:v.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionName:v.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionVersion:v.coerce.string().optional().nullable().transform(e=>e??void 0),stepIterations:v.coerce.number().optional().nullable().transform(e=>e??void 0)}),F=M.extend({logType:v.literal(`unified`),requestId:v.coerce.string(),connectorKey:v.coerce.string(),connectorVersion:v.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),mode:v.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:v.coerce.string().optional().nullable().transform(e=>e??void 0),url:v.coerce.string().optional().nullable().transform(e=>e??void 0),path:v.coerce.string().optional().nullable().transform(e=>e??void 0),resource:v.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),service:v.coerce.string().optional().nullable().transform(e=>e??void 0),action:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:v.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:v.coerce.number().optional().nullable().transform(e=>e??void 0),provider:v.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:j.optional().nullable().transform(e=>e??void 0),duration:v.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:j.optional().nullable().transform(e=>e??void 0)}),I=M.extend({logType:v.literal(`provider`),requestId:v.coerce.string(),id:v.coerce.string().optional().nullable().transform(e=>e??void 0),action:v.coerce.string(),mode:v.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:v.coerce.string(),originOwnerId:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:v.coerce.string().optional().nullable().transform(e=>e??void 0),url:v.coerce.string(),path:v.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:v.coerce.string(),connectorVersion:v.coerce.string().optional().nullable().transform(e=>e??void 0),resource:v.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),service:v.coerce.string().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),status:v.coerce.number().optional().nullable().transform(e=>e??void 0),provider:v.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:j.optional().nullable().transform(e=>e??void 0),duration:v.coerce.number().optional().nullable().transform(e=>e??void 0)}),L=v.discriminatedUnion(`logType`,[N,P,F,I]);var SchemaValidationError=class extends Error{constructor(e,t){super(e),this.name=`SchemaValidationError`,this.cause=t}},TinybirdClient=class{#e;#t;#n;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async query(e){try{let t=await this.#o(e.endpoint,e.params);return this.#a(t.data,e.schema)}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryWithPagination(e){try{let t=await this.#o(e.endpoint,e.params),n=this.#a(t.data,e.schema);return{data:n,total:t.rows_before_limit_at_least??t.rows??n.length,pageNumber:e.pageNumber??1,pageSize:e.pageSize??n.length}}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryRaw(e){try{let t=await this.#o(e.endpoint,e.params);return t.data=this.#a(t.data,e.schema),t}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}isReady(){return!!(this.#e&&this.#t?.token)}#r(){return new y.Agent({})}#i(){if(!this.#e)throw this.#n?.error({message:`HTTP client not initialized, cannot perform Tinybird query`,category:`TinybirdClient`,code:`HttpClientNotReady`}),Error(`HTTP client is not initialized`);if(!this.#t?.token)throw this.#n?.warning({message:`Missing OLAP token, cannot perform Tinybird query`,category:`TinybirdClient`}),Error(`TinybirdClient - Missing token`)}#a(e,t){if(!t)return e;try{let n=e.map(e=>t.parse(e));return this.#n?.debug({message:`Schema validation passed for ${n.length} rows`,category:`TinybirdClient`}),n}catch(e){let t=e instanceof Error?e.message:String(e);throw this.#n?.error({message:`Schema validation failed: ${t}`,category:`TinybirdClient`,code:`SchemaValidationError`,error:e}),new SchemaValidationError(t,e)}}async#o(e,t){this.#i();let n=this.#e,r=this.#t;if(!n||!r)throw Error(`Client validation failed`);let i=new URL(`/v0/pipes/${e}`,r.baseUrl);this.#n?.debug({message:`Querying Tinybird endpoint: ${e}`,category:`TinybirdClient`,context:{endpoint:e,params:t}});let a=await n.request({method:`post`,url:i.toString(),payload:t,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r.token}`},...r.allowHttp&&{httpAgent:this.#r()}});return this.#n?.debug({message:`Tinybird query returned ${a.data.data.length} rows`,category:`TinybirdClient`,context:{endpoint:e,rows:a.data.rows,statistics:a.data.statistics}}),a.data}},LogsSink=class{#e;#t;#n;constructor(e,t,n,r){this.#e=e,this.#n=r,this.#t=new TinybirdClient(t,n,r)}async initialize(){if(!this.#e){this.#n?.warning({message:`No kafka producer provided, logs sink cannot be initialized`,category:`LogsSink`});return}this.#t?.isReady()||this.#n?.warning({message:`Tinybird client is not ready (missing HTTP client or Tinybird config/token), logs sink will not be able to query`,category:`LogsSink`}),this.#n?.info({message:`Logs sink kafka producer initialized`,category:`LogsSink`})}async sendAction(e,t,n,r){await this.sendActions([{input:e,result:t,metadata:n}],r)}async sendActions(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} actions to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t,metadata:n})=>this.buildActionLog(e,t,n));await this.send(`actions`,n)}async sendStep(e,t,n){await this.sendSteps([{input:e,result:t}],n)}async sendSteps(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} steps to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t})=>this.buildStepLog(e,t));await this.send(`steps`,n)}async sendUnified(e,t,n,r){if(!r?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending unified to log sink`,category:`LogsSink`});return}this.#n?.info({message:`Sending unified to log sink (topic: unified_requests)`,category:`LogsSink`});let i=this.buildUnifiedLog(e,t,n);await this.send(`unified_requests`,[i])}async sendProvider(e,t,n){if(!n?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending provider to log sink`,category:`LogsSink`});return}this.#n?.info({message:`Sending provider to log sink (topic: provider_requests)`,category:`LogsSink`});let r=this.buildProviderLog(e,t);await this.send(`provider_requests`,[r])}async getLogs(e){try{this.#n?.info({message:`Querying logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{logs:this.validateLogs(t.data),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getActions(e){try{this.#n?.info({message:`Querying action logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_action_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} action logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{actionLogs:this.validateLogsWithSchema(t.data,N),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for action logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getAction(e,t,n){return(await this.getActions({organizationId:e,projectSecureId:t,actionRunId:n})).actionLogs[0]}async getSteps(e){try{this.#n?.info({message:`Querying step logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_step_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} step logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{stepLogs:this.validateLogsWithSchema(t.data,P),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getStep(e,t,n,r){return(await this.getSteps({organizationId:e,projectSecureId:t,actionRunId:n,stepIndex:r})).stepLogs[0]}async getUnifiedLogs(e){try{this.#n?.info({message:`Querying unified logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_unified_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} unified logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{unifiedLogs:this.validateLogsWithSchema(t.data,F),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for unified logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getUnifiedLog(e,t,n){return(await this.getUnifiedLogs({organizationId:e,projectSecureId:t,requestId:n})).unifiedLogs[0]}async getProviderLogs(e){try{this.#n?.info({message:`Querying provider logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_provider_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} provider logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{providerLogs:this.validateLogsWithSchema(t.data,I),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for provider logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getProviderLog(e,t,n,r){return(await this.getProviderLogs({organizationId:e,projectSecureId:t,requestId:n,id:r})).providerLogs[0]}async getAggregate(e,t,r){try{this.#n?.info({message:`Querying logs stats aggregate from Tinybird`,category:`LogsSink`,context:{query:r}});let{dimensions:i,startTime:a,endTime:o,...s}=r,l={organizationId:e,projectSecureId:t,...s,...i&&i.length>0&&{dimensions:i.map(c).join(`,`)},...a&&{startTime:a.toISOString()},...o&&{endTime:o.toISOString()}},u=await this.#t?.query({endpoint:`project_logs_aggregation.json`,params:l});if(!u)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{data:[]};this.#n?.info({message:`Successfully retrieved ${u.length} aggregated data points from Tinybird`,category:`LogsSink`});let d=u.map(e=>n(e,!0)),f=[`success`,`is_worker`,`is_background`,`skipped`];return{data:d.map(e=>{let t={...e};for(let e of f)e in t&&typeof t[e]==`number`&&(t[e]=t[e]===1);return t})}}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats aggregate, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{data:[]}}}async getDimensions(e,n,r){try{this.#n?.info({message:`Querying logs stats dimensions from Tinybird`,category:`LogsSink`,context:{query:r}});let{dimensions:i,startTime:a,endTime:o,maxValues:s,...l}=r,u={organizationId:e,projectSecureId:n,...l,dimensions:i.map(c).join(`,`),...a&&{startTime:a.toISOString()},...o&&{endTime:o.toISOString()},...s&&{maxValuesPerDim:s}},d=await this.#t?.query({endpoint:`project_logs_dimensions.json`,params:u});if(!d)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{};this.#n?.info({message:`Successfully retrieved ${d.length} dimension facets from Tinybird`,category:`LogsSink`});let f=[`success`,`is_worker`,`is_background`,`skipped`],p={};for(let e of d){let n=t(e.dimension);f.includes(t(e.dimension))?p[n]=e.values.map(e=>({value:e.value===`1`?`true`:e.value===`0`?`false`:e.value,count:e.count})):p[n]=e.values}return p}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats dimensions, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{}}}async getSourceUsage(e,t,n){try{this.#n?.info({message:`Querying logs stats source usage from Tinybird`,category:`LogsSink`,context:{query:n}});let{startTime:r,endTime:i,sourceType:a}=n,o={organizationId:e,projectSecureId:t,...a&&{sourceType:Array.isArray(a)?a.join(`,`):a},...r&&{startTime:r.toISOString()},...i&&{endTime:i.toISOString()}},s=await this.#t?.query({endpoint:`project_source_usage.json`,params:o});return s?(this.#n?.info({message:`Successfully retrieved ${s.length} source usage records from Tinybird`,category:`LogsSink`}),s.map(e=>({sourceId:e.sourceId,sourceType:e.sourceType,requestCount:e.request_count,lastRequest:e.last_request}))):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),[])}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats source usage, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),[]}}async send(e,t){if(!this.#e)throw this.#n?.error({message:`Kafka not initialized, dropping message for topic ${e}`,category:`KafkaSink`,code:`KafkaNotReady`}),Error(`Kafka producer is not initialized`);let n=this.validateLogsBeforeSend(t);if(n.length===0){this.#n?.warning({message:`All ${t.length} log(s) failed validation, nothing to send to topic ${e}`,category:`LogsSink`,code:`AllLogsInvalid`});return}n.length<t.length&&this.#n?.warning({message:`${t.length-n.length} of ${t.length} log(s) failed validation and were dropped`,category:`LogsSink`,code:`SomeLogsInvalid`});let r=Date.now(),i=n.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${i.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:i,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${i.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-r,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${i.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-r,topic:e,messageCount:i.length}}),t}}buildActionLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`action`,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,actionRunId:t.actionRunId,actionId:t.actionId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,...t.connectorOwner&&{connectorOwner:t.connectorOwner},...t.connectorProfileId&&{connectorProfileId:t.connectorProfileId},...i!==void 0&&{durationMs:i},...e.mode&&{mode:e.mode},...t.actionType&&{actionType:t.actionType},...t.category&&{category:t.category},...t.originOwnerId&&{originOwnerId:t.originOwnerId},...t.originOwnerName&&{originOwnerName:t.originOwnerName},...t.httpMethod&&{httpMethod:t.httpMethod},...t.url&&{url:t.url},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.defenderContext?.result?.riskLevel&&{riskLevel:t.defenderContext.result.riskLevel},...t.defenderContext?.result?.tier2Score!==void 0&&{tier2Score:t.defenderContext.result.tier2Score},startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,isBackground:e.isBackground,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt},...n?.defenderExpiresAt&&{defenderExpiresAt:n.defenderExpiresAt}}}buildStepLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:e.startTime??n,organizationId:String(e.organizationId),projectSecureId:String(e.projectSecureId),accountSecureId:String(e.accountSecureId),actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,...t.endTime&&{endTime:t.endTime},...r!==void 0&&{durationMs:r},...t.skipped!==void 0&&{skipped:t.skipped},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.message&&{message:t.message},...e.stepFunctionName&&{stepFunctionName:e.stepFunctionName},...e.stepFunctionVersion&&{stepFunctionVersion:e.stepFunctionVersion},...e.stepIterations!==void 0&&{stepIterations:e.stepIterations}}}buildUnifiedLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`unified`,requestId:e.requestId,connectorKey:e.connectorKey,connectorVersion:`2`,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},...e.mode&&{mode:e.mode},...e.httpMethod&&{httpMethod:e.httpMethod},...e.url&&{url:e.url},...e.path&&{path:e.path},...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...e.action&&{action:e.action},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.success!==void 0&&{success:t.success},isBackground:e.isBackground,durationMs:i,startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:r,duration:i,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt}}}buildProviderLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`provider`,requestId:e.requestId,id:e.id,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},action:e.action,...e.mode&&{mode:e.mode},httpMethod:e.httpMethod,url:e.url,...e.path&&{path:e.path},connectorKey:e.connectorKey,connectorVersion:`2`,...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},durationMs:r,startTime:e.startTime??n,...t.endTime&&{endTime:t.endTime},eventTime:n,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:n,duration:r}}calculateDurationMs(e,t){if(!(e instanceof Date)||!(t instanceof Date))return;let n=e.getTime(),r=t.getTime();if(!(Number.isNaN(n)||Number.isNaN(r)||r<n))return r-n}validateLogsWithSchema(e,t){return e.map(e=>{try{return t.parse(e)}catch(t){if(t instanceof _){let n=`unknown`;if(typeof e==`object`&&e&&`logType`in e){let t=e;n=typeof t.logType==`string`?t.logType:`unknown`}throw this.#n?.error({message:`Failed to validate ${n} log from Tinybird`,category:`LogsSink`,code:`LogParsingTypeError`,context:{validationErrors:t.errors,log:safeSerialize(e)}}),Error(`Tinybird data validation failed for ${n} log: ${t.message}`)}throw t}})}validateLogs(e){return this.validateLogsWithSchema(e,L)}validateLogsBeforeSend(e){let t=[];for(let n of e)try{let e=this.getSchemaForLogType(n.logType).parse(n);t.push(e)}catch(e){e instanceof _?this.#n?.warning({message:`Log validation failed before sending to Tinybird, dropping ${n.logType} log`,category:`LogsSink`,code:`PreWriteValidationFailed`,context:{logType:n.logType,validationErrors:e.errors,log:safeSerialize(n)}}):this.#n?.warning({message:`Unexpected error validating ${n.logType} log before send, dropping log`,category:`LogsSink`,code:`PreWriteValidationError`,error:e})}return t}getSchemaForLogType(e){switch(e){case`action`:return N;case`step`:return P;case`unified`:return F;case`provider`:return I}}};const R={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0},datasets:{enabled:!0,includeBackground:!1}};function resolveOlapOptions(e){return{logs:{...R.logs,...e?.logs},advanced:{...R.advanced,...e?.advanced},defender:{...R.defender,...e?.defender},datasets:{...R.datasets,...e?.datasets}}}const buildHttpClient=e=>{try{return new b({logger:e})}catch(t){let n=t;e?.error({message:`Error building http client: ${n.message}`,error:n,code:`BuildHttpClientError`,category:`buildHttpClient`});return}},buildKafkaClient=async(e,t)=>{if(e)try{let{Producer:t,stringSerializers:n}=await import(`@platformatic/kafka`);return new t({...e,serializers:n})??void 0}catch(e){let n=e;t?.error({message:`Error building kafka producer: ${n.message}`,error:n,code:`BuildKafkaProducerError`,category:`buildKafkaClient`});return}},buildS3Client=(e,t)=>{try{return new g(e)??void 0}catch(e){let n=e;t?.error({message:`Error building s3 client: ${n.message}`,error:n,code:`BuildS3ClientError`,category:`buildS3Client`});return}};var z=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#c=e,this.#l=r,this.#u=a,this.#t=t(o),this.#n=n(i,o),this.#r=o}static async create({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){let s=new OlapClient({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});return await s.initialize(),s}async initialize(){this.#e=await this.#c(this.#l,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#u,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),this.#s=new DatasetsSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#s?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){await this.recordActions([{input:e,result:t}],n)}async recordActions(e,t){let{logs:n,advanced:r,defender:i,datasets:o}=resolveOlapOptions(t);this.#r?.debug({message:`Olap client called to record ${e.length} action(s)`,category:`OlapClient`,context:{options:t,resolvedOptions:{logs:n,advanced:r,defender:i,datasets:o}}});for(let t of e)a(t.input.isBackground)&&(t.input.isBackground=isBackgroundLog(t.input.mode,t.input.sourceType));let s=o?.enabled&&this.#s?this.#s.sendActions(e,o).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to datasets sink: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve(),[c,l]=await Promise.all([r?.enabled&&this.#a?this.#a.sendActions(e,r).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null)),i?.enabled&&this.#o?this.#o.sendActions(e,i).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null))]),u=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:c[t]?.expiresAt,defenderExpiresAt:l[t]?.expiresAt}})),d=n?.enabled&&this.#i?this.#i.sendActions(u,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve();await Promise.all([s,d])}async recordStep(e,t,n){await this.recordSteps([{input:e,result:t}],n)}async recordSteps(e,t){let{logs:n,advanced:r}=resolveOlapOptions(t),i=[];n?.enabled&&this.#i&&i.push(this.#i.sendSteps(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&i.push(this.#a.sendSteps(e,r).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}async recordUnified(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record unified`,category:`OlapClient`,context:{mode:e.mode,requestId:e.requestId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:i}}}),a(e.isBackground)&&(e.isBackground=isBackgroundLog(e.mode,e.sourceType));let o={advancedExpiresAt:(i?.enabled&&this.#a?await this.#a.sendUnified(e,t,i).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):null)?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendUnified(e,t,o,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordProvider(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendProvider(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&a.push(this.#a.sendProvider(e,t,i).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}async getLogs(e,t,n){return this.#r?.debug({message:`Querying logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query logs, returning empty result`,category:`OlapClient`}),{logs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLogs(e,t,n){return this.#r?.debug({message:`Querying action logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getActions({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query action logs, returning empty result`,category:`OlapClient`}),{actionLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLog(e,t,n){let r=await this.#i?.getAction(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve action log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepLogs(e,t,n){return this.#r?.debug({message:`Querying step logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSteps({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query step logs, returning empty result`,category:`OlapClient`}),{stepLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getStepLog(e,t,n,r){let i=await this.#i?.getStep(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedLogs(e,t,n){return this.#r?.debug({message:`Querying unified logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getUnifiedLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query unified logs, returning empty result`,category:`OlapClient`}),{unifiedLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getUnifiedLog(e,t,n){let r=await this.#i?.getUnifiedLog(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve unified log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderLogs(e,t,n){return this.#r?.debug({message:`Querying provider logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getProviderLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query provider logs, returning empty result`,category:`OlapClient`}),{providerLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getProviderLog(e,t,n,r){let i=await this.#i?.getProviderLog(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve provider log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getActionAdvancedLog(e,t,n){let r=await this.#a?.getAction(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve action advanced log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepAdvancedLog(e,t,n,r){let i=await this.#a?.getStep(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedAdvancedLog(e,t,n){let r=await this.#a?.getUnified(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve unified advanced log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderAdvancedLog(e,t,n,r){let i=await this.#a?.getProvider(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve provider advanced log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getDefenderLog(e,t,n){let r=await this.#o?.getAction(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve defender log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getLogsStatsAggregate(e,t,n){return this.#r?.debug({message:`Querying logs stats aggregate`,category:`OlapClient`,context:{query:n}}),await this.#i?.getAggregate(e,t,n)??{data:[]}}async getLogsStatsDimensions(e,t,n){return this.#r?.debug({message:`Querying logs stats dimensions`,category:`OlapClient`,context:{query:n}}),await this.#i?.getDimensions(e,t,n)??{}}async getSourceUsage(e,t,n){return this.#r?.debug({message:`Querying source usage`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSourceUsage(e,t,n)??[]}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>z.create({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});var OlapClientManager=class{static{this.olapClientPromise=null}static getInstance({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o,getOlapClient:s=buildOlapClientInstance}={}){return this.olapClientPromise||=s({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}),this.olapClientPromise}static resetInstance(){this.olapClientPromise=null}};export{S as Dimension,x as LogType,z as OlapClient,OlapClientManager};
1
+ import{t as e}from"./chunk-Cfxk5zVN.mjs";import{camelToSnake as t,convertKeysToSnakeCase as n,exceedsSize as r,extractSchema as i,isMissing as a,isString as o,notMissing as s,snakeToCamel as c}from"@stackone/utils";import{CensorType as l,redactFields as u,redactObject as d,redactUrl as f}from"@stackone/redaction";import{GetObjectCommand as p,HeadObjectCommand as m,PutObjectCommand as h,S3Client as g}from"@aws-sdk/client-s3";import{ZodError as _,z as v}from"zod";import y from"node:http";import{HttpClient as b}from"@stackone/transport";const x={Action:`action`,Step:`step`,Unified:`unified`,Provider:`provider`},S={ConnectorKey:`connector_key`,Success:`success`,ActionType:`action_type`,Mode:`mode`,Service:`service`,Resource:`resource`,ActionId:`action_id`,HttpMethod:`http_method`,AccountSecureId:`account_secure_id`,SourceType:`source_type`,StatusCode:`status_code`,OriginOwnerId:`origin_owner_id`,SourceId:`source_id`,IsBackground:`is_background`},C=[`refresh_authentication`,`data_sync`,`test_action`,`webhook_setup`],w=[`TOKEN_REFRESH`,`VALIDATE_CREDENTIALS`,`DATA_SYNC`,`NATIVE_WEBHOOK_SETUP_WORKER`],T=[`data_sync`],E=[`DATA_SYNC`];function isBackgroundLog(e,t){return!!(e&&C.includes(e)||t&&w.includes(t))}function isDataSync(e,t){return!!(e&&T.includes(e)||t&&E.includes(t))}const safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},D=[`x-datadog-parent-id`,`x-datadog-sampling-priority`,`x-datadog-tags`,`x-datadog-trace-id`,`x-forwarded-proto`,`x-forwarded-port`,`x-forwarded-for`,`x-amzn-trace-id`,`traceparent`,`tracestate`,`x-request-nonce`,`x-signing-method`,`x-signature`,`host`,`via`],O=[`application/octet-stream`,`application/pdf`,`application/msword`,`application/vnd.openxmlformats-officedocument.wordprocessingml.document`,`application/vnd.ms-excel`,`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`,`application/zip`,`application/x-zip-compressed`],k=[`image/`,`audio/`,`video/`,`application/vnd.`,`binary`],A=10*1024*1024;var AdvancedSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, advanced sink will not function`,category:`AdvancedSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled,errorsOnly:t?.errorsOnly,includeBackground:t?.includeBackground,ttl:t?.ttl}}}),!t?.enabled){this.#t?.debug({message:`Advanced sink is disabled, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(isDataSync(r.mode,r.sourceType)){this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending action to advanced sink`,category:`AdvancedSink`}),n.push(null);continue}if(t.errorsOnly&&i.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${r.mode||`action`}`,category:`AdvancedSink`}),n.push(null);continue}if(isBackgroundLog(r.mode,r.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${r.mode}`,category:`AdvancedSink`}),n.push(null);continue}let e=this.createActionS3(r,i,t?.ttl),a=await this.send(e,t?.ttl);n.push(a)}return n}async sendStep(e,t,n){if(this.#t?.debug({message:`Advanced sink called to send step`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,success:t.success,options:{enabled:n?.enabled,errorsOnly:n?.errorsOnly,includeBackground:n?.includeBackground,ttl:n?.ttl}}}),!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`}),null;if(isDataSync(e.actionMode))return this.#t?.debug({message:`Advanced sink does not record data sync, skipping sending step to advanced sink`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null;if(n.errorsOnly&&e.actionSuccess===!0)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${e.actionMode||`action`}`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.actionMode)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${e.actionMode}`,category:`AdvancedSink`}),null;let r=this.createStepS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send step to advanced sink`,error:t,code:`AdvancedStepWriteError`,category:`AdvancedSink`,context:{actionRunId:e.actionRunId,stepIndex:e.stepIndex}}),null}}async sendSteps(e,t){let n=[];for(let{input:r,result:i}of e){let e=await this.sendStep(r,i,t);n.push(e)}return n}async sendUnified(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending unified to advanced sink`,category:`AdvancedSink`}),null;if(n.errorsOnly&&t.success)return this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful unified request`,category:`AdvancedSink`}),null;if(isBackgroundLog(e.mode,e.sourceType)&&!n.includeBackground)return this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping unified with mode ${e.mode}`,category:`AdvancedSink`}),null;this.#t?.debug({message:`Sending unified to advanced sink`,category:`AdvancedSink`});let r=this.createUnifiedS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send unified to advanced sink`,error:t,code:`AdvancedUnifiedWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async sendProvider(e,t,n){if(!n?.enabled)return this.#t?.debug({message:`Advanced sink is disabled, skipping sending provider to advanced sink`,category:`AdvancedSink`}),null;this.#t?.debug({message:`Sending provider to advanced sink`,category:`AdvancedSink`});let r=this.createProviderS3(e,t,n?.ttl);try{return await this.send(r,n?.ttl)}catch(t){return this.#t?.error({message:`Failed to send provider to advanced sink`,error:t,code:`AdvancedProviderWriteError`,category:`AdvancedSink`,context:{requestId:e.requestId}}),null}}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new p({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for actionRunId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for actionRunId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for actionRunId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getStep(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get step log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new p({Bucket:i,Key:`${e}/${t}/${n}/steps/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Step log not found in S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting step log from S3 for actionRunId ${n} stepIndex ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getUnified(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get unified log from advanced sink`,category:`AdvancedSink`});return}let r=process.env.ADVANCED_LOGS_BUCKET;if(!r)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let i=new p({Bucket:r,Key:`${e}/${t}/${n}/${n}.json`}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get unified log from S3 for requestId ${n}`,category:`AdvancedSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for requestId ${n}`,category:`AdvancedSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Advanced log not found in S3 for requestId ${n}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting advanced log from S3 for requestId ${n}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async getProvider(e,t,n,r){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get provider log from advanced sink`,category:`AdvancedSink`});return}let i=process.env.ADVANCED_LOGS_BUCKET;if(!i)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{let a=new p({Bucket:i,Key:`${e}/${t}/${n}/provider/${r}.json`}),o=await this.#e.send(a);if(!o.Body){this.#t?.warning({message:`Received empty body when trying to get provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}let s=await o.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved provider log from S3 for requestId ${n} id ${r}`,category:`AdvancedSink`}),JSON.parse(s)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Provider log not found in S3 for requestId ${n} id ${r}`,category:`AdvancedSink`});return}throw this.#t?.error({message:`Error when getting provider log from S3 for requestId ${n} id ${r}`,error:e,code:`AdvancedLogReadError`,category:`AdvancedSink`}),e}}async send(e,t){if(!this.#e)throw Error(`No s3 client available, cannot send to advanced sink`);let n=process.env.ADVANCED_LOGS_BUCKET;if(!n)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);let r=`ttl=30d`;typeof t==`number`&&(t===1?r=`ttl=1d`:t===7&&(r=`ttl=7d`));let i=Math.floor(Date.now()/1e3)+(t??30)*24*60*60,a=new Date(i*1e3);this.#t?.debug({message:`Storing advanced log in S3 bucket ${n} with ttl of ${r}`,category:`AdvancedSink`,context:{bucket:n,key:e.Key,ttlTag:r,expiresAt:a.toISOString()}});try{return await this.#e.send(new h({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:a,Tagging:r})),{expiresAt:a}}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}async getObjectExpiry(e){if(!this.#e)return this.#t?.warning({message:`No s3 client available, cannot check object expiry`,category:`AdvancedSink`}),{exists:!1};let t=process.env.ADVANCED_LOGS_BUCKET;if(!t)throw Error(`ADVANCED_LOGS_BUCKET environment variable is not set`);try{return{exists:!0,expiresAt:(await this.#e.send(new m({Bucket:t,Key:e}))).Expires}}catch(t){let n=t;if(n.name===`NotFound`||n.$metadata?.httpStatusCode===404)return this.#t?.debug({message:`Object not found in S3 for key ${e}`,category:`AdvancedSink`}),{exists:!1};throw this.#t?.error({message:`Error when checking object expiry in S3 for key ${e}`,error:t,code:`AdvancedLogHeadError`,category:`AdvancedSink`}),t}}async hasAction(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}async hasUnified(e,t,n){let r=`${e}/${t}/${n}/${n}.json`;return this.getObjectExpiry(r)}createActionS3(e,t,n){let r=`${t.organizationId}/${t.projectSecureId}/${t.actionRunId}/${t.actionRunId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeActionResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}createStepS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.actionRunId}/steps/${e.stepIndex}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeStepResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}createUnifiedS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/${e.requestId}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeUnifiedResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}createProviderS3(e,t,n){let r=`${e.organizationId}/${e.projectSecureId}/${e.requestId}/provider/${e.id}.json`,i=Math.floor(Date.now()/1e3)+(n??30)*24*60*60;return{Key:r,Body:this.serializeProviderResult(e,t,i,A),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let i=d({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},l.PARTIAL),a=i.req?.headers,o=i.res?.headers,s=u(e.body,l.PARTIAL,!0),c=u(t.body,l.PARTIAL,!0),p=this.processContent(a,s,`upload`),m=this.processContent(o,c,`download`),h=e.isBackground??isBackgroundLog(e.mode,e.sourceType),g=e.url,_={};if(e.url)try{g=f(e.url,l.PARTIAL);let t=new URL(g);_=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in action request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{actionRunId:t.actionRunId,actionId:t.actionId}})}let v={data:{request:{actionRunId:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(a),url:{url:g,path:e.pathParams,queryParams:_},body:p},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:m},...h?{isBackgroundLog:!0}:{}},metadata:{...h?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(v,r)}serializeStepResult(e,t,n,r){let i={data:{actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,input:e.inputs,outputs:t.outputs,errors:t.errors},metadata:{expirationTime:n}};return this.serializeAndLimit(i,r)}serializeUnifiedResult(e,t,n,r){let i=d({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},l.PARTIAL),a=i.req?.headers,o=i.res?.headers,s=u(e.body,l.PARTIAL,!0),c=u(t.body,l.PARTIAL,!0),p=this.processContent(a,s,`upload`),m=this.processContent(o,c,`download`),h=e.isBackground??isBackgroundLog(e.mode,e.sourceType),g=`/`,_=e.url,v={};if(e.url)try{_=f(e.url,l.PARTIAL);let t=new URL(_);g=t.pathname,v=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in unified request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId}})}let y={data:{request:{id:e.requestId,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:_,path:g,queryParams:v},body:p},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:m}},metadata:{...h?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(y,r)}serializeProviderResult(e,t,n,r){let i=d({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},l.PARTIAL),a=i.req?.headers,o=i.res?.headers,s=u(e.body,l.PARTIAL,!0),c=u(t.body,l.PARTIAL,!0),p=this.processContent(a,s,`upload`),m=this.processContent(o,c,`download`),h,g=``,_=`/`,v={};if(e.url)try{h=f(e.url,l.PARTIAL);let t=new URL(h);g=t.hostname,_=t.pathname,v=Object.fromEntries(t.searchParams)}catch{this.#t?.warning({message:`Invalid URL in provider request, using fallback values`,category:`AdvancedSink`,code:`InvalidUrl`,context:{requestId:e.requestId,id:e.id}})}let y={data:{request:{id:e.id,method:e.httpMethod,headers:this.filterHeaders(a),url:{url:h,hostname:g,path:_,queryParams:v},body:p},response:{statusCode:t.statusCode,headers:this.filterHeaders(o),body:m}},metadata:{expirationTime:n}};return this.serializeAndLimit(y,r)}serializeAndLimit(e,t){if(r(e,t)){let t={...e,data:{outputs:{error:`Error.TOO_LARGE`}}};return JSON.stringify(t)}return JSON.stringify(e)}filterHeaders(e){if(!e)return;let t={},n=D.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}processContent(e,t,n){let r=this.getContentType(e);if(!r)return this.parseJsonSafely(t);let i=r.toLowerCase().split(`;`)[0].trim();return O.includes(i)||k.some(e=>i.startsWith(e))?{type:`binary`,action:n,contentType:r}:this.parseJsonSafely(t)}parseJsonSafely(e){if(!a(e)){if(!o(e))return e;try{return JSON.parse(e)}catch{return e}}}getContentType(e){if(!e)return;let t=[`content-type`,`contenttype`];return Object.entries(e).find(([e])=>t.includes(e.toLowerCase()))?.[1]?.toString()}},DatasetsSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, datasets sink will not function`,category:`DatasetsSink`});return}}async sendAction(e,t,n){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Datasets sink called to send action`,category:`DatasetsSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Datasets sink is disabled, skipping sending action to datasets sink`,category:`DatasetsSink`});continue}if(a(n.body)&&a(r.body)){this.#t?.debug({message:`No body in action result, skipping sending action to datasets sink`,category:`DatasetsSink`,context:{actionRunId:r.actionRunId}});continue}if(isBackgroundLog(n.mode,n.sourceType)&&!t.includeBackground){this.#t?.debug({message:`Datasets sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`DatasetsSink`});continue}let e=this.createDatasetS3Items(n,r);await this.send(e)}}async send(e){let t=this.#e;if(!t)throw Error(`No s3 client available, cannot send to datasets sink`);let n=process.env.DATASETS_LOGS_BUCKET;if(!n)throw Error(`DATASETS_LOGS_BUCKET environment variable is not set`);let r=Math.floor(Date.now()/1e3)+365*24*60*60,i=new Date(r*1e3),a=`ttl=365d`;this.#t?.debug({message:`Storing datasets log in S3 bucket ${n} with 1-year TTL`,category:`DatasetsSink`,context:{bucket:n,keys:e.map(e=>e.Key),ttlTag:a,expiresAt:i.toISOString()}});try{await Promise.all(e.map(e=>t.send(new h({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:i,Tagging:a}))))}catch(e){throw this.#t?.error({message:`Failed to write dataset logs to S3`,error:e,code:`DatasetLogWriteError`,category:`DatasetsSink`}),e}}generateS3Path(e,t,n){return`${e}/${t}/${n}`}createDatasetS3Items(e,t){let n=t.organizationId,r=t.projectSecureId,i=this.generateS3Path(n,r,t.actionRunId),a=[],o=this.createSchemaLog(e,t);if(s(o)){let e=`${i}/schemas.json`;this.#t?.debug({message:`Extracted schema from action result, storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId,schemas:o.schemas}}),a.push({Key:e,Body:JSON.stringify(o),ContentType:`application/json`})}else this.#t?.debug({message:`No schema extracted from action result, skipping storing schema log in datasets sink`,category:`DatasetsSink`,context:{actionRunId:t.actionRunId}});return a}createSchemaLog(e,t){let n;s(e.body)&&(n=i(e.body));let r;if(s(t.body)&&(r=i(t.body)),s(n)||s(r)){let e={};return s(n)&&(e.input=n),s(r)&&(e.result=r),{organizationId:t.organizationId,projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,actionId:t.actionId,schemas:e}}}},DefenderSink=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}async initialize(){if(!this.#e){this.#t?.warning({message:`No s3 client provided, defender sink will not function`,category:`DefenderSink`});return}}async sendAction(e,t,n){return(await this.sendActions([{input:e,result:t}],n))[0]??null}async sendActions(e,t){let n=[];for(let{input:r,result:i}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:i.actionRunId,success:i.success,statusCode:i.statusCode,options:{enabled:t?.enabled}}}),!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),n.push(null);continue}if(a(i.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:i.actionRunId}}),n.push(null);continue}let e=this.createDefenderS3(i),o=await this.send(e);n.push(o)}return n}async getAction(e,t,n){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot get action log from defender sink`,category:`DefenderSink`});return}let r=process.env.DEFENDER_LOGS_BUCKET;if(!r)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);try{let i=new p({Bucket:r,Key:this.generateS3Key(e,t,n)}),a=await this.#e.send(i);if(!a.Body){this.#t?.warning({message:`Received empty body when trying to get action log from S3 for actionRunId ${n}`,category:`DefenderSink`});return}let o=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved defender log from S3 for actionRunId ${n}`,category:`DefenderSink`}),JSON.parse(o)}catch(e){let t=e;if(t.name===`NoSuchKey`||t.$metadata?.httpStatusCode===404){this.#t?.debug({message:`Defender log not found in S3 for actionRunId ${n}`,category:`DefenderSink`});return}throw this.#t?.error({message:`Error when getting defender log from S3 for actionRunId ${n}`,error:e,code:`DefenderLogReadError`,category:`DefenderSink`}),e}}async send(e){if(!this.#e)throw Error(`No s3 client available, cannot send to defender sink`);let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);let n=Math.floor(Date.now()/1e3)+365*24*60*60,r=new Date(n*1e3),i=`ttl=365d`;this.#t?.debug({message:`Storing defender log in S3 bucket ${t} with 1-year TTL`,category:`DefenderSink`,context:{bucket:t,key:e.Key,ttlTag:i,expiresAt:r.toISOString()}});try{return await this.#e.send(new h({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:r,Tagging:i})),{expiresAt:r}}catch(t){throw this.#t?.error({message:`Failed to write defender logs to S3 at ${e.Key}`,error:t,code:`DefenderLogWriteError`,category:`DefenderSink`}),t}}generateS3Key(e,t,n){return`${e}/${t}/${n}/defender.json`}createDefenderS3(e){let t=e.organizationId,n=e.projectSecureId;return{Key:this.generateS3Key(t,n,e.actionRunId),Body:JSON.stringify(e.defenderContext),ContentType:`application/json`}}};const hasTimezone=e=>/Z$|[+-]\d{2}:\d{2}$|[+-]\d{4}$/.test(e),utcDateTransform=e=>{if(hasTimezone(e))return e;let t=e.replace(` `,`T`);return new Date(t+`Z`).toISOString()},j=v.preprocess(e=>{if(e instanceof Date)return e;if(typeof e==`string`&&e.length>0)try{return new Date(utcDateTransform(e))}catch(e){throw new v.ZodError([{code:v.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},v.coerce.date()),M=v.object({logType:v.enum([`action`,`step`,`unified`,`provider`]),eventTime:j,startTime:j,endTime:j.optional().nullable().transform(e=>e??void 0),durationMs:v.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:v.coerce.string(),projectSecureId:v.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:v.coerce.string().optional().nullable().transform(e=>e??void 0)}),N=M.extend({logType:v.literal(`action`),actionRunId:v.coerce.string(),actionId:v.coerce.string(),connectorKey:v.coerce.string(),connectorVersion:v.coerce.string(),connectorOwner:v.coerce.string().optional().nullable().transform(e=>e??void 0),connectorProfileId:v.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),actionType:v.coerce.string().optional().nullable().transform(e=>e??void 0),mode:v.coerce.string().optional().nullable().transform(e=>e??void 0),category:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:v.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:v.coerce.string().optional().nullable().transform(e=>e??void 0),url:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:v.coerce.string().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:v.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:v.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:j.optional().nullable().transform(e=>e??void 0),defenderExpiresAt:j.optional().nullable().transform(e=>e??void 0)}),P=M.extend({logType:v.literal(`step`),actionRunId:v.coerce.string(),stepIndex:v.coerce.number(),stepId:v.coerce.string(),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),skipped:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),message:v.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionName:v.coerce.string().optional().nullable().transform(e=>e??void 0),stepFunctionVersion:v.coerce.string().optional().nullable().transform(e=>e??void 0),stepIterations:v.coerce.number().optional().nullable().transform(e=>e??void 0)}),F=M.extend({logType:v.literal(`unified`),requestId:v.coerce.string(),connectorKey:v.coerce.string(),connectorVersion:v.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),mode:v.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:v.coerce.string().optional().nullable().transform(e=>e??void 0),url:v.coerce.string().optional().nullable().transform(e=>e??void 0),path:v.coerce.string().optional().nullable().transform(e=>e??void 0),resource:v.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),service:v.coerce.string().optional().nullable().transform(e=>e??void 0),action:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:v.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:v.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:v.coerce.number().optional().nullable().transform(e=>e??void 0),provider:v.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:j.optional().nullable().transform(e=>e??void 0),duration:v.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:j.optional().nullable().transform(e=>e??void 0)}),I=M.extend({logType:v.literal(`provider`),requestId:v.coerce.string(),id:v.coerce.string().optional().nullable().transform(e=>e??void 0),action:v.coerce.string(),mode:v.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:v.coerce.string(),originOwnerId:v.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:v.coerce.string().optional().nullable().transform(e=>e??void 0),url:v.coerce.string(),path:v.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:v.coerce.string(),connectorVersion:v.coerce.string().optional().nullable().transform(e=>e??void 0),resource:v.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:v.coerce.string().optional().nullable().transform(e=>e??void 0),service:v.coerce.string().optional().nullable().transform(e=>e??void 0),success:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:v.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:v.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:v.coerce.string(),accountSecureId:v.coerce.string(),status:v.coerce.number().optional().nullable().transform(e=>e??void 0),provider:v.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:j.optional().nullable().transform(e=>e??void 0),duration:v.coerce.number().optional().nullable().transform(e=>e??void 0)}),L=v.discriminatedUnion(`logType`,[N,P,F,I]);var SchemaValidationError=class extends Error{constructor(e,t){super(e),this.name=`SchemaValidationError`,this.cause=t}},TinybirdClient=class{#e;#t;#n;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async query(e){try{let t=await this.#o(e.endpoint,e.params);return this.#a(t.data,e.schema)}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryWithPagination(e){try{let t=await this.#o(e.endpoint,e.params),n=this.#a(t.data,e.schema);return{data:n,total:t.rows_before_limit_at_least??t.rows??n.length,pageNumber:e.pageNumber??1,pageSize:e.pageSize??n.length}}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryRaw(e){try{let t=await this.#o(e.endpoint,e.params);return t.data=this.#a(t.data,e.schema),t}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}isReady(){return!!(this.#e&&this.#t?.token)}#r(){return new y.Agent({})}#i(){if(!this.#e)throw this.#n?.error({message:`HTTP client not initialized, cannot perform Tinybird query`,category:`TinybirdClient`,code:`HttpClientNotReady`}),Error(`HTTP client is not initialized`);if(!this.#t?.token)throw this.#n?.warning({message:`Missing OLAP token, cannot perform Tinybird query`,category:`TinybirdClient`}),Error(`TinybirdClient - Missing token`)}#a(e,t){if(!t)return e;try{let n=e.map(e=>t.parse(e));return this.#n?.debug({message:`Schema validation passed for ${n.length} rows`,category:`TinybirdClient`}),n}catch(e){let t=e instanceof Error?e.message:String(e);throw this.#n?.error({message:`Schema validation failed: ${t}`,category:`TinybirdClient`,code:`SchemaValidationError`,error:e}),new SchemaValidationError(t,e)}}async#o(e,t){this.#i();let n=this.#e,r=this.#t;if(!n||!r)throw Error(`Client validation failed`);let i=new URL(`/v0/pipes/${e}`,r.baseUrl);this.#n?.debug({message:`Querying Tinybird endpoint: ${e}`,category:`TinybirdClient`,context:{endpoint:e,params:t}});let a=await n.request({method:`post`,url:i.toString(),payload:t,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r.token}`},...r.allowHttp&&{httpAgent:this.#r()}});return this.#n?.debug({message:`Tinybird query returned ${a.data.data.length} rows`,category:`TinybirdClient`,context:{endpoint:e,rows:a.data.rows,statistics:a.data.statistics}}),a.data}},LogsSink=class{#e;#t;#n;constructor(e,t,n,r){this.#e=e,this.#n=r,this.#t=new TinybirdClient(t,n,r)}async initialize(){if(!this.#e){this.#n?.warning({message:`No kafka producer provided, logs sink cannot be initialized`,category:`LogsSink`});return}this.#t?.isReady()||this.#n?.warning({message:`Tinybird client is not ready (missing HTTP client or Tinybird config/token), logs sink will not be able to query`,category:`LogsSink`}),this.#n?.info({message:`Logs sink kafka producer initialized`,category:`LogsSink`})}async sendAction(e,t,n,r){await this.sendActions([{input:e,result:t,metadata:n}],r)}async sendActions(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} actions to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t,metadata:n})=>this.buildActionLog(e,t,n));await this.send(`actions`,n)}async sendStep(e,t,n){await this.sendSteps([{input:e,result:t}],n)}async sendSteps(e,t){if(!t?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending ${e.length} steps to log sink`,category:`LogsSink`});return}if(e.length===0)return;let n=e.map(({input:e,result:t})=>this.buildStepLog(e,t));await this.send(`steps`,n)}async sendUnified(e,t,n,r){if(!r?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending unified to log sink`,category:`LogsSink`});return}this.#n?.debug({message:`Sending unified to log sink (topic: unified_requests)`,category:`LogsSink`});let i=this.buildUnifiedLog(e,t,n);await this.send(`unified_requests`,[i])}async sendProvider(e,t,n){if(!n?.enabled){this.#n?.debug({message:`Logs sink is disabled, skipping sending provider to log sink`,category:`LogsSink`});return}this.#n?.debug({message:`Sending provider to log sink (topic: provider_requests)`,category:`LogsSink`});let r=this.buildProviderLog(e,t);await this.send(`provider_requests`,[r])}async getLogs(e){try{this.#n?.info({message:`Querying logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{logs:this.validateLogs(t.data),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{logs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getActions(e){try{this.#n?.info({message:`Querying action logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_action_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} action logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{actionLogs:this.validateLogsWithSchema(t.data,N),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for action logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{actionLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getAction(e,t,n){return(await this.getActions({organizationId:e,projectSecureId:t,actionRunId:n})).actionLogs[0]}async getSteps(e){try{this.#n?.info({message:`Querying step logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_step_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} step logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{stepLogs:this.validateLogsWithSchema(t.data,P),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{stepLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getStep(e,t,n,r){return(await this.getSteps({organizationId:e,projectSecureId:t,actionRunId:n,stepIndex:r})).stepLogs[0]}async getUnifiedLogs(e){try{this.#n?.info({message:`Querying unified logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_unified_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} unified logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{unifiedLogs:this.validateLogsWithSchema(t.data,F),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for unified logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{unifiedLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getUnifiedLog(e,t,n){return(await this.getUnifiedLogs({organizationId:e,projectSecureId:t,requestId:n})).unifiedLogs[0]}async getProviderLogs(e){try{this.#n?.info({message:`Querying provider logs from Tinybird`,category:`LogsSink`,context:{query:e}});let t=await this.#t?.queryWithPagination({endpoint:`project_provider_logs.json`,params:e,pageNumber:e.pageNumber,pageSize:e.pageSize});return t?(this.#n?.info({message:`Successfully retrieved ${t.data.length} provider logs from Tinybird (${t.total} total)`,category:`LogsSink`}),{providerLogs:this.validateLogsWithSchema(t.data,I),total:t.total,pageNumber:t.pageNumber,pageSize:t.pageSize}):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0})}catch(t){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for provider logs, returning empty results`,category:`LogsSink`,error:t}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:t}),{providerLogs:[],total:0,pageNumber:e.pageNumber??1,pageSize:e.pageSize??0}}}async getProviderLog(e,t,n,r){return(await this.getProviderLogs({organizationId:e,projectSecureId:t,requestId:n,id:r})).providerLogs[0]}async getAggregate(e,t,r){try{this.#n?.info({message:`Querying logs stats aggregate from Tinybird`,category:`LogsSink`,context:{query:r}});let{dimensions:i,startTime:a,endTime:o,...s}=r,l={organizationId:e,projectSecureId:t,...s,...i&&i.length>0&&{dimensions:i.map(c).join(`,`)},...a&&{startTime:a.toISOString()},...o&&{endTime:o.toISOString()}},u=await this.#t?.query({endpoint:`project_logs_aggregation.json`,params:l});if(!u)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{data:[]};this.#n?.info({message:`Successfully retrieved ${u.length} aggregated data points from Tinybird`,category:`LogsSink`});let d=u.map(e=>n(e,!0)),f=[`success`,`is_worker`,`is_background`,`skipped`];return{data:d.map(e=>{let t={...e};for(let e of f)e in t&&typeof t[e]==`number`&&(t[e]=t[e]===1);return t})}}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats aggregate, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{data:[]}}}async getDimensions(e,n,r){try{this.#n?.info({message:`Querying logs stats dimensions from Tinybird`,category:`LogsSink`,context:{query:r}});let{dimensions:i,startTime:a,endTime:o,maxValues:s,...l}=r,u={organizationId:e,projectSecureId:n,...l,dimensions:i.map(c).join(`,`),...a&&{startTime:a.toISOString()},...o&&{endTime:o.toISOString()},...s&&{maxValuesPerDim:s}},d=await this.#t?.query({endpoint:`project_logs_dimensions.json`,params:u});if(!d)return this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),{};this.#n?.info({message:`Successfully retrieved ${d.length} dimension facets from Tinybird`,category:`LogsSink`});let f=[`success`,`is_worker`,`is_background`,`skipped`],p={};for(let e of d){let n=t(e.dimension);f.includes(t(e.dimension))?p[n]=e.values.map(e=>({value:e.value===`1`?`true`:e.value===`0`?`false`:e.value,count:e.count})):p[n]=e.values}return p}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats dimensions, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),{}}}async getSourceUsage(e,t,n){try{this.#n?.info({message:`Querying logs stats source usage from Tinybird`,category:`LogsSink`,context:{query:n}});let{startTime:r,endTime:i,sourceType:a}=n,o={organizationId:e,projectSecureId:t,...a&&{sourceType:Array.isArray(a)?a.join(`,`):a},...r&&{startTime:r.toISOString()},...i&&{endTime:i.toISOString()}},s=await this.#t?.query({endpoint:`project_source_usage.json`,params:o});return s?(this.#n?.info({message:`Successfully retrieved ${s.length} source usage records from Tinybird`,category:`LogsSink`}),s.map(e=>({sourceId:e.sourceId,sourceType:e.sourceType,requestCount:e.request_count,lastRequest:e.last_request}))):(this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`}),[])}catch(e){return this.#t?.isReady()?this.#n?.warning({message:`Failed to query Tinybird for logs stats source usage, returning empty results`,category:`LogsSink`,error:e}):this.#n?.warning({message:`Tinybird client not available, returning empty results`,category:`LogsSink`,error:e}),[]}}async send(e,t){if(!this.#e)throw this.#n?.error({message:`Kafka not initialized, dropping message for topic ${e}`,category:`KafkaSink`,code:`KafkaNotReady`}),Error(`Kafka producer is not initialized`);let n=this.validateLogsBeforeSend(t);if(n.length===0){this.#n?.warning({message:`All ${t.length} log(s) failed validation, nothing to send to topic ${e}`,category:`LogsSink`,code:`AllLogsInvalid`});return}n.length<t.length&&this.#n?.warning({message:`${t.length-n.length} of ${t.length} log(s) failed validation and were dropped`,category:`LogsSink`,code:`SomeLogsInvalid`});let r=Date.now(),i=n.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${i.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:i,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${i.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-r,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${i.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-r,topic:e,messageCount:i.length}}),t}}buildActionLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`action`,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,actionRunId:t.actionRunId,actionId:t.actionId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,...t.connectorOwner&&{connectorOwner:t.connectorOwner},...t.connectorProfileId&&{connectorProfileId:t.connectorProfileId},...i!==void 0&&{durationMs:i},...e.mode&&{mode:e.mode},...t.actionType&&{actionType:t.actionType},...t.category&&{category:t.category},...t.originOwnerId&&{originOwnerId:t.originOwnerId},...t.originOwnerName&&{originOwnerName:t.originOwnerName},...t.httpMethod&&{httpMethod:t.httpMethod},...t.url&&{url:t.url},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.defenderContext?.result?.riskLevel&&{riskLevel:t.defenderContext.result.riskLevel},...t.defenderContext?.result?.tier2Score!==void 0&&{tier2Score:t.defenderContext.result.tier2Score},startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,isBackground:e.isBackground,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt},...n?.defenderExpiresAt&&{defenderExpiresAt:n.defenderExpiresAt}}}buildStepLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:e.startTime??n,organizationId:String(e.organizationId),projectSecureId:String(e.projectSecureId),accountSecureId:String(e.accountSecureId),actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,...t.endTime&&{endTime:t.endTime},...r!==void 0&&{durationMs:r},...t.skipped!==void 0&&{skipped:t.skipped},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.message&&{message:t.message},...e.stepFunctionName&&{stepFunctionName:e.stepFunctionName},...e.stepFunctionVersion&&{stepFunctionVersion:e.stepFunctionVersion},...e.stepIterations!==void 0&&{stepIterations:e.stepIterations}}}buildUnifiedLog(e,t,n){let r=new Date,i=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`unified`,requestId:e.requestId,connectorKey:e.connectorKey,connectorVersion:`2`,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},...e.mode&&{mode:e.mode},...e.httpMethod&&{httpMethod:e.httpMethod},...e.url&&{url:e.url},...e.path&&{path:e.path},...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...e.action&&{action:e.action},...e.sourceId&&{sourceId:e.sourceId},...e.sourceType&&{sourceType:e.sourceType},...e.sourceValue&&{sourceValue:e.sourceValue},...t.statusCode!==void 0&&{statusCode:t.statusCode},...t.success!==void 0&&{success:t.success},isBackground:e.isBackground,durationMs:i,startTime:e.startTime??r,...t.endTime&&{endTime:t.endTime},eventTime:r,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:r,duration:i,...n?.advancedExpiresAt&&{advancedExpiresAt:n.advancedExpiresAt}}}buildProviderLog(e,t){let n=new Date,r=this.calculateDurationMs(e.startTime,t.endTime);return{logType:`provider`,requestId:e.requestId,id:e.id,organizationId:e.organizationId,projectSecureId:e.projectSecureId,accountSecureId:e.accountSecureId,...e.originOwnerId&&{originOwnerId:e.originOwnerId},...e.originOwnerName&&{originOwnerName:e.originOwnerName},action:e.action,...e.mode&&{mode:e.mode},httpMethod:e.httpMethod,url:e.url,...e.path&&{path:e.path},connectorKey:e.connectorKey,connectorVersion:`2`,...e.resource&&{resource:e.resource},...e.subResource&&{subResource:e.subResource},...e.childResource&&{childResource:e.childResource},...e.service&&{service:e.service},...t.success!==void 0&&{success:t.success},...t.statusCode!==void 0&&{statusCode:t.statusCode},durationMs:r,startTime:e.startTime??n,...t.endTime&&{endTime:t.endTime},eventTime:n,...t.statusCode!==void 0&&{status:t.statusCode},provider:e.connectorKey,eventDatetime:n,duration:r}}calculateDurationMs(e,t){if(!(e instanceof Date)||!(t instanceof Date))return;let n=e.getTime(),r=t.getTime();if(!(Number.isNaN(n)||Number.isNaN(r)||r<n))return r-n}validateLogsWithSchema(e,t){return e.map(e=>{try{return t.parse(e)}catch(t){if(t instanceof _){let n=`unknown`;if(typeof e==`object`&&e&&`logType`in e){let t=e;n=typeof t.logType==`string`?t.logType:`unknown`}throw this.#n?.error({message:`Failed to validate ${n} log from Tinybird`,category:`LogsSink`,code:`LogParsingTypeError`,context:{validationErrors:t.errors,log:safeSerialize(e)}}),Error(`Tinybird data validation failed for ${n} log: ${t.message}`)}throw t}})}validateLogs(e){return this.validateLogsWithSchema(e,L)}validateLogsBeforeSend(e){let t=[];for(let n of e)try{let e=this.getSchemaForLogType(n.logType).parse(n);t.push(e)}catch(e){e instanceof _?this.#n?.warning({message:`Log validation failed before sending to Tinybird, dropping ${n.logType} log`,category:`LogsSink`,code:`PreWriteValidationFailed`,context:{logType:n.logType,validationErrors:e.errors,log:safeSerialize(n)}}):this.#n?.warning({message:`Unexpected error validating ${n.logType} log before send, dropping log`,category:`LogsSink`,code:`PreWriteValidationError`,error:e})}return t}getSchemaForLogType(e){switch(e){case`action`:return N;case`step`:return P;case`unified`:return F;case`provider`:return I}}};const R={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0},datasets:{enabled:!0,includeBackground:!1}};function resolveOlapOptions(e){return{logs:{...R.logs,...e?.logs},advanced:{...R.advanced,...e?.advanced},defender:{...R.defender,...e?.defender},datasets:{...R.datasets,...e?.datasets}}}const buildHttpClient=e=>{try{return new b({logger:e})}catch(t){let n=t;e?.error({message:`Error building http client: ${n.message}`,error:n,code:`BuildHttpClientError`,category:`buildHttpClient`});return}},buildKafkaClient=async(e,t)=>{if(e)try{let{Producer:t,stringSerializers:n}=await import(`@platformatic/kafka`);return new t({...e,serializers:n})??void 0}catch(e){let n=e;t?.error({message:`Error building kafka producer: ${n.message}`,error:n,code:`BuildKafkaProducerError`,category:`buildKafkaClient`});return}},buildS3Client=(e,t)=>{try{return new g(e)??void 0}catch(e){let n=e;t?.error({message:`Error building s3 client: ${n.message}`,error:n,code:`BuildS3ClientError`,category:`buildS3Client`});return}};var z=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#c=e,this.#l=r,this.#u=a,this.#t=t(o),this.#n=n(i,o),this.#r=o}static async create({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){let s=new OlapClient({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});return await s.initialize(),s}async initialize(){this.#e=await this.#c(this.#l,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#u,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),this.#s=new DatasetsSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#s?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){await this.recordActions([{input:e,result:t}],n)}async recordActions(e,t){let{logs:n,advanced:r,defender:i,datasets:o}=resolveOlapOptions(t);this.#r?.debug({message:`Olap client called to record ${e.length} action(s)`,category:`OlapClient`,context:{options:t,resolvedOptions:{logs:n,advanced:r,defender:i,datasets:o}}});for(let t of e)a(t.input.isBackground)&&(t.input.isBackground=isBackgroundLog(t.input.mode,t.input.sourceType));let s=o?.enabled&&this.#s?this.#s.sendActions(e,o).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to datasets sink: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve(),[c,l]=await Promise.all([r?.enabled&&this.#a?this.#a.sendActions(e,r).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null)),i?.enabled&&this.#o?this.#o.sendActions(e,i).catch(t=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${t.message}`,category:`OlapClient`,error:t}),e.map(()=>null))):Promise.resolve(e.map(()=>null))]),u=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:c[t]?.expiresAt,defenderExpiresAt:l[t]?.expiresAt}})),d=n?.enabled&&this.#i?this.#i.sendActions(u,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})}):Promise.resolve();await Promise.all([s,d])}async recordStep(e,t,n){await this.recordSteps([{input:e,result:t}],n)}async recordSteps(e,t){let{logs:n,advanced:r}=resolveOlapOptions(t),i=[];n?.enabled&&this.#i&&i.push(this.#i.sendSteps(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&i.push(this.#a.sendSteps(e,r).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}async recordUnified(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record unified`,category:`OlapClient`,context:{mode:e.mode,requestId:e.requestId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:i}}}),a(e.isBackground)&&(e.isBackground=isBackgroundLog(e.mode,e.sourceType));let o={advancedExpiresAt:(i?.enabled&&this.#a?await this.#a.sendUnified(e,t,i).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):null)?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendUnified(e,t,o,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordProvider(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendProvider(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&a.push(this.#a.sendProvider(e,t,i).then(()=>{}).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}async getLogs(e,t,n){return this.#r?.debug({message:`Querying logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query logs, returning empty result`,category:`OlapClient`}),{logs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLogs(e,t,n){return this.#r?.debug({message:`Querying action logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getActions({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query action logs, returning empty result`,category:`OlapClient`}),{actionLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getActionLog(e,t,n){let r=await this.#i?.getAction(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve action log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepLogs(e,t,n){return this.#r?.debug({message:`Querying step logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSteps({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query step logs, returning empty result`,category:`OlapClient`}),{stepLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getStepLog(e,t,n,r){let i=await this.#i?.getStep(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedLogs(e,t,n){return this.#r?.debug({message:`Querying unified logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getUnifiedLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query unified logs, returning empty result`,category:`OlapClient`}),{unifiedLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getUnifiedLog(e,t,n){let r=await this.#i?.getUnifiedLog(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve unified log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderLogs(e,t,n){return this.#r?.debug({message:`Querying provider logs`,category:`OlapClient`,context:{query:n}}),await this.#i?.getProviderLogs({...n,organizationId:e,projectSecureId:t})||(this.#r?.warning({message:`Failed to query provider logs, returning empty result`,category:`OlapClient`}),{providerLogs:[],total:0,pageNumber:n.pageNumber??1,pageSize:n.pageSize??0})}async getProviderLog(e,t,n,r){let i=await this.#i?.getProviderLog(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve provider log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getActionAdvancedLog(e,t,n){let r=await this.#a?.getAction(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve action advanced log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getStepAdvancedLog(e,t,n,r){let i=await this.#a?.getStep(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return i}async getUnifiedAdvancedLog(e,t,n){let r=await this.#a?.getUnified(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve unified advanced log for requestId ${n}`,category:`OlapClient`});return}return r}async getProviderAdvancedLog(e,t,n,r){let i=await this.#a?.getProvider(e,t,n,r);if(a(i)){this.#r?.debug({message:`Failed to retrieve provider advanced log for requestId ${n} id ${r}`,category:`OlapClient`});return}return i}async getDefenderLog(e,t,n){let r=await this.#o?.getAction(e,t,n);if(a(r)){this.#r?.debug({message:`Failed to retrieve defender log for actionRunId ${n}`,category:`OlapClient`});return}return r}async getLogsStatsAggregate(e,t,n){return this.#r?.debug({message:`Querying logs stats aggregate`,category:`OlapClient`,context:{query:n}}),await this.#i?.getAggregate(e,t,n)??{data:[]}}async getLogsStatsDimensions(e,t,n){return this.#r?.debug({message:`Querying logs stats dimensions`,category:`OlapClient`,context:{query:n}}),await this.#i?.getDimensions(e,t,n)??{}}async getSourceUsage(e,t,n){return this.#r?.debug({message:`Querying source usage`,category:`OlapClient`,context:{query:n}}),await this.#i?.getSourceUsage(e,t,n)??[]}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>z.create({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o});var OlapClientManager=class{static{this.olapClientPromise=null}static getInstance({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o,getOlapClient:s=buildOlapClientInstance}={}){return this.olapClientPromise||=s({getKafkaClient:e,getHttpClient:t,getS3Client:n,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}),this.olapClientPromise}static resetInstance(){this.olapClientPromise=null}};export{S as Dimension,x as LogType,z as OlapClient,OlapClientManager};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackone/olap",
3
- "version": "1.36.0",
3
+ "version": "1.37.0",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",