Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/wasm-rquickjs/skeleton/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod http {
mod eventemitter;
mod ieee754;
mod internal;
mod path;
mod process;
mod stream;
mod string_decoder;
Expand Down Expand Up @@ -56,6 +57,9 @@ pub fn add_module_resolvers(
.with_module("__wasm_rquickjs_builtin/process_native")
.with_module("node:process")
.with_module("process")
.with_module("__wasm_rquickjs_builtin/path_native")
.with_module("node:path")
.with_module("path")
.with_module("__wasm_rquickjs_builtin/url_native")
.with_module("__wasm_rquickjs_builtin/url")
.with_module("node:events")
Expand Down Expand Up @@ -99,6 +103,7 @@ pub fn module_loader() -> (
"__wasm_rquickjs_builtin/process_native",
process::js_native_module,
)
.with_module("__wasm_rquickjs_builtin/path_native", path::js_native_module)
.with_module("__wasm_rquickjs_builtin/url_native", url::js_native_module)
.with_module(
"__wasm_rquickjs_builtin/web_crypto_native",
Expand All @@ -122,6 +127,8 @@ pub fn module_loader() -> (
.with_module("fs", fs::FS_JS)
.with_module("node:process", process::PROCESS_JS)
.with_module("process", process::PROCESS_JS)
.with_module("node:path", path::PATH_JS)
.with_module("path", path::PATH_JS)
.with_module("__wasm_rquickjs_builtin/url", url::URL_JS)
.with_module("node:events", eventemitter::EVENTEMITTER_JS)
.with_module("events", eventemitter::EVENTEMITTER_JS)
Expand Down
112 changes: 112 additions & 0 deletions crates/wasm-rquickjs/skeleton/src/builtin/path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// node:path implementation (POSIX only)
// Provides utilities for working with file and directory paths

import {
basename,
dirname,
extname,
is_absolute as isAbsolute,
join as joinNative,
normalize,
relative,
resolve as resolveNative,
parse as parseNative,
format as formatNative,
ParsedPath,
} from "__wasm_rquickjs_builtin/path_native";

// Match a path against a glob pattern
function matchesGlob(path, pattern) {
if (typeof path !== 'string' || typeof pattern !== 'string') {
throw new TypeError('Both path and pattern must be strings');
}

// Simple glob matching: only supports * and ? wildcards
const regexStr = pattern
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape regex special chars
.replace(/\*/g, '.*') // * matches any sequence
.replace(/\?/g, '.'); // ? matches single char

const regex = new RegExp(`^${regexStr}$`);
return regex.test(path);
}

// Convert to namespaced path (no-op on POSIX)
function toNamespacedPath(path) {
if (typeof path !== 'string') {
return path;
}
return path;
}

function join(...paths) {
return joinNative(paths);
}

function resolve(...paths) {
return resolveNative(paths);
}

function parse(path) {
return parseNative(path);
}

function format(pathObject) {
if (pathObject === null || typeof pathObject !== 'object') {
throw new TypeError('The "pathObject" argument must be of type Object. Received ' + pathObject);
}

// Check if it is a ParsedPath using duck typing as we don't have the class constructor easily accessible
// If we passed a ParsedPath instance from parseNative, we can probably pass it back.
// However, to be safe and support plain objects, we create a new ParsedPath instance.

const root = pathObject.root !== undefined ? String(pathObject.root) : "";
const dir = pathObject.dir !== undefined ? String(pathObject.dir) : "";
const base = pathObject.base !== undefined ? String(pathObject.base) : "";
const ext = pathObject.ext !== undefined ? String(pathObject.ext) : "";
const name = pathObject.name !== undefined ? String(pathObject.name) : "";

const pp = new ParsedPath(root, dir, base, ext, name);

return formatNative(pp);
}

const sep = '/';
const delimiter = ':';

// POSIX path object with all methods
const posix = {
sep,
delimiter,
basename,
dirname,
extname,
isAbsolute,
join,
normalize,
relative,
resolve,
parse,
format,
matchesGlob,
toNamespacedPath,
};

// Export all path functions
export {
sep,
delimiter,
basename,
dirname,
extname,
isAbsolute,
join,
normalize,
relative,
resolve,
parse,
format,
matchesGlob,
toNamespacedPath,
posix,
};
Loading
Loading