@seeka-labs/sdk-apps-server-telemetry-core 2.2.6 → 3.2.3
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.
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{fetch as q,Headers as H}from"undici";import{jwtDecode as B}from"jwt-decode";import{getNewOrCachedAppInstallToken as G}from"@seeka-labs/sdk-apps-server";var P=new TextEncoder;function f(t){let e=t>>>0,n=[];for(;e>=128;)n.push(e&127|128),e>>>=7;return n.push(e),Uint8Array.from(n)}function A(t,e){let n=t<<3|e;return f(n)}function c(t,e){if(e==null)return[];let n=P.encode(e);return[A(t,2),f(n.length),n]}function a(t,e){return[A(t,2),f(e.length),e]}function R(t,e){if(e==null)return[];let n=new ArrayBuffer(8);return new DataView(n).setFloat64(0,e,!0),[A(t,1),new Uint8Array(n)]}function o(t){let e=t.filter(s=>s instanceof Uint8Array),n=e.reduce((s,u)=>s+u.length,0),r=new Uint8Array(n),i=0;for(let s of e)r.set(s,i),i+=s.length;return r}function V(t){if(!t)return new Uint8Array(0);let e;if("stringValue"in t&&typeof t.stringValue=="string")e=t.stringValue;else{let r=t.doubleValue??t.intValue??t.boolValue??t.bytesValue??t.arrayValue??t.kvlistValue;try{e=typeof r=="string"?r:JSON.stringify(r)}catch{e=String(r)}}let n=o(c(1,e));return n}function C(t){let e=[];return e.push(...c(1,t.key)),e.push(...a(2,V(t.value))),o(e)}function N(t){if(!t)return new Uint8Array(0);let e=[];for(let n of t.attributes??[])e.push(...a(1,C(n)));return o(e)}function w(t){let e=[];return t&&(e.push(...c(1,t.name)),e.push(...c(2,t.version))),o(e)}function D(t){let e=[];return e.push(...R(4,t.asDouble)),o(e)}function _(t){let e=[];for(let n of t.dataPoints??[])e.push(...a(1,D(n)));return o(e)}function K(t){let e=[];return e.push(...c(1,t.name)),e.push(...c(2,t.description)),e.push(...c(3,t.unit)),t.gauge&&e.push(...a(5,_(t.gauge))),o(e)}function L(t){let e=[];e.push(...a(1,w(t.scope)));for(let n of t.metrics??[])e.push(...a(2,K(n)));return o(e)}function O(t){let e=[];e.push(...a(1,N(t.resource)));for(let n of t.scopeMetrics??[])e.push(...a(2,L(n)));return o(e)}function x(t){let e=[];for(let n of t.resourceMetrics??[]){let r=O(n);e.push(...a(1,r))}return o(e)}var b=t=>{let e=r=>String(r).padStart(2,"0"),n=r=>String(r).padStart(3,"0");return t.getUTCFullYear()+"-"+e(t.getUTCMonth()+1)+"-"+e(t.getUTCDate())+"T"+e(t.getUTCHours())+":"+e(t.getUTCMinutes())+":"+e(t.getUTCSeconds())+"."+n(t.getUTCMilliseconds())};import"winston";import{urls as T}from"@seeka-labs/sdk-apps-server";var E="seeka.tel",h=class{options;constructor(e){this.options=e}pushStr=(e,n,r)=>{n!=null&&r.push({key:`${E}.${e}`,value:{stringValue:String(n)}})};getStr(e,n){let r=`${E}.${e}`,i=n.find(s=>s.key===r);if(i?.value&&"stringValue"in i.value)return i.value.stringValue}sendEgressMetric=async(e,n)=>{let r=[],i=p=>{if(typeof p=="string")return p;try{return JSON.stringify(p??{})}catch{return'""'}},s=new Date;this.pushStr("type","record.activity.egress",r),this.pushStr("originActivityId",e.originActivityId,r),this.pushStr("occurredAt",b(e.occurredAt||s),r),this.pushStr("timestamp",b(s),r),this.pushStr("personId",e.personId,r),this.pushStr("originSessionIdentifier",e.originSessionIdentifier,r),this.pushStr("originDnsName",e.originDnsName,r),this.pushStr("destinationPlatformIdentifier",e.destinationPlatformIdentifier,r),this.pushStr("destinationPlatformEgressType",e.destinationPlatformEgressType,r),this.pushStr("destinationPlatformTypeKey",e.destinationPlatformTypeKey,r),this.pushStr("originActivityName",e.originActivityName,r),this.pushStr("originActivityNameCustom",e.originActivityNameCustom,r),this.pushStr("publishedPayload",i(e.publishedPayload),r),this.pushStr("egressQualityMetrics",i(e.egressQualityMetrics),r),this.pushStr("egressIdentityMetrics",i(e.egressIdentityMetrics),r);let u={resourceMetrics:[{resource:{attributes:r},scopeMetrics:[{scope:{name:"seeka.telemetry.apps-server-core",version:"0.0.0"},metrics:[{name:"record.activity.egress",description:"Activity egress record",unit:"1",gauge:{dataPoints:[{asDouble:1}]}}]}]}]};await this.sendMetric(u,n)};sendMetric=async(e,n)=>{let{telemetryEndpointUrl:r,logger:i,issuerUrl:s,appId:u,appSecret:p}=this.options;if(!e||!Array.isArray(e.resourceMetrics))throw new Error("SeekaTelemetry: metric must be an OTLP ExportMetricsServiceRequest with a resourceMetrics array");let U={appId:u,appSecret:p,issuerUrl:s,ingestUrl:r,applicationInstallId:n.appInstallId,logger:i,grantedPermissions:[],runtime:this.getRuntimeInfo()},m=await G(U);if(!m||!m.access_token)throw new Error("SeekaTelemetry: failed to get access token for install");let v=r.endsWith("/")?r:r+"/",I=new URL("v1/metrics",v).toString(),y=B(m.access_token),l=new H;l.set("Content-Type",this.options.protobuf?"application/x-protobuf":"application/json"),l.set("Accept",this.options.protobuf?"application/x-protobuf":"application/json"),l.set("Authorization",`Bearer ${m.access_token}`),l.set("X-OrgId",y.tenantid);let g=e.resourceMetrics[0]?.resource?.attributes||[];this.pushStr("tenantId",y.tenantid,g),this.pushStr("organisationBrandId",y.org_brand_id,g),this.getStr("type",g)==="record.activity.egress"&&this.pushStr("convergeInstanceId",y.converge_instance_id,g);let M=this.options.protobuf?x(e):JSON.stringify(e),d=await q(I,{method:"POST",headers:l,body:M});if(d.ok)i?.debug("SeekaTelemetry: metric send succeeded");else{let k=await d.text().catch(()=>""),S=`SeekaTelemetry: metric send failed with status ${d.status} ${d.statusText}`;throw i?.error(S,{body:k}),new Error(S)}};shutdown=async()=>{};getRuntimeInfo(){return{type:"sdk/js/apps-server-telemetry-core",ver:"0.0.0",client:{type:"server",ver:process.versions?.node||"unknown"}}}},ee=(t,e)=>new h({...t,appId:t?.appId||process.env.SEEKA_APP_ID,appSecret:t?.appSecret||process.env.SEEKA_APP_SECRET,telemetryEndpointUrl:t?.telemetryEndpointUrl||process.env.SEEKA_TELEMETRY_URL||T.defaultTelemetryUrl,issuerUrl:t?.issuerUrl||process.env.SEEKA_ISSUER_URL||T.defaultIssuerUrl,logger:e});var W=(r=>(r[r.AGGREGATION_TEMPORALITY_UNSPECIFIED=0]="AGGREGATION_TEMPORALITY_UNSPECIFIED",r[r.AGGREGATION_TEMPORALITY_DELTA=1]="AGGREGATION_TEMPORALITY_DELTA",r[r.AGGREGATION_TEMPORALITY_CUMULATIVE=2]="AGGREGATION_TEMPORALITY_CUMULATIVE",r))(W||{}),re=(t,e,n)=>({...e,...t,personId:n.personId,originActivityId:n.activity?.activityId,occurredAt:new Date,originActivityName:n.activity?.activityName,originActivityNameCustom:n.activity?.activityNameCustom,originSessionIdentifier:n.source?.sess,originDnsName:new URL(n.source?.loc||"").hostname.toLowerCase()});export{W as AggregationTemporality,re as createEgressTelemetryRecord,ee as createSeekaTelemetryClient,b as toIsoDateTime};
|
|
2
|
-
//# sourceMappingURL=sdk-apps-server-telemetry-core.module.js.map
|
|
1
|
+
var Fe=Object.create;var K=Object.defineProperty;var qe=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var Ke=Object.getPrototypeOf,Ge=Object.prototype.hasOwnProperty;var d=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var We=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var je=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of $e(t))!Ge.call(e,n)&&n!==r&&K(e,n,{get:()=>t[n],enumerable:!(i=qe(t,n))||i.enumerable});return e};var G=(e,t,r)=>(r=e!=null?Fe(Ke(e)):{},je(t||!e||!e.__esModule?K(r,"default",{value:e,enumerable:!0}):r,e));var V=We((Wt,_e)=>{"use strict";var He=Object.create,T=Object.defineProperty,Je=Object.getOwnPropertyDescriptor,ze=Object.getOwnPropertyNames,Ye=Object.getPrototypeOf,Qe=Object.prototype.hasOwnProperty,Xe=(e,t)=>{for(var r in t)T(e,r,{get:t[r],enumerable:!0})},J=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ze(t))!Qe.call(e,n)&&n!==r&&T(e,n,{get:()=>t[n],enumerable:!(i=Je(t,n))||i.enumerable});return e},p=(e,t,r)=>(r=e!=null?He(Ye(e)):{},J(t||!e||!e.__esModule?T(r,"default",{value:e,enumerable:!0}):r,e)),Ze=e=>J(T({},"__esModule",{value:!0}),e),z={};Xe(z,{ActivityPipelineActivityFilterSourceItemType:()=>ge,ActivityPipelineActivityFilterType:()=>de,AnalyticsLibrary:()=>ye,ApiException:()=>Pe,ApiServiceProxyBase:()=>N,AppPermissionKeys:()=>y,ClickAttributionSourcePlatform:()=>ue,ConditionComparer:()=>pe,ConditionOperator:()=>me,ConsentMappingMatchType:()=>ke,ContentIdentificationBehavior:()=>he,ConvergePipelineLoggableActivityType:()=>oe,ConvergeVendorDestinationPublishStrategy:()=>fe,CrossDomainTrackingUtmBehavior:()=>ve,ECommerceContentType:()=>ie,ECommerceFinancialStatus:()=>ae,ECommerceFulfillmentStatus:()=>se,ECommercePlatform:()=>ne,IabPrivacyConsentPurposeId:()=>Se,IabPrivacyConsentPurposeIdMap:()=>Tt,IdentityServiceProxy:()=>X,IngestServiceProxy:()=>Z,PrivacyConsentType:()=>te,PrivacyDataControlMode:()=>Ie,RegionalConsentGrantOption:()=>Ae,ResponseResultType:()=>ee,SdkLogEventLevel:()=>ce,SeekaApiHelper:()=>Ce,SeekaAppCacheManager:()=>P,SeekaAppConfig:()=>Q,SeekaAppHelper:()=>It,SeekaWebhookCallType:()=>le,TrackingActivityNames:()=>x,TrackingEventSourceOriginType:()=>re,chunk:()=>U,decryptText:()=>Ne,encryptText:()=>Me,getActivityName:()=>rt,getIssuer:()=>_,getNewAppInstallToken:()=>we,getNewOrCachedAppInstallToken:()=>R,isValidSeekaProfileId:()=>xt,matchActivityPipelineFilters:()=>wt,separatePersonFullName:()=>at,throwOnInvalidWebhookSignature:()=>St,urls:()=>Ct,validateWebhookSignature:()=>Ee,webhookSignatureHeaderName:()=>M});_e.exports=Ze(z);var et="3.2.3",Y=p(d("axios")),Q=class{appId;appSecret;ingestUrl;issuerUrl;organisationId;applicationInstallId;runtime;logger;grantedPermissions;transformApiRequest;transformApiResponse;hasAnyPermissions;hasAllPermissions;hasPermission},N=class{config;constructor(e){this.config=e}transformOptions=async e=>await this.config.transformApiRequest(e);transformResult=async(e,t,r)=>await this.config.transformApiResponse(e,t,r)},X=class extends N{instance;baseUrl;jsonParseReviver=void 0;constructor(e,t,r){super(e),this.instance=r||Y.default.create(),this.baseUrl=t??"https://api-localdev-env0-seeka.au.ngrok.io"}merge(e,t){let r=this.baseUrl+"/api/identity";r=r.replace(/[?&]$/,"");let i={data:JSON.stringify(e),method:"POST",url:r,headers:{"Content-Type":"application/json",Accept:"application/json"},cancelToken:t};return this.transformOptions(i).then(n=>this.instance.request(n)).catch(n=>{if(be(n)&&n.response)return n.response;throw n}).then(n=>this.transformResult(r,n,s=>this.processMerge(s)))}processMerge(e){let t=e.status,r={};if(e.headers&&typeof e.headers=="object")for(let i in e.headers)e.headers.hasOwnProperty(i)&&(r[i]=e.headers[i]);if(t===200){let i=e.data,n=null;return n=JSON.parse(i),Promise.resolve(n)}else if(t===400){let i=e.data,n=null;return n=JSON.parse(i),h("A server side error occurred.",t,i,r,n)}else if(t===401){let i=e.data,n=null;return n=JSON.parse(i),h("A server side error occurred.",t,i,r,n)}else if(t===422){let i=e.data,n=null;return n=JSON.parse(i),h("A server side error occurred.",t,i,r,n)}else if(t!==200&&t!==204){let i=e.data;return h("An unexpected server error occurred.",t,i,r)}return Promise.resolve(null)}},Z=class extends N{instance;baseUrl;jsonParseReviver=void 0;constructor(e,t,r){super(e),this.instance=r||Y.default.create(),this.baseUrl=t??"https://api-localdev-env0-seeka.au.ngrok.io"}batch(e,t){let r=this.baseUrl+"/api/ingest";r=r.replace(/[?&]$/,"");let i={data:JSON.stringify(e),method:"POST",url:r,headers:{"Content-Type":"application/json"},cancelToken:t};return this.transformOptions(i).then(n=>this.instance.request(n)).catch(n=>{if(be(n)&&n.response)return n.response;throw n}).then(n=>this.transformResult(r,n,s=>this.processBatch(s)))}processBatch(e){let t=e.status,r={};if(e.headers&&typeof e.headers=="object")for(let i in e.headers)e.headers.hasOwnProperty(i)&&(r[i]=e.headers[i]);if(t===202){let i=e.data;return Promise.resolve(null)}else if(t===400){let i=e.data,n=null;return n=JSON.parse(i),h("A server side error occurred.",t,i,r,n)}else if(t===401){let i=e.data,n=null;return n=JSON.parse(i),h("A server side error occurred.",t,i,r,n)}else if(t===422){let i=e.data,n=null;return n=JSON.parse(i),h("A server side error occurred.",t,i,r,n)}else if(t!==200&&t!==204){let i=e.data;return h("An unexpected server error occurred.",t,i,r)}return Promise.resolve(null)}},ee=(e=>(e.Undefined="undefined",e.Success="success",e.Failed="failed",e))(ee||{}),te=(e=>(e.Unknown="unknown",e.Informed="informed",e.Implied="implied",e.Explicit="explicit",e.Active="active",e.Passive="passive",e))(te||{}),re=(e=>(e.Browser="browser",e.Server="server",e.Mobile="mobile",e.Desktop="desktop",e.PhysicalStore="physicalStore",e.Email="email",e.Phone="phone",e.Chat="chat",e.Automatic="automatic",e))(re||{}),x=(e=>(e.Undefined="undefined",e.PageViewOrganic="pageViewOrganic",e.PageViewUtmAttributed="pageViewUtmAttributed",e.AddPaymentMethod="addPaymentMethod",e.AddToWishlist="addToWishlist",e.ContactMessage="contactMessage",e.Custom="custom",e.SyncCart="syncCart",e.Order="order",e.InitiateCheckout="initiateCheckout",e.AddToCart="addToCart",e.RemoveFromCart="removeFromCart",e.OneTimeItemPurchase="oneTimeItemPurchase",e.SubscriptionItemPurchase="subscriptionItemPurchase",e.ViewProduct="viewProduct",e.ViewPage="viewPage",e.ApplyPromotionalCode="applyPromotionalCode",e.KeywordSearch="keywordSearch",e.UserLoginSignup="userLoginSignup",e.UserLogin="userLogin",e.NewsletterSignup="newsletterSignup",e.Lead="lead",e.ChangeProductAttribute="changeProductAttribute",e.FilterItemsByAttribute="filterItemsByAttribute",e.Schedule="schedule",e.ViewContentItem="viewContentItem",e.StartTrial="startTrial",e))(x||{}),ie=(e=>(e.Undefined="undefined",e.SingleProduct="singleProduct",e.SingleVariant="singleVariant",e.Collection="collection",e))(ie||{}),ne=(e=>(e.None="none",e.BigCommerce="bigCommerce",e.Shopify="shopify",e.OrderGroove="orderGroove",e.Magento="magento",e.Generic="generic",e.WooCommerce="wooCommerce",e.Demandware="demandware",e))(ne||{}),se=(e=>(e.Undefined="undefined",e.Fulfilled="fulfilled",e.NoneFulfilled="noneFulfilled",e.PartiallyFulfilled="partiallyFulfilled",e.RestockedOrCancelled="restockedOrCancelled",e.Pending="pending",e))(se||{}),ae=(e=>(e.Undefined="undefined",e.Pending="pending",e.Authorized="authorized",e.PartiallyPaid="partiallyPaid",e.Paid="paid",e.PartiallyRefunded="partiallyRefunded",e.Refunded="refunded",e.Voided="voided",e))(ae||{}),oe=(e=>(e.Generic="generic",e.ActivityIngress="activityIngress",e.ActivityEgress="activityEgress",e.UserProfile="userProfile",e.SdkLog="sdkLog",e.Detections="detections",e.ActivityEgressFilter="activityEgressFilter",e.Diagnosis="diagnosis",e.PipelineIntegrationOutput="pipelineIntegrationOutput",e))(oe||{}),ce=(e=>(e.Information="information",e.Warning="warning",e.Error="error",e.Verbose="verbose",e))(ce||{}),le=(e=>(e.None="none",e.Probe="probe",e.AppInstalled="appInstalled",e.IdentityChanged="identityChanged",e.ActivityAccepted="activityAccepted",e.AppInstallSettingsUpdated="appInstallSettingsUpdated",e.AppUninstalled="appUninstalled",e.BrowserSdkPlugin="browserSdkPlugin",e))(le||{}),ue=(e=>(e.Unknown="unknown",e.Google="google",e.Meta="meta",e.Snapchat="snapchat",e.Pinterest="pinterest",e.TikTok="tikTok",e))(ue||{}),de=(e=>(e.Undefined="undefined",e.PurchaseMade="purchaseMade",e.ActivityTracked="activityTracked",e))(de||{}),pe=(e=>(e.Undefined="undefined",e.And="and",e.Or="or",e))(pe||{}),ge=(e=>(e.Undefined="undefined",e.Domain="domain",e.Pipeline="pipeline",e.Wildcard="wildcard",e.Url="url",e.PagePath="pagePath",e))(ge||{}),me=(e=>(e.Undefined="undefined",e.Equals="equals",e.NotEquals="notEquals",e.Contains="contains",e.NotContains="notContains",e.StartsWith="startsWith",e.EndsWith="endsWith",e.IsNull="isNull",e.NotNull="notNull",e.IsTrue="isTrue",e.IsFalse="isFalse",e.GreaterThanOrEquals="greaterThanOrEquals",e.LessThanOrEquals="lessThanOrEquals",e.GreaterThan="greaterThan",e.LessThan="lessThan",e.Before="before",e.After="after",e.Between="between",e.In="in",e.NotIn="notIn",e.Regex="regEx",e.Any="any",e))(me||{}),ye=(e=>(e.Undefined="undefined",e.Seeka="seeka",e.DynamicYield="dynamicYield",e.Segment="segment",e.FacebookPixel="facebookPixel",e.GoogleAnalytics="googleAnalytics",e.Braze="braze",e.SnapchatPixel="snapchatPixel",e.Pinterest="pinterest",e.TikTokPixel="tikTokPixel",e.GoogleAds="googleAds",e))(ye||{}),he=(e=>(e.Default="default",e.Sku="sku",e.ProductId="productId",e.VariantId="variantId",e.ProductIdAndVariantIdUnderscore="productIdAndVariantIdUnderscore",e.VariantIdOrProductId="variantIdOrProductId",e))(he||{}),fe=(e=>(e.DeliverAllTraitsAndDeliverAllEvents="deliverAllTraitsAndDeliverAllEvents",e.DeliverAllTraitsAndDeliverEventsOnlyIfMaxWeightedTraitsPresent="deliverAllTraitsAndDeliverEventsOnlyIfMaxWeightedTraitsPresent",e.DeliverMaxWeightedTraitsOnlyAndDeliverAllEvents="deliverMaxWeightedTraitsOnlyAndDeliverAllEvents",e.DeliverMaxWeightedTraitsOnlyAndDeliverEventsOnlyIfMaxWeightedTraitsPresent="deliverMaxWeightedTraitsOnlyAndDeliverEventsOnlyIfMaxWeightedTraitsPresent",e))(fe||{}),ve=(e=>(e.None="none",e.SessionPassthrough="sessionPassthrough",e.UrlPassthrough="urlPassthrough",e))(ve||{}),Ae=(e=>(e.Unset="unset",e.Granted="granted",e.Denied="denied",e))(Ae||{}),Se=(e=>(e.Undefined="undefined",e.MeasureAdvertisingPerformance="measureAdvertisingPerformance",e))(Se||{}),ke=(e=>(e.Undefined="undefined",e.AllOf="allOf",e.AnyOf="anyOf",e))(ke||{}),Ie=(e=>(e.Disabled="disabled",e.Explicit="explicit",e.Implicit="implicit",e))(Ie||{}),Pe=class extends Error{message;status;response;headers;result;constructor(e,t,r,i,n){super(),this.message=e,this.status=t,this.response=r,this.headers=i,this.result=n}isApiException=!0;static isApiException(e){return e.isApiException===!0}};function h(e,t,r,i,n){throw n??new Pe(e,t,r,i,null)}function be(e){return e&&e.isAxiosError===!0}var I=d("openid-client"),O=p(d("winston")),C=p(d("memory-cache")),W="seeka:sdk",P=class{constructor(e,t){this.appId=e,this.appInstallationId=t}appId;appInstallationId;set=async(e,t,r)=>{let i=this.getKey(e);C.default.put(i,JSON.stringify(t),r)};getOrSet=async(e,t,r)=>{let i=this.getKey(e),n=C.default.get(i);if(n){let a=JSON.parse(n);return r&&await r(a),a}let s=await t();return s?(C.default.put(i,JSON.stringify(s.value),s.expiryAbsoluteMilliseconds),s.value):null};getKey=e=>this.appInstallationId?`${W}:${this.appId}:${this.appInstallationId}:${e}`:`${W}:${this.appId}:${e}`},tt=p(d("crypto")),E=()=>{let e=nt(new Date),t=it();return`${e}.${t}`},rt=e=>{let t=Object.keys(x),r=e.toLowerCase(),i=t.find(n=>n.toLowerCase()===r);return i?x[i]:"custom"},it=()=>Math.floor(Math.random()*(9999999999-1e9)+1e9).toString(),nt=e=>{let t=(e.getUTCMonth()+1).toString();t.length<2&&(t="0"+t);let r=e.getUTCDate().toString();r.length<2&&(r="0"+r);let i=e.getUTCHours().toString();i.length<2&&(i="0"+i);let n=e.getUTCMinutes().toString();n.length<2&&(n="0"+n);let s=e.getUTCSeconds().toString();return s.length<2&&(s="0"+s),`${e.getUTCFullYear()}${t}${r}.${i}${n}${s}`},st=e=>tt.createHash("md5").update(e).digest("hex"),at=e=>{if(!e)return{firstName:null,lastName:null};let t=e.trim().split(" ");return t.length===1?{firstName:e,lastName:null}:t.length===2?{firstName:t[0],lastName:t[1]}:{firstName:t[0],lastName:t.slice(1).join(" ")}},U=(e,t)=>e.reduce((r,i,n)=>{let s=Math.floor(n/t);return r[s]||(r[s]=[]),r[s].push(i),r},[]),_=async e=>{let t={applicationId:e.appId,issuer:{url:e.issuerUrl}};e.logger?e.logger.debug("Seeka auth: getting issuer",{...t}):console.debug("Seeka auth: getting issuer",{...t});let r=new P(e.appId,e.applicationInstallId),i=st(e.issuerUrl+"_"+e.appId),n=await r.getOrSet(i,async()=>{try{let s=await ot(e);return!s||!s.meta||!s.raw?null:(e.logger?e.logger.verbose("Seeka auth: got issuer from remote",{...t}):console.debug("Seeka auth: got issuer from remote",{...t}),{value:s.meta,expiryAbsoluteMilliseconds:1e3*60*60})}catch(s){return e.logger?e.logger.error("Seeka auth: failed getting issuer",{...t,ex:O.default.exceptions.getAllInfo(s)}):console.error("Seeka auth: failed getting issuer",{...t}),null}},async()=>{e.logger?e.logger.verbose("Seeka auth: got issuer from cache",{...t}):console.debug("Seeka auth: got issuer from cache",{...t})});return n===null?null:new I.Configuration(n.serverMetadata,n.clientId,e.appSecret)},ot=async e=>{let t={applicationId:e.appId,issuer:{url:e.issuerUrl}};e.logger?e.logger.verbose("Seeka auth: discovering issuer from remote",{...t}):console.info("Seeka auth: discovering issuer from remote",{...t});try{let r=e.appId.replace(/-/g,""),i=await(0,I.discovery)(new URL(e.issuerUrl),r,void 0,(0,I.None)(),{timeout:1e4});return e.logger?e.logger.verbose("Seeka auth: discovered issuer from remote",{...t,client_id:i.clientMetadata().client_id}):console.info("Seeka auth: discovered issuer from remote",{...t,client_id:i.clientMetadata().client_id}),{meta:{serverMetadata:i.serverMetadata(),clientMetadata:i.clientMetadata(),timeout:i.timeout,clientId:r},raw:i}}catch(r){return e.logger?e.logger.error("Seeka auth: failed discovering issuer from remote",{...t,ex:O.default.exceptions.getAllInfo(r)}):console.error("Seeka auth: failed discovering issuer from remote",{...t,err:r}),null}},ct=async e=>{let t={applicationId:e.appId,issuer:{url:e.issuerUrl}},r=await _(e);if(!r)return null;try{let i=await(0,I.clientCredentialsGrant)(r,{resource:r.clientMetadata().client_id}),n={...t,token:{expires_at:i.expires_at,token_type:i.token_type,scope:i.scope}};return e.logger?e.logger.verbose("Seeka auth: got client access token from server",{...n}):console.info("Seeka auth: got app client token from server",{...n}),{token_type:i.token_type,access_token:i.access_token,expires_in:i.expires_in,id_token:i.id_token,refresh_token:i.refresh_token,scope:i.scope,authorization_details:i.authorization_details}}catch(i){let n={...t,error:i};return e.logger?e.logger.error("Seeka auth: failed to get client access token from server",{...n}):console.error("Seeka auth: failed to get client access token from server",{...n,err:O.default.exceptions.getAllInfo(i)}),null}},we=async(e,t)=>{let r={applicationId:t.appId,issuer:{url:t.issuerUrl}},i=await _(t);if(!i||!i)return null;try{let n=await(0,I.genericGrantRequest)(i,"app_install_token",{applicationInstallId:t.applicationInstallId,access_token:e,scope:"Seeka.API.Ingest"}),s={...r,token:{expires_at:n.expires_at,token_type:n.token_type,scope:n.scope}};return t.logger?t.logger.verbose("Seeka auth: got app access token from server",{...s}):console.info("Seeka auth: got app access token from server",{...s}),{token_type:n.token_type,access_token:n.access_token,expires_in:n.expires_in,id_token:n.id_token,refresh_token:n.refresh_token,scope:n.scope,authorization_details:n.authorization_details}}catch(n){let s={...r,error:n};return t.logger?t.logger.error("Seeka auth: failed to get app access token from server",{...s}):console.debug("Seeka auth: failed to get app access token from server",{...s}),null}},R=async e=>{let t=new P(e.appId,e.applicationInstallId),r={applicationId:e.appId,issuer:{url:e.issuerUrl}};return await t.getOrSet("auth:token:appinstall",async()=>{let i=await ct(e);if(!i||!i.access_token)return null;let n=await we(i.access_token,e);return n?{value:n,expiryAbsoluteMilliseconds:((n.expires_in>i.expires_in?i.expires_in:n.expires_in)||900*1e3)-60*1e3}:null},async()=>{e.logger?e.logger.verbose("Seeka auth: got app token from cache",{...r}):console.debug("Seeka auth: got app token from cache",{...r})})},xe="https://router.seeka.services",lt="https://router.seeka.services/tel/otel",Te="https://account.seeka.app",ut=(e,t,r,i,n)=>{let s=new Q;return s.appId=e.applicationId,s.appSecret=t,s.ingestUrl=process.env.SEEKA_INGEST_URL||xe,s.issuerUrl=process.env.SEEKA_ISSUER_URL||Te,s.organisationId=e.organisationId,s.applicationInstallId=e.applicationInstallId,s.runtime={type:"sdk/js/apps-server",ver:et.split("-")[0],client:r},s.logger=n,s.grantedPermissions=i,s.transformApiRequest=a=>dt(s,a),s.transformApiResponse=async(a,o,l)=>pt(s,a,o,l),s.hasAnyPermissions=a=>!s.grantedPermissions||s.grantedPermissions.length===0?!1:!a||a.length===0?!0:a.some(o=>s.grantedPermissions.includes(o)),s.hasAllPermissions=a=>!s.grantedPermissions||s.grantedPermissions.length===0?!1:!a||a.length===0?!0:a.every(o=>s.grantedPermissions.includes(o)),s.hasPermission=a=>!s.grantedPermissions||s.grantedPermissions.length===0?!1:a?s.grantedPermissions.includes(a):!0,s},dt=async(e,t)=>{let r=await R(e);if(!r||!r.access_token)throw new Error("Could not get access token for API request");return t.headers={...t.headers,"X-OrgId":e.organisationId,Authorization:"Bearer "+r?.access_token},t},pt=async(e,t,r,i)=>(r.data=JSON.stringify(r.data),i(r)),y={identity:{receiveFull:"Identity.Receive.Pii",send:"Identity.Send"},activity:{receiveAnon:"Activity.Receive.Anon",receiveFull:"Activity.Receive.Pii",send:"Activity.Send"}},gt=p(d("axios")),mt=p(d("http")),yt=p(d("https")),ht=new mt.default.Agent({keepAlive:!0,scheduling:"fifo"}),ft=new yt.default.Agent({keepAlive:!0,scheduling:"fifo"}),j=e=>{let t=gt.default.create({httpAgent:ht,httpsAgent:ft});return t.interceptors.request.use(function(r){let i={url:r.url,method:r.method};return process.env.LOGGING_LEVEL==="silly"&&(i={...i,body:r.data,params:r.params}),e.logger?e.logger.debug(`Seeka API: making call to ${i.url}`,{...i}):console.debug(`Seeka API: making call to ${i.url}`,{...i}),r},function(r){let i={error:r};return e.logger?e.logger.http("Seeka API: failed to send request",{...i}):console.debug("Seeka API: failed to send request",{...i}),Promise.reject(r)}),t.interceptors.response.use(function(r){let i={url:r.request?.url||r.config.url,method:r.request?.method||r.config.method,response:{status:r.status}};return e.logger?e.logger.http(`Seeka API: call to ${i.url} succeeded`,{...i}):console.debug(`Seeka API: call to ${i.url} succeeded`,{...i}),r},function(r){let{code:i,status:n,message:s}=r,{headers:a,url:o,method:l}=r?.config,u={code:i,status:n,message:s,headers:a,url:o,method:l,content:r?.response?.data};return e.logger?e.logger.error(`Seeka API: call to ${u.url} failed`,{...u}):console.error(`Seeka API: call to ${u.url} failed`,{...u}),Promise.reject(r)}),t},H={getIdentityService:e=>new X(e,e.ingestUrl,j(e)),getIngestService:e=>new Z(e,e.ingestUrl,j(e))},Ce=class{constructor(e){this.config=e,this.ingestionService=H.getIngestService(e),this.identityService=H.getIdentityService(e)}config;maxBatchSize=50;refreshOrPrimeTokenCache=async()=>{await R(this.config)};ingestionService;identityService;checkPermission=(e,t)=>{if(!this.config.hasPermission(e))throw new Error("Cannot perform operation "+t+" on installationId "+this.config.applicationInstallId+" without permission "+e+". Currently granted permissions: "+(this.config.grantedPermissions?this.config.grantedPermissions.join(", "):"none"));return!0};mergeIdentity=async(e,t)=>{this.checkPermission(y.identity.send,"mergeIdentity");let r=E();return(await this.identityService.merge({id:e,src:{method:"",origin:t.origin,time:void 0,loc:t.loc,sess:r,diag:process.env.SEEKA_DEBUG_ENABLED==="true"?r:void 0,runtime:this.config.runtime}})).result?.personId};mergeIdentityBatch=async(e,t)=>{this.checkPermission(y.identity.send,"mergeIdentityBatch");let r=E();if(e.length===0){this.config.logger?.debug("No identities in batch");return}let i={method:"",origin:t.origin,time:void 0,loc:t.loc,sess:r,diag:process.env.SEEKA_DEBUG_ENABLED==="true"?r:void 0,runtime:this.config.runtime},n=U(e,this.maxBatchSize);if(n.length>1&&this.config.logger&&this.config.logger.debug(`Identity batch size ${e} is greater than ${this.maxBatchSize}, splitting into ${n.length} batches`),await this.trackActivityBatchRaw({data:n[0].map(s=>({id:{id:s||{},src:{...i}}}))}),n.length>1){let s=n.map((a,o)=>o===0?Promise.resolve():(this.config.logger?.verbose(`Processing identity batch ${o+1} of ${n.length}`),this.trackActivityBatchRaw({data:a.map(l=>({id:{id:l||{},src:{...i}}}))})));await Promise.all(s)}};trackActivityBatch=async(e,t)=>{this.checkPermission(y.activity.send,"trackActivityBatch");let r=E();if(e.length===0){this.config.logger?.debug("No activities in batch");return}let i={method:"",origin:t.origin,time:void 0,loc:t.loc,sess:r,diag:process.env.SEEKA_DEBUG_ENABLED==="true"?r:void 0,runtime:this.config.runtime},n=U(e,this.maxBatchSize);if(n.length>1&&this.config.logger&&this.config.logger.debug(`Activity batch size ${e.length} is greater than ${this.maxBatchSize}, splitting into ${n.length} batches`),await this.trackActivityBatchRaw({data:n[0].map(s=>({ev:{id:s.profile||{},src:{...i},payload:s.activity}}))}),n.length>1){let s=n.map((a,o)=>o===0?Promise.resolve():(this.config.logger?.verbose(`Processing activity batch ${o+1} of ${n.length}`),this.trackActivityBatchRaw({data:a.map(l=>({ev:{id:l.profile||{},src:{...i},payload:l.activity}}))})));await Promise.all(s)}};trackActivityBatchRaw=async e=>{await this.ingestionService.batch(e)};trackActivityForProfileId=async(e,t,r)=>{this.checkPermission(y.activity.send,"trackActivityForProfileId"),await this.trackActivityForProfileIdBatch([e],t,r)};trackActivityForProfileIdBatch=async(e,t,r)=>{this.checkPermission(y.activity.send,"trackActivityForProfileIdBatch"),await this.trackActivityBatch(e.map(i=>({activity:i,profile:t?{seekaPId:t}:void 0})),r)};trackActivityForProfile=async(e,t,r)=>{this.checkPermission(y.activity.send,"trackActivityForProfile"),await this.trackActivityForProfileBatch([e],t,r)};trackActivityForProfileBatch=async(e,t,r)=>{this.checkPermission(y.activity.send,"trackActivityForProfileBatch"),await this.trackActivityBatch(e.map(i=>({activity:i,profile:t})),r)}},vt=p(d("crypto")),M="x-seeka-signature-sha256",Ee=(e,t,r)=>{if(!t)return!1;let i=null;if(t.get&&typeof t.get=="function")i=t.get(M);else{let s=t[M];s&&(Array.isArray(s)&&s.length>0?i=s[0]:(typeof s=="string"||s instanceof String)&&(i=s))}if(!i)return!1;let n=At(e,r)===i;return n||console.warn("Invalid webhook signature"),n},At=(e,t)=>vt.createHmac("sha256",e).update(t).digest("hex"),St=(e,t,r)=>{if(!Ee(e,t,r))throw new Error("Invalid webhook signature")},k=p(d("crypto")),Ue="aes-192-cbc",Me=(e,t)=>{if(!e)return"";if(!t)throw new Error("Secret is required to encrypt data");let r=k.default.scryptSync(t,"salt",24),i=k.default.randomBytes(16),n=k.default.createCipheriv(Ue,r,i);return[n.update(e,"utf8","hex")+n.final("hex"),Buffer.from(i).toString("hex")].join("|")},Ne=(e,t)=>{if(!e)return"";if(!t)throw new Error("Secret is required to decrypt data");let[r,i]=e.split("|");if(!i)throw new Error("IV not found");let n=k.default.scryptSync(t,"salt",24),s=k.default.createDecipheriv(Ue,n,Buffer.from(i,"hex"));return s.update(r,"hex","utf8")+s.final("utf8")},kt=class{constructor(e){this.appSecret=e}appSecret;encryptWithAppSecret=e=>{if(!this.appSecret)throw new Error("App secret is required to encrypt data");return Me(e,this.appSecret)};decryptWithAppSecret=e=>{if(!this.appSecret)throw new Error("App secret is required to decrypt data");return Ne(e,this.appSecret)}},It=class Oe{constructor(t,r){this.context=t,this.api=new Ce(t.config),this.appCache=new P(t.config.appId),this.appInstallCache=new P(t.config.appId,t.config.applicationInstallId),this.crypto=new kt(t.config.appSecret),this.logger=r}context;appCache;appInstallCache;api;logger;crypto;static create=(t,r,i,n,s)=>new Oe({config:ut({...r},t,{type:i.name,ver:i.version.split("-")[0]},n,s)},s)},Pt=p(d("winston")),bt=["order","subscriptionItemPurchase","oneTimeItemPurchase"],wt=(e,t,r)=>{if(!e.activity)return[];let i=e.activity,n=i.activityName==="custom"?i.activityNameCustom:i.activityName;if(!n)return[];let s=n.toLowerCase(),a=[];return t.forEach(o=>{if(!o)return;switch(o.type){case"activityTracked":{if(!o.activityNames||!o.activityNames.find(c=>c.toLowerCase()===s))return;r.verbose("Matched activity tracked filter",{filter:o,activityName:n});break}case"purchaseMade":{if(!i.activityName||!bt.includes(i.activityName))return;r.verbose("Matched purchase made activity filter",{filter:o,activityName:n});break}default:{r.warn("Unknown activity filter type",{filter:o});return}}let l=o.sourceFilter;if(!l)return;let u=e.source,f;try{f=u?.loc?new URL(u.loc).hostname.toLowerCase():null}catch(c){r.error("Failed to parse activity source URL",{ex:Pt.default.exceptions.getAllInfo(c),activitySource:u}),f=null}let S=u?.pipeline?.convergePipelineIntegrationInstanceId?.toLowerCase(),v=l.filters?l.filters.map(c=>{switch(c.type){case"wildcard":return r.verbose("Matched wildcard source filter",{sourceFilter:c}),!0;case"domain":return!f||!c.key?!1:f===c.key.toLowerCase()?(r.verbose("Matched domain source filter",{sourceFilter:c,activityHostname:f}),!0):!1;case"pipeline":return!S||!c.key?!1:S===c.key.toLowerCase()?(r.verbose("Matched pipeline source filter",{sourceFilter:c,sourceConvergePipelineIntegrationInstanceId:S}),!0):!1}}):[];switch(l.comparer){case"and":{v.every(c=>c===!0)&&a.push(o);break}case"or":{v.some(c=>c===!0)&&a.push(o);break}default:{r.warn("Unknown source filter comparer",{sourceFilters:l});break}}}),a};function xt(e){if(!e||e.trim().length===0)return!1;let t=e.split(".").filter(r=>r.trim().length>0);return!(t.length!==4||t[0].toLowerCase()!=="sk".toLowerCase()||t[1].toLowerCase()!=="1".toLowerCase()||isNaN(parseInt(t[2],10))||isNaN(parseInt(t[3],10)))}var Tt={measureAdvertisingPerformance:7},Ct={defaultIssuerUrl:Te,defaultTelemetryUrl:lt,defaultIngestUrl:xe}});var De=G(V(),1);import{fetch as Ft,Headers as qt}from"undici";import{jwtDecode as $t}from"jwt-decode";var Et=new TextEncoder;function D(e){let t=e>>>0,r=[];for(;t>=128;)r.push(t&127|128),t>>>=7;return r.push(t),Uint8Array.from(r)}function B(e,t){let r=e<<3|t;return D(r)}function A(e,t){if(t==null)return[];let r=Et.encode(t);return[B(e,2),D(r.length),r]}function m(e,t){return[B(e,2),D(t.length),t]}function Ut(e,t){if(t==null)return[];let r=new ArrayBuffer(8);return new DataView(r).setFloat64(0,t,!0),[B(e,1),new Uint8Array(r)]}function g(e){let t=e.filter(s=>s instanceof Uint8Array),r=t.reduce((s,a)=>s+a.length,0),i=new Uint8Array(r),n=0;for(let s of t)i.set(s,n),n+=s.length;return i}function Mt(e){if(!e)return new Uint8Array(0);let t;if("stringValue"in e&&typeof e.stringValue=="string")t=e.stringValue;else{let i=e.doubleValue??e.intValue??e.boolValue??e.bytesValue??e.arrayValue??e.kvlistValue;try{t=typeof i=="string"?i:JSON.stringify(i)}catch{t=String(i)}}let r=g(A(1,t));return r}function Nt(e){let t=[];return t.push(...A(1,e.key)),t.push(...m(2,Mt(e.value))),g(t)}function Ot(e){if(!e)return new Uint8Array(0);let t=[];for(let r of e.attributes??[])t.push(...m(1,Nt(r)));return g(t)}function _t(e){let t=[];return e&&(t.push(...A(1,e.name)),t.push(...A(2,e.version))),g(t)}function Rt(e){let t=[];return t.push(...Ut(4,e.asDouble)),g(t)}function Vt(e){let t=[];for(let r of e.dataPoints??[])t.push(...m(1,Rt(r)));return g(t)}function Dt(e){let t=[];return t.push(...A(1,e.name)),t.push(...A(2,e.description)),t.push(...A(3,e.unit)),e.gauge&&t.push(...m(5,Vt(e.gauge))),g(t)}function Bt(e){let t=[];t.push(...m(1,_t(e.scope)));for(let r of e.metrics??[])t.push(...m(2,Dt(r)));return g(t)}function Lt(e){let t=[];t.push(...m(1,Ot(e.resource)));for(let r of e.scopeMetrics??[])t.push(...m(2,Bt(r)));return g(t)}function Re(e){let t=[];for(let r of e.resourceMetrics??[]){let i=Lt(r);t.push(...m(1,i))}return g(t)}var L=e=>{let t=i=>String(i).padStart(2,"0"),r=i=>String(i).padStart(3,"0");return e.getUTCFullYear()+"-"+t(e.getUTCMonth()+1)+"-"+t(e.getUTCDate())+"T"+t(e.getUTCHours())+":"+t(e.getUTCMinutes())+":"+t(e.getUTCSeconds())+"."+r(e.getUTCMilliseconds())};var F=G(V(),1);import"winston";var Ve="seeka.tel",q=class{options;constructor(t){this.options=t}pushStr=(t,r,i)=>{r!=null&&i.push({key:`${Ve}.${t}`,value:{stringValue:String(r)}})};getStr(t,r){let i=`${Ve}.${t}`,n=r.find(s=>s.key===i);if(n?.value&&"stringValue"in n.value)return n.value.stringValue}sendEgressMetric=async(t,r)=>{let i=[],n=o=>{if(typeof o=="string")return o;try{return JSON.stringify(o??{})}catch{return'""'}},s=new Date;this.pushStr("type","record.activity.egress",i),this.pushStr("originActivityId",t.originActivityId,i),this.pushStr("occurredAt",L(t.occurredAt||s),i),this.pushStr("timestamp",L(s),i),this.pushStr("personId",t.personId,i),this.pushStr("originSessionIdentifier",t.originSessionIdentifier,i),this.pushStr("originDnsName",t.originDnsName,i),this.pushStr("destinationPlatformIdentifier",t.destinationPlatformIdentifier,i),this.pushStr("destinationPlatformEgressType",t.destinationPlatformEgressType,i),this.pushStr("destinationPlatformTypeKey",t.destinationPlatformTypeKey,i),this.pushStr("originActivityName",t.originActivityName,i),this.pushStr("originActivityNameCustom",t.originActivityNameCustom,i),this.pushStr("publishedPayload",n(t.publishedPayload),i),this.pushStr("egressQualityMetrics",n(t.egressQualityMetrics),i),this.pushStr("egressIdentityMetrics",n(t.egressIdentityMetrics),i);let a={resourceMetrics:[{resource:{attributes:i},scopeMetrics:[{scope:{name:"seeka.telemetry.apps-server-host",version:"0.0.0"},metrics:[{name:"record.activity.egress",description:"Activity egress record",unit:"1",gauge:{dataPoints:[{asDouble:1}]}}]}]}]};await this.sendMetric(a,r)};sendMetric=async(t,r)=>{let{telemetryEndpointUrl:i,logger:n,issuerUrl:s,appId:a,appSecret:o}=this.options;if(!t||!Array.isArray(t.resourceMetrics))throw new Error("SeekaTelemetry: metric must be an OTLP ExportMetricsServiceRequest with a resourceMetrics array");let l={appId:a,appSecret:o,issuerUrl:s,ingestUrl:i,applicationInstallId:r.appInstallId,logger:n,grantedPermissions:[],runtime:this.getRuntimeInfo()},u=await(0,De.getNewOrCachedAppInstallToken)(l);if(!u||!u.access_token)throw new Error("SeekaTelemetry: failed to get access token for install");let f=i.endsWith("/")?i:i+"/",S=new URL("v1/metrics",f).toString(),v=$t(u.access_token),c=new qt;c.set("Content-Type",this.options.protobuf?"application/x-protobuf":"application/json"),c.set("Accept",this.options.protobuf?"application/x-protobuf":"application/json"),c.set("Authorization",`Bearer ${u.access_token}`),c.set("X-OrgId",v.tenantid);let b=t.resourceMetrics[0]?.resource?.attributes||[];this.pushStr("tenantId",v.tenantid,b),this.pushStr("organisationBrandId",v.org_brand_id,b),this.getStr("type",b)==="record.activity.egress"&&this.pushStr("convergeInstanceId",v.converge_instance_id,b);let Be=this.options.protobuf?Re(t):JSON.stringify(t),w=await Ft(S,{method:"POST",headers:c,body:Be});if(w.ok)n?.debug("SeekaTelemetry: metric send succeeded");else{let Le=await w.text().catch(()=>""),$=`SeekaTelemetry: metric send failed with status ${w.status} ${w.statusText}`;throw n?.error($,{body:Le}),new Error($)}};shutdown=async()=>{};getRuntimeInfo(){return{type:"sdk/js/apps-server-telemetry-core",ver:"0.0.0",client:{type:"server",ver:process.versions?.node||"unknown"}}}},or=(e,t)=>new q({...e,appId:e?.appId||process.env.SEEKA_APP_ID,appSecret:e?.appSecret||process.env.SEEKA_APP_SECRET,telemetryEndpointUrl:e?.telemetryEndpointUrl||process.env.SEEKA_TELEMETRY_URL||F.urls.defaultTelemetryUrl,issuerUrl:e?.issuerUrl||process.env.SEEKA_ISSUER_URL||F.urls.defaultIssuerUrl,logger:t});var Kt=(i=>(i[i.AGGREGATION_TEMPORALITY_UNSPECIFIED=0]="AGGREGATION_TEMPORALITY_UNSPECIFIED",i[i.AGGREGATION_TEMPORALITY_DELTA=1]="AGGREGATION_TEMPORALITY_DELTA",i[i.AGGREGATION_TEMPORALITY_CUMULATIVE=2]="AGGREGATION_TEMPORALITY_CUMULATIVE",i))(Kt||{}),lr=(e,t,r)=>({...t,...e,personId:r.personId,originActivityId:r.activity?.activityId,occurredAt:new Date,originActivityName:r.activity?.activityName,originActivityNameCustom:r.activity?.activityNameCustom,originSessionIdentifier:r.source?.sess,originDnsName:new URL(r.source?.loc||"").hostname.toLowerCase()});export{Kt as AggregationTemporality,lr as createEgressTelemetryRecord,or as createSeekaTelemetryClient,L as toIsoDateTime};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seeka-labs/sdk-apps-server-telemetry-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"description": "Seeka - Apps SDK - Server Telemetry Core (lightweight OTLP/HTTP exporter wrapper)",
|
|
5
5
|
"author": "SEEKA <platform@seeka.co>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,13 +24,15 @@
|
|
|
24
24
|
"module": "./dist/lib/sdk-apps-server-telemetry-core.module.js",
|
|
25
25
|
"scripts": {
|
|
26
26
|
"clean": "rimraf build package dist",
|
|
27
|
-
"
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"build": "yarn esbuild src/index.ts --outfile=dist/lib/sdk-apps-server-telemetry-core.module.js --bundle --analyze --platform=node --format=esm --packages=external --minify && yarn tsc --emitDeclarationOnly",
|
|
28
29
|
"dev": "yarn esbuild src/index.ts --outfile=dist/lib/sdk-apps-server-telemetry-core.module.js --bundle --analyze --platform=node --format=esm --packages=external --sourcemap && yarn tsc --emitDeclarationOnly",
|
|
29
30
|
"build:ci": "yarn run build",
|
|
30
31
|
"test": "ava"
|
|
31
32
|
},
|
|
32
33
|
"peerDependencies": {
|
|
33
|
-
"@seeka-labs/sdk-apps-
|
|
34
|
+
"@seeka-labs/sdk-apps-core": "workspace:* || ^3",
|
|
35
|
+
"@seeka-labs/sdk-apps-server": "workspace:* || ^3",
|
|
34
36
|
"axios": "^1",
|
|
35
37
|
"memory-cache": "^0",
|
|
36
38
|
"openid-client": "^6",
|
|
@@ -44,8 +46,9 @@
|
|
|
44
46
|
"@babel/core": "^7",
|
|
45
47
|
"@babel/preset-env": "^7",
|
|
46
48
|
"@babel/preset-typescript": "^7",
|
|
47
|
-
"@seeka-labs/sdk-apps-
|
|
48
|
-
"@
|
|
49
|
+
"@seeka-labs/sdk-apps-core": "^3.2.3",
|
|
50
|
+
"@seeka-labs/sdk-apps-server": "^3.2.3",
|
|
51
|
+
"@types/node": "^22",
|
|
49
52
|
"ava": "^6",
|
|
50
53
|
"axios": "^1",
|
|
51
54
|
"cross-env": "^10",
|
|
@@ -59,5 +62,5 @@
|
|
|
59
62
|
"undici": "^7",
|
|
60
63
|
"winston": "^3"
|
|
61
64
|
},
|
|
62
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "2e406e463088cdf6ccdb2e2b15eb35c369b729c0"
|
|
63
66
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/client.ts", "../../src/otlpEncoder.ts", "../../src/helpers.ts", "../../src/models.ts"],
|
|
4
|
-
"sourcesContent": ["\uFEFF\n\n// We use undici's fetch for Node environments\nimport { fetch as undiciFetch, Headers as UndiciHeaders } from 'undici';\n// For safely requiring CJS modules from ESM (used under Jest)\n// import { createRequire } from 'node:module';\n\nimport {jwtDecode, type JwtPayload} from \"jwt-decode\";\n\n// OTLP metric types (type-safe input)\nimport {type AppRuntimeInfo, getNewOrCachedAppInstallToken} from \"@seeka-labs/sdk-apps-server\";\nimport type {\n ActivityEgressTelemetryRecord,\n ExportMetricsServiceRequest, KeyValue, SeekaTelemetryClientCore, SeekaTelemetryClientCoreOptions,\n SeekaTelemetryInstallContext\n} from \"./models.ts\";\nimport { encodeExportMetricsServiceRequestToProto } from './otlpEncoder.ts';\nimport {toIsoDateTime} from \"./helpers.ts\";\nimport * as winston from \"winston\";\nimport {urls} from \"@seeka-labs/sdk-apps-server\";\n\nconst attrPrefix = 'seeka.tel';\n\nclass SeekaTelemetryClientCoreImpl implements SeekaTelemetryClientCore {\n private readonly options: SeekaTelemetryClientCoreOptions;\n\n constructor(options: SeekaTelemetryClientCoreOptions) {\n this.options = options;\n }\n\n private pushStr = (key: string, value: string | undefined | null, attrs: KeyValue[]) => {\n if (value == null) return;\n attrs.push({ key: `${attrPrefix}.${key}`, value: { stringValue: String(value) } });\n };\n\n private getStr(key: string, attrs: KeyValue[]): string | undefined {\n const targetKey = `${attrPrefix}.${key}`;\n const attr = attrs.find((a) => a.key === targetKey);\n\n if (attr?.value && 'stringValue' in attr.value) {\n return attr.value.stringValue;\n }\n\n return undefined;\n }\n\n // Convenience: build and send a standardised record.activity.egress metric\n public sendEgressMetric = async (\n record: ActivityEgressTelemetryRecord,\n installContext: SeekaTelemetryInstallContext\n ): Promise<void> => {\n const attrs: KeyValue[] = [];\n\n const stringifyJson = (v: unknown): string => {\n if (typeof v === 'string') return v;\n try { return JSON.stringify(v ?? {}); } catch { return '\"\"'; }\n };\n\n const now = new Date();\n // Required core attributes (resource-level) \u2014 default certain values from installContext when sensible\n this.pushStr('type', 'record.activity.egress', attrs);\n // this.pushStr('tenantId', record.tenantId ?? installContext.organisationId, attrs);\n this.pushStr('originActivityId', record.originActivityId, attrs);\n // this.pushStr('convergeInstanceId', record.convergeInstanceId, attrs);\n // this.pushStr('organisationBrandId', record.organisationBrandId, attrs);\n this.pushStr('occurredAt', toIsoDateTime(record.occurredAt || now), attrs);\n this.pushStr('timestamp', toIsoDateTime(now), attrs);\n // pushStr('occurredAt', (record.occurredAt || now).toISOString());\n // pushStr('timestamp', now.toISOString());\n\n // Strings\n this.pushStr('personId', record.personId, attrs);\n this.pushStr('originSessionIdentifier', record.originSessionIdentifier, attrs);\n this.pushStr('originDnsName', record.originDnsName, attrs);\n this.pushStr('destinationPlatformIdentifier', record.destinationPlatformIdentifier, attrs);\n this.pushStr('destinationPlatformEgressType', record.destinationPlatformEgressType, attrs);\n this.pushStr('destinationPlatformTypeKey', record.destinationPlatformTypeKey, attrs);\n this.pushStr('originActivityName', record.originActivityName, attrs);\n this.pushStr('originActivityNameCustom', record.originActivityNameCustom, attrs);\n\n // JSON payloads as strings per validation expectations\n this.pushStr('publishedPayload', stringifyJson(record.publishedPayload), attrs);\n this.pushStr('egressQualityMetrics', stringifyJson(record.egressQualityMetrics), attrs);\n this.pushStr('egressIdentityMetrics', stringifyJson(record.egressIdentityMetrics), attrs);\n\n const metric: ExportMetricsServiceRequest = {\n resourceMetrics: [\n {\n resource: {\n attributes: attrs\n },\n scopeMetrics: [\n {\n scope: { name: 'seeka.telemetry.apps-server-core', version: '0.0.0' },\n metrics: [\n {\n name: 'record.activity.egress',\n description: 'Activity egress record',\n unit: '1',\n gauge: {\n dataPoints: [\n {\n asDouble: 1\n }\n ]\n }\n }\n ]\n }\n ]\n }\n ]\n };\n\n await this.sendMetric(metric, installContext);\n };\n\n // Minimal serverless-friendly metric sender using OTLP/HTTP 1.1 Protobuf\n public sendMetric = async (metric: ExportMetricsServiceRequest, installContext: SeekaTelemetryInstallContext): Promise<void> => {\n const { telemetryEndpointUrl, logger, issuerUrl, appId, appSecret } = this.options;\n\n // Minimal runtime guard to help diagnose common shape mistakes without heavy validation\n if (!metric || !Array.isArray((metric as any).resourceMetrics)) {\n throw new Error('SeekaTelemetry: metric must be an OTLP ExportMetricsServiceRequest with a resourceMetrics array');\n }\n\n // Lazily load the server SDK. Prefer require() so Jest can map to a CJS mock.\n // let getNewOrCachedAppInstallToken: any;\n // try {\n // const req = createRequire(import.meta.url);\n // const mod = req('@seeka-labs/sdk-apps-server');\n // getNewOrCachedAppInstallToken = mod.getNewOrCachedAppInstallToken || mod.default?.getNewOrCachedAppInstallToken;\n // } catch {\n // // Fallback to dynamic import (ESM)\n // try {\n // ({ getNewOrCachedAppInstallToken } = await import('@seeka-labs/sdk-apps-server'));\n // } catch {\n // // Last resort: explicit ESM file path (if package exports are strict)\n // ({ getNewOrCachedAppInstallToken } = await import('@seeka-labs/sdk-apps-server/dist/sdk-apps-server.module.mjs'));\n // }\n // }\n\n // Build a minimal config POJO with the fields used by the auth flow\n const config: any = {\n appId,\n appSecret,\n issuerUrl: issuerUrl,\n ingestUrl: telemetryEndpointUrl,\n // organisationId: installContext.organisationId,\n applicationInstallId: installContext.appInstallId,\n logger,\n grantedPermissions: [],\n runtime: this.getRuntimeInfo()\n };\n\n const token = await\n getNewOrCachedAppInstallToken(config as any);\n\n if (!token || !token.access_token) {\n throw new Error('SeekaTelemetry: failed to get access token for install');\n }\n\n const base = telemetryEndpointUrl.endsWith('/') ? telemetryEndpointUrl : telemetryEndpointUrl + '/';\n const url = new URL('v1/metrics', base).toString();\n const decoded = jwtDecode<JwtPayload & {converge_instance_id: string, org_brand_id: string, tenantid: string}>(token.access_token);\n\n const headers = new UndiciHeaders();\n headers.set('Content-Type', this.options.protobuf ? 'application/x-protobuf' : 'application/json');\n headers.set('Accept', this.options.protobuf ? 'application/x-protobuf' : 'application/json');\n headers.set('Authorization', `Bearer ${token.access_token}`);\n headers.set('X-OrgId', decoded.tenantid);\n\n // Encode to Protobuf (OTLP/HTTP 1.1 over HTTP/1.1)\n // const attrs = metric.resourceMetrics[0].resource.attributes['convergeInstanceId'] = ;\n const attrs = metric.resourceMetrics[0]?.resource?.attributes || [];\n\n this.pushStr('tenantId', decoded.tenantid, attrs);\n this.pushStr('organisationBrandId', decoded.org_brand_id, attrs);\n if(this.getStr('type', attrs) === 'record.activity.egress'){\n // set convergeInstanceId to the converge_instance_id claim of the token\n // get claims from jwt token.access_token\n // console.log(JSON.stringify(decoded));\n\n this.pushStr('convergeInstanceId', decoded.converge_instance_id, attrs);\n }\n\n const body = this.options.protobuf ? encodeExportMetricsServiceRequestToProto(metric) : JSON.stringify(metric);\n\n // Avoid batching entirely: send exactly what we were given, immediately await response\n const resp = await undiciFetch(url, {\n method: 'POST',\n headers: headers as any,\n body\n });\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => '');\n const msg = `SeekaTelemetry: metric send failed with status ${resp.status} ${resp.statusText}`;\n logger?.error(msg, { body: text });\n throw new Error(msg);\n }\n else{\n logger?.debug(`SeekaTelemetry: metric send succeeded`);\n }\n }\n\n public shutdown = async (): Promise<void> => {\n // Core package has no SDK to shutdown; provided for API symmetry.\n }\n\n // NodeSDK support is intentionally omitted from the core package.\n\n private getRuntimeInfo(): AppRuntimeInfo {\n // TODO: proper runtime info for this lib version and the caller / app lib version\n return {\n type: 'sdk/js/apps-server-telemetry-core',\n ver: '0.0.0',\n client: {\n type: 'server',\n ver: process.versions?.node || 'unknown'\n }\n };\n }\n}\n\nexport const createSeekaTelemetryClient = (options?: SeekaTelemetryClientCoreOptions | null | undefined, logger?: winston.Logger): SeekaTelemetryClientCore => {\n return new SeekaTelemetryClientCoreImpl({\n ...options,\n appId: options?.appId || process.env.SEEKA_APP_ID as string,\n appSecret: options?.appSecret || process.env.SEEKA_APP_SECRET as string,\n telemetryEndpointUrl: options?.telemetryEndpointUrl || process.env.SEEKA_TELEMETRY_URL || urls.defaultTelemetryUrl,\n issuerUrl: options?.issuerUrl || process.env.SEEKA_ISSUER_URL || urls.defaultIssuerUrl,\n logger\n });\n};\n", "\uFEFF// Minimal OTLP Metrics protobuf encoder for the subset we use (HTTP/1.1, no HTTP/2)\n// We hand-encode only the fields we need for our gauge metric with string attributes.\n// This avoids pulling in a full protobuf runtime and keeps the package light.\n\nimport type {\n AnyValue,\n ExportMetricsServiceRequest,\n Gauge,\n InstrumentationScope,\n KeyValue,\n Metric,\n NumberDataPoint,\n Resource,\n ResourceMetrics,\n ScopeMetrics,\n} from './models.ts';\n\n// Protobuf wire types\n// const WT_VARINT = 0;\nconst WT_64BIT = 1; // fixed64 / double\nconst WT_LEN = 2; // length-delimited (strings, bytes, submessages)\n\n// Utilities\nconst textEncoder = new TextEncoder();\n\nfunction encodeVarint(value: number): Uint8Array {\n // Support up to 32-bit values used in tags/lengths; sufficient for our use.\n let v = value >>> 0;\n const bytes: number[] = [];\n while (v >= 0x80) {\n bytes.push((v & 0x7f) | 0x80);\n v >>>= 7;\n }\n bytes.push(v);\n return Uint8Array.from(bytes);\n}\n\nfunction encodeTag(fieldNumber: number, wireType: number): Uint8Array {\n const key = (fieldNumber << 3) | wireType;\n return encodeVarint(key);\n}\n\nfunction encodeStringField(fieldNumber: number, value: string | undefined): Uint8Array[] {\n if (value == null) return [];\n const str = textEncoder.encode(value);\n return [encodeTag(fieldNumber, WT_LEN), encodeVarint(str.length), str];\n}\n\nfunction encodeBytesField(fieldNumber: number, value: Uint8Array): Uint8Array[] {\n return [encodeTag(fieldNumber, WT_LEN), encodeVarint(value.length), value];\n}\n\nfunction encodeDoubleField(fieldNumber: number, value: number | undefined): Uint8Array[] {\n if (value == null) return [];\n const buf = new ArrayBuffer(8);\n new DataView(buf).setFloat64(0, value, true); // little-endian\n return [encodeTag(fieldNumber, WT_64BIT), new Uint8Array(buf)];\n}\n\nfunction concatParts(parts: (Uint8Array | undefined)[]): Uint8Array {\n const filtered = parts.filter((p): p is Uint8Array => p instanceof Uint8Array);\n const total = filtered.reduce((sum, p) => sum + p.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const p of filtered) { out.set(p, off); off += p.length; }\n return out;\n}\n\nfunction encodeAnyValue(value: AnyValue | undefined): Uint8Array {\n if (!value) return new Uint8Array(0);\n // We only support stringValue directly; other types are coerced to string via JSON.\n let str: string | undefined = undefined;\n if ('stringValue' in value && typeof value.stringValue === 'string') {\n str = value.stringValue;\n } else {\n // Coerce any present field to a string representation to keep encoder simple\n const v = (value as any).doubleValue ?? (value as any).intValue ?? (value as any).boolValue ?? (value as any).bytesValue ?? (value as any).arrayValue ?? (value as any).kvlistValue;\n try { str = typeof v === 'string' ? v : JSON.stringify(v); } catch { str = String(v); }\n }\n const inner = concatParts(encodeStringField(1, str)); // AnyValue.string_value = 1\n return wrapMessage(inner);\n}\n\nfunction encodeKeyValue(kv: KeyValue): Uint8Array {\n const parts: Uint8Array[] = [];\n parts.push(...encodeStringField(1, kv.key)); // key = 1\n parts.push(...encodeBytesField(2, encodeAnyValue(kv.value))); // value = 2 (submessage)\n return wrapMessage(concatParts(parts));\n}\n\nfunction encodeResource(res?: Resource): Uint8Array {\n if (!res) return wrapMessage(new Uint8Array(0));\n const parts: Uint8Array[] = [];\n for (const kv of res.attributes ?? []) {\n parts.push(...encodeBytesField(1, encodeKeyValue(kv))); // attributes = 1 (repeated)\n }\n return wrapMessage(concatParts(parts));\n}\n\nfunction encodeInstrumentationScope(scope?: InstrumentationScope): Uint8Array {\n const parts: Uint8Array[] = [];\n if (scope) {\n parts.push(...encodeStringField(1, scope.name)); // name = 1\n parts.push(...encodeStringField(2, scope.version)); // version = 2\n }\n return wrapMessage(concatParts(parts));\n}\n\nfunction encodeNumberDataPoint(ndp: NumberDataPoint): Uint8Array {\n const parts: Uint8Array[] = [];\n // We only encode the value as double (as_double = 4) and ignore timestamps/attributes for now\n parts.push(...encodeDoubleField(4, ndp.asDouble));\n return wrapMessage(concatParts(parts));\n}\n\nfunction encodeGauge(g: Gauge): Uint8Array {\n const parts: Uint8Array[] = [];\n for (const dp of g.dataPoints ?? []) {\n parts.push(...encodeBytesField(1, encodeNumberDataPoint(dp))); // data_points = 1\n }\n return wrapMessage(concatParts(parts));\n}\n\nfunction encodeMetric(m: Metric): Uint8Array {\n const parts: Uint8Array[] = [];\n parts.push(...encodeStringField(1, m.name));\n parts.push(...encodeStringField(2, m.description));\n parts.push(...encodeStringField(3, m.unit));\n if (m.gauge) {\n parts.push(...encodeBytesField(5, encodeGauge(m.gauge))); // gauge = 5\n }\n return wrapMessage(concatParts(parts));\n}\n\nfunction encodeScopeMetrics(sm: ScopeMetrics): Uint8Array {\n const parts: Uint8Array[] = [];\n parts.push(...encodeBytesField(1, encodeInstrumentationScope(sm.scope))); // scope = 1\n for (const metric of sm.metrics ?? []) {\n parts.push(...encodeBytesField(2, encodeMetric(metric))); // metrics = 2\n }\n return wrapMessage(concatParts(parts));\n}\n\nfunction encodeResourceMetrics(rm: ResourceMetrics): Uint8Array {\n const parts: Uint8Array[] = [];\n parts.push(...encodeBytesField(1, encodeResource(rm.resource))); // resource = 1\n for (const sm of rm.scopeMetrics ?? []) {\n parts.push(...encodeBytesField(2, encodeScopeMetrics(sm))); // scope_metrics = 2\n }\n return wrapMessage(concatParts(parts));\n}\n\nfunction wrapMessage(inner: Uint8Array): Uint8Array {\n // Caller will add the field tag and length for embedding; this wraps raw fields into a message body\n return inner;\n}\n\nexport function encodeExportMetricsServiceRequestToProto(req: ExportMetricsServiceRequest): Uint8Array {\n const parts: Uint8Array[] = [];\n for (const rm of req.resourceMetrics ?? []) {\n const rmBytes = encodeResourceMetrics(rm);\n parts.push(...encodeBytesField(1, rmBytes)); // resource_metrics = 1 (repeated)\n }\n return concatParts(parts);\n}\n", "\uFEFFexport const toIsoDateTime = (date: Date) => {\n const pad = (n: number) => String(n).padStart(2, '0');\n const pad3 = (n: number) => String(n).padStart(3, '0');\n\n return (\n date.getUTCFullYear() + '-' +\n pad(date.getUTCMonth() + 1) + '-' +\n pad(date.getUTCDate()) + 'T' +\n pad(date.getUTCHours()) + ':' +\n pad(date.getUTCMinutes()) + ':' +\n pad(date.getUTCSeconds()) + '.' +\n pad3(date.getUTCMilliseconds())\n );\n}", "\uFEFF// Minimal OTLP/HTTP 1.1 JSON type definitions for Metrics\n// These follow the protobuf JSON mapping for the OpenTelemetry Metrics protocol.\n// Only commonly used fields are included to keep the types lightweight but useful.\n\nimport type {Logger} from \"winston\";\nimport type {TrackingActivityNames, SeekaActivityAcceptedWebhookContent} from \"@seeka-labs/sdk-apps-server\";\n\nexport interface ExportMetricsServiceRequest {\n resourceMetrics: ResourceMetrics[];\n}\n\nexport interface ResourceMetrics {\n resource?: Resource;\n scopeMetrics: ScopeMetrics[];\n schemaUrl?: string;\n}\n\nexport interface Resource {\n attributes?: KeyValue[];\n droppedAttributesCount?: number;\n}\n\nexport interface ScopeMetrics {\n scope?: InstrumentationScope;\n metrics: Metric[];\n schemaUrl?: string;\n}\n\nexport interface InstrumentationScope {\n name: string;\n version?: string;\n attributes?: KeyValue[];\n droppedAttributesCount?: number;\n}\n\nexport interface Metric {\n name: string;\n description?: string;\n unit?: string;\n sum?: Sum;\n gauge?: Gauge;\n histogram?: Histogram;\n exponentialHistogram?: ExponentialHistogram;\n summary?: Summary; // kept for completeness (deprecated in OTLP but some exporters still accept)\n}\n\nexport interface Sum {\n dataPoints: NumberDataPoint[];\n aggregationTemporality: AggregationTemporality; // 0=Unspecified, 1=Delta, 2=Cumulative\n isMonotonic?: boolean;\n}\n\nexport interface Gauge {\n dataPoints: NumberDataPoint[];\n}\n\nexport interface Histogram {\n dataPoints: HistogramDataPoint[];\n aggregationTemporality: AggregationTemporality; // 0=Unspecified, 1=Delta, 2=Cumulative\n}\n\nexport interface ExponentialHistogram {\n dataPoints: ExponentialHistogramDataPoint[];\n aggregationTemporality: AggregationTemporality; // 0=Unspecified, 1=Delta, 2=Cumulative\n}\n\nexport interface Summary {\n dataPoints: SummaryDataPoint[];\n}\n\nexport interface NumberDataPoint {\n attributes?: KeyValue[];\n startTimeUnixNano?: string; // uint64 as string per JSON mapping\n timeUnixNano?: string; // uint64 as string per JSON mapping\n exemplars?: Exemplar[];\n flags?: number; // DataPointFlags bitfield\n asDouble?: number;\n asInt?: string | number; // int64 as string per JSON mapping; allow number for convenience\n}\n\nexport interface HistogramDataPoint {\n attributes?: KeyValue[];\n startTimeUnixNano?: string;\n timeUnixNano?: string;\n count: string | number; // uint64\n sum?: number;\n bucketCounts?: Array<string | number>; // repeated uint64\n explicitBounds?: number[];\n min?: number; // available depending on OTLP version/feature gate\n max?: number; // available depending on OTLP version/feature gate\n exemplars?: Exemplar[];\n flags?: number;\n}\n\nexport interface ExponentialHistogramDataPoint {\n attributes?: KeyValue[];\n startTimeUnixNano?: string;\n timeUnixNano?: string;\n count: string | number; // uint64\n sum?: number;\n scale?: number; // int32\n zeroCount?: string | number; // uint64\n positive?: ExponentialHistogramBuckets;\n negative?: ExponentialHistogramBuckets;\n min?: number;\n max?: number;\n exemplars?: Exemplar[];\n flags?: number;\n}\n\nexport interface ExponentialHistogramBuckets {\n offset?: number; // int32\n bucketCounts?: Array<string | number>; // repeated uint64\n}\n\nexport interface SummaryDataPoint {\n attributes?: KeyValue[];\n startTimeUnixNano?: string;\n timeUnixNano?: string;\n count: string | number; // uint64\n sum: number;\n quantileValues?: ValueAtQuantile[];\n flags?: number;\n}\n\nexport interface ValueAtQuantile {\n quantile: number;\n value: number;\n}\n\nexport interface Exemplar {\n filteredAttributes?: KeyValue[];\n timeUnixNano?: string;\n asDouble?: number;\n asInt?: string | number;\n spanId?: string; // base64-encoded or hex per exporter; keep string\n traceId?: string;\n}\n\n// Common attribute/value types\nexport interface KeyValue {\n key: string;\n value: AnyValue;\n}\n\nexport type AnyValue =\n { stringValue: string }\n | { boolValue: boolean }\n | { intValue: string | number }\n | { doubleValue: number }\n | { bytesValue: string }\n | { arrayValue: ArrayValue }\n | { kvlistValue: KeyValueList };\n\nexport interface ArrayValue {\n values: AnyValue[];\n}\n\nexport interface KeyValueList {\n values: KeyValue[];\n}\n\n// Enum mirrors otlp AggregationTemporality; we allow numbers to align with protobuf JSON mapping\nexport enum AggregationTemporality {\n AGGREGATION_TEMPORALITY_UNSPECIFIED = 0,\n AGGREGATION_TEMPORALITY_DELTA = 1,\n AGGREGATION_TEMPORALITY_CUMULATIVE = 2,\n}\n\n// Helpful alias for consumers\nexport type OtlpMetricsExportRequest = ExportMetricsServiceRequest;\n\n\n// Public types\nexport type SeekaTelemetryClientCoreOptions = {\n appId: string;\n appSecret: string;\n issuerUrl?: string;\n telemetryEndpointUrl: string;\n logger?: Logger;\n protobuf?: boolean;\n};\n\nexport type SeekaTelemetryInstallContext = {\n // appId: string;\n // appSecret: string;\n // organisationId: string;\n appInstallId: string;\n};\n\n\n// export interface AppRuntimeInfo {\n// type: string;\n// ver: string;\n// client: {\n// type: 'server' | 'browser' | string;\n// ver: string;\n// };\n// }\n\n\n// Activity Egress record type mirroring the C# model (JS-friendly)\nexport type ActivityEgressTelemetryRecord = ActivityEgressTelemetryRecordBase & ActivityEgressTelemetryRecordMetrics & {\n personId: string;\n originActivityId?: string;\n occurredAt?: Date | undefined;\n originSessionIdentifier: string;\n originDnsName: string;\n originActivityName: TrackingActivityNames;\n originActivityNameCustom?: string | null | undefined;\n};\n\nexport interface ActivityEgressTelemetryRecordBase {\n publishedPayload: unknown;\n destinationPlatformTypeKey:\n | 'google.ads'\n | 'google.analytics'\n | 'meta.capi'\n | 'pinterest.capi'\n | 'tiktok.capi'\n | 'snapchat.capi'\n | (string & {});\n destinationPlatformEgressType: string;\n destinationPlatformIdentifier: string;\n}\n\nexport interface ActivityEgressTelemetryRecordMetrics {\n egressQualityMetrics: Record<string, boolean>;\n egressIdentityMetrics: { qualityRating: number; dataPoints: number };\n}\n\nexport const createEgressTelemetryRecord = (egressRecord: ActivityEgressTelemetryRecordBase, egressMetrics: ActivityEgressTelemetryRecordMetrics, originActivity: SeekaActivityAcceptedWebhookContent): ActivityEgressTelemetryRecord => {\n return {\n ...egressMetrics,\n ...egressRecord,\n // tenantId: appInstallState.organisationId,\n // egressQualityMetrics: {'fn': true, 'em': true},\n // egressIdentityMetrics: {qualityRating: 0.8, dataPoints: 7},\n personId: originActivity.personId as string,\n originActivityId: originActivity.activity?.activityId,\n // convergeInstanceId: process.env.SEEKA_CONVERGE_INSTANCE_ID as string,\n // organisationBrandId: appInstallState.organisationBrandId,\n occurredAt: new Date(),\n originActivityName: originActivity.activity?.activityName as TrackingActivityNames,\n originActivityNameCustom: originActivity.activity?.activityNameCustom,\n originSessionIdentifier: originActivity.source?.sess as string,\n originDnsName: new URL(originActivity.source?.loc ||'').hostname.toLowerCase()\n }\n};\n\n\nexport interface SeekaTelemetryClientCore {\n sendMetric: (metric: ExportMetricsServiceRequest, installContext: SeekaTelemetryInstallContext) => Promise<void>;\n // Convenience helper to send a standardised activity egress metric\n sendEgressMetric: (record: ActivityEgressTelemetryRecord, installContext: SeekaTelemetryInstallContext) => Promise<void>;\n shutdown: () => Promise<void>;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["undiciFetch", "UndiciHeaders", "jwtDecode", "getNewOrCachedAppInstallToken", "textEncoder", "encodeVarint", "value", "v", "bytes", "encodeTag", "fieldNumber", "wireType", "key", "encodeStringField", "str", "encodeBytesField", "encodeDoubleField", "buf", "concatParts", "parts", "filtered", "p", "total", "sum", "out", "off", "encodeAnyValue", "inner", "encodeKeyValue", "kv", "encodeResource", "res", "encodeInstrumentationScope", "scope", "encodeNumberDataPoint", "ndp", "encodeGauge", "g", "dp", "encodeMetric", "m", "encodeScopeMetrics", "sm", "metric", "encodeResourceMetrics", "rm", "encodeExportMetricsServiceRequestToProto", "req", "parts", "rm", "rmBytes", "encodeResourceMetrics", "encodeBytesField", "concatParts", "toIsoDateTime", "date", "pad", "n", "pad3", "urls", "attrPrefix", "SeekaTelemetryClientCoreImpl", "options", "key", "value", "attrs", "targetKey", "attr", "a", "record", "installContext", "stringifyJson", "v", "now", "toIsoDateTime", "metric", "telemetryEndpointUrl", "logger", "issuerUrl", "appId", "appSecret", "config", "token", "getNewOrCachedAppInstallToken", "base", "url", "decoded", "jwtDecode", "headers", "UndiciHeaders", "body", "encodeExportMetricsServiceRequestToProto", "resp", "undiciFetch", "text", "msg", "createSeekaTelemetryClient", "AggregationTemporality", "createEgressTelemetryRecord", "egressRecord", "egressMetrics", "originActivity"]
|
|
7
|
-
}
|