@wener/common 2.0.2 → 2.0.3
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/lib/ai/qwen3vl/index.js +2 -0
- package/lib/ai/qwen3vl/index.js.map +1 -0
- package/lib/ai/qwen3vl/utils.js +31 -0
- package/lib/ai/qwen3vl/utils.js.map +1 -0
- package/lib/ai/vision/DocLayoutElementTypeSchema.js +28 -0
- package/lib/ai/vision/DocLayoutElementTypeSchema.js.map +1 -0
- package/lib/ai/vision/ImageAnnotationSchema.js +50 -0
- package/lib/ai/vision/ImageAnnotationSchema.js.map +1 -0
- package/lib/ai/vision/index.js +3 -0
- package/lib/ai/vision/index.js.map +1 -0
- package/lib/ai/vision/resolveImageAnnotation.js +105 -0
- package/lib/ai/vision/resolveImageAnnotation.js.map +1 -0
- package/lib/cn/ChineseResidentIdNo.js +21 -14
- package/lib/cn/ChineseResidentIdNo.js.map +1 -0
- package/lib/cn/ChineseResidentIdNo.test.js +1 -1
- package/lib/cn/DivisionCode.js +30 -25
- package/lib/cn/DivisionCode.js.map +1 -0
- package/lib/cn/DivisionCode.test.js +1 -1
- package/lib/cn/Mod11.js +38 -81
- package/lib/cn/Mod11.js.map +1 -0
- package/lib/cn/Mod31.js +41 -90
- package/lib/cn/Mod31.js.map +1 -0
- package/lib/cn/UnifiedSocialCreditCode.js +43 -34
- package/lib/cn/UnifiedSocialCreditCode.js.map +1 -0
- package/lib/cn/UnifiedSocialCreditCode.test.js +1 -1
- package/lib/cn/formatChineseAmount.js +77 -0
- package/lib/cn/formatChineseAmount.js.map +1 -0
- package/lib/cn/index.js +7 -1
- package/lib/cn/index.js.map +1 -0
- package/lib/cn/parseChineseNumber.js +94 -0
- package/lib/cn/parseChineseNumber.js.map +1 -0
- package/lib/cn/parseChineseNumber.test.js +278 -0
- package/lib/cn/pinyin/cartesianProduct.js +22 -0
- package/lib/cn/pinyin/cartesianProduct.js.map +1 -0
- package/lib/cn/pinyin/cartesianProduct.test.js +179 -0
- package/lib/cn/pinyin/data.json +23573 -0
- package/lib/cn/pinyin/loader.js +14 -0
- package/lib/cn/pinyin/loader.js.map +1 -0
- package/lib/cn/pinyin/preload.js +3 -0
- package/lib/cn/pinyin/preload.js.map +1 -0
- package/lib/cn/pinyin/toPinyin.test.js +167 -0
- package/lib/cn/pinyin/toPinyinPure.js +33 -0
- package/lib/cn/pinyin/toPinyinPure.js.map +1 -0
- package/lib/cn/pinyin/transform.js +14 -0
- package/lib/cn/pinyin/transform.js.map +1 -0
- package/lib/cn/types.d.js +2 -0
- package/lib/cn/types.d.js.map +1 -0
- package/lib/consola/createStandardConsolaReporter.js +6 -6
- package/lib/consola/createStandardConsolaReporter.js.map +1 -0
- package/lib/consola/formatLogObject.js +65 -145
- package/lib/consola/formatLogObject.js.map +1 -0
- package/lib/consola/formatLogObject.test.js +184 -0
- package/lib/consola/index.js +1 -0
- package/lib/consola/index.js.map +1 -0
- package/lib/data/formatSort.js +6 -5
- package/lib/data/formatSort.js.map +1 -0
- package/lib/data/index.js +1 -0
- package/lib/data/index.js.map +1 -0
- package/lib/data/maybeNumber.js +5 -7
- package/lib/data/maybeNumber.js.map +1 -0
- package/lib/data/parseSort.js +22 -28
- package/lib/data/parseSort.js.map +1 -0
- package/lib/data/resolvePagination.js +13 -17
- package/lib/data/resolvePagination.js.map +1 -0
- package/lib/data/types.d.js +2 -0
- package/lib/data/types.d.js.map +1 -0
- package/lib/dayjs/dayjs.js +21 -19
- package/lib/dayjs/dayjs.js.map +1 -0
- package/lib/dayjs/formatDuration.js +15 -14
- package/lib/dayjs/formatDuration.js.map +1 -0
- package/lib/dayjs/index.js +2 -0
- package/lib/dayjs/index.js.map +1 -0
- package/lib/dayjs/parseDuration.js +5 -8
- package/lib/dayjs/parseDuration.js.map +1 -0
- package/lib/dayjs/parseRelativeTime.js +90 -0
- package/lib/dayjs/parseRelativeTime.js.map +1 -0
- package/lib/dayjs/parseRelativeTime.test.js +247 -0
- package/lib/dayjs/resolveRelativeTime.js +158 -0
- package/lib/dayjs/resolveRelativeTime.js.map +1 -0
- package/lib/dayjs/resolveRelativeTime.test.js +310 -0
- package/lib/decimal/index.js +1 -0
- package/lib/decimal/index.js.map +1 -0
- package/lib/decimal/parseDecimal.js +3 -1
- package/lib/decimal/parseDecimal.js.map +1 -0
- package/lib/emittery/emitter.js +10 -0
- package/lib/emittery/emitter.js.map +1 -0
- package/lib/emittery/index.js +2 -0
- package/lib/emittery/index.js.map +1 -0
- package/lib/foundation/schema/SexType.js +5 -3
- package/lib/foundation/schema/SexType.js.map +1 -0
- package/lib/foundation/schema/index.js +1 -0
- package/lib/foundation/schema/index.js.map +1 -0
- package/lib/foundation/schema/parseSexType.js +1 -0
- package/lib/foundation/schema/parseSexType.js.map +1 -0
- package/lib/foundation/schema/types.js +4 -2
- package/lib/foundation/schema/types.js.map +1 -0
- package/lib/fs/FileSystemError.js +23 -0
- package/lib/fs/FileSystemError.js.map +1 -0
- package/lib/fs/IFileSystem.d.js +3 -0
- package/lib/fs/IFileSystem.d.js.map +1 -0
- package/lib/fs/MemoryFileSystem.test.js +188 -0
- package/lib/fs/createBrowserFileSystem.js +248 -0
- package/lib/fs/createBrowserFileSystem.js.map +1 -0
- package/lib/fs/createMemoryFileSystem.js +516 -0
- package/lib/fs/createMemoryFileSystem.js.map +1 -0
- package/lib/fs/createSandboxFileSystem.js +108 -0
- package/lib/fs/createSandboxFileSystem.js.map +1 -0
- package/lib/fs/createWebDavFileSystem.js +137 -0
- package/lib/fs/createWebDavFileSystem.js.map +1 -0
- package/lib/fs/findMimeType.js +17 -0
- package/lib/fs/findMimeType.js.map +1 -0
- package/lib/fs/index.js +8 -0
- package/lib/fs/index.js.map +1 -0
- package/lib/fs/orpc/FileSystemContract.js +93 -0
- package/lib/fs/orpc/FileSystemContract.js.map +1 -0
- package/lib/fs/orpc/createContractClientFileSystem.js +93 -0
- package/lib/fs/orpc/createContractClientFileSystem.js.map +1 -0
- package/lib/fs/orpc/index.js +3 -0
- package/lib/fs/orpc/index.js.map +1 -0
- package/lib/fs/orpc/server/createFileSystemContractImpl.js +63 -0
- package/lib/fs/orpc/server/createFileSystemContractImpl.js.map +1 -0
- package/lib/fs/orpc/server/index.js +2 -0
- package/lib/fs/orpc/server/index.js.map +1 -0
- package/lib/fs/s3/createS3MiniFileSystem.js +705 -0
- package/lib/fs/s3/createS3MiniFileSystem.js.map +1 -0
- package/lib/fs/s3/index.js +2 -0
- package/lib/fs/s3/index.js.map +1 -0
- package/lib/fs/s3/s3mini.test.js +584 -0
- package/lib/fs/scandir.js +59 -0
- package/lib/fs/scandir.js.map +1 -0
- package/lib/fs/server/createDatabaseFileSystem.js +750 -0
- package/lib/fs/server/createDatabaseFileSystem.js.map +1 -0
- package/lib/fs/server/createNodeFileSystem.js +401 -0
- package/lib/fs/server/createNodeFileSystem.js.map +1 -0
- package/lib/fs/server/dbfs.test.js +221 -0
- package/lib/fs/server/index.js +2 -0
- package/lib/fs/server/index.js.map +1 -0
- package/lib/fs/server/loadTestDatabase.js +127 -0
- package/lib/fs/server/loadTestDatabase.js.map +1 -0
- package/lib/fs/tests/runFileSystemTest.js +318 -0
- package/lib/fs/tests/runFileSystemTest.js.map +1 -0
- package/lib/fs/types.js +27 -0
- package/lib/fs/types.js.map +1 -0
- package/lib/fs/utils/getFileUrl.js +35 -0
- package/lib/fs/utils/getFileUrl.js.map +1 -0
- package/lib/fs/utils.js +22 -0
- package/lib/fs/utils.js.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/jsonschema/JsonSchema.js +146 -172
- package/lib/jsonschema/JsonSchema.js.map +1 -0
- package/lib/jsonschema/forEachJsonSchema.js +44 -0
- package/lib/jsonschema/forEachJsonSchema.js.map +1 -0
- package/lib/jsonschema/index.js +2 -0
- package/lib/jsonschema/index.js.map +1 -0
- package/lib/jsonschema/types.d.js +2 -0
- package/lib/jsonschema/types.d.js.map +1 -0
- package/lib/meta/defineFileType.js +20 -103
- package/lib/meta/defineFileType.js.map +1 -0
- package/lib/meta/defineInit.js +31 -250
- package/lib/meta/defineInit.js.map +1 -0
- package/lib/meta/defineMetadata.js +24 -140
- package/lib/meta/defineMetadata.js.map +1 -0
- package/lib/meta/index.js +1 -0
- package/lib/meta/index.js.map +1 -0
- package/lib/orpc/createOpenApiContractClient.js +27 -0
- package/lib/orpc/createOpenApiContractClient.js.map +1 -0
- package/lib/orpc/createRpcContractClient.js +34 -0
- package/lib/orpc/createRpcContractClient.js.map +1 -0
- package/lib/orpc/index.js +3 -0
- package/lib/orpc/index.js.map +1 -0
- package/lib/orpc/resolveLinkPlugins.js +28 -0
- package/lib/orpc/resolveLinkPlugins.js.map +1 -0
- package/lib/password/PHC.js +63 -87
- package/lib/password/PHC.js.map +1 -0
- package/lib/password/PHC.test.js +11 -3
- package/lib/password/Password.js +29 -294
- package/lib/password/Password.js.map +1 -0
- package/lib/password/Password.test.js +35 -22
- package/lib/password/createArgon2PasswordAlgorithm.js +35 -191
- package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -0
- package/lib/password/createBase64PasswordAlgorithm.js +8 -141
- package/lib/password/createBase64PasswordAlgorithm.js.map +1 -0
- package/lib/password/createBcryptPasswordAlgorithm.js +13 -168
- package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -0
- package/lib/password/createPBKDF2PasswordAlgorithm.js +46 -228
- package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -0
- package/lib/password/createScryptPasswordAlgorithm.js +55 -211
- package/lib/password/createScryptPasswordAlgorithm.js.map +1 -0
- package/lib/password/index.js +1 -0
- package/lib/password/index.js.map +1 -0
- package/lib/password/server/index.js +1 -0
- package/lib/password/server/index.js.map +1 -0
- package/lib/resource/Identifiable.js +2 -0
- package/lib/resource/Identifiable.js.map +1 -0
- package/lib/resource/ListQuery.js +21 -93
- package/lib/resource/ListQuery.js.map +1 -0
- package/lib/resource/getTitleOfResource.js +3 -5
- package/lib/resource/getTitleOfResource.js.map +1 -0
- package/lib/resource/index.js +1 -0
- package/lib/resource/index.js.map +1 -0
- package/lib/resource/schema/AnyResourceSchema.js +2 -1
- package/lib/resource/schema/AnyResourceSchema.js.map +1 -0
- package/lib/resource/schema/BaseResourceSchema.js +2 -1
- package/lib/resource/schema/BaseResourceSchema.js.map +1 -0
- package/lib/resource/schema/ResourceActionType.js +6 -4
- package/lib/resource/schema/ResourceActionType.js.map +1 -0
- package/lib/resource/schema/ResourceStatus.js +5 -3
- package/lib/resource/schema/ResourceStatus.js.map +1 -0
- package/lib/resource/schema/ResourceType.js +5 -3
- package/lib/resource/schema/ResourceType.js.map +1 -0
- package/lib/resource/schema/index.js +1 -0
- package/lib/resource/schema/index.js.map +1 -0
- package/lib/resource/schema/types.js +16 -20
- package/lib/resource/schema/types.js.map +1 -0
- package/lib/s3/formatS3Url.js +65 -0
- package/lib/s3/formatS3Url.js.map +1 -0
- package/lib/s3/formatS3Url.test.js +262 -0
- package/lib/s3/index.js +3 -0
- package/lib/s3/index.js.map +1 -0
- package/lib/s3/parseS3Url.js +65 -0
- package/lib/s3/parseS3Url.js.map +1 -0
- package/lib/s3/parseS3Url.test.js +270 -0
- package/lib/schema/SchemaRegistry.js +38 -38
- package/lib/schema/SchemaRegistry.js.map +1 -0
- package/lib/schema/TypeSchema.d.js +2 -0
- package/lib/schema/TypeSchema.d.js.map +1 -0
- package/lib/schema/createSchemaData.js +26 -125
- package/lib/schema/createSchemaData.js.map +1 -0
- package/lib/schema/findJsonSchemaByPath.js +13 -36
- package/lib/schema/findJsonSchemaByPath.js.map +1 -0
- package/lib/schema/formatZodError.js +140 -0
- package/lib/schema/formatZodError.js.map +1 -0
- package/lib/schema/formatZodError.test.js +196 -0
- package/lib/schema/getSchemaCache.js +5 -5
- package/lib/schema/getSchemaCache.js.map +1 -0
- package/lib/schema/getSchemaOptions.js +8 -11
- package/lib/schema/getSchemaOptions.js.map +1 -0
- package/lib/schema/index.js +2 -1
- package/lib/schema/index.js.map +1 -0
- package/lib/schema/toJsonSchema.js +47 -290
- package/lib/schema/toJsonSchema.js.map +1 -0
- package/lib/schema/validate.js +33 -45
- package/lib/schema/validate.js.map +1 -0
- package/lib/tools/generateSchema.js +39 -197
- package/lib/tools/generateSchema.js.map +1 -0
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js +55 -143
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js.map +1 -0
- package/lib/utils/buildBaseUrl.js +13 -0
- package/lib/utils/buildBaseUrl.js.map +1 -0
- package/lib/utils/buildRedactorFormSchema.js +59 -0
- package/lib/utils/buildRedactorFormSchema.js.map +1 -0
- package/lib/utils/getEstimateProcessTime.js +12 -11
- package/lib/utils/getEstimateProcessTime.js.map +1 -0
- package/lib/utils/index.js +3 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/resolveFeatureOptions.js +12 -0
- package/lib/utils/resolveFeatureOptions.js.map +1 -0
- package/package.json +61 -13
- package/src/ai/qwen3vl/index.ts +1 -0
- package/src/ai/qwen3vl/utils.ts +36 -0
- package/src/ai/vision/DocLayoutElementTypeSchema.ts +30 -0
- package/src/ai/vision/ImageAnnotationSchema.ts +60 -0
- package/src/ai/vision/index.ts +2 -0
- package/src/ai/vision/resolveImageAnnotation.ts +135 -0
- package/src/cn/ChineseResidentIdNo.test.ts +1 -1
- package/src/cn/ChineseResidentIdNo.ts +8 -0
- package/src/cn/DivisionCode.test.ts +1 -1
- package/src/cn/DivisionCode.ts +8 -0
- package/src/cn/UnifiedSocialCreditCode.test.ts +1 -1
- package/src/cn/UnifiedSocialCreditCode.ts +15 -0
- package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +23 -0
- package/src/cn/formatChineseAmount.ts +61 -0
- package/src/cn/index.ts +7 -1
- package/src/cn/parseChineseNumber.test.ts +159 -0
- package/src/cn/parseChineseNumber.ts +97 -0
- package/src/cn/pinyin/cartesianProduct.test.ts +64 -0
- package/src/cn/pinyin/cartesianProduct.ts +24 -0
- package/src/cn/pinyin/data.json +23573 -0
- package/src/cn/pinyin/loader.ts +12 -0
- package/src/cn/pinyin/preload.ts +3 -0
- package/src/cn/pinyin/toPinyin.test.ts +12 -0
- package/src/cn/pinyin/toPinyinPure.ts +43 -0
- package/src/cn/pinyin/transform.ts +12 -0
- package/src/consola/formatLogObject.test.ts +27 -0
- package/src/consola/formatLogObject.ts +34 -6
- package/src/dayjs/dayjs.ts +18 -18
- package/src/dayjs/index.ts +3 -1
- package/src/dayjs/parseRelativeTime.test.ts +185 -0
- package/src/dayjs/parseRelativeTime.ts +115 -0
- package/src/dayjs/resolveRelativeTime.test.ts +357 -0
- package/src/dayjs/resolveRelativeTime.ts +167 -0
- package/src/emittery/emitter.ts +9 -0
- package/src/emittery/index.ts +1 -0
- package/src/fs/FileSystemError.ts +26 -0
- package/src/fs/IFileSystem.d.ts +102 -0
- package/src/fs/MemoryFileSystem.test.ts +37 -0
- package/src/fs/createBrowserFileSystem.ts +291 -0
- package/src/fs/createMemoryFileSystem.ts +604 -0
- package/src/fs/createSandboxFileSystem.ts +136 -0
- package/src/fs/createWebDavFileSystem.ts +172 -0
- package/src/fs/findMimeType.ts +23 -0
- package/src/fs/index.ts +8 -0
- package/src/fs/orpc/FileSystemContract.ts +92 -0
- package/src/fs/orpc/createContractClientFileSystem.ts +115 -0
- package/src/fs/orpc/index.ts +2 -0
- package/src/fs/orpc/server/createFileSystemContractImpl.ts +64 -0
- package/src/fs/orpc/server/index.ts +1 -0
- package/src/fs/s3/createS3MiniFileSystem.ts +830 -0
- package/src/fs/s3/index.ts +1 -0
- package/src/fs/s3/s3mini.test.ts +264 -0
- package/src/fs/scandir.ts +75 -0
- package/src/fs/server/createDatabaseFileSystem.ts +668 -0
- package/src/fs/server/createNodeFileSystem.ts +499 -0
- package/src/fs/server/dbfs.test.ts +47 -0
- package/src/fs/server/index.ts +1 -0
- package/src/fs/server/loadTestDatabase.ts +131 -0
- package/src/fs/tests/runFileSystemTest.ts +288 -0
- package/src/fs/types.ts +29 -0
- package/src/fs/utils/getFileUrl.ts +44 -0
- package/src/fs/utils.ts +23 -0
- package/src/jsonschema/JsonSchema.ts +118 -110
- package/src/jsonschema/forEachJsonSchema.ts +50 -0
- package/src/jsonschema/index.ts +1 -0
- package/src/orpc/createOpenApiContractClient.ts +52 -0
- package/src/orpc/createRpcContractClient.ts +50 -0
- package/src/orpc/index.ts +2 -0
- package/src/orpc/resolveLinkPlugins.ts +29 -0
- package/src/password/PHC.ts +3 -3
- package/src/password/Password.test.ts +1 -1
- package/src/password/createPBKDF2PasswordAlgorithm.ts +2 -2
- package/src/resource/schema/AnyResourceSchema.ts +16 -2
- package/src/s3/formatS3Url.test.ts +254 -0
- package/src/s3/formatS3Url.ts +84 -0
- package/src/s3/index.ts +2 -0
- package/src/s3/parseS3Url.test.ts +258 -0
- package/src/s3/parseS3Url.ts +88 -0
- package/src/schema/SchemaRegistry.ts +35 -33
- package/src/schema/formatZodError.test.ts +196 -0
- package/src/schema/formatZodError.ts +151 -0
- package/src/schema/getSchemaOptions.ts +2 -2
- package/src/schema/index.ts +1 -1
- package/src/utils/buildBaseUrl.ts +12 -0
- package/src/utils/buildRedactorFormSchema.ts +85 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/resolveFeatureOptions.ts +14 -0
- package/src/cn/ChineseResidentIdNo.mod.ts +0 -7
- package/src/cn/DivisionCode.mod.ts +0 -7
- package/src/cn/UnifiedSocialCreditCode.mod.ts +0 -7
- package/src/cn/mod.ts +0 -3
- package/src/schema/SchemaRegistry.mod.ts +0 -1
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
import { computeIfAbsent } from "@wener/utils";
|
|
2
|
+
import { basename, dirname, normalize } from "pathe";
|
|
3
|
+
import { findMimeType } from "./findMimeType.js";
|
|
4
|
+
export function createMemoryFileSystem(options = {}) {
|
|
5
|
+
return new MemFS(options);
|
|
6
|
+
}
|
|
7
|
+
let MemoryFileSystemError = class MemoryFileSystemError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
constructor(message, code) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "MemoryFileSystemError";
|
|
12
|
+
this.code = code;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
let MemFS = class MemFS {
|
|
16
|
+
root;
|
|
17
|
+
cache = new WeakMap();
|
|
18
|
+
constructor({ root } = {}) {
|
|
19
|
+
this.root = root || {
|
|
20
|
+
name: "",
|
|
21
|
+
kind: "directory",
|
|
22
|
+
path: "/",
|
|
23
|
+
directory: "",
|
|
24
|
+
children: [],
|
|
25
|
+
size: 0,
|
|
26
|
+
mtime: Date.now(),
|
|
27
|
+
meta: {}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 核心辅助方法:通过路径查找节点
|
|
32
|
+
* @returns A tuple: [foundNode, parentNode, finalName]
|
|
33
|
+
*/ _getNodeByPath(path) {
|
|
34
|
+
if (!path || typeof path !== "string") {
|
|
35
|
+
throw new MemoryFileSystemError("Invalid path: path must be a non-empty string", "EINVAL");
|
|
36
|
+
}
|
|
37
|
+
const normalized = normalize(path);
|
|
38
|
+
if (normalized === "/") {
|
|
39
|
+
// the parent of root is itself
|
|
40
|
+
return [
|
|
41
|
+
this.root,
|
|
42
|
+
this.root,
|
|
43
|
+
""
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
const parts = normalized.split("/").filter((p) => p);
|
|
47
|
+
if (parts.length === 0) {
|
|
48
|
+
return [
|
|
49
|
+
this.root,
|
|
50
|
+
this.root,
|
|
51
|
+
""
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
const finalName = parts.pop();
|
|
55
|
+
let current = this.root;
|
|
56
|
+
for (const part of parts) {
|
|
57
|
+
if (!part)
|
|
58
|
+
continue; // skip empty parts
|
|
59
|
+
const found = current.children.find((child) => child.name === part);
|
|
60
|
+
if (!found || found.kind !== "directory") {
|
|
61
|
+
return [
|
|
62
|
+
null,
|
|
63
|
+
null,
|
|
64
|
+
finalName
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
current = found;
|
|
68
|
+
}
|
|
69
|
+
const node = current.children.find((child) => child.name === finalName) ?? null;
|
|
70
|
+
return [
|
|
71
|
+
node,
|
|
72
|
+
current,
|
|
73
|
+
finalName
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 核心辅助方法:查找或创建目录
|
|
78
|
+
*/ _findOrCreateDirectory(path) {
|
|
79
|
+
if (!path || typeof path !== "string") {
|
|
80
|
+
throw new MemoryFileSystemError("Invalid path: path must be a non-empty string", "EINVAL");
|
|
81
|
+
}
|
|
82
|
+
const normalized = normalize(path);
|
|
83
|
+
if (normalized === "/")
|
|
84
|
+
return this.root;
|
|
85
|
+
const parts = normalized.split("/").filter((p) => p);
|
|
86
|
+
if (parts.length === 0)
|
|
87
|
+
return this.root;
|
|
88
|
+
let current = this.root;
|
|
89
|
+
let currentPath = "";
|
|
90
|
+
for (const part of parts) {
|
|
91
|
+
if (!part)
|
|
92
|
+
continue; // skip empty parts
|
|
93
|
+
currentPath = `${currentPath}/${part}`;
|
|
94
|
+
let found = current.children.find((child) => child.name === part);
|
|
95
|
+
if (!found) {
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
const newDir = {
|
|
98
|
+
name: part,
|
|
99
|
+
kind: "directory",
|
|
100
|
+
path: currentPath,
|
|
101
|
+
directory: dirname(currentPath),
|
|
102
|
+
children: [],
|
|
103
|
+
size: 0,
|
|
104
|
+
mtime: now,
|
|
105
|
+
meta: {}
|
|
106
|
+
};
|
|
107
|
+
current.children.push(newDir);
|
|
108
|
+
current = newDir;
|
|
109
|
+
}
|
|
110
|
+
else if (found.kind !== "directory") {
|
|
111
|
+
throw new MemoryFileSystemError(`Path conflict: ${currentPath} is a file`, "ENOTDIR");
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
current = found;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return current;
|
|
118
|
+
}
|
|
119
|
+
async stat(path, options) {
|
|
120
|
+
if (options?.signal?.aborted) {
|
|
121
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
122
|
+
}
|
|
123
|
+
const [node] = this._getNodeByPath(path);
|
|
124
|
+
if (!node) {
|
|
125
|
+
throw new MemoryFileSystemError(`File not found: ${path}`, "ENOENT");
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
...node
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async exists(path) {
|
|
132
|
+
const [node] = this._getNodeByPath(path);
|
|
133
|
+
return !!node;
|
|
134
|
+
}
|
|
135
|
+
async readdir(path, options) {
|
|
136
|
+
if (options?.signal?.aborted) {
|
|
137
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
138
|
+
}
|
|
139
|
+
const [node] = this._getNodeByPath(path);
|
|
140
|
+
if (!node) {
|
|
141
|
+
throw new MemoryFileSystemError(`Directory not found: ${path}`, "ENOENT");
|
|
142
|
+
}
|
|
143
|
+
if (node.kind !== "directory") {
|
|
144
|
+
throw new MemoryFileSystemError(`Not a directory: ${path}`, "ENOTDIR");
|
|
145
|
+
}
|
|
146
|
+
// 返回副本
|
|
147
|
+
return node.children.map((child) => ({
|
|
148
|
+
...child
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
async mkdir(path, options) {
|
|
152
|
+
if (options?.signal?.aborted) {
|
|
153
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
154
|
+
}
|
|
155
|
+
const [node] = this._getNodeByPath(path);
|
|
156
|
+
if (node) {
|
|
157
|
+
if (node.kind === "file")
|
|
158
|
+
throw new MemoryFileSystemError(`File already exists: ${path}`, "EEXIST");
|
|
159
|
+
return; // 目录已存在
|
|
160
|
+
}
|
|
161
|
+
if (options?.recursive) {
|
|
162
|
+
this._findOrCreateDirectory(path);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const parentPath = dirname(path);
|
|
166
|
+
const [, parent] = this._getNodeByPath(parentPath);
|
|
167
|
+
if (!parent) {
|
|
168
|
+
throw new MemoryFileSystemError(`Parent directory does not exist: ${parentPath}`, "ENOENT");
|
|
169
|
+
}
|
|
170
|
+
this._findOrCreateDirectory(path);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async readFile(path, options) {
|
|
174
|
+
if (options?.signal?.aborted) {
|
|
175
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
176
|
+
}
|
|
177
|
+
const [node] = this._getNodeByPath(path);
|
|
178
|
+
if (!node) {
|
|
179
|
+
throw new MemoryFileSystemError(`File not found: ${path}`, "ENOENT");
|
|
180
|
+
}
|
|
181
|
+
if (node.kind !== "file") {
|
|
182
|
+
throw new MemoryFileSystemError(`Is a directory: ${path}`, "EISDIR");
|
|
183
|
+
}
|
|
184
|
+
const content = "content" in node ? node.content : "";
|
|
185
|
+
return options?.encoding === "text" ? content.toString() : Buffer.from(content);
|
|
186
|
+
}
|
|
187
|
+
async writeFile(path, data, options = {}) {
|
|
188
|
+
if (options?.signal?.aborted) {
|
|
189
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
190
|
+
}
|
|
191
|
+
if (!path || typeof path !== "string") {
|
|
192
|
+
throw new MemoryFileSystemError("Invalid path: path must be a non-empty string", "EINVAL");
|
|
193
|
+
}
|
|
194
|
+
if (data === null || data === undefined) {
|
|
195
|
+
throw new MemoryFileSystemError("Invalid data: data cannot be null or undefined", "EINVAL");
|
|
196
|
+
}
|
|
197
|
+
const { overwrite = true } = options;
|
|
198
|
+
const parentPath = dirname(path);
|
|
199
|
+
const filename = basename(path);
|
|
200
|
+
if (!filename) {
|
|
201
|
+
throw new MemoryFileSystemError("Invalid path: filename cannot be empty", "EINVAL");
|
|
202
|
+
}
|
|
203
|
+
const parent = this._findOrCreateDirectory(parentPath);
|
|
204
|
+
const nodeIndex = parent.children.findIndex((child) => child.name === filename);
|
|
205
|
+
const existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;
|
|
206
|
+
if (existingNode) {
|
|
207
|
+
if (!overwrite)
|
|
208
|
+
throw new MemoryFileSystemError(`File already exists: ${path}`, "EEXIST");
|
|
209
|
+
if (existingNode.kind === "directory")
|
|
210
|
+
throw new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, "EISDIR");
|
|
211
|
+
// 更新文件
|
|
212
|
+
existingNode.content = data;
|
|
213
|
+
existingNode.size = data.length;
|
|
214
|
+
existingNode.mtime = Date.now();
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
// 创建新文件
|
|
218
|
+
const now = Date.now();
|
|
219
|
+
const newFile = {
|
|
220
|
+
name: filename,
|
|
221
|
+
kind: "file",
|
|
222
|
+
path: path,
|
|
223
|
+
directory: parentPath,
|
|
224
|
+
content: data,
|
|
225
|
+
size: data.length,
|
|
226
|
+
mtime: now,
|
|
227
|
+
meta: {}
|
|
228
|
+
};
|
|
229
|
+
parent.children.push(newFile);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async rm(path, options = {}) {
|
|
233
|
+
if (options?.signal?.aborted) {
|
|
234
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
235
|
+
}
|
|
236
|
+
const { recursive = false, force = false } = options;
|
|
237
|
+
const [node, parent] = this._getNodeByPath(path);
|
|
238
|
+
if (!node) {
|
|
239
|
+
if (force)
|
|
240
|
+
return;
|
|
241
|
+
throw new MemoryFileSystemError(`File not found: ${path}`, "ENOENT");
|
|
242
|
+
}
|
|
243
|
+
if (node.kind === "directory" && node.children.length > 0 && !recursive) {
|
|
244
|
+
throw new MemoryFileSystemError(`Directory not empty: ${path}`, "ENOTEMPTY");
|
|
245
|
+
}
|
|
246
|
+
if (parent) {
|
|
247
|
+
const index = parent.children.findIndex((child) => child.name === node.name);
|
|
248
|
+
if (index !== -1) {
|
|
249
|
+
parent.children.splice(index, 1);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async rename(oldPath, newPath, options) {
|
|
254
|
+
if (options?.signal?.aborted) {
|
|
255
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
256
|
+
}
|
|
257
|
+
const [oldNode, oldParent, oldName] = this._getNodeByPath(oldPath);
|
|
258
|
+
if (!oldNode || !oldParent)
|
|
259
|
+
throw new MemoryFileSystemError(`Source not found: ${oldPath}`, "ENOENT");
|
|
260
|
+
const oldNodeIndex = oldParent.children.findIndex((c) => c.name === oldName);
|
|
261
|
+
oldParent.children.splice(oldNodeIndex, 1);
|
|
262
|
+
const newParentPath = dirname(newPath);
|
|
263
|
+
const newName = basename(newPath);
|
|
264
|
+
const newParent = this._findOrCreateDirectory(newParentPath);
|
|
265
|
+
const existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);
|
|
266
|
+
if (existingNodeIndex !== -1) {
|
|
267
|
+
if (!options?.overwrite)
|
|
268
|
+
throw new MemoryFileSystemError(`Destination exists: ${newPath}`, "EEXIST");
|
|
269
|
+
newParent.children.splice(existingNodeIndex, 1);
|
|
270
|
+
}
|
|
271
|
+
oldNode.name = newName;
|
|
272
|
+
oldNode.path = newPath;
|
|
273
|
+
oldNode.directory = newParentPath;
|
|
274
|
+
oldNode.mtime = Date.now();
|
|
275
|
+
newParent.children.push(oldNode);
|
|
276
|
+
}
|
|
277
|
+
async copy(srcPath, destPath, options) {
|
|
278
|
+
if (options?.signal?.aborted) {
|
|
279
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
280
|
+
}
|
|
281
|
+
const [srcNode] = this._getNodeByPath(srcPath);
|
|
282
|
+
if (!srcNode)
|
|
283
|
+
throw new MemoryFileSystemError(`Source not found: ${srcPath}`, "ENOENT");
|
|
284
|
+
const deepClone = (node) => JSON.parse(JSON.stringify(node));
|
|
285
|
+
const newNode = deepClone(srcNode);
|
|
286
|
+
const newParentPath = dirname(destPath);
|
|
287
|
+
const newName = basename(destPath);
|
|
288
|
+
const newParent = this._findOrCreateDirectory(newParentPath);
|
|
289
|
+
newNode.name = newName;
|
|
290
|
+
newNode.path = destPath;
|
|
291
|
+
newNode.directory = newParentPath;
|
|
292
|
+
const existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);
|
|
293
|
+
if (existingNodeIndex !== -1) {
|
|
294
|
+
if (!options?.overwrite)
|
|
295
|
+
throw new MemoryFileSystemError(`Destination exists: ${destPath}`, "EEXIST");
|
|
296
|
+
newParent.children[existingNodeIndex] = newNode;
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
newParent.children.push(newNode);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
createReadStream(path, options) {
|
|
303
|
+
const { signal, range } = options || {};
|
|
304
|
+
if (signal?.aborted) {
|
|
305
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
306
|
+
}
|
|
307
|
+
const [node] = this._getNodeByPath(path);
|
|
308
|
+
if (!node) {
|
|
309
|
+
throw new MemoryFileSystemError(`File not found: ${path}`, "ENOENT");
|
|
310
|
+
}
|
|
311
|
+
if (node.kind !== "file") {
|
|
312
|
+
throw new MemoryFileSystemError(`Is a directory: ${path}`, "EISDIR");
|
|
313
|
+
}
|
|
314
|
+
const content = Buffer.from("content" in node ? node.content : "");
|
|
315
|
+
const { Readable } = require("node:stream");
|
|
316
|
+
let data = content;
|
|
317
|
+
if (range) {
|
|
318
|
+
const start = range.start || 0;
|
|
319
|
+
const end = range.end || content.length - 1;
|
|
320
|
+
data = content.subarray(start, end + 1);
|
|
321
|
+
}
|
|
322
|
+
const stream = Readable.from([
|
|
323
|
+
data
|
|
324
|
+
]);
|
|
325
|
+
if (signal) {
|
|
326
|
+
signal.addEventListener("abort", () => {
|
|
327
|
+
stream.destroy(new MemoryFileSystemError("Operation aborted", "ABORT_ERR"));
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
return stream;
|
|
331
|
+
}
|
|
332
|
+
createWriteStream(path, options) {
|
|
333
|
+
const { signal, overwrite = true } = options || {};
|
|
334
|
+
if (signal?.aborted) {
|
|
335
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
336
|
+
}
|
|
337
|
+
const { Writable } = require("node:stream");
|
|
338
|
+
const chunks = [];
|
|
339
|
+
const self = this;
|
|
340
|
+
const stream = new Writable({
|
|
341
|
+
write(chunk, encoding, callback) {
|
|
342
|
+
if (signal?.aborted) {
|
|
343
|
+
callback(new MemoryFileSystemError("Operation aborted", "ABORT_ERR"));
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
chunks.push(chunk);
|
|
347
|
+
callback();
|
|
348
|
+
},
|
|
349
|
+
final(callback) {
|
|
350
|
+
if (signal?.aborted) {
|
|
351
|
+
callback(new MemoryFileSystemError("Operation aborted", "ABORT_ERR"));
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
try {
|
|
355
|
+
const content = Buffer.concat(chunks);
|
|
356
|
+
const parentPath = dirname(path);
|
|
357
|
+
const filename = basename(path);
|
|
358
|
+
const parent = self._findOrCreateDirectory(parentPath);
|
|
359
|
+
const nodeIndex = parent.children.findIndex((child) => child.name === filename);
|
|
360
|
+
const existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;
|
|
361
|
+
if (existingNode) {
|
|
362
|
+
if (!overwrite) {
|
|
363
|
+
callback(new MemoryFileSystemError(`File already exists: ${path}`, "EEXIST"));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (existingNode.kind === "directory") {
|
|
367
|
+
callback(new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, "EISDIR"));
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
existingNode.content = content;
|
|
371
|
+
existingNode.size = content.length;
|
|
372
|
+
existingNode.mtime = Date.now();
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
const now = Date.now();
|
|
376
|
+
const newFile = {
|
|
377
|
+
name: filename,
|
|
378
|
+
kind: "file",
|
|
379
|
+
path: path,
|
|
380
|
+
directory: parentPath,
|
|
381
|
+
content: content,
|
|
382
|
+
size: content.length,
|
|
383
|
+
mtime: now,
|
|
384
|
+
meta: {}
|
|
385
|
+
};
|
|
386
|
+
parent.children.push(newFile);
|
|
387
|
+
}
|
|
388
|
+
callback();
|
|
389
|
+
}
|
|
390
|
+
catch (error) {
|
|
391
|
+
callback(error instanceof Error ? error : new MemoryFileSystemError("Unknown error", "UNKNOWN"));
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
if (signal) {
|
|
396
|
+
signal.addEventListener("abort", () => {
|
|
397
|
+
stream.destroy(new MemoryFileSystemError("Operation aborted", "ABORT_ERR"));
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
return stream;
|
|
401
|
+
}
|
|
402
|
+
getUrl(file) {
|
|
403
|
+
let node;
|
|
404
|
+
if (typeof file === "string") {
|
|
405
|
+
[node] = this._getNodeByPath(file);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
node = file;
|
|
409
|
+
}
|
|
410
|
+
let mf = node;
|
|
411
|
+
if (mf.content) {
|
|
412
|
+
let c = computeIfAbsent(this.cache, mf, () => ({}));
|
|
413
|
+
if (!c.url) {
|
|
414
|
+
let mime = findMimeType(mf.name) || "application/octet-stream";
|
|
415
|
+
c.url = URL.createObjectURL(new Blob([
|
|
416
|
+
mf.content
|
|
417
|
+
], {
|
|
418
|
+
type: mime
|
|
419
|
+
}));
|
|
420
|
+
}
|
|
421
|
+
return c.url;
|
|
422
|
+
}
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
createReadableStream(path, options) {
|
|
426
|
+
const { signal, range } = options || {};
|
|
427
|
+
if (signal?.aborted) {
|
|
428
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
429
|
+
}
|
|
430
|
+
const [node] = this._getNodeByPath(path);
|
|
431
|
+
if (!node) {
|
|
432
|
+
throw new MemoryFileSystemError(`File not found: ${path}`, "ENOENT");
|
|
433
|
+
}
|
|
434
|
+
if (node.kind !== "file") {
|
|
435
|
+
throw new MemoryFileSystemError(`Is a directory: ${path}`, "EISDIR");
|
|
436
|
+
}
|
|
437
|
+
const content = Buffer.from("content" in node ? node.content : "");
|
|
438
|
+
let data = content;
|
|
439
|
+
if (range) {
|
|
440
|
+
const start = range.start || 0;
|
|
441
|
+
const end = range.end || content.length - 1;
|
|
442
|
+
data = content.subarray(start, end + 1);
|
|
443
|
+
}
|
|
444
|
+
const stream = new ReadableStream({
|
|
445
|
+
start(controller) {
|
|
446
|
+
controller.enqueue(data);
|
|
447
|
+
controller.close();
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
if (signal) {
|
|
451
|
+
signal.addEventListener("abort", () => {
|
|
452
|
+
stream.cancel(new MemoryFileSystemError("Operation aborted", "ABORT_ERR"));
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
return stream;
|
|
456
|
+
}
|
|
457
|
+
createWritableStream(path, options) {
|
|
458
|
+
const { signal, overwrite = true } = options || {};
|
|
459
|
+
if (signal?.aborted) {
|
|
460
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
461
|
+
}
|
|
462
|
+
const chunks = [];
|
|
463
|
+
const self = this;
|
|
464
|
+
const stream = new WritableStream({
|
|
465
|
+
write(chunk) {
|
|
466
|
+
if (signal?.aborted) {
|
|
467
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
468
|
+
}
|
|
469
|
+
chunks.push(chunk);
|
|
470
|
+
},
|
|
471
|
+
close() {
|
|
472
|
+
if (signal?.aborted) {
|
|
473
|
+
throw new MemoryFileSystemError("Operation aborted", "ABORT_ERR");
|
|
474
|
+
}
|
|
475
|
+
const content = Buffer.concat(chunks);
|
|
476
|
+
const parentPath = dirname(path);
|
|
477
|
+
const filename = basename(path);
|
|
478
|
+
const parent = self._findOrCreateDirectory(parentPath);
|
|
479
|
+
const nodeIndex = parent.children.findIndex((child) => child.name === filename);
|
|
480
|
+
const existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;
|
|
481
|
+
if (existingNode) {
|
|
482
|
+
if (!overwrite) {
|
|
483
|
+
throw new MemoryFileSystemError(`File already exists: ${path}`, "EEXIST");
|
|
484
|
+
}
|
|
485
|
+
if (existingNode.kind === "directory") {
|
|
486
|
+
throw new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, "EISDIR");
|
|
487
|
+
}
|
|
488
|
+
existingNode.content = content;
|
|
489
|
+
existingNode.size = content.length;
|
|
490
|
+
existingNode.mtime = Date.now();
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
const now = Date.now();
|
|
494
|
+
const newFile = {
|
|
495
|
+
name: filename,
|
|
496
|
+
kind: "file",
|
|
497
|
+
path: path,
|
|
498
|
+
directory: parentPath,
|
|
499
|
+
content: content,
|
|
500
|
+
size: content.length,
|
|
501
|
+
mtime: now,
|
|
502
|
+
meta: {}
|
|
503
|
+
};
|
|
504
|
+
parent.children.push(newFile);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
if (signal) {
|
|
509
|
+
signal.addEventListener("abort", () => {
|
|
510
|
+
stream.abort(new MemoryFileSystemError("Operation aborted", "ABORT_ERR"));
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
return stream;
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
//# sourceMappingURL=createMemoryFileSystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/fs/createMemoryFileSystem.ts"],"sourcesContent":["import type { Readable, Writable } from 'node:stream';\nimport { computeIfAbsent } from '@wener/utils';\nimport { basename, dirname, normalize } from 'pathe';\nimport { findMimeType } from './findMimeType';\nimport type {\n\tCopyOptions,\n\tCreateReadStreamOptions,\n\tCreateWriteStreamOptions,\n\tIFileStat,\n\tIFileSystem,\n\tMkdirOptions,\n\tReadFileOptions,\n\tRenameOptions,\n\tRmOptions,\n\tWriteFileOptions,\n} from './IFileSystem';\n\ntype MemoryNode = MemoryFile | MemoryDirectory;\n\ntype MemoryFile = IFileStat & {\n\tkind: 'file';\n\tcontent: string | Buffer;\n};\n\ntype MemoryDirectory = IFileStat & {\n\tkind: 'directory';\n\tchildren: MemoryNode[];\n};\n\nexport function createMemoryFileSystem(\n\toptions: {\n\t\troot?: MemoryDirectory;\n\t} = {},\n): IFileSystem {\n\treturn new MemFS(options);\n}\n\nclass MemoryFileSystemError extends Error {\n\tcode?: string;\n\n\tconstructor(message: string, code?: string) {\n\t\tsuper(message);\n\t\tthis.name = 'MemoryFileSystemError';\n\t\tthis.code = code;\n\t}\n}\n\ntype Cache = {\n\turl?: string;\n};\n\nclass MemFS implements IFileSystem {\n\tprivate readonly root: MemoryDirectory;\n\n\tprivate readonly cache = new WeakMap<MemoryNode, Cache>();\n\n\tconstructor({\n\t\troot,\n\t}: {\n\t\troot?: MemoryDirectory;\n\t} = {}) {\n\t\tthis.root = root || {\n\t\t\tname: '',\n\t\t\tkind: 'directory',\n\t\t\tpath: '/',\n\t\t\tdirectory: '',\n\t\t\tchildren: [],\n\t\t\tsize: 0,\n\t\t\tmtime: Date.now(),\n\t\t\tmeta: {},\n\t\t};\n\t}\n\n\t/**\n\t * 核心辅助方法:通过路径查找节点\n\t * @returns A tuple: [foundNode, parentNode, finalName]\n\t */\n\tprivate _getNodeByPath(path: string): [MemoryNode | null, MemoryDirectory | null, string] {\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tconst normalized = normalize(path);\n\t\tif (normalized === '/') {\n\t\t\t// the parent of root is itself\n\t\t\treturn [this.root, this.root, ''];\n\t\t}\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\t\tif (parts.length === 0) {\n\t\t\treturn [this.root, this.root, ''];\n\t\t}\n\n\t\tconst finalName = parts.pop()!;\n\n\t\tlet current: MemoryDirectory = this.root;\n\t\tfor (const part of parts) {\n\t\t\tif (!part) continue; // skip empty parts\n\n\t\t\tconst found = current.children.find((child) => child.name === part);\n\t\t\tif (!found || found.kind !== 'directory') {\n\t\t\t\treturn [null, null, finalName];\n\t\t\t}\n\t\t\tcurrent = found;\n\t\t}\n\n\t\tconst node = current.children.find((child) => child.name === finalName) ?? null;\n\t\treturn [node, current, finalName];\n\t}\n\n\t/**\n\t * 核心辅助方法:查找或创建目录\n\t */\n\tprivate _findOrCreateDirectory(path: string): MemoryDirectory {\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tconst normalized = normalize(path);\n\t\tif (normalized === '/') return this.root;\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\t\tif (parts.length === 0) return this.root;\n\n\t\tlet current: MemoryDirectory = this.root;\n\t\tlet currentPath = '';\n\n\t\tfor (const part of parts) {\n\t\t\tif (!part) continue; // skip empty parts\n\n\t\t\tcurrentPath = `${currentPath}/${part}`;\n\t\t\tlet found = current.children.find((child) => child.name === part);\n\t\t\tif (!found) {\n\t\t\t\tconst now = Date.now();\n\t\t\t\tconst newDir: MemoryDirectory = {\n\t\t\t\t\tname: part,\n\t\t\t\t\tkind: 'directory',\n\t\t\t\t\tpath: currentPath,\n\t\t\t\t\tdirectory: dirname(currentPath),\n\t\t\t\t\tchildren: [],\n\t\t\t\t\tsize: 0,\n\t\t\t\t\tmtime: now,\n\t\t\t\t\tmeta: {},\n\t\t\t\t};\n\t\t\t\tcurrent.children.push(newDir);\n\t\t\t\tcurrent = newDir;\n\t\t\t} else if (found.kind !== 'directory') {\n\t\t\t\tthrow new MemoryFileSystemError(`Path conflict: ${currentPath} is a file`, 'ENOTDIR');\n\t\t\t} else {\n\t\t\t\tcurrent = found;\n\t\t\t}\n\t\t}\n\t\treturn current;\n\t}\n\n\tasync stat(path: string, options?: { signal?: AbortSignal }): Promise<IFileStat> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\treturn { ...node };\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\tconst [node] = this._getNodeByPath(path);\n\t\treturn !!node;\n\t}\n\n\tasync readdir(path: string, options?: { signal?: AbortSignal }): Promise<IFileStat[]> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`Directory not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'directory') {\n\t\t\tthrow new MemoryFileSystemError(`Not a directory: ${path}`, 'ENOTDIR');\n\t\t}\n\t\t// 返回副本\n\t\treturn node.children.map((child) => ({ ...child }));\n\t}\n\n\tasync mkdir(path: string, options?: MkdirOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (node) {\n\t\t\tif (node.kind === 'file') throw new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\treturn; // 目录已存在\n\t\t}\n\n\t\tif (options?.recursive) {\n\t\t\tthis._findOrCreateDirectory(path);\n\t\t} else {\n\t\t\tconst parentPath = dirname(path);\n\t\t\tconst [, parent] = this._getNodeByPath(parentPath);\n\t\t\tif (!parent) {\n\t\t\t\tthrow new MemoryFileSystemError(`Parent directory does not exist: ${parentPath}`, 'ENOENT');\n\t\t\t}\n\t\t\tthis._findOrCreateDirectory(path);\n\t\t}\n\t}\n\n\treadFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;\n\treadFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;\n\tasync readFile(path: string, options?: ReadFileOptions): Promise<string | Uint8Array> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = 'content' in node ? node.content : '';\n\t\treturn options?.encoding === 'text' ? content.toString() : Buffer.from(content);\n\t}\n\n\tasync writeFile(path: string, data: string | Buffer, options: WriteFileOptions = {}): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: path must be a non-empty string', 'EINVAL');\n\t\t}\n\n\t\tif (data === null || data === undefined) {\n\t\t\tthrow new MemoryFileSystemError('Invalid data: data cannot be null or undefined', 'EINVAL');\n\t\t}\n\n\t\tconst { overwrite = true } = options;\n\t\tconst parentPath = dirname(path);\n\t\tconst filename = basename(path);\n\n\t\tif (!filename) {\n\t\t\tthrow new MemoryFileSystemError('Invalid path: filename cannot be empty', 'EINVAL');\n\t\t}\n\n\t\tconst parent = this._findOrCreateDirectory(parentPath);\n\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\tif (existingNode) {\n\t\t\tif (!overwrite) throw new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\tif (existingNode.kind === 'directory')\n\t\t\t\tthrow new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR');\n\n\t\t\t// 更新文件\n\t\t\texistingNode.content = data;\n\t\t\texistingNode.size = data.length;\n\t\t\texistingNode.mtime = Date.now();\n\t\t} else {\n\t\t\t// 创建新文件\n\t\t\tconst now = Date.now();\n\t\t\tconst newFile: MemoryFile = {\n\t\t\t\tname: filename,\n\t\t\t\tkind: 'file',\n\t\t\t\tpath: path,\n\t\t\t\tdirectory: parentPath,\n\t\t\t\tcontent: data,\n\t\t\t\tsize: data.length,\n\t\t\t\tmtime: now,\n\t\t\t\tmeta: {},\n\t\t\t};\n\t\t\tparent.children.push(newFile);\n\t\t}\n\t}\n\n\tasync rm(path: string, options: RmOptions = {}): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst { recursive = false, force = false } = options;\n\t\tconst [node, parent] = this._getNodeByPath(path);\n\n\t\tif (!node) {\n\t\t\tif (force) return;\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\n\t\tif (node.kind === 'directory' && node.children.length > 0 && !recursive) {\n\t\t\tthrow new MemoryFileSystemError(`Directory not empty: ${path}`, 'ENOTEMPTY');\n\t\t}\n\n\t\tif (parent) {\n\t\t\tconst index = parent.children.findIndex((child) => child.name === node.name);\n\t\t\tif (index !== -1) {\n\t\t\t\tparent.children.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync rename(oldPath: string, newPath: string, options?: RenameOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [oldNode, oldParent, oldName] = this._getNodeByPath(oldPath);\n\t\tif (!oldNode || !oldParent) throw new MemoryFileSystemError(`Source not found: ${oldPath}`, 'ENOENT');\n\n\t\tconst oldNodeIndex = oldParent.children.findIndex((c) => c.name === oldName);\n\t\toldParent.children.splice(oldNodeIndex, 1);\n\n\t\tconst newParentPath = dirname(newPath);\n\t\tconst newName = basename(newPath);\n\t\tconst newParent = this._findOrCreateDirectory(newParentPath);\n\n\t\tconst existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);\n\t\tif (existingNodeIndex !== -1) {\n\t\t\tif (!options?.overwrite) throw new MemoryFileSystemError(`Destination exists: ${newPath}`, 'EEXIST');\n\t\t\tnewParent.children.splice(existingNodeIndex, 1);\n\t\t}\n\n\t\toldNode.name = newName;\n\t\toldNode.path = newPath;\n\t\toldNode.directory = newParentPath;\n\t\toldNode.mtime = Date.now();\n\t\tnewParent.children.push(oldNode);\n\t}\n\n\tasync copy(srcPath: string, destPath: string, options?: CopyOptions): Promise<void> {\n\t\tif (options?.signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [srcNode] = this._getNodeByPath(srcPath);\n\t\tif (!srcNode) throw new MemoryFileSystemError(`Source not found: ${srcPath}`, 'ENOENT');\n\n\t\tconst deepClone = <T extends MemoryNode>(node: T): T => JSON.parse(JSON.stringify(node));\n\t\tconst newNode = deepClone(srcNode);\n\n\t\tconst newParentPath = dirname(destPath);\n\t\tconst newName = basename(destPath);\n\t\tconst newParent = this._findOrCreateDirectory(newParentPath);\n\n\t\tnewNode.name = newName;\n\t\tnewNode.path = destPath;\n\t\tnewNode.directory = newParentPath;\n\n\t\tconst existingNodeIndex = newParent.children.findIndex((c) => c.name === newName);\n\t\tif (existingNodeIndex !== -1) {\n\t\t\tif (!options?.overwrite) throw new MemoryFileSystemError(`Destination exists: ${destPath}`, 'EEXIST');\n\t\t\tnewParent.children[existingNodeIndex] = newNode;\n\t\t} else {\n\t\t\tnewParent.children.push(newNode);\n\t\t}\n\t}\n\n\tcreateReadStream(path: string, options?: CreateReadStreamOptions): Readable {\n\t\tconst { signal, range } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = Buffer.from('content' in node ? node.content : '');\n\t\tconst { Readable } = require('node:stream');\n\n\t\tlet data = content;\n\t\tif (range) {\n\t\t\tconst start = range.start || 0;\n\t\t\tconst end = range.end || content.length - 1;\n\t\t\tdata = content.subarray(start, end + 1);\n\t\t}\n\n\t\tconst stream = Readable.from([data]);\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.destroy(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tcreateWriteStream(path: string, options?: CreateWriteStreamOptions): Writable {\n\t\tconst { signal, overwrite = true } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst { Writable } = require('node:stream');\n\t\tconst chunks: Buffer[] = [];\n\n\t\tconst self = this;\n\t\tconst stream = new Writable({\n\t\t\twrite(chunk: Buffer, encoding: BufferEncoding, callback: (error?: Error | null) => void) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tcallback(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tchunks.push(chunk);\n\t\t\t\tcallback();\n\t\t\t},\n\t\t\tfinal(callback: (error?: Error | null) => void) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tcallback(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst content = Buffer.concat(chunks);\n\t\t\t\t\tconst parentPath = dirname(path);\n\t\t\t\t\tconst filename = basename(path);\n\t\t\t\t\tconst parent = self._findOrCreateDirectory(parentPath);\n\n\t\t\t\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\t\t\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\t\t\t\tif (existingNode) {\n\t\t\t\t\t\tif (!overwrite) {\n\t\t\t\t\t\t\tcallback(new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST'));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (existingNode.kind === 'directory') {\n\t\t\t\t\t\t\tcallback(new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR'));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\texistingNode.content = content;\n\t\t\t\t\t\texistingNode.size = content.length;\n\t\t\t\t\t\texistingNode.mtime = Date.now();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\t\tconst newFile: MemoryFile = {\n\t\t\t\t\t\t\tname: filename,\n\t\t\t\t\t\t\tkind: 'file',\n\t\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\t\tdirectory: parentPath,\n\t\t\t\t\t\t\tcontent: content,\n\t\t\t\t\t\t\tsize: content.length,\n\t\t\t\t\t\t\tmtime: now,\n\t\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t\t};\n\t\t\t\t\t\tparent.children.push(newFile);\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tcallback(error instanceof Error ? error : new MemoryFileSystemError('Unknown error', 'UNKNOWN'));\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.destroy(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tgetUrl(file: IFileStat | string) {\n\t\tlet node: IFileStat | null;\n\t\tif (typeof file === 'string') {\n\t\t\t[node] = this._getNodeByPath(file);\n\t\t} else {\n\t\t\tnode = file;\n\t\t}\n\t\tlet mf = node as MemoryFile;\n\t\tif (mf.content) {\n\t\t\tlet c = computeIfAbsent(this.cache, mf, () => ({}) as Cache);\n\t\t\tif (!c.url) {\n\t\t\t\tlet mime = findMimeType(mf.name) || 'application/octet-stream';\n\t\t\t\tc.url = URL.createObjectURL(new Blob([mf.content], { type: mime }));\n\t\t\t}\n\n\t\t\treturn c.url;\n\t\t}\n\t\treturn;\n\t}\n\n\tcreateReadableStream(path: string, options?: CreateReadStreamOptions): ReadableStream {\n\t\tconst { signal, range } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst [node] = this._getNodeByPath(path);\n\t\tif (!node) {\n\t\t\tthrow new MemoryFileSystemError(`File not found: ${path}`, 'ENOENT');\n\t\t}\n\t\tif (node.kind !== 'file') {\n\t\t\tthrow new MemoryFileSystemError(`Is a directory: ${path}`, 'EISDIR');\n\t\t}\n\n\t\tconst content = Buffer.from('content' in node ? node.content : '');\n\n\t\tlet data = content;\n\t\tif (range) {\n\t\t\tconst start = range.start || 0;\n\t\t\tconst end = range.end || content.length - 1;\n\t\t\tdata = content.subarray(start, end + 1);\n\t\t}\n\n\t\tconst stream = new ReadableStream({\n\t\t\tstart(controller) {\n\t\t\t\tcontroller.enqueue(data);\n\t\t\t\tcontroller.close();\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.cancel(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n\n\tcreateWritableStream(path: string, options?: CreateWriteStreamOptions): WritableStream {\n\t\tconst { signal, overwrite = true } = options || {};\n\n\t\tif (signal?.aborted) {\n\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t}\n\n\t\tconst chunks: Buffer[] = [];\n\n\t\tconst self = this;\n\t\tconst stream = new WritableStream({\n\t\t\twrite(chunk: Buffer) {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t\t\t}\n\t\t\t\tchunks.push(chunk);\n\t\t\t},\n\t\t\tclose() {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tthrow new MemoryFileSystemError('Operation aborted', 'ABORT_ERR');\n\t\t\t\t}\n\n\t\t\t\tconst content = Buffer.concat(chunks);\n\t\t\t\tconst parentPath = dirname(path);\n\t\t\t\tconst filename = basename(path);\n\t\t\t\tconst parent = self._findOrCreateDirectory(parentPath);\n\n\t\t\t\tconst nodeIndex = parent.children.findIndex((child) => child.name === filename);\n\t\t\t\tconst existingNode = nodeIndex !== -1 ? parent.children[nodeIndex] : null;\n\n\t\t\t\tif (existingNode) {\n\t\t\t\t\tif (!overwrite) {\n\t\t\t\t\t\tthrow new MemoryFileSystemError(`File already exists: ${path}`, 'EEXIST');\n\t\t\t\t\t}\n\t\t\t\t\tif (existingNode.kind === 'directory') {\n\t\t\t\t\t\tthrow new MemoryFileSystemError(`Cannot overwrite a directory: ${path}`, 'EISDIR');\n\t\t\t\t\t}\n\n\t\t\t\t\texistingNode.content = content;\n\t\t\t\t\texistingNode.size = content.length;\n\t\t\t\t\texistingNode.mtime = Date.now();\n\t\t\t\t} else {\n\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\tconst newFile: MemoryFile = {\n\t\t\t\t\t\tname: filename,\n\t\t\t\t\t\tkind: 'file',\n\t\t\t\t\t\tpath: path,\n\t\t\t\t\t\tdirectory: parentPath,\n\t\t\t\t\t\tcontent: content,\n\t\t\t\t\t\tsize: content.length,\n\t\t\t\t\t\tmtime: now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t};\n\t\t\t\t\tparent.children.push(newFile);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (signal) {\n\t\t\tsignal.addEventListener('abort', () => {\n\t\t\t\tstream.abort(new MemoryFileSystemError('Operation aborted', 'ABORT_ERR'));\n\t\t\t});\n\t\t}\n\n\t\treturn stream;\n\t}\n}\n"],"names":["computeIfAbsent","basename","dirname","normalize","findMimeType","createMemoryFileSystem","options","MemFS","MemoryFileSystemError","Error","code","message","name","root","cache","WeakMap","kind","path","directory","children","size","mtime","Date","now","meta","_getNodeByPath","normalized","parts","split","filter","p","length","finalName","pop","current","part","found","find","child","node","_findOrCreateDirectory","currentPath","newDir","push","stat","signal","aborted","exists","readdir","map","mkdir","recursive","parentPath","parent","readFile","content","encoding","toString","Buffer","from","writeFile","data","undefined","overwrite","filename","nodeIndex","findIndex","existingNode","newFile","rm","force","index","splice","rename","oldPath","newPath","oldNode","oldParent","oldName","oldNodeIndex","c","newParentPath","newName","newParent","existingNodeIndex","copy","srcPath","destPath","srcNode","deepClone","JSON","parse","stringify","newNode","createReadStream","range","Readable","require","start","end","subarray","stream","addEventListener","destroy","createWriteStream","Writable","chunks","self","write","chunk","callback","final","concat","error","getUrl","file","mf","url","mime","URL","createObjectURL","Blob","type","createReadableStream","ReadableStream","controller","enqueue","close","cancel","createWritableStream","WritableStream","abort"],"mappings":"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"}
|