All files / fs / _get_fs_flag.ts

100.00% Branches 0/0
1.52% Lines 1/66
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 
 
x7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 












































































































// Copyright 2018-2025 the Deno authors. MIT license.

import { getNodeFs } from "./_utils.ts";
import type { WriteFileOptions } from "./unstable_types.ts";
import type { OpenOptions } from "./unstable_open.ts";

type WriteBooleanOptions = Pick<
  WriteFileOptions,
  "append" | "create" | "createNew"
>;

type OpenBooleanOptions = Pick<
  OpenOptions,
  "read" | "write" | "append" | "truncate" | "create" | "createNew"
>;

/**
 * Uses the boolean options specified in {@linkcode WriteFileOptions} to
 * construct the composite flag value to pass to the `flag` option in the
 * Node.js `writeFile` function.
 */
export function getWriteFsFlag(opt: WriteBooleanOptions): number {
  const { O_APPEND, O_CREAT, O_EXCL, O_TRUNC, O_WRONLY } =
    getNodeFs().constants;

  let flag = O_WRONLY;
  if (opt.create) {
    flag |= O_CREAT;
  }
  if (opt.createNew) {
    flag |= O_EXCL;
  }
  if (opt.append) {
    flag |= O_APPEND;
  } else {
    flag |= O_TRUNC;
  }
  return flag;
}

/**
 * Uses the boolean options specified in {@linkcode OpenOptions} to construct the
 * composite flag value to pass to the `flag` option in the Node.js `open`
 * function.
 */
export function getOpenFsFlag(opt: OpenBooleanOptions): number {
  const { O_APPEND, O_CREAT, O_EXCL, O_WRONLY, O_RDONLY, O_RDWR, O_TRUNC } =
    getNodeFs().constants;

  if (
    !opt.read && !opt.write && !opt.append && !opt.truncate && !opt.create &&
    !opt.createNew
  ) {
    throw new Error("'options' requires at least one option to be true");
  }

  if (!opt.write && opt.truncate) {
    throw new Error("'truncate' option requires 'write' to be true");
  }

  if ((opt.create || opt.createNew) && !(opt.write || opt.append)) {
    throw new Error(
      "'create' or 'createNew' options require 'write' or 'append' to be true",
    );
  }

  // This error is added to match the Deno runtime. Deno throws a `TypeError`
  // (os error 22) for this OpenOption combo. Under Node.js, the bitmask
  // combinations of (O_RDWR | O_TRUNC | O_APPEND) and
  // (O_WRONLY | O_TRUNC | O_APPEND) to open files are valid.
  if (opt.write && opt.append && opt.truncate) {
    throw new TypeError("Invalid argument");
  }

  let flag = O_RDONLY;
  if (opt.read && !opt.write) {
    flag |= O_RDONLY;
  }

  if (opt.read && opt.write) {
    flag |= O_RDWR;
  }

  if (!opt.read && opt.write) {
    flag |= O_WRONLY;
  }

  if (opt.create || opt.createNew) {
    flag |= O_CREAT;
  }

  if (opt.createNew) {
    flag |= O_EXCL;
  }

  if (opt.append) {
    flag |= O_APPEND;
    if (!opt.read) {
      flag |= O_WRONLY;
    } else {
      flag |= O_RDWR;
    }
  }

  if (opt.truncate) {
    flag |= O_TRUNC;
  }

  return flag;
}