Skip to main content
Module

std/node/_fs/_fs_open.ts

Deno standard library
Go to Latest
File
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.import { O_APPEND, O_CREAT, O_EXCL, O_RDWR, O_TRUNC, O_WRONLY,} from "./_fs_constants.ts";import { existsSync } from "../../fs/exists.ts";import { getOpenOptions } from "./_fs_common.ts";import { promisify } from "../internal/util.mjs";import { parseFileMode } from "../internal/validators.mjs";import { ERR_INVALID_ARG_TYPE } from "../internal/errors.ts";import { getValidatedPath } from "../internal/fs/utils.mjs";import type { Buffer } from "../buffer.ts";
const FLAGS_AX = O_APPEND | O_CREAT | O_WRONLY | O_EXCL;const FLAGS_AX_PLUS = O_APPEND | O_CREAT | O_RDWR | O_EXCL;const FLAGS_WX = O_TRUNC | O_CREAT | O_WRONLY | O_EXCL;const FLAGS_WX_PLUS = O_TRUNC | O_CREAT | O_RDWR | O_EXCL;
export type openFlags = | "a" | "ax" | "a+" | "ax+" | "as" | "as+" | "r" | "r+" | "rs+" | "w" | "wx" | "w+" | "wx+" | number;
type openCallback = (err: Error | null, fd: number) => void;
function convertFlagAndModeToOptions( flag?: openFlags, mode?: number,): Deno.OpenOptions | undefined { if (!flag && !mode) return undefined; if (!flag && mode) return { mode }; return { ...getOpenOptions(flag), mode };}
export function open(path: string | Buffer | URL, callback: openCallback): void;export function open( path: string | Buffer | URL, flags: openFlags, callback: openCallback,): void;export function open( path: string | Buffer | URL, flags: openFlags, mode: number, callback: openCallback,): void;export function open( path: string | Buffer | URL, flags: openCallback | openFlags, mode?: openCallback | number, callback?: openCallback,) { if (flags === undefined) { throw new ERR_INVALID_ARG_TYPE( "flags or callback", ["string", "function"], flags, ); } path = getValidatedPath(path); if (arguments.length < 3) { // deno-lint-ignore no-explicit-any callback = flags as any; flags = "r"; mode = 0o666; } else if (typeof mode === "function") { callback = mode; mode = 0o666; } else { mode = parseFileMode(mode, "mode", 0o666); }
if (typeof callback !== "function") { throw new ERR_INVALID_ARG_TYPE( "callback", "function", callback, ); }
if (flags === undefined) { flags = "r"; }
if ( existenceCheckRequired(flags as openFlags) && existsSync(path as string) ) { const err = new Error(`EEXIST: file already exists, open '${path}'`); (callback as (err: Error) => void)(err); } else { if (flags === "as" || flags === "as+") { let err: Error | null = null, res: number; try { res = openSync(path, flags, mode); } catch (error) { err = error instanceof Error ? error : new Error("[non-error thrown]"); } if (err) { (callback as (err: Error) => void)(err); } else { callback(null, res!); } return; } Deno.open( path as string, convertFlagAndModeToOptions(flags as openFlags, mode), ).then( (file) => callback!(null, file.rid), (err) => (callback as (err: Error) => void)(err), ); }}
export const openPromise = promisify(open) as ( & ((path: string | Buffer | URL) => Promise<number>) & ((path: string | Buffer | URL, flags: openFlags) => Promise<number>) & ((path: string | Buffer | URL, mode?: number) => Promise<number>) & (( path: string | Buffer | URL, flags?: openFlags, mode?: number, ) => Promise<number>));
export function openSync(path: string | Buffer | URL): number;export function openSync( path: string | Buffer | URL, flags?: openFlags,): number;export function openSync(path: string | Buffer | URL, mode?: number): number;export function openSync( path: string | Buffer | URL, flags?: openFlags, mode?: number,): number;export function openSync( path: string | Buffer | URL, flags?: openFlags, maybeMode?: number,) { const mode = parseFileMode(maybeMode, "mode", 0o666); path = getValidatedPath(path);
if (flags === undefined) { flags = "r"; }
if ( existenceCheckRequired(flags) && existsSync(path as string) ) { throw new Error(`EEXIST: file already exists, open '${path}'`); }
return Deno.openSync(path as string, convertFlagAndModeToOptions(flags, mode)) .rid;}
function existenceCheckRequired(flags: openFlags | number) { return ( (typeof flags === "string" && ["ax", "ax+", "wx", "wx+"].includes(flags)) || (typeof flags === "number" && ( ((flags & FLAGS_AX) === FLAGS_AX) || ((flags & FLAGS_AX_PLUS) === FLAGS_AX_PLUS) || ((flags & FLAGS_WX) === FLAGS_WX) || ((flags & FLAGS_WX_PLUS) === FLAGS_WX_PLUS) )) );}