@hanzo/event 0.3.15 → 0.3.17
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/TAXONOMY.md +1 -1
- package/dist/{core-BZraSvcr.d.cts → core-D4PaPlOB.d.cts} +3 -3
- package/dist/{core-BZraSvcr.d.ts → core-D4PaPlOB.d.ts} +3 -3
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +6 -6
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +6 -6
- package/dist/react.mjs.map +1 -1
- package/hz.js +5 -3
- package/package.json +1 -1
- package/src/core.test.ts +8 -8
- package/src/core.ts +12 -5
- package/src/hz.test.ts +3 -3
- package/src/types.ts +3 -3
- package/src/version.ts +1 -1
package/src/core.test.ts
CHANGED
|
@@ -360,26 +360,26 @@ describe('Analytics capture', () => {
|
|
|
360
360
|
// The failure this closes is silent: a surface with no key attributes nothing
|
|
361
361
|
// for a logged-out visitor, the door refuses the write, and the page shows no
|
|
362
362
|
// sign of it. The key must resolve from the env exactly as the DSN does.
|
|
363
|
-
process.env.
|
|
363
|
+
process.env.NEXT_PUBLIC_PUBLISHABLE_KEY = 'pk-live-from-env'
|
|
364
364
|
try {
|
|
365
365
|
const a = mk() // no key in config
|
|
366
366
|
a.capture('x')
|
|
367
367
|
a.flush(true)
|
|
368
368
|
expect(tx.sent[0].ingestKey).toBe('pk-live-from-env')
|
|
369
369
|
} finally {
|
|
370
|
-
delete process.env.
|
|
370
|
+
delete process.env.NEXT_PUBLIC_PUBLISHABLE_KEY
|
|
371
371
|
}
|
|
372
372
|
})
|
|
373
373
|
|
|
374
374
|
it('prefers an explicit ingest key over the build env', () => {
|
|
375
|
-
process.env.
|
|
375
|
+
process.env.NEXT_PUBLIC_PUBLISHABLE_KEY = 'pk-live-from-env'
|
|
376
376
|
try {
|
|
377
377
|
const a = mk({ ingestKey: 'pk-live-explicit' })
|
|
378
378
|
a.capture('x')
|
|
379
379
|
a.flush(true)
|
|
380
380
|
expect(tx.sent[0].ingestKey).toBe('pk-live-explicit')
|
|
381
381
|
} finally {
|
|
382
|
-
delete process.env.
|
|
382
|
+
delete process.env.NEXT_PUBLIC_PUBLISHABLE_KEY
|
|
383
383
|
}
|
|
384
384
|
})
|
|
385
385
|
|
|
@@ -394,7 +394,7 @@ describe('Analytics capture', () => {
|
|
|
394
394
|
// The leak this closes: one console bundle is served to several brands, and a
|
|
395
395
|
// pk- names ONE org. If an env-sourced key displaced the bearer, every
|
|
396
396
|
// signed-in user's events would re-file under whichever org minted the key.
|
|
397
|
-
process.env.
|
|
397
|
+
process.env.NEXT_PUBLIC_PUBLISHABLE_KEY = 'pk-live-one-org'
|
|
398
398
|
try {
|
|
399
399
|
const a = mk({ getToken: () => 'jwt-of-a-real-person' })
|
|
400
400
|
a.capture('x')
|
|
@@ -402,12 +402,12 @@ describe('Analytics capture', () => {
|
|
|
402
402
|
expect(tx.sent[0].token).toBe('jwt-of-a-real-person')
|
|
403
403
|
expect(tx.sent[0].ingestKey).toBeUndefined()
|
|
404
404
|
} finally {
|
|
405
|
-
delete process.env.
|
|
405
|
+
delete process.env.NEXT_PUBLIC_PUBLISHABLE_KEY
|
|
406
406
|
}
|
|
407
407
|
})
|
|
408
408
|
|
|
409
409
|
it('an anonymous visitor still rides the key', () => {
|
|
410
|
-
process.env.
|
|
410
|
+
process.env.NEXT_PUBLIC_PUBLISHABLE_KEY = 'pk-live-one-org'
|
|
411
411
|
try {
|
|
412
412
|
const a = mk({ getToken: () => undefined }) // logged out
|
|
413
413
|
a.capture('x')
|
|
@@ -415,7 +415,7 @@ describe('Analytics capture', () => {
|
|
|
415
415
|
expect(tx.sent[0].ingestKey).toBe('pk-live-one-org')
|
|
416
416
|
expect(tx.sent[0].token).toBeUndefined()
|
|
417
417
|
} finally {
|
|
418
|
-
delete process.env.
|
|
418
|
+
delete process.env.NEXT_PUBLIC_PUBLISHABLE_KEY
|
|
419
419
|
}
|
|
420
420
|
})
|
|
421
421
|
|
package/src/core.ts
CHANGED
|
@@ -123,7 +123,14 @@ function normalizeError(err: unknown): Exception {
|
|
|
123
123
|
return { type: n.name, message: n.message, stack: n.stack }
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
// React Native defines a `window` but no `document` (and no `window.location`),
|
|
127
|
+
// so `typeof window !== 'undefined'` alone took the browser path there and
|
|
128
|
+
// `init()` threw on `window.location.search`. Requiring `document` makes RN read
|
|
129
|
+
// as non-browser: `init()` returns early (skips attribution + the visibility/
|
|
130
|
+
// unload listeners RN doesn't have), while `capture()`/`flush()` — which are NOT
|
|
131
|
+
// gated on this and post through plain `fetch` — still emit. So the client is
|
|
132
|
+
// inert-safe under SSR/Node and live on RN, without a second transport.
|
|
133
|
+
const isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined'
|
|
127
134
|
|
|
128
135
|
/** serializeBatch stringifies a batch, salvaging what it can. `properties` is
|
|
129
136
|
* arbitrary caller data — a DOM node, a React synthetic event, an axios error are
|
|
@@ -234,9 +241,9 @@ export class Analytics {
|
|
|
234
241
|
// The publishable key resolves the SAME way the DSN below does: an explicit
|
|
235
242
|
// config wins, else the inlined build-time env.
|
|
236
243
|
//
|
|
237
|
-
//
|
|
238
|
-
// ALREADY carries end to end — KMS holds deploy/
|
|
239
|
-
// Dockerfile takes it as the
|
|
244
|
+
// NEXT_PUBLIC_PUBLISHABLE_KEY is that env, and it is the name the fleet
|
|
245
|
+
// ALREADY carries end to end — KMS holds deploy/PUBLISHABLE_KEY, each
|
|
246
|
+
// Dockerfile takes it as the PUBLISHABLE_KEY build-arg and re-exports it
|
|
240
247
|
// with the NEXT_PUBLIC_ prefix Next needs to inline it. Reading anything
|
|
241
248
|
// else here would add a fourth spelling of one value.
|
|
242
249
|
//
|
|
@@ -246,7 +253,7 @@ export class Analytics {
|
|
|
246
253
|
// unattributed write is refused (401 ingest_key_required), which is silent
|
|
247
254
|
// in the page and invisible until you read the warehouse and find the host
|
|
248
255
|
// missing entirely.
|
|
249
|
-
ingestKey: config.ingestKey ?? readEnv('
|
|
256
|
+
ingestKey: config.ingestKey ?? readEnv('NEXT_PUBLIC_PUBLISHABLE_KEY'),
|
|
250
257
|
}
|
|
251
258
|
this.transport = config.transport ?? new DefaultTransport()
|
|
252
259
|
// Error plane, most specific source first: an explicit DSN wins, then the
|
package/src/hz.test.ts
CHANGED
|
@@ -230,8 +230,8 @@ describe('hz.js', () => {
|
|
|
230
230
|
// keyed static surface therefore sent UNATTRIBUTED writes, which the door
|
|
231
231
|
// refuses — silently, because nothing here reads the response.
|
|
232
232
|
|
|
233
|
-
it('presents the
|
|
234
|
-
const r = runSnippet({ attrs: { 'data-
|
|
233
|
+
it('presents the publishable key as a bearer on fetch', () => {
|
|
234
|
+
const r = runSnippet({ attrs: { 'data-publishable-key': 'pk-abc123' } })
|
|
235
235
|
r.api!.flush()
|
|
236
236
|
const post = r.posts.at(-1)!
|
|
237
237
|
expect(post.via).toBe('fetch')
|
|
@@ -239,7 +239,7 @@ describe('hz.js', () => {
|
|
|
239
239
|
expect(post.url).toBe('https://api.hanzo.ai/v1/event')
|
|
240
240
|
})
|
|
241
241
|
|
|
242
|
-
it('
|
|
242
|
+
it('still reads the retiring data-ingest-key, on a headerless beacon', () => {
|
|
243
243
|
const r = runSnippet({ attrs: { 'data-ingest-key': 'pk-abc123' }, beacon: true })
|
|
244
244
|
r.api!.flush()
|
|
245
245
|
const post = r.posts.at(-1)!
|
package/src/types.ts
CHANGED
|
@@ -120,11 +120,11 @@ export interface AnalyticsConfig {
|
|
|
120
120
|
* a reading principal — so it is safe to ship in a bundle. Mint one per org with
|
|
121
121
|
* POST /v1/keys {"type":"publishable"}.
|
|
122
122
|
*
|
|
123
|
-
* Omit it and the client reads
|
|
123
|
+
* Omit it and the client reads NEXT_PUBLIC_PUBLISHABLE_KEY from the inlined
|
|
124
124
|
* build env, the same way `dsn` falls back — so a surface declares BOTH planes
|
|
125
125
|
* in its build and neither needs code to switch on. That is the ONE spelling
|
|
126
|
-
* the fleet already carries: KMS holds deploy/
|
|
127
|
-
* Dockerfile takes
|
|
126
|
+
* the fleet already carries: KMS holds deploy/PUBLISHABLE_KEY, and each
|
|
127
|
+
* Dockerfile takes PUBLISHABLE_KEY as a build-arg and re-exports it with the
|
|
128
128
|
* NEXT_PUBLIC_ prefix that makes Next inline it.
|
|
129
129
|
*
|
|
130
130
|
* A surface with no key at all still reports for whoever is SIGNED IN (the
|
package/src/version.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// The library version, stamped on every event (`libraryVersion`) and on the
|
|
2
2
|
// Sentry `sdk` block. It lives alone so `sentry.ts` can read it without importing
|
|
3
3
|
// `core.ts` — core imports sentry, so the reverse would be an import cycle.
|
|
4
|
-
export const VERSION = '0.3.
|
|
4
|
+
export const VERSION = '0.3.17'
|