summaryrefslogtreecommitdiff
path: root/ext/node/polyfills/os.ts
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2023-02-14 17:38:45 +0100
committerGitHub <noreply@github.com>2023-02-14 17:38:45 +0100
commitd47147fb6ad229b1c039aff9d0959b6e281f4df5 (patch)
tree6e9e790f2b9bc71b5f0c9c7e64b95cae31579d58 /ext/node/polyfills/os.ts
parent1d00bbe47e2ca14e2d2151518e02b2324461a065 (diff)
feat(ext/node): embed std/node into the snapshot (#17724)
This commit moves "deno_std/node" in "ext/node" crate. The code is transpiled and snapshotted during the build process. During the first pass a minimal amount of work was done to create the snapshot, a lot of code in "ext/node" depends on presence of "Deno" global. This code will be gradually fixed in the follow up PRs to migrate it to import relevant APIs from "internal:" modules. Currently the code from snapshot is not used in any way, and all Node/npm compatibility still uses code from "https://deno.land/std/node" (or from the location specified by "DENO_NODE_COMPAT_URL"). This will also be handled in a follow up PRs. --------- Co-authored-by: crowlkats <crowlkats@toaxl.com> Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com> Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
Diffstat (limited to 'ext/node/polyfills/os.ts')
-rw-r--r--ext/node/polyfills/os.ts349
1 files changed, 349 insertions, 0 deletions
diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts
new file mode 100644
index 000000000..94ca944c8
--- /dev/null
+++ b/ext/node/polyfills/os.ts
@@ -0,0 +1,349 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import { notImplemented } from "internal:deno_node/polyfills/_utils.ts";
+import { validateIntegerRange } from "internal:deno_node/polyfills/_utils.ts";
+import process from "internal:deno_node/polyfills/process.ts";
+import { isWindows, osType } from "internal:deno_node/polyfills/_util/os.ts";
+import { os } from "internal:deno_node/polyfills/internal_binding/constants.ts";
+
+export const constants = os;
+
+const SEE_GITHUB_ISSUE = "See https://github.com/denoland/deno_std/issues/1436";
+
+// @ts-ignore Deno[Deno.internal] is used on purpose here
+const DenoOsUptime = Deno[Deno.internal]?.nodeUnstable?.osUptime ||
+ Deno.osUptime;
+
+interface CPUTimes {
+ /** The number of milliseconds the CPU has spent in user mode */
+ user: number;
+
+ /** The number of milliseconds the CPU has spent in nice mode */
+ nice: number;
+
+ /** The number of milliseconds the CPU has spent in sys mode */
+ sys: number;
+
+ /** The number of milliseconds the CPU has spent in idle mode */
+ idle: number;
+
+ /** The number of milliseconds the CPU has spent in irq mode */
+ irq: number;
+}
+
+interface CPUCoreInfo {
+ model: string;
+
+ /** in MHz */
+ speed: number;
+
+ times: CPUTimes;
+}
+
+interface NetworkAddress {
+ /** The assigned IPv4 or IPv6 address */
+ address: string;
+
+ /** The IPv4 or IPv6 network mask */
+ netmask: string;
+
+ family: "IPv4" | "IPv6";
+
+ /** The MAC address of the network interface */
+ mac: string;
+
+ /** true if the network interface is a loopback or similar interface that is not remotely accessible; otherwise false */
+ internal: boolean;
+
+ /** The numeric IPv6 scope ID (only specified when family is IPv6) */
+ scopeid?: number;
+
+ /** The assigned IPv4 or IPv6 address with the routing prefix in CIDR notation. If the netmask is invalid, this property is set to null. */
+ cidr: string;
+}
+
+interface NetworkInterfaces {
+ [key: string]: NetworkAddress[];
+}
+
+export interface UserInfoOptions {
+ encoding: string;
+}
+
+interface UserInfo {
+ username: string;
+ uid: number;
+ gid: number;
+ shell: string;
+ homedir: string;
+}
+
+export function arch(): string {
+ return process.arch;
+}
+
+// deno-lint-ignore no-explicit-any
+(arch as any)[Symbol.toPrimitive] = (): string => process.arch;
+// deno-lint-ignore no-explicit-any
+(endianness as any)[Symbol.toPrimitive] = (): string => endianness();
+// deno-lint-ignore no-explicit-any
+(freemem as any)[Symbol.toPrimitive] = (): number => freemem();
+// deno-lint-ignore no-explicit-any
+(homedir as any)[Symbol.toPrimitive] = (): string | null => homedir();
+// deno-lint-ignore no-explicit-any
+(hostname as any)[Symbol.toPrimitive] = (): string | null => hostname();
+// deno-lint-ignore no-explicit-any
+(platform as any)[Symbol.toPrimitive] = (): string => platform();
+// deno-lint-ignore no-explicit-any
+(release as any)[Symbol.toPrimitive] = (): string => release();
+// deno-lint-ignore no-explicit-any
+(version as any)[Symbol.toPrimitive] = (): string => version();
+// deno-lint-ignore no-explicit-any
+(totalmem as any)[Symbol.toPrimitive] = (): number => totalmem();
+// deno-lint-ignore no-explicit-any
+(type as any)[Symbol.toPrimitive] = (): string => type();
+// deno-lint-ignore no-explicit-any
+(uptime as any)[Symbol.toPrimitive] = (): number => uptime();
+
+export function cpus(): CPUCoreInfo[] {
+ return Array.from(Array(navigator.hardwareConcurrency)).map(() => {
+ return {
+ model: "",
+ speed: 0,
+ times: {
+ user: 0,
+ nice: 0,
+ sys: 0,
+ idle: 0,
+ irq: 0,
+ },
+ };
+ });
+}
+
+/**
+ * Returns a string identifying the endianness of the CPU for which the Deno
+ * binary was compiled. Possible values are 'BE' for big endian and 'LE' for
+ * little endian.
+ */
+export function endianness(): "BE" | "LE" {
+ // Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView#Endianness
+ const buffer = new ArrayBuffer(2);
+ new DataView(buffer).setInt16(0, 256, true /* littleEndian */);
+ // Int16Array uses the platform's endianness.
+ return new Int16Array(buffer)[0] === 256 ? "LE" : "BE";
+}
+
+/** Return free memory amount */
+export function freemem(): number {
+ return Deno.systemMemoryInfo().free;
+}
+
+/** Not yet implemented */
+export function getPriority(pid = 0): number {
+ validateIntegerRange(pid, "pid");
+ notImplemented(SEE_GITHUB_ISSUE);
+}
+
+/** Returns the string path of the current user's home directory. */
+export function homedir(): string | null {
+ // Note: Node/libuv calls getpwuid() / GetUserProfileDirectory() when the
+ // environment variable isn't set but that's the (very uncommon) fallback
+ // path. IMO, it's okay to punt on that for now.
+ switch (osType) {
+ case "windows":
+ return Deno.env.get("USERPROFILE") || null;
+ case "linux":
+ case "darwin":
+ case "freebsd":
+ return Deno.env.get("HOME") || null;
+ default:
+ throw Error("unreachable");
+ }
+}
+
+/** Returns the host name of the operating system as a string. */
+export function hostname(): string {
+ return Deno.hostname();
+}
+
+/** Returns an array containing the 1, 5, and 15 minute load averages */
+export function loadavg(): number[] {
+ if (isWindows) {
+ return [0, 0, 0];
+ }
+ return Deno.loadavg();
+}
+
+/** Returns an object containing network interfaces that have been assigned a network address.
+ * Each key on the returned object identifies a network interface. The associated value is an array of objects that each describe an assigned network address. */
+export function networkInterfaces(): NetworkInterfaces {
+ const interfaces: NetworkInterfaces = {};
+ for (
+ const { name, address, netmask, family, mac, scopeid, cidr } of Deno
+ .networkInterfaces()
+ ) {
+ const addresses = interfaces[name] ||= [];
+ const networkAddress: NetworkAddress = {
+ address,
+ netmask,
+ family,
+ mac,
+ internal: (family === "IPv4" && isIPv4LoopbackAddr(address)) ||
+ (family === "IPv6" && isIPv6LoopbackAddr(address)),
+ cidr,
+ };
+ if (family === "IPv6") {
+ networkAddress.scopeid = scopeid!;
+ }
+ addresses.push(networkAddress);
+ }
+ return interfaces;
+}
+
+function isIPv4LoopbackAddr(addr: string) {
+ return addr.startsWith("127");
+}
+
+function isIPv6LoopbackAddr(addr: string) {
+ return addr === "::1" || addr === "fe80::1";
+}
+
+/** Returns the a string identifying the operating system platform. The value is set at compile time. Possible values are 'darwin', 'linux', and 'win32'. */
+export function platform(): string {
+ return process.platform;
+}
+
+/** Returns the operating system as a string */
+export function release(): string {
+ return Deno.osRelease();
+}
+
+/** Returns a string identifying the kernel version */
+export function version(): string {
+ // TODO(kt3k): Temporarily uses Deno.osRelease().
+ // Revisit this if this implementation is insufficient for any npm module
+ return Deno.osRelease();
+}
+
+/** Not yet implemented */
+export function setPriority(pid: number, priority?: number) {
+ /* The node API has the 'pid' as the first parameter and as optional.
+ This makes for a problematic implementation in Typescript. */
+ if (priority === undefined) {
+ priority = pid;
+ pid = 0;
+ }
+ validateIntegerRange(pid, "pid");
+ validateIntegerRange(priority, "priority", -20, 19);
+
+ notImplemented(SEE_GITHUB_ISSUE);
+}
+
+/** Returns the operating system's default directory for temporary files as a string. */
+export function tmpdir(): string | null {
+ /* This follows the node js implementation, but has a few
+ differences:
+ * On windows, if none of the environment variables are defined,
+ we return null.
+ * On unix we use a plain Deno.env.get, instead of safeGetenv,
+ which special cases setuid binaries.
+ * Node removes a single trailing / or \, we remove all.
+ */
+ if (isWindows) {
+ const temp = Deno.env.get("TEMP") || Deno.env.get("TMP");
+ if (temp) {
+ return temp.replace(/(?<!:)[/\\]*$/, "");
+ }
+ const base = Deno.env.get("SYSTEMROOT") || Deno.env.get("WINDIR");
+ if (base) {
+ return base + "\\temp";
+ }
+ return null;
+ } else { // !isWindows
+ const temp = Deno.env.get("TMPDIR") || Deno.env.get("TMP") ||
+ Deno.env.get("TEMP") || "/tmp";
+ return temp.replace(/(?<!^)\/*$/, "");
+ }
+}
+
+/** Return total physical memory amount */
+export function totalmem(): number {
+ return Deno.systemMemoryInfo().total;
+}
+
+/** Returns operating system type (i.e. 'Windows_NT', 'Linux', 'Darwin') */
+export function type(): string {
+ switch (Deno.build.os as string) {
+ case "windows":
+ return "Windows_NT";
+ case "linux":
+ return "Linux";
+ case "darwin":
+ return "Darwin";
+ case "freebsd":
+ return "FreeBSD";
+ default:
+ throw Error("unreachable");
+ }
+}
+
+/** Returns the Operating System uptime in number of seconds. */
+export function uptime(): number {
+ return DenoOsUptime();
+}
+
+/** Not yet implemented */
+export function userInfo(
+ // deno-lint-ignore no-unused-vars
+ options: UserInfoOptions = { encoding: "utf-8" },
+): UserInfo {
+ notImplemented(SEE_GITHUB_ISSUE);
+}
+
+export const EOL = isWindows ? "\r\n" : "\n";
+export const devNull = isWindows ? "\\\\.\\nul" : "/dev/null";
+
+export default {
+ arch,
+ cpus,
+ endianness,
+ freemem,
+ getPriority,
+ homedir,
+ hostname,
+ loadavg,
+ networkInterfaces,
+ platform,
+ release,
+ setPriority,
+ tmpdir,
+ totalmem,
+ type,
+ uptime,
+ userInfo,
+ version,
+ constants,
+ EOL,
+ devNull,
+};