@inploi/sdk 1.15.2 → 1.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +72 -13
- package/dist/index.d.ts +72 -13
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/cdn/index.js +0 -3
package/dist/index.d.mts
CHANGED
|
@@ -172,22 +172,27 @@ declare const getSessionInfo: (request?: Request) => {
|
|
|
172
172
|
anonymous_id: string | null;
|
|
173
173
|
session_id: string | null;
|
|
174
174
|
};
|
|
175
|
+
type AnalyticsOnEventCallback = (event: AnalyticsLogParams) => void;
|
|
175
176
|
|
|
176
|
-
declare class
|
|
177
|
-
|
|
177
|
+
declare class ErrorWithStatus extends Error {
|
|
178
|
+
status?: number;
|
|
179
|
+
constructor(message?: string, status?: number);
|
|
178
180
|
}
|
|
179
|
-
declare class
|
|
181
|
+
declare class NotFoundError extends ErrorWithStatus {
|
|
180
182
|
constructor(message?: string);
|
|
181
183
|
}
|
|
182
|
-
declare class
|
|
184
|
+
declare class UnauthorisedError extends ErrorWithStatus {
|
|
185
|
+
constructor(message?: string, status?: number);
|
|
186
|
+
}
|
|
187
|
+
declare class SchemaValidationError extends ErrorWithStatus {
|
|
183
188
|
issues: readonly StandardSchemaV1.Issue[];
|
|
184
|
-
|
|
189
|
+
source?: "searchParams" | "body" | "response" | undefined;
|
|
190
|
+
constructor(issues: readonly StandardSchemaV1.Issue[], source?: "searchParams" | "body" | "response" | undefined);
|
|
185
191
|
}
|
|
186
|
-
declare class ApiError extends
|
|
187
|
-
|
|
188
|
-
constructor(message: string, errors: unknown[]);
|
|
192
|
+
declare class ApiError extends ErrorWithStatus {
|
|
193
|
+
constructor(message: string, status?: number);
|
|
189
194
|
}
|
|
190
|
-
declare class JsonParsingError extends
|
|
195
|
+
declare class JsonParsingError extends ErrorWithStatus {
|
|
191
196
|
response?: Response | undefined;
|
|
192
197
|
constructor(response?: Response | undefined);
|
|
193
198
|
}
|
|
@@ -234,12 +239,41 @@ interface InploiRpcClientParams {
|
|
|
234
239
|
key: string;
|
|
235
240
|
};
|
|
236
241
|
}
|
|
242
|
+
type NonReducibleUnknown = {} | null | undefined;
|
|
243
|
+
type LooseAutocomplete<T extends BaseType, BaseType> = T | BaseType;
|
|
237
244
|
/** RPC client for making API calls to the Inploi API. */
|
|
238
245
|
declare class InploiRpcClient {
|
|
239
246
|
private baseUrl;
|
|
240
247
|
private headers;
|
|
241
248
|
private logger;
|
|
242
249
|
constructor(params: InploiRpcClientParams);
|
|
250
|
+
/** Gets params for a fetch request to the given endpoint */
|
|
251
|
+
getFetchParams<T extends RpcEndpoint>(endpoint: T, options: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ? GetSchemaValues<{
|
|
252
|
+
body: TBody;
|
|
253
|
+
searchParams: TSearch;
|
|
254
|
+
params: TPathParams;
|
|
255
|
+
}> & {
|
|
256
|
+
signal?: AbortSignal;
|
|
257
|
+
/**
|
|
258
|
+
* Whether to validate the inputs against the schema.
|
|
259
|
+
* If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.
|
|
260
|
+
*/
|
|
261
|
+
validateIn?: boolean;
|
|
262
|
+
} : never): [url: string, options: RequestInit];
|
|
263
|
+
/** Parses a response against an endpoint’s response schema, considering common errors thrown from the API.
|
|
264
|
+
* @throws {JsonParsingError} - If the response is not valid JSON.
|
|
265
|
+
* @throws {SchemaValidationError} - If the response does not match the schema.
|
|
266
|
+
* @throws {ApiError} - If the API responded with an error message.
|
|
267
|
+
*/
|
|
268
|
+
parseResponse<T extends RpcEndpoint>(endpoint: T, options: {
|
|
269
|
+
response: Response;
|
|
270
|
+
/**
|
|
271
|
+
* Whether to validate the response against the schema.
|
|
272
|
+
* This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.
|
|
273
|
+
* ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.
|
|
274
|
+
*/
|
|
275
|
+
validateOut?: boolean;
|
|
276
|
+
}): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>>;
|
|
243
277
|
/** Fetches, parses and validates an API endpoint.
|
|
244
278
|
* Logs errors and throws them again so that the caller can handle them.
|
|
245
279
|
*
|
|
@@ -256,14 +290,25 @@ declare class InploiRpcClient {
|
|
|
256
290
|
params: TPathParams;
|
|
257
291
|
}> & {
|
|
258
292
|
signal?: AbortSignal;
|
|
259
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Whether to validate the inputs against the schema.
|
|
295
|
+
* If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.
|
|
296
|
+
*/
|
|
297
|
+
validateIn?: boolean;
|
|
298
|
+
/**
|
|
299
|
+
* Whether to validate the response against the schema.
|
|
300
|
+
* This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.
|
|
301
|
+
* ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.
|
|
302
|
+
*/
|
|
303
|
+
validateOut?: boolean;
|
|
304
|
+
} : never): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>>;
|
|
260
305
|
}
|
|
261
306
|
type GetSchemaValues<T extends {
|
|
262
307
|
searchParams: any;
|
|
263
308
|
body: any;
|
|
264
309
|
params?: any;
|
|
265
310
|
}> = {
|
|
266
|
-
[K in keyof T as T[K] extends never ? never : T[K] extends Record<string, never> ? never : K]: T[K] extends never ? never : T[K]
|
|
311
|
+
[K in keyof T as T[K] extends never ? never : T[K] extends Record<string, never> ? never : K]: T[K] extends never ? never : LooseAutocomplete<T[K], NonReducibleUnknown>;
|
|
267
312
|
};
|
|
268
313
|
/**
|
|
269
314
|
* Typed but *not runtime validated* schema
|
|
@@ -292,6 +337,18 @@ declare function endpoint<TMethod extends RequestMethod, TPathname extends strin
|
|
|
292
337
|
response: TResponse;
|
|
293
338
|
};
|
|
294
339
|
}): RpcEndpoint<TMethod, TPathname, ExtractPathParams<TPathname>, StandardSchemaV1.InferInput<TSearch>, StandardSchemaV1.InferInput<TBody>, StandardSchemaV1.InferOutput<TResponse>>;
|
|
340
|
+
/** Validates the inputs for an endpoint ahead of time
|
|
341
|
+
* Useful when you need to validate and throw earlier, or use the inputs for something other than the API call.
|
|
342
|
+
*/
|
|
343
|
+
declare function validateEndpointInputs<T extends RpcEndpoint>(endpoint: T, options: GetSchemaValues<{
|
|
344
|
+
body: unknown;
|
|
345
|
+
searchParams: unknown;
|
|
346
|
+
}>): T extends RpcEndpoint<infer _ extends RequestMethod, infer __ extends string, infer ___, infer TSearch, infer TBody, any> ? GetSchemaValues<{
|
|
347
|
+
body: TBody;
|
|
348
|
+
searchParams: TSearch;
|
|
349
|
+
}> & {
|
|
350
|
+
validateIn: false;
|
|
351
|
+
} : never;
|
|
295
352
|
|
|
296
353
|
type PluginParams = {
|
|
297
354
|
apiClient: ApiClient;
|
|
@@ -317,12 +374,14 @@ type InitialiseInploiSdkParams = {
|
|
|
317
374
|
* @default inploiBrandedLogger
|
|
318
375
|
* */
|
|
319
376
|
logger?: Logger | false;
|
|
377
|
+
/** When provided, this callback will be called with every event that is logged to the analytics service. */
|
|
378
|
+
onEvent?: AnalyticsOnEventCallback;
|
|
320
379
|
};
|
|
321
|
-
declare function initialiseSdk({ publishableKey, env, logger }: InitialiseInploiSdkParams): {
|
|
380
|
+
declare function initialiseSdk({ publishableKey, env, logger, onEvent, }: InitialiseInploiSdkParams): {
|
|
322
381
|
register: <P extends InploiSdkPlugin>(plugin: P) => ReturnType<P>;
|
|
323
382
|
analytics: AnalyticsService;
|
|
324
383
|
apiClient: ApiClient;
|
|
325
384
|
};
|
|
326
385
|
type InploiSdk = ReturnType<typeof initialiseSdk>;
|
|
327
386
|
|
|
328
|
-
export { AnalyticsLogEvent, AnalyticsService, ApiClient, ApiError, InitialiseInploiSdkParams, InploiRpcClient, InploiSdk, InploiSdkEnvironment, InploiSdkPlugin, Logger, NotFoundError, JsonParsingError as ParsingError, PluginParams, RpcEndpoint, SchemaValidationError, SdkError, UnauthorisedError, createPlugin, endpoint, initialiseSdk, inploiBrandedLogger, isSdkError, noLogging, typed };
|
|
387
|
+
export { AnalyticsLogEvent, AnalyticsLogParams, AnalyticsOnEventCallback, AnalyticsService, ApiClient, ApiError, InitialiseInploiSdkParams, InploiRpcClient, InploiSdk, InploiSdkEnvironment, InploiSdkPlugin, Logger, NotFoundError, JsonParsingError as ParsingError, PluginParams, RpcEndpoint, SchemaValidationError, SdkError, UnauthorisedError, createPlugin, endpoint, initialiseSdk, inploiBrandedLogger, isSdkError, noLogging, typed, validateEndpointInputs };
|
package/dist/index.d.ts
CHANGED
|
@@ -172,22 +172,27 @@ declare const getSessionInfo: (request?: Request) => {
|
|
|
172
172
|
anonymous_id: string | null;
|
|
173
173
|
session_id: string | null;
|
|
174
174
|
};
|
|
175
|
+
type AnalyticsOnEventCallback = (event: AnalyticsLogParams) => void;
|
|
175
176
|
|
|
176
|
-
declare class
|
|
177
|
-
|
|
177
|
+
declare class ErrorWithStatus extends Error {
|
|
178
|
+
status?: number;
|
|
179
|
+
constructor(message?: string, status?: number);
|
|
178
180
|
}
|
|
179
|
-
declare class
|
|
181
|
+
declare class NotFoundError extends ErrorWithStatus {
|
|
180
182
|
constructor(message?: string);
|
|
181
183
|
}
|
|
182
|
-
declare class
|
|
184
|
+
declare class UnauthorisedError extends ErrorWithStatus {
|
|
185
|
+
constructor(message?: string, status?: number);
|
|
186
|
+
}
|
|
187
|
+
declare class SchemaValidationError extends ErrorWithStatus {
|
|
183
188
|
issues: readonly StandardSchemaV1.Issue[];
|
|
184
|
-
|
|
189
|
+
source?: "searchParams" | "body" | "response" | undefined;
|
|
190
|
+
constructor(issues: readonly StandardSchemaV1.Issue[], source?: "searchParams" | "body" | "response" | undefined);
|
|
185
191
|
}
|
|
186
|
-
declare class ApiError extends
|
|
187
|
-
|
|
188
|
-
constructor(message: string, errors: unknown[]);
|
|
192
|
+
declare class ApiError extends ErrorWithStatus {
|
|
193
|
+
constructor(message: string, status?: number);
|
|
189
194
|
}
|
|
190
|
-
declare class JsonParsingError extends
|
|
195
|
+
declare class JsonParsingError extends ErrorWithStatus {
|
|
191
196
|
response?: Response | undefined;
|
|
192
197
|
constructor(response?: Response | undefined);
|
|
193
198
|
}
|
|
@@ -234,12 +239,41 @@ interface InploiRpcClientParams {
|
|
|
234
239
|
key: string;
|
|
235
240
|
};
|
|
236
241
|
}
|
|
242
|
+
type NonReducibleUnknown = {} | null | undefined;
|
|
243
|
+
type LooseAutocomplete<T extends BaseType, BaseType> = T | BaseType;
|
|
237
244
|
/** RPC client for making API calls to the Inploi API. */
|
|
238
245
|
declare class InploiRpcClient {
|
|
239
246
|
private baseUrl;
|
|
240
247
|
private headers;
|
|
241
248
|
private logger;
|
|
242
249
|
constructor(params: InploiRpcClientParams);
|
|
250
|
+
/** Gets params for a fetch request to the given endpoint */
|
|
251
|
+
getFetchParams<T extends RpcEndpoint>(endpoint: T, options: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ? GetSchemaValues<{
|
|
252
|
+
body: TBody;
|
|
253
|
+
searchParams: TSearch;
|
|
254
|
+
params: TPathParams;
|
|
255
|
+
}> & {
|
|
256
|
+
signal?: AbortSignal;
|
|
257
|
+
/**
|
|
258
|
+
* Whether to validate the inputs against the schema.
|
|
259
|
+
* If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.
|
|
260
|
+
*/
|
|
261
|
+
validateIn?: boolean;
|
|
262
|
+
} : never): [url: string, options: RequestInit];
|
|
263
|
+
/** Parses a response against an endpoint’s response schema, considering common errors thrown from the API.
|
|
264
|
+
* @throws {JsonParsingError} - If the response is not valid JSON.
|
|
265
|
+
* @throws {SchemaValidationError} - If the response does not match the schema.
|
|
266
|
+
* @throws {ApiError} - If the API responded with an error message.
|
|
267
|
+
*/
|
|
268
|
+
parseResponse<T extends RpcEndpoint>(endpoint: T, options: {
|
|
269
|
+
response: Response;
|
|
270
|
+
/**
|
|
271
|
+
* Whether to validate the response against the schema.
|
|
272
|
+
* This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.
|
|
273
|
+
* ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.
|
|
274
|
+
*/
|
|
275
|
+
validateOut?: boolean;
|
|
276
|
+
}): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>>;
|
|
243
277
|
/** Fetches, parses and validates an API endpoint.
|
|
244
278
|
* Logs errors and throws them again so that the caller can handle them.
|
|
245
279
|
*
|
|
@@ -256,14 +290,25 @@ declare class InploiRpcClient {
|
|
|
256
290
|
params: TPathParams;
|
|
257
291
|
}> & {
|
|
258
292
|
signal?: AbortSignal;
|
|
259
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Whether to validate the inputs against the schema.
|
|
295
|
+
* If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.
|
|
296
|
+
*/
|
|
297
|
+
validateIn?: boolean;
|
|
298
|
+
/**
|
|
299
|
+
* Whether to validate the response against the schema.
|
|
300
|
+
* This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.
|
|
301
|
+
* ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.
|
|
302
|
+
*/
|
|
303
|
+
validateOut?: boolean;
|
|
304
|
+
} : never): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>>;
|
|
260
305
|
}
|
|
261
306
|
type GetSchemaValues<T extends {
|
|
262
307
|
searchParams: any;
|
|
263
308
|
body: any;
|
|
264
309
|
params?: any;
|
|
265
310
|
}> = {
|
|
266
|
-
[K in keyof T as T[K] extends never ? never : T[K] extends Record<string, never> ? never : K]: T[K] extends never ? never : T[K]
|
|
311
|
+
[K in keyof T as T[K] extends never ? never : T[K] extends Record<string, never> ? never : K]: T[K] extends never ? never : LooseAutocomplete<T[K], NonReducibleUnknown>;
|
|
267
312
|
};
|
|
268
313
|
/**
|
|
269
314
|
* Typed but *not runtime validated* schema
|
|
@@ -292,6 +337,18 @@ declare function endpoint<TMethod extends RequestMethod, TPathname extends strin
|
|
|
292
337
|
response: TResponse;
|
|
293
338
|
};
|
|
294
339
|
}): RpcEndpoint<TMethod, TPathname, ExtractPathParams<TPathname>, StandardSchemaV1.InferInput<TSearch>, StandardSchemaV1.InferInput<TBody>, StandardSchemaV1.InferOutput<TResponse>>;
|
|
340
|
+
/** Validates the inputs for an endpoint ahead of time
|
|
341
|
+
* Useful when you need to validate and throw earlier, or use the inputs for something other than the API call.
|
|
342
|
+
*/
|
|
343
|
+
declare function validateEndpointInputs<T extends RpcEndpoint>(endpoint: T, options: GetSchemaValues<{
|
|
344
|
+
body: unknown;
|
|
345
|
+
searchParams: unknown;
|
|
346
|
+
}>): T extends RpcEndpoint<infer _ extends RequestMethod, infer __ extends string, infer ___, infer TSearch, infer TBody, any> ? GetSchemaValues<{
|
|
347
|
+
body: TBody;
|
|
348
|
+
searchParams: TSearch;
|
|
349
|
+
}> & {
|
|
350
|
+
validateIn: false;
|
|
351
|
+
} : never;
|
|
295
352
|
|
|
296
353
|
type PluginParams = {
|
|
297
354
|
apiClient: ApiClient;
|
|
@@ -317,12 +374,14 @@ type InitialiseInploiSdkParams = {
|
|
|
317
374
|
* @default inploiBrandedLogger
|
|
318
375
|
* */
|
|
319
376
|
logger?: Logger | false;
|
|
377
|
+
/** When provided, this callback will be called with every event that is logged to the analytics service. */
|
|
378
|
+
onEvent?: AnalyticsOnEventCallback;
|
|
320
379
|
};
|
|
321
|
-
declare function initialiseSdk({ publishableKey, env, logger }: InitialiseInploiSdkParams): {
|
|
380
|
+
declare function initialiseSdk({ publishableKey, env, logger, onEvent, }: InitialiseInploiSdkParams): {
|
|
322
381
|
register: <P extends InploiSdkPlugin>(plugin: P) => ReturnType<P>;
|
|
323
382
|
analytics: AnalyticsService;
|
|
324
383
|
apiClient: ApiClient;
|
|
325
384
|
};
|
|
326
385
|
type InploiSdk = ReturnType<typeof initialiseSdk>;
|
|
327
386
|
|
|
328
|
-
export { AnalyticsLogEvent, AnalyticsService, ApiClient, ApiError, InitialiseInploiSdkParams, InploiRpcClient, InploiSdk, InploiSdkEnvironment, InploiSdkPlugin, Logger, NotFoundError, JsonParsingError as ParsingError, PluginParams, RpcEndpoint, SchemaValidationError, SdkError, UnauthorisedError, createPlugin, endpoint, initialiseSdk, inploiBrandedLogger, isSdkError, noLogging, typed };
|
|
387
|
+
export { AnalyticsLogEvent, AnalyticsLogParams, AnalyticsOnEventCallback, AnalyticsService, ApiClient, ApiError, InitialiseInploiSdkParams, InploiRpcClient, InploiSdk, InploiSdkEnvironment, InploiSdkPlugin, Logger, NotFoundError, JsonParsingError as ParsingError, PluginParams, RpcEndpoint, SchemaValidationError, SdkError, UnauthorisedError, createPlugin, endpoint, initialiseSdk, inploiBrandedLogger, isSdkError, noLogging, typed, validateEndpointInputs };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var v=Object.defineProperty,W=Object.defineProperties,z=Object.getOwnPropertyDescriptor,X=Object.getOwnPropertyDescriptors,Z=Object.getOwnPropertyNames,V=Object.getOwnPropertySymbols;var F=Object.prototype.hasOwnProperty,Q=Object.prototype.propertyIsEnumerable;var M=(r,e,n)=>e in r?v(r,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):r[e]=n,_=(r,e)=>{for(var n in e||(e={}))F.call(e,n)&&M(r,n,e[n]);if(V)for(var n of V(e))Q.call(e,n)&&M(r,n,e[n]);return r},B=(r,e)=>W(r,X(e));var ee=(r,e)=>{for(var n in e)v(r,n,{get:e[n],enumerable:!0})},re=(r,e,n,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Z(e))!F.call(r,o)&&o!==n&&v(r,o,{get:()=>e[o],enumerable:!(t=z(e,o))||t.enumerable});return r};var ne=r=>re(v({},"__esModule",{value:!0}),r);var l=(r,e,n)=>new Promise((t,o)=>{var a=i=>{try{s(n.next(i))}catch(u){o(u)}},p=i=>{try{s(n.throw(i))}catch(u){o(u)}},s=i=>i.done?t(i.value):Promise.resolve(i.value).then(a,p);s((n=n.apply(r,e)).next())});var ge={};ee(ge,{ApiError:()=>h,InploiRpcClient:()=>T,NotFoundError:()=>f,ParsingError:()=>m,SchemaValidationError:()=>d,SdkError:()=>L,UnauthorisedError:()=>y,createPlugin:()=>q,endpoint:()=>O,initialiseSdk:()=>G,inploiBrandedLogger:()=>E,isSdkError:()=>U,noLogging:()=>I,typed:()=>S,validateEndpointInputs:()=>N});module.exports=ne(ge);var x="%c[inploi SDK]",b="color: #65BC67; font-weight: bold;",E={warn:(...r)=>console.warn(x,b,...r),error:(...r)=>console.error(x,b,...r),info:(...r)=>console.info(x,b,...r),log:(...r)=>console.log(x,b,...r)},I={info:()=>{},error:()=>{},log:()=>{},warn:()=>{}};var q=r=>r;function k(r,e){if(!r)throw new Error(e)}function R(r,e){return e in r}var be=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});var te="Unauthenticated",oe="This action is unauthorized.",g=class extends Error{constructor(n,t){super(n);this.status=t,this.name="ErrorWithStatus"}},f=class extends g{constructor(e){super(e!=null?e:"Not found"),this.name="NotFoundError",this.status=404}},y=class extends g{constructor(e,n){super(e!=null?e:"You are not authorised to perform this action."),this.name="UnauthorisedError",this.status=n!=null?n:401}},d=class extends g{constructor(n,t){let o=t?` in ${t}`:"";super(`Schema validation failed${o}`);this.issues=n;this.source=t;this.name="SchemaValidationError",this.status=400}},h=class extends g{constructor(e,n){super(e),this.name="ApiError",this.status=n!=null?n:500}},m=class extends g{constructor(n){super("Error parsing response into JSON.");this.response=n;this.name="ParsingError",this.status=500}};var se=["message","error","errors","exception","exceptions"];function ie(r){console.log("json",r);let e=[];if(typeof r=="object"&&r!==null){for(let n of se)if(R(r,n)){console.log("hasProp",n,r[n]);let t=r[n];typeof t=="string"&&e.push(t),Array.isArray(t)&&t.every(o=>typeof o=="string")&&e.push(...t)}}return e.length===0&&e.push("Unknown error"),e.join(", ")}function A(r,e){if(e>=300&&e<=500){let n=ie(r);throw e===404?new f(n):n===te?new y("You are not authenticated.",e):n===oe?new y(n,e):new h(n,e)}}var j=r=>{let e={Accept:"application/json","Content-Type":"application/json","x-publishable-key":r.publishableKey};return{fetch:(o,...a)=>l(void 0,[o,...a],function*(n,t={}){let p=B(_({},t),{headers:_(_({},t.headers),e)}),s=yield fetch(`${r.baseUrl}${n}`,p);if(s.status===404)throw new f;let i=yield s.json().catch(()=>l(void 0,null,function*(){throw new m(s)}));return A(i,s.status),i})}},L={NotFound:f,Unauthorised:y,SchemaValidation:d,Api:h,JsonParsing:m};function U(r){return Object.values(L).some(e=>r instanceof e)}var K="1.15.3";var w={sandbox:"https://api.staging.inploi.com",production:"https://api.inploi.com",_internal_local:"http://api.test"},$=K;var P="isdk_session";var D=r=>{let e=new Date;return e.setTime(e.getTime()+7*24*60*60*1e3),`${P}=${r};expires=${e.toUTCString()};path=/`},pe=(r,e)=>{let n=r.get("session_id");if(e||n)return n;let t=sessionStorage.getItem(`${P}-session_id`);return typeof t=="string"?t:null},ce=new RegExp(`${P}=([^;]+)`),H=r=>{let e=r?r.url:location.href,{searchParams:n}=new URL(e),t=n.get("anonymous_id"),o=pe(n,typeof window=="undefined");if(t)return{anonymous_id:t,session_id:o};let a=r?r.headers.get("cookie"):document.cookie;if(a){let p=ce.exec(a),s=p==null?void 0:p[1];return{anonymous_id:s!=null?s:null,session_id:o}}return{anonymous_id:t,session_id:o}},de=r=>typeof r!="object"||r===null?null:{anonymous_id:"anonymous_id"in r&&typeof r.anonymous_id=="string"?r.anonymous_id:null,session_id:"session_id"in r&&typeof r.session_id=="string"?r.session_id:null},ue=r=>r==="about:client"?"":r,le={pathname:"/log",method:"POST",schema:{response:S(),body:S()}},J=({rpcClient:r,logger:e,onEvent:n})=>({log:o=>l(void 0,null,function*(){k(o.request||typeof window!="undefined","Cannot log on the server without a request. Please pass a request to `log`.");let a="request"in o&&o.request?{href:o.request.url,referrer:ue(o.request.referrer),title:""}:{href:location.href,referrer:document.referrer,title:document.title};try{let p={library:{name:"inploi-sdk",version:$},page:a},s=H(o.request),i={anonymous_id:s.anonymous_id,session_id:s.session_id,event:o.event,sent_at:new Date().toISOString(),context:p,properties:o.properties,custom_properties:o.customProperties},u=yield r.request(le,{body:i}),c=de(u);return c!=null&&c.anonymous_id&&(i.anonymous_id=c.anonymous_id),c!=null&&c.session_id&&(i.session_id=c.session_id),typeof window!="undefined"&&i.anonymous_id&&(i.session_id&&sessionStorage.setItem(`${P}-session_id`,i.session_id.toString()),document.cookie=D(i.anonymous_id)),n==null||n(i),{success:!0,data:i}}catch(p){return e.error("Failed to send log to API. Inspect error response of `log` for more information."),{success:!1,error:p}}}),getHeaders:o=>{let a=new Headers;return o!=null&&o.anonymous_id&&a.append("Set-Cookie",D(o.anonymous_id)),a},getSessionInfo:H});var Y=require("neoqs");function C(r,e,n){let t=r["~standard"].validate(e);if(t instanceof Promise)throw new TypeError("Async schema");if(t.issues)throw new d(t.issues,n);return t.value}function me(r,e,n){try{return{success:!0,output:C(r,e,n)}}catch(t){if(t instanceof d)return{success:!1,issues:t.issues,source:t.source};throw t}}var T=class{constructor(e){if(this.baseUrl=w[e.environment],this.headers=new Headers({"Content-Type":"application/json",Accept:"application/json"}),e.apiKey.type==="secret"){if(typeof window!="undefined")throw new Error("Secret key cannot be used in a browser environment");this.headers.set("x-secret-key",e.apiKey.key)}else this.headers.set("x-publishable-key",e.apiKey.key);this.logger=e.logger}getFetchParams(e,n){var i;let t=(i=n.validateIn)!=null?i:!0,{searchParams:o,body:a}=t?N(e,n):n,p=new URL(this.baseUrl),s=e.pathname;if("params"in n&&n.params)for(let[u,c]of Object.entries(n.params))s=s.replace(`:${u}`,String(c));return p.pathname=s,e.schema.searchParams&&(p.search=(0,Y.stringify)(o)),[p.toString(),{method:e.method,body:a?JSON.stringify(a):void 0,headers:this.headers,signal:n.signal}]}parseResponse(e,n){return l(this,null,function*(){var p;let t=yield n.response.json().catch(s=>{throw this.logger.error(s),new m(n.response)});if(!((p=n.validateOut)!=null?p:!0))return t;let a=me(e.schema.response,t,"response");if(!a.success)throw A(t,n.response.status),new d(a.issues,a.source);return a.output})}request(e,n){return l(this,null,function*(){try{let t=this.getFetchParams(e,n),o=yield fetch(...t);return this.parseResponse(e,{response:o,validateOut:n.validateOut})}catch(t){throw t instanceof d?this.logger.error(t.message,t.issues):this.logger.error(t),t}})}};function S(){return{"~standard":{vendor:"inploi",version:1,validate:r=>({value:r})}}}function O(r){return r}function N(r,e){let n={searchParams:void 0,body:void 0,validateIn:!1};return r.schema.searchParams&&(n.searchParams=C(r.schema.searchParams,"searchParams"in e?e.searchParams:{})),r.schema.body&&(n.body=C(r.schema.body,"body"in e?e.body:{})),n}function G({publishableKey:r,env:e,logger:n=E,onEvent:t}){let o=j({baseUrl:w[e],publishableKey:r}),a=n===!1?I:n,p=new T({environment:e,apiKey:{type:"publishable",key:r},logger:a}),s=J({rpcClient:p,logger:a,onEvent:t});return{register:u=>u({logger:a,apiClient:o,analytics:s,rpcClient:p}),analytics:s,apiClient:o}}0&&(module.exports={ApiError,InploiRpcClient,NotFoundError,ParsingError,SchemaValidationError,SdkError,UnauthorisedError,createPlugin,endpoint,initialiseSdk,inploiBrandedLogger,isSdkError,noLogging,typed,validateEndpointInputs});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/sdk.logger.ts","../src/sdk.plugins.ts","../src/sdk.api.ts","../../core/src/common/common.utils.ts","../../core/src/common/common.currency.ts","../../core/src/common/common.datetime.ts","../package.json","../src/sdk.constants.ts","../src/sdk.analytics.ts","../src/sdk.rpc.ts","../src/sdk.ts"],"sourcesContent":["export { inploiBrandedLogger, noLogging } from './sdk.logger';\nexport type { Logger } from './sdk.logger';\n\nexport type { PluginParams, InploiSdkPlugin } from './sdk.plugins';\nexport { createPlugin } from './sdk.plugins';\n\nexport type { InploiSdkEnvironment } from './sdk.constants';\n\nexport type { ApiClient } from './sdk.api';\nexport {\n\tApiError,\n\tNotFoundError,\n\tJsonParsingError as ParsingError,\n\tUnauthorisedError,\n\tisSdkError,\n\tSchemaValidationError,\n\tSdkError,\n} from './sdk.api';\n\nexport { initialiseSdk } from './sdk';\nexport type { InitialiseInploiSdkParams, InploiSdk } from './sdk';\n\nexport type { AnalyticsService, AnalyticsLogEvent } from './sdk.analytics';\n\nexport { InploiRpcClient, endpoint, typed } from './sdk.rpc';\nexport type { RpcEndpoint } from './sdk.rpc';\n","export const CONSOLE_PREFIX = '%c[inploi SDK]';\nexport const CONSOLE_STYLE = 'color: #65BC67; font-weight: bold;';\n\ntype LogMessage = (...data: any[]) => void;\nexport type Logger = {\n\twarn: LogMessage;\n\terror: LogMessage;\n\tinfo: LogMessage;\n\tlog: LogMessage;\n};\n\nexport const inploiBrandedLogger: Logger = {\n\twarn: (...args) => console.warn(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\terror: (...args) => console.error(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tinfo: (...args) => console.info(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tlog: (...args) => console.log(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n};\n\nexport const noLogging: Logger = { info: () => void 0, error: () => void 0, log: () => void 0, warn: () => void 0 };\n","import { AnalyticsService } from './sdk.analytics';\nimport { ApiClient } from './sdk.api';\nimport { Logger } from './sdk.logger';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type PluginParams = {\n\tapiClient: ApiClient;\n\tlogger: Logger;\n};\n\nexport type Plugin<T extends string, P extends Record<string, unknown>> = {\n\tpluginName: T;\n\tpure_createActions: (params: PluginParams) => P;\n};\n\ntype PluginDependencies = {\n\tapiClient: ApiClient;\n\trpcClient: InploiRpcClient;\n\tlogger: Logger;\n\tanalytics: AnalyticsService;\n};\n\nexport type InploiSdkPlugin = (dependencies: PluginDependencies) => any;\n\nexport const createPlugin = <T extends InploiSdkPlugin>(pluginFn: T) => pluginFn;\n","import { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport const unauthenticatedMessage = 'Unauthenticated';\nexport const unauthorisedMessage = 'This action is unauthorized.';\n\nexport class NotFoundError extends Error {\n\tconstructor() {\n\t\tsuper('Not found');\n\t\tthis.name = 'NotFoundError';\n\t}\n}\n\nexport class UnauthorisedError extends Error {\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'You are not authorised to perform this action.');\n\t\tthis.name = 'UnauthorisedError';\n\t}\n}\n\nexport class SchemaValidationError extends Error {\n\tconstructor(public issues: readonly StandardSchemaV1.Issue[]) {\n\t\tsuper('Schema validation failed');\n\t\tthis.name = 'SchemaValidationError';\n\t}\n}\n\nexport class ApiError extends Error {\n\terrors: unknown[];\n\tconstructor(message: string, errors: unknown[]) {\n\t\tsuper(message);\n\t\tthis.name = 'ApiError';\n\t\tthis.errors = errors;\n\t}\n}\n\nexport class JsonParsingError extends Error {\n\tconstructor(public response?: Response) {\n\t\tsuper('Error parsing response into JSON.');\n\t\tthis.name = 'ParsingError';\n\t}\n}\n\n/** @deprecated - use `JsonParsingError` instead */\nexport class ParsingError extends JsonParsingError {}\n\nexport type ApiClient = {\n\tfetch: (pathname: string, options?: RequestInit) => Promise<unknown>;\n};\n\n/** Throws branded errors when API returns a known error. */\nexport function handleApiExceptions(json: unknown) {\n\tif (json === null) return;\n\n\tif (typeof json === 'object') {\n\t\tlet message = 'Generic API Error';\n\t\tif ('message' in json && typeof json.message === 'string') message = json.message;\n\n\t\tif (message === unauthenticatedMessage) {\n\t\t\tthrow new UnauthorisedError('You are not authenticated.');\n\t\t}\n\t\tif (message === unauthorisedMessage) {\n\t\t\tthrow new UnauthorisedError();\n\t\t}\n\t\tif ('exception' in json) {\n\t\t\tthrow new ApiError(message, [json.exception]);\n\t\t}\n\t\tif ('errors' in json) {\n\t\t\tif (Array.isArray(json.errors) && json.errors.every(error => typeof error === 'string')) {\n\t\t\t\tthrow new ApiError(message, json.errors);\n\t\t\t}\n\t\t\tif (typeof json.errors === 'object' && json.errors !== null) {\n\t\t\t\tconst entries = Object.entries(json.errors);\n\n\t\t\t\tif (entries.every(([, value]) => Array.isArray(value) && value.every(error => typeof error === 'string'))) {\n\t\t\t\t\tthrow new SchemaValidationError(\n\t\t\t\t\t\tentries.map(\n\t\t\t\t\t\t\t([key, value]): StandardSchemaV1.Issue => ({\n\t\t\t\t\t\t\t\tpath: key.split('.'),\n\t\t\t\t\t\t\t\tmessage: value.join(', '),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new ApiError(\n\t\t\t\t\tmessage,\n\t\t\t\t\tentries.map(([key, value]) => `${key}: ${value}`),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (typeof json.errors === 'string') throw new ApiError(message, [json.errors]);\n\t\t}\n\t\tif ('error' in json && typeof json.error === 'string') {\n\t\t\tthrow new ApiError(json.error, [json.error]);\n\t\t}\n\t}\n}\n\nexport const createApiClient = (params: { baseUrl: string; publishableKey: string }): ApiClient => {\n\tconst defaultHeaders: HeadersInit = {\n\t\tAccept: 'application/json',\n\t\t'Content-Type': 'application/json',\n\t\t'x-publishable-key': params.publishableKey,\n\t};\n\n\treturn {\n\t\t/** Fetches from a pathname with a pre-established base path.\n\t\t * Parses received output as JSON, and throw if one of the common error messages is received.\n\t\t */\n\t\tfetch: async (pathname, options = {}) => {\n\t\t\tconst init = { ...options, headers: { ...options.headers, ...defaultHeaders } };\n\t\t\tconst response = await fetch(`${params.baseUrl}${pathname}`, init);\n\t\t\tif (response.status === 404) throw new NotFoundError();\n\n\t\t\tconst json = await response.json().catch(async () => {\n\t\t\t\tthrow new JsonParsingError(response);\n\t\t\t});\n\n\t\t\thandleApiExceptions(json);\n\n\t\t\t// We’re assuming no other exceptions have happened.\n\t\t\treturn json;\n\t\t},\n\t};\n};\n\nexport const SdkError = {\n\tNotFound: NotFoundError,\n\tUnauthorised: UnauthorisedError,\n\tSchemaValidation: SchemaValidationError,\n\tApi: ApiError,\n\tJsonParsing: JsonParsingError,\n};\n\nexport function isSdkError(error: unknown): error is (typeof SdkError)[keyof typeof SdkError] {\n\treturn Object.values(SdkError).some(ErrorClass => error instanceof ErrorClass);\n}\n","export const exhaustive = (value: never) => {\n\tthrow new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);\n};\n\nexport function invariant(condition: any, message?: string): asserts condition {\n\tif (condition) {\n\t\treturn;\n\t}\n\n\tthrow new Error(message);\n}\n\nexport const uniqueOrThrow = <T>(array: T[]) => {\n\tconst uniqueValues = new Set(array);\n\n\tif (array.length !== uniqueValues.size) {\n\t\tthrow new Error('Duplicate values found');\n\t}\n\treturn true;\n};\n\nexport const uniqueByPropertyOrThrow =\n\t<T extends PropertyKey>(propertyKey: T) =>\n\t(array: { [K in T]: any }[]) => {\n\t\tconst values = array.map(item => item[propertyKey]);\n\t\tconst uniqueValues = new Set(values);\n\n\t\tif (values.length !== uniqueValues.size) {\n\t\t\tthrow new Error(`Duplicate values found for property: ${propertyKey.toString()}`);\n\t\t}\n\t\treturn true;\n\t};\n\n/**\n * A destructive way to ensure an object has a property.\n * This is useful when working with unknowns.\n */\nexport function hasProp<K extends PropertyKey>(data: object, prop: K): data is Record<K, unknown> {\n\treturn prop in data;\n}\n\n/**\n * A sort of type-safe way to check whether a key exists in an object.\n */\nexport function isKeyInObj<O extends Record<string, unknown>>(key: PropertyKey, obj: O): key is keyof O {\n\treturn key in obj;\n}\n","type TFunction = (key: 'competitive' | 'invalid_salary' | 'from' | 'up_to') => string;\n\ninterface SalaryParams {\n\tpay: string | null;\n\tpay_min: string | null;\n\tpay_mask: boolean;\n\tpay_max: string | null;\n\tpay_type: 'ANNUALLY' | 'HOURLY' | 'MONTHLY' | 'WEEKLY' | 'DAILY' | null;\n\tpay_currency: string;\n\tpay_display: boolean;\n}\n\nconst payPeriods: Record<NonNullable<SalaryParams['pay_type']>, string> = {\n\tANNUALLY: 'per year',\n\tDAILY: 'per day',\n\tHOURLY: 'per hour',\n\tMONTHLY: 'per month',\n\tWEEKLY: 'per week',\n};\n\nexport const getSalaryAsText = (params: {\n\tsalary: SalaryParams;\n\tconfig: { locales: string | string[] | undefined };\n\tt?: TFunction;\n}) => {\n\tconst { salary, config, t = s => s } = params;\n\tconst numberFormatter = new Intl.NumberFormat(config.locales, {\n\t\tstyle: 'currency',\n\t\tcurrency: salary.pay_currency,\n\t\t// @ts-expect-error - CI/CD is not happy with this, though locally it works\n\t\ttrailingZeroDisplay: 'stripIfInteger',\n\t});\n\tif (salary.pay_display === false) return undefined;\n\tif (salary.pay_mask) return t('competitive');\n\n\tif (salary.pay_max && Number.isNaN(+salary.pay_max)) return t('invalid_salary');\n\tif (salary.pay_min && Number.isNaN(+salary.pay_min)) return t('invalid_salary');\n\tif (salary.pay && Number.isNaN(+salary.pay)) return t('invalid_salary');\n\n\tconst period = salary.pay_type && salary.pay_type in payPeriods ? payPeriods[salary.pay_type] : undefined;\n\n\tif (salary.pay) return [numberFormatter.format(+salary.pay), period].filter(Boolean).join(' ');\n\n\tif (salary.pay_max && salary.pay_min)\n\t\treturn [numberFormatter.formatRange(+salary.pay_min, +salary.pay_max), period].filter(Boolean).join(' ') || '';\n\n\tif (salary.pay_max)\n\t\treturn `${t('up_to')} ${[numberFormatter.format(+salary.pay_max), period].filter(Boolean).join(' ')}`;\n\tif (salary.pay_min)\n\t\treturn `${t('from')} ${[numberFormatter.format(+salary.pay_min), period].filter(Boolean).join(' ')}`;\n\treturn t('invalid_salary');\n};\n","type TFunction = (key: 'today' | 'over_30_days_ago' | 'in_over_30_days') => string;\n\ntype Params = {\n\tfrom?: Date;\n\tto: string | number | Date;\n\tformatter?: Intl.RelativeTimeFormat;\n\tt?: TFunction;\n};\n\nconst DEFAULT_FORMATTER = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });\n/** From a date, calculates the relative time difference from now */\nexport const getRelativeTimeDifference = ({\n\tfrom = new Date(),\n\tto,\n\tformatter = DEFAULT_FORMATTER,\n\tt = s => s,\n}: Params) => {\n\tconst then = to instanceof Date ? to : new Date(to);\n\tconst diff = then.getTime() - from.getTime();\n\n\tconst diffIn = {\n\t\tdays: Math.round(diff / 1000 / 60 / 60 / 24),\n\t\tmonths: Math.round(diff / 1000 / 60 / 60 / 24 / 30),\n\t};\n\n\tif (diffIn.days === 0) return t('today');\n\tif (Math.abs(diffIn.days) < 30) return formatter.format(diffIn.days, 'days');\n\tif (Math.abs(diffIn.days) < 3) return formatter.format(diffIn.months, 'months');\n\treturn diffIn.months < 0 ? t('over_30_days_ago') : t('in_over_30_days');\n};\n","{\n\t\"name\": \"@inploi/sdk\",\n\t\"version\": \"1.15.2\",\n\t\"main\": \"dist/index.js\",\n\t\"types\": \"dist/index.d.ts\",\n\t\"license\": \"MIT\",\n\t\"files\": [\n\t\t\"/dist\",\n\t\t\"/cdn\"\n\t],\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"require\": \"./dist/index.js\",\n\t\t\t\"import\": \"./dist/index.mjs\",\n\t\t\t\"types\": \"./dist/index.d.ts\"\n\t\t}\n\t},\n\t\"scripts\": {\n\t\t\"build:npm\": \"tsup --dts --dts-resolve\",\n\t\t\"build:cdn\": \"tsup --config tsup.cdn.config.ts\",\n\t\t\"build\": \"concurrently 'pnpm run build:npm' 'pnpm run build:cdn'\",\n\t\t\"dev\": \"tsup --watch --config tsup.cdn.config.ts\",\n\t\t\"check\": \"eslint src --fix --max-warnings 0 && tsc\",\n\t\t\"test\": \"bun test\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@happy-dom/global-registrator\": \"^13.6.2\",\n\t\t\"@inploi/core\": \"workspace:*\",\n\t\t\"@total-typescript/ts-reset\": \"^0.5.1\",\n\t\t\"@types/bun\": \"^1.2.5\",\n\t\t\"@types/react\": \"^18.2.33\",\n\t\t\"@types/react-dom\": \"^18.2.14\",\n\t\t\"autoprefixer\": \"^10.4.16\",\n\t\t\"concurrently\": \"9.1.2\",\n\t\t\"eslint\": \"^7.32.0\",\n\t\t\"eslint-config-custom\": \"workspace:*\",\n\t\t\"happy-dom\": \"^12.6.0\",\n\t\t\"ts-toolbelt\": \"^9.6.0\",\n\t\t\"tsconfig\": \"workspace:*\",\n\t\t\"tsup\": \"^7.2.0\"\n\t},\n\t\"dependencies\": {\n\t\t\"@standard-schema/spec\": \"^1.0.0\",\n\t\t\"neoqs\": \"^6.13.0\"\n\t}\n}\n","import { version } from '../package.json';\n\n/**\n * The environment the SDK should run in.\n * - `production`: data will be stored and displayed on dashboards\n * - `sandbox`: data will be stored temporarily and purged periodically\n */\nexport type InploiSdkEnvironment = 'production' | 'sandbox';\n\nexport const ENV_TO_API_URL: Record<InploiSdkEnvironment, string> = {\n\tsandbox: 'https://api.staging.inploi.com',\n\tproduction: 'https://api.inploi.com',\n\t// @ts-expect-error - local test environment\n\t_internal_local: 'http://api.test',\n};\n\nexport const ANALYTICS_VERSION = version;\n\nexport const LOG_PATHNAME = '/log';\n\nexport const ANALYTICS_COOKIE_NAME = 'isdk_session';\n","import type { ResponseObj } from '@inploi/core/common';\nimport { invariant } from '@inploi/core/common';\n\nimport { InploiRpcClient, Logger, endpoint, typed } from '.';\nimport { ANALYTICS_COOKIE_NAME, ANALYTICS_VERSION } from './sdk.constants';\n\nconst formatCookie = (value: string) => {\n\tconst now = new Date();\n\tnow.setTime(now.getTime() + 7 * 24 * 60 * 60 * 1000); // 7 days expiration\n\n\treturn `${ANALYTICS_COOKIE_NAME}=${value};expires=${now.toUTCString()};path=/`;\n};\n\ntype FlowProperties = { flow_id: string; flow_version: number; flow_session_id: string; flow_build: number };\n\ntype JobProperties = {\n\tid: string;\n\tid_type: 'internal' | 'external';\n};\n\ntype AnalyticsLogParams =\n\t| {\n\t\t\tevent: 'VIEW_JOB';\n\t\t\tproperties: { job: JobProperties };\n\t }\n\t| {\n\t\t\tevent: 'FLOW_REDIRECT';\n\t\t\tproperties: { href: string; job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_START' | 'FLOW_END';\n\t\t\tproperties: { job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_NODE';\n\t\t\tproperties: {\n\t\t\t\t/** Increments by 1 per node interpreted */\n\t\t\t\tsequence: number;\n\t\t\t\tfrom_node_id: string;\n\t\t\t\tto_node_id: string;\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_SUBMIT';\n\t\t\tproperties: {\n\t\t\t\tservice: string;\n\t\t\t\tresponse: {\n\t\t\t\t\tstatus: number;\n\t\t\t\t\tpayload: unknown;\n\t\t\t\t};\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'SUBMIT_FORM' | 'VIEW_PAGE';\n\t\t\tproperties?: {\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'IDENTIFY';\n\t\t\tproperties: {\n\t\t\t\tidentifier: string;\n\t\t\t\tfirst_name?: string;\n\t\t\t\tlast_name?: string;\n\t\t\t\tphone_number?: string;\n\t\t\t\temail?: string;\n\t\t\t\tcustom_traits?: Record<string, unknown>;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_PAGINATE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_SETTLE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_JOB_CLICK';\n\t\t\tproperties: {\n\t\t\t\tjob_id: number;\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'VIEW_SEARCH';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'FEEDBACK';\n\t\t\tproperties: {\n\t\t\t\tkey: string;\n\t\t\t\tscore?: -1 | 0 | 1;\n\t\t\t\tcomment?: string;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'LINK_CLICK';\n\t\t\tproperties: {\n\t\t\t\ttarget_href: string;\n\t\t\t\tjob_id: string | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'INTERACTION';\n\t\t\tproperties: {\n\t\t\t\ttag: string;\n\t\t\t};\n\t };\n\nexport type AnalyticsLogEvent = AnalyticsLogParams['event'];\n\ntype EventPropertyMap = {\n\t[Param in AnalyticsLogParams as Param['event']]: Omit<Param, 'event'>;\n};\n\ntype AnalyticsContext = {\n\tlibrary: {\n\t\tname: 'inploi-sdk';\n\t\tversion: string;\n\t};\n\tpage: {\n\t\thref: string;\n\t\treferrer: string;\n\t\ttitle: string;\n\t};\n};\n\ntype TrackPayload<P = EventPropertyMap[keyof EventPropertyMap]['properties']> = {\n\tanonymous_id: string | null;\n\tsession_id: string | null;\n\tevent: AnalyticsLogEvent;\n\tsent_at: string;\n\tcontext: AnalyticsContext;\n\tproperties: P;\n\tcustom_properties?: Record<string, unknown>;\n};\n\ntype LogFnParams<T extends keyof EventPropertyMap> = {\n\tevent: T;\n\tcustomProperties?: Record<string, unknown>;\n\t/** Passing a request will make logging possible on a server environment. */\n\trequest?: Request;\n} & EventPropertyMap[T];\n\ntype LogFn = <TEvent extends keyof EventPropertyMap>(\n\tparams: LogFnParams<TEvent>,\n) => Promise<ResponseObj<TrackPayload<EventPropertyMap[TEvent]['properties']>>>;\n\nexport type AnalyticsService = {\n\tlog: LogFn;\n\t/** From a log payload data, generate headers to use in server environments to update the anonymous_id */\n\tgetHeaders: (payload?: TrackPayload) => Headers;\n\tgetSessionInfo: typeof getSessionInfo;\n};\n\nconst getSessionId = (searchParams: URLSearchParams, isServer: boolean) => {\n\tconst fromSearchParams = searchParams.get('session_id');\n\tif (isServer) return fromSearchParams;\n\tif (fromSearchParams) return fromSearchParams;\n\tconst fromSessionStorage = sessionStorage.getItem(`${ANALYTICS_COOKIE_NAME}-session_id`);\n\tif (typeof fromSessionStorage === 'string') return fromSessionStorage;\n\treturn null;\n};\n\nconst cookieRegex = new RegExp(`${ANALYTICS_COOKIE_NAME}=([^;]+)`);\nconst getSessionInfo = (request?: Request) => {\n\tconst href = request ? request.url : location.href;\n\tconst { searchParams } = new URL(href);\n\tconst anonymous_id = searchParams.get('anonymous_id');\n\tconst session_id = getSessionId(searchParams, typeof window === 'undefined');\n\n\t// If there’s an anonymous_id in the search params, use it\n\tif (anonymous_id)\n\t\treturn {\n\t\t\tanonymous_id,\n\t\t\tsession_id,\n\t\t};\n\n\t// If there’s a cookie, use it\n\tconst cookie = request ? request.headers.get('cookie') : document.cookie;\n\tif (cookie) {\n\t\tconst match = cookieRegex.exec(cookie);\n\t\tconst anonymous_id = match?.[1];\n\t\treturn {\n\t\t\tanonymous_id: anonymous_id ?? null,\n\t\t\tsession_id,\n\t\t};\n\t}\n\n\t// Otherwise, return what we have\n\treturn {\n\t\tanonymous_id,\n\t\tsession_id,\n\t};\n};\n\nconst getSessionInfoFromResponse = (response: unknown) => {\n\tif (typeof response !== 'object' || response === null) return null;\n\treturn {\n\t\tanonymous_id:\n\t\t\t'anonymous_id' in response && typeof response.anonymous_id === 'string' ? response.anonymous_id : null,\n\t\tsession_id: 'session_id' in response && typeof response.session_id === 'string' ? response.session_id : null,\n\t};\n};\n\nconst serverReferrer = (referrer: typeof Request.prototype.referrer) => {\n\tif (referrer === 'about:client') return '';\n\treturn referrer;\n};\n\nconst analyticsLogEndpoint = endpoint({\n\tpathname: '/log',\n\tmethod: 'POST',\n\tschema: {\n\t\tresponse: typed<unknown>(),\n\t\tbody: typed<TrackPayload>(),\n\t},\n});\n\nexport const createAnalyticsService = ({\n\trpcClient,\n\tlogger,\n}: {\n\tlogger: Logger;\n\trpcClient: InploiRpcClient;\n}): AnalyticsService => {\n\tconst logFn: LogFn = async params => {\n\t\tinvariant(\n\t\t\tparams.request || typeof window !== 'undefined',\n\t\t\t'Cannot log on the server without a request. Please pass a request to `log`.',\n\t\t);\n\n\t\t// if there’s a request, use it instead of browser APIs\n\t\tconst page =\n\t\t\t'request' in params && params.request ?\n\t\t\t\t{\n\t\t\t\t\thref: params.request.url,\n\t\t\t\t\treferrer: serverReferrer(params.request.referrer),\n\t\t\t\t\ttitle: '',\n\t\t\t\t}\n\t\t\t:\t{\n\t\t\t\t\thref: location.href,\n\t\t\t\t\treferrer: document.referrer,\n\t\t\t\t\ttitle: document.title,\n\t\t\t\t};\n\n\t\ttry {\n\t\t\tconst context: AnalyticsContext = {\n\t\t\t\tlibrary: {\n\t\t\t\t\tname: 'inploi-sdk',\n\t\t\t\t\tversion: ANALYTICS_VERSION,\n\t\t\t\t},\n\t\t\t\tpage,\n\t\t\t};\n\n\t\t\tconst sessionInfo = getSessionInfo(params.request);\n\t\t\tconst payload: TrackPayload = {\n\t\t\t\tanonymous_id: sessionInfo.anonymous_id,\n\t\t\t\tsession_id: sessionInfo.session_id,\n\t\t\t\tevent: params.event,\n\t\t\t\tsent_at: new Date().toISOString(),\n\t\t\t\tcontext,\n\t\t\t\tproperties: params.properties,\n\t\t\t\tcustom_properties: params.customProperties,\n\t\t\t};\n\n\t\t\tconst responseJson = await rpcClient.request(analyticsLogEndpoint, {\n\t\t\t\tbody: payload,\n\t\t\t});\n\n\t\t\tconst newSession = getSessionInfoFromResponse(responseJson);\n\t\t\tif (newSession?.anonymous_id) {\n\t\t\t\tpayload.anonymous_id = newSession.anonymous_id;\n\t\t\t}\n\t\t\tif (newSession?.session_id) {\n\t\t\t\tpayload.session_id = newSession.session_id;\n\t\t\t}\n\n\t\t\tif (typeof window !== 'undefined' && payload.anonymous_id) {\n\t\t\t\tif (payload.session_id) {\n\t\t\t\t\tsessionStorage.setItem(`${ANALYTICS_COOKIE_NAME}-session_id`, payload.session_id.toString());\n\t\t\t\t}\n\t\t\t\tdocument.cookie = formatCookie(payload.anonymous_id);\n\t\t\t}\n\n\t\t\treturn { success: true, data: payload };\n\t\t} catch (e) {\n\t\t\t/** We dont’t log any PII on the console */\n\t\t\tlogger.error('Failed to send log to API. Inspect error response of `log` for more information.');\n\t\t\treturn { success: false, error: e };\n\t\t}\n\t};\n\n\treturn {\n\t\tlog: logFn,\n\t\tgetHeaders: payload => {\n\t\t\tconst headers = new Headers();\n\t\t\tif (!payload?.anonymous_id) return headers;\n\n\t\t\theaders.append('Set-Cookie', formatCookie(payload.anonymous_id));\n\t\t\treturn headers;\n\t\t},\n\t\tgetSessionInfo,\n\t};\n};\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { stringify } from 'neoqs';\n\nimport { JsonParsingError, SchemaValidationError, handleApiExceptions } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger } from './sdk.logger';\n\ntype RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\n/** Extract parameter names from a pathname string */\ntype ExtractParamNames<T extends string> =\n\tT extends `${infer _Before}:${infer Param}/${infer After}` ? Param | ExtractParamNames<`/${After}`>\n\t: T extends `${infer _Before}:${infer Param}` ? Param\n\t: never;\n\n/** Create params object from parameter names */\ntype ExtractPathParams<T extends string> =\n\tstring extends T ? Record<string, string | number>\n\t: ExtractParamNames<T> extends never ? Record<string, never>\n\t: { [K in ExtractParamNames<T>]: string | number };\n\n/** Parses a StandardSchemaV1 schema and input into an output. */\nexport function parse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n): StandardSchemaV1.InferOutput<T> {\n\tconst result = schema['~standard'].validate(input);\n\tif (result instanceof Promise) {\n\t\tthrow new TypeError('Async schema');\n\t}\n\n\tif (result.issues) {\n\t\tthrow new SchemaValidationError(result.issues);\n\t}\n\n\treturn result.value;\n}\n\n/** Parses a StandardSchemaV1 schema and input into an output, returning a success flag and issues if the parse fails. */\nexport function safeParse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n):\n\t| {\n\t\t\tsuccess: true;\n\t\t\toutput: StandardSchemaV1.InferOutput<T>;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t } {\n\ttry {\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\toutput: parse(schema, input),\n\t\t};\n\t} catch (e) {\n\t\tif (e instanceof SchemaValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tissues: e.issues,\n\t\t\t};\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nexport interface InploiRpcClientParams {\n\tenvironment: InploiSdkEnvironment;\n\tlogger: Logger;\n\tapiKey:\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-secret-key header\n\t\t\t\t * This will error if used in a browser environment.\n\t\t\t\t */\n\t\t\t\ttype: 'secret';\n\t\t\t\tkey: string;\n\t\t }\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-publishable-key header\n\t\t\t\t * This can be called in a browser or server environment.\n\t\t\t\t */\n\t\t\t\ttype: 'publishable';\n\t\t\t\tkey: string;\n\t\t };\n}\n\n/** RPC client for making API calls to the Inploi API. */\nexport class InploiRpcClient {\n\tprivate baseUrl: string;\n\tprivate headers: Headers;\n\tprivate logger: Logger;\n\n\tconstructor(params: InploiRpcClientParams) {\n\t\tthis.baseUrl = ENV_TO_API_URL[params.environment];\n\t\tthis.headers = new Headers({\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t});\n\t\tif (params.apiKey.type === 'secret') {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\tthrow new Error('Secret key cannot be used in a browser environment');\n\t\t\t}\n\t\t\tthis.headers.set('x-secret-key', params.apiKey.key);\n\t\t} else {\n\t\t\tthis.headers.set('x-publishable-key', params.apiKey.key);\n\t\t}\n\t\tthis.logger = params.logger;\n\t}\n\n\t/** Fetches, parses and validates an API endpoint.\n\t * Logs errors and throws them again so that the caller can handle them.\n\t *\n\t * @throws {JsonParsingError} - If the response is not valid JSON.\n\t * @throws {SchemaValidationError} - If the searchParams, body or response does not match the schema.\n\t * @throws {ApiError} - If the API responded with an error message.\n\t * @throws {UnauthorisedError} - If the request is unauthorised either by missing key or unmet permissions.\n\t * @throws {NotFoundError} - If the endpoint is not found.\n\t * @throws {Error} - Another unhandled error.\n\t */\n\tasync request<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ?\n\t\t\tGetSchemaValues<{\n\t\t\t\tbody: TBody;\n\t\t\t\tsearchParams: TSearch;\n\t\t\t\tparams: TPathParams;\n\t\t\t}> & { signal?: AbortSignal }\n\t\t:\tnever,\n\t) {\n\t\ttry {\n\t\t\tconst url = new URL(this.baseUrl);\n\n\t\t\t// Replace path parameters in pathname\n\t\t\tlet pathname = endpoint.pathname;\n\t\t\tif ('params' in options && options.params) {\n\t\t\t\tfor (const [key, value] of Object.entries(options.params)) {\n\t\t\t\t\tpathname = pathname.replace(`:${key}`, String(value));\n\t\t\t\t}\n\t\t\t}\n\t\t\turl.pathname = pathname;\n\n\t\t\tif (endpoint.schema.searchParams) {\n\t\t\t\turl.search = stringify(\n\t\t\t\t\tparse(endpoint.schema.searchParams, 'searchParams' in options ? options.searchParams : {}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst body =\n\t\t\t\tendpoint.schema.body ? parse(endpoint.schema.body, 'body' in options ? options.body : {}) : undefined;\n\n\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\tmethod: endpoint.method,\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\theaders: this.headers,\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\n\t\t\tconst json = await response.json().catch(e => {\n\t\t\t\tthis.logger.error(e);\n\t\t\t\tthrow new JsonParsingError(response);\n\t\t\t});\n\n\t\t\tconst result = safeParse(endpoint.schema.response, json);\n\t\t\tif (!result.success) {\n\t\t\t\thandleApiExceptions(json);\n\t\t\t\tthrow new SchemaValidationError(result.issues);\n\t\t\t}\n\n\t\t\treturn result.output as StandardSchemaV1.InferOutput<T['schema']['response']>;\n\t\t} catch (e) {\n\t\t\tif (e instanceof SchemaValidationError) {\n\t\t\t\tthis.logger.error(e.message, e.issues);\n\t\t\t} else {\n\t\t\t\tthis.logger.error(e);\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n}\n\ntype GetSchemaValues<T extends { searchParams: any; body: any; params?: any }> = {\n\t[K in keyof T as T[K] extends never ? never\n\t: T[K] extends Record<string, never> ? never\n\t: K]: T[K] extends never ? never : T[K];\n};\n\n/**\n * Typed but *not runtime validated* schema\n * useful for type-checking the schema without bundling validation schemas\n */\nexport function typed<T>(): StandardSchemaV1<T, T> {\n\treturn {\n\t\t'~standard': {\n\t\t\tvendor: 'inploi',\n\t\t\tversion: 1,\n\t\t\tvalidate: input => {\n\t\t\t\treturn {\n\t\t\t\t\tvalue: input as T,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t};\n}\n\nexport interface RpcEndpoint<\n\tTMethod extends RequestMethod = RequestMethod,\n\tTPathname extends string = string,\n\tTPathParams = any,\n\tTSearch = any,\n\tTBody = any,\n\tTResponse = any,\n> {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: StandardSchemaV1<TSearch, TSearch>;\n\t\tbody?: StandardSchemaV1<TBody, TBody>;\n\t\tresponse: StandardSchemaV1<TResponse, TResponse>;\n\t};\n\t/** Type-only property to store path parameter types */\n\treadonly __pathParams?: TPathParams;\n}\n\nexport function endpoint<\n\tTMethod extends RequestMethod,\n\tTPathname extends string,\n\tTSearch extends StandardSchemaV1 | never = never,\n\tTBody extends StandardSchemaV1 | never = never,\n\tTResponse extends StandardSchemaV1 | never = never,\n>(endpoint: {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: TSearch;\n\t\tbody?: TBody;\n\t\tresponse: TResponse;\n\t};\n}) {\n\ttype PathParams = ExtractPathParams<TPathname>;\n\treturn endpoint as RpcEndpoint<\n\t\tTMethod,\n\t\tTPathname,\n\t\tPathParams,\n\t\tStandardSchemaV1.InferInput<TSearch>,\n\t\tStandardSchemaV1.InferInput<TBody>,\n\t\tStandardSchemaV1.InferOutput<TResponse>\n\t>;\n}\n","import { createAnalyticsService } from './sdk.analytics';\nimport { createApiClient } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger, inploiBrandedLogger, noLogging } from './sdk.logger';\nimport { InploiSdkPlugin } from './sdk.plugins';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type InitialiseInploiSdkParams = {\n\t/** Your public API key for the inploi SDK. */\n\tpublishableKey: string;\n\t/** Which app environment to run. This ultimately affects which inploi endpoints to gather data are going to be used.\n\t * Anything other than `production` should be considered a development environment and the data periodicaly purged. */\n\tenv: InploiSdkEnvironment;\n\t/** Logger object that handles logging of different levels.\n\t * You can override this to use your own logger, or to disable logging altogether by passing`false`.\n\t * @default inploiBrandedLogger\n\t * */\n\tlogger?: Logger | false;\n};\n\nexport function initialiseSdk({ publishableKey, env, logger = inploiBrandedLogger }: InitialiseInploiSdkParams) {\n\t/** @deprecated - use `rpcClient` instead */\n\tconst apiClient = createApiClient({ baseUrl: ENV_TO_API_URL[env], publishableKey });\n\tconst loggerService = logger === false ? noLogging : logger;\n\tconst rpcClient = new InploiRpcClient({\n\t\tenvironment: env,\n\t\tapiKey: { type: 'publishable', key: publishableKey },\n\t\tlogger: loggerService,\n\t});\n\tconst analytics = createAnalyticsService({ rpcClient, logger: loggerService });\n\n\tconst register = <P extends InploiSdkPlugin>(plugin: P): ReturnType<P> => {\n\t\treturn plugin({ logger: loggerService, apiClient, analytics, rpcClient });\n\t};\n\n\treturn { register, analytics, apiClient };\n}\n\nexport type InploiSdk = ReturnType<typeof initialiseSdk>;\n"],"mappings":"i9BAAA,IAAAA,GAAA,GAAAC,EAAAD,GAAA,cAAAE,EAAA,oBAAAC,EAAA,kBAAAC,EAAA,iBAAAC,EAAA,0BAAAC,EAAA,aAAAC,EAAA,sBAAAC,EAAA,iBAAAC,EAAA,aAAAC,EAAA,kBAAAC,EAAA,wBAAAC,EAAA,eAAAC,EAAA,cAAAC,EAAA,UAAAC,IAAA,eAAAC,EAAAhB,ICAO,IAAMiB,EAAiB,iBACjBC,EAAgB,qCAUhBC,EAA8B,CAC1C,KAAM,IAAIC,IAAS,QAAQ,KAAKH,EAAgBC,EAAe,GAAGE,CAAI,EACtE,MAAO,IAAIA,IAAS,QAAQ,MAAMH,EAAgBC,EAAe,GAAGE,CAAI,EACxE,KAAM,IAAIA,IAAS,QAAQ,KAAKH,EAAgBC,EAAe,GAAGE,CAAI,EACtE,IAAK,IAAIA,IAAS,QAAQ,IAAIH,EAAgBC,EAAe,GAAGE,CAAI,CACrE,EAEaC,EAAoB,CAAE,KAAM,IAAG,GAAW,MAAO,IAAG,GAAW,IAAK,IAAG,GAAW,KAAM,IAAG,EAAU,ECM3G,IAAMC,EAA2CC,GAAgBA,ECtBjE,IAAMC,GAAyB,kBACzBC,GAAsB,+BAEtBC,EAAN,cAA4B,KAAM,CACxC,aAAc,CACb,MAAM,WAAW,EACjB,KAAK,KAAO,eACb,CACD,EAEaC,EAAN,cAAgC,KAAM,CAC5C,YAAYC,EAAkB,CAC7B,MAAMA,GAAA,KAAAA,EAAW,gDAAgD,EACjE,KAAK,KAAO,mBACb,CACD,EAEaC,EAAN,cAAoC,KAAM,CAChD,YAAmBC,EAA2C,CAC7D,MAAM,0BAA0B,EADd,YAAAA,EAElB,KAAK,KAAO,uBACb,CACD,EAEaC,EAAN,cAAuB,KAAM,CAEnC,YAAYH,EAAiBI,EAAmB,CAC/C,MAAMJ,CAAO,EACb,KAAK,KAAO,WACZ,KAAK,OAASI,CACf,CACD,EAEaC,EAAN,cAA+B,KAAM,CAC3C,YAAmBC,EAAqB,CACvC,MAAM,mCAAmC,EADvB,cAAAA,EAElB,KAAK,KAAO,cACb,CACD,EAUO,SAASC,EAAoBC,EAAe,CAClD,GAAIA,IAAS,MAET,OAAOA,GAAS,SAAU,CAC7B,IAAIC,EAAU,oBAGd,GAFI,YAAaD,GAAQ,OAAOA,EAAK,SAAY,WAAUC,EAAUD,EAAK,SAEtEC,IAAYC,GACf,MAAM,IAAIC,EAAkB,4BAA4B,EAEzD,GAAIF,IAAYG,GACf,MAAM,IAAID,EAEX,GAAI,cAAeH,EAClB,MAAM,IAAIK,EAASJ,EAAS,CAACD,EAAK,SAAS,CAAC,EAE7C,GAAI,WAAYA,EAAM,CACrB,GAAI,MAAM,QAAQA,EAAK,MAAM,GAAKA,EAAK,OAAO,MAAMM,GAAS,OAAOA,GAAU,QAAQ,EACrF,MAAM,IAAID,EAASJ,EAASD,EAAK,MAAM,EAExC,GAAI,OAAOA,EAAK,QAAW,UAAYA,EAAK,SAAW,KAAM,CAC5D,IAAMO,EAAU,OAAO,QAAQP,EAAK,MAAM,EAE1C,MAAIO,EAAQ,MAAM,CAAC,CAAC,CAAEC,CAAK,IAAM,MAAM,QAAQA,CAAK,GAAKA,EAAM,MAAMF,GAAS,OAAOA,GAAU,QAAQ,CAAC,EACjG,IAAIG,EACTF,EAAQ,IACP,CAAC,CAACG,EAAKF,CAAK,KAA+B,CAC1C,KAAME,EAAI,MAAM,GAAG,EACnB,QAASF,EAAM,KAAK,IAAI,CACzB,EACD,CACD,EAEK,IAAIH,EACTJ,EACAM,EAAQ,IAAI,CAAC,CAACG,EAAKF,CAAK,IAAM,GAAGE,CAAG,KAAKF,CAAK,EAAE,CACjD,CACD,CACA,GAAI,OAAOR,EAAK,QAAW,SAAU,MAAM,IAAIK,EAASJ,EAAS,CAACD,EAAK,MAAM,CAAC,CAC/E,CACA,GAAI,UAAWA,GAAQ,OAAOA,EAAK,OAAU,SAC5C,MAAM,IAAIK,EAASL,EAAK,MAAO,CAACA,EAAK,KAAK,CAAC,CAE7C,CACD,CAEO,IAAMW,EAAmBC,GAAmE,CAClG,IAAMC,EAA8B,CACnC,OAAQ,mBACR,eAAgB,mBAChB,oBAAqBD,EAAO,cAC7B,EAEA,MAAO,CAIN,MAAO,CAAOE,KAA2BC,IAAAC,EAAA,QAA3BF,EAA2B,GAAAC,GAAA,UAA3BE,EAAUC,EAAU,CAAC,EAAM,CACxC,IAAMC,EAAOC,EAAAC,EAAA,GAAKH,GAAL,CAAc,QAASG,IAAA,GAAKH,EAAQ,SAAYL,EAAiB,GACxES,EAAW,MAAM,MAAM,GAAGV,EAAO,OAAO,GAAGK,CAAQ,GAAIE,CAAI,EACjE,GAAIG,EAAS,SAAW,IAAK,MAAM,IAAIC,EAEvC,IAAMvB,EAAO,MAAMsB,EAAS,KAAK,EAAE,MAAM,IAAYN,EAAA,wBACpD,MAAM,IAAIQ,EAAiBF,CAAQ,CACpC,EAAC,EAED,OAAAvB,EAAoBC,CAAI,EAGjBA,CACR,EACD,CACD,EAEayB,EAAW,CACvB,SAAUF,EACV,aAAcpB,EACd,iBAAkBM,EAClB,IAAKJ,EACL,YAAamB,CACd,EAEO,SAASE,EAAWpB,EAAmE,CAC7F,OAAO,OAAO,OAAOmB,CAAQ,EAAE,KAAKE,GAAcrB,aAAiBqB,CAAU,CAC9E,CClIO,SAASC,EAAUC,EAAgBC,EAAqC,CAC9E,GAAI,CAAAD,EAIJ,MAAM,IAAI,MAAMC,CAAO,CACxB,CEDA,IAAMC,GAAoB,IAAI,KAAK,mBAAmB,OAAW,CAAE,QAAS,MAAO,CAAC,ECPnF,IAAAC,EAAW,SCOL,IAAMC,EAAuD,CACnE,QAAS,iCACT,WAAY,yBAEZ,gBAAiB,iBAClB,EAEaC,EAAoBC,EAI1B,IAAMC,EAAwB,eCdrC,IAAMC,EAAgBC,GAAkB,CACvC,IAAMC,EAAM,IAAI,KAChB,OAAAA,EAAI,QAAQA,EAAI,QAAQ,EAAI,EAAI,GAAK,GAAK,GAAK,GAAI,EAE5C,GAAGC,CAAqB,IAAIF,CAAK,YAAYC,EAAI,YAAY,CAAC,SACtE,EA6KME,GAAe,CAACC,EAA+BC,IAAsB,CAC1E,IAAMC,EAAmBF,EAAa,IAAI,YAAY,EAEtD,GADIC,GACAC,EAAkB,OAAOA,EAC7B,IAAMC,EAAqB,eAAe,QAAQ,GAAGL,CAAqB,aAAa,EACvF,OAAI,OAAOK,GAAuB,SAAiBA,EAC5C,IACR,EAEMC,GAAc,IAAI,OAAO,GAAGN,CAAqB,UAAU,EAC3DO,EAAkBC,GAAsB,CAC7C,IAAMC,EAAOD,EAAUA,EAAQ,IAAM,SAAS,KACxC,CAAE,aAAAN,CAAa,EAAI,IAAI,IAAIO,CAAI,EAC/BC,EAAeR,EAAa,IAAI,cAAc,EAC9CS,EAAaV,GAAaC,EAAc,OAAO,QAAW,WAAW,EAG3E,GAAIQ,EACH,MAAO,CACN,aAAAA,EACA,WAAAC,CACD,EAGD,IAAMC,EAASJ,EAAUA,EAAQ,QAAQ,IAAI,QAAQ,EAAI,SAAS,OAClE,GAAII,EAAQ,CACX,IAAMC,EAAQP,GAAY,KAAKM,CAAM,EAC/BF,EAAeG,GAAA,YAAAA,EAAQ,GAC7B,MAAO,CACN,aAAcH,GAAA,KAAAA,EAAgB,KAC9B,WAAAC,CACD,CACD,CAGA,MAAO,CACN,aAAAD,EACA,WAAAC,CACD,CACD,EAEMG,GAA8BC,GAC/B,OAAOA,GAAa,UAAYA,IAAa,KAAa,KACvD,CACN,aACC,iBAAkBA,GAAY,OAAOA,EAAS,cAAiB,SAAWA,EAAS,aAAe,KACnG,WAAY,eAAgBA,GAAY,OAAOA,EAAS,YAAe,SAAWA,EAAS,WAAa,IACzG,EAGKC,GAAkBC,GACnBA,IAAa,eAAuB,GACjCA,EAGFC,GAAgC,CACrC,SAAU,OACV,OAAQ,OACR,OAAQ,CACP,SAAUC,EAAe,EACzB,KAAMA,EAAoB,CAC3B,CACD,EAEaC,EAAyB,CAAC,CACtC,UAAAC,EACA,OAAAC,CACD,KAuEQ,CACN,IApE0BC,GAAUC,EAAA,wBACpCC,EACCF,EAAO,SAAW,OAAO,QAAW,YACpC,6EACD,EAGA,IAAMG,EACL,YAAaH,GAAUA,EAAO,QAC7B,CACC,KAAMA,EAAO,QAAQ,IACrB,SAAUP,GAAeO,EAAO,QAAQ,QAAQ,EAChD,MAAO,EACR,EACC,CACA,KAAM,SAAS,KACf,SAAU,SAAS,SACnB,MAAO,SAAS,KACjB,EAEF,GAAI,CACH,IAAMI,EAA4B,CACjC,QAAS,CACR,KAAM,aACN,QAASC,CACV,EACA,KAAAF,CACD,EAEMG,EAActB,EAAegB,EAAO,OAAO,EAC3CO,EAAwB,CAC7B,aAAcD,EAAY,aAC1B,WAAYA,EAAY,WACxB,MAAON,EAAO,MACd,QAAS,IAAI,KAAK,EAAE,YAAY,EAChC,QAAAI,EACA,WAAYJ,EAAO,WACnB,kBAAmBA,EAAO,gBAC3B,EAEMQ,EAAe,MAAMV,EAAU,QAAQH,GAAsB,CAClE,KAAMY,CACP,CAAC,EAEKE,EAAalB,GAA2BiB,CAAY,EAC1D,OAAIC,GAAA,MAAAA,EAAY,eACfF,EAAQ,aAAeE,EAAW,cAE/BA,GAAA,MAAAA,EAAY,aACfF,EAAQ,WAAaE,EAAW,YAG7B,OAAO,QAAW,aAAeF,EAAQ,eACxCA,EAAQ,YACX,eAAe,QAAQ,GAAG9B,CAAqB,cAAe8B,EAAQ,WAAW,SAAS,CAAC,EAE5F,SAAS,OAASjC,EAAaiC,EAAQ,YAAY,GAG7C,CAAE,QAAS,GAAM,KAAMA,CAAQ,CACvC,OAASG,EAAG,CAEX,OAAAX,EAAO,MAAM,kFAAkF,EACxF,CAAE,QAAS,GAAO,MAAOW,CAAE,CACnC,CACD,GAIC,WAAYH,GAAW,CACtB,IAAMI,EAAU,IAAI,QACpB,OAAKJ,GAAA,MAAAA,EAAS,cAEdI,EAAQ,OAAO,aAAcrC,EAAaiC,EAAQ,YAAY,CAAC,EACxDI,CACR,EACA,eAAA3B,CACD,GC3UD,IAAA4B,EAA0B,iBAqBnB,SAASC,EACfC,EACAC,EACkC,CAClC,IAAMC,EAASF,EAAO,WAAW,EAAE,SAASC,CAAK,EACjD,GAAIC,aAAkB,QACrB,MAAM,IAAI,UAAU,cAAc,EAGnC,GAAIA,EAAO,OACV,MAAM,IAAIC,EAAsBD,EAAO,MAAM,EAG9C,OAAOA,EAAO,KACf,CAGO,SAASE,GACfJ,EACAC,EASI,CACJ,GAAI,CACH,MAAO,CACN,QAAS,GACT,OAAQF,EAAMC,EAAQC,CAAK,CAC5B,CACD,OAASI,EAAG,CACX,GAAIA,aAAaF,EAChB,MAAO,CACN,QAAS,GACT,OAAQE,EAAE,MACX,EAED,MAAMA,CACP,CACD,CAuBO,IAAMC,EAAN,KAAsB,CAK5B,YAAYC,EAA+B,CAM1C,GALA,KAAK,QAAUC,EAAeD,EAAO,WAAW,EAChD,KAAK,QAAU,IAAI,QAAQ,CAC1B,eAAgB,mBAChB,OAAQ,kBACT,CAAC,EACGA,EAAO,OAAO,OAAS,SAAU,CACpC,GAAI,OAAO,QAAW,YACrB,MAAM,IAAI,MAAM,oDAAoD,EAErE,KAAK,QAAQ,IAAI,eAAgBA,EAAO,OAAO,GAAG,CACnD,MACC,KAAK,QAAQ,IAAI,oBAAqBA,EAAO,OAAO,GAAG,EAExD,KAAK,OAASA,EAAO,MACtB,CAYM,QACLE,EACAC,EAOC,QAAAC,EAAA,sBACD,GAAI,CACH,IAAMC,EAAM,IAAI,IAAI,KAAK,OAAO,EAG5BC,EAAWJ,EAAS,SACxB,GAAI,WAAYC,GAAWA,EAAQ,OAClC,OAAW,CAACI,EAAKC,CAAK,IAAK,OAAO,QAAQL,EAAQ,MAAM,EACvDG,EAAWA,EAAS,QAAQ,IAAIC,CAAG,GAAI,OAAOC,CAAK,CAAC,EAGtDH,EAAI,SAAWC,EAEXJ,EAAS,OAAO,eACnBG,EAAI,UAAS,aACZb,EAAMU,EAAS,OAAO,aAAc,iBAAkBC,EAAUA,EAAQ,aAAe,CAAC,CAAC,CAC1F,GAGD,IAAMM,EACLP,EAAS,OAAO,KAAOV,EAAMU,EAAS,OAAO,KAAM,SAAUC,EAAUA,EAAQ,KAAO,CAAC,CAAC,EAAI,OAEvFO,EAAW,MAAM,MAAML,EAAI,SAAS,EAAG,CAC5C,OAAQH,EAAS,OACjB,KAAMO,EAAO,KAAK,UAAUA,CAAI,EAAI,OACpC,QAAS,KAAK,QACd,OAAQN,EAAQ,MACjB,CAAC,EAEKQ,EAAO,MAAMD,EAAS,KAAK,EAAE,MAAMZ,GAAK,CAC7C,WAAK,OAAO,MAAMA,CAAC,EACb,IAAIc,EAAiBF,CAAQ,CACpC,CAAC,EAEKf,EAASE,GAAUK,EAAS,OAAO,SAAUS,CAAI,EACvD,GAAI,CAAChB,EAAO,QACX,MAAAkB,EAAoBF,CAAI,EAClB,IAAIf,EAAsBD,EAAO,MAAM,EAG9C,OAAOA,EAAO,MACf,OAASG,EAAG,CACX,MAAIA,aAAaF,EAChB,KAAK,OAAO,MAAME,EAAE,QAASA,EAAE,MAAM,EAErC,KAAK,OAAO,MAAMA,CAAC,EAEdA,CACP,CACD,GACD,EAYO,SAASgB,GAAmC,CAClD,MAAO,CACN,YAAa,CACZ,OAAQ,SACR,QAAS,EACT,SAAUpB,IACF,CACN,MAAOA,CACR,EAEF,CACD,CACD,CAsBO,SAASQ,EAMdA,EASC,CAEF,OAAOA,CAQR,CCtOO,SAASa,EAAc,CAAE,eAAAC,EAAgB,IAAAC,EAAK,OAAAC,EAASC,CAAoB,EAA8B,CAE/G,IAAMC,EAAYC,EAAgB,CAAE,QAASC,EAAeL,CAAG,EAAG,eAAAD,CAAe,CAAC,EAC5EO,EAAgBL,IAAW,GAAQM,EAAYN,EAC/CO,EAAY,IAAIC,EAAgB,CACrC,YAAaT,EACb,OAAQ,CAAE,KAAM,cAAe,IAAKD,CAAe,EACnD,OAAQO,CACT,CAAC,EACKI,EAAYC,EAAuB,CAAE,UAAAH,EAAW,OAAQF,CAAc,CAAC,EAM7E,MAAO,CAAE,SAJoCM,GACrCA,EAAO,CAAE,OAAQN,EAAe,UAAAH,EAAW,UAAAO,EAAW,UAAAF,CAAU,CAAC,EAGtD,UAAAE,EAAW,UAAAP,CAAU,CACzC","names":["src_exports","__export","ApiError","InploiRpcClient","NotFoundError","JsonParsingError","SchemaValidationError","SdkError","UnauthorisedError","createPlugin","endpoint","initialiseSdk","inploiBrandedLogger","isSdkError","noLogging","typed","__toCommonJS","CONSOLE_PREFIX","CONSOLE_STYLE","inploiBrandedLogger","args","noLogging","createPlugin","pluginFn","unauthenticatedMessage","unauthorisedMessage","NotFoundError","UnauthorisedError","message","SchemaValidationError","issues","ApiError","errors","JsonParsingError","response","handleApiExceptions","json","message","unauthenticatedMessage","UnauthorisedError","unauthorisedMessage","ApiError","error","entries","value","SchemaValidationError","key","createApiClient","params","defaultHeaders","_0","_1","__async","pathname","options","init","__spreadProps","__spreadValues","response","NotFoundError","JsonParsingError","SdkError","isSdkError","ErrorClass","invariant","condition","message","DEFAULT_FORMATTER","version","ENV_TO_API_URL","ANALYTICS_VERSION","version","ANALYTICS_COOKIE_NAME","formatCookie","value","now","ANALYTICS_COOKIE_NAME","getSessionId","searchParams","isServer","fromSearchParams","fromSessionStorage","cookieRegex","getSessionInfo","request","href","anonymous_id","session_id","cookie","match","getSessionInfoFromResponse","response","serverReferrer","referrer","analyticsLogEndpoint","typed","createAnalyticsService","rpcClient","logger","params","__async","invariant","page","context","ANALYTICS_VERSION","sessionInfo","payload","responseJson","newSession","e","headers","import_neoqs","parse","schema","input","result","SchemaValidationError","safeParse","e","InploiRpcClient","params","ENV_TO_API_URL","endpoint","options","__async","url","pathname","key","value","body","response","json","JsonParsingError","handleApiExceptions","typed","initialiseSdk","publishableKey","env","logger","inploiBrandedLogger","apiClient","createApiClient","ENV_TO_API_URL","loggerService","noLogging","rpcClient","InploiRpcClient","analytics","createAnalyticsService","plugin"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/sdk.logger.ts","../src/sdk.plugins.ts","../../core/src/common/common.utils.ts","../../core/src/common/common.currency.ts","../../core/src/common/common.datetime.ts","../src/sdk.api.ts","../package.json","../src/sdk.constants.ts","../src/sdk.analytics.ts","../src/sdk.rpc.ts","../src/sdk.ts"],"sourcesContent":["export { inploiBrandedLogger, noLogging } from './sdk.logger';\nexport type { Logger } from './sdk.logger';\n\nexport type { PluginParams, InploiSdkPlugin } from './sdk.plugins';\nexport { createPlugin } from './sdk.plugins';\n\nexport type { InploiSdkEnvironment } from './sdk.constants';\n\nexport type { ApiClient } from './sdk.api';\nexport {\n\tApiError,\n\tNotFoundError,\n\tJsonParsingError as ParsingError,\n\tUnauthorisedError,\n\tisSdkError,\n\tSchemaValidationError,\n\tSdkError,\n} from './sdk.api';\n\nexport { initialiseSdk } from './sdk';\nexport type { InitialiseInploiSdkParams, InploiSdk } from './sdk';\n\nexport type {\n\tAnalyticsService,\n\tAnalyticsLogEvent,\n\tAnalyticsLogParams,\n\tAnalyticsOnEventCallback,\n} from './sdk.analytics';\n\nexport { InploiRpcClient, endpoint, typed, validateEndpointInputs } from './sdk.rpc';\nexport type { RpcEndpoint } from './sdk.rpc';\n","export const CONSOLE_PREFIX = '%c[inploi SDK]';\nexport const CONSOLE_STYLE = 'color: #65BC67; font-weight: bold;';\n\ntype LogMessage = (...data: any[]) => void;\nexport type Logger = {\n\twarn: LogMessage;\n\terror: LogMessage;\n\tinfo: LogMessage;\n\tlog: LogMessage;\n};\n\nexport const inploiBrandedLogger: Logger = {\n\twarn: (...args) => console.warn(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\terror: (...args) => console.error(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tinfo: (...args) => console.info(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tlog: (...args) => console.log(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n};\n\nexport const noLogging: Logger = { info: () => void 0, error: () => void 0, log: () => void 0, warn: () => void 0 };\n","import { AnalyticsService } from './sdk.analytics';\nimport { ApiClient } from './sdk.api';\nimport { Logger } from './sdk.logger';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type PluginParams = {\n\tapiClient: ApiClient;\n\tlogger: Logger;\n};\n\nexport type Plugin<T extends string, P extends Record<string, unknown>> = {\n\tpluginName: T;\n\tpure_createActions: (params: PluginParams) => P;\n};\n\ntype PluginDependencies = {\n\tapiClient: ApiClient;\n\trpcClient: InploiRpcClient;\n\tlogger: Logger;\n\tanalytics: AnalyticsService;\n};\n\nexport type InploiSdkPlugin = (dependencies: PluginDependencies) => any;\n\nexport const createPlugin = <T extends InploiSdkPlugin>(pluginFn: T) => pluginFn;\n","export const exhaustive = (value: never) => {\n\tthrow new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);\n};\n\nexport function invariant(condition: any, message?: string): asserts condition {\n\tif (condition) {\n\t\treturn;\n\t}\n\n\tthrow new Error(message);\n}\n\nexport const uniqueOrThrow = <T>(array: T[]) => {\n\tconst uniqueValues = new Set(array);\n\n\tif (array.length !== uniqueValues.size) {\n\t\tthrow new Error('Duplicate values found');\n\t}\n\treturn true;\n};\n\nexport const uniqueByPropertyOrThrow =\n\t<T extends PropertyKey>(propertyKey: T) =>\n\t(array: { [K in T]: any }[]) => {\n\t\tconst values = array.map(item => item[propertyKey]);\n\t\tconst uniqueValues = new Set(values);\n\n\t\tif (values.length !== uniqueValues.size) {\n\t\t\tthrow new Error(`Duplicate values found for property: ${propertyKey.toString()}`);\n\t\t}\n\t\treturn true;\n\t};\n\n/**\n * A destructive way to ensure an object has a property.\n * This is useful when working with unknowns.\n */\nexport function hasProp<K extends PropertyKey>(data: object, prop: K): data is Record<K, unknown> {\n\treturn prop in data;\n}\n\n/**\n * A sort of type-safe way to check whether a key exists in an object.\n */\nexport function isKeyInObj<O extends Record<string, unknown>>(key: PropertyKey, obj: O): key is keyof O {\n\treturn key in obj;\n}\n","type TFunction = (key: 'competitive' | 'invalid_salary' | 'from' | 'up_to') => string;\n\ninterface SalaryParams {\n\tpay: string | null;\n\tpay_min: string | null;\n\tpay_mask: boolean;\n\tpay_max: string | null;\n\tpay_type: 'ANNUALLY' | 'HOURLY' | 'MONTHLY' | 'WEEKLY' | 'DAILY' | null;\n\tpay_currency: string;\n\tpay_display: boolean;\n}\n\nconst payPeriods: Record<NonNullable<SalaryParams['pay_type']>, string> = {\n\tANNUALLY: 'per year',\n\tDAILY: 'per day',\n\tHOURLY: 'per hour',\n\tMONTHLY: 'per month',\n\tWEEKLY: 'per week',\n};\n\nexport const getSalaryAsText = (params: {\n\tsalary: SalaryParams;\n\tconfig: { locales: string | string[] | undefined };\n\tt?: TFunction;\n}) => {\n\tconst { salary, config, t = s => s } = params;\n\tconst numberFormatter = new Intl.NumberFormat(config.locales, {\n\t\tstyle: 'currency',\n\t\tcurrency: salary.pay_currency,\n\t\t// @ts-expect-error - CI/CD is not happy with this, though locally it works\n\t\ttrailingZeroDisplay: 'stripIfInteger',\n\t});\n\tif (salary.pay_display === false) return undefined;\n\tif (salary.pay_mask) return t('competitive');\n\n\tif (salary.pay_max && Number.isNaN(+salary.pay_max)) return t('invalid_salary');\n\tif (salary.pay_min && Number.isNaN(+salary.pay_min)) return t('invalid_salary');\n\tif (salary.pay && Number.isNaN(+salary.pay)) return t('invalid_salary');\n\n\tconst period = salary.pay_type && salary.pay_type in payPeriods ? payPeriods[salary.pay_type] : undefined;\n\n\tif (salary.pay) return [numberFormatter.format(+salary.pay), period].filter(Boolean).join(' ');\n\n\tif (salary.pay_max && salary.pay_min)\n\t\treturn [numberFormatter.formatRange(+salary.pay_min, +salary.pay_max), period].filter(Boolean).join(' ') || '';\n\n\tif (salary.pay_max)\n\t\treturn `${t('up_to')} ${[numberFormatter.format(+salary.pay_max), period].filter(Boolean).join(' ')}`;\n\tif (salary.pay_min)\n\t\treturn `${t('from')} ${[numberFormatter.format(+salary.pay_min), period].filter(Boolean).join(' ')}`;\n\treturn t('invalid_salary');\n};\n","type TFunction = (key: 'today' | 'over_30_days_ago' | 'in_over_30_days') => string;\n\ntype Params = {\n\tfrom?: Date;\n\tto: string | number | Date;\n\tformatter?: Intl.RelativeTimeFormat;\n\tt?: TFunction;\n};\n\nconst DEFAULT_FORMATTER = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });\n/** From a date, calculates the relative time difference from now */\nexport const getRelativeTimeDifference = ({\n\tfrom = new Date(),\n\tto,\n\tformatter = DEFAULT_FORMATTER,\n\tt = s => s,\n}: Params) => {\n\tconst then = to instanceof Date ? to : new Date(to);\n\tconst diff = then.getTime() - from.getTime();\n\n\tconst diffIn = {\n\t\tdays: Math.round(diff / 1000 / 60 / 60 / 24),\n\t\tmonths: Math.round(diff / 1000 / 60 / 60 / 24 / 30),\n\t};\n\n\tif (diffIn.days === 0) return t('today');\n\tif (Math.abs(diffIn.days) < 30) return formatter.format(diffIn.days, 'days');\n\tif (Math.abs(diffIn.days) < 3) return formatter.format(diffIn.months, 'months');\n\treturn diffIn.months < 0 ? t('over_30_days_ago') : t('in_over_30_days');\n};\n","import { hasProp } from '@inploi/core/common';\nimport { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport const unauthenticatedMessage = 'Unauthenticated';\nexport const unauthorisedMessage = 'This action is unauthorized.';\n\nexport class ErrorWithStatus extends Error {\n\tpublic status?: number;\n\tconstructor(message?: string, status?: number) {\n\t\tsuper(message);\n\t\tthis.status = status;\n\t\tthis.name = 'ErrorWithStatus';\n\t}\n}\n\nexport class NotFoundError extends ErrorWithStatus {\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Not found');\n\t\tthis.name = 'NotFoundError';\n\t\tthis.status = 404;\n\t}\n}\n\nexport class UnauthorisedError extends ErrorWithStatus {\n\tconstructor(message?: string, status?: number) {\n\t\tsuper(message ?? 'You are not authorised to perform this action.');\n\t\tthis.name = 'UnauthorisedError';\n\t\tthis.status = status ?? 401;\n\t}\n}\n\nexport class SchemaValidationError extends ErrorWithStatus {\n\tconstructor(\n\t\tpublic issues: readonly StandardSchemaV1.Issue[],\n\t\tpublic source?: 'body' | 'searchParams' | 'response',\n\t) {\n\t\tconst sourceText = source ? ` in ${source}` : '';\n\t\tsuper(`Schema validation failed${sourceText}`);\n\t\tthis.name = 'SchemaValidationError';\n\t\tthis.status = 400;\n\t}\n}\n\nexport class ApiError extends ErrorWithStatus {\n\tconstructor(message: string, status?: number) {\n\t\tsuper(message);\n\t\tthis.name = 'ApiError';\n\t\tthis.status = status ?? 500;\n\t}\n}\n\nexport class JsonParsingError extends ErrorWithStatus {\n\tconstructor(public response?: Response) {\n\t\tsuper('Error parsing response into JSON.');\n\t\tthis.name = 'ParsingError';\n\t\tthis.status = 500;\n\t}\n}\n\n/** @deprecated - use `JsonParsingError` instead */\nexport class ParsingError extends JsonParsingError {}\n\nexport type ApiClient = {\n\tfetch: (pathname: string, options?: RequestInit) => Promise<unknown>;\n};\n\nconst ERROR_MESSAGE_KEYS = ['message', 'error', 'errors', 'exception', 'exceptions'] as const;\nfunction getErrorMessageFromJson(json: unknown): string {\n\tconsole.log('json', json);\n\tconst messages: string[] = [];\n\tif (typeof json === 'object' && json !== null) {\n\t\tfor (const key of ERROR_MESSAGE_KEYS) {\n\t\t\tif (hasProp(json, key)) {\n\t\t\t\tconsole.log('hasProp', key, json[key]);\n\t\t\t\tconst value = json[key];\n\t\t\t\tif (typeof value === 'string') messages.push(value);\n\t\t\t\tif (Array.isArray(value) && value.every((item): item is string => typeof item === 'string'))\n\t\t\t\t\tmessages.push(...value);\n\t\t\t}\n\t\t}\n\t}\n\tif (messages.length === 0) messages.push('Unknown error');\n\treturn messages.join(', ');\n}\n\n/** Throws branded errors when API returns a known error. */\nexport function handleApiExceptions(json: unknown, status: number) {\n\tif (status >= 300 && status <= 500) {\n\t\tconst message = getErrorMessageFromJson(json);\n\t\tif (status === 404) {\n\t\t\tthrow new NotFoundError(message);\n\t\t}\n\t\tif (message === unauthenticatedMessage) {\n\t\t\tthrow new UnauthorisedError('You are not authenticated.', status);\n\t\t}\n\t\tif (message === unauthorisedMessage) {\n\t\t\tthrow new UnauthorisedError(message, status);\n\t\t}\n\t\tthrow new ApiError(message, status);\n\t}\n}\n\nexport const createApiClient = (params: { baseUrl: string; publishableKey: string }): ApiClient => {\n\tconst defaultHeaders: HeadersInit = {\n\t\tAccept: 'application/json',\n\t\t'Content-Type': 'application/json',\n\t\t'x-publishable-key': params.publishableKey,\n\t};\n\n\treturn {\n\t\t/** Fetches from a pathname with a pre-established base path.\n\t\t * Parses received output as JSON, and throw if one of the common error messages is received.\n\t\t */\n\t\tfetch: async (pathname, options = {}) => {\n\t\t\tconst init = { ...options, headers: { ...options.headers, ...defaultHeaders } };\n\t\t\tconst response = await fetch(`${params.baseUrl}${pathname}`, init);\n\t\t\tif (response.status === 404) throw new NotFoundError();\n\n\t\t\tconst json = await response.json().catch(async () => {\n\t\t\t\tthrow new JsonParsingError(response);\n\t\t\t});\n\n\t\t\thandleApiExceptions(json, response.status);\n\n\t\t\t// We’re assuming no other exceptions have happened.\n\t\t\treturn json;\n\t\t},\n\t};\n};\n\nexport const SdkError = {\n\tNotFound: NotFoundError,\n\tUnauthorised: UnauthorisedError,\n\tSchemaValidation: SchemaValidationError,\n\tApi: ApiError,\n\tJsonParsing: JsonParsingError,\n};\n\nexport function isSdkError(error: unknown): error is (typeof SdkError)[keyof typeof SdkError] {\n\treturn Object.values(SdkError).some(ErrorClass => error instanceof ErrorClass);\n}\n","{\n\t\"name\": \"@inploi/sdk\",\n\t\"version\": \"1.15.3\",\n\t\"main\": \"dist/index.js\",\n\t\"types\": \"dist/index.d.ts\",\n\t\"license\": \"MIT\",\n\t\"files\": [\n\t\t\"/dist\",\n\t\t\"/cdn\"\n\t],\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"require\": \"./dist/index.js\",\n\t\t\t\"import\": \"./dist/index.mjs\",\n\t\t\t\"types\": \"./dist/index.d.ts\"\n\t\t}\n\t},\n\t\"scripts\": {\n\t\t\"build:npm\": \"tsup --dts --dts-resolve\",\n\t\t\"build:cdn\": \"tsup --config tsup.cdn.config.ts\",\n\t\t\"build\": \"concurrently 'pnpm run build:npm' 'pnpm run build:cdn'\",\n\t\t\"dev\": \"tsup --watch --config tsup.cdn.config.ts\",\n\t\t\"check\": \"eslint src --fix --max-warnings 0 && tsc\",\n\t\t\"test\": \"bun test\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@happy-dom/global-registrator\": \"^13.6.2\",\n\t\t\"@inploi/core\": \"workspace:*\",\n\t\t\"@total-typescript/ts-reset\": \"^0.5.1\",\n\t\t\"@types/bun\": \"^1.2.5\",\n\t\t\"@types/react\": \"^18.2.33\",\n\t\t\"@types/react-dom\": \"^18.2.14\",\n\t\t\"autoprefixer\": \"^10.4.16\",\n\t\t\"concurrently\": \"9.1.2\",\n\t\t\"eslint\": \"^7.32.0\",\n\t\t\"eslint-config-custom\": \"workspace:*\",\n\t\t\"happy-dom\": \"^12.6.0\",\n\t\t\"ts-toolbelt\": \"^9.6.0\",\n\t\t\"tsconfig\": \"workspace:*\",\n\t\t\"tsup\": \"^7.2.0\"\n\t},\n\t\"dependencies\": {\n\t\t\"@standard-schema/spec\": \"^1.0.0\",\n\t\t\"neoqs\": \"^6.13.0\"\n\t}\n}\n","import { version } from '../package.json';\n\n/**\n * The environment the SDK should run in.\n * - `production`: data will be stored and displayed on dashboards\n * - `sandbox`: data will be stored temporarily and purged periodically\n */\nexport type InploiSdkEnvironment = 'production' | 'sandbox';\n\nexport const ENV_TO_API_URL: Record<InploiSdkEnvironment, string> = {\n\tsandbox: 'https://api.staging.inploi.com',\n\tproduction: 'https://api.inploi.com',\n\t// @ts-expect-error - local test environment\n\t_internal_local: 'http://api.test',\n};\n\nexport const ANALYTICS_VERSION = version;\n\nexport const LOG_PATHNAME = '/log';\n\nexport const ANALYTICS_COOKIE_NAME = 'isdk_session';\n","import type { ResponseObj } from '@inploi/core/common';\nimport { invariant } from '@inploi/core/common';\n\nimport { InploiRpcClient, Logger, endpoint, typed } from '.';\nimport { ANALYTICS_COOKIE_NAME, ANALYTICS_VERSION } from './sdk.constants';\n\nconst formatCookie = (value: string) => {\n\tconst now = new Date();\n\tnow.setTime(now.getTime() + 7 * 24 * 60 * 60 * 1000); // 7 days expiration\n\n\treturn `${ANALYTICS_COOKIE_NAME}=${value};expires=${now.toUTCString()};path=/`;\n};\n\ntype FlowProperties = { flow_id: string; flow_version: number; flow_session_id: string; flow_build: number };\n\ntype JobProperties = {\n\tid: string;\n\tid_type: 'internal' | 'external';\n};\n\nexport type AnalyticsLogParams =\n\t| {\n\t\t\tevent: 'VIEW_JOB';\n\t\t\tproperties: { job: JobProperties };\n\t }\n\t| {\n\t\t\tevent: 'FLOW_REDIRECT';\n\t\t\tproperties: { href: string; job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_START' | 'FLOW_END';\n\t\t\tproperties: { job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_NODE';\n\t\t\tproperties: {\n\t\t\t\t/** Increments by 1 per node interpreted */\n\t\t\t\tsequence: number;\n\t\t\t\tfrom_node_id: string;\n\t\t\t\tto_node_id: string;\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_SUBMIT';\n\t\t\tproperties: {\n\t\t\t\tservice: string;\n\t\t\t\tresponse: {\n\t\t\t\t\tstatus: number;\n\t\t\t\t\tpayload: unknown;\n\t\t\t\t};\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'SUBMIT_FORM' | 'VIEW_PAGE';\n\t\t\tproperties?: {\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'IDENTIFY';\n\t\t\tproperties: {\n\t\t\t\tidentifier: string;\n\t\t\t\tfirst_name?: string;\n\t\t\t\tlast_name?: string;\n\t\t\t\tphone_number?: string;\n\t\t\t\temail?: string;\n\t\t\t\tcustom_traits?: Record<string, unknown>;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_PAGINATE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_SETTLE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_JOB_CLICK';\n\t\t\tproperties: {\n\t\t\t\tjob_id: number;\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'VIEW_SEARCH';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'FEEDBACK';\n\t\t\tproperties: {\n\t\t\t\tkey: string;\n\t\t\t\tscore?: -1 | 0 | 1;\n\t\t\t\tcomment?: string;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'LINK_CLICK';\n\t\t\tproperties: {\n\t\t\t\ttarget_href: string;\n\t\t\t\tjob_id: string | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'INTERACTION';\n\t\t\tproperties: {\n\t\t\t\ttag: string;\n\t\t\t};\n\t };\n\nexport type AnalyticsLogEvent = AnalyticsLogParams['event'];\n\ntype EventPropertyMap = {\n\t[Param in AnalyticsLogParams as Param['event']]: Omit<Param, 'event'>;\n};\n\ntype AnalyticsContext = {\n\tlibrary: {\n\t\tname: 'inploi-sdk';\n\t\tversion: string;\n\t};\n\tpage: {\n\t\thref: string;\n\t\treferrer: string;\n\t\ttitle: string;\n\t};\n};\n\ntype TrackPayload<P = EventPropertyMap[keyof EventPropertyMap]['properties']> = {\n\tanonymous_id: string | null;\n\tsession_id: string | null;\n\tevent: AnalyticsLogEvent;\n\tsent_at: string;\n\tcontext: AnalyticsContext;\n\tproperties: P;\n\tcustom_properties?: Record<string, unknown>;\n};\n\ntype LogFnParams<T extends keyof EventPropertyMap> = {\n\tevent: T;\n\tcustomProperties?: Record<string, unknown>;\n\t/** Passing a request will make logging possible on a server environment. */\n\trequest?: Request;\n} & EventPropertyMap[T];\n\ntype LogFn = <TEvent extends keyof EventPropertyMap>(\n\tparams: LogFnParams<TEvent>,\n) => Promise<ResponseObj<TrackPayload<EventPropertyMap[TEvent]['properties']>>>;\n\nexport type AnalyticsService = {\n\tlog: LogFn;\n\t/** From a log payload data, generate headers to use in server environments to update the anonymous_id */\n\tgetHeaders: (payload?: TrackPayload) => Headers;\n\tgetSessionInfo: typeof getSessionInfo;\n};\n\nconst getSessionId = (searchParams: URLSearchParams, isServer: boolean) => {\n\tconst fromSearchParams = searchParams.get('session_id');\n\tif (isServer) return fromSearchParams;\n\tif (fromSearchParams) return fromSearchParams;\n\tconst fromSessionStorage = sessionStorage.getItem(`${ANALYTICS_COOKIE_NAME}-session_id`);\n\tif (typeof fromSessionStorage === 'string') return fromSessionStorage;\n\treturn null;\n};\n\nconst cookieRegex = new RegExp(`${ANALYTICS_COOKIE_NAME}=([^;]+)`);\nconst getSessionInfo = (request?: Request) => {\n\tconst href = request ? request.url : location.href;\n\tconst { searchParams } = new URL(href);\n\tconst anonymous_id = searchParams.get('anonymous_id');\n\tconst session_id = getSessionId(searchParams, typeof window === 'undefined');\n\n\t// If there’s an anonymous_id in the search params, use it\n\tif (anonymous_id)\n\t\treturn {\n\t\t\tanonymous_id,\n\t\t\tsession_id,\n\t\t};\n\n\t// If there’s a cookie, use it\n\tconst cookie = request ? request.headers.get('cookie') : document.cookie;\n\tif (cookie) {\n\t\tconst match = cookieRegex.exec(cookie);\n\t\tconst anonymous_id = match?.[1];\n\t\treturn {\n\t\t\tanonymous_id: anonymous_id ?? null,\n\t\t\tsession_id,\n\t\t};\n\t}\n\n\t// Otherwise, return what we have\n\treturn {\n\t\tanonymous_id,\n\t\tsession_id,\n\t};\n};\n\nconst getSessionInfoFromResponse = (response: unknown) => {\n\tif (typeof response !== 'object' || response === null) return null;\n\treturn {\n\t\tanonymous_id:\n\t\t\t'anonymous_id' in response && typeof response.anonymous_id === 'string' ? response.anonymous_id : null,\n\t\tsession_id: 'session_id' in response && typeof response.session_id === 'string' ? response.session_id : null,\n\t};\n};\n\nconst serverReferrer = (referrer: typeof Request.prototype.referrer) => {\n\tif (referrer === 'about:client') return '';\n\treturn referrer;\n};\n\nconst analyticsLogEndpoint = endpoint({\n\tpathname: '/log',\n\tmethod: 'POST',\n\tschema: {\n\t\tresponse: typed<unknown>(),\n\t\tbody: typed<TrackPayload>(),\n\t},\n});\n\nexport type AnalyticsOnEventCallback = (event: AnalyticsLogParams) => void;\n\nexport const createAnalyticsService = ({\n\trpcClient,\n\tlogger,\n\tonEvent,\n}: {\n\tlogger: Logger;\n\trpcClient: InploiRpcClient;\n\tonEvent?: AnalyticsOnEventCallback;\n}): AnalyticsService => {\n\tconst logFn: LogFn = async params => {\n\t\tinvariant(\n\t\t\tparams.request || typeof window !== 'undefined',\n\t\t\t'Cannot log on the server without a request. Please pass a request to `log`.',\n\t\t);\n\n\t\t// if there’s a request, use it instead of browser APIs\n\t\tconst page =\n\t\t\t'request' in params && params.request ?\n\t\t\t\t{\n\t\t\t\t\thref: params.request.url,\n\t\t\t\t\treferrer: serverReferrer(params.request.referrer),\n\t\t\t\t\ttitle: '',\n\t\t\t\t}\n\t\t\t:\t{\n\t\t\t\t\thref: location.href,\n\t\t\t\t\treferrer: document.referrer,\n\t\t\t\t\ttitle: document.title,\n\t\t\t\t};\n\n\t\ttry {\n\t\t\tconst context: AnalyticsContext = {\n\t\t\t\tlibrary: {\n\t\t\t\t\tname: 'inploi-sdk',\n\t\t\t\t\tversion: ANALYTICS_VERSION,\n\t\t\t\t},\n\t\t\t\tpage,\n\t\t\t};\n\n\t\t\tconst sessionInfo = getSessionInfo(params.request);\n\t\t\tconst payload: TrackPayload = {\n\t\t\t\tanonymous_id: sessionInfo.anonymous_id,\n\t\t\t\tsession_id: sessionInfo.session_id,\n\t\t\t\tevent: params.event,\n\t\t\t\tsent_at: new Date().toISOString(),\n\t\t\t\tcontext,\n\t\t\t\tproperties: params.properties,\n\t\t\t\tcustom_properties: params.customProperties,\n\t\t\t};\n\n\t\t\tconst responseJson = await rpcClient.request(analyticsLogEndpoint, {\n\t\t\t\tbody: payload,\n\t\t\t});\n\n\t\t\tconst newSession = getSessionInfoFromResponse(responseJson);\n\t\t\tif (newSession?.anonymous_id) {\n\t\t\t\tpayload.anonymous_id = newSession.anonymous_id;\n\t\t\t}\n\t\t\tif (newSession?.session_id) {\n\t\t\t\tpayload.session_id = newSession.session_id;\n\t\t\t}\n\n\t\t\tif (typeof window !== 'undefined' && payload.anonymous_id) {\n\t\t\t\tif (payload.session_id) {\n\t\t\t\t\tsessionStorage.setItem(`${ANALYTICS_COOKIE_NAME}-session_id`, payload.session_id.toString());\n\t\t\t\t}\n\t\t\t\tdocument.cookie = formatCookie(payload.anonymous_id);\n\t\t\t}\n\n\t\t\tonEvent?.(payload as AnalyticsLogParams);\n\t\t\treturn { success: true, data: payload };\n\t\t} catch (e) {\n\t\t\t/** We dont’t log any PII on the console */\n\t\t\tlogger.error('Failed to send log to API. Inspect error response of `log` for more information.');\n\t\t\treturn { success: false, error: e };\n\t\t}\n\t};\n\n\treturn {\n\t\tlog: logFn,\n\t\tgetHeaders: payload => {\n\t\t\tconst headers = new Headers();\n\t\t\tif (!payload?.anonymous_id) return headers;\n\n\t\t\theaders.append('Set-Cookie', formatCookie(payload.anonymous_id));\n\t\t\treturn headers;\n\t\t},\n\t\tgetSessionInfo,\n\t};\n};\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { stringify } from 'neoqs';\n\nimport { JsonParsingError, SchemaValidationError, handleApiExceptions } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger } from './sdk.logger';\n\ntype RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\n/** Extract parameter names from a pathname string */\ntype ExtractParamNames<T extends string> =\n\tT extends `${infer _Before}:${infer Param}/${infer After}` ? Param | ExtractParamNames<`/${After}`>\n\t: T extends `${infer _Before}:${infer Param}` ? Param\n\t: never;\n\n/** Create params object from parameter names */\ntype ExtractPathParams<T extends string> =\n\tstring extends T ? Record<string, string | number>\n\t: ExtractParamNames<T> extends never ? Record<string, never>\n\t: { [K in ExtractParamNames<T>]: string | number };\n\n/** Parses a StandardSchemaV1 schema and input into an output. */\nexport function parse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n\tsource?: 'body' | 'searchParams' | 'response',\n): StandardSchemaV1.InferOutput<T> {\n\tconst result = schema['~standard'].validate(input);\n\tif (result instanceof Promise) {\n\t\tthrow new TypeError('Async schema');\n\t}\n\n\tif (result.issues) {\n\t\tthrow new SchemaValidationError(result.issues, source);\n\t}\n\n\treturn result.value;\n}\n\n/** Parses a StandardSchemaV1 schema and input into an output, returning a success flag and issues if the parse fails. */\nexport function safeParse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n\tsource?: 'body' | 'searchParams' | 'response',\n):\n\t| {\n\t\t\tsuccess: true;\n\t\t\toutput: StandardSchemaV1.InferOutput<T>;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t\t\tsource?: 'body' | 'searchParams' | 'response';\n\t } {\n\ttry {\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\toutput: parse(schema, input, source),\n\t\t};\n\t} catch (e) {\n\t\tif (e instanceof SchemaValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tissues: e.issues,\n\t\t\t\tsource: e.source,\n\t\t\t};\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nexport interface InploiRpcClientParams {\n\tenvironment: InploiSdkEnvironment;\n\tlogger: Logger;\n\tapiKey:\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-secret-key header\n\t\t\t\t * This will error if used in a browser environment.\n\t\t\t\t */\n\t\t\t\ttype: 'secret';\n\t\t\t\tkey: string;\n\t\t }\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-publishable-key header\n\t\t\t\t * This can be called in a browser or server environment.\n\t\t\t\t */\n\t\t\t\ttype: 'publishable';\n\t\t\t\tkey: string;\n\t\t };\n}\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype NonReducibleUnknown = {} | null | undefined;\ntype LooseAutocomplete<T extends BaseType, BaseType> = T | BaseType;\n\n/** RPC client for making API calls to the Inploi API. */\nexport class InploiRpcClient {\n\tprivate baseUrl: string;\n\tprivate headers: Headers;\n\tprivate logger: Logger;\n\n\tconstructor(params: InploiRpcClientParams) {\n\t\tthis.baseUrl = ENV_TO_API_URL[params.environment];\n\t\tthis.headers = new Headers({\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t});\n\t\tif (params.apiKey.type === 'secret') {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\tthrow new Error('Secret key cannot be used in a browser environment');\n\t\t\t}\n\t\t\tthis.headers.set('x-secret-key', params.apiKey.key);\n\t\t} else {\n\t\t\tthis.headers.set('x-publishable-key', params.apiKey.key);\n\t\t}\n\t\tthis.logger = params.logger;\n\t}\n\n\t/** Gets params for a fetch request to the given endpoint */\n\tgetFetchParams<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ?\n\t\t\tGetSchemaValues<{\n\t\t\t\tbody: TBody;\n\t\t\t\tsearchParams: TSearch;\n\t\t\t\tparams: TPathParams;\n\t\t\t}> & {\n\t\t\t\tsignal?: AbortSignal;\n\t\t\t\t/**\n\t\t\t\t * Whether to validate the inputs against the schema.\n\t\t\t\t * If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.\n\t\t\t\t */\n\t\t\t\tvalidateIn?: boolean;\n\t\t\t}\n\t\t:\tnever,\n\t): [url: string, options: RequestInit] {\n\t\tconst validateIn = options.validateIn ?? true;\n\t\tconst { searchParams, body } = validateIn ? validateEndpointInputs(endpoint, options) : options;\n\n\t\tconst url = new URL(this.baseUrl);\n\n\t\t// Replace path parameters in pathname\n\t\tlet pathname = endpoint.pathname;\n\t\tif ('params' in options && options.params) {\n\t\t\tfor (const [key, value] of Object.entries(options.params)) {\n\t\t\t\tpathname = pathname.replace(`:${key}`, String(value));\n\t\t\t}\n\t\t}\n\t\turl.pathname = pathname;\n\n\t\tif (endpoint.schema.searchParams) {\n\t\t\turl.search = stringify(searchParams);\n\t\t}\n\n\t\treturn [\n\t\t\turl.toString(),\n\t\t\t{\n\t\t\t\tmethod: endpoint.method,\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\theaders: this.headers,\n\t\t\t\tsignal: options.signal,\n\t\t\t},\n\t\t];\n\t}\n\n\t/** Parses a response against an endpoint’s response schema, considering common errors thrown from the API.\n\t * @throws {JsonParsingError} - If the response is not valid JSON.\n\t * @throws {SchemaValidationError} - If the response does not match the schema.\n\t * @throws {ApiError} - If the API responded with an error message.\n\t */\n\tasync parseResponse<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: {\n\t\t\tresponse: Response;\n\t\t\t/**\n\t\t\t * Whether to validate the response against the schema.\n\t\t\t * This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.\n\t\t\t * ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.\n\t\t\t */\n\t\t\tvalidateOut?: boolean;\n\t\t},\n\t): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>> {\n\t\tconst json = await options.response.json().catch(e => {\n\t\t\tthis.logger.error(e);\n\t\t\tthrow new JsonParsingError(options.response);\n\t\t});\n\n\t\tconst validateOut = options.validateOut ?? true;\n\t\tif (!validateOut) return json as StandardSchemaV1.InferOutput<T['schema']['response']>;\n\n\t\tconst result = safeParse(endpoint.schema.response, json, 'response');\n\t\tif (!result.success) {\n\t\t\thandleApiExceptions(json, options.response.status);\n\t\t\tthrow new SchemaValidationError(result.issues, result.source);\n\t\t}\n\n\t\treturn result.output as StandardSchemaV1.InferOutput<T['schema']['response']>;\n\t}\n\n\t/** Fetches, parses and validates an API endpoint.\n\t * Logs errors and throws them again so that the caller can handle them.\n\t *\n\t * @throws {JsonParsingError} - If the response is not valid JSON.\n\t * @throws {SchemaValidationError} - If the searchParams, body or response does not match the schema.\n\t * @throws {ApiError} - If the API responded with an error message.\n\t * @throws {UnauthorisedError} - If the request is unauthorised either by missing key or unmet permissions.\n\t * @throws {NotFoundError} - If the endpoint is not found.\n\t * @throws {Error} - Another unhandled error.\n\t */\n\tasync request<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ?\n\t\t\tGetSchemaValues<{\n\t\t\t\tbody: TBody;\n\t\t\t\tsearchParams: TSearch;\n\t\t\t\tparams: TPathParams;\n\t\t\t}> & {\n\t\t\t\tsignal?: AbortSignal;\n\t\t\t\t/**\n\t\t\t\t * Whether to validate the inputs against the schema.\n\t\t\t\t * If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.\n\t\t\t\t */\n\t\t\t\tvalidateIn?: boolean;\n\t\t\t\t/**\n\t\t\t\t * Whether to validate the response against the schema.\n\t\t\t\t * This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.\n\t\t\t\t * ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.\n\t\t\t\t */\n\t\t\t\tvalidateOut?: boolean;\n\t\t\t}\n\t\t:\tnever,\n\t): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>> {\n\t\ttry {\n\t\t\tconst fetchParams = this.getFetchParams(endpoint, options);\n\t\t\tconst response = await fetch(...fetchParams);\n\t\t\treturn this.parseResponse(endpoint, { response, validateOut: options.validateOut });\n\t\t} catch (e) {\n\t\t\tif (e instanceof SchemaValidationError) {\n\t\t\t\tthis.logger.error(e.message, e.issues);\n\t\t\t} else {\n\t\t\t\tthis.logger.error(e);\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n}\n\ntype GetSchemaValues<T extends { searchParams: any; body: any; params?: any }> = {\n\t[K in keyof T as T[K] extends never ? never\n\t: T[K] extends Record<string, never> ? never\n\t: K]: T[K] extends never ? never : LooseAutocomplete<T[K], NonReducibleUnknown>;\n};\n\n/**\n * Typed but *not runtime validated* schema\n * useful for type-checking the schema without bundling validation schemas\n */\nexport function typed<T>(): StandardSchemaV1<T, T> {\n\treturn {\n\t\t'~standard': {\n\t\t\tvendor: 'inploi',\n\t\t\tversion: 1,\n\t\t\tvalidate: input => {\n\t\t\t\treturn {\n\t\t\t\t\tvalue: input as T,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t};\n}\n\nexport interface RpcEndpoint<\n\tTMethod extends RequestMethod = RequestMethod,\n\tTPathname extends string = string,\n\tTPathParams = any,\n\tTSearch = any,\n\tTBody = any,\n\tTResponse = any,\n> {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: StandardSchemaV1<TSearch, TSearch>;\n\t\tbody?: StandardSchemaV1<TBody, TBody>;\n\t\tresponse: StandardSchemaV1<TResponse, TResponse>;\n\t};\n\t/** Type-only property to store path parameter types */\n\treadonly __pathParams?: TPathParams;\n}\n\nexport function endpoint<\n\tTMethod extends RequestMethod,\n\tTPathname extends string,\n\tTSearch extends StandardSchemaV1 | never = never,\n\tTBody extends StandardSchemaV1 | never = never,\n\tTResponse extends StandardSchemaV1 | never = never,\n>(endpoint: {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: TSearch;\n\t\tbody?: TBody;\n\t\tresponse: TResponse;\n\t};\n}) {\n\ttype PathParams = ExtractPathParams<TPathname>;\n\treturn endpoint as RpcEndpoint<\n\t\tTMethod,\n\t\tTPathname,\n\t\tPathParams,\n\t\tStandardSchemaV1.InferInput<TSearch>,\n\t\tStandardSchemaV1.InferInput<TBody>,\n\t\tStandardSchemaV1.InferOutput<TResponse>\n\t>;\n}\n\n/** Validates the inputs for an endpoint ahead of time\n * Useful when you need to validate and throw earlier, or use the inputs for something other than the API call.\n */\nexport function validateEndpointInputs<T extends RpcEndpoint>(\n\tendpoint: T,\n\toptions: GetSchemaValues<{ body: unknown; searchParams: unknown }>,\n) {\n\tconst validatedInputs = {\n\t\tsearchParams: undefined,\n\t\tbody: undefined,\n\t\tvalidateIn: false,\n\t} as T extends RpcEndpoint<infer _, infer __, infer ___, infer TSearch, infer TBody> ?\n\t\tGetSchemaValues<{\n\t\t\tbody: TBody;\n\t\t\tsearchParams: TSearch;\n\t\t}> & {\n\t\t\tvalidateIn: false;\n\t\t}\n\t:\tnever;\n\n\tif (endpoint.schema.searchParams) {\n\t\tvalidatedInputs.searchParams = parse(\n\t\t\tendpoint.schema.searchParams,\n\t\t\t'searchParams' in options ? options.searchParams : {},\n\t\t);\n\t}\n\n\tif (endpoint.schema.body) {\n\t\tvalidatedInputs.body = parse(endpoint.schema.body, 'body' in options ? options.body : {});\n\t}\n\n\treturn validatedInputs;\n}\n","import { AnalyticsOnEventCallback, createAnalyticsService } from './sdk.analytics';\nimport { createApiClient } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger, inploiBrandedLogger, noLogging } from './sdk.logger';\nimport { InploiSdkPlugin } from './sdk.plugins';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type InitialiseInploiSdkParams = {\n\t/** Your public API key for the inploi SDK. */\n\tpublishableKey: string;\n\t/** Which app environment to run. This ultimately affects which inploi endpoints to gather data are going to be used.\n\t * Anything other than `production` should be considered a development environment and the data periodicaly purged. */\n\tenv: InploiSdkEnvironment;\n\t/** Logger object that handles logging of different levels.\n\t * You can override this to use your own logger, or to disable logging altogether by passing`false`.\n\t * @default inploiBrandedLogger\n\t * */\n\tlogger?: Logger | false;\n\n\t/** When provided, this callback will be called with every event that is logged to the analytics service. */\n\tonEvent?: AnalyticsOnEventCallback;\n};\n\nexport function initialiseSdk({\n\tpublishableKey,\n\tenv,\n\tlogger = inploiBrandedLogger,\n\tonEvent,\n}: InitialiseInploiSdkParams) {\n\t/** @deprecated - use `rpcClient` instead */\n\tconst apiClient = createApiClient({ baseUrl: ENV_TO_API_URL[env], publishableKey });\n\tconst loggerService = logger === false ? noLogging : logger;\n\tconst rpcClient = new InploiRpcClient({\n\t\tenvironment: env,\n\t\tapiKey: { type: 'publishable', key: publishableKey },\n\t\tlogger: loggerService,\n\t});\n\tconst analytics = createAnalyticsService({ rpcClient, logger: loggerService, onEvent });\n\n\tconst register = <P extends InploiSdkPlugin>(plugin: P): ReturnType<P> => {\n\t\treturn plugin({ logger: loggerService, apiClient, analytics, rpcClient });\n\t};\n\n\treturn { register, analytics, apiClient };\n}\n\nexport type InploiSdk = ReturnType<typeof initialiseSdk>;\n"],"mappings":"q9BAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,cAAAE,EAAA,oBAAAC,EAAA,kBAAAC,EAAA,iBAAAC,EAAA,0BAAAC,EAAA,aAAAC,EAAA,sBAAAC,EAAA,iBAAAC,EAAA,aAAAC,EAAA,kBAAAC,EAAA,wBAAAC,EAAA,eAAAC,EAAA,cAAAC,EAAA,UAAAC,EAAA,2BAAAC,IAAA,eAAAC,GAAAjB,ICAO,IAAMkB,EAAiB,iBACjBC,EAAgB,qCAUhBC,EAA8B,CAC1C,KAAM,IAAIC,IAAS,QAAQ,KAAKH,EAAgBC,EAAe,GAAGE,CAAI,EACtE,MAAO,IAAIA,IAAS,QAAQ,MAAMH,EAAgBC,EAAe,GAAGE,CAAI,EACxE,KAAM,IAAIA,IAAS,QAAQ,KAAKH,EAAgBC,EAAe,GAAGE,CAAI,EACtE,IAAK,IAAIA,IAAS,QAAQ,IAAIH,EAAgBC,EAAe,GAAGE,CAAI,CACrE,EAEaC,EAAoB,CAAE,KAAM,IAAG,GAAW,MAAO,IAAG,GAAW,IAAK,IAAG,GAAW,KAAM,IAAG,EAAU,ECM3G,IAAMC,EAA2CC,GAAgBA,ECpBjE,SAASC,EAAUC,EAAgBC,EAAqC,CAC9E,GAAI,CAAAD,EAIJ,MAAM,IAAI,MAAMC,CAAO,CACxB,CA2BO,SAASC,EAA+BC,EAAcC,EAAqC,CACjG,OAAOA,KAAQD,CAChB,CE9BA,IAAME,GAAoB,IAAI,KAAK,mBAAmB,OAAW,CAAE,QAAS,MAAO,CAAC,ECN7E,IAAMC,GAAyB,kBACzBC,GAAsB,+BAEtBC,EAAN,cAA8B,KAAM,CAE1C,YAAYC,EAAkBC,EAAiB,CAC9C,MAAMD,CAAO,EACb,KAAK,OAASC,EACd,KAAK,KAAO,iBACb,CACD,EAEaC,EAAN,cAA4BH,CAAgB,CAClD,YAAYC,EAAkB,CAC7B,MAAMA,GAAA,KAAAA,EAAW,WAAW,EAC5B,KAAK,KAAO,gBACZ,KAAK,OAAS,GACf,CACD,EAEaG,EAAN,cAAgCJ,CAAgB,CACtD,YAAYC,EAAkBC,EAAiB,CAC9C,MAAMD,GAAA,KAAAA,EAAW,gDAAgD,EACjE,KAAK,KAAO,oBACZ,KAAK,OAASC,GAAA,KAAAA,EAAU,GACzB,CACD,EAEaG,EAAN,cAAoCL,CAAgB,CAC1D,YACQM,EACAC,EACN,CACD,IAAMC,EAAaD,EAAS,OAAOA,CAAM,GAAK,GAC9C,MAAM,2BAA2BC,CAAU,EAAE,EAJtC,YAAAF,EACA,YAAAC,EAIP,KAAK,KAAO,wBACZ,KAAK,OAAS,GACf,CACD,EAEaE,EAAN,cAAuBT,CAAgB,CAC7C,YAAYC,EAAiBC,EAAiB,CAC7C,MAAMD,CAAO,EACb,KAAK,KAAO,WACZ,KAAK,OAASC,GAAA,KAAAA,EAAU,GACzB,CACD,EAEaQ,EAAN,cAA+BV,CAAgB,CACrD,YAAmBW,EAAqB,CACvC,MAAM,mCAAmC,EADvB,cAAAA,EAElB,KAAK,KAAO,eACZ,KAAK,OAAS,GACf,CACD,EASA,IAAMC,GAAqB,CAAC,UAAW,QAAS,SAAU,YAAa,YAAY,EACnF,SAASC,GAAwBC,EAAuB,CACvD,QAAQ,IAAI,OAAQA,CAAI,EACxB,IAAMC,EAAqB,CAAC,EAC5B,GAAI,OAAOD,GAAS,UAAYA,IAAS,MACxC,QAAWE,KAAOJ,GACjB,GAAIK,EAAQH,EAAME,CAAG,EAAG,CACvB,QAAQ,IAAI,UAAWA,EAAKF,EAAKE,CAAG,CAAC,EACrC,IAAME,EAAQJ,EAAKE,CAAG,EAClB,OAAOE,GAAU,UAAUH,EAAS,KAAKG,CAAK,EAC9C,MAAM,QAAQA,CAAK,GAAKA,EAAM,MAAOC,GAAyB,OAAOA,GAAS,QAAQ,GACzFJ,EAAS,KAAK,GAAGG,CAAK,CACxB,EAGF,OAAIH,EAAS,SAAW,GAAGA,EAAS,KAAK,eAAe,EACjDA,EAAS,KAAK,IAAI,CAC1B,CAGO,SAASK,EAAoBN,EAAeO,EAAgB,CAClE,GAAIA,GAAU,KAAOA,GAAU,IAAK,CACnC,IAAMC,EAAUT,GAAwBC,CAAI,EAC5C,MAAIO,IAAW,IACR,IAAIE,EAAcD,CAAO,EAE5BA,IAAYE,GACT,IAAIC,EAAkB,6BAA8BJ,CAAM,EAE7DC,IAAYI,GACT,IAAID,EAAkBH,EAASD,CAAM,EAEtC,IAAIM,EAASL,EAASD,CAAM,CACnC,CACD,CAEO,IAAMO,EAAmBC,GAAmE,CAClG,IAAMC,EAA8B,CACnC,OAAQ,mBACR,eAAgB,mBAChB,oBAAqBD,EAAO,cAC7B,EAEA,MAAO,CAIN,MAAO,CAAOE,KAA2BC,IAAAC,EAAA,QAA3BF,EAA2B,GAAAC,GAAA,UAA3BE,EAAUC,EAAU,CAAC,EAAM,CACxC,IAAMC,EAAOC,EAAAC,EAAA,GAAKH,GAAL,CAAc,QAASG,IAAA,GAAKH,EAAQ,SAAYL,EAAiB,GACxES,EAAW,MAAM,MAAM,GAAGV,EAAO,OAAO,GAAGK,CAAQ,GAAIE,CAAI,EACjE,GAAIG,EAAS,SAAW,IAAK,MAAM,IAAIhB,EAEvC,IAAMT,EAAO,MAAMyB,EAAS,KAAK,EAAE,MAAM,IAAYN,EAAA,wBACpD,MAAM,IAAIO,EAAiBD,CAAQ,CACpC,EAAC,EAED,OAAAnB,EAAoBN,EAAMyB,EAAS,MAAM,EAGlCzB,CACR,EACD,CACD,EAEa2B,EAAW,CACvB,SAAUlB,EACV,aAAcE,EACd,iBAAkBiB,EAClB,IAAKf,EACL,YAAaa,CACd,EAEO,SAASG,EAAWC,EAAmE,CAC7F,OAAO,OAAO,OAAOH,CAAQ,EAAE,KAAKI,GAAcD,aAAiBC,CAAU,CAC9E,CC1IC,IAAAC,EAAW,SCOL,IAAMC,EAAuD,CACnE,QAAS,iCACT,WAAY,yBAEZ,gBAAiB,iBAClB,EAEaC,EAAoBC,EAI1B,IAAMC,EAAwB,eCdrC,IAAMC,EAAgBC,GAAkB,CACvC,IAAMC,EAAM,IAAI,KAChB,OAAAA,EAAI,QAAQA,EAAI,QAAQ,EAAI,EAAI,GAAK,GAAK,GAAK,GAAI,EAE5C,GAAGC,CAAqB,IAAIF,CAAK,YAAYC,EAAI,YAAY,CAAC,SACtE,EA6KME,GAAe,CAACC,EAA+BC,IAAsB,CAC1E,IAAMC,EAAmBF,EAAa,IAAI,YAAY,EAEtD,GADIC,GACAC,EAAkB,OAAOA,EAC7B,IAAMC,EAAqB,eAAe,QAAQ,GAAGL,CAAqB,aAAa,EACvF,OAAI,OAAOK,GAAuB,SAAiBA,EAC5C,IACR,EAEMC,GAAc,IAAI,OAAO,GAAGN,CAAqB,UAAU,EAC3DO,EAAkBC,GAAsB,CAC7C,IAAMC,EAAOD,EAAUA,EAAQ,IAAM,SAAS,KACxC,CAAE,aAAAN,CAAa,EAAI,IAAI,IAAIO,CAAI,EAC/BC,EAAeR,EAAa,IAAI,cAAc,EAC9CS,EAAaV,GAAaC,EAAc,OAAO,QAAW,WAAW,EAG3E,GAAIQ,EACH,MAAO,CACN,aAAAA,EACA,WAAAC,CACD,EAGD,IAAMC,EAASJ,EAAUA,EAAQ,QAAQ,IAAI,QAAQ,EAAI,SAAS,OAClE,GAAII,EAAQ,CACX,IAAMC,EAAQP,GAAY,KAAKM,CAAM,EAC/BF,EAAeG,GAAA,YAAAA,EAAQ,GAC7B,MAAO,CACN,aAAcH,GAAA,KAAAA,EAAgB,KAC9B,WAAAC,CACD,CACD,CAGA,MAAO,CACN,aAAAD,EACA,WAAAC,CACD,CACD,EAEMG,GAA8BC,GAC/B,OAAOA,GAAa,UAAYA,IAAa,KAAa,KACvD,CACN,aACC,iBAAkBA,GAAY,OAAOA,EAAS,cAAiB,SAAWA,EAAS,aAAe,KACnG,WAAY,eAAgBA,GAAY,OAAOA,EAAS,YAAe,SAAWA,EAAS,WAAa,IACzG,EAGKC,GAAkBC,GACnBA,IAAa,eAAuB,GACjCA,EAGFC,GAAgC,CACrC,SAAU,OACV,OAAQ,OACR,OAAQ,CACP,SAAUC,EAAe,EACzB,KAAMA,EAAoB,CAC3B,CACD,EAIaC,EAAyB,CAAC,CACtC,UAAAC,EACA,OAAAC,EACA,QAAAC,CACD,KAyEQ,CACN,IArE0BC,GAAUC,EAAA,wBACpCC,EACCF,EAAO,SAAW,OAAO,QAAW,YACpC,6EACD,EAGA,IAAMG,EACL,YAAaH,GAAUA,EAAO,QAC7B,CACC,KAAMA,EAAO,QAAQ,IACrB,SAAUR,GAAeQ,EAAO,QAAQ,QAAQ,EAChD,MAAO,EACR,EACC,CACA,KAAM,SAAS,KACf,SAAU,SAAS,SACnB,MAAO,SAAS,KACjB,EAEF,GAAI,CACH,IAAMI,EAA4B,CACjC,QAAS,CACR,KAAM,aACN,QAASC,CACV,EACA,KAAAF,CACD,EAEMG,EAAcvB,EAAeiB,EAAO,OAAO,EAC3CO,EAAwB,CAC7B,aAAcD,EAAY,aAC1B,WAAYA,EAAY,WACxB,MAAON,EAAO,MACd,QAAS,IAAI,KAAK,EAAE,YAAY,EAChC,QAAAI,EACA,WAAYJ,EAAO,WACnB,kBAAmBA,EAAO,gBAC3B,EAEMQ,EAAe,MAAMX,EAAU,QAAQH,GAAsB,CAClE,KAAMa,CACP,CAAC,EAEKE,EAAanB,GAA2BkB,CAAY,EAC1D,OAAIC,GAAA,MAAAA,EAAY,eACfF,EAAQ,aAAeE,EAAW,cAE/BA,GAAA,MAAAA,EAAY,aACfF,EAAQ,WAAaE,EAAW,YAG7B,OAAO,QAAW,aAAeF,EAAQ,eACxCA,EAAQ,YACX,eAAe,QAAQ,GAAG/B,CAAqB,cAAe+B,EAAQ,WAAW,SAAS,CAAC,EAE5F,SAAS,OAASlC,EAAakC,EAAQ,YAAY,GAGpDR,GAAA,MAAAA,EAAUQ,GACH,CAAE,QAAS,GAAM,KAAMA,CAAQ,CACvC,OAASG,EAAG,CAEX,OAAAZ,EAAO,MAAM,kFAAkF,EACxF,CAAE,QAAS,GAAO,MAAOY,CAAE,CACnC,CACD,GAIC,WAAYH,GAAW,CACtB,IAAMI,EAAU,IAAI,QACpB,OAAKJ,GAAA,MAAAA,EAAS,cAEdI,EAAQ,OAAO,aAActC,EAAakC,EAAQ,YAAY,CAAC,EACxDI,CACR,EACA,eAAA5B,CACD,GChVD,IAAA6B,EAA0B,iBAqBnB,SAASC,EACfC,EACAC,EACAC,EACkC,CAClC,IAAMC,EAASH,EAAO,WAAW,EAAE,SAASC,CAAK,EACjD,GAAIE,aAAkB,QACrB,MAAM,IAAI,UAAU,cAAc,EAGnC,GAAIA,EAAO,OACV,MAAM,IAAIC,EAAsBD,EAAO,OAAQD,CAAM,EAGtD,OAAOC,EAAO,KACf,CAGO,SAASE,GACfL,EACAC,EACAC,EAUI,CACJ,GAAI,CACH,MAAO,CACN,QAAS,GACT,OAAQH,EAAMC,EAAQC,EAAOC,CAAM,CACpC,CACD,OAASI,EAAG,CACX,GAAIA,aAAaF,EAChB,MAAO,CACN,QAAS,GACT,OAAQE,EAAE,OACV,OAAQA,EAAE,MACX,EAED,MAAMA,CACP,CACD,CA2BO,IAAMC,EAAN,KAAsB,CAK5B,YAAYC,EAA+B,CAM1C,GALA,KAAK,QAAUC,EAAeD,EAAO,WAAW,EAChD,KAAK,QAAU,IAAI,QAAQ,CAC1B,eAAgB,mBAChB,OAAQ,kBACT,CAAC,EACGA,EAAO,OAAO,OAAS,SAAU,CACpC,GAAI,OAAO,QAAW,YACrB,MAAM,IAAI,MAAM,oDAAoD,EAErE,KAAK,QAAQ,IAAI,eAAgBA,EAAO,OAAO,GAAG,CACnD,MACC,KAAK,QAAQ,IAAI,oBAAqBA,EAAO,OAAO,GAAG,EAExD,KAAK,OAASA,EAAO,MACtB,CAGA,eACCE,EACAC,EAcsC,CAvIxC,IAAAC,EAwIE,IAAMC,GAAaD,EAAAD,EAAQ,aAAR,KAAAC,EAAsB,GACnC,CAAE,aAAAE,EAAc,KAAAC,CAAK,EAAIF,EAAaG,EAAuBN,EAAUC,CAAO,EAAIA,EAElFM,EAAM,IAAI,IAAI,KAAK,OAAO,EAG5BC,EAAWR,EAAS,SACxB,GAAI,WAAYC,GAAWA,EAAQ,OAClC,OAAW,CAACQ,EAAKC,CAAK,IAAK,OAAO,QAAQT,EAAQ,MAAM,EACvDO,EAAWA,EAAS,QAAQ,IAAIC,CAAG,GAAI,OAAOC,CAAK,CAAC,EAGtD,OAAAH,EAAI,SAAWC,EAEXR,EAAS,OAAO,eACnBO,EAAI,UAAS,aAAUH,CAAY,GAG7B,CACNG,EAAI,SAAS,EACb,CACC,OAAQP,EAAS,OACjB,KAAMK,EAAO,KAAK,UAAUA,CAAI,EAAI,OACpC,QAAS,KAAK,QACd,OAAQJ,EAAQ,MACjB,CACD,CACD,CAOM,cACLD,EACAC,EASiE,QAAAU,EAAA,sBArLnE,IAAAT,EAsLE,IAAMU,EAAO,MAAMX,EAAQ,SAAS,KAAK,EAAE,MAAML,GAAK,CACrD,WAAK,OAAO,MAAMA,CAAC,EACb,IAAIiB,EAAiBZ,EAAQ,QAAQ,CAC5C,CAAC,EAGD,GAAI,GADgBC,EAAAD,EAAQ,cAAR,KAAAC,EAAuB,IACzB,OAAOU,EAEzB,IAAMnB,EAASE,GAAUK,EAAS,OAAO,SAAUY,EAAM,UAAU,EACnE,GAAI,CAACnB,EAAO,QACX,MAAAqB,EAAoBF,EAAMX,EAAQ,SAAS,MAAM,EAC3C,IAAIP,EAAsBD,EAAO,OAAQA,EAAO,MAAM,EAG7D,OAAOA,EAAO,MACf,GAYM,QACLO,EACAC,EAoBiE,QAAAU,EAAA,sBACjE,GAAI,CACH,IAAMI,EAAc,KAAK,eAAef,EAAUC,CAAO,EACnDe,EAAW,MAAM,MAAM,GAAGD,CAAW,EAC3C,OAAO,KAAK,cAAcf,EAAU,CAAE,SAAAgB,EAAU,YAAaf,EAAQ,WAAY,CAAC,CACnF,OAASL,EAAG,CACX,MAAIA,aAAaF,EAChB,KAAK,OAAO,MAAME,EAAE,QAASA,EAAE,MAAM,EAErC,KAAK,OAAO,MAAMA,CAAC,EAEdA,CACP,CACD,GACD,EAYO,SAASqB,GAAmC,CAClD,MAAO,CACN,YAAa,CACZ,OAAQ,SACR,QAAS,EACT,SAAU1B,IACF,CACN,MAAOA,CACR,EAEF,CACD,CACD,CAsBO,SAASS,EAMdA,EASC,CAEF,OAAOA,CAQR,CAKO,SAASM,EACfN,EACAC,EACC,CACD,IAAMiB,EAAkB,CACvB,aAAc,OACd,KAAM,OACN,WAAY,EACb,EASA,OAAIlB,EAAS,OAAO,eACnBkB,EAAgB,aAAe7B,EAC9BW,EAAS,OAAO,aAChB,iBAAkBC,EAAUA,EAAQ,aAAe,CAAC,CACrD,GAGGD,EAAS,OAAO,OACnBkB,EAAgB,KAAO7B,EAAMW,EAAS,OAAO,KAAM,SAAUC,EAAUA,EAAQ,KAAO,CAAC,CAAC,GAGlFiB,CACR,CCvUO,SAASC,EAAc,CAC7B,eAAAC,EACA,IAAAC,EACA,OAAAC,EAASC,EACT,QAAAC,CACD,EAA8B,CAE7B,IAAMC,EAAYC,EAAgB,CAAE,QAASC,EAAeN,CAAG,EAAG,eAAAD,CAAe,CAAC,EAC5EQ,EAAgBN,IAAW,GAAQO,EAAYP,EAC/CQ,EAAY,IAAIC,EAAgB,CACrC,YAAaV,EACb,OAAQ,CAAE,KAAM,cAAe,IAAKD,CAAe,EACnD,OAAQQ,CACT,CAAC,EACKI,EAAYC,EAAuB,CAAE,UAAAH,EAAW,OAAQF,EAAe,QAAAJ,CAAQ,CAAC,EAMtF,MAAO,CAAE,SAJoCU,GACrCA,EAAO,CAAE,OAAQN,EAAe,UAAAH,EAAW,UAAAO,EAAW,UAAAF,CAAU,CAAC,EAGtD,UAAAE,EAAW,UAAAP,CAAU,CACzC","names":["src_exports","__export","ApiError","InploiRpcClient","NotFoundError","JsonParsingError","SchemaValidationError","SdkError","UnauthorisedError","createPlugin","endpoint","initialiseSdk","inploiBrandedLogger","isSdkError","noLogging","typed","validateEndpointInputs","__toCommonJS","CONSOLE_PREFIX","CONSOLE_STYLE","inploiBrandedLogger","args","noLogging","createPlugin","pluginFn","invariant","condition","message","hasProp","data","prop","DEFAULT_FORMATTER","unauthenticatedMessage","unauthorisedMessage","ErrorWithStatus","message","status","NotFoundError","UnauthorisedError","SchemaValidationError","issues","source","sourceText","ApiError","JsonParsingError","response","ERROR_MESSAGE_KEYS","getErrorMessageFromJson","json","messages","key","hasProp","value","item","handleApiExceptions","status","message","NotFoundError","unauthenticatedMessage","UnauthorisedError","unauthorisedMessage","ApiError","createApiClient","params","defaultHeaders","_0","_1","__async","pathname","options","init","__spreadProps","__spreadValues","response","JsonParsingError","SdkError","SchemaValidationError","isSdkError","error","ErrorClass","version","ENV_TO_API_URL","ANALYTICS_VERSION","version","ANALYTICS_COOKIE_NAME","formatCookie","value","now","ANALYTICS_COOKIE_NAME","getSessionId","searchParams","isServer","fromSearchParams","fromSessionStorage","cookieRegex","getSessionInfo","request","href","anonymous_id","session_id","cookie","match","getSessionInfoFromResponse","response","serverReferrer","referrer","analyticsLogEndpoint","typed","createAnalyticsService","rpcClient","logger","onEvent","params","__async","invariant","page","context","ANALYTICS_VERSION","sessionInfo","payload","responseJson","newSession","e","headers","import_neoqs","parse","schema","input","source","result","SchemaValidationError","safeParse","e","InploiRpcClient","params","ENV_TO_API_URL","endpoint","options","_a","validateIn","searchParams","body","validateEndpointInputs","url","pathname","key","value","__async","json","JsonParsingError","handleApiExceptions","fetchParams","response","typed","validatedInputs","initialiseSdk","publishableKey","env","logger","inploiBrandedLogger","onEvent","apiClient","createApiClient","ENV_TO_API_URL","loggerService","noLogging","rpcClient","InploiRpcClient","analytics","createAnalyticsService","plugin"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var $=Object.defineProperty,D=Object.defineProperties;var H=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var J=Object.prototype.hasOwnProperty,Y=Object.prototype.propertyIsEnumerable;var O=(r,e,n)=>e in r?$(r,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):r[e]=n,S=(r,e)=>{for(var n in e||(e={}))J.call(e,n)&&O(r,n,e[n]);if(L)for(var n of L(e))Y.call(e,n)&&O(r,n,e[n]);return r},C=(r,e)=>D(r,H(e));var l=(r,e,n)=>new Promise((t,o)=>{var a=i=>{try{s(n.next(i))}catch(d){o(d)}},p=i=>{try{s(n.throw(i))}catch(d){o(d)}},s=i=>i.done?t(i.value):Promise.resolve(i.value).then(a,p);s((n=n.apply(r,e)).next())});var v="%c[inploi SDK]",_="color: #65BC67; font-weight: bold;",E={warn:(...r)=>console.warn(v,_,...r),error:(...r)=>console.error(v,_,...r),info:(...r)=>console.info(v,_,...r),log:(...r)=>console.log(v,_,...r)},I={info:()=>{},error:()=>{},log:()=>{},warn:()=>{}};var G=r=>r;function w(r,e){if(!r)throw new Error(e)}function k(r,e){return e in r}var Te=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});var W="Unauthenticated",z="This action is unauthorized.",m=class extends Error{constructor(n,t){super(n);this.status=t,this.name="ErrorWithStatus"}},f=class extends m{constructor(e){super(e!=null?e:"Not found"),this.name="NotFoundError",this.status=404}},y=class extends m{constructor(e,n){super(e!=null?e:"You are not authorised to perform this action."),this.name="UnauthorisedError",this.status=n!=null?n:401}},u=class extends m{constructor(n,t){let o=t?` in ${t}`:"";super(`Schema validation failed${o}`);this.issues=n;this.source=t;this.name="SchemaValidationError",this.status=400}},h=class extends m{constructor(e,n){super(e),this.name="ApiError",this.status=n!=null?n:500}},g=class extends m{constructor(n){super("Error parsing response into JSON.");this.response=n;this.name="ParsingError",this.status=500}};var X=["message","error","errors","exception","exceptions"];function Z(r){console.log("json",r);let e=[];if(typeof r=="object"&&r!==null){for(let n of X)if(k(r,n)){console.log("hasProp",n,r[n]);let t=r[n];typeof t=="string"&&e.push(t),Array.isArray(t)&&t.every(o=>typeof o=="string")&&e.push(...t)}}return e.length===0&&e.push("Unknown error"),e.join(", ")}function R(r,e){if(e>=300&&e<=500){let n=Z(r);throw e===404?new f(n):n===W?new y("You are not authenticated.",e):n===z?new y(n,e):new h(n,e)}}var N=r=>{let e={Accept:"application/json","Content-Type":"application/json","x-publishable-key":r.publishableKey};return{fetch:(o,...a)=>l(void 0,[o,...a],function*(n,t={}){let p=C(S({},t),{headers:S(S({},t.headers),e)}),s=yield fetch(`${r.baseUrl}${n}`,p);if(s.status===404)throw new f;let i=yield s.json().catch(()=>l(void 0,null,function*(){throw new g(s)}));return R(i,s.status),i})}},V={NotFound:f,Unauthorised:y,SchemaValidation:u,Api:h,JsonParsing:g};function Q(r){return Object.values(V).some(e=>r instanceof e)}var M="1.15.3";var x={sandbox:"https://api.staging.inploi.com",production:"https://api.inploi.com",_internal_local:"http://api.test"},F=M;var T="isdk_session";var B=r=>{let e=new Date;return e.setTime(e.getTime()+7*24*60*60*1e3),`${T}=${r};expires=${e.toUTCString()};path=/`},re=(r,e)=>{let n=r.get("session_id");if(e||n)return n;let t=sessionStorage.getItem(`${T}-session_id`);return typeof t=="string"?t:null},ne=new RegExp(`${T}=([^;]+)`),q=r=>{let e=r?r.url:location.href,{searchParams:n}=new URL(e),t=n.get("anonymous_id"),o=re(n,typeof window=="undefined");if(t)return{anonymous_id:t,session_id:o};let a=r?r.headers.get("cookie"):document.cookie;if(a){let p=ne.exec(a),s=p==null?void 0:p[1];return{anonymous_id:s!=null?s:null,session_id:o}}return{anonymous_id:t,session_id:o}},te=r=>typeof r!="object"||r===null?null:{anonymous_id:"anonymous_id"in r&&typeof r.anonymous_id=="string"?r.anonymous_id:null,session_id:"session_id"in r&&typeof r.session_id=="string"?r.session_id:null},oe=r=>r==="about:client"?"":r,se={pathname:"/log",method:"POST",schema:{response:b(),body:b()}},j=({rpcClient:r,logger:e,onEvent:n})=>({log:o=>l(void 0,null,function*(){w(o.request||typeof window!="undefined","Cannot log on the server without a request. Please pass a request to `log`.");let a="request"in o&&o.request?{href:o.request.url,referrer:oe(o.request.referrer),title:""}:{href:location.href,referrer:document.referrer,title:document.title};try{let p={library:{name:"inploi-sdk",version:F},page:a},s=q(o.request),i={anonymous_id:s.anonymous_id,session_id:s.session_id,event:o.event,sent_at:new Date().toISOString(),context:p,properties:o.properties,custom_properties:o.customProperties},d=yield r.request(se,{body:i}),c=te(d);return c!=null&&c.anonymous_id&&(i.anonymous_id=c.anonymous_id),c!=null&&c.session_id&&(i.session_id=c.session_id),typeof window!="undefined"&&i.anonymous_id&&(i.session_id&&sessionStorage.setItem(`${T}-session_id`,i.session_id.toString()),document.cookie=B(i.anonymous_id)),n==null||n(i),{success:!0,data:i}}catch(p){return e.error("Failed to send log to API. Inspect error response of `log` for more information."),{success:!1,error:p}}}),getHeaders:o=>{let a=new Headers;return o!=null&&o.anonymous_id&&a.append("Set-Cookie",B(o.anonymous_id)),a},getSessionInfo:q});import{stringify as ie}from"neoqs";function A(r,e,n){let t=r["~standard"].validate(e);if(t instanceof Promise)throw new TypeError("Async schema");if(t.issues)throw new u(t.issues,n);return t.value}function ae(r,e,n){try{return{success:!0,output:A(r,e,n)}}catch(t){if(t instanceof u)return{success:!1,issues:t.issues,source:t.source};throw t}}var P=class{constructor(e){if(this.baseUrl=x[e.environment],this.headers=new Headers({"Content-Type":"application/json",Accept:"application/json"}),e.apiKey.type==="secret"){if(typeof window!="undefined")throw new Error("Secret key cannot be used in a browser environment");this.headers.set("x-secret-key",e.apiKey.key)}else this.headers.set("x-publishable-key",e.apiKey.key);this.logger=e.logger}getFetchParams(e,n){var i;let t=(i=n.validateIn)!=null?i:!0,{searchParams:o,body:a}=t?K(e,n):n,p=new URL(this.baseUrl),s=e.pathname;if("params"in n&&n.params)for(let[d,c]of Object.entries(n.params))s=s.replace(`:${d}`,String(c));return p.pathname=s,e.schema.searchParams&&(p.search=ie(o)),[p.toString(),{method:e.method,body:a?JSON.stringify(a):void 0,headers:this.headers,signal:n.signal}]}parseResponse(e,n){return l(this,null,function*(){var p;let t=yield n.response.json().catch(s=>{throw this.logger.error(s),new g(n.response)});if(!((p=n.validateOut)!=null?p:!0))return t;let a=ae(e.schema.response,t,"response");if(!a.success)throw R(t,n.response.status),new u(a.issues,a.source);return a.output})}request(e,n){return l(this,null,function*(){try{let t=this.getFetchParams(e,n),o=yield fetch(...t);return this.parseResponse(e,{response:o,validateOut:n.validateOut})}catch(t){throw t instanceof u?this.logger.error(t.message,t.issues):this.logger.error(t),t}})}};function b(){return{"~standard":{vendor:"inploi",version:1,validate:r=>({value:r})}}}function U(r){return r}function K(r,e){let n={searchParams:void 0,body:void 0,validateIn:!1};return r.schema.searchParams&&(n.searchParams=A(r.schema.searchParams,"searchParams"in e?e.searchParams:{})),r.schema.body&&(n.body=A(r.schema.body,"body"in e?e.body:{})),n}function pe({publishableKey:r,env:e,logger:n=E,onEvent:t}){let o=N({baseUrl:x[e],publishableKey:r}),a=n===!1?I:n,p=new P({environment:e,apiKey:{type:"publishable",key:r},logger:a}),s=j({rpcClient:p,logger:a,onEvent:t});return{register:d=>d({logger:a,apiClient:o,analytics:s,rpcClient:p}),analytics:s,apiClient:o}}export{h as ApiError,P as InploiRpcClient,f as NotFoundError,g as ParsingError,u as SchemaValidationError,V as SdkError,y as UnauthorisedError,G as createPlugin,U as endpoint,pe as initialiseSdk,E as inploiBrandedLogger,Q as isSdkError,I as noLogging,b as typed,K as validateEndpointInputs};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sdk.logger.ts","../src/sdk.plugins.ts","../src/sdk.api.ts","../../core/src/common/common.utils.ts","../../core/src/common/common.currency.ts","../../core/src/common/common.datetime.ts","../package.json","../src/sdk.constants.ts","../src/sdk.analytics.ts","../src/sdk.rpc.ts","../src/sdk.ts"],"sourcesContent":["export const CONSOLE_PREFIX = '%c[inploi SDK]';\nexport const CONSOLE_STYLE = 'color: #65BC67; font-weight: bold;';\n\ntype LogMessage = (...data: any[]) => void;\nexport type Logger = {\n\twarn: LogMessage;\n\terror: LogMessage;\n\tinfo: LogMessage;\n\tlog: LogMessage;\n};\n\nexport const inploiBrandedLogger: Logger = {\n\twarn: (...args) => console.warn(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\terror: (...args) => console.error(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tinfo: (...args) => console.info(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tlog: (...args) => console.log(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n};\n\nexport const noLogging: Logger = { info: () => void 0, error: () => void 0, log: () => void 0, warn: () => void 0 };\n","import { AnalyticsService } from './sdk.analytics';\nimport { ApiClient } from './sdk.api';\nimport { Logger } from './sdk.logger';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type PluginParams = {\n\tapiClient: ApiClient;\n\tlogger: Logger;\n};\n\nexport type Plugin<T extends string, P extends Record<string, unknown>> = {\n\tpluginName: T;\n\tpure_createActions: (params: PluginParams) => P;\n};\n\ntype PluginDependencies = {\n\tapiClient: ApiClient;\n\trpcClient: InploiRpcClient;\n\tlogger: Logger;\n\tanalytics: AnalyticsService;\n};\n\nexport type InploiSdkPlugin = (dependencies: PluginDependencies) => any;\n\nexport const createPlugin = <T extends InploiSdkPlugin>(pluginFn: T) => pluginFn;\n","import { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport const unauthenticatedMessage = 'Unauthenticated';\nexport const unauthorisedMessage = 'This action is unauthorized.';\n\nexport class NotFoundError extends Error {\n\tconstructor() {\n\t\tsuper('Not found');\n\t\tthis.name = 'NotFoundError';\n\t}\n}\n\nexport class UnauthorisedError extends Error {\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'You are not authorised to perform this action.');\n\t\tthis.name = 'UnauthorisedError';\n\t}\n}\n\nexport class SchemaValidationError extends Error {\n\tconstructor(public issues: readonly StandardSchemaV1.Issue[]) {\n\t\tsuper('Schema validation failed');\n\t\tthis.name = 'SchemaValidationError';\n\t}\n}\n\nexport class ApiError extends Error {\n\terrors: unknown[];\n\tconstructor(message: string, errors: unknown[]) {\n\t\tsuper(message);\n\t\tthis.name = 'ApiError';\n\t\tthis.errors = errors;\n\t}\n}\n\nexport class JsonParsingError extends Error {\n\tconstructor(public response?: Response) {\n\t\tsuper('Error parsing response into JSON.');\n\t\tthis.name = 'ParsingError';\n\t}\n}\n\n/** @deprecated - use `JsonParsingError` instead */\nexport class ParsingError extends JsonParsingError {}\n\nexport type ApiClient = {\n\tfetch: (pathname: string, options?: RequestInit) => Promise<unknown>;\n};\n\n/** Throws branded errors when API returns a known error. */\nexport function handleApiExceptions(json: unknown) {\n\tif (json === null) return;\n\n\tif (typeof json === 'object') {\n\t\tlet message = 'Generic API Error';\n\t\tif ('message' in json && typeof json.message === 'string') message = json.message;\n\n\t\tif (message === unauthenticatedMessage) {\n\t\t\tthrow new UnauthorisedError('You are not authenticated.');\n\t\t}\n\t\tif (message === unauthorisedMessage) {\n\t\t\tthrow new UnauthorisedError();\n\t\t}\n\t\tif ('exception' in json) {\n\t\t\tthrow new ApiError(message, [json.exception]);\n\t\t}\n\t\tif ('errors' in json) {\n\t\t\tif (Array.isArray(json.errors) && json.errors.every(error => typeof error === 'string')) {\n\t\t\t\tthrow new ApiError(message, json.errors);\n\t\t\t}\n\t\t\tif (typeof json.errors === 'object' && json.errors !== null) {\n\t\t\t\tconst entries = Object.entries(json.errors);\n\n\t\t\t\tif (entries.every(([, value]) => Array.isArray(value) && value.every(error => typeof error === 'string'))) {\n\t\t\t\t\tthrow new SchemaValidationError(\n\t\t\t\t\t\tentries.map(\n\t\t\t\t\t\t\t([key, value]): StandardSchemaV1.Issue => ({\n\t\t\t\t\t\t\t\tpath: key.split('.'),\n\t\t\t\t\t\t\t\tmessage: value.join(', '),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow new ApiError(\n\t\t\t\t\tmessage,\n\t\t\t\t\tentries.map(([key, value]) => `${key}: ${value}`),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (typeof json.errors === 'string') throw new ApiError(message, [json.errors]);\n\t\t}\n\t\tif ('error' in json && typeof json.error === 'string') {\n\t\t\tthrow new ApiError(json.error, [json.error]);\n\t\t}\n\t}\n}\n\nexport const createApiClient = (params: { baseUrl: string; publishableKey: string }): ApiClient => {\n\tconst defaultHeaders: HeadersInit = {\n\t\tAccept: 'application/json',\n\t\t'Content-Type': 'application/json',\n\t\t'x-publishable-key': params.publishableKey,\n\t};\n\n\treturn {\n\t\t/** Fetches from a pathname with a pre-established base path.\n\t\t * Parses received output as JSON, and throw if one of the common error messages is received.\n\t\t */\n\t\tfetch: async (pathname, options = {}) => {\n\t\t\tconst init = { ...options, headers: { ...options.headers, ...defaultHeaders } };\n\t\t\tconst response = await fetch(`${params.baseUrl}${pathname}`, init);\n\t\t\tif (response.status === 404) throw new NotFoundError();\n\n\t\t\tconst json = await response.json().catch(async () => {\n\t\t\t\tthrow new JsonParsingError(response);\n\t\t\t});\n\n\t\t\thandleApiExceptions(json);\n\n\t\t\t// We’re assuming no other exceptions have happened.\n\t\t\treturn json;\n\t\t},\n\t};\n};\n\nexport const SdkError = {\n\tNotFound: NotFoundError,\n\tUnauthorised: UnauthorisedError,\n\tSchemaValidation: SchemaValidationError,\n\tApi: ApiError,\n\tJsonParsing: JsonParsingError,\n};\n\nexport function isSdkError(error: unknown): error is (typeof SdkError)[keyof typeof SdkError] {\n\treturn Object.values(SdkError).some(ErrorClass => error instanceof ErrorClass);\n}\n","export const exhaustive = (value: never) => {\n\tthrow new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);\n};\n\nexport function invariant(condition: any, message?: string): asserts condition {\n\tif (condition) {\n\t\treturn;\n\t}\n\n\tthrow new Error(message);\n}\n\nexport const uniqueOrThrow = <T>(array: T[]) => {\n\tconst uniqueValues = new Set(array);\n\n\tif (array.length !== uniqueValues.size) {\n\t\tthrow new Error('Duplicate values found');\n\t}\n\treturn true;\n};\n\nexport const uniqueByPropertyOrThrow =\n\t<T extends PropertyKey>(propertyKey: T) =>\n\t(array: { [K in T]: any }[]) => {\n\t\tconst values = array.map(item => item[propertyKey]);\n\t\tconst uniqueValues = new Set(values);\n\n\t\tif (values.length !== uniqueValues.size) {\n\t\t\tthrow new Error(`Duplicate values found for property: ${propertyKey.toString()}`);\n\t\t}\n\t\treturn true;\n\t};\n\n/**\n * A destructive way to ensure an object has a property.\n * This is useful when working with unknowns.\n */\nexport function hasProp<K extends PropertyKey>(data: object, prop: K): data is Record<K, unknown> {\n\treturn prop in data;\n}\n\n/**\n * A sort of type-safe way to check whether a key exists in an object.\n */\nexport function isKeyInObj<O extends Record<string, unknown>>(key: PropertyKey, obj: O): key is keyof O {\n\treturn key in obj;\n}\n","type TFunction = (key: 'competitive' | 'invalid_salary' | 'from' | 'up_to') => string;\n\ninterface SalaryParams {\n\tpay: string | null;\n\tpay_min: string | null;\n\tpay_mask: boolean;\n\tpay_max: string | null;\n\tpay_type: 'ANNUALLY' | 'HOURLY' | 'MONTHLY' | 'WEEKLY' | 'DAILY' | null;\n\tpay_currency: string;\n\tpay_display: boolean;\n}\n\nconst payPeriods: Record<NonNullable<SalaryParams['pay_type']>, string> = {\n\tANNUALLY: 'per year',\n\tDAILY: 'per day',\n\tHOURLY: 'per hour',\n\tMONTHLY: 'per month',\n\tWEEKLY: 'per week',\n};\n\nexport const getSalaryAsText = (params: {\n\tsalary: SalaryParams;\n\tconfig: { locales: string | string[] | undefined };\n\tt?: TFunction;\n}) => {\n\tconst { salary, config, t = s => s } = params;\n\tconst numberFormatter = new Intl.NumberFormat(config.locales, {\n\t\tstyle: 'currency',\n\t\tcurrency: salary.pay_currency,\n\t\t// @ts-expect-error - CI/CD is not happy with this, though locally it works\n\t\ttrailingZeroDisplay: 'stripIfInteger',\n\t});\n\tif (salary.pay_display === false) return undefined;\n\tif (salary.pay_mask) return t('competitive');\n\n\tif (salary.pay_max && Number.isNaN(+salary.pay_max)) return t('invalid_salary');\n\tif (salary.pay_min && Number.isNaN(+salary.pay_min)) return t('invalid_salary');\n\tif (salary.pay && Number.isNaN(+salary.pay)) return t('invalid_salary');\n\n\tconst period = salary.pay_type && salary.pay_type in payPeriods ? payPeriods[salary.pay_type] : undefined;\n\n\tif (salary.pay) return [numberFormatter.format(+salary.pay), period].filter(Boolean).join(' ');\n\n\tif (salary.pay_max && salary.pay_min)\n\t\treturn [numberFormatter.formatRange(+salary.pay_min, +salary.pay_max), period].filter(Boolean).join(' ') || '';\n\n\tif (salary.pay_max)\n\t\treturn `${t('up_to')} ${[numberFormatter.format(+salary.pay_max), period].filter(Boolean).join(' ')}`;\n\tif (salary.pay_min)\n\t\treturn `${t('from')} ${[numberFormatter.format(+salary.pay_min), period].filter(Boolean).join(' ')}`;\n\treturn t('invalid_salary');\n};\n","type TFunction = (key: 'today' | 'over_30_days_ago' | 'in_over_30_days') => string;\n\ntype Params = {\n\tfrom?: Date;\n\tto: string | number | Date;\n\tformatter?: Intl.RelativeTimeFormat;\n\tt?: TFunction;\n};\n\nconst DEFAULT_FORMATTER = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });\n/** From a date, calculates the relative time difference from now */\nexport const getRelativeTimeDifference = ({\n\tfrom = new Date(),\n\tto,\n\tformatter = DEFAULT_FORMATTER,\n\tt = s => s,\n}: Params) => {\n\tconst then = to instanceof Date ? to : new Date(to);\n\tconst diff = then.getTime() - from.getTime();\n\n\tconst diffIn = {\n\t\tdays: Math.round(diff / 1000 / 60 / 60 / 24),\n\t\tmonths: Math.round(diff / 1000 / 60 / 60 / 24 / 30),\n\t};\n\n\tif (diffIn.days === 0) return t('today');\n\tif (Math.abs(diffIn.days) < 30) return formatter.format(diffIn.days, 'days');\n\tif (Math.abs(diffIn.days) < 3) return formatter.format(diffIn.months, 'months');\n\treturn diffIn.months < 0 ? t('over_30_days_ago') : t('in_over_30_days');\n};\n","{\n\t\"name\": \"@inploi/sdk\",\n\t\"version\": \"1.15.2\",\n\t\"main\": \"dist/index.js\",\n\t\"types\": \"dist/index.d.ts\",\n\t\"license\": \"MIT\",\n\t\"files\": [\n\t\t\"/dist\",\n\t\t\"/cdn\"\n\t],\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"require\": \"./dist/index.js\",\n\t\t\t\"import\": \"./dist/index.mjs\",\n\t\t\t\"types\": \"./dist/index.d.ts\"\n\t\t}\n\t},\n\t\"scripts\": {\n\t\t\"build:npm\": \"tsup --dts --dts-resolve\",\n\t\t\"build:cdn\": \"tsup --config tsup.cdn.config.ts\",\n\t\t\"build\": \"concurrently 'pnpm run build:npm' 'pnpm run build:cdn'\",\n\t\t\"dev\": \"tsup --watch --config tsup.cdn.config.ts\",\n\t\t\"check\": \"eslint src --fix --max-warnings 0 && tsc\",\n\t\t\"test\": \"bun test\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@happy-dom/global-registrator\": \"^13.6.2\",\n\t\t\"@inploi/core\": \"workspace:*\",\n\t\t\"@total-typescript/ts-reset\": \"^0.5.1\",\n\t\t\"@types/bun\": \"^1.2.5\",\n\t\t\"@types/react\": \"^18.2.33\",\n\t\t\"@types/react-dom\": \"^18.2.14\",\n\t\t\"autoprefixer\": \"^10.4.16\",\n\t\t\"concurrently\": \"9.1.2\",\n\t\t\"eslint\": \"^7.32.0\",\n\t\t\"eslint-config-custom\": \"workspace:*\",\n\t\t\"happy-dom\": \"^12.6.0\",\n\t\t\"ts-toolbelt\": \"^9.6.0\",\n\t\t\"tsconfig\": \"workspace:*\",\n\t\t\"tsup\": \"^7.2.0\"\n\t},\n\t\"dependencies\": {\n\t\t\"@standard-schema/spec\": \"^1.0.0\",\n\t\t\"neoqs\": \"^6.13.0\"\n\t}\n}\n","import { version } from '../package.json';\n\n/**\n * The environment the SDK should run in.\n * - `production`: data will be stored and displayed on dashboards\n * - `sandbox`: data will be stored temporarily and purged periodically\n */\nexport type InploiSdkEnvironment = 'production' | 'sandbox';\n\nexport const ENV_TO_API_URL: Record<InploiSdkEnvironment, string> = {\n\tsandbox: 'https://api.staging.inploi.com',\n\tproduction: 'https://api.inploi.com',\n\t// @ts-expect-error - local test environment\n\t_internal_local: 'http://api.test',\n};\n\nexport const ANALYTICS_VERSION = version;\n\nexport const LOG_PATHNAME = '/log';\n\nexport const ANALYTICS_COOKIE_NAME = 'isdk_session';\n","import type { ResponseObj } from '@inploi/core/common';\nimport { invariant } from '@inploi/core/common';\n\nimport { InploiRpcClient, Logger, endpoint, typed } from '.';\nimport { ANALYTICS_COOKIE_NAME, ANALYTICS_VERSION } from './sdk.constants';\n\nconst formatCookie = (value: string) => {\n\tconst now = new Date();\n\tnow.setTime(now.getTime() + 7 * 24 * 60 * 60 * 1000); // 7 days expiration\n\n\treturn `${ANALYTICS_COOKIE_NAME}=${value};expires=${now.toUTCString()};path=/`;\n};\n\ntype FlowProperties = { flow_id: string; flow_version: number; flow_session_id: string; flow_build: number };\n\ntype JobProperties = {\n\tid: string;\n\tid_type: 'internal' | 'external';\n};\n\ntype AnalyticsLogParams =\n\t| {\n\t\t\tevent: 'VIEW_JOB';\n\t\t\tproperties: { job: JobProperties };\n\t }\n\t| {\n\t\t\tevent: 'FLOW_REDIRECT';\n\t\t\tproperties: { href: string; job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_START' | 'FLOW_END';\n\t\t\tproperties: { job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_NODE';\n\t\t\tproperties: {\n\t\t\t\t/** Increments by 1 per node interpreted */\n\t\t\t\tsequence: number;\n\t\t\t\tfrom_node_id: string;\n\t\t\t\tto_node_id: string;\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_SUBMIT';\n\t\t\tproperties: {\n\t\t\t\tservice: string;\n\t\t\t\tresponse: {\n\t\t\t\t\tstatus: number;\n\t\t\t\t\tpayload: unknown;\n\t\t\t\t};\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'SUBMIT_FORM' | 'VIEW_PAGE';\n\t\t\tproperties?: {\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'IDENTIFY';\n\t\t\tproperties: {\n\t\t\t\tidentifier: string;\n\t\t\t\tfirst_name?: string;\n\t\t\t\tlast_name?: string;\n\t\t\t\tphone_number?: string;\n\t\t\t\temail?: string;\n\t\t\t\tcustom_traits?: Record<string, unknown>;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_PAGINATE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_SETTLE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_JOB_CLICK';\n\t\t\tproperties: {\n\t\t\t\tjob_id: number;\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'VIEW_SEARCH';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'FEEDBACK';\n\t\t\tproperties: {\n\t\t\t\tkey: string;\n\t\t\t\tscore?: -1 | 0 | 1;\n\t\t\t\tcomment?: string;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'LINK_CLICK';\n\t\t\tproperties: {\n\t\t\t\ttarget_href: string;\n\t\t\t\tjob_id: string | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'INTERACTION';\n\t\t\tproperties: {\n\t\t\t\ttag: string;\n\t\t\t};\n\t };\n\nexport type AnalyticsLogEvent = AnalyticsLogParams['event'];\n\ntype EventPropertyMap = {\n\t[Param in AnalyticsLogParams as Param['event']]: Omit<Param, 'event'>;\n};\n\ntype AnalyticsContext = {\n\tlibrary: {\n\t\tname: 'inploi-sdk';\n\t\tversion: string;\n\t};\n\tpage: {\n\t\thref: string;\n\t\treferrer: string;\n\t\ttitle: string;\n\t};\n};\n\ntype TrackPayload<P = EventPropertyMap[keyof EventPropertyMap]['properties']> = {\n\tanonymous_id: string | null;\n\tsession_id: string | null;\n\tevent: AnalyticsLogEvent;\n\tsent_at: string;\n\tcontext: AnalyticsContext;\n\tproperties: P;\n\tcustom_properties?: Record<string, unknown>;\n};\n\ntype LogFnParams<T extends keyof EventPropertyMap> = {\n\tevent: T;\n\tcustomProperties?: Record<string, unknown>;\n\t/** Passing a request will make logging possible on a server environment. */\n\trequest?: Request;\n} & EventPropertyMap[T];\n\ntype LogFn = <TEvent extends keyof EventPropertyMap>(\n\tparams: LogFnParams<TEvent>,\n) => Promise<ResponseObj<TrackPayload<EventPropertyMap[TEvent]['properties']>>>;\n\nexport type AnalyticsService = {\n\tlog: LogFn;\n\t/** From a log payload data, generate headers to use in server environments to update the anonymous_id */\n\tgetHeaders: (payload?: TrackPayload) => Headers;\n\tgetSessionInfo: typeof getSessionInfo;\n};\n\nconst getSessionId = (searchParams: URLSearchParams, isServer: boolean) => {\n\tconst fromSearchParams = searchParams.get('session_id');\n\tif (isServer) return fromSearchParams;\n\tif (fromSearchParams) return fromSearchParams;\n\tconst fromSessionStorage = sessionStorage.getItem(`${ANALYTICS_COOKIE_NAME}-session_id`);\n\tif (typeof fromSessionStorage === 'string') return fromSessionStorage;\n\treturn null;\n};\n\nconst cookieRegex = new RegExp(`${ANALYTICS_COOKIE_NAME}=([^;]+)`);\nconst getSessionInfo = (request?: Request) => {\n\tconst href = request ? request.url : location.href;\n\tconst { searchParams } = new URL(href);\n\tconst anonymous_id = searchParams.get('anonymous_id');\n\tconst session_id = getSessionId(searchParams, typeof window === 'undefined');\n\n\t// If there’s an anonymous_id in the search params, use it\n\tif (anonymous_id)\n\t\treturn {\n\t\t\tanonymous_id,\n\t\t\tsession_id,\n\t\t};\n\n\t// If there’s a cookie, use it\n\tconst cookie = request ? request.headers.get('cookie') : document.cookie;\n\tif (cookie) {\n\t\tconst match = cookieRegex.exec(cookie);\n\t\tconst anonymous_id = match?.[1];\n\t\treturn {\n\t\t\tanonymous_id: anonymous_id ?? null,\n\t\t\tsession_id,\n\t\t};\n\t}\n\n\t// Otherwise, return what we have\n\treturn {\n\t\tanonymous_id,\n\t\tsession_id,\n\t};\n};\n\nconst getSessionInfoFromResponse = (response: unknown) => {\n\tif (typeof response !== 'object' || response === null) return null;\n\treturn {\n\t\tanonymous_id:\n\t\t\t'anonymous_id' in response && typeof response.anonymous_id === 'string' ? response.anonymous_id : null,\n\t\tsession_id: 'session_id' in response && typeof response.session_id === 'string' ? response.session_id : null,\n\t};\n};\n\nconst serverReferrer = (referrer: typeof Request.prototype.referrer) => {\n\tif (referrer === 'about:client') return '';\n\treturn referrer;\n};\n\nconst analyticsLogEndpoint = endpoint({\n\tpathname: '/log',\n\tmethod: 'POST',\n\tschema: {\n\t\tresponse: typed<unknown>(),\n\t\tbody: typed<TrackPayload>(),\n\t},\n});\n\nexport const createAnalyticsService = ({\n\trpcClient,\n\tlogger,\n}: {\n\tlogger: Logger;\n\trpcClient: InploiRpcClient;\n}): AnalyticsService => {\n\tconst logFn: LogFn = async params => {\n\t\tinvariant(\n\t\t\tparams.request || typeof window !== 'undefined',\n\t\t\t'Cannot log on the server without a request. Please pass a request to `log`.',\n\t\t);\n\n\t\t// if there’s a request, use it instead of browser APIs\n\t\tconst page =\n\t\t\t'request' in params && params.request ?\n\t\t\t\t{\n\t\t\t\t\thref: params.request.url,\n\t\t\t\t\treferrer: serverReferrer(params.request.referrer),\n\t\t\t\t\ttitle: '',\n\t\t\t\t}\n\t\t\t:\t{\n\t\t\t\t\thref: location.href,\n\t\t\t\t\treferrer: document.referrer,\n\t\t\t\t\ttitle: document.title,\n\t\t\t\t};\n\n\t\ttry {\n\t\t\tconst context: AnalyticsContext = {\n\t\t\t\tlibrary: {\n\t\t\t\t\tname: 'inploi-sdk',\n\t\t\t\t\tversion: ANALYTICS_VERSION,\n\t\t\t\t},\n\t\t\t\tpage,\n\t\t\t};\n\n\t\t\tconst sessionInfo = getSessionInfo(params.request);\n\t\t\tconst payload: TrackPayload = {\n\t\t\t\tanonymous_id: sessionInfo.anonymous_id,\n\t\t\t\tsession_id: sessionInfo.session_id,\n\t\t\t\tevent: params.event,\n\t\t\t\tsent_at: new Date().toISOString(),\n\t\t\t\tcontext,\n\t\t\t\tproperties: params.properties,\n\t\t\t\tcustom_properties: params.customProperties,\n\t\t\t};\n\n\t\t\tconst responseJson = await rpcClient.request(analyticsLogEndpoint, {\n\t\t\t\tbody: payload,\n\t\t\t});\n\n\t\t\tconst newSession = getSessionInfoFromResponse(responseJson);\n\t\t\tif (newSession?.anonymous_id) {\n\t\t\t\tpayload.anonymous_id = newSession.anonymous_id;\n\t\t\t}\n\t\t\tif (newSession?.session_id) {\n\t\t\t\tpayload.session_id = newSession.session_id;\n\t\t\t}\n\n\t\t\tif (typeof window !== 'undefined' && payload.anonymous_id) {\n\t\t\t\tif (payload.session_id) {\n\t\t\t\t\tsessionStorage.setItem(`${ANALYTICS_COOKIE_NAME}-session_id`, payload.session_id.toString());\n\t\t\t\t}\n\t\t\t\tdocument.cookie = formatCookie(payload.anonymous_id);\n\t\t\t}\n\n\t\t\treturn { success: true, data: payload };\n\t\t} catch (e) {\n\t\t\t/** We dont’t log any PII on the console */\n\t\t\tlogger.error('Failed to send log to API. Inspect error response of `log` for more information.');\n\t\t\treturn { success: false, error: e };\n\t\t}\n\t};\n\n\treturn {\n\t\tlog: logFn,\n\t\tgetHeaders: payload => {\n\t\t\tconst headers = new Headers();\n\t\t\tif (!payload?.anonymous_id) return headers;\n\n\t\t\theaders.append('Set-Cookie', formatCookie(payload.anonymous_id));\n\t\t\treturn headers;\n\t\t},\n\t\tgetSessionInfo,\n\t};\n};\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { stringify } from 'neoqs';\n\nimport { JsonParsingError, SchemaValidationError, handleApiExceptions } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger } from './sdk.logger';\n\ntype RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\n/** Extract parameter names from a pathname string */\ntype ExtractParamNames<T extends string> =\n\tT extends `${infer _Before}:${infer Param}/${infer After}` ? Param | ExtractParamNames<`/${After}`>\n\t: T extends `${infer _Before}:${infer Param}` ? Param\n\t: never;\n\n/** Create params object from parameter names */\ntype ExtractPathParams<T extends string> =\n\tstring extends T ? Record<string, string | number>\n\t: ExtractParamNames<T> extends never ? Record<string, never>\n\t: { [K in ExtractParamNames<T>]: string | number };\n\n/** Parses a StandardSchemaV1 schema and input into an output. */\nexport function parse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n): StandardSchemaV1.InferOutput<T> {\n\tconst result = schema['~standard'].validate(input);\n\tif (result instanceof Promise) {\n\t\tthrow new TypeError('Async schema');\n\t}\n\n\tif (result.issues) {\n\t\tthrow new SchemaValidationError(result.issues);\n\t}\n\n\treturn result.value;\n}\n\n/** Parses a StandardSchemaV1 schema and input into an output, returning a success flag and issues if the parse fails. */\nexport function safeParse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n):\n\t| {\n\t\t\tsuccess: true;\n\t\t\toutput: StandardSchemaV1.InferOutput<T>;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t } {\n\ttry {\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\toutput: parse(schema, input),\n\t\t};\n\t} catch (e) {\n\t\tif (e instanceof SchemaValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tissues: e.issues,\n\t\t\t};\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nexport interface InploiRpcClientParams {\n\tenvironment: InploiSdkEnvironment;\n\tlogger: Logger;\n\tapiKey:\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-secret-key header\n\t\t\t\t * This will error if used in a browser environment.\n\t\t\t\t */\n\t\t\t\ttype: 'secret';\n\t\t\t\tkey: string;\n\t\t }\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-publishable-key header\n\t\t\t\t * This can be called in a browser or server environment.\n\t\t\t\t */\n\t\t\t\ttype: 'publishable';\n\t\t\t\tkey: string;\n\t\t };\n}\n\n/** RPC client for making API calls to the Inploi API. */\nexport class InploiRpcClient {\n\tprivate baseUrl: string;\n\tprivate headers: Headers;\n\tprivate logger: Logger;\n\n\tconstructor(params: InploiRpcClientParams) {\n\t\tthis.baseUrl = ENV_TO_API_URL[params.environment];\n\t\tthis.headers = new Headers({\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t});\n\t\tif (params.apiKey.type === 'secret') {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\tthrow new Error('Secret key cannot be used in a browser environment');\n\t\t\t}\n\t\t\tthis.headers.set('x-secret-key', params.apiKey.key);\n\t\t} else {\n\t\t\tthis.headers.set('x-publishable-key', params.apiKey.key);\n\t\t}\n\t\tthis.logger = params.logger;\n\t}\n\n\t/** Fetches, parses and validates an API endpoint.\n\t * Logs errors and throws them again so that the caller can handle them.\n\t *\n\t * @throws {JsonParsingError} - If the response is not valid JSON.\n\t * @throws {SchemaValidationError} - If the searchParams, body or response does not match the schema.\n\t * @throws {ApiError} - If the API responded with an error message.\n\t * @throws {UnauthorisedError} - If the request is unauthorised either by missing key or unmet permissions.\n\t * @throws {NotFoundError} - If the endpoint is not found.\n\t * @throws {Error} - Another unhandled error.\n\t */\n\tasync request<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ?\n\t\t\tGetSchemaValues<{\n\t\t\t\tbody: TBody;\n\t\t\t\tsearchParams: TSearch;\n\t\t\t\tparams: TPathParams;\n\t\t\t}> & { signal?: AbortSignal }\n\t\t:\tnever,\n\t) {\n\t\ttry {\n\t\t\tconst url = new URL(this.baseUrl);\n\n\t\t\t// Replace path parameters in pathname\n\t\t\tlet pathname = endpoint.pathname;\n\t\t\tif ('params' in options && options.params) {\n\t\t\t\tfor (const [key, value] of Object.entries(options.params)) {\n\t\t\t\t\tpathname = pathname.replace(`:${key}`, String(value));\n\t\t\t\t}\n\t\t\t}\n\t\t\turl.pathname = pathname;\n\n\t\t\tif (endpoint.schema.searchParams) {\n\t\t\t\turl.search = stringify(\n\t\t\t\t\tparse(endpoint.schema.searchParams, 'searchParams' in options ? options.searchParams : {}),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst body =\n\t\t\t\tendpoint.schema.body ? parse(endpoint.schema.body, 'body' in options ? options.body : {}) : undefined;\n\n\t\t\tconst response = await fetch(url.toString(), {\n\t\t\t\tmethod: endpoint.method,\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\theaders: this.headers,\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\n\t\t\tconst json = await response.json().catch(e => {\n\t\t\t\tthis.logger.error(e);\n\t\t\t\tthrow new JsonParsingError(response);\n\t\t\t});\n\n\t\t\tconst result = safeParse(endpoint.schema.response, json);\n\t\t\tif (!result.success) {\n\t\t\t\thandleApiExceptions(json);\n\t\t\t\tthrow new SchemaValidationError(result.issues);\n\t\t\t}\n\n\t\t\treturn result.output as StandardSchemaV1.InferOutput<T['schema']['response']>;\n\t\t} catch (e) {\n\t\t\tif (e instanceof SchemaValidationError) {\n\t\t\t\tthis.logger.error(e.message, e.issues);\n\t\t\t} else {\n\t\t\t\tthis.logger.error(e);\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n}\n\ntype GetSchemaValues<T extends { searchParams: any; body: any; params?: any }> = {\n\t[K in keyof T as T[K] extends never ? never\n\t: T[K] extends Record<string, never> ? never\n\t: K]: T[K] extends never ? never : T[K];\n};\n\n/**\n * Typed but *not runtime validated* schema\n * useful for type-checking the schema without bundling validation schemas\n */\nexport function typed<T>(): StandardSchemaV1<T, T> {\n\treturn {\n\t\t'~standard': {\n\t\t\tvendor: 'inploi',\n\t\t\tversion: 1,\n\t\t\tvalidate: input => {\n\t\t\t\treturn {\n\t\t\t\t\tvalue: input as T,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t};\n}\n\nexport interface RpcEndpoint<\n\tTMethod extends RequestMethod = RequestMethod,\n\tTPathname extends string = string,\n\tTPathParams = any,\n\tTSearch = any,\n\tTBody = any,\n\tTResponse = any,\n> {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: StandardSchemaV1<TSearch, TSearch>;\n\t\tbody?: StandardSchemaV1<TBody, TBody>;\n\t\tresponse: StandardSchemaV1<TResponse, TResponse>;\n\t};\n\t/** Type-only property to store path parameter types */\n\treadonly __pathParams?: TPathParams;\n}\n\nexport function endpoint<\n\tTMethod extends RequestMethod,\n\tTPathname extends string,\n\tTSearch extends StandardSchemaV1 | never = never,\n\tTBody extends StandardSchemaV1 | never = never,\n\tTResponse extends StandardSchemaV1 | never = never,\n>(endpoint: {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: TSearch;\n\t\tbody?: TBody;\n\t\tresponse: TResponse;\n\t};\n}) {\n\ttype PathParams = ExtractPathParams<TPathname>;\n\treturn endpoint as RpcEndpoint<\n\t\tTMethod,\n\t\tTPathname,\n\t\tPathParams,\n\t\tStandardSchemaV1.InferInput<TSearch>,\n\t\tStandardSchemaV1.InferInput<TBody>,\n\t\tStandardSchemaV1.InferOutput<TResponse>\n\t>;\n}\n","import { createAnalyticsService } from './sdk.analytics';\nimport { createApiClient } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger, inploiBrandedLogger, noLogging } from './sdk.logger';\nimport { InploiSdkPlugin } from './sdk.plugins';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type InitialiseInploiSdkParams = {\n\t/** Your public API key for the inploi SDK. */\n\tpublishableKey: string;\n\t/** Which app environment to run. This ultimately affects which inploi endpoints to gather data are going to be used.\n\t * Anything other than `production` should be considered a development environment and the data periodicaly purged. */\n\tenv: InploiSdkEnvironment;\n\t/** Logger object that handles logging of different levels.\n\t * You can override this to use your own logger, or to disable logging altogether by passing`false`.\n\t * @default inploiBrandedLogger\n\t * */\n\tlogger?: Logger | false;\n};\n\nexport function initialiseSdk({ publishableKey, env, logger = inploiBrandedLogger }: InitialiseInploiSdkParams) {\n\t/** @deprecated - use `rpcClient` instead */\n\tconst apiClient = createApiClient({ baseUrl: ENV_TO_API_URL[env], publishableKey });\n\tconst loggerService = logger === false ? noLogging : logger;\n\tconst rpcClient = new InploiRpcClient({\n\t\tenvironment: env,\n\t\tapiKey: { type: 'publishable', key: publishableKey },\n\t\tlogger: loggerService,\n\t});\n\tconst analytics = createAnalyticsService({ rpcClient, logger: loggerService });\n\n\tconst register = <P extends InploiSdkPlugin>(plugin: P): ReturnType<P> => {\n\t\treturn plugin({ logger: loggerService, apiClient, analytics, rpcClient });\n\t};\n\n\treturn { register, analytics, apiClient };\n}\n\nexport type InploiSdk = ReturnType<typeof initialiseSdk>;\n"],"mappings":"0nBAAO,IAAMA,EAAiB,iBACjBC,EAAgB,qCAUhBC,EAA8B,CAC1C,KAAM,IAAIC,IAAS,QAAQ,KAAKH,EAAgBC,EAAe,GAAGE,CAAI,EACtE,MAAO,IAAIA,IAAS,QAAQ,MAAMH,EAAgBC,EAAe,GAAGE,CAAI,EACxE,KAAM,IAAIA,IAAS,QAAQ,KAAKH,EAAgBC,EAAe,GAAGE,CAAI,EACtE,IAAK,IAAIA,IAAS,QAAQ,IAAIH,EAAgBC,EAAe,GAAGE,CAAI,CACrE,EAEaC,EAAoB,CAAE,KAAM,IAAG,GAAW,MAAO,IAAG,GAAW,IAAK,IAAG,GAAW,KAAM,IAAG,EAAU,ECM3G,IAAMC,EAA2CC,GAAgBA,ECtBjE,IAAMC,EAAyB,kBACzBC,EAAsB,+BAEtBC,EAAN,cAA4B,KAAM,CACxC,aAAc,CACb,MAAM,WAAW,EACjB,KAAK,KAAO,eACb,CACD,EAEaC,EAAN,cAAgC,KAAM,CAC5C,YAAYC,EAAkB,CAC7B,MAAMA,GAAA,KAAAA,EAAW,gDAAgD,EACjE,KAAK,KAAO,mBACb,CACD,EAEaC,EAAN,cAAoC,KAAM,CAChD,YAAmBC,EAA2C,CAC7D,MAAM,0BAA0B,EADd,YAAAA,EAElB,KAAK,KAAO,uBACb,CACD,EAEaC,EAAN,cAAuB,KAAM,CAEnC,YAAYH,EAAiBI,EAAmB,CAC/C,MAAMJ,CAAO,EACb,KAAK,KAAO,WACZ,KAAK,OAASI,CACf,CACD,EAEaC,EAAN,cAA+B,KAAM,CAC3C,YAAmBC,EAAqB,CACvC,MAAM,mCAAmC,EADvB,cAAAA,EAElB,KAAK,KAAO,cACb,CACD,EAUO,SAASC,EAAoBC,EAAe,CAClD,GAAIA,IAAS,MAET,OAAOA,GAAS,SAAU,CAC7B,IAAIC,EAAU,oBAGd,GAFI,YAAaD,GAAQ,OAAOA,EAAK,SAAY,WAAUC,EAAUD,EAAK,SAEtEC,IAAYC,EACf,MAAM,IAAIC,EAAkB,4BAA4B,EAEzD,GAAIF,IAAYG,EACf,MAAM,IAAID,EAEX,GAAI,cAAeH,EAClB,MAAM,IAAIK,EAASJ,EAAS,CAACD,EAAK,SAAS,CAAC,EAE7C,GAAI,WAAYA,EAAM,CACrB,GAAI,MAAM,QAAQA,EAAK,MAAM,GAAKA,EAAK,OAAO,MAAMM,GAAS,OAAOA,GAAU,QAAQ,EACrF,MAAM,IAAID,EAASJ,EAASD,EAAK,MAAM,EAExC,GAAI,OAAOA,EAAK,QAAW,UAAYA,EAAK,SAAW,KAAM,CAC5D,IAAMO,EAAU,OAAO,QAAQP,EAAK,MAAM,EAE1C,MAAIO,EAAQ,MAAM,CAAC,CAAC,CAAEC,CAAK,IAAM,MAAM,QAAQA,CAAK,GAAKA,EAAM,MAAMF,GAAS,OAAOA,GAAU,QAAQ,CAAC,EACjG,IAAIG,EACTF,EAAQ,IACP,CAAC,CAACG,EAAKF,CAAK,KAA+B,CAC1C,KAAME,EAAI,MAAM,GAAG,EACnB,QAASF,EAAM,KAAK,IAAI,CACzB,EACD,CACD,EAEK,IAAIH,EACTJ,EACAM,EAAQ,IAAI,CAAC,CAACG,EAAKF,CAAK,IAAM,GAAGE,CAAG,KAAKF,CAAK,EAAE,CACjD,CACD,CACA,GAAI,OAAOR,EAAK,QAAW,SAAU,MAAM,IAAIK,EAASJ,EAAS,CAACD,EAAK,MAAM,CAAC,CAC/E,CACA,GAAI,UAAWA,GAAQ,OAAOA,EAAK,OAAU,SAC5C,MAAM,IAAIK,EAASL,EAAK,MAAO,CAACA,EAAK,KAAK,CAAC,CAE7C,CACD,CAEO,IAAMW,EAAmBC,GAAmE,CAClG,IAAMC,EAA8B,CACnC,OAAQ,mBACR,eAAgB,mBAChB,oBAAqBD,EAAO,cAC7B,EAEA,MAAO,CAIN,MAAO,CAAOE,KAA2BC,IAAAC,EAAA,QAA3BF,EAA2B,GAAAC,GAAA,UAA3BE,EAAUC,EAAU,CAAC,EAAM,CACxC,IAAMC,EAAOC,EAAAC,EAAA,GAAKH,GAAL,CAAc,QAASG,IAAA,GAAKH,EAAQ,SAAYL,EAAiB,GACxES,EAAW,MAAM,MAAM,GAAGV,EAAO,OAAO,GAAGK,CAAQ,GAAIE,CAAI,EACjE,GAAIG,EAAS,SAAW,IAAK,MAAM,IAAIC,EAEvC,IAAMvB,EAAO,MAAMsB,EAAS,KAAK,EAAE,MAAM,IAAYN,EAAA,wBACpD,MAAM,IAAIQ,EAAiBF,CAAQ,CACpC,EAAC,EAED,OAAAvB,EAAoBC,CAAI,EAGjBA,CACR,EACD,CACD,EAEayB,EAAW,CACvB,SAAUF,EACV,aAAcpB,EACd,iBAAkBM,EAClB,IAAKJ,EACL,YAAamB,CACd,EAEO,SAASE,EAAWpB,EAAmE,CAC7F,OAAO,OAAO,OAAOmB,CAAQ,EAAE,KAAKE,GAAcrB,aAAiBqB,CAAU,CAC9E,CClIO,SAASC,EAAUC,EAAgBC,EAAqC,CAC9E,GAAI,CAAAD,EAIJ,MAAM,IAAI,MAAMC,CAAO,CACxB,CEDA,IAAMC,GAAoB,IAAI,KAAK,mBAAmB,OAAW,CAAE,QAAS,MAAO,CAAC,ECPnF,IAAAC,EAAW,SCOL,IAAMC,EAAuD,CACnE,QAAS,iCACT,WAAY,yBAEZ,gBAAiB,iBAClB,EAEaC,EAAoBC,EAI1B,IAAMC,EAAwB,eCdrC,IAAMC,EAAgBC,GAAkB,CACvC,IAAMC,EAAM,IAAI,KAChB,OAAAA,EAAI,QAAQA,EAAI,QAAQ,EAAI,EAAI,GAAK,GAAK,GAAK,GAAI,EAE5C,GAAGC,CAAqB,IAAIF,CAAK,YAAYC,EAAI,YAAY,CAAC,SACtE,EA6KME,EAAe,CAACC,EAA+BC,IAAsB,CAC1E,IAAMC,EAAmBF,EAAa,IAAI,YAAY,EAEtD,GADIC,GACAC,EAAkB,OAAOA,EAC7B,IAAMC,EAAqB,eAAe,QAAQ,GAAGL,CAAqB,aAAa,EACvF,OAAI,OAAOK,GAAuB,SAAiBA,EAC5C,IACR,EAEMC,EAAc,IAAI,OAAO,GAAGN,CAAqB,UAAU,EAC3DO,EAAkBC,GAAsB,CAC7C,IAAMC,EAAOD,EAAUA,EAAQ,IAAM,SAAS,KACxC,CAAE,aAAAN,CAAa,EAAI,IAAI,IAAIO,CAAI,EAC/BC,EAAeR,EAAa,IAAI,cAAc,EAC9CS,EAAaV,EAAaC,EAAc,OAAO,QAAW,WAAW,EAG3E,GAAIQ,EACH,MAAO,CACN,aAAAA,EACA,WAAAC,CACD,EAGD,IAAMC,EAASJ,EAAUA,EAAQ,QAAQ,IAAI,QAAQ,EAAI,SAAS,OAClE,GAAII,EAAQ,CACX,IAAMC,EAAQP,EAAY,KAAKM,CAAM,EAC/BF,EAAeG,GAAA,YAAAA,EAAQ,GAC7B,MAAO,CACN,aAAcH,GAAA,KAAAA,EAAgB,KAC9B,WAAAC,CACD,CACD,CAGA,MAAO,CACN,aAAAD,EACA,WAAAC,CACD,CACD,EAEMG,EAA8BC,GAC/B,OAAOA,GAAa,UAAYA,IAAa,KAAa,KACvD,CACN,aACC,iBAAkBA,GAAY,OAAOA,EAAS,cAAiB,SAAWA,EAAS,aAAe,KACnG,WAAY,eAAgBA,GAAY,OAAOA,EAAS,YAAe,SAAWA,EAAS,WAAa,IACzG,EAGKC,EAAkBC,GACnBA,IAAa,eAAuB,GACjCA,EAGFC,GAAgC,CACrC,SAAU,OACV,OAAQ,OACR,OAAQ,CACP,SAAUC,EAAe,EACzB,KAAMA,EAAoB,CAC3B,CACD,EAEaC,EAAyB,CAAC,CACtC,UAAAC,EACA,OAAAC,CACD,KAuEQ,CACN,IApE0BC,GAAUC,EAAA,wBACpCC,EACCF,EAAO,SAAW,OAAO,QAAW,YACpC,6EACD,EAGA,IAAMG,EACL,YAAaH,GAAUA,EAAO,QAC7B,CACC,KAAMA,EAAO,QAAQ,IACrB,SAAUP,EAAeO,EAAO,QAAQ,QAAQ,EAChD,MAAO,EACR,EACC,CACA,KAAM,SAAS,KACf,SAAU,SAAS,SACnB,MAAO,SAAS,KACjB,EAEF,GAAI,CACH,IAAMI,EAA4B,CACjC,QAAS,CACR,KAAM,aACN,QAASC,CACV,EACA,KAAAF,CACD,EAEMG,EAActB,EAAegB,EAAO,OAAO,EAC3CO,EAAwB,CAC7B,aAAcD,EAAY,aAC1B,WAAYA,EAAY,WACxB,MAAON,EAAO,MACd,QAAS,IAAI,KAAK,EAAE,YAAY,EAChC,QAAAI,EACA,WAAYJ,EAAO,WACnB,kBAAmBA,EAAO,gBAC3B,EAEMQ,EAAe,MAAMV,EAAU,QAAQH,GAAsB,CAClE,KAAMY,CACP,CAAC,EAEKE,EAAalB,EAA2BiB,CAAY,EAC1D,OAAIC,GAAA,MAAAA,EAAY,eACfF,EAAQ,aAAeE,EAAW,cAE/BA,GAAA,MAAAA,EAAY,aACfF,EAAQ,WAAaE,EAAW,YAG7B,OAAO,QAAW,aAAeF,EAAQ,eACxCA,EAAQ,YACX,eAAe,QAAQ,GAAG9B,CAAqB,cAAe8B,EAAQ,WAAW,SAAS,CAAC,EAE5F,SAAS,OAASjC,EAAaiC,EAAQ,YAAY,GAG7C,CAAE,QAAS,GAAM,KAAMA,CAAQ,CACvC,OAASG,EAAG,CAEX,OAAAX,EAAO,MAAM,kFAAkF,EACxF,CAAE,QAAS,GAAO,MAAOW,CAAE,CACnC,CACD,GAIC,WAAYH,GAAW,CACtB,IAAMI,EAAU,IAAI,QACpB,OAAKJ,GAAA,MAAAA,EAAS,cAEdI,EAAQ,OAAO,aAAcrC,EAAaiC,EAAQ,YAAY,CAAC,EACxDI,CACR,EACA,eAAA3B,CACD,GC3UD,OAAS,aAAA4B,OAAiB,QAqBnB,SAASC,EACfC,EACAC,EACkC,CAClC,IAAMC,EAASF,EAAO,WAAW,EAAE,SAASC,CAAK,EACjD,GAAIC,aAAkB,QACrB,MAAM,IAAI,UAAU,cAAc,EAGnC,GAAIA,EAAO,OACV,MAAM,IAAIC,EAAsBD,EAAO,MAAM,EAG9C,OAAOA,EAAO,KACf,CAGO,SAASE,GACfJ,EACAC,EASI,CACJ,GAAI,CACH,MAAO,CACN,QAAS,GACT,OAAQF,EAAMC,EAAQC,CAAK,CAC5B,CACD,OAASI,EAAG,CACX,GAAIA,aAAaF,EAChB,MAAO,CACN,QAAS,GACT,OAAQE,EAAE,MACX,EAED,MAAMA,CACP,CACD,CAuBO,IAAMC,EAAN,KAAsB,CAK5B,YAAYC,EAA+B,CAM1C,GALA,KAAK,QAAUC,EAAeD,EAAO,WAAW,EAChD,KAAK,QAAU,IAAI,QAAQ,CAC1B,eAAgB,mBAChB,OAAQ,kBACT,CAAC,EACGA,EAAO,OAAO,OAAS,SAAU,CACpC,GAAI,OAAO,QAAW,YACrB,MAAM,IAAI,MAAM,oDAAoD,EAErE,KAAK,QAAQ,IAAI,eAAgBA,EAAO,OAAO,GAAG,CACnD,MACC,KAAK,QAAQ,IAAI,oBAAqBA,EAAO,OAAO,GAAG,EAExD,KAAK,OAASA,EAAO,MACtB,CAYM,QACLE,EACAC,EAOC,QAAAC,EAAA,sBACD,GAAI,CACH,IAAMC,EAAM,IAAI,IAAI,KAAK,OAAO,EAG5BC,EAAWJ,EAAS,SACxB,GAAI,WAAYC,GAAWA,EAAQ,OAClC,OAAW,CAACI,EAAKC,CAAK,IAAK,OAAO,QAAQL,EAAQ,MAAM,EACvDG,EAAWA,EAAS,QAAQ,IAAIC,CAAG,GAAI,OAAOC,CAAK,CAAC,EAGtDH,EAAI,SAAWC,EAEXJ,EAAS,OAAO,eACnBG,EAAI,OAASI,GACZjB,EAAMU,EAAS,OAAO,aAAc,iBAAkBC,EAAUA,EAAQ,aAAe,CAAC,CAAC,CAC1F,GAGD,IAAMO,EACLR,EAAS,OAAO,KAAOV,EAAMU,EAAS,OAAO,KAAM,SAAUC,EAAUA,EAAQ,KAAO,CAAC,CAAC,EAAI,OAEvFQ,EAAW,MAAM,MAAMN,EAAI,SAAS,EAAG,CAC5C,OAAQH,EAAS,OACjB,KAAMQ,EAAO,KAAK,UAAUA,CAAI,EAAI,OACpC,QAAS,KAAK,QACd,OAAQP,EAAQ,MACjB,CAAC,EAEKS,EAAO,MAAMD,EAAS,KAAK,EAAE,MAAMb,GAAK,CAC7C,WAAK,OAAO,MAAMA,CAAC,EACb,IAAIe,EAAiBF,CAAQ,CACpC,CAAC,EAEKhB,EAASE,GAAUK,EAAS,OAAO,SAAUU,CAAI,EACvD,GAAI,CAACjB,EAAO,QACX,MAAAmB,EAAoBF,CAAI,EAClB,IAAIhB,EAAsBD,EAAO,MAAM,EAG9C,OAAOA,EAAO,MACf,OAASG,EAAG,CACX,MAAIA,aAAaF,EAChB,KAAK,OAAO,MAAME,EAAE,QAASA,EAAE,MAAM,EAErC,KAAK,OAAO,MAAMA,CAAC,EAEdA,CACP,CACD,GACD,EAYO,SAASiB,GAAmC,CAClD,MAAO,CACN,YAAa,CACZ,OAAQ,SACR,QAAS,EACT,SAAUrB,IACF,CACN,MAAOA,CACR,EAEF,CACD,CACD,CAsBO,SAASQ,EAMdA,EASC,CAEF,OAAOA,CAQR,CCtOO,SAASc,GAAc,CAAE,eAAAC,EAAgB,IAAAC,EAAK,OAAAC,EAASC,CAAoB,EAA8B,CAE/G,IAAMC,EAAYC,EAAgB,CAAE,QAASC,EAAeL,CAAG,EAAG,eAAAD,CAAe,CAAC,EAC5EO,EAAgBL,IAAW,GAAQM,EAAYN,EAC/CO,EAAY,IAAIC,EAAgB,CACrC,YAAaT,EACb,OAAQ,CAAE,KAAM,cAAe,IAAKD,CAAe,EACnD,OAAQO,CACT,CAAC,EACKI,EAAYC,EAAuB,CAAE,UAAAH,EAAW,OAAQF,CAAc,CAAC,EAM7E,MAAO,CAAE,SAJoCM,GACrCA,EAAO,CAAE,OAAQN,EAAe,UAAAH,EAAW,UAAAO,EAAW,UAAAF,CAAU,CAAC,EAGtD,UAAAE,EAAW,UAAAP,CAAU,CACzC","names":["CONSOLE_PREFIX","CONSOLE_STYLE","inploiBrandedLogger","args","noLogging","createPlugin","pluginFn","unauthenticatedMessage","unauthorisedMessage","NotFoundError","UnauthorisedError","message","SchemaValidationError","issues","ApiError","errors","JsonParsingError","response","handleApiExceptions","json","message","unauthenticatedMessage","UnauthorisedError","unauthorisedMessage","ApiError","error","entries","value","SchemaValidationError","key","createApiClient","params","defaultHeaders","_0","_1","__async","pathname","options","init","__spreadProps","__spreadValues","response","NotFoundError","JsonParsingError","SdkError","isSdkError","ErrorClass","invariant","condition","message","DEFAULT_FORMATTER","version","ENV_TO_API_URL","ANALYTICS_VERSION","version","ANALYTICS_COOKIE_NAME","formatCookie","value","now","ANALYTICS_COOKIE_NAME","getSessionId","searchParams","isServer","fromSearchParams","fromSessionStorage","cookieRegex","getSessionInfo","request","href","anonymous_id","session_id","cookie","match","getSessionInfoFromResponse","response","serverReferrer","referrer","analyticsLogEndpoint","typed","createAnalyticsService","rpcClient","logger","params","__async","invariant","page","context","ANALYTICS_VERSION","sessionInfo","payload","responseJson","newSession","e","headers","stringify","parse","schema","input","result","SchemaValidationError","safeParse","e","InploiRpcClient","params","ENV_TO_API_URL","endpoint","options","__async","url","pathname","key","value","stringify","body","response","json","JsonParsingError","handleApiExceptions","typed","initialiseSdk","publishableKey","env","logger","inploiBrandedLogger","apiClient","createApiClient","ENV_TO_API_URL","loggerService","noLogging","rpcClient","InploiRpcClient","analytics","createAnalyticsService","plugin"]}
|
|
1
|
+
{"version":3,"sources":["../src/sdk.logger.ts","../src/sdk.plugins.ts","../../core/src/common/common.utils.ts","../../core/src/common/common.currency.ts","../../core/src/common/common.datetime.ts","../src/sdk.api.ts","../package.json","../src/sdk.constants.ts","../src/sdk.analytics.ts","../src/sdk.rpc.ts","../src/sdk.ts"],"sourcesContent":["export const CONSOLE_PREFIX = '%c[inploi SDK]';\nexport const CONSOLE_STYLE = 'color: #65BC67; font-weight: bold;';\n\ntype LogMessage = (...data: any[]) => void;\nexport type Logger = {\n\twarn: LogMessage;\n\terror: LogMessage;\n\tinfo: LogMessage;\n\tlog: LogMessage;\n};\n\nexport const inploiBrandedLogger: Logger = {\n\twarn: (...args) => console.warn(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\terror: (...args) => console.error(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tinfo: (...args) => console.info(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n\tlog: (...args) => console.log(CONSOLE_PREFIX, CONSOLE_STYLE, ...args),\n};\n\nexport const noLogging: Logger = { info: () => void 0, error: () => void 0, log: () => void 0, warn: () => void 0 };\n","import { AnalyticsService } from './sdk.analytics';\nimport { ApiClient } from './sdk.api';\nimport { Logger } from './sdk.logger';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type PluginParams = {\n\tapiClient: ApiClient;\n\tlogger: Logger;\n};\n\nexport type Plugin<T extends string, P extends Record<string, unknown>> = {\n\tpluginName: T;\n\tpure_createActions: (params: PluginParams) => P;\n};\n\ntype PluginDependencies = {\n\tapiClient: ApiClient;\n\trpcClient: InploiRpcClient;\n\tlogger: Logger;\n\tanalytics: AnalyticsService;\n};\n\nexport type InploiSdkPlugin = (dependencies: PluginDependencies) => any;\n\nexport const createPlugin = <T extends InploiSdkPlugin>(pluginFn: T) => pluginFn;\n","export const exhaustive = (value: never) => {\n\tthrow new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);\n};\n\nexport function invariant(condition: any, message?: string): asserts condition {\n\tif (condition) {\n\t\treturn;\n\t}\n\n\tthrow new Error(message);\n}\n\nexport const uniqueOrThrow = <T>(array: T[]) => {\n\tconst uniqueValues = new Set(array);\n\n\tif (array.length !== uniqueValues.size) {\n\t\tthrow new Error('Duplicate values found');\n\t}\n\treturn true;\n};\n\nexport const uniqueByPropertyOrThrow =\n\t<T extends PropertyKey>(propertyKey: T) =>\n\t(array: { [K in T]: any }[]) => {\n\t\tconst values = array.map(item => item[propertyKey]);\n\t\tconst uniqueValues = new Set(values);\n\n\t\tif (values.length !== uniqueValues.size) {\n\t\t\tthrow new Error(`Duplicate values found for property: ${propertyKey.toString()}`);\n\t\t}\n\t\treturn true;\n\t};\n\n/**\n * A destructive way to ensure an object has a property.\n * This is useful when working with unknowns.\n */\nexport function hasProp<K extends PropertyKey>(data: object, prop: K): data is Record<K, unknown> {\n\treturn prop in data;\n}\n\n/**\n * A sort of type-safe way to check whether a key exists in an object.\n */\nexport function isKeyInObj<O extends Record<string, unknown>>(key: PropertyKey, obj: O): key is keyof O {\n\treturn key in obj;\n}\n","type TFunction = (key: 'competitive' | 'invalid_salary' | 'from' | 'up_to') => string;\n\ninterface SalaryParams {\n\tpay: string | null;\n\tpay_min: string | null;\n\tpay_mask: boolean;\n\tpay_max: string | null;\n\tpay_type: 'ANNUALLY' | 'HOURLY' | 'MONTHLY' | 'WEEKLY' | 'DAILY' | null;\n\tpay_currency: string;\n\tpay_display: boolean;\n}\n\nconst payPeriods: Record<NonNullable<SalaryParams['pay_type']>, string> = {\n\tANNUALLY: 'per year',\n\tDAILY: 'per day',\n\tHOURLY: 'per hour',\n\tMONTHLY: 'per month',\n\tWEEKLY: 'per week',\n};\n\nexport const getSalaryAsText = (params: {\n\tsalary: SalaryParams;\n\tconfig: { locales: string | string[] | undefined };\n\tt?: TFunction;\n}) => {\n\tconst { salary, config, t = s => s } = params;\n\tconst numberFormatter = new Intl.NumberFormat(config.locales, {\n\t\tstyle: 'currency',\n\t\tcurrency: salary.pay_currency,\n\t\t// @ts-expect-error - CI/CD is not happy with this, though locally it works\n\t\ttrailingZeroDisplay: 'stripIfInteger',\n\t});\n\tif (salary.pay_display === false) return undefined;\n\tif (salary.pay_mask) return t('competitive');\n\n\tif (salary.pay_max && Number.isNaN(+salary.pay_max)) return t('invalid_salary');\n\tif (salary.pay_min && Number.isNaN(+salary.pay_min)) return t('invalid_salary');\n\tif (salary.pay && Number.isNaN(+salary.pay)) return t('invalid_salary');\n\n\tconst period = salary.pay_type && salary.pay_type in payPeriods ? payPeriods[salary.pay_type] : undefined;\n\n\tif (salary.pay) return [numberFormatter.format(+salary.pay), period].filter(Boolean).join(' ');\n\n\tif (salary.pay_max && salary.pay_min)\n\t\treturn [numberFormatter.formatRange(+salary.pay_min, +salary.pay_max), period].filter(Boolean).join(' ') || '';\n\n\tif (salary.pay_max)\n\t\treturn `${t('up_to')} ${[numberFormatter.format(+salary.pay_max), period].filter(Boolean).join(' ')}`;\n\tif (salary.pay_min)\n\t\treturn `${t('from')} ${[numberFormatter.format(+salary.pay_min), period].filter(Boolean).join(' ')}`;\n\treturn t('invalid_salary');\n};\n","type TFunction = (key: 'today' | 'over_30_days_ago' | 'in_over_30_days') => string;\n\ntype Params = {\n\tfrom?: Date;\n\tto: string | number | Date;\n\tformatter?: Intl.RelativeTimeFormat;\n\tt?: TFunction;\n};\n\nconst DEFAULT_FORMATTER = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' });\n/** From a date, calculates the relative time difference from now */\nexport const getRelativeTimeDifference = ({\n\tfrom = new Date(),\n\tto,\n\tformatter = DEFAULT_FORMATTER,\n\tt = s => s,\n}: Params) => {\n\tconst then = to instanceof Date ? to : new Date(to);\n\tconst diff = then.getTime() - from.getTime();\n\n\tconst diffIn = {\n\t\tdays: Math.round(diff / 1000 / 60 / 60 / 24),\n\t\tmonths: Math.round(diff / 1000 / 60 / 60 / 24 / 30),\n\t};\n\n\tif (diffIn.days === 0) return t('today');\n\tif (Math.abs(diffIn.days) < 30) return formatter.format(diffIn.days, 'days');\n\tif (Math.abs(diffIn.days) < 3) return formatter.format(diffIn.months, 'months');\n\treturn diffIn.months < 0 ? t('over_30_days_ago') : t('in_over_30_days');\n};\n","import { hasProp } from '@inploi/core/common';\nimport { StandardSchemaV1 } from '@standard-schema/spec';\n\nexport const unauthenticatedMessage = 'Unauthenticated';\nexport const unauthorisedMessage = 'This action is unauthorized.';\n\nexport class ErrorWithStatus extends Error {\n\tpublic status?: number;\n\tconstructor(message?: string, status?: number) {\n\t\tsuper(message);\n\t\tthis.status = status;\n\t\tthis.name = 'ErrorWithStatus';\n\t}\n}\n\nexport class NotFoundError extends ErrorWithStatus {\n\tconstructor(message?: string) {\n\t\tsuper(message ?? 'Not found');\n\t\tthis.name = 'NotFoundError';\n\t\tthis.status = 404;\n\t}\n}\n\nexport class UnauthorisedError extends ErrorWithStatus {\n\tconstructor(message?: string, status?: number) {\n\t\tsuper(message ?? 'You are not authorised to perform this action.');\n\t\tthis.name = 'UnauthorisedError';\n\t\tthis.status = status ?? 401;\n\t}\n}\n\nexport class SchemaValidationError extends ErrorWithStatus {\n\tconstructor(\n\t\tpublic issues: readonly StandardSchemaV1.Issue[],\n\t\tpublic source?: 'body' | 'searchParams' | 'response',\n\t) {\n\t\tconst sourceText = source ? ` in ${source}` : '';\n\t\tsuper(`Schema validation failed${sourceText}`);\n\t\tthis.name = 'SchemaValidationError';\n\t\tthis.status = 400;\n\t}\n}\n\nexport class ApiError extends ErrorWithStatus {\n\tconstructor(message: string, status?: number) {\n\t\tsuper(message);\n\t\tthis.name = 'ApiError';\n\t\tthis.status = status ?? 500;\n\t}\n}\n\nexport class JsonParsingError extends ErrorWithStatus {\n\tconstructor(public response?: Response) {\n\t\tsuper('Error parsing response into JSON.');\n\t\tthis.name = 'ParsingError';\n\t\tthis.status = 500;\n\t}\n}\n\n/** @deprecated - use `JsonParsingError` instead */\nexport class ParsingError extends JsonParsingError {}\n\nexport type ApiClient = {\n\tfetch: (pathname: string, options?: RequestInit) => Promise<unknown>;\n};\n\nconst ERROR_MESSAGE_KEYS = ['message', 'error', 'errors', 'exception', 'exceptions'] as const;\nfunction getErrorMessageFromJson(json: unknown): string {\n\tconsole.log('json', json);\n\tconst messages: string[] = [];\n\tif (typeof json === 'object' && json !== null) {\n\t\tfor (const key of ERROR_MESSAGE_KEYS) {\n\t\t\tif (hasProp(json, key)) {\n\t\t\t\tconsole.log('hasProp', key, json[key]);\n\t\t\t\tconst value = json[key];\n\t\t\t\tif (typeof value === 'string') messages.push(value);\n\t\t\t\tif (Array.isArray(value) && value.every((item): item is string => typeof item === 'string'))\n\t\t\t\t\tmessages.push(...value);\n\t\t\t}\n\t\t}\n\t}\n\tif (messages.length === 0) messages.push('Unknown error');\n\treturn messages.join(', ');\n}\n\n/** Throws branded errors when API returns a known error. */\nexport function handleApiExceptions(json: unknown, status: number) {\n\tif (status >= 300 && status <= 500) {\n\t\tconst message = getErrorMessageFromJson(json);\n\t\tif (status === 404) {\n\t\t\tthrow new NotFoundError(message);\n\t\t}\n\t\tif (message === unauthenticatedMessage) {\n\t\t\tthrow new UnauthorisedError('You are not authenticated.', status);\n\t\t}\n\t\tif (message === unauthorisedMessage) {\n\t\t\tthrow new UnauthorisedError(message, status);\n\t\t}\n\t\tthrow new ApiError(message, status);\n\t}\n}\n\nexport const createApiClient = (params: { baseUrl: string; publishableKey: string }): ApiClient => {\n\tconst defaultHeaders: HeadersInit = {\n\t\tAccept: 'application/json',\n\t\t'Content-Type': 'application/json',\n\t\t'x-publishable-key': params.publishableKey,\n\t};\n\n\treturn {\n\t\t/** Fetches from a pathname with a pre-established base path.\n\t\t * Parses received output as JSON, and throw if one of the common error messages is received.\n\t\t */\n\t\tfetch: async (pathname, options = {}) => {\n\t\t\tconst init = { ...options, headers: { ...options.headers, ...defaultHeaders } };\n\t\t\tconst response = await fetch(`${params.baseUrl}${pathname}`, init);\n\t\t\tif (response.status === 404) throw new NotFoundError();\n\n\t\t\tconst json = await response.json().catch(async () => {\n\t\t\t\tthrow new JsonParsingError(response);\n\t\t\t});\n\n\t\t\thandleApiExceptions(json, response.status);\n\n\t\t\t// We’re assuming no other exceptions have happened.\n\t\t\treturn json;\n\t\t},\n\t};\n};\n\nexport const SdkError = {\n\tNotFound: NotFoundError,\n\tUnauthorised: UnauthorisedError,\n\tSchemaValidation: SchemaValidationError,\n\tApi: ApiError,\n\tJsonParsing: JsonParsingError,\n};\n\nexport function isSdkError(error: unknown): error is (typeof SdkError)[keyof typeof SdkError] {\n\treturn Object.values(SdkError).some(ErrorClass => error instanceof ErrorClass);\n}\n","{\n\t\"name\": \"@inploi/sdk\",\n\t\"version\": \"1.15.3\",\n\t\"main\": \"dist/index.js\",\n\t\"types\": \"dist/index.d.ts\",\n\t\"license\": \"MIT\",\n\t\"files\": [\n\t\t\"/dist\",\n\t\t\"/cdn\"\n\t],\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"require\": \"./dist/index.js\",\n\t\t\t\"import\": \"./dist/index.mjs\",\n\t\t\t\"types\": \"./dist/index.d.ts\"\n\t\t}\n\t},\n\t\"scripts\": {\n\t\t\"build:npm\": \"tsup --dts --dts-resolve\",\n\t\t\"build:cdn\": \"tsup --config tsup.cdn.config.ts\",\n\t\t\"build\": \"concurrently 'pnpm run build:npm' 'pnpm run build:cdn'\",\n\t\t\"dev\": \"tsup --watch --config tsup.cdn.config.ts\",\n\t\t\"check\": \"eslint src --fix --max-warnings 0 && tsc\",\n\t\t\"test\": \"bun test\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@happy-dom/global-registrator\": \"^13.6.2\",\n\t\t\"@inploi/core\": \"workspace:*\",\n\t\t\"@total-typescript/ts-reset\": \"^0.5.1\",\n\t\t\"@types/bun\": \"^1.2.5\",\n\t\t\"@types/react\": \"^18.2.33\",\n\t\t\"@types/react-dom\": \"^18.2.14\",\n\t\t\"autoprefixer\": \"^10.4.16\",\n\t\t\"concurrently\": \"9.1.2\",\n\t\t\"eslint\": \"^7.32.0\",\n\t\t\"eslint-config-custom\": \"workspace:*\",\n\t\t\"happy-dom\": \"^12.6.0\",\n\t\t\"ts-toolbelt\": \"^9.6.0\",\n\t\t\"tsconfig\": \"workspace:*\",\n\t\t\"tsup\": \"^7.2.0\"\n\t},\n\t\"dependencies\": {\n\t\t\"@standard-schema/spec\": \"^1.0.0\",\n\t\t\"neoqs\": \"^6.13.0\"\n\t}\n}\n","import { version } from '../package.json';\n\n/**\n * The environment the SDK should run in.\n * - `production`: data will be stored and displayed on dashboards\n * - `sandbox`: data will be stored temporarily and purged periodically\n */\nexport type InploiSdkEnvironment = 'production' | 'sandbox';\n\nexport const ENV_TO_API_URL: Record<InploiSdkEnvironment, string> = {\n\tsandbox: 'https://api.staging.inploi.com',\n\tproduction: 'https://api.inploi.com',\n\t// @ts-expect-error - local test environment\n\t_internal_local: 'http://api.test',\n};\n\nexport const ANALYTICS_VERSION = version;\n\nexport const LOG_PATHNAME = '/log';\n\nexport const ANALYTICS_COOKIE_NAME = 'isdk_session';\n","import type { ResponseObj } from '@inploi/core/common';\nimport { invariant } from '@inploi/core/common';\n\nimport { InploiRpcClient, Logger, endpoint, typed } from '.';\nimport { ANALYTICS_COOKIE_NAME, ANALYTICS_VERSION } from './sdk.constants';\n\nconst formatCookie = (value: string) => {\n\tconst now = new Date();\n\tnow.setTime(now.getTime() + 7 * 24 * 60 * 60 * 1000); // 7 days expiration\n\n\treturn `${ANALYTICS_COOKIE_NAME}=${value};expires=${now.toUTCString()};path=/`;\n};\n\ntype FlowProperties = { flow_id: string; flow_version: number; flow_session_id: string; flow_build: number };\n\ntype JobProperties = {\n\tid: string;\n\tid_type: 'internal' | 'external';\n};\n\nexport type AnalyticsLogParams =\n\t| {\n\t\t\tevent: 'VIEW_JOB';\n\t\t\tproperties: { job: JobProperties };\n\t }\n\t| {\n\t\t\tevent: 'FLOW_REDIRECT';\n\t\t\tproperties: { href: string; job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_START' | 'FLOW_END';\n\t\t\tproperties: { job: JobProperties | undefined } & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_NODE';\n\t\t\tproperties: {\n\t\t\t\t/** Increments by 1 per node interpreted */\n\t\t\t\tsequence: number;\n\t\t\t\tfrom_node_id: string;\n\t\t\t\tto_node_id: string;\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'FLOW_SUBMIT';\n\t\t\tproperties: {\n\t\t\t\tservice: string;\n\t\t\t\tresponse: {\n\t\t\t\t\tstatus: number;\n\t\t\t\t\tpayload: unknown;\n\t\t\t\t};\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t} & FlowProperties;\n\t }\n\t| {\n\t\t\tevent: 'SUBMIT_FORM' | 'VIEW_PAGE';\n\t\t\tproperties?: {\n\t\t\t\tjob: JobProperties | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'IDENTIFY';\n\t\t\tproperties: {\n\t\t\t\tidentifier: string;\n\t\t\t\tfirst_name?: string;\n\t\t\t\tlast_name?: string;\n\t\t\t\tphone_number?: string;\n\t\t\t\temail?: string;\n\t\t\t\tcustom_traits?: Record<string, unknown>;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_PAGINATE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_SETTLE';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'SEARCH_JOB_CLICK';\n\t\t\tproperties: {\n\t\t\t\tjob_id: number;\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'VIEW_SEARCH';\n\t\t\tproperties: {\n\t\t\t\tquery?: string;\n\t\t\t\tfilters?: Record<string, string[]>;\n\t\t\t\tdefault_filters?: Record<string, string[]>;\n\t\t\t\ttotal_count: number;\n\t\t\t\tpage_size: number;\n\t\t\t\tpage: number;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'FEEDBACK';\n\t\t\tproperties: {\n\t\t\t\tkey: string;\n\t\t\t\tscore?: -1 | 0 | 1;\n\t\t\t\tcomment?: string;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'LINK_CLICK';\n\t\t\tproperties: {\n\t\t\t\ttarget_href: string;\n\t\t\t\tjob_id: string | undefined;\n\t\t\t};\n\t }\n\t| {\n\t\t\tevent: 'INTERACTION';\n\t\t\tproperties: {\n\t\t\t\ttag: string;\n\t\t\t};\n\t };\n\nexport type AnalyticsLogEvent = AnalyticsLogParams['event'];\n\ntype EventPropertyMap = {\n\t[Param in AnalyticsLogParams as Param['event']]: Omit<Param, 'event'>;\n};\n\ntype AnalyticsContext = {\n\tlibrary: {\n\t\tname: 'inploi-sdk';\n\t\tversion: string;\n\t};\n\tpage: {\n\t\thref: string;\n\t\treferrer: string;\n\t\ttitle: string;\n\t};\n};\n\ntype TrackPayload<P = EventPropertyMap[keyof EventPropertyMap]['properties']> = {\n\tanonymous_id: string | null;\n\tsession_id: string | null;\n\tevent: AnalyticsLogEvent;\n\tsent_at: string;\n\tcontext: AnalyticsContext;\n\tproperties: P;\n\tcustom_properties?: Record<string, unknown>;\n};\n\ntype LogFnParams<T extends keyof EventPropertyMap> = {\n\tevent: T;\n\tcustomProperties?: Record<string, unknown>;\n\t/** Passing a request will make logging possible on a server environment. */\n\trequest?: Request;\n} & EventPropertyMap[T];\n\ntype LogFn = <TEvent extends keyof EventPropertyMap>(\n\tparams: LogFnParams<TEvent>,\n) => Promise<ResponseObj<TrackPayload<EventPropertyMap[TEvent]['properties']>>>;\n\nexport type AnalyticsService = {\n\tlog: LogFn;\n\t/** From a log payload data, generate headers to use in server environments to update the anonymous_id */\n\tgetHeaders: (payload?: TrackPayload) => Headers;\n\tgetSessionInfo: typeof getSessionInfo;\n};\n\nconst getSessionId = (searchParams: URLSearchParams, isServer: boolean) => {\n\tconst fromSearchParams = searchParams.get('session_id');\n\tif (isServer) return fromSearchParams;\n\tif (fromSearchParams) return fromSearchParams;\n\tconst fromSessionStorage = sessionStorage.getItem(`${ANALYTICS_COOKIE_NAME}-session_id`);\n\tif (typeof fromSessionStorage === 'string') return fromSessionStorage;\n\treturn null;\n};\n\nconst cookieRegex = new RegExp(`${ANALYTICS_COOKIE_NAME}=([^;]+)`);\nconst getSessionInfo = (request?: Request) => {\n\tconst href = request ? request.url : location.href;\n\tconst { searchParams } = new URL(href);\n\tconst anonymous_id = searchParams.get('anonymous_id');\n\tconst session_id = getSessionId(searchParams, typeof window === 'undefined');\n\n\t// If there’s an anonymous_id in the search params, use it\n\tif (anonymous_id)\n\t\treturn {\n\t\t\tanonymous_id,\n\t\t\tsession_id,\n\t\t};\n\n\t// If there’s a cookie, use it\n\tconst cookie = request ? request.headers.get('cookie') : document.cookie;\n\tif (cookie) {\n\t\tconst match = cookieRegex.exec(cookie);\n\t\tconst anonymous_id = match?.[1];\n\t\treturn {\n\t\t\tanonymous_id: anonymous_id ?? null,\n\t\t\tsession_id,\n\t\t};\n\t}\n\n\t// Otherwise, return what we have\n\treturn {\n\t\tanonymous_id,\n\t\tsession_id,\n\t};\n};\n\nconst getSessionInfoFromResponse = (response: unknown) => {\n\tif (typeof response !== 'object' || response === null) return null;\n\treturn {\n\t\tanonymous_id:\n\t\t\t'anonymous_id' in response && typeof response.anonymous_id === 'string' ? response.anonymous_id : null,\n\t\tsession_id: 'session_id' in response && typeof response.session_id === 'string' ? response.session_id : null,\n\t};\n};\n\nconst serverReferrer = (referrer: typeof Request.prototype.referrer) => {\n\tif (referrer === 'about:client') return '';\n\treturn referrer;\n};\n\nconst analyticsLogEndpoint = endpoint({\n\tpathname: '/log',\n\tmethod: 'POST',\n\tschema: {\n\t\tresponse: typed<unknown>(),\n\t\tbody: typed<TrackPayload>(),\n\t},\n});\n\nexport type AnalyticsOnEventCallback = (event: AnalyticsLogParams) => void;\n\nexport const createAnalyticsService = ({\n\trpcClient,\n\tlogger,\n\tonEvent,\n}: {\n\tlogger: Logger;\n\trpcClient: InploiRpcClient;\n\tonEvent?: AnalyticsOnEventCallback;\n}): AnalyticsService => {\n\tconst logFn: LogFn = async params => {\n\t\tinvariant(\n\t\t\tparams.request || typeof window !== 'undefined',\n\t\t\t'Cannot log on the server without a request. Please pass a request to `log`.',\n\t\t);\n\n\t\t// if there’s a request, use it instead of browser APIs\n\t\tconst page =\n\t\t\t'request' in params && params.request ?\n\t\t\t\t{\n\t\t\t\t\thref: params.request.url,\n\t\t\t\t\treferrer: serverReferrer(params.request.referrer),\n\t\t\t\t\ttitle: '',\n\t\t\t\t}\n\t\t\t:\t{\n\t\t\t\t\thref: location.href,\n\t\t\t\t\treferrer: document.referrer,\n\t\t\t\t\ttitle: document.title,\n\t\t\t\t};\n\n\t\ttry {\n\t\t\tconst context: AnalyticsContext = {\n\t\t\t\tlibrary: {\n\t\t\t\t\tname: 'inploi-sdk',\n\t\t\t\t\tversion: ANALYTICS_VERSION,\n\t\t\t\t},\n\t\t\t\tpage,\n\t\t\t};\n\n\t\t\tconst sessionInfo = getSessionInfo(params.request);\n\t\t\tconst payload: TrackPayload = {\n\t\t\t\tanonymous_id: sessionInfo.anonymous_id,\n\t\t\t\tsession_id: sessionInfo.session_id,\n\t\t\t\tevent: params.event,\n\t\t\t\tsent_at: new Date().toISOString(),\n\t\t\t\tcontext,\n\t\t\t\tproperties: params.properties,\n\t\t\t\tcustom_properties: params.customProperties,\n\t\t\t};\n\n\t\t\tconst responseJson = await rpcClient.request(analyticsLogEndpoint, {\n\t\t\t\tbody: payload,\n\t\t\t});\n\n\t\t\tconst newSession = getSessionInfoFromResponse(responseJson);\n\t\t\tif (newSession?.anonymous_id) {\n\t\t\t\tpayload.anonymous_id = newSession.anonymous_id;\n\t\t\t}\n\t\t\tif (newSession?.session_id) {\n\t\t\t\tpayload.session_id = newSession.session_id;\n\t\t\t}\n\n\t\t\tif (typeof window !== 'undefined' && payload.anonymous_id) {\n\t\t\t\tif (payload.session_id) {\n\t\t\t\t\tsessionStorage.setItem(`${ANALYTICS_COOKIE_NAME}-session_id`, payload.session_id.toString());\n\t\t\t\t}\n\t\t\t\tdocument.cookie = formatCookie(payload.anonymous_id);\n\t\t\t}\n\n\t\t\tonEvent?.(payload as AnalyticsLogParams);\n\t\t\treturn { success: true, data: payload };\n\t\t} catch (e) {\n\t\t\t/** We dont’t log any PII on the console */\n\t\t\tlogger.error('Failed to send log to API. Inspect error response of `log` for more information.');\n\t\t\treturn { success: false, error: e };\n\t\t}\n\t};\n\n\treturn {\n\t\tlog: logFn,\n\t\tgetHeaders: payload => {\n\t\t\tconst headers = new Headers();\n\t\t\tif (!payload?.anonymous_id) return headers;\n\n\t\t\theaders.append('Set-Cookie', formatCookie(payload.anonymous_id));\n\t\t\treturn headers;\n\t\t},\n\t\tgetSessionInfo,\n\t};\n};\n","import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { stringify } from 'neoqs';\n\nimport { JsonParsingError, SchemaValidationError, handleApiExceptions } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger } from './sdk.logger';\n\ntype RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\n/** Extract parameter names from a pathname string */\ntype ExtractParamNames<T extends string> =\n\tT extends `${infer _Before}:${infer Param}/${infer After}` ? Param | ExtractParamNames<`/${After}`>\n\t: T extends `${infer _Before}:${infer Param}` ? Param\n\t: never;\n\n/** Create params object from parameter names */\ntype ExtractPathParams<T extends string> =\n\tstring extends T ? Record<string, string | number>\n\t: ExtractParamNames<T> extends never ? Record<string, never>\n\t: { [K in ExtractParamNames<T>]: string | number };\n\n/** Parses a StandardSchemaV1 schema and input into an output. */\nexport function parse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n\tsource?: 'body' | 'searchParams' | 'response',\n): StandardSchemaV1.InferOutput<T> {\n\tconst result = schema['~standard'].validate(input);\n\tif (result instanceof Promise) {\n\t\tthrow new TypeError('Async schema');\n\t}\n\n\tif (result.issues) {\n\t\tthrow new SchemaValidationError(result.issues, source);\n\t}\n\n\treturn result.value;\n}\n\n/** Parses a StandardSchemaV1 schema and input into an output, returning a success flag and issues if the parse fails. */\nexport function safeParse<T extends StandardSchemaV1>(\n\tschema: T,\n\tinput: StandardSchemaV1.InferInput<T>,\n\tsource?: 'body' | 'searchParams' | 'response',\n):\n\t| {\n\t\t\tsuccess: true;\n\t\t\toutput: StandardSchemaV1.InferOutput<T>;\n\t }\n\t| {\n\t\t\tsuccess: false;\n\t\t\tissues: readonly StandardSchemaV1.Issue[];\n\t\t\tsource?: 'body' | 'searchParams' | 'response';\n\t } {\n\ttry {\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\toutput: parse(schema, input, source),\n\t\t};\n\t} catch (e) {\n\t\tif (e instanceof SchemaValidationError) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\tissues: e.issues,\n\t\t\t\tsource: e.source,\n\t\t\t};\n\t\t}\n\t\tthrow e;\n\t}\n}\n\nexport interface InploiRpcClientParams {\n\tenvironment: InploiSdkEnvironment;\n\tlogger: Logger;\n\tapiKey:\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-secret-key header\n\t\t\t\t * This will error if used in a browser environment.\n\t\t\t\t */\n\t\t\t\ttype: 'secret';\n\t\t\t\tkey: string;\n\t\t }\n\t\t| {\n\t\t\t\t/** Makes the API call with an x-publishable-key header\n\t\t\t\t * This can be called in a browser or server environment.\n\t\t\t\t */\n\t\t\t\ttype: 'publishable';\n\t\t\t\tkey: string;\n\t\t };\n}\n\n// eslint-disable-next-line @typescript-eslint/ban-types\ntype NonReducibleUnknown = {} | null | undefined;\ntype LooseAutocomplete<T extends BaseType, BaseType> = T | BaseType;\n\n/** RPC client for making API calls to the Inploi API. */\nexport class InploiRpcClient {\n\tprivate baseUrl: string;\n\tprivate headers: Headers;\n\tprivate logger: Logger;\n\n\tconstructor(params: InploiRpcClientParams) {\n\t\tthis.baseUrl = ENV_TO_API_URL[params.environment];\n\t\tthis.headers = new Headers({\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAccept: 'application/json',\n\t\t});\n\t\tif (params.apiKey.type === 'secret') {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\tthrow new Error('Secret key cannot be used in a browser environment');\n\t\t\t}\n\t\t\tthis.headers.set('x-secret-key', params.apiKey.key);\n\t\t} else {\n\t\t\tthis.headers.set('x-publishable-key', params.apiKey.key);\n\t\t}\n\t\tthis.logger = params.logger;\n\t}\n\n\t/** Gets params for a fetch request to the given endpoint */\n\tgetFetchParams<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ?\n\t\t\tGetSchemaValues<{\n\t\t\t\tbody: TBody;\n\t\t\t\tsearchParams: TSearch;\n\t\t\t\tparams: TPathParams;\n\t\t\t}> & {\n\t\t\t\tsignal?: AbortSignal;\n\t\t\t\t/**\n\t\t\t\t * Whether to validate the inputs against the schema.\n\t\t\t\t * If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.\n\t\t\t\t */\n\t\t\t\tvalidateIn?: boolean;\n\t\t\t}\n\t\t:\tnever,\n\t): [url: string, options: RequestInit] {\n\t\tconst validateIn = options.validateIn ?? true;\n\t\tconst { searchParams, body } = validateIn ? validateEndpointInputs(endpoint, options) : options;\n\n\t\tconst url = new URL(this.baseUrl);\n\n\t\t// Replace path parameters in pathname\n\t\tlet pathname = endpoint.pathname;\n\t\tif ('params' in options && options.params) {\n\t\t\tfor (const [key, value] of Object.entries(options.params)) {\n\t\t\t\tpathname = pathname.replace(`:${key}`, String(value));\n\t\t\t}\n\t\t}\n\t\turl.pathname = pathname;\n\n\t\tif (endpoint.schema.searchParams) {\n\t\t\turl.search = stringify(searchParams);\n\t\t}\n\n\t\treturn [\n\t\t\turl.toString(),\n\t\t\t{\n\t\t\t\tmethod: endpoint.method,\n\t\t\t\tbody: body ? JSON.stringify(body) : undefined,\n\t\t\t\theaders: this.headers,\n\t\t\t\tsignal: options.signal,\n\t\t\t},\n\t\t];\n\t}\n\n\t/** Parses a response against an endpoint’s response schema, considering common errors thrown from the API.\n\t * @throws {JsonParsingError} - If the response is not valid JSON.\n\t * @throws {SchemaValidationError} - If the response does not match the schema.\n\t * @throws {ApiError} - If the API responded with an error message.\n\t */\n\tasync parseResponse<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: {\n\t\t\tresponse: Response;\n\t\t\t/**\n\t\t\t * Whether to validate the response against the schema.\n\t\t\t * This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.\n\t\t\t * ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.\n\t\t\t */\n\t\t\tvalidateOut?: boolean;\n\t\t},\n\t): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>> {\n\t\tconst json = await options.response.json().catch(e => {\n\t\t\tthis.logger.error(e);\n\t\t\tthrow new JsonParsingError(options.response);\n\t\t});\n\n\t\tconst validateOut = options.validateOut ?? true;\n\t\tif (!validateOut) return json as StandardSchemaV1.InferOutput<T['schema']['response']>;\n\n\t\tconst result = safeParse(endpoint.schema.response, json, 'response');\n\t\tif (!result.success) {\n\t\t\thandleApiExceptions(json, options.response.status);\n\t\t\tthrow new SchemaValidationError(result.issues, result.source);\n\t\t}\n\n\t\treturn result.output as StandardSchemaV1.InferOutput<T['schema']['response']>;\n\t}\n\n\t/** Fetches, parses and validates an API endpoint.\n\t * Logs errors and throws them again so that the caller can handle them.\n\t *\n\t * @throws {JsonParsingError} - If the response is not valid JSON.\n\t * @throws {SchemaValidationError} - If the searchParams, body or response does not match the schema.\n\t * @throws {ApiError} - If the API responded with an error message.\n\t * @throws {UnauthorisedError} - If the request is unauthorised either by missing key or unmet permissions.\n\t * @throws {NotFoundError} - If the endpoint is not found.\n\t * @throws {Error} - Another unhandled error.\n\t */\n\tasync request<T extends RpcEndpoint>(\n\t\tendpoint: T,\n\t\toptions: T extends RpcEndpoint<infer _, infer _TPathname, infer TPathParams, infer TSearch, infer TBody> ?\n\t\t\tGetSchemaValues<{\n\t\t\t\tbody: TBody;\n\t\t\t\tsearchParams: TSearch;\n\t\t\t\tparams: TPathParams;\n\t\t\t}> & {\n\t\t\t\tsignal?: AbortSignal;\n\t\t\t\t/**\n\t\t\t\t * Whether to validate the inputs against the schema.\n\t\t\t\t * If you want to skip validation (e.g.: already validated yourself or with `validateEndpontInputs`), set this to false.\n\t\t\t\t */\n\t\t\t\tvalidateIn?: boolean;\n\t\t\t\t/**\n\t\t\t\t * Whether to validate the response against the schema.\n\t\t\t\t * This is meant more as an escape hatch for when the response is not as expected and you want to handle it separately yourself.\n\t\t\t\t * ⚠️ This will lead to potential type/runtime mismatch as it does not verify the response against the schema.\n\t\t\t\t */\n\t\t\t\tvalidateOut?: boolean;\n\t\t\t}\n\t\t:\tnever,\n\t): Promise<StandardSchemaV1.InferOutput<T['schema']['response']>> {\n\t\ttry {\n\t\t\tconst fetchParams = this.getFetchParams(endpoint, options);\n\t\t\tconst response = await fetch(...fetchParams);\n\t\t\treturn this.parseResponse(endpoint, { response, validateOut: options.validateOut });\n\t\t} catch (e) {\n\t\t\tif (e instanceof SchemaValidationError) {\n\t\t\t\tthis.logger.error(e.message, e.issues);\n\t\t\t} else {\n\t\t\t\tthis.logger.error(e);\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n}\n\ntype GetSchemaValues<T extends { searchParams: any; body: any; params?: any }> = {\n\t[K in keyof T as T[K] extends never ? never\n\t: T[K] extends Record<string, never> ? never\n\t: K]: T[K] extends never ? never : LooseAutocomplete<T[K], NonReducibleUnknown>;\n};\n\n/**\n * Typed but *not runtime validated* schema\n * useful for type-checking the schema without bundling validation schemas\n */\nexport function typed<T>(): StandardSchemaV1<T, T> {\n\treturn {\n\t\t'~standard': {\n\t\t\tvendor: 'inploi',\n\t\t\tversion: 1,\n\t\t\tvalidate: input => {\n\t\t\t\treturn {\n\t\t\t\t\tvalue: input as T,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t};\n}\n\nexport interface RpcEndpoint<\n\tTMethod extends RequestMethod = RequestMethod,\n\tTPathname extends string = string,\n\tTPathParams = any,\n\tTSearch = any,\n\tTBody = any,\n\tTResponse = any,\n> {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: StandardSchemaV1<TSearch, TSearch>;\n\t\tbody?: StandardSchemaV1<TBody, TBody>;\n\t\tresponse: StandardSchemaV1<TResponse, TResponse>;\n\t};\n\t/** Type-only property to store path parameter types */\n\treadonly __pathParams?: TPathParams;\n}\n\nexport function endpoint<\n\tTMethod extends RequestMethod,\n\tTPathname extends string,\n\tTSearch extends StandardSchemaV1 | never = never,\n\tTBody extends StandardSchemaV1 | never = never,\n\tTResponse extends StandardSchemaV1 | never = never,\n>(endpoint: {\n\tpathname: TPathname;\n\tmethod: TMethod;\n\theaders?: Headers;\n\tschema: {\n\t\tsearchParams?: TSearch;\n\t\tbody?: TBody;\n\t\tresponse: TResponse;\n\t};\n}) {\n\ttype PathParams = ExtractPathParams<TPathname>;\n\treturn endpoint as RpcEndpoint<\n\t\tTMethod,\n\t\tTPathname,\n\t\tPathParams,\n\t\tStandardSchemaV1.InferInput<TSearch>,\n\t\tStandardSchemaV1.InferInput<TBody>,\n\t\tStandardSchemaV1.InferOutput<TResponse>\n\t>;\n}\n\n/** Validates the inputs for an endpoint ahead of time\n * Useful when you need to validate and throw earlier, or use the inputs for something other than the API call.\n */\nexport function validateEndpointInputs<T extends RpcEndpoint>(\n\tendpoint: T,\n\toptions: GetSchemaValues<{ body: unknown; searchParams: unknown }>,\n) {\n\tconst validatedInputs = {\n\t\tsearchParams: undefined,\n\t\tbody: undefined,\n\t\tvalidateIn: false,\n\t} as T extends RpcEndpoint<infer _, infer __, infer ___, infer TSearch, infer TBody> ?\n\t\tGetSchemaValues<{\n\t\t\tbody: TBody;\n\t\t\tsearchParams: TSearch;\n\t\t}> & {\n\t\t\tvalidateIn: false;\n\t\t}\n\t:\tnever;\n\n\tif (endpoint.schema.searchParams) {\n\t\tvalidatedInputs.searchParams = parse(\n\t\t\tendpoint.schema.searchParams,\n\t\t\t'searchParams' in options ? options.searchParams : {},\n\t\t);\n\t}\n\n\tif (endpoint.schema.body) {\n\t\tvalidatedInputs.body = parse(endpoint.schema.body, 'body' in options ? options.body : {});\n\t}\n\n\treturn validatedInputs;\n}\n","import { AnalyticsOnEventCallback, createAnalyticsService } from './sdk.analytics';\nimport { createApiClient } from './sdk.api';\nimport { ENV_TO_API_URL, InploiSdkEnvironment } from './sdk.constants';\nimport { Logger, inploiBrandedLogger, noLogging } from './sdk.logger';\nimport { InploiSdkPlugin } from './sdk.plugins';\nimport { InploiRpcClient } from './sdk.rpc';\n\nexport type InitialiseInploiSdkParams = {\n\t/** Your public API key for the inploi SDK. */\n\tpublishableKey: string;\n\t/** Which app environment to run. This ultimately affects which inploi endpoints to gather data are going to be used.\n\t * Anything other than `production` should be considered a development environment and the data periodicaly purged. */\n\tenv: InploiSdkEnvironment;\n\t/** Logger object that handles logging of different levels.\n\t * You can override this to use your own logger, or to disable logging altogether by passing`false`.\n\t * @default inploiBrandedLogger\n\t * */\n\tlogger?: Logger | false;\n\n\t/** When provided, this callback will be called with every event that is logged to the analytics service. */\n\tonEvent?: AnalyticsOnEventCallback;\n};\n\nexport function initialiseSdk({\n\tpublishableKey,\n\tenv,\n\tlogger = inploiBrandedLogger,\n\tonEvent,\n}: InitialiseInploiSdkParams) {\n\t/** @deprecated - use `rpcClient` instead */\n\tconst apiClient = createApiClient({ baseUrl: ENV_TO_API_URL[env], publishableKey });\n\tconst loggerService = logger === false ? noLogging : logger;\n\tconst rpcClient = new InploiRpcClient({\n\t\tenvironment: env,\n\t\tapiKey: { type: 'publishable', key: publishableKey },\n\t\tlogger: loggerService,\n\t});\n\tconst analytics = createAnalyticsService({ rpcClient, logger: loggerService, onEvent });\n\n\tconst register = <P extends InploiSdkPlugin>(plugin: P): ReturnType<P> => {\n\t\treturn plugin({ logger: loggerService, apiClient, analytics, rpcClient });\n\t};\n\n\treturn { register, analytics, apiClient };\n}\n\nexport type InploiSdk = ReturnType<typeof initialiseSdk>;\n"],"mappings":"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","names":["CONSOLE_PREFIX","CONSOLE_STYLE","inploiBrandedLogger","args","noLogging","createPlugin","pluginFn","invariant","condition","message","hasProp","data","prop","DEFAULT_FORMATTER","unauthenticatedMessage","unauthorisedMessage","ErrorWithStatus","message","status","NotFoundError","UnauthorisedError","SchemaValidationError","issues","source","sourceText","ApiError","JsonParsingError","response","ERROR_MESSAGE_KEYS","getErrorMessageFromJson","json","messages","key","hasProp","value","item","handleApiExceptions","status","message","NotFoundError","unauthenticatedMessage","UnauthorisedError","unauthorisedMessage","ApiError","createApiClient","params","defaultHeaders","_0","_1","__async","pathname","options","init","__spreadProps","__spreadValues","response","JsonParsingError","SdkError","SchemaValidationError","isSdkError","error","ErrorClass","version","ENV_TO_API_URL","ANALYTICS_VERSION","version","ANALYTICS_COOKIE_NAME","formatCookie","value","now","ANALYTICS_COOKIE_NAME","getSessionId","searchParams","isServer","fromSearchParams","fromSessionStorage","cookieRegex","getSessionInfo","request","href","anonymous_id","session_id","cookie","match","getSessionInfoFromResponse","response","serverReferrer","referrer","analyticsLogEndpoint","typed","createAnalyticsService","rpcClient","logger","onEvent","params","__async","invariant","page","context","ANALYTICS_VERSION","sessionInfo","payload","responseJson","newSession","e","headers","stringify","parse","schema","input","source","result","SchemaValidationError","safeParse","e","InploiRpcClient","params","ENV_TO_API_URL","endpoint","options","_a","validateIn","searchParams","body","validateEndpointInputs","url","pathname","key","value","stringify","__async","json","JsonParsingError","handleApiExceptions","fetchParams","response","typed","validatedInputs","initialiseSdk","publishableKey","env","logger","inploiBrandedLogger","onEvent","apiClient","createApiClient","ENV_TO_API_URL","loggerService","noLogging","rpcClient","InploiRpcClient","analytics","createAnalyticsService","plugin"]}
|
package/package.json
CHANGED
package/cdn/index.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
// This is an inploi sdk script. Learn more at https://inploi.com
|
|
2
|
-
|
|
3
|
-
"use strict";(()=>{var be=Object.defineProperty,we=Object.defineProperties;var _e=Object.getOwnPropertyDescriptors;var ne=Object.getOwnPropertySymbols;var Se=Object.prototype.hasOwnProperty,ve=Object.prototype.propertyIsEnumerable;var oe=(e,r,n)=>r in e?be(e,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[r]=n,N=(e,r)=>{for(var n in r||(r={}))Se.call(r,n)&&oe(e,n,r[n]);if(ne)for(var n of ne(r))ve.call(r,n)&&oe(e,n,r[n]);return e},ie=(e,r)=>we(e,_e(r));var v=(e,r,n)=>new Promise((t,o)=>{var l=c=>{try{i(n.next(c))}catch(s){o(s)}},p=c=>{try{i(n.throw(c))}catch(s){o(s)}},i=c=>c.done?t(c.value):Promise.resolve(c.value).then(l,p);i((n=n.apply(e,r)).next())});function H(e,r){if(!e)throw new Error(r)}var Ge=new Intl.RelativeTimeFormat(void 0,{numeric:"auto"});var C="%c[inploi SDK]",D="color: #65BC67; font-weight: bold;",U={warn:(...e)=>console.warn(C,D,...e),error:(...e)=>console.error(C,D,...e),info:(...e)=>console.info(C,D,...e),log:(...e)=>console.log(C,D,...e)},$={info:()=>{},error:()=>{},log:()=>{},warn:()=>{}};var xe="Unauthenticated",Te="This action is unauthorized.",F=class extends Error{constructor(){super("Not found"),this.name="NotFoundError"}},k=class extends Error{constructor(r){super(r!=null?r:"You are not authorised to perform this action."),this.name="UnauthorisedError"}},w=class extends Error{constructor(n){super("Schema validation failed");this.issues=n;this.name="SchemaValidationError"}},S=class extends Error{constructor(n,t){super(n);this.name="ApiError",this.errors=t}},T=class extends Error{constructor(n){super("Error parsing response into JSON.");this.response=n;this.name="ParsingError"}};function J(e){if(e!==null&&typeof e=="object"){let r="Generic API Error";if("message"in e&&typeof e.message=="string"&&(r=e.message),r===xe)throw new k("You are not authenticated.");if(r===Te)throw new k;if("exception"in e)throw new S(r,[e.exception]);if("errors"in e){if(Array.isArray(e.errors)&&e.errors.every(n=>typeof n=="string"))throw new S(r,e.errors);if(typeof e.errors=="object"&&e.errors!==null){let n=Object.entries(e.errors);throw n.every(([,t])=>Array.isArray(t)&&t.every(o=>typeof o=="string"))?new w(n.map(([t,o])=>({path:t.split("."),message:o.join(", ")}))):new S(r,n.map(([t,o])=>`${t}: ${o}`))}if(typeof e.errors=="string")throw new S(r,[e.errors])}if("error"in e&&typeof e.error=="string")throw new S(e.error,[e.error])}}var se=e=>{let r={Accept:"application/json","Content-Type":"application/json","x-publishable-key":e.publishableKey};return{fetch:(o,...l)=>v(void 0,[o,...l],function*(n,t={}){let p=ie(N({},t),{headers:N(N({},t.headers),r)}),i=yield fetch(`${e.baseUrl}${n}`,p);if(i.status===404)throw new F;let c=yield i.json().catch(()=>v(void 0,null,function*(){throw new T(i)}));return J(c),c})}};var Q="RFC3986",G={RFC1738:e=>String(e).replace(/%20/g,"+"),RFC3986:e=>String(e)},Ee="RFC1738";var Pe=Array.isArray,g=(()=>{let e=[];for(let r=0;r<256;++r)e.push("%"+((r<16?"0":"")+r.toString(16)).toUpperCase());return e})();var W=1024,ke=(e,r,n,t,o)=>{if(e.length===0)return e;let l=e;if(typeof e=="symbol"?l=Symbol.prototype.toString.call(e):typeof e!="string"&&(l=String(e)),n==="iso-8859-1")return escape(l).replace(/%u[0-9a-f]{4}/gi,function(i){return"%26%23"+parseInt(i.slice(2),16)+"%3B"});let p="";for(let i=0;i<l.length;i+=W){let c=l.length>=W?l.slice(i,i+W):l,s=[];for(let f=0;f<c.length;++f){let a=c.charCodeAt(f);if(a===45||a===46||a===95||a===126||a>=48&&a<=57||a>=65&&a<=90||a>=97&&a<=122||o===Ee&&(a===40||a===41)){s[s.length]=c.charAt(f);continue}if(a<128){s[s.length]=g[a];continue}if(a<2048){s[s.length]=g[192|a>>6]+g[128|a&63];continue}if(a<55296||a>=57344){s[s.length]=g[224|a>>12]+g[128|a>>6&63]+g[128|a&63];continue}f+=1,a=65536+((a&1023)<<10|c.charCodeAt(f)&1023),s[s.length]=g[240|a>>18]+g[128|a>>12&63]+g[128|a>>6&63]+g[128|a&63]}p+=s.join("")}return p};function Ie(e){return!e||typeof e!="object"?!1:!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))}function ae(e,r){if(Pe(e)){let n=[];for(let t=0;t<e.length;t+=1)n.push(r(e[t]));return n}return r(e)}var tr=Array.isArray;var Ae=Object.prototype.hasOwnProperty,le={brackets(e){return String(e)+"[]"},comma:"comma",indices(e,r){return String(e)+"["+r+"]"},repeat(e){return String(e)}},b=Array.isArray,Oe=Array.prototype.push,ce=function(e,r){Oe.apply(e,b(r)?r:[r])},Re=Date.prototype.toISOString,u={addQueryPrefix:!1,allowDots:!1,allowEmptyArrays:!1,arrayFormat:"indices",charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encodeDotInKeys:!1,encoder:ke,encodeValuesOnly:!1,format:Q,formatter:G[Q],indices:!1,serializeDate(e){return Re.call(e)},skipNulls:!1,strictNullHandling:!1};function Le(e){return typeof e=="string"||typeof e=="number"||typeof e=="boolean"||typeof e=="symbol"||typeof e=="bigint"}var Y={};function de(e,r,n,t,o,l,p,i,c,s,f,a,h,_,m,E,O,M){let d=e,R=M,L=0,Z=!1;for(;(R=R.get(Y))!==void 0&&!Z;){let y=R.get(e);if(L+=1,typeof y!="undefined"){if(y===L)throw new RangeError("Cyclic object value");Z=!0}typeof R.get(Y)=="undefined"&&(L=0)}if(typeof s=="function"?d=s(r,d):d instanceof Date?d=h==null?void 0:h(d):n==="comma"&&b(d)&&(d=ae(d,function(y){return y instanceof Date?h==null?void 0:h(y):y})),d===null){if(l)return c&&!E?c(r,u.encoder,O,"key",_):r;d=""}if(Le(d)||Ie(d)){if(c){let y=E?r:c(r,u.encoder,O,"key",_);return[(m==null?void 0:m(y))+"="+(m==null?void 0:m(c(d,u.encoder,O,"value",_)))]}return[(m==null?void 0:m(r))+"="+(m==null?void 0:m(String(d)))]}let q=[];if(typeof d=="undefined")return q;let P;if(n==="comma"&&b(d))E&&c&&(d=ae(d,c)),P=[{value:d.length>0?d.join(",")||null:void 0}];else if(b(s))P=s;else{let y=Object.keys(d);P=f?y.sort(f):y}let ee=i?String(r).replace(/\./g,"%2E"):String(r),j=t&&b(d)&&d.length===1?ee+"[]":ee;if(o&&b(d)&&d.length===0)return j+"[]";for(let y=0;y<P.length;++y){let x=P[y],re=typeof x=="object"&&typeof x.value!="undefined"?x.value:d[x];if(p&&re===null)continue;let B=a&&i?x.replace(/\./g,"%2E"):x,ge=b(d)?typeof n=="function"?n(j,B):j:j+(a?"."+B:"["+B+"]");M.set(e,L);let te=new WeakMap;te.set(Y,M),ce(q,de(re,ge,n,t,o,l,p,i,n==="comma"&&E&&b(d)?null:c,s,f,a,h,_,m,E,O,te))}return q}function je(e=u){if(typeof e.allowEmptyArrays!="undefined"&&typeof e.allowEmptyArrays!="boolean")throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");if(typeof e.encodeDotInKeys!="undefined"&&typeof e.encodeDotInKeys!="boolean")throw new TypeError("`encodeDotInKeys` option can only be `true` or `false`, when provided");if(e.encoder!==null&&typeof e.encoder!="undefined"&&typeof e.encoder!="function")throw new TypeError("Encoder has to be a function.");let r=e.charset||u.charset;if(typeof e.charset!="undefined"&&e.charset!=="utf-8"&&e.charset!=="iso-8859-1")throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");let n=Q;if(typeof e.format!="undefined"){if(!Ae.call(G,e.format))throw new TypeError("Unknown format option provided.");n=e.format}let t=G[n],o=u.filter;(typeof e.filter=="function"||b(e.filter))&&(o=e.filter);let l;if(e.arrayFormat&&e.arrayFormat in le?l=e.arrayFormat:"indices"in e?l=e.indices?"indices":"repeat":l=u.arrayFormat,"commaRoundTrip"in e&&typeof e.commaRoundTrip!="boolean")throw new TypeError("`commaRoundTrip` must be a boolean, or absent");let p=typeof e.allowDots=="undefined"?e.encodeDotInKeys?!0:u.allowDots:!!e.allowDots;return{addQueryPrefix:typeof e.addQueryPrefix=="boolean"?e.addQueryPrefix:u.addQueryPrefix,allowDots:p,allowEmptyArrays:typeof e.allowEmptyArrays=="boolean"?!!e.allowEmptyArrays:u.allowEmptyArrays,arrayFormat:l,charset:r,charsetSentinel:typeof e.charsetSentinel=="boolean"?e.charsetSentinel:u.charsetSentinel,commaRoundTrip:!!e.commaRoundTrip,delimiter:typeof e.delimiter=="undefined"?u.delimiter:e.delimiter,encode:typeof e.encode=="boolean"?e.encode:u.encode,encodeDotInKeys:typeof e.encodeDotInKeys=="boolean"?e.encodeDotInKeys:u.encodeDotInKeys,encoder:typeof e.encoder=="function"?e.encoder:u.encoder,encodeValuesOnly:typeof e.encodeValuesOnly=="boolean"?e.encodeValuesOnly:u.encodeValuesOnly,filter:o,format:n,formatter:t,serializeDate:typeof e.serializeDate=="function"?e.serializeDate:u.serializeDate,skipNulls:typeof e.skipNulls=="boolean"?e.skipNulls:u.skipNulls,sort:typeof e.sort=="function"?e.sort:null,strictNullHandling:typeof e.strictNullHandling=="boolean"?e.strictNullHandling:u.strictNullHandling}}function pe(e,r={}){let n=e,t=je(r),o,l;typeof t.filter=="function"?(l=t.filter,n=l("",n)):b(t.filter)&&(l=t.filter,o=l);let p=[];if(typeof n!="object"||n===null)return"";let i=le[t.arrayFormat],c=i==="comma"&&t.commaRoundTrip;o||(o=Object.keys(n)),t.sort&&o.sort(t.sort);let s=new WeakMap;for(let h=0;h<o.length;++h){let _=o[h];t.skipNulls&&n[_]===null||ce(p,de(n[_],_,i,c,t.allowEmptyArrays,t.strictNullHandling,t.skipNulls,t.encodeDotInKeys,t.encode?t.encoder:null,t.filter,t.sort,t.allowDots,t.serializeDate,t.format,t.formatter,t.encodeValuesOnly,t.charset,s))}let f=p.join(t.delimiter),a=t.addQueryPrefix===!0?"?":"";return t.charsetSentinel&&(t.charset==="iso-8859-1"?a+="utf8=%26%2310003%3B&":a+="utf8=%E2%9C%93&"),f.length>0?a+f:""}var ue="1.15.2";var K={sandbox:"https://api.staging.inploi.com",production:"https://api.inploi.com",_internal_local:"http://api.test"},fe=ue;var I="isdk_session";function z(e,r){let n=e["~standard"].validate(r);if(n instanceof Promise)throw new TypeError("Async schema");if(n.issues)throw new w(n.issues);return n.value}function Ce(e,r){try{return{success:!0,output:z(e,r)}}catch(n){if(n instanceof w)return{success:!1,issues:n.issues};throw n}}var A=class{constructor(r){if(this.baseUrl=K[r.environment],this.headers=new Headers({"Content-Type":"application/json",Accept:"application/json"}),r.apiKey.type==="secret"){if(typeof window!="undefined")throw new Error("Secret key cannot be used in a browser environment");this.headers.set("x-secret-key",r.apiKey.key)}else this.headers.set("x-publishable-key",r.apiKey.key);this.logger=r.logger}request(r,n){return v(this,null,function*(){try{let t=new URL(this.baseUrl),o=r.pathname;if("params"in n&&n.params)for(let[s,f]of Object.entries(n.params))o=o.replace(`:${s}`,String(f));t.pathname=o,r.schema.searchParams&&(t.search=pe(z(r.schema.searchParams,"searchParams"in n?n.searchParams:{})));let l=r.schema.body?z(r.schema.body,"body"in n?n.body:{}):void 0,p=yield fetch(t.toString(),{method:r.method,body:l?JSON.stringify(l):void 0,headers:this.headers,signal:n.signal}),i=yield p.json().catch(s=>{throw this.logger.error(s),new T(p)}),c=Ce(r.schema.response,i);if(!c.success)throw J(i),new w(c.issues);return c.output}catch(t){throw t instanceof w?this.logger.error(t.message,t.issues):this.logger.error(t),t}})}};function V(){return{"~standard":{vendor:"inploi",version:1,validate:e=>({value:e})}}}var ye=e=>{let r=new Date;return r.setTime(r.getTime()+7*24*60*60*1e3),`${I}=${e};expires=${r.toUTCString()};path=/`},Fe=(e,r)=>{let n=e.get("session_id");if(r||n)return n;let t=sessionStorage.getItem(`${I}-session_id`);return typeof t=="string"?t:null},Ke=new RegExp(`${I}=([^;]+)`),me=e=>{let r=e?e.url:location.href,{searchParams:n}=new URL(r),t=n.get("anonymous_id"),o=Fe(n,typeof window=="undefined");if(t)return{anonymous_id:t,session_id:o};let l=e?e.headers.get("cookie"):document.cookie;if(l){let p=Ke.exec(l),i=p==null?void 0:p[1];return{anonymous_id:i!=null?i:null,session_id:o}}return{anonymous_id:t,session_id:o}},Ve=e=>typeof e!="object"||e===null?null:{anonymous_id:"anonymous_id"in e&&typeof e.anonymous_id=="string"?e.anonymous_id:null,session_id:"session_id"in e&&typeof e.session_id=="string"?e.session_id:null},Me=e=>e==="about:client"?"":e,qe={pathname:"/log",method:"POST",schema:{response:V(),body:V()}},he=({rpcClient:e,logger:r})=>({log:t=>v(void 0,null,function*(){H(t.request||typeof window!="undefined","Cannot log on the server without a request. Please pass a request to `log`.");let o="request"in t&&t.request?{href:t.request.url,referrer:Me(t.request.referrer),title:""}:{href:location.href,referrer:document.referrer,title:document.title};try{let l={library:{name:"inploi-sdk",version:fe},page:o},p=me(t.request),i={anonymous_id:p.anonymous_id,session_id:p.session_id,event:t.event,sent_at:new Date().toISOString(),context:l,properties:t.properties,custom_properties:t.customProperties},c=yield e.request(qe,{body:i}),s=Ve(c);return s!=null&&s.anonymous_id&&(i.anonymous_id=s.anonymous_id),s!=null&&s.session_id&&(i.session_id=s.session_id),typeof window!="undefined"&&i.anonymous_id&&(i.session_id&&sessionStorage.setItem(`${I}-session_id`,i.session_id.toString()),document.cookie=ye(i.anonymous_id)),{success:!0,data:i}}catch(l){return r.error("Failed to send log to API. Inspect error response of `log` for more information."),{success:!1,error:l}}}),getHeaders:t=>{let o=new Headers;return t!=null&&t.anonymous_id&&o.append("Set-Cookie",ye(t.anonymous_id)),o},getSessionInfo:me});function X({publishableKey:e,env:r,logger:n=U}){let t=se({baseUrl:K[r],publishableKey:e}),o=n===!1?$:n,l=new A({environment:r,apiKey:{type:"publishable",key:e},logger:o}),p=he({rpcClient:l,logger:o});return{register:c=>c({logger:o,apiClient:t,analytics:p,rpcClient:l}),analytics:p,apiClient:t}}typeof window.inploi!="object"&&(window.inploi={});window.process=window.process||{};window.process.env=window.process.env||{};window.process.env.NODE_ENV="production";window.inploi.initialiseSdk=X;})();
|