Skip to content
UniKVS
English
Esc
↑↓navigate↵open⌘Jpreview
On this page

@unikvs/utils

How to use @unikvs/utils for filename validation, byte operations, and stream conversion.

Overview

@unikvs/utils provides filename and dirname validation, byte conversion and splitting, and conversion from iterables to ReadableStream.

For plugin authors

Install it with the following command.

npm install @unikvs/utils
pnpm add @unikvs/utils
yarn add @unikvs/utils
bun add @unikvs/utils
nub add @unikvs/utils
aube add @unikvs/utils
import {
  assertValidFilename,
  assertValidDirname,
  bytesToHex,
  chunks,
  isValidFilename,
  isValidDirname,
  toReadableStream,
  withReadableStreamFrom,
  InvalidDirnameError,
  InvalidFilenameError,
} from "@unikvs/utils";

Filename validation

Checks whether a filename works on Windows, macOS, and Linux.

isValidFilename

function isValidFilename(filename: string): boolean;

Returns false for unusable names. Never throws.

import { isValidFilename } from "@unikvs/utils";

if (isValidFilename("report.txt")) {
  console.log("Usable filename.");
}

assertValidFilename

function assertValidFilename(filename: string): void;

Returns silently when valid, throws InvalidFilenameError when invalid.

import { assertValidFilename } from "@unikvs/utils";

assertValidFilename("report.txt");

Dirname validation

Checks whether a dirname works on Windows, macOS, and Linux.

isValidDirname

function isValidDirname(dirname: string): boolean;

Returns true when valid, false when invalid. Never throws.

import { isValidDirname } from "@unikvs/utils";

if (!isValidDirname("my-dir")) {
  console.log("Unusable dirname.");
}

assertValidDirname

function assertValidDirname(dirname: string): void;

Returns silently when valid, throws InvalidDirnameError when invalid.

import { assertValidDirname } from "@unikvs/utils";

assertValidDirname("my-dir");

Byte operations

Converts and splits binary data.

bytesToHex

function bytesToHex(bytes: Uint8Array): string;

Converts a Uint8Array to a lowercase hex string.

import { bytesToHex } from "@unikvs/utils";

const hex = bytesToHex(new Uint8Array([0, 255, 16]));
console.log(hex); // "00ff10"

chunks

function chunks<TData extends DataView | ITypedArray>(
  data: TData,
  maxChunkByteSize: number,
): Generator<TData, void, unknown>;

Splits data into chunks of up to the given byte size.

import { chunks } from "@unikvs/utils";

const data = new Uint8Array([1, 2, 3, 4, 5]);

for (const chunk of chunks(data, 2)) {
  console.log(chunk);
}

Stream conversion

Converts iterables to ReadableStream.

toReadableStream

function toReadableStream<T>(
  iterable: Iterable<T> | AsyncIterable<T>,
): ReadableStream<T>;

Creates a ReadableStream from a sync or async iterable.

import { toReadableStream } from "@unikvs/utils";

const stream = toReadableStream([1, 2, 3]);

for await (const value of stream) {
  console.log(value);
}

withReadableStreamFrom

function withReadableStreamFrom<T>(
  cb: (ReadableStream: ReadableStreamWithFrom) => T,
): T;

Runs ReadableStream.from code in the same way, even on runtimes without it.

import { withReadableStreamFrom } from "@unikvs/utils";

const stream = withReadableStreamFrom((ReadableStream) =>
  ReadableStream.from([1, 2, 3]),
);

Errors

Validation errors for filenames and dirnames. Thrown for unusable names.

Error Condition
InvalidFilenameError An unusable filename was given.
InvalidDirnameError An unusable dirname was given.
import { InvalidFilenameError } from "@unikvs/utils";

throw new InvalidFilenameError({ filename: "../evil" });

Examples

A combined example of validation, splitting, and stream conversion.

import {
  assertValidFilename,
  chunks,
  InvalidFilenameError,
  toReadableStream,
} from "@unikvs/utils";

async function saveChunks(filename: string, data: Uint8Array): Promise<void> {
  try {
    assertValidFilename(filename);
  } catch (error) {
    if (error instanceof InvalidFilenameError) {
      console.error(`Invalid filename: ${error.meta.filename}`);
    }
    throw error;
  }

  const stream = toReadableStream(chunks(data, 64 * 1024));

  for await (const chunk of stream) {
    await writeChunk(filename, chunk);
  }
}

async function writeChunk(filename: string, chunk: Uint8Array): Promise<void> {
  console.log(`Writing ${chunk.byteLength} bytes to ${filename}.`);
}

Was this page helpful?