@hanzo/event 0.3.32 → 0.3.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.cjs CHANGED
@@ -86,6 +86,56 @@ function dsnForProduct(product, key) {
86
86
  return `https://${key}@api.hanzo.ai/v1/event/${projectId}`;
87
87
  }
88
88
 
89
+ // src/org.ts
90
+ var ORG_DOMAIN = Object.freeze({
91
+ hanzo: Object.freeze(["hanzo.ai", "hanzo.app", "hanzo.chat", "hanzo.id", "hanzo.bot", "hanzo.sh"]),
92
+ lux: Object.freeze([
93
+ "lux.network",
94
+ "lux.exchange",
95
+ "lux.market",
96
+ "lux.finance",
97
+ "lux.financial",
98
+ "lux.credit",
99
+ "lux.fund",
100
+ "lux.id"
101
+ ]),
102
+ zoo: Object.freeze(["zoo.ngo", "zoo.network", "zoolabs.id"])
103
+ });
104
+ var ORG_KEY = Object.freeze({
105
+ hanzo: "pk-rM_CdaF2MQckGCrla113SrR1oH4zvqN8xh2I95Z9tY8",
106
+ lux: "pk-gUZp6ZVfhJzSwK-rb4oLbVkpCnMBx5uSCpxf_5yEhQk",
107
+ zoo: "pk-3TKpKnERV9AQSsBUERWkZejC1O1mUxc1jRzsP3MPbs4"
108
+ });
109
+ var PUBLISHABLE = "pk-";
110
+ var normalize = (host) => host.trim().toLowerCase().replace(/\.$/, "").split(":")[0] ?? "";
111
+ function orgOf(host) {
112
+ const h = normalize(host);
113
+ if (!h) return void 0;
114
+ let best;
115
+ let bestLen = 0;
116
+ for (const [org, domains] of Object.entries(ORG_DOMAIN)) {
117
+ for (const d of domains) {
118
+ if ((h === d || h.endsWith(`.${d}`)) && d.length > bestLen) {
119
+ best = org;
120
+ bestLen = d.length;
121
+ }
122
+ }
123
+ }
124
+ return best;
125
+ }
126
+ function keyFor(host, keyring = ORG_KEY) {
127
+ const org = orgOf(host);
128
+ if (!org) return void 0;
129
+ const key = keyring[org];
130
+ if (typeof key !== "string") return void 0;
131
+ const trimmed = key.trim();
132
+ return trimmed.startsWith(PUBLISHABLE) ? trimmed : void 0;
133
+ }
134
+ function keyForPage(keyring = ORG_KEY) {
135
+ if (typeof location === "undefined") return void 0;
136
+ return keyFor(location.hostname, keyring);
137
+ }
138
+
89
139
  // src/scrub.ts
90
140
  var REDACTED = "[redacted]";
91
141
  var EMAIL_MARK = "[email]";
@@ -207,8 +257,8 @@ function scrubText(s, capturePII = false) {
207
257
  }
208
258
 
209
259
  // src/anon.js
210
- var HZ_ANON_KEY = "hz_anon_id";
211
- var HZ_ANON_LEGACY_KEY = "hz_id";
260
+ var HZ_ANON_KEY = "iam-anon-id";
261
+ var HZ_ANON_ADOPT = ["hz_anon_id", "hz_id"];
212
262
  var HZ_ANON_DOMAIN = "hanzo.ai";
213
263
  var HZ_ANON_MAX_AGE = 2 * 365 * 24 * 60 * 60;
214
264
  var hzAnonMemo;
@@ -295,10 +345,17 @@ function hzAnonWrite(name, value) {
295
345
  } catch (e) {
296
346
  }
297
347
  }
348
+ function hzAnonAdopted(s) {
349
+ for (var i = 0; i < HZ_ANON_ADOPT.length; i++) {
350
+ var id = hzAnonCookie(HZ_ANON_ADOPT[i]) || hzAnonItem(s, HZ_ANON_ADOPT[i]);
351
+ if (id) return id;
352
+ }
353
+ return "";
354
+ }
298
355
  function hzAnonId() {
299
356
  if (typeof window === "undefined") return "";
300
357
  var s = hzAnonStore();
301
- var id = hzAnonCookie(HZ_ANON_KEY) || hzAnonItem(s, HZ_ANON_KEY) || hzAnonItem(s, HZ_ANON_LEGACY_KEY) || hzAnonMemo || hzUuidv7();
358
+ var id = hzAnonCookie(HZ_ANON_KEY) || hzAnonItem(s, HZ_ANON_KEY) || hzAnonAdopted(s) || hzAnonMemo || hzUuidv7();
302
359
  hzAnonMemo = id;
303
360
  hzAnonWrite(HZ_ANON_KEY, id);
304
361
  try {
@@ -309,7 +366,7 @@ function hzAnonId() {
309
366
  }
310
367
 
311
368
  // src/version.ts
312
- var VERSION = "0.3.32";
369
+ var VERSION = "0.3.34";
313
370
 
314
371
  // src/sentry.ts
315
372
  var MAX_FRAMES = 50;
@@ -771,12 +828,20 @@ var Analytics = class {
771
828
  // carries end to end — KMS `deploy/PUBLISHABLE_KEY` -> the PUBLISHABLE_KEY
772
829
  // build-arg -> the NEXT_PUBLIC_ prefix Next inlines.
773
830
  //
774
- // A surface that provides neither has no key, and its anonymous traffic
775
- // files under `$public` (which drops track/identify/group and answers 200);
776
- // the fix is to give it the KMS-sourced env, not to hardcode the org key
777
- // here. The key is a credential-class value: its home is KMS, and the ONE
778
- // build reads it from there.
779
- ingestKey: config.ingestKey ?? readEnv("NEXT_PUBLIC_PUBLISHABLE_KEY")
831
+ // 3. the org that owns the HOST this page is served from (`org.ts`).
832
+ //
833
+ // Step 3 fires only when a surface configured NOTHING, so it never overrides
834
+ // the KMS chain above it replaces going dark with reporting to the right
835
+ // brand. That is what a static export needs: `output: export` inlines no env,
836
+ // so before this the only way to report was to commit a key literal, and the
837
+ // fleet grew one copy per site of a value with a single source.
838
+ //
839
+ // A surface no brand claims still has no key, and the door REFUSES an
840
+ // unattributed event (401 `ingest_key_required`) — the reserved `$public`
841
+ // tenant that once caught keyless beacons is retired, and anonymous ingest is
842
+ // refused at every door on every brand host. So there is no quiet fallback to
843
+ // rely on: an event lands in the org a credential names, or it does not land.
844
+ ingestKey: config.ingestKey ?? readEnv("NEXT_PUBLIC_PUBLISHABLE_KEY") ?? keyForPage()
780
845
  };
781
846
  this.transport = config.transport ?? new DefaultTransport();
782
847
  this.dsn = parseDsn(
@@ -1116,26 +1181,26 @@ var ErrorBoundary = class extends react.Component {
1116
1181
  }
1117
1182
  };
1118
1183
  ErrorBoundary.contextType = Ctx;
1119
- /*! anon.js — THE anonymous-identity chain. ONE implementation, three distributions.
1184
+ /*! anon.js — THE anonymous-identity chain. ONE implementation, two distributions.
1120
1185
  *
1121
1186
  * One browser is ONE person on every Hanzo surface, whichever client a page
1122
- * happens to have loaded. There were three implementations writing TWO keys —
1123
- * `hz_anon_id` (the npm client, the hosted tag) and `hz_id` (hz.js) — so the same
1124
- * visitor was several people depending on which snippet the surface shipped.
1187
+ * happens to have loaded. There were once three implementations writing TWO keys —
1188
+ * `hz_anon_id` and `hz_id` — so the same visitor was several people depending on
1189
+ * which snippet the surface shipped.
1125
1190
  *
1126
- * The three call sites:
1191
+ * The two call sites:
1127
1192
  * 1. src/storage.ts — the bundled npm client; IMPORTS this file.
1128
- * 2. hz.js — the no-build script tag; INLINES the marked region.
1129
- * 3. hanzoai/cloud apps/analytics/tag.js — the tag the door hosts at
1193
+ * 2. hanzoai/cloud apps/analytics/tag.js — the tag the door hosts at
1130
1194
  * /v1/event.js; vendors this file and its tag.go serves the marked region
1131
1195
  * with the tag as one asset, so the door holds no second copy either.
1132
1196
  *
1133
- * (2) and (3) have no bundler and cannot import anything, which is why the chain
1134
- * lives in a file that is plain ES5 rather than in a .ts: the region between the
1135
- * BEGIN and END markers is COPIED VERBATIM, and src/anon.test.ts fails if hz.js's
1136
- * copy is so much as a byte different. Keep the region ES5, dependency-free,
1137
- * `hz`-prefixed (it is spliced into other people's scopes) and unformatted — a
1138
- * reformat of one copy is a diff against the other.
1197
+ * (2) has no bundler and cannot import anything, which is why the chain lives in a
1198
+ * file that is plain ES5 rather than in a .ts: the region between the BEGIN and END
1199
+ * markers is COPIED VERBATIM. Keep it ES5, dependency-free, `hz`-prefixed (it is
1200
+ * spliced into other people's scopes) and unformatted a reformat here is a diff
1201
+ * against the vendored copy. After editing, resync the door:
1202
+ *
1203
+ * curl -fsSL https://unpkg.com/@hanzo/event/src/anon.js -o apps/analytics/anon.js
1139
1204
  */
1140
1205
 
1141
1206
  exports.AnalyticsProvider = AnalyticsProvider;