@interfere/types 8.1.1 → 8.1.6

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.
Files changed (57) hide show
  1. package/dist/data/frame.d.mts.map +1 -1
  2. package/dist/data/frame.mjs +4 -0
  3. package/dist/data/frame.mjs.map +1 -1
  4. package/dist/data/session.d.mts.map +1 -1
  5. package/dist/data/session.mjs +5 -1
  6. package/dist/data/session.mjs.map +1 -1
  7. package/dist/integrations/index.d.mts +16 -1
  8. package/dist/integrations/index.d.mts.map +1 -1
  9. package/dist/integrations/index.mjs +29 -7
  10. package/dist/integrations/index.mjs.map +1 -1
  11. package/dist/integrations/platforms/github.mjs.map +1 -1
  12. package/dist/integrations/platforms/vercel.mjs.map +1 -1
  13. package/dist/releases/definition.d.mts +5 -4
  14. package/dist/releases/definition.d.mts.map +1 -1
  15. package/dist/releases/definition.mjs +41 -13
  16. package/dist/releases/definition.mjs.map +1 -1
  17. package/dist/sdk/envelope.d.mts +1144 -35
  18. package/dist/sdk/envelope.d.mts.map +1 -1
  19. package/dist/sdk/envelope.mjs +75 -32
  20. package/dist/sdk/envelope.mjs.map +1 -1
  21. package/dist/sdk/errors.d.mts +86 -6
  22. package/dist/sdk/errors.d.mts.map +1 -1
  23. package/dist/sdk/errors.mjs +174 -12
  24. package/dist/sdk/errors.mjs.map +1 -1
  25. package/dist/sdk/identify.d.mts.map +1 -1
  26. package/dist/sdk/identify.mjs +18 -1
  27. package/dist/sdk/identify.mjs.map +1 -1
  28. package/dist/sdk/plugins/context/browser.d.mts.map +1 -1
  29. package/dist/sdk/plugins/context/browser.mjs +65 -25
  30. package/dist/sdk/plugins/context/browser.mjs.map +1 -1
  31. package/dist/sdk/plugins/context/edge.d.mts.map +1 -1
  32. package/dist/sdk/plugins/context/edge.mjs +5 -1
  33. package/dist/sdk/plugins/context/edge.mjs.map +1 -1
  34. package/dist/sdk/plugins/context/next.d.mts +25 -1
  35. package/dist/sdk/plugins/context/next.d.mts.map +1 -1
  36. package/dist/sdk/plugins/context/next.mjs +40 -16
  37. package/dist/sdk/plugins/context/next.mjs.map +1 -1
  38. package/dist/sdk/plugins/payload/errors.d.mts.map +1 -1
  39. package/dist/sdk/plugins/payload/errors.mjs +17 -2
  40. package/dist/sdk/plugins/payload/errors.mjs.map +1 -1
  41. package/dist/sdk/plugins/payload/page-events.d.mts.map +1 -1
  42. package/dist/sdk/plugins/payload/page-events.mjs +13 -1
  43. package/dist/sdk/plugins/payload/page-events.mjs.map +1 -1
  44. package/dist/sdk/plugins/payload/rage-click.d.mts.map +1 -1
  45. package/dist/sdk/plugins/payload/rage-click.mjs +4 -0
  46. package/dist/sdk/plugins/payload/rage-click.mjs.map +1 -1
  47. package/dist/sdk/plugins/payload/replay.d.mts.map +1 -1
  48. package/dist/sdk/plugins/payload/replay.mjs +6 -0
  49. package/dist/sdk/plugins/payload/replay.mjs.map +1 -1
  50. package/dist/sdk/runtime.d.mts.map +1 -1
  51. package/dist/sdk/runtime.mjs +10 -2
  52. package/dist/sdk/runtime.mjs.map +1 -1
  53. package/package.json +8 -14
  54. package/dist/util/omit-undefined.d.mts +0 -5
  55. package/dist/util/omit-undefined.d.mts.map +0 -1
  56. package/dist/util/omit-undefined.mjs +0 -8
  57. package/dist/util/omit-undefined.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.d.mts","names":[],"sources":["../../src/sdk/envelope.ts"],"mappings":";;;;;AA0BA;;;;;;cAAa,mBAAA,EAAmB,CAAA,CAAA,WAAA,CAAA,CAAA,CAAA,OAAA;;;;;;KAIpB,aAAA,GAAgB,CAAA,CAAE,KAAA,QAAa,mBAAA;AAAA,cAE9B,qBAAA,EAAqB,CAAA,CAAA,qBAAA,EAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAMtB,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,qBAAA;AAAA,cAgBhC,cAAA,EAAc,CAAA,CAAA,eAAA,CAAA,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6BtB,YAAA,GAAe,CAAA,CAAE,KAAA,QAAa,cAAA;AAAA,KAEvB,SAAA,GAAY,YAAA;AAAA,KAEZ,QAAA,WAAmB,SAAA,4BAC7B,CAAA,SAAU,SAAA,GAAY,OAAA,CAAQ,YAAA;EAAgB,IAAA,EAAM,CAAA;AAAA,KAAO,YAAA;AAAA,KAEjD,eAAA,WAA0B,SAAA,IAAa,QAAA,CAAS,CAAA"}
1
+ {"version":3,"file":"envelope.d.mts","names":[],"sources":["../../src/sdk/envelope.ts"],"mappings":"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"}
@@ -9,7 +9,6 @@ import { rageClickPayloadSchema } from "#sdk/plugins/payload/rage-click";
9
9
  import { replayChunkPayloadSchema } from "#sdk/plugins/payload/replay";
10
10
  import { envSchema, runtimeSchema } from "#sdk/runtime";
11
11
  //#region src/sdk/envelope.ts
12
- const envelopeVersion = z.union([z.literal(0)]);
13
12
  /**
14
13
  * Indicates how the sessionId was resolved on the server.
15
14
  *
@@ -23,13 +22,21 @@ const sessionSourceSchema = z.enum([
23
22
  "async_context",
24
23
  "fallback",
25
24
  "client"
26
- ]).optional();
25
+ ]).optional().meta({
26
+ id: "SessionSource",
27
+ title: "SessionSource",
28
+ description: "How the server resolved the sessionId for this envelope."
29
+ });
27
30
  const envelopeContextSchema = z.discriminatedUnion("runtime", [
28
31
  browserContextSchema,
29
32
  nextjsContextSchema,
30
33
  edgeContextSchema
31
- ]);
32
- const envelopeSchema = z.object({
34
+ ]).meta({
35
+ id: "EnvelopeContext",
36
+ title: "EnvelopeContext",
37
+ description: "Runtime-specific request context attached to every envelope."
38
+ });
39
+ const envelopeHeadersShape = {
33
40
  buildId: z.string(),
34
41
  clientTs: z.int(),
35
42
  context: envelopeContextSchema.optional(),
@@ -37,35 +44,71 @@ const envelopeSchema = z.object({
37
44
  producerVersion: z.string().optional(),
38
45
  releaseId: z.string().nullable(),
39
46
  runtime: runtimeSchema,
47
+ sdkStack: z.array(z.string()).optional(),
40
48
  sessionId: sessionIdSchema.nullable(),
41
49
  sessionSource: sessionSourceSchema,
42
50
  uuid: z.uuidv7(),
43
- v: envelopeVersion
44
- }).and(z.discriminatedUnion("type", [
45
- z.object({
46
- payload: errorEnvelopePayloadSchema,
47
- type: z.literal("error")
48
- }),
49
- z.object({
50
- payload: pageviewPayloadSchema,
51
- type: z.literal("pageview")
52
- }),
53
- z.object({
54
- payload: pageleavePayloadSchema,
55
- type: z.literal("pageleave")
56
- }),
57
- z.object({
58
- payload: uiEventPayloadSchema,
59
- type: z.literal("ui_event")
60
- }),
61
- z.object({
62
- payload: replayChunkPayloadSchema,
63
- type: z.literal("replay_chunk")
64
- }),
65
- z.object({
66
- payload: rageClickPayloadSchema,
67
- type: z.literal("rage_click")
68
- })
69
- ]));
51
+ v: z.literal(0)
52
+ };
53
+ const errorEnvelopeSchema = z.object({
54
+ ...envelopeHeadersShape,
55
+ type: z.literal("error"),
56
+ payload: errorEnvelopePayloadSchema
57
+ }).meta({
58
+ id: "ErrorEnvelope",
59
+ title: "ErrorEnvelope"
60
+ });
61
+ const pageviewEnvelopeSchema = z.object({
62
+ ...envelopeHeadersShape,
63
+ type: z.literal("pageview"),
64
+ payload: pageviewPayloadSchema
65
+ }).meta({
66
+ id: "PageviewEnvelope",
67
+ title: "PageviewEnvelope"
68
+ });
69
+ const pageleaveEnvelopeSchema = z.object({
70
+ ...envelopeHeadersShape,
71
+ type: z.literal("pageleave"),
72
+ payload: pageleavePayloadSchema
73
+ }).meta({
74
+ id: "PageleaveEnvelope",
75
+ title: "PageleaveEnvelope"
76
+ });
77
+ const uiEventEnvelopeSchema = z.object({
78
+ ...envelopeHeadersShape,
79
+ type: z.literal("ui_event"),
80
+ payload: uiEventPayloadSchema
81
+ }).meta({
82
+ id: "UiEventEnvelope",
83
+ title: "UiEventEnvelope"
84
+ });
85
+ const replayChunkEnvelopeSchema = z.object({
86
+ ...envelopeHeadersShape,
87
+ type: z.literal("replay_chunk"),
88
+ payload: replayChunkPayloadSchema
89
+ }).meta({
90
+ id: "ReplayChunkEnvelope",
91
+ title: "ReplayChunkEnvelope"
92
+ });
93
+ const rageClickEnvelopeSchema = z.object({
94
+ ...envelopeHeadersShape,
95
+ type: z.literal("rage_click"),
96
+ payload: rageClickPayloadSchema
97
+ }).meta({
98
+ id: "RageClickEnvelope",
99
+ title: "RageClickEnvelope"
100
+ });
101
+ const envelopeSchema = z.discriminatedUnion("type", [
102
+ errorEnvelopeSchema,
103
+ pageviewEnvelopeSchema,
104
+ pageleaveEnvelopeSchema,
105
+ uiEventEnvelopeSchema,
106
+ replayChunkEnvelopeSchema,
107
+ rageClickEnvelopeSchema
108
+ ]).meta({
109
+ id: "Envelope",
110
+ title: "Envelope",
111
+ description: "A single event envelope accepted by the collector."
112
+ });
70
113
  //#endregion
71
- export { envelopeContextSchema, envelopeSchema, sessionSourceSchema };
114
+ export { envelopeContextSchema, envelopeSchema, errorEnvelopeSchema, pageleaveEnvelopeSchema, pageviewEnvelopeSchema, rageClickEnvelopeSchema, replayChunkEnvelopeSchema, sessionSourceSchema, uiEventEnvelopeSchema };
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.mjs","names":[],"sources":["../../src/sdk/envelope.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { sessionIdSchema } from \"#data/session\";\nimport { browserContextSchema } from \"#sdk/plugins/context/browser\";\nimport { edgeContextSchema } from \"#sdk/plugins/context/edge\";\nimport { nextjsContextSchema } from \"#sdk/plugins/context/next\";\nimport { errorEnvelopePayloadSchema } from \"#sdk/plugins/payload/errors\";\nimport {\n pageleavePayloadSchema,\n pageviewPayloadSchema,\n uiEventPayloadSchema,\n} from \"#sdk/plugins/payload/page-events\";\nimport { rageClickPayloadSchema } from \"#sdk/plugins/payload/rage-click\";\nimport { replayChunkPayloadSchema } from \"#sdk/plugins/payload/replay\";\nimport { envSchema, runtimeSchema } from \"#sdk/runtime\";\n\nconst envelopeVersion = z.union([z.literal(0)]);\n\n/**\n * Indicates how the sessionId was resolved on the server.\n *\n * - \"header\": Extracted from x-interfere-request header (ideal case)\n * - \"async_context\": Retrieved from AsyncLocalStorage context\n * - \"fallback\": Generated as server-side fallback (breaks session continuity)\n * - \"client\": Session ID was set on the client (browser SDK)\n */\nexport const sessionSourceSchema = z\n .enum([\"header\", \"async_context\", \"fallback\", \"client\"])\n .optional();\n\nexport type SessionSource = z.infer<typeof sessionSourceSchema>;\n\nexport const envelopeContextSchema = z.discriminatedUnion(\"runtime\", [\n browserContextSchema,\n nextjsContextSchema,\n edgeContextSchema,\n]);\n\nexport type EnvelopeContext = z.infer<typeof envelopeContextSchema>;\n\nconst envelopeHeadersSchema = z.object({\n buildId: z.string(),\n clientTs: z.int(),\n context: envelopeContextSchema.optional(),\n environment: envSchema,\n producerVersion: z.string().optional(),\n releaseId: z.string().nullable(),\n runtime: runtimeSchema,\n sessionId: sessionIdSchema.nullable(),\n sessionSource: sessionSourceSchema,\n uuid: z.uuidv7(),\n v: envelopeVersion,\n});\n\nexport const envelopeSchema = envelopeHeadersSchema.and(\n z.discriminatedUnion(\"type\", [\n z.object({\n payload: errorEnvelopePayloadSchema,\n type: z.literal(\"error\"),\n }),\n z.object({\n payload: pageviewPayloadSchema,\n type: z.literal(\"pageview\"),\n }),\n z.object({\n payload: pageleavePayloadSchema,\n type: z.literal(\"pageleave\"),\n }),\n z.object({\n payload: uiEventPayloadSchema,\n type: z.literal(\"ui_event\"),\n }),\n z.object({\n payload: replayChunkPayloadSchema,\n type: z.literal(\"replay_chunk\"),\n }),\n z.object({\n payload: rageClickPayloadSchema,\n type: z.literal(\"rage_click\"),\n }),\n ])\n);\n\ntype EnvelopeBase = z.infer<typeof envelopeSchema>;\n\nexport type EventType = EnvelopeBase[\"type\"];\n\nexport type Envelope<T extends EventType | undefined = undefined> =\n T extends EventType ? Extract<EnvelopeBase, { type: T }> : EnvelopeBase;\n\nexport type EnvelopePayload<T extends EventType> = Envelope<T>[\"payload\"];\n"],"mappings":";;;;;;;;;;;AAgBA,MAAM,kBAAkB,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;;;;;;;;;AAU/C,MAAa,sBAAsB,EAChC,KAAK;CAAC;CAAU;CAAiB;CAAY;CAAS,CAAC,CACvD,UAAU;AAIb,MAAa,wBAAwB,EAAE,mBAAmB,WAAW;CACnE;CACA;CACA;CACD,CAAC;AAkBF,MAAa,iBAdiB,EAAE,OAAO;CACrC,SAAS,EAAE,QAAQ;CACnB,UAAU,EAAE,KAAK;CACjB,SAAS,sBAAsB,UAAU;CACzC,aAAa;CACb,iBAAiB,EAAE,QAAQ,CAAC,UAAU;CACtC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,SAAS;CACT,WAAW,gBAAgB,UAAU;CACrC,eAAe;CACf,MAAM,EAAE,QAAQ;CAChB,GAAG;CACJ,CAAC,CAEkD,IAClD,EAAE,mBAAmB,QAAQ;CAC3B,EAAE,OAAO;EACP,SAAS;EACT,MAAM,EAAE,QAAQ,QAAQ;EACzB,CAAC;CACF,EAAE,OAAO;EACP,SAAS;EACT,MAAM,EAAE,QAAQ,WAAW;EAC5B,CAAC;CACF,EAAE,OAAO;EACP,SAAS;EACT,MAAM,EAAE,QAAQ,YAAY;EAC7B,CAAC;CACF,EAAE,OAAO;EACP,SAAS;EACT,MAAM,EAAE,QAAQ,WAAW;EAC5B,CAAC;CACF,EAAE,OAAO;EACP,SAAS;EACT,MAAM,EAAE,QAAQ,eAAe;EAChC,CAAC;CACF,EAAE,OAAO;EACP,SAAS;EACT,MAAM,EAAE,QAAQ,aAAa;EAC9B,CAAC;CACH,CAAC,CACH"}
1
+ {"version":3,"file":"envelope.mjs","names":[],"sources":["../../src/sdk/envelope.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { sessionIdSchema } from \"#data/session\";\nimport { browserContextSchema } from \"#sdk/plugins/context/browser\";\nimport { edgeContextSchema } from \"#sdk/plugins/context/edge\";\nimport { nextjsContextSchema } from \"#sdk/plugins/context/next\";\nimport { errorEnvelopePayloadSchema } from \"#sdk/plugins/payload/errors\";\nimport {\n pageleavePayloadSchema,\n pageviewPayloadSchema,\n uiEventPayloadSchema,\n} from \"#sdk/plugins/payload/page-events\";\nimport { rageClickPayloadSchema } from \"#sdk/plugins/payload/rage-click\";\nimport { replayChunkPayloadSchema } from \"#sdk/plugins/payload/replay\";\nimport { envSchema, runtimeSchema } from \"#sdk/runtime\";\n\n/**\n * Indicates how the sessionId was resolved on the server.\n *\n * - \"header\": Extracted from x-interfere-request header (ideal case)\n * - \"async_context\": Retrieved from AsyncLocalStorage context\n * - \"fallback\": Generated as server-side fallback (breaks session continuity)\n * - \"client\": Session ID was set on the client (browser SDK)\n */\nexport const sessionSourceSchema = z\n .enum([\"header\", \"async_context\", \"fallback\", \"client\"])\n .optional()\n .meta({\n id: \"SessionSource\",\n title: \"SessionSource\",\n description: \"How the server resolved the sessionId for this envelope.\",\n });\n\nexport type SessionSource = z.infer<typeof sessionSourceSchema>;\n\nexport const envelopeContextSchema = z\n .discriminatedUnion(\"runtime\", [\n browserContextSchema,\n nextjsContextSchema,\n edgeContextSchema,\n ])\n .meta({\n id: \"EnvelopeContext\",\n title: \"EnvelopeContext\",\n description: \"Runtime-specific request context attached to every envelope.\",\n });\n\nexport type EnvelopeContext = z.infer<typeof envelopeContextSchema>;\n\nconst envelopeHeadersShape = {\n buildId: z.string(),\n clientTs: z.int(),\n context: envelopeContextSchema.optional(),\n environment: envSchema,\n producerVersion: z.string().optional(),\n releaseId: z.string().nullable(),\n runtime: runtimeSchema,\n sdkStack: z.array(z.string()).optional(),\n sessionId: sessionIdSchema.nullable(),\n sessionSource: sessionSourceSchema,\n uuid: z.uuidv7(),\n v: z.literal(0),\n} as const;\n\nexport const errorEnvelopeSchema = z\n .object({\n ...envelopeHeadersShape,\n type: z.literal(\"error\"),\n payload: errorEnvelopePayloadSchema,\n })\n .meta({ id: \"ErrorEnvelope\", title: \"ErrorEnvelope\" });\n\nexport const pageviewEnvelopeSchema = z\n .object({\n ...envelopeHeadersShape,\n type: z.literal(\"pageview\"),\n payload: pageviewPayloadSchema,\n })\n .meta({ id: \"PageviewEnvelope\", title: \"PageviewEnvelope\" });\n\nexport const pageleaveEnvelopeSchema = z\n .object({\n ...envelopeHeadersShape,\n type: z.literal(\"pageleave\"),\n payload: pageleavePayloadSchema,\n })\n .meta({ id: \"PageleaveEnvelope\", title: \"PageleaveEnvelope\" });\n\nexport const uiEventEnvelopeSchema = z\n .object({\n ...envelopeHeadersShape,\n type: z.literal(\"ui_event\"),\n payload: uiEventPayloadSchema,\n })\n .meta({ id: \"UiEventEnvelope\", title: \"UiEventEnvelope\" });\n\nexport const replayChunkEnvelopeSchema = z\n .object({\n ...envelopeHeadersShape,\n type: z.literal(\"replay_chunk\"),\n payload: replayChunkPayloadSchema,\n })\n .meta({ id: \"ReplayChunkEnvelope\", title: \"ReplayChunkEnvelope\" });\n\nexport const rageClickEnvelopeSchema = z\n .object({\n ...envelopeHeadersShape,\n type: z.literal(\"rage_click\"),\n payload: rageClickPayloadSchema,\n })\n .meta({ id: \"RageClickEnvelope\", title: \"RageClickEnvelope\" });\n\nexport const envelopeSchema = z\n .discriminatedUnion(\"type\", [\n errorEnvelopeSchema,\n pageviewEnvelopeSchema,\n pageleaveEnvelopeSchema,\n uiEventEnvelopeSchema,\n replayChunkEnvelopeSchema,\n rageClickEnvelopeSchema,\n ])\n .meta({\n id: \"Envelope\",\n title: \"Envelope\",\n description: \"A single event envelope accepted by the collector.\",\n });\n\ntype EnvelopeBase = z.infer<typeof envelopeSchema>;\n\nexport type EventType = EnvelopeBase[\"type\"];\n\nexport type Envelope<T extends EventType | undefined = undefined> =\n T extends EventType ? Extract<EnvelopeBase, { type: T }> : EnvelopeBase;\n\nexport type EnvelopePayload<T extends EventType> = Envelope<T>[\"payload\"];\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAwBA,MAAa,sBAAsB,EAChC,KAAK;CAAC;CAAU;CAAiB;CAAY;CAAS,CAAC,CACvD,UAAU,CACV,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACd,CAAC;AAIJ,MAAa,wBAAwB,EAClC,mBAAmB,WAAW;CAC7B;CACA;CACA;CACD,CAAC,CACD,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACd,CAAC;AAIJ,MAAM,uBAAuB;CAC3B,SAAS,EAAE,QAAQ;CACnB,UAAU,EAAE,KAAK;CACjB,SAAS,sBAAsB,UAAU;CACzC,aAAa;CACb,iBAAiB,EAAE,QAAQ,CAAC,UAAU;CACtC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,SAAS;CACT,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CACxC,WAAW,gBAAgB,UAAU;CACrC,eAAe;CACf,MAAM,EAAE,QAAQ;CAChB,GAAG,EAAE,QAAQ,EAAE;CAChB;AAED,MAAa,sBAAsB,EAChC,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,QAAQ;CACxB,SAAS;CACV,CAAC,CACD,KAAK;CAAE,IAAI;CAAiB,OAAO;CAAiB,CAAC;AAExD,MAAa,yBAAyB,EACnC,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,WAAW;CAC3B,SAAS;CACV,CAAC,CACD,KAAK;CAAE,IAAI;CAAoB,OAAO;CAAoB,CAAC;AAE9D,MAAa,0BAA0B,EACpC,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,YAAY;CAC5B,SAAS;CACV,CAAC,CACD,KAAK;CAAE,IAAI;CAAqB,OAAO;CAAqB,CAAC;AAEhE,MAAa,wBAAwB,EAClC,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,WAAW;CAC3B,SAAS;CACV,CAAC,CACD,KAAK;CAAE,IAAI;CAAmB,OAAO;CAAmB,CAAC;AAE5D,MAAa,4BAA4B,EACtC,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,eAAe;CAC/B,SAAS;CACV,CAAC,CACD,KAAK;CAAE,IAAI;CAAuB,OAAO;CAAuB,CAAC;AAEpE,MAAa,0BAA0B,EACpC,OAAO;CACN,GAAG;CACH,MAAM,EAAE,QAAQ,aAAa;CAC7B,SAAS;CACV,CAAC,CACD,KAAK;CAAE,IAAI;CAAqB,OAAO;CAAqB,CAAC;AAEhE,MAAa,iBAAiB,EAC3B,mBAAmB,QAAQ;CAC1B;CACA;CACA;CACA;CACA;CACA;CACD,CAAC,CACD,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACd,CAAC"}
@@ -1,16 +1,96 @@
1
+ import { IngestedFrame } from "#data/frame";
1
2
  import { ErrorMechanism, ExceptionValue } from "#sdk/plugins/payload/errors";
2
3
 
3
4
  //#region src/sdk/errors.d.ts
4
5
  /**
5
- * True when the root exception has at least one stack frame whose `fileName` is
6
- * a browser-extension script URL. Covers extension-only stacks, extension
7
- * interceptors (extension frames above app), and app errors whose stack still
8
- * includes extension code (e.g. hydration) — stacks with no filenames are
9
- * unchanged (returns false).
6
+ * Structured taxonomy of capture sources, tagged onto each
7
+ * `ErrorMechanism.type`. Follows the `auto.<surface>.<library>.<method>`
8
+ * convention Sentry also uses, so downstream analytics / classification can
9
+ * group on common prefixes:
10
+ *
11
+ * `auto.browser.*` — captured by SDK global handlers in the browser
12
+ * `auto.function.*` — captured by SDK functions (boundaries, callbacks,
13
+ * server wrappers)
14
+ *
15
+ * Leaves (`.onerror`, `.error_boundary`, `.on_request_error`, …) identify
16
+ * the specific capture site, which lets the agent's skill classifier reason
17
+ * about what "kind" of event this is without string-matching loose names.
18
+ */
19
+ declare const MECHANISM_TYPE: {
20
+ readonly browser: {
21
+ readonly onerror: "auto.browser.global_handlers.onerror";
22
+ readonly onunhandledrejection: "auto.browser.global_handlers.onunhandledrejection";
23
+ readonly consoleError: "auto.browser.console.error";
24
+ };
25
+ readonly react: {
26
+ readonly errorBoundary: "auto.function.react.error_boundary";
27
+ readonly captureBoundary: "auto.function.react.capture_boundary";
28
+ readonly caughtError: "auto.function.react.caught_error";
29
+ readonly uncaughtError: "auto.function.react.uncaught_error";
30
+ readonly recoverableError: "auto.function.react.recoverable_error";
31
+ };
32
+ readonly nextjs: {
33
+ readonly onRequestError: "auto.function.nextjs.on_request_error";
34
+ readonly captureError: "auto.function.nextjs.capture_error";
35
+ };
36
+ };
37
+ /**
38
+ * True when any exception in the cause chain has at least one stack frame
39
+ * whose `fileName` is a browser-extension script URL. Covers extension-only
40
+ * stacks, extension interceptors (extension frames above app), app errors
41
+ * whose stack still includes extension code (e.g. hydration), and errors
42
+ * whose outer throw is app code but whose inner `.cause` originated in an
43
+ * extension. Stacks with no filenames are unchanged (returns false).
10
44
  */
11
45
  declare function shouldDropBrowserExtensionNoise(exceptions: readonly ExceptionValue[]): boolean;
46
+ /**
47
+ * True when no frame across the full cause chain carries any `fileName`.
48
+ *
49
+ * Such stacks are structurally uninvestigatable: they come from inline
50
+ * `<script>` blocks (`at <anonymous>:N:M`), `eval()` / `new Function()`,
51
+ * CORS-masked cross-origin scripts (`"Script error."`), or browser-internal
52
+ * code with no URL. No source map can resolve them, no repo lookup can find
53
+ * them, and the agent has nothing to reason over. Dropping at capture time
54
+ * prevents them from dominating ingest volume.
55
+ */
56
+ declare function shouldDropUnresolvableStack(exceptions: readonly ExceptionValue[]): boolean;
57
+ /**
58
+ * Normalizes an `Error.stack` string before feeding it to the stack parser.
59
+ *
60
+ * - Truncates each line to {@link MAX_STACK_LINE_LENGTH} to prevent ReDoS on
61
+ * pathological inputs (a single frame with a 100 KiB URL can stall the
62
+ * main thread for seconds in a regex-based parser).
63
+ * - Strips the trailing `(error: *)` suffix some webpack builds emit.
64
+ */
65
+ declare function preprocessStack(stack: string): string;
66
+ /**
67
+ * Parses a React `errorInfo.componentStack` string into synthetic frames.
68
+ *
69
+ * React produces different formats across versions:
70
+ * - React 16–18 legacy: ` in ComponentName`
71
+ * ` in ComponentName (created by Parent)`
72
+ * - React 19 owner stacks: ` at ComponentName`
73
+ * ` at ComponentName (file.tsx:10:5)`
74
+ *
75
+ * Each line becomes one frame with the component as `functionName`. When file
76
+ * positions are present (React 19), they're preserved.
77
+ */
78
+ declare function parseReactComponentStack(componentStack: string): IngestedFrame[];
79
+ /**
80
+ * Coerces any thrown value into an `Error` instance, preferring a nested
81
+ * `Error` inside a plain-object rejection over a stringified fallback.
82
+ *
83
+ * Motivated by the common `Promise.reject({ error: realErr })` pattern
84
+ * (tRPC, GraphQL clients, some fetch wrappers). Without this, the captured
85
+ * exception would be `new Error("[object Object]")` and the nested Error's
86
+ * stack/message would be lost entirely.
87
+ *
88
+ * When multiple candidate Error values exist on the object, the first one
89
+ * found (in declaration order) wins. `cause` is preferred if present, since
90
+ * it's the documented ES2022 convention.
91
+ */
12
92
  declare function toError(error: unknown): Error;
13
93
  declare function toExceptions(error: Error, mechanism: ErrorMechanism): ExceptionValue[];
14
94
  declare function extractFilenameFromStack(stack: string): string | null;
15
95
  //#endregion
16
- export { extractFilenameFromStack, shouldDropBrowserExtensionNoise, toError, toExceptions };
96
+ export { MECHANISM_TYPE, extractFilenameFromStack, parseReactComponentStack, preprocessStack, shouldDropBrowserExtensionNoise, shouldDropUnresolvableStack, toError, toExceptions };
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.mts","names":[],"sources":["../../src/sdk/errors.ts"],"mappings":";;;;;AA8BA;;;;;iBAAgB,+BAAA,CACd,UAAA,WAAqB,cAAA;AAAA,iBAkBP,OAAA,CAAQ,KAAA,YAAiB,KAAA;AAAA,iBAYzB,YAAA,CACd,KAAA,EAAO,KAAA,EACP,SAAA,EAAW,cAAA,GACV,cAAA;AAAA,iBAwDa,wBAAA,CAAyB,KAAA"}
1
+ {"version":3,"file":"errors.d.mts","names":[],"sources":["../../src/sdk/errors.ts"],"mappings":";;;;;;AAsBA;;;;;;;;;;;;cAAa,cAAA;EAAA;;;;;;;;;;;;;;;;;;;;;AAuJb;;;;iBAtGgB,+BAAA,CACd,UAAA,WAAqB,cAAA;AAkJvB;;;;;AA0BA;;;;;AA1BA,iBAjIgB,2BAAA,CACd,UAAA,WAAqB,cAAA;;;;;;;;;iBA4CP,eAAA,CAAgB,KAAA;AA8MhC;;;;;;;;;;;;AAAA,iBAvKgB,wBAAA,CACd,cAAA,WACC,aAAA;;;;;;;;;;;;;;iBA2Ca,OAAA,CAAQ,KAAA,YAAiB,KAAA;AAAA,iBA0BzB,YAAA,CACd,KAAA,EAAO,KAAA,EACP,SAAA,EAAW,cAAA,GACV,cAAA;AAAA,iBA6Fa,wBAAA,CAAyB,KAAA"}
@@ -1,36 +1,178 @@
1
1
  import { parse } from "error-stack-parser-es";
2
2
  //#region src/sdk/errors.ts
3
- /** URL schemes used by browser extensions in stack frame `fileName` values. */
3
+ /**
4
+ * Structured taxonomy of capture sources, tagged onto each
5
+ * `ErrorMechanism.type`. Follows the `auto.<surface>.<library>.<method>`
6
+ * convention Sentry also uses, so downstream analytics / classification can
7
+ * group on common prefixes:
8
+ *
9
+ * `auto.browser.*` — captured by SDK global handlers in the browser
10
+ * `auto.function.*` — captured by SDK functions (boundaries, callbacks,
11
+ * server wrappers)
12
+ *
13
+ * Leaves (`.onerror`, `.error_boundary`, `.on_request_error`, …) identify
14
+ * the specific capture site, which lets the agent's skill classifier reason
15
+ * about what "kind" of event this is without string-matching loose names.
16
+ */
17
+ const MECHANISM_TYPE = {
18
+ browser: {
19
+ onerror: "auto.browser.global_handlers.onerror",
20
+ onunhandledrejection: "auto.browser.global_handlers.onunhandledrejection",
21
+ consoleError: "auto.browser.console.error"
22
+ },
23
+ react: {
24
+ errorBoundary: "auto.function.react.error_boundary",
25
+ captureBoundary: "auto.function.react.capture_boundary",
26
+ caughtError: "auto.function.react.caught_error",
27
+ uncaughtError: "auto.function.react.uncaught_error",
28
+ recoverableError: "auto.function.react.recoverable_error"
29
+ },
30
+ nextjs: {
31
+ onRequestError: "auto.function.nextjs.on_request_error",
32
+ captureError: "auto.function.nextjs.capture_error"
33
+ }
34
+ };
35
+ /**
36
+ * URL schemes used by browser extensions in stack frame `fileName` values.
37
+ *
38
+ * `webkit-masked-url://` is Safari's opaque scheme introduced to mask the
39
+ * origin of content scripts under ITP — it serves the same purpose as the
40
+ * `*-extension://` schemes from a noise-filtering perspective.
41
+ */
4
42
  const BROWSER_EXTENSION_SCRIPT_URL_PREFIXES = [
5
43
  "chrome-extension://",
6
44
  "moz-extension://",
7
45
  "safari-web-extension://",
8
46
  "safari-extension://",
9
- "ms-browser-extension://"
47
+ "ms-browser-extension://",
48
+ "webkit-masked-url://"
10
49
  ];
11
50
  function isExtensionOriginated({ fileName }) {
12
51
  return BROWSER_EXTENSION_SCRIPT_URL_PREFIXES.some((prefix) => fileName?.startsWith(prefix) ?? false);
13
52
  }
14
53
  /**
15
- * True when the root exception has at least one stack frame whose `fileName` is
16
- * a browser-extension script URL. Covers extension-only stacks, extension
17
- * interceptors (extension frames above app), and app errors whose stack still
18
- * includes extension code (e.g. hydration) stacks with no filenames are
19
- * unchanged (returns false).
54
+ * True when any exception in the cause chain has at least one stack frame
55
+ * whose `fileName` is a browser-extension script URL. Covers extension-only
56
+ * stacks, extension interceptors (extension frames above app), app errors
57
+ * whose stack still includes extension code (e.g. hydration), and errors
58
+ * whose outer throw is app code but whose inner `.cause` originated in an
59
+ * extension. Stacks with no filenames are unchanged (returns false).
20
60
  */
21
61
  function shouldDropBrowserExtensionNoise(exceptions) {
22
- const frames = exceptions[0]?.frames;
23
- if (!frames?.length) return false;
24
- return frames.some(isExtensionOriginated);
62
+ return exceptions.some((exception) => exception.frames?.some(isExtensionOriginated) ?? false);
63
+ }
64
+ /**
65
+ * True when no frame across the full cause chain carries any `fileName`.
66
+ *
67
+ * Such stacks are structurally uninvestigatable: they come from inline
68
+ * `<script>` blocks (`at <anonymous>:N:M`), `eval()` / `new Function()`,
69
+ * CORS-masked cross-origin scripts (`"Script error."`), or browser-internal
70
+ * code with no URL. No source map can resolve them, no repo lookup can find
71
+ * them, and the agent has nothing to reason over. Dropping at capture time
72
+ * prevents them from dominating ingest volume.
73
+ */
74
+ function shouldDropUnresolvableStack(exceptions) {
75
+ for (const exception of exceptions) {
76
+ const frames = exception.frames;
77
+ if (!frames?.length) continue;
78
+ if (frames.some((frame) => typeof frame.fileName === "string")) return false;
79
+ }
80
+ return true;
25
81
  }
26
82
  const MAX_CAUSE_DEPTH = 5;
83
+ /**
84
+ * Upper bound for any single stack-trace line. Pathologically long lines can
85
+ * trigger catastrophic backtracking in regex-based stack parsers (the
86
+ * `error-stack-parser-es` library we depend on is regex-driven). Sentry uses
87
+ * the same 1 KiB ceiling for the same reason.
88
+ */
89
+ const MAX_STACK_LINE_LENGTH = 1024;
90
+ /**
91
+ * Webpack emits `(error: *)` wrappers around stack frames under certain
92
+ * devtool configurations. The pattern is always a trailing suffix; trimming
93
+ * it lets the downstream parser see a clean `at fn (file:L:C)`.
94
+ */
95
+ const WEBPACK_ERROR_WRAPPER_RE = /\s*\(error:\s+\*\)$/;
27
96
  const PAREN_FILE_RE = /\((.+?)(?::\d+){1,2}\)/;
28
97
  const AT_FILE_RE = /at\s+(.+?)(?::\d+){1,2}$/;
29
98
  const SPIDERMONKEY_RE = /(?:^|@)((?:https?:\/\/|\/).+?)(?::\d+){1,2}$/;
30
99
  const BARE_FILE_RE = /(?:^|@)(.+?)(?::\d+){1,2}$/;
100
+ /**
101
+ * Normalizes an `Error.stack` string before feeding it to the stack parser.
102
+ *
103
+ * - Truncates each line to {@link MAX_STACK_LINE_LENGTH} to prevent ReDoS on
104
+ * pathological inputs (a single frame with a 100 KiB URL can stall the
105
+ * main thread for seconds in a regex-based parser).
106
+ * - Strips the trailing `(error: *)` suffix some webpack builds emit.
107
+ */
108
+ function preprocessStack(stack) {
109
+ if (!stack) return stack;
110
+ const out = [];
111
+ for (const rawLine of stack.split("\n")) {
112
+ const line = rawLine.length > MAX_STACK_LINE_LENGTH ? rawLine.slice(0, MAX_STACK_LINE_LENGTH) : rawLine;
113
+ out.push(line.replace(WEBPACK_ERROR_WRAPPER_RE, ""));
114
+ }
115
+ return out.join("\n");
116
+ }
117
+ /**
118
+ * Matches one React component-stack line. Captures:
119
+ * 1. component name
120
+ * 2. optional file name (required to have a line number, to avoid matching
121
+ * "(created by Parent)" annotations emitted by React 16-18)
122
+ * 3. optional line number
123
+ * 4. optional column number
124
+ */
125
+ const COMPONENT_STACK_RE = /^(?:in|at)\s+([^\s(]+)(?:\s+\(([^\s:)]+):(\d+)(?::(\d+))?\))?/;
126
+ /**
127
+ * Parses a React `errorInfo.componentStack` string into synthetic frames.
128
+ *
129
+ * React produces different formats across versions:
130
+ * - React 16–18 legacy: ` in ComponentName`
131
+ * ` in ComponentName (created by Parent)`
132
+ * - React 19 owner stacks: ` at ComponentName`
133
+ * ` at ComponentName (file.tsx:10:5)`
134
+ *
135
+ * Each line becomes one frame with the component as `functionName`. When file
136
+ * positions are present (React 19), they're preserved.
137
+ */
138
+ function parseReactComponentStack(componentStack) {
139
+ const frames = [];
140
+ for (const rawLine of componentStack.split("\n")) {
141
+ const line = rawLine.trim();
142
+ if (!line) continue;
143
+ const match = COMPONENT_STACK_RE.exec(line);
144
+ if (!match) continue;
145
+ const [, name, fileName, lineStr, colStr] = match;
146
+ if (!name) continue;
147
+ const frame = { functionName: name };
148
+ if (fileName) frame.fileName = fileName;
149
+ if (lineStr) frame.lineNumber = Number(lineStr);
150
+ if (colStr) frame.columnNumber = Number(colStr);
151
+ frames.push(frame);
152
+ }
153
+ return frames;
154
+ }
155
+ /**
156
+ * Coerces any thrown value into an `Error` instance, preferring a nested
157
+ * `Error` inside a plain-object rejection over a stringified fallback.
158
+ *
159
+ * Motivated by the common `Promise.reject({ error: realErr })` pattern
160
+ * (tRPC, GraphQL clients, some fetch wrappers). Without this, the captured
161
+ * exception would be `new Error("[object Object]")` and the nested Error's
162
+ * stack/message would be lost entirely.
163
+ *
164
+ * When multiple candidate Error values exist on the object, the first one
165
+ * found (in declaration order) wins. `cause` is preferred if present, since
166
+ * it's the documented ES2022 convention.
167
+ */
31
168
  function toError(error) {
32
169
  if (error instanceof Error) return error;
33
170
  if (typeof error === "string") return new Error(error);
171
+ if (error !== null && typeof error === "object") {
172
+ const record = error;
173
+ if (record["cause"] instanceof Error) return record["cause"];
174
+ for (const value of Object.values(record)) if (value instanceof Error) return value;
175
+ }
34
176
  return new Error(String(error));
35
177
  }
36
178
  function toExceptions(error, mechanism) {
@@ -42,12 +184,32 @@ function toExceptions(error, mechanism) {
42
184
  type: current.name,
43
185
  value: current.message,
44
186
  mechanism: depth === 0 ? mechanism : void 0,
45
- frames: parse(current, { allowEmpty: true }).map((frame) => normalizeFrame(frame, debugIdMap))
187
+ frames: framesFromError(current, debugIdMap)
46
188
  });
47
189
  current = current.cause instanceof Error ? current.cause : void 0;
48
190
  }
49
191
  return exceptions;
50
192
  }
193
+ /**
194
+ * Extracts and normalizes frames from an Error, applying:
195
+ * 1. `preprocessStack` — line truncation and webpack-wrapper stripping.
196
+ * 2. `error-stack-parser-es` — engine-specific stack parsing.
197
+ * 3. `framesToPop` — honoring the documented Node convention where an
198
+ * Error constructor sets this field to instruct callers to drop N top
199
+ * frames (used by invariant libraries, assertion wrappers, etc.).
200
+ */
201
+ function framesFromError(error, debugIdMap) {
202
+ const rawStack = error.stack ?? "";
203
+ const cleaned = preprocessStack(rawStack);
204
+ let frames = parse(cleaned === rawStack ? error : {
205
+ name: error.name,
206
+ message: error.message,
207
+ stack: cleaned
208
+ }, { allowEmpty: true }).map((frame) => normalizeFrame(frame, debugIdMap));
209
+ const framesToPop = error.framesToPop;
210
+ if (typeof framesToPop === "number" && framesToPop > 0) frames = frames.slice(Math.floor(framesToPop));
211
+ return frames;
212
+ }
51
213
  let cachedDebugIdMap;
52
214
  let cachedDebugIdCount = 0;
53
215
  function getDebugIdMap() {
@@ -88,4 +250,4 @@ function normalizeFrame(frame, debugIdMap) {
88
250
  };
89
251
  }
90
252
  //#endregion
91
- export { extractFilenameFromStack, shouldDropBrowserExtensionNoise, toError, toExceptions };
253
+ export { MECHANISM_TYPE, extractFilenameFromStack, parseReactComponentStack, preprocessStack, shouldDropBrowserExtensionNoise, shouldDropUnresolvableStack, toError, toExceptions };
@@ -1 +1 @@
1
- {"version":3,"file":"errors.mjs","names":[],"sources":["../../src/sdk/errors.ts"],"sourcesContent":["import { parse } from \"error-stack-parser-es\";\n\nimport type { IngestedFrame } from \"#data/frame\";\nimport type {\n ErrorMechanism,\n ExceptionValue,\n} from \"#sdk/plugins/payload/errors\";\n\n/** URL schemes used by browser extensions in stack frame `fileName` values. */\nconst BROWSER_EXTENSION_SCRIPT_URL_PREFIXES: readonly string[] = [\n \"chrome-extension://\",\n \"moz-extension://\",\n \"safari-web-extension://\",\n \"safari-extension://\",\n \"ms-browser-extension://\",\n];\n\nfunction isExtensionOriginated({ fileName }: IngestedFrame): boolean {\n return BROWSER_EXTENSION_SCRIPT_URL_PREFIXES.some(\n (prefix) => fileName?.startsWith(prefix) ?? false\n );\n}\n\n/**\n * True when the root exception has at least one stack frame whose `fileName` is\n * a browser-extension script URL. Covers extension-only stacks, extension\n * interceptors (extension frames above app), and app errors whose stack still\n * includes extension code (e.g. hydration) — stacks with no filenames are\n * unchanged (returns false).\n */\nexport function shouldDropBrowserExtensionNoise(\n exceptions: readonly ExceptionValue[]\n): boolean {\n const frames = exceptions[0]?.frames;\n\n if (!frames?.length) {\n return false;\n }\n\n return frames.some(isExtensionOriginated);\n}\n\nconst MAX_CAUSE_DEPTH = 5;\n\nconst PAREN_FILE_RE = /\\((.+?)(?::\\d+){1,2}\\)/;\nconst AT_FILE_RE = /at\\s+(.+?)(?::\\d+){1,2}$/;\nconst SPIDERMONKEY_RE = /(?:^|@)((?:https?:\\/\\/|\\/).+?)(?::\\d+){1,2}$/;\nconst BARE_FILE_RE = /(?:^|@)(.+?)(?::\\d+){1,2}$/;\n\nexport function toError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n\n if (typeof error === \"string\") {\n return new Error(error);\n }\n\n return new Error(String(error));\n}\n\nexport function toExceptions(\n error: Error,\n mechanism: ErrorMechanism\n): ExceptionValue[] {\n const debugIdMap = getDebugIdMap();\n const exceptions: ExceptionValue[] = [];\n let current: Error | undefined = error;\n\n for (let depth = 0; current && depth < MAX_CAUSE_DEPTH; depth += 1) {\n exceptions.push({\n type: current.name,\n value: current.message,\n mechanism: depth === 0 ? mechanism : undefined,\n frames: parse(current, { allowEmpty: true }).map((frame) =>\n normalizeFrame(frame, debugIdMap)\n ),\n });\n\n current = current.cause instanceof Error ? current.cause : undefined;\n }\n\n return exceptions;\n}\n\nlet cachedDebugIdMap: Map<string, string> | undefined;\nlet cachedDebugIdCount = 0;\n\nfunction getDebugIdMap(): Map<string, string> {\n const registry = (globalThis as Record<string, unknown>)[\"_debugIds\"] as\n | Record<string, string>\n | undefined;\n\n if (!registry) {\n return new Map();\n }\n\n const entries = Object.keys(registry);\n if (cachedDebugIdMap && entries.length === cachedDebugIdCount) {\n return cachedDebugIdMap;\n }\n\n const map = new Map<string, string>();\n for (const stackKey of entries) {\n const debugId = registry[stackKey];\n if (!debugId) {\n continue;\n }\n\n const filename = extractFilenameFromStack(stackKey);\n if (filename) {\n map.set(filename, debugId);\n }\n }\n\n cachedDebugIdMap = map;\n cachedDebugIdCount = entries.length;\n return map;\n}\n\nexport function extractFilenameFromStack(stack: string): string | null {\n const lines = stack.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i];\n if (!line) {\n continue;\n }\n const match =\n line.match(PAREN_FILE_RE) ??\n line.match(AT_FILE_RE) ??\n line.match(SPIDERMONKEY_RE) ??\n line.match(BARE_FILE_RE);\n\n if (match?.[1]) {\n return match[1].trim();\n }\n }\n return null;\n}\n\nfunction normalizeFrame(\n frame: {\n fileName?: unknown;\n functionName?: unknown;\n lineNumber?: unknown;\n columnNumber?: unknown;\n source?: unknown;\n },\n debugIdMap: Map<string, string>\n): IngestedFrame {\n const fileName =\n typeof frame.fileName === \"string\" ? frame.fileName : undefined;\n\n return {\n fileName,\n functionName:\n typeof frame.functionName === \"string\" ? frame.functionName : undefined,\n lineNumber:\n typeof frame.lineNumber === \"number\" ? frame.lineNumber : undefined,\n columnNumber:\n typeof frame.columnNumber === \"number\" ? frame.columnNumber : undefined,\n source: typeof frame.source === \"string\" ? frame.source : undefined,\n debugId: fileName ? debugIdMap.get(fileName) : undefined,\n };\n}\n"],"mappings":";;;AASA,MAAM,wCAA2D;CAC/D;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,sBAAsB,EAAE,YAAoC;AACnE,QAAO,sCAAsC,MAC1C,WAAW,UAAU,WAAW,OAAO,IAAI,MAC7C;;;;;;;;;AAUH,SAAgB,gCACd,YACS;CACT,MAAM,SAAS,WAAW,IAAI;AAE9B,KAAI,CAAC,QAAQ,OACX,QAAO;AAGT,QAAO,OAAO,KAAK,sBAAsB;;AAG3C,MAAM,kBAAkB;AAExB,MAAM,gBAAgB;AACtB,MAAM,aAAa;AACnB,MAAM,kBAAkB;AACxB,MAAM,eAAe;AAErB,SAAgB,QAAQ,OAAuB;AAC7C,KAAI,iBAAiB,MACnB,QAAO;AAGT,KAAI,OAAO,UAAU,SACnB,QAAO,IAAI,MAAM,MAAM;AAGzB,QAAO,IAAI,MAAM,OAAO,MAAM,CAAC;;AAGjC,SAAgB,aACd,OACA,WACkB;CAClB,MAAM,aAAa,eAAe;CAClC,MAAM,aAA+B,EAAE;CACvC,IAAI,UAA6B;AAEjC,MAAK,IAAI,QAAQ,GAAG,WAAW,QAAQ,iBAAiB,SAAS,GAAG;AAClE,aAAW,KAAK;GACd,MAAM,QAAQ;GACd,OAAO,QAAQ;GACf,WAAW,UAAU,IAAI,YAAY,KAAA;GACrC,QAAQ,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC,CAAC,KAAK,UAChD,eAAe,OAAO,WAAW,CAClC;GACF,CAAC;AAEF,YAAU,QAAQ,iBAAiB,QAAQ,QAAQ,QAAQ,KAAA;;AAG7D,QAAO;;AAGT,IAAI;AACJ,IAAI,qBAAqB;AAEzB,SAAS,gBAAqC;CAC5C,MAAM,WAAY,WAAuC;AAIzD,KAAI,CAAC,SACH,wBAAO,IAAI,KAAK;CAGlB,MAAM,UAAU,OAAO,KAAK,SAAS;AACrC,KAAI,oBAAoB,QAAQ,WAAW,mBACzC,QAAO;CAGT,MAAM,sBAAM,IAAI,KAAqB;AACrC,MAAK,MAAM,YAAY,SAAS;EAC9B,MAAM,UAAU,SAAS;AACzB,MAAI,CAAC,QACH;EAGF,MAAM,WAAW,yBAAyB,SAAS;AACnD,MAAI,SACF,KAAI,IAAI,UAAU,QAAQ;;AAI9B,oBAAmB;AACnB,sBAAqB,QAAQ;AAC7B,QAAO;;AAGT,SAAgB,yBAAyB,OAA8B;CACrE,MAAM,QAAQ,MAAM,MAAM,KAAK;AAC/B,MAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;EAC1C,MAAM,OAAO,MAAM;AACnB,MAAI,CAAC,KACH;EAEF,MAAM,QACJ,KAAK,MAAM,cAAc,IACzB,KAAK,MAAM,WAAW,IACtB,KAAK,MAAM,gBAAgB,IAC3B,KAAK,MAAM,aAAa;AAE1B,MAAI,QAAQ,GACV,QAAO,MAAM,GAAG,MAAM;;AAG1B,QAAO;;AAGT,SAAS,eACP,OAOA,YACe;CACf,MAAM,WACJ,OAAO,MAAM,aAAa,WAAW,MAAM,WAAW,KAAA;AAExD,QAAO;EACL;EACA,cACE,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe,KAAA;EAChE,YACE,OAAO,MAAM,eAAe,WAAW,MAAM,aAAa,KAAA;EAC5D,cACE,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe,KAAA;EAChE,QAAQ,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS,KAAA;EAC1D,SAAS,WAAW,WAAW,IAAI,SAAS,GAAG,KAAA;EAChD"}
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../../src/sdk/errors.ts"],"sourcesContent":["import { parse } from \"error-stack-parser-es\";\n\nimport type { IngestedFrame } from \"#data/frame\";\nimport type {\n ErrorMechanism,\n ExceptionValue,\n} from \"#sdk/plugins/payload/errors\";\n\n/**\n * Structured taxonomy of capture sources, tagged onto each\n * `ErrorMechanism.type`. Follows the `auto.<surface>.<library>.<method>`\n * convention Sentry also uses, so downstream analytics / classification can\n * group on common prefixes:\n *\n * `auto.browser.*` — captured by SDK global handlers in the browser\n * `auto.function.*` — captured by SDK functions (boundaries, callbacks,\n * server wrappers)\n *\n * Leaves (`.onerror`, `.error_boundary`, `.on_request_error`, …) identify\n * the specific capture site, which lets the agent's skill classifier reason\n * about what \"kind\" of event this is without string-matching loose names.\n */\nexport const MECHANISM_TYPE = {\n browser: {\n onerror: \"auto.browser.global_handlers.onerror\",\n onunhandledrejection: \"auto.browser.global_handlers.onunhandledrejection\",\n consoleError: \"auto.browser.console.error\",\n },\n react: {\n errorBoundary: \"auto.function.react.error_boundary\",\n captureBoundary: \"auto.function.react.capture_boundary\",\n caughtError: \"auto.function.react.caught_error\",\n uncaughtError: \"auto.function.react.uncaught_error\",\n recoverableError: \"auto.function.react.recoverable_error\",\n },\n nextjs: {\n onRequestError: \"auto.function.nextjs.on_request_error\",\n captureError: \"auto.function.nextjs.capture_error\",\n },\n} as const;\n\n/**\n * URL schemes used by browser extensions in stack frame `fileName` values.\n *\n * `webkit-masked-url://` is Safari's opaque scheme introduced to mask the\n * origin of content scripts under ITP — it serves the same purpose as the\n * `*-extension://` schemes from a noise-filtering perspective.\n */\nconst BROWSER_EXTENSION_SCRIPT_URL_PREFIXES: readonly string[] = [\n \"chrome-extension://\",\n \"moz-extension://\",\n \"safari-web-extension://\",\n \"safari-extension://\",\n \"ms-browser-extension://\",\n \"webkit-masked-url://\",\n];\n\nfunction isExtensionOriginated({ fileName }: IngestedFrame): boolean {\n return BROWSER_EXTENSION_SCRIPT_URL_PREFIXES.some(\n (prefix) => fileName?.startsWith(prefix) ?? false\n );\n}\n\n/**\n * True when any exception in the cause chain has at least one stack frame\n * whose `fileName` is a browser-extension script URL. Covers extension-only\n * stacks, extension interceptors (extension frames above app), app errors\n * whose stack still includes extension code (e.g. hydration), and errors\n * whose outer throw is app code but whose inner `.cause` originated in an\n * extension. Stacks with no filenames are unchanged (returns false).\n */\nexport function shouldDropBrowserExtensionNoise(\n exceptions: readonly ExceptionValue[]\n): boolean {\n return exceptions.some(\n (exception) => exception.frames?.some(isExtensionOriginated) ?? false\n );\n}\n\n/**\n * True when no frame across the full cause chain carries any `fileName`.\n *\n * Such stacks are structurally uninvestigatable: they come from inline\n * `<script>` blocks (`at <anonymous>:N:M`), `eval()` / `new Function()`,\n * CORS-masked cross-origin scripts (`\"Script error.\"`), or browser-internal\n * code with no URL. No source map can resolve them, no repo lookup can find\n * them, and the agent has nothing to reason over. Dropping at capture time\n * prevents them from dominating ingest volume.\n */\nexport function shouldDropUnresolvableStack(\n exceptions: readonly ExceptionValue[]\n): boolean {\n for (const exception of exceptions) {\n const frames = exception.frames;\n if (!frames?.length) {\n continue;\n }\n if (frames.some((frame) => typeof frame.fileName === \"string\")) {\n return false;\n }\n }\n return true;\n}\n\nconst MAX_CAUSE_DEPTH = 5;\n\n/**\n * Upper bound for any single stack-trace line. Pathologically long lines can\n * trigger catastrophic backtracking in regex-based stack parsers (the\n * `error-stack-parser-es` library we depend on is regex-driven). Sentry uses\n * the same 1 KiB ceiling for the same reason.\n */\nconst MAX_STACK_LINE_LENGTH = 1024;\n\n/**\n * Webpack emits `(error: *)` wrappers around stack frames under certain\n * devtool configurations. The pattern is always a trailing suffix; trimming\n * it lets the downstream parser see a clean `at fn (file:L:C)`.\n */\nconst WEBPACK_ERROR_WRAPPER_RE = /\\s*\\(error:\\s+\\*\\)$/;\n\nconst PAREN_FILE_RE = /\\((.+?)(?::\\d+){1,2}\\)/;\nconst AT_FILE_RE = /at\\s+(.+?)(?::\\d+){1,2}$/;\nconst SPIDERMONKEY_RE = /(?:^|@)((?:https?:\\/\\/|\\/).+?)(?::\\d+){1,2}$/;\nconst BARE_FILE_RE = /(?:^|@)(.+?)(?::\\d+){1,2}$/;\n\n/**\n * Normalizes an `Error.stack` string before feeding it to the stack parser.\n *\n * - Truncates each line to {@link MAX_STACK_LINE_LENGTH} to prevent ReDoS on\n * pathological inputs (a single frame with a 100 KiB URL can stall the\n * main thread for seconds in a regex-based parser).\n * - Strips the trailing `(error: *)` suffix some webpack builds emit.\n */\nexport function preprocessStack(stack: string): string {\n if (!stack) {\n return stack;\n }\n\n const out: string[] = [];\n for (const rawLine of stack.split(\"\\n\")) {\n const line =\n rawLine.length > MAX_STACK_LINE_LENGTH\n ? rawLine.slice(0, MAX_STACK_LINE_LENGTH)\n : rawLine;\n out.push(line.replace(WEBPACK_ERROR_WRAPPER_RE, \"\"));\n }\n return out.join(\"\\n\");\n}\n\n/**\n * Matches one React component-stack line. Captures:\n * 1. component name\n * 2. optional file name (required to have a line number, to avoid matching\n * \"(created by Parent)\" annotations emitted by React 16-18)\n * 3. optional line number\n * 4. optional column number\n */\nconst COMPONENT_STACK_RE =\n /^(?:in|at)\\s+([^\\s(]+)(?:\\s+\\(([^\\s:)]+):(\\d+)(?::(\\d+))?\\))?/;\n\n/**\n * Parses a React `errorInfo.componentStack` string into synthetic frames.\n *\n * React produces different formats across versions:\n * - React 16–18 legacy: ` in ComponentName`\n * ` in ComponentName (created by Parent)`\n * - React 19 owner stacks: ` at ComponentName`\n * ` at ComponentName (file.tsx:10:5)`\n *\n * Each line becomes one frame with the component as `functionName`. When file\n * positions are present (React 19), they're preserved.\n */\nexport function parseReactComponentStack(\n componentStack: string\n): IngestedFrame[] {\n const frames: IngestedFrame[] = [];\n for (const rawLine of componentStack.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line) {\n continue;\n }\n const match = COMPONENT_STACK_RE.exec(line);\n if (!match) {\n continue;\n }\n const [, name, fileName, lineStr, colStr] = match;\n if (!name) {\n continue;\n }\n const frame: IngestedFrame = { functionName: name };\n if (fileName) {\n frame.fileName = fileName;\n }\n if (lineStr) {\n frame.lineNumber = Number(lineStr);\n }\n if (colStr) {\n frame.columnNumber = Number(colStr);\n }\n frames.push(frame);\n }\n return frames;\n}\n\n/**\n * Coerces any thrown value into an `Error` instance, preferring a nested\n * `Error` inside a plain-object rejection over a stringified fallback.\n *\n * Motivated by the common `Promise.reject({ error: realErr })` pattern\n * (tRPC, GraphQL clients, some fetch wrappers). Without this, the captured\n * exception would be `new Error(\"[object Object]\")` and the nested Error's\n * stack/message would be lost entirely.\n *\n * When multiple candidate Error values exist on the object, the first one\n * found (in declaration order) wins. `cause` is preferred if present, since\n * it's the documented ES2022 convention.\n */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n\n if (typeof error === \"string\") {\n return new Error(error);\n }\n\n if (error !== null && typeof error === \"object\") {\n const record = error as Record<string, unknown>;\n\n if (record[\"cause\"] instanceof Error) {\n return record[\"cause\"];\n }\n\n for (const value of Object.values(record)) {\n if (value instanceof Error) {\n return value;\n }\n }\n }\n\n return new Error(String(error));\n}\n\nexport function toExceptions(\n error: Error,\n mechanism: ErrorMechanism\n): ExceptionValue[] {\n const debugIdMap = getDebugIdMap();\n const exceptions: ExceptionValue[] = [];\n let current: Error | undefined = error;\n\n for (let depth = 0; current && depth < MAX_CAUSE_DEPTH; depth += 1) {\n exceptions.push({\n type: current.name,\n value: current.message,\n mechanism: depth === 0 ? mechanism : undefined,\n frames: framesFromError(current, debugIdMap),\n });\n\n current = current.cause instanceof Error ? current.cause : undefined;\n }\n\n return exceptions;\n}\n\n/**\n * Extracts and normalizes frames from an Error, applying:\n * 1. `preprocessStack` — line truncation and webpack-wrapper stripping.\n * 2. `error-stack-parser-es` — engine-specific stack parsing.\n * 3. `framesToPop` — honoring the documented Node convention where an\n * Error constructor sets this field to instruct callers to drop N top\n * frames (used by invariant libraries, assertion wrappers, etc.).\n */\nfunction framesFromError(\n error: Error,\n debugIdMap: Map<string, string>\n): IngestedFrame[] {\n const rawStack = error.stack ?? \"\";\n const cleaned = preprocessStack(rawStack);\n\n // error-stack-parser-es reads the Error's `.stack` property directly; we\n // build a minimal parse target so preprocessing doesn't mutate the caller's\n // Error.\n const parseTarget =\n cleaned === rawStack\n ? error\n : ({\n name: error.name,\n message: error.message,\n stack: cleaned,\n } as Error);\n\n let frames = parse(parseTarget, { allowEmpty: true }).map((frame) =>\n normalizeFrame(frame, debugIdMap)\n );\n\n const framesToPop = (error as Error & { framesToPop?: unknown }).framesToPop;\n if (typeof framesToPop === \"number\" && framesToPop > 0) {\n frames = frames.slice(Math.floor(framesToPop));\n }\n\n return frames;\n}\n\nlet cachedDebugIdMap: Map<string, string> | undefined;\nlet cachedDebugIdCount = 0;\n\nfunction getDebugIdMap(): Map<string, string> {\n const registry = (globalThis as Record<string, unknown>)[\"_debugIds\"] as\n | Record<string, string>\n | undefined;\n\n if (!registry) {\n return new Map();\n }\n\n const entries = Object.keys(registry);\n if (cachedDebugIdMap && entries.length === cachedDebugIdCount) {\n return cachedDebugIdMap;\n }\n\n const map = new Map<string, string>();\n for (const stackKey of entries) {\n const debugId = registry[stackKey];\n if (!debugId) {\n continue;\n }\n\n const filename = extractFilenameFromStack(stackKey);\n if (filename) {\n map.set(filename, debugId);\n }\n }\n\n cachedDebugIdMap = map;\n cachedDebugIdCount = entries.length;\n return map;\n}\n\nexport function extractFilenameFromStack(stack: string): string | null {\n const lines = stack.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i];\n if (!line) {\n continue;\n }\n const match =\n line.match(PAREN_FILE_RE) ??\n line.match(AT_FILE_RE) ??\n line.match(SPIDERMONKEY_RE) ??\n line.match(BARE_FILE_RE);\n\n if (match?.[1]) {\n return match[1].trim();\n }\n }\n return null;\n}\n\nfunction normalizeFrame(\n frame: {\n fileName?: unknown;\n functionName?: unknown;\n lineNumber?: unknown;\n columnNumber?: unknown;\n source?: unknown;\n },\n debugIdMap: Map<string, string>\n): IngestedFrame {\n const fileName =\n typeof frame.fileName === \"string\" ? frame.fileName : undefined;\n\n return {\n fileName,\n functionName:\n typeof frame.functionName === \"string\" ? frame.functionName : undefined,\n lineNumber:\n typeof frame.lineNumber === \"number\" ? frame.lineNumber : undefined,\n columnNumber:\n typeof frame.columnNumber === \"number\" ? frame.columnNumber : undefined,\n source: typeof frame.source === \"string\" ? frame.source : undefined,\n debugId: fileName ? debugIdMap.get(fileName) : undefined,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"identify.d.mts","names":[],"sources":["../../src/sdk/identify.ts"],"mappings":";;;cAEa,oBAAA,EAAoB,CAAA,CAAA,qBAAA,EAAA,CAAA,CAAA,SAAA;;;;;;;;;;KAMrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;KASrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA"}
1
+ {"version":3,"file":"identify.d.mts","names":[],"sources":["../../src/sdk/identify.ts"],"mappings":";;;cAEa,oBAAA,EAAoB,CAAA,CAAA,qBAAA,EAAA,CAAA,CAAA,SAAA;;;;;;;;;;KAkBrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;KAerB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA"}
@@ -4,16 +4,29 @@ const identifySourceSchema = z.discriminatedUnion("type", [
4
4
  z.object({
5
5
  type: z.literal("clerk"),
6
6
  name: z.literal("Clerk")
7
+ }).meta({
8
+ id: "ClerkIdentifySource",
9
+ title: "ClerkIdentifySource"
7
10
  }),
8
11
  z.object({
9
12
  type: z.literal("auth0"),
10
13
  name: z.literal("Auth0")
14
+ }).meta({
15
+ id: "Auth0IdentifySource",
16
+ title: "Auth0IdentifySource"
11
17
  }),
12
18
  z.object({
13
19
  type: z.literal("custom"),
14
20
  name: z.string()
21
+ }).meta({
22
+ id: "CustomIdentifySource",
23
+ title: "CustomIdentifySource"
15
24
  })
16
- ]);
25
+ ]).meta({
26
+ id: "IdentifySource",
27
+ title: "IdentifySource",
28
+ description: "Auth provider that surfaced this identification."
29
+ });
17
30
  const identifyParamsSchema = z.object({
18
31
  avatar: z.string().optional(),
19
32
  email: z.string().optional(),
@@ -21,6 +34,10 @@ const identifyParamsSchema = z.object({
21
34
  name: z.string().optional(),
22
35
  source: identifySourceSchema,
23
36
  traits: z.record(z.string(), z.unknown()).optional()
37
+ }).meta({
38
+ id: "IdentifyParams",
39
+ title: "IdentifyParams",
40
+ description: "User attributes attached when identifying a session."
24
41
  });
25
42
  //#endregion
26
43
  export { identifyParamsSchema, identifySourceSchema };
@@ -1 +1 @@
1
- {"version":3,"file":"identify.mjs","names":[],"sources":["../../src/sdk/identify.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const identifySourceSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"clerk\"), name: z.literal(\"Clerk\") }),\n z.object({ type: z.literal(\"auth0\"), name: z.literal(\"Auth0\") }),\n z.object({ type: z.literal(\"custom\"), name: z.string() }),\n]);\n\nexport type IdentifySource = z.infer<typeof identifySourceSchema>;\n\nexport const identifyParamsSchema = z.object({\n avatar: z.string().optional(),\n email: z.string().optional(),\n identifier: z.string(),\n name: z.string().optional(),\n source: identifySourceSchema,\n traits: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type IdentifyParams = z.infer<typeof identifyParamsSchema>;\n"],"mappings":";;AAEA,MAAa,uBAAuB,EAAE,mBAAmB,QAAQ;CAC/D,EAAE,OAAO;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,CAAC;CAChE,EAAE,OAAO;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,CAAC;CAChE,EAAE,OAAO;EAAE,MAAM,EAAE,QAAQ,SAAS;EAAE,MAAM,EAAE,QAAQ;EAAE,CAAC;CAC1D,CAAC;AAIF,MAAa,uBAAuB,EAAE,OAAO;CAC3C,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,YAAY,EAAE,QAAQ;CACtB,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,QAAQ;CACR,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACrD,CAAC"}
1
+ {"version":3,"file":"identify.mjs","names":[],"sources":["../../src/sdk/identify.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const identifySourceSchema = z\n .discriminatedUnion(\"type\", [\n z\n .object({ type: z.literal(\"clerk\"), name: z.literal(\"Clerk\") })\n .meta({ id: \"ClerkIdentifySource\", title: \"ClerkIdentifySource\" }),\n z\n .object({ type: z.literal(\"auth0\"), name: z.literal(\"Auth0\") })\n .meta({ id: \"Auth0IdentifySource\", title: \"Auth0IdentifySource\" }),\n z\n .object({ type: z.literal(\"custom\"), name: z.string() })\n .meta({ id: \"CustomIdentifySource\", title: \"CustomIdentifySource\" }),\n ])\n .meta({\n id: \"IdentifySource\",\n title: \"IdentifySource\",\n description: \"Auth provider that surfaced this identification.\",\n });\n\nexport type IdentifySource = z.infer<typeof identifySourceSchema>;\n\nexport const identifyParamsSchema = z\n .object({\n avatar: z.string().optional(),\n email: z.string().optional(),\n identifier: z.string(),\n name: z.string().optional(),\n source: identifySourceSchema,\n traits: z.record(z.string(), z.unknown()).optional(),\n })\n .meta({\n id: \"IdentifyParams\",\n title: \"IdentifyParams\",\n description: \"User attributes attached when identifying a session.\",\n });\n\nexport type IdentifyParams = z.infer<typeof identifyParamsSchema>;\n"],"mappings":";;AAEA,MAAa,uBAAuB,EACjC,mBAAmB,QAAQ;CAC1B,EACG,OAAO;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,CAAC,CAC9D,KAAK;EAAE,IAAI;EAAuB,OAAO;EAAuB,CAAC;CACpE,EACG,OAAO;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,MAAM,EAAE,QAAQ,QAAQ;EAAE,CAAC,CAC9D,KAAK;EAAE,IAAI;EAAuB,OAAO;EAAuB,CAAC;CACpE,EACG,OAAO;EAAE,MAAM,EAAE,QAAQ,SAAS;EAAE,MAAM,EAAE,QAAQ;EAAE,CAAC,CACvD,KAAK;EAAE,IAAI;EAAwB,OAAO;EAAwB,CAAC;CACvE,CAAC,CACD,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACd,CAAC;AAIJ,MAAa,uBAAuB,EACjC,OAAO;CACN,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,YAAY,EAAE,QAAQ;CACtB,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,QAAQ;CACR,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACrD,CAAC,CACD,KAAK;CACJ,IAAI;CACJ,OAAO;CACP,aAAa;CACd,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.mts","names":[],"sources":["../../../../src/sdk/plugins/context/browser.ts"],"mappings":";;;cAEa,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;KA0BrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAEtC,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;;KAYf,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,qBAAA;AAAA,cAEhC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAMrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA"}
1
+ {"version":3,"file":"browser.d.mts","names":[],"sources":["../../../../src/sdk/plugins/context/browser.ts"],"mappings":";;;cAuCa,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;KAerB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAgBtC,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;;KAYf,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,qBAAA;AAAA,cAEhC,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAYrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA"}