const MAX_SAFE_INTEGER_ABS_STR = String(Number.MAX_SAFE_INTEGER);
function isAsciiDigit(ch: string | undefined): boolean {
return ch !== undefined && ch >= "0" && ch <= "9" ;
}
function parseJsonNumberToken(
input: string,
start: number,
): { token: string; end: number; isInteger: boolean } | null {
let idx = start;
if (input[idx] === "-" ) {
idx += 1 ;
}
if (idx >= input.length) {
return null ;
}
if (input[idx] === "0" ) {
idx += 1 ;
} else if (isAsciiDigit(input[idx]) && input[idx] !== "0" ) {
while (isAsciiDigit(input[idx])) {
idx += 1 ;
}
} else {
return null ;
}
let isInteger = true ;
if (input[idx] === "." ) {
isInteger = false ;
idx += 1 ;
if (!isAsciiDigit(input[idx])) {
return null ;
}
while (isAsciiDigit(input[idx])) {
idx += 1 ;
}
}
if (input[idx] === "e" || input[idx] === "E" ) {
isInteger = false ;
idx += 1 ;
if (input[idx] === "+" || input[idx] === "-" ) {
idx += 1 ;
}
if (!isAsciiDigit(input[idx])) {
return null ;
}
while (isAsciiDigit(input[idx])) {
idx += 1 ;
}
}
return {
token: input.slice(start, idx),
end: idx,
isInteger,
};
}
function isUnsafeIntegerLiteral(token: string): boolean {
const digits = token[0 ] === "-" ? token.slice(1 ) : token;
if (digits.length < MAX_SAFE_INTEGER_ABS_STR.length) {
return false ;
}
if (digits.length > MAX_SAFE_INTEGER_ABS_STR.length) {
return true ;
}
return digits > MAX_SAFE_INTEGER_ABS_STR;
}
function quoteUnsafeIntegerLiterals(input: string): string {
let out = "" ;
let inString = false ;
let escaped = false ;
let idx = 0 ;
while (idx < input.length) {
const ch = input[idx] ?? "" ;
if (inString) {
out += ch;
if (escaped) {
escaped = false ;
} else if (ch === "\\" ) {
escaped = true ;
} else if (ch === '"' ) {
inString = false ;
}
idx += 1 ;
continue ;
}
if (ch === '"' ) {
inString = true ;
out += ch;
idx += 1 ;
continue ;
}
if (ch === "-" || isAsciiDigit(ch)) {
const parsed = parseJsonNumberToken(input, idx);
if (parsed) {
if (parsed.isInteger && isUnsafeIntegerLiteral(parsed.token)) {
out += `"${parsed.token}" `;
} else {
out += parsed.token;
}
idx = parsed.end;
continue ;
}
}
out += ch;
idx += 1 ;
}
return out;
}
export function parseJsonPreservingUnsafeIntegers(input: string): unknown {
return JSON.parse(quoteUnsafeIntegerLiterals(input)) as unknown;
}
export function parseJsonObjectPreservingUnsafeIntegers(
value: unknown,
): Record<string, unknown> | null {
if (typeof value === "string" ) {
try {
const parsed = parseJsonPreservingUnsafeIntegers(value);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
return parsed as Record<string, unknown>;
}
} catch {
return null ;
}
return null ;
}
if (value && typeof value === "object" && !Array.isArray(value)) {
return value as Record<string, unknown>;
}
return null ;
}
Messung V0.5 in Prozent C=100 H=92 G=95
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland