deepline 0.1.74 → 0.1.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1305 -345
- package/dist/cli/index.mjs +1307 -347
- package/dist/index.d.mts +77 -1
- package/dist/index.d.ts +77 -1
- package/dist/index.js +201 -3
- package/dist/index.mjs +201 -3
- package/dist/repo/apps/play-runner-workers/src/entry.ts +101 -45
- package/dist/repo/sdk/src/client.ts +8 -0
- package/dist/repo/sdk/src/play.ts +2 -1
- package/dist/repo/sdk/src/plays/harness-stub.ts +1 -0
- package/dist/repo/sdk/src/release.ts +3 -3
- package/dist/repo/sdk/src/worker-play-entry.ts +3 -0
- package/dist/repo/shared_libs/play-runtime/cell-staleness.ts +88 -0
- package/dist/repo/shared_libs/play-runtime/email-status.ts +301 -0
- package/dist/repo/shared_libs/play-runtime/step-program-dataset-builder.ts +5 -0
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +58 -1
- package/dist/repo/shared_libs/plays/row-identity.ts +0 -40
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1051,6 +1051,43 @@ interface PlayStagedFileRef {
|
|
|
1051
1051
|
bytes: number;
|
|
1052
1052
|
}
|
|
1053
1053
|
|
|
1054
|
+
type EnrichStepCommand = {
|
|
1055
|
+
alias: string;
|
|
1056
|
+
tool: string;
|
|
1057
|
+
operation?: string;
|
|
1058
|
+
payload: Record<string, unknown>;
|
|
1059
|
+
extract_js?: string;
|
|
1060
|
+
run_if_js?: string;
|
|
1061
|
+
description?: string;
|
|
1062
|
+
disabled?: boolean;
|
|
1063
|
+
};
|
|
1064
|
+
type EnrichWaterfallCommand = {
|
|
1065
|
+
with_waterfall: string;
|
|
1066
|
+
min_results?: number;
|
|
1067
|
+
commands: EnrichCommand[];
|
|
1068
|
+
description?: string;
|
|
1069
|
+
};
|
|
1070
|
+
type EnrichCommand = EnrichStepCommand | EnrichWaterfallCommand;
|
|
1071
|
+
type EnrichCompiledConfig = {
|
|
1072
|
+
version: 1;
|
|
1073
|
+
commands: EnrichCommand[];
|
|
1074
|
+
cost_cap_usd_per_run?: number;
|
|
1075
|
+
_comments?: Array<{
|
|
1076
|
+
path: string;
|
|
1077
|
+
lines: string[];
|
|
1078
|
+
}>;
|
|
1079
|
+
_expansion_preview?: {
|
|
1080
|
+
plays: Array<{
|
|
1081
|
+
alias: string;
|
|
1082
|
+
tool_id: string;
|
|
1083
|
+
template_group: string;
|
|
1084
|
+
runtime_group: string;
|
|
1085
|
+
estimated_credits_range: string;
|
|
1086
|
+
steps: Array<Record<string, unknown>>;
|
|
1087
|
+
}>;
|
|
1088
|
+
};
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1054
1091
|
type ExecuteToolRawOptions = {
|
|
1055
1092
|
includeToolMetadata?: boolean;
|
|
1056
1093
|
};
|
|
@@ -1350,6 +1387,12 @@ declare class DeeplineClient {
|
|
|
1350
1387
|
sourceFiles?: Record<string, string>;
|
|
1351
1388
|
artifact: Record<string, unknown>;
|
|
1352
1389
|
}): Promise<PlayCheckResult>;
|
|
1390
|
+
compileEnrichPlan(input: {
|
|
1391
|
+
plan_args?: string[];
|
|
1392
|
+
config?: unknown;
|
|
1393
|
+
}): Promise<{
|
|
1394
|
+
config: EnrichCompiledConfig;
|
|
1395
|
+
}>;
|
|
1353
1396
|
startPlayRunFromBundle(input: {
|
|
1354
1397
|
name: string;
|
|
1355
1398
|
sourceCode: string;
|
|
@@ -1954,6 +1997,37 @@ interface PlayDataset<T> extends AsyncIterable<T> {
|
|
|
1954
1997
|
};
|
|
1955
1998
|
}
|
|
1956
1999
|
|
|
2000
|
+
type EmailStatusVerdict = 'send' | 'send_with_caution' | 'verify_next' | 'hold' | 'drop';
|
|
2001
|
+
type EmailStatusValue = 'valid' | 'invalid' | 'catch_all' | 'valid_catch_all' | 'unknown' | 'do_not_mail' | 'spamtrap' | 'abuse' | 'disposable';
|
|
2002
|
+
type EmailStatusMapEntry = {
|
|
2003
|
+
status: EmailStatusValue;
|
|
2004
|
+
verdict?: EmailStatusVerdict;
|
|
2005
|
+
verified?: boolean;
|
|
2006
|
+
reason?: string;
|
|
2007
|
+
};
|
|
2008
|
+
type EmailStatusRule = EmailStatusMapEntry & {
|
|
2009
|
+
when: Record<string, string | number | boolean | null>;
|
|
2010
|
+
};
|
|
2011
|
+
type EmailStatusExtractorConfig = {
|
|
2012
|
+
provider: string;
|
|
2013
|
+
rawStatus?: string[];
|
|
2014
|
+
rawScore?: string[];
|
|
2015
|
+
valid?: string[];
|
|
2016
|
+
deliverability?: string[];
|
|
2017
|
+
catchAll?: string[];
|
|
2018
|
+
mxProvider?: string[];
|
|
2019
|
+
mxRecord?: string[];
|
|
2020
|
+
fraudScore?: string[];
|
|
2021
|
+
disposable?: string[];
|
|
2022
|
+
roleBased?: string[];
|
|
2023
|
+
freeEmail?: string[];
|
|
2024
|
+
abuse?: string[];
|
|
2025
|
+
spamtrap?: string[];
|
|
2026
|
+
suspect?: string[];
|
|
2027
|
+
statusMap?: Record<string, EmailStatusMapEntry>;
|
|
2028
|
+
rules?: EmailStatusRule[];
|
|
2029
|
+
};
|
|
2030
|
+
|
|
1957
2031
|
type ToolResultExecutionMetadata = {
|
|
1958
2032
|
idempotent: true;
|
|
1959
2033
|
cached: boolean;
|
|
@@ -1974,6 +2048,7 @@ type ToolResultExtractorDescriptor = {
|
|
|
1974
2048
|
transforms?: readonly string[];
|
|
1975
2049
|
enum?: readonly string[];
|
|
1976
2050
|
overrides?: readonly ToolResultExtractorOverride[];
|
|
2051
|
+
emailStatus?: EmailStatusExtractorConfig;
|
|
1977
2052
|
};
|
|
1978
2053
|
type ToolResultExtractorOverride = {
|
|
1979
2054
|
paths: readonly string[];
|
|
@@ -2145,6 +2220,7 @@ type ConditionalStepResolver<Row, Value, Else = null> = {
|
|
|
2145
2220
|
};
|
|
2146
2221
|
type StepOptions<Row> = {
|
|
2147
2222
|
readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
|
|
2223
|
+
readonly staleAfterSeconds?: number;
|
|
2148
2224
|
};
|
|
2149
2225
|
type StepProgram<Input, Output, Return = Output> = {
|
|
2150
2226
|
readonly kind: 'steps';
|
|
@@ -2163,6 +2239,7 @@ type StepProgramResolver<Input, Return> = {
|
|
|
2163
2239
|
};
|
|
2164
2240
|
type PlayStepProgramStep = {
|
|
2165
2241
|
readonly name: string;
|
|
2242
|
+
readonly staleAfterSeconds?: number;
|
|
2166
2243
|
readonly resolver: StepResolver<Record<string, unknown>, unknown> | ConditionalStepResolver<Record<string, unknown>, unknown> | StepProgramResolver<Record<string, unknown>, unknown>;
|
|
2167
2244
|
};
|
|
2168
2245
|
type ColumnResolver<Row, Value> = StepResolver<Row, Value> | ConditionalStepResolver<Row, Value> | StepProgramResolver<Row, Value>;
|
|
@@ -2197,7 +2274,6 @@ type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
|
|
|
2197
2274
|
*/
|
|
2198
2275
|
run(options?: {
|
|
2199
2276
|
description?: string;
|
|
2200
|
-
staleAfterSeconds?: number;
|
|
2201
2277
|
key?: (keyof InputRow & string) | readonly (keyof InputRow & string)[] | ((row: InputRow, index: number) => string | number | readonly unknown[]);
|
|
2202
2278
|
}): Promise<PlayDataset<OutputRow>>;
|
|
2203
2279
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1051,6 +1051,43 @@ interface PlayStagedFileRef {
|
|
|
1051
1051
|
bytes: number;
|
|
1052
1052
|
}
|
|
1053
1053
|
|
|
1054
|
+
type EnrichStepCommand = {
|
|
1055
|
+
alias: string;
|
|
1056
|
+
tool: string;
|
|
1057
|
+
operation?: string;
|
|
1058
|
+
payload: Record<string, unknown>;
|
|
1059
|
+
extract_js?: string;
|
|
1060
|
+
run_if_js?: string;
|
|
1061
|
+
description?: string;
|
|
1062
|
+
disabled?: boolean;
|
|
1063
|
+
};
|
|
1064
|
+
type EnrichWaterfallCommand = {
|
|
1065
|
+
with_waterfall: string;
|
|
1066
|
+
min_results?: number;
|
|
1067
|
+
commands: EnrichCommand[];
|
|
1068
|
+
description?: string;
|
|
1069
|
+
};
|
|
1070
|
+
type EnrichCommand = EnrichStepCommand | EnrichWaterfallCommand;
|
|
1071
|
+
type EnrichCompiledConfig = {
|
|
1072
|
+
version: 1;
|
|
1073
|
+
commands: EnrichCommand[];
|
|
1074
|
+
cost_cap_usd_per_run?: number;
|
|
1075
|
+
_comments?: Array<{
|
|
1076
|
+
path: string;
|
|
1077
|
+
lines: string[];
|
|
1078
|
+
}>;
|
|
1079
|
+
_expansion_preview?: {
|
|
1080
|
+
plays: Array<{
|
|
1081
|
+
alias: string;
|
|
1082
|
+
tool_id: string;
|
|
1083
|
+
template_group: string;
|
|
1084
|
+
runtime_group: string;
|
|
1085
|
+
estimated_credits_range: string;
|
|
1086
|
+
steps: Array<Record<string, unknown>>;
|
|
1087
|
+
}>;
|
|
1088
|
+
};
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1054
1091
|
type ExecuteToolRawOptions = {
|
|
1055
1092
|
includeToolMetadata?: boolean;
|
|
1056
1093
|
};
|
|
@@ -1350,6 +1387,12 @@ declare class DeeplineClient {
|
|
|
1350
1387
|
sourceFiles?: Record<string, string>;
|
|
1351
1388
|
artifact: Record<string, unknown>;
|
|
1352
1389
|
}): Promise<PlayCheckResult>;
|
|
1390
|
+
compileEnrichPlan(input: {
|
|
1391
|
+
plan_args?: string[];
|
|
1392
|
+
config?: unknown;
|
|
1393
|
+
}): Promise<{
|
|
1394
|
+
config: EnrichCompiledConfig;
|
|
1395
|
+
}>;
|
|
1353
1396
|
startPlayRunFromBundle(input: {
|
|
1354
1397
|
name: string;
|
|
1355
1398
|
sourceCode: string;
|
|
@@ -1954,6 +1997,37 @@ interface PlayDataset<T> extends AsyncIterable<T> {
|
|
|
1954
1997
|
};
|
|
1955
1998
|
}
|
|
1956
1999
|
|
|
2000
|
+
type EmailStatusVerdict = 'send' | 'send_with_caution' | 'verify_next' | 'hold' | 'drop';
|
|
2001
|
+
type EmailStatusValue = 'valid' | 'invalid' | 'catch_all' | 'valid_catch_all' | 'unknown' | 'do_not_mail' | 'spamtrap' | 'abuse' | 'disposable';
|
|
2002
|
+
type EmailStatusMapEntry = {
|
|
2003
|
+
status: EmailStatusValue;
|
|
2004
|
+
verdict?: EmailStatusVerdict;
|
|
2005
|
+
verified?: boolean;
|
|
2006
|
+
reason?: string;
|
|
2007
|
+
};
|
|
2008
|
+
type EmailStatusRule = EmailStatusMapEntry & {
|
|
2009
|
+
when: Record<string, string | number | boolean | null>;
|
|
2010
|
+
};
|
|
2011
|
+
type EmailStatusExtractorConfig = {
|
|
2012
|
+
provider: string;
|
|
2013
|
+
rawStatus?: string[];
|
|
2014
|
+
rawScore?: string[];
|
|
2015
|
+
valid?: string[];
|
|
2016
|
+
deliverability?: string[];
|
|
2017
|
+
catchAll?: string[];
|
|
2018
|
+
mxProvider?: string[];
|
|
2019
|
+
mxRecord?: string[];
|
|
2020
|
+
fraudScore?: string[];
|
|
2021
|
+
disposable?: string[];
|
|
2022
|
+
roleBased?: string[];
|
|
2023
|
+
freeEmail?: string[];
|
|
2024
|
+
abuse?: string[];
|
|
2025
|
+
spamtrap?: string[];
|
|
2026
|
+
suspect?: string[];
|
|
2027
|
+
statusMap?: Record<string, EmailStatusMapEntry>;
|
|
2028
|
+
rules?: EmailStatusRule[];
|
|
2029
|
+
};
|
|
2030
|
+
|
|
1957
2031
|
type ToolResultExecutionMetadata = {
|
|
1958
2032
|
idempotent: true;
|
|
1959
2033
|
cached: boolean;
|
|
@@ -1974,6 +2048,7 @@ type ToolResultExtractorDescriptor = {
|
|
|
1974
2048
|
transforms?: readonly string[];
|
|
1975
2049
|
enum?: readonly string[];
|
|
1976
2050
|
overrides?: readonly ToolResultExtractorOverride[];
|
|
2051
|
+
emailStatus?: EmailStatusExtractorConfig;
|
|
1977
2052
|
};
|
|
1978
2053
|
type ToolResultExtractorOverride = {
|
|
1979
2054
|
paths: readonly string[];
|
|
@@ -2145,6 +2220,7 @@ type ConditionalStepResolver<Row, Value, Else = null> = {
|
|
|
2145
2220
|
};
|
|
2146
2221
|
type StepOptions<Row> = {
|
|
2147
2222
|
readonly runIf?: (row: Row, index: number) => boolean | Promise<boolean>;
|
|
2223
|
+
readonly staleAfterSeconds?: number;
|
|
2148
2224
|
};
|
|
2149
2225
|
type StepProgram<Input, Output, Return = Output> = {
|
|
2150
2226
|
readonly kind: 'steps';
|
|
@@ -2163,6 +2239,7 @@ type StepProgramResolver<Input, Return> = {
|
|
|
2163
2239
|
};
|
|
2164
2240
|
type PlayStepProgramStep = {
|
|
2165
2241
|
readonly name: string;
|
|
2242
|
+
readonly staleAfterSeconds?: number;
|
|
2166
2243
|
readonly resolver: StepResolver<Record<string, unknown>, unknown> | ConditionalStepResolver<Record<string, unknown>, unknown> | StepProgramResolver<Record<string, unknown>, unknown>;
|
|
2167
2244
|
};
|
|
2168
2245
|
type ColumnResolver<Row, Value> = StepResolver<Row, Value> | ConditionalStepResolver<Row, Value> | StepProgramResolver<Row, Value>;
|
|
@@ -2197,7 +2274,6 @@ type DatasetBuilder<InputRow extends object, OutputRow extends object> = {
|
|
|
2197
2274
|
*/
|
|
2198
2275
|
run(options?: {
|
|
2199
2276
|
description?: string;
|
|
2200
|
-
staleAfterSeconds?: number;
|
|
2201
2277
|
key?: (keyof InputRow & string) | readonly (keyof InputRow & string)[] | ((row: InputRow, index: number) => string | number | readonly unknown[]);
|
|
2202
2278
|
}): Promise<PlayDataset<OutputRow>>;
|
|
2203
2279
|
};
|
package/dist/index.js
CHANGED
|
@@ -241,10 +241,10 @@ var import_node_path2 = require("path");
|
|
|
241
241
|
|
|
242
242
|
// src/release.ts
|
|
243
243
|
var SDK_RELEASE = {
|
|
244
|
-
version: "0.1.
|
|
245
|
-
apiContract: "2026-06-dataset-column-
|
|
244
|
+
version: "0.1.77",
|
|
245
|
+
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
246
246
|
supportPolicy: {
|
|
247
|
-
latest: "0.1.
|
|
247
|
+
latest: "0.1.77",
|
|
248
248
|
minimumSupported: "0.1.53",
|
|
249
249
|
deprecatedBelow: "0.1.53"
|
|
250
250
|
}
|
|
@@ -1127,6 +1127,9 @@ var DeeplineClient = class {
|
|
|
1127
1127
|
async checkPlayArtifact(input) {
|
|
1128
1128
|
return this.http.post("/api/v2/plays/check", input);
|
|
1129
1129
|
}
|
|
1130
|
+
async compileEnrichPlan(input) {
|
|
1131
|
+
return this.http.post("/api/v2/enrich/compile", input);
|
|
1132
|
+
}
|
|
1130
1133
|
async startPlayRunFromBundle(input) {
|
|
1131
1134
|
const compilerManifest = input.compilerManifest ?? await this.compilePlayManifest({
|
|
1132
1135
|
name: input.name,
|
|
@@ -1903,6 +1906,160 @@ function formatPlayBootstrapFinderKindsForSentence() {
|
|
|
1903
1906
|
return `${allButLast.join(", ")} or ${last}`;
|
|
1904
1907
|
}
|
|
1905
1908
|
|
|
1909
|
+
// ../shared_libs/play-runtime/email-status.ts
|
|
1910
|
+
var DEFAULT_STATUS_MAP = {
|
|
1911
|
+
verified: { status: "valid", verdict: "send", verified: true },
|
|
1912
|
+
valid: { status: "valid", verdict: "send", verified: true },
|
|
1913
|
+
deliverable: { status: "valid", verdict: "send", verified: true },
|
|
1914
|
+
true: { status: "valid", verdict: "send", verified: true },
|
|
1915
|
+
invalid: { status: "invalid", verdict: "drop", verified: false },
|
|
1916
|
+
undeliverable: { status: "invalid", verdict: "drop", verified: false },
|
|
1917
|
+
false: { status: "invalid", verdict: "drop", verified: false },
|
|
1918
|
+
"catch-all": {
|
|
1919
|
+
status: "catch_all",
|
|
1920
|
+
verdict: "verify_next",
|
|
1921
|
+
verified: false
|
|
1922
|
+
},
|
|
1923
|
+
catch_all: {
|
|
1924
|
+
status: "catch_all",
|
|
1925
|
+
verdict: "verify_next",
|
|
1926
|
+
verified: false
|
|
1927
|
+
},
|
|
1928
|
+
valid_catch_all: {
|
|
1929
|
+
status: "valid_catch_all",
|
|
1930
|
+
verdict: "send_with_caution",
|
|
1931
|
+
verified: true
|
|
1932
|
+
},
|
|
1933
|
+
accept_all: {
|
|
1934
|
+
status: "catch_all",
|
|
1935
|
+
verdict: "verify_next",
|
|
1936
|
+
verified: false
|
|
1937
|
+
},
|
|
1938
|
+
unknown: { status: "unknown", verdict: "hold", verified: false },
|
|
1939
|
+
unavailable: { status: "unknown", verdict: "hold", verified: false },
|
|
1940
|
+
do_not_mail: { status: "do_not_mail", verdict: "drop", verified: false },
|
|
1941
|
+
spamtrap: { status: "spamtrap", verdict: "drop", verified: false },
|
|
1942
|
+
abuse: { status: "abuse", verdict: "drop", verified: false },
|
|
1943
|
+
disposable: { status: "disposable", verdict: "drop", verified: false }
|
|
1944
|
+
};
|
|
1945
|
+
function normalizeKey(value) {
|
|
1946
|
+
if (value == null) return null;
|
|
1947
|
+
if (typeof value === "boolean") return String(value);
|
|
1948
|
+
const normalized = String(value).trim().toLowerCase().replace(/\s+/g, "_");
|
|
1949
|
+
return normalized || null;
|
|
1950
|
+
}
|
|
1951
|
+
function boolish(value) {
|
|
1952
|
+
if (typeof value === "boolean") return value;
|
|
1953
|
+
if (typeof value === "number") return value === 1 ? true : value === 0 ? false : null;
|
|
1954
|
+
if (typeof value !== "string") return null;
|
|
1955
|
+
const normalized = value.trim().toLowerCase();
|
|
1956
|
+
if (["true", "yes", "y", "1"].includes(normalized)) return true;
|
|
1957
|
+
if (["false", "no", "n", "0"].includes(normalized)) return false;
|
|
1958
|
+
return null;
|
|
1959
|
+
}
|
|
1960
|
+
function numberish(value) {
|
|
1961
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1962
|
+
if (typeof value !== "string" || value.trim() === "") return null;
|
|
1963
|
+
const parsed = Number(value);
|
|
1964
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1965
|
+
}
|
|
1966
|
+
function stringish(value) {
|
|
1967
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
1968
|
+
}
|
|
1969
|
+
function deliverability(value) {
|
|
1970
|
+
const normalized = normalizeKey(value);
|
|
1971
|
+
return normalized === "high" || normalized === "medium" || normalized === "low" ? normalized : "unknown";
|
|
1972
|
+
}
|
|
1973
|
+
function mxClass(mxProvider, mxRecord) {
|
|
1974
|
+
const haystack = `${stringish(mxProvider) ?? ""} ${stringish(mxRecord) ?? ""}`.toLowerCase();
|
|
1975
|
+
if (!haystack.trim()) return "unknown";
|
|
1976
|
+
if (/proofpoint|pphosted|mimecast|barracuda|ess\.barracudanetworks|ironport|cisco|iphmx|messagelabs|symantec/.test(
|
|
1977
|
+
haystack
|
|
1978
|
+
)) {
|
|
1979
|
+
return "security_gateway";
|
|
1980
|
+
}
|
|
1981
|
+
if (/aspmx\.l\.google|google|g-suite|google workspace/.test(haystack)) {
|
|
1982
|
+
return "workspace_mailbox";
|
|
1983
|
+
}
|
|
1984
|
+
if (/protection\.outlook|office365|microsoft|outlook|exchange online/.test(haystack)) {
|
|
1985
|
+
return "workspace_mailbox";
|
|
1986
|
+
}
|
|
1987
|
+
if (/gmail|yahoo|icloud|aol|hotmail/.test(haystack)) return "consumer_mailbox";
|
|
1988
|
+
if (/postfix|exim|sendmail|zimbra|plesk|cpanel|mail\./.test(haystack)) return "on_prem";
|
|
1989
|
+
return "unknown";
|
|
1990
|
+
}
|
|
1991
|
+
function entryForStatus(key, map) {
|
|
1992
|
+
if (!key) return null;
|
|
1993
|
+
return map?.[key] ?? DEFAULT_STATUS_MAP[key] ?? null;
|
|
1994
|
+
}
|
|
1995
|
+
function read(values, name) {
|
|
1996
|
+
return values[name];
|
|
1997
|
+
}
|
|
1998
|
+
function matchesRule(rule, values) {
|
|
1999
|
+
return Object.entries(rule.when).every(([key, expected]) => {
|
|
2000
|
+
const actual = read(values, key);
|
|
2001
|
+
if (key.endsWith("Lt")) {
|
|
2002
|
+
const source = numberish(read(values, key.slice(0, -2)));
|
|
2003
|
+
return typeof expected === "number" && source != null && source < expected;
|
|
2004
|
+
}
|
|
2005
|
+
if (typeof expected === "boolean") return boolish(actual) === expected;
|
|
2006
|
+
if (typeof expected === "number") return numberish(actual) === expected;
|
|
2007
|
+
return normalizeKey(actual) === normalizeKey(expected);
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
function buildEmailStatus({
|
|
2011
|
+
config,
|
|
2012
|
+
values
|
|
2013
|
+
}) {
|
|
2014
|
+
const rawStatus = read(values, "rawStatus");
|
|
2015
|
+
const rawScore = numberish(read(values, "rawScore"));
|
|
2016
|
+
const valid = boolish(read(values, "valid"));
|
|
2017
|
+
const catchAll = boolish(read(values, "catchAll"));
|
|
2018
|
+
const disposable = boolish(read(values, "disposable"));
|
|
2019
|
+
const abuse = boolish(read(values, "abuse"));
|
|
2020
|
+
const spamtrap = boolish(read(values, "spamtrap"));
|
|
2021
|
+
const suspect = boolish(read(values, "suspect"));
|
|
2022
|
+
const rawKey = normalizeKey(rawStatus);
|
|
2023
|
+
const mapped = config.rules?.find((rule) => matchesRule(rule, values)) ?? entryForStatus(rawKey, config.statusMap) ?? entryForStatus(valid == null ? null : String(valid), config.statusMap);
|
|
2024
|
+
const status = mapped?.status ?? (disposable ? "disposable" : abuse ? "abuse" : spamtrap ? "spamtrap" : catchAll ? "catch_all" : valid === true ? "valid" : valid === false ? "invalid" : "unknown");
|
|
2025
|
+
const defaultVerdict = status === "valid" ? "send" : status === "valid_catch_all" ? "send_with_caution" : status === "catch_all" ? "verify_next" : status === "unknown" ? "hold" : "drop";
|
|
2026
|
+
const verdict = mapped?.verdict ?? defaultVerdict;
|
|
2027
|
+
const verified = mapped?.verified ?? (status === "valid" || status === "valid_catch_all" || verdict === "send");
|
|
2028
|
+
const reasons = [
|
|
2029
|
+
mapped?.reason,
|
|
2030
|
+
catchAll ? "catch_all_domain" : null,
|
|
2031
|
+
mxClass(read(values, "mxProvider"), read(values, "mxRecord")) === "security_gateway" ? "security_gateway_mx" : null,
|
|
2032
|
+
suspect ? "provider_marked_suspect" : null
|
|
2033
|
+
].filter((reason) => typeof reason === "string");
|
|
2034
|
+
return {
|
|
2035
|
+
verdict,
|
|
2036
|
+
status,
|
|
2037
|
+
verified,
|
|
2038
|
+
confidence: rawScore,
|
|
2039
|
+
reasons,
|
|
2040
|
+
signals: {
|
|
2041
|
+
catch_all: catchAll,
|
|
2042
|
+
deliverability: deliverability(read(values, "deliverability")),
|
|
2043
|
+
mx_class: mxClass(read(values, "mxProvider"), read(values, "mxRecord")),
|
|
2044
|
+
mx_provider: stringish(read(values, "mxProvider")),
|
|
2045
|
+
mx_record: stringish(read(values, "mxRecord")),
|
|
2046
|
+
fraud_score: numberish(read(values, "fraudScore")),
|
|
2047
|
+
disposable,
|
|
2048
|
+
role_based: boolish(read(values, "roleBased")),
|
|
2049
|
+
free_email: boolish(read(values, "freeEmail")),
|
|
2050
|
+
abuse,
|
|
2051
|
+
spamtrap,
|
|
2052
|
+
suspect,
|
|
2053
|
+
valid
|
|
2054
|
+
},
|
|
2055
|
+
provider: {
|
|
2056
|
+
name: config.provider,
|
|
2057
|
+
raw_status: typeof rawStatus === "string" || typeof rawStatus === "boolean" || typeof rawStatus === "number" ? rawStatus : null,
|
|
2058
|
+
raw_score: rawScore
|
|
2059
|
+
}
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
|
|
1906
2063
|
// ../shared_libs/play-runtime/tool-result.ts
|
|
1907
2064
|
var TARGET_FALLBACK_KEYS = {
|
|
1908
2065
|
email: [/^email$/i, /^address$/i, /email/i],
|
|
@@ -2086,6 +2243,42 @@ function findFirstTargetByPath(result, paths) {
|
|
|
2086
2243
|
}
|
|
2087
2244
|
return null;
|
|
2088
2245
|
}
|
|
2246
|
+
function firstValueForPaths(result, paths) {
|
|
2247
|
+
return findFirstTargetByPath(result, paths);
|
|
2248
|
+
}
|
|
2249
|
+
function buildEmailStatusTarget(result, descriptor) {
|
|
2250
|
+
const config = descriptor.emailStatus;
|
|
2251
|
+
if (!config) return null;
|
|
2252
|
+
const values = {};
|
|
2253
|
+
const pathSets = {
|
|
2254
|
+
rawStatus: config.rawStatus,
|
|
2255
|
+
rawScore: config.rawScore,
|
|
2256
|
+
valid: config.valid,
|
|
2257
|
+
deliverability: config.deliverability,
|
|
2258
|
+
catchAll: config.catchAll,
|
|
2259
|
+
mxProvider: config.mxProvider,
|
|
2260
|
+
mxRecord: config.mxRecord,
|
|
2261
|
+
fraudScore: config.fraudScore,
|
|
2262
|
+
disposable: config.disposable,
|
|
2263
|
+
roleBased: config.roleBased,
|
|
2264
|
+
freeEmail: config.freeEmail,
|
|
2265
|
+
abuse: config.abuse,
|
|
2266
|
+
spamtrap: config.spamtrap,
|
|
2267
|
+
suspect: config.suspect
|
|
2268
|
+
};
|
|
2269
|
+
let firstPath = null;
|
|
2270
|
+
for (const [name, paths] of Object.entries(pathSets)) {
|
|
2271
|
+
const match = firstValueForPaths(result, paths);
|
|
2272
|
+
if (!match) continue;
|
|
2273
|
+
values[name] = match.value;
|
|
2274
|
+
firstPath ??= match.path;
|
|
2275
|
+
}
|
|
2276
|
+
if (!firstPath) return null;
|
|
2277
|
+
return {
|
|
2278
|
+
path: firstPath,
|
|
2279
|
+
value: buildEmailStatus({ config, values })
|
|
2280
|
+
};
|
|
2281
|
+
}
|
|
2089
2282
|
function findFirstTargetByKey(result, target, depth = 0, path = []) {
|
|
2090
2283
|
if (depth > 6) return null;
|
|
2091
2284
|
if (Array.isArray(result)) {
|
|
@@ -2235,6 +2428,11 @@ function deriveListKeys(input) {
|
|
|
2235
2428
|
function buildTargets(result, extractors, targetGetters) {
|
|
2236
2429
|
const targets = {};
|
|
2237
2430
|
for (const [target, descriptor] of Object.entries(extractors ?? {})) {
|
|
2431
|
+
const emailStatusTarget = buildEmailStatusTarget(result, descriptor);
|
|
2432
|
+
if (emailStatusTarget) {
|
|
2433
|
+
targets[target] = emailStatusTarget;
|
|
2434
|
+
continue;
|
|
2435
|
+
}
|
|
2238
2436
|
const fromExtractor = findFirstTargetByPath(result, descriptor.paths);
|
|
2239
2437
|
if (!fromExtractor) continue;
|
|
2240
2438
|
const transformed = coerceToEnum(
|