1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 07:44:48 -05:00

Add readlink, readlinkSync for std/node/fs.ts (#3926)

This commit is contained in:
Benny Shi 2020-02-10 17:38:05 +08:00 committed by GitHub
parent 1abd408770
commit e8f639ce53
2 changed files with 104 additions and 2 deletions

57
std/node/fs.ts Normal file → Executable file
View file

@ -3,7 +3,12 @@ import {
intoCallbackAPIWithIntercept, intoCallbackAPIWithIntercept,
MaybeEmpty MaybeEmpty
} from "./_utils.ts"; } from "./_utils.ts";
const { readFile: denoReadFile, readFileSync: denoReadFileSync } = Deno; const {
readFile: denoReadFile,
readFileSync: denoReadFileSync,
readlink: denoReadlink,
readlinkSync: denoReadlinkSync
} = Deno;
type ReadFileCallback = ( type ReadFileCallback = (
err: MaybeEmpty<Error>, err: MaybeEmpty<Error>,
@ -15,6 +20,15 @@ interface ReadFileOptions {
flag?: string; flag?: string;
} }
type ReadlinkCallback = (
err: MaybeEmpty<Error>,
linkString: MaybeEmpty<string | Uint8Array>
) => void;
interface ReadlinkOptions {
encoding?: string | null;
}
function getEncoding( function getEncoding(
optOrCallback?: ReadFileOptions | ReadFileCallback optOrCallback?: ReadFileOptions | ReadFileCallback
): string | null { ): string | null {
@ -27,6 +41,8 @@ function getEncoding(
optOrCallback.encoding === "utf-8" optOrCallback.encoding === "utf-8"
) { ) {
return "utf8"; return "utf8";
} else if (optOrCallback.encoding === "buffer") {
return "buffer";
} else { } else {
notImplemented(); notImplemented();
} }
@ -45,6 +61,16 @@ function maybeDecode(
return data; return data;
} }
function maybeEncode(
data: string,
encoding: string | null
): string | Uint8Array {
if (encoding === "buffer") {
return new TextEncoder().encode(data);
}
return data;
}
export function readFile( export function readFile(
path: string, path: string,
optOrCallback: ReadFileCallback | ReadFileOptions, optOrCallback: ReadFileCallback | ReadFileOptions,
@ -73,3 +99,32 @@ export function readFileSync(
): string | Uint8Array { ): string | Uint8Array {
return maybeDecode(denoReadFileSync(path), getEncoding(opt)); return maybeDecode(denoReadFileSync(path), getEncoding(opt));
} }
export function readlink(
path: string,
optOrCallback: ReadlinkCallback | ReadlinkOptions,
callback?: ReadlinkCallback
): void {
let cb: ReadlinkCallback | undefined;
if (typeof optOrCallback === "function") {
cb = optOrCallback;
} else {
cb = callback;
}
const encoding = getEncoding(optOrCallback);
intoCallbackAPIWithIntercept<string, Uint8Array | string>(
denoReadlink,
(data: string): string | Uint8Array => maybeEncode(data, encoding),
cb,
path
);
}
export function readlinkSync(
path: string,
opt?: ReadlinkOptions
): string | Uint8Array {
return maybeEncode(denoReadlinkSync(path), getEncoding(opt));
}

49
std/node/fs_test.ts Normal file → Executable file
View file

@ -1,9 +1,12 @@
import { readFile, readFileSync } from "./fs.ts"; import { readFile, readFileSync, readlink, readlinkSync } from "./fs.ts";
import { test } from "../testing/mod.ts"; import { test } from "../testing/mod.ts";
import * as path from "../path/mod.ts"; import * as path from "../path/mod.ts";
import { assertEquals, assert } from "../testing/asserts.ts"; import { assertEquals, assert } from "../testing/asserts.ts";
const testData = path.resolve(path.join("node", "testdata", "hello.txt")); const testData = path.resolve(path.join("node", "testdata", "hello.txt"));
const testDir = Deno.makeTempDirSync();
const oldname = testDir + "/oldname";
const newname = testDir + "/newname";
// Need to convert to promises, otherwise test() won't report error correctly. // Need to convert to promises, otherwise test() won't report error correctly.
test(async function readFileSuccess() { test(async function readFileSuccess() {
@ -45,3 +48,47 @@ test(function readFileEncodeUtf8Success() {
assertEquals(typeof data, "string"); assertEquals(typeof data, "string");
assertEquals(data as string, "hello world"); assertEquals(data as string, "hello world");
}); });
// Just for now, until we implement symlink for Windows.
if (Deno.build.os !== "win") {
Deno.symlinkSync(oldname, newname);
test(async function readlinkSuccess() {
const data = await new Promise((res, rej) => {
readlink(newname, (err, data) => {
if (err) {
rej(err);
}
res(data);
});
});
assertEquals(typeof data, "string");
assertEquals(data as string, oldname);
});
test(async function readlinkEncodeBufferSuccess() {
const data = await new Promise((res, rej) => {
readlink(newname, { encoding: "buffer" }, (err, data) => {
if (err) {
rej(err);
}
res(data);
});
});
assert(data instanceof Uint8Array);
assertEquals(new TextDecoder().decode(data as Uint8Array), oldname);
});
test(function readlinkSyncSuccess() {
const data = readlinkSync(newname);
assertEquals(typeof data, "string");
assertEquals(data as string, oldname);
});
test(function readlinkEncodeBufferSuccess() {
const data = readlinkSync(newname, { encoding: "buffer" });
assert(data instanceof Uint8Array);
assertEquals(new TextDecoder().decode(data as Uint8Array), oldname);
});
}