Files
helper-tools/public/docs/API.md
T
2026-09-01 02:33:45 +02:00

6.0 KiB

Package API

@add-ideas/toolbox-helpers is a side-effect-free ESM package with generated TypeScript declarations and no runtime dependency. Import named helpers from the package root; internal deep paths are not public API.

Bounds

type BytesLike = ArrayBuffer | ArrayBufferView;

const DEFAULT_HELPER_LIMITS: Readonly<{
  maxInputBytes: number; // 16 MiB
  maxTextChars: 2_000_000;
  maxItems: 100_000;
  maxDepth: 128;
}>;

assertBoundedText(value: string, maximum?: number, label?: string): string;
assertBoundedBytes(value: BytesLike, maximum?: number, label?: string): Uint8Array;
assertBoundedItems(count: number, maximum?: number, label?: string): number;
assertPositiveSafeInteger(value: number, label: string): number;
asUint8Array(value: BytesLike): Uint8Array;

HelperLimitError extends RangeError and exposes numeric actual and limit properties. Per-operation ceilings can be made narrower. They are compatibility and denial-of-service boundaries, not a substitute for an application-wide memory budget.

Encoding and URLs

type TextEncoding = "utf-8" | "utf-16le" | "utf-16be" | "latin1";
interface DecodeBinaryOptions {
  maxOutputBytes?: number;
  allowWhitespace?: boolean;
}

bytesToBase64(input: BytesLike): string;
bytesToBase64Url(input: BytesLike, padded?: boolean): string;
base64ToBytes(input: string, options?: DecodeBinaryOptions): Uint8Array;
base64UrlToBytes(input: string, options?: DecodeBinaryOptions): Uint8Array;
bytesToHex(input: BytesLike, uppercase?: boolean): string;
hexToBytes(
  input: string,
  options?: DecodeBinaryOptions & { allowPrefix?: boolean },
): Uint8Array;
encodeText(input: string, encoding?: TextEncoding): Uint8Array;
decodeText(input: BytesLike, encoding?: TextEncoding, fatal?: boolean): string;

encodeUrlComponent(value: string): string;
decodeUrlComponent(value: string): string;
inspectUrl(value: string, base?: string): UrlParts;
parseFormEncoded(input: string, maximumFields?: number): FormEntries;
stringifyFormEncoded(entries: Iterable<readonly [string, string]>, maximumFields?: number): string;

Base64 decoders reject non-canonical alphabets, malformed padding and non-zero unused bits. Base64URL accepts either no padding or the exact RFC 4648 padding required for that value. URL inspection is inert: it parses text but never opens or fetches the result.

Checksums and digests

type DigestAlgorithm = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";

crc32(input: BytesLike, maximumBytes?: number): number;
adler32(input: BytesLike, maximumBytes?: number): number;
fnv1a32(input: BytesLike, maximumBytes?: number): number;
formatChecksum(value: number): string;
digestBytes(
  input: BytesLike,
  algorithm?: DigestAlgorithm,
  maximumBytes?: number,
  cryptoProvider?: Pick<Crypto, "subtle">,
): Promise<Uint8Array>;
digestHex(
  input: BytesLike,
  algorithm?: DigestAlgorithm,
  maximumBytes?: number,
  cryptoProvider?: Pick<Crypto, "subtle">,
): Promise<string>;

Digests use Web Crypto. SHA-1 is available only for interoperability. Checksums and hashes do not establish authorship, and none of these functions is a password-hashing API.

Network

type IpVersion = 4 | 6;
interface ParsedIpAddress {
  version: IpVersion;
  bytes: Uint8Array;
  value: bigint;
  canonical: string;
}
interface ParsedCidr {
  version: IpVersion;
  prefixLength: number;
  address: ParsedIpAddress;
  network: ParsedIpAddress;
  first: ParsedIpAddress;
  last: ParsedIpAddress;
  broadcast?: ParsedIpAddress;
  size: bigint;
  canonical: string;
}

parseIpAddress(input: string): ParsedIpAddress;
parseIpv4(input: string): ParsedIpAddress;
parseIpv6(input: string): ParsedIpAddress;
formatIpv4(input: bigint | BytesLike): string;
formatIpv6(input: bigint | BytesLike): string;
parseCidr(input: string): ParsedCidr;
cidrContains(
  cidr: string | ParsedCidr,
  address: string | ParsedIpAddress,
): boolean;

IPv4 leading zeroes and IPv6 zone identifiers are rejected rather than guessed. The helpers perform no DNS, HTTP, probing or scanning. bigint fields preserve 128-bit values exactly and must be converted explicitly before JSON encoding.

Downloads

interface ObjectUrlLease {
  readonly url: string;
  readonly revoked: boolean;
  revoke(): void;
}

sanitizeDownloadFilename(input: string, fallback?: string, maximumLength?: number): string;
createObjectUrlLease(
  blob: Blob,
  urlApi?: Pick<typeof URL, "createObjectURL" | "revokeObjectURL">,
): ObjectUrlLease;
triggerBlobDownload(
  blob: Blob,
  filename: string,
  ownerDocument?: Document,
): ObjectUrlLease;

triggerBlobDownload removes its temporary anchor synchronously and schedules object URL revocation for the next task. Long-lived previews should instead keep a lease and call revoke() when replaced or unmounted.

Remaining groups

Group Exports
Unicode and text inspectCodePoints, fromCodePoints, segmentGraphemes, normalizeUnicode, transformCase, convertLineEndings
Numbers and units parseBigIntRadix, formatBigIntRadix, convertNumberBase, convertDataUnit, convertUnit, unitDimension
Time parseTimestamp, formatTimestamp, parseDuration, formatDuration
Structured data safeJsonParse, stableStringify, parseCsv, stringifyCsv
Random secureRandomBytes, secureRandomInt, createSeededRandom, shuffleSeeded

JSON dangerous object keys are rejected by default, cycles and unsupported values are rejected by deterministic JSON, and CSV dimensions and fields are bounded. Secure random functions use Web Crypto. The seeded generator is reproducible and deliberately unsuitable for any secret, nonce, key, salt or token.