diff options
author | 2023-05-31 22:20:50 -0300 | |
---|---|---|
committer | 2023-05-31 18:20:50 -0700 | |
commit | e24d579a329d91350623e82b3ec5de79c7160a78 (patch) | |
tree | cece32694b749c12da2da5b136f18ad109bbb6c6 | |
parent | a7c7128cd7907b0f288e4488f60e289efa16d30c (diff) | |
download | bun-e24d579a329d91350623e82b3ec5de79c7160a78.tar.gz bun-e24d579a329d91350623e82b3ec5de79c7160a78.tar.zst bun-e24d579a329d91350623e82b3ec5de79c7160a78.zip |
isolated version of Path compatible with nodejs (#3143)
-rw-r--r-- | src/bun.js/node/types.zig | 7 | ||||
-rw-r--r-- | src/fs.zig | 114 |
2 files changed, 87 insertions, 34 deletions
diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index da0459866..f090b3a12 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -1775,7 +1775,7 @@ pub const Path = struct { var path_slice: JSC.ZigString.Slice = args_ptr[0].toSlice(globalThis, heap_allocator); defer path_slice.deinit(); var path = path_slice.slice(); - var path_name = Fs.PathName.init(path); + var path_name = Fs.NodeJSPathName.init(path); var dir = JSC.ZigString.init(path_name.dir); const is_absolute = (isWindows and isZigStringAbsoluteWindows(dir)) or (!isWindows and path.len > 0 and path[0] == '/'); @@ -1788,9 +1788,8 @@ pub const Path = struct { dir = root; } } - // we use filename as base, and base as name because node.js/internals compatibilty - var base = JSC.ZigString.init(path_name.filename); - var name_ = JSC.ZigString.init(path_name.base); + var base = JSC.ZigString.init(path_name.base); + var name_ = JSC.ZigString.init(path_name.filename); var ext = JSC.ZigString.init(path_name.ext); dir.setOutputEncoding(); root.setOutputEncoding(); diff --git a/src/fs.zig b/src/fs.zig index e22b6b0b5..c0f3cd9dd 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -1190,6 +1190,78 @@ pub const FileSystem = struct { pub const Directory = struct { path: Path, contents: []string }; pub const File = struct { path: Path, contents: string }; +pub const NodeJSPathName = struct { + base: string, + dir: string, + /// includes the leading . + ext: string, + filename: string, + + pub fn init(_path: string) NodeJSPathName { + var path = _path; + var base = path; + // ext must be empty if not detected + var ext: string = ""; + var dir = path; + var is_absolute = true; + var _i = strings.lastIndexOfChar(path, '/'); + var first = true; + while (_i) |i| { + + // Stop if we found a non-trailing slash + if (i + 1 != path.len) { + base = path[i + 1 ..]; + dir = path[0..i]; + is_absolute = false; + break; + } + + // If the path starts with a slash and it's the only slash, it's absolute + if (i == 0 and first) { + base = path[1..]; + dir = &([_]u8{}); + break; + } + + first = false; + // Ignore trailing slashes + + path = path[0..i]; + + _i = strings.lastIndexOfChar(path, '/'); + } + + // clean trailing slashs + if (base.len > 1 and base[base.len - 1] == '/') { + base = base[0 .. base.len - 1]; + } + + // filename is base without extension + var filename = base; + + // if only one character ext = "" even if filename it's "." + if (filename.len > 1) { + // Strip off the extension + var _dot = strings.lastIndexOfChar(filename, '.'); + if (_dot) |dot| { + ext = filename[dot..]; + filename = filename[0..dot]; + } + } + + if (is_absolute) { + dir = &([_]u8{}); + } + + return NodeJSPathName{ + .dir = dir, + .base = base, + .ext = ext, + .filename = filename, + }; + } +}; + pub const PathName = struct { base: string, dir: string, @@ -1254,14 +1326,12 @@ pub const PathName = struct { pub fn init(_path: string) PathName { var path = _path; var base = path; - // ext must be empty if not detected - var ext: string = ""; + var ext = path; var dir = path; var is_absolute = true; + var _i = strings.lastIndexOfChar(path, '/'); - var first = true; while (_i) |i| { - // Stop if we found a non-trailing slash if (i + 1 != path.len) { base = path[i + 1 ..]; @@ -1270,48 +1340,32 @@ pub const PathName = struct { break; } - // If the path starts with a slash and it's the only slash, it's absolute - if (i == 0 and first) { - base = path[1..]; - dir = &([_]u8{}); - break; - } - - first = false; // Ignore trailing slashes - path = path[0..i]; _i = strings.lastIndexOfChar(path, '/'); } - // clean trailing slashs - if (base.len > 1 and base[base.len - 1] == '/') { - base = base[0 .. base.len - 1]; - } - - // filename is base with extension - var filename = base; - - // if only one character ext = "" even if base it's "." - if (base.len > 1) { - // Strip off the extension - var _dot = strings.lastIndexOfChar(base, '.'); - if (_dot) |dot| { - ext = base[dot..]; - base = base[0..dot]; - } + // Strip off the extension + var _dot = strings.lastIndexOfChar(base, '.'); + if (_dot) |dot| { + ext = base[dot..]; + base = base[0..dot]; } if (is_absolute) { dir = &([_]u8{}); } + if (base.len > 1 and base[base.len - 1] == '/') { + base = base[0 .. base.len - 1]; + } + return PathName{ .dir = dir, .base = base, .ext = ext, - .filename = filename, + .filename = if (dir.len > 0) _path[dir.len + 1 ..] else _path, }; } }; |