@seeka-labs/sdk-apps-server 1.1.8 → 1.1.9
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/sdk-apps-server.js +1 -1
- package/dist/sdk-apps-server.js.map +1 -1
- package/dist/sdk-apps-server.module.js +1 -1
- package/dist/sdk-apps-server.module.js.map +1 -1
- package/dist/types/src/api/services/index.d.ts +31 -0
- package/dist/types/src/api/services/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/sdk-apps-server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=require("memory-cache"),t=require("crypto"),i=require("axios"),r=require("openid-client"),s=require("http"),n=require("https");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function a(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(i){if("default"!==i){var r=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,r.get?r:{enumerable:!0,get:function(){return e[i]}})}}),t.default=e,t}var c=/*#__PURE__*/a(e),l=/*#__PURE__*/a(t),d=/*#__PURE__*/o(i),p=/*#__PURE__*/o(s),u=/*#__PURE__*/o(n);const g={identity:{receiveFull:"Identity.Receive.Pii",send:"Identity.Send"},activity:{receiveAnon:"Activity.Receive.Anon",receiveFull:"Activity.Receive.Pii",send:"Activity.Send"}},h="seeka:sdk";class v{constructor(e,t){this.appId=void 0,this.appInstallationId=void 0,this.set=async(e,t,i)=>{const r=this.getKey(e);c.put(r,JSON.stringify(t),i)},this.getOrSet=async(e,t,i)=>{const r=this.getKey(e),s=c.get(r);if(s){const e=JSON.parse(s);return i&&await i(e),e}const n=await t();return n?(c.put(r,JSON.stringify(n.value),n.expiryAbsoluteMilliseconds),n.value):null},this.getKey=e=>this.appInstallationId?`${h}:${this.appId}:${this.appInstallationId}:${e}`:`${h}:${this.appId}:${e}`,this.appId=e,this.appInstallationId=t}}class m{constructor(){this.appId=void 0,this.appSecret=void 0,this.ingestUrl=void 0,this.issuerUrl=void 0,this.organisationId=void 0,this.applicationInstallId=void 0,this.runtime=void 0,this.logger=void 0,this.grantedPermissions=void 0,this.transformApiRequest=void 0,this.transformApiResponse=void 0,this.hasAnyPermissions=void 0,this.hasAllPermissions=void 0,this.hasPermission=void 0}}class f{constructor(e){this.config=void 0,this.transformOptions=async e=>await this.config.transformApiRequest(e),this.transformResult=async(e,t,i)=>await this.config.transformApiResponse(e,t,i),this.config=e}}class y extends f{constructor(e,t,i){super(e),this.instance=void 0,this.baseUrl=void 0,this.jsonParseReviver=void 0,this.instance=i||d.default.create(),this.baseUrl=null!=t?t:"https://api-localdev-env0-seeka.au.ngrok.io"}merge(e,t){let i=this.baseUrl+"/api/identity";i=i.replace(/[?&]$/,"");const r=JSON.stringify(e);return this.transformOptions({data:r,method:"POST",url:i,headers:{"Content-Type":"application/json",Accept:"application/json"},cancelToken:t}).then(e=>this.instance.request(e)).catch(e=>{if(B(e)&&e.response)return e.response;throw e}).then(e=>this.transformResult(i,e,e=>this.processMerge(e)))}processMerge(e){const t=e.status;let i={};if(e.headers&&"object"==typeof e.headers)for(const t in e.headers)e.headers.hasOwnProperty(t)&&(i[t]=e.headers[t]);if(200===t){let t=null;return t=JSON.parse(e.data),Promise.resolve(t)}if(401===t){const r=e.data;let s=null;return s=JSON.parse(r),N("A server side error occurred.",t,r,i,s)}if(422===t){const r=e.data;let s=null;return s=JSON.parse(r),N("A server side error occurred.",t,r,i,s)}if(400===t){const r=e.data;let s=null;return s=JSON.parse(r),N("A server side error occurred.",t,r,i,s)}return 200!==t&&204!==t?N("An unexpected server error occurred.",t,e.data,i):Promise.resolve(null)}}class k extends f{constructor(e,t,i){super(e),this.instance=void 0,this.baseUrl=void 0,this.jsonParseReviver=void 0,this.instance=i||d.default.create(),this.baseUrl=null!=t?t:"https://api-localdev-env0-seeka.au.ngrok.io"}batch(e,t){let i=this.baseUrl+"/api/ingest";i=i.replace(/[?&]$/,"");const r=JSON.stringify(e);return this.transformOptions({data:r,method:"POST",url:i,headers:{"Content-Type":"application/json"},cancelToken:t}).then(e=>this.instance.request(e)).catch(e=>{if(B(e)&&e.response)return e.response;throw e}).then(e=>this.transformResult(i,e,e=>this.processBatch(e)))}processBatch(e){const t=e.status;let i={};if(e.headers&&"object"==typeof e.headers)for(const t in e.headers)e.headers.hasOwnProperty(t)&&(i[t]=e.headers[t]);if(202===t)return Promise.resolve(null);if(401===t){const r=e.data;let s=null;return s=JSON.parse(r),N("A server side error occurred.",t,r,i,s)}if(422===t){const r=e.data;let s=null;return s=JSON.parse(r),N("A server side error occurred.",t,r,i,s)}if(400===t){const r=e.data;let s=null;return s=JSON.parse(r),N("A server side error occurred.",t,r,i,s)}return 200!==t&&204!==t?N("An unexpected server error occurred.",t,e.data,i):Promise.resolve(null)}}var S,P,A,I,w,x,C,b,E,T,U;exports.ResponseResultType=void 0,(S=exports.ResponseResultType||(exports.ResponseResultType={})).Undefined="undefined",S.Success="success",S.Failed="failed",exports.PrivacyConsentType=void 0,(P=exports.PrivacyConsentType||(exports.PrivacyConsentType={})).Unknown="unknown",P.Informed="informed",P.Implied="implied",P.Explicit="explicit",P.Active="active",P.Passive="passive",exports.TrackingEventSourceOriginType=void 0,(A=exports.TrackingEventSourceOriginType||(exports.TrackingEventSourceOriginType={})).Browser="browser",A.Server="server",A.Mobile="mobile",A.Desktop="desktop",A.PhysicalStore="physicalStore",A.Email="email",A.Phone="phone",A.Chat="chat",A.Automatic="automatic",exports.TrackingActivityNames=void 0,(I=exports.TrackingActivityNames||(exports.TrackingActivityNames={})).Undefined="undefined",I.PageViewOrganic="pageViewOrganic",I.PageViewUtmAttributed="pageViewUtmAttributed",I.AddPaymentMethod="addPaymentMethod",I.AddToWishlist="addToWishlist",I.ContactMessage="contactMessage",I.Custom="custom",I.SyncCart="syncCart",I.Order="order",I.InitiateCheckout="initiateCheckout",I.AddToCart="addToCart",I.RemoveFromCart="removeFromCart",I.OneTimeItemPurchase="oneTimeItemPurchase",I.SubscriptionItemPurchase="subscriptionItemPurchase",I.ViewProduct="viewProduct",I.ViewPage="viewPage",I.ApplyPromotionalCode="applyPromotionalCode",I.KeywordSearch="keywordSearch",I.UserLoginSignup="userLoginSignup",I.UserLogin="userLogin",I.NewsletterSignup="newsletterSignup",I.Lead="lead",I.ChangeProductAttribute="changeProductAttribute",I.FilterItemsByAttribute="filterItemsByAttribute",I.Schedule="schedule",I.ViewContentItem="viewContentItem",I.StartTrial="startTrial",exports.ECommerceContentType=void 0,(w=exports.ECommerceContentType||(exports.ECommerceContentType={})).Undefined="undefined",w.SingleProduct="singleProduct",w.SingleVariant="singleVariant",w.Collection="collection",exports.ECommercePlatform=void 0,(x=exports.ECommercePlatform||(exports.ECommercePlatform={})).None="none",x.BigCommerce="bigCommerce",x.Shopify="shopify",x.OrderGroove="orderGroove",x.Magento="magento",x.Generic="generic",x.WooCommerce="wooCommerce",x.Demandware="demandware",exports.ECommerceFulfillmentStatus=void 0,(C=exports.ECommerceFulfillmentStatus||(exports.ECommerceFulfillmentStatus={})).Undefined="undefined",C.Fulfilled="fulfilled",C.NoneFulfilled="noneFulfilled",C.PartiallyFulfilled="partiallyFulfilled",C.RestockedOrCancelled="restockedOrCancelled",exports.ECommerceFinancialStatus=void 0,(b=exports.ECommerceFinancialStatus||(exports.ECommerceFinancialStatus={})).Undefined="undefined",b.Pending="pending",b.Authorized="authorized",b.PartiallyPaid="partiallyPaid",b.Paid="paid",b.PartiallyRefunded="partiallyRefunded",b.Refunded="refunded",b.Voided="voided",exports.ConvergePipelineLoggableActivityType=void 0,(E=exports.ConvergePipelineLoggableActivityType||(exports.ConvergePipelineLoggableActivityType={})).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",exports.SdkLogEventLevel=void 0,(T=exports.SdkLogEventLevel||(exports.SdkLogEventLevel={})).Information="information",T.Warning="warning",T.Error="error",T.Verbose="verbose",exports.SeekaWebhookCallType=void 0,(U=exports.SeekaWebhookCallType||(exports.SeekaWebhookCallType={})).None="none",U.Probe="probe",U.AppInstalled="appInstalled",U.IdentityChanged="identityChanged",U.ActivityAccepted="activityAccepted",U.AppInstallSettingsUpdated="appInstallSettingsUpdated",U.AppUninstalled="appUninstalled",U.BrowserSdkPlugin="browserSdkPlugin";class O extends Error{constructor(e,t,i,r,s){super(),this.message=void 0,this.status=void 0,this.response=void 0,this.headers=void 0,this.result=void 0,this.isApiException=!0,this.message=e,this.status=t,this.response=i,this.headers=r,this.result=s}static isApiException(e){return!0===e.isApiException}}function N(e,t,i,r,s){throw null!=s?s:new O(e,t,i,r,null)}function B(e){return e&&!0===e.isAxiosError}const _=()=>`${$(new Date)}.${R()}`,R=()=>Math.floor(8999999999*Math.random()+1e9).toString(),$=e=>{let t=(e.getUTCMonth()+1).toString();t.length<2&&(t="0"+t);let i=e.getUTCDate().toString();i.length<2&&(i="0"+i);let r=e.getUTCHours().toString();r.length<2&&(r="0"+r);let s=e.getUTCMinutes().toString();s.length<2&&(s="0"+s);let n=e.getUTCSeconds().toString();return n.length<2&&(n="0"+n),`${e.getUTCFullYear()}${t}${i}.${r}${s}${n}`},F=(e,t)=>e.reduce((e,i,r)=>{const s=Math.floor(r/t);return e[s]||(e[s]=[]),e[s].push(i),e},[]),L=async e=>{const t=await j(e),i=new r.Issuer(t);return i[r.custom.http_options]=(e,t)=>({timeout:1e4}),i},j=async e=>{const 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});const i=new v(e.appId,e.applicationInstallId),r=(s=e.issuerUrl,l.createHash("md5").update(s).digest("hex"));var s;return await i.getOrSet(r,async()=>({value:await M(e),expiryAbsoluteMilliseconds:36e5}),async()=>{e.logger?e.logger.verbose("Seeka auth: got issuer from cache",{...t}):console.debug("Seeka auth: got issuer from cache",{...t})})},M=async e=>{const t={applicationId:e.appId,issuer:{url:e.issuerUrl}};return e.logger?e.logger.info("Seeka auth: discovering issuer from server",{...t}):console.info("Seeka auth: discovering issuer from server",{...t}),(await r.Issuer.discover(e.issuerUrl)).metadata},q=async e=>{const t=new v(e.appId,e.applicationInstallId),i={applicationId:e.appId,issuer:{url:e.issuerUrl}};return await t.getOrSet("auth:token:appinstall",async()=>{const t=await(async e=>{const t={applicationId:e.appId,issuer:{url:e.issuerUrl}},i=new((await L(e)).Client)({client_id:e.appId.replace(/-/g,""),client_secret:e.appSecret});try{const r=await i.grant({grant_type:"client_credentials"}),s={...t,token:{expires_at:r.expires_at,token_type:r.token_type,scope:r.scope}};return e.logger?e.logger.info("Seeka auth: got client access token from server",{...s}):console.info("Seeka auth: got app client token from server",{...s}),r}catch(i){const r={...t,error:i};return e.logger?e.logger.error("Seeka auth: failed to get client access token from server",{...r}):console.debug("Seeka auth: failed to get client access token from server",{...r}),null}})(e);if(!t)return null;const i=await(async(e,t)=>{const i={applicationId:t.appId,issuer:{url:t.issuerUrl}},r=new((await L(t)).Client)({client_id:t.appId.replace(/-/g,""),client_secret:t.appSecret});try{const s=await r.grant({grant_type:"app_install_token",applicationInstallId:t.applicationInstallId,access_token:e}),n={...i,token:{expires_at:s.expires_at,token_type:s.token_type,scope:s.scope}};return t.logger?t.logger.info("Seeka auth: got app access token from server",{...n}):console.info("Seeka auth: got app access token from server",{...n}),s}catch(e){const r={...i,error:e};return t.logger?t.logger.error("Seeka auth: failed to get app access token from server",{...r}):console.debug("Seeka auth: failed to get app access token from server",{...r}),null}})(t.access_token,e);return i?{value:i,expiryAbsoluteMilliseconds:((i.expires_in>t.expires_in?t.expires_in:i.expires_in)||9e5)-6e4}:null},async()=>{e.logger?e.logger.verbose("Seeka auth: got app token from cache",{...i}):console.debug("Seeka auth: got app token from cache",{...i})})},D=new p.default.Agent({keepAlive:!0,scheduling:"fifo"}),J=new u.default.Agent({keepAlive:!0,scheduling:"fifo"}),V=e=>{const t=d.default.create({httpAgent:D,httpsAgent:J});return t.interceptors.request.use(function(t){const i={url:t.url,method:t.method};return e.logger?e.logger.debug(`Seeka API: making call to ${i.url}`,{...i}):console.debug(`Seeka API: making call to ${i.url}`,{...i}),t},function(t){const i={error:t};return e.logger?e.logger.http("Seeka API: failed to send request",{...i}):console.debug("Seeka API: failed to send request",{...i}),Promise.reject(t)}),t.interceptors.response.use(function(t){var i,r;const s={url:(null==(i=t.request)?void 0:i.url)||t.config.url,method:(null==(r=t.request)?void 0:r.method)||t.config.method,response:{status:t.status}};return e.logger?e.logger.http(`Seeka API: call to ${s.url} succeeded`,{...s}):console.debug(`Seeka API: call to ${s.url} succeeded`,{...s}),t},function(t){var i;const{code:r,status:s,message:n}=t,{headers:o,url:a,method:c}=null==t?void 0:t.config,l={code:r,status:s,message:n,headers:o,url:a,method:c,content:null==t||null==(i=t.response)?void 0:i.data};return e.logger?e.logger.error(`Seeka API: call to ${l.url} failed`,{...l}):console.error(`Seeka API: call to ${l.url} failed`,{...l}),Promise.reject(t)}),t};class z{constructor(e){this.config=void 0,this.maxBatchSize=50,this.refreshOrPrimeTokenCache=async()=>{await q(this.config)},this.ingestionService=void 0,this.identityService=void 0,this.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},this.mergeIdentity=async(e,t)=>{var i;this.checkPermission(g.identity.send,"mergeIdentity");const r=_();return null==(i=(await this.identityService.merge({id:e,src:{method:"",origin:t.origin,time:void 0,loc:t.loc,sess:r,diag:"true"===process.env.SEEKA_DEBUG_ENABLED?r:void 0,runtime:this.config.runtime}})).result)?void 0:i.personId},this.mergeIdentityBatch=async(e,t)=>{this.checkPermission(g.identity.send,"mergeIdentityBatch");const i=_();var r;if(0===e.length)return void(null==(r=this.config.logger)||r.info("No identities in batch"));const s={method:"",origin:t.origin,time:void 0,loc:t.loc,sess:i,diag:"true"===process.env.SEEKA_DEBUG_ENABLED?i:void 0,runtime:this.config.runtime},n=F(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(e=>({id:{id:e||{},src:{...s}}}))}),n.length>1){const e=n.map((e,t)=>{var i;return 0===t?Promise.resolve():(null==(i=this.config.logger)||i.info(`Processing identity batch ${t+1} of ${n.length}`),this.trackActivityBatchRaw({data:e.map(e=>({id:{id:e||{},src:{...s}}}))}))});await Promise.all(e)}},this.trackActivityBatch=async(e,t)=>{this.checkPermission(g.activity.send,"trackActivityBatch");const i=_();var r;if(0===e.length)return void(null==(r=this.config.logger)||r.info("No activities in batch"));const s={method:"",origin:t.origin,time:void 0,loc:t.loc,sess:i,diag:"true"===process.env.SEEKA_DEBUG_ENABLED?i:void 0,runtime:this.config.runtime},n=F(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(e=>({ev:{id:e.profile||{},src:{...s},payload:e.activity}}))}),n.length>1){const e=n.map((e,t)=>{var i;return 0===t?Promise.resolve():(null==(i=this.config.logger)||i.info(`Processing activity batch ${t+1} of ${n.length}`),this.trackActivityBatchRaw({data:e.map(e=>({ev:{id:e.profile||{},src:{...s},payload:e.activity}}))}))});await Promise.all(e)}},this.trackActivityBatchRaw=async e=>{await this.ingestionService.batch(e)},this.trackActivityForProfileId=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfileId"),await this.trackActivityForProfileIdBatch([e],t,i)},this.trackActivityForProfileIdBatch=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfileIdBatch"),await this.trackActivityBatch(e.map(e=>({activity:e,profile:t?{seekaPId:t}:void 0})),i)},this.trackActivityForProfile=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfile"),await this.trackActivityForProfileBatch([e],t,i)},this.trackActivityForProfileBatch=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfileBatch"),await this.trackActivityBatch(e.map(e=>({activity:e,profile:t})),i)},this.config=e,this.ingestionService=(e=>new k(e,e.ingestUrl,V(e)))(e),this.identityService=(e=>new y(e,e.ingestUrl,V(e)))(e)}}const K="x-seeka-signature-sha256",W=(e,t,i)=>{if(!t)return!1;let r=null;if(t.get&&"function"==typeof t.get)r=t.get(K);else{const e=t[K];e&&(Array.isArray(e)&&e.length>0?r=e[0]:("string"==typeof e||e instanceof String)&&(r=e))}if(!r)return!1;const s=G(e,i)===r;return s||console.warn("Invalid webhook signature"),s},G=(e,t)=>l.createHmac("sha256",e).update(t).digest("hex"),H=(e,t,i,r,s)=>{const n=new m;return n.appId=e.applicationId,n.appSecret=t,n.ingestUrl=process.env.SEEKA_INGEST_URL||"https://router.seeka.services",n.issuerUrl=process.env.SEEKA_ISSUER_URL||"https://account.seeka.app",n.organisationId=e.organisationId,n.applicationInstallId=e.applicationInstallId,n.runtime={type:"sdk/js/apps-server",ver:"1.1.8",client:i},n.logger=s,n.grantedPermissions=r,n.transformApiRequest=e=>X(n,e),n.transformApiResponse=async(e,t,i)=>Y(n,e,t,i),n.hasAnyPermissions=e=>!(!n.grantedPermissions||0===n.grantedPermissions.length)&&(!e||0===e.length||e.some(e=>n.grantedPermissions.includes(e))),n.hasAllPermissions=e=>!(!n.grantedPermissions||0===n.grantedPermissions.length)&&(!e||0===e.length||e.every(e=>n.grantedPermissions.includes(e))),n.hasPermission=e=>!(!n.grantedPermissions||0===n.grantedPermissions.length)&&(!e||n.grantedPermissions.includes(e)),n},X=async(e,t)=>{const i=await q(e);return t.headers={...t.headers,"X-OrgId":e.organisationId,Authorization:"Bearer "+(null==i?void 0:i.access_token)},t},Y=async(e,t,i,r)=>(i.data=JSON.stringify(i.data),r(i));var Q;class Z{constructor(e,t){this.context=void 0,this.appCache=void 0,this.appInstallCache=void 0,this.api=void 0,this.logger=void 0,this.context=e,this.api=new z(e.config),this.appCache=new v(e.config.appId),this.appInstallCache=new v(e.config.appId,e.config.applicationInstallId),this.logger=t}}Q=Z,Z.create=(e,t,i,r,s)=>new Q({config:H({...t},e,{type:i.name,ver:i.version},r,s)},s),exports.ApiException=O,exports.ApiServiceProxyBase=f,exports.AppPermissionKeys=g,exports.IdentityServiceProxy=y,exports.IngestServiceProxy=k,exports.SeekaApiHelper=z,exports.SeekaAppCacheManager=v,exports.SeekaAppConfig=m,exports.SeekaAppHelper=Z,exports.chunk=F,exports.getActivityName=e=>{const t=Object.keys(exports.TrackingActivityNames),i=e.toLowerCase(),r=t.find(e=>e.toLowerCase()===i);return r?exports.TrackingActivityNames[r]:exports.TrackingActivityNames.Custom},exports.separatePersonFullName=e=>{if(!e)return{firstName:null,lastName:null};const t=e.trim().split(" ");return 1===t.length?{firstName:e,lastName:null}:2===t.length?{firstName:t[0],lastName:t[1]}:{firstName:t[0],lastName:t.slice(1).join(" ")}},exports.throwOnInvalidWebhookSignature=(e,t,i)=>{if(!W(e,t,i))throw new Error("Invalid webhook signature")},exports.validateWebhookSignature=W,exports.webhookSignatureHeaderName=K;
|
|
1
|
+
var e=require("memory-cache"),t=require("crypto"),i=require("axios"),r=require("openid-client"),s=require("http"),n=require("https");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function a(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(i){if("default"!==i){var r=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,r.get?r:{enumerable:!0,get:function(){return e[i]}})}}),t.default=e,t}var c=/*#__PURE__*/a(e),l=/*#__PURE__*/a(t),d=/*#__PURE__*/o(i),p=/*#__PURE__*/o(s),u=/*#__PURE__*/o(n);const g={identity:{receiveFull:"Identity.Receive.Pii",send:"Identity.Send"},activity:{receiveAnon:"Activity.Receive.Anon",receiveFull:"Activity.Receive.Pii",send:"Activity.Send"}},h="seeka:sdk";class v{constructor(e,t){this.appId=void 0,this.appInstallationId=void 0,this.set=async(e,t,i)=>{const r=this.getKey(e);c.put(r,JSON.stringify(t),i)},this.getOrSet=async(e,t,i)=>{const r=this.getKey(e),s=c.get(r);if(s){const e=JSON.parse(s);return i&&await i(e),e}const n=await t();return n?(c.put(r,JSON.stringify(n.value),n.expiryAbsoluteMilliseconds),n.value):null},this.getKey=e=>this.appInstallationId?`${h}:${this.appId}:${this.appInstallationId}:${e}`:`${h}:${this.appId}:${e}`,this.appId=e,this.appInstallationId=t}}class m{constructor(){this.appId=void 0,this.appSecret=void 0,this.ingestUrl=void 0,this.issuerUrl=void 0,this.organisationId=void 0,this.applicationInstallId=void 0,this.runtime=void 0,this.logger=void 0,this.grantedPermissions=void 0,this.transformApiRequest=void 0,this.transformApiResponse=void 0,this.hasAnyPermissions=void 0,this.hasAllPermissions=void 0,this.hasPermission=void 0}}class f{constructor(e){this.config=void 0,this.transformOptions=async e=>await this.config.transformApiRequest(e),this.transformResult=async(e,t,i)=>await this.config.transformApiResponse(e,t,i),this.config=e}}class y extends f{constructor(e,t,i){super(e),this.instance=void 0,this.baseUrl=void 0,this.jsonParseReviver=void 0,this.instance=i||d.default.create(),this.baseUrl=null!=t?t:"https://api-localdev-env0-seeka.au.ngrok.io"}merge(e,t){let i=this.baseUrl+"/api/identity";i=i.replace(/[?&]$/,"");const r=JSON.stringify(e);return this.transformOptions({data:r,method:"POST",url:i,headers:{"Content-Type":"application/json",Accept:"application/json"},cancelToken:t}).then(e=>this.instance.request(e)).catch(e=>{if(R(e)&&e.response)return e.response;throw e}).then(e=>this.transformResult(i,e,e=>this.processMerge(e)))}processMerge(e){const t=e.status;let i={};if(e.headers&&"object"==typeof e.headers)for(const t in e.headers)e.headers.hasOwnProperty(t)&&(i[t]=e.headers[t]);if(200===t){let t=null;return t=JSON.parse(e.data),Promise.resolve(t)}if(401===t){const r=e.data;let s=null;return s=JSON.parse(r),_("A server side error occurred.",t,r,i,s)}if(422===t){const r=e.data;let s=null;return s=JSON.parse(r),_("A server side error occurred.",t,r,i,s)}if(400===t){const r=e.data;let s=null;return s=JSON.parse(r),_("A server side error occurred.",t,r,i,s)}return 200!==t&&204!==t?_("An unexpected server error occurred.",t,e.data,i):Promise.resolve(null)}}class k extends f{constructor(e,t,i){super(e),this.instance=void 0,this.baseUrl=void 0,this.jsonParseReviver=void 0,this.instance=i||d.default.create(),this.baseUrl=null!=t?t:"https://api-localdev-env0-seeka.au.ngrok.io"}batch(e,t){let i=this.baseUrl+"/api/ingest";i=i.replace(/[?&]$/,"");const r=JSON.stringify(e);return this.transformOptions({data:r,method:"POST",url:i,headers:{"Content-Type":"application/json"},cancelToken:t}).then(e=>this.instance.request(e)).catch(e=>{if(R(e)&&e.response)return e.response;throw e}).then(e=>this.transformResult(i,e,e=>this.processBatch(e)))}processBatch(e){const t=e.status;let i={};if(e.headers&&"object"==typeof e.headers)for(const t in e.headers)e.headers.hasOwnProperty(t)&&(i[t]=e.headers[t]);if(202===t)return Promise.resolve(null);if(401===t){const r=e.data;let s=null;return s=JSON.parse(r),_("A server side error occurred.",t,r,i,s)}if(422===t){const r=e.data;let s=null;return s=JSON.parse(r),_("A server side error occurred.",t,r,i,s)}if(400===t){const r=e.data;let s=null;return s=JSON.parse(r),_("A server side error occurred.",t,r,i,s)}return 200!==t&&204!==t?_("An unexpected server error occurred.",t,e.data,i):Promise.resolve(null)}}var A,P,S,I,x,w,C,b,T,E,U,O,N,B;exports.ResponseResultType=void 0,(A=exports.ResponseResultType||(exports.ResponseResultType={})).Undefined="undefined",A.Success="success",A.Failed="failed",exports.PrivacyConsentType=void 0,(P=exports.PrivacyConsentType||(exports.PrivacyConsentType={})).Unknown="unknown",P.Informed="informed",P.Implied="implied",P.Explicit="explicit",P.Active="active",P.Passive="passive",exports.TrackingEventSourceOriginType=void 0,(S=exports.TrackingEventSourceOriginType||(exports.TrackingEventSourceOriginType={})).Browser="browser",S.Server="server",S.Mobile="mobile",S.Desktop="desktop",S.PhysicalStore="physicalStore",S.Email="email",S.Phone="phone",S.Chat="chat",S.Automatic="automatic",exports.TrackingActivityNames=void 0,(I=exports.TrackingActivityNames||(exports.TrackingActivityNames={})).Undefined="undefined",I.PageViewOrganic="pageViewOrganic",I.PageViewUtmAttributed="pageViewUtmAttributed",I.AddPaymentMethod="addPaymentMethod",I.AddToWishlist="addToWishlist",I.ContactMessage="contactMessage",I.Custom="custom",I.SyncCart="syncCart",I.Order="order",I.InitiateCheckout="initiateCheckout",I.AddToCart="addToCart",I.RemoveFromCart="removeFromCart",I.OneTimeItemPurchase="oneTimeItemPurchase",I.SubscriptionItemPurchase="subscriptionItemPurchase",I.ViewProduct="viewProduct",I.ViewPage="viewPage",I.ApplyPromotionalCode="applyPromotionalCode",I.KeywordSearch="keywordSearch",I.UserLoginSignup="userLoginSignup",I.UserLogin="userLogin",I.NewsletterSignup="newsletterSignup",I.Lead="lead",I.ChangeProductAttribute="changeProductAttribute",I.FilterItemsByAttribute="filterItemsByAttribute",I.Schedule="schedule",I.ViewContentItem="viewContentItem",I.StartTrial="startTrial",exports.ECommerceContentType=void 0,(x=exports.ECommerceContentType||(exports.ECommerceContentType={})).Undefined="undefined",x.SingleProduct="singleProduct",x.SingleVariant="singleVariant",x.Collection="collection",exports.ECommercePlatform=void 0,(w=exports.ECommercePlatform||(exports.ECommercePlatform={})).None="none",w.BigCommerce="bigCommerce",w.Shopify="shopify",w.OrderGroove="orderGroove",w.Magento="magento",w.Generic="generic",w.WooCommerce="wooCommerce",w.Demandware="demandware",exports.ECommerceFulfillmentStatus=void 0,(C=exports.ECommerceFulfillmentStatus||(exports.ECommerceFulfillmentStatus={})).Undefined="undefined",C.Fulfilled="fulfilled",C.NoneFulfilled="noneFulfilled",C.PartiallyFulfilled="partiallyFulfilled",C.RestockedOrCancelled="restockedOrCancelled",exports.ECommerceFinancialStatus=void 0,(b=exports.ECommerceFinancialStatus||(exports.ECommerceFinancialStatus={})).Undefined="undefined",b.Pending="pending",b.Authorized="authorized",b.PartiallyPaid="partiallyPaid",b.Paid="paid",b.PartiallyRefunded="partiallyRefunded",b.Refunded="refunded",b.Voided="voided",exports.ConvergePipelineLoggableActivityType=void 0,(T=exports.ConvergePipelineLoggableActivityType||(exports.ConvergePipelineLoggableActivityType={})).Generic="generic",T.ActivityIngress="activityIngress",T.ActivityEgress="activityEgress",T.UserProfile="userProfile",T.SdkLog="sdkLog",T.Detections="detections",T.ActivityEgressFilter="activityEgressFilter",T.Diagnosis="diagnosis",T.PipelineIntegrationOutput="pipelineIntegrationOutput",exports.SdkLogEventLevel=void 0,(E=exports.SdkLogEventLevel||(exports.SdkLogEventLevel={})).Information="information",E.Warning="warning",E.Error="error",E.Verbose="verbose",exports.SeekaWebhookCallType=void 0,(U=exports.SeekaWebhookCallType||(exports.SeekaWebhookCallType={})).None="none",U.Probe="probe",U.AppInstalled="appInstalled",U.IdentityChanged="identityChanged",U.ActivityAccepted="activityAccepted",U.AppInstallSettingsUpdated="appInstallSettingsUpdated",U.AppUninstalled="appUninstalled",U.BrowserSdkPlugin="browserSdkPlugin",exports.ActivityPipelineActivityFilterType=void 0,(O=exports.ActivityPipelineActivityFilterType||(exports.ActivityPipelineActivityFilterType={})).Undefined="undefined",O.PurchaseMade="purchaseMade",O.ActivityTracked="activityTracked",exports.ConditionComparer=void 0,(N=exports.ConditionComparer||(exports.ConditionComparer={})).Undefined="undefined",N.And="and",N.Or="or",exports.ActivityPipelineActivityFilterSourceItemType=void 0,(B=exports.ActivityPipelineActivityFilterSourceItemType||(exports.ActivityPipelineActivityFilterSourceItemType={})).Undefined="undefined",B.Domain="domain",B.Pipeline="pipeline",B.Wildcard="wildcard";class F extends Error{constructor(e,t,i,r,s){super(),this.message=void 0,this.status=void 0,this.response=void 0,this.headers=void 0,this.result=void 0,this.isApiException=!0,this.message=e,this.status=t,this.response=i,this.headers=r,this.result=s}static isApiException(e){return!0===e.isApiException}}function _(e,t,i,r,s){throw null!=s?s:new F(e,t,i,r,null)}function R(e){return e&&!0===e.isAxiosError}const $=()=>`${M(new Date)}.${L()}`,L=()=>Math.floor(8999999999*Math.random()+1e9).toString(),M=e=>{let t=(e.getUTCMonth()+1).toString();t.length<2&&(t="0"+t);let i=e.getUTCDate().toString();i.length<2&&(i="0"+i);let r=e.getUTCHours().toString();r.length<2&&(r="0"+r);let s=e.getUTCMinutes().toString();s.length<2&&(s="0"+s);let n=e.getUTCSeconds().toString();return n.length<2&&(n="0"+n),`${e.getUTCFullYear()}${t}${i}.${r}${s}${n}`},j=(e,t)=>e.reduce((e,i,r)=>{const s=Math.floor(r/t);return e[s]||(e[s]=[]),e[s].push(i),e},[]),q=async e=>{const t=await D(e),i=new r.Issuer(t);return i[r.custom.http_options]=(e,t)=>({timeout:1e4}),i},D=async e=>{const 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});const i=new v(e.appId,e.applicationInstallId),r=(s=e.issuerUrl,l.createHash("md5").update(s).digest("hex"));var s;return await i.getOrSet(r,async()=>({value:await J(e),expiryAbsoluteMilliseconds:36e5}),async()=>{e.logger?e.logger.verbose("Seeka auth: got issuer from cache",{...t}):console.debug("Seeka auth: got issuer from cache",{...t})})},J=async e=>{const t={applicationId:e.appId,issuer:{url:e.issuerUrl}};return e.logger?e.logger.info("Seeka auth: discovering issuer from server",{...t}):console.info("Seeka auth: discovering issuer from server",{...t}),(await r.Issuer.discover(e.issuerUrl)).metadata},V=async e=>{const t=new v(e.appId,e.applicationInstallId),i={applicationId:e.appId,issuer:{url:e.issuerUrl}};return await t.getOrSet("auth:token:appinstall",async()=>{const t=await(async e=>{const t={applicationId:e.appId,issuer:{url:e.issuerUrl}},i=new((await q(e)).Client)({client_id:e.appId.replace(/-/g,""),client_secret:e.appSecret});try{const r=await i.grant({grant_type:"client_credentials"}),s={...t,token:{expires_at:r.expires_at,token_type:r.token_type,scope:r.scope}};return e.logger?e.logger.info("Seeka auth: got client access token from server",{...s}):console.info("Seeka auth: got app client token from server",{...s}),r}catch(i){const r={...t,error:i};return e.logger?e.logger.error("Seeka auth: failed to get client access token from server",{...r}):console.debug("Seeka auth: failed to get client access token from server",{...r}),null}})(e);if(!t)return null;const i=await(async(e,t)=>{const i={applicationId:t.appId,issuer:{url:t.issuerUrl}},r=new((await q(t)).Client)({client_id:t.appId.replace(/-/g,""),client_secret:t.appSecret});try{const s=await r.grant({grant_type:"app_install_token",applicationInstallId:t.applicationInstallId,access_token:e}),n={...i,token:{expires_at:s.expires_at,token_type:s.token_type,scope:s.scope}};return t.logger?t.logger.info("Seeka auth: got app access token from server",{...n}):console.info("Seeka auth: got app access token from server",{...n}),s}catch(e){const r={...i,error:e};return t.logger?t.logger.error("Seeka auth: failed to get app access token from server",{...r}):console.debug("Seeka auth: failed to get app access token from server",{...r}),null}})(t.access_token,e);return i?{value:i,expiryAbsoluteMilliseconds:((i.expires_in>t.expires_in?t.expires_in:i.expires_in)||9e5)-6e4}:null},async()=>{e.logger?e.logger.verbose("Seeka auth: got app token from cache",{...i}):console.debug("Seeka auth: got app token from cache",{...i})})},z=new p.default.Agent({keepAlive:!0,scheduling:"fifo"}),K=new u.default.Agent({keepAlive:!0,scheduling:"fifo"}),W=e=>{const t=d.default.create({httpAgent:z,httpsAgent:K});return t.interceptors.request.use(function(t){const i={url:t.url,method:t.method};return e.logger?e.logger.debug(`Seeka API: making call to ${i.url}`,{...i}):console.debug(`Seeka API: making call to ${i.url}`,{...i}),t},function(t){const i={error:t};return e.logger?e.logger.http("Seeka API: failed to send request",{...i}):console.debug("Seeka API: failed to send request",{...i}),Promise.reject(t)}),t.interceptors.response.use(function(t){var i,r;const s={url:(null==(i=t.request)?void 0:i.url)||t.config.url,method:(null==(r=t.request)?void 0:r.method)||t.config.method,response:{status:t.status}};return e.logger?e.logger.http(`Seeka API: call to ${s.url} succeeded`,{...s}):console.debug(`Seeka API: call to ${s.url} succeeded`,{...s}),t},function(t){var i;const{code:r,status:s,message:n}=t,{headers:o,url:a,method:c}=null==t?void 0:t.config,l={code:r,status:s,message:n,headers:o,url:a,method:c,content:null==t||null==(i=t.response)?void 0:i.data};return e.logger?e.logger.error(`Seeka API: call to ${l.url} failed`,{...l}):console.error(`Seeka API: call to ${l.url} failed`,{...l}),Promise.reject(t)}),t};class G{constructor(e){this.config=void 0,this.maxBatchSize=50,this.refreshOrPrimeTokenCache=async()=>{await V(this.config)},this.ingestionService=void 0,this.identityService=void 0,this.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},this.mergeIdentity=async(e,t)=>{var i;this.checkPermission(g.identity.send,"mergeIdentity");const r=$();return null==(i=(await this.identityService.merge({id:e,src:{method:"",origin:t.origin,time:void 0,loc:t.loc,sess:r,diag:"true"===process.env.SEEKA_DEBUG_ENABLED?r:void 0,runtime:this.config.runtime}})).result)?void 0:i.personId},this.mergeIdentityBatch=async(e,t)=>{this.checkPermission(g.identity.send,"mergeIdentityBatch");const i=$();var r;if(0===e.length)return void(null==(r=this.config.logger)||r.info("No identities in batch"));const s={method:"",origin:t.origin,time:void 0,loc:t.loc,sess:i,diag:"true"===process.env.SEEKA_DEBUG_ENABLED?i:void 0,runtime:this.config.runtime},n=j(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(e=>({id:{id:e||{},src:{...s}}}))}),n.length>1){const e=n.map((e,t)=>{var i;return 0===t?Promise.resolve():(null==(i=this.config.logger)||i.info(`Processing identity batch ${t+1} of ${n.length}`),this.trackActivityBatchRaw({data:e.map(e=>({id:{id:e||{},src:{...s}}}))}))});await Promise.all(e)}},this.trackActivityBatch=async(e,t)=>{this.checkPermission(g.activity.send,"trackActivityBatch");const i=$();var r;if(0===e.length)return void(null==(r=this.config.logger)||r.info("No activities in batch"));const s={method:"",origin:t.origin,time:void 0,loc:t.loc,sess:i,diag:"true"===process.env.SEEKA_DEBUG_ENABLED?i:void 0,runtime:this.config.runtime},n=j(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(e=>({ev:{id:e.profile||{},src:{...s},payload:e.activity}}))}),n.length>1){const e=n.map((e,t)=>{var i;return 0===t?Promise.resolve():(null==(i=this.config.logger)||i.info(`Processing activity batch ${t+1} of ${n.length}`),this.trackActivityBatchRaw({data:e.map(e=>({ev:{id:e.profile||{},src:{...s},payload:e.activity}}))}))});await Promise.all(e)}},this.trackActivityBatchRaw=async e=>{await this.ingestionService.batch(e)},this.trackActivityForProfileId=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfileId"),await this.trackActivityForProfileIdBatch([e],t,i)},this.trackActivityForProfileIdBatch=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfileIdBatch"),await this.trackActivityBatch(e.map(e=>({activity:e,profile:t?{seekaPId:t}:void 0})),i)},this.trackActivityForProfile=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfile"),await this.trackActivityForProfileBatch([e],t,i)},this.trackActivityForProfileBatch=async(e,t,i)=>{this.checkPermission(g.activity.send,"trackActivityForProfileBatch"),await this.trackActivityBatch(e.map(e=>({activity:e,profile:t})),i)},this.config=e,this.ingestionService=(e=>new k(e,e.ingestUrl,W(e)))(e),this.identityService=(e=>new y(e,e.ingestUrl,W(e)))(e)}}const H="x-seeka-signature-sha256",X=(e,t,i)=>{if(!t)return!1;let r=null;if(t.get&&"function"==typeof t.get)r=t.get(H);else{const e=t[H];e&&(Array.isArray(e)&&e.length>0?r=e[0]:("string"==typeof e||e instanceof String)&&(r=e))}if(!r)return!1;const s=Y(e,i)===r;return s||console.warn("Invalid webhook signature"),s},Y=(e,t)=>l.createHmac("sha256",e).update(t).digest("hex"),Q=(e,t,i,r,s)=>{const n=new m;return n.appId=e.applicationId,n.appSecret=t,n.ingestUrl=process.env.SEEKA_INGEST_URL||"https://router.seeka.services",n.issuerUrl=process.env.SEEKA_ISSUER_URL||"https://account.seeka.app",n.organisationId=e.organisationId,n.applicationInstallId=e.applicationInstallId,n.runtime={type:"sdk/js/apps-server",ver:"1.1.9",client:i},n.logger=s,n.grantedPermissions=r,n.transformApiRequest=e=>Z(n,e),n.transformApiResponse=async(e,t,i)=>ee(n,e,t,i),n.hasAnyPermissions=e=>!(!n.grantedPermissions||0===n.grantedPermissions.length)&&(!e||0===e.length||e.some(e=>n.grantedPermissions.includes(e))),n.hasAllPermissions=e=>!(!n.grantedPermissions||0===n.grantedPermissions.length)&&(!e||0===e.length||e.every(e=>n.grantedPermissions.includes(e))),n.hasPermission=e=>!(!n.grantedPermissions||0===n.grantedPermissions.length)&&(!e||n.grantedPermissions.includes(e)),n},Z=async(e,t)=>{const i=await V(e);return t.headers={...t.headers,"X-OrgId":e.organisationId,Authorization:"Bearer "+(null==i?void 0:i.access_token)},t},ee=async(e,t,i,r)=>(i.data=JSON.stringify(i.data),r(i));var te;class ie{constructor(e,t){this.context=void 0,this.appCache=void 0,this.appInstallCache=void 0,this.api=void 0,this.logger=void 0,this.context=e,this.api=new G(e.config),this.appCache=new v(e.config.appId),this.appInstallCache=new v(e.config.appId,e.config.applicationInstallId),this.logger=t}}te=ie,ie.create=(e,t,i,r,s)=>new te({config:Q({...t},e,{type:i.name,ver:i.version},r,s)},s),exports.ApiException=F,exports.ApiServiceProxyBase=f,exports.AppPermissionKeys=g,exports.IdentityServiceProxy=y,exports.IngestServiceProxy=k,exports.SeekaApiHelper=G,exports.SeekaAppCacheManager=v,exports.SeekaAppConfig=m,exports.SeekaAppHelper=ie,exports.chunk=j,exports.getActivityName=e=>{const t=Object.keys(exports.TrackingActivityNames),i=e.toLowerCase(),r=t.find(e=>e.toLowerCase()===i);return r?exports.TrackingActivityNames[r]:exports.TrackingActivityNames.Custom},exports.separatePersonFullName=e=>{if(!e)return{firstName:null,lastName:null};const t=e.trim().split(" ");return 1===t.length?{firstName:e,lastName:null}:2===t.length?{firstName:t[0],lastName:t[1]}:{firstName:t[0],lastName:t.slice(1).join(" ")}},exports.throwOnInvalidWebhookSignature=(e,t,i)=>{if(!X(e,t,i))throw new Error("Invalid webhook signature")},exports.validateWebhookSignature=X,exports.webhookSignatureHeaderName=H;
|
|
2
2
|
//# sourceMappingURL=sdk-apps-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-apps-server.js","sources":["../src/api/models/index.ts","../src/cache/appCacheManager/index.ts","../src/api/services/index.ts","../src/helpers/util/index.ts","../src/api/helper/auth/index.ts","../src/api/helper/serviceResolver/index.ts","../src/api/helper/index.ts","../src/api/webhooks/index.ts","../src/api/helper/config/index.ts","../src/helpers/app/index.ts"],"sourcesContent":["import { SeekaPipelineIntegrationSource, TrackingEventSourceOriginType } from '../../api/services';\n\nexport interface ServiceCallSource {\n /** Source method that requested the tracking. */\n method?: string;\n\n /** Type of origin that generated the tracking request.\n This is not the same as where the tracking event originated from, this property specifies where the tracking event was tracked from. */\n origin?: TrackingEventSourceOriginType;\n\n /** URL where the tracking event originated from. */\n loc?: string;\n\n pipeline?: SeekaPipelineIntegrationSource\n}\n\nexport const AppPermissionKeys = {\n identity: {\n receiveFull: 'Identity.Receive.Pii',\n send: 'Identity.Send'\n },\n activity: {\n receiveAnon: 'Activity.Receive.Anon',\n receiveFull: 'Activity.Receive.Pii',\n send: 'Activity.Send'\n }\n}","import * as memoryCache from 'memory-cache';\n\nconst prefix = 'seeka:sdk';\n\nexport class SeekaAppCacheManager {\n constructor(appId: string, appInstallationId?: string) {\n this.appId = appId;\n this.appInstallationId = appInstallationId;\n }\n\n private readonly appId: string;\n private readonly appInstallationId?: string;\n\n public set = async (key: string, value: any, expiryAbsoluteMilliseconds?: number): Promise<void> => {\n const cacheKey = this.getKey(key);\n memoryCache.put(cacheKey, JSON.stringify(value), expiryAbsoluteMilliseconds);\n }\n\n public getOrSet = async <TValue>(key: string, getValueAndExpiryFunc: () => Promise<{ value: TValue, expiryAbsoluteMilliseconds?: number } | null>, onGetFromCache?: (val: TValue | null) => Promise<void>): Promise<TValue | null> => {\n const cacheKey = this.getKey(key);\n\n const existing = memoryCache.get(cacheKey);\n if (existing) {\n const cached = JSON.parse(existing) as TValue;\n if (onGetFromCache) {\n await onGetFromCache(cached)\n }\n return cached;\n }\n\n const newVal = await getValueAndExpiryFunc();\n if (!newVal) return null;\n\n memoryCache.put(cacheKey, JSON.stringify(newVal.value), newVal.expiryAbsoluteMilliseconds);\n\n return newVal.value;\n }\n\n private getKey = (key: string): string => {\n if (this.appInstallationId) {\n return `${prefix}:${this.appId}:${this.appInstallationId}:${key}`;\n }\n return `${prefix}:${this.appId}:${key}`;\n }\n}","//----------------------\n// <auto-generated>\n// Generated using the NSwag toolchain v14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org)\n// </auto-generated>\n//----------------------\n\n/* tslint:disable */\n/* eslint-disable */\n// ReSharper disable InconsistentNaming\n\nimport axios, { AxiosError } from 'axios';\nimport { Logger } from 'winston';\nimport type { AxiosInstance, AxiosRequestConfig, AxiosResponse, CancelToken, Canceler } from 'axios';\nexport class SeekaAppConfig {\n appId!: string;\n appSecret!: string;\n ingestUrl!: string;\n issuerUrl!: string;\n organisationId!: string;\n applicationInstallId!: string;\n runtime!: AppRuntimeInfo;\n logger?: Logger\n grantedPermissions!: string[];\n\n transformApiRequest!: (options: AxiosRequestConfig) => Promise<AxiosRequestConfig>;\n transformApiResponse!: (url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => any;\n hasAnyPermissions!: (permissionKeys: string[]) => boolean\n hasAllPermissions!: (permissionKeys: string[]) => boolean\n hasPermission!: (permissionKey: string) => boolean\n}\n\nexport class ApiServiceProxyBase {\n private readonly config: SeekaAppConfig;\n\n protected constructor(config: SeekaAppConfig) {\n this.config = config;\n }\n\n protected transformOptions = async (options: AxiosRequestConfig): Promise<AxiosRequestConfig> => {\n return await this.config.transformApiRequest(options);\n };\n\n protected transformResult = async (url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => {\n return await this.config.transformApiResponse(url, response, processor);\n }\n}\n\nexport class IdentityServiceProxy extends ApiServiceProxyBase {\n protected instance: AxiosInstance;\n protected baseUrl: string;\n protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;\n\n constructor(configuration: SeekaAppConfig, baseUrl?: string, instance?: AxiosInstance) {\n\n super(configuration);\n\n this.instance = instance || axios.create();\n\n this.baseUrl = baseUrl ?? \"https://api-localdev-env0-seeka.au.ngrok.io\";\n\n }\n\n /**\n * Merge identity\n */\n merge(payload: PersonIdentificationRequest, cancelToken?: CancelToken): Promise<ApiResponseDtoOfPersonIdentificationResolutionResponse> {\n let url_ = this.baseUrl + \"/api/identity\";\n url_ = url_.replace(/[?&]$/, \"\");\n\n const content_ = JSON.stringify(payload);\n\n let options_: AxiosRequestConfig = {\n data: content_,\n method: \"POST\",\n url: url_,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\"\n },\n cancelToken\n };\n\n return this.transformOptions(options_).then(transformedOptions_ => {\n return this.instance.request(transformedOptions_);\n }).catch((_error: any) => {\n if (isAxiosError(_error) && _error.response) {\n return _error.response;\n } else {\n throw _error;\n }\n }).then((_response: AxiosResponse) => {\n return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processMerge(_response));\n });\n }\n\n protected processMerge(response: AxiosResponse): Promise<ApiResponseDtoOfPersonIdentificationResolutionResponse> {\n const status = response.status;\n let _headers: any = {};\n if (response.headers && typeof response.headers === \"object\") {\n for (const k in response.headers) {\n if (response.headers.hasOwnProperty(k)) {\n _headers[k] = response.headers[k];\n }\n }\n }\n if (status === 200) {\n const _responseText = response.data;\n let result200: any = null;\n let resultData200 = _responseText;\n result200 = JSON.parse(resultData200);\n return Promise.resolve<ApiResponseDtoOfPersonIdentificationResolutionResponse>(result200);\n\n } else if (status === 401) {\n const _responseText = response.data;\n let result401: any = null;\n let resultData401 = _responseText;\n result401 = JSON.parse(resultData401);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result401);\n\n } else if (status === 422) {\n const _responseText = response.data;\n let result422: any = null;\n let resultData422 = _responseText;\n result422 = JSON.parse(resultData422);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result422);\n\n } else if (status === 400) {\n const _responseText = response.data;\n let result400: any = null;\n let resultData400 = _responseText;\n result400 = JSON.parse(resultData400);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result400);\n\n } else if (status !== 200 && status !== 204) {\n const _responseText = response.data;\n return throwException(\"An unexpected server error occurred.\", status, _responseText, _headers);\n }\n return Promise.resolve<ApiResponseDtoOfPersonIdentificationResolutionResponse>(null as any);\n }\n}\n\nexport class IngestServiceProxy extends ApiServiceProxyBase {\n protected instance: AxiosInstance;\n protected baseUrl: string;\n protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;\n\n constructor(configuration: SeekaAppConfig, baseUrl?: string, instance?: AxiosInstance) {\n\n super(configuration);\n\n this.instance = instance || axios.create();\n\n this.baseUrl = baseUrl ?? \"https://api-localdev-env0-seeka.au.ngrok.io\";\n\n }\n\n /**\n * Track activity\n */\n batch(payload: DataIngestBatchHttpRequest, cancelToken?: CancelToken): Promise<void> {\n let url_ = this.baseUrl + \"/api/ingest\";\n url_ = url_.replace(/[?&]$/, \"\");\n\n const content_ = JSON.stringify(payload);\n\n let options_: AxiosRequestConfig = {\n data: content_,\n method: \"POST\",\n url: url_,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n cancelToken\n };\n\n return this.transformOptions(options_).then(transformedOptions_ => {\n return this.instance.request(transformedOptions_);\n }).catch((_error: any) => {\n if (isAxiosError(_error) && _error.response) {\n return _error.response;\n } else {\n throw _error;\n }\n }).then((_response: AxiosResponse) => {\n return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processBatch(_response));\n });\n }\n\n protected processBatch(response: AxiosResponse): Promise<void> {\n const status = response.status;\n let _headers: any = {};\n if (response.headers && typeof response.headers === \"object\") {\n for (const k in response.headers) {\n if (response.headers.hasOwnProperty(k)) {\n _headers[k] = response.headers[k];\n }\n }\n }\n if (status === 202) {\n const _responseText = response.data;\n return Promise.resolve<void>(null as any);\n\n } else if (status === 401) {\n const _responseText = response.data;\n let result401: any = null;\n let resultData401 = _responseText;\n result401 = JSON.parse(resultData401);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result401);\n\n } else if (status === 422) {\n const _responseText = response.data;\n let result422: any = null;\n let resultData422 = _responseText;\n result422 = JSON.parse(resultData422);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result422);\n\n } else if (status === 400) {\n const _responseText = response.data;\n let result400: any = null;\n let resultData400 = _responseText;\n result400 = JSON.parse(resultData400);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result400);\n\n } else if (status !== 200 && status !== 204) {\n const _responseText = response.data;\n return throwException(\"An unexpected server error occurred.\", status, _responseText, _headers);\n }\n return Promise.resolve<void>(null as any);\n }\n}\n\nexport interface ApiResponseDtoOfPersonIdentificationResolutionResponse {\n result?: PersonIdentificationResolutionResponse;\n}\n\nexport interface PersonIdentificationResolutionResponse {\n personId?: string;\n}\n\nexport interface ApiResponseDtoOfObject {\n result?: any;\n}\n\nexport interface DetailedApiResponseDtoOfObject extends ApiResponseDtoOfObject {\n type?: ResponseResultType;\n error?: ErrorInfo;\n success?: boolean;\n}\n\nexport interface ApiResponseErrorDtoOfObject extends DetailedApiResponseDtoOfObject {\n}\n\nexport interface ApiResponseError extends ApiResponseErrorDtoOfObject {\n}\n\nexport enum ResponseResultType {\n Undefined = \"undefined\",\n Success = \"success\",\n Failed = \"failed\",\n}\n\nexport interface ErrorInfo {\n message?: string;\n code?: number;\n correlationId?: string;\n validation?: ValidationSummary;\n}\n\nexport interface ValidationSummary {\n properties?: PropertyValidationError[];\n}\n\nexport interface PropertyValidationError {\n errorKey?: string;\n helpActions?: HelpAction[];\n propertyName?: string;\n attemptedValue?: any;\n errorMessage?: string;\n children?: PropertyValidationError[];\n}\n\nexport interface HelpAction {\n helpActionUrl?: string;\n helpActionTitle?: string;\n}\n\nexport interface PersonIdentificationRequest {\n /** Collection of identifiers used to calculate the identity graph. */\n id: PersonIdentifiers;\n /** Source of the identification request. */\n src: TrackingEventSource;\n}\n\nexport interface PersonIdentifiersBase {\n /** Browser user agent */\n ua?: string[];\n /** IP Address */\n ip?: string[];\n /** Seeka Person ID - Identity graph ID */\n seekaPId?: string;\n /** Seeka Browser ID */\n seekaBId?: string[];\n /** Email address */\n email?: string[];\n /** Gender */\n gender?: string[];\n /** Phone number. Recommended to provide in E.164 format. */\n phone?: string[];\n /** First name */\n firstName?: string[];\n /** Last name / surname */\n lastName?: string[];\n /** Shipping, mailing or residential address */\n address?: PlaceAddress[];\n /** Date of birth */\n dob?: Date[];\n /** Shopify identifiers */\n shopify?: ShopifyPersonIdentifiers;\n /** WooCommerce identifiers */\n wooCommerce?: WooCommercePersonIdentifiers;\n /** BigCommerce identifiers */\n bigCommerce?: BigCommercePersonIdentifiers;\n /** Magento identifiers */\n magento?: MagentoPersonIdentifiers;\n /** Klaviyo identifiers scoped by Klaviyo account ID */\n klaviyo?: ScopedIdentifiersOfKlaviyoPersonIdentifiersDtoAndString;\n /** Arbitrary traits */\n traits?: { [key: string]: any; };\n}\n\nexport interface PersonIdentifiers extends PersonIdentifiersBase {\n /** Facebook identifiers */\n facebook?: FacebookPersonIdentifiers;\n /** Snapchat identifiers */\n snapchat?: SnapchatPersonIdentifiers;\n /** TikTok identifiers */\n tiktok?: TikTokPersonIdentifiers;\n /** Google identifiers */\n google?: GooglePersonIdentifiers;\n /** Pinterest identifiers */\n pinterest?: PinterestPersonIdentifiers;\n /** Marketing, analytics and other third-party opt in/consent information */\n consent?: PersonConsentInfo;\n}\n\nexport interface BrandScopedFacebookPersonIdentifiers {\n /** Facebook user login ID */\n login?: string[];\n /** Facebook click ID */\n fbc?: string[];\n /** Facebook lead ID */\n lead?: string[];\n}\n\nexport interface FacebookPersonIdentifiers extends BrandScopedFacebookPersonIdentifiers {\n /** Facebook pixel / browser ID */\n fbp?: string[];\n}\n\nexport interface BrandScopedSnapchatPersonIdentifiers {\n /** Snapchat click ID */\n sccid?: string[];\n}\n\nexport interface SnapchatPersonIdentifiers extends BrandScopedSnapchatPersonIdentifiers {\n /** Snapchat pixel / browser ID */\n scid?: string[];\n}\n\nexport interface BrandScopedTikTokPersonIdentifiers {\n /** TikTok click ID */\n ttclid?: string[];\n /** TikTok lead ID */\n lead?: string[];\n}\n\nexport interface TikTokPersonIdentifiers extends BrandScopedTikTokPersonIdentifiers {\n /** TikTok pixel / browser ID */\n ttp?: string[];\n}\n\nexport interface BrandScopedGooglePersonIdentifiers {\n /** Google click ID */\n gclid?: string[];\n}\n\nexport interface GooglePersonIdentifiers extends BrandScopedGooglePersonIdentifiers {\n /** Google user client ID */\n userClientId?: string[];\n}\n\nexport interface BrandScopedPinterestPersonIdentifiers {\n /** Pinterest click ID / epik ID */\n epik?: string[];\n}\n\nexport interface PinterestPersonIdentifiers extends BrandScopedPinterestPersonIdentifiers {\n}\n\nexport interface PersonConsentInfo {\n /** Grant for sending data to 3rd party analytics and marketing platforms. */\n analytics?: ConsentInfo;\n /** Grant for marketing via re-marketing campaigns, EDMs etc. */\n marketing?: MarketingConsentInfo;\n /** Grant for enrolling and participating in loyalty programs. */\n loyalty?: ConsentInfo;\n privacy?: PrivacyState;\n}\n\nexport interface ConsentInfo {\n type?: PrivacyConsentType;\n /** When the consent was granted. */\n consentGrantedAt?: Date | undefined;\n /** The name of the source that provided the grant information. Set to the source platform like Shopify, Wordpress or your custom integration client name. */\n consentGrantedSourceName?: string;\n /** When the consent was not granted. */\n consentNotGrantedAt?: Date | undefined;\n /** The name of the source that provided the grant information. Set to the source platform like Shopify, Wordpress or your custom integration client name. */\n consentNotGrantedSourceName?: string;\n}\n\nexport enum PrivacyConsentType {\n Unknown = \"unknown\",\n Informed = \"informed\",\n Implied = \"implied\",\n Explicit = \"explicit\",\n Active = \"active\",\n Passive = \"passive\",\n}\n\nexport interface MarketingConsentInfo {\n email?: ConsentInfo;\n sms?: ConsentInfo;\n}\n\nexport interface PrivacyState {\n /** Transparency and Consent Framework (TCF) consent string v2.0\nSee https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20Consent%20string%20and%20vendor%20list%20formats%20v2.md */\n tcfConsentString?: string | undefined;\n}\n\nexport interface PlaceAddress {\n description?: string;\n addressLine1?: string;\n addressLine2?: string;\n streetName?: string;\n locality?: string;\n /** Full name of the state / province / territory */\n state?: string;\n /** ISO 3166-2 - Two or three character subdivision code */\n stateCode?: string;\n postcode?: string;\n /** Full name of the country */\n country?: string;\n /** ISO 3166-2 - Two character country code */\n countryCode?: string;\n googlePlaceId?: string;\n timeZone?: TimeZoneInfo;\n geoLocation?: GeographicalCoordinate;\n}\n\nexport interface TimeZoneInfo {\n /** IANA timezone ID */\n friendlyId?: string;\n description?: string;\n}\n\nexport interface GeographicalCoordinate {\n longitude?: number;\n latitude?: number;\n}\n\nexport interface ShopifyPersonIdentifiers {\n customerId?: string[];\n uniqueToken?: string[];\n microSessionId?: string[];\n visitToken?: string[];\n cartToken?: string[];\n checkoutToken?: string[];\n cartId?: string[];\n deviceId?: string[];\n checkoutId?: string[];\n orderId?: string[];\n sessionHash?: string[];\n}\n\nexport interface WooCommercePersonIdentifiers {\n customerId?: string[];\n orderId?: string[];\n cartHash?: string[];\n}\n\nexport interface BigCommercePersonIdentifiers {\n /** BigCommerce */\n customerId?: string[];\n /** BigCommerce */\n cartId?: string[];\n /** BigCommerce */\n orderId?: string[];\n}\n\nexport interface MagentoPersonIdentifiers {\n /** Magento customer */\n customerId?: string[];\n /** Magento cart */\n cartId?: string[];\n /** Magento order unique identifier */\n orderId?: string[];\n /** Magento order number / incremental ID */\n orderNumber?: string[];\n /** Magento checkout */\n checkoutId?: string[];\n}\n\nexport interface ScopedIdentifiersOfKlaviyoPersonIdentifiersDtoAndString {\n data?: { [key: string]: KlaviyoPersonIdentifiers; };\n}\n\nexport interface KlaviyoPersonIdentifiers {\n /** Klaviyo profile ID */\n profileId?: string[] | undefined;\n}\n\nexport interface TrackingEventSource {\n /** Source method that requested the tracking. */\n method: string;\n /** Type of origin that generated the tracking request.\nThis is not the same as where the tracking event originated from, this property specifies where the tracking event was tracked from. */\n origin?: TrackingEventSourceOriginType | undefined;\n /** Time occurred. Do not provide to use server time (recommended) */\n time?: Date | undefined;\n /** URL where the tracking event originated from. */\n loc: string;\n /** Title of the view or page where the tracking event originated from. */\n vt?: string | undefined;\n /** Session ID where the tracking event originated from. UTC date.time and then random digits.\nFormat YYYYMMDD.HHMMSS.{random 10 digits} */\n sess?: string | undefined;\n /** Diagnosis session ID. UTC date.time and then random digits.\nFormat YYYYMMDD.HHMMSS.{random 10 digits} */\n diag?: string | undefined;\n runtime?: SeekaSdkRuntimeInfo;\n /** Context of the pipeline integration that raised the tracking event. */\n pipeline?: SeekaPipelineIntegrationSource | undefined;\n /** IP address */\n ip?: string | undefined;\n device?: DeviceTrackingSource | undefined;\n privacy?: PrivacyState | undefined;\n}\n\nexport enum TrackingEventSourceOriginType {\n Browser = \"browser\",\n Server = \"server\",\n Mobile = \"mobile\",\n Desktop = \"desktop\",\n PhysicalStore = \"physicalStore\",\n Email = \"email\",\n Phone = \"phone\",\n Chat = \"chat\",\n Automatic = \"automatic\",\n}\n\nexport interface SeekaSdkRuntimeInfo {\n /** Version of the package or library being used to interact with the SDK */\n ver?: string;\n /** Type of the package or library being used to interact with the SDK */\n type?: string;\n client?: SeekaSdkClientRuntimeInfo;\n}\n\nexport interface SeekaSdkClientRuntimeInfo {\n /** Client version used to identify the implementation of the SDK */\n ver?: string;\n /** Name or type used to identify the implementation of the SDK. This could be specified as 'backend' for a backend integration with the SDK or 'website' for integrations placed on a website. */\n type?: string;\n}\n\nexport interface SeekaPipelineIntegrationSource {\n convergePipelineIntegrationInstanceId?: string;\n /** The IntegrationVendorNameKey could be set to \"Klaviyo\" for all Klaviyo pipeline integration classes so that the rate limit for certain operations are shared across all Klaviyo integration instances that share the same IntegrationInstanceUniqueKey\nAlpha only\nMax length of 12 characters */\n integrationVendorNameKey?: string;\n /** In format of IntegrationPublisherCompany.IntegrationVendorNameKey.IntegrationName. Eg. Seeka.Klaviyo.Identity */\n convergePipelineIntegrationTypeKey?: string;\n}\n\nexport interface DeviceTrackingSource {\n /** Browser name (Chrome, Firefox, Safari, etc) */\n bn?: string | undefined;\n /** Browser version */\n bv?: string | undefined;\n /** Platform name (Win32, OSX etc) */\n pl?: string | undefined;\n /** Device fingerprint */\n fp?: string | undefined;\n}\n\nexport interface DataIngestBatchHttpRequest {\n /** Max batch size is 50 */\n data?: DataIngestBatchHttpItem[];\n}\n\nexport interface DataIngestBatchHttpItem {\n ev?: ActivityTrackingRequest;\n id?: PersonIdentificationRequest;\n bot?: BotMetricTrackingRequest;\n log?: ActivityLogRequest;\n}\n\nexport interface ActivityTrackingRequest {\n /** Collection of identifiers used to calculate the identity graph. */\n id: PersonIdentifiers;\n /** Source of the identification request. */\n src: TrackingEventSource;\n /** Custom properties to attach to tracking event */\n props?: { [key: string]: string; };\n /** UTM tracking information */\n utm?: UtmTrackingEvent[];\n /** Activity tracking information */\n payload?: ActivityPayload;\n}\n\nexport interface UtmTrackingEvent {\n /** UTM ID */\n id?: string;\n /** UTM content */\n content?: string;\n /** UTM source */\n source?: string;\n /** UTM campaign */\n campaign?: string;\n /** UTM term */\n term?: string;\n /** UTM medium */\n medium?: string;\n}\n\nexport interface ActivityPayloadBase {\n /** Standard or custom activity / behavior activity name. */\n activityName?: TrackingActivityNames;\n /** Required if ActivityName is set to Custom.\nWhen setting this parameter in conjunction with setting ActivityName to a standard event name, Seeka will process the event\nas a standard event with the exception of conversion based data destinations being sent the event as the ActivityNameCustom value\nwith the parameters of the standard event. */\n activityNameCustom?: string;\n /** Unique identifier used to de-duplicate activities */\n activityId?: string;\n /** E-Commerce specific activity properties */\n commerce?: CommerceActivityTrackingEventMetadata;\n /** Search function specific activity properties */\n search?: SearchActivityTrackingEventMetadata;\n /** Sign up / newsletter function specific activity properties */\n signUp?: SignUpActivityTrackingEventMetadata;\n /** User account specific activity properties */\n userAccount?: UserAccountActivityTrackingEventMetadata;\n /** Promotion specific activity properties */\n promotion?: PromotionalActivityTrackingEventMetadata;\n /** Content behavior specific activity properties */\n contentBehaviour?: ContentBehaviourActivityTrackingEventMetadata;\n /** Lead activity properties */\n lead?: LeadActivityTrackingEventMetadata;\n /** Content item activity properties */\n contentItem?: ContentItemActivityTrackingEventMetadata;\n /** Custom properties attached to the tracking event */\n properties?: { [key: string]: string; };\n}\n\nexport interface ActivityPayload extends ActivityPayloadBase {\n /** Time activity occurred. Do not provide to use server time (recommended) */\n time?: Date | undefined;\n}\n\nexport enum TrackingActivityNames {\n Undefined = \"undefined\",\n PageViewOrganic = \"pageViewOrganic\",\n PageViewUtmAttributed = \"pageViewUtmAttributed\",\n AddPaymentMethod = \"addPaymentMethod\",\n AddToWishlist = \"addToWishlist\",\n ContactMessage = \"contactMessage\",\n Custom = \"custom\",\n SyncCart = \"syncCart\",\n Order = \"order\",\n InitiateCheckout = \"initiateCheckout\",\n AddToCart = \"addToCart\",\n RemoveFromCart = \"removeFromCart\",\n OneTimeItemPurchase = \"oneTimeItemPurchase\",\n SubscriptionItemPurchase = \"subscriptionItemPurchase\",\n ViewProduct = \"viewProduct\",\n ViewPage = \"viewPage\",\n ApplyPromotionalCode = \"applyPromotionalCode\",\n KeywordSearch = \"keywordSearch\",\n UserLoginSignup = \"userLoginSignup\",\n UserLogin = \"userLogin\",\n NewsletterSignup = \"newsletterSignup\",\n Lead = \"lead\",\n ChangeProductAttribute = \"changeProductAttribute\",\n FilterItemsByAttribute = \"filterItemsByAttribute\",\n Schedule = \"schedule\",\n ViewContentItem = \"viewContentItem\",\n StartTrial = \"startTrial\",\n}\n\nexport interface CommerceActivityTrackingEventMetadata {\n products?: CommerceActivityTrackingEventProductMetadata[];\n checkoutIdentifier?: string;\n cartIdentifier?: string;\n orderIdentifier?: string;\n orderNumber?: string;\n customerIdentifier?: string;\n sourceChannelName?: string;\n platformType?: ECommercePlatform;\n paymentMethodName?: string;\n currencyCode?: string;\n isTest?: boolean;\n totalRefunds?: number | undefined;\n totalDiscounts?: number | undefined;\n totalLineItemsPrice?: number | undefined;\n totalPrice?: number | undefined;\n totalTax?: number | undefined;\n totalShippingPrice?: number | undefined;\n fulfillmentStatus?: ECommerceFulfillmentStatus | undefined;\n financialStatus?: ECommerceFinancialStatus | undefined;\n}\n\nexport interface CommerceActivityTrackingEventProductMetadata {\n /** ISO 4217 currency code */\n currencyCode?: string;\n productIdentifier?: string;\n variantIdentifier?: string;\n sku?: string;\n lineItemIdentifier?: string;\n productName?: string;\n variantName?: string;\n categoryName?: string;\n brandName?: string;\n unitPrice?: number | undefined;\n quantity?: number | undefined;\n totalDiscount?: number | undefined;\n type?: ECommerceContentType | undefined;\n attributes?: { [key: string]: any; };\n}\n\nexport enum ECommerceContentType {\n Undefined = \"undefined\",\n SingleProduct = \"singleProduct\",\n SingleVariant = \"singleVariant\",\n Collection = \"collection\",\n}\n\nexport enum ECommercePlatform {\n None = \"none\",\n BigCommerce = \"bigCommerce\",\n Shopify = \"shopify\",\n OrderGroove = \"orderGroove\",\n Magento = \"magento\",\n Generic = \"generic\",\n WooCommerce = \"wooCommerce\",\n Demandware = \"demandware\",\n}\n\n/** https://shopify.dev/api/admin-rest/2022-01/resources/order#resource-object */\nexport enum ECommerceFulfillmentStatus {\n Undefined = \"undefined\",\n Fulfilled = \"fulfilled\",\n NoneFulfilled = \"noneFulfilled\",\n PartiallyFulfilled = \"partiallyFulfilled\",\n RestockedOrCancelled = \"restockedOrCancelled\",\n}\n\n/** https://shopify.dev/api/admin-rest/2022-01/resources/order#resource-object */\nexport enum ECommerceFinancialStatus {\n Undefined = \"undefined\",\n Pending = \"pending\",\n Authorized = \"authorized\",\n PartiallyPaid = \"partiallyPaid\",\n Paid = \"paid\",\n PartiallyRefunded = \"partiallyRefunded\",\n Refunded = \"refunded\",\n Voided = \"voided\",\n}\n\nexport interface SearchActivityTrackingEventMetadata {\n searchText?: string;\n}\n\nexport interface UserAccountActivityTrackingEventMetadata {\n emailAddress?: string | undefined;\n userAccountIdentifierValue?: string | undefined;\n userAccountIdentifierTypeName?: string | undefined;\n}\n\nexport interface SignUpActivityTrackingEventMetadata extends UserAccountActivityTrackingEventMetadata {\n}\n\nexport interface PromotionalActivityTrackingEventMetadata {\n code?: string;\n}\n\nexport interface ContentBehaviourActivityTrackingEventMetadata {\n /** Behavior that changes or customised a product via an attribute. */\n changeProduct?: ChangeProductAttributeActivityTrackingEventMetadata;\n /** Behavior that filters a list of items or content via an attribute. */\n filterItems?: FilterItemsByAttributeActivityTrackingEventMetadata;\n}\n\nexport interface ChangeProductAttributeActivityTrackingEventMetadata {\n /** Name of the type of attribute. */\n attributeTypeName?: string;\n /** Previous value of the attribute before the change. */\n previousAttributeValue?: string;\n /** Value the attribute was changed to. */\n newAttributeValue?: string;\n /** Product that relates to attribute change. */\n product?: CommerceActivityTrackingEventProductMetadata;\n}\n\nexport interface FilterItemsByAttributeActivityTrackingEventMetadata {\n /** Name of the type of attribute that is being filtered by. */\n attributeTypeName?: string;\n /** String value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n stringValue?: string;\n /** Numerical value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n numericValue?: number | undefined;\n /** Date value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n dateValue?: Date | undefined;\n /** Boolean (true/false) value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n booleanValue?: boolean | undefined;\n}\n\nexport interface LeadActivityTrackingEventMetadata {\n sourceContentName?: string;\n companySize?: string;\n companyName?: string;\n predictedLtv?: number | undefined;\n predictedValue?: number | undefined;\n /** ISO 4217 currency code */\n currencyCode?: string;\n}\n\nexport interface ContentItemActivityTrackingEventMetadata {\n contentName?: string;\n identifiers?: string[];\n categoryName?: string;\n /** ISO 4217 currency code */\n currencyCode?: string;\n value?: number | undefined;\n contentType?: ECommerceContentType | undefined;\n items?: CommerceActivityTrackingEventProductMetadata[];\n}\n\nexport interface BotMetricTrackingRequest extends PersonIdentificationRequest {\n}\n\nexport interface ActivityTrackingBase {\n id?: string;\n source?: TrackingEventSource;\n properties?: { [key: string]: string; };\n utm?: UtmTrackingEvent;\n}\n\nexport interface ActivityLogRequest extends ActivityTrackingBase {\n logType?: ConvergePipelineLoggableActivityType;\n logLevel?: SdkLogEventLevel;\n messageTemplate?: string;\n identifiers?: PersonIdentifiers;\n}\n\nexport enum ConvergePipelineLoggableActivityType {\n Generic = \"generic\",\n ActivityIngress = \"activityIngress\",\n ActivityEgress = \"activityEgress\",\n UserProfile = \"userProfile\",\n SdkLog = \"sdkLog\",\n Detections = \"detections\",\n ActivityEgressFilter = \"activityEgressFilter\",\n Diagnosis = \"diagnosis\",\n PipelineIntegrationOutput = \"pipelineIntegrationOutput\",\n}\n\nexport enum SdkLogEventLevel {\n Information = \"information\",\n Warning = \"warning\",\n Error = \"error\",\n Verbose = \"verbose\",\n}\n\nexport enum SeekaWebhookCallType {\n None = \"none\",\n Probe = \"probe\",\n AppInstalled = \"appInstalled\",\n IdentityChanged = \"identityChanged\",\n ActivityAccepted = \"activityAccepted\",\n AppInstallSettingsUpdated = \"appInstallSettingsUpdated\",\n AppUninstalled = \"appUninstalled\",\n BrowserSdkPlugin = \"browserSdkPlugin\",\n}\n\nexport interface SeekaWebhookPayload {\n type?: SeekaWebhookCallType;\n /** Determines if the webhook is sent as a result of a test call */\n isTest?: boolean;\n /** Unique identifier for the webhook request */\n requestId?: string;\n causationId?: string | undefined;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContext extends SeekaWebhookPayload {\n context?: SeekaAppWebhookContext;\n}\n\nexport interface SeekaAppWebhookContext {\n /** ID of the organisation that installed the app */\n organisationId?: string;\n /** ID of the brand that installed the app */\n organisationBrandId?: string;\n /** Pipeline integration ID / ID of the installation of the app */\n applicationInstallId?: string;\n /** The client / application ID */\n applicationId?: string;\n}\n\nexport interface SeekaBrowserSdkPluginWebhookResponse {\n content: string;\n init: string;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaAppInstalledWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstalledWebhookContent;\n}\n\nexport interface SeekaAppInstalledWebhookContent {\n installationSettings?: { [key: string]: any; };\n /** The permissions granted to the app install by the user that installed the app. */\n grantedPermissions?: string[];\n}\n\nexport interface SeekaAppInstalledWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstalledWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaAppUninstalledWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppUninstalledWebhookContent;\n}\n\nexport interface SeekaAppUninstalledWebhookContent {\n installationSettings?: { [key: string]: any; };\n}\n\nexport interface SeekaAppUninstalledWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppUninstalledWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaAppInstallSettingsUpdatedWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstallSettingsUpdatedWebhookContent;\n}\n\nexport interface SeekaAppInstallSettingsUpdatedWebhookContent {\n installationSettings?: { [key: string]: any; };\n /** The permissions granted to the app install by the user that installed the app. */\n grantedPermissions?: string[];\n}\n\nexport interface SeekaAppInstallSettingsUpdatedWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstallSettingsUpdatedWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaActivityAcceptedWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaActivityAcceptedWebhookContent;\n}\n\nexport interface SeekaActivityAcceptedWebhookContent {\n source?: TrackingEventSource;\n identifiers?: PersonIdentifiers;\n activity?: WebsiteEventActivityAppsPayload;\n personId?: string;\n}\n\nexport interface WebsiteEventActivityAppsPayload extends ActivityPayloadBase {\n /** Time activity occurred */\n time?: Date;\n}\n\nexport interface SeekaActivityAcceptedWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaActivityAcceptedWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaIdentityChangedWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaIdentityChangedWebhookContent;\n}\n\nexport interface SeekaIdentityChangedWebhookContent {\n identifiers?: PersonIdentifiers;\n personId?: string;\n}\n\nexport interface SeekaIdentityChangedWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaIdentityChangedWebhookContent;\n}\n\nexport class ApiException extends Error {\n override message: string;\n status: number;\n response: string;\n headers: { [key: string]: any; };\n result: any;\n\n constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {\n super();\n\n this.message = message;\n this.status = status;\n this.response = response;\n this.headers = headers;\n this.result = result;\n }\n\n protected isApiException = true;\n\n static isApiException(obj: any): obj is ApiException {\n return obj.isApiException === true;\n }\n}\n\nfunction throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any {\n if (result !== null && result !== undefined)\n throw result;\n else\n throw new ApiException(message, status, response, headers, null);\n}\n\nfunction isAxiosError(obj: any): obj is AxiosError {\n return obj && obj.isAxiosError === true;\n}\n\n// Dont remove unused imports as they are used in the generated code\n\n// Dont remove unused imports as they are used in the generated code\n\nexport interface AppClientRuntimeInfo {\n /** Client version used to identify the implementation of the SDK */\n ver: string;\n /** Name or type used to identify the implementation of the SDK. This could be specified as 'backend' for a backend integration with the SDK or 'website' for integrations placed on a website. */\n type: string;\n}\n\nexport interface AppRuntimeInfo {\n /** Version of the package or library being used to interact with the SDK */\n ver: string;\n /** Type of the package or library being used to interact with the SDK */\n type: string;\n client: AppClientRuntimeInfo;\n}","import * as crypto from 'crypto';\nimport { TrackingActivityNames } from 'src/api/services';\n\nexport const generateNewSessionId = (): string => {\n /** Session ID where the tracking event originated from. Format of UTC time YYYYMMDD.HHMMSS.{random 6 digits} */\n const dateReference = dateToUtcDateTimeReferenceString(new Date());\n const random = getRandomNumberString();\n\n return `${dateReference}.${random}`;\n}\n\nexport const getActivityName = (event: string): TrackingActivityNames => {\n const vals = Object.keys(TrackingActivityNames)\n const evLower = event.toLowerCase();\n\n const matched = vals.find(e => e.toLowerCase() === evLower);\n\n if (matched) {\n return TrackingActivityNames[matched as keyof typeof TrackingActivityNames];\n }\n\n return TrackingActivityNames.Custom;\n}\n\nexport const getRandomNumberString = (): string => {\n const min = 1000000000;\n const max = 9999999999;\n return Math.floor(Math.random() * (max - min) + min).toString();\n}\n\nexport const dateToUtcDateTimeReferenceString = (forDateTime: Date): string => {\n let month = (forDateTime.getUTCMonth() + 1).toString();\n if (month.length < 2) {\n month = \"0\" + month;\n }\n let day = forDateTime.getUTCDate().toString();\n if (day.length < 2) {\n day = \"0\" + day;\n }\n let hour = forDateTime.getUTCHours().toString();\n if (hour.length < 2) {\n hour = \"0\" + hour;\n }\n let minute = forDateTime.getUTCMinutes().toString();\n if (minute.length < 2) {\n minute = \"0\" + minute;\n }\n let second = forDateTime.getUTCSeconds().toString();\n if (second.length < 2) {\n second = \"0\" + second;\n }\n\n return `${forDateTime.getUTCFullYear()}${month}${day}.${hour}${minute}${second}`;\n}\n\nexport const md5Hash = (input: string): string => {\n return crypto.createHash('md5').update(input).digest(\"hex\");\n}\n\nexport const separatePersonFullName = (fullname: string): { firstName: string | null, lastName: string | null } => {\n if (!fullname) return { firstName: null, lastName: null };\n\n const parts = fullname.trim().split(' ');\n if (parts.length === 1) return { firstName: fullname, lastName: null };\n else if (parts.length === 2) return { firstName: parts[0], lastName: parts[1] };\n else return { firstName: parts[0], lastName: parts.slice(1).join(' ') };\n}\n\n// Replicates lodash chunk method\nexport const chunk = <T>(array: T[], size: number): T[][] => {\n return array.reduce((resultArray: Array<T[]>, item, index) => {\n const chunkIndex = Math.floor(index / size)\n\n if (!resultArray[chunkIndex]) {\n resultArray[chunkIndex] = [] // start a new chunk\n }\n\n resultArray[chunkIndex].push(item)\n\n return resultArray\n }, [])\n}","import { BaseClient, custom, Issuer, IssuerMetadata, TokenSet } from 'openid-client';\n\nimport { SeekaAppConfig } from '../../../api/services';\nimport { SeekaAppCacheManager } from '../../../cache/appCacheManager';\nimport { md5Hash } from '../../../helpers/util';\n\nexport const getIssuer = async (config: SeekaAppConfig): Promise<Issuer<BaseClient>> => {\n const seekaIssuer = await getIssuerMetadata(config);\n const issuer = new Issuer(seekaIssuer);\n\n issuer[custom.http_options] = (url, options) => {\n return { timeout: 10000 };\n }\n\n return issuer;\n}\n\nexport const getIssuerMetadata = async (config: SeekaAppConfig): Promise<IssuerMetadata> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n\n if (config.logger) {\n config.logger.debug(`Seeka auth: getting issuer`, { ...logParams });\n }\n else {\n console.debug(`Seeka auth: getting issuer`, { ...logParams });\n }\n\n const cache = new SeekaAppCacheManager(config.appId, config.applicationInstallId);\n const cacheKey = md5Hash(config.issuerUrl);\n\n return await cache.getOrSet(cacheKey, async () => {\n const seekaIssuer = await discoverIssuerMetadata(config);\n return {\n value: seekaIssuer,\n expiryAbsoluteMilliseconds: 1000 * 60 * 60 // 1hour\n };\n }, async () => {\n if (config.logger) {\n config.logger.verbose(`Seeka auth: got issuer from cache`, { ...logParams });\n }\n else {\n console.debug(`Seeka auth: got issuer from cache`, { ...logParams });\n }\n }) as IssuerMetadata\n}\n\nexport const discoverIssuerMetadata = async (config: SeekaAppConfig): Promise<IssuerMetadata> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n\n if (config.logger) {\n config.logger.info(`Seeka auth: discovering issuer from server`, { ...logParams });\n }\n else {\n console.info(`Seeka auth: discovering issuer from server`, { ...logParams });\n }\n return (await Issuer.discover(config.issuerUrl)).metadata;\n}\n\n\nconst getNewClientToken = async (config: SeekaAppConfig): Promise<TokenSet | null> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n const issuer = await getIssuer(config);\n const client = new issuer.Client({\n client_id: config.appId.replace(/-/g, ''),\n client_secret: config.appSecret\n });\n client\n\n try {\n const token = await client.grant({\n grant_type: \"client_credentials\"\n });\n\n const successLogParams = {\n ...logParams,\n token: {\n expires_at: token.expires_at,\n token_type: token.token_type,\n scope: token.scope\n }\n }\n\n if (config.logger) {\n config.logger.info(`Seeka auth: got client access token from server`, { ...successLogParams });\n }\n else {\n console.info(`Seeka auth: got app client token from server`, { ...successLogParams });\n }\n\n return token;\n }\n catch (err) {\n const errorLogParams = {\n ...logParams,\n error: err\n }\n if (config.logger) {\n config.logger.error(`Seeka auth: failed to get client access token from server`, { ...errorLogParams });\n }\n else {\n console.debug(`Seeka auth: failed to get client access token from server`, { ...errorLogParams });\n }\n\n return null;\n }\n}\n\nexport const getNewAppInstallToken = async (clientAccessToken: string, config: SeekaAppConfig): Promise<TokenSet | null> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n const issuer = await getIssuer(config);\n const client = new issuer.Client({\n client_id: config.appId.replace(/-/g, ''),\n client_secret: config.appSecret\n });\n\n try {\n const token = await client.grant({\n grant_type: \"app_install_token\",\n applicationInstallId: config.applicationInstallId,\n access_token: clientAccessToken,\n // scopes: [\n // \"organisationBrandId\",\n // \"convergeInstanceId\",\n // \"applicationInstallId\"\n // ]\n });\n\n // console.log('Got new app install token', {\n // expires_at: token.expires_at,\n // token_type: token.token_type,\n // scope: token.scope\n // });\n const successLogParams = {\n ...logParams,\n token: {\n expires_at: token.expires_at,\n token_type: token.token_type,\n scope: token.scope\n }\n }\n if (config.logger) {\n config.logger.info(`Seeka auth: got app access token from server`, { ...successLogParams });\n }\n else {\n console.info(`Seeka auth: got app access token from server`, { ...successLogParams });\n }\n\n return token;\n }\n catch (err) {\n const errorLogParams = {\n ...logParams,\n error: err\n }\n if (config.logger) {\n config.logger.error(`Seeka auth: failed to get app access token from server`, { ...errorLogParams });\n }\n else {\n console.debug(`Seeka auth: failed to get app access token from server`, { ...errorLogParams });\n }\n\n return null;\n }\n}\n\nexport const getNewOrCachedAppInstallToken = async (config: SeekaAppConfig): Promise<TokenSet | null> => {\n const appInstallCache = new SeekaAppCacheManager(config.appId, config.applicationInstallId);\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n\n return await appInstallCache.getOrSet('auth:token:appinstall', async () => {\n const clientToken = await getNewClientToken(config);\n if (!clientToken) return null;\n\n const appToken = await getNewAppInstallToken(clientToken.access_token as string, config);\n if (!appToken) return null;\n\n return {\n value: appToken,\n expiryAbsoluteMilliseconds: (((appToken.expires_in as number) > (clientToken.expires_in as number) ? clientToken.expires_in : appToken.expires_in) || 15 * 60 * 1000) - (60 * 1000)\n }\n }, async () => {\n if (config.logger) {\n config.logger.verbose(`Seeka auth: got app token from cache`, { ...logParams });\n }\n else {\n console.debug(`Seeka auth: got app token from cache`, { ...logParams });\n }\n })\n}","import axios from 'axios';\nimport http from 'http';\nimport https from 'https';\n\nimport { IdentityServiceProxy, IngestServiceProxy, SeekaAppConfig } from '../../services';\n\nconst httpAgent = new http.Agent({ keepAlive: true, scheduling: 'fifo' });\nconst httpsAgent = new https.Agent({ keepAlive: true, scheduling: 'fifo' });\n\nconst createAxiosInstance = (config: SeekaAppConfig) => {\n\n const instance = axios.create({\n httpAgent,\n httpsAgent,\n });\n\n instance.interceptors.request.use(function (reqConfig) {\n const logParams = {\n url: reqConfig.url,\n method: reqConfig.method\n };\n if (config.logger) {\n config.logger.debug(`Seeka API: making call to ${logParams.url}`, { ...logParams });\n }\n else {\n console.debug(`Seeka API: making call to ${logParams.url}`, { ...logParams });\n }\n\n return reqConfig;\n }, function (error) {\n const logParams = {\n // url: response.request?.url || response.config.url,\n // method: response.request?.method || response.config.method,\n error\n };\n if (config.logger) {\n config.logger.http(`Seeka API: failed to send request`, { ...logParams });\n }\n else {\n console.debug(`Seeka API: failed to send request`, { ...logParams });\n }\n return Promise.reject(error);\n });\n\n instance.interceptors.response.use(function (response) {\n const logParams = {\n url: response.request?.url || response.config.url,\n method: response.request?.method || response.config.method,\n response: {\n status: response.status,\n }\n };\n if (config.logger) {\n config.logger.http(`Seeka API: call to ${logParams.url} succeeded`, { ...logParams });\n }\n else {\n console.debug(`Seeka API: call to ${logParams.url} succeeded`, { ...logParams });\n }\n\n return response;\n }, function (error) {\n const { code, status, message } = error\n const { headers, url, method } = error?.config;\n const errorLogParams = {\n code,\n status,\n message,\n headers,\n url,\n method,\n content: error?.response?.data\n }\n if (config.logger) {\n config.logger.error(`Seeka API: call to ${errorLogParams.url} failed`, { ...errorLogParams });\n }\n else {\n console.error(`Seeka API: call to ${errorLogParams.url} failed`, { ...errorLogParams });\n }\n\n return Promise.reject(error);\n });\n\n return instance;\n}\n\nexport const serviceResolver = {\n getIdentityService: (config: SeekaAppConfig) => new IdentityServiceProxy(config, config.ingestUrl, createAxiosInstance(config)),\n getIngestService: (config: SeekaAppConfig) => new IngestServiceProxy(config, config.ingestUrl, createAxiosInstance(config)),\n}","import { chunk, generateNewSessionId } from '../../helpers/util';\nimport { AppPermissionKeys, ServiceCallSource } from '../models';\nimport {\n ActivityPayload, DataIngestBatchHttpRequest, IdentityServiceProxy, IngestServiceProxy,\n PersonIdentifiers, SeekaAppConfig\n} from '../services';\nimport { getNewOrCachedAppInstallToken } from './auth';\nimport { serviceResolver } from './serviceResolver';\n\nexport class SeekaApiHelper {\n constructor(config: SeekaAppConfig) {\n this.config = config;\n this.ingestionService = serviceResolver.getIngestService(config);\n this.identityService = serviceResolver.getIdentityService(config);\n }\n\n private readonly config;\n\n private maxBatchSize = 50;\n\n // Used to prime the token cache and issue refresh tokens if required\n public refreshOrPrimeTokenCache = async (): Promise<void> => {\n await getNewOrCachedAppInstallToken(this.config);\n }\n\n public ingestionService: IngestServiceProxy;\n public identityService: IdentityServiceProxy;\n\n private checkPermission = (permissionKey: string, opName: string): boolean => {\n if (!this.config.hasPermission(permissionKey)) {\n throw new Error('Cannot perform operation ' + opName + ' on installationId ' + this.config.applicationInstallId + ' without permission ' + permissionKey + '. Currently granted permissions: ' + (this.config.grantedPermissions ? this.config.grantedPermissions.join(', ') : 'none'));\n }\n\n return true;\n }\n\n public mergeIdentity = async (identity: PersonIdentifiers, src: ServiceCallSource): Promise<string> => {\n this.checkPermission(AppPermissionKeys.identity.send, 'mergeIdentity');\n\n const sessionId = generateNewSessionId();\n\n const result = await this.identityService.merge({\n id: identity,\n src: {\n method: '', // TODO\n origin: src.origin,\n time: undefined,\n loc: src.loc as string,\n sess: sessionId,\n diag: process.env.SEEKA_DEBUG_ENABLED === 'true' ? sessionId : undefined,\n runtime: this.config.runtime\n }\n })\n\n return result.result?.personId as string;\n }\n\n public mergeIdentityBatch = async (batch: PersonIdentifiers[], src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.identity.send, 'mergeIdentityBatch');\n\n const sessionId = generateNewSessionId();\n if (batch.length === 0) {\n this.config.logger?.info('No identities in batch');\n return;\n }\n\n const sourceMetadata = {\n method: '', // TODO\n origin: src.origin,\n time: undefined,\n loc: src.loc as string,\n sess: sessionId,\n diag: process.env.SEEKA_DEBUG_ENABLED === 'true' ? sessionId : undefined,\n runtime: this.config.runtime\n }\n\n // Make ingestion is ${this.maxBatchSize} per batch, send in parallel\n const chunks = chunk(batch, this.maxBatchSize);\n if (chunks.length > 1) {\n if (this.config.logger) {\n this.config.logger.debug(`Identity batch size ${batch} is greater than ${this.maxBatchSize}, splitting into ${chunks.length} batches`);\n }\n }\n\n // Process first batch to prime authorization, then process the rest of the batches\n await this.trackActivityBatchRaw({\n data: chunks[0].map(profile => {\n return {\n id: {\n id: profile || {},\n src: { ...sourceMetadata },\n }\n }\n })\n })\n\n if (chunks.length > 1) {\n const promises = chunks.map((chunk, index) => {\n if (index === 0) return Promise.resolve();\n\n this.config.logger?.info(`Processing identity batch ${index + 1} of ${chunks.length}`);\n return this.trackActivityBatchRaw({\n data: chunk.map(profile => {\n return {\n id: {\n id: profile || {},\n src: { ...sourceMetadata },\n }\n }\n })\n })\n })\n\n await Promise.all(promises);\n }\n }\n\n public trackActivityBatch = async (batch: { activity: ActivityPayload, profile?: PersonIdentifiers | undefined }[], src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityBatch');\n\n const sessionId = generateNewSessionId();\n if (batch.length === 0) {\n this.config.logger?.info('No activities in batch');\n return;\n }\n\n const sourceMetadata = {\n method: '', // TODO\n origin: src.origin,\n time: undefined,\n loc: src.loc as string,\n sess: sessionId,\n diag: process.env.SEEKA_DEBUG_ENABLED === 'true' ? sessionId : undefined,\n runtime: this.config.runtime\n }\n\n // Make ingestion is ${this.maxBatchSize} per batch, send in parallel\n const chunks = chunk(batch, this.maxBatchSize);\n if (chunks.length > 1) {\n if (this.config.logger) {\n this.config.logger.debug(`Activity batch size ${batch.length} is greater than ${this.maxBatchSize}, splitting into ${chunks.length} batches`);\n }\n }\n\n // Process first batch to prime authorization, then process the rest of the batches\n await this.trackActivityBatchRaw({\n data: chunks[0].map(item => {\n return {\n ev: {\n id: item.profile || {},\n src: { ...sourceMetadata },\n payload: item.activity\n }\n }\n })\n })\n\n if (chunks.length > 1) {\n const promises = chunks.map((chunk, index) => {\n if (index === 0) return Promise.resolve();\n\n this.config.logger?.info(`Processing activity batch ${index + 1} of ${chunks.length}`);\n return this.trackActivityBatchRaw({\n data: chunk.map(item => {\n return {\n ev: {\n id: item.profile || {},\n src: { ...sourceMetadata },\n payload: item.activity\n }\n }\n })\n })\n })\n\n await Promise.all(promises);\n }\n }\n\n public trackActivityBatchRaw = async (data: DataIngestBatchHttpRequest): Promise<void> => {\n await this.ingestionService.batch(data);\n }\n\n public trackActivityForProfileId = async (activity: ActivityPayload, profileId: string | undefined, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfileId');\n\n await this.trackActivityForProfileIdBatch([activity], profileId, src);\n }\n\n public trackActivityForProfileIdBatch = async (activities: ActivityPayload[], profileId: string | undefined, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfileIdBatch');\n\n await this.trackActivityBatch(activities.map(e => {\n return {\n activity: e,\n profile: profileId ? { seekaPId: profileId } : undefined\n }\n }), src);\n }\n\n public trackActivityForProfile = async (activity: ActivityPayload, profile: PersonIdentifiers, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfile');\n\n await this.trackActivityForProfileBatch([activity], profile, src);\n }\n\n public trackActivityForProfileBatch = async (activities: ActivityPayload[], profile: PersonIdentifiers, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfileBatch');\n\n await this.trackActivityBatch(activities.map(e => {\n return {\n activity: e,\n profile: profile\n }\n }), src);\n }\n}\n","import * as crypto from 'crypto';\n\nimport type { Headers as UndiciHeaders } from 'undici';\n\nexport const webhookSignatureHeaderName = 'x-seeka-signature-sha256';\n\nexport const validateWebhookSignature = (secret: string, headers: UndiciHeaders | Headers | NodeJS.Dict<string | string[]>, requestBody: string): boolean => {\n if (!headers) return false;\n\n let signature: string | null = null;\n\n if (headers.get && typeof headers.get === 'function') {\n // undici and fetch\n signature = (headers as Headers).get(webhookSignatureHeaderName);\n }\n else {\n // express\n const signatures = (headers as NodeJS.Dict<string | string[]>)[webhookSignatureHeaderName];\n if (signatures) {\n if (Array.isArray(signatures) && signatures.length > 0) {\n signature = signatures[0]\n }\n else if (typeof signatures === 'string' || signatures instanceof String) {\n signature = signatures as string;\n }\n }\n }\n if (!signature) return false;\n\n // Check hash\n const hash = getHmacSignature(secret, requestBody);\n const valid = hash === signature;\n\n if (!valid) {\n console.warn(\"Invalid webhook signature\")\n }\n\n return valid;\n}\n\nexport const getHmacSignature = (secret: string, requestBody: string): string => {\n return crypto.createHmac('sha256', secret)\n .update(requestBody)\n .digest('hex');\n}\n\nexport const throwOnInvalidWebhookSignature = (secret: string, headers: UndiciHeaders | Headers | NodeJS.Dict<string | string[]>, requestBody: string): void => {\n if (!validateWebhookSignature(secret, headers, requestBody)) throw new Error('Invalid webhook signature');\n} ","import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { Logger } from 'winston';\n\nimport { version } from '../../../../package.json';\nimport { AppClientRuntimeInfo, SeekaAppConfig } from '../../services';\nimport { getNewOrCachedAppInstallToken } from '../auth';\n\nconst defaultIngestUrl = 'https://router.seeka.services';\nconst defaultIssuerUrl = 'https://account.seeka.app'\n\nexport const getAppConfig = (context: { applicationId: string, organisationId: string, applicationInstallId: string }, appSecret: string, client: AppClientRuntimeInfo, grantedPermissions: string[], logger?: Logger): SeekaAppConfig => {\n const config = new SeekaAppConfig();\n config.appId = context.applicationId;\n config.appSecret = appSecret;\n config.ingestUrl = process.env.SEEKA_INGEST_URL || defaultIngestUrl;\n config.issuerUrl = process.env.SEEKA_ISSUER_URL || defaultIssuerUrl;\n config.organisationId = context.organisationId;\n config.applicationInstallId = context.applicationInstallId;\n config.runtime = {\n type: 'sdk/js/apps-server',\n ver: version,\n client: client\n };\n config.logger = logger;\n config.grantedPermissions = grantedPermissions;\n\n config.transformApiRequest = (options: AxiosRequestConfig) => transformApiRequest(config, options);\n config.transformApiResponse = async (url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => transformApiResponse(config, url, response, processor)\n\n config.hasAnyPermissions = (permissionKeys: string[]): boolean => {\n if (!config.grantedPermissions || config.grantedPermissions.length === 0) return false;\n if (!permissionKeys || permissionKeys.length === 0) return true;\n\n return permissionKeys.some(key => config.grantedPermissions.includes(key));\n }\n config.hasAllPermissions = (permissionKeys: string[]): boolean => {\n if (!config.grantedPermissions || config.grantedPermissions.length === 0) return false;\n if (!permissionKeys || permissionKeys.length === 0) return true;\n\n return permissionKeys.every(key => config.grantedPermissions.includes(key));\n }\n config.hasPermission = (permissionKey: string): boolean => {\n if (!config.grantedPermissions || config.grantedPermissions.length === 0) return false;\n if (!permissionKey) return true;\n\n return config.grantedPermissions.includes(permissionKey);\n }\n\n return config;\n}\n\nconst transformApiRequest = async (config: SeekaAppConfig, options: AxiosRequestConfig): Promise<AxiosRequestConfig> => {\n const token = await getNewOrCachedAppInstallToken(config);\n\n options.headers = {\n ...options.headers,\n 'X-OrgId': config.organisationId,\n Authorization: 'Bearer ' + token?.access_token,\n };\n\n // if(!token){\n // // TODO: Test\n // options.cancelToken = new axios.CancelToken((cancel: Canceler) => {\n // cancel();\n // }) \n // } \n\n return options;\n}\n\nconst transformApiResponse = async (config: SeekaAppConfig, url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => {\n // Force string response, for some reason nswag is trying to JSON.parse the response when it is already deserialised to an object\n response.data = JSON.stringify(response.data);\n\n return processor(response);\n}\n\n// // export const handleApiError = (error: any, operationName: string) => {\n// // if(error.isAxiosError){\n// // const err = error as AxiosError;\n// // console.error(`Failed to ${operationName} - response ${err.code || err.status}`, {\n// // url: err.config?.url,\n// // code: err.code,\n// // message: err.message,\n// // response: err.response?.data\n// // });\n// // }\n// // else{\n// // console.error('Failed to ' + operationName, error)\n// // }\n// // }","import { Logger } from 'winston';\n\nimport { SeekaApiHelper } from '../../api/helper';\nimport { getAppConfig } from '../../api/helper/config';\nimport { SeekaAppConfig } from '../../api/services';\nimport { SeekaAppCacheManager } from '../../cache/appCacheManager';\n\nexport interface SeekaAppHelperContext {\n config: SeekaAppConfig;\n}\n\nexport class SeekaAppHelper {\n constructor(context: SeekaAppHelperContext, logger?: Logger) {\n this.context = context;\n this.api = new SeekaApiHelper(context.config);\n this.appCache = new SeekaAppCacheManager(context.config.appId);\n this.appInstallCache = new SeekaAppCacheManager(context.config.appId, context.config.applicationInstallId);\n this.logger = logger;\n }\n\n private readonly context;\n public appCache: SeekaAppCacheManager;\n public appInstallCache: SeekaAppCacheManager;\n public api: SeekaApiHelper;\n public logger?: Logger;\n\n public static create = (appSecret: string, context: { applicationId: string, organisationId: string, applicationInstallId: string }, client: { name: string, version: string }, grantedPermissions: string[], logger?: Logger): SeekaAppHelper => {\n return new SeekaAppHelper({\n config: getAppConfig({\n ...context\n }, appSecret, {\n type: client.name,\n ver: client.version,\n }, grantedPermissions, logger)\n }, logger)\n }\n}"],"names":["AppPermissionKeys","identity","receiveFull","send","activity","receiveAnon","prefix","SeekaAppCacheManager","constructor","appId","appInstallationId","this","set","async","key","value","expiryAbsoluteMilliseconds","cacheKey","getKey","memoryCache","put","JSON","stringify","getOrSet","getValueAndExpiryFunc","onGetFromCache","existing","get","cached","parse","newVal","SeekaAppConfig","appSecret","ingestUrl","issuerUrl","organisationId","applicationInstallId","runtime","logger","grantedPermissions","transformApiRequest","transformApiResponse","hasAnyPermissions","hasAllPermissions","hasPermission","ApiServiceProxyBase","config","transformOptions","options","transformResult","url","response","processor","IdentityServiceProxy","configuration","baseUrl","instance","super","jsonParseReviver","undefined","axios","create","merge","payload","cancelToken","url_","replace","content_","data","method","headers","Accept","then","transformedOptions_","request","catch","_error","isAxiosError","_response","processMerge","status","_headers","k","hasOwnProperty","result200","Promise","resolve","_responseText","result401","throwException","result422","result400","IngestServiceProxy","batch","processBatch","ResponseResultType","PrivacyConsentType","TrackingEventSourceOriginType","TrackingActivityNames","ECommerceContentType","ECommercePlatform","ECommerceFulfillmentStatus","ECommerceFinancialStatus","ConvergePipelineLoggableActivityType","SdkLogEventLevel","SeekaWebhookCallType","ApiException","Error","message","result","isApiException","obj","generateNewSessionId","dateToUtcDateTimeReferenceString","Date","getRandomNumberString","Math","floor","random","toString","forDateTime","month","getUTCMonth","length","day","getUTCDate","hour","getUTCHours","minute","getUTCMinutes","second","getUTCSeconds","getUTCFullYear","chunk","array","size","reduce","resultArray","item","index","chunkIndex","push","getIssuer","seekaIssuer","getIssuerMetadata","issuer","Issuer","custom","http_options","timeout","logParams","applicationId","debug","console","cache","input","crypto","createHash","update","digest","discoverIssuerMetadata","verbose","info","discover","metadata","getNewOrCachedAppInstallToken","appInstallCache","clientToken","client","Client","client_id","client_secret","token","grant","grant_type","successLogParams","expires_at","token_type","scope","err","errorLogParams","error","getNewClientToken","appToken","clientAccessToken","access_token","getNewAppInstallToken","expires_in","httpAgent","http","Agent","keepAlive","scheduling","httpsAgent","https","createAxiosInstance","interceptors","use","reqConfig","reject","_response$request","_response$request2","_error$response","code","content","SeekaApiHelper","maxBatchSize","refreshOrPrimeTokenCache","ingestionService","identityService","checkPermission","permissionKey","opName","join","mergeIdentity","src","_result$result","sessionId","id","origin","time","loc","sess","diag","process","env","SEEKA_DEBUG_ENABLED","personId","mergeIdentityBatch","_this$config$logger","sourceMetadata","chunks","trackActivityBatchRaw","map","profile","promises","_this$config$logger2","all","trackActivityBatch","_this$config$logger3","ev","_this$config$logger4","trackActivityForProfileId","profileId","trackActivityForProfileIdBatch","activities","e","seekaPId","trackActivityForProfile","trackActivityForProfileBatch","serviceResolver","webhookSignatureHeaderName","validateWebhookSignature","secret","requestBody","signature","signatures","Array","isArray","String","valid","getHmacSignature","warn","createHmac","getAppConfig","context","SEEKA_INGEST_URL","SEEKA_ISSUER_URL","type","ver","permissionKeys","some","includes","every","Authorization","_class","SeekaAppHelper","appCache","api","name","version","event","vals","Object","keys","evLower","toLowerCase","matched","find","Custom","fullname","firstName","lastName","parts","trim","split","slice","throwOnInvalidWebhookSignature"],"mappings":"mkBAgBa,MAAAA,EAAoB,CAC7BC,SAAU,CACNC,YAAa,uBACbC,KAAM,iBAEVC,SAAU,CACNC,YAAa,wBACbH,YAAa,uBACbC,KAAM,kBCtBRG,EAAS,YAEF,MAAAC,EACTC,WAAAA,CAAYC,EAAeC,GAA0BC,KAKpCF,WAAK,EAAAE,KACLD,uBAEVE,EAAAA,KAAAA,IAAMC,MAAOC,EAAaC,EAAYC,KACzC,MAAMC,EAAWN,KAAKO,OAAOJ,GAC7BK,EAAYC,IAAIH,EAAUI,KAAKC,UAAUP,GAAQC,EACrD,EAACL,KAEMY,SAAWV,MAAeC,EAAaU,EAAqGC,KAC/I,MAAMR,EAAWN,KAAKO,OAAOJ,GAEvBY,EAAWP,EAAYQ,IAAIV,GACjC,GAAIS,EAAU,CACV,MAAME,EAASP,KAAKQ,MAAMH,GAI1B,OAHID,SACMA,EAAeG,GAElBA,CACX,CAEA,MAAME,QAAeN,IACrB,OAAKM,GAELX,EAAYC,IAAIH,EAAUI,KAAKC,UAAUQ,EAAOf,OAAQe,EAAOd,4BAExDc,EAAOf,OAJU,IAIVA,EAGVG,KAAAA,OAAUJ,GACVH,KAAKD,kBACK,GAAAJ,KAAUK,KAAKF,SAASE,KAAKD,qBAAqBI,IAEzD,GAAGR,KAAUK,KAAKF,SAASK,IApClCH,KAAKF,MAAQA,EACbE,KAAKD,kBAAoBA,CAC7B,ECKS,MAAAqB,EAAcvB,WAAAA,GAAAG,KACzBF,WAAK,EAAAE,KACLqB,eAAS,EAAArB,KACTsB,eAAS,EAAAtB,KACTuB,eAAS,EAAAvB,KACTwB,oBAAc,EAAAxB,KACdyB,0BAAoB,EAAAzB,KACpB0B,aAAO,EAAA1B,KACP2B,YAAM,EAAA3B,KACN4B,wBAEAC,EAAAA,KAAAA,yBACAC,EAAAA,KAAAA,0BACAC,EAAAA,KAAAA,uBACAC,EAAAA,KAAAA,uBACAC,EAAAA,KAAAA,mBACD,CAAA,QAEYC,EAGXrC,WAAAA,CAAsBsC,GAAsBnC,KAF3BmC,YAAM,EAAAnC,KAMboC,iBAAmBlC,eACVF,KAACmC,OAAON,oBAAoBQ,GAC9CrC,KAESsC,gBAAkBpC,MAAOqC,EAAaC,EAAmCC,UAChEzC,KAACmC,OAAOL,qBAAqBS,EAAKC,EAAUC,GAR7DzC,KAAKmC,OAASA,CAChB,EAWI,MAAOO,UAA6BR,EAKtCrC,WAAAA,CAAY8C,EAA+BC,EAAkBC,GAEzDC,MAAMH,GAAe3C,KANf6C,cAAQ,EAAA7C,KACR4C,aAAO,EAAA5C,KACP+C,sBAAmEC,EAMzEhD,KAAK6C,SAAWA,GAAYI,EAAAA,QAAMC,SAElClD,KAAK4C,QAAiB,MAAPA,EAAAA,EAAW,6CAE9B,CAKAO,KAAAA,CAAMC,EAAsCC,GACxC,IAAIC,EAAOtD,KAAK4C,QAAU,gBAC1BU,EAAOA,EAAKC,QAAQ,QAAS,IAE7B,MAAMC,EAAW9C,KAAKC,UAAUyC,GAahC,OAAOpD,KAAKoC,iBAXuB,CAC/BqB,KAAMD,EACNE,OAAQ,OACRnB,IAAKe,EACLK,QAAS,CACL,eAAgB,mBAChBC,OAAU,oBAEdP,gBAGmCQ,KAAKC,GAC7B9D,KAAC6C,SAASkB,QAAQD,IAC9BE,MAAOC,IACN,GAAIC,EAAaD,IAAWA,EAAOzB,SAC/B,OAAOyB,EAAOzB,SAEd,MAAMyB,CACV,GACDJ,KAAMM,GACEnE,KAAKsC,gBAAgBgB,EAAMa,EAAYA,GAA6BnE,KAAKoE,aAAaD,IAErG,CAEUC,YAAAA,CAAa5B,GACnB,MAAM6B,EAAS7B,EAAS6B,OACxB,IAAIC,EAAgB,CAAE,EACtB,GAAI9B,EAASmB,SAAuC,iBAArBnB,EAASmB,QACpC,IAAK,MAAMY,KAAK/B,EAASmB,QACjBnB,EAASmB,QAAQa,eAAeD,KAChCD,EAASC,GAAK/B,EAASmB,QAAQY,IAI3C,GAAe,MAAXF,EAAgB,CAEhB,IAAII,EAAiB,KAGrB,OADAA,EAAY/D,KAAKQ,MAHKsB,EAASiB,MAIxBiB,QAAQC,QAAgEF,EAEnF,CAAO,GAAe,MAAXJ,EAAgB,CACvB,MAAMO,EAAgBpC,EAASiB,KAC/B,IAAIoB,EAAiB,KAGrB,OADAA,EAAYnE,KAAKQ,MADI0D,GAEdE,EAAe,gCAAiCT,EAAQO,EAAeN,EAAUO,EAE5F,CAAO,GAAe,MAAXR,EAAgB,CACvB,MAAMO,EAAgBpC,EAASiB,KAC/B,IAAIsB,EAAiB,KAGrB,OADAA,EAAYrE,KAAKQ,MADI0D,GAEdE,EAAe,gCAAiCT,EAAQO,EAAeN,EAAUS,EAE5F,CAAO,GAAe,MAAXV,EAAgB,CACvB,MAAMO,EAAgBpC,EAASiB,KAC/B,IAAIuB,EAAiB,KAGrB,OADAA,EAAYtE,KAAKQ,MADI0D,GAEdE,EAAe,gCAAiCT,EAAQO,EAAeN,EAAUU,EAE5F,CAAO,OAAe,MAAXX,GAA6B,MAAXA,EAElBS,EAAe,uCAAwCT,EADxC7B,EAASiB,KACsDa,GAElFI,QAAQC,QAAgE,KACnF,EAGS,MAAAM,UAA2B/C,EAKpCrC,WAAAA,CAAY8C,EAA+BC,EAAkBC,GAEzDC,MAAMH,GAAe3C,KANf6C,cACAD,EAAAA,KAAAA,aACAG,EAAAA,KAAAA,sBAAmEC,EAMzEhD,KAAK6C,SAAWA,GAAYI,EAAK,QAACC,SAElClD,KAAK4C,QAAiB,MAAPA,EAAAA,EAAW,6CAE9B,CAKAsC,KAAAA,CAAM9B,EAAqCC,GACvC,IAAIC,EAAOtD,KAAK4C,QAAU,cAC1BU,EAAOA,EAAKC,QAAQ,QAAS,IAE7B,MAAMC,EAAW9C,KAAKC,UAAUyC,GAYhC,OAAWpD,KAACoC,iBAVuB,CAC/BqB,KAAMD,EACNE,OAAQ,OACRnB,IAAKe,EACLK,QAAS,CACL,eAAgB,oBAEpBN,gBAGmCQ,KAAKC,GACjC9D,KAAK6C,SAASkB,QAAQD,IAC9BE,MAAOC,IACN,GAAIC,EAAaD,IAAWA,EAAOzB,SAC/B,OAAOyB,EAAOzB,SAEd,MAAMyB,CACV,GACDJ,KAAMM,GACEnE,KAAKsC,gBAAgBgB,EAAMa,EAAYA,GAA6BnE,KAAKmF,aAAahB,IAErG,CAEUgB,YAAAA,CAAa3C,GACnB,MAAM6B,EAAS7B,EAAS6B,OACxB,IAAIC,EAAgB,CAAA,EACpB,GAAI9B,EAASmB,SAAuC,iBAArBnB,EAASmB,QACpC,IAAK,MAAMY,KAAK/B,EAASmB,QACjBnB,EAASmB,QAAQa,eAAeD,KAChCD,EAASC,GAAK/B,EAASmB,QAAQY,IAI3C,GAAe,MAAXF,EAEA,OAAOK,QAAQC,QAAc,MAEtBN,GAAW,MAAXA,EAAgB,CACvB,MAAMO,EAAgBpC,EAASiB,KAC/B,IAAIoB,EAAiB,KAGrB,OADAA,EAAYnE,KAAKQ,MADI0D,GAEdE,EAAe,gCAAiCT,EAAQO,EAAeN,EAAUO,EAE5F,CAAO,GAAe,MAAXR,EAAgB,CACvB,MAAMO,EAAgBpC,EAASiB,KAC/B,IAAIsB,EAAiB,KAGrB,OADAA,EAAYrE,KAAKQ,MADI0D,GAEdE,EAAe,gCAAiCT,EAAQO,EAAeN,EAAUS,EAE5F,CAAO,GAAe,MAAXV,EAAgB,CACvB,MAAMO,EAAgBpC,EAASiB,KAC/B,IAAIuB,EAAiB,KAGrB,OADAA,EAAYtE,KAAKQ,MADI0D,GAEdE,EAAe,gCAAiCT,EAAQO,EAAeN,EAAUU,EAE5F,CAAO,OAAe,MAAXX,GAA6B,MAAXA,EAElBS,EAAe,uCAAwCT,EADxC7B,EAASiB,KACsDa,GAElFI,QAAQC,QAAc,KACjC,EA2BJ,IAAYS,EAsKAC,EAiIAC,EA2HAC,EAsEAC,EAOAC,EAYAC,EASAC,EAiGAC,EAYAC,EAOAC,EAxnBAV,QAAZA,wBAAA,GAAYA,EAAAA,QAAAA,qBAAAA,QAAAA,mBAIX,CAAA,IAHG,UAAA,YACAA,EAAA,QAAA,UACAA,EAAA,OAAA,SAmKQC,QAAAA,wBAAAA,GAAAA,EAAAA,QAAAA,qBAAAA,QAAAA,mBAOX,CAAA,IANG,QAAA,UACAA,EAAA,SAAA,WACAA,EAAA,QAAA,UACAA,EAAA,SAAA,WACAA,EAAA,OAAA,SACAA,EAAA,QAAA,UA2HQC,QAAAA,mCAAAA,GAAAA,EAAAA,QAAAA,gCAAAA,QAAAA,8BAUX,CAAA,IATG,QAAA,UACAA,EAAA,OAAA,SACAA,EAAA,OAAA,SACAA,EAAA,QAAA,UACAA,EAAA,cAAA,gBACAA,EAAA,MAAA,QACAA,EAAA,MAAA,QACAA,EAAA,KAAA,OACAA,EAAA,UAAA,YAkHQC,QAAAA,2BAAAA,GAAAA,EAAAA,QAAqBA,wBAArBA,QAAqBA,sBA4BhC,KA3BG,UAAA,YACAA,EAAA,gBAAA,kBACAA,EAAA,sBAAA,wBACAA,EAAA,iBAAA,mBACAA,EAAA,cAAA,gBACAA,EAAA,eAAA,iBACAA,EAAA,OAAA,SACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QACAA,EAAA,iBAAA,mBACAA,EAAA,UAAA,YACAA,EAAA,eAAA,iBACAA,EAAA,oBAAA,sBACAA,EAAA,yBAAA,2BACAA,EAAA,YAAA,cACAA,EAAA,SAAA,WACAA,EAAA,qBAAA,uBACAA,EAAA,cAAA,gBACAA,EAAA,gBAAA,kBACAA,EAAA,UAAA,YACAA,EAAA,iBAAA,mBACAA,EAAA,KAAA,OACAA,EAAA,uBAAA,yBACAA,EAAA,uBAAA,yBACAA,EAAA,SAAA,WACAA,EAAA,gBAAA,kBACAA,EAAA,WAAA,aA2CQC,QAAAA,0BAAAA,GAAAA,EAAAA,QAAAA,uBAAAA,QAAAA,qBAKX,CAAA,IAJG,UAAA,YACAA,EAAA,cAAA,gBACAA,EAAA,cAAA,gBACAA,EAAA,WAAA,aAGQC,QAAAA,uBAAAA,GAAAA,EAAAA,QAAAA,oBAAAA,QAAAA,kBASX,CAAA,IARG,KAAA,OACAA,EAAA,YAAA,cACAA,EAAA,QAAA,UACAA,EAAA,YAAA,cACAA,EAAA,QAAA,UACAA,EAAA,QAAA,UACAA,EAAA,YAAA,cACAA,EAAA,WAAA,aAIQC,QAAAA,gCAAAA,GAAAA,EAAAA,QAA0BA,6BAA1BA,QAA0BA,2BAMrC,KALG,UAAA,YACAA,EAAA,UAAA,YACAA,EAAA,cAAA,gBACAA,EAAA,mBAAA,qBACAA,EAAA,qBAAA,uBAIQC,QAAAA,8BAAAA,GAAAA,EAAAA,QAAAA,2BAAAA,QAAAA,yBASX,CAAA,IARG,UAAA,YACAA,EAAA,QAAA,UACAA,EAAA,WAAA,aACAA,EAAA,cAAA,gBACAA,EAAA,KAAA,OACAA,EAAA,kBAAA,oBACAA,EAAA,SAAA,WACAA,EAAA,OAAA,SAyFQC,QAAAA,0CAAAA,GAAAA,EAAAA,QAAAA,uCAAAA,QAAAA,qCAUX,CAAA,IATG,QAAA,UACAA,EAAA,gBAAA,kBACAA,EAAA,eAAA,iBACAA,EAAA,YAAA,cACAA,EAAA,OAAA,SACAA,EAAA,WAAA,aACAA,EAAA,qBAAA,uBACAA,EAAA,UAAA,YACAA,EAAA,0BAAA,4BAGQC,QAAAA,sBAAAA,GAAAA,EAAAA,QAAAA,mBAAAA,QAAAA,iBAKX,CAAA,IAJG,YAAA,cACAA,EAAA,QAAA,UACAA,EAAA,MAAA,QACAA,EAAA,QAAA,UAGQC,QAAAA,0BAAAA,GAAAA,EAAAA,QAAAA,uBAAAA,QAAAA,qBASX,CAAA,IARG,KAAA,OACAA,EAAA,MAAA,QACAA,EAAA,aAAA,eACAA,EAAA,gBAAA,kBACAA,EAAA,iBAAA,mBACAA,EAAA,0BAAA,4BACAA,EAAA,eAAA,iBACAA,EAAA,iBAAA,mBAyGE,MAAOC,UAAqBC,MAO9BnG,WAAAA,CAAYoG,EAAiB5B,EAAgB7B,EAAkBmB,EAAkCuC,GAC7FpD,QAAQ9C,KAPHiG,aACT5B,EAAAA,KAAAA,YACA7B,EAAAA,KAAAA,cACAmB,EAAAA,KAAAA,aACAuC,EAAAA,KAAAA,YAYUC,EAAAA,KAAAA,gBAAiB,EAPvBnG,KAAKiG,QAAUA,EACfjG,KAAKqE,OAASA,EACdrE,KAAKwC,SAAWA,EAChBxC,KAAK2D,QAAUA,EACf3D,KAAKkG,OAASA,CAClB,CAIA,qBAAOC,CAAeC,GAClB,OAA8B,IAAvBA,EAAID,cACf,EAGJ,SAASrB,EAAemB,EAAiB5B,EAAgB7B,EAAkBmB,EAAkCuC,GACzG,MAAIA,QACMA,EAEI,IAAAH,EAAaE,EAAS5B,EAAQ7B,EAAUmB,EAAS,KACnE,CAEA,SAASO,EAAakC,GAClB,OAAOA,IAA4B,IAArBA,EAAIlC,YACtB,CCtgCa,MAAAmC,EAAuBA,IAKxB,GAHYC,EAAiC,IAAIC,SAC5CC,MAkBJA,EAAwBA,IAG5BC,KAAKC,MAAmB,WAAbD,KAAKE,SAFX,KAEyCC,WAG1CN,EAAoCO,IAC/C,IAAIC,GAASD,EAAYE,cAAgB,GAAGH,WACxCE,EAAME,OAAS,IACjBF,EAAQ,IAAMA,GAEhB,IAAIG,EAAMJ,EAAYK,aAAaN,WAC/BK,EAAID,OAAS,IACfC,EAAM,IAAMA,GAEd,IAAIE,EAAON,EAAYO,cAAcR,WACjCO,EAAKH,OAAS,IAChBG,EAAO,IAAMA,GAEf,IAAIE,EAASR,EAAYS,gBAAgBV,WACrCS,EAAOL,OAAS,IAClBK,EAAS,IAAMA,GAEjB,IAAIE,EAASV,EAAYW,gBAAgBZ,WAKzC,OAJIW,EAAOP,OAAS,IAClBO,EAAS,IAAMA,MAGPV,EAAYY,mBAAmBX,IAAQG,KAAOE,IAAOE,IAASE,KAiB7DG,EAAQA,CAAIC,EAAYC,IAC5BD,EAAME,OAAO,CAACC,EAAyBC,EAAMC,KAClD,MAAMC,EAAaxB,KAAKC,MAAMsB,EAAQJ,GAQtC,OANKE,EAAYG,KACfH,EAAYG,GAAc,IAG5BH,EAAYG,GAAYC,KAAKH,GAEtBD,GACN,IC1EQK,EAAYjI,UACrB,MAAMkI,QAAoBC,EAAkBlG,GACtCmG,EAAS,IAAIC,SAAOH,GAM1B,OAJAE,EAAOE,SAAOC,cAAgB,CAAClG,EAAKF,KACzB,CAAEqG,QAAS,MAGfJ,GAGED,EAAoBnI,UAC7B,MAAMyI,EAAY,CAAEC,cAAezG,EAAOrC,MAAOwI,OAAQ,CAAE/F,IAAKJ,EAAOZ,YAEnEY,EAAOR,OACPQ,EAAOR,OAAOkH,MAAM,6BAA8B,IAAKF,IAGvDG,QAAQD,MAAkC,6BAAE,IAAKF,IAGrD,MAAMI,EAAQ,IAAInJ,EAAqBuC,EAAOrC,MAAOqC,EAAOV,sBACtDnB,GD2Bc0I,EC3BK7G,EAAOZ,UD4B3B0H,EAAOC,WAAW,OAAOC,OAAOH,GAAOI,OAAO,QAD/BJ,MCzBpB,aAAaD,EAAMnI,SAASN,EAAUJ,UAE3B,CACHE,YAFsBiJ,EAAuBlH,GAG7C9B,2BAA4B,OAEjCH,UACKiC,EAAOR,OACPQ,EAAOR,OAAO2H,QAAQ,oCAAqC,IAAKX,IAGhEG,QAAQD,MAAyC,oCAAE,IAAKF,GAC5D,EACH,EAGQU,EAAyBnJ,UAClC,MAAMyI,EAAY,CAAEC,cAAezG,EAAOrC,MAAOwI,OAAQ,CAAE/F,IAAKJ,EAAOZ,YAQvE,OANIY,EAAOR,OACPQ,EAAOR,OAAO4H,KAAK,6CAA8C,IAAKZ,IAGtEG,QAAQS,KAAiD,6CAAE,IAAKZ,WAEtDJ,EAAMA,OAACiB,SAASrH,EAAOZ,YAAYkI,UA8GxCC,EAAgCxJ,UACzC,MAAMyJ,EAAkB,IAAI/J,EAAqBuC,EAAOrC,MAAOqC,EAAOV,sBAChEkH,EAAY,CAAEC,cAAezG,EAAOrC,MAAOwI,OAAQ,CAAE/F,IAAKJ,EAAOZ,YAEvE,aAAaoI,EAAgB/I,SAAS,wBAAyBV,UAC3D,MAAM0J,OA/GY1J,WACtB,MAAMyI,EAAY,CAAEC,cAAezG,EAAOrC,MAAOwI,OAAQ,CAAE/F,IAAKJ,EAAOZ,YAEjEsI,EAAS,WADM1B,EAAUhG,IACL2H,QAAO,CAC7BC,UAAW5H,EAAOrC,MAAMyD,QAAQ,KAAM,IACtCyG,cAAe7H,EAAOd,YAI1B,IACI,MAAM4I,QAAcJ,EAAOK,MAAM,CAC7BC,WAAY,uBAGVC,EAAmB,IAClBzB,EACHsB,MAAO,CACHI,WAAYJ,EAAMI,WAClBC,WAAYL,EAAMK,WAClBC,MAAON,EAAMM,QAWrB,OAPIpI,EAAOR,OACPQ,EAAOR,OAAO4H,KAAK,kDAAmD,IAAKa,IAG3EtB,QAAQS,KAAmD,+CAAE,IAAKa,IAG/DH,CACX,CACA,MAAOO,GACH,MAAMC,EAAiB,IAChB9B,EACH+B,MAAOF,GASX,OAPIrI,EAAOR,OACPQ,EAAOR,OAAO+I,MAAM,4DAA6D,IAAKD,IAGtF3B,QAAQD,MAAiE,4DAAE,IAAK4B,IAIxF,IAAA,GAkE8BE,CAAkBxI,GAC5C,IAAKyH,EAAa,OAAW,KAE7B,MAAMgB,OAlEuB1K,OAAO2K,EAA2B1I,KACnE,MAAMwG,EAAY,CAAEC,cAAezG,EAAOrC,MAAOwI,OAAQ,CAAE/F,IAAKJ,EAAOZ,YAEjEsI,EAAS,WADM1B,EAAUhG,IACL2H,QAAO,CAC7BC,UAAW5H,EAAOrC,MAAMyD,QAAQ,KAAM,IACtCyG,cAAe7H,EAAOd,YAG1B,IACI,MAAM4I,QAAcJ,EAAOK,MAAM,CAC7BC,WAAY,oBACZ1I,qBAAsBU,EAAOV,qBAC7BqJ,aAAcD,IAaZT,EAAmB,IAClBzB,EACHsB,MAAO,CACHI,WAAYJ,EAAMI,WAClBC,WAAYL,EAAMK,WAClBC,MAAON,EAAMM,QAUrB,OAPIpI,EAAOR,OACPQ,EAAOR,OAAO4H,KAAK,+CAAgD,IAAKa,IAGxEtB,QAAQS,KAAmD,+CAAE,IAAKa,IAG/DH,CACX,CACA,MAAOO,GACH,MAAMC,EAAiB,IAChB9B,EACH+B,MAAOF,GASX,OAPIrI,EAAOR,OACPQ,EAAOR,OAAO+I,MAAM,yDAA0D,IAAKD,IAGnF3B,QAAQD,MAA8D,yDAAE,IAAK4B,IAIrF,IAAA,GAW2BM,CAAsBnB,EAAYkB,aAAwB3I,GACjF,OAAKyI,EAEE,CACHxK,MAAOwK,EACPvK,6BAA+BuK,EAASI,WAAyBpB,EAAYoB,WAAwBpB,EAAYoB,WAAaJ,EAASI,aAAe,KAAmB,KAJvJ,MAMvB9K,UACKiC,EAAOR,OACPQ,EAAOR,OAAO2H,QAAQ,uCAAwC,IAAKX,IAGnEG,QAAQD,MAA4C,uCAAE,IAAKF,GAC/D,EACH,ECrLCsC,EAAY,IAAIC,EAAAA,QAAKC,MAAM,CAAEC,WAAW,EAAMC,WAAY,SAC1DC,EAAa,IAAIC,EAAK,QAACJ,MAAM,CAAEC,WAAW,EAAMC,WAAY,SAE5DG,EAAuBrJ,IAEzB,MAAMU,EAAWI,EAAK,QAACC,OAAO,CAC1B+H,YACAK,eAqEJ,OAlEAzI,EAAS4I,aAAa1H,QAAQ2H,IAAI,SAAUC,GACxC,MAAMhD,EAAY,CACdpG,IAAKoJ,EAAUpJ,IACfmB,OAAQiI,EAAUjI,QAStB,OAPIvB,EAAOR,OACPQ,EAAOR,OAAOkH,mCAAmCF,EAAUpG,MAAO,IAAKoG,IAGvEG,QAAQD,MAAM,6BAA6BF,EAAUpG,MAAO,IAAKoG,IAG9DgD,CACX,EAAG,SAAUjB,GACT,MAAM/B,EAAY,CAGd+B,SAQJ,OANIvI,EAAOR,OACPQ,EAAOR,OAAOuJ,KAAK,oCAAqC,IAAKvC,IAG7DG,QAAQD,MAAyC,oCAAE,IAAKF,IAErDjE,QAAQkH,OAAOlB,EAC1B,GAEA7H,EAAS4I,aAAajJ,SAASkJ,IAAI,SAAUlJ,GAAQqJ,IAAAA,EAAAC,EACjD,MAAMnD,EAAY,CACdpG,KAAKsJ,OAAAA,EAAArJ,EAASuB,cAAT8H,EAAAA,EAAkBtJ,MAAOC,EAASL,OAAOI,IAC9CmB,QAAQoI,OAAAA,EAAAtJ,EAASuB,cAAT+H,EAAAA,EAAkBpI,SAAUlB,EAASL,OAAOuB,OACpDlB,SAAU,CACN6B,OAAQ7B,EAAS6B,SAUzB,OAPIlC,EAAOR,OACPQ,EAAOR,OAAOuJ,2BAA2BvC,EAAUpG,gBAAiB,IAAKoG,IAGzEG,QAAQD,MAAM,sBAAsBF,EAAUpG,gBAAiB,IAAKoG,IAGjEnG,CACX,EAAG,SAAUkI,GAAKqB,IAAAA,EACd,MAAMC,KAAEA,EAAI3H,OAAEA,EAAM4B,QAAEA,GAAYyE,GAC5B/G,QAAEA,EAAOpB,IAAEA,EAAGmB,OAAEA,GAAWgH,MAAAA,OAAAA,EAAAA,EAAOvI,OAClCsI,EAAiB,CACnBuB,OACA3H,SACA4B,UACAtC,UACApB,MACAmB,SACAuI,QAAc,MAALvB,GAAe,OAAVqB,EAALrB,EAAOlI,eAAQ,EAAfuJ,EAAiBtI,MAS9B,OAPItB,EAAOR,OACPQ,EAAOR,OAAO+I,4BAA4BD,EAAelI,aAAc,IAAKkI,IAG5E3B,QAAQ4B,MAAM,sBAAsBD,EAAelI,aAAc,IAAKkI,IAGnE/F,QAAQkH,OAAOlB,EAC1B,GAEO7H,SCzEEqJ,EACXrM,WAAAA,CAAYsC,GAMKA,KAAAA,YAETgK,EAAAA,KAAAA,aAAe,GAGhBC,KAAAA,yBAA2BlM,gBAC1BwJ,EAA8B1J,KAAKmC,OAC3C,EAACnC,KAEMqM,sBAAgB,EAAArM,KAChBsM,qBAAe,EAAAtM,KAEduM,gBAAkB,CAACC,EAAuBC,KAChD,IAAKzM,KAAKmC,OAAOF,cAAcuK,GAC7B,MAAM,IAAIxG,MAAM,4BAA8ByG,EAAS,sBAAwBzM,KAAKmC,OAAOV,qBAAuB,uBAAyB+K,EAAgB,qCAAuCxM,KAAKmC,OAAOP,mBAAqB5B,KAAKmC,OAAOP,mBAAmB8K,KAAK,MAAQ,SAGjR,OAAO,GACR1M,KAEM2M,cAAgBzM,MAAOZ,EAA6BsN,KAA2CC,IAAAA,EACpG7M,KAAKuM,gBAAgBlN,EAAkBC,SAASE,KAAM,iBAEtD,MAAMsN,EAAYzG,IAelB,OAAOwG,OAAPA,SAbqB7M,KAAKsM,gBAAgBnJ,MAAM,CAC9C4J,GAAIzN,EACJsN,IAAK,CACHlJ,OAAQ,GACRsJ,OAAQJ,EAAII,OACZC,UAAMjK,EACNkK,IAAKN,EAAIM,IACTC,KAAML,EACNM,KAA0C,SAApCC,QAAQC,IAAIC,oBAAiCT,OAAY9J,EAC/DtB,QAAS1B,KAAKmC,OAAOT,YAIXwE,aAAP2G,EAAAA,EAAeW,UAGjBC,KAAAA,mBAAqBvN,MAAOgF,EAA4B0H,KAC7D5M,KAAKuM,gBAAgBlN,EAAkBC,SAASE,KAAM,sBAEtD,MAAMsN,EAAYzG,IACMqH,IAAAA,EAAxB,GAAqB,IAAjBxI,EAAM8B,OAER,YADkB,OAAlB0G,EAAI1N,KAACmC,OAAOR,SAAZ+L,EAAoBnE,KAAK,2BAI3B,MAAMoE,EAAiB,CACrBjK,OAAQ,GACRsJ,OAAQJ,EAAII,OACZC,UAAMjK,EACNkK,IAAKN,EAAIM,IACTC,KAAML,EACNM,KAA0C,SAApCC,QAAQC,IAAIC,oBAAiCT,OAAY9J,EAC/DtB,QAAS1B,KAAKmC,OAAOT,SAIjBkM,EAASlG,EAAMxC,EAAOlF,KAAKmM,cAmBjC,GAlBIyB,EAAO5G,OAAS,GACdhH,KAAKmC,OAAOR,QACd3B,KAAKmC,OAAOR,OAAOkH,MAA6B,uBAAA3D,qBAAyBlF,KAAKmM,gCAAgCyB,EAAO5G,wBAK/GhH,KAAC6N,sBAAsB,CAC/BpK,KAAMmK,EAAO,GAAGE,IAAIC,IACX,CACLhB,GAAI,CACFA,GAAIgB,GAAW,CAAA,EACfnB,IAAK,IAAKe,SAMdC,EAAO5G,OAAS,EAAG,CACrB,MAAMgH,EAAWJ,EAAOE,IAAI,CAACpG,EAAOM,KAAS,IAAAiG,EAC3C,OAAc,IAAVjG,EAAoBtD,QAAQC,WAEhCsJ,OAAAA,OAAK9L,OAAOR,SAAZsM,EAAoB1E,KAAK,6BAA6BvB,EAAQ,QAAQ4F,EAAO5G,UAClEhH,KAAC6N,sBAAsB,CAChCpK,KAAMiE,EAAMoG,IAAIC,IACP,CACLhB,GAAI,CACFA,GAAIgB,GAAW,CAAE,EACjBnB,IAAK,IAAKe,SAIjB,SAGGjJ,QAAQwJ,IAAIF,EACpB,GAGKG,KAAAA,mBAAqBjO,MAAOgF,EAAiF0H,KAClH5M,KAAKuM,gBAAgBlN,EAAkBI,SAASD,KAAM,sBAEtD,MAAMsN,EAAYzG,IACM+H,IAAAA,EAAxB,GAAqB,IAAjBlJ,EAAM8B,OAER,YADkB,OAAlBoH,EAAIpO,KAACmC,OAAOR,SAAZyM,EAAoB7E,KAAK,2BAI3B,MAAMoE,EAAiB,CACrBjK,OAAQ,GACRsJ,OAAQJ,EAAII,OACZC,UAAMjK,EACNkK,IAAKN,EAAIM,IACTC,KAAML,EACNM,KAA0C,SAApCC,QAAQC,IAAIC,oBAAiCT,OAAY9J,EAC/DtB,QAAS1B,KAAKmC,OAAOT,SAIjBkM,EAASlG,EAAMxC,EAAOlF,KAAKmM,cAoBjC,GAnBIyB,EAAO5G,OAAS,GACdhH,KAAKmC,OAAOR,QACd3B,KAAKmC,OAAOR,OAAOkH,6BAA6B3D,EAAM8B,0BAA0BhH,KAAKmM,gCAAgCyB,EAAO5G,6BAKrH6G,sBAAsB,CAC/BpK,KAAMmK,EAAO,GAAGE,IAAI/F,IACX,CACLsG,GAAI,CACFtB,GAAIhF,EAAKgG,SAAW,CAAA,EACpBnB,IAAK,IAAKe,GACVvK,QAAS2E,EAAKtI,eAMlBmO,EAAO5G,OAAS,EAAG,CACrB,MAAMgH,EAAWJ,EAAOE,IAAI,CAACpG,EAAOM,KAASsG,IAAAA,EAC3C,OAAc,IAAVtG,EAAoBtD,QAAQC,WAEd,OAAlB2J,EAAItO,KAACmC,OAAOR,SAAZ2M,EAAoB/E,KAAK,6BAA6BvB,EAAQ,QAAQ4F,EAAO5G,UACtEhH,KAAK6N,sBAAsB,CAChCpK,KAAMiE,EAAMoG,IAAI/F,IACP,CACLsG,GAAI,CACFtB,GAAIhF,EAAKgG,SAAW,CAAA,EACpBnB,IAAK,IAAKe,GACVvK,QAAS2E,EAAKtI,eAIrB,SAGGiF,QAAQwJ,IAAIF,EACpB,GACDhO,KAEM6N,sBAAwB3N,gBACvBF,KAAKqM,iBAAiBnH,MAAMzB,EACpC,EAACzD,KAEMuO,0BAA4BrO,MAAOT,EAA2B+O,EAA+B5B,KAClG5M,KAAKuM,gBAAgBlN,EAAkBI,SAASD,KAAM,mCAE5CQ,KAACyO,+BAA+B,CAAChP,GAAW+O,EAAW5B,EACnE,EAEO6B,KAAAA,+BAAiCvO,MAAOwO,EAA+BF,EAA+B5B,KAC3G5M,KAAKuM,gBAAgBlN,EAAkBI,SAASD,KAAM,wCAEhDQ,KAAKmO,mBAAmBO,EAAWZ,IAAIa,IACpC,CACLlP,SAAUkP,EACVZ,QAASS,EAAY,CAAEI,SAAUJ,QAAcxL,KAE/C4J,EAAG,EACR5M,KAEM6O,wBAA0B3O,MAAOT,EAA2BsO,EAA4BnB,KAC7F5M,KAAKuM,gBAAgBlN,EAAkBI,SAASD,KAAM,iCAE5CQ,KAAC8O,6BAA6B,CAACrP,GAAWsO,EAASnB,EAAG,OAG3DkC,6BAA+B5O,MAAOwO,EAA+BX,EAA4BnB,KACtG5M,KAAKuM,gBAAgBlN,EAAkBI,SAASD,KAAM,sCAEhDQ,KAAKmO,mBAAmBO,EAAWZ,IAAIa,IACpC,CACLlP,SAAUkP,EACVZ,QAASA,KAETnB,EAAG,EA3MP5M,KAAKmC,OAASA,EACdnC,KAAKqM,iBD2EclK,IAA2B,IAAI8C,EAAmB9C,EAAQA,EAAOb,UAAWkK,EAAoBrJ,IC3E3F4M,CAAiC5M,GACzDnC,KAAKsM,gBDyEgBnK,IAA2B,IAAIO,EAAqBP,EAAQA,EAAOb,UAAWkK,EAAoBrJ,ICzEhG4M,CAAmC5M,EAC5D,ECVW,MAAA6M,EAA6B,2BAE7BC,EAA2BA,CAACC,EAAgBvL,EAAmEwL,KACxH,IAAKxL,EAAS,OAAY,EAE1B,IAAIyL,EAA2B,KAE/B,GAAIzL,EAAQ3C,KAA8B,mBAAhB2C,EAAQ3C,IAE9BoO,EAAazL,EAAoB3C,IAAIgO,OAEpC,CAED,MAAMK,EAAc1L,EAA2CqL,GAC3DK,IACIC,MAAMC,QAAQF,IAAeA,EAAWrI,OAAS,EACjDoI,EAAYC,EAAW,IAEI,iBAAfA,GAA2BA,aAAsBG,UAC7DJ,EAAYC,GAGxB,CACA,IAAKD,EAAW,OAAO,EAGvB,MACMK,EADOC,EAAiBR,EAAQC,KACfC,EAMvB,OAJKK,GACD3G,QAAQ6G,KAAK,6BAGVF,GAGEC,EAAmBA,CAACR,EAAgBC,IACtClG,EAAO2G,WAAW,SAAUV,GAC9B/F,OAAOgG,GACP/F,OAAO,OCjCHyG,EAAeA,CAACC,EAA0FzO,EAAmBwI,EAA8BjI,EAA8BD,KAClM,MAAMQ,EAAS,IAAIf,EAqCnB,OApCAe,EAAOrC,MAAQgQ,EAAQlH,cACvBzG,EAAOd,UAAYA,EACnBc,EAAOb,UAAY+L,QAAQC,IAAIyC,kBAPV,gCAQrB5N,EAAOZ,UAAY8L,QAAQC,IAAI0C,kBAPV,4BAQrB7N,EAAOX,eAAiBsO,EAAQtO,eAChCW,EAAOV,qBAAuBqO,EAAQrO,qBACtCU,EAAOT,QAAU,CACbuO,KAAM,qBACNC,YACArG,OAAQA,GAEZ1H,EAAOR,OAASA,EAChBQ,EAAOP,mBAAqBA,EAE5BO,EAAON,oBAAuBQ,GAAgCR,EAAoBM,EAAQE,GAC1FF,EAAOL,qBAAuB5B,MAAOqC,EAAaC,EAAmCC,IAA0DX,EAAqBK,EAAQI,EAAKC,EAAUC,GAE3LN,EAAOJ,kBAAqBoO,MACnBhO,EAAOP,oBAA2D,IAArCO,EAAOP,mBAAmBoF,WACvDmJ,GAA4C,IAA1BA,EAAenJ,QAE/BmJ,EAAeC,KAAKjQ,GAAOgC,EAAOP,mBAAmByO,SAASlQ,KAEzEgC,EAAOH,kBAAqBmO,MACnBhO,EAAOP,oBAA2D,IAArCO,EAAOP,mBAAmBoF,WACvDmJ,GAA4C,IAA1BA,EAAenJ,QAE/BmJ,EAAeG,MAAMnQ,GAAOgC,EAAOP,mBAAmByO,SAASlQ,KAE1EgC,EAAOF,cAAiBuK,MACfrK,EAAOP,oBAA2D,IAArCO,EAAOP,mBAAmBoF,WACvDwF,GAEErK,EAAOP,mBAAmByO,SAAS7D,IAGvCrK,GAGLN,EAAsB3B,MAAOiC,EAAwBE,KACvD,MAAM4H,QAAcP,EAA8BvH,GAelD,OAbAE,EAAQsB,QAAU,IACXtB,EAAQsB,QACX,UAAWxB,EAAOX,eAClB+O,cAAe,WAAiB,MAALtG,OAAK,EAALA,EAAOa,eAU/BzI,GAGLP,EAAuB5B,MAAOiC,EAAwBI,EAAaC,EAAmCC,KAExGD,EAASiB,KAAO/C,KAAKC,UAAU6B,EAASiB,MAEjChB,EAAUD,ICxErB,IAAAgO,QASaC,EACX5Q,WAAAA,CAAYiQ,EAAgCnO,QAQ3BmO,aAAO,EAAA9P,KACjB0Q,cAAQ,EAAA1Q,KACR2J,qBACAgH,EAAAA,KAAAA,SACAhP,EAAAA,KAAAA,cAXL3B,KAAK8P,QAAUA,EACf9P,KAAK2Q,IAAM,IAAIzE,EAAe4D,EAAQ3N,QACtCnC,KAAK0Q,SAAW,IAAI9Q,EAAqBkQ,EAAQ3N,OAAOrC,OACxDE,KAAK2J,gBAAkB,IAAI/J,EAAqBkQ,EAAQ3N,OAAOrC,MAAOgQ,EAAQ3N,OAAOV,sBACrFzB,KAAK2B,OAASA,CAChB,IAPW8O,EAAAA,EAeGvN,OAAS,CAAC7B,EAAmByO,EAA0FjG,EAA2CjI,EAA8BD,IACrM,IAAI8O,EAAe,CACxBtO,OAAQ0N,EAAa,IAChBC,GACFzO,EAAW,CACZ4O,KAAMpG,EAAO+G,KACbV,IAAKrG,EAAOgH,SACXjP,EAAoBD,IACtBA,kSNvByBmP,IAC9B,MAAMC,EAAOC,OAAOC,KAAK1L,QAAqBA,uBACxC2L,EAAUJ,EAAMK,cAEhBC,EAAUL,EAAKM,KAAK1C,GAAKA,EAAEwC,gBAAkBD,GAEnD,OAAIE,EACK7L,QAAAA,sBAAsB6L,GAGxB7L,QAAAA,sBAAsB+L,uCAsCQC,IACrC,IAAKA,EAAU,MAAO,CAAEC,UAAW,KAAMC,SAAU,MAEnD,MAAMC,EAAQH,EAASI,OAAOC,MAAM,KACpC,OAAqB,IAAjBF,EAAM1K,OAAqB,CAAEwK,UAAWD,EAAUE,SAAU,MACtC,IAAjBC,EAAM1K,OAAqB,CAAEwK,UAAWE,EAAM,GAAID,SAAUC,EAAM,IAC/D,CAAEF,UAAWE,EAAM,GAAID,SAAUC,EAAMG,MAAM,GAAGnF,KAAK,KAAI,yCInBzBoF,CAAC5C,EAAgBvL,EAAmEwL,KAC9H,IAAKF,EAAyBC,EAAQvL,EAASwL,GAAc,MAAU,IAAAnJ,MAAM,4BAA2B"}
|
|
1
|
+
{"version":3,"file":"sdk-apps-server.js","sources":["../src/api/models/index.ts","../src/cache/appCacheManager/index.ts","../src/api/services/index.ts","../src/helpers/util/index.ts","../src/api/helper/auth/index.ts","../src/api/helper/serviceResolver/index.ts","../src/api/helper/index.ts","../src/api/webhooks/index.ts","../src/api/helper/config/index.ts","../src/helpers/app/index.ts"],"sourcesContent":["import { SeekaPipelineIntegrationSource, TrackingEventSourceOriginType } from '../../api/services';\n\nexport interface ServiceCallSource {\n /** Source method that requested the tracking. */\n method?: string;\n\n /** Type of origin that generated the tracking request.\n This is not the same as where the tracking event originated from, this property specifies where the tracking event was tracked from. */\n origin?: TrackingEventSourceOriginType;\n\n /** URL where the tracking event originated from. */\n loc?: string;\n\n pipeline?: SeekaPipelineIntegrationSource\n}\n\nexport const AppPermissionKeys = {\n identity: {\n receiveFull: 'Identity.Receive.Pii',\n send: 'Identity.Send'\n },\n activity: {\n receiveAnon: 'Activity.Receive.Anon',\n receiveFull: 'Activity.Receive.Pii',\n send: 'Activity.Send'\n }\n}","import * as memoryCache from 'memory-cache';\n\nconst prefix = 'seeka:sdk';\n\nexport class SeekaAppCacheManager {\n constructor(appId: string, appInstallationId?: string) {\n this.appId = appId;\n this.appInstallationId = appInstallationId;\n }\n\n private readonly appId: string;\n private readonly appInstallationId?: string;\n\n public set = async (key: string, value: any, expiryAbsoluteMilliseconds?: number): Promise<void> => {\n const cacheKey = this.getKey(key);\n memoryCache.put(cacheKey, JSON.stringify(value), expiryAbsoluteMilliseconds);\n }\n\n public getOrSet = async <TValue>(key: string, getValueAndExpiryFunc: () => Promise<{ value: TValue, expiryAbsoluteMilliseconds?: number } | null>, onGetFromCache?: (val: TValue | null) => Promise<void>): Promise<TValue | null> => {\n const cacheKey = this.getKey(key);\n\n const existing = memoryCache.get(cacheKey);\n if (existing) {\n const cached = JSON.parse(existing) as TValue;\n if (onGetFromCache) {\n await onGetFromCache(cached)\n }\n return cached;\n }\n\n const newVal = await getValueAndExpiryFunc();\n if (!newVal) return null;\n\n memoryCache.put(cacheKey, JSON.stringify(newVal.value), newVal.expiryAbsoluteMilliseconds);\n\n return newVal.value;\n }\n\n private getKey = (key: string): string => {\n if (this.appInstallationId) {\n return `${prefix}:${this.appId}:${this.appInstallationId}:${key}`;\n }\n return `${prefix}:${this.appId}:${key}`;\n }\n}","//----------------------\n// <auto-generated>\n// Generated using the NSwag toolchain v14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org)\n// </auto-generated>\n//----------------------\n\n/* tslint:disable */\n/* eslint-disable */\n// ReSharper disable InconsistentNaming\n\nimport axios, { AxiosError } from 'axios';\nimport { Logger } from 'winston';\nimport type { AxiosInstance, AxiosRequestConfig, AxiosResponse, CancelToken, Canceler } from 'axios';\nexport class SeekaAppConfig {\n appId!: string;\n appSecret!: string;\n ingestUrl!: string;\n issuerUrl!: string;\n organisationId!: string;\n applicationInstallId!: string;\n runtime!: AppRuntimeInfo;\n logger?: Logger\n grantedPermissions!: string[];\n\n transformApiRequest!: (options: AxiosRequestConfig) => Promise<AxiosRequestConfig>;\n transformApiResponse!: (url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => any;\n hasAnyPermissions!: (permissionKeys: string[]) => boolean\n hasAllPermissions!: (permissionKeys: string[]) => boolean\n hasPermission!: (permissionKey: string) => boolean\n}\n\nexport class ApiServiceProxyBase {\n private readonly config: SeekaAppConfig;\n\n protected constructor(config: SeekaAppConfig) {\n this.config = config;\n }\n\n protected transformOptions = async (options: AxiosRequestConfig): Promise<AxiosRequestConfig> => {\n return await this.config.transformApiRequest(options);\n };\n\n protected transformResult = async (url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => {\n return await this.config.transformApiResponse(url, response, processor);\n }\n}\n\nexport class IdentityServiceProxy extends ApiServiceProxyBase {\n protected instance: AxiosInstance;\n protected baseUrl: string;\n protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;\n\n constructor(configuration: SeekaAppConfig, baseUrl?: string, instance?: AxiosInstance) {\n\n super(configuration);\n\n this.instance = instance || axios.create();\n\n this.baseUrl = baseUrl ?? \"https://api-localdev-env0-seeka.au.ngrok.io\";\n\n }\n\n /**\n * Merge identity\n */\n merge(payload: PersonIdentificationRequest, cancelToken?: CancelToken): Promise<ApiResponseDtoOfPersonIdentificationResolutionResponse> {\n let url_ = this.baseUrl + \"/api/identity\";\n url_ = url_.replace(/[?&]$/, \"\");\n\n const content_ = JSON.stringify(payload);\n\n let options_: AxiosRequestConfig = {\n data: content_,\n method: \"POST\",\n url: url_,\n headers: {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\"\n },\n cancelToken\n };\n\n return this.transformOptions(options_).then(transformedOptions_ => {\n return this.instance.request(transformedOptions_);\n }).catch((_error: any) => {\n if (isAxiosError(_error) && _error.response) {\n return _error.response;\n } else {\n throw _error;\n }\n }).then((_response: AxiosResponse) => {\n return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processMerge(_response));\n });\n }\n\n protected processMerge(response: AxiosResponse): Promise<ApiResponseDtoOfPersonIdentificationResolutionResponse> {\n const status = response.status;\n let _headers: any = {};\n if (response.headers && typeof response.headers === \"object\") {\n for (const k in response.headers) {\n if (response.headers.hasOwnProperty(k)) {\n _headers[k] = response.headers[k];\n }\n }\n }\n if (status === 200) {\n const _responseText = response.data;\n let result200: any = null;\n let resultData200 = _responseText;\n result200 = JSON.parse(resultData200);\n return Promise.resolve<ApiResponseDtoOfPersonIdentificationResolutionResponse>(result200);\n\n } else if (status === 401) {\n const _responseText = response.data;\n let result401: any = null;\n let resultData401 = _responseText;\n result401 = JSON.parse(resultData401);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result401);\n\n } else if (status === 422) {\n const _responseText = response.data;\n let result422: any = null;\n let resultData422 = _responseText;\n result422 = JSON.parse(resultData422);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result422);\n\n } else if (status === 400) {\n const _responseText = response.data;\n let result400: any = null;\n let resultData400 = _responseText;\n result400 = JSON.parse(resultData400);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result400);\n\n } else if (status !== 200 && status !== 204) {\n const _responseText = response.data;\n return throwException(\"An unexpected server error occurred.\", status, _responseText, _headers);\n }\n return Promise.resolve<ApiResponseDtoOfPersonIdentificationResolutionResponse>(null as any);\n }\n}\n\nexport class IngestServiceProxy extends ApiServiceProxyBase {\n protected instance: AxiosInstance;\n protected baseUrl: string;\n protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;\n\n constructor(configuration: SeekaAppConfig, baseUrl?: string, instance?: AxiosInstance) {\n\n super(configuration);\n\n this.instance = instance || axios.create();\n\n this.baseUrl = baseUrl ?? \"https://api-localdev-env0-seeka.au.ngrok.io\";\n\n }\n\n /**\n * Track activity\n */\n batch(payload: DataIngestBatchHttpRequest, cancelToken?: CancelToken): Promise<void> {\n let url_ = this.baseUrl + \"/api/ingest\";\n url_ = url_.replace(/[?&]$/, \"\");\n\n const content_ = JSON.stringify(payload);\n\n let options_: AxiosRequestConfig = {\n data: content_,\n method: \"POST\",\n url: url_,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n cancelToken\n };\n\n return this.transformOptions(options_).then(transformedOptions_ => {\n return this.instance.request(transformedOptions_);\n }).catch((_error: any) => {\n if (isAxiosError(_error) && _error.response) {\n return _error.response;\n } else {\n throw _error;\n }\n }).then((_response: AxiosResponse) => {\n return this.transformResult(url_, _response, (_response: AxiosResponse) => this.processBatch(_response));\n });\n }\n\n protected processBatch(response: AxiosResponse): Promise<void> {\n const status = response.status;\n let _headers: any = {};\n if (response.headers && typeof response.headers === \"object\") {\n for (const k in response.headers) {\n if (response.headers.hasOwnProperty(k)) {\n _headers[k] = response.headers[k];\n }\n }\n }\n if (status === 202) {\n const _responseText = response.data;\n return Promise.resolve<void>(null as any);\n\n } else if (status === 401) {\n const _responseText = response.data;\n let result401: any = null;\n let resultData401 = _responseText;\n result401 = JSON.parse(resultData401);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result401);\n\n } else if (status === 422) {\n const _responseText = response.data;\n let result422: any = null;\n let resultData422 = _responseText;\n result422 = JSON.parse(resultData422);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result422);\n\n } else if (status === 400) {\n const _responseText = response.data;\n let result400: any = null;\n let resultData400 = _responseText;\n result400 = JSON.parse(resultData400);\n return throwException(\"A server side error occurred.\", status, _responseText, _headers, result400);\n\n } else if (status !== 200 && status !== 204) {\n const _responseText = response.data;\n return throwException(\"An unexpected server error occurred.\", status, _responseText, _headers);\n }\n return Promise.resolve<void>(null as any);\n }\n}\n\nexport interface ApiResponseDtoOfPersonIdentificationResolutionResponse {\n result?: PersonIdentificationResolutionResponse;\n}\n\nexport interface PersonIdentificationResolutionResponse {\n personId?: string;\n}\n\nexport interface ApiResponseDtoOfObject {\n result?: any;\n}\n\nexport interface DetailedApiResponseDtoOfObject extends ApiResponseDtoOfObject {\n type?: ResponseResultType;\n error?: ErrorInfo;\n success?: boolean;\n}\n\nexport interface ApiResponseErrorDtoOfObject extends DetailedApiResponseDtoOfObject {\n}\n\nexport interface ApiResponseError extends ApiResponseErrorDtoOfObject {\n}\n\nexport enum ResponseResultType {\n Undefined = \"undefined\",\n Success = \"success\",\n Failed = \"failed\",\n}\n\nexport interface ErrorInfo {\n message?: string;\n code?: number;\n correlationId?: string;\n validation?: ValidationSummary;\n}\n\nexport interface ValidationSummary {\n properties?: PropertyValidationError[];\n}\n\nexport interface PropertyValidationError {\n errorKey?: string;\n helpActions?: HelpAction[];\n propertyName?: string;\n attemptedValue?: any;\n errorMessage?: string;\n children?: PropertyValidationError[];\n}\n\nexport interface HelpAction {\n helpActionUrl?: string;\n helpActionTitle?: string;\n}\n\nexport interface PersonIdentificationRequest {\n /** Collection of identifiers used to calculate the identity graph. */\n id: PersonIdentifiers;\n /** Source of the identification request. */\n src: TrackingEventSource;\n}\n\nexport interface PersonIdentifiersBase {\n /** Browser user agent */\n ua?: string[];\n /** IP Address */\n ip?: string[];\n /** Seeka Person ID - Identity graph ID */\n seekaPId?: string;\n /** Seeka Browser ID */\n seekaBId?: string[];\n /** Email address */\n email?: string[];\n /** Gender */\n gender?: string[];\n /** Phone number. Recommended to provide in E.164 format. */\n phone?: string[];\n /** First name */\n firstName?: string[];\n /** Last name / surname */\n lastName?: string[];\n /** Shipping, mailing or residential address */\n address?: PlaceAddress[];\n /** Date of birth */\n dob?: Date[];\n /** Shopify identifiers */\n shopify?: ShopifyPersonIdentifiers;\n /** WooCommerce identifiers */\n wooCommerce?: WooCommercePersonIdentifiers;\n /** BigCommerce identifiers */\n bigCommerce?: BigCommercePersonIdentifiers;\n /** Magento identifiers */\n magento?: MagentoPersonIdentifiers;\n /** Klaviyo identifiers scoped by Klaviyo account ID */\n klaviyo?: ScopedIdentifiersOfKlaviyoPersonIdentifiersDtoAndString;\n /** Arbitrary traits */\n traits?: { [key: string]: any; };\n}\n\nexport interface PersonIdentifiers extends PersonIdentifiersBase {\n /** Facebook identifiers */\n facebook?: FacebookPersonIdentifiers;\n /** Snapchat identifiers */\n snapchat?: SnapchatPersonIdentifiers;\n /** TikTok identifiers */\n tiktok?: TikTokPersonIdentifiers;\n /** Google identifiers */\n google?: GooglePersonIdentifiers;\n /** Pinterest identifiers */\n pinterest?: PinterestPersonIdentifiers;\n /** Marketing, analytics and other third-party opt in/consent information */\n consent?: PersonConsentInfo;\n}\n\nexport interface BrandScopedFacebookPersonIdentifiers {\n /** Facebook user login ID */\n login?: string[];\n /** Facebook click ID */\n fbc?: string[];\n /** Facebook lead ID */\n lead?: string[];\n}\n\nexport interface FacebookPersonIdentifiers extends BrandScopedFacebookPersonIdentifiers {\n /** Facebook pixel / browser ID */\n fbp?: string[];\n}\n\nexport interface BrandScopedSnapchatPersonIdentifiers {\n /** Snapchat click ID */\n sccid?: string[];\n}\n\nexport interface SnapchatPersonIdentifiers extends BrandScopedSnapchatPersonIdentifiers {\n /** Snapchat pixel / browser ID */\n scid?: string[];\n}\n\nexport interface BrandScopedTikTokPersonIdentifiers {\n /** TikTok click ID */\n ttclid?: string[];\n /** TikTok lead ID */\n lead?: string[];\n}\n\nexport interface TikTokPersonIdentifiers extends BrandScopedTikTokPersonIdentifiers {\n /** TikTok pixel / browser ID */\n ttp?: string[];\n}\n\nexport interface BrandScopedGooglePersonIdentifiers {\n /** Google click ID */\n gclid?: string[];\n}\n\nexport interface GooglePersonIdentifiers extends BrandScopedGooglePersonIdentifiers {\n /** Google user client ID */\n userClientId?: string[];\n}\n\nexport interface BrandScopedPinterestPersonIdentifiers {\n /** Pinterest click ID / epik ID */\n epik?: string[];\n}\n\nexport interface PinterestPersonIdentifiers extends BrandScopedPinterestPersonIdentifiers {\n}\n\nexport interface PersonConsentInfo {\n /** Grant for sending data to 3rd party analytics and marketing platforms. */\n analytics?: ConsentInfo;\n /** Grant for marketing via re-marketing campaigns, EDMs etc. */\n marketing?: MarketingConsentInfo;\n /** Grant for enrolling and participating in loyalty programs. */\n loyalty?: ConsentInfo;\n privacy?: PrivacyState;\n}\n\nexport interface ConsentInfo {\n type?: PrivacyConsentType;\n /** When the consent was granted. */\n consentGrantedAt?: Date | undefined;\n /** The name of the source that provided the grant information. Set to the source platform like Shopify, Wordpress or your custom integration client name. */\n consentGrantedSourceName?: string;\n /** When the consent was not granted. */\n consentNotGrantedAt?: Date | undefined;\n /** The name of the source that provided the grant information. Set to the source platform like Shopify, Wordpress or your custom integration client name. */\n consentNotGrantedSourceName?: string;\n}\n\nexport enum PrivacyConsentType {\n Unknown = \"unknown\",\n Informed = \"informed\",\n Implied = \"implied\",\n Explicit = \"explicit\",\n Active = \"active\",\n Passive = \"passive\",\n}\n\nexport interface MarketingConsentInfo {\n email?: ConsentInfo;\n sms?: ConsentInfo;\n}\n\nexport interface PrivacyState {\n /** Transparency and Consent Framework (TCF) consent string v2.0\nSee https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20Consent%20string%20and%20vendor%20list%20formats%20v2.md */\n tcfConsentString?: string | undefined;\n}\n\nexport interface PlaceAddress {\n description?: string;\n addressLine1?: string;\n addressLine2?: string;\n streetName?: string;\n locality?: string;\n /** Full name of the state / province / territory */\n state?: string;\n /** ISO 3166-2 - Two or three character subdivision code */\n stateCode?: string;\n postcode?: string;\n /** Full name of the country */\n country?: string;\n /** ISO 3166-2 - Two character country code */\n countryCode?: string;\n googlePlaceId?: string;\n timeZone?: TimeZoneInfo;\n geoLocation?: GeographicalCoordinate;\n}\n\nexport interface TimeZoneInfo {\n /** IANA timezone ID */\n friendlyId?: string;\n description?: string;\n}\n\nexport interface GeographicalCoordinate {\n longitude?: number;\n latitude?: number;\n}\n\nexport interface ShopifyPersonIdentifiers {\n customerId?: string[];\n uniqueToken?: string[];\n microSessionId?: string[];\n visitToken?: string[];\n cartToken?: string[];\n checkoutToken?: string[];\n cartId?: string[];\n deviceId?: string[];\n checkoutId?: string[];\n orderId?: string[];\n sessionHash?: string[];\n}\n\nexport interface WooCommercePersonIdentifiers {\n customerId?: string[];\n orderId?: string[];\n cartHash?: string[];\n}\n\nexport interface BigCommercePersonIdentifiers {\n /** BigCommerce */\n customerId?: string[];\n /** BigCommerce */\n cartId?: string[];\n /** BigCommerce */\n orderId?: string[];\n}\n\nexport interface MagentoPersonIdentifiers {\n /** Magento customer */\n customerId?: string[];\n /** Magento cart */\n cartId?: string[];\n /** Magento order unique identifier */\n orderId?: string[];\n /** Magento order number / incremental ID */\n orderNumber?: string[];\n /** Magento checkout */\n checkoutId?: string[];\n}\n\nexport interface ScopedIdentifiersOfKlaviyoPersonIdentifiersDtoAndString {\n data?: { [key: string]: KlaviyoPersonIdentifiers; };\n}\n\nexport interface KlaviyoPersonIdentifiers {\n /** Klaviyo profile ID */\n profileId?: string[] | undefined;\n}\n\nexport interface TrackingEventSource {\n /** Source method that requested the tracking. */\n method: string;\n /** Type of origin that generated the tracking request.\nThis is not the same as where the tracking event originated from, this property specifies where the tracking event was tracked from. */\n origin?: TrackingEventSourceOriginType | undefined;\n /** Time occurred. Do not provide to use server time (recommended) */\n time?: Date | undefined;\n /** URL where the tracking event originated from. */\n loc: string;\n /** Title of the view or page where the tracking event originated from. */\n vt?: string | undefined;\n /** Session ID where the tracking event originated from. UTC date.time and then random digits.\nFormat YYYYMMDD.HHMMSS.{random 10 digits} */\n sess?: string | undefined;\n /** Diagnosis session ID. UTC date.time and then random digits.\nFormat YYYYMMDD.HHMMSS.{random 10 digits} */\n diag?: string | undefined;\n runtime?: SeekaSdkRuntimeInfo;\n /** Context of the pipeline integration that raised the tracking event. */\n pipeline?: SeekaPipelineIntegrationSource | undefined;\n /** IP address */\n ip?: string | undefined;\n device?: DeviceTrackingSource | undefined;\n privacy?: PrivacyState | undefined;\n}\n\nexport enum TrackingEventSourceOriginType {\n Browser = \"browser\",\n Server = \"server\",\n Mobile = \"mobile\",\n Desktop = \"desktop\",\n PhysicalStore = \"physicalStore\",\n Email = \"email\",\n Phone = \"phone\",\n Chat = \"chat\",\n Automatic = \"automatic\",\n}\n\nexport interface SeekaSdkRuntimeInfo {\n /** Version of the package or library being used to interact with the SDK */\n ver?: string;\n /** Type of the package or library being used to interact with the SDK */\n type?: string;\n client?: SeekaSdkClientRuntimeInfo;\n}\n\nexport interface SeekaSdkClientRuntimeInfo {\n /** Client version used to identify the implementation of the SDK */\n ver?: string;\n /** Name or type used to identify the implementation of the SDK. This could be specified as 'backend' for a backend integration with the SDK or 'website' for integrations placed on a website. */\n type?: string;\n}\n\nexport interface SeekaPipelineIntegrationSource {\n convergePipelineIntegrationInstanceId?: string;\n /** The IntegrationVendorNameKey could be set to \"Klaviyo\" for all Klaviyo pipeline integration classes so that the rate limit for certain operations are shared across all Klaviyo integration instances that share the same IntegrationInstanceUniqueKey\nAlpha only\nMax length of 12 characters */\n integrationVendorNameKey?: string;\n /** In format of IntegrationPublisherCompany.IntegrationVendorNameKey.IntegrationName. Eg. Seeka.Klaviyo.Identity */\n convergePipelineIntegrationTypeKey?: string;\n}\n\nexport interface DeviceTrackingSource {\n /** Browser name (Chrome, Firefox, Safari, etc) */\n bn?: string | undefined;\n /** Browser version */\n bv?: string | undefined;\n /** Platform name (Win32, OSX etc) */\n pl?: string | undefined;\n /** Device fingerprint */\n fp?: string | undefined;\n}\n\nexport interface DataIngestBatchHttpRequest {\n /** Max batch size is 50 */\n data?: DataIngestBatchHttpItem[];\n}\n\nexport interface DataIngestBatchHttpItem {\n ev?: ActivityTrackingRequest;\n id?: PersonIdentificationRequest;\n bot?: BotMetricTrackingRequest;\n log?: ActivityLogRequest;\n}\n\nexport interface ActivityTrackingRequest {\n /** Collection of identifiers used to calculate the identity graph. */\n id: PersonIdentifiers;\n /** Source of the identification request. */\n src: TrackingEventSource;\n /** Custom properties to attach to tracking event */\n props?: { [key: string]: string; };\n /** UTM tracking information */\n utm?: UtmTrackingEvent[];\n /** Activity tracking information */\n payload?: ActivityPayload;\n}\n\nexport interface UtmTrackingEvent {\n /** UTM ID */\n id?: string;\n /** UTM content */\n content?: string;\n /** UTM source */\n source?: string;\n /** UTM campaign */\n campaign?: string;\n /** UTM term */\n term?: string;\n /** UTM medium */\n medium?: string;\n}\n\nexport interface ActivityPayloadBase {\n /** Standard or custom activity / behavior activity name. */\n activityName?: TrackingActivityNames;\n /** Required if ActivityName is set to Custom.\nWhen setting this parameter in conjunction with setting ActivityName to a standard event name, Seeka will process the event\nas a standard event with the exception of conversion based data destinations being sent the event as the ActivityNameCustom value\nwith the parameters of the standard event. */\n activityNameCustom?: string;\n /** Unique identifier used to de-duplicate activities */\n activityId?: string;\n /** E-Commerce specific activity properties */\n commerce?: CommerceActivityTrackingEventMetadata;\n /** Search function specific activity properties */\n search?: SearchActivityTrackingEventMetadata;\n /** Sign up / newsletter function specific activity properties */\n signUp?: SignUpActivityTrackingEventMetadata;\n /** User account specific activity properties */\n userAccount?: UserAccountActivityTrackingEventMetadata;\n /** Promotion specific activity properties */\n promotion?: PromotionalActivityTrackingEventMetadata;\n /** Content behavior specific activity properties */\n contentBehaviour?: ContentBehaviourActivityTrackingEventMetadata;\n /** Lead activity properties */\n lead?: LeadActivityTrackingEventMetadata;\n /** Content item activity properties */\n contentItem?: ContentItemActivityTrackingEventMetadata;\n /** Custom properties attached to the tracking event */\n properties?: { [key: string]: string; };\n}\n\nexport interface ActivityPayload extends ActivityPayloadBase {\n /** Time activity occurred. Do not provide to use server time (recommended) */\n time?: Date | undefined;\n}\n\nexport enum TrackingActivityNames {\n Undefined = \"undefined\",\n PageViewOrganic = \"pageViewOrganic\",\n PageViewUtmAttributed = \"pageViewUtmAttributed\",\n AddPaymentMethod = \"addPaymentMethod\",\n AddToWishlist = \"addToWishlist\",\n ContactMessage = \"contactMessage\",\n Custom = \"custom\",\n SyncCart = \"syncCart\",\n Order = \"order\",\n InitiateCheckout = \"initiateCheckout\",\n AddToCart = \"addToCart\",\n RemoveFromCart = \"removeFromCart\",\n OneTimeItemPurchase = \"oneTimeItemPurchase\",\n SubscriptionItemPurchase = \"subscriptionItemPurchase\",\n ViewProduct = \"viewProduct\",\n ViewPage = \"viewPage\",\n ApplyPromotionalCode = \"applyPromotionalCode\",\n KeywordSearch = \"keywordSearch\",\n UserLoginSignup = \"userLoginSignup\",\n UserLogin = \"userLogin\",\n NewsletterSignup = \"newsletterSignup\",\n Lead = \"lead\",\n ChangeProductAttribute = \"changeProductAttribute\",\n FilterItemsByAttribute = \"filterItemsByAttribute\",\n Schedule = \"schedule\",\n ViewContentItem = \"viewContentItem\",\n StartTrial = \"startTrial\",\n}\n\nexport interface CommerceActivityTrackingEventMetadata {\n products?: CommerceActivityTrackingEventProductMetadata[];\n checkoutIdentifier?: string;\n cartIdentifier?: string;\n orderIdentifier?: string;\n orderNumber?: string;\n customerIdentifier?: string;\n sourceChannelName?: string;\n platformType?: ECommercePlatform;\n paymentMethodName?: string;\n currencyCode?: string;\n isTest?: boolean;\n totalRefunds?: number | undefined;\n totalDiscounts?: number | undefined;\n totalLineItemsPrice?: number | undefined;\n totalPrice?: number | undefined;\n totalTax?: number | undefined;\n totalShippingPrice?: number | undefined;\n fulfillmentStatus?: ECommerceFulfillmentStatus | undefined;\n financialStatus?: ECommerceFinancialStatus | undefined;\n}\n\nexport interface CommerceActivityTrackingEventProductMetadata {\n /** ISO 4217 currency code */\n currencyCode?: string;\n productIdentifier?: string;\n variantIdentifier?: string;\n sku?: string;\n lineItemIdentifier?: string;\n productName?: string;\n variantName?: string;\n categoryName?: string;\n brandName?: string;\n unitPrice?: number | undefined;\n quantity?: number | undefined;\n totalDiscount?: number | undefined;\n type?: ECommerceContentType | undefined;\n attributes?: { [key: string]: any; };\n}\n\nexport enum ECommerceContentType {\n Undefined = \"undefined\",\n SingleProduct = \"singleProduct\",\n SingleVariant = \"singleVariant\",\n Collection = \"collection\",\n}\n\nexport enum ECommercePlatform {\n None = \"none\",\n BigCommerce = \"bigCommerce\",\n Shopify = \"shopify\",\n OrderGroove = \"orderGroove\",\n Magento = \"magento\",\n Generic = \"generic\",\n WooCommerce = \"wooCommerce\",\n Demandware = \"demandware\",\n}\n\n/** https://shopify.dev/api/admin-rest/2022-01/resources/order#resource-object */\nexport enum ECommerceFulfillmentStatus {\n Undefined = \"undefined\",\n Fulfilled = \"fulfilled\",\n NoneFulfilled = \"noneFulfilled\",\n PartiallyFulfilled = \"partiallyFulfilled\",\n RestockedOrCancelled = \"restockedOrCancelled\",\n}\n\n/** https://shopify.dev/api/admin-rest/2022-01/resources/order#resource-object */\nexport enum ECommerceFinancialStatus {\n Undefined = \"undefined\",\n Pending = \"pending\",\n Authorized = \"authorized\",\n PartiallyPaid = \"partiallyPaid\",\n Paid = \"paid\",\n PartiallyRefunded = \"partiallyRefunded\",\n Refunded = \"refunded\",\n Voided = \"voided\",\n}\n\nexport interface SearchActivityTrackingEventMetadata {\n searchText?: string;\n}\n\nexport interface UserAccountActivityTrackingEventMetadata {\n emailAddress?: string | undefined;\n userAccountIdentifierValue?: string | undefined;\n userAccountIdentifierTypeName?: string | undefined;\n}\n\nexport interface SignUpActivityTrackingEventMetadata extends UserAccountActivityTrackingEventMetadata {\n}\n\nexport interface PromotionalActivityTrackingEventMetadata {\n code?: string;\n}\n\nexport interface ContentBehaviourActivityTrackingEventMetadata {\n /** Behavior that changes or customised a product via an attribute. */\n changeProduct?: ChangeProductAttributeActivityTrackingEventMetadata;\n /** Behavior that filters a list of items or content via an attribute. */\n filterItems?: FilterItemsByAttributeActivityTrackingEventMetadata;\n}\n\nexport interface ChangeProductAttributeActivityTrackingEventMetadata {\n /** Name of the type of attribute. */\n attributeTypeName?: string;\n /** Previous value of the attribute before the change. */\n previousAttributeValue?: string;\n /** Value the attribute was changed to. */\n newAttributeValue?: string;\n /** Product that relates to attribute change. */\n product?: CommerceActivityTrackingEventProductMetadata;\n}\n\nexport interface FilterItemsByAttributeActivityTrackingEventMetadata {\n /** Name of the type of attribute that is being filtered by. */\n attributeTypeName?: string;\n /** String value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n stringValue?: string;\n /** Numerical value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n numericValue?: number | undefined;\n /** Date value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n dateValue?: Date | undefined;\n /** Boolean (true/false) value of the filter. Use only one of StringValue, NumericValue, BooleanValue or DateValue properties. */\n booleanValue?: boolean | undefined;\n}\n\nexport interface LeadActivityTrackingEventMetadata {\n sourceContentName?: string;\n companySize?: string;\n companyName?: string;\n predictedLtv?: number | undefined;\n predictedValue?: number | undefined;\n /** ISO 4217 currency code */\n currencyCode?: string;\n}\n\nexport interface ContentItemActivityTrackingEventMetadata {\n contentName?: string;\n identifiers?: string[];\n categoryName?: string;\n /** ISO 4217 currency code */\n currencyCode?: string;\n value?: number | undefined;\n contentType?: ECommerceContentType | undefined;\n items?: CommerceActivityTrackingEventProductMetadata[];\n}\n\nexport interface BotMetricTrackingRequest extends PersonIdentificationRequest {\n}\n\nexport interface ActivityTrackingBase {\n id?: string;\n source?: TrackingEventSource;\n properties?: { [key: string]: string; };\n utm?: UtmTrackingEvent;\n}\n\nexport interface ActivityLogRequest extends ActivityTrackingBase {\n logType?: ConvergePipelineLoggableActivityType;\n logLevel?: SdkLogEventLevel;\n messageTemplate?: string;\n identifiers?: PersonIdentifiers;\n}\n\nexport enum ConvergePipelineLoggableActivityType {\n Generic = \"generic\",\n ActivityIngress = \"activityIngress\",\n ActivityEgress = \"activityEgress\",\n UserProfile = \"userProfile\",\n SdkLog = \"sdkLog\",\n Detections = \"detections\",\n ActivityEgressFilter = \"activityEgressFilter\",\n Diagnosis = \"diagnosis\",\n PipelineIntegrationOutput = \"pipelineIntegrationOutput\",\n}\n\nexport enum SdkLogEventLevel {\n Information = \"information\",\n Warning = \"warning\",\n Error = \"error\",\n Verbose = \"verbose\",\n}\n\nexport enum SeekaWebhookCallType {\n None = \"none\",\n Probe = \"probe\",\n AppInstalled = \"appInstalled\",\n IdentityChanged = \"identityChanged\",\n ActivityAccepted = \"activityAccepted\",\n AppInstallSettingsUpdated = \"appInstallSettingsUpdated\",\n AppUninstalled = \"appUninstalled\",\n BrowserSdkPlugin = \"browserSdkPlugin\",\n}\n\nexport interface SeekaWebhookPayload {\n type?: SeekaWebhookCallType;\n /** Determines if the webhook is sent as a result of a test call */\n isTest?: boolean;\n /** Unique identifier for the webhook request */\n requestId?: string;\n causationId?: string | undefined;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContext extends SeekaWebhookPayload {\n context?: SeekaAppWebhookContext;\n}\n\nexport interface SeekaAppWebhookContext {\n /** ID of the organisation that installed the app */\n organisationId?: string;\n /** ID of the brand that installed the app */\n organisationBrandId?: string;\n /** Pipeline integration ID / ID of the installation of the app */\n applicationInstallId?: string;\n /** The client / application ID */\n applicationId?: string;\n}\n\nexport interface SeekaBrowserSdkPluginWebhookResponse {\n content: string;\n init: string;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaAppInstalledWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstalledWebhookContent;\n}\n\nexport interface SeekaAppInstalledWebhookContent {\n installationSettings?: { [key: string]: any; };\n /** The permissions granted to the app install by the user that installed the app. */\n grantedPermissions?: string[];\n}\n\nexport interface SeekaAppInstalledWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstalledWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaAppUninstalledWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppUninstalledWebhookContent;\n}\n\nexport interface SeekaAppUninstalledWebhookContent {\n installationSettings?: { [key: string]: any; };\n}\n\nexport interface SeekaAppUninstalledWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppUninstalledWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaAppInstallSettingsUpdatedWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstallSettingsUpdatedWebhookContent;\n}\n\nexport interface SeekaAppInstallSettingsUpdatedWebhookContent {\n installationSettings?: { [key: string]: any; };\n /** The permissions granted to the app install by the user that installed the app. */\n grantedPermissions?: string[];\n}\n\nexport interface SeekaAppInstallSettingsUpdatedWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaAppInstallSettingsUpdatedWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaActivityAcceptedWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaActivityAcceptedWebhookContent;\n}\n\nexport interface SeekaActivityAcceptedWebhookContent {\n source?: TrackingEventSource;\n identifiers?: PersonIdentifiers;\n activity?: WebsiteEventActivityAppsPayload;\n personId?: string;\n}\n\nexport interface WebsiteEventActivityAppsPayload extends ActivityPayloadBase {\n /** Time activity occurred */\n time?: Date;\n}\n\nexport interface SeekaActivityAcceptedWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaActivityAcceptedWebhookContent;\n}\n\nexport interface SeekaWebhookPayloadOfSeekaAppWebhookContextAndSeekaIdentityChangedWebhookContent extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaIdentityChangedWebhookContent;\n}\n\nexport interface SeekaIdentityChangedWebhookContent {\n identifiers?: PersonIdentifiers;\n personId?: string;\n}\n\nexport interface SeekaIdentityChangedWebhookPayload extends SeekaWebhookPayloadOfSeekaAppWebhookContext {\n content?: SeekaIdentityChangedWebhookContent;\n}\n\nexport interface ActivityPipelineActivityFilter {\n id?: string;\n type?: ActivityPipelineActivityFilterType;\n sourceFilter?: ActivityPipelineActivitySourceFilter;\n activityNames?: string[];\n}\n\nexport enum ActivityPipelineActivityFilterType {\n Undefined = \"undefined\",\n PurchaseMade = \"purchaseMade\",\n ActivityTracked = \"activityTracked\",\n}\n\nexport interface ActivityPipelineActivitySourceFilter {\n comparer?: ConditionComparer;\n filters?: ActivityPipelineActivityFilterSourceItem[];\n}\n\nexport enum ConditionComparer {\n Undefined = \"undefined\",\n And = \"and\",\n Or = \"or\",\n}\n\nexport interface ActivityPipelineActivityFilterSourceItem {\n label?: string;\n type?: ActivityPipelineActivityFilterSourceItemType;\n key?: string;\n}\n\nexport enum ActivityPipelineActivityFilterSourceItemType {\n Undefined = \"undefined\",\n Domain = \"domain\",\n Pipeline = \"pipeline\",\n Wildcard = \"wildcard\",\n}\n\nexport class ApiException extends Error {\n override message: string;\n status: number;\n response: string;\n headers: { [key: string]: any; };\n result: any;\n\n constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) {\n super();\n\n this.message = message;\n this.status = status;\n this.response = response;\n this.headers = headers;\n this.result = result;\n }\n\n protected isApiException = true;\n\n static isApiException(obj: any): obj is ApiException {\n return obj.isApiException === true;\n }\n}\n\nfunction throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): any {\n if (result !== null && result !== undefined)\n throw result;\n else\n throw new ApiException(message, status, response, headers, null);\n}\n\nfunction isAxiosError(obj: any): obj is AxiosError {\n return obj && obj.isAxiosError === true;\n}\n\n// Dont remove unused imports as they are used in the generated code\n\n// Dont remove unused imports as they are used in the generated code\n\nexport interface AppClientRuntimeInfo {\n /** Client version used to identify the implementation of the SDK */\n ver: string;\n /** Name or type used to identify the implementation of the SDK. This could be specified as 'backend' for a backend integration with the SDK or 'website' for integrations placed on a website. */\n type: string;\n}\n\nexport interface AppRuntimeInfo {\n /** Version of the package or library being used to interact with the SDK */\n ver: string;\n /** Type of the package or library being used to interact with the SDK */\n type: string;\n client: AppClientRuntimeInfo;\n}","import * as crypto from 'crypto';\nimport { TrackingActivityNames } from 'src/api/services';\n\nexport const generateNewSessionId = (): string => {\n /** Session ID where the tracking event originated from. Format of UTC time YYYYMMDD.HHMMSS.{random 6 digits} */\n const dateReference = dateToUtcDateTimeReferenceString(new Date());\n const random = getRandomNumberString();\n\n return `${dateReference}.${random}`;\n}\n\nexport const getActivityName = (event: string): TrackingActivityNames => {\n const vals = Object.keys(TrackingActivityNames)\n const evLower = event.toLowerCase();\n\n const matched = vals.find(e => e.toLowerCase() === evLower);\n\n if (matched) {\n return TrackingActivityNames[matched as keyof typeof TrackingActivityNames];\n }\n\n return TrackingActivityNames.Custom;\n}\n\nexport const getRandomNumberString = (): string => {\n const min = 1000000000;\n const max = 9999999999;\n return Math.floor(Math.random() * (max - min) + min).toString();\n}\n\nexport const dateToUtcDateTimeReferenceString = (forDateTime: Date): string => {\n let month = (forDateTime.getUTCMonth() + 1).toString();\n if (month.length < 2) {\n month = \"0\" + month;\n }\n let day = forDateTime.getUTCDate().toString();\n if (day.length < 2) {\n day = \"0\" + day;\n }\n let hour = forDateTime.getUTCHours().toString();\n if (hour.length < 2) {\n hour = \"0\" + hour;\n }\n let minute = forDateTime.getUTCMinutes().toString();\n if (minute.length < 2) {\n minute = \"0\" + minute;\n }\n let second = forDateTime.getUTCSeconds().toString();\n if (second.length < 2) {\n second = \"0\" + second;\n }\n\n return `${forDateTime.getUTCFullYear()}${month}${day}.${hour}${minute}${second}`;\n}\n\nexport const md5Hash = (input: string): string => {\n return crypto.createHash('md5').update(input).digest(\"hex\");\n}\n\nexport const separatePersonFullName = (fullname: string): { firstName: string | null, lastName: string | null } => {\n if (!fullname) return { firstName: null, lastName: null };\n\n const parts = fullname.trim().split(' ');\n if (parts.length === 1) return { firstName: fullname, lastName: null };\n else if (parts.length === 2) return { firstName: parts[0], lastName: parts[1] };\n else return { firstName: parts[0], lastName: parts.slice(1).join(' ') };\n}\n\n// Replicates lodash chunk method\nexport const chunk = <T>(array: T[], size: number): T[][] => {\n return array.reduce((resultArray: Array<T[]>, item, index) => {\n const chunkIndex = Math.floor(index / size)\n\n if (!resultArray[chunkIndex]) {\n resultArray[chunkIndex] = [] // start a new chunk\n }\n\n resultArray[chunkIndex].push(item)\n\n return resultArray\n }, [])\n}","import { BaseClient, custom, Issuer, IssuerMetadata, TokenSet } from 'openid-client';\n\nimport { SeekaAppConfig } from '../../../api/services';\nimport { SeekaAppCacheManager } from '../../../cache/appCacheManager';\nimport { md5Hash } from '../../../helpers/util';\n\nexport const getIssuer = async (config: SeekaAppConfig): Promise<Issuer<BaseClient>> => {\n const seekaIssuer = await getIssuerMetadata(config);\n const issuer = new Issuer(seekaIssuer);\n\n issuer[custom.http_options] = (url, options) => {\n return { timeout: 10000 };\n }\n\n return issuer;\n}\n\nexport const getIssuerMetadata = async (config: SeekaAppConfig): Promise<IssuerMetadata> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n\n if (config.logger) {\n config.logger.debug(`Seeka auth: getting issuer`, { ...logParams });\n }\n else {\n console.debug(`Seeka auth: getting issuer`, { ...logParams });\n }\n\n const cache = new SeekaAppCacheManager(config.appId, config.applicationInstallId);\n const cacheKey = md5Hash(config.issuerUrl);\n\n return await cache.getOrSet(cacheKey, async () => {\n const seekaIssuer = await discoverIssuerMetadata(config);\n return {\n value: seekaIssuer,\n expiryAbsoluteMilliseconds: 1000 * 60 * 60 // 1hour\n };\n }, async () => {\n if (config.logger) {\n config.logger.verbose(`Seeka auth: got issuer from cache`, { ...logParams });\n }\n else {\n console.debug(`Seeka auth: got issuer from cache`, { ...logParams });\n }\n }) as IssuerMetadata\n}\n\nexport const discoverIssuerMetadata = async (config: SeekaAppConfig): Promise<IssuerMetadata> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n\n if (config.logger) {\n config.logger.info(`Seeka auth: discovering issuer from server`, { ...logParams });\n }\n else {\n console.info(`Seeka auth: discovering issuer from server`, { ...logParams });\n }\n return (await Issuer.discover(config.issuerUrl)).metadata;\n}\n\n\nconst getNewClientToken = async (config: SeekaAppConfig): Promise<TokenSet | null> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n const issuer = await getIssuer(config);\n const client = new issuer.Client({\n client_id: config.appId.replace(/-/g, ''),\n client_secret: config.appSecret\n });\n client\n\n try {\n const token = await client.grant({\n grant_type: \"client_credentials\"\n });\n\n const successLogParams = {\n ...logParams,\n token: {\n expires_at: token.expires_at,\n token_type: token.token_type,\n scope: token.scope\n }\n }\n\n if (config.logger) {\n config.logger.info(`Seeka auth: got client access token from server`, { ...successLogParams });\n }\n else {\n console.info(`Seeka auth: got app client token from server`, { ...successLogParams });\n }\n\n return token;\n }\n catch (err) {\n const errorLogParams = {\n ...logParams,\n error: err\n }\n if (config.logger) {\n config.logger.error(`Seeka auth: failed to get client access token from server`, { ...errorLogParams });\n }\n else {\n console.debug(`Seeka auth: failed to get client access token from server`, { ...errorLogParams });\n }\n\n return null;\n }\n}\n\nexport const getNewAppInstallToken = async (clientAccessToken: string, config: SeekaAppConfig): Promise<TokenSet | null> => {\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n const issuer = await getIssuer(config);\n const client = new issuer.Client({\n client_id: config.appId.replace(/-/g, ''),\n client_secret: config.appSecret\n });\n\n try {\n const token = await client.grant({\n grant_type: \"app_install_token\",\n applicationInstallId: config.applicationInstallId,\n access_token: clientAccessToken,\n // scopes: [\n // \"organisationBrandId\",\n // \"convergeInstanceId\",\n // \"applicationInstallId\"\n // ]\n });\n\n // console.log('Got new app install token', {\n // expires_at: token.expires_at,\n // token_type: token.token_type,\n // scope: token.scope\n // });\n const successLogParams = {\n ...logParams,\n token: {\n expires_at: token.expires_at,\n token_type: token.token_type,\n scope: token.scope\n }\n }\n if (config.logger) {\n config.logger.info(`Seeka auth: got app access token from server`, { ...successLogParams });\n }\n else {\n console.info(`Seeka auth: got app access token from server`, { ...successLogParams });\n }\n\n return token;\n }\n catch (err) {\n const errorLogParams = {\n ...logParams,\n error: err\n }\n if (config.logger) {\n config.logger.error(`Seeka auth: failed to get app access token from server`, { ...errorLogParams });\n }\n else {\n console.debug(`Seeka auth: failed to get app access token from server`, { ...errorLogParams });\n }\n\n return null;\n }\n}\n\nexport const getNewOrCachedAppInstallToken = async (config: SeekaAppConfig): Promise<TokenSet | null> => {\n const appInstallCache = new SeekaAppCacheManager(config.appId, config.applicationInstallId);\n const logParams = { applicationId: config.appId, issuer: { url: config.issuerUrl } }\n\n return await appInstallCache.getOrSet('auth:token:appinstall', async () => {\n const clientToken = await getNewClientToken(config);\n if (!clientToken) return null;\n\n const appToken = await getNewAppInstallToken(clientToken.access_token as string, config);\n if (!appToken) return null;\n\n return {\n value: appToken,\n expiryAbsoluteMilliseconds: (((appToken.expires_in as number) > (clientToken.expires_in as number) ? clientToken.expires_in : appToken.expires_in) || 15 * 60 * 1000) - (60 * 1000)\n }\n }, async () => {\n if (config.logger) {\n config.logger.verbose(`Seeka auth: got app token from cache`, { ...logParams });\n }\n else {\n console.debug(`Seeka auth: got app token from cache`, { ...logParams });\n }\n })\n}","import axios from 'axios';\nimport http from 'http';\nimport https from 'https';\n\nimport { IdentityServiceProxy, IngestServiceProxy, SeekaAppConfig } from '../../services';\n\nconst httpAgent = new http.Agent({ keepAlive: true, scheduling: 'fifo' });\nconst httpsAgent = new https.Agent({ keepAlive: true, scheduling: 'fifo' });\n\nconst createAxiosInstance = (config: SeekaAppConfig) => {\n\n const instance = axios.create({\n httpAgent,\n httpsAgent,\n });\n\n instance.interceptors.request.use(function (reqConfig) {\n const logParams = {\n url: reqConfig.url,\n method: reqConfig.method\n };\n if (config.logger) {\n config.logger.debug(`Seeka API: making call to ${logParams.url}`, { ...logParams });\n }\n else {\n console.debug(`Seeka API: making call to ${logParams.url}`, { ...logParams });\n }\n\n return reqConfig;\n }, function (error) {\n const logParams = {\n // url: response.request?.url || response.config.url,\n // method: response.request?.method || response.config.method,\n error\n };\n if (config.logger) {\n config.logger.http(`Seeka API: failed to send request`, { ...logParams });\n }\n else {\n console.debug(`Seeka API: failed to send request`, { ...logParams });\n }\n return Promise.reject(error);\n });\n\n instance.interceptors.response.use(function (response) {\n const logParams = {\n url: response.request?.url || response.config.url,\n method: response.request?.method || response.config.method,\n response: {\n status: response.status,\n }\n };\n if (config.logger) {\n config.logger.http(`Seeka API: call to ${logParams.url} succeeded`, { ...logParams });\n }\n else {\n console.debug(`Seeka API: call to ${logParams.url} succeeded`, { ...logParams });\n }\n\n return response;\n }, function (error) {\n const { code, status, message } = error\n const { headers, url, method } = error?.config;\n const errorLogParams = {\n code,\n status,\n message,\n headers,\n url,\n method,\n content: error?.response?.data\n }\n if (config.logger) {\n config.logger.error(`Seeka API: call to ${errorLogParams.url} failed`, { ...errorLogParams });\n }\n else {\n console.error(`Seeka API: call to ${errorLogParams.url} failed`, { ...errorLogParams });\n }\n\n return Promise.reject(error);\n });\n\n return instance;\n}\n\nexport const serviceResolver = {\n getIdentityService: (config: SeekaAppConfig) => new IdentityServiceProxy(config, config.ingestUrl, createAxiosInstance(config)),\n getIngestService: (config: SeekaAppConfig) => new IngestServiceProxy(config, config.ingestUrl, createAxiosInstance(config)),\n}","import { chunk, generateNewSessionId } from '../../helpers/util';\nimport { AppPermissionKeys, ServiceCallSource } from '../models';\nimport {\n ActivityPayload, DataIngestBatchHttpRequest, IdentityServiceProxy, IngestServiceProxy,\n PersonIdentifiers, SeekaAppConfig\n} from '../services';\nimport { getNewOrCachedAppInstallToken } from './auth';\nimport { serviceResolver } from './serviceResolver';\n\nexport class SeekaApiHelper {\n constructor(config: SeekaAppConfig) {\n this.config = config;\n this.ingestionService = serviceResolver.getIngestService(config);\n this.identityService = serviceResolver.getIdentityService(config);\n }\n\n private readonly config;\n\n private maxBatchSize = 50;\n\n // Used to prime the token cache and issue refresh tokens if required\n public refreshOrPrimeTokenCache = async (): Promise<void> => {\n await getNewOrCachedAppInstallToken(this.config);\n }\n\n public ingestionService: IngestServiceProxy;\n public identityService: IdentityServiceProxy;\n\n private checkPermission = (permissionKey: string, opName: string): boolean => {\n if (!this.config.hasPermission(permissionKey)) {\n throw new Error('Cannot perform operation ' + opName + ' on installationId ' + this.config.applicationInstallId + ' without permission ' + permissionKey + '. Currently granted permissions: ' + (this.config.grantedPermissions ? this.config.grantedPermissions.join(', ') : 'none'));\n }\n\n return true;\n }\n\n public mergeIdentity = async (identity: PersonIdentifiers, src: ServiceCallSource): Promise<string> => {\n this.checkPermission(AppPermissionKeys.identity.send, 'mergeIdentity');\n\n const sessionId = generateNewSessionId();\n\n const result = await this.identityService.merge({\n id: identity,\n src: {\n method: '', // TODO\n origin: src.origin,\n time: undefined,\n loc: src.loc as string,\n sess: sessionId,\n diag: process.env.SEEKA_DEBUG_ENABLED === 'true' ? sessionId : undefined,\n runtime: this.config.runtime\n }\n })\n\n return result.result?.personId as string;\n }\n\n public mergeIdentityBatch = async (batch: PersonIdentifiers[], src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.identity.send, 'mergeIdentityBatch');\n\n const sessionId = generateNewSessionId();\n if (batch.length === 0) {\n this.config.logger?.info('No identities in batch');\n return;\n }\n\n const sourceMetadata = {\n method: '', // TODO\n origin: src.origin,\n time: undefined,\n loc: src.loc as string,\n sess: sessionId,\n diag: process.env.SEEKA_DEBUG_ENABLED === 'true' ? sessionId : undefined,\n runtime: this.config.runtime\n }\n\n // Make ingestion is ${this.maxBatchSize} per batch, send in parallel\n const chunks = chunk(batch, this.maxBatchSize);\n if (chunks.length > 1) {\n if (this.config.logger) {\n this.config.logger.debug(`Identity batch size ${batch} is greater than ${this.maxBatchSize}, splitting into ${chunks.length} batches`);\n }\n }\n\n // Process first batch to prime authorization, then process the rest of the batches\n await this.trackActivityBatchRaw({\n data: chunks[0].map(profile => {\n return {\n id: {\n id: profile || {},\n src: { ...sourceMetadata },\n }\n }\n })\n })\n\n if (chunks.length > 1) {\n const promises = chunks.map((chunk, index) => {\n if (index === 0) return Promise.resolve();\n\n this.config.logger?.info(`Processing identity batch ${index + 1} of ${chunks.length}`);\n return this.trackActivityBatchRaw({\n data: chunk.map(profile => {\n return {\n id: {\n id: profile || {},\n src: { ...sourceMetadata },\n }\n }\n })\n })\n })\n\n await Promise.all(promises);\n }\n }\n\n public trackActivityBatch = async (batch: { activity: ActivityPayload, profile?: PersonIdentifiers | undefined }[], src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityBatch');\n\n const sessionId = generateNewSessionId();\n if (batch.length === 0) {\n this.config.logger?.info('No activities in batch');\n return;\n }\n\n const sourceMetadata = {\n method: '', // TODO\n origin: src.origin,\n time: undefined,\n loc: src.loc as string,\n sess: sessionId,\n diag: process.env.SEEKA_DEBUG_ENABLED === 'true' ? sessionId : undefined,\n runtime: this.config.runtime\n }\n\n // Make ingestion is ${this.maxBatchSize} per batch, send in parallel\n const chunks = chunk(batch, this.maxBatchSize);\n if (chunks.length > 1) {\n if (this.config.logger) {\n this.config.logger.debug(`Activity batch size ${batch.length} is greater than ${this.maxBatchSize}, splitting into ${chunks.length} batches`);\n }\n }\n\n // Process first batch to prime authorization, then process the rest of the batches\n await this.trackActivityBatchRaw({\n data: chunks[0].map(item => {\n return {\n ev: {\n id: item.profile || {},\n src: { ...sourceMetadata },\n payload: item.activity\n }\n }\n })\n })\n\n if (chunks.length > 1) {\n const promises = chunks.map((chunk, index) => {\n if (index === 0) return Promise.resolve();\n\n this.config.logger?.info(`Processing activity batch ${index + 1} of ${chunks.length}`);\n return this.trackActivityBatchRaw({\n data: chunk.map(item => {\n return {\n ev: {\n id: item.profile || {},\n src: { ...sourceMetadata },\n payload: item.activity\n }\n }\n })\n })\n })\n\n await Promise.all(promises);\n }\n }\n\n public trackActivityBatchRaw = async (data: DataIngestBatchHttpRequest): Promise<void> => {\n await this.ingestionService.batch(data);\n }\n\n public trackActivityForProfileId = async (activity: ActivityPayload, profileId: string | undefined, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfileId');\n\n await this.trackActivityForProfileIdBatch([activity], profileId, src);\n }\n\n public trackActivityForProfileIdBatch = async (activities: ActivityPayload[], profileId: string | undefined, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfileIdBatch');\n\n await this.trackActivityBatch(activities.map(e => {\n return {\n activity: e,\n profile: profileId ? { seekaPId: profileId } : undefined\n }\n }), src);\n }\n\n public trackActivityForProfile = async (activity: ActivityPayload, profile: PersonIdentifiers, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfile');\n\n await this.trackActivityForProfileBatch([activity], profile, src);\n }\n\n public trackActivityForProfileBatch = async (activities: ActivityPayload[], profile: PersonIdentifiers, src: ServiceCallSource): Promise<void> => {\n this.checkPermission(AppPermissionKeys.activity.send, 'trackActivityForProfileBatch');\n\n await this.trackActivityBatch(activities.map(e => {\n return {\n activity: e,\n profile: profile\n }\n }), src);\n }\n}\n","import * as crypto from 'crypto';\n\nimport type { Headers as UndiciHeaders } from 'undici';\n\nexport const webhookSignatureHeaderName = 'x-seeka-signature-sha256';\n\nexport const validateWebhookSignature = (secret: string, headers: UndiciHeaders | Headers | NodeJS.Dict<string | string[]>, requestBody: string): boolean => {\n if (!headers) return false;\n\n let signature: string | null = null;\n\n if (headers.get && typeof headers.get === 'function') {\n // undici and fetch\n signature = (headers as Headers).get(webhookSignatureHeaderName);\n }\n else {\n // express\n const signatures = (headers as NodeJS.Dict<string | string[]>)[webhookSignatureHeaderName];\n if (signatures) {\n if (Array.isArray(signatures) && signatures.length > 0) {\n signature = signatures[0]\n }\n else if (typeof signatures === 'string' || signatures instanceof String) {\n signature = signatures as string;\n }\n }\n }\n if (!signature) return false;\n\n // Check hash\n const hash = getHmacSignature(secret, requestBody);\n const valid = hash === signature;\n\n if (!valid) {\n console.warn(\"Invalid webhook signature\")\n }\n\n return valid;\n}\n\nexport const getHmacSignature = (secret: string, requestBody: string): string => {\n return crypto.createHmac('sha256', secret)\n .update(requestBody)\n .digest('hex');\n}\n\nexport const throwOnInvalidWebhookSignature = (secret: string, headers: UndiciHeaders | Headers | NodeJS.Dict<string | string[]>, requestBody: string): void => {\n if (!validateWebhookSignature(secret, headers, requestBody)) throw new Error('Invalid webhook signature');\n} ","import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { Logger } from 'winston';\n\nimport { version } from '../../../../package.json';\nimport { AppClientRuntimeInfo, SeekaAppConfig } from '../../services';\nimport { getNewOrCachedAppInstallToken } from '../auth';\n\nconst defaultIngestUrl = 'https://router.seeka.services';\nconst defaultIssuerUrl = 'https://account.seeka.app'\n\nexport const getAppConfig = (context: { applicationId: string, organisationId: string, applicationInstallId: string }, appSecret: string, client: AppClientRuntimeInfo, grantedPermissions: string[], logger?: Logger): SeekaAppConfig => {\n const config = new SeekaAppConfig();\n config.appId = context.applicationId;\n config.appSecret = appSecret;\n config.ingestUrl = process.env.SEEKA_INGEST_URL || defaultIngestUrl;\n config.issuerUrl = process.env.SEEKA_ISSUER_URL || defaultIssuerUrl;\n config.organisationId = context.organisationId;\n config.applicationInstallId = context.applicationInstallId;\n config.runtime = {\n type: 'sdk/js/apps-server',\n ver: version,\n client: client\n };\n config.logger = logger;\n config.grantedPermissions = grantedPermissions;\n\n config.transformApiRequest = (options: AxiosRequestConfig) => transformApiRequest(config, options);\n config.transformApiResponse = async (url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => transformApiResponse(config, url, response, processor)\n\n config.hasAnyPermissions = (permissionKeys: string[]): boolean => {\n if (!config.grantedPermissions || config.grantedPermissions.length === 0) return false;\n if (!permissionKeys || permissionKeys.length === 0) return true;\n\n return permissionKeys.some(key => config.grantedPermissions.includes(key));\n }\n config.hasAllPermissions = (permissionKeys: string[]): boolean => {\n if (!config.grantedPermissions || config.grantedPermissions.length === 0) return false;\n if (!permissionKeys || permissionKeys.length === 0) return true;\n\n return permissionKeys.every(key => config.grantedPermissions.includes(key));\n }\n config.hasPermission = (permissionKey: string): boolean => {\n if (!config.grantedPermissions || config.grantedPermissions.length === 0) return false;\n if (!permissionKey) return true;\n\n return config.grantedPermissions.includes(permissionKey);\n }\n\n return config;\n}\n\nconst transformApiRequest = async (config: SeekaAppConfig, options: AxiosRequestConfig): Promise<AxiosRequestConfig> => {\n const token = await getNewOrCachedAppInstallToken(config);\n\n options.headers = {\n ...options.headers,\n 'X-OrgId': config.organisationId,\n Authorization: 'Bearer ' + token?.access_token,\n };\n\n // if(!token){\n // // TODO: Test\n // options.cancelToken = new axios.CancelToken((cancel: Canceler) => {\n // cancel();\n // }) \n // } \n\n return options;\n}\n\nconst transformApiResponse = async (config: SeekaAppConfig, url: string, response: AxiosResponse<any, any>, processor: (response: AxiosResponse<any, any>) => any) => {\n // Force string response, for some reason nswag is trying to JSON.parse the response when it is already deserialised to an object\n response.data = JSON.stringify(response.data);\n\n return processor(response);\n}\n\n// // export const handleApiError = (error: any, operationName: string) => {\n// // if(error.isAxiosError){\n// // const err = error as AxiosError;\n// // console.error(`Failed to ${operationName} - response ${err.code || err.status}`, {\n// // url: err.config?.url,\n// // code: err.code,\n// // message: err.message,\n// // response: err.response?.data\n// // });\n// // }\n// // else{\n// // console.error('Failed to ' + operationName, error)\n// // }\n// // }","import { Logger } from 'winston';\n\nimport { SeekaApiHelper } from '../../api/helper';\nimport { getAppConfig } from '../../api/helper/config';\nimport { SeekaAppConfig } from '../../api/services';\nimport { SeekaAppCacheManager } from '../../cache/appCacheManager';\n\nexport interface SeekaAppHelperContext {\n config: SeekaAppConfig;\n}\n\nexport class SeekaAppHelper {\n constructor(context: SeekaAppHelperContext, logger?: Logger) {\n this.context = context;\n this.api = new SeekaApiHelper(context.config);\n this.appCache = new SeekaAppCacheManager(context.config.appId);\n this.appInstallCache = new SeekaAppCacheManager(context.config.appId, context.config.applicationInstallId);\n this.logger = logger;\n }\n\n private readonly context;\n public appCache: SeekaAppCacheManager;\n public appInstallCache: SeekaAppCacheManager;\n public api: SeekaApiHelper;\n public logger?: Logger;\n\n public static create = (appSecret: string, context: { applicationId: string, organisationId: string, applicationInstallId: string }, client: { name: string, version: string }, grantedPermissions: string[], logger?: Logger): SeekaAppHelper => {\n return new SeekaAppHelper({\n config: getAppConfig({\n ...context\n }, appSecret, {\n type: client.name,\n ver: client.version,\n }, grantedPermissions, logger)\n }, logger)\n }\n}"],"names":["AppPermissionKeys","identity","receiveFull","send","activity","receiveAnon","prefix","SeekaAppCacheManager","constructor","appId","appInstallationId","this","set","async","key","value","expiryAbsoluteMilliseconds","cacheKey","getKey","memoryCache","put","JSON","stringify","getOrSet","getValueAndExpiryFunc","onGetFromCache","existing","get","cached","parse","newVal","SeekaAppConfig","appSecret","ingestUrl","issuerUrl","organisationId","applicationInstallId","runtime","logger","grantedPermissions","transformApiRequest","transformApiResponse","hasAnyPermissions","hasAllPermissions","hasPermission","ApiServiceProxyBase","config","transformOptions","options","transformResult","url","response","processor","IdentityServiceProxy","configuration","baseUrl","instance","super","jsonParseReviver","undefined","axios","create","merge","payload","cancelToken","url_","replace","content_","data","method","headers","Accept","then","transformedOptions_","request","catch","_error","isAxiosError","_response","processMerge","status","_headers","k","hasOwnProperty","result200","Promise","resolve","_responseText","result401","throwException","result422","result400","IngestServiceProxy","batch","processBatch","ResponseResultType","PrivacyConsentType","TrackingEventSourceOriginType","TrackingActivityNames","ECommerceContentType","ECommercePlatform","ECommerceFulfillmentStatus","ECommerceFinancialStatus","ConvergePipelineLoggableActivityType","SdkLogEventLevel","SeekaWebhookCallType","ActivityPipelineActivityFilterType","ConditionComparer","ActivityPipelineActivityFilterSourceItemType","ApiException","Error","message","result","isApiException","obj","generateNewSessionId","dateToUtcDateTimeReferenceString","Date","getRandomNumberString","Math","floor","random","toString","forDateTime","month","getUTCMonth","length","day","getUTCDate","hour","getUTCHours","minute","getUTCMinutes","second","getUTCSeconds","getUTCFullYear","chunk","array","size","reduce","resultArray","item","index","chunkIndex","push","getIssuer","seekaIssuer","getIssuerMetadata","issuer","Issuer","custom","http_options","timeout","logParams","applicationId","debug","console","cache","input","crypto","createHash","update","digest","discoverIssuerMetadata","verbose","info","discover","metadata","getNewOrCachedAppInstallToken","appInstallCache","clientToken","client","Client","client_id","client_secret","token","grant","grant_type","successLogParams","expires_at","token_type","scope","err","errorLogParams","error","getNewClientToken","appToken","clientAccessToken","access_token","getNewAppInstallToken","expires_in","httpAgent","http","Agent","keepAlive","scheduling","httpsAgent","https","createAxiosInstance","interceptors","use","reqConfig","reject","_response$request","_response$request2","_error$response","code","content","SeekaApiHelper","maxBatchSize","refreshOrPrimeTokenCache","ingestionService","identityService","checkPermission","permissionKey","opName","join","mergeIdentity","src","_result$result","sessionId","id","origin","time","loc","sess","diag","process","env","SEEKA_DEBUG_ENABLED","personId","mergeIdentityBatch","_this$config$logger","sourceMetadata","chunks","trackActivityBatchRaw","map","profile","promises","_this$config$logger2","all","trackActivityBatch","_this$config$logger3","ev","_this$config$logger4","trackActivityForProfileId","profileId","trackActivityForProfileIdBatch","activities","e","seekaPId","trackActivityForProfile","trackActivityForProfileBatch","serviceResolver","webhookSignatureHeaderName","validateWebhookSignature","secret","requestBody","signature","signatures","Array","isArray","String","valid","getHmacSignature","warn","createHmac","getAppConfig","context","SEEKA_INGEST_URL","SEEKA_ISSUER_URL","type","ver","permissionKeys","some","includes","every","Authorization","_class","SeekaAppHelper","appCache","api","name","version","event","vals","Object","keys","evLower","toLowerCase","matched","find","Custom","fullname","firstName","lastName","parts","trim","split","slice","throwOnInvalidWebhookSignature"],"mappings":"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"}
|