@zokugun/fs-path 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +153 -0
  3. package/lib/cjs/absolute.cjs +6 -0
  4. package/lib/cjs/absolute.d.cts +3 -0
  5. package/lib/cjs/dir.cjs +6 -0
  6. package/lib/cjs/dir.d.cts +3 -0
  7. package/lib/cjs/index.cjs +50 -0
  8. package/lib/cjs/index.d.cts +47 -0
  9. package/lib/cjs/is-in-dir.cjs +18 -0
  10. package/lib/cjs/is-in-dir.d.cts +3 -0
  11. package/lib/cjs/is-in-dirs.cjs +38 -0
  12. package/lib/cjs/is-in-dirs.d.cts +3 -0
  13. package/lib/cjs/is-safe-path.cjs +42 -0
  14. package/lib/cjs/is-safe-path.d.cts +8 -0
  15. package/lib/cjs/is-safe-segment.cjs +27 -0
  16. package/lib/cjs/is-safe-segment.d.cts +4 -0
  17. package/lib/cjs/join.cjs +14 -0
  18. package/lib/cjs/join.d.cts +3 -0
  19. package/lib/cjs/parent.cjs +14 -0
  20. package/lib/cjs/parent.d.cts +3 -0
  21. package/lib/cjs/platform.cjs +67 -0
  22. package/lib/cjs/platform.d.cts +2 -0
  23. package/lib/cjs/resolve.cjs +42 -0
  24. package/lib/cjs/resolve.d.cts +3 -0
  25. package/lib/cjs/sanitize.cjs +62 -0
  26. package/lib/cjs/sanitize.d.cts +10 -0
  27. package/lib/cjs/types.cjs +2 -0
  28. package/lib/cjs/types.d.cts +34 -0
  29. package/lib/cjs/untildify.cjs +25 -0
  30. package/lib/cjs/untildify.d.cts +3 -0
  31. package/lib/cjs/utils/get-home.cjs +12 -0
  32. package/lib/cjs/utils/get-home.d.cts +1 -0
  33. package/lib/cjs/utils/get-user-home.cjs +18 -0
  34. package/lib/cjs/utils/get-user-home.d.cts +1 -0
  35. package/lib/esm/absolute.d.mts +3 -0
  36. package/lib/esm/absolute.mjs +3 -0
  37. package/lib/esm/dir.d.mts +3 -0
  38. package/lib/esm/dir.mjs +3 -0
  39. package/lib/esm/index.d.mts +47 -0
  40. package/lib/esm/index.mjs +29 -0
  41. package/lib/esm/is-in-dir.d.mts +3 -0
  42. package/lib/esm/is-in-dir.mjs +15 -0
  43. package/lib/esm/is-in-dirs.d.mts +3 -0
  44. package/lib/esm/is-in-dirs.mjs +35 -0
  45. package/lib/esm/is-safe-path.d.mts +8 -0
  46. package/lib/esm/is-safe-path.mjs +36 -0
  47. package/lib/esm/is-safe-segment.d.mts +4 -0
  48. package/lib/esm/is-safe-segment.mjs +21 -0
  49. package/lib/esm/join.d.mts +3 -0
  50. package/lib/esm/join.mjs +11 -0
  51. package/lib/esm/parent.d.mts +3 -0
  52. package/lib/esm/parent.mjs +11 -0
  53. package/lib/esm/platform.d.mts +2 -0
  54. package/lib/esm/platform.mjs +61 -0
  55. package/lib/esm/resolve.d.mts +3 -0
  56. package/lib/esm/resolve.mjs +36 -0
  57. package/lib/esm/sanitize.d.mts +10 -0
  58. package/lib/esm/sanitize.mjs +56 -0
  59. package/lib/esm/types.d.mts +34 -0
  60. package/lib/esm/types.mjs +1 -0
  61. package/lib/esm/untildify.d.mts +3 -0
  62. package/lib/esm/untildify.mjs +22 -0
  63. package/lib/esm/utils/get-home.d.mts +1 -0
  64. package/lib/esm/utils/get-home.mjs +6 -0
  65. package/lib/esm/utils/get-user-home.d.mts +1 -0
  66. package/lib/esm/utils/get-user-home.mjs +12 -0
  67. package/package.json +83 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2026-present Baptiste Augrain
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,153 @@
1
+ [@zokugun/fs-path](https://github.com/zokugun/node-fs-path)
2
+ ===========================================================
3
+
4
+ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
5
+ [![NPM Version](https://img.shields.io/npm/v/@zokugun/fs-path.svg?colorB=green)](https://www.npmjs.com/package/@zokugun/fs-path)
6
+ [![Donation](https://img.shields.io/badge/donate-ko--fi-green)](https://ko-fi.com/daiyam)
7
+ [![Donation](https://img.shields.io/badge/donate-liberapay-green)](https://liberapay.com/daiyam/donate)
8
+ [![Donation](https://img.shields.io/badge/donate-paypal-green)](https://paypal.me/daiyam99)
9
+
10
+ > Compact set of path utilities that complement Node's builtin `path` module.
11
+
12
+ Features
13
+ --------
14
+
15
+ - Tilde expansion: expand `~` to the current user's home directory with `untildify`.
16
+ - Safe joining and resolving: helpers that avoid common pitfalls when composing paths.
17
+ - Useful utilities: retrieve parent paths, absolute normalization, and platform-aware helpers.
18
+ - Small package with ESM and CJS builds
19
+
20
+ Installation
21
+ ------------
22
+
23
+ ```bash
24
+ npm add @zokugun/fs-path
25
+ ```
26
+
27
+ Quick Start
28
+ -----------
29
+
30
+ ```ts
31
+ import { isInDir, join, resolve } from '@zokugun/fs-path'
32
+
33
+ const configDir = resolve('~/.config/myapp')
34
+ const dataFile = join(configDir, 'data.json')
35
+
36
+ console.log('Config dir:', configDir)
37
+ console.log('Data file:', dataFile)
38
+
39
+ console.log('Is data file inside config dir?', isInDir(dataFile, configDir))
40
+ ```
41
+
42
+ This example expands the current user's home directory, joins paths safely, and prints the resolved absolute path for `configDir`.
43
+
44
+ API reference
45
+ -------------
46
+
47
+ - `absolute(...paths: string[]): string`: Return an absolute path for the given segments. Uses the current platform resolution behavior.
48
+ - `dir(path: string): string`: Return the directory portion of `path` (empty string when the result is `.`).
49
+ - `extension(path: string): string`: Return the file extension (same as `path.extname`).
50
+ - `isAbsolute(path: string): boolean`: Return `true` when `path` is absolute for the current platform.
51
+ - `isInDir(path: string, parent: string): boolean`: Return `true` when `path` is equal to or contained within `parent`.
52
+ - `isInDirs(path: string, parents: string[]): boolean`: Return `true` when `path` is equal to or contained within in one of the `parents`.
53
+ - `isSafePath(path: string, options?): boolean`: Return `true` when `path` is considered safe for use (guards against suspicious segments such as `..` when appropriate for the platform).
54
+ - `isSafeSegment(segment: string, target?: Target | 'auto'): boolean`: Return `true` when a single path segment is safe (doesn't contain path separators or traversal sequences).
55
+ - `join(...paths: string[]): string`: Join path segments; returns empty string when the join result is `.`.
56
+ - `leaf(path: string, suffix?: string): string`: Return the basename of `path` (alias of `path.basename`).
57
+ - `matchesGlob?(path: string, pattern: string): boolean`: Optional platform-provided glob matcher when available.
58
+ - `normalize(path: string): string`: Normalize the path (same as `path.normalize`).
59
+ - `parent(path: string): string`: Return the parent directory of `file` (empty string when the result is `.`).
60
+ - `relative(from: string, to: string): string`: Compute the relative path from `from` to `to`.
61
+ - `resolve(...paths: string[]): string`: Resolve path segments to an absolute path. Supports tilde expansion:
62
+ - `~` expands to the current user's home directory.
63
+ - `~username/...` attempts to expand to that user's home directory when available.
64
+ - `sanitize(path: string, options?): Result<string>`: Return a sanitized form of `path` with unsafe segments normalized.
65
+ - `untildify(path: string): string`: Expand a leading `~` or `~username` to the home directory, or return `path` unchanged.
66
+ - `delimiter`: Platform-specific character (`;`/`:`).
67
+ - `separator`: Platform-specific character (`\`/`/`).
68
+
69
+ ```ts
70
+ export type PlatformPath = {
71
+ readonly delimiter: ';' | ':';
72
+ readonly separator: '\\' | '/';
73
+ readonly posix: PlatformPath;
74
+ readonly win32: PlatformPath;
75
+ absolute: (...paths: string[]) => string;
76
+ dir: (path: string) => string;
77
+ extension: (path: string) => string;
78
+ isAbsolute: (path: string) => boolean;
79
+ isInDir(path: string, parent: string): boolean;
80
+ isInDirs(path: string, parents: string[]): boolean;
81
+ isSafePath: (path: string, options?: {
82
+ parent?: string | null;
83
+ parents?: string | string[] | null;
84
+ target?: Target | 'auto';
85
+ }) => boolean;
86
+ isSafeSegment: (segment: string, target?: Target | 'auto') => boolean;
87
+ join: (...paths: string[]) => string;
88
+ leaf: (path: string, suffix?: string) => string;
89
+ matchesGlob?: (path: string, pattern: string) => boolean;
90
+ normalize: (path: string) => string;
91
+ parent: (path: string) => string;
92
+ relative: (from: string, to: string) => string;
93
+ resolve: (...paths: string[]) => string;
94
+ sanitize(path: string, options?: {
95
+ parent?: string | null;
96
+ parents?: string | string[] | null;
97
+ replacement?: string | null;
98
+ target?: Target | 'auto'
99
+ }) => Result<string>
100
+ untildify: (path: string) => string;
101
+ };
102
+ ```
103
+
104
+ Comparison with Node's `path`
105
+ -----------------------------
106
+
107
+ This library intentionally mirrors many of Node's `path` APIs but provides small ergonomic differences and extra features where useful:
108
+
109
+ - `absolute(...paths)`: resolves using the runtime platform and always returns a normalized absolute path.
110
+ - `dir(path)`: returns `path.parse(path).dir` (similar to `path.dirname`, kept for API symmetry).
111
+ - `extension(path)`: alias of `path.extname`.
112
+ - `join(...paths)`: wraps `path.join`. Returns `''` instead of `.` when the joined result is the current directory.
113
+ - `isAbsolute(path)`, `normalize(path)`, `relative(from, to)`: direct mappings to `path.isAbsolute`, `path.normalize`, and `path.relative` respectively.
114
+ - `leaf(path, suffix?)`: alias of `path.basename`.
115
+ - `parent(file)`: wraps `path.dirname`. Returns `''` instead of `.` for consistency with `join`.
116
+ - `resolve(...paths)`: wraps `path.resolve` but adds tilde expansion (`~` and `~username`) before resolving.
117
+ - `untildify(path)`: purely handles `~` expansion; no direct equivalent in Node core.
118
+ - `delimiter`: same value as `path.delimiter` on the current platform.
119
+ - `separator`: same value as `path.sep` on the current platform.
120
+
121
+ Contributions
122
+ -------------
123
+
124
+ Contributions are most welcome. Please:
125
+ - Open issues and feature requests under the repository discussions.
126
+ - Follow the [`CONTRIBUTING.md`](./CONTRIBUTING.md).
127
+
128
+ Donations
129
+ ---------
130
+
131
+ Support this project by becoming a financial contributor.
132
+
133
+ <table>
134
+ <tr>
135
+ <td><img src="https://raw.githubusercontent.com/daiyam/assets/master/icons/256/funding_kofi.png" alt="Ko-fi" width="80px" height="80px"></td>
136
+ <td><a href="https://ko-fi.com/daiyam" target="_blank">ko-fi.com/daiyam</a></td>
137
+ </tr>
138
+ <tr>
139
+ <td><img src="https://raw.githubusercontent.com/daiyam/assets/master/icons/256/funding_liberapay.png" alt="Liberapay" width="80px" height="80px"></td>
140
+ <td><a href="https://liberapay.com/daiyam/donate" target="_blank">liberapay.com/daiyam/donate</a></td>
141
+ </tr>
142
+ <tr>
143
+ <td><img src="https://raw.githubusercontent.com/daiyam/assets/master/icons/256/funding_paypal.png" alt="PayPal" width="80px" height="80px"></td>
144
+ <td><a href="https://paypal.me/daiyam99" target="_blank">paypal.me/daiyam99</a></td>
145
+ </tr>
146
+ </table>
147
+
148
+ License
149
+ -------
150
+
151
+ Copyright &copy; 2026-present Baptiste Augrain
152
+
153
+ Licensed under the [MIT license](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.absolute = absolute;
4
+ function absolute(nodePath, localPath) {
5
+ return (...paths) => nodePath.resolve(localPath.resolve(...paths));
6
+ }
@@ -0,0 +1,3 @@
1
+ import type path from 'node:path';
2
+ import { type PlatformPath } from './types.cjs';
3
+ export declare function absolute(nodePath: path.PlatformPath, localPath: PlatformPath): (...paths: string[]) => string;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dir = dir;
4
+ function dir(nodePath, _localPath) {
5
+ return (path) => nodePath.parse(path).dir;
6
+ }
@@ -0,0 +1,3 @@
1
+ import type path from 'node:path';
2
+ import { type PlatformPath } from './types.cjs';
3
+ export declare function dir(nodePath: path.PlatformPath, _localPath: PlatformPath): (path: string) => string;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.win32 = exports.untildify = exports.separator = exports.sanitize = exports.resolve = exports.relative = exports.posix = exports.isSafeSegment = exports.isSafePath = exports.isInDirs = exports.isInDir = exports.parent = exports.normalize = exports.matchesGlob = exports.leaf = exports.join = exports.isAbsolute = exports.extension = exports.delimiter = exports.absolute = void 0;
4
+ const platform_js_1 = require("./platform.cjs");
5
+ const { absolute, delimiter, extension, isAbsolute, join, leaf, matchesGlob, normalize, parent, isInDir, isInDirs, isSafePath, isSafeSegment, posix, relative, resolve, sanitize, separator, untildify, win32, } = platform_js_1.DEFAULT_PLATFORM;
6
+ exports.absolute = absolute;
7
+ exports.delimiter = delimiter;
8
+ exports.extension = extension;
9
+ exports.isAbsolute = isAbsolute;
10
+ exports.join = join;
11
+ exports.leaf = leaf;
12
+ exports.matchesGlob = matchesGlob;
13
+ exports.normalize = normalize;
14
+ exports.parent = parent;
15
+ exports.isInDir = isInDir;
16
+ exports.isInDirs = isInDirs;
17
+ exports.isSafePath = isSafePath;
18
+ exports.isSafeSegment = isSafeSegment;
19
+ exports.posix = posix;
20
+ exports.relative = relative;
21
+ exports.resolve = resolve;
22
+ exports.sanitize = sanitize;
23
+ exports.separator = separator;
24
+ exports.untildify = untildify;
25
+ exports.win32 = win32;
26
+ /* eslint-enable unicorn/prefer-export-from */
27
+ // eslint-disable-next-line import/no-anonymous-default-export
28
+ exports.default = {
29
+ PlatformPath: undefined,
30
+ absolute,
31
+ delimiter,
32
+ extension,
33
+ isAbsolute,
34
+ join,
35
+ leaf,
36
+ matchesGlob,
37
+ normalize,
38
+ parent,
39
+ isInDir,
40
+ isInDirs,
41
+ isSafePath,
42
+ isSafeSegment,
43
+ posix,
44
+ relative,
45
+ resolve,
46
+ sanitize,
47
+ separator,
48
+ untildify,
49
+ win32,
50
+ };
@@ -0,0 +1,47 @@
1
+ import { type PlatformPath } from './types.cjs';
2
+ declare const absolute: (...paths: string[]) => string, delimiter: ";" | ":", extension: (path: string) => string, isAbsolute: (path: string) => boolean, join: (...paths: string[]) => string, leaf: (path: string, suffix?: string) => string, matchesGlob: ((path: string, pattern: string) => boolean) | undefined, normalize: (path: string) => string, parent: (file: string) => string, isInDir: (file: string, dir: string) => boolean, isInDirs: (file: string, directories: string[]) => boolean, isSafePath: (path: string, options?: {
3
+ parent?: string | null;
4
+ parents?: string | string[] | null;
5
+ target?: Target | "auto";
6
+ }) => boolean, isSafeSegment: (segment: string, target?: Target | "auto") => boolean, posix: PlatformPath, relative: (from: string, to: string) => string, resolve: (...paths: string[]) => string, sanitize: (path: string, options?: {
7
+ parent?: string | null;
8
+ parents?: string | string[] | null;
9
+ replacement?: string | null;
10
+ target?: Target | "auto";
11
+ }) => DResult<string>, separator: "\\" | "/", untildify: (path: string) => string, win32: PlatformPath;
12
+ export { type PlatformPath, absolute, delimiter, extension, isAbsolute, join, leaf, matchesGlob, normalize, parent, isInDir, isInDirs, isSafePath, isSafeSegment, posix, relative, resolve, sanitize, separator, untildify, win32, };
13
+ import { type Target } from "@zokugun/fs-path-sanitize";
14
+ import { type DResult } from "@zokugun/xtry/result";
15
+ declare const _default: {
16
+ PlatformPath: PlatformPath;
17
+ absolute: (...paths: string[]) => string;
18
+ delimiter: ";" | ":";
19
+ extension: (path: string) => string;
20
+ isAbsolute: (path: string) => boolean;
21
+ join: (...paths: string[]) => string;
22
+ leaf: (path: string, suffix?: string) => string;
23
+ matchesGlob: ((path: string, pattern: string) => boolean) | undefined;
24
+ normalize: (path: string) => string;
25
+ parent: (file: string) => string;
26
+ isInDir: (file: string, dir: string) => boolean;
27
+ isInDirs: (file: string, directories: string[]) => boolean;
28
+ isSafePath: (path: string, options?: {
29
+ parent?: string | null;
30
+ parents?: string | string[] | null;
31
+ target?: Target | "auto";
32
+ }) => boolean;
33
+ isSafeSegment: (segment: string, target?: Target | "auto") => boolean;
34
+ posix: PlatformPath;
35
+ relative: (from: string, to: string) => string;
36
+ resolve: (...paths: string[]) => string;
37
+ sanitize: (path: string, options?: {
38
+ parent?: string | null;
39
+ parents?: string | string[] | null;
40
+ replacement?: string | null;
41
+ target?: Target | "auto";
42
+ }) => DResult<string>;
43
+ separator: "\\" | "/";
44
+ untildify: (path: string) => string;
45
+ win32: PlatformPath;
46
+ };
47
+ export default _default;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isInDir = isInDir;
4
+ function isInDir(_nodePath, localPath) {
5
+ return (path, parent) => {
6
+ let resolvedPath = localPath.resolve(path);
7
+ let resolvedParent = localPath.resolve(parent);
8
+ if (localPath.separator === '\\') {
9
+ resolvedPath = resolvedPath.toLowerCase();
10
+ resolvedParent = resolvedParent.toLowerCase();
11
+ }
12
+ if (resolvedPath === resolvedParent) {
13
+ return true;
14
+ }
15
+ const suffixedParent = resolvedParent.endsWith(localPath.separator) ? resolvedParent : resolvedParent + localPath.separator;
16
+ return resolvedPath.startsWith(suffixedParent);
17
+ };
18
+ }
@@ -0,0 +1,3 @@
1
+ import type path from 'node:path';
2
+ import { type PlatformPath } from './types.cjs';
3
+ export declare function isInDir(_nodePath: path.PlatformPath, localPath: PlatformPath): (path: string, parent: string) => boolean;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isInDirs = isInDirs;
4
+ // eslint-disable-next-line unicorn/prevent-abbreviations
5
+ function isInDirs(_nodePath, localPath) {
6
+ if (localPath.separator === '\\') {
7
+ return (path, parents) => {
8
+ const resolvedPath = localPath.resolve(path).toLowerCase();
9
+ for (const parent of parents) {
10
+ const resolvedParent = localPath.resolve(parent).toLowerCase();
11
+ if (resolvedPath === resolvedParent) {
12
+ return true;
13
+ }
14
+ const suffixedParent = resolvedParent.endsWith(localPath.separator) ? resolvedParent : resolvedParent + localPath.separator;
15
+ if (resolvedPath.startsWith(suffixedParent)) {
16
+ return true;
17
+ }
18
+ }
19
+ return false;
20
+ };
21
+ }
22
+ else {
23
+ return (path, parents) => {
24
+ const resolvedPath = localPath.resolve(path);
25
+ for (const parent of parents) {
26
+ const resolvedParent = localPath.resolve(parent);
27
+ if (resolvedPath === resolvedParent) {
28
+ return true;
29
+ }
30
+ const suffixedParent = resolvedParent.endsWith(localPath.separator) ? resolvedParent : resolvedParent + localPath.separator;
31
+ if (resolvedPath.startsWith(suffixedParent)) {
32
+ return true;
33
+ }
34
+ }
35
+ return false;
36
+ };
37
+ }
38
+ }
@@ -0,0 +1,3 @@
1
+ import type path from 'node:path';
2
+ import { type PlatformPath } from './types.cjs';
3
+ export declare function isInDirs(_nodePath: path.PlatformPath, localPath: PlatformPath): (path: string, parents: string[]) => boolean;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isSafePath = isSafePath;
7
+ const node_os_1 = __importDefault(require("node:os"));
8
+ const fs_path_sanitize_1 = require("@zokugun/fs-path-sanitize");
9
+ const is_it_type_1 = require("@zokugun/is-it-type");
10
+ function isSafePath(_nodePath, localPath) {
11
+ let target;
12
+ if (localPath.separator === '\\') {
13
+ target = 'windows.safe';
14
+ }
15
+ else {
16
+ const system = node_os_1.default.platform();
17
+ target = system === 'darwin' ? 'macos.safe' : 'linux.safe';
18
+ }
19
+ const sanitizer = fs_path_sanitize_1.Sanitizer.getInstance(target);
20
+ return (path, options = {}) => {
21
+ let parents;
22
+ if ((0, is_it_type_1.isString)(options.parent)) {
23
+ parents = [options.parent];
24
+ }
25
+ if ((0, is_it_type_1.isString)(options.parents)) {
26
+ parents = [options.parents];
27
+ }
28
+ else if ((0, is_it_type_1.isArray)(options.parents)) {
29
+ parents = options.parents;
30
+ }
31
+ const safe = !options.target || options.target === 'auto' ? sanitizer.isSafePath(path) : (0, fs_path_sanitize_1.isSafePath)(path, target);
32
+ if (!safe) {
33
+ return false;
34
+ }
35
+ else if (parents) {
36
+ return localPath.isInDirs(path, parents);
37
+ }
38
+ else {
39
+ return true;
40
+ }
41
+ };
42
+ }
@@ -0,0 +1,8 @@
1
+ import type path from 'node:path';
2
+ import { type Target } from '@zokugun/fs-path-sanitize';
3
+ import { type PlatformPath } from './types.cjs';
4
+ export declare function isSafePath(_nodePath: path.PlatformPath, localPath: PlatformPath): (path: string, options?: {
5
+ parent?: string | null;
6
+ parents?: string | string[] | null;
7
+ target?: Target | 'auto';
8
+ }) => boolean;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isSafeSegment = isSafeSegment;
7
+ const node_os_1 = __importDefault(require("node:os"));
8
+ const fs_path_sanitize_1 = require("@zokugun/fs-path-sanitize");
9
+ function isSafeSegment(_nodePath, localPath) {
10
+ let target;
11
+ if (localPath.separator === '\\') {
12
+ target = 'windows.safe';
13
+ }
14
+ else {
15
+ const system = node_os_1.default.platform();
16
+ target = system === 'darwin' ? 'macos.safe' : 'linux.safe';
17
+ }
18
+ const sanitizer = fs_path_sanitize_1.Sanitizer.getInstance(target);
19
+ return (segment, target) => {
20
+ if (!target || target === 'auto') {
21
+ return sanitizer.isSafePath(segment);
22
+ }
23
+ else {
24
+ return (0, fs_path_sanitize_1.isSafeSegment)(segment, target);
25
+ }
26
+ };
27
+ }
@@ -0,0 +1,4 @@
1
+ import type path from 'node:path';
2
+ import { type Target } from '@zokugun/fs-path-sanitize';
3
+ import { type PlatformPath } from './types.cjs';
4
+ export declare function isSafeSegment(_nodePath: path.PlatformPath, localPath: PlatformPath): (segment: string, target?: Target | 'auto') => boolean;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.join = join;
4
+ function join(nodePath, _localPath) {
5
+ return (...paths) => {
6
+ const joined = nodePath.join(...paths);
7
+ if (joined === '.') {
8
+ return '';
9
+ }
10
+ else {
11
+ return joined;
12
+ }
13
+ };
14
+ }
@@ -0,0 +1,3 @@
1
+ import type path from 'path';
2
+ import { type PlatformPath } from './types.cjs';
3
+ export declare function join(nodePath: path.PlatformPath, _localPath: PlatformPath): (...paths: string[]) => string;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parent = parent;
4
+ function parent(nodePath, _localPath) {
5
+ return (file) => {
6
+ const parent = nodePath.dirname(file);
7
+ if (parent === '.') {
8
+ return '';
9
+ }
10
+ else {
11
+ return parent;
12
+ }
13
+ };
14
+ }
@@ -0,0 +1,3 @@
1
+ import type path from 'node:path';
2
+ import { type PlatformPath } from './types.cjs';
3
+ export declare function parent(nodePath: path.PlatformPath, _localPath: PlatformPath): (file: string) => string;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_PLATFORM = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const absolute_js_1 = require("./absolute.cjs");
9
+ const dir_js_1 = require("./dir.cjs");
10
+ const is_in_dir_js_1 = require("./is-in-dir.cjs");
11
+ // eslint-disable-next-line unicorn/prevent-abbreviations
12
+ const is_in_dirs_js_1 = require("./is-in-dirs.cjs");
13
+ const is_safe_path_js_1 = require("./is-safe-path.cjs");
14
+ const is_safe_segment_js_1 = require("./is-safe-segment.cjs");
15
+ const join_js_1 = require("./join.cjs");
16
+ const parent_js_1 = require("./parent.cjs");
17
+ const resolve_js_1 = require("./resolve.cjs");
18
+ const sanitize_js_1 = require("./sanitize.cjs");
19
+ const untildify_js_1 = require("./untildify.cjs");
20
+ function buildPlatform(path) {
21
+ const { basename: leaf, delimiter, extname: extension, isAbsolute, normalize, relative, sep: separator, } = path;
22
+ const result = {
23
+ delimiter,
24
+ separator,
25
+ extension,
26
+ isAbsolute,
27
+ leaf,
28
+ matchesGlob: path.matchesGlob ?? undefined,
29
+ normalize,
30
+ relative,
31
+ };
32
+ result.absolute = (0, absolute_js_1.absolute)(path, result);
33
+ result.dir = (0, dir_js_1.dir)(path, result);
34
+ result.isInDir = (0, is_in_dir_js_1.isInDir)(path, result);
35
+ result.isInDirs = (0, is_in_dirs_js_1.isInDirs)(path, result);
36
+ result.isSafePath = (0, is_safe_path_js_1.isSafePath)(path, result);
37
+ result.isSafeSegment = (0, is_safe_segment_js_1.isSafeSegment)(path, result);
38
+ result.join = (0, join_js_1.join)(path, result);
39
+ result.parent = (0, parent_js_1.parent)(path, result);
40
+ result.resolve = (0, resolve_js_1.resolve)(path, result);
41
+ result.sanitize = (0, sanitize_js_1.sanitize)(path, result);
42
+ result.untildify = (0, untildify_js_1.untildify)(path, result);
43
+ return result;
44
+ }
45
+ const POSIX_PLATFORM = buildPlatform(node_path_1.default.posix);
46
+ const WIN32_PLATFORM = buildPlatform(node_path_1.default.win32);
47
+ Object.defineProperties(POSIX_PLATFORM, {
48
+ posix: {
49
+ value: POSIX_PLATFORM,
50
+ writable: false,
51
+ },
52
+ win32: {
53
+ value: WIN32_PLATFORM,
54
+ writable: false,
55
+ },
56
+ });
57
+ Object.defineProperties(WIN32_PLATFORM, {
58
+ posix: {
59
+ value: POSIX_PLATFORM,
60
+ writable: false,
61
+ },
62
+ win32: {
63
+ value: WIN32_PLATFORM,
64
+ writable: false,
65
+ },
66
+ });
67
+ exports.DEFAULT_PLATFORM = (node_path_1.default === node_path_1.default.posix ? POSIX_PLATFORM : WIN32_PLATFORM);
@@ -0,0 +1,2 @@
1
+ import { type PlatformPath } from './types.cjs';
2
+ export declare const DEFAULT_PLATFORM: PlatformPath;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolve = resolve;
7
+ const node_process_1 = __importDefault(require("node:process"));
8
+ const is_it_type_1 = require("@zokugun/is-it-type");
9
+ const get_home_js_1 = require("./utils/get-home.cjs");
10
+ const get_user_home_js_1 = require("./utils/get-user-home.cjs");
11
+ const TILDE_REGEX = /^~(?=$|\/|\\)/;
12
+ const USER_REGEX = /^~([^/\\]+)(.*)$/;
13
+ function resolve(nodePath, _localPath) {
14
+ return (...paths) => {
15
+ if (paths.length === 0) {
16
+ return node_process_1.default.cwd();
17
+ }
18
+ else if (nodePath.isAbsolute(paths[0])) {
19
+ return nodePath.normalize(nodePath.join(...paths));
20
+ }
21
+ else if (TILDE_REGEX.test(paths[0])) {
22
+ const homedir = (0, get_home_js_1.getHome)();
23
+ if ((0, is_it_type_1.isString)(homedir)) {
24
+ paths.shift();
25
+ return nodePath.normalize(nodePath.join(homedir, ...paths));
26
+ }
27
+ }
28
+ else {
29
+ const match = USER_REGEX.exec(paths[0]);
30
+ if (match) {
31
+ const [, username, rest] = match;
32
+ const userHome = (0, get_user_home_js_1.getUserHome)(username);
33
+ if ((0, is_it_type_1.isString)(userHome)) {
34
+ paths.shift();
35
+ return nodePath.normalize(nodePath.join(userHome + rest, ...paths));
36
+ }
37
+ }
38
+ }
39
+ paths.unshift();
40
+ return nodePath.normalize(nodePath.join(node_process_1.default.cwd(), ...paths));
41
+ };
42
+ }
@@ -0,0 +1,3 @@
1
+ import type path from 'node:path';
2
+ import { type PlatformPath } from './types.cjs';
3
+ export declare function resolve(nodePath: path.PlatformPath, _localPath: PlatformPath): (...paths: string[]) => string;