mirror of
https://github.com/denoland/deno.git
synced 2025-09-23 10:52:33 +00:00

Fixes #30299 I decided to build the `OpenOptions` on the Rust side, because it's cheaper to pass integers to the op function and we can enable the fast op call. Also the tests that I added to the `config.toml` were already passing before this PR.
136 lines
3.6 KiB
TypeScript
136 lines
3.6 KiB
TypeScript
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
|
|
import { primordials } from "ext:core/mod.js";
|
|
const {
|
|
StringPrototypeToLowerCase,
|
|
ArrayPrototypeIncludes,
|
|
ReflectApply,
|
|
Error,
|
|
} = primordials;
|
|
import { validateFunction } from "ext:deno_node/internal/validators.mjs";
|
|
import type { ErrnoException } from "ext:deno_node/_global.d.ts";
|
|
import {
|
|
BinaryEncodings,
|
|
Encodings,
|
|
notImplemented,
|
|
TextEncodings,
|
|
} from "ext:deno_node/_utils.ts";
|
|
import { type Buffer } from "node:buffer";
|
|
|
|
export type CallbackWithError = (err: ErrnoException | null) => void;
|
|
|
|
export interface FileOptions {
|
|
encoding?: Encodings;
|
|
flag?: string;
|
|
signal?: AbortSignal;
|
|
}
|
|
|
|
export type TextOptionsArgument =
|
|
| TextEncodings
|
|
| ({ encoding: TextEncodings } & FileOptions);
|
|
export type BinaryOptionsArgument =
|
|
| BinaryEncodings
|
|
| ({ encoding: BinaryEncodings } & FileOptions);
|
|
export type FileOptionsArgument = Encodings | FileOptions;
|
|
|
|
export type ReadOptions = {
|
|
buffer: Buffer | ArrayBufferView;
|
|
offset: number;
|
|
length: number;
|
|
position: number | null;
|
|
};
|
|
|
|
export interface WriteFileOptions extends FileOptions {
|
|
mode?: number;
|
|
}
|
|
|
|
export function isFileOptions(
|
|
fileOptions: string | WriteFileOptions | undefined,
|
|
): fileOptions is FileOptions {
|
|
if (!fileOptions) return false;
|
|
|
|
return (
|
|
(fileOptions as FileOptions).encoding != undefined ||
|
|
(fileOptions as FileOptions).flag != undefined ||
|
|
(fileOptions as FileOptions).signal != undefined ||
|
|
(fileOptions as WriteFileOptions).mode != undefined
|
|
);
|
|
}
|
|
|
|
export function getEncoding(
|
|
optOrCallback?:
|
|
| FileOptions
|
|
| WriteFileOptions
|
|
// deno-lint-ignore no-explicit-any
|
|
| ((...args: any[]) => any)
|
|
| Encodings
|
|
| null,
|
|
): Encodings | null {
|
|
if (!optOrCallback || typeof optOrCallback === "function") {
|
|
return null;
|
|
}
|
|
|
|
const encoding = typeof optOrCallback === "string"
|
|
? optOrCallback
|
|
: optOrCallback.encoding;
|
|
if (!encoding) return null;
|
|
return encoding;
|
|
}
|
|
|
|
export function getSignal(optOrCallback?: FileOptions): AbortSignal | null {
|
|
if (!optOrCallback || typeof optOrCallback === "function") {
|
|
return null;
|
|
}
|
|
|
|
const signal = typeof optOrCallback === "object" && optOrCallback.signal
|
|
? optOrCallback.signal
|
|
: null;
|
|
|
|
return signal;
|
|
}
|
|
|
|
export function checkEncoding(encoding: Encodings | null): Encodings | null {
|
|
if (!encoding) return null;
|
|
|
|
encoding = StringPrototypeToLowerCase(encoding) as Encodings;
|
|
if (ArrayPrototypeIncludes(["utf8", "hex", "base64", "ascii"], encoding)) {
|
|
return encoding;
|
|
}
|
|
|
|
if (encoding === "utf-8") {
|
|
return "utf8";
|
|
}
|
|
if (encoding === "binary") {
|
|
return "binary";
|
|
// before this was buffer, however buffer is not used in Node
|
|
// node -e "require('fs').readFile('../world.txt', 'buffer', console.log)"
|
|
}
|
|
|
|
const notImplementedEncodings = ["utf16le", "latin1", "ucs2"];
|
|
|
|
if (ArrayPrototypeIncludes(notImplementedEncodings, encoding as string)) {
|
|
notImplemented(`"${encoding}" encoding`);
|
|
}
|
|
|
|
throw new Error(`The value "${encoding}" is invalid for option "encoding"`);
|
|
}
|
|
|
|
export { isUint32 as isFd } from "ext:deno_node/internal/validators.mjs";
|
|
|
|
export function maybeCallback(cb: unknown) {
|
|
validateFunction(cb, "cb");
|
|
|
|
return cb as CallbackWithError;
|
|
}
|
|
|
|
// Ensure that callbacks run in the global context. Only use this function
|
|
// for callbacks that are passed to the binding layer, callbacks that are
|
|
// invoked from JS already run in the proper scope.
|
|
export function makeCallback<T extends unknown[]>(
|
|
this: unknown,
|
|
cb?: (...args: T) => void,
|
|
) {
|
|
validateFunction(cb, "cb");
|
|
|
|
return (...args: T) => ReflectApply(cb!, this, args);
|
|
}
|