Skip to content

Commit

Permalink
Revert deno compat refactor and just inline isIP
Browse files Browse the repository at this point in the history
  • Loading branch information
scotttrinh committed Dec 5, 2023
1 parent 5cc06c0 commit 1eb91d5
Show file tree
Hide file tree
Showing 2 changed files with 259 additions and 13 deletions.
16 changes: 15 additions & 1 deletion integration-tests/lts/deno/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

256 changes: 244 additions & 12 deletions packages/driver/src/adapter.deno.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import process from "node:process";
import { process } from "https://deno.land/[email protected]/node/process.ts";
import {
crypto,
toHashString,
} from "https://deno.land/[email protected]/crypto/mod.ts";

import path from "node:path";
import * as _fs from "https://deno.land/[email protected]/fs/mod.ts";
import fs from "node:fs/promises";
import util from "node:util";
import net from "node:net";
import crypto from "node:crypto";
import url from "node:url";
import tls from "node:tls";
import path from "https://deno.land/[email protected]/node/path.ts";
import * as _fs from "https://deno.land/[email protected]/fs/mod.ts";
import * as fs from "https://deno.land/[email protected]/node/fs/promises.ts";
import EventEmitter from "https://deno.land/[email protected]/node/events.ts";
import util from "https://deno.land/[email protected]/node/util.ts";
import { isIP as _isIP } from "https://deno.land/[email protected]/node/net.ts";

export { path, process, util, fs, net, tls };
export { path, process, util, fs };

export async function readFileUtf8(...pathParts: string[]): Promise<string> {
return await Deno.readTextFile(path.join(...pathParts));
Expand Down Expand Up @@ -49,7 +51,7 @@ export async function walk(
}

export async function exists(fn: string | URL): Promise<boolean> {
fn = fn instanceof URL ? url.fileURLToPath(fn) : fn;
fn = fn instanceof URL ? path.fromFileUrl(fn) : fn;
try {
await Deno.lstat(fn);
return true;
Expand All @@ -63,7 +65,10 @@ export async function exists(fn: string | URL): Promise<boolean> {
}

export function hashSHA1toHex(msg: string): string {
return crypto.createHash("sha1").update(msg).digest("hex");
return toHashString(
crypto.subtle.digestSync("SHA-1", new TextEncoder().encode(msg)),
"hex"
);
}

export function homeDir(): string {
Expand All @@ -79,13 +84,240 @@ export function homeDir(): string {
throw new Error("Unable to determine home path");
}

// TODO: replace this with
// `import * as fs from "https://deno.land/[email protected]/node/fs.ts";`
// when the 'fs' compat module does not require '--unstable' flag.

// async function toArray(iter: AsyncIterable<unknown>) {
// const arr = [];
// for await (const i of iter) arr.push(i);
// return arr;
// }

// deno-lint-ignore-file
// export namespace fs {
// export function realpath(path: string): Promise<string> {
// return Deno.realPath(path);
// }

// export async function access(path: string) {
// return Deno.stat(path);
// }

// export async function readdir(path: string) {
// const dirContents = Deno.readDir(path);
// return toArray(dirContents);
// }

// export function stat(path: string): Promise<Deno.FileInfo> {
// return Deno.stat(path);
// }

// export function rm(
// path: string,
// params?: {recursive?: boolean}
// ): Promise<void> {
// return Deno.remove(path, params);
// }
// export function mkdir(
// path: string,
// _params?: {recursive?: boolean}
// ): Promise<void> {
// return _fs.ensureDir(path);
// }

// export function writeFile(path: string, contents: string): Promise<void> {
// return Deno.writeTextFile(path, contents);
// }
// export function writeFileSync(path: string, contents: string): void {
// return Deno.writeTextFileSync(path, contents);
// }
// export function appendFile(path: string, contents: string): Promise<void> {
// return Deno.writeTextFile(path, contents, {append: true});
// }
// }

export async function input(message = "", _params?: { silent?: boolean }) {
const buf = new Uint8Array(1024);
await Deno.stdout.write(new TextEncoder().encode(message));
const n = <number>await Deno.stdin.read(buf);
return new TextDecoder().decode(buf.subarray(0, n)).trim();
}

// TODO: when 'net.Socket' is implemented in deno node compatibility library
// replace this (https://github.com/denoland/deno_std/pull/694)
export namespace net {
export function createConnection(port: number, hostname?: string): Socket;
export function createConnection(unixpath: string): Socket;
export function createConnection(
port: number | string,
hostname?: string
): Socket {
// TODO: unix transport is currently behind --unstable flag, add correct
// typing when (if?) this becomes stable
const opts: any =
typeof port === "string"
? { transport: "unix", path: port }
: { port, hostname };

const conn = Deno.connect(opts);

return new Socket(conn);
}

export const isIP = _isIP;

export declare interface Socket {
on(eventName: "error", listener: (e: any) => void): this;
on(eventName: "connect", listener: () => void): this;
on(eventName: "data", listener: (data: Uint8Array) => void): this;
on(eventName: "close", listener: () => void): this;
}

export class BaseSocket<T extends Deno.Conn> extends EventEmitter {
protected _conn: T | null = null;
protected _reader: Deno.Reader | null = null;
protected _paused = true;

setNoDelay() {
// No deno api for this
}

unref() {
// No deno api for this
// Without this api, open idle connections will block deno from exiting
// after all other tasks are finished
return this;
}

ref() {
// No deno api for this
return this;
}

pause() {
this._paused = true;
}

async resume() {
this._paused = false;
while (!this._paused && this._reader) {
try {
const buf = new Uint8Array(16 * 1024);
const bytes = await this._reader.read(buf);

if (bytes !== null) {
this.emit("data", buf.subarray(0, bytes));
} else {
// I'm assuming when the reader has ended
// the connection is closed
this._conn = null;
this._reader = null;
this.emit("close");
}
} catch (e) {
this.emit("error", e);
}
}
}

async write(data: Uint8Array) {
try {
await this._conn?.write(data);
} catch (e) {
this.emit("error", e);
}
}

destroy(error?: Error) {
this._conn?.close();
this._conn = null;
this._reader = null;
if (error) {
throw error;
}
}
}

export class Socket extends BaseSocket<Deno.Conn> {
constructor(pconn: Promise<Deno.Conn>) {
super();
pconn
.then((conn) => {
this._conn = conn;
this._reader = conn;
this.emit("connect");
this.resume();
})
.catch((e) => {
this.emit("error", e);
});
}
}
}

export namespace tls {
export function connect(options: tls.ConnectionOptions): tls.TLSSocket {
if (options.host == null) {
throw new Error("host option must be set");
}

if (options.port == null) {
throw new Error("port option must be set");
}

const conn = Deno.connectTls({
port: options.port,
hostname: options.host,
alpnProtocols: options.ALPNProtocols,
caCerts: typeof options.ca === "string" ? [options.ca] : options.ca,
});

return new TLSSocket(conn);
}

export function checkServerIdentity(
hostname: string,
cert: Object
): Error | undefined {
return undefined;
}

export interface ConnectionOptions {
host?: string;
port?: number;
ALPNProtocols?: string[];
ca?: string | string[];
checkServerIdentity?: (a: string, b: any) => Error | undefined;
rejectUnauthorized?: boolean;
servername?: string;
}

export class TLSSocket extends net.BaseSocket<Deno.TlsConn> {
private _alpnProtocol: string | null = null;

constructor(pconn: Promise<Deno.TlsConn>) {
super();
pconn
.then(async (conn) => {
const handshake = await conn.handshake();
this._alpnProtocol = handshake.alpnProtocol;
this._conn = conn;
this._reader = conn;
this.emit("secureConnect");
this.resume();
})
.catch((e) => {
this.emit("error", e);
});
}

get alpnProtocol(): string | false {
return this._alpnProtocol ?? false;
}
}
}

export function exit(code?: number) {
Deno.exit(code);
}
Expand Down

0 comments on commit 1eb91d5

Please sign in to comment.