@simplr-ai/node 1.1.0 → 1.1.1
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/README.md +94 -2
- package/dist/index.cjs +306 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +265 -3
- package/dist/index.d.ts +265 -3
- package/dist/index.js +303 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,13 @@ interface SimplrOptions {
|
|
|
12
12
|
apiKey: string;
|
|
13
13
|
/** Public key (pk_…) — enables `simplr.flags` for server-side feature-flag evaluation. */
|
|
14
14
|
publicKey?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Which environment's flags `simplr.flags` should load. Accepts a named
|
|
17
|
+
* environment slug (e.g. "dev", "uat", "prod") as well as the legacy
|
|
18
|
+
* "live"/"test" key modes. When unset, the API falls back to the public
|
|
19
|
+
* key's own live/test mode.
|
|
20
|
+
*/
|
|
21
|
+
environment?: string;
|
|
15
22
|
/** API base URL. Defaults to https://api.simplr.sh. */
|
|
16
23
|
baseUrl?: string;
|
|
17
24
|
/** Per-request timeout in ms (default 15000). */
|
|
@@ -74,6 +81,133 @@ interface EdgeLogEntry {
|
|
|
74
81
|
message: string;
|
|
75
82
|
[key: string]: unknown;
|
|
76
83
|
}
|
|
84
|
+
interface IdentifyOptions {
|
|
85
|
+
/** Profile type. */
|
|
86
|
+
profileType?: "customer" | "cashier" | "employee";
|
|
87
|
+
/** Device fingerprint hash to link to this profile. */
|
|
88
|
+
fingerprintHash?: string;
|
|
89
|
+
/** Extra fields merged into the request body. */
|
|
90
|
+
[key: string]: unknown;
|
|
91
|
+
}
|
|
92
|
+
interface ProfileResult {
|
|
93
|
+
profile: {
|
|
94
|
+
id: string;
|
|
95
|
+
external_id: string;
|
|
96
|
+
profile_type: string;
|
|
97
|
+
status: string;
|
|
98
|
+
risk_score: number;
|
|
99
|
+
risk_level: string;
|
|
100
|
+
device_count: number;
|
|
101
|
+
total_orders: number;
|
|
102
|
+
first_seen_at: string;
|
|
103
|
+
last_seen_at: string;
|
|
104
|
+
};
|
|
105
|
+
is_new: boolean;
|
|
106
|
+
device_linked: boolean;
|
|
107
|
+
device_anomaly?: string;
|
|
108
|
+
[key: string]: unknown;
|
|
109
|
+
}
|
|
110
|
+
interface ProfileRiskResult {
|
|
111
|
+
profile: {
|
|
112
|
+
id: string;
|
|
113
|
+
external_id: string;
|
|
114
|
+
profile_type: string;
|
|
115
|
+
status: string;
|
|
116
|
+
risk_score: number;
|
|
117
|
+
risk_level: string;
|
|
118
|
+
signals: Record<string, number>;
|
|
119
|
+
device_count: number;
|
|
120
|
+
total_orders: number;
|
|
121
|
+
flagged_orders: number;
|
|
122
|
+
fraud_reports: number;
|
|
123
|
+
legitimate_reports: number;
|
|
124
|
+
first_seen_at: string;
|
|
125
|
+
last_seen_at: string;
|
|
126
|
+
};
|
|
127
|
+
[key: string]: unknown;
|
|
128
|
+
}
|
|
129
|
+
type RUMEventType = "session_start" | "session_end" | "view" | "action" | "error" | "log";
|
|
130
|
+
type RUMLogLevel = "debug" | "info" | "warn" | "error";
|
|
131
|
+
interface RUMEvent {
|
|
132
|
+
type: RUMEventType;
|
|
133
|
+
timestamp: number;
|
|
134
|
+
sessionId: string;
|
|
135
|
+
viewId?: string;
|
|
136
|
+
userId?: string;
|
|
137
|
+
applicationId: string;
|
|
138
|
+
applicationVersion?: string;
|
|
139
|
+
environment?: string;
|
|
140
|
+
view?: {
|
|
141
|
+
id: string;
|
|
142
|
+
name: string;
|
|
143
|
+
};
|
|
144
|
+
action?: {
|
|
145
|
+
name: string;
|
|
146
|
+
type: string;
|
|
147
|
+
};
|
|
148
|
+
error?: {
|
|
149
|
+
message: string;
|
|
150
|
+
stack?: string;
|
|
151
|
+
type?: string;
|
|
152
|
+
};
|
|
153
|
+
log?: {
|
|
154
|
+
level: RUMLogLevel;
|
|
155
|
+
message: string;
|
|
156
|
+
};
|
|
157
|
+
attributes?: Record<string, unknown>;
|
|
158
|
+
userAttributes?: Record<string, unknown>;
|
|
159
|
+
globalAttributes?: Record<string, unknown>;
|
|
160
|
+
}
|
|
161
|
+
interface RUMEventBatch {
|
|
162
|
+
events: RUMEvent[];
|
|
163
|
+
sentAt: number;
|
|
164
|
+
}
|
|
165
|
+
type BindingMode = "verified_device" | "any_location";
|
|
166
|
+
interface CreateDelegationOptions {
|
|
167
|
+
userId: string;
|
|
168
|
+
email?: string;
|
|
169
|
+
binding?: BindingMode;
|
|
170
|
+
expiresInDays?: number;
|
|
171
|
+
sessionId?: string;
|
|
172
|
+
fingerprintHash?: string;
|
|
173
|
+
}
|
|
174
|
+
interface DelegationResult {
|
|
175
|
+
token: string;
|
|
176
|
+
delegationId: string;
|
|
177
|
+
expiresAt: string;
|
|
178
|
+
bindingMode: BindingMode;
|
|
179
|
+
}
|
|
180
|
+
interface DelegationInfo {
|
|
181
|
+
delegationId: string;
|
|
182
|
+
endUserId: string;
|
|
183
|
+
bindingMode: BindingMode;
|
|
184
|
+
status: "active" | "revoked" | "expired";
|
|
185
|
+
expiresAt: string;
|
|
186
|
+
useCount: number;
|
|
187
|
+
lastUsedAt?: string;
|
|
188
|
+
createdAt: string;
|
|
189
|
+
}
|
|
190
|
+
interface ValidationResult {
|
|
191
|
+
valid: boolean;
|
|
192
|
+
sessionType?: "ai";
|
|
193
|
+
endUserId?: string;
|
|
194
|
+
delegation?: {
|
|
195
|
+
delegationId: string;
|
|
196
|
+
bindingMode: BindingMode;
|
|
197
|
+
expiresAt: string;
|
|
198
|
+
useCount: number;
|
|
199
|
+
};
|
|
200
|
+
error?: string;
|
|
201
|
+
}
|
|
202
|
+
interface DelegationStats {
|
|
203
|
+
totalDelegations: number;
|
|
204
|
+
activeDelegations: number;
|
|
205
|
+
totalUses: number;
|
|
206
|
+
delegationsByBinding: {
|
|
207
|
+
verifiedDevice: number;
|
|
208
|
+
anyLocation: number;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
77
211
|
|
|
78
212
|
/** Order fraud scoring. */
|
|
79
213
|
declare class OrdersResource {
|
|
@@ -129,8 +263,13 @@ interface FlagsOptions {
|
|
|
129
263
|
publicKey: string;
|
|
130
264
|
/** API base URL. Defaults to https://api.simplr.sh. */
|
|
131
265
|
baseUrl?: string;
|
|
132
|
-
/**
|
|
133
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Which environment's flags to load. Defaults to the key's own environment
|
|
268
|
+
* (the API falls back to the key's live/test mode when unset). Accepts a
|
|
269
|
+
* named environment slug (e.g. "dev", "uat", "prod") as well as the legacy
|
|
270
|
+
* "live"/"test" key modes. Sent to the API as `?environment=<value>`.
|
|
271
|
+
*/
|
|
272
|
+
environment?: string;
|
|
134
273
|
/** Auto-refresh interval in ms (default 60000; 0 disables). */
|
|
135
274
|
refreshIntervalMs?: number;
|
|
136
275
|
timeoutMs?: number;
|
|
@@ -172,6 +311,123 @@ declare class SimplrFlags {
|
|
|
172
311
|
dispose(): void;
|
|
173
312
|
}
|
|
174
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Anonymous user profile management and order fraud monitoring.
|
|
316
|
+
*
|
|
317
|
+
* Works with the configured key (secret for server-side use). Mirrors the
|
|
318
|
+
* browser SimplrProfiles surface but reuses the Node http helper (which unwraps
|
|
319
|
+
* the `{ success, message, content }` envelope).
|
|
320
|
+
*/
|
|
321
|
+
declare class SimplrProfiles {
|
|
322
|
+
private readonly cfg;
|
|
323
|
+
constructor(cfg: HttpConfig);
|
|
324
|
+
/**
|
|
325
|
+
* Identify a user — creates or updates an anonymous profile and (optionally)
|
|
326
|
+
* links a device fingerprint. POST /v1/profiles.
|
|
327
|
+
*/
|
|
328
|
+
identify(externalId: string, options?: IdentifyOptions): Promise<ProfileResult>;
|
|
329
|
+
/** Submit an order for real-time fraud scoring. POST /v1/orders. */
|
|
330
|
+
submitOrder(order: OrderInput): Promise<OrderResult>;
|
|
331
|
+
/** Get the risk profile for a user. GET /v1/profiles/{externalId}. */
|
|
332
|
+
getProfileRisk(externalId: string): Promise<ProfileRiskResult>;
|
|
333
|
+
/** Report a profile as fraud or legitimate. POST /v1/profiles/{externalId}/outcome. */
|
|
334
|
+
reportOutcome(externalId: string, outcome: "fraud" | "legitimate"): Promise<void>;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
interface SimplrRUMConfig {
|
|
338
|
+
/** Application identifier (required). */
|
|
339
|
+
applicationId: string;
|
|
340
|
+
/** Optional version/environment tags applied to every event. */
|
|
341
|
+
applicationVersion?: string;
|
|
342
|
+
environment?: string;
|
|
343
|
+
/** Flush when this many events are queued (default 30). */
|
|
344
|
+
batchSize?: number;
|
|
345
|
+
/** Background flush interval in ms (default 10000; 0 disables the timer). */
|
|
346
|
+
flushInterval?: number;
|
|
347
|
+
/** Override the events endpoint path (default /v1/rum/events). */
|
|
348
|
+
endpoint?: string;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Server-side Real User Monitoring. Batches events and flushes them to
|
|
352
|
+
* POST /v1/rum/events using the configured key. Unlike the browser SDK there is
|
|
353
|
+
* no DOM auto-capture — views/actions/errors/logs are reported via the public
|
|
354
|
+
* API. A timer-based flush is installed with `unref()` so it never keeps the
|
|
355
|
+
* Node process alive.
|
|
356
|
+
*/
|
|
357
|
+
declare class SimplrRUM {
|
|
358
|
+
private readonly cfg;
|
|
359
|
+
private config;
|
|
360
|
+
private initialized;
|
|
361
|
+
private queue;
|
|
362
|
+
private timer;
|
|
363
|
+
private flushing;
|
|
364
|
+
private sessionId;
|
|
365
|
+
private currentViewId;
|
|
366
|
+
private userId?;
|
|
367
|
+
private userAttributes?;
|
|
368
|
+
private globalAttributes;
|
|
369
|
+
private batchSize;
|
|
370
|
+
private endpoint;
|
|
371
|
+
constructor(cfg: HttpConfig);
|
|
372
|
+
/** Initialize the SDK, start a session, and begin the flush timer. */
|
|
373
|
+
initialize(config: SimplrRUMConfig): void;
|
|
374
|
+
isInitialized(): boolean;
|
|
375
|
+
/** Associate subsequent events with a user. */
|
|
376
|
+
setUser(userId: string, attributes?: Record<string, unknown>): void;
|
|
377
|
+
clearUser(): void;
|
|
378
|
+
addAttribute(key: string, value: unknown): void;
|
|
379
|
+
removeAttribute(key: string): void;
|
|
380
|
+
/** Track a screen/page view. */
|
|
381
|
+
trackView(name: string, attributes?: Record<string, unknown>): void;
|
|
382
|
+
/** Track a user action. */
|
|
383
|
+
trackAction(name: string, attributes?: Record<string, unknown>): void;
|
|
384
|
+
/** Track an error. */
|
|
385
|
+
trackError(error: Error | {
|
|
386
|
+
message: string;
|
|
387
|
+
stack?: string;
|
|
388
|
+
type?: string;
|
|
389
|
+
}, attributes?: Record<string, unknown>): void;
|
|
390
|
+
/** Emit a log line. */
|
|
391
|
+
log(level: RUMLogLevel, message: string, attributes?: Record<string, unknown>): void;
|
|
392
|
+
private trackEvent;
|
|
393
|
+
/** Flush queued events to POST /v1/rum/events. */
|
|
394
|
+
flush(): Promise<void>;
|
|
395
|
+
/** End the session, flush remaining events, and stop the timer. */
|
|
396
|
+
stopSession(): Promise<void>;
|
|
397
|
+
getSessionId(): string | null;
|
|
398
|
+
getViewId(): string | null;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* AI delegation — OAuth-like AI authentication. Lets you mint, validate and
|
|
403
|
+
* revoke delegation tokens that an end user shares with their AI agent.
|
|
404
|
+
*
|
|
405
|
+
* Reuses the Node http helper, which unwraps the `{ success, message, content }`
|
|
406
|
+
* envelope — so `apiRequest` returns the inner `content` object directly.
|
|
407
|
+
*/
|
|
408
|
+
declare class SimplrAI {
|
|
409
|
+
private readonly cfg;
|
|
410
|
+
constructor(cfg: HttpConfig);
|
|
411
|
+
/** Create a new AI delegation token for a user. POST /v1/ai/delegations. */
|
|
412
|
+
createDelegation(options: CreateDelegationOptions): Promise<DelegationResult>;
|
|
413
|
+
/** Validate (introspect) an AI delegation token. POST /v1/ai/validate. */
|
|
414
|
+
validate(token: string, options?: {
|
|
415
|
+
fingerprintHash?: string;
|
|
416
|
+
aiProvider?: string;
|
|
417
|
+
action?: string;
|
|
418
|
+
}): Promise<ValidationResult>;
|
|
419
|
+
/** Revoke a delegation. POST /v1/ai/delegations/{id}/revoke. */
|
|
420
|
+
revoke(delegationId: string, reason?: string): Promise<void>;
|
|
421
|
+
/** List delegations, optionally filtered by user. GET /v1/ai/delegations. */
|
|
422
|
+
list(userId?: string): Promise<DelegationInfo[]>;
|
|
423
|
+
/** Get a single delegation. GET /v1/ai/delegations/{id}. */
|
|
424
|
+
get(delegationId: string): Promise<DelegationInfo>;
|
|
425
|
+
/** Get delegation statistics. GET /v1/ai/stats. */
|
|
426
|
+
stats(): Promise<DelegationStats>;
|
|
427
|
+
/** Revoke all delegations for a user (e.g. on logout). POST /v1/ai/revoke-all. */
|
|
428
|
+
revokeAllForUser(userId: string, reason?: string): Promise<number>;
|
|
429
|
+
}
|
|
430
|
+
|
|
175
431
|
interface VerifyOptions {
|
|
176
432
|
/** Reject signatures whose timestamp is older than this many seconds (default 300). 0 disables. */
|
|
177
433
|
toleranceSec?: number;
|
|
@@ -299,6 +555,12 @@ declare class Simplr {
|
|
|
299
555
|
readonly orders: OrdersResource;
|
|
300
556
|
readonly phone: PhoneResource;
|
|
301
557
|
readonly edge: EdgeResource;
|
|
558
|
+
/** Anonymous user profiles + order fraud monitoring. */
|
|
559
|
+
readonly profiles: SimplrProfiles;
|
|
560
|
+
/** Real User Monitoring — batched events to /v1/rum/events. */
|
|
561
|
+
readonly rum: SimplrRUM;
|
|
562
|
+
/** AI delegation — OAuth-like AI authentication. */
|
|
563
|
+
readonly ai: SimplrAI;
|
|
302
564
|
/** Webhook signature helpers (no network). */
|
|
303
565
|
readonly webhooks: typeof webhooks$1;
|
|
304
566
|
private readonly _flags?;
|
|
@@ -314,4 +576,4 @@ declare class Simplr {
|
|
|
314
576
|
checkBulk(items: CheckInput[]): Promise<BulkResult<CheckResult>>;
|
|
315
577
|
}
|
|
316
578
|
|
|
317
|
-
export { type BulkResult, type CheckInput, type CheckResult, type EdgeLogEntry, type EvalContext, type FlagDefinition, type FlagRule, type FlagsOptions, type OrderInput, type OrderResult, type PhoneOutcome, type PhoneReportInput, type RiskLevel, Simplr, SimplrAdmin, type SimplrAdminOptions, SimplrError, SimplrFlags, type SimplrOptions, WebhookVerificationError, constructEvent as constructWebhookEvent, Simplr as default, verify as verifyWebhook };
|
|
579
|
+
export { type BindingMode, type BulkResult, type CheckInput, type CheckResult, type CreateDelegationOptions, type DelegationInfo, type DelegationResult, type DelegationStats, type EdgeLogEntry, type EvalContext, type FlagDefinition, type FlagRule, type FlagsOptions, type IdentifyOptions, type OrderInput, type OrderResult, type PhoneOutcome, type PhoneReportInput, type ProfileResult, type ProfileRiskResult, type RUMEvent, type RUMEventBatch, type RUMEventType, type RUMLogLevel, type RiskLevel, Simplr, SimplrAI, SimplrAdmin, type SimplrAdminOptions, SimplrError, SimplrFlags, type SimplrOptions, SimplrProfiles, SimplrRUM, type SimplrRUMConfig, type ValidationResult, WebhookVerificationError, constructEvent as constructWebhookEvent, Simplr as default, verify as verifyWebhook };
|
package/dist/index.js
CHANGED
|
@@ -183,7 +183,7 @@ var SimplrFlags = class {
|
|
|
183
183
|
}
|
|
184
184
|
/** Re-fetch the flag config (counts as one billable request). */
|
|
185
185
|
async refresh() {
|
|
186
|
-
const path = this.environment ? `/v1/flags?environment=${this.environment}` : "/v1/flags";
|
|
186
|
+
const path = this.environment ? `/v1/flags?environment=${encodeURIComponent(this.environment)}` : "/v1/flags";
|
|
187
187
|
try {
|
|
188
188
|
const content = await apiRequest(this.cfg, "GET", path);
|
|
189
189
|
const list = content?.flags || [];
|
|
@@ -219,6 +219,295 @@ var SimplrFlags = class {
|
|
|
219
219
|
}
|
|
220
220
|
};
|
|
221
221
|
|
|
222
|
+
// src/profiles.ts
|
|
223
|
+
var SimplrProfiles = class {
|
|
224
|
+
constructor(cfg) {
|
|
225
|
+
this.cfg = cfg;
|
|
226
|
+
}
|
|
227
|
+
cfg;
|
|
228
|
+
/**
|
|
229
|
+
* Identify a user — creates or updates an anonymous profile and (optionally)
|
|
230
|
+
* links a device fingerprint. POST /v1/profiles.
|
|
231
|
+
*/
|
|
232
|
+
identify(externalId, options) {
|
|
233
|
+
const { profileType, fingerprintHash, ...rest } = options ?? {};
|
|
234
|
+
const body = {
|
|
235
|
+
external_id: externalId,
|
|
236
|
+
profile_type: profileType || "customer",
|
|
237
|
+
...rest
|
|
238
|
+
};
|
|
239
|
+
if (fingerprintHash) body.fingerprint_hash = fingerprintHash;
|
|
240
|
+
return apiRequest(this.cfg, "POST", "/v1/profiles", body);
|
|
241
|
+
}
|
|
242
|
+
/** Submit an order for real-time fraud scoring. POST /v1/orders. */
|
|
243
|
+
submitOrder(order) {
|
|
244
|
+
return apiRequest(this.cfg, "POST", "/v1/orders", order);
|
|
245
|
+
}
|
|
246
|
+
/** Get the risk profile for a user. GET /v1/profiles/{externalId}. */
|
|
247
|
+
getProfileRisk(externalId) {
|
|
248
|
+
return apiRequest(
|
|
249
|
+
this.cfg,
|
|
250
|
+
"GET",
|
|
251
|
+
`/v1/profiles/${encodeURIComponent(externalId)}`
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
/** Report a profile as fraud or legitimate. POST /v1/profiles/{externalId}/outcome. */
|
|
255
|
+
async reportOutcome(externalId, outcome) {
|
|
256
|
+
await apiRequest(
|
|
257
|
+
this.cfg,
|
|
258
|
+
"POST",
|
|
259
|
+
`/v1/profiles/${encodeURIComponent(externalId)}/outcome`,
|
|
260
|
+
{ outcome }
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// src/rum.ts
|
|
266
|
+
var DEFAULT_BATCH_SIZE = 30;
|
|
267
|
+
var DEFAULT_FLUSH_INTERVAL = 1e4;
|
|
268
|
+
var DEFAULT_ENDPOINT = "/v1/rum/events";
|
|
269
|
+
function genId() {
|
|
270
|
+
return Date.now().toString(36) + Math.random().toString(36).slice(2, 10);
|
|
271
|
+
}
|
|
272
|
+
var SimplrRUM = class {
|
|
273
|
+
constructor(cfg) {
|
|
274
|
+
this.cfg = cfg;
|
|
275
|
+
}
|
|
276
|
+
cfg;
|
|
277
|
+
config = null;
|
|
278
|
+
initialized = false;
|
|
279
|
+
queue = [];
|
|
280
|
+
timer = null;
|
|
281
|
+
flushing = false;
|
|
282
|
+
sessionId = null;
|
|
283
|
+
currentViewId = null;
|
|
284
|
+
userId;
|
|
285
|
+
userAttributes;
|
|
286
|
+
globalAttributes = {};
|
|
287
|
+
batchSize = DEFAULT_BATCH_SIZE;
|
|
288
|
+
endpoint = DEFAULT_ENDPOINT;
|
|
289
|
+
/** Initialize the SDK, start a session, and begin the flush timer. */
|
|
290
|
+
initialize(config) {
|
|
291
|
+
if (this.initialized) return;
|
|
292
|
+
this.config = config;
|
|
293
|
+
this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
294
|
+
this.endpoint = config.endpoint ?? DEFAULT_ENDPOINT;
|
|
295
|
+
this.sessionId = genId();
|
|
296
|
+
this.initialized = true;
|
|
297
|
+
this.trackEvent("session_start");
|
|
298
|
+
const interval = config.flushInterval ?? DEFAULT_FLUSH_INTERVAL;
|
|
299
|
+
if (interval > 0) {
|
|
300
|
+
this.timer = setInterval(() => {
|
|
301
|
+
void this.flush();
|
|
302
|
+
}, interval);
|
|
303
|
+
this.timer?.unref?.();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
isInitialized() {
|
|
307
|
+
return this.initialized;
|
|
308
|
+
}
|
|
309
|
+
/** Associate subsequent events with a user. */
|
|
310
|
+
setUser(userId, attributes) {
|
|
311
|
+
this.userId = userId;
|
|
312
|
+
this.userAttributes = attributes;
|
|
313
|
+
}
|
|
314
|
+
clearUser() {
|
|
315
|
+
this.userId = void 0;
|
|
316
|
+
this.userAttributes = void 0;
|
|
317
|
+
}
|
|
318
|
+
addAttribute(key, value) {
|
|
319
|
+
this.globalAttributes[key] = value;
|
|
320
|
+
}
|
|
321
|
+
removeAttribute(key) {
|
|
322
|
+
delete this.globalAttributes[key];
|
|
323
|
+
}
|
|
324
|
+
/** Track a screen/page view. */
|
|
325
|
+
trackView(name, attributes) {
|
|
326
|
+
if (!this.initialized) return;
|
|
327
|
+
this.currentViewId = genId();
|
|
328
|
+
this.trackEvent("view", {
|
|
329
|
+
view: { id: this.currentViewId, name },
|
|
330
|
+
attributes
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
/** Track a user action. */
|
|
334
|
+
trackAction(name, attributes) {
|
|
335
|
+
if (!this.initialized) return;
|
|
336
|
+
this.trackEvent("action", { action: { name, type: "custom" }, attributes });
|
|
337
|
+
}
|
|
338
|
+
/** Track an error. */
|
|
339
|
+
trackError(error, attributes) {
|
|
340
|
+
if (!this.initialized) return;
|
|
341
|
+
const data = error instanceof Error ? { message: error.message, stack: error.stack, type: error.constructor.name } : error;
|
|
342
|
+
this.trackEvent("error", { error: data, attributes });
|
|
343
|
+
}
|
|
344
|
+
/** Emit a log line. */
|
|
345
|
+
log(level, message, attributes) {
|
|
346
|
+
if (!this.initialized) return;
|
|
347
|
+
this.trackEvent("log", { log: { level, message }, attributes });
|
|
348
|
+
}
|
|
349
|
+
trackEvent(type, data) {
|
|
350
|
+
if (!this.initialized || !this.sessionId) return;
|
|
351
|
+
const event = {
|
|
352
|
+
type,
|
|
353
|
+
timestamp: Date.now(),
|
|
354
|
+
sessionId: this.sessionId,
|
|
355
|
+
viewId: this.currentViewId || void 0,
|
|
356
|
+
userId: this.userId,
|
|
357
|
+
applicationId: this.config.applicationId,
|
|
358
|
+
applicationVersion: this.config?.applicationVersion,
|
|
359
|
+
environment: this.config?.environment,
|
|
360
|
+
userAttributes: this.userAttributes,
|
|
361
|
+
globalAttributes: Object.keys(this.globalAttributes).length > 0 ? this.globalAttributes : void 0,
|
|
362
|
+
...data
|
|
363
|
+
};
|
|
364
|
+
this.queue.push(event);
|
|
365
|
+
if (this.queue.length >= this.batchSize) void this.flush();
|
|
366
|
+
}
|
|
367
|
+
/** Flush queued events to POST /v1/rum/events. */
|
|
368
|
+
async flush() {
|
|
369
|
+
if (this.flushing || this.queue.length === 0) return;
|
|
370
|
+
this.flushing = true;
|
|
371
|
+
const events = this.queue;
|
|
372
|
+
this.queue = [];
|
|
373
|
+
try {
|
|
374
|
+
await apiRequest(this.cfg, "POST", this.endpoint, {
|
|
375
|
+
events,
|
|
376
|
+
sentAt: Date.now()
|
|
377
|
+
});
|
|
378
|
+
} catch {
|
|
379
|
+
this.queue = [...events, ...this.queue];
|
|
380
|
+
} finally {
|
|
381
|
+
this.flushing = false;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
/** End the session, flush remaining events, and stop the timer. */
|
|
385
|
+
async stopSession() {
|
|
386
|
+
if (!this.initialized) return;
|
|
387
|
+
this.trackEvent("session_end");
|
|
388
|
+
await this.flush();
|
|
389
|
+
if (this.timer) {
|
|
390
|
+
clearInterval(this.timer);
|
|
391
|
+
this.timer = null;
|
|
392
|
+
}
|
|
393
|
+
this.initialized = false;
|
|
394
|
+
}
|
|
395
|
+
getSessionId() {
|
|
396
|
+
return this.sessionId;
|
|
397
|
+
}
|
|
398
|
+
getViewId() {
|
|
399
|
+
return this.currentViewId;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
// src/ai.ts
|
|
404
|
+
function mapDelegation(d) {
|
|
405
|
+
return {
|
|
406
|
+
delegationId: d.delegation_id,
|
|
407
|
+
endUserId: d.end_user_id,
|
|
408
|
+
bindingMode: d.binding_mode,
|
|
409
|
+
status: d.status,
|
|
410
|
+
expiresAt: d.expires_at,
|
|
411
|
+
useCount: d.use_count,
|
|
412
|
+
lastUsedAt: d.last_used_at,
|
|
413
|
+
createdAt: d.created_at
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
var SimplrAI = class {
|
|
417
|
+
constructor(cfg) {
|
|
418
|
+
this.cfg = cfg;
|
|
419
|
+
}
|
|
420
|
+
cfg;
|
|
421
|
+
/** Create a new AI delegation token for a user. POST /v1/ai/delegations. */
|
|
422
|
+
async createDelegation(options) {
|
|
423
|
+
const content = await apiRequest(this.cfg, "POST", "/v1/ai/delegations", {
|
|
424
|
+
end_user_id: options.userId,
|
|
425
|
+
end_user_email: options.email,
|
|
426
|
+
binding: options.binding || "any_location",
|
|
427
|
+
expires_in_days: options.expiresInDays || 7,
|
|
428
|
+
session_id: options.sessionId,
|
|
429
|
+
fingerprint_hash: options.fingerprintHash
|
|
430
|
+
});
|
|
431
|
+
const d = content.delegation;
|
|
432
|
+
return {
|
|
433
|
+
token: d.token,
|
|
434
|
+
delegationId: d.delegation_id,
|
|
435
|
+
expiresAt: d.expires_at,
|
|
436
|
+
bindingMode: d.binding_mode
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
/** Validate (introspect) an AI delegation token. POST /v1/ai/validate. */
|
|
440
|
+
async validate(token, options) {
|
|
441
|
+
try {
|
|
442
|
+
const content = await apiRequest(this.cfg, "POST", "/v1/ai/validate", {
|
|
443
|
+
token,
|
|
444
|
+
fingerprint_hash: options?.fingerprintHash,
|
|
445
|
+
ai_provider: options?.aiProvider,
|
|
446
|
+
action: options?.action
|
|
447
|
+
});
|
|
448
|
+
return {
|
|
449
|
+
valid: true,
|
|
450
|
+
sessionType: content.session_type,
|
|
451
|
+
endUserId: content.end_user_id,
|
|
452
|
+
delegation: content.delegation ? {
|
|
453
|
+
delegationId: content.delegation.delegation_id,
|
|
454
|
+
bindingMode: content.delegation.binding_mode,
|
|
455
|
+
expiresAt: content.delegation.expires_at,
|
|
456
|
+
useCount: content.delegation.use_count
|
|
457
|
+
} : void 0
|
|
458
|
+
};
|
|
459
|
+
} catch (err) {
|
|
460
|
+
return { valid: false, error: err instanceof Error ? err.message : "Validation failed" };
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
/** Revoke a delegation. POST /v1/ai/delegations/{id}/revoke. */
|
|
464
|
+
async revoke(delegationId, reason) {
|
|
465
|
+
await apiRequest(
|
|
466
|
+
this.cfg,
|
|
467
|
+
"POST",
|
|
468
|
+
`/v1/ai/delegations/${encodeURIComponent(delegationId)}/revoke`,
|
|
469
|
+
{ reason }
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
/** List delegations, optionally filtered by user. GET /v1/ai/delegations. */
|
|
473
|
+
async list(userId) {
|
|
474
|
+
const path = userId ? `/v1/ai/delegations?end_user_id=${encodeURIComponent(userId)}` : "/v1/ai/delegations";
|
|
475
|
+
const content = await apiRequest(this.cfg, "GET", path);
|
|
476
|
+
return (content.delegations || []).map(mapDelegation);
|
|
477
|
+
}
|
|
478
|
+
/** Get a single delegation. GET /v1/ai/delegations/{id}. */
|
|
479
|
+
async get(delegationId) {
|
|
480
|
+
const content = await apiRequest(
|
|
481
|
+
this.cfg,
|
|
482
|
+
"GET",
|
|
483
|
+
`/v1/ai/delegations/${encodeURIComponent(delegationId)}`
|
|
484
|
+
);
|
|
485
|
+
return mapDelegation(content.delegation);
|
|
486
|
+
}
|
|
487
|
+
/** Get delegation statistics. GET /v1/ai/stats. */
|
|
488
|
+
async stats() {
|
|
489
|
+
const content = await apiRequest(this.cfg, "GET", "/v1/ai/stats");
|
|
490
|
+
const s = content.stats;
|
|
491
|
+
return {
|
|
492
|
+
totalDelegations: s.total_delegations,
|
|
493
|
+
activeDelegations: s.active_delegations,
|
|
494
|
+
totalUses: s.total_uses,
|
|
495
|
+
delegationsByBinding: {
|
|
496
|
+
verifiedDevice: s.delegations_by_binding.verified_device,
|
|
497
|
+
anyLocation: s.delegations_by_binding.any_location
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
/** Revoke all delegations for a user (e.g. on logout). POST /v1/ai/revoke-all. */
|
|
502
|
+
async revokeAllForUser(userId, reason) {
|
|
503
|
+
const content = await apiRequest(this.cfg, "POST", "/v1/ai/revoke-all", {
|
|
504
|
+
end_user_id: userId,
|
|
505
|
+
reason
|
|
506
|
+
});
|
|
507
|
+
return content.revoked_count;
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
|
|
222
511
|
// src/webhooks.ts
|
|
223
512
|
var webhooks_exports = {};
|
|
224
513
|
__export(webhooks_exports, {
|
|
@@ -365,6 +654,12 @@ var Simplr = class {
|
|
|
365
654
|
orders;
|
|
366
655
|
phone;
|
|
367
656
|
edge;
|
|
657
|
+
/** Anonymous user profiles + order fraud monitoring. */
|
|
658
|
+
profiles;
|
|
659
|
+
/** Real User Monitoring — batched events to /v1/rum/events. */
|
|
660
|
+
rum;
|
|
661
|
+
/** AI delegation — OAuth-like AI authentication. */
|
|
662
|
+
ai;
|
|
368
663
|
/** Webhook signature helpers (no network). */
|
|
369
664
|
webhooks = webhooks_exports;
|
|
370
665
|
_flags;
|
|
@@ -382,9 +677,13 @@ var Simplr = class {
|
|
|
382
677
|
this.orders = new OrdersResource(this.cfg);
|
|
383
678
|
this.phone = new PhoneResource(this.cfg);
|
|
384
679
|
this.edge = new EdgeResource(this.cfg);
|
|
680
|
+
this.profiles = new SimplrProfiles(this.cfg);
|
|
681
|
+
this.rum = new SimplrRUM(this.cfg);
|
|
682
|
+
this.ai = new SimplrAI(this.cfg);
|
|
385
683
|
if (options.publicKey) {
|
|
386
684
|
this._flags = new SimplrFlags({
|
|
387
685
|
publicKey: options.publicKey,
|
|
686
|
+
environment: options.environment,
|
|
388
687
|
baseUrl: this.cfg.baseUrl,
|
|
389
688
|
timeoutMs: this.cfg.timeoutMs,
|
|
390
689
|
fetch: this.cfg.fetchImpl
|
|
@@ -415,9 +714,12 @@ var Simplr = class {
|
|
|
415
714
|
var src_default = Simplr;
|
|
416
715
|
export {
|
|
417
716
|
Simplr,
|
|
717
|
+
SimplrAI,
|
|
418
718
|
SimplrAdmin,
|
|
419
719
|
SimplrError,
|
|
420
720
|
SimplrFlags,
|
|
721
|
+
SimplrProfiles,
|
|
722
|
+
SimplrRUM,
|
|
421
723
|
WebhookVerificationError,
|
|
422
724
|
constructEvent as constructWebhookEvent,
|
|
423
725
|
src_default as default,
|