deepline 0.1.76 → 0.1.78
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/README.md +5 -8
- package/dist/cli/index.js +534 -350
- package/dist/cli/index.mjs +547 -363
- package/dist/index.d.mts +40 -2
- package/dist/index.d.ts +40 -2
- package/dist/index.js +198 -2
- package/dist/index.mjs +198 -2
- package/dist/repo/sdk/src/client.ts +7 -0
- package/dist/repo/sdk/src/play.ts +1 -1
- package/dist/repo/sdk/src/release.ts +2 -2
- package/dist/repo/sdk/src/types.ts +4 -0
- package/dist/repo/shared_libs/play-runtime/email-status.ts +301 -0
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +58 -1
- package/dist/repo/shared_libs/plays/dataset.ts +3 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -775,6 +775,9 @@ interface PlayListItem {
|
|
|
775
775
|
isDraftDirty?: boolean;
|
|
776
776
|
inputSchema?: Record<string, unknown> | null;
|
|
777
777
|
outputSchema?: Record<string, unknown> | null;
|
|
778
|
+
staticPipeline?: unknown;
|
|
779
|
+
currentRevision?: PlayRevisionSummary | null;
|
|
780
|
+
liveRevision?: PlayRevisionSummary | null;
|
|
778
781
|
aliases?: string[];
|
|
779
782
|
}
|
|
780
783
|
interface PlayDescription {
|
|
@@ -788,6 +791,7 @@ interface PlayDescription {
|
|
|
788
791
|
aliases: string[];
|
|
789
792
|
inputSchema?: Record<string, unknown> | null;
|
|
790
793
|
outputSchema?: Record<string, unknown> | null;
|
|
794
|
+
staticPipeline?: Record<string, unknown> | null;
|
|
791
795
|
csvInput?: Record<string, unknown> | null;
|
|
792
796
|
rowOutputSchema?: Record<string, unknown> | null;
|
|
793
797
|
runCommand: string;
|
|
@@ -1953,7 +1957,9 @@ type PlayDatasetTransformOptions = {
|
|
|
1953
1957
|
* Deepline keeps row progress, retries, memory use, and table output under
|
|
1954
1958
|
* runtime control. Use `count()` and `peek()` for bounded inspection. Use
|
|
1955
1959
|
* `materialize(limit)` or async iteration only when the dataset is intentionally
|
|
1956
|
-
* small and bounded.
|
|
1960
|
+
* small and bounded. `PlayDataset` intentionally does not expose `.rows`,
|
|
1961
|
+
* `.toArray()`, or other array aliases; those hide the runtime cost of loading
|
|
1962
|
+
* persisted rows into memory.
|
|
1957
1963
|
*/
|
|
1958
1964
|
interface PlayDataset<T> extends AsyncIterable<T> {
|
|
1959
1965
|
readonly [PLAY_DATASET_BRAND]: true;
|
|
@@ -1997,6 +2003,37 @@ interface PlayDataset<T> extends AsyncIterable<T> {
|
|
|
1997
2003
|
};
|
|
1998
2004
|
}
|
|
1999
2005
|
|
|
2006
|
+
type EmailStatusVerdict = 'send' | 'send_with_caution' | 'verify_next' | 'hold' | 'drop';
|
|
2007
|
+
type EmailStatusValue = 'valid' | 'invalid' | 'catch_all' | 'valid_catch_all' | 'unknown' | 'do_not_mail' | 'spamtrap' | 'abuse' | 'disposable';
|
|
2008
|
+
type EmailStatusMapEntry = {
|
|
2009
|
+
status: EmailStatusValue;
|
|
2010
|
+
verdict?: EmailStatusVerdict;
|
|
2011
|
+
verified?: boolean;
|
|
2012
|
+
reason?: string;
|
|
2013
|
+
};
|
|
2014
|
+
type EmailStatusRule = EmailStatusMapEntry & {
|
|
2015
|
+
when: Record<string, string | number | boolean | null>;
|
|
2016
|
+
};
|
|
2017
|
+
type EmailStatusExtractorConfig = {
|
|
2018
|
+
provider: string;
|
|
2019
|
+
rawStatus?: string[];
|
|
2020
|
+
rawScore?: string[];
|
|
2021
|
+
valid?: string[];
|
|
2022
|
+
deliverability?: string[];
|
|
2023
|
+
catchAll?: string[];
|
|
2024
|
+
mxProvider?: string[];
|
|
2025
|
+
mxRecord?: string[];
|
|
2026
|
+
fraudScore?: string[];
|
|
2027
|
+
disposable?: string[];
|
|
2028
|
+
roleBased?: string[];
|
|
2029
|
+
freeEmail?: string[];
|
|
2030
|
+
abuse?: string[];
|
|
2031
|
+
spamtrap?: string[];
|
|
2032
|
+
suspect?: string[];
|
|
2033
|
+
statusMap?: Record<string, EmailStatusMapEntry>;
|
|
2034
|
+
rules?: EmailStatusRule[];
|
|
2035
|
+
};
|
|
2036
|
+
|
|
2000
2037
|
type ToolResultExecutionMetadata = {
|
|
2001
2038
|
idempotent: true;
|
|
2002
2039
|
cached: boolean;
|
|
@@ -2017,6 +2054,7 @@ type ToolResultExtractorDescriptor = {
|
|
|
2017
2054
|
transforms?: readonly string[];
|
|
2018
2055
|
enum?: readonly string[];
|
|
2019
2056
|
overrides?: readonly ToolResultExtractorOverride[];
|
|
2057
|
+
emailStatus?: EmailStatusExtractorConfig;
|
|
2020
2058
|
};
|
|
2021
2059
|
type ToolResultExtractorOverride = {
|
|
2022
2060
|
paths: readonly string[];
|
|
@@ -2435,7 +2473,7 @@ interface DeeplinePlayRuntimeContext {
|
|
|
2435
2473
|
* @param options - Run options.
|
|
2436
2474
|
* @returns Program output.
|
|
2437
2475
|
*/
|
|
2438
|
-
runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput,
|
|
2476
|
+
runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput, any, TOutput>, input: TInput, options?: {
|
|
2439
2477
|
description?: string;
|
|
2440
2478
|
}): Promise<TOutput>;
|
|
2441
2479
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -775,6 +775,9 @@ interface PlayListItem {
|
|
|
775
775
|
isDraftDirty?: boolean;
|
|
776
776
|
inputSchema?: Record<string, unknown> | null;
|
|
777
777
|
outputSchema?: Record<string, unknown> | null;
|
|
778
|
+
staticPipeline?: unknown;
|
|
779
|
+
currentRevision?: PlayRevisionSummary | null;
|
|
780
|
+
liveRevision?: PlayRevisionSummary | null;
|
|
778
781
|
aliases?: string[];
|
|
779
782
|
}
|
|
780
783
|
interface PlayDescription {
|
|
@@ -788,6 +791,7 @@ interface PlayDescription {
|
|
|
788
791
|
aliases: string[];
|
|
789
792
|
inputSchema?: Record<string, unknown> | null;
|
|
790
793
|
outputSchema?: Record<string, unknown> | null;
|
|
794
|
+
staticPipeline?: Record<string, unknown> | null;
|
|
791
795
|
csvInput?: Record<string, unknown> | null;
|
|
792
796
|
rowOutputSchema?: Record<string, unknown> | null;
|
|
793
797
|
runCommand: string;
|
|
@@ -1953,7 +1957,9 @@ type PlayDatasetTransformOptions = {
|
|
|
1953
1957
|
* Deepline keeps row progress, retries, memory use, and table output under
|
|
1954
1958
|
* runtime control. Use `count()` and `peek()` for bounded inspection. Use
|
|
1955
1959
|
* `materialize(limit)` or async iteration only when the dataset is intentionally
|
|
1956
|
-
* small and bounded.
|
|
1960
|
+
* small and bounded. `PlayDataset` intentionally does not expose `.rows`,
|
|
1961
|
+
* `.toArray()`, or other array aliases; those hide the runtime cost of loading
|
|
1962
|
+
* persisted rows into memory.
|
|
1957
1963
|
*/
|
|
1958
1964
|
interface PlayDataset<T> extends AsyncIterable<T> {
|
|
1959
1965
|
readonly [PLAY_DATASET_BRAND]: true;
|
|
@@ -1997,6 +2003,37 @@ interface PlayDataset<T> extends AsyncIterable<T> {
|
|
|
1997
2003
|
};
|
|
1998
2004
|
}
|
|
1999
2005
|
|
|
2006
|
+
type EmailStatusVerdict = 'send' | 'send_with_caution' | 'verify_next' | 'hold' | 'drop';
|
|
2007
|
+
type EmailStatusValue = 'valid' | 'invalid' | 'catch_all' | 'valid_catch_all' | 'unknown' | 'do_not_mail' | 'spamtrap' | 'abuse' | 'disposable';
|
|
2008
|
+
type EmailStatusMapEntry = {
|
|
2009
|
+
status: EmailStatusValue;
|
|
2010
|
+
verdict?: EmailStatusVerdict;
|
|
2011
|
+
verified?: boolean;
|
|
2012
|
+
reason?: string;
|
|
2013
|
+
};
|
|
2014
|
+
type EmailStatusRule = EmailStatusMapEntry & {
|
|
2015
|
+
when: Record<string, string | number | boolean | null>;
|
|
2016
|
+
};
|
|
2017
|
+
type EmailStatusExtractorConfig = {
|
|
2018
|
+
provider: string;
|
|
2019
|
+
rawStatus?: string[];
|
|
2020
|
+
rawScore?: string[];
|
|
2021
|
+
valid?: string[];
|
|
2022
|
+
deliverability?: string[];
|
|
2023
|
+
catchAll?: string[];
|
|
2024
|
+
mxProvider?: string[];
|
|
2025
|
+
mxRecord?: string[];
|
|
2026
|
+
fraudScore?: string[];
|
|
2027
|
+
disposable?: string[];
|
|
2028
|
+
roleBased?: string[];
|
|
2029
|
+
freeEmail?: string[];
|
|
2030
|
+
abuse?: string[];
|
|
2031
|
+
spamtrap?: string[];
|
|
2032
|
+
suspect?: string[];
|
|
2033
|
+
statusMap?: Record<string, EmailStatusMapEntry>;
|
|
2034
|
+
rules?: EmailStatusRule[];
|
|
2035
|
+
};
|
|
2036
|
+
|
|
2000
2037
|
type ToolResultExecutionMetadata = {
|
|
2001
2038
|
idempotent: true;
|
|
2002
2039
|
cached: boolean;
|
|
@@ -2017,6 +2054,7 @@ type ToolResultExtractorDescriptor = {
|
|
|
2017
2054
|
transforms?: readonly string[];
|
|
2018
2055
|
enum?: readonly string[];
|
|
2019
2056
|
overrides?: readonly ToolResultExtractorOverride[];
|
|
2057
|
+
emailStatus?: EmailStatusExtractorConfig;
|
|
2020
2058
|
};
|
|
2021
2059
|
type ToolResultExtractorOverride = {
|
|
2022
2060
|
paths: readonly string[];
|
|
@@ -2435,7 +2473,7 @@ interface DeeplinePlayRuntimeContext {
|
|
|
2435
2473
|
* @param options - Run options.
|
|
2436
2474
|
* @returns Program output.
|
|
2437
2475
|
*/
|
|
2438
|
-
runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput,
|
|
2476
|
+
runSteps<TInput extends Record<string, unknown>, TOutput>(program: StepProgram<TInput, any, TOutput>, input: TInput, options?: {
|
|
2439
2477
|
description?: string;
|
|
2440
2478
|
}): Promise<TOutput>;
|
|
2441
2479
|
/**
|
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.
|
|
244
|
+
version: "0.1.78",
|
|
245
245
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
246
246
|
supportPolicy: {
|
|
247
|
-
latest: "0.1.
|
|
247
|
+
latest: "0.1.78",
|
|
248
248
|
minimumSupported: "0.1.53",
|
|
249
249
|
deprecatedBelow: "0.1.53"
|
|
250
250
|
}
|
|
@@ -820,6 +820,7 @@ var DeeplineClient = class {
|
|
|
820
820
|
aliases,
|
|
821
821
|
inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
|
|
822
822
|
outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
|
|
823
|
+
staticPipeline: isRecord(play.staticPipeline) ? play.staticPipeline : isRecord(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
|
|
823
824
|
...csvInput ? { csvInput } : {},
|
|
824
825
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
825
826
|
runCommand,
|
|
@@ -1906,6 +1907,160 @@ function formatPlayBootstrapFinderKindsForSentence() {
|
|
|
1906
1907
|
return `${allButLast.join(", ")} or ${last}`;
|
|
1907
1908
|
}
|
|
1908
1909
|
|
|
1910
|
+
// ../shared_libs/play-runtime/email-status.ts
|
|
1911
|
+
var DEFAULT_STATUS_MAP = {
|
|
1912
|
+
verified: { status: "valid", verdict: "send", verified: true },
|
|
1913
|
+
valid: { status: "valid", verdict: "send", verified: true },
|
|
1914
|
+
deliverable: { status: "valid", verdict: "send", verified: true },
|
|
1915
|
+
true: { status: "valid", verdict: "send", verified: true },
|
|
1916
|
+
invalid: { status: "invalid", verdict: "drop", verified: false },
|
|
1917
|
+
undeliverable: { status: "invalid", verdict: "drop", verified: false },
|
|
1918
|
+
false: { status: "invalid", verdict: "drop", verified: false },
|
|
1919
|
+
"catch-all": {
|
|
1920
|
+
status: "catch_all",
|
|
1921
|
+
verdict: "verify_next",
|
|
1922
|
+
verified: false
|
|
1923
|
+
},
|
|
1924
|
+
catch_all: {
|
|
1925
|
+
status: "catch_all",
|
|
1926
|
+
verdict: "verify_next",
|
|
1927
|
+
verified: false
|
|
1928
|
+
},
|
|
1929
|
+
valid_catch_all: {
|
|
1930
|
+
status: "valid_catch_all",
|
|
1931
|
+
verdict: "send_with_caution",
|
|
1932
|
+
verified: true
|
|
1933
|
+
},
|
|
1934
|
+
accept_all: {
|
|
1935
|
+
status: "catch_all",
|
|
1936
|
+
verdict: "verify_next",
|
|
1937
|
+
verified: false
|
|
1938
|
+
},
|
|
1939
|
+
unknown: { status: "unknown", verdict: "hold", verified: false },
|
|
1940
|
+
unavailable: { status: "unknown", verdict: "hold", verified: false },
|
|
1941
|
+
do_not_mail: { status: "do_not_mail", verdict: "drop", verified: false },
|
|
1942
|
+
spamtrap: { status: "spamtrap", verdict: "drop", verified: false },
|
|
1943
|
+
abuse: { status: "abuse", verdict: "drop", verified: false },
|
|
1944
|
+
disposable: { status: "disposable", verdict: "drop", verified: false }
|
|
1945
|
+
};
|
|
1946
|
+
function normalizeKey(value) {
|
|
1947
|
+
if (value == null) return null;
|
|
1948
|
+
if (typeof value === "boolean") return String(value);
|
|
1949
|
+
const normalized = String(value).trim().toLowerCase().replace(/\s+/g, "_");
|
|
1950
|
+
return normalized || null;
|
|
1951
|
+
}
|
|
1952
|
+
function boolish(value) {
|
|
1953
|
+
if (typeof value === "boolean") return value;
|
|
1954
|
+
if (typeof value === "number") return value === 1 ? true : value === 0 ? false : null;
|
|
1955
|
+
if (typeof value !== "string") return null;
|
|
1956
|
+
const normalized = value.trim().toLowerCase();
|
|
1957
|
+
if (["true", "yes", "y", "1"].includes(normalized)) return true;
|
|
1958
|
+
if (["false", "no", "n", "0"].includes(normalized)) return false;
|
|
1959
|
+
return null;
|
|
1960
|
+
}
|
|
1961
|
+
function numberish(value) {
|
|
1962
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1963
|
+
if (typeof value !== "string" || value.trim() === "") return null;
|
|
1964
|
+
const parsed = Number(value);
|
|
1965
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1966
|
+
}
|
|
1967
|
+
function stringish(value) {
|
|
1968
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
1969
|
+
}
|
|
1970
|
+
function deliverability(value) {
|
|
1971
|
+
const normalized = normalizeKey(value);
|
|
1972
|
+
return normalized === "high" || normalized === "medium" || normalized === "low" ? normalized : "unknown";
|
|
1973
|
+
}
|
|
1974
|
+
function mxClass(mxProvider, mxRecord) {
|
|
1975
|
+
const haystack = `${stringish(mxProvider) ?? ""} ${stringish(mxRecord) ?? ""}`.toLowerCase();
|
|
1976
|
+
if (!haystack.trim()) return "unknown";
|
|
1977
|
+
if (/proofpoint|pphosted|mimecast|barracuda|ess\.barracudanetworks|ironport|cisco|iphmx|messagelabs|symantec/.test(
|
|
1978
|
+
haystack
|
|
1979
|
+
)) {
|
|
1980
|
+
return "security_gateway";
|
|
1981
|
+
}
|
|
1982
|
+
if (/aspmx\.l\.google|google|g-suite|google workspace/.test(haystack)) {
|
|
1983
|
+
return "workspace_mailbox";
|
|
1984
|
+
}
|
|
1985
|
+
if (/protection\.outlook|office365|microsoft|outlook|exchange online/.test(haystack)) {
|
|
1986
|
+
return "workspace_mailbox";
|
|
1987
|
+
}
|
|
1988
|
+
if (/gmail|yahoo|icloud|aol|hotmail/.test(haystack)) return "consumer_mailbox";
|
|
1989
|
+
if (/postfix|exim|sendmail|zimbra|plesk|cpanel|mail\./.test(haystack)) return "on_prem";
|
|
1990
|
+
return "unknown";
|
|
1991
|
+
}
|
|
1992
|
+
function entryForStatus(key, map) {
|
|
1993
|
+
if (!key) return null;
|
|
1994
|
+
return map?.[key] ?? DEFAULT_STATUS_MAP[key] ?? null;
|
|
1995
|
+
}
|
|
1996
|
+
function read(values, name) {
|
|
1997
|
+
return values[name];
|
|
1998
|
+
}
|
|
1999
|
+
function matchesRule(rule, values) {
|
|
2000
|
+
return Object.entries(rule.when).every(([key, expected]) => {
|
|
2001
|
+
const actual = read(values, key);
|
|
2002
|
+
if (key.endsWith("Lt")) {
|
|
2003
|
+
const source = numberish(read(values, key.slice(0, -2)));
|
|
2004
|
+
return typeof expected === "number" && source != null && source < expected;
|
|
2005
|
+
}
|
|
2006
|
+
if (typeof expected === "boolean") return boolish(actual) === expected;
|
|
2007
|
+
if (typeof expected === "number") return numberish(actual) === expected;
|
|
2008
|
+
return normalizeKey(actual) === normalizeKey(expected);
|
|
2009
|
+
});
|
|
2010
|
+
}
|
|
2011
|
+
function buildEmailStatus({
|
|
2012
|
+
config,
|
|
2013
|
+
values
|
|
2014
|
+
}) {
|
|
2015
|
+
const rawStatus = read(values, "rawStatus");
|
|
2016
|
+
const rawScore = numberish(read(values, "rawScore"));
|
|
2017
|
+
const valid = boolish(read(values, "valid"));
|
|
2018
|
+
const catchAll = boolish(read(values, "catchAll"));
|
|
2019
|
+
const disposable = boolish(read(values, "disposable"));
|
|
2020
|
+
const abuse = boolish(read(values, "abuse"));
|
|
2021
|
+
const spamtrap = boolish(read(values, "spamtrap"));
|
|
2022
|
+
const suspect = boolish(read(values, "suspect"));
|
|
2023
|
+
const rawKey = normalizeKey(rawStatus);
|
|
2024
|
+
const mapped = config.rules?.find((rule) => matchesRule(rule, values)) ?? entryForStatus(rawKey, config.statusMap) ?? entryForStatus(valid == null ? null : String(valid), config.statusMap);
|
|
2025
|
+
const status = mapped?.status ?? (disposable ? "disposable" : abuse ? "abuse" : spamtrap ? "spamtrap" : catchAll ? "catch_all" : valid === true ? "valid" : valid === false ? "invalid" : "unknown");
|
|
2026
|
+
const defaultVerdict = status === "valid" ? "send" : status === "valid_catch_all" ? "send_with_caution" : status === "catch_all" ? "verify_next" : status === "unknown" ? "hold" : "drop";
|
|
2027
|
+
const verdict = mapped?.verdict ?? defaultVerdict;
|
|
2028
|
+
const verified = mapped?.verified ?? (status === "valid" || status === "valid_catch_all" || verdict === "send");
|
|
2029
|
+
const reasons = [
|
|
2030
|
+
mapped?.reason,
|
|
2031
|
+
catchAll ? "catch_all_domain" : null,
|
|
2032
|
+
mxClass(read(values, "mxProvider"), read(values, "mxRecord")) === "security_gateway" ? "security_gateway_mx" : null,
|
|
2033
|
+
suspect ? "provider_marked_suspect" : null
|
|
2034
|
+
].filter((reason) => typeof reason === "string");
|
|
2035
|
+
return {
|
|
2036
|
+
verdict,
|
|
2037
|
+
status,
|
|
2038
|
+
verified,
|
|
2039
|
+
confidence: rawScore,
|
|
2040
|
+
reasons,
|
|
2041
|
+
signals: {
|
|
2042
|
+
catch_all: catchAll,
|
|
2043
|
+
deliverability: deliverability(read(values, "deliverability")),
|
|
2044
|
+
mx_class: mxClass(read(values, "mxProvider"), read(values, "mxRecord")),
|
|
2045
|
+
mx_provider: stringish(read(values, "mxProvider")),
|
|
2046
|
+
mx_record: stringish(read(values, "mxRecord")),
|
|
2047
|
+
fraud_score: numberish(read(values, "fraudScore")),
|
|
2048
|
+
disposable,
|
|
2049
|
+
role_based: boolish(read(values, "roleBased")),
|
|
2050
|
+
free_email: boolish(read(values, "freeEmail")),
|
|
2051
|
+
abuse,
|
|
2052
|
+
spamtrap,
|
|
2053
|
+
suspect,
|
|
2054
|
+
valid
|
|
2055
|
+
},
|
|
2056
|
+
provider: {
|
|
2057
|
+
name: config.provider,
|
|
2058
|
+
raw_status: typeof rawStatus === "string" || typeof rawStatus === "boolean" || typeof rawStatus === "number" ? rawStatus : null,
|
|
2059
|
+
raw_score: rawScore
|
|
2060
|
+
}
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
|
|
1909
2064
|
// ../shared_libs/play-runtime/tool-result.ts
|
|
1910
2065
|
var TARGET_FALLBACK_KEYS = {
|
|
1911
2066
|
email: [/^email$/i, /^address$/i, /email/i],
|
|
@@ -2089,6 +2244,42 @@ function findFirstTargetByPath(result, paths) {
|
|
|
2089
2244
|
}
|
|
2090
2245
|
return null;
|
|
2091
2246
|
}
|
|
2247
|
+
function firstValueForPaths(result, paths) {
|
|
2248
|
+
return findFirstTargetByPath(result, paths);
|
|
2249
|
+
}
|
|
2250
|
+
function buildEmailStatusTarget(result, descriptor) {
|
|
2251
|
+
const config = descriptor.emailStatus;
|
|
2252
|
+
if (!config) return null;
|
|
2253
|
+
const values = {};
|
|
2254
|
+
const pathSets = {
|
|
2255
|
+
rawStatus: config.rawStatus,
|
|
2256
|
+
rawScore: config.rawScore,
|
|
2257
|
+
valid: config.valid,
|
|
2258
|
+
deliverability: config.deliverability,
|
|
2259
|
+
catchAll: config.catchAll,
|
|
2260
|
+
mxProvider: config.mxProvider,
|
|
2261
|
+
mxRecord: config.mxRecord,
|
|
2262
|
+
fraudScore: config.fraudScore,
|
|
2263
|
+
disposable: config.disposable,
|
|
2264
|
+
roleBased: config.roleBased,
|
|
2265
|
+
freeEmail: config.freeEmail,
|
|
2266
|
+
abuse: config.abuse,
|
|
2267
|
+
spamtrap: config.spamtrap,
|
|
2268
|
+
suspect: config.suspect
|
|
2269
|
+
};
|
|
2270
|
+
let firstPath = null;
|
|
2271
|
+
for (const [name, paths] of Object.entries(pathSets)) {
|
|
2272
|
+
const match = firstValueForPaths(result, paths);
|
|
2273
|
+
if (!match) continue;
|
|
2274
|
+
values[name] = match.value;
|
|
2275
|
+
firstPath ??= match.path;
|
|
2276
|
+
}
|
|
2277
|
+
if (!firstPath) return null;
|
|
2278
|
+
return {
|
|
2279
|
+
path: firstPath,
|
|
2280
|
+
value: buildEmailStatus({ config, values })
|
|
2281
|
+
};
|
|
2282
|
+
}
|
|
2092
2283
|
function findFirstTargetByKey(result, target, depth = 0, path = []) {
|
|
2093
2284
|
if (depth > 6) return null;
|
|
2094
2285
|
if (Array.isArray(result)) {
|
|
@@ -2238,6 +2429,11 @@ function deriveListKeys(input) {
|
|
|
2238
2429
|
function buildTargets(result, extractors, targetGetters) {
|
|
2239
2430
|
const targets = {};
|
|
2240
2431
|
for (const [target, descriptor] of Object.entries(extractors ?? {})) {
|
|
2432
|
+
const emailStatusTarget = buildEmailStatusTarget(result, descriptor);
|
|
2433
|
+
if (emailStatusTarget) {
|
|
2434
|
+
targets[target] = emailStatusTarget;
|
|
2435
|
+
continue;
|
|
2436
|
+
}
|
|
2241
2437
|
const fromExtractor = findFirstTargetByPath(result, descriptor.paths);
|
|
2242
2438
|
if (!fromExtractor) continue;
|
|
2243
2439
|
const transformed = coerceToEnum(
|
package/dist/index.mjs
CHANGED
|
@@ -179,10 +179,10 @@ import { join as join2 } from "path";
|
|
|
179
179
|
|
|
180
180
|
// src/release.ts
|
|
181
181
|
var SDK_RELEASE = {
|
|
182
|
-
version: "0.1.
|
|
182
|
+
version: "0.1.78",
|
|
183
183
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
184
184
|
supportPolicy: {
|
|
185
|
-
latest: "0.1.
|
|
185
|
+
latest: "0.1.78",
|
|
186
186
|
minimumSupported: "0.1.53",
|
|
187
187
|
deprecatedBelow: "0.1.53"
|
|
188
188
|
}
|
|
@@ -758,6 +758,7 @@ var DeeplineClient = class {
|
|
|
758
758
|
aliases,
|
|
759
759
|
inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
|
|
760
760
|
outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
|
|
761
|
+
staticPipeline: isRecord(play.staticPipeline) ? play.staticPipeline : isRecord(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
|
|
761
762
|
...csvInput ? { csvInput } : {},
|
|
762
763
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
763
764
|
runCommand,
|
|
@@ -1844,6 +1845,160 @@ function formatPlayBootstrapFinderKindsForSentence() {
|
|
|
1844
1845
|
return `${allButLast.join(", ")} or ${last}`;
|
|
1845
1846
|
}
|
|
1846
1847
|
|
|
1848
|
+
// ../shared_libs/play-runtime/email-status.ts
|
|
1849
|
+
var DEFAULT_STATUS_MAP = {
|
|
1850
|
+
verified: { status: "valid", verdict: "send", verified: true },
|
|
1851
|
+
valid: { status: "valid", verdict: "send", verified: true },
|
|
1852
|
+
deliverable: { status: "valid", verdict: "send", verified: true },
|
|
1853
|
+
true: { status: "valid", verdict: "send", verified: true },
|
|
1854
|
+
invalid: { status: "invalid", verdict: "drop", verified: false },
|
|
1855
|
+
undeliverable: { status: "invalid", verdict: "drop", verified: false },
|
|
1856
|
+
false: { status: "invalid", verdict: "drop", verified: false },
|
|
1857
|
+
"catch-all": {
|
|
1858
|
+
status: "catch_all",
|
|
1859
|
+
verdict: "verify_next",
|
|
1860
|
+
verified: false
|
|
1861
|
+
},
|
|
1862
|
+
catch_all: {
|
|
1863
|
+
status: "catch_all",
|
|
1864
|
+
verdict: "verify_next",
|
|
1865
|
+
verified: false
|
|
1866
|
+
},
|
|
1867
|
+
valid_catch_all: {
|
|
1868
|
+
status: "valid_catch_all",
|
|
1869
|
+
verdict: "send_with_caution",
|
|
1870
|
+
verified: true
|
|
1871
|
+
},
|
|
1872
|
+
accept_all: {
|
|
1873
|
+
status: "catch_all",
|
|
1874
|
+
verdict: "verify_next",
|
|
1875
|
+
verified: false
|
|
1876
|
+
},
|
|
1877
|
+
unknown: { status: "unknown", verdict: "hold", verified: false },
|
|
1878
|
+
unavailable: { status: "unknown", verdict: "hold", verified: false },
|
|
1879
|
+
do_not_mail: { status: "do_not_mail", verdict: "drop", verified: false },
|
|
1880
|
+
spamtrap: { status: "spamtrap", verdict: "drop", verified: false },
|
|
1881
|
+
abuse: { status: "abuse", verdict: "drop", verified: false },
|
|
1882
|
+
disposable: { status: "disposable", verdict: "drop", verified: false }
|
|
1883
|
+
};
|
|
1884
|
+
function normalizeKey(value) {
|
|
1885
|
+
if (value == null) return null;
|
|
1886
|
+
if (typeof value === "boolean") return String(value);
|
|
1887
|
+
const normalized = String(value).trim().toLowerCase().replace(/\s+/g, "_");
|
|
1888
|
+
return normalized || null;
|
|
1889
|
+
}
|
|
1890
|
+
function boolish(value) {
|
|
1891
|
+
if (typeof value === "boolean") return value;
|
|
1892
|
+
if (typeof value === "number") return value === 1 ? true : value === 0 ? false : null;
|
|
1893
|
+
if (typeof value !== "string") return null;
|
|
1894
|
+
const normalized = value.trim().toLowerCase();
|
|
1895
|
+
if (["true", "yes", "y", "1"].includes(normalized)) return true;
|
|
1896
|
+
if (["false", "no", "n", "0"].includes(normalized)) return false;
|
|
1897
|
+
return null;
|
|
1898
|
+
}
|
|
1899
|
+
function numberish(value) {
|
|
1900
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1901
|
+
if (typeof value !== "string" || value.trim() === "") return null;
|
|
1902
|
+
const parsed = Number(value);
|
|
1903
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
1904
|
+
}
|
|
1905
|
+
function stringish(value) {
|
|
1906
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
1907
|
+
}
|
|
1908
|
+
function deliverability(value) {
|
|
1909
|
+
const normalized = normalizeKey(value);
|
|
1910
|
+
return normalized === "high" || normalized === "medium" || normalized === "low" ? normalized : "unknown";
|
|
1911
|
+
}
|
|
1912
|
+
function mxClass(mxProvider, mxRecord) {
|
|
1913
|
+
const haystack = `${stringish(mxProvider) ?? ""} ${stringish(mxRecord) ?? ""}`.toLowerCase();
|
|
1914
|
+
if (!haystack.trim()) return "unknown";
|
|
1915
|
+
if (/proofpoint|pphosted|mimecast|barracuda|ess\.barracudanetworks|ironport|cisco|iphmx|messagelabs|symantec/.test(
|
|
1916
|
+
haystack
|
|
1917
|
+
)) {
|
|
1918
|
+
return "security_gateway";
|
|
1919
|
+
}
|
|
1920
|
+
if (/aspmx\.l\.google|google|g-suite|google workspace/.test(haystack)) {
|
|
1921
|
+
return "workspace_mailbox";
|
|
1922
|
+
}
|
|
1923
|
+
if (/protection\.outlook|office365|microsoft|outlook|exchange online/.test(haystack)) {
|
|
1924
|
+
return "workspace_mailbox";
|
|
1925
|
+
}
|
|
1926
|
+
if (/gmail|yahoo|icloud|aol|hotmail/.test(haystack)) return "consumer_mailbox";
|
|
1927
|
+
if (/postfix|exim|sendmail|zimbra|plesk|cpanel|mail\./.test(haystack)) return "on_prem";
|
|
1928
|
+
return "unknown";
|
|
1929
|
+
}
|
|
1930
|
+
function entryForStatus(key, map) {
|
|
1931
|
+
if (!key) return null;
|
|
1932
|
+
return map?.[key] ?? DEFAULT_STATUS_MAP[key] ?? null;
|
|
1933
|
+
}
|
|
1934
|
+
function read(values, name) {
|
|
1935
|
+
return values[name];
|
|
1936
|
+
}
|
|
1937
|
+
function matchesRule(rule, values) {
|
|
1938
|
+
return Object.entries(rule.when).every(([key, expected]) => {
|
|
1939
|
+
const actual = read(values, key);
|
|
1940
|
+
if (key.endsWith("Lt")) {
|
|
1941
|
+
const source = numberish(read(values, key.slice(0, -2)));
|
|
1942
|
+
return typeof expected === "number" && source != null && source < expected;
|
|
1943
|
+
}
|
|
1944
|
+
if (typeof expected === "boolean") return boolish(actual) === expected;
|
|
1945
|
+
if (typeof expected === "number") return numberish(actual) === expected;
|
|
1946
|
+
return normalizeKey(actual) === normalizeKey(expected);
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
function buildEmailStatus({
|
|
1950
|
+
config,
|
|
1951
|
+
values
|
|
1952
|
+
}) {
|
|
1953
|
+
const rawStatus = read(values, "rawStatus");
|
|
1954
|
+
const rawScore = numberish(read(values, "rawScore"));
|
|
1955
|
+
const valid = boolish(read(values, "valid"));
|
|
1956
|
+
const catchAll = boolish(read(values, "catchAll"));
|
|
1957
|
+
const disposable = boolish(read(values, "disposable"));
|
|
1958
|
+
const abuse = boolish(read(values, "abuse"));
|
|
1959
|
+
const spamtrap = boolish(read(values, "spamtrap"));
|
|
1960
|
+
const suspect = boolish(read(values, "suspect"));
|
|
1961
|
+
const rawKey = normalizeKey(rawStatus);
|
|
1962
|
+
const mapped = config.rules?.find((rule) => matchesRule(rule, values)) ?? entryForStatus(rawKey, config.statusMap) ?? entryForStatus(valid == null ? null : String(valid), config.statusMap);
|
|
1963
|
+
const status = mapped?.status ?? (disposable ? "disposable" : abuse ? "abuse" : spamtrap ? "spamtrap" : catchAll ? "catch_all" : valid === true ? "valid" : valid === false ? "invalid" : "unknown");
|
|
1964
|
+
const defaultVerdict = status === "valid" ? "send" : status === "valid_catch_all" ? "send_with_caution" : status === "catch_all" ? "verify_next" : status === "unknown" ? "hold" : "drop";
|
|
1965
|
+
const verdict = mapped?.verdict ?? defaultVerdict;
|
|
1966
|
+
const verified = mapped?.verified ?? (status === "valid" || status === "valid_catch_all" || verdict === "send");
|
|
1967
|
+
const reasons = [
|
|
1968
|
+
mapped?.reason,
|
|
1969
|
+
catchAll ? "catch_all_domain" : null,
|
|
1970
|
+
mxClass(read(values, "mxProvider"), read(values, "mxRecord")) === "security_gateway" ? "security_gateway_mx" : null,
|
|
1971
|
+
suspect ? "provider_marked_suspect" : null
|
|
1972
|
+
].filter((reason) => typeof reason === "string");
|
|
1973
|
+
return {
|
|
1974
|
+
verdict,
|
|
1975
|
+
status,
|
|
1976
|
+
verified,
|
|
1977
|
+
confidence: rawScore,
|
|
1978
|
+
reasons,
|
|
1979
|
+
signals: {
|
|
1980
|
+
catch_all: catchAll,
|
|
1981
|
+
deliverability: deliverability(read(values, "deliverability")),
|
|
1982
|
+
mx_class: mxClass(read(values, "mxProvider"), read(values, "mxRecord")),
|
|
1983
|
+
mx_provider: stringish(read(values, "mxProvider")),
|
|
1984
|
+
mx_record: stringish(read(values, "mxRecord")),
|
|
1985
|
+
fraud_score: numberish(read(values, "fraudScore")),
|
|
1986
|
+
disposable,
|
|
1987
|
+
role_based: boolish(read(values, "roleBased")),
|
|
1988
|
+
free_email: boolish(read(values, "freeEmail")),
|
|
1989
|
+
abuse,
|
|
1990
|
+
spamtrap,
|
|
1991
|
+
suspect,
|
|
1992
|
+
valid
|
|
1993
|
+
},
|
|
1994
|
+
provider: {
|
|
1995
|
+
name: config.provider,
|
|
1996
|
+
raw_status: typeof rawStatus === "string" || typeof rawStatus === "boolean" || typeof rawStatus === "number" ? rawStatus : null,
|
|
1997
|
+
raw_score: rawScore
|
|
1998
|
+
}
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
|
|
1847
2002
|
// ../shared_libs/play-runtime/tool-result.ts
|
|
1848
2003
|
var TARGET_FALLBACK_KEYS = {
|
|
1849
2004
|
email: [/^email$/i, /^address$/i, /email/i],
|
|
@@ -2027,6 +2182,42 @@ function findFirstTargetByPath(result, paths) {
|
|
|
2027
2182
|
}
|
|
2028
2183
|
return null;
|
|
2029
2184
|
}
|
|
2185
|
+
function firstValueForPaths(result, paths) {
|
|
2186
|
+
return findFirstTargetByPath(result, paths);
|
|
2187
|
+
}
|
|
2188
|
+
function buildEmailStatusTarget(result, descriptor) {
|
|
2189
|
+
const config = descriptor.emailStatus;
|
|
2190
|
+
if (!config) return null;
|
|
2191
|
+
const values = {};
|
|
2192
|
+
const pathSets = {
|
|
2193
|
+
rawStatus: config.rawStatus,
|
|
2194
|
+
rawScore: config.rawScore,
|
|
2195
|
+
valid: config.valid,
|
|
2196
|
+
deliverability: config.deliverability,
|
|
2197
|
+
catchAll: config.catchAll,
|
|
2198
|
+
mxProvider: config.mxProvider,
|
|
2199
|
+
mxRecord: config.mxRecord,
|
|
2200
|
+
fraudScore: config.fraudScore,
|
|
2201
|
+
disposable: config.disposable,
|
|
2202
|
+
roleBased: config.roleBased,
|
|
2203
|
+
freeEmail: config.freeEmail,
|
|
2204
|
+
abuse: config.abuse,
|
|
2205
|
+
spamtrap: config.spamtrap,
|
|
2206
|
+
suspect: config.suspect
|
|
2207
|
+
};
|
|
2208
|
+
let firstPath = null;
|
|
2209
|
+
for (const [name, paths] of Object.entries(pathSets)) {
|
|
2210
|
+
const match = firstValueForPaths(result, paths);
|
|
2211
|
+
if (!match) continue;
|
|
2212
|
+
values[name] = match.value;
|
|
2213
|
+
firstPath ??= match.path;
|
|
2214
|
+
}
|
|
2215
|
+
if (!firstPath) return null;
|
|
2216
|
+
return {
|
|
2217
|
+
path: firstPath,
|
|
2218
|
+
value: buildEmailStatus({ config, values })
|
|
2219
|
+
};
|
|
2220
|
+
}
|
|
2030
2221
|
function findFirstTargetByKey(result, target, depth = 0, path = []) {
|
|
2031
2222
|
if (depth > 6) return null;
|
|
2032
2223
|
if (Array.isArray(result)) {
|
|
@@ -2176,6 +2367,11 @@ function deriveListKeys(input) {
|
|
|
2176
2367
|
function buildTargets(result, extractors, targetGetters) {
|
|
2177
2368
|
const targets = {};
|
|
2178
2369
|
for (const [target, descriptor] of Object.entries(extractors ?? {})) {
|
|
2370
|
+
const emailStatusTarget = buildEmailStatusTarget(result, descriptor);
|
|
2371
|
+
if (emailStatusTarget) {
|
|
2372
|
+
targets[target] = emailStatusTarget;
|
|
2373
|
+
continue;
|
|
2374
|
+
}
|
|
2179
2375
|
const fromExtractor = findFirstTargetByPath(result, descriptor.paths);
|
|
2180
2376
|
if (!fromExtractor) continue;
|
|
2181
2377
|
const transformed = coerceToEnum(
|
|
@@ -565,6 +565,13 @@ export class DeeplineClient {
|
|
|
565
565
|
outputSchema: options?.compact
|
|
566
566
|
? this.compactSchema(play.outputSchema)
|
|
567
567
|
: (play.outputSchema ?? null),
|
|
568
|
+
staticPipeline: isRecord(play.staticPipeline)
|
|
569
|
+
? play.staticPipeline
|
|
570
|
+
: isRecord(play.currentRevision?.staticPipeline)
|
|
571
|
+
? play.currentRevision.staticPipeline
|
|
572
|
+
: isRecord(play.liveRevision?.staticPipeline)
|
|
573
|
+
? play.liveRevision.staticPipeline
|
|
574
|
+
: null,
|
|
568
575
|
...(csvInput ? { csvInput } : {}),
|
|
569
576
|
...(rowOutputSchema ? { rowOutputSchema } : {}),
|
|
570
577
|
runCommand,
|
|
@@ -540,7 +540,7 @@ export interface DeeplinePlayRuntimeContext {
|
|
|
540
540
|
* @returns Program output.
|
|
541
541
|
*/
|
|
542
542
|
runSteps<TInput extends Record<string, unknown>, TOutput>(
|
|
543
|
-
program: StepProgram<TInput,
|
|
543
|
+
program: StepProgram<TInput, any, TOutput>,
|
|
544
544
|
input: TInput,
|
|
545
545
|
options?: { description?: string },
|
|
546
546
|
): Promise<TOutput>;
|
|
@@ -50,10 +50,10 @@ export type SdkRelease = {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export const SDK_RELEASE = {
|
|
53
|
-
version: '0.1.
|
|
53
|
+
version: '0.1.78',
|
|
54
54
|
apiContract: '2026-06-dataset-column-cell-stale-hard-cutover',
|
|
55
55
|
supportPolicy: {
|
|
56
|
-
latest: '0.1.
|
|
56
|
+
latest: '0.1.78',
|
|
57
57
|
minimumSupported: '0.1.53',
|
|
58
58
|
deprecatedBelow: '0.1.53',
|
|
59
59
|
},
|