Initial Commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { HIBP_CODES } from "../error-codes.js";
|
||||
import { HibpError } from "../errors/hibp-error.js";
|
||||
|
||||
/** Strict-mode framing: uppercase hex, single colon, decimal count. */
|
||||
const STRICT_LINE_RE = /^[0-9A-F]{35}:[0-9]+$/;
|
||||
|
||||
/**
|
||||
* One parsed line from a range response: the 35-char hex suffix plus its
|
||||
* documented breach count.
|
||||
*/
|
||||
export interface RangeLine {
|
||||
readonly suffix: string;
|
||||
readonly count: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and split a raw line. In strict mode, malformed lines throw
|
||||
* `HIBP.MALFORMED_RESPONSE` with the offending zero-based line index. In
|
||||
* off-mode, lowercase hex is accepted (uppercased on the way out), and an
|
||||
* unparseable count defaults to `0`.
|
||||
*/
|
||||
export function parseRangeLine(
|
||||
raw: string,
|
||||
lineIndex: number,
|
||||
strict: boolean
|
||||
): RangeLine {
|
||||
if (strict) {
|
||||
if (!STRICT_LINE_RE.test(raw)) {
|
||||
throw new HibpError(
|
||||
HIBP_CODES.MALFORMED_RESPONSE,
|
||||
`malformed range line at index ${lineIndex}`,
|
||||
{ context: { lineIndex } }
|
||||
);
|
||||
}
|
||||
const idx = raw.indexOf(":");
|
||||
return {
|
||||
suffix: raw.slice(0, idx),
|
||||
count: Number.parseInt(raw.slice(idx + 1), 10),
|
||||
};
|
||||
}
|
||||
const idx = raw.indexOf(":");
|
||||
if (idx === -1) {
|
||||
throw new HibpError(
|
||||
HIBP_CODES.MALFORMED_RESPONSE,
|
||||
`malformed range line at index ${lineIndex}`,
|
||||
{ context: { lineIndex } }
|
||||
);
|
||||
}
|
||||
const suffix = raw.slice(0, idx).toUpperCase();
|
||||
if (suffix.length !== 35 || !/^[0-9A-F]{35}$/.test(suffix)) {
|
||||
throw new HibpError(
|
||||
HIBP_CODES.MALFORMED_RESPONSE,
|
||||
`malformed range line at index ${lineIndex}`,
|
||||
{ context: { lineIndex } }
|
||||
);
|
||||
}
|
||||
const tail = raw.slice(idx + 1);
|
||||
const parsed = Number.parseInt(tail, 10);
|
||||
const count = Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
||||
return { suffix, count };
|
||||
}
|
||||
Reference in New Issue
Block a user