From 3a8a60177ac8f5d8610f83e62eb78d31e7dff725 Mon Sep 17 00:00:00 2001 From: Ultraslayyy Date: Sun, 16 Nov 2025 11:04:41 +1100 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#73762=20[spf-p?= =?UTF-8?q?arse]=20Add=20types=20for=20spf-parse=20by=20@ultraslayyy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adam Thompson-Sharpe --- types/spf-parse/.npmignore | 5 ++ types/spf-parse/index.d.ts | 76 ++++++++++++++++++++++++++++++ types/spf-parse/package.json | 17 +++++++ types/spf-parse/spf-parse-tests.ts | 26 ++++++++++ types/spf-parse/tsconfig.json | 19 ++++++++ 5 files changed, 143 insertions(+) create mode 100644 types/spf-parse/.npmignore create mode 100644 types/spf-parse/index.d.ts create mode 100644 types/spf-parse/package.json create mode 100644 types/spf-parse/spf-parse-tests.ts create mode 100644 types/spf-parse/tsconfig.json diff --git a/types/spf-parse/.npmignore b/types/spf-parse/.npmignore new file mode 100644 index 00000000000000..680c524577719f --- /dev/null +++ b/types/spf-parse/.npmignore @@ -0,0 +1,5 @@ +* +!**/*.d.ts +!**/*.d.cts +!**/*.d.mts +!**/*.d.*.ts \ No newline at end of file diff --git a/types/spf-parse/index.d.ts b/types/spf-parse/index.d.ts new file mode 100644 index 00000000000000..cf6e2be054bcc6 --- /dev/null +++ b/types/spf-parse/index.d.ts @@ -0,0 +1,76 @@ +export = spfParse; + +declare namespace spfParse { + /** Qualifer prefix characters */ + type Prefix = '+' | '-' | '~' | '?' | 'v'; + + /** Prefix descriptions */ + interface PrefixDescriptions { + '+': 'Pass'; + '-': 'Fail'; + '~': 'SoftFail'; + '?': 'Neutral'; + v?: string; + } + + /** A single parsed SPF mechanism */ + interface Mechanism { + /** Mechanism type, e.g. 'ip4', 'mx', 'all' */ + type: string; + + /** Optional value associated with the mechanism (domain, IP, etc.) */ + value?: string; + + /** The qualifier prefix */ + prefix: Prefix; + + /** Human-readable description of the prefix */ + prefixdesc?: string; + + /** Human-readable description of the mechanism */ + description?: string; + } + + /** Parse message (warning or error) */ + interface ParseMessage { + /** Text of the message */ + message: string; + + /** Message type: error or warning */ + type: 'error' | 'warning'; + } + + /** Result of parsing a single SPF record */ + interface ParseResult { + /** Parsed mechanisms */ + mechanisms: Mechanism[]; + + /** Validation messages */ + messages?: ParseMessage[]; + + /** True if record parsed successfully */ + valid: boolean; + } + + /** Error thrown by mechanism validators */ + class MechanismError extends Error { + /** Error type */ + type: 'warning' | 'error'; + constructor(message: string, type?: 'warning' | 'error'); + } + + /** + * Parse a single SPF term (e.g. "+ip4:192.0.2.0/24") + * @param term SPF term string + * @param messages Message array to push validation errors/warnings into + * @returns Parsed mechanism record + */ + function parseTerm(term: string, messages: ParseMessage[]): Mechanism; +} + +/** + * Parse a full SPF record string (e.g. "v=spf1 include:some.sender.org -all") + * @param record SPF record string + * @returns Structured parse result + */ +declare function spfParse(record: string): spfParse.ParseResult; \ No newline at end of file diff --git a/types/spf-parse/package.json b/types/spf-parse/package.json new file mode 100644 index 00000000000000..ed1239a63172c8 --- /dev/null +++ b/types/spf-parse/package.json @@ -0,0 +1,17 @@ +{ + "private": true, + "name": "@types/spf-parse", + "version": "1.0.9999", + "projects": [ + "https://github.com/softvu/spf-parse#readme" + ], + "devDependencies": { + "@types/spf-parse": "workspace:." + }, + "owners": [ + { + "name": "ultraslayyy", + "githubUsername": "ultraslayyy" + } + ] +} diff --git a/types/spf-parse/spf-parse-tests.ts b/types/spf-parse/spf-parse-tests.ts new file mode 100644 index 00000000000000..8d7717757bf4c7 --- /dev/null +++ b/types/spf-parse/spf-parse-tests.ts @@ -0,0 +1,26 @@ +import spfParse = require('spf-parse'); + +const result = spfParse('v=spf1 a mx -all'); // $ExpectType ParseResult +result.mechanisms; // $ExpectType Mechanism[] +result.valid; // $ExpectType boolean + +for (const mech of result.mechanisms) { + mech.type; // $ExpectType string + mech.value; // $ExpectType string | undefined + mech.prefix; // $ExpectType Prefix + mech.prefixdesc; // $ExpectType string | undefined + mech.description; // $ExpectType string | undefined +} + +if (result.messages) { + for (const msg of result.messages) { + msg.message; // $ExpectType string + msg.type; // $ ExpectType "error" | "warning" + } +} + +const messages: spfParse.ParseMessage[] = []; +const mech = spfParse.parseTerm('ip4:192.0.2.0/24', messages); // $ExpectType Mechanism + +const err = new spfParse.MechanismError('invalid mech', 'error'); // $ExpectType MechanismError +err.type; // $ExpectType "warning" | "error" \ No newline at end of file diff --git a/types/spf-parse/tsconfig.json b/types/spf-parse/tsconfig.json new file mode 100644 index 00000000000000..652a7bb8370713 --- /dev/null +++ b/types/spf-parse/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "node16", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "spf-parse-tests.ts" + ] +} \ No newline at end of file From 09cb336295f87400d9bcfe4a8024a848cd3fa7a4 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Sun, 16 Nov 2025 00:05:26 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=A4=96=20dprint=20fmt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- types/spf-parse/index.d.ts | 18 +++++++++--------- types/spf-parse/spf-parse-tests.ts | 10 +++++----- types/spf-parse/tsconfig.json | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/types/spf-parse/index.d.ts b/types/spf-parse/index.d.ts index cf6e2be054bcc6..abb030f6e79842 100644 --- a/types/spf-parse/index.d.ts +++ b/types/spf-parse/index.d.ts @@ -2,14 +2,14 @@ export = spfParse; declare namespace spfParse { /** Qualifer prefix characters */ - type Prefix = '+' | '-' | '~' | '?' | 'v'; + type Prefix = "+" | "-" | "~" | "?" | "v"; /** Prefix descriptions */ interface PrefixDescriptions { - '+': 'Pass'; - '-': 'Fail'; - '~': 'SoftFail'; - '?': 'Neutral'; + "+": "Pass"; + "-": "Fail"; + "~": "SoftFail"; + "?": "Neutral"; v?: string; } @@ -37,7 +37,7 @@ declare namespace spfParse { message: string; /** Message type: error or warning */ - type: 'error' | 'warning'; + type: "error" | "warning"; } /** Result of parsing a single SPF record */ @@ -55,8 +55,8 @@ declare namespace spfParse { /** Error thrown by mechanism validators */ class MechanismError extends Error { /** Error type */ - type: 'warning' | 'error'; - constructor(message: string, type?: 'warning' | 'error'); + type: "warning" | "error"; + constructor(message: string, type?: "warning" | "error"); } /** @@ -73,4 +73,4 @@ declare namespace spfParse { * @param record SPF record string * @returns Structured parse result */ -declare function spfParse(record: string): spfParse.ParseResult; \ No newline at end of file +declare function spfParse(record: string): spfParse.ParseResult; diff --git a/types/spf-parse/spf-parse-tests.ts b/types/spf-parse/spf-parse-tests.ts index 8d7717757bf4c7..377f27b8d558a2 100644 --- a/types/spf-parse/spf-parse-tests.ts +++ b/types/spf-parse/spf-parse-tests.ts @@ -1,6 +1,6 @@ -import spfParse = require('spf-parse'); +import spfParse = require("spf-parse"); -const result = spfParse('v=spf1 a mx -all'); // $ExpectType ParseResult +const result = spfParse("v=spf1 a mx -all"); // $ExpectType ParseResult result.mechanisms; // $ExpectType Mechanism[] result.valid; // $ExpectType boolean @@ -20,7 +20,7 @@ if (result.messages) { } const messages: spfParse.ParseMessage[] = []; -const mech = spfParse.parseTerm('ip4:192.0.2.0/24', messages); // $ExpectType Mechanism +const mech = spfParse.parseTerm("ip4:192.0.2.0/24", messages); // $ExpectType Mechanism -const err = new spfParse.MechanismError('invalid mech', 'error'); // $ExpectType MechanismError -err.type; // $ExpectType "warning" | "error" \ No newline at end of file +const err = new spfParse.MechanismError("invalid mech", "error"); // $ExpectType MechanismError +err.type; // $ExpectType "warning" | "error" diff --git a/types/spf-parse/tsconfig.json b/types/spf-parse/tsconfig.json index 652a7bb8370713..3bd7961a4de6c3 100644 --- a/types/spf-parse/tsconfig.json +++ b/types/spf-parse/tsconfig.json @@ -16,4 +16,4 @@ "index.d.ts", "spf-parse-tests.ts" ] -} \ No newline at end of file +}