@proappstore/sdk 1.16.42 → 1.16.44
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 +78 -0
- package/dist/actions.d.ts +6 -1
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +6 -1
- package/dist/actions.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/logs.d.ts +96 -0
- package/dist/logs.d.ts.map +1 -0
- package/dist/logs.js +298 -0
- package/dist/logs.js.map +1 -0
- package/dist/telemetry-transport.d.ts +36 -0
- package/dist/telemetry-transport.d.ts.map +1 -0
- package/dist/telemetry-transport.js +56 -0
- package/dist/telemetry-transport.js.map +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +10 -40
- package/dist/usage.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -302,6 +302,64 @@ app.usage.flush() // final ping (called automatically on pagehide)
|
|
|
302
302
|
|
|
303
303
|
What we record (also documented at <https://proappstore.online/privacy#usage-analytics>): per `(app, user, day)` rollups of session-seconds and API calls. No event-by-event logs, no IP, nothing while the tab is hidden or the user is signed out.
|
|
304
304
|
|
|
305
|
+
### Error monitoring (`app.logs`)
|
|
306
|
+
|
|
307
|
+
**Auto-started by `initPro()`** — uncaught errors and unhandled promise rejections
|
|
308
|
+
are captured and uploaded, so a user-visible failure leaves a platform record you
|
|
309
|
+
can read afterwards instead of relying on "it said something about permissions".
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
// Default — monitoring on, no code required
|
|
313
|
+
const app = initPro({ appId: 'my-app' })
|
|
314
|
+
|
|
315
|
+
// Attach build metadata so a report names the deploy it came from
|
|
316
|
+
const app = initPro({
|
|
317
|
+
appId: 'my-app',
|
|
318
|
+
monitoring: { build: { sha: __COMMIT_SHA__, version: '1.4.2' } },
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
// Opt out
|
|
322
|
+
const app = initPro({ appId: 'my-app', monitoring: { auto: false } })
|
|
323
|
+
|
|
324
|
+
// Log deliberately
|
|
325
|
+
app.logs.error('checkout failed', { step: 'confirm' })
|
|
326
|
+
app.logs.warn('slow board render')
|
|
327
|
+
app.logs.info('tournament joined')
|
|
328
|
+
app.logs.capture('warn', 'checkout', 'card declined') // your own category
|
|
329
|
+
|
|
330
|
+
// Manual controls (rarely needed)
|
|
331
|
+
app.logs.flush() // fire-and-forget; also runs on pagehide
|
|
332
|
+
await app.logs.flushAsync() // await the upload
|
|
333
|
+
app.logs.stop()
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Read them back as the app owner — the console's per-app view, or directly:
|
|
337
|
+
|
|
338
|
+
```
|
|
339
|
+
GET /v1/apps/:appId/logs # rows: level, category, fingerprint, source
|
|
340
|
+
GET /v1/apps/:appId/logs/groups # occurrences, affected clients, first/last seen
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Works signed out.** A crash before sign-in is the report most worth having, so
|
|
344
|
+
entries upload anonymously, tagged with a rotating per-install `clientId` (browser
|
|
345
|
+
storage only, clears with site data, never correlated across apps).
|
|
346
|
+
|
|
347
|
+
**Never log secrets.** Messages and payloads are scrubbed on both sides for
|
|
348
|
+
password/token/bearer/JWT/email-shaped content, but that is a backstop:
|
|
349
|
+
|
|
350
|
+
> Do not put passwords, tokens, student identifiers, or raw request bodies into a
|
|
351
|
+
> log message or its `data`.
|
|
352
|
+
|
|
353
|
+
Limits: `debug` is dropped unless you set `monitoring: { level: 'debug' }`; 100
|
|
354
|
+
entries per upload, 4 KB per entry; each app has a daily budget, and past it
|
|
355
|
+
entries are still *counted* (so spikes stay visible) while detail stops and the
|
|
356
|
+
SDK goes quiet for a minute rather than retrying. Detail rows are pruned after 30
|
|
357
|
+
days. Stack traces are not symbolicated yet — grouping still works, and `build`
|
|
358
|
+
identifies the deploy.
|
|
359
|
+
|
|
360
|
+
`app.logs` is independent of `app.usage`: usage measures engagement, logs record
|
|
361
|
+
faults.
|
|
362
|
+
|
|
305
363
|
### Notifications (Web Push)
|
|
306
364
|
|
|
307
365
|
Push notifications to your users. Subscribe from the browser, send targeted or broadcast pushes from your app (creator-only).
|
|
@@ -598,6 +656,26 @@ are enforced by the platform before SQL reaches the data worker.
|
|
|
598
656
|
|
|
599
657
|
Tables are user-defined (create them via `db.execute('CREATE TABLE IF NOT EXISTS ...')`). The schema is entirely up to the app developer.
|
|
600
658
|
|
|
659
|
+
## Monitoring (`app.logs`)
|
|
660
|
+
|
|
661
|
+
Runtime monitoring is **on by default**. `initPro()` captures uncaught `error` /
|
|
662
|
+
`unhandledrejection` events and records failed `app.actions.call()` (action name +
|
|
663
|
+
HTTP status only), batching them to `POST /v1/apps/:appId/logs`. Owners read them
|
|
664
|
+
back (owner-only) via `GET /v1/apps/:appId/logs` / the dashboard.
|
|
665
|
+
|
|
666
|
+
```ts
|
|
667
|
+
app.logs.error('billing', 'checkout failed', { code }); // your own entries
|
|
668
|
+
app.logs.capture(err, 'payments'); // a caught exception
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
Entries include route, auth mode, and any `monitoring.build` metadata. The SDK
|
|
672
|
+
**never** logs tokens, credentials, SQL params, or request bodies. Works in both
|
|
673
|
+
`legacy-bearer` and `platform-cookie` modes; flushes on an interval and on
|
|
674
|
+
`pagehide`. Opt out with `initPro({ monitoring: { auto: false } })`.
|
|
675
|
+
|
|
676
|
+
Ingestion is hardened (issue #108): the app must exist and each (app, user) has a
|
|
677
|
+
daily ingest quota, so logs can't be spoofed onto other apps or flooded.
|
|
678
|
+
|
|
601
679
|
## License
|
|
602
680
|
|
|
603
681
|
MIT.
|
package/dist/actions.d.ts
CHANGED
|
@@ -2,11 +2,16 @@ interface AuthLike {
|
|
|
2
2
|
handleUnauthorized(): void;
|
|
3
3
|
authenticatedFetch(input: string | URL, init?: RequestInit): Promise<Response>;
|
|
4
4
|
}
|
|
5
|
+
/** Minimal logger surface (satisfied by Logs) — failures only, never params. */
|
|
6
|
+
interface LoggerLike {
|
|
7
|
+
capture(level: 'error', category: string, message: string, data?: Record<string, unknown>): void;
|
|
8
|
+
}
|
|
5
9
|
export declare class Actions {
|
|
6
10
|
private readonly appId;
|
|
7
11
|
private readonly apiBase;
|
|
8
12
|
private readonly auth;
|
|
9
|
-
|
|
13
|
+
private readonly logger?;
|
|
14
|
+
constructor(appId: string, apiBase: string, auth: AuthLike, logger?: LoggerLike | undefined);
|
|
10
15
|
call<T = unknown>(name: string, params?: Record<string, unknown>): Promise<T>;
|
|
11
16
|
callPublic<T = unknown>(name: string, params?: Record<string, unknown>): Promise<T>;
|
|
12
17
|
}
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,UAAU,QAAQ;IAChB,kBAAkB,IAAI,IAAI,CAAC;IAC3B,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChF;AAED,qBAAa,OAAO;IAEhB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,UAAU,QAAQ;IAChB,kBAAkB,IAAI,IAAI,CAAC;IAC3B,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChF;AAED,gFAAgF;AAChF,UAAU,UAAU;IAClB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAClG;AAED,qBAAa,OAAO;IAEhB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAHP,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ,EACd,MAAM,CAAC,EAAE,UAAU,YAAA;IAGhC,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAuBjF,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAe9F"}
|
package/dist/actions.js
CHANGED
|
@@ -2,10 +2,12 @@ export class Actions {
|
|
|
2
2
|
appId;
|
|
3
3
|
apiBase;
|
|
4
4
|
auth;
|
|
5
|
-
|
|
5
|
+
logger;
|
|
6
|
+
constructor(appId, apiBase, auth, logger) {
|
|
6
7
|
this.appId = appId;
|
|
7
8
|
this.apiBase = apiBase;
|
|
8
9
|
this.auth = auth;
|
|
10
|
+
this.logger = logger;
|
|
9
11
|
}
|
|
10
12
|
async call(name, params = {}) {
|
|
11
13
|
const response = await this.auth.authenticatedFetch(`${this.apiBase}/v1/apps/${encodeURIComponent(this.appId)}/actions/${encodeURIComponent(name)}`, {
|
|
@@ -14,11 +16,14 @@ export class Actions {
|
|
|
14
16
|
body: JSON.stringify({ params }),
|
|
15
17
|
});
|
|
16
18
|
if (response.status === 401) {
|
|
19
|
+
// #106: record the failure (action name + status only — never the params).
|
|
20
|
+
this.logger?.capture('error', 'action', `action ${name} unauthorized`, { action: name, status: 401 });
|
|
17
21
|
this.auth.handleUnauthorized();
|
|
18
22
|
throw new Error('Not signed in.');
|
|
19
23
|
}
|
|
20
24
|
if (!response.ok) {
|
|
21
25
|
const text = await response.text().catch(() => '');
|
|
26
|
+
this.logger?.capture('error', 'action', `action ${name} failed`, { action: name, status: response.status });
|
|
22
27
|
throw new Error(`actions.${name} failed: ${response.status} ${text}`);
|
|
23
28
|
}
|
|
24
29
|
return (await response.json());
|
package/dist/actions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAUA,MAAM,OAAO,OAAO;IAEC;IACA;IACA;IACA;IAJnB,YACmB,KAAa,EACb,OAAe,EACf,IAAc,EACd,MAAmB;QAHnB,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAQ;QACf,SAAI,GAAJ,IAAI,CAAU;QACd,WAAM,GAAN,MAAM,CAAa;IACnC,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAc,IAAY,EAAE,SAAkC,EAAE;QACxE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CACjD,GAAG,IAAI,CAAC,OAAO,YAAY,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAC/F;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;SACjC,CACF,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,2EAA2E;YAC3E,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,IAAI,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACtG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,IAAI,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5G,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,YAAY,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,UAAU,CAAc,IAAY,EAAE,SAAkC,EAAE;QAC9E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,IAAI,CAAC,OAAO,YAAY,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAC/F;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;SACjC,CACF,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,YAAY,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;IACtC,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { Email } from './email.js';
|
|
|
17
17
|
import { Webhooks } from './webhooks.js';
|
|
18
18
|
import { Invites } from './invites.js';
|
|
19
19
|
import { Actions } from './actions.js';
|
|
20
|
+
import { Logs } from './logs.js';
|
|
20
21
|
import type { ProInitOptions } from './types.js';
|
|
21
22
|
export type { User, Unsubscribe } from './base-types.js';
|
|
22
23
|
export type { AuthMode, AuthProvider } from './auth.js';
|
|
@@ -66,6 +67,8 @@ export declare class ProAppStore {
|
|
|
66
67
|
readonly webhooks: Webhooks;
|
|
67
68
|
readonly invites: Invites;
|
|
68
69
|
readonly actions: Actions;
|
|
70
|
+
/** Runtime error capture — auto-captures errors + records failed ops to app_logs. */
|
|
71
|
+
readonly logs: Logs;
|
|
69
72
|
constructor(opts: ProInitOptions);
|
|
70
73
|
}
|
|
71
74
|
/** Create a new ProAppStore SDK instance. Includes all free + pro features. */
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import { Email } from './email.js';
|
|
|
19
19
|
import { Webhooks } from './webhooks.js';
|
|
20
20
|
import { Invites } from './invites.js';
|
|
21
21
|
import { Actions } from './actions.js';
|
|
22
|
+
import { Logs } from './logs.js';
|
|
22
23
|
export { DEFAULT_ROLES } from './roles.js';
|
|
23
24
|
export { Actions } from './actions.js';
|
|
24
25
|
export { TenantScope } from './tenant.js';
|
|
@@ -56,6 +57,8 @@ export class ProAppStore {
|
|
|
56
57
|
webhooks;
|
|
57
58
|
invites;
|
|
58
59
|
actions;
|
|
60
|
+
/** Runtime error capture — auto-captures errors + records failed ops to app_logs. */
|
|
61
|
+
logs;
|
|
59
62
|
constructor(opts) {
|
|
60
63
|
const apiBase = opts.proApiBase ?? 'https://api.proappstore.online';
|
|
61
64
|
const authMode = opts.authMode ?? 'legacy-bearer';
|
|
@@ -78,7 +81,9 @@ export class ProAppStore {
|
|
|
78
81
|
this.email = new Email(opts.appId, apiBase, this.auth);
|
|
79
82
|
this.webhooks = new Webhooks(opts.appId, apiBase, this.auth);
|
|
80
83
|
this.invites = new Invites(opts.appId, apiBase, this.auth);
|
|
81
|
-
|
|
84
|
+
// Constructed before Actions: Actions reports failed calls to the logger (#106).
|
|
85
|
+
this.logs = new Logs(opts.appId, apiBase, this.auth, opts.monitoring ?? {});
|
|
86
|
+
this.actions = new Actions(opts.appId, apiBase, this.auth, this.logs);
|
|
82
87
|
// Auto-start telemetry unless the app opts out. Wrapped in try-catch
|
|
83
88
|
// because localStorage can throw in incognito, sandboxed iframes, or
|
|
84
89
|
// when storage quota is exceeded.
|
|
@@ -88,6 +93,16 @@ export class ProAppStore {
|
|
|
88
93
|
}
|
|
89
94
|
catch { /* non-fatal — app runs without usage tracking */ }
|
|
90
95
|
}
|
|
96
|
+
// Runtime error capture. Started here rather than lazily so a crash during the
|
|
97
|
+
// app's own first render is still recorded — the white-screen case is exactly
|
|
98
|
+
// what platform#105 exists for, and it happens before any app code could call
|
|
99
|
+
// start() itself.
|
|
100
|
+
if (opts.monitoring?.auto !== false) {
|
|
101
|
+
try {
|
|
102
|
+
this.logs.start();
|
|
103
|
+
}
|
|
104
|
+
catch { /* non-fatal — app runs without monitoring */ }
|
|
105
|
+
}
|
|
91
106
|
}
|
|
92
107
|
}
|
|
93
108
|
/** Create a new ProAppStore SDK instance. Includes all free + pro features. */
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,uEAAuE;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/logs.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App logging + automatic runtime error capture (platform#105, ADR-008).
|
|
3
|
+
*
|
|
4
|
+
* Auto-started by `initPro()` unless `monitoring.auto === false`. Captures
|
|
5
|
+
* `window.onerror` and `unhandledrejection`, batches entries, and flushes them to
|
|
6
|
+
* `POST /v1/apps/:appId/logs`, where the app owner reads them in the console.
|
|
7
|
+
*
|
|
8
|
+
* Design notes:
|
|
9
|
+
*
|
|
10
|
+
* - **Works signed out.** Anonymous reports are the point: a white screen on load
|
|
11
|
+
* or a broken sign-in has no session, and those are the failures worth having.
|
|
12
|
+
* A rotating per-install `clientId` gives them a cardinality without naming a
|
|
13
|
+
* person.
|
|
14
|
+
* - **Browser-only.** Every method no-ops without `window`, so the import stays
|
|
15
|
+
* SSR-safe.
|
|
16
|
+
* - **Silent.** No throw path, ever. A logger that breaks the app it observes is
|
|
17
|
+
* worse than no logger.
|
|
18
|
+
* - **Backs off instead of retrying.** The server answers 202 when an app is over
|
|
19
|
+
* its budget; retrying would turn an error loop into a flood. See `cooldown`.
|
|
20
|
+
* - **Not a replacement for usage telemetry.** `app.usage` is unchanged; the two
|
|
21
|
+
* share only the transport.
|
|
22
|
+
*/
|
|
23
|
+
import { type TelemetryAuth } from './telemetry-transport.js';
|
|
24
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
25
|
+
export interface MonitoringOptions {
|
|
26
|
+
/** Default true. Set false to disable auto-capture and the flush timer. */
|
|
27
|
+
auto?: boolean;
|
|
28
|
+
/** Build metadata attached to every entry (commit sha, version, built-at). */
|
|
29
|
+
build?: Record<string, unknown>;
|
|
30
|
+
/** Minimum level actually sent. Default 'info' — `debug` is dropped unless asked for. */
|
|
31
|
+
level?: LogLevel;
|
|
32
|
+
}
|
|
33
|
+
export declare function redactClient(input: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Stable-per-install id, created on first use.
|
|
36
|
+
*
|
|
37
|
+
* Not a person identifier: it lives in this browser's storage, clears with site
|
|
38
|
+
* data, and is never correlated across apps. It exists so an owner can tell "one
|
|
39
|
+
* user hit this 40 times" from "40 users hit it once" for reports that have no
|
|
40
|
+
* session at all.
|
|
41
|
+
*/
|
|
42
|
+
export declare function readOrCreateClientId(): string | null;
|
|
43
|
+
/** Serialize an unknown thrown value into a message + stack. */
|
|
44
|
+
export declare function describeError(value: unknown): {
|
|
45
|
+
message: string;
|
|
46
|
+
stack?: string | undefined;
|
|
47
|
+
};
|
|
48
|
+
export declare class Logs {
|
|
49
|
+
private readonly appId;
|
|
50
|
+
private readonly apiBase;
|
|
51
|
+
private readonly auth;
|
|
52
|
+
private readonly options;
|
|
53
|
+
private queue;
|
|
54
|
+
private running;
|
|
55
|
+
private timer;
|
|
56
|
+
private onError;
|
|
57
|
+
private onRejection;
|
|
58
|
+
private onPageHide;
|
|
59
|
+
private clientId;
|
|
60
|
+
/** Epoch ms until which we send nothing (server asked us to stop). */
|
|
61
|
+
private quietUntil;
|
|
62
|
+
/** Set when the server says this app cannot accept logs at all (404). */
|
|
63
|
+
private disabled;
|
|
64
|
+
/** Guards against an error raised inside our own handler re-entering. */
|
|
65
|
+
private capturing;
|
|
66
|
+
private minLevel;
|
|
67
|
+
constructor(appId: string, apiBase: string, auth: TelemetryAuth, options?: MonitoringOptions);
|
|
68
|
+
/** Begin auto-capture and periodic flushing. Idempotent. */
|
|
69
|
+
start(): void;
|
|
70
|
+
/** Stop capture and timers. Does not flush — call `flush()` first if needed. */
|
|
71
|
+
stop(): void;
|
|
72
|
+
debug(message: string, data?: unknown): void;
|
|
73
|
+
info(message: string, data?: unknown): void;
|
|
74
|
+
warn(message: string, data?: unknown): void;
|
|
75
|
+
error(message: string, data?: unknown): void;
|
|
76
|
+
/** Number of entries waiting to be sent. Exposed for tests and diagnostics. */
|
|
77
|
+
get pending(): number;
|
|
78
|
+
/**
|
|
79
|
+
* Queue one entry.
|
|
80
|
+
*
|
|
81
|
+
* Public so app code can record its own categories (`app.logs.capture('warn',
|
|
82
|
+
* 'checkout', ...)`), and so SDK primitives can report their own failures
|
|
83
|
+
* (platform#106's client half) without another queue.
|
|
84
|
+
*/
|
|
85
|
+
capture(level: LogLevel, category: string, message: string, data?: unknown): void;
|
|
86
|
+
/** Fire-and-forget flush, safe on the unload path. */
|
|
87
|
+
flush(): void;
|
|
88
|
+
/** Await a flush. For tests and deliberate checkpoints. */
|
|
89
|
+
flushAsync(): Promise<void>;
|
|
90
|
+
private safeData;
|
|
91
|
+
/** W3C traceparent trace-id, so a client entry can be lined up with the
|
|
92
|
+
* backend and data-worker records for the same logical request. */
|
|
93
|
+
private newTraceId;
|
|
94
|
+
private send;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE7E,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,yFAAyF;IACzF,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AA4CD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAMD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAiBpD;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAU7F;AAED,qBAAa,IAAI;IAiBb,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAnB1B,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,WAAW,CAAqD;IACxE,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,QAAQ,CAAuB;IACvC,sEAAsE;IACtE,OAAO,CAAC,UAAU,CAAK;IACvB,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAS;IACzB,yEAAyE;IACzE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAW;gBAGR,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,iBAAsB;IAKlD,4DAA4D;IAC5D,KAAK,IAAI,IAAI;IAiCb,gFAAgF;IAChF,IAAI,IAAI,IAAI;IAiBZ,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAI5C,+EAA+E;IAC/E,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;;;;;OAMG;IACH,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IA0BjF,sDAAsD;IACtD,KAAK,IAAI,IAAI;IAIb,2DAA2D;IACrD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,OAAO,CAAC,QAAQ;IAShB;wEACoE;IACpE,OAAO,CAAC,UAAU;YAWJ,IAAI;CAmCnB"}
|
package/dist/logs.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App logging + automatic runtime error capture (platform#105, ADR-008).
|
|
3
|
+
*
|
|
4
|
+
* Auto-started by `initPro()` unless `monitoring.auto === false`. Captures
|
|
5
|
+
* `window.onerror` and `unhandledrejection`, batches entries, and flushes them to
|
|
6
|
+
* `POST /v1/apps/:appId/logs`, where the app owner reads them in the console.
|
|
7
|
+
*
|
|
8
|
+
* Design notes:
|
|
9
|
+
*
|
|
10
|
+
* - **Works signed out.** Anonymous reports are the point: a white screen on load
|
|
11
|
+
* or a broken sign-in has no session, and those are the failures worth having.
|
|
12
|
+
* A rotating per-install `clientId` gives them a cardinality without naming a
|
|
13
|
+
* person.
|
|
14
|
+
* - **Browser-only.** Every method no-ops without `window`, so the import stays
|
|
15
|
+
* SSR-safe.
|
|
16
|
+
* - **Silent.** No throw path, ever. A logger that breaks the app it observes is
|
|
17
|
+
* worse than no logger.
|
|
18
|
+
* - **Backs off instead of retrying.** The server answers 202 when an app is over
|
|
19
|
+
* its budget; retrying would turn an error loop into a flood. See `cooldown`.
|
|
20
|
+
* - **Not a replacement for usage telemetry.** `app.usage` is unchanged; the two
|
|
21
|
+
* share only the transport.
|
|
22
|
+
*/
|
|
23
|
+
import { postTelemetry } from './telemetry-transport.js';
|
|
24
|
+
const FLUSH_INTERVAL_MS = 10_000;
|
|
25
|
+
/** Matches the server's per-request cap; a full queue flushes immediately. */
|
|
26
|
+
const MAX_BATCH = 100;
|
|
27
|
+
/** Hard ceiling while offline or backing off. Oldest entries are dropped. */
|
|
28
|
+
const MAX_QUEUE = 200;
|
|
29
|
+
/** How long to stay quiet after the server says we are over budget. */
|
|
30
|
+
const COOLDOWN_MS = 60_000;
|
|
31
|
+
const MESSAGE_MAX = 4096;
|
|
32
|
+
const CLIENT_ID_KEY = 'pas:client-id';
|
|
33
|
+
const LEVEL_ORDER = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
34
|
+
/**
|
|
35
|
+
* Redact secret-shaped substrings before anything leaves the browser.
|
|
36
|
+
*
|
|
37
|
+
* Vendored deliberately rather than shared with the backend (the SDK ships to npm
|
|
38
|
+
* and cannot import a private package). The server scrubs again at ingest — this
|
|
39
|
+
* copy exists so a secret never crosses the network in the first place.
|
|
40
|
+
*/
|
|
41
|
+
const REDACTIONS = [
|
|
42
|
+
[/\bBearer\s+[\w\-._~+/]+=*/gi, 'Bearer [redacted]'],
|
|
43
|
+
[
|
|
44
|
+
/\b(password|passwd|pwd|secret|token|api[_-]?key|authorization|cookie|client[_-]?secret)\b("?\s*[:=]\s*)("?)[^\s,;"}&]+\3/gi,
|
|
45
|
+
'$1$2[redacted]',
|
|
46
|
+
],
|
|
47
|
+
[/\beyJ[\w-]+\.[\w-]+\.[\w-]+/g, '[jwt]'],
|
|
48
|
+
[/\b[\w.+-]+@[\w-]+\.[\w.-]{2,}\b/g, '[email]'],
|
|
49
|
+
[/\b[A-Fa-f0-9]{32,}\b/g, '[hex]'],
|
|
50
|
+
];
|
|
51
|
+
export function redactClient(input) {
|
|
52
|
+
let out = input;
|
|
53
|
+
for (const [pattern, replacement] of REDACTIONS)
|
|
54
|
+
out = out.replace(pattern, replacement);
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function hasBrowser() {
|
|
58
|
+
return typeof window !== 'undefined';
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Stable-per-install id, created on first use.
|
|
62
|
+
*
|
|
63
|
+
* Not a person identifier: it lives in this browser's storage, clears with site
|
|
64
|
+
* data, and is never correlated across apps. It exists so an owner can tell "one
|
|
65
|
+
* user hit this 40 times" from "40 users hit it once" for reports that have no
|
|
66
|
+
* session at all.
|
|
67
|
+
*/
|
|
68
|
+
export function readOrCreateClientId() {
|
|
69
|
+
if (!hasBrowser())
|
|
70
|
+
return null;
|
|
71
|
+
try {
|
|
72
|
+
const existing = window.localStorage.getItem(CLIENT_ID_KEY);
|
|
73
|
+
if (existing && /^[A-Za-z0-9_-]{8,64}$/.test(existing))
|
|
74
|
+
return existing;
|
|
75
|
+
const bytes = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
|
|
76
|
+
? crypto.randomUUID().replace(/-/g, '')
|
|
77
|
+
: Math.random().toString(36).slice(2).padEnd(24, '0');
|
|
78
|
+
const id = bytes.slice(0, 24);
|
|
79
|
+
window.localStorage.setItem(CLIENT_ID_KEY, id);
|
|
80
|
+
return id;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Incognito, blocked storage, quota — anonymous reports still work, they
|
|
84
|
+
// just lose their per-install grouping.
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Serialize an unknown thrown value into a message + stack. */
|
|
89
|
+
export function describeError(value) {
|
|
90
|
+
if (value instanceof Error) {
|
|
91
|
+
return { message: `${value.name}: ${value.message}`, stack: value.stack ?? undefined };
|
|
92
|
+
}
|
|
93
|
+
if (typeof value === 'string')
|
|
94
|
+
return { message: value };
|
|
95
|
+
try {
|
|
96
|
+
return { message: JSON.stringify(value) ?? String(value) };
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return { message: String(value) };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export class Logs {
|
|
103
|
+
appId;
|
|
104
|
+
apiBase;
|
|
105
|
+
auth;
|
|
106
|
+
options;
|
|
107
|
+
queue = [];
|
|
108
|
+
running = false;
|
|
109
|
+
timer = null;
|
|
110
|
+
onError = null;
|
|
111
|
+
onRejection = null;
|
|
112
|
+
onPageHide = null;
|
|
113
|
+
clientId = null;
|
|
114
|
+
/** Epoch ms until which we send nothing (server asked us to stop). */
|
|
115
|
+
quietUntil = 0;
|
|
116
|
+
/** Set when the server says this app cannot accept logs at all (404). */
|
|
117
|
+
disabled = false;
|
|
118
|
+
/** Guards against an error raised inside our own handler re-entering. */
|
|
119
|
+
capturing = false;
|
|
120
|
+
minLevel;
|
|
121
|
+
constructor(appId, apiBase, auth, options = {}) {
|
|
122
|
+
this.appId = appId;
|
|
123
|
+
this.apiBase = apiBase;
|
|
124
|
+
this.auth = auth;
|
|
125
|
+
this.options = options;
|
|
126
|
+
this.minLevel = options.level ?? 'info';
|
|
127
|
+
}
|
|
128
|
+
/** Begin auto-capture and periodic flushing. Idempotent. */
|
|
129
|
+
start() {
|
|
130
|
+
if (this.running || !hasBrowser())
|
|
131
|
+
return;
|
|
132
|
+
this.running = true;
|
|
133
|
+
this.clientId = readOrCreateClientId();
|
|
134
|
+
this.onError = (event) => {
|
|
135
|
+
const described = event.error
|
|
136
|
+
? describeError(event.error)
|
|
137
|
+
: { message: event.message || 'unknown error' };
|
|
138
|
+
this.capture('error', 'window.error', described.message, {
|
|
139
|
+
stack: described.stack,
|
|
140
|
+
source: event.filename || undefined,
|
|
141
|
+
line: event.lineno || undefined,
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
window.addEventListener('error', this.onError);
|
|
145
|
+
this.onRejection = (event) => {
|
|
146
|
+
const described = describeError(event.reason);
|
|
147
|
+
this.capture('error', 'unhandledrejection', described.message, {
|
|
148
|
+
stack: described.stack,
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
window.addEventListener('unhandledrejection', this.onRejection);
|
|
152
|
+
this.onPageHide = () => this.flush();
|
|
153
|
+
window.addEventListener('pagehide', this.onPageHide);
|
|
154
|
+
this.timer = setInterval(() => {
|
|
155
|
+
void this.send(false);
|
|
156
|
+
}, FLUSH_INTERVAL_MS);
|
|
157
|
+
}
|
|
158
|
+
/** Stop capture and timers. Does not flush — call `flush()` first if needed. */
|
|
159
|
+
stop() {
|
|
160
|
+
if (!this.running)
|
|
161
|
+
return;
|
|
162
|
+
this.running = false;
|
|
163
|
+
if (this.timer) {
|
|
164
|
+
clearInterval(this.timer);
|
|
165
|
+
this.timer = null;
|
|
166
|
+
}
|
|
167
|
+
if (hasBrowser()) {
|
|
168
|
+
if (this.onError)
|
|
169
|
+
window.removeEventListener('error', this.onError);
|
|
170
|
+
if (this.onRejection)
|
|
171
|
+
window.removeEventListener('unhandledrejection', this.onRejection);
|
|
172
|
+
if (this.onPageHide)
|
|
173
|
+
window.removeEventListener('pagehide', this.onPageHide);
|
|
174
|
+
}
|
|
175
|
+
this.onError = null;
|
|
176
|
+
this.onRejection = null;
|
|
177
|
+
this.onPageHide = null;
|
|
178
|
+
}
|
|
179
|
+
debug(message, data) {
|
|
180
|
+
this.capture('debug', 'app', message, data);
|
|
181
|
+
}
|
|
182
|
+
info(message, data) {
|
|
183
|
+
this.capture('info', 'app', message, data);
|
|
184
|
+
}
|
|
185
|
+
warn(message, data) {
|
|
186
|
+
this.capture('warn', 'app', message, data);
|
|
187
|
+
}
|
|
188
|
+
error(message, data) {
|
|
189
|
+
this.capture('error', 'app', message, data);
|
|
190
|
+
}
|
|
191
|
+
/** Number of entries waiting to be sent. Exposed for tests and diagnostics. */
|
|
192
|
+
get pending() {
|
|
193
|
+
return this.queue.length;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Queue one entry.
|
|
197
|
+
*
|
|
198
|
+
* Public so app code can record its own categories (`app.logs.capture('warn',
|
|
199
|
+
* 'checkout', ...)`), and so SDK primitives can report their own failures
|
|
200
|
+
* (platform#106's client half) without another queue.
|
|
201
|
+
*/
|
|
202
|
+
capture(level, category, message, data) {
|
|
203
|
+
if (this.disabled || this.capturing)
|
|
204
|
+
return;
|
|
205
|
+
if (LEVEL_ORDER[level] < LEVEL_ORDER[this.minLevel])
|
|
206
|
+
return;
|
|
207
|
+
this.capturing = true;
|
|
208
|
+
try {
|
|
209
|
+
const entry = {
|
|
210
|
+
ts: Date.now(),
|
|
211
|
+
level,
|
|
212
|
+
category,
|
|
213
|
+
message: redactClient(String(message)).slice(0, MESSAGE_MAX),
|
|
214
|
+
data: data === undefined ? undefined : this.safeData(data),
|
|
215
|
+
build: this.options.build,
|
|
216
|
+
traceId: this.newTraceId(),
|
|
217
|
+
};
|
|
218
|
+
this.queue.push(entry);
|
|
219
|
+
// Drop the OLDEST on overflow: during a loop the newest entries are all
|
|
220
|
+
// the same fault, while the first entries include what preceded it.
|
|
221
|
+
if (this.queue.length > MAX_QUEUE)
|
|
222
|
+
this.queue.splice(0, this.queue.length - MAX_QUEUE);
|
|
223
|
+
if (this.queue.length >= MAX_BATCH)
|
|
224
|
+
void this.send(false);
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Never let capture throw into app code.
|
|
228
|
+
}
|
|
229
|
+
finally {
|
|
230
|
+
this.capturing = false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/** Fire-and-forget flush, safe on the unload path. */
|
|
234
|
+
flush() {
|
|
235
|
+
void this.send(true);
|
|
236
|
+
}
|
|
237
|
+
/** Await a flush. For tests and deliberate checkpoints. */
|
|
238
|
+
async flushAsync() {
|
|
239
|
+
await this.send(false);
|
|
240
|
+
}
|
|
241
|
+
safeData(data) {
|
|
242
|
+
try {
|
|
243
|
+
return JSON.parse(redactClient(JSON.stringify(data) ?? 'null'));
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// Cyclic, BigInt, or a getter that throws — keep the entry, drop the payload.
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/** W3C traceparent trace-id, so a client entry can be lined up with the
|
|
251
|
+
* backend and data-worker records for the same logical request. */
|
|
252
|
+
newTraceId() {
|
|
253
|
+
try {
|
|
254
|
+
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
|
|
255
|
+
return crypto.randomUUID().replace(/-/g, '');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
/* fall through */
|
|
260
|
+
}
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
async send(keepalive) {
|
|
264
|
+
if (this.disabled || this.queue.length === 0)
|
|
265
|
+
return;
|
|
266
|
+
if (Date.now() < this.quietUntil)
|
|
267
|
+
return;
|
|
268
|
+
const batch = this.queue.slice(0, MAX_BATCH);
|
|
269
|
+
// Remove before sending: a retry loop is worse than losing a log line, and
|
|
270
|
+
// the entries most likely to be dropped are duplicates of a fault we already
|
|
271
|
+
// reported.
|
|
272
|
+
this.queue = this.queue.slice(batch.length);
|
|
273
|
+
const body = JSON.stringify({
|
|
274
|
+
entries: batch,
|
|
275
|
+
...(this.clientId ? { clientId: this.clientId } : {}),
|
|
276
|
+
});
|
|
277
|
+
const res = await postTelemetry(this.auth, this.apiBase, `/v1/apps/${this.appId}/logs`, body, {
|
|
278
|
+
keepalive,
|
|
279
|
+
// A beacon cannot carry the bearer token, so only use it where the
|
|
280
|
+
// same-origin cookie speaks for us. In legacy-bearer mode a keepalive
|
|
281
|
+
// fetch still attaches the token and still survives unload in practice.
|
|
282
|
+
beacon: this.auth.usesPlatformCookie === true,
|
|
283
|
+
});
|
|
284
|
+
if (!res)
|
|
285
|
+
return;
|
|
286
|
+
if (res.status === 404) {
|
|
287
|
+
// Unknown app id — a misconfigured `appId` will never succeed, so stop
|
|
288
|
+
// rather than retry every ten seconds for the life of the page.
|
|
289
|
+
this.disabled = true;
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (res.status === 202 || res.status === 429) {
|
|
293
|
+
// Over budget. Go quiet; the server is still counting the spike.
|
|
294
|
+
this.quietUntil = Date.now() + COOLDOWN_MS;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=logs.js.map
|
package/dist/logs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared POST transport for SDK telemetry (usage pings, app logs).
|
|
3
|
+
*
|
|
4
|
+
* Extracted from usage.ts rather than reimplemented for the logger: the awkward
|
|
5
|
+
* parts — same-origin mediated URL vs absolute API base, bearer-vs-cookie auth,
|
|
6
|
+
* and `sendBeacon` on unload — were already solved there, and a second copy
|
|
7
|
+
* would drift.
|
|
8
|
+
*
|
|
9
|
+
* Never throws and never rejects. Telemetry must not break an app.
|
|
10
|
+
*/
|
|
11
|
+
export interface TelemetryAuth {
|
|
12
|
+
token: string | null;
|
|
13
|
+
usesPlatformCookie?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** In platform-cookie mode all calls go same-origin through the host's mediation
|
|
16
|
+
* so the HttpOnly cookie rides along (and the host can assert the app id). */
|
|
17
|
+
export declare function telemetryUrl(auth: TelemetryAuth, apiBase: string, path: string): string;
|
|
18
|
+
export interface PostOptions {
|
|
19
|
+
/** Unload path: prefer a transport that survives page close. */
|
|
20
|
+
keepalive?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether `sendBeacon` is acceptable for this payload.
|
|
23
|
+
*
|
|
24
|
+
* Beacons cannot set `Authorization`. In platform-cookie mode the same-origin
|
|
25
|
+
* beacon still carries the session cookie, so nothing is lost; in
|
|
26
|
+
* legacy-bearer mode the request would arrive unauthenticated, which each
|
|
27
|
+
* caller has to decide about for itself.
|
|
28
|
+
*/
|
|
29
|
+
beacon?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* POST a JSON body. Returns the Response, or null when the request could not be
|
|
33
|
+
* made or was sent via `sendBeacon` (which yields no response).
|
|
34
|
+
*/
|
|
35
|
+
export declare function postTelemetry(auth: TelemetryAuth, apiBase: string, path: string, body: string, opts?: PostOptions): Promise<Response | null>;
|
|
36
|
+
//# sourceMappingURL=telemetry-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-transport.d.ts","sourceRoot":"","sources":["../src/telemetry-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;+EAC+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAkC1B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared POST transport for SDK telemetry (usage pings, app logs).
|
|
3
|
+
*
|
|
4
|
+
* Extracted from usage.ts rather than reimplemented for the logger: the awkward
|
|
5
|
+
* parts — same-origin mediated URL vs absolute API base, bearer-vs-cookie auth,
|
|
6
|
+
* and `sendBeacon` on unload — were already solved there, and a second copy
|
|
7
|
+
* would drift.
|
|
8
|
+
*
|
|
9
|
+
* Never throws and never rejects. Telemetry must not break an app.
|
|
10
|
+
*/
|
|
11
|
+
/** In platform-cookie mode all calls go same-origin through the host's mediation
|
|
12
|
+
* so the HttpOnly cookie rides along (and the host can assert the app id). */
|
|
13
|
+
export function telemetryUrl(auth, apiBase, path) {
|
|
14
|
+
return auth.usesPlatformCookie ? `/.pas/api${path}` : `${apiBase}${path}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* POST a JSON body. Returns the Response, or null when the request could not be
|
|
18
|
+
* made or was sent via `sendBeacon` (which yields no response).
|
|
19
|
+
*/
|
|
20
|
+
export async function postTelemetry(auth, apiBase, path, body, opts = {}) {
|
|
21
|
+
const url = telemetryUrl(auth, apiBase, path);
|
|
22
|
+
const keepalive = opts.keepalive === true;
|
|
23
|
+
if (keepalive &&
|
|
24
|
+
opts.beacon !== false &&
|
|
25
|
+
typeof navigator !== 'undefined' &&
|
|
26
|
+
typeof navigator.sendBeacon === 'function') {
|
|
27
|
+
try {
|
|
28
|
+
const blob = new Blob([body], { type: 'application/json' });
|
|
29
|
+
if (navigator.sendBeacon(url, blob))
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Fall through to fetch.
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (typeof fetch === 'undefined')
|
|
37
|
+
return null;
|
|
38
|
+
try {
|
|
39
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
40
|
+
const init = { method: 'POST', headers, body, keepalive };
|
|
41
|
+
if (auth.usesPlatformCookie) {
|
|
42
|
+
init.credentials = 'same-origin';
|
|
43
|
+
}
|
|
44
|
+
else if (auth.token) {
|
|
45
|
+
headers.Authorization = `Bearer ${auth.token}`;
|
|
46
|
+
}
|
|
47
|
+
// No token and no cookie is not an error here: log ingestion accepts
|
|
48
|
+
// anonymous reports on purpose, since a failure before sign-in is exactly
|
|
49
|
+
// the one worth having.
|
|
50
|
+
return await fetch(url, init);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=telemetry-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-transport.js","sourceRoot":"","sources":["../src/telemetry-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH;+EAC+E;AAC/E,MAAM,UAAU,YAAY,CAAC,IAAmB,EAAE,OAAe,EAAE,IAAY;IAC7E,OAAO,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,CAAC;AAC5E,CAAC;AAgBD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAmB,EACnB,OAAe,EACf,IAAY,EACZ,IAAY,EACZ,OAAoB,EAAE;IAEtB,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC;IAE1C,IACE,SAAS;QACT,IAAI,CAAC,MAAM,KAAK,KAAK;QACrB,OAAO,SAAS,KAAK,WAAW;QAChC,OAAO,SAAS,CAAC,UAAU,KAAK,UAAU,EAC1C,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC5D,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;QAC/E,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACvE,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC;QACnC,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,aAAa,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;QACjD,CAAC;QACD,qEAAqE;QACrE,0EAA0E;QAC1E,wBAAwB;QACxB,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -21,6 +21,21 @@ export interface ProInitOptions {
|
|
|
21
21
|
/** Default true. Set false to disable the auto-heartbeat in this app. */
|
|
22
22
|
auto?: boolean;
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Runtime error capture (`app.logs`). On by default: `window.onerror` and
|
|
26
|
+
* `unhandledrejection` are recorded so a user-visible failure leaves a platform
|
|
27
|
+
* record, readable by the app owner in the console.
|
|
28
|
+
*
|
|
29
|
+
* Independent of `usage` above — that measures engagement, this records faults.
|
|
30
|
+
*/
|
|
31
|
+
monitoring?: {
|
|
32
|
+
/** Default true. Set false to disable auto-capture and the flush timer. */
|
|
33
|
+
auto?: boolean;
|
|
34
|
+
/** Build metadata attached to every entry (commit sha, version, built-at). */
|
|
35
|
+
build?: Record<string, unknown>;
|
|
36
|
+
/** Minimum level sent. Default 'info', so `app.logs.debug()` is dropped. */
|
|
37
|
+
level?: 'debug' | 'info' | 'warn' | 'error';
|
|
38
|
+
};
|
|
24
39
|
}
|
|
25
40
|
export type SubscriptionStatus = 'active' | 'past_due' | 'canceled' | 'incomplete';
|
|
26
41
|
export interface Subscription {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAC/C,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8GAA8G;IAC9G,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,KAAK,CAAC,EAAE;QACN,yEAAyE;QACzE,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAED,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,CAAC;AAEnF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,sDAAsD;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAC/C,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8GAA8G;IAC9G,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,KAAK,CAAC,EAAE;QACN,yEAAyE;QACzE,IAAI,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;IACF;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QACX,2EAA2E;QAC3E,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,8EAA8E;QAC9E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,4EAA4E;QAC5E,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;KAC7C,CAAC;CACH;AAED,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,CAAC;AAEnF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,sDAAsD;IACtD,gBAAgB,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
|
package/dist/usage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AASD,qBAAa,KAAK;IAWd,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAZvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,YAAY,CAAuB;IAC3C,gFAAgF;IAChF,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,UAAU,CAA6B;gBAG5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ;IAGjC,wEAAwE;IACxE,KAAK,IAAI,IAAI;IA6Bb,iFAAiF;IACjF,IAAI,IAAI,IAAI;IAkBZ;;;OAGG;IACH,aAAa,CAAC,CAAC,GAAE,MAAU,GAAG,IAAI;IAKlC;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAWb,+DAA+D;IAC/D,OAAO,CAAC,WAAW;IAOnB,qFAAqF;IACrF,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;YAMP,IAAI;YAoBJ,IAAI;IAkBlB,OAAO,CAAC,eAAe;CAGxB"}
|
package/dist/usage.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* residual elapsed seconds via `navigator.sendBeacon` (survives unload)
|
|
19
19
|
* falling back to `fetch(..., { keepalive: true })`.
|
|
20
20
|
*/
|
|
21
|
+
import { postTelemetry } from './telemetry-transport.js';
|
|
21
22
|
const HEARTBEAT_MS = 60_000;
|
|
22
23
|
const MAX_DELTA_SECONDS = 90;
|
|
23
24
|
function hasBrowser() {
|
|
@@ -169,46 +170,15 @@ export class Usage {
|
|
|
169
170
|
deltaSeconds: seconds,
|
|
170
171
|
deltaApiCalls: apiCalls,
|
|
171
172
|
});
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (ok)
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
catch {
|
|
185
|
-
// fall through
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
try {
|
|
189
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
190
|
-
const init = {
|
|
191
|
-
method: 'POST',
|
|
192
|
-
headers,
|
|
193
|
-
body,
|
|
194
|
-
keepalive,
|
|
195
|
-
};
|
|
196
|
-
if (this.auth.usesPlatformCookie) {
|
|
197
|
-
init.credentials = 'same-origin';
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
const token = this.auth.token;
|
|
201
|
-
if (!token)
|
|
202
|
-
return;
|
|
203
|
-
headers.Authorization = `Bearer ${token}`;
|
|
204
|
-
}
|
|
205
|
-
await fetch(url, {
|
|
206
|
-
...init,
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
catch {
|
|
210
|
-
// Telemetry never breaks an app.
|
|
211
|
-
}
|
|
173
|
+
// Transport lives in telemetry-transport.ts, shared with the app logger
|
|
174
|
+
// (mediated URL, bearer-vs-cookie, sendBeacon on unload). Behaviour here is
|
|
175
|
+
// unchanged: beacon is still attempted in both auth modes on the unload path,
|
|
176
|
+
// which stays best-effort in legacy-bearer mode because a beacon cannot carry
|
|
177
|
+
// the token.
|
|
178
|
+
await postTelemetry(this.auth, this.apiBase, '/v1/usage/ping', body, {
|
|
179
|
+
keepalive,
|
|
180
|
+
beacon: true,
|
|
181
|
+
});
|
|
212
182
|
}
|
|
213
183
|
isAuthenticated() {
|
|
214
184
|
return this.auth.usesPlatformCookie ? this.auth.isSignedIn === true : !!this.auth.token;
|
package/dist/usage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAazD,MAAM,YAAY,GAAG,MAAM,CAAC;AAC5B,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,SAAS,UAAU;IACjB,OAAO,OAAO,QAAQ,KAAK,WAAW,IAAI,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1E,CAAC;AAED,MAAM,OAAO,KAAK;IAWG;IACA;IACA;IAZX,OAAO,GAAG,KAAK,CAAC;IAChB,KAAK,GAA0C,IAAI,CAAC;IACpD,YAAY,GAAkB,IAAI,CAAC;IAC3C,gFAAgF;IACxE,SAAS,GAAG,CAAC,CAAC;IACd,eAAe,GAAG,CAAC,CAAC;IACpB,YAAY,GAAwB,IAAI,CAAC;IACzC,UAAU,GAAwB,IAAI,CAAC;IAE/C,YACmB,KAAa,EACb,OAAe,EACf,IAAc;QAFd,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAQ;QACf,SAAI,GAAJ,IAAI,CAAU;IAC9B,CAAC;IAEJ,wEAAwE;IACxE,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,UAAU,EAAE;YAAE,OAAO;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,+BAA+B;QAC/B,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YAC3C,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACxC,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,GAAG,EAAE;YACvB,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;gBAC3C,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI;oBAAE,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAEjE,IAAI,CAAC,UAAU,GAAG,GAAG,EAAE;YACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAErD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9B,CAAC,EAAE,YAAY,CAAC,CAAC;IACnB,CAAC;IAED,iFAAiF;IACjF,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,YAAY;gBAAE,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3F,IAAI,IAAI,CAAC,UAAU;gBAAE,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,IAAY,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO;QAC1C,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,KAAK;QACH,IAAI,CAAC,UAAU,EAAE;YAAE,OAAO;QAC1B,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO;QAC5C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,6EAA6E;IAE7E,+DAA+D;IACvD,WAAW;QACjB,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI;YAAE,OAAO;QACtC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,qFAAqF;IAC7E,YAAY;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;QAChD,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,IAAI,CAAC;QAC9B,uEAAuE;QACvE,uCAAuC;QACvC,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC;YAAE,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,aAAa;QACnB,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;QAC/B,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;QACzB,OAAO,CAAC,CAAC;IACX,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YAC3C,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO;QAC5C,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC5B,oEAAoE;YACpE,uEAAuE;YACvE,oEAAoE;YACpE,sEAAsE;YACtE,IAAI,CAAC,SAAS,IAAI,OAAO,GAAG,IAAI,CAAC;YACjC,IAAI,CAAC,eAAe,IAAI,QAAQ,CAAC;YACjC,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,OAAe,EAAE,QAAgB,EAAE,SAAkB;QACtE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;YAAE,OAAO;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,OAAO;YACrB,aAAa,EAAE,QAAQ;SACxB,CAAC,CAAC;QACH,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,8EAA8E;QAC9E,aAAa;QACb,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE;YACnE,SAAS;YACT,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;IACL,CAAC;IAEO,eAAe;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IAC1F,CAAC;CACF"}
|