@stackone/olap 1.32.0 → 1.34.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(`@stackone/transport`),u=require(`zod`),d=require(`node:http`);d=__toESM(d);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`},m=[`refresh_authentication`],h=[`data_sync`];function isBackgroundLog(e){return e!=null&&m.includes(e)}function isDataSync(e){return e!=null&&h.includes(e)}const safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},g=[`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`],_=[`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`],v=[`image/`,`audio/`,`video/`,`application/vnd.`,`binary`],y=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)){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)&&!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)&&!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,y),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,y),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,y),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,y),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=isBackgroundLog(e.mode),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=isBackgroundLog(e.mode),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=g.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 _.includes(i)||v.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()}};const 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 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}}}),(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}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),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 buildHttpClient=e=>{try{return new l.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}},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()},b=u.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 u.z.ZodError([{code:u.z.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},u.z.coerce.date()),x=u.z.object({logType:u.z.enum([`action`,`step`,`unified`,`provider`]),eventTime:b,startTime:b,endTime:b.optional().nullable().transform(e=>e??void 0),durationMs:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:u.z.coerce.string(),projectSecureId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0)}),S=x.extend({logType:u.z.literal(`action`),actionRunId:u.z.coerce.string(),actionId:u.z.coerce.string(),connectorKey:u.z.coerce.string(),connectorVersion:u.z.coerce.string(),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),actionType:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),mode:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),category:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:b.optional().nullable().transform(e=>e??void 0),defenderExpiresAt:b.optional().nullable().transform(e=>e??void 0)}),C=x.extend({logType:u.z.literal(`step`),actionRunId:u.z.coerce.string(),stepIndex:u.z.coerce.number(),stepId:u.z.coerce.string(),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),skipped:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),message:u.z.coerce.string().optional().nullable().transform(e=>e??void 0)}),w=x.extend({logType:u.z.literal(`unified`),requestId:u.z.coerce.string(),connectorKey:u.z.coerce.string(),connectorVersion:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),mode:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),path:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:b.optional().nullable().transform(e=>e??void 0),duration:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:b.optional().nullable().transform(e=>e??void 0)}),T=x.extend({logType:u.z.literal(`provider`),requestId:u.z.coerce.string(),id:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:u.z.coerce.string(),mode:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:u.z.coerce.string(),originOwnerId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:u.z.coerce.string(),path:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:u.z.coerce.string(),connectorVersion:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),status:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:b.optional().nullable().transform(e=>e??void 0),duration:u.z.coerce.number().optional().nullable().transform(e=>e??void 0)}),E=u.z.discriminatedUnion(`logType`,[S,C,w,T]);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 d.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 D=`project_logs.json`,O=`project_action_logs.json`,k=`project_step_logs.json`,A=`project_unified_logs.json`,j=`project_provider_logs.json`,M=`project_logs_aggregation.json`,N=`project_logs_dimensions.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,S),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,C),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,w),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,T),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 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,...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(t.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:t.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.message&&{message:t.message}}}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 u.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,E)}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 u.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 S;case`step`:return C;case`unified`:return w;case`provider`:return T}}};const P={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0}};function resolveOlapOptions(e){return{logs:{...P.logs,...e?.logs},advanced:{...P.advanced,...e?.advanced},defender:{...P.defender,...e?.defender}}}var F=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#s=e,this.#c=r,this.#l=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.#s(this.#c,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#l,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){let{logs:r,advanced:i,defender:a}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record action`,category:`OlapClient`,context:{mode:e.mode,actionId:e.actionId,actionRunId:t.actionRunId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:i,defender:a}}});let[o,s]=await Promise.all([i?.enabled&&this.#a?this.#a.sendAction(e,t,i).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null),a?.enabled&&this.#o?this.#o.sendAction(e,t,a).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null)]),c={advancedExpiresAt:o?.expiresAt,defenderExpiresAt:s?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendAction(e,t,c,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),[a,o]=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))]);if(n?.enabled&&this.#i){let t=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:a[t]?.expiresAt,defenderExpiresAt:o[t]?.expiresAt}}));await this.#i.sendActions(t,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}}async recordStep(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendStep(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.sendStep(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 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}}});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)??{}}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>F.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=F,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(`@stackone/transport`),u=require(`zod`),d=require(`node:http`);d=__toESM(d);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`],h=[`TOKEN_REFRESH`,`VALIDATE_CREDENTIALS`,`DATA_SYNC`],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()}};const 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 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}}}),(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}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),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 buildHttpClient=e=>{try{return new l.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}},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=u.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 u.z.ZodError([{code:u.z.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},u.z.coerce.date()),C=u.z.object({logType:u.z.enum([`action`,`step`,`unified`,`provider`]),eventTime:S,startTime:S,endTime:S.optional().nullable().transform(e=>e??void 0),durationMs:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:u.z.coerce.string(),projectSecureId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0)}),w=C.extend({logType:u.z.literal(`action`),actionRunId:u.z.coerce.string(),actionId:u.z.coerce.string(),connectorKey:u.z.coerce.string(),connectorVersion:u.z.coerce.string(),connectorOwner:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),connectorProfileId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),actionType:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),mode:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),category:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:u.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:u.z.literal(`step`),actionRunId:u.z.coerce.string(),stepIndex:u.z.coerce.number(),stepId:u.z.coerce.string(),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),skipped:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),message:u.z.coerce.string().optional().nullable().transform(e=>e??void 0)}),E=C.extend({logType:u.z.literal(`unified`),requestId:u.z.coerce.string(),connectorKey:u.z.coerce.string(),connectorVersion:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),mode:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),path:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:S.optional().nullable().transform(e=>e??void 0),duration:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:S.optional().nullable().transform(e=>e??void 0)}),D=C.extend({logType:u.z.literal(`provider`),requestId:u.z.coerce.string(),id:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),action:u.z.coerce.string(),mode:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:u.z.coerce.string(),originOwnerId:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),url:u.z.coerce.string(),path:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:u.z.coerce.string(),connectorVersion:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),resource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),service:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),success:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string(),status:u.z.coerce.number().optional().nullable().transform(e=>e??void 0),provider:u.z.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:S.optional().nullable().transform(e=>e??void 0),duration:u.z.coerce.number().optional().nullable().transform(e=>e??void 0)}),O=u.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 d.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(t.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:t.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.message&&{message:t.message}}}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 u.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 u.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}};function resolveOlapOptions(e){return{logs:{...L.logs,...e?.logs},advanced:{...L.advanced,...e?.advanced},defender:{...L.defender,...e?.defender}}}var R=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#s=e,this.#c=r,this.#l=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.#s(this.#c,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#l,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){let{logs:r,advanced:i,defender:a}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record action`,category:`OlapClient`,context:{mode:e.mode,actionId:e.actionId,actionRunId:t.actionRunId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:i,defender:a}}}),(0,o.isMissing)(e.isBackground)&&(e.isBackground=isBackgroundLog(e.mode,e.sourceType));let[s,c]=await Promise.all([i?.enabled&&this.#a?this.#a.sendAction(e,t,i).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null),a?.enabled&&this.#o?this.#o.sendAction(e,t,a).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null)]),l={advancedExpiresAt:s?.expiresAt,defenderExpiresAt:c?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendAction(e,t,l,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),[a,o]=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))]);if(n?.enabled&&this.#i){let t=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:a[t]?.expiresAt,defenderExpiresAt:o[t]?.expiresAt}}));await this.#i.sendActions(t,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}}async recordStep(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendStep(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.sendStep(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 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.d.cts CHANGED
@@ -1,7 +1,7 @@
1
- import * as redis from "redis";
2
- import { AxiosInstance } from "axios";
3
1
  import http from "node:http";
4
2
  import https from "node:https";
3
+ import { AxiosInstance } from "axios";
4
+ import * as redis from "redis";
5
5
  import { Readable } from "node:stream";
6
6
  import { S3Client } from "@aws-sdk/client-s3";
7
7
  import { Producer } from "@platformatic/kafka";
@@ -562,6 +562,7 @@ interface IOlapClient {
562
562
  getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
563
563
  getLogsStatsAggregate(organizationId: string, projectSecureId: string, query: AggregateQuery): Promise<AggregateResult>;
564
564
  getLogsStatsDimensions(organizationId: string, projectSecureId: string, query: DimensionsQuery): Promise<DimensionsResult>;
565
+ getSourceUsage(organizationId: string, projectSecureId: string, query: SourceQuery): Promise<SourceResult>;
565
566
  }
566
567
  type DefenderContext = {
567
568
  result?: {
@@ -590,6 +591,8 @@ type ActionResult = {
590
591
  actionId: string;
591
592
  connectorKey: string;
592
593
  connectorVersion: string;
594
+ connectorOwner?: string;
595
+ connectorProfileId?: string;
593
596
  actionType: string;
594
597
  category?: string;
595
598
  organizationId: string;
@@ -729,6 +732,7 @@ type Query = {
729
732
  sourceValue?: string | string[];
730
733
  originOwnerId?: string | string[];
731
734
  httpMethod?: string | string[];
735
+ isBackground?: boolean;
732
736
  logType?: (typeof LogType.Action | typeof LogType.Unified) | (typeof LogType.Action | typeof LogType.Unified)[];
733
737
  success?: boolean;
734
738
  startTime?: Date;
@@ -751,6 +755,7 @@ type ActionsQuery = {
751
755
  connectorKey?: string | string[];
752
756
  mode?: string | string[];
753
757
  category?: string | string[];
758
+ isBackground?: boolean;
754
759
  success?: boolean;
755
760
  startTime?: Date;
756
761
  endTime?: Date;
@@ -792,6 +797,7 @@ type UnifiedQuery = {
792
797
  source?: string | string[];
793
798
  category?: string | string[];
794
799
  originOwnerId?: string | string[];
800
+ isBackground?: boolean;
795
801
  success?: boolean;
796
802
  startTime?: Date;
797
803
  endTime?: Date;
@@ -837,6 +843,7 @@ declare const Dimension: {
837
843
  readonly StatusCode: "status_code";
838
844
  readonly OriginOwnerId: "origin_owner_id";
839
845
  readonly SourceId: "source_id";
846
+ readonly IsBackground: "is_background";
840
847
  };
841
848
  type Dimension = (typeof Dimension)[keyof typeof Dimension];
842
849
  type AggregateQuery = Partial<Query> & {
@@ -861,6 +868,13 @@ type DimensionsResult = {
861
868
  count: number;
862
869
  }>;
863
870
  };
871
+ type SourceQuery = Partial<Query>;
872
+ type SourceResult = Array<{
873
+ sourceId: string;
874
+ sourceType: string;
875
+ requestCount: number;
876
+ lastRequest: string;
877
+ }>;
864
878
  type HttpClientBuilder = (logger?: ILogger) => HttpClient | undefined;
865
879
  type SASLMechanism = 'PLAIN' | 'SCRAM-SHA-256' | 'SCRAM-SHA-512';
866
880
  interface KafkaClientConfig {
@@ -921,6 +935,8 @@ type ActionLog = ILog & {
921
935
  actionId: string;
922
936
  connectorKey: string;
923
937
  connectorVersion: string;
938
+ connectorOwner?: string;
939
+ connectorProfileId?: string;
924
940
  organizationId: string;
925
941
  projectSecureId: string;
926
942
  accountSecureId: string;
@@ -1066,6 +1082,7 @@ declare class OlapClient implements IOlapClient {
1066
1082
  getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
1067
1083
  getLogsStatsAggregate(organizationId: string, projectSecureId: string, query: AggregateQuery): Promise<AggregateResult>;
1068
1084
  getLogsStatsDimensions(organizationId: string, projectSecureId: string, query: DimensionsQuery): Promise<DimensionsResult>;
1085
+ getSourceUsage(organizationId: string, projectSecureId: string, query: SourceQuery): Promise<SourceResult>;
1069
1086
  }
1070
1087
  //#endregion
1071
1088
  //#region src/olap/olapClientManager.d.ts
@@ -1110,4 +1127,4 @@ declare class OlapClientManager {
1110
1127
  static resetInstance(): void;
1111
1128
  }
1112
1129
  //#endregion
1113
- export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type AggregateQuery, type AggregateResult, type DefenderContext, type DefenderLog, type DefenderOptions, Dimension, type Dimension as DimensionValues, type DimensionsQuery, type DimensionsResult, type ILog, type IOlapClient, type IntervalType, LogType, type LogType as LogTypeValues, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type ProviderAdvancedLog, type ProviderInput, type ProviderLog, type ProviderQuery, type ProviderQueryResult, type ProviderResult, type Query, type QueryResult, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse, type UnifiedAdvancedLog, type UnifiedInput, type UnifiedLog, type UnifiedQuery, type UnifiedQueryResult, type UnifiedResult };
1130
+ export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type AggregateQuery, type AggregateResult, type DefenderContext, type DefenderLog, type DefenderOptions, Dimension, type Dimension as DimensionValues, type DimensionsQuery, type DimensionsResult, type ILog, type IOlapClient, type IntervalType, LogType, type LogType as LogTypeValues, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type ProviderAdvancedLog, type ProviderInput, type ProviderLog, type ProviderQuery, type ProviderQueryResult, type ProviderResult, type Query, type QueryResult, type SourceQuery, type SourceResult, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse, type UnifiedAdvancedLog, type UnifiedInput, type UnifiedLog, type UnifiedQuery, type UnifiedQueryResult, type UnifiedResult };
package/dist/index.d.mts CHANGED
@@ -3,9 +3,9 @@ import "@stackone/utils";
3
3
  import { S3Client } from "@aws-sdk/client-s3";
4
4
  import http from "node:http";
5
5
  import { Producer } from "@platformatic/kafka";
6
- import * as redis from "redis";
7
- import { AxiosInstance } from "axios";
8
6
  import https from "node:https";
7
+ import { AxiosInstance } from "axios";
8
+ import * as redis from "redis";
9
9
  import { Readable } from "node:stream";
10
10
 
11
11
  //#region ../logger/src/types.d.ts
@@ -562,6 +562,7 @@ interface IOlapClient {
562
562
  getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
563
563
  getLogsStatsAggregate(organizationId: string, projectSecureId: string, query: AggregateQuery): Promise<AggregateResult>;
564
564
  getLogsStatsDimensions(organizationId: string, projectSecureId: string, query: DimensionsQuery): Promise<DimensionsResult>;
565
+ getSourceUsage(organizationId: string, projectSecureId: string, query: SourceQuery): Promise<SourceResult>;
565
566
  }
566
567
  type DefenderContext = {
567
568
  result?: {
@@ -590,6 +591,8 @@ type ActionResult = {
590
591
  actionId: string;
591
592
  connectorKey: string;
592
593
  connectorVersion: string;
594
+ connectorOwner?: string;
595
+ connectorProfileId?: string;
593
596
  actionType: string;
594
597
  category?: string;
595
598
  organizationId: string;
@@ -729,6 +732,7 @@ type Query = {
729
732
  sourceValue?: string | string[];
730
733
  originOwnerId?: string | string[];
731
734
  httpMethod?: string | string[];
735
+ isBackground?: boolean;
732
736
  logType?: (typeof LogType.Action | typeof LogType.Unified) | (typeof LogType.Action | typeof LogType.Unified)[];
733
737
  success?: boolean;
734
738
  startTime?: Date;
@@ -751,6 +755,7 @@ type ActionsQuery = {
751
755
  connectorKey?: string | string[];
752
756
  mode?: string | string[];
753
757
  category?: string | string[];
758
+ isBackground?: boolean;
754
759
  success?: boolean;
755
760
  startTime?: Date;
756
761
  endTime?: Date;
@@ -792,6 +797,7 @@ type UnifiedQuery = {
792
797
  source?: string | string[];
793
798
  category?: string | string[];
794
799
  originOwnerId?: string | string[];
800
+ isBackground?: boolean;
795
801
  success?: boolean;
796
802
  startTime?: Date;
797
803
  endTime?: Date;
@@ -837,6 +843,7 @@ declare const Dimension: {
837
843
  readonly StatusCode: "status_code";
838
844
  readonly OriginOwnerId: "origin_owner_id";
839
845
  readonly SourceId: "source_id";
846
+ readonly IsBackground: "is_background";
840
847
  };
841
848
  type Dimension = (typeof Dimension)[keyof typeof Dimension];
842
849
  type AggregateQuery = Partial<Query> & {
@@ -861,6 +868,13 @@ type DimensionsResult = {
861
868
  count: number;
862
869
  }>;
863
870
  };
871
+ type SourceQuery = Partial<Query>;
872
+ type SourceResult = Array<{
873
+ sourceId: string;
874
+ sourceType: string;
875
+ requestCount: number;
876
+ lastRequest: string;
877
+ }>;
864
878
  type HttpClientBuilder = (logger?: ILogger) => HttpClient | undefined;
865
879
  type SASLMechanism = 'PLAIN' | 'SCRAM-SHA-256' | 'SCRAM-SHA-512';
866
880
  interface KafkaClientConfig {
@@ -921,6 +935,8 @@ type ActionLog = ILog & {
921
935
  actionId: string;
922
936
  connectorKey: string;
923
937
  connectorVersion: string;
938
+ connectorOwner?: string;
939
+ connectorProfileId?: string;
924
940
  organizationId: string;
925
941
  projectSecureId: string;
926
942
  accountSecureId: string;
@@ -1066,6 +1082,7 @@ declare class OlapClient implements IOlapClient {
1066
1082
  getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
1067
1083
  getLogsStatsAggregate(organizationId: string, projectSecureId: string, query: AggregateQuery): Promise<AggregateResult>;
1068
1084
  getLogsStatsDimensions(organizationId: string, projectSecureId: string, query: DimensionsQuery): Promise<DimensionsResult>;
1085
+ getSourceUsage(organizationId: string, projectSecureId: string, query: SourceQuery): Promise<SourceResult>;
1069
1086
  }
1070
1087
  //#endregion
1071
1088
  //#region src/olap/olapClientManager.d.ts
@@ -1110,4 +1127,4 @@ declare class OlapClientManager {
1110
1127
  static resetInstance(): void;
1111
1128
  }
1112
1129
  //#endregion
1113
- export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type AggregateQuery, type AggregateResult, type DefenderContext, type DefenderLog, type DefenderOptions, Dimension, type Dimension as DimensionValues, type DimensionsQuery, type DimensionsResult, type ILog, type IOlapClient, type IntervalType, LogType, type LogType as LogTypeValues, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type ProviderAdvancedLog, type ProviderInput, type ProviderLog, type ProviderQuery, type ProviderQueryResult, type ProviderResult, type Query, type QueryResult, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse, type UnifiedAdvancedLog, type UnifiedInput, type UnifiedLog, type UnifiedQuery, type UnifiedQueryResult, type UnifiedResult };
1130
+ export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type AggregateQuery, type AggregateResult, type DefenderContext, type DefenderLog, type DefenderOptions, Dimension, type Dimension as DimensionValues, type DimensionsQuery, type DimensionsResult, type ILog, type IOlapClient, type IntervalType, LogType, type LogType as LogTypeValues, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type ProviderAdvancedLog, type ProviderInput, type ProviderLog, type ProviderQuery, type ProviderQueryResult, type ProviderResult, type Query, type QueryResult, type SourceQuery, type SourceResult, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse, type UnifiedAdvancedLog, type UnifiedInput, type UnifiedLog, type UnifiedQuery, type UnifiedQueryResult, type UnifiedResult };
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,isMissing as i,isString as a,snakeToCamel as o}from"@stackone/utils";import{CensorType as s,redactFields as c,redactObject as l,redactUrl as u}from"@stackone/redaction";import{GetObjectCommand as d,HeadObjectCommand as f,PutObjectCommand as p,S3Client as m}from"@aws-sdk/client-s3";import{HttpClient as h}from"@stackone/transport";import{ZodError as g,z as _}from"zod";import v from"node:http";const y={Action:`action`,Step:`step`,Unified:`unified`,Provider:`provider`},b={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`},x=[`refresh_authentication`],S=[`data_sync`];function isBackgroundLog(e){return e!=null&&x.includes(e)}function isDataSync(e){return e!=null&&S.includes(e)}const safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},C=[`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`],w=[`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`],T=[`image/`,`audio/`,`video/`,`application/vnd.`,`binary`],E=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)){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)&&!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)&&!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 d({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 d({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 d({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 d({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 p({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 f({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,E),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,E),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,E),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,E),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let i=l({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.PARTIAL),a=i.req?.headers,o=i.res?.headers,d=c(e.body,s.PARTIAL,!0),f=c(t.body,s.PARTIAL,!0),p=this.processContent(a,d,`upload`),m=this.processContent(o,f,`download`),h=isBackgroundLog(e.mode),g=e.url,_={};if(e.url)try{g=u(e.url,s.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=l({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.PARTIAL),a=i.req?.headers,o=i.res?.headers,d=c(e.body,s.PARTIAL,!0),f=c(t.body,s.PARTIAL,!0),p=this.processContent(a,d,`upload`),m=this.processContent(o,f,`download`),h=isBackgroundLog(e.mode),g=`/`,_=e.url,v={};if(e.url)try{_=u(e.url,s.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=l({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.PARTIAL),a=i.req?.headers,o=i.res?.headers,d=c(e.body,s.PARTIAL,!0),f=c(t.body,s.PARTIAL,!0),p=this.processContent(a,d,`upload`),m=this.processContent(o,f,`download`),h,g=``,_=`/`,v={};if(e.url)try{h=u(e.url,s.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=C.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 w.includes(i)||T.some(e=>i.startsWith(e))?{type:`binary`,action:n,contentType:r}:this.parseJsonSafely(t)}parseJsonSafely(e){if(!i(e)){if(!a(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()}};const buildS3Client=(e,t)=>{try{return new m(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 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:a}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:a.actionRunId,success:a.success,statusCode:a.statusCode,options:{enabled:t?.enabled}}}),i(a.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:a.actionRunId}}),n.push(null);continue}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),n.push(null);continue}let e=this.createDefenderS3(a),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 d({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 p({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 buildHttpClient=e=>{try{return new h({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}},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()},D=_.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 _.ZodError([{code:_.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},_.coerce.date()),O=_.object({logType:_.enum([`action`,`step`,`unified`,`provider`]),eventTime:D,startTime:D,endTime:D.optional().nullable().transform(e=>e??void 0),durationMs:_.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:_.coerce.string(),projectSecureId:_.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:_.coerce.string().optional().nullable().transform(e=>e??void 0)}),k=O.extend({logType:_.literal(`action`),actionRunId:_.coerce.string(),actionId:_.coerce.string(),connectorKey:_.coerce.string(),connectorVersion:_.coerce.string(),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),actionType:_.coerce.string().optional().nullable().transform(e=>e??void 0),mode:_.coerce.string().optional().nullable().transform(e=>e??void 0),category:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:_.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:_.coerce.string().optional().nullable().transform(e=>e??void 0),url:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:_.coerce.string().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:_.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:_.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:_.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:D.optional().nullable().transform(e=>e??void 0),defenderExpiresAt:D.optional().nullable().transform(e=>e??void 0)}),A=O.extend({logType:_.literal(`step`),actionRunId:_.coerce.string(),stepIndex:_.coerce.number(),stepId:_.coerce.string(),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),skipped:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),message:_.coerce.string().optional().nullable().transform(e=>e??void 0)}),j=O.extend({logType:_.literal(`unified`),requestId:_.coerce.string(),connectorKey:_.coerce.string(),connectorVersion:_.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),mode:_.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:_.coerce.string().optional().nullable().transform(e=>e??void 0),url:_.coerce.string().optional().nullable().transform(e=>e??void 0),path:_.coerce.string().optional().nullable().transform(e=>e??void 0),resource:_.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),service:_.coerce.string().optional().nullable().transform(e=>e??void 0),action:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:_.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:_.coerce.number().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:_.coerce.number().optional().nullable().transform(e=>e??void 0),provider:_.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:D.optional().nullable().transform(e=>e??void 0),duration:_.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:D.optional().nullable().transform(e=>e??void 0)}),M=O.extend({logType:_.literal(`provider`),requestId:_.coerce.string(),id:_.coerce.string().optional().nullable().transform(e=>e??void 0),action:_.coerce.string(),mode:_.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:_.coerce.string(),originOwnerId:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:_.coerce.string().optional().nullable().transform(e=>e??void 0),url:_.coerce.string(),path:_.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:_.coerce.string(),connectorVersion:_.coerce.string().optional().nullable().transform(e=>e??void 0),resource:_.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),service:_.coerce.string().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:_.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),status:_.coerce.number().optional().nullable().transform(e=>e??void 0),provider:_.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:D.optional().nullable().transform(e=>e??void 0),duration:_.coerce.number().optional().nullable().transform(e=>e??void 0)}),N=_.discriminatedUnion(`logType`,[k,A,j,M]);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 v.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,k),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,A),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,j),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,M),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:s,...c}=r,l={organizationId:e,projectSecureId:t,...c,...i&&i.length>0&&{dimensions:i.map(o).join(`,`)},...a&&{startTime:a.toISOString()},...s&&{endTime:s.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:s,maxValues:c,...l}=r,u={organizationId:e,projectSecureId:n,...l,dimensions:i.map(o).join(`,`),...a&&{startTime:a.toISOString()},...s&&{endTime:s.toISOString()},...c&&{maxValuesPerDim:c}},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 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,...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(t.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:t.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.message&&{message:t.message}}}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 g){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,N)}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 g?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 k;case`step`:return A;case`unified`:return j;case`provider`:return M}}};const P={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0}};function resolveOlapOptions(e){return{logs:{...P.logs,...e?.logs},advanced:{...P.advanced,...e?.advanced},defender:{...P.defender,...e?.defender}}}var F=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#s=e,this.#c=r,this.#l=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.#s(this.#c,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#l,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){let{logs:r,advanced:i,defender:a}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record action`,category:`OlapClient`,context:{mode:e.mode,actionId:e.actionId,actionRunId:t.actionRunId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:i,defender:a}}});let[o,s]=await Promise.all([i?.enabled&&this.#a?this.#a.sendAction(e,t,i).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null),a?.enabled&&this.#o?this.#o.sendAction(e,t,a).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null)]),c={advancedExpiresAt:o?.expiresAt,defenderExpiresAt:s?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendAction(e,t,c,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),[a,o]=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))]);if(n?.enabled&&this.#i){let t=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:a[t]?.expiresAt,defenderExpiresAt:o[t]?.expiresAt}}));await this.#i.sendActions(t,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}}async recordStep(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendStep(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.sendStep(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 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}}});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(i(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 a=await this.#i?.getStep(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return a}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(i(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 a=await this.#i?.getProviderLog(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve provider log for requestId ${n} id ${r}`,category:`OlapClient`});return}return a}async getActionAdvancedLog(e,t,n){let r=await this.#a?.getAction(e,t,n);if(i(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 a=await this.#a?.getStep(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return a}async getUnifiedAdvancedLog(e,t,n){let r=await this.#a?.getUnified(e,t,n);if(i(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 a=await this.#a?.getProvider(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve provider advanced log for requestId ${n} id ${r}`,category:`OlapClient`});return}return a}async getDefenderLog(e,t,n){let r=await this.#o?.getAction(e,t,n);if(i(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)??{}}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>F.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{b as Dimension,y as LogType,F as OlapClient,OlapClientManager};
1
+ import{t as e}from"./chunk-Cfxk5zVN.mjs";import{camelToSnake as t,convertKeysToSnakeCase as n,exceedsSize as r,isMissing as i,isString as a,snakeToCamel as o}from"@stackone/utils";import{CensorType as s,redactFields as c,redactObject as l,redactUrl as u}from"@stackone/redaction";import{GetObjectCommand as d,HeadObjectCommand as f,PutObjectCommand as p,S3Client as m}from"@aws-sdk/client-s3";import{HttpClient as h}from"@stackone/transport";import{ZodError as g,z as _}from"zod";import v from"node:http";const y={Action:`action`,Step:`step`,Unified:`unified`,Provider:`provider`},b={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`},x=[`refresh_authentication`,`data_sync`,`test_action`],S=[`TOKEN_REFRESH`,`VALIDATE_CREDENTIALS`,`DATA_SYNC`],C=[`data_sync`],w=[`DATA_SYNC`];function isBackgroundLog(e,t){return!!(e&&x.includes(e)||t&&S.includes(t))}function isDataSync(e,t){return!!(e&&C.includes(e)||t&&w.includes(t))}const safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},T=[`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`],E=[`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`],D=[`image/`,`audio/`,`video/`,`application/vnd.`,`binary`],O=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 d({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 d({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 d({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 d({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 p({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 f({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,O),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,O),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,O),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,O),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let i=l({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.PARTIAL),a=i.req?.headers,o=i.res?.headers,d=c(e.body,s.PARTIAL,!0),f=c(t.body,s.PARTIAL,!0),p=this.processContent(a,d,`upload`),m=this.processContent(o,f,`download`),h=e.isBackground??isBackgroundLog(e.mode,e.sourceType),g=e.url,_={};if(e.url)try{g=u(e.url,s.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=l({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.PARTIAL),a=i.req?.headers,o=i.res?.headers,d=c(e.body,s.PARTIAL,!0),f=c(t.body,s.PARTIAL,!0),p=this.processContent(a,d,`upload`),m=this.processContent(o,f,`download`),h=e.isBackground??isBackgroundLog(e.mode,e.sourceType),g=`/`,_=e.url,v={};if(e.url)try{_=u(e.url,s.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=l({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},s.PARTIAL),a=i.req?.headers,o=i.res?.headers,d=c(e.body,s.PARTIAL,!0),f=c(t.body,s.PARTIAL,!0),p=this.processContent(a,d,`upload`),m=this.processContent(o,f,`download`),h,g=``,_=`/`,v={};if(e.url)try{h=u(e.url,s.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=T.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 E.includes(i)||D.some(e=>i.startsWith(e))?{type:`binary`,action:n,contentType:r}:this.parseJsonSafely(t)}parseJsonSafely(e){if(!i(e)){if(!a(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()}};const buildS3Client=(e,t)=>{try{return new m(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 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:a}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:r.mode,actionId:r.actionId,actionRunId:a.actionRunId,success:a.success,statusCode:a.statusCode,options:{enabled:t?.enabled}}}),i(a.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:a.actionRunId}}),n.push(null);continue}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`}),n.push(null);continue}let e=this.createDefenderS3(a),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 d({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 p({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 buildHttpClient=e=>{try{return new h({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}},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()},k=_.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 _.ZodError([{code:_.ZodIssueCode.custom,path:[],message:e instanceof Error?e.message:`Invalid date string`}])}return e},_.coerce.date()),A=_.object({logType:_.enum([`action`,`step`,`unified`,`provider`]),eventTime:k,startTime:k,endTime:k.optional().nullable().transform(e=>e??void 0),durationMs:_.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:_.coerce.string(),projectSecureId:_.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:_.coerce.string().optional().nullable().transform(e=>e??void 0)}),j=A.extend({logType:_.literal(`action`),actionRunId:_.coerce.string(),actionId:_.coerce.string(),connectorKey:_.coerce.string(),connectorVersion:_.coerce.string(),connectorOwner:_.coerce.string().optional().nullable().transform(e=>e??void 0),connectorProfileId:_.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),actionType:_.coerce.string().optional().nullable().transform(e=>e??void 0),mode:_.coerce.string().optional().nullable().transform(e=>e??void 0),category:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:_.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:_.coerce.string().optional().nullable().transform(e=>e??void 0),url:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:_.coerce.string().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:_.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:_.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:_.coerce.number().optional().nullable().transform(e=>e??void 0),isBackground:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:k.optional().nullable().transform(e=>e??void 0),defenderExpiresAt:k.optional().nullable().transform(e=>e??void 0)}),M=A.extend({logType:_.literal(`step`),actionRunId:_.coerce.string(),stepIndex:_.coerce.number(),stepId:_.coerce.string(),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),skipped:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),message:_.coerce.string().optional().nullable().transform(e=>e??void 0)}),N=A.extend({logType:_.literal(`unified`),requestId:_.coerce.string(),connectorKey:_.coerce.string(),connectorVersion:_.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),mode:_.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:_.coerce.string().optional().nullable().transform(e=>e??void 0),url:_.coerce.string().optional().nullable().transform(e=>e??void 0),path:_.coerce.string().optional().nullable().transform(e=>e??void 0),resource:_.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),service:_.coerce.string().optional().nullable().transform(e=>e??void 0),action:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:_.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:_.coerce.string().optional().nullable().transform(e=>e??void 0),statusCode:_.coerce.number().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),isWorker:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),isBackground:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),status:_.coerce.number().optional().nullable().transform(e=>e??void 0),provider:_.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:k.optional().nullable().transform(e=>e??void 0),duration:_.coerce.number().optional().nullable().transform(e=>e??void 0),advancedExpiresAt:k.optional().nullable().transform(e=>e??void 0)}),P=A.extend({logType:_.literal(`provider`),requestId:_.coerce.string(),id:_.coerce.string().optional().nullable().transform(e=>e??void 0),action:_.coerce.string(),mode:_.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:_.coerce.string(),originOwnerId:_.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:_.coerce.string().optional().nullable().transform(e=>e??void 0),url:_.coerce.string(),path:_.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:_.coerce.string(),connectorVersion:_.coerce.string().optional().nullable().transform(e=>e??void 0),resource:_.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:_.coerce.string().optional().nullable().transform(e=>e??void 0),service:_.coerce.string().optional().nullable().transform(e=>e??void 0),success:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:_.coerce.number().optional().nullable().transform(e=>e??void 0),isWorker:_.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:_.coerce.string(),accountSecureId:_.coerce.string(),status:_.coerce.number().optional().nullable().transform(e=>e??void 0),provider:_.coerce.string().optional().nullable().transform(e=>e??void 0),eventDatetime:k.optional().nullable().transform(e=>e??void 0),duration:_.coerce.number().optional().nullable().transform(e=>e??void 0)}),F=_.discriminatedUnion(`logType`,[j,M,N,P]);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 v.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,j),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,M),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,N),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,P),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:s,...c}=r,l={organizationId:e,projectSecureId:t,...c,...i&&i.length>0&&{dimensions:i.map(o).join(`,`)},...a&&{startTime:a.toISOString()},...s&&{endTime:s.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:s,maxValues:c,...l}=r,u={organizationId:e,projectSecureId:n,...l,dimensions:i.map(o).join(`,`),...a&&{startTime:a.toISOString()},...s&&{endTime:s.toISOString()},...c&&{maxValuesPerDim:c}},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(t.startTime,t.endTime);return{logType:`step`,eventTime:n,startTime:t.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.message&&{message:t.message}}}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 g){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,F)}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 g?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 j;case`step`:return M;case`unified`:return N;case`provider`:return P}}};const I={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0}};function resolveOlapOptions(e){return{logs:{...I.logs,...e?.logs},advanced:{...I.advanced,...e?.advanced},defender:{...I.defender,...e?.defender}}}var L=class OlapClient{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;constructor({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={}){this.name=`OlapClient`,this.#s=e,this.#c=r,this.#l=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.#s(this.#c,this.#r),this.#i=new LogsSink(this.#e,this.#t,this.#l,this.#r),this.#a=new AdvancedSink(this.#n,this.#r),this.#o=new DefenderSink(this.#n,this.#r),await this.#i?.initialize(),await this.#a?.initialize(),await this.#o?.initialize()}async recordAction(e,t,n){let{logs:r,advanced:a,defender:o}=resolveOlapOptions(n);this.#r?.debug({message:`Olap client called to record action`,category:`OlapClient`,context:{mode:e.mode,actionId:e.actionId,actionRunId:t.actionRunId,success:t.success,options:n,resolvedOptions:{logs:r,advanced:a,defender:o}}}),i(e.isBackground)&&(e.isBackground=isBackgroundLog(e.mode,e.sourceType));let[s,c]=await Promise.all([a?.enabled&&this.#a?this.#a.sendAction(e,t,a).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null),o?.enabled&&this.#o?this.#o.sendAction(e,t,o).catch(e=>(this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e}),null)):Promise.resolve(null)]),l={advancedExpiresAt:s?.expiresAt,defenderExpiresAt:c?.expiresAt};r?.enabled&&this.#i&&await this.#i.sendAction(e,t,l,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),[a,o]=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))]);if(n?.enabled&&this.#i){let t=e.map((e,t)=>({...e,metadata:{advancedExpiresAt:a[t]?.expiresAt,defenderExpiresAt:o[t]?.expiresAt}}));await this.#i.sendActions(t,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})}}async recordStep(e,t,n){let{logs:r,advanced:i}=resolveOlapOptions(n),a=[];r?.enabled&&this.#i&&a.push(this.#i.sendStep(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.sendStep(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 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:a}=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:a}}}),i(e.isBackground)&&(e.isBackground=isBackgroundLog(e.mode,e.sourceType));let o={advancedExpiresAt:(a?.enabled&&this.#a?await this.#a.sendUnified(e,t,a).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(i(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 a=await this.#i?.getStep(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return a}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(i(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 a=await this.#i?.getProviderLog(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve provider log for requestId ${n} id ${r}`,category:`OlapClient`});return}return a}async getActionAdvancedLog(e,t,n){let r=await this.#a?.getAction(e,t,n);if(i(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 a=await this.#a?.getStep(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${n} stepIndex ${r}`,category:`OlapClient`});return}return a}async getUnifiedAdvancedLog(e,t,n){let r=await this.#a?.getUnified(e,t,n);if(i(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 a=await this.#a?.getProvider(e,t,n,r);if(i(a)){this.#r?.debug({message:`Failed to retrieve provider advanced log for requestId ${n} id ${r}`,category:`OlapClient`});return}return a}async getDefenderLog(e,t,n){let r=await this.#o?.getAction(e,t,n);if(i(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}={})=>L.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{b as Dimension,y as LogType,L as OlapClient,OlapClientManager};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackone/olap",
3
- "version": "1.32.0",
3
+ "version": "1.34.0",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",