deepline 0.3.395 → 0.3.396

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 (107) hide show
  1. package/dist/bundling-sources/sdk/src/plays/play-description.ts +1 -1
  2. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  3. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +1 -1
  4. package/dist/cli/{auth-NMQXZRS7.mjs → auth-3LTD62VL.mjs} +4 -4
  5. package/dist/cli/auth-562JPKOM.js +39 -0
  6. package/dist/cli/{billing-5MVXZRS6.mjs → billing-DP7ZAJBO.mjs} +5 -5
  7. package/dist/cli/{billing-Z4JTGUU3.js → billing-PA5OXEM5.js} +76 -76
  8. package/dist/cli/{chunk-BLYL3KOC.mjs → chunk-23GAA3YO.mjs} +1 -1
  9. package/dist/cli/{chunk-LZLBR2SF.js → chunk-2VOLOWYZ.js} +1087 -1056
  10. package/dist/cli/{chunk-EFLQHJZ6.mjs → chunk-3T4MCB5R.mjs} +1026 -995
  11. package/dist/cli/{chunk-VB6KECLU.mjs → chunk-5WNJF2T3.mjs} +102 -36
  12. package/dist/cli/{chunk-UKU6JM3S.js → chunk-772W2SAU.js} +8 -8
  13. package/dist/cli/{chunk-K5T3EN6D.js → chunk-7Z66NHUC.js} +26 -26
  14. package/dist/cli/{chunk-WCCKMLHL.mjs → chunk-AUYXWELC.mjs} +2 -2
  15. package/dist/cli/{chunk-PZ5BZ76S.js → chunk-AVHLATII.js} +50 -50
  16. package/dist/cli/{chunk-MYIBHORT.js → chunk-DC6LTULT.js} +2 -2
  17. package/dist/cli/{chunk-5VCZ3WRH.mjs → chunk-EIMG75BT.mjs} +1 -0
  18. package/dist/cli/{chunk-TO2MWPGR.js → chunk-GNN4MY5X.js} +1 -1
  19. package/dist/cli/{chunk-OCSG6X67.mjs → chunk-I4T4XAA2.mjs} +4 -4
  20. package/dist/cli/{chunk-ZWH2TFA7.mjs → chunk-JCN4DHF7.mjs} +2 -2
  21. package/dist/cli/{chunk-R4XZO6Z5.js → chunk-KAEZNPUM.js} +23 -8
  22. package/dist/cli/{chunk-DRM3CMHL.js → chunk-KXMNM4AQ.js} +2 -1
  23. package/dist/cli/{chunk-3TRY7KAC.mjs → chunk-LOGGNW4H.mjs} +2 -2
  24. package/dist/cli/{chunk-RDXFGPJU.js → chunk-LWERJUKN.js} +218 -218
  25. package/dist/cli/{chunk-UCXK2DS4.js → chunk-ME6XRFLY.js} +15 -15
  26. package/dist/cli/{chunk-G4IWGRMK.mjs → chunk-MR6XCBQJ.mjs} +2 -2
  27. package/dist/cli/{chunk-BON3DRC6.mjs → chunk-NHB5YUCS.mjs} +1 -1
  28. package/dist/cli/{chunk-ZMVJSS6N.js → chunk-NSOTASOP.js} +101 -35
  29. package/dist/cli/{chunk-7XAM7KDW.mjs → chunk-QHGPA362.mjs} +18 -3
  30. package/dist/cli/{chunk-VYLJJQ7Y.js → chunk-RMTASUAK.js} +65 -65
  31. package/dist/cli/{chunk-HRWUQJ4K.js → chunk-RTO5QZWT.js} +6 -6
  32. package/dist/cli/{chunk-7MVWUXOD.mjs → chunk-TLQ3FZOC.mjs} +3 -3
  33. package/dist/cli/{chunk-56IFFVIB.js → chunk-V7UP2F4U.js} +4 -4
  34. package/dist/cli/{chunk-6D7A2FSL.mjs → chunk-VE3U3SQC.mjs} +1 -1
  35. package/dist/cli/{chunk-36ML3YKA.js → chunk-WQJJNIMQ.js} +13 -13
  36. package/dist/cli/{chunk-47M6HPGP.mjs → chunk-XKZXO7D3.mjs} +1 -1
  37. package/dist/cli/{csv-SVOD5UBH.mjs → csv-RLRR74RQ.mjs} +3 -3
  38. package/dist/cli/{csv-HTS5ZYQ4.js → csv-TF576S77.js} +12 -12
  39. package/dist/cli/{db-7AP4P52N.js → db-FDBJUTFO.js} +30 -30
  40. package/dist/cli/{db-7QLNI3Q4.mjs → db-XORGNBIC.mjs} +5 -5
  41. package/dist/cli/{describe-DBRY5BNK.mjs → describe-6O2ENKTP.mjs} +86 -68
  42. package/dist/cli/{describe-YKOE54ZO.js → describe-EFWNECHI.js} +100 -82
  43. package/dist/cli/{executions-GRQXTB2P.js → executions-SFYAXPF4.js} +7 -7
  44. package/dist/cli/{executions-QNZTPNG4.mjs → executions-YPP7WR77.mjs} +5 -5
  45. package/dist/cli/{feedback-ZOLA2KY7.js → feedback-5UZFYMGB.js} +7 -7
  46. package/dist/cli/{feedback-JMCSR624.mjs → feedback-RBGA5ARU.mjs} +3 -3
  47. package/dist/cli/git-5LDY5ZID.js +23 -0
  48. package/dist/cli/{git-LJGL2IHS.mjs → git-IRSAJEK2.mjs} +4 -4
  49. package/dist/cli/index.js +94 -94
  50. package/dist/cli/index.mjs +38 -38
  51. package/dist/cli/{legacy-noops-YSCIR2SD.js → legacy-noops-CVAOQY2F.js} +7 -7
  52. package/dist/cli/{legacy-noops-F23PKVBN.mjs → legacy-noops-NA7N6ZOU.mjs} +4 -4
  53. package/dist/cli/{monitors-WMZ6HJZX.js → monitors-4OMRXCXP.js} +86 -86
  54. package/dist/cli/{monitors-S4LOEL7W.mjs → monitors-ILZ2XHYG.mjs} +5 -5
  55. package/dist/cli/{org-U3WA2NQM.mjs → org-QDDXAE3J.mjs} +5 -5
  56. package/dist/cli/{org-PFHM5ZLY.js → org-YGNJDD2X.js} +65 -65
  57. package/dist/cli/{chunk-4KLCLLTO.js → play-L535H26U.js} +266 -323
  58. package/dist/cli/{chunk-XMAPE2KH.mjs → play-VT6OHB2D.mjs} +72 -129
  59. package/dist/cli/{providers-XYMHLKCA.js → providers-GPZ6PQAL.js} +8 -8
  60. package/dist/cli/{providers-QBBRFBOH.mjs → providers-KG4W5MPK.mjs} +5 -5
  61. package/dist/cli/{quickstart-5JTDGISY.mjs → quickstart-2JDGTXIG.mjs} +3 -3
  62. package/dist/cli/{quickstart-IYGD6ZY3.js → quickstart-UI27S5LO.js} +5 -5
  63. package/dist/cli/search-MGWROZ33.js +28 -0
  64. package/dist/cli/{search-X6W6GRHS.mjs → search-PW3RAUX7.mjs} +6 -6
  65. package/dist/cli/{secrets-N55B67H6.mjs → secrets-HNOMK5A2.mjs} +5 -5
  66. package/dist/cli/{secrets-UHG6OQFD.js → secrets-WFAXOUZE.js} +14 -14
  67. package/dist/cli/{sessions-57L5MGHN.js → sessions-366KROUA.js} +5 -5
  68. package/dist/cli/{sessions-JTRSTDSS.mjs → sessions-XLX3E5UO.mjs} +4 -4
  69. package/dist/cli/{settings-ATX4U5AS.js → settings-GADAG2UK.js} +75 -75
  70. package/dist/cli/{settings-Q24HRAQI.mjs → settings-YNZ4YKCH.mjs} +8 -8
  71. package/dist/cli/{setup-77ZWLVHT.mjs → setup-PSEHIUXO.mjs} +6 -6
  72. package/dist/cli/{setup-EJCNOUCE.js → setup-R5YO7GT6.js} +41 -41
  73. package/dist/cli/skills-JF2LPEGM.js +28 -0
  74. package/dist/cli/{skills-XIS5AWQI.mjs → skills-LTQBP6CZ.mjs} +4 -4
  75. package/dist/cli/tools-CP2PEFRN.js +34 -0
  76. package/dist/cli/{tools-WCKLYEGQ.mjs → tools-UAXDWU63.mjs} +11 -19
  77. package/dist/cli/update-HZHZOU6C.js +28 -0
  78. package/dist/cli/{update-UT5WANMV.mjs → update-SMNIBIMS.mjs} +6 -6
  79. package/dist/cli/{workflow-226QYUN2.js → workflow-AOQVZHMD.js} +16 -16
  80. package/dist/cli/{workflow-ZMX3L4ML.mjs → workflow-IKGMBGF6.mjs} +6 -6
  81. package/dist/{client-CivP-PAI.d.ts → client-Bgis7F6-.d.ts} +2 -1
  82. package/dist/{client-hdFtwhTm.d.mts → client-DiGl8ska.d.mts} +2 -1
  83. package/dist/index.d.mts +2 -2
  84. package/dist/index.d.ts +2 -2
  85. package/dist/index.js +11 -11
  86. package/dist/index.mjs +9 -9
  87. package/dist/install-integrity.json +78 -80
  88. package/dist/plays/play-description.d.mts +1 -1
  89. package/dist/plays/play-description.d.ts +1 -1
  90. package/dist/plays/play-description.js +4 -2
  91. package/dist/plays/play-description.mjs +3 -1
  92. package/dist/plays/run-request.d.mts +1 -1
  93. package/dist/plays/run-request.d.ts +1 -1
  94. package/dist/release.d.mts +1 -1
  95. package/dist/release.d.ts +1 -1
  96. package/dist/release.js +2 -2
  97. package/dist/release.mjs +1 -1
  98. package/package.json +1 -1
  99. package/dist/cli/auth-UYCOBAL5.js +0 -39
  100. package/dist/cli/git-EJQLRK27.js +0 -23
  101. package/dist/cli/play-AGSECQFN.mjs +0 -159
  102. package/dist/cli/play-BR2LWGXK.js +0 -159
  103. package/dist/cli/search-ZVSYH5GY.js +0 -28
  104. package/dist/cli/skills-SPXUBLII.js +0 -28
  105. package/dist/cli/tools-DBHUUZJX.js +0 -42
  106. package/dist/cli/update-VSNFXRHJ.js +0 -28
  107. package/dist/cli/{chunk-KZZC33PY.mjs → chunk-H5KLUGY7.mjs} +214 -214
@@ -1,217 +1,3 @@
1
- // ../plays/email-status.ts
2
- var nullable = (type) => ({ type: [type, "null"] });
3
- var oneOf = (values) => ({ type: "string", enum: values });
4
- var EMAIL_STATUS_JSON_SCHEMA = {
5
- type: "object",
6
- required: [
7
- "verdict",
8
- "status",
9
- "verified",
10
- "confidence",
11
- "reasons",
12
- "signals",
13
- "provider"
14
- ],
15
- properties: {
16
- verdict: oneOf([
17
- "send",
18
- "send_with_caution",
19
- "verify_next",
20
- "hold",
21
- "drop"
22
- ]),
23
- status: oneOf([
24
- "valid",
25
- "invalid",
26
- "catch_all",
27
- "valid_catch_all",
28
- "unknown",
29
- "do_not_mail",
30
- "spamtrap",
31
- "abuse",
32
- "disposable"
33
- ]),
34
- verified: { type: "boolean" },
35
- confidence: nullable("number"),
36
- reasons: { type: "array", items: { type: "string" } },
37
- signals: {
38
- type: "object",
39
- required: [
40
- "catch_all",
41
- "deliverability",
42
- "mx_class",
43
- "mx_provider",
44
- "mx_record",
45
- "fraud_score",
46
- "disposable",
47
- "role_based",
48
- "free_email",
49
- "abuse",
50
- "spamtrap",
51
- "suspect",
52
- "valid"
53
- ],
54
- properties: {
55
- catch_all: nullable("boolean"),
56
- deliverability: oneOf([
57
- "high",
58
- "medium",
59
- "low",
60
- "unknown"
61
- ]),
62
- mx_class: oneOf([
63
- "consumer_mailbox",
64
- "workspace_mailbox",
65
- "security_gateway",
66
- "on_prem",
67
- "unknown"
68
- ]),
69
- mx_provider: nullable("string"),
70
- mx_record: nullable("string"),
71
- fraud_score: nullable("number"),
72
- disposable: nullable("boolean"),
73
- role_based: nullable("boolean"),
74
- free_email: nullable("boolean"),
75
- abuse: nullable("boolean"),
76
- spamtrap: nullable("boolean"),
77
- suspect: nullable("boolean"),
78
- valid: nullable("boolean")
79
- }
80
- },
81
- provider: {
82
- type: "object",
83
- required: ["name", "raw_status", "raw_score"],
84
- properties: {
85
- name: { type: "string" },
86
- raw_status: { type: ["string", "boolean", "number", "null"] },
87
- raw_score: nullable("number")
88
- }
89
- }
90
- }
91
- };
92
- function normalizeKey(value) {
93
- if (value == null) return null;
94
- if (typeof value === "boolean") return String(value);
95
- const normalized = String(value).trim().toLowerCase().replace(/\s+/g, "_");
96
- return normalized || null;
97
- }
98
- function boolish(value) {
99
- if (typeof value === "boolean") return value;
100
- if (typeof value === "number")
101
- return value === 1 ? true : value === 0 ? false : null;
102
- if (typeof value !== "string") return null;
103
- const normalized = value.trim().toLowerCase();
104
- if (["true", "yes", "y", "1"].includes(normalized)) return true;
105
- if (["false", "no", "n", "0"].includes(normalized)) return false;
106
- return null;
107
- }
108
- function numberish(value) {
109
- if (typeof value === "number" && Number.isFinite(value)) return value;
110
- if (typeof value !== "string" || value.trim() === "") return null;
111
- const parsed = Number(value);
112
- return Number.isFinite(parsed) ? parsed : null;
113
- }
114
- function stringish(value) {
115
- return typeof value === "string" && value.trim() ? value.trim() : null;
116
- }
117
- function deliverability(value) {
118
- const normalized = normalizeKey(value);
119
- return normalized === "high" || normalized === "medium" || normalized === "low" ? normalized : "unknown";
120
- }
121
- function mxClass(mxProvider, mxRecord) {
122
- const haystack = `${stringish(mxProvider) ?? ""} ${stringish(mxRecord) ?? ""}`.toLowerCase();
123
- if (!haystack.trim()) return "unknown";
124
- if (/proofpoint|pphosted|mimecast|barracuda|ess\.barracudanetworks|ironport|cisco|iphmx|messagelabs|symantec/.test(
125
- haystack
126
- )) {
127
- return "security_gateway";
128
- }
129
- if (/aspmx\.l\.google|google|g-suite|google workspace/.test(haystack)) {
130
- return "workspace_mailbox";
131
- }
132
- if (/protection\.outlook|office365|microsoft|outlook|exchange online/.test(
133
- haystack
134
- )) {
135
- return "workspace_mailbox";
136
- }
137
- if (/gmail|yahoo|icloud|aol|hotmail/.test(haystack))
138
- return "consumer_mailbox";
139
- if (/postfix|exim|sendmail|zimbra|plesk|cpanel|mail\./.test(haystack))
140
- return "on_prem";
141
- return "unknown";
142
- }
143
- function entryForStatus(key, map) {
144
- if (!key) return null;
145
- return map?.[key] ?? null;
146
- }
147
- function read(values, name) {
148
- return values[name];
149
- }
150
- function matchesRule(rule, values) {
151
- return Object.entries(rule.when).every(([key, expected]) => {
152
- const actual = read(values, key);
153
- if (key.endsWith("Lt")) {
154
- const source = numberish(read(values, key.slice(0, -2)));
155
- return typeof expected === "number" && source != null && source < expected;
156
- }
157
- if (typeof expected === "boolean") return boolish(actual) === expected;
158
- if (typeof expected === "number") return numberish(actual) === expected;
159
- return normalizeKey(actual) === normalizeKey(expected);
160
- });
161
- }
162
- function buildEmailStatus({
163
- config,
164
- values
165
- }) {
166
- const rawStatus = read(values, "rawStatus");
167
- const rawScore = numberish(read(values, "rawScore"));
168
- const valid = boolish(read(values, "valid"));
169
- const catchAll = boolish(read(values, "catchAll"));
170
- const disposable = boolish(read(values, "disposable"));
171
- const abuse = boolish(read(values, "abuse"));
172
- const spamtrap = boolish(read(values, "spamtrap"));
173
- const suspect = boolish(read(values, "suspect"));
174
- const rawKey = normalizeKey(rawStatus);
175
- const mapped = config.rules?.find((rule) => matchesRule(rule, values)) ?? entryForStatus(rawKey, config.statusMap) ?? entryForStatus(valid == null ? null : String(valid), config.statusMap);
176
- const status = mapped?.status ?? (disposable ? "disposable" : abuse ? "abuse" : spamtrap ? "spamtrap" : catchAll ? "catch_all" : valid === true ? "valid" : valid === false ? "invalid" : "unknown");
177
- const defaultVerdict = status === "valid" ? "send" : status === "valid_catch_all" ? "send_with_caution" : status === "catch_all" ? "verify_next" : status === "unknown" ? "hold" : "drop";
178
- const verdict = mapped?.verdict ?? defaultVerdict;
179
- const verified = mapped?.verified ?? (status === "valid" || status === "valid_catch_all" || verdict === "send");
180
- const reasons = [
181
- mapped?.reason,
182
- catchAll ? "catch_all_domain" : null,
183
- mxClass(read(values, "mxProvider"), read(values, "mxRecord")) === "security_gateway" ? "security_gateway_mx" : null,
184
- suspect ? "provider_marked_suspect" : null
185
- ].filter((reason) => typeof reason === "string");
186
- return {
187
- verdict,
188
- status,
189
- verified,
190
- confidence: rawScore,
191
- reasons,
192
- signals: {
193
- catch_all: catchAll,
194
- deliverability: deliverability(read(values, "deliverability")),
195
- mx_class: mxClass(read(values, "mxProvider"), read(values, "mxRecord")),
196
- mx_provider: stringish(read(values, "mxProvider")),
197
- mx_record: stringish(read(values, "mxRecord")),
198
- fraud_score: numberish(read(values, "fraudScore")),
199
- disposable,
200
- role_based: boolish(read(values, "roleBased")),
201
- free_email: boolish(read(values, "freeEmail")),
202
- abuse,
203
- spamtrap,
204
- suspect,
205
- valid
206
- },
207
- provider: {
208
- name: config.provider,
209
- raw_status: typeof rawStatus === "string" || typeof rawStatus === "boolean" || typeof rawStatus === "number" ? rawStatus : null,
210
- raw_score: rawScore
211
- }
212
- };
213
- }
214
-
215
1
  // ../plays/extractor-targets.ts
216
2
  var JOB_CHANGE_STATUS_VALUES = [
217
3
  "moved",
@@ -477,6 +263,220 @@ function extractSummaryFields(payload) {
477
263
  return {};
478
264
  }
479
265
 
266
+ // ../plays/email-status.ts
267
+ var nullable = (type) => ({ type: [type, "null"] });
268
+ var oneOf = (values) => ({ type: "string", enum: values });
269
+ var EMAIL_STATUS_JSON_SCHEMA = {
270
+ type: "object",
271
+ required: [
272
+ "verdict",
273
+ "status",
274
+ "verified",
275
+ "confidence",
276
+ "reasons",
277
+ "signals",
278
+ "provider"
279
+ ],
280
+ properties: {
281
+ verdict: oneOf([
282
+ "send",
283
+ "send_with_caution",
284
+ "verify_next",
285
+ "hold",
286
+ "drop"
287
+ ]),
288
+ status: oneOf([
289
+ "valid",
290
+ "invalid",
291
+ "catch_all",
292
+ "valid_catch_all",
293
+ "unknown",
294
+ "do_not_mail",
295
+ "spamtrap",
296
+ "abuse",
297
+ "disposable"
298
+ ]),
299
+ verified: { type: "boolean" },
300
+ confidence: nullable("number"),
301
+ reasons: { type: "array", items: { type: "string" } },
302
+ signals: {
303
+ type: "object",
304
+ required: [
305
+ "catch_all",
306
+ "deliverability",
307
+ "mx_class",
308
+ "mx_provider",
309
+ "mx_record",
310
+ "fraud_score",
311
+ "disposable",
312
+ "role_based",
313
+ "free_email",
314
+ "abuse",
315
+ "spamtrap",
316
+ "suspect",
317
+ "valid"
318
+ ],
319
+ properties: {
320
+ catch_all: nullable("boolean"),
321
+ deliverability: oneOf([
322
+ "high",
323
+ "medium",
324
+ "low",
325
+ "unknown"
326
+ ]),
327
+ mx_class: oneOf([
328
+ "consumer_mailbox",
329
+ "workspace_mailbox",
330
+ "security_gateway",
331
+ "on_prem",
332
+ "unknown"
333
+ ]),
334
+ mx_provider: nullable("string"),
335
+ mx_record: nullable("string"),
336
+ fraud_score: nullable("number"),
337
+ disposable: nullable("boolean"),
338
+ role_based: nullable("boolean"),
339
+ free_email: nullable("boolean"),
340
+ abuse: nullable("boolean"),
341
+ spamtrap: nullable("boolean"),
342
+ suspect: nullable("boolean"),
343
+ valid: nullable("boolean")
344
+ }
345
+ },
346
+ provider: {
347
+ type: "object",
348
+ required: ["name", "raw_status", "raw_score"],
349
+ properties: {
350
+ name: { type: "string" },
351
+ raw_status: { type: ["string", "boolean", "number", "null"] },
352
+ raw_score: nullable("number")
353
+ }
354
+ }
355
+ }
356
+ };
357
+ function normalizeKey(value) {
358
+ if (value == null) return null;
359
+ if (typeof value === "boolean") return String(value);
360
+ const normalized = String(value).trim().toLowerCase().replace(/\s+/g, "_");
361
+ return normalized || null;
362
+ }
363
+ function boolish(value) {
364
+ if (typeof value === "boolean") return value;
365
+ if (typeof value === "number")
366
+ return value === 1 ? true : value === 0 ? false : null;
367
+ if (typeof value !== "string") return null;
368
+ const normalized = value.trim().toLowerCase();
369
+ if (["true", "yes", "y", "1"].includes(normalized)) return true;
370
+ if (["false", "no", "n", "0"].includes(normalized)) return false;
371
+ return null;
372
+ }
373
+ function numberish(value) {
374
+ if (typeof value === "number" && Number.isFinite(value)) return value;
375
+ if (typeof value !== "string" || value.trim() === "") return null;
376
+ const parsed = Number(value);
377
+ return Number.isFinite(parsed) ? parsed : null;
378
+ }
379
+ function stringish(value) {
380
+ return typeof value === "string" && value.trim() ? value.trim() : null;
381
+ }
382
+ function deliverability(value) {
383
+ const normalized = normalizeKey(value);
384
+ return normalized === "high" || normalized === "medium" || normalized === "low" ? normalized : "unknown";
385
+ }
386
+ function mxClass(mxProvider, mxRecord) {
387
+ const haystack = `${stringish(mxProvider) ?? ""} ${stringish(mxRecord) ?? ""}`.toLowerCase();
388
+ if (!haystack.trim()) return "unknown";
389
+ if (/proofpoint|pphosted|mimecast|barracuda|ess\.barracudanetworks|ironport|cisco|iphmx|messagelabs|symantec/.test(
390
+ haystack
391
+ )) {
392
+ return "security_gateway";
393
+ }
394
+ if (/aspmx\.l\.google|google|g-suite|google workspace/.test(haystack)) {
395
+ return "workspace_mailbox";
396
+ }
397
+ if (/protection\.outlook|office365|microsoft|outlook|exchange online/.test(
398
+ haystack
399
+ )) {
400
+ return "workspace_mailbox";
401
+ }
402
+ if (/gmail|yahoo|icloud|aol|hotmail/.test(haystack))
403
+ return "consumer_mailbox";
404
+ if (/postfix|exim|sendmail|zimbra|plesk|cpanel|mail\./.test(haystack))
405
+ return "on_prem";
406
+ return "unknown";
407
+ }
408
+ function entryForStatus(key, map) {
409
+ if (!key) return null;
410
+ return map?.[key] ?? null;
411
+ }
412
+ function read(values, name) {
413
+ return values[name];
414
+ }
415
+ function matchesRule(rule, values) {
416
+ return Object.entries(rule.when).every(([key, expected]) => {
417
+ const actual = read(values, key);
418
+ if (key.endsWith("Lt")) {
419
+ const source = numberish(read(values, key.slice(0, -2)));
420
+ return typeof expected === "number" && source != null && source < expected;
421
+ }
422
+ if (typeof expected === "boolean") return boolish(actual) === expected;
423
+ if (typeof expected === "number") return numberish(actual) === expected;
424
+ return normalizeKey(actual) === normalizeKey(expected);
425
+ });
426
+ }
427
+ function buildEmailStatus({
428
+ config,
429
+ values
430
+ }) {
431
+ const rawStatus = read(values, "rawStatus");
432
+ const rawScore = numberish(read(values, "rawScore"));
433
+ const valid = boolish(read(values, "valid"));
434
+ const catchAll = boolish(read(values, "catchAll"));
435
+ const disposable = boolish(read(values, "disposable"));
436
+ const abuse = boolish(read(values, "abuse"));
437
+ const spamtrap = boolish(read(values, "spamtrap"));
438
+ const suspect = boolish(read(values, "suspect"));
439
+ const rawKey = normalizeKey(rawStatus);
440
+ const mapped = config.rules?.find((rule) => matchesRule(rule, values)) ?? entryForStatus(rawKey, config.statusMap) ?? entryForStatus(valid == null ? null : String(valid), config.statusMap);
441
+ const status = mapped?.status ?? (disposable ? "disposable" : abuse ? "abuse" : spamtrap ? "spamtrap" : catchAll ? "catch_all" : valid === true ? "valid" : valid === false ? "invalid" : "unknown");
442
+ const defaultVerdict = status === "valid" ? "send" : status === "valid_catch_all" ? "send_with_caution" : status === "catch_all" ? "verify_next" : status === "unknown" ? "hold" : "drop";
443
+ const verdict = mapped?.verdict ?? defaultVerdict;
444
+ const verified = mapped?.verified ?? (status === "valid" || status === "valid_catch_all" || verdict === "send");
445
+ const reasons = [
446
+ mapped?.reason,
447
+ catchAll ? "catch_all_domain" : null,
448
+ mxClass(read(values, "mxProvider"), read(values, "mxRecord")) === "security_gateway" ? "security_gateway_mx" : null,
449
+ suspect ? "provider_marked_suspect" : null
450
+ ].filter((reason) => typeof reason === "string");
451
+ return {
452
+ verdict,
453
+ status,
454
+ verified,
455
+ confidence: rawScore,
456
+ reasons,
457
+ signals: {
458
+ catch_all: catchAll,
459
+ deliverability: deliverability(read(values, "deliverability")),
460
+ mx_class: mxClass(read(values, "mxProvider"), read(values, "mxRecord")),
461
+ mx_provider: stringish(read(values, "mxProvider")),
462
+ mx_record: stringish(read(values, "mxRecord")),
463
+ fraud_score: numberish(read(values, "fraudScore")),
464
+ disposable,
465
+ role_based: boolish(read(values, "roleBased")),
466
+ free_email: boolish(read(values, "freeEmail")),
467
+ abuse,
468
+ spamtrap,
469
+ suspect,
470
+ valid
471
+ },
472
+ provider: {
473
+ name: config.provider,
474
+ raw_status: typeof rawStatus === "string" || typeof rawStatus === "boolean" || typeof rawStatus === "number" ? rawStatus : null,
475
+ raw_score: rawScore
476
+ }
477
+ };
478
+ }
479
+
480
480
  export {
481
481
  EMAIL_STATUS_JSON_SCHEMA,
482
482
  buildEmailStatus,