Release Helper Tools 0.1.0
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
# 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user