@stackone/olap 1.23.0 → 1.25.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 +1 -1
- package/dist/index.d.cts +143 -16
- package/dist/index.d.mts +143 -16
- package/dist/index.mjs +1 -1
- package/package.json +4 -3
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(`node:http`);u=__toESM(u);const d=[`x-datadog-parent-id`,`x-datadog-sampling-priority`,`x-datadog-tags`,`x-datadog-trace-id`,`x-forwarded-proto`,`x-forwarded-port`,`x-forwarded-for`,`x-amzn-trace-id`,`traceparent`,`tracestate`,`x-request-nonce`,`x-signing-method`,`x-signature`,`host`,`via`],f=[`refresh_authentication`],p=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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.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`});continue}if(t.errorsOnly&&r.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${n.mode||`action`}`,category:`AdvancedSink`});continue}if(this.isBackgroundLog(n)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`AdvancedSink`});continue}let e=this.createActionS3(n,r,t?.ttl);await this.send(e)}}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){this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`});return}let r=this.createStepS3(e,t,n?.ttl);await this.send(r)}async sendSteps(e,t){for(let{input:n,result:r}of e)await this.sendStep(n,r,t)}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 send(e,t){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot send to advanced sink`,category:`AdvancedSink`});return}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;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:new Date(i*1e3).toISOString()}});try{await this.#e.send(new c.PutObjectCommand({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:new Date(i*1e3),Tagging:r}))}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}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,p),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,p),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.redactObject)(e.body,s.CensorType.PARTIAL),l=(0,s.redactObject)(t.body,s.CensorType.PARTIAL),u=this.isBackgroundLog(e),d={data:{request:{id:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(a),url:{url:e.url,path:e.pathParams,queryParams:e.queryParams},body:c},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:l},...u?{isBackgroundLog:!0}:{}},metadata:{...u?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(d,r)}serializeStepResult(e,t,n,r){let i={data:{id: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)}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=d.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}isDataSyncRequest(e){return e.mode===`data_sync`}isBackgroundLog(e){return(0,o.notMissing)(e.mode)&&f.includes(e.mode)}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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.statusCode,options:{enabled:t?.enabled}}}),(0,o.isMissing)(r.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:r.actionRunId}});continue}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`});continue}let e=this.createActionS3(r);await this.send(e)}}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){this.#t?.warning({message:`No s3 client available, cannot send to defender sink`,category:`DefenderSink`});return}let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);this.#t?.debug({message:`Storing defender log in S3 bucket ${t}`,category:`DefenderSink`,context:{bucket:t,key:e.Key}});try{await this.#e.send(new c.PutObjectCommand({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType}))}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`}createActionS3(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}},safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}};var SchemaValidationError=class extends Error{constructor(e,t){super(e),this.name=`SchemaValidationError`,this.cause=t}},TinybirdClient=class{#e;#t;#n;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async query(e){try{let t=await this.#o(e.endpoint,e.params);return this.#a(t.data,e.schema)}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryWithPagination(e){try{let t=await this.#o(e.endpoint,e.params),n=this.#a(t.data,e.schema);return{data:n,total:t.rows_before_limit_at_least??t.rows??n.length,pageNumber:e.pageNumber??1,pageSize:e.pageSize??n.length}}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryRaw(e){try{let t=await this.#o(e.endpoint,e.params);return t.data=this.#a(t.data,e.schema),t}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}isReady(){return!!(this.#e&&this.#t?.token)}#r(){return new u.default.Agent({})}#i(){if(!this.#e)throw this.#n?.error({message:`HTTP client not initialized, cannot perform Tinybird query`,category:`TinybirdClient`,code:`HttpClientNotReady`}),Error(`HTTP client is not initialized`);if(!this.#t?.token)throw this.#n?.warning({message:`Missing OLAP token, cannot perform Tinybird query`,category:`TinybirdClient`}),Error(`TinybirdClient - Missing token`)}#a(e,t){if(!t)return e;try{let n=e.map(e=>t.parse(e));return this.#n?.debug({message:`Schema validation passed for ${n.length} rows`,category:`TinybirdClient`}),n}catch(e){let t=e instanceof Error?e.message:String(e);throw this.#n?.error({message:`Schema validation failed: ${t}`,category:`TinybirdClient`,code:`SchemaValidationError`,error:e}),new SchemaValidationError(t,e)}}async#o(e,t){this.#i();let n=this.#e,r=this.#t;if(!n||!r)throw Error(`Client validation failed`);let i=new URL(`/v0/pipes/${e}`,r.baseUrl);this.#n?.debug({message:`Querying Tinybird endpoint: ${e}`,category:`TinybirdClient`,context:{endpoint:e,params:t}});let a=await n.request({method:`post`,url:i.toString(),payload:t,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r.token}`},...r.allowHttp&&{httpAgent:this.#r()}});return this.#n?.debug({message:`Tinybird query returned ${a.data.data.length} rows`,category:`TinybirdClient`,context:{endpoint:e,rows:a.data.rows,statistics:a.data.statistics}}),a.data}};const m=`project_actions_logs.json`,h=`project_steps_logs.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)}get tinybirdClient(){return this.#t}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){await this.sendActions([{input:e,result:t}],n)}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})=>this.buildActionLog(e,t));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 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_actions_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:t.data,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_steps_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:t.data,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 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=Date.now(),r=t.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${r.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:r,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${r.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-n,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${r.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-n,topic:e,messageCount:r.length}}),t}}buildActionLog(e,t){return Object.fromEntries(Object.entries({actionRunId:t.actionRunId,actionId:t.actionId,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,mode:e.mode,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,actionType:t.actionType,category:t.category,originOwnerId:t.originOwnerId,originOwnerName:t.originOwnerName,httpMethod:t.httpMethod,url:t.url,sourceId:e.sourceId,sourceType:e.sourceType,sourceValue:e.sourceValue,success:t.success,statusCode:t.statusCode,riskLevel:t.defenderContext?.riskLevel,tier2Score:t.defenderContext?.tier2Score,startTime:t.startTime,endTime:t.endTime,durationMs:this.calculateDuration(t.startTime,t.endTime),eventTime:new Date}).filter(([,e])=>e!==void 0))}buildStepLog(e,t){return Object.fromEntries(Object.entries({actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,organizationId:String(e.organizationId),projectSecureId:String(e.projectSecureId),accountSecureId:String(e.accountSecureId),skipped:t.skipped,success:t.success,message:t.message,startTime:t.startTime,endTime:t.endTime,durationMs:this.calculateDuration(t.startTime,t.endTime),eventTime:new Date}).filter(([,e])=>e!==void 0))}calculateDuration(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}};const g={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0}};function resolveOlapOptions(e){return{logs:{...g.logs,...e?.logs},advanced:{...g.advanced,...e?.advanced},defender:{...g.defender,...e?.defender}}}var OlapClient=class{#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}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()}get tinybirdClient(){return this.#i?.tinybirdClient}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=[];r?.enabled&&this.#i&&o.push(this.#i.sendAction(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&o.push(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})})),a?.enabled&&this.#o&&o.push(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})})),await Promise.all(o)}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),a=[];n?.enabled&&this.#i&&a.push(this.#i.sendActions(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&a.push(this.#a.sendActions(e,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#o&&a.push(this.#o.sendActions(e,i).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}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).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).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}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 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 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}};const buildOlapClientInstance=async({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};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.OlapClient=OlapClient,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=[`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`],p=[`refresh_authentication`],m=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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.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`});continue}if(t.errorsOnly&&r.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${n.mode||`action`}`,category:`AdvancedSink`});continue}if(this.isBackgroundLog(n)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`AdvancedSink`});continue}let e=this.createActionS3(n,r,t?.ttl);await this.send(e)}}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){this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`});return}let r=this.createStepS3(e,t,n?.ttl);await this.send(r)}async sendSteps(e,t){for(let{input:n,result:r}of e)await this.sendStep(n,r,t)}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 send(e,t){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot send to advanced sink`,category:`AdvancedSink`});return}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;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:new Date(i*1e3).toISOString()}});try{await this.#e.send(new c.PutObjectCommand({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:new Date(i*1e3),Tagging:r}))}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}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,m),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,m),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.redactObject)(e.body,s.CensorType.PARTIAL),l=(0,s.redactObject)(t.body,s.CensorType.PARTIAL),u=this.isBackgroundLog(e),d={data:{request:{id:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(a),url:{url:e.url,path:e.pathParams,queryParams:e.queryParams},body:c},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(o),body:l},...u?{isBackgroundLog:!0}:{}},metadata:{...u?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(d,r)}serializeStepResult(e,t,n,r){let i={data:{id: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)}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=f.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}isDataSyncRequest(e){return e.mode===`data_sync`}isBackgroundLog(e){return(0,o.notMissing)(e.mode)&&p.includes(e.mode)}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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Defender sink called to send action`,category:`DefenderSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.statusCode,options:{enabled:t?.enabled}}}),(0,o.isMissing)(r.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:r.actionRunId}});continue}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`});continue}let e=this.createActionS3(r);await this.send(e)}}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){this.#t?.warning({message:`No s3 client available, cannot send to defender sink`,category:`DefenderSink`});return}let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);this.#t?.debug({message:`Storing defender log in S3 bucket ${t}`,category:`DefenderSink`,context:{bucket:t,key:e.Key}});try{await this.#e.send(new c.PutObjectCommand({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType}))}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`}createActionS3(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}},safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},h=u.z.object({logType:u.z.enum([`action`,`step`,`unified`,`provider`]),eventTime:u.z.coerce.date(),startTime:u.z.coerce.date(),endTime:u.z.coerce.date().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)}),g=h.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(),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)}),_=h.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)}),v=h.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),status:u.z.coerce.number(),success:u.z.coerce.boolean(),isWorker:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0)}),y=h.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(),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(),success:u.z.coerce.boolean(),status:u.z.coerce.number(),isWorker:u.z.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:u.z.coerce.string(),accountSecureId:u.z.coerce.string()}),b=u.z.discriminatedUnion(`logType`,[g,_,v,y]);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 x=`project_logs.json`,S=`project_action_logs.json`,C=`project_step_logs.json`,w=`project_unified_logs.json`,T=`project_provider_logs.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){await this.sendActions([{input:e,result:t}],n)}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})=>this.buildActionLog(e,t));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 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,g),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,_),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,v),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,y),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 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=Date.now(),r=t.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${r.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:r,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${r.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-n,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${r.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-n,topic:e,messageCount:r.length}}),t}}buildActionLog(e,t){let n=new Date,r=this.calculateDurationMs(t.startTime,t.endTime);return{logType:`action`,eventTime:n,startTime:t.startTime??n,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,actionRunId:t.actionRunId,actionId:t.actionId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,...t.endTime&&{endTime:t.endTime},...r!==void 0&&{durationMs:r},...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?.riskLevel&&{riskLevel:t.defenderContext.riskLevel},...t.defenderContext?.tier2Score!==void 0&&{tier2Score:t.defenderContext.tier2Score}}}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}}}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,b)}};const E={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0}};function resolveOlapOptions(e){return{logs:{...E.logs,...e?.logs},advanced:{...E.advanced,...e?.advanced},defender:{...E.defender,...e?.defender}}}var D=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=[];r?.enabled&&this.#i&&o.push(this.#i.sendAction(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&o.push(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})})),a?.enabled&&this.#o&&o.push(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})})),await Promise.all(o)}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),a=[];n?.enabled&&this.#i&&a.push(this.#i.sendActions(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&a.push(this.#a.sendActions(e,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#o&&a.push(this.#o.sendActions(e,i).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}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).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).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}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 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}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>D.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.OlapClient=D,exports.OlapClientManager=OlapClientManager;
|
package/dist/index.d.cts
CHANGED
|
@@ -99,6 +99,7 @@ type DefenderLog = {
|
|
|
99
99
|
//#endregion
|
|
100
100
|
//#region ../transport/src/cacheClient/types.d.ts
|
|
101
101
|
interface ICacheClient<ClientType = unknown> {
|
|
102
|
+
isAvailable(): boolean;
|
|
102
103
|
getData<T>(key: string): Promise<T | null>;
|
|
103
104
|
getDataKeysFromGroup(groupKey: string): Promise<string[] | null>;
|
|
104
105
|
listData<T>({
|
|
@@ -144,7 +145,7 @@ interface ICacheClient<ClientType = unknown> {
|
|
|
144
145
|
unsubscribe?(pattern: string): Promise<boolean>;
|
|
145
146
|
publish?(channel: string, message: string): Promise<number | null>;
|
|
146
147
|
getClient?(): ClientType | null;
|
|
147
|
-
deleteData?(key: string): Promise<boolean>;
|
|
148
|
+
deleteData?(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
148
149
|
close?(): Promise<void> | void;
|
|
149
150
|
}
|
|
150
151
|
type PubSubListener<ReturnsBuffer extends boolean = false> = <T extends (ReturnsBuffer extends true ? Buffer : string)>(message: T, channel: T) => unknown;
|
|
@@ -489,6 +490,28 @@ declare class HttpClient<TError extends Error = Error> implements IHttpClient {
|
|
|
489
490
|
}
|
|
490
491
|
//#endregion
|
|
491
492
|
//#region src/logs/types.d.ts
|
|
493
|
+
type Query = {
|
|
494
|
+
organizationId?: string | string[];
|
|
495
|
+
projectSecureId?: string | string[];
|
|
496
|
+
actionRunId?: string | string[];
|
|
497
|
+
accountSecureId?: string | string[];
|
|
498
|
+
actionId?: string | string[];
|
|
499
|
+
connectorKey?: string | string[];
|
|
500
|
+
mode?: string | string[];
|
|
501
|
+
category?: string | string[];
|
|
502
|
+
logType?: ('action' | 'unified') | ('action' | 'unified')[];
|
|
503
|
+
success?: boolean;
|
|
504
|
+
startTime?: Date;
|
|
505
|
+
endTime?: Date;
|
|
506
|
+
pageNumber?: number;
|
|
507
|
+
pageSize?: number;
|
|
508
|
+
};
|
|
509
|
+
type QueryResult = {
|
|
510
|
+
logs: Array<ActionLog | UnifiedLog | StepLog | ProviderLog>;
|
|
511
|
+
total: number;
|
|
512
|
+
pageNumber: number;
|
|
513
|
+
pageSize: number;
|
|
514
|
+
};
|
|
492
515
|
type ActionsQuery = {
|
|
493
516
|
organizationId?: string | string[];
|
|
494
517
|
projectSecureId?: string | string[];
|
|
@@ -529,6 +552,46 @@ type StepsQueryResult = {
|
|
|
529
552
|
pageNumber: number;
|
|
530
553
|
pageSize: number;
|
|
531
554
|
};
|
|
555
|
+
type UnifiedQuery = {
|
|
556
|
+
organizationId?: string | string[];
|
|
557
|
+
projectSecureId?: string | string[];
|
|
558
|
+
accountSecureId?: string | string[];
|
|
559
|
+
requestId?: string | string[];
|
|
560
|
+
connectorKey?: string | string[];
|
|
561
|
+
resource?: string | string[];
|
|
562
|
+
source?: string | string[];
|
|
563
|
+
category?: string | string[];
|
|
564
|
+
originOwnerId?: string | string[];
|
|
565
|
+
success?: boolean;
|
|
566
|
+
startTime?: Date;
|
|
567
|
+
endTime?: Date;
|
|
568
|
+
pageNumber?: number;
|
|
569
|
+
pageSize?: number;
|
|
570
|
+
};
|
|
571
|
+
type UnifiedQueryResult = {
|
|
572
|
+
unifiedLogs: UnifiedLog[];
|
|
573
|
+
total: number;
|
|
574
|
+
pageNumber: number;
|
|
575
|
+
pageSize: number;
|
|
576
|
+
};
|
|
577
|
+
type ProviderQuery = {
|
|
578
|
+
organizationId?: string | string[];
|
|
579
|
+
projectSecureId?: string | string[];
|
|
580
|
+
accountSecureId?: string | string[];
|
|
581
|
+
requestId?: string | string[];
|
|
582
|
+
id?: string | string[];
|
|
583
|
+
success?: boolean;
|
|
584
|
+
startTime?: Date;
|
|
585
|
+
endTime?: Date;
|
|
586
|
+
pageNumber?: number;
|
|
587
|
+
pageSize?: number;
|
|
588
|
+
};
|
|
589
|
+
type ProviderQueryResult = {
|
|
590
|
+
providerLogs: ProviderLog[];
|
|
591
|
+
total: number;
|
|
592
|
+
pageNumber: number;
|
|
593
|
+
pageSize: number;
|
|
594
|
+
};
|
|
532
595
|
type HttpClientBuilder = (logger?: ILogger) => HttpClient | undefined;
|
|
533
596
|
type SASLMechanism = 'PLAIN' | 'SCRAM-SHA-256' | 'SCRAM-SHA-512';
|
|
534
597
|
interface KafkaClientConfig {
|
|
@@ -587,7 +650,18 @@ interface ITinybirdClient {
|
|
|
587
650
|
queryRaw<TParams = Record<string, unknown>, TResult = unknown>(options: TinybirdQueryOptions<TParams, TResult>): Promise<TinybirdResponse<TResult[]>>;
|
|
588
651
|
isReady(): boolean;
|
|
589
652
|
}
|
|
590
|
-
|
|
653
|
+
interface ILog {
|
|
654
|
+
logType: 'action' | 'step' | 'unified' | 'provider';
|
|
655
|
+
eventTime: Date;
|
|
656
|
+
startTime: Date;
|
|
657
|
+
endTime?: Date;
|
|
658
|
+
durationMs?: number;
|
|
659
|
+
organizationId: string;
|
|
660
|
+
projectSecureId?: string;
|
|
661
|
+
accountSecureId?: string;
|
|
662
|
+
}
|
|
663
|
+
type ActionLog = ILog & {
|
|
664
|
+
logType: 'action';
|
|
591
665
|
actionRunId: string;
|
|
592
666
|
actionId: string;
|
|
593
667
|
connectorKey: string;
|
|
@@ -606,14 +680,11 @@ type ActionLog = {
|
|
|
606
680
|
sourceValue?: string;
|
|
607
681
|
success?: boolean;
|
|
608
682
|
statusCode?: number;
|
|
609
|
-
startTime?: Date;
|
|
610
|
-
endTime?: Date;
|
|
611
|
-
durationMs?: number;
|
|
612
|
-
eventTime?: Date;
|
|
613
683
|
riskLevel?: string;
|
|
614
684
|
tier2Score?: number;
|
|
615
685
|
};
|
|
616
|
-
type StepLog = {
|
|
686
|
+
type StepLog = ILog & {
|
|
687
|
+
logType: 'step';
|
|
617
688
|
actionRunId: string;
|
|
618
689
|
stepIndex: number;
|
|
619
690
|
stepId: string;
|
|
@@ -623,10 +694,56 @@ type StepLog = {
|
|
|
623
694
|
skipped?: boolean;
|
|
624
695
|
success?: boolean;
|
|
625
696
|
message?: string;
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
697
|
+
};
|
|
698
|
+
type UnifiedLog = ILog & {
|
|
699
|
+
logType: 'unified';
|
|
700
|
+
requestId: string;
|
|
701
|
+
connectorKey: string;
|
|
702
|
+
connectorVersion?: string;
|
|
703
|
+
organizationId: string;
|
|
704
|
+
projectSecureId: string;
|
|
705
|
+
accountSecureId: string;
|
|
706
|
+
mode?: string;
|
|
707
|
+
httpMethod?: string;
|
|
708
|
+
url?: string;
|
|
709
|
+
path?: string;
|
|
710
|
+
resource?: string;
|
|
711
|
+
subResource?: string;
|
|
712
|
+
childResource?: string;
|
|
713
|
+
service?: string;
|
|
714
|
+
action?: string;
|
|
715
|
+
sourceId?: string;
|
|
716
|
+
sourceType?: string;
|
|
717
|
+
sourceValue?: string;
|
|
718
|
+
originOwnerId?: string;
|
|
719
|
+
originOwnerName?: string;
|
|
720
|
+
status: number;
|
|
721
|
+
success: boolean;
|
|
722
|
+
isWorker?: boolean;
|
|
723
|
+
};
|
|
724
|
+
type ProviderLog = ILog & {
|
|
725
|
+
logType: 'provider';
|
|
726
|
+
requestId: string;
|
|
727
|
+
id?: string;
|
|
728
|
+
action: string;
|
|
729
|
+
mode?: string;
|
|
730
|
+
httpMethod: string;
|
|
731
|
+
originOwnerId?: string;
|
|
732
|
+
originOwnerName?: string;
|
|
733
|
+
url: string;
|
|
734
|
+
path?: string;
|
|
735
|
+
connectorKey: string;
|
|
736
|
+
connectorVersion?: string;
|
|
737
|
+
resource: string;
|
|
738
|
+
subResource?: string;
|
|
739
|
+
childResource?: string;
|
|
740
|
+
service: string;
|
|
741
|
+
success: boolean;
|
|
742
|
+
status: number;
|
|
743
|
+
isWorker?: boolean;
|
|
744
|
+
organizationId: string;
|
|
745
|
+
projectSecureId: string;
|
|
746
|
+
accountSecureId: string;
|
|
630
747
|
};
|
|
631
748
|
//#endregion
|
|
632
749
|
//#region src/types.d.ts
|
|
@@ -641,10 +758,15 @@ interface IOlapClient {
|
|
|
641
758
|
input: StepInput;
|
|
642
759
|
result: StepResult;
|
|
643
760
|
}>, options?: OlapOptions): Promise<void>;
|
|
761
|
+
getLogs(organizationId: string, projectSecureId: string, query: Query): Promise<QueryResult>;
|
|
644
762
|
getActionLogs(organizationId: string, projectSecureId: string, query: ActionsQuery): Promise<ActionsQueryResult>;
|
|
645
763
|
getActionLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionLog | undefined>;
|
|
646
764
|
getStepLogs(organizationId: string, projectSecureId: string, query: StepsQuery): Promise<StepsQueryResult>;
|
|
647
765
|
getStepLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepLog | undefined>;
|
|
766
|
+
getUnifiedLogs(organizationId: string, projectSecureId: string, query: UnifiedQuery): Promise<UnifiedQueryResult>;
|
|
767
|
+
getUnifiedLog(organizationId: string, projectSecureId: string, requestId: string): Promise<UnifiedLog | undefined>;
|
|
768
|
+
getProviderLogs(organizationId: string, projectSecureId: string, query: ProviderQuery): Promise<ProviderQueryResult>;
|
|
769
|
+
getProviderLog(organizationId: string, projectSecureId: string, requestId: string, id: string): Promise<ProviderLog | undefined>;
|
|
648
770
|
getActionAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionAdvancedLog | undefined>;
|
|
649
771
|
getStepAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepAdvancedLog | undefined>;
|
|
650
772
|
getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
|
|
@@ -741,7 +863,8 @@ type S3ClientBuilder = (config?: S3ClientConfig, logger?: ILogger) => S3Client |
|
|
|
741
863
|
declare class OlapClient implements IOlapClient {
|
|
742
864
|
#private;
|
|
743
865
|
name: string;
|
|
744
|
-
constructor(
|
|
866
|
+
private constructor();
|
|
867
|
+
static create({
|
|
745
868
|
getKafkaClient,
|
|
746
869
|
getHttpClient,
|
|
747
870
|
getS3Client,
|
|
@@ -757,9 +880,8 @@ declare class OlapClient implements IOlapClient {
|
|
|
757
880
|
s3ClientConfig?: S3ClientConfig;
|
|
758
881
|
tinybirdConfig?: TinybirdConfig;
|
|
759
882
|
logger?: ILogger;
|
|
760
|
-
})
|
|
761
|
-
initialize
|
|
762
|
-
get tinybirdClient(): ITinybirdClient | undefined;
|
|
883
|
+
}): Promise<OlapClient>;
|
|
884
|
+
private initialize;
|
|
763
885
|
recordAction(actionInput: ActionInput, actionResult: ActionResult, options?: OlapOptions): Promise<void>;
|
|
764
886
|
recordActions(actions: Array<{
|
|
765
887
|
input: ActionInput;
|
|
@@ -770,10 +892,15 @@ declare class OlapClient implements IOlapClient {
|
|
|
770
892
|
input: StepInput;
|
|
771
893
|
result: StepResult;
|
|
772
894
|
}>, options?: OlapOptions): Promise<void>;
|
|
895
|
+
getLogs(organizationId: string, projectSecureId: string, query: Query): Promise<QueryResult>;
|
|
773
896
|
getActionLogs(organizationId: string, projectSecureId: string, query: ActionsQuery): Promise<ActionsQueryResult>;
|
|
774
897
|
getActionLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionLog | undefined>;
|
|
775
898
|
getStepLogs(organizationId: string, projectSecureId: string, query: StepsQuery): Promise<StepsQueryResult>;
|
|
776
899
|
getStepLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepLog | undefined>;
|
|
900
|
+
getUnifiedLogs(organizationId: string, projectSecureId: string, query: UnifiedQuery): Promise<UnifiedQueryResult>;
|
|
901
|
+
getUnifiedLog(organizationId: string, projectSecureId: string, requestId: string): Promise<UnifiedLog | undefined>;
|
|
902
|
+
getProviderLogs(organizationId: string, projectSecureId: string, query: ProviderQuery): Promise<ProviderQueryResult>;
|
|
903
|
+
getProviderLog(organizationId: string, projectSecureId: string, requestId: string, id: string): Promise<ProviderLog | undefined>;
|
|
777
904
|
getActionAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionAdvancedLog | undefined>;
|
|
778
905
|
getStepAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepAdvancedLog | undefined>;
|
|
779
906
|
getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
|
|
@@ -821,4 +948,4 @@ declare class OlapClientManager {
|
|
|
821
948
|
static resetInstance(): void;
|
|
822
949
|
}
|
|
823
950
|
//#endregion
|
|
824
|
-
export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type DefenderContext, type DefenderLog, type DefenderOptions, type IOlapClient, type ITinybirdClient, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse };
|
|
951
|
+
export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type DefenderContext, type DefenderLog, type DefenderOptions, type ILog, type IOlapClient, type ITinybirdClient, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type ProviderLog, type ProviderQuery, type ProviderQueryResult, type Query, type QueryResult, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse, type UnifiedLog, type UnifiedQuery, type UnifiedQueryResult };
|
package/dist/index.d.mts
CHANGED
|
@@ -99,6 +99,7 @@ type DefenderLog = {
|
|
|
99
99
|
//#endregion
|
|
100
100
|
//#region ../transport/src/cacheClient/types.d.ts
|
|
101
101
|
interface ICacheClient<ClientType = unknown> {
|
|
102
|
+
isAvailable(): boolean;
|
|
102
103
|
getData<T>(key: string): Promise<T | null>;
|
|
103
104
|
getDataKeysFromGroup(groupKey: string): Promise<string[] | null>;
|
|
104
105
|
listData<T>({
|
|
@@ -144,7 +145,7 @@ interface ICacheClient<ClientType = unknown> {
|
|
|
144
145
|
unsubscribe?(pattern: string): Promise<boolean>;
|
|
145
146
|
publish?(channel: string, message: string): Promise<number | null>;
|
|
146
147
|
getClient?(): ClientType | null;
|
|
147
|
-
deleteData?(key: string): Promise<boolean>;
|
|
148
|
+
deleteData?(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
148
149
|
close?(): Promise<void> | void;
|
|
149
150
|
}
|
|
150
151
|
type PubSubListener<ReturnsBuffer extends boolean = false> = <T extends (ReturnsBuffer extends true ? Buffer : string)>(message: T, channel: T) => unknown;
|
|
@@ -489,6 +490,28 @@ declare class HttpClient<TError extends Error = Error> implements IHttpClient {
|
|
|
489
490
|
}
|
|
490
491
|
//#endregion
|
|
491
492
|
//#region src/logs/types.d.ts
|
|
493
|
+
type Query = {
|
|
494
|
+
organizationId?: string | string[];
|
|
495
|
+
projectSecureId?: string | string[];
|
|
496
|
+
actionRunId?: string | string[];
|
|
497
|
+
accountSecureId?: string | string[];
|
|
498
|
+
actionId?: string | string[];
|
|
499
|
+
connectorKey?: string | string[];
|
|
500
|
+
mode?: string | string[];
|
|
501
|
+
category?: string | string[];
|
|
502
|
+
logType?: ('action' | 'unified') | ('action' | 'unified')[];
|
|
503
|
+
success?: boolean;
|
|
504
|
+
startTime?: Date;
|
|
505
|
+
endTime?: Date;
|
|
506
|
+
pageNumber?: number;
|
|
507
|
+
pageSize?: number;
|
|
508
|
+
};
|
|
509
|
+
type QueryResult = {
|
|
510
|
+
logs: Array<ActionLog | UnifiedLog | StepLog | ProviderLog>;
|
|
511
|
+
total: number;
|
|
512
|
+
pageNumber: number;
|
|
513
|
+
pageSize: number;
|
|
514
|
+
};
|
|
492
515
|
type ActionsQuery = {
|
|
493
516
|
organizationId?: string | string[];
|
|
494
517
|
projectSecureId?: string | string[];
|
|
@@ -529,6 +552,46 @@ type StepsQueryResult = {
|
|
|
529
552
|
pageNumber: number;
|
|
530
553
|
pageSize: number;
|
|
531
554
|
};
|
|
555
|
+
type UnifiedQuery = {
|
|
556
|
+
organizationId?: string | string[];
|
|
557
|
+
projectSecureId?: string | string[];
|
|
558
|
+
accountSecureId?: string | string[];
|
|
559
|
+
requestId?: string | string[];
|
|
560
|
+
connectorKey?: string | string[];
|
|
561
|
+
resource?: string | string[];
|
|
562
|
+
source?: string | string[];
|
|
563
|
+
category?: string | string[];
|
|
564
|
+
originOwnerId?: string | string[];
|
|
565
|
+
success?: boolean;
|
|
566
|
+
startTime?: Date;
|
|
567
|
+
endTime?: Date;
|
|
568
|
+
pageNumber?: number;
|
|
569
|
+
pageSize?: number;
|
|
570
|
+
};
|
|
571
|
+
type UnifiedQueryResult = {
|
|
572
|
+
unifiedLogs: UnifiedLog[];
|
|
573
|
+
total: number;
|
|
574
|
+
pageNumber: number;
|
|
575
|
+
pageSize: number;
|
|
576
|
+
};
|
|
577
|
+
type ProviderQuery = {
|
|
578
|
+
organizationId?: string | string[];
|
|
579
|
+
projectSecureId?: string | string[];
|
|
580
|
+
accountSecureId?: string | string[];
|
|
581
|
+
requestId?: string | string[];
|
|
582
|
+
id?: string | string[];
|
|
583
|
+
success?: boolean;
|
|
584
|
+
startTime?: Date;
|
|
585
|
+
endTime?: Date;
|
|
586
|
+
pageNumber?: number;
|
|
587
|
+
pageSize?: number;
|
|
588
|
+
};
|
|
589
|
+
type ProviderQueryResult = {
|
|
590
|
+
providerLogs: ProviderLog[];
|
|
591
|
+
total: number;
|
|
592
|
+
pageNumber: number;
|
|
593
|
+
pageSize: number;
|
|
594
|
+
};
|
|
532
595
|
type HttpClientBuilder = (logger?: ILogger) => HttpClient | undefined;
|
|
533
596
|
type SASLMechanism = 'PLAIN' | 'SCRAM-SHA-256' | 'SCRAM-SHA-512';
|
|
534
597
|
interface KafkaClientConfig {
|
|
@@ -587,7 +650,18 @@ interface ITinybirdClient {
|
|
|
587
650
|
queryRaw<TParams = Record<string, unknown>, TResult = unknown>(options: TinybirdQueryOptions<TParams, TResult>): Promise<TinybirdResponse<TResult[]>>;
|
|
588
651
|
isReady(): boolean;
|
|
589
652
|
}
|
|
590
|
-
|
|
653
|
+
interface ILog {
|
|
654
|
+
logType: 'action' | 'step' | 'unified' | 'provider';
|
|
655
|
+
eventTime: Date;
|
|
656
|
+
startTime: Date;
|
|
657
|
+
endTime?: Date;
|
|
658
|
+
durationMs?: number;
|
|
659
|
+
organizationId: string;
|
|
660
|
+
projectSecureId?: string;
|
|
661
|
+
accountSecureId?: string;
|
|
662
|
+
}
|
|
663
|
+
type ActionLog = ILog & {
|
|
664
|
+
logType: 'action';
|
|
591
665
|
actionRunId: string;
|
|
592
666
|
actionId: string;
|
|
593
667
|
connectorKey: string;
|
|
@@ -606,14 +680,11 @@ type ActionLog = {
|
|
|
606
680
|
sourceValue?: string;
|
|
607
681
|
success?: boolean;
|
|
608
682
|
statusCode?: number;
|
|
609
|
-
startTime?: Date;
|
|
610
|
-
endTime?: Date;
|
|
611
|
-
durationMs?: number;
|
|
612
|
-
eventTime?: Date;
|
|
613
683
|
riskLevel?: string;
|
|
614
684
|
tier2Score?: number;
|
|
615
685
|
};
|
|
616
|
-
type StepLog = {
|
|
686
|
+
type StepLog = ILog & {
|
|
687
|
+
logType: 'step';
|
|
617
688
|
actionRunId: string;
|
|
618
689
|
stepIndex: number;
|
|
619
690
|
stepId: string;
|
|
@@ -623,10 +694,56 @@ type StepLog = {
|
|
|
623
694
|
skipped?: boolean;
|
|
624
695
|
success?: boolean;
|
|
625
696
|
message?: string;
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
697
|
+
};
|
|
698
|
+
type UnifiedLog = ILog & {
|
|
699
|
+
logType: 'unified';
|
|
700
|
+
requestId: string;
|
|
701
|
+
connectorKey: string;
|
|
702
|
+
connectorVersion?: string;
|
|
703
|
+
organizationId: string;
|
|
704
|
+
projectSecureId: string;
|
|
705
|
+
accountSecureId: string;
|
|
706
|
+
mode?: string;
|
|
707
|
+
httpMethod?: string;
|
|
708
|
+
url?: string;
|
|
709
|
+
path?: string;
|
|
710
|
+
resource?: string;
|
|
711
|
+
subResource?: string;
|
|
712
|
+
childResource?: string;
|
|
713
|
+
service?: string;
|
|
714
|
+
action?: string;
|
|
715
|
+
sourceId?: string;
|
|
716
|
+
sourceType?: string;
|
|
717
|
+
sourceValue?: string;
|
|
718
|
+
originOwnerId?: string;
|
|
719
|
+
originOwnerName?: string;
|
|
720
|
+
status: number;
|
|
721
|
+
success: boolean;
|
|
722
|
+
isWorker?: boolean;
|
|
723
|
+
};
|
|
724
|
+
type ProviderLog = ILog & {
|
|
725
|
+
logType: 'provider';
|
|
726
|
+
requestId: string;
|
|
727
|
+
id?: string;
|
|
728
|
+
action: string;
|
|
729
|
+
mode?: string;
|
|
730
|
+
httpMethod: string;
|
|
731
|
+
originOwnerId?: string;
|
|
732
|
+
originOwnerName?: string;
|
|
733
|
+
url: string;
|
|
734
|
+
path?: string;
|
|
735
|
+
connectorKey: string;
|
|
736
|
+
connectorVersion?: string;
|
|
737
|
+
resource: string;
|
|
738
|
+
subResource?: string;
|
|
739
|
+
childResource?: string;
|
|
740
|
+
service: string;
|
|
741
|
+
success: boolean;
|
|
742
|
+
status: number;
|
|
743
|
+
isWorker?: boolean;
|
|
744
|
+
organizationId: string;
|
|
745
|
+
projectSecureId: string;
|
|
746
|
+
accountSecureId: string;
|
|
630
747
|
};
|
|
631
748
|
//#endregion
|
|
632
749
|
//#region src/types.d.ts
|
|
@@ -641,10 +758,15 @@ interface IOlapClient {
|
|
|
641
758
|
input: StepInput;
|
|
642
759
|
result: StepResult;
|
|
643
760
|
}>, options?: OlapOptions): Promise<void>;
|
|
761
|
+
getLogs(organizationId: string, projectSecureId: string, query: Query): Promise<QueryResult>;
|
|
644
762
|
getActionLogs(organizationId: string, projectSecureId: string, query: ActionsQuery): Promise<ActionsQueryResult>;
|
|
645
763
|
getActionLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionLog | undefined>;
|
|
646
764
|
getStepLogs(organizationId: string, projectSecureId: string, query: StepsQuery): Promise<StepsQueryResult>;
|
|
647
765
|
getStepLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepLog | undefined>;
|
|
766
|
+
getUnifiedLogs(organizationId: string, projectSecureId: string, query: UnifiedQuery): Promise<UnifiedQueryResult>;
|
|
767
|
+
getUnifiedLog(organizationId: string, projectSecureId: string, requestId: string): Promise<UnifiedLog | undefined>;
|
|
768
|
+
getProviderLogs(organizationId: string, projectSecureId: string, query: ProviderQuery): Promise<ProviderQueryResult>;
|
|
769
|
+
getProviderLog(organizationId: string, projectSecureId: string, requestId: string, id: string): Promise<ProviderLog | undefined>;
|
|
648
770
|
getActionAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionAdvancedLog | undefined>;
|
|
649
771
|
getStepAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepAdvancedLog | undefined>;
|
|
650
772
|
getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
|
|
@@ -741,7 +863,8 @@ type S3ClientBuilder = (config?: S3ClientConfig, logger?: ILogger) => S3Client |
|
|
|
741
863
|
declare class OlapClient implements IOlapClient {
|
|
742
864
|
#private;
|
|
743
865
|
name: string;
|
|
744
|
-
constructor(
|
|
866
|
+
private constructor();
|
|
867
|
+
static create({
|
|
745
868
|
getKafkaClient,
|
|
746
869
|
getHttpClient,
|
|
747
870
|
getS3Client,
|
|
@@ -757,9 +880,8 @@ declare class OlapClient implements IOlapClient {
|
|
|
757
880
|
s3ClientConfig?: S3ClientConfig;
|
|
758
881
|
tinybirdConfig?: TinybirdConfig;
|
|
759
882
|
logger?: ILogger;
|
|
760
|
-
})
|
|
761
|
-
initialize
|
|
762
|
-
get tinybirdClient(): ITinybirdClient | undefined;
|
|
883
|
+
}): Promise<OlapClient>;
|
|
884
|
+
private initialize;
|
|
763
885
|
recordAction(actionInput: ActionInput, actionResult: ActionResult, options?: OlapOptions): Promise<void>;
|
|
764
886
|
recordActions(actions: Array<{
|
|
765
887
|
input: ActionInput;
|
|
@@ -770,10 +892,15 @@ declare class OlapClient implements IOlapClient {
|
|
|
770
892
|
input: StepInput;
|
|
771
893
|
result: StepResult;
|
|
772
894
|
}>, options?: OlapOptions): Promise<void>;
|
|
895
|
+
getLogs(organizationId: string, projectSecureId: string, query: Query): Promise<QueryResult>;
|
|
773
896
|
getActionLogs(organizationId: string, projectSecureId: string, query: ActionsQuery): Promise<ActionsQueryResult>;
|
|
774
897
|
getActionLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionLog | undefined>;
|
|
775
898
|
getStepLogs(organizationId: string, projectSecureId: string, query: StepsQuery): Promise<StepsQueryResult>;
|
|
776
899
|
getStepLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepLog | undefined>;
|
|
900
|
+
getUnifiedLogs(organizationId: string, projectSecureId: string, query: UnifiedQuery): Promise<UnifiedQueryResult>;
|
|
901
|
+
getUnifiedLog(organizationId: string, projectSecureId: string, requestId: string): Promise<UnifiedLog | undefined>;
|
|
902
|
+
getProviderLogs(organizationId: string, projectSecureId: string, query: ProviderQuery): Promise<ProviderQueryResult>;
|
|
903
|
+
getProviderLog(organizationId: string, projectSecureId: string, requestId: string, id: string): Promise<ProviderLog | undefined>;
|
|
777
904
|
getActionAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<ActionAdvancedLog | undefined>;
|
|
778
905
|
getStepAdvancedLog(organizationId: string, projectSecureId: string, actionRunId: string, stepIndex: number): Promise<StepAdvancedLog | undefined>;
|
|
779
906
|
getDefenderLog(organizationId: string, projectSecureId: string, actionRunId: string): Promise<DefenderLog | undefined>;
|
|
@@ -821,4 +948,4 @@ declare class OlapClientManager {
|
|
|
821
948
|
static resetInstance(): void;
|
|
822
949
|
}
|
|
823
950
|
//#endregion
|
|
824
|
-
export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type DefenderContext, type DefenderLog, type DefenderOptions, type IOlapClient, type ITinybirdClient, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse };
|
|
951
|
+
export { type ActionAdvancedLog, type ActionInput, type ActionLog, type ActionResult, type ActionsQuery, type ActionsQueryResult, type AdvancedOptions, type DefenderContext, type DefenderLog, type DefenderOptions, type ILog, type IOlapClient, type ITinybirdClient, type LogsOptions, OlapClient, OlapClientManager, type OlapOptions, type ProviderLog, type ProviderQuery, type ProviderQueryResult, type Query, type QueryResult, type StepAdvancedLog, type StepInput, type StepLog, type StepResult, type StepsQuery, type StepsQueryResult, type TinybirdConfig, type TinybirdQueryOptions, type TinybirdResponse, type UnifiedLog, type UnifiedQuery, type UnifiedQueryResult };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./chunk-Cfxk5zVN.mjs";import{exceedsSize as t,isMissing as n,notMissing as r}from"@stackone/utils";import{CensorType as i,redactObject as a}from"@stackone/redaction";import{GetObjectCommand as o,PutObjectCommand as s,S3Client as c}from"@aws-sdk/client-s3";import{HttpClient as l}from"@stackone/transport";import u from"node:http";const d=[`x-datadog-parent-id`,`x-datadog-sampling-priority`,`x-datadog-tags`,`x-datadog-trace-id`,`x-forwarded-proto`,`x-forwarded-port`,`x-forwarded-for`,`x-amzn-trace-id`,`traceparent`,`tracestate`,`x-request-nonce`,`x-signing-method`,`x-signature`,`host`,`via`],f=[`refresh_authentication`],p=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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.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`});continue}if(t.errorsOnly&&r.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${n.mode||`action`}`,category:`AdvancedSink`});continue}if(this.isBackgroundLog(n)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`AdvancedSink`});continue}let e=this.createActionS3(n,r,t?.ttl);await this.send(e)}}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){this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`});return}let r=this.createStepS3(e,t,n?.ttl);await this.send(r)}async sendSteps(e,t){for(let{input:n,result:r}of e)await this.sendStep(n,r,t)}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 o({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 s=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for actionRunId ${n}`,category:`AdvancedSink`}),JSON.parse(s)}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 o({Bucket:i,Key:`${e}/${t}/${n}/steps/${r}.json`}),s=await this.#e.send(a);if(!s.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 c=await s.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`}),JSON.parse(c)}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 send(e,t){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot send to advanced sink`,category:`AdvancedSink`});return}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;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:new Date(i*1e3).toISOString()}});try{await this.#e.send(new s({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:new Date(i*1e3),Tagging:r}))}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}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,p),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,p),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let o=a({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},i.PARTIAL),s=o.req?.headers,c=o.res?.headers,l=a(e.body,i.PARTIAL),u=a(t.body,i.PARTIAL),d=this.isBackgroundLog(e),f={data:{request:{id:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(s),url:{url:e.url,path:e.pathParams,queryParams:e.queryParams},body:l},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(c),body:u},...d?{isBackgroundLog:!0}:{}},metadata:{...d?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(f,r)}serializeStepResult(e,t,n,r){let i={data:{id: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)}serializeAndLimit(e,n){if(t(e,n)){let t={...e,data:{outputs:{error:`Error.TOO_LARGE`}}};return JSON.stringify(t)}return JSON.stringify(e)}filterHeaders(e){if(!e)return;let t={},n=d.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}isDataSyncRequest(e){return e.mode===`data_sync`}isBackgroundLog(e){return r(e.mode)&&f.includes(e.mode)}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(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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){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}}}),n(i.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:i.actionRunId}});continue}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`});continue}let e=this.createActionS3(i);await this.send(e)}}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 o({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 s=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved defender log from S3 for actionRunId ${n}`,category:`DefenderSink`}),JSON.parse(s)}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){this.#t?.warning({message:`No s3 client available, cannot send to defender sink`,category:`DefenderSink`});return}let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);this.#t?.debug({message:`Storing defender log in S3 bucket ${t}`,category:`DefenderSink`,context:{bucket:t,key:e.Key}});try{await this.#e.send(new s({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType}))}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`}createActionS3(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({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}},safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}};var SchemaValidationError=class extends Error{constructor(e,t){super(e),this.name=`SchemaValidationError`,this.cause=t}},TinybirdClient=class{#e;#t;#n;constructor(e,t,n){this.#e=e,this.#t=t,this.#n=n}async query(e){try{let t=await this.#o(e.endpoint,e.params);return this.#a(t.data,e.schema)}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryWithPagination(e){try{let t=await this.#o(e.endpoint,e.params),n=this.#a(t.data,e.schema);return{data:n,total:t.rows_before_limit_at_least??t.rows??n.length,pageNumber:e.pageNumber??1,pageSize:e.pageSize??n.length}}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}async queryRaw(e){try{let t=await this.#o(e.endpoint,e.params);return t.data=this.#a(t.data,e.schema),t}catch(t){if(t instanceof SchemaValidationError)throw t;let n=t instanceof Error?t.message:String(t);throw this.#n?.error({message:`Error querying Tinybird endpoint ${e.endpoint}: ${n}`,category:`TinybirdClient`,code:`TinybirdQueryError`}),t}}isReady(){return!!(this.#e&&this.#t?.token)}#r(){return new u.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)}get tinybirdClient(){return this.#t}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){await this.sendActions([{input:e,result:t}],n)}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})=>this.buildActionLog(e,t));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 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_actions_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:t.data,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_steps_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:t.data,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 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=Date.now(),r=t.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${r.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:r,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${r.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-n,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${r.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-n,topic:e,messageCount:r.length}}),t}}buildActionLog(e,t){return Object.fromEntries(Object.entries({actionRunId:t.actionRunId,actionId:t.actionId,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,mode:e.mode,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,actionType:t.actionType,category:t.category,originOwnerId:t.originOwnerId,originOwnerName:t.originOwnerName,httpMethod:t.httpMethod,url:t.url,sourceId:e.sourceId,sourceType:e.sourceType,sourceValue:e.sourceValue,success:t.success,statusCode:t.statusCode,riskLevel:t.defenderContext?.riskLevel,tier2Score:t.defenderContext?.tier2Score,startTime:t.startTime,endTime:t.endTime,durationMs:this.calculateDuration(t.startTime,t.endTime),eventTime:new Date}).filter(([,e])=>e!==void 0))}buildStepLog(e,t){return Object.fromEntries(Object.entries({actionRunId:e.actionRunId,stepIndex:e.stepIndex,stepId:e.stepId,organizationId:String(e.organizationId),projectSecureId:String(e.projectSecureId),accountSecureId:String(e.accountSecureId),skipped:t.skipped,success:t.success,message:t.message,startTime:t.startTime,endTime:t.endTime,durationMs:this.calculateDuration(t.startTime,t.endTime),eventTime:new Date}).filter(([,e])=>e!==void 0))}calculateDuration(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}};const m={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0}};function resolveOlapOptions(e){return{logs:{...m.logs,...e?.logs},advanced:{...m.advanced,...e?.advanced},defender:{...m.defender,...e?.defender}}}var OlapClient=class{#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}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()}get tinybirdClient(){return this.#i?.tinybirdClient}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=[];r?.enabled&&this.#i&&o.push(this.#i.sendAction(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&o.push(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})})),a?.enabled&&this.#o&&o.push(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})})),await Promise.all(o)}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),a=[];n?.enabled&&this.#i&&a.push(this.#i.sendActions(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&a.push(this.#a.sendActions(e,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#o&&a.push(this.#o.sendActions(e,i).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}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).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).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}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,r){let i=await this.#i?.getAction(e,t,r);if(n(i)){this.#r?.debug({message:`Failed to retrieve action log for actionRunId ${r}`,category:`OlapClient`});return}return i}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,r,i){let a=await this.#i?.getStep(e,t,r,i);if(n(a)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${r} stepIndex ${i}`,category:`OlapClient`});return}return a}async getActionAdvancedLog(e,t,r){let i=await this.#a?.getAction(e,t,r);if(n(i)){this.#r?.debug({message:`Failed to retrieve action advanced log for actionRunId ${r}`,category:`OlapClient`});return}return i}async getStepAdvancedLog(e,t,r,i){let a=await this.#a?.getStep(e,t,r,i);if(n(a)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${r} stepIndex ${i}`,category:`OlapClient`});return}return a}async getDefenderLog(e,t,r){let i=await this.#o?.getAction(e,t,r);if(n(i)){this.#r?.debug({message:`Failed to retrieve defender log for actionRunId ${r}`,category:`OlapClient`});return}return i}};const buildOlapClientInstance=async({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};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{OlapClient,OlapClientManager};
|
|
1
|
+
import{t as e}from"./chunk-Cfxk5zVN.mjs";import{exceedsSize as t,isMissing as n,notMissing as r}from"@stackone/utils";import{CensorType as i,redactObject as a}from"@stackone/redaction";import{GetObjectCommand as o,PutObjectCommand as s,S3Client as c}from"@aws-sdk/client-s3";import{HttpClient as l}from"@stackone/transport";import{ZodError as u,z as d}from"zod";import f from"node:http";const p=[`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`],m=[`refresh_authentication`],h=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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){for(let{input:n,result:r}of e){if(this.#t?.debug({message:`Advanced sink called to send action`,category:`AdvancedSink`,context:{mode:n.mode,actionId:n.actionId,actionRunId:r.actionRunId,success:r.success,statusCode:r.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`});continue}if(t.errorsOnly&&r.success){this.#t?.debug({message:`Advanced sink errorsOnly is enabled, skipping successful action for ${n.mode||`action`}`,category:`AdvancedSink`});continue}if(this.isBackgroundLog(n)&&!t.includeBackground){this.#t?.debug({message:`Advanced sink is configured to exclude background logs, skipping action with mode ${n.mode}`,category:`AdvancedSink`});continue}let e=this.createActionS3(n,r,t?.ttl);await this.send(e)}}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){this.#t?.debug({message:`Advanced sink is disabled, skipping sending step to advanced sink`,category:`AdvancedSink`});return}let r=this.createStepS3(e,t,n?.ttl);await this.send(r)}async sendSteps(e,t){for(let{input:n,result:r}of e)await this.sendStep(n,r,t)}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 o({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 s=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved advanced log from S3 for actionRunId ${n}`,category:`AdvancedSink`}),JSON.parse(s)}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 o({Bucket:i,Key:`${e}/${t}/${n}/steps/${r}.json`}),s=await this.#e.send(a);if(!s.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 c=await s.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved step log from S3 for actionRunId ${n} stepIndex ${r}`,category:`AdvancedSink`}),JSON.parse(c)}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 send(e,t){if(!this.#e){this.#t?.warning({message:`No s3 client available, cannot send to advanced sink`,category:`AdvancedSink`});return}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;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:new Date(i*1e3).toISOString()}});try{await this.#e.send(new s({Bucket:n,Key:e.Key,Body:e.Body,ContentType:e.ContentType,Expires:new Date(i*1e3),Tagging:r}))}catch(t){throw this.#t?.error({message:`Failed to write advanced logs to S3 at ${e.Key}`,error:t,code:`AdvancedLogWriteError`,category:`AdvancedSink`}),t}}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,h),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,h),ContentType:`application/json`,Expires:new Date(i*1e3)}}serializeActionResult(e,t,n,r){let o=a({req:{...e.headers&&{headers:{...e.headers}}},res:{...t.headers&&{headers:{...t.headers}}}},i.PARTIAL),s=o.req?.headers,c=o.res?.headers,l=a(e.body,i.PARTIAL),u=a(t.body,i.PARTIAL),d=this.isBackgroundLog(e),f={data:{request:{id:t.actionRunId,actionId:t.actionId,method:t.httpMethod,headers:this.filterHeaders(s),url:{url:e.url,path:e.pathParams,queryParams:e.queryParams},body:l},response:{statusCode:t.statusCode??500,headers:this.filterHeaders(c),body:u},...d?{isBackgroundLog:!0}:{}},metadata:{...d?{isBackgroundLog:!0}:{},expirationTime:n}};return this.serializeAndLimit(f,r)}serializeStepResult(e,t,n,r){let i={data:{id: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)}serializeAndLimit(e,n){if(t(e,n)){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=p.map(e=>e.toLowerCase());for(let[r,i]of Object.entries(e))n.includes(r.toLowerCase())||(t[r]=i);return t}isDataSyncRequest(e){return e.mode===`data_sync`}isBackgroundLog(e){return r(e.mode)&&m.includes(e.mode)}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(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){await this.sendActions([{input:e,result:t}],n)}async sendActions(e,t){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}}}),n(i.defenderContext)){this.#t?.debug({message:`No defender context in action result, skipping sending action to defender sink`,category:`DefenderSink`,context:{actionRunId:i.actionRunId}});continue}if(!t?.enabled){this.#t?.debug({message:`Defender sink is disabled, skipping sending action to defender sink`,category:`DefenderSink`});continue}let e=this.createActionS3(i);await this.send(e)}}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 o({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 s=await a.Body.transformToString();return this.#t?.debug({message:`Successfully retrieved defender log from S3 for actionRunId ${n}`,category:`DefenderSink`}),JSON.parse(s)}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){this.#t?.warning({message:`No s3 client available, cannot send to defender sink`,category:`DefenderSink`});return}let t=process.env.DEFENDER_LOGS_BUCKET;if(!t)throw Error(`DEFENDER_LOGS_BUCKET environment variable is not set`);this.#t?.debug({message:`Storing defender log in S3 bucket ${t}`,category:`DefenderSink`,context:{bucket:t,key:e.Key}});try{await this.#e.send(new s({Bucket:t,Key:e.Key,Body:e.Body,ContentType:e.ContentType}))}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`}createActionS3(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({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}},safeSerialize=e=>{try{return JSON.stringify(e)}catch{return`[Unserializable payload]`}},g=d.object({logType:d.enum([`action`,`step`,`unified`,`provider`]),eventTime:d.coerce.date(),startTime:d.coerce.date(),endTime:d.coerce.date().optional().nullable().transform(e=>e??void 0),durationMs:d.coerce.number().optional().nullable().transform(e=>e??void 0),organizationId:d.coerce.string(),projectSecureId:d.coerce.string().optional().nullable().transform(e=>e??void 0),accountSecureId:d.coerce.string().optional().nullable().transform(e=>e??void 0)}),_=g.extend({logType:d.literal(`action`),actionRunId:d.coerce.string(),actionId:d.coerce.string(),connectorKey:d.coerce.string(),connectorVersion:d.coerce.string(),projectSecureId:d.coerce.string(),accountSecureId:d.coerce.string(),mode:d.coerce.string().optional().nullable().transform(e=>e??void 0),category:d.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:d.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:d.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:d.coerce.string().optional().nullable().transform(e=>e??void 0),url:d.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:d.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:d.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:d.coerce.string().optional().nullable().transform(e=>e??void 0),success:d.coerce.boolean().optional().nullable().transform(e=>e??void 0),statusCode:d.coerce.number().optional().nullable().transform(e=>e??void 0),riskLevel:d.coerce.string().optional().nullable().transform(e=>e??void 0),tier2Score:d.coerce.number().optional().nullable().transform(e=>e??void 0)}),v=g.extend({logType:d.literal(`step`),actionRunId:d.coerce.string(),stepIndex:d.coerce.number(),stepId:d.coerce.string(),projectSecureId:d.coerce.string(),accountSecureId:d.coerce.string(),skipped:d.coerce.boolean().optional().nullable().transform(e=>e??void 0),success:d.coerce.boolean().optional().nullable().transform(e=>e??void 0),message:d.coerce.string().optional().nullable().transform(e=>e??void 0)}),y=g.extend({logType:d.literal(`unified`),requestId:d.coerce.string(),connectorKey:d.coerce.string(),connectorVersion:d.coerce.string().optional().nullable().transform(e=>e??void 0),projectSecureId:d.coerce.string(),accountSecureId:d.coerce.string(),mode:d.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:d.coerce.string().optional().nullable().transform(e=>e??void 0),url:d.coerce.string().optional().nullable().transform(e=>e??void 0),path:d.coerce.string().optional().nullable().transform(e=>e??void 0),resource:d.coerce.string().optional().nullable().transform(e=>e??void 0),subResource:d.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:d.coerce.string().optional().nullable().transform(e=>e??void 0),service:d.coerce.string().optional().nullable().transform(e=>e??void 0),action:d.coerce.string().optional().nullable().transform(e=>e??void 0),sourceId:d.coerce.string().optional().nullable().transform(e=>e??void 0),sourceType:d.coerce.string().optional().nullable().transform(e=>e??void 0),sourceValue:d.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerId:d.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:d.coerce.string().optional().nullable().transform(e=>e??void 0),status:d.coerce.number(),success:d.coerce.boolean(),isWorker:d.coerce.boolean().optional().nullable().transform(e=>e??void 0)}),b=g.extend({logType:d.literal(`provider`),requestId:d.coerce.string(),id:d.coerce.string().optional().nullable().transform(e=>e??void 0),action:d.coerce.string(),mode:d.coerce.string().optional().nullable().transform(e=>e??void 0),httpMethod:d.coerce.string(),originOwnerId:d.coerce.string().optional().nullable().transform(e=>e??void 0),originOwnerName:d.coerce.string().optional().nullable().transform(e=>e??void 0),url:d.coerce.string(),path:d.coerce.string().optional().nullable().transform(e=>e??void 0),connectorKey:d.coerce.string(),connectorVersion:d.coerce.string().optional().nullable().transform(e=>e??void 0),resource:d.coerce.string(),subResource:d.coerce.string().optional().nullable().transform(e=>e??void 0),childResource:d.coerce.string().optional().nullable().transform(e=>e??void 0),service:d.coerce.string(),success:d.coerce.boolean(),status:d.coerce.number(),isWorker:d.coerce.boolean().optional().nullable().transform(e=>e??void 0),projectSecureId:d.coerce.string(),accountSecureId:d.coerce.string()}),x=d.discriminatedUnion(`logType`,[_,v,y,b]);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 f.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){await this.sendActions([{input:e,result:t}],n)}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})=>this.buildActionLog(e,t));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 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,_),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,v),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,y),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,b),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 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=Date.now(),r=t.map(t=>({topic:e,value:safeSerialize(t)}));this.#n?.debug({message:`Sending ${r.length} message(s) to topic ${e}`,category:`KafkaSink`});try{let t=await this.#e.send({messages:r,compression:`gzip`});this.#n?.debug({message:`Successfully sent ${r.length} message(s) to topic ${e}`,category:`KafkaSink`,context:{durationMs:Date.now()-n,topic:e,result:t}})}catch(t){throw this.#n?.error({message:`Error sending ${r.length} message(s) to topic ${e}: ${t.message}`,category:`KafkaSink`,error:t,code:`KafkaSendError`,context:{durationMs:Date.now()-n,topic:e,messageCount:r.length}}),t}}buildActionLog(e,t){let n=new Date,r=this.calculateDurationMs(t.startTime,t.endTime);return{logType:`action`,eventTime:n,startTime:t.startTime??n,organizationId:String(t.organizationId),projectSecureId:t.projectSecureId,accountSecureId:t.accountSecureId,actionRunId:t.actionRunId,actionId:t.actionId,connectorKey:t.connectorKey,connectorVersion:t.connectorVersion,...t.endTime&&{endTime:t.endTime},...r!==void 0&&{durationMs:r},...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?.riskLevel&&{riskLevel:t.defenderContext.riskLevel},...t.defenderContext?.tier2Score!==void 0&&{tier2Score:t.defenderContext.tier2Score}}}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}}}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){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,x)}};const S={logs:{enabled:!0},advanced:{enabled:!1,ttl:7,errorsOnly:!1,includeBackground:!1},defender:{enabled:!0}};function resolveOlapOptions(e){return{logs:{...S.logs,...e?.logs},advanced:{...S.advanced,...e?.advanced},defender:{...S.defender,...e?.defender}}}var C=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=[];r?.enabled&&this.#i&&o.push(this.#i.sendAction(e,t,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#a&&o.push(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})})),a?.enabled&&this.#o&&o.push(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})})),await Promise.all(o)}async recordActions(e,t){let{logs:n,advanced:r,defender:i}=resolveOlapOptions(t),a=[];n?.enabled&&this.#i&&a.push(this.#i.sendActions(e,n).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to kafka: ${e.message}`,category:`OlapClient`,error:e})})),r?.enabled&&this.#a&&a.push(this.#a.sendActions(e,r).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to advanced logs s3: ${e.message}`,category:`OlapClient`,error:e})})),i?.enabled&&this.#o&&a.push(this.#o.sendActions(e,i).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to defender logs s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(a)}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).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).catch(e=>{this.#r?.warning({message:`[OlapClient] Error sending to s3: ${e.message}`,category:`OlapClient`,error:e})})),await Promise.all(i)}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,r){let i=await this.#i?.getAction(e,t,r);if(n(i)){this.#r?.debug({message:`Failed to retrieve action log for actionRunId ${r}`,category:`OlapClient`});return}return i}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,r,i){let a=await this.#i?.getStep(e,t,r,i);if(n(a)){this.#r?.debug({message:`Failed to retrieve step log for actionRunId ${r} stepIndex ${i}`,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,r){let i=await this.#i?.getUnifiedLog(e,t,r);if(n(i)){this.#r?.debug({message:`Failed to retrieve unified log for requestId ${r}`,category:`OlapClient`});return}return i}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,r,i){let a=await this.#i?.getProviderLog(e,t,r,i);if(n(a)){this.#r?.debug({message:`Failed to retrieve provider log for requestId ${r} id ${i}`,category:`OlapClient`});return}return a}async getActionAdvancedLog(e,t,r){let i=await this.#a?.getAction(e,t,r);if(n(i)){this.#r?.debug({message:`Failed to retrieve action advanced log for actionRunId ${r}`,category:`OlapClient`});return}return i}async getStepAdvancedLog(e,t,r,i){let a=await this.#a?.getStep(e,t,r,i);if(n(a)){this.#r?.debug({message:`Failed to retrieve step advanced log for actionRunId ${r} stepIndex ${i}`,category:`OlapClient`});return}return a}async getDefenderLog(e,t,r){let i=await this.#o?.getAction(e,t,r);if(n(i)){this.#r?.debug({message:`Failed to retrieve defender log for actionRunId ${r}`,category:`OlapClient`});return}return i}};const buildOlapClientInstance=async({getKafkaClient:e=buildKafkaClient,getHttpClient:t=buildHttpClient,getS3Client:n=buildS3Client,kafkaClientConfig:r,s3ClientConfig:i,tinybirdConfig:a,logger:o}={})=>C.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{C as OlapClient,OlapClientManager};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackone/olap",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -42,11 +42,12 @@
|
|
|
42
42
|
"license": "ISC",
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@aws-sdk/client-s3": "3.913.0",
|
|
45
|
+
"@platformatic/kafka": "1.31.0",
|
|
45
46
|
"@stackone/logger": "*",
|
|
46
47
|
"@stackone/redaction": "*",
|
|
47
48
|
"@stackone/transport": "*",
|
|
48
49
|
"@stackone/utils": "*",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
50
|
+
"date-fns": "2.30.0",
|
|
51
|
+
"zod": "3.25.76"
|
|
51
52
|
}
|
|
52
53
|
}
|