1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 15:24:46 -05:00
denoland-deno/runtime/js/30_fs.js

560 lines
12 KiB
JavaScript

// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
"use strict";
((window) => {
const core = window.Deno.core;
const ops = core.ops;
const {
Date,
DatePrototype,
MathTrunc,
ObjectPrototypeIsPrototypeOf,
SymbolAsyncIterator,
SymbolIterator,
Function,
ObjectEntries,
Uint32Array,
} = window.__bootstrap.primordials;
const { pathFromURL } = window.__bootstrap.util;
const build = window.__bootstrap.build.build;
function chmodSync(path, mode) {
ops.op_chmod_sync(pathFromURL(path), mode);
}
async function chmod(path, mode) {
await core.opAsync("op_chmod_async", pathFromURL(path), mode);
}
function chownSync(
path,
uid,
gid,
) {
ops.op_chown_sync(pathFromURL(path), uid, gid);
}
async function chown(
path,
uid,
gid,
) {
await core.opAsync(
"op_chown_async",
pathFromURL(path),
uid,
gid,
);
}
function copyFileSync(
fromPath,
toPath,
) {
ops.op_copy_file_sync(
pathFromURL(fromPath),
pathFromURL(toPath),
);
}
async function copyFile(
fromPath,
toPath,
) {
await core.opAsync(
"op_copy_file_async",
pathFromURL(fromPath),
pathFromURL(toPath),
);
}
function cwd() {
return ops.op_cwd();
}
function chdir(directory) {
ops.op_chdir(pathFromURL(directory));
}
function makeTempDirSync(options = {}) {
return ops.op_make_temp_dir_sync(options);
}
function makeTempDir(options = {}) {
return core.opAsync("op_make_temp_dir_async", options);
}
function makeTempFileSync(options = {}) {
return ops.op_make_temp_file_sync(options);
}
function makeTempFile(options = {}) {
return core.opAsync("op_make_temp_file_async", options);
}
function mkdirArgs(path, options) {
const args = { path: pathFromURL(path), recursive: false };
if (options != null) {
if (typeof options.recursive == "boolean") {
args.recursive = options.recursive;
}
if (options.mode) {
args.mode = options.mode;
}
}
return args;
}
function mkdirSync(path, options) {
ops.op_mkdir_sync(mkdirArgs(path, options));
}
async function mkdir(
path,
options,
) {
await core.opAsync("op_mkdir_async", mkdirArgs(path, options));
}
function readDirSync(path) {
return ops.op_read_dir_sync(pathFromURL(path))[
SymbolIterator
]();
}
function readDir(path) {
const array = core.opAsync(
"op_read_dir_async",
pathFromURL(path),
);
return {
async *[SymbolAsyncIterator]() {
yield* await array;
},
};
}
function readLinkSync(path) {
return ops.op_read_link_sync(pathFromURL(path));
}
function readLink(path) {
return core.opAsync("op_read_link_async", pathFromURL(path));
}
function realPathSync(path) {
return ops.op_realpath_sync(pathFromURL(path));
}
function realPath(path) {
return core.opAsync("op_realpath_async", pathFromURL(path));
}
function removeSync(
path,
options = {},
) {
ops.op_remove_sync(
pathFromURL(path),
!!options.recursive,
);
}
async function remove(
path,
options = {},
) {
await core.opAsync(
"op_remove_async",
pathFromURL(path),
!!options.recursive,
);
}
function renameSync(oldpath, newpath) {
ops.op_rename_sync(
pathFromURL(oldpath),
pathFromURL(newpath),
);
}
async function rename(oldpath, newpath) {
await core.opAsync(
"op_rename_async",
pathFromURL(oldpath),
pathFromURL(newpath),
);
}
// Extract the FsStat object from the encoded buffer.
// See `runtime/ops/fs.rs` for the encoder.
//
// This is not a general purpose decoder. There are 4 types:
//
// 1. date
// offset += 4
// 1/0 | extra padding | high u32 | low u32
// if date[0] == 1, new Date(u64) else null
//
// 2. bool
// offset += 2
// 1/0 | extra padding
//
// 3. u64
// offset += 2
// high u32 | low u32
//
// 4. ?u64 converts a zero u64 value to JS null on Windows.
function createByteStruct(types) {
// types can be "date", "bool" or "u64".
// `?` prefix means optional on windows.
let offset = 0;
let str =
'const unix = Deno.build.os === "darwin" || Deno.build.os === "linux"; return {';
const typeEntries = ObjectEntries(types);
for (let i = 0; i < typeEntries.length; ++i) {
let [name, type] = typeEntries[i];
const optional = type.startsWith("?");
if (optional) type = type.slice(1);
if (type == "u64") {
if (!optional) {
str += `${name}: view[${offset}] + view[${offset + 1}] * 2**32,`;
} else {
str += `${name}: (unix ? (view[${offset}] + view[${
offset + 1
}] * 2**32) : (view[${offset}] + view[${
offset + 1
}] * 2**32) || null),`;
}
} else if (type == "date") {
str += `${name}: view[${offset}] === 0 ? null : new Date(view[${
offset + 2
}] + view[${offset + 3}] * 2**32),`;
offset += 2;
} else {
str += `${name}: !!(view[${offset}] + view[${offset + 1}] * 2**32),`;
}
offset += 2;
}
str += "};";
// ...so you don't like eval huh? don't worry, it only executes during snapshot :)
return [new Function("view", str), new Uint32Array(offset)];
}
const [statStruct, statBuf] = createByteStruct({
isFile: "bool",
isDirectory: "bool",
isSymlink: "bool",
size: "u64",
mtime: "date",
atime: "date",
birthtime: "date",
dev: "?u64",
ino: "?u64",
mode: "?u64",
nlink: "?u64",
uid: "?u64",
gid: "?u64",
rdev: "?u64",
blksize: "?u64",
blocks: "?u64",
});
function parseFileInfo(response) {
const unix = build.os === "darwin" || build.os === "linux";
return {
isFile: response.isFile,
isDirectory: response.isDirectory,
isSymlink: response.isSymlink,
size: response.size,
mtime: response.mtimeSet !== null ? new Date(response.mtime) : null,
atime: response.atimeSet !== null ? new Date(response.atime) : null,
birthtime: response.birthtimeSet !== null
? new Date(response.birthtime)
: null,
// Only non-null if on Unix
dev: unix ? response.dev : null,
ino: unix ? response.ino : null,
mode: unix ? response.mode : null,
nlink: unix ? response.nlink : null,
uid: unix ? response.uid : null,
gid: unix ? response.gid : null,
rdev: unix ? response.rdev : null,
blksize: unix ? response.blksize : null,
blocks: unix ? response.blocks : null,
};
}
function fstatSync(rid) {
ops.op_fstat_sync(rid, statBuf);
return statStruct(statBuf);
}
async function fstat(rid) {
return parseFileInfo(await core.opAsync("op_fstat_async", rid));
}
async function lstat(path) {
const res = await core.opAsync("op_stat_async", {
path: pathFromURL(path),
lstat: true,
});
return parseFileInfo(res);
}
function lstatSync(path) {
ops.op_stat_sync(
pathFromURL(path),
true,
statBuf,
);
return statStruct(statBuf);
}
async function stat(path) {
const res = await core.opAsync("op_stat_async", {
path: pathFromURL(path),
lstat: false,
});
return parseFileInfo(res);
}
function statSync(path) {
ops.op_stat_sync(
pathFromURL(path),
false,
statBuf,
);
return statStruct(statBuf);
}
function coerceLen(len) {
if (len == null || len < 0) {
return 0;
}
return len;
}
function ftruncateSync(rid, len) {
ops.op_ftruncate_sync(rid, coerceLen(len));
}
async function ftruncate(rid, len) {
await core.opAsync("op_ftruncate_async", rid, coerceLen(len));
}
function truncateSync(path, len) {
ops.op_truncate_sync(path, coerceLen(len));
}
async function truncate(path, len) {
await core.opAsync("op_truncate_async", path, coerceLen(len));
}
function umask(mask) {
return ops.op_umask(mask);
}
function linkSync(oldpath, newpath) {
ops.op_link_sync(oldpath, newpath);
}
async function link(oldpath, newpath) {
await core.opAsync("op_link_async", oldpath, newpath);
}
function toUnixTimeFromEpoch(value) {
if (ObjectPrototypeIsPrototypeOf(DatePrototype, value)) {
const time = value.valueOf();
const seconds = MathTrunc(time / 1e3);
const nanoseconds = MathTrunc(time - (seconds * 1e3)) * 1e6;
return [
seconds,
nanoseconds,
];
}
const seconds = value;
const nanoseconds = 0;
return [
seconds,
nanoseconds,
];
}
function futimeSync(
rid,
atime,
mtime,
) {
const [atimeSec, atimeNsec] = toUnixTimeFromEpoch(atime);
const [mtimeSec, mtimeNsec] = toUnixTimeFromEpoch(mtime);
ops.op_futime_sync(rid, atimeSec, atimeNsec, mtimeSec, mtimeNsec);
}
async function futime(
rid,
atime,
mtime,
) {
const [atimeSec, atimeNsec] = toUnixTimeFromEpoch(atime);
const [mtimeSec, mtimeNsec] = toUnixTimeFromEpoch(mtime);
await core.opAsync(
"op_futime_async",
rid,
atimeSec,
atimeNsec,
mtimeSec,
mtimeNsec,
);
}
function utimeSync(
path,
atime,
mtime,
) {
const [atimeSec, atimeNsec] = toUnixTimeFromEpoch(atime);
const [mtimeSec, mtimeNsec] = toUnixTimeFromEpoch(mtime);
ops.op_utime_sync(
pathFromURL(path),
atimeSec,
atimeNsec,
mtimeSec,
mtimeNsec,
);
}
async function utime(
path,
atime,
mtime,
) {
const [atimeSec, atimeNsec] = toUnixTimeFromEpoch(atime);
const [mtimeSec, mtimeNsec] = toUnixTimeFromEpoch(mtime);
await core.opAsync(
"op_utime_async",
pathFromURL(path),
atimeSec,
atimeNsec,
mtimeSec,
mtimeNsec,
);
}
function symlinkSync(
oldpath,
newpath,
options,
) {
ops.op_symlink_sync(
pathFromURL(oldpath),
pathFromURL(newpath),
options?.type,
);
}
async function symlink(
oldpath,
newpath,
options,
) {
await core.opAsync(
"op_symlink_async",
pathFromURL(oldpath),
pathFromURL(newpath),
options?.type,
);
}
function fdatasyncSync(rid) {
ops.op_fdatasync_sync(rid);
}
async function fdatasync(rid) {
await core.opAsync("op_fdatasync_async", rid);
}
function fsyncSync(rid) {
ops.op_fsync_sync(rid);
}
async function fsync(rid) {
await core.opAsync("op_fsync_async", rid);
}
function flockSync(rid, exclusive) {
ops.op_flock_sync(rid, exclusive === true);
}
async function flock(rid, exclusive) {
await core.opAsync("op_flock_async", rid, exclusive === true);
}
function funlockSync(rid) {
ops.op_funlock_sync(rid);
}
async function funlock(rid) {
await core.opAsync("op_funlock_async", rid);
}
window.__bootstrap.fs = {
cwd,
chdir,
chmodSync,
chmod,
chown,
chownSync,
copyFile,
copyFileSync,
makeTempFile,
makeTempDir,
makeTempFileSync,
makeTempDirSync,
mkdir,
mkdirSync,
readDir,
readDirSync,
readLinkSync,
readLink,
realPathSync,
realPath,
remove,
removeSync,
renameSync,
rename,
lstat,
lstatSync,
stat,
statSync,
ftruncate,
ftruncateSync,
truncate,
truncateSync,
umask,
link,
linkSync,
fstatSync,
fstat,
futime,
futimeSync,
utime,
utimeSync,
symlink,
symlinkSync,
fdatasync,
fdatasyncSync,
fsync,
fsyncSync,
flock,
flockSync,
funlock,
funlockSync,
};
})(this);