summaryrefslogtreecommitdiff
path: root/js/os.ts
blob: 2fc06434a874ca9a5ed78a2d9e02bcc190085dd4 (plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { core } from "./core.ts";
import * as dispatch from "./dispatch.ts";
import { sendSync } from "./dispatch_json.ts";
import { assert } from "./util.ts";
import * as util from "./util.ts";
import { window } from "./window.ts";
import { OperatingSystem, Arch } from "./build.ts";

// builtin modules
import { _setGlobals } from "./deno.ts";

/** Check if running in terminal.
 *
 *       console.log(Deno.isTTY().stdout);
 */
export function isTTY(): { stdin: boolean; stdout: boolean; stderr: boolean } {
  return sendSync(dispatch.OP_IS_TTY);
}

/** Get the hostname.
 * Requires the `--allow-env` flag.
 *
 *       console.log(Deno.hostname());
 */
export function hostname(): string {
  return sendSync(dispatch.OP_HOSTNAME);
}

/** Exit the Deno process with optional exit code. */
export function exit(code = 0): never {
  sendSync(dispatch.OP_EXIT, { code });
  return util.unreachable();
}

function setEnv(key: string, value: string): void {
  sendSync(dispatch.OP_SET_ENV, { key, value });
}

function getEnv(key: string): string | undefined {
  return sendSync(dispatch.OP_GET_ENV, { key })[0];
}

/** Returns a snapshot of the environment variables at invocation. Mutating a
 * property in the object will set that variable in the environment for
 * the process. The environment object will only accept `string`s
 * as values.
 *
 *       console.log(Deno.env("SHELL"));
 *       const myEnv = Deno.env();
 *       console.log(myEnv.SHELL);
 *       myEnv.TEST_VAR = "HELLO";
 *       const newEnv = Deno.env();
 *       console.log(myEnv.TEST_VAR == newEnv.TEST_VAR);
 */
export function env(): { [index: string]: string };
export function env(key: string): string | undefined;
export function env(
  key?: string
): { [index: string]: string } | string | undefined {
  if (key) {
    return getEnv(key);
  }
  const env = sendSync(dispatch.OP_ENV);
  return new Proxy(env, {
    set(obj, prop: string, value: string): boolean {
      setEnv(prop, value);
      return Reflect.set(obj, prop, value);
    }
  });
}

interface Start {
  cwd: string;
  pid: number;
  argv: string[];
  mainModule: string; // Absolute URL.
  debugFlag: boolean;
  depsFlag: boolean;
  typesFlag: boolean;
  versionFlag: boolean;
  denoVersion: string;
  v8Version: string;
  tsVersion: string;
  noColor: boolean;
  xevalDelim: string;
  os: OperatingSystem;
  arch: Arch;
}

// This function bootstraps an environment within Deno, it is shared both by
// the runtime and the compiler environments.
// @internal
export function start(preserveDenoNamespace = true, source?: string): Start {
  core.setAsyncHandler(dispatch.asyncMsgFromRust);
  const ops = core.ops();
  // TODO(bartlomieju): this is a prototype, we should come up with
  // something a bit more sophisticated
  for (const [name, opId] of Object.entries(ops)) {
    const opName = `OP_${name.toUpperCase()}`;
    // Assign op ids to actual variables
    dispatch[opName] = opId;
  }
  // First we send an empty `Start` message to let the privileged side know we
  // are ready. The response should be a `StartRes` message containing the CLI
  // args and other info.
  const s = sendSync(dispatch.OP_START);

  util.setLogDebug(s.debugFlag, source);

  // pid and noColor need to be set in the Deno module before it's set to be
  // frozen.
  _setGlobals(s.pid, s.noColor);
  delete window.Deno._setGlobals;
  Object.freeze(window.Deno);

  if (preserveDenoNamespace) {
    util.immutableDefine(window, "Deno", window.Deno);
    // Deno.core could ONLY be safely frozen here (not in globals.ts)
    // since shared_queue.js will modify core properties.
    Object.freeze(window.Deno.core);
    // core.sharedQueue is an object so we should also freeze it.
    Object.freeze(window.Deno.core.sharedQueue);
  } else {
    // Remove window.Deno
    delete window.Deno;
    assert(window.Deno === undefined);
  }

  return s;
}

/**
 * Returns the current user's home directory.
 * Requires the `--allow-env` flag.
 */
export function homeDir(): string {
  const path = sendSync(dispatch.OP_HOME_DIR);
  if (!path) {
    throw new Error("Could not get home directory.");
  }
  return path;
}

/**
 * Returns the path to the current deno executable.
 * Requires the `--allow-env` flag.
 */
export function execPath(): string {
  return sendSync(dispatch.OP_EXEC_PATH);
}