@genn-inc/cluebase-frontend-sdk 0.0.1

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 (140) hide show
  1. package/README.md +222 -0
  2. package/dist/_generated/correlation-attribute-keys.d.ts +2 -0
  3. package/dist/_generated/correlation-attribute-keys.js +33 -0
  4. package/dist/_generated/identity-pii-policy.d.ts +38 -0
  5. package/dist/_generated/identity-pii-policy.js +103 -0
  6. package/dist/_generated/ingest-privacy-tables.d.ts +120 -0
  7. package/dist/_generated/ingest-privacy-tables.js +890 -0
  8. package/dist/_generated/otel-resource-keys.d.ts +21 -0
  9. package/dist/_generated/otel-resource-keys.js +72 -0
  10. package/dist/_generated/otel-span-conversion.d.ts +48 -0
  11. package/dist/_generated/otel-span-conversion.js +69 -0
  12. package/dist/_generated/parameter-snapshot-leaf.d.ts +11 -0
  13. package/dist/_generated/parameter-snapshot-leaf.js +37 -0
  14. package/dist/_generated/sdk-runtime-policy.d.ts +7 -0
  15. package/dist/_generated/sdk-runtime-policy.js +14 -0
  16. package/dist/_generated/usage-governor-tables.d.ts +15 -0
  17. package/dist/_generated/usage-governor-tables.js +44 -0
  18. package/dist/context/browser-storage.d.ts +15 -0
  19. package/dist/context/browser-storage.js +38 -0
  20. package/dist/context/environment.d.ts +37 -0
  21. package/dist/context/environment.js +229 -0
  22. package/dist/context/identity.d.ts +16 -0
  23. package/dist/context/identity.js +139 -0
  24. package/dist/context/organization.d.ts +16 -0
  25. package/dist/context/organization.js +60 -0
  26. package/dist/context/session.d.ts +28 -0
  27. package/dist/context/session.js +130 -0
  28. package/dist/context/tab.d.ts +22 -0
  29. package/dist/context/tab.js +117 -0
  30. package/dist/context/trace.d.ts +76 -0
  31. package/dist/context/trace.js +163 -0
  32. package/dist/exporter/batch.d.ts +94 -0
  33. package/dist/exporter/batch.js +485 -0
  34. package/dist/exporter/browser-outbox-records.d.ts +159 -0
  35. package/dist/exporter/browser-outbox-records.js +341 -0
  36. package/dist/exporter/browser-outbox.d.ts +112 -0
  37. package/dist/exporter/browser-outbox.js +876 -0
  38. package/dist/exporter/client.d.ts +92 -0
  39. package/dist/exporter/client.js +541 -0
  40. package/dist/exporter/delivery-response-contract.d.ts +103 -0
  41. package/dist/exporter/delivery-response-contract.js +147 -0
  42. package/dist/exporter/delivery-response.d.ts +37 -0
  43. package/dist/exporter/delivery-response.js +151 -0
  44. package/dist/exporter/diagnostics.d.ts +42 -0
  45. package/dist/exporter/diagnostics.js +148 -0
  46. package/dist/exporter/event-id.d.ts +10 -0
  47. package/dist/exporter/event-id.js +75 -0
  48. package/dist/exporter/frontend-resource.d.ts +20 -0
  49. package/dist/exporter/frontend-resource.js +52 -0
  50. package/dist/exporter/local-minimization.d.ts +29 -0
  51. package/dist/exporter/local-minimization.js +87 -0
  52. package/dist/exporter/observation-source-event-exporter.d.ts +69 -0
  53. package/dist/exporter/observation-source-event-exporter.js +154 -0
  54. package/dist/exporter/parameter-snapshot.d.ts +14 -0
  55. package/dist/exporter/parameter-snapshot.js +215 -0
  56. package/dist/exporter/path-template.d.ts +1 -0
  57. package/dist/exporter/path-template.js +67 -0
  58. package/dist/exporter/raw-event-to-source-signal.d.ts +12 -0
  59. package/dist/exporter/raw-event-to-source-signal.js +297 -0
  60. package/dist/exporter/retry.d.ts +8 -0
  61. package/dist/exporter/retry.js +8 -0
  62. package/dist/exporter/sanitize.d.ts +30 -0
  63. package/dist/exporter/sanitize.js +177 -0
  64. package/dist/exporter/schema-evidence.d.ts +20 -0
  65. package/dist/exporter/schema-evidence.js +232 -0
  66. package/dist/exporter/source-event.d.ts +99 -0
  67. package/dist/exporter/source-event.js +13 -0
  68. package/dist/exporter/span-to-source-signal.d.ts +8 -0
  69. package/dist/exporter/span-to-source-signal.js +174 -0
  70. package/dist/exporter/text-fingerprint.d.ts +9 -0
  71. package/dist/exporter/text-fingerprint.js +16 -0
  72. package/dist/index.d.ts +25 -0
  73. package/dist/index.js +158 -0
  74. package/dist/instrumentation/action.d.ts +2 -0
  75. package/dist/instrumentation/action.js +171 -0
  76. package/dist/instrumentation/cluebase-authored-attributes.d.ts +4 -0
  77. package/dist/instrumentation/cluebase-authored-attributes.js +32 -0
  78. package/dist/instrumentation/common.d.ts +73 -0
  79. package/dist/instrumentation/common.js +90 -0
  80. package/dist/instrumentation/dom.d.ts +63 -0
  81. package/dist/instrumentation/dom.js +640 -0
  82. package/dist/instrumentation/drag.d.ts +2 -0
  83. package/dist/instrumentation/drag.js +82 -0
  84. package/dist/instrumentation/error.d.ts +2 -0
  85. package/dist/instrumentation/error.js +318 -0
  86. package/dist/instrumentation/form.d.ts +2 -0
  87. package/dist/instrumentation/form.js +132 -0
  88. package/dist/instrumentation/input.d.ts +2 -0
  89. package/dist/instrumentation/input.js +180 -0
  90. package/dist/instrumentation/location.d.ts +11 -0
  91. package/dist/instrumentation/location.js +69 -0
  92. package/dist/instrumentation/naming-evidence.d.ts +20 -0
  93. package/dist/instrumentation/naming-evidence.js +11 -0
  94. package/dist/instrumentation/navigation.d.ts +2 -0
  95. package/dist/instrumentation/navigation.js +144 -0
  96. package/dist/instrumentation/network-request.d.ts +103 -0
  97. package/dist/instrumentation/network-request.js +285 -0
  98. package/dist/instrumentation/network-span-attributes.d.ts +25 -0
  99. package/dist/instrumentation/network-span-attributes.js +153 -0
  100. package/dist/instrumentation/network.d.ts +16 -0
  101. package/dist/instrumentation/network.js +502 -0
  102. package/dist/instrumentation/page.d.ts +2 -0
  103. package/dist/instrumentation/page.js +56 -0
  104. package/dist/instrumentation/performance.d.ts +2 -0
  105. package/dist/instrumentation/performance.js +365 -0
  106. package/dist/integrations/next-router.d.ts +16 -0
  107. package/dist/integrations/next-router.js +18 -0
  108. package/dist/integrations/react-router.d.ts +7 -0
  109. package/dist/integrations/react-router.js +61 -0
  110. package/dist/internal/internal-log.d.ts +23 -0
  111. package/dist/internal/internal-log.js +47 -0
  112. package/dist/internal/metrics.d.ts +10 -0
  113. package/dist/internal/metrics.js +50 -0
  114. package/dist/provider/_version.d.ts +1 -0
  115. package/dist/provider/_version.js +3 -0
  116. package/dist/provider/config.d.ts +12 -0
  117. package/dist/provider/config.js +177 -0
  118. package/dist/provider/constants.d.ts +62 -0
  119. package/dist/provider/constants.js +118 -0
  120. package/dist/provider/contracts.d.ts +51 -0
  121. package/dist/provider/contracts.js +46 -0
  122. package/dist/provider/privacy-policy-store.d.ts +20 -0
  123. package/dist/provider/privacy-policy-store.js +56 -0
  124. package/dist/provider/sampling.d.ts +2 -0
  125. package/dist/provider/sampling.js +17 -0
  126. package/dist/provider/sdk-event-pipeline.d.ts +60 -0
  127. package/dist/provider/sdk-event-pipeline.js +478 -0
  128. package/dist/provider/sdk-input-normalization.d.ts +7 -0
  129. package/dist/provider/sdk-input-normalization.js +113 -0
  130. package/dist/provider/sdk-otel-pipeline.d.ts +14 -0
  131. package/dist/provider/sdk-otel-pipeline.js +148 -0
  132. package/dist/provider/sdk-runtime-surfaces.d.ts +49 -0
  133. package/dist/provider/sdk-runtime-surfaces.js +216 -0
  134. package/dist/provider/sdk.d.ts +2 -0
  135. package/dist/provider/sdk.js +614 -0
  136. package/dist/provider/types.d.ts +323 -0
  137. package/dist/provider/types.js +1 -0
  138. package/dist/provider/usage-governor.d.ts +7 -0
  139. package/dist/provider/usage-governor.js +116 -0
  140. package/package.json +59 -0
@@ -0,0 +1,890 @@
1
+ // 自動生成です。**手で編集しないでください。**
2
+ //
3
+ // 正本: packages/cluebase-shared/src/ingest/ingest-privacy-policy.v1.json
4
+ // 出し直す: node scripts/generate-shared-contract-tables.mjs
5
+ //
6
+ // 正本を直したらこの file も一緒に commit してください。CI が
7
+ // `node scripts/generate-shared-contract-tables.mjs --check` で照合し、ずれていれば落とします。
8
+ /** 受付側が、どの許可設定によらず必ず落とす項目名。 */
9
+ export const INGEST_HARD_DENY_KEYS = [
10
+ "authorization",
11
+ "cookie",
12
+ "set_cookie",
13
+ "password",
14
+ "passwd",
15
+ "token",
16
+ "access_token",
17
+ "refresh_token",
18
+ "secret",
19
+ "api_key",
20
+ "apikey",
21
+ "private_key",
22
+ "session_token",
23
+ "x_csrf_token",
24
+ "x_xsrf_token",
25
+ "email",
26
+ "phone",
27
+ "ssn",
28
+ "date_of_birth",
29
+ "dob",
30
+ "drivers_license",
31
+ "passport",
32
+ "national_id",
33
+ "tax_id",
34
+ "credit_card",
35
+ "card_number",
36
+ "cvv",
37
+ "cvc",
38
+ "account_number",
39
+ "routing_number",
40
+ "iban",
41
+ "raw_sql",
42
+ "sql_query",
43
+ "sql_statement",
44
+ "bind_value",
45
+ "bind_values",
46
+ "bindings",
47
+ "row_value",
48
+ "row_values",
49
+ "raw_row",
50
+ "request_body",
51
+ "response_body",
52
+ "request_headers",
53
+ "response_headers",
54
+ "auth_headers",
55
+ "cookies",
56
+ "prompt_body",
57
+ "raw_prompt",
58
+ "completion_body",
59
+ "raw_completion",
60
+ "raw_ai_output",
61
+ ];
62
+ /**
63
+ * 配る部品が送り出す前に落とす項目名。
64
+ *
65
+ * 必ず {@link INGEST_HARD_DENY_KEYS} を含みます(同じ正本の配列を先頭に
66
+ * 並べて出しているため、包含関係は**構造で保証**されます。試験の主張ではありません)。
67
+ */
68
+ export const SDK_ALWAYS_DENIED_KEYS = [
69
+ "authorization",
70
+ "cookie",
71
+ "set_cookie",
72
+ "password",
73
+ "passwd",
74
+ "token",
75
+ "access_token",
76
+ "refresh_token",
77
+ "secret",
78
+ "api_key",
79
+ "apikey",
80
+ "private_key",
81
+ "session_token",
82
+ "x_csrf_token",
83
+ "x_xsrf_token",
84
+ "email",
85
+ "phone",
86
+ "ssn",
87
+ "date_of_birth",
88
+ "dob",
89
+ "drivers_license",
90
+ "passport",
91
+ "national_id",
92
+ "tax_id",
93
+ "credit_card",
94
+ "card_number",
95
+ "cvv",
96
+ "cvc",
97
+ "account_number",
98
+ "routing_number",
99
+ "iban",
100
+ "raw_sql",
101
+ "sql_query",
102
+ "sql_statement",
103
+ "bind_value",
104
+ "bind_values",
105
+ "bindings",
106
+ "row_value",
107
+ "row_values",
108
+ "raw_row",
109
+ "request_body",
110
+ "response_body",
111
+ "request_headers",
112
+ "response_headers",
113
+ "auth_headers",
114
+ "cookies",
115
+ "prompt_body",
116
+ "raw_prompt",
117
+ "completion_body",
118
+ "raw_completion",
119
+ "raw_ai_output",
120
+ "set-cookie",
121
+ "session",
122
+ ];
123
+ /**
124
+ * 受付側が**計測の属性**(OpenTelemetry の span 属性)を畳む時に落とす項目名。
125
+ *
126
+ * この面は顧客の任意の属性が丸ごと来るので、本文・問い合わせ文・見出しの類を
127
+ * 面ごと落とします。広すぎて利用者の項目名の面へは広げられないため、面ごとの
128
+ * 追加として持ちます。{@link INGEST_HARD_DENY_KEYS} を必ず含みます(同じ正本の
129
+ * 配列を先頭に並べて出しているため、包含関係は**構造で保証**されます)。
130
+ */
131
+ export const INGEST_SIGNAL_DENIED_KEYS = [
132
+ "authorization",
133
+ "cookie",
134
+ "set_cookie",
135
+ "password",
136
+ "passwd",
137
+ "token",
138
+ "access_token",
139
+ "refresh_token",
140
+ "secret",
141
+ "api_key",
142
+ "apikey",
143
+ "private_key",
144
+ "session_token",
145
+ "x_csrf_token",
146
+ "x_xsrf_token",
147
+ "email",
148
+ "phone",
149
+ "ssn",
150
+ "date_of_birth",
151
+ "dob",
152
+ "drivers_license",
153
+ "passport",
154
+ "national_id",
155
+ "tax_id",
156
+ "credit_card",
157
+ "card_number",
158
+ "cvv",
159
+ "cvc",
160
+ "account_number",
161
+ "routing_number",
162
+ "iban",
163
+ "raw_sql",
164
+ "sql_query",
165
+ "sql_statement",
166
+ "bind_value",
167
+ "bind_values",
168
+ "bindings",
169
+ "row_value",
170
+ "row_values",
171
+ "raw_row",
172
+ "request_body",
173
+ "response_body",
174
+ "request_headers",
175
+ "response_headers",
176
+ "auth_headers",
177
+ "cookies",
178
+ "prompt_body",
179
+ "raw_prompt",
180
+ "completion_body",
181
+ "raw_completion",
182
+ "raw_ai_output",
183
+ "body",
184
+ "query",
185
+ "headers",
186
+ "statement",
187
+ "db_statement",
188
+ ];
189
+ /**
190
+ * 自分たちが出す**追跡情報(trace)の属性**で落とす項目名。
191
+ *
192
+ * この面は開発者が書いた属性がそのまま外へ出るので、広く落として困りません。
193
+ * `session` はこの面だけです。取り込みの面へ広げると、相関に使う
194
+ * `cluebase.session_id` まで落ちます。**面ごとに違うのは落とす語の一覧だけで、
195
+ * 突き合わせ方は 1 つ**です。
196
+ */
197
+ export const INGEST_TRACE_DENIED_KEYS = [
198
+ "authorization",
199
+ "cookie",
200
+ "set_cookie",
201
+ "password",
202
+ "passwd",
203
+ "token",
204
+ "access_token",
205
+ "refresh_token",
206
+ "secret",
207
+ "api_key",
208
+ "apikey",
209
+ "private_key",
210
+ "session_token",
211
+ "x_csrf_token",
212
+ "x_xsrf_token",
213
+ "email",
214
+ "phone",
215
+ "ssn",
216
+ "date_of_birth",
217
+ "dob",
218
+ "drivers_license",
219
+ "passport",
220
+ "national_id",
221
+ "tax_id",
222
+ "credit_card",
223
+ "card_number",
224
+ "cvv",
225
+ "cvc",
226
+ "account_number",
227
+ "routing_number",
228
+ "iban",
229
+ "raw_sql",
230
+ "sql_query",
231
+ "sql_statement",
232
+ "bind_value",
233
+ "bind_values",
234
+ "bindings",
235
+ "row_value",
236
+ "row_values",
237
+ "raw_row",
238
+ "request_body",
239
+ "response_body",
240
+ "request_headers",
241
+ "response_headers",
242
+ "auth_headers",
243
+ "cookies",
244
+ "prompt_body",
245
+ "raw_prompt",
246
+ "completion_body",
247
+ "raw_completion",
248
+ "raw_ai_output",
249
+ "bearer",
250
+ "session",
251
+ ];
252
+ /**
253
+ * 見た目が同じ別の文字を ASCII へ畳む表。
254
+ *
255
+ * NFKC はこれらを畳みません(互換分解ではなく別の文字だからです)。畳まないと
256
+ * \`τօκen\` のような綴りが \`token\` に一致せず、資格情報が伏せられないまま
257
+ * 送出されます。
258
+ *
259
+ * **畳んだ先はすべて小文字です。これは正しい形です。** Unicode の規格(UTS #39)は、
260
+ * 見た目が同じ文字を畳んだ結果について「大文字小文字を保つ形ではない」「項目名の
261
+ * 正規化として使ってはならない」と明記しています。したがって**畳んだ後の大文字小文字を
262
+ * 当てにする突き合わせを書いてはいけません**(下の突き合わせ用の形は、大文字小文字も
263
+ * 区切りも捨てます)。
264
+ */
265
+ export const ASCII_CONFUSABLES_FOLD = {
266
+ "×": "x",
267
+ "þ": "p",
268
+ "ı": "i",
269
+ "Ƅ": "b",
270
+ "ƍ": "g",
271
+ "ƒ": "f",
272
+ "Ɩ": "l",
273
+ "Ʀ": "r",
274
+ "Ƨ": "2",
275
+ "Ʒ": "3",
276
+ "Ƽ": "5",
277
+ "ƽ": "s",
278
+ "ƿ": "p",
279
+ "ǀ": "l",
280
+ "Ȝ": "3",
281
+ "Ȣ": "8",
282
+ "ȣ": "8",
283
+ "ɑ": "a",
284
+ "ɡ": "g",
285
+ "ɣ": "y",
286
+ "ɩ": "i",
287
+ "ɪ": "i",
288
+ "ɯ": "w",
289
+ "ʋ": "u",
290
+ "ʏ": "y",
291
+ "Ϳ": "j",
292
+ "Α": "a",
293
+ "Β": "b",
294
+ "Ε": "e",
295
+ "Ζ": "z",
296
+ "Η": "h",
297
+ "Ι": "l",
298
+ "Κ": "k",
299
+ "Μ": "m",
300
+ "Ν": "n",
301
+ "Ο": "o",
302
+ "Ρ": "p",
303
+ "Τ": "t",
304
+ "Υ": "y",
305
+ "Χ": "x",
306
+ "α": "a",
307
+ "β": "b",
308
+ "γ": "y",
309
+ "ε": "e",
310
+ "ι": "i",
311
+ "κ": "k",
312
+ "ν": "v",
313
+ "ο": "o",
314
+ "ρ": "p",
315
+ "σ": "o",
316
+ "τ": "t",
317
+ "υ": "u",
318
+ "χ": "x",
319
+ "Ϝ": "f",
320
+ "Ϩ": "2",
321
+ "Ϭ": "6",
322
+ "ϭ": "o",
323
+ "ϳ": "j",
324
+ "ϸ": "p",
325
+ "Ϻ": "m",
326
+ "Ѕ": "s",
327
+ "І": "l",
328
+ "Ј": "j",
329
+ "А": "a",
330
+ "В": "b",
331
+ "Е": "e",
332
+ "З": "3",
333
+ "К": "k",
334
+ "М": "m",
335
+ "Н": "h",
336
+ "О": "o",
337
+ "Р": "p",
338
+ "С": "c",
339
+ "Т": "t",
340
+ "У": "y",
341
+ "Х": "x",
342
+ "Ь": "b",
343
+ "а": "a",
344
+ "б": "6",
345
+ "в": "b",
346
+ "г": "r",
347
+ "е": "e",
348
+ "м": "m",
349
+ "н": "h",
350
+ "о": "o",
351
+ "р": "p",
352
+ "с": "c",
353
+ "т": "t",
354
+ "у": "y",
355
+ "х": "x",
356
+ "ш": "w",
357
+ "ѕ": "s",
358
+ "і": "i",
359
+ "ј": "j",
360
+ "ѡ": "w",
361
+ "Ѵ": "v",
362
+ "ѵ": "v",
363
+ "Ү": "y",
364
+ "ү": "y",
365
+ "Һ": "h",
366
+ "һ": "h",
367
+ "ҽ": "e",
368
+ "Ӏ": "l",
369
+ "ӏ": "l",
370
+ "Ӡ": "3",
371
+ "ԁ": "d",
372
+ "Ԍ": "g",
373
+ "ԛ": "q",
374
+ "Ԝ": "w",
375
+ "ԝ": "w",
376
+ "Ս": "u",
377
+ "Տ": "s",
378
+ "Օ": "o",
379
+ "ա": "w",
380
+ "գ": "q",
381
+ "զ": "q",
382
+ "հ": "h",
383
+ "ո": "n",
384
+ "ռ": "n",
385
+ "ս": "u",
386
+ "ց": "g",
387
+ "ւ": "i",
388
+ "ք": "f",
389
+ "օ": "o",
390
+ "׀": "l",
391
+ "ו": "l",
392
+ "ט": "v",
393
+ "ן": "l",
394
+ "ס": "o",
395
+ "ا": "l",
396
+ "ه": "o",
397
+ "١": "l",
398
+ "٥": "o",
399
+ "٧": "v",
400
+ "ھ": "o",
401
+ "ہ": "o",
402
+ "ە": "o",
403
+ "۱": "l",
404
+ "۵": "o",
405
+ "۷": "v",
406
+ "߀": "o",
407
+ "ߊ": "l",
408
+ "०": "o",
409
+ "३": "3",
410
+ "০": "o",
411
+ "৪": "8",
412
+ "৭": "9",
413
+ "੦": "o",
414
+ "੧": "9",
415
+ "੪": "8",
416
+ "૦": "o",
417
+ "૩": "3",
418
+ "ଃ": "8",
419
+ "ଠ": "o",
420
+ "୦": "o",
421
+ "୨": "9",
422
+ "௦": "o",
423
+ "ం": "o",
424
+ "౦": "o",
425
+ "ಂ": "o",
426
+ "೦": "o",
427
+ "ം": "o",
428
+ "ട": "s",
429
+ "ഠ": "o",
430
+ "൦": "o",
431
+ "൭": "9",
432
+ "ං": "o",
433
+ "๐": "o",
434
+ "໐": "o",
435
+ "င": "c",
436
+ "ဝ": "o",
437
+ "၀": "o",
438
+ "ၚ": "c",
439
+ "ყ": "y",
440
+ "ჿ": "o",
441
+ "ሀ": "u",
442
+ "ዐ": "o",
443
+ "Ꭰ": "d",
444
+ "Ꭱ": "r",
445
+ "Ꭲ": "t",
446
+ "Ꭵ": "i",
447
+ "Ꭹ": "y",
448
+ "Ꭺ": "a",
449
+ "Ꭻ": "j",
450
+ "Ꭼ": "e",
451
+ "Ꮃ": "w",
452
+ "Ꮇ": "m",
453
+ "Ꮋ": "h",
454
+ "Ꮍ": "y",
455
+ "Ꮐ": "g",
456
+ "Ꮒ": "h",
457
+ "Ꮓ": "z",
458
+ "Ꮞ": "4",
459
+ "Ꮟ": "b",
460
+ "Ꮢ": "r",
461
+ "Ꮤ": "w",
462
+ "Ꮥ": "s",
463
+ "Ꮩ": "v",
464
+ "Ꮪ": "s",
465
+ "Ꮮ": "l",
466
+ "Ꮯ": "c",
467
+ "Ꮲ": "p",
468
+ "Ꮶ": "k",
469
+ "Ꮷ": "d",
470
+ "Ꮾ": "6",
471
+ "Ᏻ": "g",
472
+ "Ᏼ": "b",
473
+ "ᐯ": "v",
474
+ "ᑌ": "u",
475
+ "ᑭ": "p",
476
+ "ᑯ": "d",
477
+ "ᑲ": "b",
478
+ "ᒍ": "j",
479
+ "ᒪ": "l",
480
+ "ᒿ": "2",
481
+ "ᕁ": "x",
482
+ "ᕼ": "h",
483
+ "ᕽ": "x",
484
+ "ᖇ": "r",
485
+ "ᖯ": "b",
486
+ "ᖴ": "f",
487
+ "ᗅ": "a",
488
+ "ᗞ": "d",
489
+ "ᗪ": "d",
490
+ "ᗰ": "m",
491
+ "ᗷ": "b",
492
+ "᙭": "x",
493
+ "᙮": "x",
494
+ "ᚷ": "x",
495
+ "ᛁ": "l",
496
+ "ᛕ": "k",
497
+ "ᛖ": "m",
498
+ "០": "o",
499
+ "ᴄ": "c",
500
+ "ᴏ": "o",
501
+ "ᴑ": "o",
502
+ "ᴜ": "u",
503
+ "ᴠ": "v",
504
+ "ᴡ": "w",
505
+ "ᴢ": "z",
506
+ "ᴦ": "r",
507
+ "ᶃ": "g",
508
+ "ᶌ": "y",
509
+ "ẝ": "f",
510
+ "ỿ": "y",
511
+ "℮": "e",
512
+ "∣": "l",
513
+ "∨": "v",
514
+ "∪": "u",
515
+ "⊤": "t",
516
+ "⋁": "v",
517
+ "⋃": "u",
518
+ "⋿": "e",
519
+ "⍳": "i",
520
+ "⍴": "p",
521
+ "⍺": "a",
522
+ "⏽": "l",
523
+ "╳": "x",
524
+ "⟙": "t",
525
+ "⤫": "x",
526
+ "⤬": "x",
527
+ "⨯": "x",
528
+ "Ⲃ": "b",
529
+ "ⲅ": "r",
530
+ "Ⲏ": "h",
531
+ "Ⲓ": "l",
532
+ "ⲓ": "i",
533
+ "Ⲕ": "k",
534
+ "Ⲙ": "m",
535
+ "Ⲛ": "n",
536
+ "Ⲝ": "3",
537
+ "Ⲟ": "o",
538
+ "ⲟ": "o",
539
+ "Ⲣ": "p",
540
+ "ⲣ": "p",
541
+ "Ⲥ": "c",
542
+ "ⲥ": "c",
543
+ "Ⲧ": "t",
544
+ "Ⲩ": "y",
545
+ "ⲩ": "y",
546
+ "Ⲭ": "x",
547
+ "ⲽ": "w",
548
+ "Ⳅ": "3",
549
+ "Ⳋ": "9",
550
+ "ⳋ": "9",
551
+ "Ⳍ": "3",
552
+ "Ⳏ": "p",
553
+ "ⳏ": "p",
554
+ "Ⳑ": "l",
555
+ "Ⳓ": "6",
556
+ "ⳓ": "6",
557
+ "Ⳝ": "6",
558
+ "ⴸ": "v",
559
+ "ⴹ": "e",
560
+ "ⵏ": "l",
561
+ "ⵔ": "o",
562
+ "ⵕ": "q",
563
+ "ⵝ": "x",
564
+ "〇": "o",
565
+ "ꓐ": "b",
566
+ "ꓑ": "p",
567
+ "ꓒ": "d",
568
+ "ꓓ": "d",
569
+ "ꓔ": "t",
570
+ "ꓖ": "g",
571
+ "ꓗ": "k",
572
+ "ꓙ": "j",
573
+ "ꓚ": "c",
574
+ "ꓜ": "z",
575
+ "ꓝ": "f",
576
+ "ꓟ": "m",
577
+ "ꓠ": "n",
578
+ "ꓡ": "l",
579
+ "ꓢ": "s",
580
+ "ꓣ": "r",
581
+ "ꓦ": "v",
582
+ "ꓧ": "h",
583
+ "ꓪ": "w",
584
+ "ꓫ": "x",
585
+ "ꓬ": "y",
586
+ "ꓮ": "a",
587
+ "ꓰ": "e",
588
+ "ꓲ": "l",
589
+ "ꓳ": "o",
590
+ "ꓴ": "u",
591
+ "Ꙅ": "2",
592
+ "ꙇ": "i",
593
+ "ꛟ": "v",
594
+ "ꛯ": "2",
595
+ "ꜱ": "s",
596
+ "Ꝛ": "2",
597
+ "Ꝫ": "3",
598
+ "Ꝯ": "9",
599
+ "Ꞙ": "f",
600
+ "ꞙ": "f",
601
+ "ꞟ": "u",
602
+ "Ɜ": "3",
603
+ "Ʝ": "j",
604
+ "Ꭓ": "x",
605
+ "Ꞵ": "b",
606
+ "ꬲ": "e",
607
+ "ꬵ": "f",
608
+ "ꬽ": "o",
609
+ "ꭇ": "r",
610
+ "ꭈ": "r",
611
+ "ꭎ": "u",
612
+ "ꭒ": "u",
613
+ "ꭚ": "y",
614
+ "ꭵ": "i",
615
+ "ꮁ": "r",
616
+ "ꮃ": "w",
617
+ "ꮓ": "z",
618
+ "ꮩ": "v",
619
+ "ꮪ": "s",
620
+ "ꮯ": "c",
621
+ "𐊂": "b",
622
+ "𐊆": "e",
623
+ "𐊇": "f",
624
+ "𐊊": "l",
625
+ "𐊐": "x",
626
+ "𐊒": "o",
627
+ "𐊕": "p",
628
+ "𐊖": "s",
629
+ "𐊗": "t",
630
+ "𐊠": "a",
631
+ "𐊡": "b",
632
+ "𐊢": "c",
633
+ "𐊥": "f",
634
+ "𐊫": "o",
635
+ "𐊰": "m",
636
+ "𐊱": "t",
637
+ "𐊲": "y",
638
+ "𐊴": "x",
639
+ "𐋏": "h",
640
+ "𐋵": "z",
641
+ "𐌁": "b",
642
+ "𐌂": "c",
643
+ "𐌉": "l",
644
+ "𐌑": "m",
645
+ "𐌕": "t",
646
+ "𐌗": "x",
647
+ "𐌚": "8",
648
+ "𐌠": "l",
649
+ "𐌢": "x",
650
+ "𐐄": "o",
651
+ "𐐕": "c",
652
+ "𐐛": "l",
653
+ "𐐠": "s",
654
+ "𐐬": "o",
655
+ "𐐽": "c",
656
+ "𐑈": "s",
657
+ "𐒴": "r",
658
+ "𐓂": "o",
659
+ "𐓎": "u",
660
+ "𐓒": "7",
661
+ "𐓪": "o",
662
+ "𐓶": "u",
663
+ "𐔓": "n",
664
+ "𐔖": "o",
665
+ "𐔘": "k",
666
+ "𐔜": "c",
667
+ "𐔝": "v",
668
+ "𐔥": "f",
669
+ "𐔦": "l",
670
+ "𐔧": "x",
671
+ "𑓐": "o",
672
+ "𑜆": "v",
673
+ "𑜊": "w",
674
+ "𑜎": "w",
675
+ "𑜏": "w",
676
+ "𑢠": "v",
677
+ "𑢢": "f",
678
+ "𑢣": "l",
679
+ "𑢤": "y",
680
+ "𑢦": "e",
681
+ "𑢩": "z",
682
+ "𑢬": "9",
683
+ "𑢮": "e",
684
+ "𑢯": "4",
685
+ "𑢲": "l",
686
+ "𑢵": "o",
687
+ "𑢸": "u",
688
+ "𑢻": "5",
689
+ "𑢼": "t",
690
+ "𑣀": "v",
691
+ "𑣁": "s",
692
+ "𑣂": "f",
693
+ "𑣃": "i",
694
+ "𑣄": "z",
695
+ "𑣆": "7",
696
+ "𑣈": "o",
697
+ "𑣊": "3",
698
+ "𑣌": "9",
699
+ "𑣕": "6",
700
+ "𑣖": "9",
701
+ "𑣗": "o",
702
+ "𑣘": "u",
703
+ "𑣜": "y",
704
+ "𑣠": "o",
705
+ "𑣥": "z",
706
+ "𑣦": "w",
707
+ "𑣩": "c",
708
+ "𑣬": "x",
709
+ "𑣯": "w",
710
+ "𑣲": "c",
711
+ "𑷚": "l",
712
+ "𑷠": "o",
713
+ "𑷡": "l",
714
+ "𖺪": "l",
715
+ "𖺶": "b",
716
+ "𖼈": "v",
717
+ "𖼊": "t",
718
+ "𖼖": "l",
719
+ "𖼨": "l",
720
+ "𖼵": "r",
721
+ "𖼺": "s",
722
+ "𖼻": "3",
723
+ "𖽀": "a",
724
+ "𖽂": "u",
725
+ "𖽃": "y",
726
+ "𝈆": "3",
727
+ "𝈍": "v",
728
+ "𝈒": "7",
729
+ "𝈓": "f",
730
+ "𝈖": "r",
731
+ "𝈪": "l",
732
+ "𞣇": "l",
733
+ "𞣋": "8",
734
+ "🝌": "c",
735
+ "🝨": "t",
736
+ };
737
+ export const foldAsciiConfusables = (value) => {
738
+ let out = "";
739
+ for (const character of value) {
740
+ out += ASCII_CONFUSABLES_FOLD[character] ?? character;
741
+ }
742
+ return out;
743
+ };
744
+ /**
745
+ * 項目名を、区切りの見える形にします。
746
+ *
747
+ * \`userEmail\` / \`user_email\` / \`user-email\` / \`USER_EMAIL\` / \`User.Email\`
748
+ * はすべて \`user_email\` になります。**この形は「経路っぽい項目名か」の判定に使います。**
749
+ * 落とすかどうかの突き合わせには使いません(下の {@link toPrivacyMatchKey} を使います)。
750
+ */
751
+ export const normalizePrivacyLookupKey = (key) => foldAsciiConfusables(key.normalize("NFKC"))
752
+ .trim()
753
+ .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
754
+ .toLowerCase()
755
+ .replace(/[^a-z0-9]+/g, "_")
756
+ .replace(/^_+|_+$/g, "");
757
+ /**
758
+ * 突き合わせる形。**区切りを落として詰めます。**
759
+ *
760
+ * 区切りを残してはいけません。区切りの位置は**送ってくる側が決められる**からです。
761
+ * 上の形は大文字の位置から区切りを補いますが、大文字を「見た目が同じ小文字の別文字」
762
+ * に替えられると、その区切りが消えます(\`accessтoken\` の \`т\` はキリル文字の小文字)。
763
+ * ASCII だけでも \`accesstoken\` \`ACCESSTOKEN\` のように区切りを 1 つも書かない綴りが
764
+ * 普通にあり、これらは**同形異字を使わなくても**素通りしていました。
765
+ *
766
+ * したがって**区切りに頼らない形にしてから突き合わせます。**
767
+ */
768
+ export const toPrivacyMatchKey = (key) => normalizePrivacyLookupKey(key).replace(/_/g, "");
769
+ /**
770
+ * 落とす語を含むが、落としてはいけないと決めた項目名。
771
+ *
772
+ * 部分一致で落とす方式は必ず巻き添えを出すので、業界の既定は逃し口を
773
+ * **完全一致**の一覧として持つことです(Sentry の Safe Fields も完全一致)。
774
+ * 中身は「トークンの個数」だけです。資格情報ではなく数量で、生成 AI の費用の
775
+ * 分析に要ります。
776
+ */
777
+ export const INGEST_DENY_EXEMPT_KEYS = [
778
+ "input_tokens",
779
+ "output_tokens",
780
+ "total_tokens",
781
+ "max_tokens",
782
+ "prompt_tokens",
783
+ "completion_tokens",
784
+ "token_count",
785
+ "cache_read_input_tokens",
786
+ "cache_creation_input_tokens",
787
+ "gen_ai.usage.input_tokens",
788
+ "gen_ai.usage.output_tokens",
789
+ "gen_ai.usage.total_tokens",
790
+ "gen_ai.request.max_tokens",
791
+ "ai_input_tokens",
792
+ "ai_output_tokens",
793
+ "ai_total_tokens",
794
+ "ai_request_max_tokens",
795
+ ];
796
+ const DENY_EXEMPT_MATCH_KEYS = new Set(INGEST_DENY_EXEMPT_KEYS.map(toPrivacyMatchKey));
797
+ /** 落とす項目名の一覧を、突き合わせ用の集合にします。空になるものは捨てます。 */
798
+ export const toDeniedLookupKeySet = (deniedKeys) => {
799
+ const set = new Set();
800
+ for (const entry of deniedKeys) {
801
+ const matchKey = toPrivacyMatchKey(entry);
802
+ if (matchKey)
803
+ set.add(matchKey);
804
+ }
805
+ return set;
806
+ };
807
+ /**
808
+ * 詰めた形への部分一致で突き合わせる、落とす語の最短の長さ。
809
+ *
810
+ * これ未満の語は、区切りの塊の**端に接している**時だけ落とします。
811
+ */
812
+ export const PRIVACY_SUBSTRING_MATCH_MIN_LENGTH = 4;
813
+ /** 既に伏せてある値の綴り(そのまま一致する分)。 */
814
+ export const MASKED_VALUE_EXACT = [
815
+ "__cluebase_masked__",
816
+ ];
817
+ /** 既に伏せてある値の綴り(先頭が一致する分)。後ろは指紋です。 */
818
+ export const MASKED_VALUE_PREFIXES = [
819
+ "cluebase_pii_hashed:",
820
+ ];
821
+ /**
822
+ * 連絡先(メール)の形。**指紋にする前に小文字へ畳んでよいかだけを決めます。**
823
+ *
824
+ * 合えば前後の空白を落として小文字にしてから指紋にし、合わなければ元の値のまま
825
+ * 指紋にします。**両側で同じ規則でなければ、同じ人の同じメールが経路ごとに別の
826
+ * 指紋になり、突き合わせが 0 件で返ります。**
827
+ */
828
+ export const CONTACT_EMAIL_SHAPE = "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$";
829
+ /** その値は、指紋にする前に小文字へ畳んでよい形か。 */
830
+ export const isContactEmailShaped = (value) => new RegExp(CONTACT_EMAIL_SHAPE).test(value);
831
+ /**
832
+ * この項目名を落とすか。**落とす語の長さで、突き合わせ方を分けます。**
833
+ *
834
+ * | 落とす語 | 突き合わせ | 例 |
835
+ * |---|---|---|
836
+ * | 4 文字以上 | 詰めた形への**部分一致** | `token` が `accesstoken` `ACCESSTOKEN` `myAccessToken` `accessтoken` に当たる |
837
+ * | 4 文字未満 | 区切りの塊の**端に接する**か、塊を繋いだ形と一致 | `ssn` が `user_ssn` `ssnLast4` `userssn` `s.s.n` に当たり、`class_snapshot` には当たらない |
838
+ *
839
+ * **部分一致は業界の既定ですが、3 文字の頭字語に当てると顧客の正当な項目名を
840
+ * 無言で捨てます。** 実測(2026-08-14): 辞書由来の項目名 160 万件のうち
841
+ * **50,041 件**が誤って落ち、`class_snapshot`(`classsnapshot` の中の `ssn`)・
842
+ * `boss_snapshot`・`cross_snapshot`・`business_snapshot`・`press_note`・
843
+ * `adobe_id`(`adobe` の中の `dob`)が消えていました。
844
+ *
845
+ * **業界が同じことをしていない、とは書けません。** Rails の
846
+ * `ActiveSupport::ParameterFilter` は既定で `ssn` `cvv` `cvc` を持ち、部分一致で
847
+ * 当てています。Rails で許されるのは対象が**ログ出力**だけで、誤爆しても
848
+ * `[FILTERED]` と出るだけで元データが残るからです。**こちらは取り込みで項目
849
+ * そのものを捨てるので復元できません。**釣り合いが違うので、Rails の許容は
850
+ * こちらへ持ち込めません。
851
+ *
852
+ * **両方は満たせません。** 部分一致をやめた分だけ、詰めた綴り(`xssnvalue`)は
853
+ * 通ります。攻撃綴り 11,627 件での素通りは、この案で 560 件です(塊とちょうど
854
+ * 一致させる案は 984 件)。この案は**現行が落とすものしか落とさない**ので、
855
+ * 誤爆を新たに増やしません。
856
+ */
857
+ export const isDeniedLookupKey = (key, deniedSet) => {
858
+ const matchKey = toPrivacyMatchKey(key);
859
+ if (!matchKey)
860
+ return false;
861
+ // 逃し口は**完全一致**です。前に語を足した綴り(\`my_max_tokens\`)は逃しません。
862
+ if (DENY_EXEMPT_MATCH_KEYS.has(matchKey))
863
+ return false;
864
+ let segments = null;
865
+ for (const denied of deniedSet) {
866
+ if (denied.length >= PRIVACY_SUBSTRING_MATCH_MIN_LENGTH) {
867
+ if (matchKey.includes(denied))
868
+ return true;
869
+ continue;
870
+ }
871
+ // 短い語は、区切りの塊の端に接している時だけ落とします。\`class_snapshot\` の
872
+ // \`ssn\` は塊をまたいだ位置にあるので当たりません。\`s.s.n\` のように 1 文字ずつ
873
+ // 区切っても、続いた塊を繋げば当たります。
874
+ segments ?? (segments = normalizePrivacyLookupKey(key).split("_").filter(Boolean));
875
+ for (let start = 0; start < segments.length; start += 1) {
876
+ const segment = segments[start];
877
+ if (segment.startsWith(denied) || segment.endsWith(denied))
878
+ return true;
879
+ let run = "";
880
+ for (let end = start; end < segments.length; end += 1) {
881
+ run += segments[end];
882
+ if (run.length > denied.length)
883
+ break;
884
+ if (run === denied)
885
+ return true;
886
+ }
887
+ }
888
+ }
889
+ return false;
890
+ };