@visulima/fs 4.0.6 → 4.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.
- package/CHANGELOG.md +10 -0
- package/dist/error/already-exists-error.d.ts +1 -1
- package/dist/error/directory-error.d.ts +1 -1
- package/dist/error/not-empty-error.d.ts +1 -1
- package/dist/error/not-found-error.d.ts +1 -1
- package/dist/error/permission-error.d.ts +1 -1
- package/dist/error.js +5 -5
- package/dist/find/walk-sync.d.ts +9 -1
- package/dist/find/walk.d.ts +8 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -6
- package/dist/move/index.d.ts +0 -2
- package/dist/move/types.d.ts +1 -3
- package/dist/packem_shared/{AlreadyExistsError-D5BGeeNR.js → AlreadyExistsError-6Y9hjgMn.js} +1 -1
- package/dist/packem_shared/{DirectoryError-CaUV2Pbk.js → DirectoryError-BfYPkIYP.js} +1 -1
- package/dist/packem_shared/{NotEmptyError-mOHWXE0m.js → NotEmptyError-B21RUlVr.js} +1 -1
- package/dist/packem_shared/{NotFoundError-D4llRgRs.js → NotFoundError-BIp61X6k.js} +1 -1
- package/dist/packem_shared/{PermissionError-1qs0skfo.js → PermissionError-CjoiJgip.js} +1 -1
- package/dist/packem_shared/{ensureSymlink-BGz6W-Wa.js → ensureSymlink-U5B6J0BN.js} +1 -1
- package/dist/packem_shared/{ensureSymlinkSync-C5Gk8QYi.js → ensureSymlinkSync-DHnZj-9F.js} +1 -1
- package/dist/packem_shared/{parseJson-CqUuRguZ.js → parseJson-C8xb-3LR.js} +2 -2
- package/dist/packem_shared/{readFile-XVOjAw8r.js → readFile-BcK0rkht.js} +1 -1
- package/dist/packem_shared/{readFileSync-B9Zg5PSF.js → readFileSync-BDgEnnqT.js} +1 -1
- package/dist/packem_shared/{readJson-Dra2m6s-.js → readJson-ac6N9-5G.js} +2 -2
- package/dist/packem_shared/{readJsonSync-B6Dl1I_6.js → readJsonSync-BTlwqLNV.js} +2 -2
- package/dist/packem_shared/{readYaml-Bu1nsexB.js → readYaml-Cj6HxRoa.js} +1 -1
- package/dist/packem_shared/{readYamlSync-Di88aMME.js → readYamlSync-D3_iAKVv.js} +1 -1
- package/dist/packem_shared/sanitize-lOzE6k2A.js +205 -0
- package/dist/read/read-yaml-sync.d.ts +3 -3
- package/dist/read/read-yaml.d.ts +3 -3
- package/dist/remove/empty-dir-sync.d.ts +0 -1
- package/dist/remove/remove-sync.d.ts +0 -1
- package/dist/sanitize.d.ts +31 -0
- package/dist/size.d.ts +17 -6
- package/dist/types.d.ts +5 -0
- package/dist/utils.js +1 -1
- package/dist/write/write-json-sync.d.ts +0 -1
- package/dist/yaml.js +2 -2
- package/package.json +2 -1
- /package/dist/find/utils/{glob-to-regex.d.ts → glob-to-regexp.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## @visulima/fs [4.1.0](https://github.com/visulima/visulima/compare/@visulima/fs@4.0.6...@visulima/fs@4.1.0) (2025-11-19)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* **fs:** Added new `sanitize.ts` utility for string file name sanitization ([78ee034](https://github.com/visulima/visulima/commit/78ee0349fe8b35145cfa6eebe3d72e1907da2990))
|
|
6
|
+
|
|
7
|
+
### Miscellaneous Chores
|
|
8
|
+
|
|
9
|
+
* **release:** update dependencies and versions across multiple packages ([39ad777](https://github.com/visulima/visulima/commit/39ad777e15aeb77d1ec4182763ab7473740ccbc4))
|
|
10
|
+
|
|
1
11
|
## @visulima/fs [4.0.6](https://github.com/visulima/visulima/compare/@visulima/fs@4.0.5...@visulima/fs@4.0.6) (2025-11-13)
|
|
2
12
|
|
|
3
13
|
### Bug Fixes
|
package/dist/error.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { default as AlreadyExistsError } from './packem_shared/AlreadyExistsError-
|
|
2
|
-
export { default as DirectoryError } from './packem_shared/DirectoryError-
|
|
1
|
+
export { default as AlreadyExistsError } from './packem_shared/AlreadyExistsError-6Y9hjgMn.js';
|
|
2
|
+
export { default as DirectoryError } from './packem_shared/DirectoryError-BfYPkIYP.js';
|
|
3
3
|
export { default as JSONError } from './packem_shared/JSONError-BkHRnInH.js';
|
|
4
|
-
export { default as NotEmptyError } from './packem_shared/NotEmptyError-
|
|
5
|
-
export { default as NotFoundError } from './packem_shared/NotFoundError-
|
|
6
|
-
export { default as PermissionError } from './packem_shared/PermissionError-
|
|
4
|
+
export { default as NotEmptyError } from './packem_shared/NotEmptyError-B21RUlVr.js';
|
|
5
|
+
export { default as NotFoundError } from './packem_shared/NotFoundError-BIp61X6k.js';
|
|
6
|
+
export { default as PermissionError } from './packem_shared/PermissionError-CjoiJgip.js';
|
|
7
7
|
export { default as WalkError } from './packem_shared/WalkError-DUdQd6FT.js';
|
package/dist/find/walk-sync.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import type { WalkEntry, WalkOptions } from "../types.d.ts";
|
|
2
2
|
/**
|
|
3
3
|
* Synchronously walks the file tree rooted at `directory`, yielding each file or directory that matches the criteria specified in `options`.
|
|
4
|
-
* This is the synchronous version of the {@
|
|
4
|
+
* This is the synchronous version of the {@linkcode walk} function.
|
|
5
5
|
* @param directory The root directory to start walking from.
|
|
6
6
|
* @param options Optional configuration to control the walking process. See {@link WalkOptions}.
|
|
7
|
+
* @param options.extensions List of file extensions used to filter entries.
|
|
8
|
+
* @param options.followSymlinks Indicates whether symlinks should be resolved or not.
|
|
9
|
+
* @param options.includeDirs Indicates whether directory entries should be included or not.
|
|
10
|
+
* @param options.includeFiles Indicates whether file entries should be included or not.
|
|
11
|
+
* @param options.includeSymlinks Indicates whether symlink entries should be included or not.
|
|
12
|
+
* @param options.match List of regular expression or glob patterns used to filter entries.
|
|
13
|
+
* @param options.maxDepth Maximum depth to walk. Defaults to infinity.
|
|
14
|
+
* @param options.skip List of regular expression or glob patterns used to skip entries.
|
|
7
15
|
* @returns An iterable iterator yielding {@link WalkEntry} objects for each matching file or directory.
|
|
8
16
|
* @example
|
|
9
17
|
* ```javascript
|
package/dist/find/walk.d.ts
CHANGED
|
@@ -3,6 +3,14 @@ import type { WalkEntry, WalkOptions } from "../types.d.ts";
|
|
|
3
3
|
* Asynchronously walks the file tree rooted at `directory`, yielding each file or directory that matches the criteria specified in `options`.
|
|
4
4
|
* @param directory The root directory to start walking from.
|
|
5
5
|
* @param options Optional configuration to control the walking process. See {@link WalkOptions}.
|
|
6
|
+
* @param options.extensions List of file extensions used to filter entries.
|
|
7
|
+
* @param options.followSymlinks Indicates whether symlinks should be resolved or not.
|
|
8
|
+
* @param options.includeDirs Indicates whether directory entries should be included or not.
|
|
9
|
+
* @param options.includeFiles Indicates whether file entries should be included or not.
|
|
10
|
+
* @param options.includeSymlinks Indicates whether symlink entries should be included or not.
|
|
11
|
+
* @param options.match List of regular expression or glob patterns used to filter entries.
|
|
12
|
+
* @param options.maxDepth Maximum depth to walk. Defaults to infinity.
|
|
13
|
+
* @param options.skip List of regular expression or glob patterns used to skip entries.
|
|
6
14
|
* @returns An async iterable iterator yielding {@link WalkEntry} objects for each matching file or directory.
|
|
7
15
|
* @example
|
|
8
16
|
* ```javascript
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export { default as emptyDir } from "./remove/empty-dir.d.ts";
|
|
|
26
26
|
export { default as emptyDirSync } from "./remove/empty-dir-sync.d.ts";
|
|
27
27
|
export { default as remove } from "./remove/remove.d.ts";
|
|
28
28
|
export { default as removeSync } from "./remove/remove-sync.d.ts";
|
|
29
|
+
export type { SanitizeOptions } from "./sanitize.d.ts";
|
|
30
|
+
export { sanitize } from "./sanitize.d.ts";
|
|
29
31
|
export type { CodeFrameLocation, CodeFrameOptions, ContentType, FindUpName, FindUpNameFnResult, FindUpNameSync, FindUpNameSyncFnResult, FindUpOptions, JsonReplacer, JsonReviver, ReadFileEncoding, ReadFileOptions, ReadJsonOptions, WalkEntry, WalkOptions, WriteFileOptions, WriteJsonOptions, } from "./types.d.ts";
|
|
30
32
|
export { default as writeFile } from "./write/write-file.d.ts";
|
|
31
33
|
export { default as writeFileSync } from "./write/write-file-sync.d.ts";
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,8 @@ export { default as ensureFile } from './packem_shared/ensureFile-BUtXGlGT.js';
|
|
|
5
5
|
export { default as ensureFileSync } from './packem_shared/ensureFileSync-C8hASR-1.js';
|
|
6
6
|
export { default as ensureLink } from './packem_shared/ensureLink-BPnAG5-P.js';
|
|
7
7
|
export { default as ensureLinkSync } from './packem_shared/ensureLinkSync-B-Z7X0ub.js';
|
|
8
|
-
export { default as ensureSymlink } from './packem_shared/ensureSymlink-
|
|
9
|
-
export { default as ensureSymlinkSync } from './packem_shared/ensureSymlinkSync-
|
|
8
|
+
export { default as ensureSymlink } from './packem_shared/ensureSymlink-U5B6J0BN.js';
|
|
9
|
+
export { default as ensureSymlinkSync } from './packem_shared/ensureSymlinkSync-DHnZj-9F.js';
|
|
10
10
|
export { CRLF, EOL, LF, detect, format } from './eol.js';
|
|
11
11
|
export { default as collect } from './packem_shared/collect-DcBwsYYd.js';
|
|
12
12
|
export { default as collectSync } from './packem_shared/collectSync-Bkjf9Dbm.js';
|
|
@@ -17,14 +17,15 @@ export { default as walkSync } from './packem_shared/walkSync-DDBq95s8.js';
|
|
|
17
17
|
export { default as isAccessible } from './packem_shared/isAccessible-iOp0Bou6.js';
|
|
18
18
|
export { default as isAccessibleSync } from './packem_shared/isAccessibleSync-38BmiIcx.js';
|
|
19
19
|
export { move, moveSync, rename, renameSync } from './packem_shared/move-BD6JbYSu.js';
|
|
20
|
-
export { default as readFile } from './packem_shared/readFile-
|
|
21
|
-
export { default as readFileSync } from './packem_shared/readFileSync-
|
|
22
|
-
export { default as readJson } from './packem_shared/readJson-
|
|
23
|
-
export { default as readJsonSync } from './packem_shared/readJsonSync-
|
|
20
|
+
export { default as readFile } from './packem_shared/readFile-BcK0rkht.js';
|
|
21
|
+
export { default as readFileSync } from './packem_shared/readFileSync-BDgEnnqT.js';
|
|
22
|
+
export { default as readJson } from './packem_shared/readJson-ac6N9-5G.js';
|
|
23
|
+
export { default as readJsonSync } from './packem_shared/readJsonSync-BTlwqLNV.js';
|
|
24
24
|
export { default as emptyDir } from './packem_shared/emptyDir-CYB5Tict.js';
|
|
25
25
|
export { default as emptyDirSync } from './packem_shared/emptyDirSync-BD8-1Ytl.js';
|
|
26
26
|
export { default as remove } from './packem_shared/remove-_oDY3uKo.js';
|
|
27
27
|
export { default as removeSync } from './packem_shared/removeSync-DETRj7Qn.js';
|
|
28
|
+
export { sanitize } from './packem_shared/sanitize-lOzE6k2A.js';
|
|
28
29
|
export { default as writeFile } from './packem_shared/writeFile-NT1fLEEe.js';
|
|
29
30
|
export { default as writeFileSync } from './packem_shared/writeFileSync-Bj5UDSf0.js';
|
|
30
31
|
export { default as writeJson } from './packem_shared/writeJson-DQLdAi0d.js';
|
package/dist/move/index.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ export declare const move: (sourcePath: string, destinationPath: string, options
|
|
|
28
28
|
* @param sourcePath The file you want to move.
|
|
29
29
|
* @param destinationPath Where you want the file moved.
|
|
30
30
|
* @param options Configuration options.
|
|
31
|
-
* @returns Nothing is returned.
|
|
32
31
|
* @example
|
|
33
32
|
* ```
|
|
34
33
|
* import { moveSync } from '@visulima/fs';
|
|
@@ -58,7 +57,6 @@ export declare const rename: (source: string, destination: string, options?: Opt
|
|
|
58
57
|
* @param source The file you want to rename.
|
|
59
58
|
* @param destination The name of the renamed file.
|
|
60
59
|
* @param options Configuration options.
|
|
61
|
-
* @returns A `Promise` that resolves when the file has been renamed.
|
|
62
60
|
* @example
|
|
63
61
|
* ```
|
|
64
62
|
* import { renameSync } from '@visulima/fs';
|
package/dist/move/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
type FilePermissions = number;
|
|
2
1
|
export type Options = {
|
|
3
2
|
/**
|
|
4
3
|
* The working directory to find source files.
|
|
@@ -12,7 +11,7 @@ export type Options = {
|
|
|
12
11
|
* It has no effect on Windows.
|
|
13
12
|
* @default 0o777
|
|
14
13
|
*/
|
|
15
|
-
readonly directoryMode?:
|
|
14
|
+
readonly directoryMode?: number;
|
|
16
15
|
/**
|
|
17
16
|
* Overwrite existing destination file.
|
|
18
17
|
* @default true
|
|
@@ -35,4 +34,3 @@ export type InternalOptions = Options & {
|
|
|
35
34
|
*/
|
|
36
35
|
validateDirectory?: boolean;
|
|
37
36
|
};
|
|
38
|
-
export {};
|
|
@@ -30,7 +30,7 @@ import ensureDir from './ensureDir-C_kuQ5Ik.js';
|
|
|
30
30
|
import { g as getFileInfoType } from './get-file-info-type-FD4-jsyg.js';
|
|
31
31
|
import { i as isStatsIdentical } from './is-stats-identical-D8FxpvQU.js';
|
|
32
32
|
import { r as resolveSymlinkTarget } from './resolve-symlink-target-Kh4GovFf.js';
|
|
33
|
-
import AlreadyExistsError from './AlreadyExistsError-
|
|
33
|
+
import AlreadyExistsError from './AlreadyExistsError-6Y9hjgMn.js';
|
|
34
34
|
|
|
35
35
|
const isWindows = process.platform === "win32" || /^(?:msys|cygwin)$/.test(process.env.OSTYPE);
|
|
36
36
|
const ensureSymlink = async (target, linkName, type) => {
|
|
@@ -30,7 +30,7 @@ import ensureDirSync from './ensureDirSync-CI5g-uBI.js';
|
|
|
30
30
|
import { g as getFileInfoType } from './get-file-info-type-FD4-jsyg.js';
|
|
31
31
|
import { i as isStatsIdentical } from './is-stats-identical-D8FxpvQU.js';
|
|
32
32
|
import { r as resolveSymlinkTarget } from './resolve-symlink-target-Kh4GovFf.js';
|
|
33
|
-
import AlreadyExistsError from './AlreadyExistsError-
|
|
33
|
+
import AlreadyExistsError from './AlreadyExistsError-6Y9hjgMn.js';
|
|
34
34
|
|
|
35
35
|
const isWindows = process.platform === "win32" || /^(?:msys|cygwin)$/.test(process.env.OSTYPE);
|
|
36
36
|
const ensureSymlinkSync = (target, linkName, type) => {
|
|
@@ -169,7 +169,7 @@ const indexToLineColumn = (input, index, options) => {
|
|
|
169
169
|
};
|
|
170
170
|
};
|
|
171
171
|
|
|
172
|
-
const getCodePoint = (character) =>
|
|
172
|
+
const getCodePoint = (character) => String.raw`\u{${character.codePointAt(0).toString(16)}}`;
|
|
173
173
|
const generateCodeFrame = (source, location, options) => codeFrame(
|
|
174
174
|
source,
|
|
175
175
|
{ start: location },
|
|
@@ -194,7 +194,7 @@ const getErrorLocation = (source, message) => {
|
|
|
194
194
|
return indexToLineColumn(source, index);
|
|
195
195
|
};
|
|
196
196
|
const addCodePointToUnexpectedToken = (message) => message.replace(
|
|
197
|
-
//
|
|
197
|
+
// The token is always quoted after Node.js 20, but we handle both cases for compatibility
|
|
198
198
|
// eslint-disable-next-line regexp/no-potentially-useless-backreference
|
|
199
199
|
/(?<=^Unexpected token )(?<quote>')?(.)\k<quote>/,
|
|
200
200
|
(_, _quote, token) => `"${token}"(${getCodePoint(token)})`
|
|
@@ -26,7 +26,7 @@ const {
|
|
|
26
26
|
} = __cjs_getBuiltinModule("node:zlib");
|
|
27
27
|
import { toPath } from '@visulima/path/utils';
|
|
28
28
|
import { R_OK } from './F_OK-BalxCn9n.js';
|
|
29
|
-
import PermissionError from './PermissionError-
|
|
29
|
+
import PermissionError from './PermissionError-CjoiJgip.js';
|
|
30
30
|
import isAccessible from './isAccessible-iOp0Bou6.js';
|
|
31
31
|
import assertValidFileOrDirectoryPath from './assertValidFileOrDirectoryPath-8HANmVjk.js';
|
|
32
32
|
|
|
@@ -26,7 +26,7 @@ const {
|
|
|
26
26
|
} = __cjs_getBuiltinModule("node:zlib");
|
|
27
27
|
import { toPath } from '@visulima/path/utils';
|
|
28
28
|
import { R_OK } from './F_OK-BalxCn9n.js';
|
|
29
|
-
import PermissionError from './PermissionError-
|
|
29
|
+
import PermissionError from './PermissionError-CjoiJgip.js';
|
|
30
30
|
import isAccessibleSync from './isAccessibleSync-38BmiIcx.js';
|
|
31
31
|
import assertValidFileOrDirectoryPath from './assertValidFileOrDirectoryPath-8HANmVjk.js';
|
|
32
32
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { toPath } from '@visulima/path/utils';
|
|
2
|
-
import parseJson from './parseJson-
|
|
3
|
-
import readFile from './readFile-
|
|
2
|
+
import parseJson from './parseJson-C8xb-3LR.js';
|
|
3
|
+
import readFile from './readFile-BcK0rkht.js';
|
|
4
4
|
|
|
5
5
|
async function readJson(path, reviver, options) {
|
|
6
6
|
if (typeof reviver === "object") {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { toPath } from '@visulima/path/utils';
|
|
2
|
-
import parseJson from './parseJson-
|
|
3
|
-
import readFileSync from './readFileSync-
|
|
2
|
+
import parseJson from './parseJson-C8xb-3LR.js';
|
|
3
|
+
import readFileSync from './readFileSync-BDgEnnqT.js';
|
|
4
4
|
|
|
5
5
|
function readJsonSync(path, reviver, options) {
|
|
6
6
|
if (typeof reviver === "object") {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parse } from 'yaml';
|
|
2
|
-
import readFile from './readFile-
|
|
2
|
+
import readFile from './readFile-BcK0rkht.js';
|
|
3
3
|
|
|
4
4
|
async function readYaml(path, reviver, options) {
|
|
5
5
|
const { buffer, compression, encoding = "utf8", flag, ...parseOptions } = options ?? {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parse } from 'yaml';
|
|
2
|
-
import readFileSync from './readFileSync-
|
|
2
|
+
import readFileSync from './readFileSync-BDgEnnqT.js';
|
|
3
3
|
|
|
4
4
|
function readYamlSync(path, reviver, options) {
|
|
5
5
|
const { buffer, compression, encoding = "utf8", flag, ...parseOptions } = options ?? {};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
platform
|
|
9
|
+
} = __cjs_getProcess;
|
|
10
|
+
|
|
11
|
+
const FALLBACK_NAME = "unnamed";
|
|
12
|
+
const MAX_LENGTH = 128;
|
|
13
|
+
const REPLACEMENT_CHARACTERS = {
|
|
14
|
+
'"': "ˮ",
|
|
15
|
+
// 0x02EE - MODIFIER LETTER DOUBLE APOSTROPHE
|
|
16
|
+
"*": "⁎",
|
|
17
|
+
// 0x204E - LOW ASTERISK
|
|
18
|
+
"/": "⁄",
|
|
19
|
+
// 0x2044 - FRACTION SLASH
|
|
20
|
+
":": "꞉",
|
|
21
|
+
// 0xA789 - MODIFIER LETTER COLON
|
|
22
|
+
"<": "‹",
|
|
23
|
+
// 0x2039 - SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
|
24
|
+
">": "›",
|
|
25
|
+
// 0x203A - SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
|
26
|
+
"?": "ʔ",
|
|
27
|
+
// 0x0294 - LATIN LETTER GLOTTAL STOP
|
|
28
|
+
"\\": "∖",
|
|
29
|
+
// 0x2216 - SET MINUS
|
|
30
|
+
"|": "ǀ"
|
|
31
|
+
// 0x01C0 - LATIN LETTER DENTAL CLICK
|
|
32
|
+
};
|
|
33
|
+
const CONTROL_CHARS_REGEX = /[\u0000-\u001F\u0080-\u009F]/g;
|
|
34
|
+
const RELATIVE_PATHS_REGEX = /^(?:\.+[/\\]+)+|^\.+$/g;
|
|
35
|
+
const WINDOWS_SPECIAL_NAMES_REGEX = /^(?:con|prn|aux|nul|com\d|lpt\d)$/i;
|
|
36
|
+
const WINDOWS_FORBIDDEN_CHARS_REGEX = /[<>:"/\\|?*]/g;
|
|
37
|
+
const UNIX_FORBIDDEN_CHARS_REGEX = /\//g;
|
|
38
|
+
const TRIM_CHARS = /* @__PURE__ */ new Set([" ", " ", "."]);
|
|
39
|
+
const hasExtension = (name, lastDotIndex) => lastDotIndex > 0 && lastDotIndex < name.length - 1;
|
|
40
|
+
const truncateWithExtension = (name, maxLength) => {
|
|
41
|
+
const lastDotIndex = name.lastIndexOf(".");
|
|
42
|
+
if (!hasExtension(name, lastDotIndex)) {
|
|
43
|
+
return name.slice(0, maxLength);
|
|
44
|
+
}
|
|
45
|
+
const baseName = name.slice(0, lastDotIndex);
|
|
46
|
+
const extension = name.slice(lastDotIndex);
|
|
47
|
+
const maxBaseLength = maxLength - extension.length;
|
|
48
|
+
return maxBaseLength > 0 ? `${baseName.slice(0, maxBaseLength)}${extension}` : name.slice(0, maxLength);
|
|
49
|
+
};
|
|
50
|
+
const trimSpacesAndPeriods = (input) => {
|
|
51
|
+
let start = 0;
|
|
52
|
+
let end = input.length;
|
|
53
|
+
while (start < end) {
|
|
54
|
+
const char = input[start];
|
|
55
|
+
if (char === void 0 || !TRIM_CHARS.has(char)) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
start += 1;
|
|
59
|
+
}
|
|
60
|
+
while (end > start) {
|
|
61
|
+
const char = input[end - 1];
|
|
62
|
+
if (char === void 0 || !TRIM_CHARS.has(char)) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
end -= 1;
|
|
66
|
+
}
|
|
67
|
+
return input.slice(start, end);
|
|
68
|
+
};
|
|
69
|
+
const cleanWindowsName = (name) => {
|
|
70
|
+
const lastDotIndex = name.lastIndexOf(".");
|
|
71
|
+
if (hasExtension(name, lastDotIndex)) {
|
|
72
|
+
const baseName = name.slice(0, lastDotIndex);
|
|
73
|
+
const extension = name.slice(lastDotIndex);
|
|
74
|
+
let cleanedBaseName = baseName;
|
|
75
|
+
while (cleanedBaseName.length > 0) {
|
|
76
|
+
const char = cleanedBaseName[cleanedBaseName.length - 1];
|
|
77
|
+
if (char === void 0 || !TRIM_CHARS.has(char)) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
cleanedBaseName = cleanedBaseName.slice(0, -1);
|
|
81
|
+
}
|
|
82
|
+
if (cleanedBaseName.length === 0) {
|
|
83
|
+
return extension.slice(1);
|
|
84
|
+
}
|
|
85
|
+
return `${cleanedBaseName}${extension}`;
|
|
86
|
+
}
|
|
87
|
+
let cleaned = name;
|
|
88
|
+
while (cleaned.length > 0) {
|
|
89
|
+
const char = cleaned[cleaned.length - 1];
|
|
90
|
+
if (char === void 0 || !TRIM_CHARS.has(char)) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
cleaned = cleaned.slice(0, -1);
|
|
94
|
+
}
|
|
95
|
+
return cleaned;
|
|
96
|
+
};
|
|
97
|
+
const isWindowsReservedName = (name) => {
|
|
98
|
+
const lastDotIndex = name.lastIndexOf(".");
|
|
99
|
+
if (hasExtension(name, lastDotIndex)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
if (WINDOWS_SPECIAL_NAMES_REGEX.test(name)) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
let trimmed = name;
|
|
106
|
+
while (trimmed.length > 0) {
|
|
107
|
+
const char = trimmed[trimmed.length - 1];
|
|
108
|
+
if (char === void 0 || !TRIM_CHARS.has(char)) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
trimmed = trimmed.slice(0, -1);
|
|
112
|
+
}
|
|
113
|
+
if (trimmed.length > 0 && WINDOWS_SPECIAL_NAMES_REGEX.test(trimmed)) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
};
|
|
118
|
+
const cleanFat32Name = (name) => {
|
|
119
|
+
const lastDotIndex = name.lastIndexOf(".");
|
|
120
|
+
if (hasExtension(name, lastDotIndex)) {
|
|
121
|
+
const baseName = name.slice(0, lastDotIndex);
|
|
122
|
+
const extension = name.slice(lastDotIndex);
|
|
123
|
+
const cleanedBaseName = trimSpacesAndPeriods(baseName);
|
|
124
|
+
if (cleanedBaseName.length === 0) {
|
|
125
|
+
return void 0;
|
|
126
|
+
}
|
|
127
|
+
return `${cleanedBaseName}${extension}`;
|
|
128
|
+
}
|
|
129
|
+
const trimmed = name.trim();
|
|
130
|
+
if (trimmed.length > 0 && trimmed[0] === "." && trimmed.length <= 5) {
|
|
131
|
+
const secondDotIndex = trimmed.indexOf(".", 1);
|
|
132
|
+
if (secondDotIndex === -1) {
|
|
133
|
+
return void 0;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const cleaned = trimSpacesAndPeriods(name);
|
|
137
|
+
if (cleaned.length === 0) {
|
|
138
|
+
return void 0;
|
|
139
|
+
}
|
|
140
|
+
return cleaned;
|
|
141
|
+
};
|
|
142
|
+
const getFileSystemType = (options) => {
|
|
143
|
+
const filesystem = options?.filesystem ?? "auto";
|
|
144
|
+
if (filesystem === "auto") {
|
|
145
|
+
return platform === "win32" ? "win32" : "unix";
|
|
146
|
+
}
|
|
147
|
+
if (filesystem === "darwin") {
|
|
148
|
+
return "unix";
|
|
149
|
+
}
|
|
150
|
+
return filesystem;
|
|
151
|
+
};
|
|
152
|
+
const sanitize = (name, options) => {
|
|
153
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
154
|
+
return FALLBACK_NAME;
|
|
155
|
+
}
|
|
156
|
+
const fileSystemType = getFileSystemType(options);
|
|
157
|
+
let sanitized = name;
|
|
158
|
+
sanitized = sanitized.replace(CONTROL_CHARS_REGEX, "");
|
|
159
|
+
if (sanitized.length === 0) {
|
|
160
|
+
return FALLBACK_NAME;
|
|
161
|
+
}
|
|
162
|
+
sanitized = sanitized.replace(RELATIVE_PATHS_REGEX, "");
|
|
163
|
+
if (sanitized.length === 0) {
|
|
164
|
+
return FALLBACK_NAME;
|
|
165
|
+
}
|
|
166
|
+
if (fileSystemType === "win32" || fileSystemType === "fat32") {
|
|
167
|
+
const lastDotIndex = sanitized.lastIndexOf(".");
|
|
168
|
+
if (!hasExtension(sanitized, lastDotIndex) && WINDOWS_SPECIAL_NAMES_REGEX.test(sanitized)) {
|
|
169
|
+
return FALLBACK_NAME;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
sanitized = fileSystemType === "win32" || fileSystemType === "fat32" ? sanitized.replaceAll(WINDOWS_FORBIDDEN_CHARS_REGEX, (char) => REPLACEMENT_CHARACTERS[char] ?? "") : sanitized.replaceAll(UNIX_FORBIDDEN_CHARS_REGEX, REPLACEMENT_CHARACTERS["/"]);
|
|
173
|
+
sanitized = sanitized.trim();
|
|
174
|
+
if (fileSystemType === "win32" || fileSystemType === "fat32") {
|
|
175
|
+
if (isWindowsReservedName(sanitized)) {
|
|
176
|
+
return FALLBACK_NAME;
|
|
177
|
+
}
|
|
178
|
+
if (fileSystemType === "win32") {
|
|
179
|
+
sanitized = cleanWindowsName(sanitized);
|
|
180
|
+
if (sanitized.length === 0) {
|
|
181
|
+
return FALLBACK_NAME;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (fileSystemType === "fat32") {
|
|
186
|
+
const cleaned = cleanFat32Name(sanitized);
|
|
187
|
+
if (cleaned === void 0) {
|
|
188
|
+
return FALLBACK_NAME;
|
|
189
|
+
}
|
|
190
|
+
sanitized = cleaned;
|
|
191
|
+
}
|
|
192
|
+
if (sanitized.length === 0) {
|
|
193
|
+
return FALLBACK_NAME;
|
|
194
|
+
}
|
|
195
|
+
const maxLength = options?.maxLength ?? MAX_LENGTH;
|
|
196
|
+
if (sanitized.length > maxLength) {
|
|
197
|
+
sanitized = truncateWithExtension(sanitized, maxLength);
|
|
198
|
+
if (sanitized.length === 0) {
|
|
199
|
+
return FALLBACK_NAME;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return sanitized;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export { sanitize };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReadYamlOptions, YamlReviver } from "../types.d.ts";
|
|
2
|
-
declare function readYamlSync<R = Record<string, unknown>>(path: URL | string, options?: ReadYamlOptions<
|
|
3
|
-
declare function readYamlSync<R = Record<string, unknown>>(path: URL | string, reviver?: YamlReviver, options?: ReadYamlOptions<
|
|
1
|
+
import type { CompressionType, ReadYamlOptions, YamlReviver } from "../types.d.ts";
|
|
2
|
+
declare function readYamlSync<R = Record<string, unknown>>(path: URL | string, options?: ReadYamlOptions<CompressionType>): R;
|
|
3
|
+
declare function readYamlSync<R = Record<string, unknown>>(path: URL | string, reviver?: YamlReviver, options?: ReadYamlOptions<CompressionType>): R;
|
|
4
4
|
export default readYamlSync;
|
package/dist/read/read-yaml.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReadYamlOptions, YamlReviver } from "../types.d.ts";
|
|
2
|
-
declare function readYaml<R = Record<string, unknown>>(path: URL | string, options?: ReadYamlOptions<
|
|
3
|
-
declare function readYaml<R = Record<string, unknown>>(path: URL | string, reviver?: YamlReviver, options?: ReadYamlOptions<
|
|
1
|
+
import type { CompressionType, ReadYamlOptions, YamlReviver } from "../types.d.ts";
|
|
2
|
+
declare function readYaml<R = Record<string, unknown>>(path: URL | string, options?: ReadYamlOptions<CompressionType>): Promise<R>;
|
|
3
|
+
declare function readYaml<R = Record<string, unknown>>(path: URL | string, reviver?: YamlReviver, options?: ReadYamlOptions<CompressionType>): Promise<R>;
|
|
4
4
|
export default readYaml;
|
|
@@ -6,7 +6,6 @@ import type { RetryOptions } from "../types.d.ts";
|
|
|
6
6
|
* The directory itself is not deleted.
|
|
7
7
|
* @param dir The path to the directory to empty.
|
|
8
8
|
* @param options Optional configuration for the operation. See {@link RetryOptions}.
|
|
9
|
-
* @returns void
|
|
10
9
|
* @example
|
|
11
10
|
* ```javascript
|
|
12
11
|
* import { emptyDirSync } from "@visulima/fs";
|
|
@@ -4,7 +4,6 @@ import type { RetryOptions } from "../types.d.ts";
|
|
|
4
4
|
* If the path does not exist, it does nothing.
|
|
5
5
|
* @param path The path to the file or directory to remove.
|
|
6
6
|
* @param options Optional configuration for the operation. See {@link RetryOptions}.
|
|
7
|
-
* @returns void
|
|
8
7
|
* @example
|
|
9
8
|
* ```javascript
|
|
10
9
|
* import { removeSync } from "@visulima/fs";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported filesystem types
|
|
3
|
+
*/
|
|
4
|
+
export type FileSystemType = "win32" | "unix" | "darwin" | "fat32" | "auto";
|
|
5
|
+
/**
|
|
6
|
+
* Options for the sanitize function
|
|
7
|
+
*/
|
|
8
|
+
export interface SanitizeOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Target filesystem type for sanitization rules
|
|
11
|
+
* - "win32": Windows filesystem rules (reserved names, Windows forbidden chars, no trailing periods/spaces)
|
|
12
|
+
* - "unix": Unix/Linux filesystem rules (only / and null forbidden)
|
|
13
|
+
* - "darwin": macOS filesystem rules (same as unix)
|
|
14
|
+
* - "fat32": FAT32 filesystem rules (Windows rules + no leading/trailing spaces/periods in name part)
|
|
15
|
+
* - "auto": Automatically detect from process.platform
|
|
16
|
+
* @default "auto"
|
|
17
|
+
*/
|
|
18
|
+
filesystem?: FileSystemType;
|
|
19
|
+
/**
|
|
20
|
+
* Maximum length of the sanitized name
|
|
21
|
+
* @default 128
|
|
22
|
+
*/
|
|
23
|
+
maxLength?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sanitizes a filename by removing or replacing forbidden characters.
|
|
27
|
+
* @param name The filename to sanitize.
|
|
28
|
+
* @param options Optional configuration.
|
|
29
|
+
* @returns The sanitized filename, or "unnamed" if the result would be empty.
|
|
30
|
+
*/
|
|
31
|
+
export declare const sanitize: (name: string, options?: Partial<SanitizeOptions>) => string;
|
package/dist/size.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { Readable } from "node:stream";
|
|
2
2
|
import { URL } from "node:url";
|
|
3
3
|
import type { BrotliOptions, ZlibOptions } from "node:zlib";
|
|
4
|
+
/**
|
|
5
|
+
* Input type for size calculation functions.
|
|
6
|
+
* Can be a Buffer, Readable stream, URL object, or string (file path or content).
|
|
7
|
+
*/
|
|
8
|
+
type SizeInput = Buffer | Readable | URL | string;
|
|
9
|
+
/**
|
|
10
|
+
* Input type for synchronous size calculation functions.
|
|
11
|
+
* Can be a Buffer, URL object, or string (file path or content).
|
|
12
|
+
*/
|
|
13
|
+
type SizeInputSync = Buffer | URL | string;
|
|
4
14
|
/**
|
|
5
15
|
* Asynchronously calculates the gzipped size of the given input.
|
|
6
16
|
* The input can be a Buffer, a Readable stream, a URL object pointing to a file, or a string (file path or content).
|
|
@@ -44,7 +54,7 @@ import type { BrotliOptions, ZlibOptions } from "node:zlib";
|
|
|
44
54
|
* main().catch(console.error);
|
|
45
55
|
* ```
|
|
46
56
|
*/
|
|
47
|
-
export declare const gzipSize: (input:
|
|
57
|
+
export declare const gzipSize: (input: SizeInput, options?: ZlibOptions) => Promise<number>;
|
|
48
58
|
/**
|
|
49
59
|
* Asynchronously calculates the Brotli compressed size of the given input.
|
|
50
60
|
* The input can be a Buffer, a Readable stream, a URL object pointing to a file, or a string (file path or content).
|
|
@@ -88,7 +98,7 @@ export declare const gzipSize: (input: Buffer | Readable | URL | string, options
|
|
|
88
98
|
* main().catch(console.error);
|
|
89
99
|
* ```
|
|
90
100
|
*/
|
|
91
|
-
export declare const brotliSize: (input:
|
|
101
|
+
export declare const brotliSize: (input: SizeInput, options?: BrotliOptions) => Promise<number>;
|
|
92
102
|
/**
|
|
93
103
|
* Asynchronously calculates the raw (uncompressed) size of the given input.
|
|
94
104
|
* The input can be a Buffer, a Readable stream, a URL object pointing to a file, or a string (file path or content).
|
|
@@ -131,7 +141,7 @@ export declare const brotliSize: (input: Buffer | Readable | URL | string, optio
|
|
|
131
141
|
* main().catch(console.error);
|
|
132
142
|
* ```
|
|
133
143
|
*/
|
|
134
|
-
export declare const rawSize: (input:
|
|
144
|
+
export declare const rawSize: (input: SizeInput) => Promise<number>;
|
|
135
145
|
/**
|
|
136
146
|
* Synchronously calculates the gzipped size of the given input.
|
|
137
147
|
* The input can be a Buffer, a URL object pointing to a file, or a string (file path or content).
|
|
@@ -168,7 +178,7 @@ export declare const rawSize: (input: Buffer | Readable | URL | string) => Promi
|
|
|
168
178
|
* }
|
|
169
179
|
* ```
|
|
170
180
|
*/
|
|
171
|
-
export declare const gzipSizeSync: (input:
|
|
181
|
+
export declare const gzipSizeSync: (input: SizeInputSync, options?: ZlibOptions) => number;
|
|
172
182
|
/**
|
|
173
183
|
* Synchronously calculates the Brotli compressed size of the given input.
|
|
174
184
|
* The input can be a Buffer, a URL object pointing to a file, or a string (file path or content).
|
|
@@ -205,7 +215,7 @@ export declare const gzipSizeSync: (input: Buffer | URL | string, options?: Zlib
|
|
|
205
215
|
* }
|
|
206
216
|
* ```
|
|
207
217
|
*/
|
|
208
|
-
export declare const brotliSizeSync: (input:
|
|
218
|
+
export declare const brotliSizeSync: (input: SizeInputSync, options?: BrotliOptions) => number;
|
|
209
219
|
/**
|
|
210
220
|
* Synchronously calculates the raw (uncompressed) size of the given input.
|
|
211
221
|
* The input can be a Buffer, a URL object pointing to a file, or a string (file path or content).
|
|
@@ -242,4 +252,5 @@ export declare const brotliSizeSync: (input: Buffer | URL | string, options?: Br
|
|
|
242
252
|
* }
|
|
243
253
|
* ```
|
|
244
254
|
*/
|
|
245
|
-
export declare const rawSizeSync: (input:
|
|
255
|
+
export declare const rawSizeSync: (input: SizeInputSync) => number;
|
|
256
|
+
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -58,6 +58,10 @@ export interface WalkEntry extends Pick<Dirent, "isDirectory" | "isFile" | "isSy
|
|
|
58
58
|
/** The full path to the entry. */
|
|
59
59
|
path: string;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Supported compression types for file operations.
|
|
63
|
+
*/
|
|
64
|
+
export type CompressionType = "brotli" | "gzip" | "none";
|
|
61
65
|
/**
|
|
62
66
|
* Supported file encodings for reading files.
|
|
63
67
|
*/
|
|
@@ -175,6 +179,7 @@ export type WriteFileOptions = {
|
|
|
175
179
|
export type JsonReplacer = (number | string)[] | ((this: unknown, key: string, value: unknown) => unknown) | null;
|
|
176
180
|
/**
|
|
177
181
|
* Type for the `replacer` parameter used in YAML serialization, similar to `JSON.stringify`'s replacer.
|
|
182
|
+
* @deprecated Use {@link JsonReplacer} directly instead.
|
|
178
183
|
*/
|
|
179
184
|
export type YamlReplacer = JsonReplacer;
|
|
180
185
|
/**
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { default as JSONError } from './packem_shared/JSONError-BkHRnInH.js';
|
|
2
2
|
export { default as assertValidFileContents } from './packem_shared/assertValidFileContents-BmcLtsGd.js';
|
|
3
3
|
export { default as assertValidFileOrDirectoryPath } from './packem_shared/assertValidFileOrDirectoryPath-8HANmVjk.js';
|
|
4
|
-
export { default as parseJson } from './packem_shared/parseJson-
|
|
4
|
+
export { default as parseJson } from './packem_shared/parseJson-C8xb-3LR.js';
|
|
5
5
|
export { default as stripJsonComments } from './packem_shared/stripJsonComments-21XWVDwP.js';
|
|
6
6
|
export { toPath } from '@visulima/path/utils';
|
|
@@ -5,7 +5,6 @@ import type { WriteJsonOptions } from "../types.d.ts";
|
|
|
5
5
|
* @param path The path to the JSON file to write. Can be a file URL or a string path.
|
|
6
6
|
* @param data The data to serialize and write. Can be any JavaScript value that can be stringified by `JSON.stringify` or a custom stringifier.
|
|
7
7
|
* @param options Optional configuration for writing the JSON file. See {@link WriteJsonOptions}.
|
|
8
|
-
* @returns void
|
|
9
8
|
* @example
|
|
10
9
|
* ```javascript
|
|
11
10
|
* import { writeJsonSync } from "@visulima/fs";
|
package/dist/yaml.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as readYaml } from './packem_shared/readYaml-
|
|
2
|
-
export { default as readYamlSync } from './packem_shared/readYamlSync-
|
|
1
|
+
export { default as readYaml } from './packem_shared/readYaml-Cj6HxRoa.js';
|
|
2
|
+
export { default as readYamlSync } from './packem_shared/readYamlSync-D3_iAKVv.js';
|
|
3
3
|
export { default as writeYaml } from './packem_shared/writeYaml-BMY0kOPf.js';
|
|
4
4
|
export { default as writeYamlSync } from './packem_shared/writeYamlSync-DqPu8cCd.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/fs",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Human friendly file system utilities for Node.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"anolilab",
|
|
@@ -113,6 +113,7 @@
|
|
|
113
113
|
"LICENSE.md"
|
|
114
114
|
],
|
|
115
115
|
"dependencies": {
|
|
116
|
+
"type-fest": "^5.2.0",
|
|
116
117
|
"@visulima/path": "2.0.5"
|
|
117
118
|
},
|
|
118
119
|
"peerDependencies": {
|
|
File without changes
|