// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. const core = globalThis.Deno.core; const ops = core.ops; const primordials = globalThis.__bootstrap.primordials; const { Date, DatePrototype, MathTrunc, ObjectPrototypeIsPrototypeOf, SymbolAsyncIterator, SymbolIterator, Function, ObjectEntries, Uint32Array, } = primordials; import { pathFromURL } from "internal:runtime/js/06_util.js"; import { build } from "internal:runtime/js/01_build.js"; 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 { 0: name, 1: 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 { 0: statStruct, 1: 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 { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); ops.op_futime_sync(rid, atimeSec, atimeNsec, mtimeSec, mtimeNsec); } async function futime( rid, atime, mtime, ) { const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); await core.opAsync( "op_futime_async", rid, atimeSec, atimeNsec, mtimeSec, mtimeNsec, ); } function utimeSync( path, atime, mtime, ) { const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); const { 0: mtimeSec, 1: mtimeNsec } = toUnixTimeFromEpoch(mtime); ops.op_utime_sync( pathFromURL(path), atimeSec, atimeNsec, mtimeSec, mtimeNsec, ); } async function utime( path, atime, mtime, ) { const { 0: atimeSec, 1: atimeNsec } = toUnixTimeFromEpoch(atime); const { 0: mtimeSec, 1: 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); } export { chdir, chmod, chmodSync, chown, chownSync, copyFile, copyFileSync, cwd, fdatasync, fdatasyncSync, flock, flockSync, fstat, fstatSync, fsync, fsyncSync, ftruncate, ftruncateSync, funlock, funlockSync, futime, futimeSync, link, linkSync, lstat, lstatSync, makeTempDir, makeTempDirSync, makeTempFile, makeTempFileSync, mkdir, mkdirSync, readDir, readDirSync, readLink, readLinkSync, realPath, realPathSync, remove, removeSync, rename, renameSync, stat, statSync, symlink, symlinkSync, truncate, truncateSync, umask, utime, utimeSync, };