@sentry/cloudflare 11.0.0-beta.2 → 11.0.0-rc.0

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 (95) hide show
  1. package/build/cjs/dev/index.js +4 -0
  2. package/build/cjs/dev/index.js.map +1 -1
  3. package/build/cjs/dev/instrumentations/worker/instrumentD1.js +19 -17
  4. package/build/cjs/dev/instrumentations/worker/instrumentD1.js.map +1 -1
  5. package/build/cjs/dev/instrumentations/worker/instrumentEmail.js +4 -3
  6. package/build/cjs/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
  7. package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js +10 -5
  8. package/build/cjs/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
  9. package/build/cjs/dev/orchestrion-deferred-channels.js +39 -0
  10. package/build/cjs/dev/orchestrion-deferred-channels.js.map +1 -0
  11. package/build/cjs/dev/orchestrion-diagnostics-channel.js +83 -0
  12. package/build/cjs/dev/orchestrion-diagnostics-channel.js.map +1 -0
  13. package/build/cjs/dev/vite/index.js +6 -1
  14. package/build/cjs/dev/vite/index.js.map +1 -1
  15. package/build/cjs/dev/vite/mastraObservability.js +39 -0
  16. package/build/cjs/dev/vite/mastraObservability.js.map +1 -0
  17. package/build/cjs/dev/wrapMethodWithSentry.js +8 -4
  18. package/build/cjs/dev/wrapMethodWithSentry.js.map +1 -1
  19. package/build/cjs/dev/wrapRequestHandlerWithInit.js +2 -0
  20. package/build/cjs/dev/wrapRequestHandlerWithInit.js.map +1 -1
  21. package/build/cjs/prod/index.js +4 -0
  22. package/build/cjs/prod/index.js.map +1 -1
  23. package/build/cjs/prod/instrumentations/worker/instrumentD1.js +19 -17
  24. package/build/cjs/prod/instrumentations/worker/instrumentD1.js.map +1 -1
  25. package/build/cjs/prod/instrumentations/worker/instrumentEmail.js +4 -3
  26. package/build/cjs/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
  27. package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js +10 -5
  28. package/build/cjs/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
  29. package/build/cjs/prod/orchestrion-deferred-channels.js +39 -0
  30. package/build/cjs/prod/orchestrion-deferred-channels.js.map +1 -0
  31. package/build/cjs/prod/orchestrion-diagnostics-channel.js +83 -0
  32. package/build/cjs/prod/orchestrion-diagnostics-channel.js.map +1 -0
  33. package/build/cjs/prod/vite/index.js +6 -1
  34. package/build/cjs/prod/vite/index.js.map +1 -1
  35. package/build/cjs/prod/vite/mastraObservability.js +39 -0
  36. package/build/cjs/prod/vite/mastraObservability.js.map +1 -0
  37. package/build/cjs/prod/wrapMethodWithSentry.js +8 -4
  38. package/build/cjs/prod/wrapMethodWithSentry.js.map +1 -1
  39. package/build/cjs/prod/wrapRequestHandlerWithInit.js +2 -0
  40. package/build/cjs/prod/wrapRequestHandlerWithInit.js.map +1 -1
  41. package/build/esm/dev/index.js +1 -1
  42. package/build/esm/dev/instrumentations/worker/instrumentD1.js +20 -18
  43. package/build/esm/dev/instrumentations/worker/instrumentD1.js.map +1 -1
  44. package/build/esm/dev/instrumentations/worker/instrumentEmail.js +6 -5
  45. package/build/esm/dev/instrumentations/worker/instrumentEmail.js.map +1 -1
  46. package/build/esm/dev/instrumentations/worker/instrumentScheduled.js +12 -7
  47. package/build/esm/dev/instrumentations/worker/instrumentScheduled.js.map +1 -1
  48. package/build/esm/dev/orchestrion-deferred-channels.js +35 -0
  49. package/build/esm/dev/orchestrion-deferred-channels.js.map +1 -0
  50. package/build/esm/dev/orchestrion-diagnostics-channel.js +77 -0
  51. package/build/esm/dev/orchestrion-diagnostics-channel.js.map +1 -0
  52. package/build/esm/dev/package.json +1 -1
  53. package/build/esm/dev/vite/index.js +6 -1
  54. package/build/esm/dev/vite/index.js.map +1 -1
  55. package/build/esm/dev/vite/mastraObservability.js +36 -0
  56. package/build/esm/dev/vite/mastraObservability.js.map +1 -0
  57. package/build/esm/dev/wrapMethodWithSentry.js +7 -3
  58. package/build/esm/dev/wrapMethodWithSentry.js.map +1 -1
  59. package/build/esm/dev/wrapRequestHandlerWithInit.js +2 -0
  60. package/build/esm/dev/wrapRequestHandlerWithInit.js.map +1 -1
  61. package/build/esm/prod/index.js +1 -1
  62. package/build/esm/prod/instrumentations/worker/instrumentD1.js +20 -18
  63. package/build/esm/prod/instrumentations/worker/instrumentD1.js.map +1 -1
  64. package/build/esm/prod/instrumentations/worker/instrumentEmail.js +6 -5
  65. package/build/esm/prod/instrumentations/worker/instrumentEmail.js.map +1 -1
  66. package/build/esm/prod/instrumentations/worker/instrumentScheduled.js +12 -7
  67. package/build/esm/prod/instrumentations/worker/instrumentScheduled.js.map +1 -1
  68. package/build/esm/prod/orchestrion-deferred-channels.js +35 -0
  69. package/build/esm/prod/orchestrion-deferred-channels.js.map +1 -0
  70. package/build/esm/prod/orchestrion-diagnostics-channel.js +77 -0
  71. package/build/esm/prod/orchestrion-diagnostics-channel.js.map +1 -0
  72. package/build/esm/prod/package.json +1 -1
  73. package/build/esm/prod/vite/index.js +6 -1
  74. package/build/esm/prod/vite/index.js.map +1 -1
  75. package/build/esm/prod/vite/mastraObservability.js +36 -0
  76. package/build/esm/prod/vite/mastraObservability.js.map +1 -0
  77. package/build/esm/prod/wrapMethodWithSentry.js +7 -3
  78. package/build/esm/prod/wrapMethodWithSentry.js.map +1 -1
  79. package/build/esm/prod/wrapRequestHandlerWithInit.js +2 -0
  80. package/build/esm/prod/wrapRequestHandlerWithInit.js.map +1 -1
  81. package/build/types/index.d.ts +2 -2
  82. package/build/types/index.d.ts.map +1 -1
  83. package/build/types/instrumentations/worker/instrumentD1.d.ts.map +1 -1
  84. package/build/types/instrumentations/worker/instrumentEmail.d.ts.map +1 -1
  85. package/build/types/instrumentations/worker/instrumentScheduled.d.ts.map +1 -1
  86. package/build/types/orchestrion-deferred-channels.d.ts +26 -0
  87. package/build/types/orchestrion-deferred-channels.d.ts.map +1 -0
  88. package/build/types/orchestrion-diagnostics-channel.d.ts +44 -0
  89. package/build/types/orchestrion-diagnostics-channel.d.ts.map +1 -0
  90. package/build/types/vite/index.d.ts.map +1 -1
  91. package/build/types/vite/mastraObservability.d.ts +27 -0
  92. package/build/types/vite/mastraObservability.d.ts.map +1 -0
  93. package/build/types/wrapMethodWithSentry.d.ts.map +1 -1
  94. package/build/types/wrapRequestHandlerWithInit.d.ts.map +1 -1
  95. package/package.json +10 -5
@@ -100,12 +100,16 @@ exports.withStreamedSpan = core.withStreamedSpan;
100
100
  exports.zodErrorsIntegration = core.zodErrorsIntegration;
101
101
  exports.trpcMiddleware = server.trpcMiddleware;
102
102
  exports.wrapMcpServerWithSentry = server.wrapMcpServerWithSentry;
103
+ exports.createFlueInstrumentation = serverUtils.createFlueInstrumentation;
103
104
  exports.createLangChainCallbackHandler = serverUtils.createLangChainCallbackHandler;
105
+ exports.eveConversationHook = serverUtils.eveConversationHook;
106
+ exports.getInstrumentedModuleNames = serverUtils.getInstrumentedModuleNames;
104
107
  exports.getOtlpTracesEndpoint = serverUtils.getOtlpTracesEndpoint;
105
108
  exports.instrumentAnthropicAiClient = serverUtils.instrumentAnthropicAiClient;
106
109
  exports.instrumentCreateReactAgent = serverUtils.instrumentCreateReactAgent;
107
110
  exports.instrumentGoogleGenAIClient = serverUtils.instrumentGoogleGenAIClient;
108
111
  exports.instrumentLangChainEmbeddings = serverUtils.instrumentLangChainEmbeddings;
112
+ exports.instrumentMistralAiClient = serverUtils.instrumentMistralAiClient;
109
113
  exports.instrumentOpenAiClient = serverUtils.instrumentOpenAiClient;
110
114
  exports.instrumentPostgresJsSql = serverUtils.instrumentPostgresJsSql;
111
115
  exports.instrumentStateGraph = serverUtils.instrumentStateGraph;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -11,40 +11,41 @@ function instrumentD1PreparedStatementQueries(statement, query) {
11
11
  if (patchedStatement.has(statement)) {
12
12
  return statement;
13
13
  }
14
+ const queryText = query ? serverUtils.sanitizeSqlQuery(query) : void 0;
14
15
  statement.first = new Proxy(statement.first, {
15
16
  apply(target, thisArg, args) {
16
- return core.startSpan(createStartSpanOptions(query, "first"), async () => {
17
+ return core.startSpan(createStartSpanOptions(queryText, "first"), async () => {
17
18
  const res = await Reflect.apply(target, thisArg, args);
18
- createD1Breadcrumb(query, "first");
19
+ createD1Breadcrumb(queryText, "first");
19
20
  return res;
20
21
  });
21
22
  }
22
23
  });
23
24
  statement.run = new Proxy(statement.run, {
24
25
  apply(target, thisArg, args) {
25
- return core.startSpan(createStartSpanOptions(query, "run"), async (span) => {
26
+ return core.startSpan(createStartSpanOptions(queryText, "run"), async (span) => {
26
27
  const d1Response = await Reflect.apply(target, thisArg, args);
27
28
  applyD1ReturnObjectToSpan(span, d1Response);
28
- createD1Breadcrumb(query, "run", d1Response);
29
+ createD1Breadcrumb(queryText, "run", d1Response);
29
30
  return d1Response;
30
31
  });
31
32
  }
32
33
  });
33
34
  statement.all = new Proxy(statement.all, {
34
35
  apply(target, thisArg, args) {
35
- return core.startSpan(createStartSpanOptions(query, "all"), async (span) => {
36
+ return core.startSpan(createStartSpanOptions(queryText, "all"), async (span) => {
36
37
  const d1Result = await Reflect.apply(target, thisArg, args);
37
38
  applyD1ReturnObjectToSpan(span, d1Result);
38
- createD1Breadcrumb(query, "all", d1Result);
39
+ createD1Breadcrumb(queryText, "all", d1Result);
39
40
  return d1Result;
40
41
  });
41
42
  }
42
43
  });
43
44
  statement.raw = new Proxy(statement.raw, {
44
45
  apply(target, thisArg, args) {
45
- return core.startSpan(createStartSpanOptions(query, "raw"), async () => {
46
+ return core.startSpan(createStartSpanOptions(queryText, "raw"), async () => {
46
47
  const res = await Reflect.apply(target, thisArg, args);
47
- createD1Breadcrumb(query, "raw");
48
+ createD1Breadcrumb(queryText, "raw");
48
49
  return res;
49
50
  });
50
51
  }
@@ -73,27 +74,27 @@ function getAttributesFromD1Response(d1Result) {
73
74
  "cloudflare.d1.rows_written": d1Result.meta.rows_written
74
75
  };
75
76
  }
76
- function createD1Breadcrumb(query, type, d1Result) {
77
+ function createD1Breadcrumb(message, type, d1Result) {
77
78
  core.addBreadcrumb({
78
79
  category: "query",
79
- message: query,
80
+ message,
80
81
  data: {
81
82
  ...d1Result ? getAttributesFromD1Response(d1Result) : {},
82
83
  "db.operation.name": type
83
84
  }
84
85
  });
85
86
  }
86
- function createStartSpanOptions(query, type) {
87
- const querySummary = query ? serverUtils.getSqlQuerySummary(serverUtils.sanitizeSqlQuery(query)) : void 0;
87
+ function createStartSpanOptions(queryText, type) {
88
+ const querySummary = queryText ? serverUtils.getSqlQuerySummary(queryText) : void 0;
88
89
  const client = core.getClient();
89
- const name = client && core.hasSpanStreamingEnabled(client) ? querySummary || "cloudflare-d1" : query;
90
+ const name = client && core.hasSpanStreamingEnabled(client) ? querySummary || "cloudflare-d1" : queryText ?? "cloudflare-d1";
90
91
  return {
91
92
  name,
92
93
  attributes: {
93
94
  [attributes.SENTRY_OP]: op.DB_QUERY,
94
95
  "db.system.name": "cloudflare-d1",
95
96
  "db.operation.name": type,
96
- "db.query.text": query,
97
+ "db.query.text": queryText,
97
98
  "db.query.summary": querySummary,
98
99
  [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.db.cloudflare.d1"
99
100
  }
@@ -111,7 +112,7 @@ function instrumentBatch(batch) {
111
112
  return new Proxy(batch, {
112
113
  apply(target, thisArg, args) {
113
114
  const statements = args[0];
114
- const queryText = statements.map((statement) => statement.statement ?? "").filter(Boolean).join("\n");
115
+ const queryText = statements.map((statement) => statement.statement ?? "").filter(Boolean).map((statement) => serverUtils.sanitizeSqlQuery(statement)).join("\n");
115
116
  return core.startSpan(
116
117
  {
117
118
  name: "D1 batch",
@@ -144,9 +145,10 @@ function _instrumentD1(db) {
144
145
  db.exec = new Proxy(db.exec, {
145
146
  apply(target, thisArg, args) {
146
147
  const [query] = args;
147
- return core.startSpan(createStartSpanOptions(query, "exec"), async () => {
148
+ const queryText = query ? serverUtils.sanitizeSqlQuery(query) : void 0;
149
+ return core.startSpan(createStartSpanOptions(queryText, "exec"), async () => {
148
150
  const res = await Reflect.apply(target, thisArg, args);
149
- createD1Breadcrumb(query, "exec");
151
+ createD1Breadcrumb(queryText, "exec");
150
152
  return res;
151
153
  });
152
154
  }
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentD1.js","sources":["../../../../../src/instrumentations/worker/instrumentD1.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport type { D1Database, D1DatabaseSession, D1PreparedStatement, D1Response } from '@cloudflare/workers-types';\nimport { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { DB_QUERY } from '@sentry/conventions/op';\nimport type { Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n addBreadcrumb,\n getClient,\n hasSpanStreamingEnabled,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n} from '@sentry/core';\nimport { getSqlQuerySummary, sanitizeSqlQuery } from '@sentry/server-utils';\nimport { ensureInstrumented } from '../../instrument';\n\n// Patching is based on internal Cloudflare D1 API\n// https://github.com/cloudflare/workerd/blob/cd5279e7b305003f1d9c851e73efa9d67e4b68b2/src/cloudflare/internal/d1-api.ts\n\nconst patchedStatement = new WeakSet<D1PreparedStatement>();\n\n/**\n * Patches the query methods of a Cloudflare D1 prepared statement with Sentry.\n */\nfunction instrumentD1PreparedStatementQueries(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n if (patchedStatement.has(statement)) {\n return statement;\n }\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.first = new Proxy(statement.first, {\n apply(target, thisArg, args: Parameters<typeof statement.first>) {\n return startSpan(createStartSpanOptions(query, 'first'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(query, 'first');\n return res;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.run = new Proxy(statement.run, {\n apply(target, thisArg, args: Parameters<typeof statement.run>) {\n return startSpan(createStartSpanOptions(query, 'run'), async span => {\n const d1Response = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Response);\n createD1Breadcrumb(query, 'run', d1Response);\n return d1Response;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.all = new Proxy(statement.all, {\n apply(target, thisArg, args: Parameters<typeof statement.all>) {\n return startSpan(createStartSpanOptions(query, 'all'), async span => {\n const d1Result = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Result);\n createD1Breadcrumb(query, 'all', d1Result);\n return d1Result;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.raw = new Proxy(statement.raw, {\n apply(target, thisArg, args: Parameters<typeof statement.raw>) {\n return startSpan(createStartSpanOptions(query, 'raw'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(query, 'raw');\n return res;\n });\n },\n });\n\n patchedStatement.add(statement);\n\n return statement;\n}\n\n/**\n * Instruments a Cloudflare D1 prepared statement with Sentry.\n *\n * This is meant to be used as a top-level call, under the hood it calls `instrumentD1PreparedStatementQueries`\n * to patch the query methods. The reason for this abstraction is to ensure that the `bind` method is also patched.\n */\nfunction instrumentD1PreparedStatement(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n // statement.bind() returns a new instance of D1PreparedStatement, so we have to patch it as well.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.bind = new Proxy(statement.bind, {\n apply(target, thisArg, args: Parameters<typeof statement.bind>) {\n return instrumentD1PreparedStatementQueries(Reflect.apply(target, thisArg, args), query);\n },\n });\n\n return instrumentD1PreparedStatementQueries(statement, query);\n}\n\n/**\n * Add D1Response meta information to a span.\n *\n * See: https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/#return-object\n */\nfunction applyD1ReturnObjectToSpan(span: Span, d1Result: D1Response): void {\n if (!d1Result.success) {\n span.setStatus({ code: SPAN_STATUS_ERROR });\n }\n\n span.setAttributes(getAttributesFromD1Response(d1Result));\n}\n\nfunction getAttributesFromD1Response(d1Result: D1Response): SpanAttributes {\n return {\n 'cloudflare.d1.duration': d1Result.meta.duration,\n 'cloudflare.d1.rows_read': d1Result.meta.rows_read,\n 'cloudflare.d1.rows_written': d1Result.meta.rows_written,\n };\n}\n\ntype D1QueryType = 'first' | 'run' | 'all' | 'raw' | 'batch' | 'exec';\n\nfunction createD1Breadcrumb(query: string, type: D1QueryType, d1Result?: D1Response): void {\n addBreadcrumb({\n category: 'query',\n message: query,\n data: {\n ...(d1Result ? getAttributesFromD1Response(d1Result) : {}),\n 'db.operation.name': type,\n },\n });\n}\n\nfunction createStartSpanOptions(query: string, type: D1QueryType): StartSpanOptions {\n const querySummary = query ? getSqlQuerySummary(sanitizeSqlQuery(query)) : undefined;\n\n const client = getClient();\n const name = client && hasSpanStreamingEnabled(client) ? querySummary || 'cloudflare-d1' : query;\n\n return {\n name,\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': type,\n 'db.query.text': query,\n 'db.query.summary': querySummary,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n };\n}\n\nfunction instrumentPrepare(\n prepare: D1Database['prepare'] | D1DatabaseSession['prepare'],\n): D1Database['prepare'] | D1DatabaseSession['prepare'] {\n return new Proxy(prepare, {\n apply(target, thisArg, args: Parameters<typeof prepare>) {\n const [query] = args;\n return instrumentD1PreparedStatement(Reflect.apply(target, thisArg, args), query);\n },\n });\n}\n\nfunction instrumentBatch(\n batch: D1Database['batch'] | D1DatabaseSession['batch'],\n): D1Database['batch'] | D1DatabaseSession['batch'] {\n return new Proxy(batch, {\n apply(target, thisArg, args: Parameters<typeof batch>) {\n const statements = args[0];\n // D1PreparedStatement exposes a `statement` property at runtime, but it's not in @cloudflare/workers-types.\n // https://github.com/cloudflare/workerd/blob/dc12d7650b4f5d4f9ba6a47aa45fad769cdf8db4/src/cloudflare/internal/d1-api.ts#L210\n const queryText = statements\n .map(statement => (statement as unknown as { statement?: string }).statement ?? '')\n .filter(Boolean)\n .join('\\n');\n\n return startSpan(\n {\n name: 'D1 batch',\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': 'batch',\n 'db.query.text': queryText || undefined,\n 'db.operation.batch.size': statements.length,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n },\n async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb('D1 batch', 'batch');\n return res;\n },\n );\n },\n });\n}\n\nfunction instrumentD1Session(session: D1DatabaseSession): D1DatabaseSession {\n session.prepare = instrumentPrepare(session.prepare);\n session.batch = instrumentBatch(session.batch);\n return session;\n}\n\nfunction _instrumentD1(db: D1Database): D1Database {\n db.prepare = instrumentPrepare(db.prepare);\n db.batch = instrumentBatch(db.batch);\n\n db.exec = new Proxy(db.exec, {\n apply(target, thisArg, args: Parameters<typeof db.exec>) {\n const [query] = args;\n return startSpan(createStartSpanOptions(query, 'exec'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(query, 'exec');\n return res;\n });\n },\n });\n\n if ('withSession' in db && typeof db.withSession === 'function') {\n db.withSession = new Proxy(db.withSession, {\n apply(target, thisArg, args: [unknown]) {\n return instrumentD1Session(Reflect.apply(target, thisArg, args) as D1DatabaseSession);\n },\n });\n }\n\n return db;\n}\n\nexport function instrumentD1(db: D1Database): D1Database {\n return ensureInstrumented(db, _instrumentD1);\n}\n"],"names":["startSpan","SPAN_STATUS_ERROR","addBreadcrumb","getSqlQuerySummary","sanitizeSqlQuery","getClient","hasSpanStreamingEnabled","SENTRY_OP","DB_QUERY","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","ensureInstrumented"],"mappings":"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"}
1
+ {"version":3,"file":"instrumentD1.js","sources":["../../../../../src/instrumentations/worker/instrumentD1.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/unbound-method */\nimport type { D1Database, D1DatabaseSession, D1PreparedStatement, D1Response } from '@cloudflare/workers-types';\nimport { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { DB_QUERY } from '@sentry/conventions/op';\nimport type { Span, SpanAttributes, StartSpanOptions } from '@sentry/core';\nimport {\n addBreadcrumb,\n getClient,\n hasSpanStreamingEnabled,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SPAN_STATUS_ERROR,\n startSpan,\n} from '@sentry/core';\nimport { getSqlQuerySummary, sanitizeSqlQuery } from '@sentry/server-utils';\nimport { ensureInstrumented } from '../../instrument';\n\n// Patching is based on internal Cloudflare D1 API\n// https://github.com/cloudflare/workerd/blob/cd5279e7b305003f1d9c851e73efa9d67e4b68b2/src/cloudflare/internal/d1-api.ts\n\nconst patchedStatement = new WeakSet<D1PreparedStatement>();\n\n/**\n * Patches the query methods of a Cloudflare D1 prepared statement with Sentry.\n */\nfunction instrumentD1PreparedStatementQueries(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n if (patchedStatement.has(statement)) {\n return statement;\n }\n\n const queryText = query ? sanitizeSqlQuery(query) : undefined;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.first = new Proxy(statement.first, {\n apply(target, thisArg, args: Parameters<typeof statement.first>) {\n return startSpan(createStartSpanOptions(queryText, 'first'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(queryText, 'first');\n return res;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.run = new Proxy(statement.run, {\n apply(target, thisArg, args: Parameters<typeof statement.run>) {\n return startSpan(createStartSpanOptions(queryText, 'run'), async span => {\n const d1Response = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Response);\n createD1Breadcrumb(queryText, 'run', d1Response);\n return d1Response;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.all = new Proxy(statement.all, {\n apply(target, thisArg, args: Parameters<typeof statement.all>) {\n return startSpan(createStartSpanOptions(queryText, 'all'), async span => {\n const d1Result = await Reflect.apply(target, thisArg, args);\n applyD1ReturnObjectToSpan(span, d1Result);\n createD1Breadcrumb(queryText, 'all', d1Result);\n return d1Result;\n });\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.raw = new Proxy(statement.raw, {\n apply(target, thisArg, args: Parameters<typeof statement.raw>) {\n return startSpan(createStartSpanOptions(queryText, 'raw'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(queryText, 'raw');\n return res;\n });\n },\n });\n\n patchedStatement.add(statement);\n\n return statement;\n}\n\n/**\n * Instruments a Cloudflare D1 prepared statement with Sentry.\n *\n * This is meant to be used as a top-level call, under the hood it calls `instrumentD1PreparedStatementQueries`\n * to patch the query methods. The reason for this abstraction is to ensure that the `bind` method is also patched.\n */\nfunction instrumentD1PreparedStatement(statement: D1PreparedStatement, query: string): D1PreparedStatement {\n // statement.bind() returns a new instance of D1PreparedStatement, so we have to patch it as well.\n // eslint-disable-next-line @typescript-eslint/unbound-method\n statement.bind = new Proxy(statement.bind, {\n apply(target, thisArg, args: Parameters<typeof statement.bind>) {\n return instrumentD1PreparedStatementQueries(Reflect.apply(target, thisArg, args), query);\n },\n });\n\n return instrumentD1PreparedStatementQueries(statement, query);\n}\n\n/**\n * Add D1Response meta information to a span.\n *\n * See: https://developers.cloudflare.com/d1/build-with-d1/d1-client-api/#return-object\n */\nfunction applyD1ReturnObjectToSpan(span: Span, d1Result: D1Response): void {\n if (!d1Result.success) {\n span.setStatus({ code: SPAN_STATUS_ERROR });\n }\n\n span.setAttributes(getAttributesFromD1Response(d1Result));\n}\n\nfunction getAttributesFromD1Response(d1Result: D1Response): SpanAttributes {\n return {\n 'cloudflare.d1.duration': d1Result.meta.duration,\n 'cloudflare.d1.rows_read': d1Result.meta.rows_read,\n 'cloudflare.d1.rows_written': d1Result.meta.rows_written,\n };\n}\n\ntype D1QueryType = 'first' | 'run' | 'all' | 'raw' | 'batch' | 'exec';\n\n/** The message is the span's query text (already sanitized) or a static label such as `D1 batch`. */\nfunction createD1Breadcrumb(message: string | undefined, type: D1QueryType, d1Result?: D1Response): void {\n addBreadcrumb({\n category: 'query',\n message,\n data: {\n ...(d1Result ? getAttributesFromD1Response(d1Result) : {}),\n 'db.operation.name': type,\n },\n });\n}\n\nfunction createStartSpanOptions(queryText: string | undefined, type: D1QueryType): StartSpanOptions {\n const querySummary = queryText ? getSqlQuerySummary(queryText) : undefined;\n\n const client = getClient();\n const name =\n client && hasSpanStreamingEnabled(client) ? querySummary || 'cloudflare-d1' : (queryText ?? 'cloudflare-d1');\n\n return {\n name,\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': type,\n 'db.query.text': queryText,\n 'db.query.summary': querySummary,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n };\n}\n\nfunction instrumentPrepare(\n prepare: D1Database['prepare'] | D1DatabaseSession['prepare'],\n): D1Database['prepare'] | D1DatabaseSession['prepare'] {\n return new Proxy(prepare, {\n apply(target, thisArg, args: Parameters<typeof prepare>) {\n const [query] = args;\n return instrumentD1PreparedStatement(Reflect.apply(target, thisArg, args), query);\n },\n });\n}\n\nfunction instrumentBatch(\n batch: D1Database['batch'] | D1DatabaseSession['batch'],\n): D1Database['batch'] | D1DatabaseSession['batch'] {\n return new Proxy(batch, {\n apply(target, thisArg, args: Parameters<typeof batch>) {\n const statements = args[0];\n // D1PreparedStatement exposes a `statement` property at runtime, but it's not in @cloudflare/workers-types.\n // https://github.com/cloudflare/workerd/blob/dc12d7650b4f5d4f9ba6a47aa45fad769cdf8db4/src/cloudflare/internal/d1-api.ts#L210\n const queryText = statements\n .map(statement => (statement as unknown as { statement?: string }).statement ?? '')\n .filter(Boolean)\n .map(statement => sanitizeSqlQuery(statement))\n .join('\\n');\n\n return startSpan(\n {\n name: 'D1 batch',\n attributes: {\n [SENTRY_OP]: DB_QUERY,\n 'db.system.name': 'cloudflare-d1',\n 'db.operation.name': 'batch',\n 'db.query.text': queryText || undefined,\n 'db.operation.batch.size': statements.length,\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.cloudflare.d1',\n },\n },\n async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb('D1 batch', 'batch');\n return res;\n },\n );\n },\n });\n}\n\nfunction instrumentD1Session(session: D1DatabaseSession): D1DatabaseSession {\n session.prepare = instrumentPrepare(session.prepare);\n session.batch = instrumentBatch(session.batch);\n return session;\n}\n\nfunction _instrumentD1(db: D1Database): D1Database {\n db.prepare = instrumentPrepare(db.prepare);\n db.batch = instrumentBatch(db.batch);\n\n db.exec = new Proxy(db.exec, {\n apply(target, thisArg, args: Parameters<typeof db.exec>) {\n const [query] = args;\n const queryText = query ? sanitizeSqlQuery(query) : undefined;\n return startSpan(createStartSpanOptions(queryText, 'exec'), async () => {\n const res = await Reflect.apply(target, thisArg, args);\n createD1Breadcrumb(queryText, 'exec');\n return res;\n });\n },\n });\n\n if ('withSession' in db && typeof db.withSession === 'function') {\n db.withSession = new Proxy(db.withSession, {\n apply(target, thisArg, args: [unknown]) {\n return instrumentD1Session(Reflect.apply(target, thisArg, args) as D1DatabaseSession);\n },\n });\n }\n\n return db;\n}\n\nexport function instrumentD1(db: D1Database): D1Database {\n return ensureInstrumented(db, _instrumentD1);\n}\n"],"names":["sanitizeSqlQuery","startSpan","SPAN_STATUS_ERROR","addBreadcrumb","getSqlQuerySummary","getClient","hasSpanStreamingEnabled","SENTRY_OP","DB_QUERY","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","ensureInstrumented"],"mappings":"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"}
@@ -21,11 +21,12 @@ function wrapEmailHandler(emailMessage, options, context, fn) {
21
21
  scopeUtils.addCloudResourceContext(isolationScope);
22
22
  return core.startSpan(
23
23
  {
24
- name: `Handle Email ${emailMessage.to}`,
24
+ name: "email",
25
25
  attributes: {
26
26
  [attributes.SENTRY_OP]: op.FUNCTION,
27
- "faas.trigger": "email",
28
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.faas.cloudflare.email",
27
+ [attributes.CODE_FUNCTION_NAME]: "email",
28
+ [attributes.FAAS_TRIGGER]: "email",
29
+ [attributes.SENTRY_ORIGIN]: "auto.faas.cloudflare.email",
29
30
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "task"
30
31
  }
31
32
  },
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentEmail.js","sources":["../../../../../src/instrumentations/worker/instrumentEmail.ts"],"sourcesContent":["import type { EmailMessage } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv } from 'cloudflare:workers';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP } from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\n/**\n * Core email handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapEmailHandler(\n emailMessage: EmailMessage,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n name: `Handle Email ${emailMessage.to}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n 'faas.trigger': 'email',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.email' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments an email handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerEmail<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('email' in handler) || typeof handler.email !== 'function') {\n return;\n }\n\n handler.email = ensureInstrumented(\n handler.email,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['email']>>) {\n const [emailMessage, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapEmailHandler(emailMessage, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","SENTRY_OP","FUNCTION","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAS,gBAAA,CACP,YAAA,EACA,OAAA,EACA,OAAA,EACA,EAAA,EACS;AACT,EAAA,OAAOA,wBAAmB,CAAA,cAAA,KAAkB;AAC1C,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAEhD,IAAAC,oCAAA,CAAmB,cAAA,EAAgB,EAAE,GAAA,EAAK,OAAA,EAAS,CAAA;AAEnD,IAAA,MAAM,SAASC,QAAA,CAAK,EAAE,GAAG,OAAA,EAAS,GAAA,EAAK,SAAS,CAAA;AAChD,IAAA,cAAA,CAAe,UAAU,MAAM,CAAA;AAE/B,IAAAC,kCAAA,CAAwB,cAAc,CAAA;AAEtC,IAAA,OAAOC,cAAA;AAAA,MACL;AAAA,QACE,IAAA,EAAM,CAAA,aAAA,EAAgB,YAAA,CAAa,EAAE,CAAA,CAAA;AAAA,QACrC,UAAA,EAAY;AAAA,UACV,CAACC,oBAAS,GAAGC,WAAA;AAAA,UACb,cAAA,EAAgB,OAAA;AAAA,UAChB,CAACC,qCAAgC,GAAG,4BAAA;AAAA,UACpC,CAACC,qCAA0B,GAAG;AAAA;AAChC,OACF;AAAA,MACA,YAAY;AACV,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,EAAA,EAAG;AAAA,QAClB,SAAS,CAAA,EAAG;AACV,UAAAC,qBAAA,CAAiB,CAAA,EAAG,EAAE,SAAA,EAAW,EAAE,SAAS,KAAA,EAAO,IAAA,EAAM,4BAAA,EAA6B,EAAG,CAAA;AACzF,UAAA,MAAM,CAAA;AAAA,QACR,CAAA,SAAE;AACA,UAAA,SAAA,CAAUC,qBAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,QACnC;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH;AAKO,SAAS,8BAAA,CACd,SACA,eAAA,EACM;AACN,EAAA,IAAI,EAAE,OAAA,IAAW,OAAA,CAAA,IAAY,OAAO,OAAA,CAAQ,UAAU,UAAA,EAAY;AAChE,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,KAAA,GAAQC,6BAAA;AAAA,IACd,OAAA,CAAQ,KAAA;AAAA,IACR,CAAA,QAAA,KACE,IAAI,KAAA,CAAM,QAAA,EAAU;AAAA,MAClB,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAA2C;AAChE,QAAA,MAAM,CAAC,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA,GAAI,IAAA;AACjC,QAAA,MAAM,OAAA,GAAUC,oCAAkB,GAAG,CAAA;AACrC,QAAA,MAAMC,SAAA,GAAUC,uBAAA,CAAgB,eAAA,CAAgB,GAAG,GAAG,GAAG,CAAA;AACzD,QAAA,IAAA,CAAK,CAAC,CAAA,GAAIC,2BAAA,CAAc,GAAA,EAAKF,SAAO,CAAA;AACpC,QAAA,IAAA,CAAK,CAAC,CAAA,GAAI,OAAA;AAEV,QAAA,OAAO,gBAAA,CAAiB,cAAcA,SAAA,EAAS,OAAA,EAAS,MAAM,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA,MAC3F;AAAA,KACD;AAAA,GACL;AACF;;;;"}
1
+ {"version":3,"file":"instrumentEmail.js","sources":["../../../../../src/instrumentations/worker/instrumentEmail.ts"],"sourcesContent":["import type { EmailMessage } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv } from 'cloudflare:workers';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n FAAS_TRIGGER,\n SENTRY_ORIGIN,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\n/**\n * Core email handler logic - wraps execution with Sentry instrumentation.\n */\nfunction wrapEmailHandler(\n emailMessage: EmailMessage,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n name: 'email',\n attributes: {\n [SENTRY_OP]: FUNCTION,\n [CODE_FUNCTION_NAME]: 'email',\n [FAAS_TRIGGER]: 'email',\n [SENTRY_ORIGIN]: 'auto.faas.cloudflare.email',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.email' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments an email handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerEmail<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('email' in handler) || typeof handler.email !== 'function') {\n return;\n }\n\n handler.email = ensureInstrumented(\n handler.email,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['email']>>) {\n const [emailMessage, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapEmailHandler(emailMessage, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","SENTRY_OP","FUNCTION","CODE_FUNCTION_NAME","FAAS_TRIGGER","SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":";;;;;;;;;;;;;;AAyBA,SAAS,gBAAA,CACP,YAAA,EACA,OAAA,EACA,OAAA,EACA,EAAA,EACS;AACT,EAAA,OAAOA,wBAAmB,CAAA,cAAA,KAAkB;AAC1C,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,CAAU,IAAA,CAAK,OAAO,CAAA;AAEhD,IAAAC,oCAAA,CAAmB,cAAA,EAAgB,EAAE,GAAA,EAAK,OAAA,EAAS,CAAA;AAEnD,IAAA,MAAM,SAASC,QAAA,CAAK,EAAE,GAAG,OAAA,EAAS,GAAA,EAAK,SAAS,CAAA;AAChD,IAAA,cAAA,CAAe,UAAU,MAAM,CAAA;AAE/B,IAAAC,kCAAA,CAAwB,cAAc,CAAA;AAEtC,IAAA,OAAOC,cAAA;AAAA,MACL;AAAA,QACE,IAAA,EAAM,OAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,CAACC,oBAAS,GAAGC,WAAA;AAAA,UACb,CAACC,6BAAkB,GAAG,OAAA;AAAA,UACtB,CAACC,uBAAY,GAAG,OAAA;AAAA,UAChB,CAACC,wBAAa,GAAG,4BAAA;AAAA,UACjB,CAACC,qCAA0B,GAAG;AAAA;AAChC,OACF;AAAA,MACA,YAAY;AACV,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,EAAA,EAAG;AAAA,QAClB,SAAS,CAAA,EAAG;AACV,UAAAC,qBAAA,CAAiB,CAAA,EAAG,EAAE,SAAA,EAAW,EAAE,SAAS,KAAA,EAAO,IAAA,EAAM,4BAAA,EAA6B,EAAG,CAAA;AACzF,UAAA,MAAM,CAAA;AAAA,QACR,CAAA,SAAE;AACA,UAAA,SAAA,CAAUC,qBAAA,CAAgB,MAAM,CAAC,CAAA;AAAA,QACnC;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AACH;AAKO,SAAS,8BAAA,CACd,SACA,eAAA,EACM;AACN,EAAA,IAAI,EAAE,OAAA,IAAW,OAAA,CAAA,IAAY,OAAO,OAAA,CAAQ,UAAU,UAAA,EAAY;AAChE,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,KAAA,GAAQC,6BAAA;AAAA,IACd,OAAA,CAAQ,KAAA;AAAA,IACR,CAAA,QAAA,KACE,IAAI,KAAA,CAAM,QAAA,EAAU;AAAA,MAClB,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAA2C;AAChE,QAAA,MAAM,CAAC,YAAA,EAAc,GAAA,EAAK,GAAG,CAAA,GAAI,IAAA;AACjC,QAAA,MAAM,OAAA,GAAUC,oCAAkB,GAAG,CAAA;AACrC,QAAA,MAAMC,SAAA,GAAUC,uBAAA,CAAgB,eAAA,CAAgB,GAAG,GAAG,GAAG,CAAA;AACzD,QAAA,IAAA,CAAK,CAAC,CAAA,GAAIC,2BAAA,CAAc,GAAA,EAAKF,SAAO,CAAA;AACpC,QAAA,IAAA,CAAK,CAAC,CAAA,GAAI,OAAA;AAEV,QAAA,OAAO,gBAAA,CAAiB,cAAcA,SAAA,EAAS,OAAA,EAAS,MAAM,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA,MAC3F;AAAA,KACD;AAAA,GACL;AACF;;;;"}
@@ -19,15 +19,20 @@ function wrapScheduledHandler(controller, options, context, fn) {
19
19
  const client = sdk.init({ ...options, ctx: context });
20
20
  isolationScope.setClient(client);
21
21
  scopeUtils.addCloudResourceContext(isolationScope);
22
+ const description = `Scheduled Cron ${controller.cron}`;
22
23
  return core.startSpan(
23
24
  {
24
- name: `Scheduled Cron ${controller.cron}`,
25
+ name: client && core.hasSpanStreamingEnabled(client) ? "scheduled" : description,
25
26
  attributes: {
26
27
  [attributes.SENTRY_OP]: op.FUNCTION,
27
- "faas.cron": controller.cron,
28
- "faas.time": new Date(controller.scheduledTime).toISOString(),
29
- "faas.trigger": "timer",
30
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.faas.cloudflare.scheduled",
28
+ // override description inference by Relay to preserve the original (transaction-based) description.
29
+ // sentry-conventions can't map the special case for the "Scheduled Cron" prefix and the chron string.
30
+ [attributes.SENTRY_DESCRIPTION]: description,
31
+ [attributes.CODE_FUNCTION_NAME]: "scheduled",
32
+ [attributes.FAAS_CRON]: controller.cron,
33
+ [attributes.FAAS_TIME]: new Date(controller.scheduledTime).toISOString(),
34
+ [attributes.FAAS_TRIGGER]: "timer",
35
+ [attributes.SENTRY_ORIGIN]: "auto.faas.cloudflare.scheduled",
31
36
  [attributes.SENTRY_SEGMENT_NAME_SOURCE]: "task"
32
37
  }
33
38
  },
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentScheduled.js","sources":["../../../../../src/instrumentations/worker/instrumentScheduled.ts"],"sourcesContent":["import type { ScheduledController } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport { SENTRY_SEGMENT_NAME_SOURCE, SENTRY_OP } from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\nfunction wrapScheduledHandler(\n controller: ScheduledController,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n return startSpan(\n {\n name: `Scheduled Cron ${controller.cron}`,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n 'faas.cron': controller.cron,\n 'faas.time': new Date(controller.scheduledTime).toISOString(),\n 'faas.trigger': 'timer',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.scheduled' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a scheduled handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerScheduled<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('scheduled' in handler) || typeof handler.scheduled !== 'function') {\n return;\n }\n\n handler.scheduled = ensureInstrumented(\n handler.scheduled,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['scheduled']>>) {\n const [controller, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapScheduledHandler(controller, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n\n/**\n * Instruments a scheduled method for WorkerEntrypoint (options/context already available).\n */\nexport function instrumentWorkerEntrypointScheduled<T extends WorkerEntrypoint>(\n instance: T,\n options: CloudflareOptions,\n context: ExecutionContext,\n): void {\n if (!instance.scheduled) {\n return;\n }\n\n const original = instance.scheduled.bind(instance);\n instance.scheduled = new Proxy(original, {\n apply(target, thisArg, args: [ScheduledController]) {\n const [controller] = args;\n\n return wrapScheduledHandler(controller, options, context, () => Reflect.apply(target, thisArg, args));\n },\n });\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","SENTRY_OP","FUNCTION","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":"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"}
1
+ {"version":3,"file":"instrumentScheduled.js","sources":["../../../../../src/instrumentations/worker/instrumentScheduled.ts"],"sourcesContent":["import type { ScheduledController } from '@cloudflare/workers-types';\nimport type { AnyExportedHandler } from '../../types';\nimport type { env as cloudflareEnv, WorkerEntrypoint } from 'cloudflare:workers';\nimport {\n SENTRY_SEGMENT_NAME_SOURCE,\n CODE_FUNCTION_NAME,\n SENTRY_OP,\n FAAS_CRON,\n FAAS_TIME,\n FAAS_TRIGGER,\n SENTRY_DESCRIPTION,\n SENTRY_ORIGIN,\n} from '@sentry/conventions/attributes';\nimport { FUNCTION } from '@sentry/conventions/op';\nimport { captureException, hasSpanStreamingEnabled, startSpan, withIsolationScope } from '@sentry/core';\nimport type { CloudflareOptions } from '../../client';\nimport { flushAndDispose } from '../../flush';\nimport { ensureInstrumented } from '../../instrument';\nimport { getFinalOptions } from '../../options';\nimport { addCloudResourceContext } from '../../scope-utils';\nimport { init } from '../../sdk';\nimport { instrumentContext } from '../../utils/instrumentContext';\nimport { setInvocationState } from '../../utils/invocationContext';\nimport { instrumentEnv } from './instrumentEnv';\n\nfunction wrapScheduledHandler(\n controller: ScheduledController,\n options: CloudflareOptions,\n context: ExecutionContext,\n fn: () => unknown,\n): unknown {\n return withIsolationScope(isolationScope => {\n const waitUntil = context.waitUntil.bind(context);\n\n setInvocationState(isolationScope, { ctx: context });\n\n const client = init({ ...options, ctx: context });\n isolationScope.setClient(client);\n\n addCloudResourceContext(isolationScope);\n\n const description = `Scheduled Cron ${controller.cron}`;\n\n return startSpan(\n {\n name: client && hasSpanStreamingEnabled(client) ? 'scheduled' : description,\n attributes: {\n [SENTRY_OP]: FUNCTION,\n // override description inference by Relay to preserve the original (transaction-based) description.\n // sentry-conventions can't map the special case for the \"Scheduled Cron\" prefix and the chron string.\n [SENTRY_DESCRIPTION]: description,\n [CODE_FUNCTION_NAME]: 'scheduled',\n [FAAS_CRON]: controller.cron,\n [FAAS_TIME]: new Date(controller.scheduledTime).toISOString(),\n [FAAS_TRIGGER]: 'timer',\n [SENTRY_ORIGIN]: 'auto.faas.cloudflare.scheduled',\n [SENTRY_SEGMENT_NAME_SOURCE]: 'task',\n },\n },\n async () => {\n try {\n return await fn();\n } catch (e) {\n captureException(e, { mechanism: { handled: false, type: 'auto.faas.cloudflare.scheduled' } });\n throw e;\n } finally {\n waitUntil(flushAndDispose(client));\n }\n },\n );\n });\n}\n\n/**\n * Instruments a scheduled handler for ExportedHandler (env/ctx come from args).\n */\nexport function instrumentExportedHandlerScheduled<T extends AnyExportedHandler>(\n handler: T,\n optionsCallback: (env: typeof cloudflareEnv) => CloudflareOptions | undefined,\n): void {\n if (!('scheduled' in handler) || typeof handler.scheduled !== 'function') {\n return;\n }\n\n handler.scheduled = ensureInstrumented(\n handler.scheduled,\n original =>\n new Proxy(original, {\n apply(target, thisArg, args: Parameters<NonNullable<T['scheduled']>>) {\n const [controller, env, ctx] = args;\n const context = instrumentContext(ctx);\n const options = getFinalOptions(optionsCallback(env), env);\n args[1] = instrumentEnv(env, options);\n args[2] = context;\n\n return wrapScheduledHandler(controller, options, context, () => target.apply(thisArg, args));\n },\n }),\n );\n}\n\n/**\n * Instruments a scheduled method for WorkerEntrypoint (options/context already available).\n */\nexport function instrumentWorkerEntrypointScheduled<T extends WorkerEntrypoint>(\n instance: T,\n options: CloudflareOptions,\n context: ExecutionContext,\n): void {\n if (!instance.scheduled) {\n return;\n }\n\n const original = instance.scheduled.bind(instance);\n instance.scheduled = new Proxy(original, {\n apply(target, thisArg, args: [ScheduledController]) {\n const [controller] = args;\n\n return wrapScheduledHandler(controller, options, context, () => Reflect.apply(target, thisArg, args));\n },\n });\n}\n"],"names":["withIsolationScope","setInvocationState","init","addCloudResourceContext","startSpan","hasSpanStreamingEnabled","SENTRY_OP","FUNCTION","SENTRY_DESCRIPTION","CODE_FUNCTION_NAME","FAAS_CRON","FAAS_TIME","FAAS_TRIGGER","SENTRY_ORIGIN","SENTRY_SEGMENT_NAME_SOURCE","captureException","flushAndDispose","ensureInstrumented","instrumentContext","options","getFinalOptions","instrumentEnv"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const debugBuild = require('./debug-build.js');
5
+
6
+ const deferred = [];
7
+ const DEFERRED = /* @__PURE__ */ Symbol("sentryOrchestrionDeferred");
8
+ function isGlobalScopeError(error) {
9
+ return error instanceof Error && /within global scope/.test(error.message);
10
+ }
11
+ function deferChannelEvent(channel, ctx) {
12
+ if (ctx[DEFERRED]) {
13
+ return;
14
+ }
15
+ ctx[DEFERRED] = true;
16
+ deferred.push({ channel, ctx, hadError: "error" in ctx });
17
+ }
18
+ function flushDeferredChannelEvents() {
19
+ if (deferred.length === 0) {
20
+ return;
21
+ }
22
+ const pending = deferred.splice(0, deferred.length);
23
+ for (const { channel, ctx, hadError } of pending) {
24
+ try {
25
+ channel.start.publish(ctx);
26
+ if (hadError) {
27
+ channel.error.publish(ctx);
28
+ }
29
+ channel.end.publish(ctx);
30
+ } catch (error) {
31
+ debugBuild.DEBUG_BUILD && core.debug.warn("[orchestrion] failed to emit a deferred channel event", error);
32
+ }
33
+ }
34
+ }
35
+
36
+ exports.deferChannelEvent = deferChannelEvent;
37
+ exports.flushDeferredChannelEvents = flushDeferredChannelEvents;
38
+ exports.isGlobalScopeError = isGlobalScopeError;
39
+ //# sourceMappingURL=orchestrion-deferred-channels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrion-deferred-channels.js","sources":["../../../src/orchestrion-deferred-channels.ts"],"sourcesContent":["/**\n * Deferral for orchestrion channel events that could not be published when they occurred.\n *\n * On workerd, `channel.publish()`/`runStores()` throw at module/global scope, so a library\n * instantiated at module scope (`const app = new Hono()`) cannot emit its wrapping event\n * there. {@link ./orchestrion-diagnostics-channel} defers those events here;\n * {@link flushDeferredChannelEvents} emits them once a request is being handled (where\n * publish works) and the SDK's `init()` has registered subscribers.\n *\n * This module imports NO `node:*` builtin, so it is safe to pull into the request wrapper on\n * runtimes without `nodejs_compat` — there the queue is always empty (no channels were ever\n * injected) and the flush is a no-op.\n */\nimport { debug } from '@sentry/core';\nimport { DEBUG_BUILD } from './debug-build';\n\ntype Ctx = Record<string, unknown>;\n\n// The minimal slice of a `node:diagnostics_channel` TracingChannel we emit on. Declared locally\n// (rather than imported from `node:diagnostics_channel`) so this module's graph carries no `node:`\n// specifier — `wrapRequestHandler` must load on runtimes without `nodejs_compat`, and the\n// module-graph test forbids any `node:` import reachable from it.\ninterface PublishableTracingChannel {\n start: { publish(ctx: Ctx): void };\n end: { publish(ctx: Ctx): void };\n error: { publish(ctx: Ctx): void };\n}\n\ninterface DeferredChannelEvent {\n channel: PublishableTracingChannel;\n ctx: Ctx;\n hadError: boolean;\n}\n\nconst deferred: DeferredChannelEvent[] = [];\nconst DEFERRED = Symbol('sentryOrchestrionDeferred');\n\n/** workerd's global-scope guard is the only error we degrade on; anything else is a real fault. */\nexport function isGlobalScopeError(error: unknown): boolean {\n return error instanceof Error && /within global scope/.test(error.message);\n}\n\n/** Queue a channel event that could not be published now, at most once per context object. */\nexport function deferChannelEvent(channel: PublishableTracingChannel, ctx: Ctx): void {\n if ((ctx as Record<symbol, unknown>)[DEFERRED]) {\n return;\n }\n (ctx as Record<symbol, unknown>)[DEFERRED] = true;\n deferred.push({ channel, ctx, hadError: 'error' in ctx });\n}\n\n/**\n * Emit every deferred channel event via the real channel. Called at the top of the request\n * handler, after `init()` has subscribed. Uses bare `start`/`end` publish (never `runStores`),\n * so no `bindStore` producer runs and no span is parented to this request — only the plain\n * subscribers (the instance patchers) fire. Idempotent: it drains the queue, so later requests\n * and re-entrant calls are no-ops.\n */\nexport function flushDeferredChannelEvents(): void {\n if (deferred.length === 0) {\n return;\n }\n const pending = deferred.splice(0, deferred.length);\n for (const { channel, ctx, hadError } of pending) {\n try {\n channel.start.publish(ctx);\n if (hadError) {\n channel.error.publish(ctx);\n }\n channel.end.publish(ctx);\n } catch (error) {\n DEBUG_BUILD && debug.warn('[orchestrion] failed to emit a deferred channel event', error);\n }\n }\n}\n"],"names":["DEBUG_BUILD","debug"],"mappings":";;;;;AAkCA,MAAM,WAAmC,EAAC;AAC1C,MAAM,QAAA,0BAAkB,2BAA2B,CAAA;AAG5C,SAAS,mBAAmB,KAAA,EAAyB;AAC1D,EAAA,OAAO,KAAA,YAAiB,KAAA,IAAS,qBAAA,CAAsB,IAAA,CAAK,MAAM,OAAO,CAAA;AAC3E;AAGO,SAAS,iBAAA,CAAkB,SAAoC,GAAA,EAAgB;AACpF,EAAA,IAAK,GAAA,CAAgC,QAAQ,CAAA,EAAG;AAC9C,IAAA;AAAA,EACF;AACA,EAAC,GAAA,CAAgC,QAAQ,CAAA,GAAI,IAAA;AAC7C,EAAA,QAAA,CAAS,KAAK,EAAE,OAAA,EAAS,KAAK,QAAA,EAAU,OAAA,IAAW,KAAK,CAAA;AAC1D;AASO,SAAS,0BAAA,GAAmC;AACjD,EAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,IAAA;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,SAAS,MAAM,CAAA;AAClD,EAAA,KAAA,MAAW,EAAE,OAAA,EAAS,GAAA,EAAK,QAAA,MAAc,OAAA,EAAS;AAChD,IAAA,IAAI;AACF,MAAA,OAAA,CAAQ,KAAA,CAAM,QAAQ,GAAG,CAAA;AACzB,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAA,CAAQ,KAAA,CAAM,QAAQ,GAAG,CAAA;AAAA,MAC3B;AACA,MAAA,OAAA,CAAQ,GAAA,CAAI,QAAQ,GAAG,CAAA;AAAA,IACzB,SAAS,KAAA,EAAO;AACd,MAAAA,sBAAA,IAAeC,UAAA,CAAM,IAAA,CAAK,uDAAA,EAAyD,KAAK,CAAA;AAAA,IAC1F;AAAA,EACF;AACF;;;;;;"}
@@ -0,0 +1,83 @@
1
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
+
3
+ const realDc = require('node:diagnostics_channel');
4
+ const orchestrionDeferredChannels = require('./orchestrion-deferred-channels.js');
5
+
6
+ const cache = /* @__PURE__ */ new Map();
7
+ function channelHasSubscribers(ch) {
8
+ const value = ch.hasSubscribers;
9
+ return typeof value === "function" ? Boolean(value.call(ch)) : Boolean(value);
10
+ }
11
+ function wrapSubChannel(tracing, real) {
12
+ return {
13
+ name: real.name,
14
+ // A method (not a getter) so it reads truthy as a property in the emit guard *and* is callable,
15
+ // matching workerd's native shape. Forced `true`: on Cloudflare a channel is only injected for a
16
+ // bundled integration, so the wrapper's no-subscriber short-circuit buys nothing — and disabling
17
+ // it is what lets the wrapper run (and reach us) at module scope before `init()` has subscribed.
18
+ hasSubscribers() {
19
+ return true;
20
+ },
21
+ publish(ctx) {
22
+ const hadSubscribers = channelHasSubscribers(real);
23
+ try {
24
+ real.publish(ctx);
25
+ } catch (error) {
26
+ if (!orchestrionDeferredChannels.isGlobalScopeError(error)) {
27
+ throw error;
28
+ }
29
+ if (!hadSubscribers) {
30
+ orchestrionDeferredChannels.deferChannelEvent(tracing, ctx);
31
+ }
32
+ }
33
+ },
34
+ runStores(ctx, fn, ...rest) {
35
+ try {
36
+ return real.runStores(ctx, fn, ...rest);
37
+ } catch (error) {
38
+ if (!orchestrionDeferredChannels.isGlobalScopeError(error)) {
39
+ throw error;
40
+ }
41
+ return fn();
42
+ }
43
+ },
44
+ subscribe: real.subscribe.bind(real),
45
+ unsubscribe: real.unsubscribe.bind(real),
46
+ bindStore: real.bindStore.bind(real),
47
+ unbindStore: real.unbindStore.bind(real)
48
+ };
49
+ }
50
+ function tracingChannel(name) {
51
+ const cached = cache.get(name);
52
+ if (cached) {
53
+ return cached;
54
+ }
55
+ const real = realDc.tracingChannel(name);
56
+ const facade = {
57
+ start: wrapSubChannel(real, real.start),
58
+ end: wrapSubChannel(real, real.end),
59
+ asyncStart: wrapSubChannel(real, real.asyncStart),
60
+ asyncEnd: wrapSubChannel(real, real.asyncEnd),
61
+ error: wrapSubChannel(real, real.error),
62
+ // Iterator (`:next`) channels call these on the tracingChannel itself; delegate to the real
63
+ // implementation (they only run in-request, where publish/runStores are allowed).
64
+ traceSync: real.traceSync.bind(real),
65
+ tracePromise: real.tracePromise.bind(real),
66
+ traceCallback: real.traceCallback.bind(real),
67
+ subscribe: real.subscribe.bind(real),
68
+ unsubscribe: real.unsubscribe.bind(real)
69
+ };
70
+ cache.set(name, facade);
71
+ return facade;
72
+ }
73
+ const channel = realDc.channel;
74
+ const subscribe = realDc.subscribe;
75
+ const unsubscribe = realDc.unsubscribe;
76
+ const orchestrionDiagnosticsChannel = { tracingChannel, channel, subscribe, unsubscribe };
77
+
78
+ exports.channel = channel;
79
+ exports.default = orchestrionDiagnosticsChannel;
80
+ exports.subscribe = subscribe;
81
+ exports.tracingChannel = tracingChannel;
82
+ exports.unsubscribe = unsubscribe;
83
+ //# sourceMappingURL=orchestrion-diagnostics-channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrion-diagnostics-channel.js","sources":["../../../src/orchestrion-diagnostics-channel.ts"],"sourcesContent":["/**\n * A workerd-safe `diagnostics_channel` façade for the orchestrion EMIT side, and the\n * `dcModule` target for the Cloudflare orchestrion build (see `vite/index.ts`): orchestrion's\n * transformed code imports `tracingChannel` from here (its default export) instead of\n * `node:diagnostics_channel`.\n *\n * On workerd, `channel.publish()` and `channel.runStores()` throw at module/global scope\n * (\"Disallowed operation called within global scope …\"); only inside a request handler do they\n * work. `subscribe` and channel creation are fine anywhere. Orchestrion's transformed code emits\n * `start.runStores(...)` / `end.publish(...)` at each wrapped call site, so a library\n * instantiated at module scope (`const app = new Hono()`) throws the moment it is wrapped — or,\n * if no subscriber exists yet, is skipped by the wrapper's `if (!hasSubscribers) return\n * __apm$traced()` short-circuit and never instrumented.\n *\n * This façade delegates to the real `node:diagnostics_channel` singletons — so subscribers, which\n * keep subscribing through `node:diagnostics_channel`, are reached unchanged — and changes two\n * things:\n *\n * 1. `hasSubscribers` always reports `true`, so the wrapper never short-circuits. On Cloudflare a\n * channel is only injected for an integration that is actually bundled, so the short-circuit\n * buys nothing — and disabling it is what lets the wrapper run (and reach us) at module scope,\n * before the per-request cached `init()` has subscribed.\n * 2. When a delegated `publish`/`runStores` throws the global-scope error, the event is queued via\n * {@link deferChannelEvent} instead. {@link flushDeferredChannelEvents}, called at the top of\n * the request handler after `init()`, emits it via the real channel — now inside a request,\n * where publish works.\n *\n * In a request handler nothing throws, so every call is a transparent pass-through to the real\n * channel: lifecycle channels (spans, context binding) behave exactly as on Node.\n */\nimport * as realDc from 'node:diagnostics_channel';\nimport { deferChannelEvent, isGlobalScopeError } from './orchestrion-deferred-channels';\n\ntype Ctx = Record<string, unknown>;\n\n// One façade per channel name (node's `tracingChannel` is itself a per-name singleton), built\n// once when the transformed module declares `const CH = tracingChannel(name)`.\nconst cache = new Map<string, realDc.TracingChannel>();\n\n// `Channel.hasSubscribers` is a getter on Node but a method on workerd — normalize both to a\n// boolean. (This shape difference is also why the emit wrapper never short-circuits on workerd:\n// its `if (!ch.start.hasSubscribers)` guard reads a truthy method reference.)\nfunction channelHasSubscribers(ch: realDc.Channel): boolean {\n const value = (ch as { hasSubscribers: unknown }).hasSubscribers;\n return typeof value === 'function' ? Boolean((value as () => unknown).call(ch)) : Boolean(value);\n}\n\nfunction wrapSubChannel(tracing: realDc.TracingChannel, real: realDc.Channel): realDc.Channel {\n return {\n name: real.name,\n // A method (not a getter) so it reads truthy as a property in the emit guard *and* is callable,\n // matching workerd's native shape. Forced `true`: on Cloudflare a channel is only injected for a\n // bundled integration, so the wrapper's no-subscriber short-circuit buys nothing — and disabling\n // it is what lets the wrapper run (and reach us) at module scope before `init()` has subscribed.\n hasSubscribers(): boolean {\n return true;\n },\n publish(ctx: Ctx): void {\n // Snapshot subscriber presence before publishing — it decides whether to defer if the\n // global-scope error fires below.\n const hadSubscribers = channelHasSubscribers(real);\n try {\n real.publish(ctx);\n } catch (error) {\n if (!isGlobalScopeError(error)) {\n throw error;\n }\n // We're at module scope (workerd throws here even with no subscribers). If someone was\n // already subscribed — top-level `Sentry.init()` — workerd delivered to them before\n // throwing, so they got it exactly once; don't defer. Otherwise — the common per-request\n // cached-init case — nobody received it, so defer for a subscriber that registers later\n // (at `init()`), which then gets it exactly once. In a request `publish` doesn't throw,\n // so this path never defers a normal in-request event.\n if (!hadSubscribers) {\n deferChannelEvent(tracing, ctx);\n }\n }\n },\n runStores(ctx: Ctx, fn: (...args: unknown[]) => unknown, ...rest: unknown[]): unknown {\n try {\n return real.runStores(ctx, fn, ...rest);\n } catch (error) {\n if (!isGlobalScopeError(error)) {\n throw error;\n }\n // publish() is gated too, so the store can't be established — just run the wrapped call\n // so its return value (e.g. the constructed instance) is produced now. Its own\n // `end.publish` runs back through this façade and is deferred.\n return fn();\n }\n },\n subscribe: real.subscribe.bind(real),\n unsubscribe: real.unsubscribe.bind(real),\n bindStore: real.bindStore.bind(real),\n unbindStore: real.unbindStore.bind(real),\n } as unknown as realDc.Channel;\n}\n\nexport function tracingChannel<T = Ctx>(name: string): realDc.TracingChannel<T> {\n const cached = cache.get(name);\n if (cached) {\n return cached;\n }\n\n const real = realDc.tracingChannel(name);\n const facade = {\n start: wrapSubChannel(real, real.start),\n end: wrapSubChannel(real, real.end),\n asyncStart: wrapSubChannel(real, real.asyncStart),\n asyncEnd: wrapSubChannel(real, real.asyncEnd),\n error: wrapSubChannel(real, real.error),\n // Iterator (`:next`) channels call these on the tracingChannel itself; delegate to the real\n // implementation (they only run in-request, where publish/runStores are allowed).\n traceSync: real.traceSync.bind(real),\n tracePromise: real.tracePromise.bind(real),\n traceCallback: real.traceCallback.bind(real),\n subscribe: real.subscribe.bind(real),\n unsubscribe: real.unsubscribe.bind(real),\n } as unknown as realDc.TracingChannel<T>;\n\n cache.set(name, facade);\n return facade;\n}\n\nexport const channel = realDc.channel;\nexport const subscribe = realDc.subscribe;\nexport const unsubscribe = realDc.unsubscribe;\n\n// Orchestrion's emit imports the default and destructures `tracingChannel`.\nexport default { tracingChannel, channel, subscribe, unsubscribe };\n"],"names":["isGlobalScopeError","deferChannelEvent"],"mappings":"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"}
@@ -2,12 +2,17 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const vite = require('@sentry/server-utils/orchestrion/vite');
4
4
  const autoInstrument = require('./autoInstrument.js');
5
+ const mastraObservability = require('./mastraObservability.js');
5
6
 
6
7
  function sentryCloudflareVitePlugin(options = {}) {
7
8
  return [
8
9
  vite.sentryOrchestrionPlugin({
9
- buildTimeInstrumentation: options.buildTimeInstrumentation
10
+ buildTimeInstrumentation: options.buildTimeInstrumentation,
11
+ // Route the injected `tracingChannel` imports through the workerd-safe façade so a
12
+ // dependency wrapped at module scope (`const app = new Hono()`) doesn't throw on workerd.
13
+ dcModule: "@sentry/cloudflare/orchestrion-diagnostics-channel"
10
14
  }),
15
+ mastraObservability.sentryMastraObservabilityProviderPlugin(),
11
16
  ...options.autoInstrumentation !== false ? [autoInstrument.sentryCloudflareAutoInstrumentPlugin({ wranglerConfigPath: options.wranglerConfigPath })] : []
12
17
  ];
13
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/vite/index.ts"],"sourcesContent":["// Published ESM-only via the `@sentry/cloudflare/vite` subpath export:\n// `@sentry/server-utils/orchestrion/vite` exposes no `require` condition, so a\n// CJS entry here would fail at resolution time (ERR_PACKAGE_PATH_NOT_EXPORTED).\n// The CJS rollup variant still emits this file, but `package.json` doesn't\n// expose it — same setup as `@sentry/server-utils/orchestrion/vite` itself.\nimport { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';\nimport { sentryCloudflareAutoInstrumentPlugin } from './autoInstrument';\n\n/**\n * Options for {@link sentryCloudflareVitePlugin}.\n */\nexport interface SentryCloudflareVitePluginOptions {\n /**\n * Path to the wrangler config, relative to the Vite root (or absolute).\n * Set this when your config doesn't use a default name — e.g. when you\n * pass `configPath: './wrangler.agent.jsonc'` to `@cloudflare/vite-plugin`,\n * which the Sentry plugin cannot see. When set, only this file is read\n * (no default-name probing), and a warning is emitted if it is missing or\n * unparseable.\n *\n * @default undefined (probes `wrangler.json`, `wrangler.jsonc`, `wrangler.toml` at the Vite root)\n */\n wranglerConfigPath?: string;\n /**\n * Build-time automatic instrumentation of supported dependencies (e.g.\n * database clients like `mysql`) so the Sentry Cloudflare SDK can trace them\n * without monkey-patching, which wouldn't work in workerd anyway.\n *\n * When enabled, the plugin injects `diagnostics_channel.tracingChannel` calls\n * into the bundled packages and, next to each, a snippet that registers the\n * matching Sentry channel-subscriber factory on the global marker, which the\n * SDK picks up in `Sentry.withSentry()`. Both `vite build` and `vite dev` are\n * instrumented. Set to `false` to opt out.\n *\n * @default true\n */\n buildTimeInstrumentation?: boolean;\n /**\n * Automatically wraps your Worker at build time so you don't have to edit\n * your entry: the plugin reads your wrangler config, wraps the default\n * export with `Sentry.withSentry()` (sourcing options from a co-located\n * `instrument.*` file, falling back to env), and wraps any configured\n * Durable Object class with `instrumentDurableObjectWithSentry`. Both\n * `vite build` and `vite dev` are instrumented. Already-wrapped entries are\n * left alone, so this is safe alongside manual instrumentation. Set to\n * `false` to opt out.\n *\n * The plugin also adds the bindings that resolve to the wrapped classes (this worker's own\n * Durable Objects and self service bindings) to `rpcTracePropagationBindings`. Bindings to\n * other workers stay opt-in, their receivers may not run Sentry.\n *\n * @default true\n */\n autoInstrumentation?: boolean;\n}\n\n/**\n * Sentry Vite plugin for Cloudflare Workers.\n *\n * Add this plugin to your Vite configuration to enable additional Sentry\n * instrumentation for Cloudflare Workers built with Vite.\n *\n * By default, the plugin\n * - build-time instruments supported dependencies (such as database clients) so\n * they are traced without changing your application code — opt out with\n * `buildTimeInstrumentation: false`, and\n * - wraps your Worker entry (and any Durable Object, Workflow or\n * WorkerEntrypoint class in your wrangler config) with the matching Sentry\n * helper — opt out with `autoInstrumentation: false` and call\n * `Sentry.withSentry()` yourself.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { cloudflare } from '@cloudflare/vite-plugin';\n * import { sentryCloudflareVitePlugin } from '@sentry/cloudflare/vite';\n * import { defineConfig } from 'vite';\n *\n * export default defineConfig({\n * plugins: [cloudflare(), sentryCloudflareVitePlugin()],\n * });\n * ```\n */\nexport function sentryCloudflareVitePlugin(options: SentryCloudflareVitePluginOptions = {}): Array<{ name: string }> {\n return [\n sentryOrchestrionPlugin({\n buildTimeInstrumentation: options.buildTimeInstrumentation,\n }),\n ...(options.autoInstrumentation !== false\n ? [sentryCloudflareAutoInstrumentPlugin({ wranglerConfigPath: options.wranglerConfigPath })]\n : []),\n ];\n}\n"],"names":["sentryOrchestrionPlugin","sentryCloudflareAutoInstrumentPlugin"],"mappings":";;;;;AAmFO,SAAS,0BAAA,CAA2B,OAAA,GAA6C,EAAC,EAA4B;AACnH,EAAA,OAAO;AAAA,IACLA,4BAAA,CAAwB;AAAA,MACtB,0BAA0B,OAAA,CAAQ;AAAA,KACnC,CAAA;AAAA,IACD,GAAI,OAAA,CAAQ,mBAAA,KAAwB,KAAA,GAChC,CAACC,mDAAA,CAAqC,EAAE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,EAAoB,CAAC,IACzF;AAAC,GACP;AACF;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/vite/index.ts"],"sourcesContent":["// Published ESM-only via the `@sentry/cloudflare/vite` subpath export:\n// `@sentry/server-utils/orchestrion/vite` exposes no `require` condition, so a\n// CJS entry here would fail at resolution time (ERR_PACKAGE_PATH_NOT_EXPORTED).\n// The CJS rollup variant still emits this file, but `package.json` doesn't\n// expose it — same setup as `@sentry/server-utils/orchestrion/vite` itself.\nimport { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';\nimport { sentryCloudflareAutoInstrumentPlugin } from './autoInstrument';\nimport { sentryMastraObservabilityProviderPlugin } from './mastraObservability';\n\n/**\n * Options for {@link sentryCloudflareVitePlugin}.\n */\nexport interface SentryCloudflareVitePluginOptions {\n /**\n * Path to the wrangler config, relative to the Vite root (or absolute).\n * Set this when your config doesn't use a default name — e.g. when you\n * pass `configPath: './wrangler.agent.jsonc'` to `@cloudflare/vite-plugin`,\n * which the Sentry plugin cannot see. When set, only this file is read\n * (no default-name probing), and a warning is emitted if it is missing or\n * unparseable.\n *\n * @default undefined (probes `wrangler.json`, `wrangler.jsonc`, `wrangler.toml` at the Vite root)\n */\n wranglerConfigPath?: string;\n /**\n * Build-time automatic instrumentation of supported dependencies (e.g.\n * database clients like `mysql`) so the Sentry Cloudflare SDK can trace them\n * without monkey-patching, which wouldn't work in workerd anyway.\n *\n * When enabled, the plugin injects `diagnostics_channel.tracingChannel` calls\n * into the bundled packages and, next to each, a snippet that registers the\n * matching Sentry channel-subscriber factory on the global marker, which the\n * SDK picks up in `Sentry.withSentry()`. Both `vite build` and `vite dev` are\n * instrumented. Set to `false` to opt out.\n *\n * @default true\n */\n buildTimeInstrumentation?: boolean;\n /**\n * Automatically wraps your Worker at build time so you don't have to edit\n * your entry: the plugin reads your wrangler config, wraps the default\n * export with `Sentry.withSentry()` (sourcing options from a co-located\n * `instrument.*` file, falling back to env), and wraps any configured\n * Durable Object class with `instrumentDurableObjectWithSentry`. Both\n * `vite build` and `vite dev` are instrumented. Already-wrapped entries are\n * left alone, so this is safe alongside manual instrumentation. Set to\n * `false` to opt out.\n *\n * The plugin also adds the bindings that resolve to the wrapped classes (this worker's own\n * Durable Objects and self service bindings) to `rpcTracePropagationBindings`. Bindings to\n * other workers stay opt-in, their receivers may not run Sentry.\n *\n * @default true\n */\n autoInstrumentation?: boolean;\n}\n\n/**\n * Sentry Vite plugin for Cloudflare Workers.\n *\n * Add this plugin to your Vite configuration to enable additional Sentry\n * instrumentation for Cloudflare Workers built with Vite.\n *\n * By default, the plugin\n * - build-time instruments supported dependencies (such as database clients) so\n * they are traced without changing your application code — opt out with\n * `buildTimeInstrumentation: false`, and\n * - wraps your Worker entry (and any Durable Object, Workflow or\n * WorkerEntrypoint class in your wrangler config) with the matching Sentry\n * helper — opt out with `autoInstrumentation: false` and call\n * `Sentry.withSentry()` yourself.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { cloudflare } from '@cloudflare/vite-plugin';\n * import { sentryCloudflareVitePlugin } from '@sentry/cloudflare/vite';\n * import { defineConfig } from 'vite';\n *\n * export default defineConfig({\n * plugins: [cloudflare(), sentryCloudflareVitePlugin()],\n * });\n * ```\n */\nexport function sentryCloudflareVitePlugin(options: SentryCloudflareVitePluginOptions = {}): Array<{ name: string }> {\n return [\n sentryOrchestrionPlugin({\n buildTimeInstrumentation: options.buildTimeInstrumentation,\n // Route the injected `tracingChannel` imports through the workerd-safe façade so a\n // dependency wrapped at module scope (`const app = new Hono()`) doesn't throw on workerd.\n dcModule: '@sentry/cloudflare/orchestrion-diagnostics-channel',\n }),\n sentryMastraObservabilityProviderPlugin(),\n ...(options.autoInstrumentation !== false\n ? [sentryCloudflareAutoInstrumentPlugin({ wranglerConfigPath: options.wranglerConfigPath })]\n : []),\n ];\n}\n"],"names":["sentryOrchestrionPlugin","sentryMastraObservabilityProviderPlugin","sentryCloudflareAutoInstrumentPlugin"],"mappings":";;;;;;AAoFO,SAAS,0BAAA,CAA2B,OAAA,GAA6C,EAAC,EAA4B;AACnH,EAAA,OAAO;AAAA,IACLA,4BAAA,CAAwB;AAAA,MACtB,0BAA0B,OAAA,CAAQ,wBAAA;AAAA;AAAA;AAAA,MAGlC,QAAA,EAAU;AAAA,KACX,CAAA;AAAA,IACDC,2DAAA,EAAwC;AAAA,IACxC,GAAI,OAAA,CAAQ,mBAAA,KAAwB,KAAA,GAChC,CAACC,mDAAA,CAAqC,EAAE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,EAAoB,CAAC,IACzF;AAAC,GACP;AACF;;;;"}
@@ -0,0 +1,39 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const node_module = require('node:module');
4
+ const node_path = require('node:path');
5
+ const MagicString = require('magic-string');
6
+
7
+ const PROVIDER_IDENTIFIER = "__SENTRY_MASTRA_OBSERVABILITY__";
8
+ const MASTRA_INTEGRATION_ID = /@sentry\/server-utils\/build\/esm\/integrations\/mastra\.js$/;
9
+ function isMastraIntegrationModuleId(id) {
10
+ const normalizedId = id.replace(/\\/g, "/").replace(/[?#].*$/, "");
11
+ return MASTRA_INTEGRATION_ID.test(normalizedId);
12
+ }
13
+ function sentryMastraObservabilityProviderPlugin() {
14
+ let providerSnippet;
15
+ return {
16
+ name: "sentry-cloudflare-mastra-observability-provider",
17
+ configResolved(config) {
18
+ try {
19
+ node_module.createRequire(node_path.resolve(config.root, "noop.js")).resolve("@mastra/observability");
20
+ } catch {
21
+ return;
22
+ }
23
+ providerSnippet = `import * as ${PROVIDER_IDENTIFIER} from '@mastra/observability';
24
+ (globalThis.__SENTRY_ORCHESTRION__ = globalThis.__SENTRY_ORCHESTRION__ || {});
25
+ (globalThis.__SENTRY_ORCHESTRION__.providedModules = globalThis.__SENTRY_ORCHESTRION__.providedModules || {})['@mastra/observability'] = ${PROVIDER_IDENTIFIER};
26
+ `;
27
+ },
28
+ transform(code, id) {
29
+ if (!providerSnippet || !isMastraIntegrationModuleId(id)) return void 0;
30
+ const ms = new MagicString.default(code);
31
+ ms.prepend(providerSnippet);
32
+ return { code: ms.toString(), map: ms.generateMap({ hires: true }) };
33
+ }
34
+ };
35
+ }
36
+
37
+ exports.isMastraIntegrationModuleId = isMastraIntegrationModuleId;
38
+ exports.sentryMastraObservabilityProviderPlugin = sentryMastraObservabilityProviderPlugin;
39
+ //# sourceMappingURL=mastraObservability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mastraObservability.js","sources":["../../../../src/vite/mastraObservability.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\nimport MagicString from 'magic-string';\n\n// Namespace binding the injected provider import uses; read back by the integration\n// off the global marker.\nconst PROVIDER_IDENTIFIER = '__SENTRY_MASTRA_OBSERVABILITY__';\n\n// The bundled `@sentry/server-utils` Mastra integration module (ESM build — the only\n// one a worker loads). Its `loadMastraObservability` reads `@mastra/observability` off\n// the global marker this provider populates, instead of `createRequire`, which cannot\n// resolve a package inside a bundled worker.\nconst MASTRA_INTEGRATION_ID = /@sentry\\/server-utils\\/build\\/esm\\/integrations\\/mastra\\.js$/;\n\n/** Whether `id` is the Sentry Mastra integration module the provider injects into. */\nexport function isMastraIntegrationModuleId(id: string): boolean {\n const normalizedId = id.replace(/\\\\/g, '/').replace(/[?#].*$/, '');\n return MASTRA_INTEGRATION_ID.test(normalizedId);\n}\n\n/**\n * Splices a static `import * as … from '@mastra/observability'` into Sentry's own\n * Mastra integration module and stashes the namespace on the global orchestrion\n * marker.\n *\n * On Cloudflare the integration cannot `createRequire('@mastra/observability')` to\n * bootstrap Mastra's observability pipeline — there is no on-disk `node_modules` in\n * workerd — so without this the user has to construct and wire up an `Observability`\n * themselves. The import is static (statically analyzable, no lazy `import()`), lands\n * in Sentry's module rather than the user's code, and is only emitted when the package\n * actually resolves; if it is absent, the integration keeps its Node `createRequire`\n * fallback and the marker stays empty.\n */\nexport function sentryMastraObservabilityProviderPlugin(): {\n name: string;\n configResolved(config: { root: string }): void;\n transform(code: string, id: string): { code: string; map: ReturnType<MagicString['generateMap']> } | undefined;\n} {\n let providerSnippet: string | undefined;\n\n return {\n name: 'sentry-cloudflare-mastra-observability-provider',\n\n configResolved(config: { root: string }): void {\n // Resolved at build time (Node), so this `createRequire` never ships to the worker.\n try {\n createRequire(resolve(config.root, 'noop.js')).resolve('@mastra/observability');\n } catch {\n return;\n }\n providerSnippet =\n `import * as ${PROVIDER_IDENTIFIER} from '@mastra/observability';\\n` +\n '(globalThis.__SENTRY_ORCHESTRION__ = globalThis.__SENTRY_ORCHESTRION__ || {});\\n' +\n '(globalThis.__SENTRY_ORCHESTRION__.providedModules = globalThis.__SENTRY_ORCHESTRION__.providedModules || {})' +\n `['@mastra/observability'] = ${PROVIDER_IDENTIFIER};\\n`;\n },\n\n transform(code: string, id: string): { code: string; map: ReturnType<MagicString['generateMap']> } | undefined {\n if (!providerSnippet || !isMastraIntegrationModuleId(id)) return undefined;\n\n const ms = new MagicString(code);\n ms.prepend(providerSnippet);\n return { code: ms.toString(), map: ms.generateMap({ hires: true }) };\n },\n };\n}\n"],"names":["createRequire","resolve","MagicString"],"mappings":";;;;;;AAMA,MAAM,mBAAA,GAAsB,iCAAA;AAM5B,MAAM,qBAAA,GAAwB,8DAAA;AAGvB,SAAS,4BAA4B,EAAA,EAAqB;AAC/D,EAAA,MAAM,YAAA,GAAe,GAAG,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,WAAW,EAAE,CAAA;AACjE,EAAA,OAAO,qBAAA,CAAsB,KAAK,YAAY,CAAA;AAChD;AAeO,SAAS,uCAAA,GAId;AACA,EAAA,IAAI,eAAA;AAEJ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,iDAAA;AAAA,IAEN,eAAe,MAAA,EAAgC;AAE7C,MAAA,IAAI;AACF,QAAAA,yBAAA,CAAcC,kBAAQ,MAAA,CAAO,IAAA,EAAM,SAAS,CAAC,CAAA,CAAE,QAAQ,uBAAuB,CAAA;AAAA,MAChF,CAAA,CAAA,MAAQ;AACN,QAAA;AAAA,MACF;AACA,MAAA,eAAA,GACE,eAAe,mBAAmB,CAAA;AAAA;AAAA,yIAAA,EAGH,mBAAmB,CAAA;AAAA,CAAA;AAAA,IACtD,CAAA;AAAA,IAEA,SAAA,CAAU,MAAc,EAAA,EAAuF;AAC7G,MAAA,IAAI,CAAC,eAAA,IAAmB,CAAC,2BAAA,CAA4B,EAAE,GAAG,OAAO,MAAA;AAEjE,MAAA,MAAM,EAAA,GAAK,IAAIC,mBAAA,CAAY,IAAI,CAAA;AAC/B,MAAA,EAAA,CAAG,QAAQ,eAAe,CAAA;AAC1B,MAAA,OAAO,EAAE,IAAA,EAAM,EAAA,CAAG,QAAA,EAAS,EAAG,GAAA,EAAK,EAAA,CAAG,WAAA,CAAY,EAAE,KAAA,EAAO,IAAA,EAAM,CAAA,EAAE;AAAA,IACrE;AAAA,GACF;AACF;;;;;"}
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ const attributes = require('@sentry/conventions/attributes');
4
+ const op = require('@sentry/conventions/op');
3
5
  const core = require('@sentry/core');
4
6
  const flush = require('./flush.js');
5
7
  const instrument = require('./instrument.js');
@@ -92,12 +94,14 @@ function wrapMethodWithSentry(wrapperOptions, handler, callback, noMark) {
92
94
  return onRejected(e);
93
95
  }
94
96
  }
95
- const attributes = wrapperOptions.spanOp ? {
96
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: wrapperOptions.spanOp,
97
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: origin
97
+ const attributes$1 = wrapperOptions.spanOp ? {
98
+ [attributes.SENTRY_OP]: wrapperOptions.spanOp,
99
+ [attributes.SENTRY_ORIGIN]: origin,
100
+ // `function` spans are already named like their function name, so we just set `code.function.name` here.
101
+ ...wrapperOptions.spanOp === op.FUNCTION && { [attributes.CODE_FUNCTION_NAME]: methodName }
98
102
  } : {};
99
103
  const executeSpan = () => {
100
- return core.startSpan({ name: methodName, attributes }, (span) => {
104
+ return core.startSpan({ name: methodName, attributes: attributes$1 }, (span) => {
101
105
  if (startNewTrace && storage) {
102
106
  const storedContext = traceLinks.getStoredSpanContext(storage, methodName);
103
107
  if (storedContext) {