Skip to content

Commit

Permalink
Partial implementation of node os polyfill based on currently availab…
Browse files Browse the repository at this point in the history
…le Deno functionality (denoland/deno#3821)
  • Loading branch information
cknight authored and caspervonb committed Jan 24, 2021
1 parent 3817a7d commit 5551781
Show file tree
Hide file tree
Showing 5 changed files with 505 additions and 1 deletion.
2 changes: 1 addition & 1 deletion node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ deno standard library as it's a compatiblity module.
- [ ] https
- [x] module
- [ ] net
- [ ] os
- [x] os _partly_
- [x] path
- [ ] perf_hooks
- [x] process _partly_
Expand Down
2 changes: 2 additions & 0 deletions node/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import * as nodeFS from "./fs.ts";
import * as nodeUtil from "./util.ts";
import * as nodePath from "./path.ts";
import * as nodeTimers from "./timers.ts";
import * as nodeOs from "./os.ts";

import * as path from "../path/mod.ts";
import { assert } from "../testing/asserts.ts";
Expand Down Expand Up @@ -582,6 +583,7 @@ nativeModulePolyfill.set("fs", createNativeModule("fs", nodeFS));
nativeModulePolyfill.set("util", createNativeModule("util", nodeUtil));
nativeModulePolyfill.set("path", createNativeModule("path", nodePath));
nativeModulePolyfill.set("timers", createNativeModule("timers", nodeTimers));
nativeModulePolyfill.set("os", createNativeModule("os", nodeOs));
function loadNativeModule(
_filename: string,
request: string
Expand Down
6 changes: 6 additions & 0 deletions node/module_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ test(function requireIndexJS() {
const { isIndex } = require_("./tests/cjs");
assert(isIndex);
});

test(function requireNodeOs() {
const os = require_("os");
assert(os.arch);
assert(typeof os.arch() == "string");
});
221 changes: 221 additions & 0 deletions node/os.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
// 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 "./_utils.ts";

const SEE_GITHUB_ISSUE = "See https://github.com/denoland/deno/issues/3802";

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;
}

/** Returns the operating system CPU architecture for which the Deno binary was compiled */
export function arch(): string {
return Deno.build.arch;
}

/** Not yet implemented */
export function cpus(): CPUCoreInfo[] {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function endianness(): "BE" | "LE" {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function freemem(): number {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function getPriority(pid = 0): number {
validateInt32(pid, "pid");
notImplemented(SEE_GITHUB_ISSUE);
}

/** Returns the string path of the current user's home directory. */
export function homedir(): string {
return Deno.dir("home");
}

/** Returns the host name of the operating system as a string. */
export function hostname(): string {
return Deno.hostname();
}

/** Not yet implemented */
export function loadavg(): number[] {
if (Deno.build.os == "win") {
return [0, 0, 0];
}
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function networkInterfaces(): NetworkInterfaces {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function platform(): string {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function release(): string {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function setPriority(pid: number, priority?: number): void {
/* 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;
}
validateInt32(pid, "pid");
validateInt32(priority, "priority", -20, 19);

notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function tmpdir(): string {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function totalmem(): number {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function type(): string {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function uptime(): number {
notImplemented(SEE_GITHUB_ISSUE);
}

/** Not yet implemented */
export function userInfo(
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
options: UserInfoOptions = { encoding: "utf-8" }
): UserInfo {
notImplemented(SEE_GITHUB_ISSUE);
}

export const constants = {
// UV_UDP_REUSEADDR: 4, //see https://nodejs.org/docs/latest-v12.x/api/os.html#os_libuv_constants
dlopen: {
// see https://nodejs.org/docs/latest-v12.x/api/os.html#os_dlopen_constants
},
errno: {
// see https://nodejs.org/docs/latest-v12.x/api/os.html#os_error_constants
},
signals: Deno.Signal,
priority: {
// see https://nodejs.org/docs/latest-v12.x/api/os.html#os_priority_constants
}
};

export const EOL = Deno.build.os == "win" ? "\r\n" : "\n";

const validateInt32 = (
value: number,
name: string,
min = -2147483648,
max = 2147483647
): void => {
// The defaults for min and max correspond to the limits of 32-bit integers.
if (!Number.isInteger(value)) {
throw new Error(`${name} must be 'an integer' but was ${value}`);
}
if (value < min || value > max) {
throw new Error(
`${name} must be >= ${min} && <= ${max}. Value was ${value}`
);
}
};
Loading

0 comments on commit 5551781

Please sign in to comment.