validator.js input cleaning: working versions (tested 2026-10-15)
Validate and sanitize form input with validator.js: isEmail, isURL with protocol options, isUUID, isStrongPassword scoring, plus normalizeEmail, escape and trim sanitizers offline.
passed6 passed · 0 failed2026-10-15 22:58 UTC- Status
- passed
- Last passed
- 2026-10-15 22:58 UTC
- Tests
- 6 / 6
- Language
- TypeScript
- Runtime
- node v22.23.3
pinned versions4
validator@13.15.35@types/validator@13.15.10@types/node@26.6.5tsx@4.23.15
run it
npm install --no-audit --no-fund --ignore-scripts=false npm test
test environment
node v22.23.3 linux 6.17.0-1022-azure x64 runner: github-actions 38820570375
The code
Exactly the files that passed. Your agent can pull them with get_recipe("validator-js-sanitize") (install), or see them on GitHub.
package.json
{
"name": "validator-js-sanitize",
"private": true,
"type": "module",
"scripts": {
"test": "node --import tsx --test test/*.test.ts"
},
"dependencies": {
"validator": "13.15.35"
},
"devDependencies": {
"@types/validator": "13.15.10",
"@types/node": "26.6.5",
"tsx": "4.23.15"
}
}
src/sanitize.ts
import validator from "validator";
// validator is CommonJS: use the default export, named ESM imports fail at runtime.
const {
escape,
isEmail,
isStrongPassword,
isURL,
isUUID,
normalizeEmail,
trim,
} = validator;
export type RawInput = {
email?: unknown;
website?: unknown;
userId?: unknown;
password?: unknown;
note?: unknown;
};
export type CleanInput = {
email: string;
emailValid: boolean;
website: string;
websiteValid: boolean;
userId: string;
userIdValid: boolean;
passwordScore: number;
passwordStrong: boolean;
note: string;
};
function str(value: unknown): string {
return typeof value === "string" ? value : "";
}
export function scorePassword(password: string): number {
return isStrongPassword(password, { returnScore: true }) as unknown as number;
}
export function cleanInput(input: RawInput): CleanInput {
const email = trim(str(input.email));
const website = trim(str(input.website));
const userId = trim(str(input.userId)).toLowerCase();
const password = str(input.password);
const note = escape(trim(str(input.note)));
return {
email: normalizeEmail(email) || email,
emailValid: isEmail(email),
website,
websiteValid: isURL(website, {
require_protocol: true,
protocols: ["http", "https"],
}),
userId,
userIdValid: isUUID(userId, "4"),
passwordScore: scorePassword(password),
passwordStrong: isStrongPassword(password),
note,
};
}
test/sanitize.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { cleanInput, scorePassword } from "../src/sanitize.ts";
test("validates and normalizes an email", () => {
const result = cleanInput({ email: " [email protected] " });
assert.equal(result.emailValid, true);
assert.equal(result.email, "[email protected]");
});
test("flags malformed emails", () => {
const result = cleanInput({ email: "not-an-email" });
assert.equal(result.emailValid, false);
});
test("validates URLs with protocol options", () => {
assert.equal(cleanInput({ website: "https://example.com" }).websiteValid, true);
assert.equal(cleanInput({ website: "ftp://example.com" }).websiteValid, false);
});
test("validates UUID v4 values", () => {
assert.equal(
cleanInput({ userId: "F47AC10B-58CC-4372-A567-0E02B2C3D479" }).userIdValid,
true,
);
assert.equal(cleanInput({ userId: "nope" }).userIdValid, false);
});
test("scores strong passwords higher than weak ones", () => {
const weak = scorePassword("password");
const strong = scorePassword("Str0ng!Passw0rd");
assert.equal(cleanInput({ password: "password" }).passwordStrong, false);
assert.equal(cleanInput({ password: "Str0ng!Passw0rd" }).passwordStrong, true);
assert.ok(strong > weak);
});
test("escapes and trims notes with sanitizers", () => {
const result = cleanInput({ note: " <b>hi & bye " });
assert.equal(result.note, "<b>hi & bye");
});
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
~/.cursor/mcp.json
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }.vscode/mcp.json
{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }MCP settings
{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.