/** * Bun runtime APIs * * @example * * ```js * import {file} from 'bun'; * * // Log the file to the console * const input = await file('/path/to/file.txt').text(); * console.log(input); * ``` * * This module aliases `globalThis.Bun`. */ declare module "bun" { type PathLike = string | NodeJS.TypedArray | ArrayBufferLike | URL; type ArrayBufferView = | NodeJS.TypedArray | DataView; type BufferSource = NodeJS.TypedArray | DataView | ArrayBufferLike; type StringOrBuffer = string | NodeJS.TypedArray | ArrayBufferLike; type XMLHttpRequestBodyInit = Blob | BufferSource | FormData | URLSearchParams | string; type ReadableStreamController = ReadableStreamDefaultController; type ReadableStreamDefaultReadResult = | ReadableStreamDefaultReadValueResult | ReadableStreamDefaultReadDoneResult; type ReadableStreamReader = ReadableStreamDefaultReader; type Transferable = ArrayBuffer | MessagePort; type MessageEventSource = Bun.__internal.UseLibDomIfAvailable<"MessageEventSource", undefined>; /** * An encoding label from the WHATWG Encoding Standard, as accepted by the * `TextDecoder` constructor. * * The labels of the `replacement` encoding are excluded: the `TextDecoder` * constructor rejects them with a `RangeError`. * * @see https://encoding.spec.whatwg.org/#names-and-labels */ type Encoding = // utf-8 | "unicode-1-1-utf-8" | "unicode11utf8" | "unicode20utf8" | "utf-8" | "utf8" | "x-unicode20utf8" // ibm866 | "866" | "cp866" | "csibm866" | "ibm866" // iso-8859-2 | "csisolatin2" | "iso-8859-2" | "iso-ir-101" | "iso8859-2" | "iso88592" | "iso_8859-2" | "iso_8859-2:1987" | "l2" | "latin2" // iso-8859-3 | "csisolatin3" | "iso-8859-3" | "iso-ir-109" | "iso8859-3" | "iso88593" | "iso_8859-3" | "iso_8859-3:1988" | "l3" | "latin3" // iso-8859-4 | "csisolatin4" | "iso-8859-4" | "iso-ir-110" | "iso8859-4" | "iso88594" | "iso_8859-4" | "iso_8859-4:1988" | "l4" | "latin4" // iso-8859-5 | "csisolatincyrillic" | "cyrillic" | "iso-8859-5" | "iso-ir-144" | "iso8859-5" | "iso88595" | "iso_8859-5" | "iso_8859-5:1988" // iso-8859-6 | "arabic" | "asmo-708" | "csiso88596e" | "csiso88596i" | "csisolatinarabic" | "ecma-114" | "iso-8859-6" | "iso-8859-6-e" | "iso-8859-6-i" | "iso-ir-127" | "iso8859-6" | "iso88596" | "iso_8859-6" | "iso_8859-6:1987" // iso-8859-7 | "csisolatingreek" | "ecma-118" | "elot_928" | "greek" | "greek8" | "iso-8859-7" | "iso-ir-126" | "iso8859-7" | "iso88597" | "iso_8859-7" | "iso_8859-7:1987" | "sun_eu_greek" // iso-8859-8 | "csiso88598e" | "csisolatinhebrew" | "hebrew" | "iso-8859-8" | "iso-8859-8-e" | "iso-ir-138" | "iso8859-8" | "iso88598" | "iso_8859-8" | "iso_8859-8:1988" | "visual" // iso-8859-8-i | "csiso88598i" | "iso-8859-8-i" | "logical" // iso-8859-10 | "csisolatin6" | "iso-8859-10" | "iso-ir-157" | "iso8859-10" | "iso885910" | "l6" | "latin6" // iso-8859-13 | "iso-8859-13" | "iso8859-13" | "iso885913" // iso-8859-14 | "iso-8859-14" | "iso8859-14" | "iso885914" // iso-8859-15 | "csisolatin9" | "iso-8859-15" | "iso8859-15" | "iso885915" | "iso_8859-15" | "l9" // iso-8859-16 | "iso-8859-16" // koi8-r | "cskoi8r" | "koi" | "koi8" | "koi8-r" | "koi8_r" // koi8-u | "koi8-ru" | "koi8-u" // macintosh | "csmacintosh" | "mac" | "macintosh" | "x-mac-roman" // windows-874 | "dos-874" | "iso-8859-11" | "iso8859-11" | "iso885911" | "tis-620" | "windows-874" // windows-1250 | "cp1250" | "windows-1250" | "x-cp1250" // windows-1251 | "cp1251" | "windows-1251" | "x-cp1251" // windows-1252 | "ansi_x3.4-1968" | "ascii" | "cp1252" | "cp819" | "csisolatin1" | "ibm819" | "iso-8859-1" | "iso-ir-100" | "iso8859-1" | "iso88591" | "iso_8859-1" | "iso_8859-1:1987" | "l1" | "latin1" | "us-ascii" | "windows-1252" | "x-cp1252" // windows-1253 | "cp1253" | "windows-1253" | "x-cp1253" // windows-1254 | "cp1254" | "csisolatin5" | "iso-8859-9" | "iso-ir-148" | "iso8859-9" | "iso88599" | "iso_8859-9" | "iso_8859-9:1989" | "l5" | "latin5" | "windows-1254" | "x-cp1254" // windows-1255 | "cp1255" | "windows-1255" | "x-cp1255" // windows-1256 | "cp1256" | "windows-1256" | "x-cp1256" // windows-1257 | "cp1257" | "windows-1257" | "x-cp1257" // windows-1258 | "cp1258" | "windows-1258" | "x-cp1258" // x-mac-cyrillic | "x-mac-cyrillic" | "x-mac-ukrainian" // gbk | "chinese" | "csgb2312" | "csiso58gb231280" | "gb2312" | "gb_2312" | "gb_2312-80" | "gbk" | "iso-ir-58" | "x-gbk" // gb18030 | "gb18030" // big5 | "big5" | "big5-hkscs" | "cn-big5" | "csbig5" | "x-x-big5" // euc-jp | "cseucpkdfmtjapanese" | "euc-jp" | "x-euc-jp" // iso-2022-jp | "csiso2022jp" | "iso-2022-jp" // shift_jis | "csshiftjis" | "ms932" | "ms_kanji" | "shift-jis" | "shift_jis" | "sjis" | "windows-31j" | "x-sjis" // euc-kr | "cseuckr" | "csksc56011987" | "euc-kr" | "iso-ir-149" | "korean" | "ks_c_5601-1987" | "ks_c_5601-1989" | "ksc5601" | "ksc_5601" | "windows-949" // utf-16be | "unicodefffe" | "utf-16be" // utf-16le | "csunicode" | "iso-10646-ucs-2" | "ucs-2" | "unicode" | "unicodefeff" | "utf-16" | "utf-16le" // x-user-defined | "x-user-defined"; type UncaughtExceptionOrigin = "uncaughtException" | "unhandledRejection"; type MultipleResolveType = "resolve" | "reject"; type BeforeExitListener = (code: number) => void; type DisconnectListener = () => void; type ExitListener = (code: number) => void; type RejectionHandledListener = (promise: Promise) => void; type FormDataEntryValue = File | string; type WarningListener = (warning: Error) => void; type MessageListener = (message: unknown, sendHandle: unknown) => void; type SignalsListener = (signal: NodeJS.Signals) => void; type BlobPart = string | Blob | BufferSource; type TimerHandler = (...args: any[]) => void; type DOMHighResTimeStamp = number; type EventListenerOrEventListenerObject = EventListener | EventListenerObject; type BlobOrStringOrBuffer = string | NodeJS.TypedArray | ArrayBufferLike | Blob; type MaybePromise = T | Promise; namespace __internal { type LibDomIsLoaded = typeof globalThis extends { onabort: any } ? true : false; /** * Uses the lib.dom.d.ts definition of a global if it exists, otherwise falls back to `Otherwise`. * * Some symbols can't be declared in a way that satisfies both \@types/bun and lib.dom.d.ts, * so when lib.dom.d.ts is loaded, its definition wins. */ type UseLibDomIfAvailable = // `onabort` is defined in lib.dom.d.ts, so we can check to see if lib dom is loaded by checking if `onabort` is defined LibDomIsLoaded extends true ? typeof globalThis extends { [K in GlobalThisKeyName]: infer T } // if it is loaded, infer it from `globalThis` and use that value ? T : Otherwise // Not defined in lib dom (or anywhere else), so no conflict. We can safely use our own definition : Otherwise; // Lib dom not loaded anyway, so no conflict. We can safely use our own definition /** * Like Omit, but correctly distributes over unions. Most useful for removing * properties from union options objects, like {@link Bun.SQL.Options} * * @example * ```ts * type X = Bun.DistributedOmit<{type?: 'a', url?: string} | {type?: 'b', flag?: boolean}, "url"> * // `{type?: 'a'} | {type?: 'b', flag?: boolean}` (Omit applied to each union item instead of entire type) * * type X = Omit<{type?: 'a', url?: string} | {type?: 'b', flag?: boolean}, "url">; * // `{type?: "a" | "b" | undefined}` (Missing `flag` property and no longer a union) * ``` */ type DistributedOmit = T extends T ? Omit : never; type KeysInBoth = Extract; type MergeInner = Omit> & Omit> & { [Key in KeysInBoth]: A[Key] | B[Key]; }; type Merge = MergeInner & MergeInner; type DistributedMerge = T extends T ? Merge> : never; type Without = A & { [Key in Exclude]?: never; }; type XOR = Without | Without; } interface ErrorEventInit extends EventInit { colno?: number; error?: any; filename?: string; lineno?: number; message?: string; } interface CloseEventInit extends EventInit { code?: number; reason?: string; wasClean?: boolean; } interface MessageEventInit extends EventInit { data?: T; lastEventId?: string; origin?: string; source?: Bun.MessageEventSource | null; } interface EventInit { bubbles?: boolean; cancelable?: boolean; composed?: boolean; } interface EventListenerOptions { capture?: boolean; } interface CustomEventInit extends Bun.EventInit { detail?: T; } /** A message received by a target object. */ interface BunMessageEvent extends Event { /** Returns the data of the message. */ readonly data: T; /** Returns the last event ID string, for server-sent events. */ readonly lastEventId: string; /** Returns the origin of the message, for server-sent events and cross-document messaging. */ readonly origin: string; /** Returns the MessagePort array sent with the message, for cross-document messaging and channel messaging. */ readonly ports: readonly MessagePort[]; // ReadonlyArray; readonly source: Bun.MessageEventSource | null; } type MessageEvent = Bun.__internal.UseLibDomIfAvailable<"MessageEvent", BunMessageEvent>; interface ReadableStreamDefaultReadManyResult { done: boolean; /** Number of bytes */ size: number; value: T[]; } interface EventSourceEventMap { error: Event; message: MessageEvent; open: Event; } interface AddEventListenerOptions extends EventListenerOptions { /** When `true`, the listener is automatically removed when it is first invoked. Default: `false`. */ once?: boolean; /** When `true`, serves as a hint that the listener will not call the `Event` object's `preventDefault()` method. Default: false. */ passive?: boolean; signal?: AbortSignal; } interface EventListener { (evt: Event): void; } interface EventListenerObject { handleEvent(object: Event): void; } interface FetchEvent extends Event { readonly request: Request; readonly url: string; waitUntil(promise: Promise): void; respondWith(response: Response | Promise): void; } interface EventMap { fetch: FetchEvent; message: MessageEvent; messageerror: MessageEvent; // exit: Event; } interface StructuredSerializeOptions { transfer?: Bun.Transferable[]; } interface EventSource extends EventTarget { new (url: string | URL, eventSourceInitDict?: EventSourceInit): EventSource; onerror: ((this: EventSource, ev: Event) => any) | null; onmessage: ((this: EventSource, ev: MessageEvent) => any) | null; onopen: ((this: EventSource, ev: Event) => any) | null; /** Returns the state of this EventSource object's connection: `CONNECTING` (0), `OPEN` (1), or `CLOSED` (2). */ readonly readyState: number; /** Returns the URL providing the event stream. */ readonly url: string; /** Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise. * * Not supported in Bun */ readonly withCredentials: boolean; /** Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED. */ close(): void; readonly CLOSED: 2; readonly CONNECTING: 0; readonly OPEN: 1; addEventListener( type: K, listener: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions, ): void; addEventListener( type: string, listener: (this: EventSource, event: MessageEvent) => any, options?: boolean | AddEventListenerOptions, ): void; addEventListener( type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions, ): void; removeEventListener( type: K, listener: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | EventListenerOptions, ): void; removeEventListener( type: string, listener: (this: EventSource, event: MessageEvent) => any, options?: boolean | EventListenerOptions, ): void; removeEventListener( type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions, ): void; /** * Keep the event loop alive while the connection is open or reconnecting * * Not available in browsers */ ref(): void; /** * Do not keep the event loop alive while the connection is open or reconnecting * * Not available in browsers */ unref(): void; } interface TransformerFlushCallback { (controller: TransformStreamDefaultController): void | PromiseLike; } interface TransformerStartCallback { (controller: TransformStreamDefaultController): any; } interface TransformerTransformCallback { (chunk: I, controller: TransformStreamDefaultController): void | PromiseLike; } interface UnderlyingSinkAbortCallback { (reason?: any): void | PromiseLike; } interface UnderlyingSinkCloseCallback { (): void | PromiseLike; } interface UnderlyingSinkStartCallback { (controller: WritableStreamDefaultController): any; } interface UnderlyingSinkWriteCallback { (chunk: W, controller: WritableStreamDefaultController): void | PromiseLike; } interface UnderlyingSourceCancelCallback { (reason?: any): void | PromiseLike; } interface UnderlyingSink { abort?: UnderlyingSinkAbortCallback; close?: UnderlyingSinkCloseCallback; start?: UnderlyingSinkStartCallback; type?: undefined | "default" | "bytes"; write?: UnderlyingSinkWriteCallback; } interface UnderlyingSource { cancel?: UnderlyingSourceCancelCallback; pull?: UnderlyingSourcePullCallback; start?: UnderlyingSourceStartCallback; /** * Mode "bytes" is not supported. */ type?: undefined; } interface DirectUnderlyingSource { cancel?: UnderlyingSourceCancelCallback; pull: (controller: ReadableStreamDirectController) => void | PromiseLike; type: "direct"; } interface UnderlyingSourcePullCallback { (controller: ReadableStreamController): void | PromiseLike; } interface UnderlyingSourceStartCallback { (controller: ReadableStreamController): any; } interface GenericTransformStream { readonly readable: ReadableStream; readonly writable: WritableStream; } interface AbstractWorkerEventMap { error: ErrorEvent; } interface WorkerEventMap extends AbstractWorkerEventMap { message: MessageEvent; messageerror: MessageEvent; close: CloseEvent; open: Event; } type WorkerType = "classic" | "module"; interface AbstractWorker { /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/error_event) */ onerror: ((this: AbstractWorker, ev: ErrorEvent) => any) | null; addEventListener( type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions, ): void; addEventListener( type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions, ): void; removeEventListener( type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions, ): void; removeEventListener( type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions, ): void; } /** * Bun's Web Worker constructor supports some extra options on top of the API browsers have. */ interface WorkerOptions { /** * An identifying name for the worker's `DedicatedWorkerGlobalScope`, mainly * useful for debugging. */ name?: string; /** * Use less memory, but make the worker slower. * * Internally, this sets the heap size configuration in JavaScriptCore to be * the small heap instead of the large heap. */ smol?: boolean; /** * When `true`, the worker keeps the parent thread alive until the worker is terminated or `unref`'d. * When `false`, it does not. * * @default false */ ref?: boolean; /** * In Bun, this does nothing. */ type?: Bun.WorkerType | undefined; /** * List of arguments to stringify and append to `Bun.argv` / `process.argv` * in the worker. The values are available on the global `Bun.argv` as if * they were passed as CLI options to the script. */ argv?: any[] | undefined; /** If `true` and the first argument is a string, interpret the first argument to the constructor as a script that is executed once the worker is online. */ // eval?: boolean | undefined; /** * If set, the initial value of `process.env` inside the Worker thread. Pass `worker.SHARE_ENV` * from `node:worker_threads` to share environment variables between the parent and worker threads; * changes to one thread's `process.env` then affect the other thread as well. Default: `process.env`. */ env?: Record | (typeof import("node:worker_threads"))["SHARE_ENV"] | undefined; /** * In Bun, this does nothing. */ credentials?: import("undici-types").RequestCredentials | undefined; /** * @default true */ // trackUnmanagedFds?: boolean; // resourceLimits?: import("worker_threads").ResourceLimits; /** * An array of module specifiers to preload in the worker. * * These modules load before the worker's entry point is executed. * * Equivalent to passing the `--preload` CLI argument, but only for this Worker. */ preload?: string[] | string | undefined; } interface Worker extends EventTarget, AbstractWorker { /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/message_event) */ onmessage: ((this: Worker, ev: MessageEvent) => any) | null; /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/messageerror_event) */ onmessageerror: ((this: Worker, ev: MessageEvent) => any) | null; /** * Clones message and transmits it to worker's global environment. transfer can be passed as a list of objects that are to be transferred rather than cloned. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/postMessage) */ postMessage(message: any, transfer: Transferable[]): void; postMessage(message: any, options?: StructuredSerializeOptions): void; /** * Aborts worker's associated global environment. * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/terminate) */ terminate(): void; addEventListener( type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions, ): void; addEventListener( type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions, ): void; removeEventListener( type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions, ): void; removeEventListener( type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions, ): void; /** * Opposite of `unref()`: calling `ref()` on a previously `unref()`ed worker does _not_ let the * program exit if it's the only active handle left (the default behavior). * If the worker is already `ref()`ed, calling `ref()` again has no effect. */ ref(): void; /** * Calling `unref()` on a worker allows the thread to exit if this is the only * active handle in the event system. If the worker is already `unref()`ed, * calling `unref()` again has no effect. */ unref(): void; /** * An integer identifier for the referenced thread. Inside the worker thread, * it is available as `require('node:worker_threads').threadId`. * This value is unique for each `Worker` instance inside a single process. */ threadId: number; } interface Env { NODE_ENV?: string; /** * Set to change the default timezone at runtime */ TZ?: string; } /** * The environment variables of the process * * Defaults to `process.env` as it was when the current Bun process launched. * * Changes to `process.env` at runtime won't automatically be reflected in the default value. For that, you can pass `process.env` explicitly. */ const env: Env & NodeJS.ProcessEnv & ImportMetaEnv; /** * The raw arguments passed to the process, including flags passed to Bun. * To read the flags passed to your script, use `process.argv` instead. */ const argv: string[]; interface WhichOptions { /** * Overrides the `PATH` environment variable */ PATH?: string; /** * When `command` is a relative path, resolve it against this directory. */ cwd?: string; } /** * Find the path to an executable, like the `which` command in your terminal. * Reads the `PATH` environment variable unless overridden with `options.PATH`. * * @category Utilities * * @param command The name of the executable or script to find * @param options Options for the search * @returns The path to the executable, or `null` if it isn't found */ function which(command: string, options?: WhichOptions): string | null; interface StringWidthOptions { /** * If `true`, count ANSI escape codes as part of the string width. If `false`, ignore them. * * @default false */ countAnsiEscapeCodes?: boolean; /** * If `true`, count ambiguous-width characters as 1 character wide. If `false`, count them as 2 characters wide. * * @default true */ ambiguousIsNarrow?: boolean; /** * If `true`, measure every Unicode code point individually (East Asian * Width plus emoji presentation, the algorithm Node.js uses for * `console.table` and `util.inspect` alignment), so each member of an * emoji ZWJ sequence is counted: `"πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦"` measures 8. If `false`, * emoji sequences and other grapheme clusters count once: `"πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦"` * measures 2. * * @default false */ perCodePoint?: boolean; } /** * Get the column count of a string as it would be displayed in a terminal. * Supports ANSI escape codes, emoji, and wide characters. * * This API is designed to match the `string-width` npm package, so existing * code can be ported in either direction. * * @category Utilities * * @returns The width of the string in columns * * @example * ```ts * import { stringWidth } from "bun"; * * console.log(stringWidth("abc")); // 3 * console.log(stringWidth("πŸ‘©β€πŸ‘©β€πŸ‘§β€πŸ‘¦")); // 1 * console.log(stringWidth("\u001b[31mhello\u001b[39m")); // 5 * console.log(stringWidth("\u001b[31mhello\u001b[39m", { countAnsiEscapeCodes: false })); // 5 * console.log(stringWidth("\u001b[31mhello\u001b[39m", { countAnsiEscapeCodes: true })); // 13 * ``` */ function stringWidth( /** * The string to measure */ input: string, options?: StringWidthOptions, ): number; /** * Remove ANSI escape codes from a string. * * @category Utilities * * @param input The string to remove ANSI escape codes from. * @returns The string with ANSI escape codes removed. * * @example * ```ts * import { stripANSI } from "bun"; * * console.log(stripANSI("\u001b[31mhello\u001b[39m")); // "hello" * ``` */ function stripANSI(input: string): string; interface SliceAnsiOptions { /** * If set, and content was cut at either edge of the requested range, * insert this string at the cut edge(s). The ellipsis is counted against * the visible-width budget and is emitted *inside* any active SGR styles * (color, bold, etc.) so it inherits them, but *outside* any active OSC 8 * hyperlink. * * This turns `sliceAnsi` into a drop-in `cli-truncate` replacement: * - truncate-end: `sliceAnsi(str, 0, max, { ellipsis: "\u2026" })` * - truncate-start: `sliceAnsi(str, -max, undefined, { ellipsis: "\u2026" })` */ ellipsis?: string; /** * Count characters with East Asian Width "Ambiguous" as 1 column (narrow) * instead of 2 (wide). Affects Greek, Cyrillic, some symbols, etc. that * render wide in CJK-encoded terminals but narrow in Western ones. * * Matches the option of the same name in {@link stringWidth} and * {@link wrapAnsi}. * * @default true */ ambiguousIsNarrow?: boolean; } /** * Slice a string by visible column width, preserving ANSI escape codes. * * Like `String.prototype.slice`, but indices are terminal column widths * (accounting for wide CJK characters, emoji grapheme clusters, and * zero-width joiners), and ANSI escape sequences (SGR colors, OSC 8 * hyperlinks, etc.) are preserved and correctly re-opened/closed at the * slice boundaries. * * @category Utilities * * @param input The string to slice * @param start Starting column (default 0). Negative counts from end. * @param end Ending column, exclusive (default end of string). Negative counts from end. * @param options Optional behavior flags (such as `ellipsis` for truncation) * @returns The sliced string with ANSI codes intact * * @example * ```ts * import { sliceAnsi } from "bun"; * * // Plain slice (replaces the `slice-ansi` npm package) * sliceAnsi("hello", 1, 4); // "ell" * sliceAnsi("\u001b[31mhello\u001b[39m", 1, 4); // "\u001b[31mell\u001b[39m" * sliceAnsi("\u5b89\u5b81\u54c8", 0, 4); // "\u5b89\u5b81" (CJK: width 2 each) * * // Truncation (replaces the `cli-truncate` npm package) * sliceAnsi("unicorn", 0, 4, "\u2026"); // "uni\u2026" * sliceAnsi("unicorn", -4, undefined, "\u2026"); // "\u2026orn" * ``` */ function sliceAnsi( input: string, start?: number, end?: number, /** * Shorthand for common options (avoids `{}` allocation): * - `string` β†’ ellipsis (equivalent to `{ ellipsis: string }`) * - `boolean` β†’ ambiguousIsNarrow (equivalent to `{ ambiguousIsNarrow: boolean }`) * - `SliceAnsiOptions` β†’ full options object */ options?: string | boolean | SliceAnsiOptions, /** * ambiguousIsNarrow as a positional arg, usable when the 4th arg is an * ellipsis string (or `undefined`). Lets you pass both options without * an object: `sliceAnsi(s, 0, n, "\u2026", false)`. */ ambiguousIsNarrow?: boolean, ): string; interface WrapAnsiOptions { /** * If `true`, break words in the middle if they don't fit on a line. * If `false`, only break at word boundaries. * * @default false */ hard?: boolean; /** * If `true`, wrap at word boundaries when possible. * If `false`, break every line at exactly the column width (characters * are split wherever the limit falls, ignoring word boundaries). * * @default true */ wordWrap?: boolean; /** * If `true`, trim leading and trailing whitespace from each line. * If `false`, preserve whitespace. * * @default true */ trim?: boolean; /** * If `true`, count ambiguous-width characters as 1 character wide. * If `false`, count them as 2 characters wide. * * @default true */ ambiguousIsNarrow?: boolean; } /** * Wrap a string to fit within the specified column width, preserving ANSI escape codes. * * Designed to be compatible with the `wrap-ansi` npm package. * * Features: * - Preserves ANSI escape codes (colors, styles) across line breaks * - Supports SGR codes (colors, bold, italic, etc.) and OSC 8 hyperlinks * - Respects Unicode display widths (full-width characters, emoji) * - Word wrapping at word boundaries (configurable) * * @category Utilities * * @param input The string to wrap * @param columns The maximum column width * @param options Wrapping options * @returns The wrapped string * * @example * ```ts * import { wrapAnsi } from "bun"; * * console.log(wrapAnsi("hello world", 5)); * // Output: * // hello * // world * * // Preserves ANSI colors across line breaks * console.log(wrapAnsi("\u001b[31mhello world\u001b[0m", 5)); * // Output: * // \u001b[31mhello\u001b[0m * // \u001b[31mworld\u001b[0m * * // Hard wrap long words * console.log(wrapAnsi("abcdefghij", 3, { hard: true })); * // Output: * // abc * // def * // ghi * // j * ``` */ function wrapAnsi( /** * The string to wrap */ input: string, /** * The maximum column width */ columns: number, /** * Wrapping options */ options?: WrapAnsiOptions, ): string; /** * TOML related APIs */ namespace TOML { /** * Parse a TOML (v1.1.0) document into a JavaScript object. * * Date/time values parse as Temporal objects: offset date-times as * `Temporal.Instant`, local date-times as `Temporal.PlainDateTime`, * local dates as `Temporal.PlainDate`, and local times as * `Temporal.PlainTime`. Integers outside `Number.MAX_SAFE_INTEGER` * throw, since they cannot be represented losslessly as JavaScript * numbers. * * @category Utilities * * @param input The TOML document to parse, as a string or UTF-8 bytes * @returns A JavaScript object * @throws {SyntaxError} If the input is not valid TOML */ export function parse( input: string | NodeJS.TypedArray | DataView | ArrayBufferLike | Blob, ): object; /** * Serialize a JavaScript object to a TOML document. * * The top-level value must be an object (a TOML document is a table). * `Temporal.Instant`, `Temporal.PlainDateTime`, `Temporal.PlainDate`, * and `Temporal.PlainTime` values become the corresponding TOML * date/time literals, `Temporal.ZonedDateTime` becomes an offset * date-time, and `Date` becomes an offset date-time in UTC; time-zone * and calendar annotations are dropped, since TOML has no syntax for * them. `null`, `BigInt`, circular structures, invalid `Date`s, date * values outside years 0000–9999, and Temporal types with no TOML form * (`Temporal.PlainYearMonth`, `Temporal.PlainMonthDay`, * `Temporal.Duration`) throw, since TOML cannot represent them; * `undefined`, function, and symbol properties are skipped (inside * arrays they throw, since TOML arrays cannot have holes). * * @category Utilities * * @param input The JavaScript object to serialize. * @param replacer Not supported; pass `undefined` or `null`. * @param space Accepted for signature parity with `YAML.stringify` and * `JSON5.stringify`, but ignored: TOML output is line-oriented. * @returns A TOML document string, or `undefined` if the input is `undefined`, a function, or a symbol. * * @example * ```js * import { TOML } from "bun"; * TOML.stringify({ name: "app", server: { port: 8080 } }); * // 'name = "app"\n\n[server]\nport = 8080\n' * ``` */ export function stringify(input: unknown, replacer?: undefined | null, space?: string | number): string | undefined; } /** * XML related APIs */ namespace XML { // ── compact shape ────────────────────────────────────────────────────── /** * An element in the compact shape {@link parse} returns by default: its * character data (a string) when it has no attributes and no child * elements, otherwise an {@link Element}. */ type Value = string | Element; /** * An element that has attributes or child elements, in the compact shape. * * - `"@name"` β€” one per attribute, holding its value. * - `"#text"` β€” the element's own character data, exactly, when it has any: * its text runs concatenated, leaving out only whitespace-only runs that * sit between child elements (layout). * - any other key β€” a child element name, holding that child's * {@link Value}, or an array of them when the name occurs more than once * in this element. * * Keys are in document order: attributes first, then child names and * `"#text"` in order of first appearance. `@` and `#` cannot begin an XML * name, so these keys never collide with element names. */ interface Element { [key: string]: Value | Value[]; } /** * A parsed document in the compact shape: exactly one key, the root * element's name. This is also what importing an `.xml` file evaluates to. */ interface Document { [rootName: string]: Value; } // ── tree shape ───────────────────────────────────────────────────────── /** An element in the tree {@link parse} returns with `{ compact: false }`. */ interface Node { /** The element name as written, including any namespace prefix (`"soap:Envelope"`). */ name: string; /** * Attribute values by name as written, in document order, after * attribute-value normalization and with defaults declared in the * internal DTD subset applied. Namespace declarations (`xmlns`, * `xmlns:*`) are ordinary attributes. */ attributes: Record; /** * The element's content in document order: character data as strings * (exact β€” CDATA sections, character references and internal entities * expanded, whitespace untouched, adjacent text merged into one string), * child elements, comments and processing instructions. An object here is * an element if it has `name`, a comment if it has `comment`, and a * processing instruction if it has `target`. */ children: Array; } /** `` among a {@link Node}'s children. */ interface Comment { comment: string; } /** `` among a {@link Node}'s children. */ interface ProcessingInstruction { target: string; /** The text after the whitespace that follows the target; `""` when there is none. */ data: string; } // ── parse ────────────────────────────────────────────────────────────── interface ParseOptions { /** * Selects the shape of the result. * * - `true` (default): the compact {@link Document} β€” elements keyed by * name, leaves as strings. The shape for data. It does not keep the * relative order of differently named siblings, where text sat relative * to child elements, comments, or processing instructions. * - `false`: the root element as a {@link Node} tree, which keeps all of * those, in document order. The shape for documents. * * Neither shape represents the XML declaration, the document type * declaration, or anything outside the root element. * * @default true */ compact?: boolean; } /** * Parse an XML 1.0 document. * * `Bun.XML` is a conforming, non-validating XML processor. The document β€” * including any internal DTD subset β€” must be well-formed or a * `SyntaxError` is thrown; there is no lenient mode. Internal entities are * expanded (within an expansion limit), attribute values are normalized, * and attribute defaults declared in the internal subset are applied. * External DTDs and external entities are never read. Nothing is coerced: * every value is a string. * * `compact` selects a structure; it never alters character data. The text * of an element is the same in both shapes β€” as written, whitespace * included. The compact shape only does what having a single `"#text"` * forces: an element's text runs are concatenated, and a whitespace-only * run between child elements (the document's layout) is left out. * * A reference to an entity that only an unread external DTD could declare * is not an error (XML 1.0 Β§4.1) and is kept in the text as written * (`"&name;"` β€” indistinguishable afterwards from an escaped `&name;`). * * A string is parsed as already-decoded text. Bytes (`Buffer`, * `TypedArray`, `DataView`, `ArrayBuffer`, `Blob`) are decoded per the XML * rules: a byte-order mark or the `encoding` declared in `` * selects UTF-8, UTF-16, or ISO-8859-1; other encodings throw. * * @category Utilities * * @param input The XML document * @throws {SyntaxError} If the document is not well-formed, uses an * unsupported encoding, or exceeds the entity-expansion limits * @throws {RangeError} If elements are nested too deeply * * @example * ```ts * import { XML } from "bun"; * * XML.parse(`TeaMug`); * // { * // order: { * // "@id": "A1", * // item: [ { "@sku": "x", "#text": "Tea" }, { "@sku": "y", "#text": "Mug" } ], * // paid: "", * // }, * // } * * XML.parse(`

Hello world!

`, { compact: false }); * // { * // name: "p", * // attributes: {}, * // children: [ "Hello ", { name: "b", attributes: {}, children: ["world"] }, "!", { comment: " bye " } ], * // } * ``` */ function parse( input: string | NodeJS.TypedArray | DataView | ArrayBufferLike | Blob, options?: ParseOptions & { compact?: true }, ): Document; function parse( input: string | NodeJS.TypedArray | DataView | ArrayBufferLike | Blob, options: ParseOptions & { compact: false }, ): Node; function parse( input: string | NodeJS.TypedArray | DataView | ArrayBufferLike | Blob, options?: ParseOptions, ): Document | Node; // ── stringify ────────────────────────────────────────────────────────── /** A value {@link stringify} writes as text: `String(v)`, or the ISO string of a `Date`. */ type Scalar = string | number | boolean | bigint | Date; /** * A {@link Node} as {@link stringify} accepts it: `attributes` and * `children` may be omitted, scalars may stand where text goes, and * `null`/`undefined` entries are skipped. */ interface NodeInput { name: string; attributes?: { [name: string]: Scalar | null | undefined } | null; children?: Array | null; } /** * Serialize one element to XML: a {@link NodeInput} tree (any object with a * string `name` and a `children` or `attributes` property), or a compact * object with exactly one key naming the root element whose value follows * the {@link Element} conventions. * * The result is that element's markup only β€” no XML declaration and no * document type declaration; prepend them as text when writing a file * (`'\n' + XML.stringify(doc)`). * Because of that, results can be concatenated inside an enclosing element. * * The output is well-formed or `stringify` throws. `& < >` are escaped * everywhere; `"`, tabs and newlines in attribute values, and carriage * returns anywhere, are written as character references so they survive * being parsed again. It throws for element, attribute or processing * instruction names that are not XML names; for characters XML cannot * contain (U+0000, other C0 controls except tab/newline/carriage return, * U+FFFE, U+FFFF, unpaired surrogates); for `--` inside a comment or `?>` * inside processing-instruction data; for an array at the root or inside * another array; and for circular structures. * * Strings, numbers, booleans and bigints become text via `String()`, a * `Date` its ISO string; `null` becomes an empty element (or leaves an * attribute out); `undefined`, functions and symbols are skipped, as are * symbol-keyed, non-enumerable and inherited properties. In the compact * shape an array is one element per item and any other object is a child * element. * * `XML.parse(XML.stringify(value))` deep-equals `value` for anything * `XML.parse` returned, in either shape. * * @category Utilities * * @param value The element to serialize * @param replacer Reserved; must be `undefined` or `null` * @param space Indentation for element-only content, as in `JSON.stringify`: * a number of spaces (at most 10) or a string (its first 10 characters). * An element with any text child is written on one line so character data * is unchanged. * @returns The XML, or `undefined` if `value` is `undefined`, a function, or a symbol * * @example * ```ts * import { XML } from "bun"; * * XML.stringify({ order: { "@id": "A1", item: ["Tea", "Mug"], paid: null } }); * // 'TeaMug' * * XML.stringify({ name: "p", attributes: { class: "x" }, children: ["Hi ", { name: "b", children: ["!"] }] }, null, 2); * // '

Hi !

' * ``` */ function stringify(value: NodeInput | Document, replacer?: undefined | null, space?: string | number): string; function stringify(value: unknown, replacer?: undefined | null, space?: string | number): string | undefined; } /** * JSONC related APIs */ namespace JSONC { /** * Parse a JSONC (JSON with Comments) string into a JavaScript value. * * Supports both single-line (`//`) and block comments (`/* ... *\/`), as well as * trailing commas in objects and arrays. * * @category Utilities * * @param input The JSONC string to parse * @returns A JavaScript value * @throws {SyntaxError} If the input is not valid JSONC * * @example * ```js * const result = Bun.JSONC.parse(`{ * // This is a comment * "name": "my-app", * "version": "1.0.0", // trailing comma is allowed * }`); * ``` */ export function parse(input: string): unknown; } /** * JSONL (JSON Lines) related APIs. * * Each line of the input is a JSON value. */ namespace JSONL { /** * The result of `Bun.JSONL.parseChunk`. */ interface ParseChunkResult { /** The successfully parsed JSON values. */ values: unknown[]; /** How much of the input was consumed. When the input is a string, this is a character offset. When the input is a `TypedArray`, this is a byte offset. Use `input.slice(read)` or `input.subarray(read)` to get the unconsumed remainder. */ read: number; /** `true` if all input was consumed successfully. `false` if the input ends with an incomplete value or a parse error occurred. */ done: boolean; /** A `SyntaxError` if a parse error occurred, otherwise `null`. Values parsed before the error are still available in `values`. */ error: SyntaxError | null; } /** * Parse a JSONL (JSON Lines) string into an array of JavaScript values. * * If a parse error occurs and no values were successfully parsed, throws * a `SyntaxError`. If values were parsed before the error, returns the * successfully parsed values without throwing. * * Incomplete trailing values (for example, from a partial chunk) are * silently ignored. * * When a `TypedArray` is passed, the bytes are parsed directly without * copying if the content is ASCII. * * @param input The JSONL string or typed array to parse * @returns An array of parsed values * @throws {SyntaxError} If the input starts with invalid JSON and no values could be parsed * * @example * ```js * const items = Bun.JSONL.parse('{"a":1}\n{"b":2}\n'); * // [{ a: 1 }, { b: 2 }] * * // From a Uint8Array (zero-copy for ASCII): * const buf = new TextEncoder().encode('{"a":1}\n{"b":2}\n'); * const items = Bun.JSONL.parse(buf); * // [{ a: 1 }, { b: 2 }] * * // Partial results on error after valid values: * const partial = Bun.JSONL.parse('{"a":1}\n{bad}\n'); * // [{ a: 1 }] * * // Throws when no valid values precede the error: * Bun.JSONL.parse('{bad}\n'); // throws SyntaxError * ``` */ export function parse(input: string | NodeJS.TypedArray | DataView | ArrayBufferLike): unknown[]; /** * Parse a JSONL chunk, designed for streaming use. * * Never throws on parse errors. Instead, returns whatever values were * successfully parsed along with an `error` property containing the * `SyntaxError` (or `null` on success). Use `read` to determine how * much input was consumed and `done` to check if all input was parsed. * * When a `TypedArray` is passed, the bytes are parsed directly without * copying if the content is ASCII. Optional `start` and `end` parameters * select a window of the input without copying. For typed arrays these * are byte offsets and `read` is a byte offset into the original * typed array. For strings these are character offsets and `read` is * a character offset into the original string. * * @param input The JSONL string or typed array to parse * @param start Offset to start parsing from (bytes for typed arrays, characters for strings, default: 0) * @param end Offset to stop parsing at (bytes for typed arrays, characters for strings, default: input length) * @returns An object with `values`, `read`, `done`, and `error` properties * * @example * ```js * let buffer = new Uint8Array(0); * for await (const chunk of stream) { * buffer = Buffer.concat([buffer, chunk]); * const { values, read, error } = Bun.JSONL.parseChunk(buffer); * if (error) throw error; * for (const value of values) handle(value); * buffer = buffer.subarray(read); * } * ``` */ export function parseChunk( input: string | NodeJS.TypedArray | DataView | ArrayBufferLike, start?: number, end?: number, ): ParseChunkResult; } /** * YAML related APIs */ namespace YAML { /** * Parse a YAML string into a JavaScript value. Every alias (`*name`) of an anchored collection yields the * same object, and an alias may refer to a collection that contains it, so the result can be cyclic. * * @category Utilities * * @param input The YAML string to parse * @returns A JavaScript value, or an array of them for a multi-document stream * * @example * ```ts * import { YAML } from "bun"; * * console.log(YAML.parse("123")) // 123 * console.log(YAML.parse("null")) // null * console.log(YAML.parse("false")) // false * console.log(YAML.parse("abc")) // "abc" * console.log(YAML.parse("- abc")) // [ "abc" ] * console.log(YAML.parse("abc: def")) // { "abc": "def" } * ``` */ export function parse(input: string): unknown; /** * Convert a JavaScript value into a YAML string. Strings are double quoted if they contain keywords, non-printable or * escaped characters, or if a YAML parser would parse them as numbers. Anchors and aliases are inferred from objects, allowing cycles. * * @category Utilities * * @param input The JavaScript value to stringify. * @param replacer Not supported. * @param space A number for how many spaces each level of indentation gets, or a string used as indentation. * Without this parameter, outputs flow-style (single-line) YAML. * With this parameter, outputs block-style (multi-line) YAML. * The number is clamped between 0 and 10, and the first 10 characters of the string are used. * @returns A string containing the YAML document. * * @example * ```ts * import { YAML } from "bun"; * * const input = { * abc: "def", * num: 123 * }; * * // Without space - flow style (single-line) * console.log(YAML.stringify(input)); * // {abc: def,num: 123} * * // With space - block style (multi-line) * console.log(YAML.stringify(input, null, 2)); * // abc: def * // num: 123 * * const cycle = {}; * cycle.obj = cycle; * console.log(YAML.stringify(cycle, null, 2)); * // &1 * // obj: *1 * ``` */ export function stringify(input: unknown, replacer?: undefined | null, space?: string | number): string; } /** * Markdown related APIs. * * Parses and renders markdown with four output modes: * - `html()` β€” render to an HTML string * - `ansi()` β€” render to an ANSI-colored string for terminals * - `render()` β€” render with custom callbacks for each element * - `react()` β€” parse to React-compatible JSX elements * * Supports GFM extensions (tables, strikethrough, task lists, autolinks) and * component overrides to replace default HTML tags with custom components. * * @example * ```tsx * // Render markdown to HTML * const html = Bun.markdown.html("# Hello **world**"); * // "

Hello world

\n" * * // Render with custom callbacks * const ansi = Bun.markdown.render("# Hello **world**", { * heading: (children, { level }) => `\x1b[1m${children}\x1b[0m\n`, * strong: (children) => `\x1b[1m${children}\x1b[22m`, * paragraph: (children) => children + "\n", * }); * * // Render as a React component * function Markdown({ text }: { text: string }) { * return Bun.markdown.react(text); * } * * // With component overrides * const element = Bun.markdown.react("# Hello", { h1: MyHeadingComponent }); * ``` */ namespace markdown { /** * Options for configuring the markdown parser. * * By default, GFM extensions (tables, strikethrough, task lists) are enabled. */ interface Options { /** Enable GFM tables. Default: `true`. */ tables?: boolean; /** Enable GFM strikethrough (`~~text~~`). Default: `true`. */ strikethrough?: boolean; /** Enable GFM task lists (`- [x] item`). Default: `true`. */ tasklists?: boolean; /** Treat soft line breaks as hard line breaks. Default: `false`. */ hardSoftBreaks?: boolean; /** Enable wiki-style links (`[[target]]` or `[[target|label]]`). Default: `false`. */ wikiLinks?: boolean; /** Enable underline syntax (`__text__` renders as `` instead of ``). Default: `false`. */ underline?: boolean; /** Enable LaTeX math (`$inline$` and `$$display$$`). Default: `false`. */ latexMath?: boolean; /** Collapse whitespace in text content. Default: `false`. */ collapseWhitespace?: boolean; /** Allow ATX headers without a space after `#`. Default: `false`. */ permissiveAtxHeaders?: boolean; /** Disable indented code blocks. Default: `false`. */ noIndentedCodeBlocks?: boolean; /** Disable HTML blocks. Default: `false`. */ noHtmlBlocks?: boolean; /** Disable inline HTML spans. Default: `false`. */ noHtmlSpans?: boolean; /** * Enable the GFM tag filter, which replaces `<` with `<` for disallowed * HTML tags (e.g. `