@wener/common 2.0.3 → 2.0.6
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 +1 -1
- package/lib/ai/qwen3vl/utils.js +15 -15
- package/lib/ai/qwen3vl/utils.js.map +1 -1
- package/lib/ai/vision/DocLayoutElementTypeSchema.js +22 -22
- package/lib/ai/vision/ImageAnnotationSchema.js +63 -47
- package/lib/ai/vision/index.js +2 -2
- package/lib/ai/vision/resolveImageAnnotation.js +81 -95
- package/lib/cn/ChineseResidentIdNo.js +55 -41
- package/lib/cn/ChineseResidentIdNo.js.map +1 -1
- package/lib/cn/ChineseResidentIdNo.mod.js +6 -1
- package/lib/cn/ChineseResidentIdNo.test.js +22 -21
- package/lib/cn/DivisionCode.js +220 -235
- package/lib/cn/DivisionCode.mod.js +6 -1
- package/lib/cn/DivisionCode.test.js +92 -121
- package/lib/cn/Mod11.js +18 -37
- package/lib/cn/Mod11.js.map +1 -1
- package/lib/cn/Mod31.js +23 -41
- package/lib/cn/UnifiedSocialCreditCode.js +143 -137
- package/lib/cn/UnifiedSocialCreditCode.mod.js +6 -1
- package/lib/cn/UnifiedSocialCreditCode.test.js +21 -15
- package/lib/cn/formatChineseAmount.js +46 -71
- package/lib/cn/index.js +6 -6
- package/lib/cn/mod.js +5 -3
- package/lib/cn/parseChineseNumber.js +81 -85
- package/lib/cn/parseChineseNumber.test.js +183 -261
- package/lib/cn/pinyin/cartesianProduct.js +19 -19
- package/lib/cn/pinyin/cartesianProduct.test.js +78 -178
- package/lib/cn/pinyin/loader.js +13 -11
- package/lib/cn/pinyin/preload.js +2 -1
- package/lib/cn/pinyin/toPinyin.test.js +149 -161
- package/lib/cn/pinyin/toPinyinPure.js +28 -23
- package/lib/cn/pinyin/transform.js +11 -11
- package/lib/cn/types.d.js +2 -2
- package/lib/consola/createStandardConsolaReporter.js +14 -15
- package/lib/consola/formatLogObject.js +149 -133
- package/lib/consola/formatLogObject.js.map +1 -1
- package/lib/consola/formatLogObject.test.js +167 -178
- package/lib/consola/index.js +2 -2
- package/lib/data/formatSort.js +14 -12
- package/lib/data/formatSort.test.js +33 -33
- package/lib/data/index.js +3 -3
- package/lib/data/maybeNumber.js +23 -23
- package/lib/data/maybeNumber.js.map +1 -1
- package/lib/data/parseSort.js +75 -68
- package/lib/data/parseSort.test.js +196 -187
- package/lib/data/resolvePagination.js +38 -39
- package/lib/data/resolvePagination.test.js +228 -218
- package/lib/data/types.d.js +2 -2
- package/lib/data/types.d.js.map +1 -1
- package/lib/dayjs/dayjs.js +20 -20
- package/lib/dayjs/formatDuration.js +56 -56
- package/lib/dayjs/formatDuration.js.map +1 -1
- package/lib/dayjs/formatDuration.test.js +63 -77
- package/lib/dayjs/index.js +4 -4
- package/lib/dayjs/parseDuration.js +21 -26
- package/lib/dayjs/parseRelativeTime.js +65 -66
- package/lib/dayjs/parseRelativeTime.test.js +227 -243
- package/lib/dayjs/resolveRelativeTime.js +74 -144
- package/lib/dayjs/resolveRelativeTime.js.map +1 -1
- package/lib/dayjs/resolveRelativeTime.test.js +296 -307
- package/lib/decimal/index.js +1 -1
- package/lib/decimal/parseDecimal.js +12 -12
- package/lib/drain3/Drain.js +321 -0
- package/lib/drain3/Drain.js.map +1 -0
- package/lib/drain3/LogCluster.js +38 -0
- package/lib/drain3/LogCluster.js.map +1 -0
- package/lib/drain3/Node.js +39 -0
- package/lib/drain3/Node.js.map +1 -0
- package/lib/drain3/TemplateMiner.js +205 -0
- package/lib/drain3/TemplateMiner.js.map +1 -0
- package/lib/drain3/index.js +31 -0
- package/lib/drain3/index.js.map +1 -0
- package/lib/drain3/persistence/FilePersistence.js +24 -0
- package/lib/drain3/persistence/FilePersistence.js.map +1 -0
- package/lib/drain3/persistence/MemoryPersistence.js +18 -0
- package/lib/drain3/persistence/MemoryPersistence.js.map +1 -0
- package/lib/drain3/persistence/PersistenceHandler.js +5 -0
- package/lib/drain3/persistence/PersistenceHandler.js.map +1 -0
- package/lib/drain3/types.js +7 -0
- package/lib/drain3/types.js.map +1 -0
- package/lib/emittery/emitter.js +7 -7
- package/lib/emittery/index.js +1 -1
- package/lib/foundation/schema/SexType.js +15 -12
- package/lib/foundation/schema/index.js +1 -1
- package/lib/foundation/schema/parseSexType.js +15 -16
- package/lib/foundation/schema/types.js +8 -6
- package/lib/fs/FileSystemError.js +18 -18
- package/lib/fs/IFileSystem.d.js +2 -2
- package/lib/fs/IFileSystem.d.js.map +1 -1
- package/lib/fs/MemoryFileSystem.test.js +172 -181
- package/lib/fs/createBrowserFileSystem.js +222 -233
- package/lib/fs/createBrowserFileSystem.js.map +1 -1
- package/lib/fs/createMemoryFileSystem.js +473 -510
- package/lib/fs/createMemoryFileSystem.js.map +1 -1
- package/lib/fs/createSandboxFileSystem.js +102 -101
- package/lib/fs/createSandboxFileSystem.js.map +1 -1
- package/lib/fs/createWebDavFileSystem.js +162 -132
- package/lib/fs/createWebDavFileSystem.js.map +1 -1
- package/lib/fs/createWebFileSystem.js +202 -0
- package/lib/fs/createWebFileSystem.js.map +1 -0
- package/lib/fs/findMimeType.js +14 -14
- package/lib/fs/findMimeType.js.map +1 -1
- package/lib/fs/index.js +7 -7
- package/lib/fs/index.js.map +1 -1
- package/lib/fs/minio/createMinioFileSystem.js +977 -0
- package/lib/fs/minio/createMinioFileSystem.js.map +1 -0
- package/lib/fs/minio/index.js +2 -0
- package/lib/fs/minio/index.js.map +1 -0
- package/lib/fs/orpc/FileSystemContract.js +57 -57
- package/lib/fs/orpc/createContractClientFileSystem.js +88 -88
- package/lib/fs/orpc/createContractClientFileSystem.js.map +1 -1
- package/lib/fs/orpc/index.js +2 -2
- package/lib/fs/orpc/server/createFileSystemContractImpl.js +62 -60
- package/lib/fs/orpc/server/createFileSystemContractImpl.js.map +1 -1
- package/lib/fs/orpc/server/index.js +1 -1
- package/lib/fs/s3/createS3MiniFileSystem.js +756 -689
- package/lib/fs/s3/createS3MiniFileSystem.js.map +1 -1
- package/lib/fs/s3/index.js +1 -1
- package/lib/fs/s3/s3mini.test.js +524 -553
- package/lib/fs/scandir.js +56 -56
- package/lib/fs/server/createDatabaseFileSystem.js +834 -741
- package/lib/fs/server/createDatabaseFileSystem.js.map +1 -1
- package/lib/fs/server/createNodeFileSystem.js +407 -380
- package/lib/fs/server/createNodeFileSystem.js.map +1 -1
- package/lib/fs/server/dbfs.test.js +201 -214
- package/lib/fs/server/index.js +1 -1
- package/lib/fs/server/loadTestDatabase.js +40 -43
- package/lib/fs/tests/runFileSystemTest.js +352 -315
- package/lib/fs/tests/runFileSystemTest.js.map +1 -1
- package/lib/fs/types.js +17 -20
- package/lib/fs/utils/getFileUrl.js +24 -30
- package/lib/fs/utils.js +17 -17
- package/lib/fs/utils.js.map +1 -1
- package/lib/fs/webdav/index.js +2 -0
- package/lib/fs/webdav/index.js.map +1 -0
- package/lib/index.js +2 -2
- package/lib/jsonschema/JsonSchema.js +216 -155
- package/lib/jsonschema/JsonSchema.js.map +1 -1
- package/lib/jsonschema/JsonSchema.test.js +123 -124
- package/lib/jsonschema/forEachJsonSchema.js +41 -41
- package/lib/jsonschema/forEachJsonSchema.js.map +1 -1
- package/lib/jsonschema/index.js +2 -2
- package/lib/jsonschema/types.d.js +2 -2
- package/lib/jsonschema/types.d.js.map +1 -1
- package/lib/meta/defineFileType.js +32 -38
- package/lib/meta/defineInit.js +39 -35
- package/lib/meta/defineMetadata.js +37 -34
- package/lib/meta/defineMetadata.js.map +1 -1
- package/lib/meta/defineMetadata.test.js +13 -12
- package/lib/meta/index.js +3 -3
- package/lib/orpc/createOpenApiContractClient.js +26 -24
- package/lib/orpc/createOpenApiContractClient.js.map +1 -1
- package/lib/orpc/createRpcContractClient.js +37 -31
- package/lib/orpc/index.js +2 -2
- package/lib/orpc/resolveLinkPlugins.js +25 -25
- package/lib/password/PHC.js +187 -189
- package/lib/password/PHC.js.map +1 -1
- package/lib/password/PHC.test.js +517 -535
- package/lib/password/Password.js +85 -80
- package/lib/password/Password.test.js +330 -364
- package/lib/password/createArgon2PasswordAlgorithm.js +50 -51
- package/lib/password/createArgon2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBase64PasswordAlgorithm.js +11 -11
- package/lib/password/createBase64PasswordAlgorithm.js.map +1 -1
- package/lib/password/createBcryptPasswordAlgorithm.js +20 -18
- package/lib/password/createBcryptPasswordAlgorithm.js.map +1 -1
- package/lib/password/createPBKDF2PasswordAlgorithm.js +65 -52
- package/lib/password/createPBKDF2PasswordAlgorithm.js.map +1 -1
- package/lib/password/createScryptPasswordAlgorithm.js +74 -63
- package/lib/password/createScryptPasswordAlgorithm.js.map +1 -1
- package/lib/password/index.js +5 -5
- package/lib/password/server/index.js +1 -1
- package/lib/resource/Identifiable.js +2 -2
- package/lib/resource/ListQuery.js +42 -42
- package/lib/resource/ListQuery.js.map +1 -1
- package/lib/resource/getTitleOfResource.js +5 -5
- package/lib/resource/index.js +2 -2
- package/lib/resource/index.js.map +1 -1
- package/lib/resource/schema/AnyResourceSchema.js +91 -89
- package/lib/resource/schema/BaseResourceSchema.js +26 -26
- package/lib/resource/schema/ResourceActionType.js +117 -115
- package/lib/resource/schema/ResourceStatus.js +94 -92
- package/lib/resource/schema/ResourceType.js +25 -23
- package/lib/resource/schema/index.js +5 -5
- package/lib/resource/schema/types.js +86 -55
- package/lib/resource/schema/types.test.js +16 -13
- package/lib/s3/formatS3Url.js +60 -60
- package/lib/s3/formatS3Url.js.map +1 -1
- package/lib/s3/formatS3Url.test.js +238 -261
- package/lib/s3/index.js +2 -2
- package/lib/s3/parseS3Url.js +61 -60
- package/lib/s3/parseS3Url.js.map +1 -1
- package/lib/s3/parseS3Url.test.js +270 -269
- package/lib/schema/SchemaRegistry.js +41 -42
- package/lib/schema/SchemaRegistry.js.map +1 -1
- package/lib/schema/SchemaRegistry.mod.js +1 -1
- package/lib/schema/TypeSchema.d.js +2 -2
- package/lib/schema/TypeSchema.d.js.map +1 -1
- package/lib/schema/createSchemaData.js +113 -67
- package/lib/schema/createSchemaData.js.map +1 -1
- package/lib/schema/findJsonSchemaByPath.js +28 -23
- package/lib/schema/findJsonSchemaByPath.js.map +1 -1
- package/lib/schema/formatZodError.js +113 -134
- package/lib/schema/formatZodError.js.map +1 -1
- package/lib/schema/formatZodError.test.js +192 -195
- package/lib/schema/getSchemaCache.js +7 -7
- package/lib/schema/getSchemaOptions.js +17 -16
- package/lib/schema/index.js +6 -6
- package/lib/schema/toJsonSchema.js +196 -190
- package/lib/schema/toJsonSchema.js.map +1 -1
- package/lib/schema/toJsonSchema.test.js +34 -26
- package/lib/schema/validate.js +106 -97
- package/lib/schema/validate.js.map +1 -1
- package/lib/tools/generateSchema.js +40 -40
- package/lib/tools/renderJsonSchemaToMarkdownDoc.js +74 -74
- package/lib/utils/buildBaseUrl.js +8 -8
- package/lib/utils/buildRedactorFormSchema.js +55 -54
- package/lib/utils/buildRedactorFormSchema.js.map +1 -1
- package/lib/utils/getEstimateProcessTime.js +24 -19
- package/lib/utils/index.js +3 -3
- package/lib/utils/resolveFeatureOptions.js +9 -9
- package/package.json +37 -18
- package/src/ai/qwen3vl/utils.ts +1 -1
- package/src/ai/vision/index.ts +2 -2
- package/src/cn/ChineseResidentIdNo.ts +1 -1
- package/src/cn/Mod11.ts +1 -1
- package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +1 -1
- package/src/cn/__snapshots__/UnifiedSocialCreditCode.test.ts.snap +0 -23
- package/src/cn/index.ts +1 -2
- package/src/cn/parseChineseNumber.test.ts +4 -4
- package/src/consola/formatLogObject.ts +6 -6
- package/src/consola/index.ts +1 -1
- package/src/data/index.ts +3 -4
- package/src/data/maybeNumber.ts +1 -1
- package/src/data/parseSort.test.ts +0 -1
- package/src/data/resolvePagination.ts +2 -2
- package/src/data/types.d.ts +2 -2
- package/src/dayjs/formatDuration.ts +10 -11
- package/src/dayjs/index.ts +1 -1
- package/src/dayjs/parseRelativeTime.ts +1 -1
- package/src/dayjs/resolveRelativeTime.ts +11 -14
- package/src/drain3/Drain.test.ts +378 -0
- package/src/drain3/Drain.ts +394 -0
- package/src/drain3/LogCluster.ts +46 -0
- package/src/drain3/Node.ts +53 -0
- package/src/drain3/TemplateMiner.ts +246 -0
- package/src/drain3/index.ts +34 -0
- package/src/drain3/persistence/FilePersistence.ts +24 -0
- package/src/drain3/persistence/MemoryPersistence.ts +23 -0
- package/src/drain3/persistence/PersistenceHandler.ts +19 -0
- package/src/drain3/types.ts +75 -0
- package/src/fs/IFileSystem.d.ts +1 -2
- package/src/fs/createBrowserFileSystem.ts +7 -5
- package/src/fs/createMemoryFileSystem.ts +9 -13
- package/src/fs/createSandboxFileSystem.ts +1 -1
- package/src/fs/createWebDavFileSystem.ts +30 -17
- package/src/fs/createWebFileSystem.ts +242 -0
- package/src/fs/findMimeType.ts +1 -4
- package/src/fs/index.ts +5 -5
- package/src/fs/minio/createMinioFileSystem.ts +1148 -0
- package/src/fs/minio/index.ts +1 -0
- package/src/fs/orpc/createContractClientFileSystem.ts +5 -5
- package/src/fs/orpc/server/createFileSystemContractImpl.ts +1 -1
- package/src/fs/s3/createS3MiniFileSystem.ts +120 -79
- package/src/fs/s3/s3fs.test.ts +441 -0
- package/src/fs/s3/s3mini.test.ts +2 -2
- package/src/fs/server/createDatabaseFileSystem.ts +78 -114
- package/src/fs/server/createNodeFileSystem.ts +32 -13
- package/src/fs/server/dbfs.test.ts +13 -8
- package/src/fs/server/index.ts +1 -0
- package/src/fs/server/loadTestDatabase.ts +8 -119
- package/src/fs/tests/runFileSystemTest.ts +29 -28
- package/src/fs/utils.ts +1 -1
- package/src/fs/webdav/index.ts +1 -0
- package/src/jsonschema/JsonSchema.ts +5 -5
- package/src/jsonschema/forEachJsonSchema.ts +1 -1
- package/src/jsonschema/index.ts +1 -1
- package/src/jsonschema/types.d.ts +1 -1
- package/src/meta/defineMetadata.ts +1 -1
- package/src/meta/index.ts +2 -3
- package/src/orm/createSqliteDialect.ts +17 -0
- package/src/orm/index.ts +1 -0
- package/src/orpc/createOpenApiContractClient.ts +3 -3
- package/src/orpc/index.ts +1 -1
- package/src/password/PHC.ts +3 -3
- package/src/password/createArgon2PasswordAlgorithm.ts +2 -2
- package/src/password/createBase64PasswordAlgorithm.ts +2 -2
- package/src/password/createBcryptPasswordAlgorithm.ts +4 -2
- package/src/password/createPBKDF2PasswordAlgorithm.ts +2 -2
- package/src/password/createScryptPasswordAlgorithm.ts +4 -4
- package/src/password/index.ts +2 -2
- package/src/resource/ListQuery.ts +4 -1
- package/src/resource/index.ts +3 -3
- package/src/resource/schema/index.ts +4 -4
- package/src/s3/formatS3Url.test.ts +1 -1
- package/src/s3/formatS3Url.ts +2 -2
- package/src/s3/index.ts +1 -1
- package/src/s3/parseS3Url.ts +1 -1
- package/src/schema/SchemaRegistry.ts +2 -2
- package/src/schema/TypeSchema.d.ts +6 -6
- package/src/schema/createSchemaData.ts +5 -5
- package/src/schema/findJsonSchemaByPath.ts +5 -5
- package/src/schema/formatZodError.test.ts +2 -1
- package/src/schema/formatZodError.ts +50 -62
- package/src/schema/index.ts +5 -5
- package/src/schema/toJsonSchema.ts +6 -6
- package/src/schema/validate.ts +2 -2
- package/src/utils/buildRedactorFormSchema.ts +4 -4
- package/src/utils/formatNumber.ts +18 -0
- package/src/utils/formatPercent.ts +17 -0
- package/src/utils/index.ts +3 -3
- package/src/utils/resolveFeatureOptions.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fs/server/createDatabaseFileSystem.ts"],"sourcesContent":["import * as crypto from 'node:crypto';\nimport { basename, dirname, join, normalize } from 'node:path';\nimport {\n\tCascade,\n\tCollection,\n\tEntity,\n\tManyToOne,\n\tOneToMany,\n\tOneToOne,\n\tProperty,\n\ttypes,\n\tUnique,\n\ttype Opt,\n\ttype Rel,\n} from '@mikro-orm/core';\nimport type { EntityManager } from '@mikro-orm/knex';\nimport { TenantBaseEntity } from '@wener/server/entity';\nimport { getEntityManager } from '@wener/server/mikro-orm';\nimport type { CopyOptions } from 'fs-extra';\nimport { FileSystemError, FileSystemErrorCode } from '../FileSystemError';\nimport type {\n\tCreateReadStreamOptions,\n\tCreateWriteStreamOptions,\n\tIFileStat,\n\tIFileSystem,\n\tMkdirOptions,\n\tReaddirOptions,\n\tReadFileOptions,\n\tRenameOptions,\n\tRmOptions,\n\tStatOptions,\n\tWriteFileOptions,\n} from '../IFileSystem';\nimport { FileKind } from '../types';\n\nexport function createDatabaseFileSystem(options: Partial<IDatabaseFileSystemOptions> = {}): IDatabaseFileSystem {\n\treturn new DBFS(options);\n}\n\ntype IDatabaseFileSystem = IFileSystem & {\n\tensureRootNode(): Promise<FileNodeMetaEntity>;\n};\ntype IDatabaseFileSystemOptions = {\n\tgetEntityManager: () => EntityManager;\n\tsmallFileThreshold?: number;\n};\n\nclass DBFS implements IFileSystem {\n\toptions: IDatabaseFileSystemOptions;\n\n\tconstructor(options: Partial<IDatabaseFileSystemOptions> = {}) {\n\t\tthis.options = {\n\t\t\tgetEntityManager: () => getEntityManager<EntityManager>().fork(),\n\t\t\tsmallFileThreshold: 512,\n\t\t\t...options,\n\t\t};\n\t}\n\n\tget em() {\n\t\treturn this.options.getEntityManager();\n\t}\n\n\t/**\n\t * Ensure root node exists, create it if it doesn't exist\n\t * @returns The root FileNodeMetaEntity\n\t */\n\tasync ensureRootNode(): Promise<FileNodeMetaEntity> {\n\t\tconst em = this.em;\n\t\tconst rootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\trootQb.where({ parent: null });\n\t\tconst rootNode = await rootQb.getSingleResult();\n\n\t\tif (rootNode) {\n\t\t\treturn rootNode;\n\t\t}\n\n\t\t// Create root directory (parent is null, filename is empty string)\n\t\tconst now = new Date();\n\t\tconst rootDir = em.create(FileNodeMetaEntity, {\n\t\t\tfilename: '',\n\t\t\tparent: null,\n\t\t\tkind: FileKind.directory,\n\t\t\tsize: 0,\n\t\t\tatime: now,\n\t\t\tbtime: now,\n\t\t\tctime: now,\n\t\t\tmtime: now,\n\t\t});\n\t\ttry {\n\t\t\tawait em.persistAndFlush(rootDir);\n\t\t\treturn rootDir;\n\t\t} catch (error: any) {\n\t\t\t// If root already exists (race condition), fetch and return it\n\t\t\tif (error.message?.includes('UNIQUE constraint') || error.message?.includes('duplicate')) {\n\t\t\t\tconst existingRootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\t\texistingRootQb.where({ parent: null });\n\t\t\t\tconst existingRoot = await existingRootQb.getSingleResult();\n\t\t\t\tif (existingRoot) {\n\t\t\t\t\treturn existingRoot;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync stat(path: string, options?: StatOptions): Promise<IFileStat> {\n\t\t// Validate input\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new FileSystemError('Invalid path', FileSystemErrorCode.EINVAL);\n\t\t}\n\n\t\tconst em = this.em;\n\t\tconst node = await this._getNodeByPath(path, em);\n\t\tif (!node) {\n\t\t\tthrow new FileSystemError(`Path not found: ${path}`, FileSystemErrorCode.ENOENT);\n\t\t}\n\t\treturn this._toFileStat(node, path);\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\treturn !!(await this._getNodeByPath(path, this.em));\n\t}\n\n\tasync readdir(dir: string, options?: ReaddirOptions): Promise<IFileStat[]> {\n\t\tconst em = this.em;\n\t\tconst parentNode = await this._getNodeByPath(dir, em);\n\n\t\tif (!parentNode) {\n\t\t\tthrow new FileSystemError(`Directory not found: ${dir}`, FileSystemErrorCode.ENOENT);\n\t\t}\n\t\tif (parentNode.kind !== FileKind.directory) {\n\t\t\tthrow new FileSystemError(`Path is not a directory: ${dir}`, FileSystemErrorCode.ENOTDIR);\n\t\t}\n\n\t\t// Use QueryBuilder to avoid automatic relationship loading\n\t\tconst qb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\tqb.where({ parent: parentNode });\n\t\tconst children = await qb.getResult();\n\n\t\treturn children.map((child) => this._toFileStat(child, join(dir, child.filename)));\n\t}\n\n\tasync mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n\t\tawait this._mkdirInTransaction(path, options, this.em);\n\t}\n\n\tprivate async _mkdirInTransaction(path: string, options: MkdirOptions, em: EntityManager): Promise<void> {\n\t\tconst normalized = normalize(path);\n\n\t\t// Special handling for root directory\n\t\tif (normalized === '/') {\n\t\t\tconst rootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\trootQb.where({ parent: null });\n\t\t\tconst rootNode = await rootQb.getSingleResult();\n\t\t\tif (rootNode) {\n\t\t\t\t// Root directory already exists\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Create root directory (parent is null, filename is empty string)\n\t\t\tconst now = new Date();\n\t\t\tconst rootDir = em.create(FileNodeMetaEntity, {\n\t\t\t\tfilename: '',\n\t\t\t\tparent: null,\n\t\t\t\tkind: FileKind.directory,\n\t\t\t\tsize: 0,\n\t\t\t\tatime: now,\n\t\t\t\tbtime: now,\n\t\t\t\tctime: now,\n\t\t\t\tmtime: now,\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tawait em.persistAndFlush(rootDir);\n\t\t\t} catch (error: any) {\n\t\t\t\t// If root already exists (race condition), ignore the error\n\t\t\t\tif (!error.message?.includes('UNIQUE constraint') && !error.message?.includes('duplicate')) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst parentPath = dirname(normalized);\n\t\tconst newDirName = basename(normalized);\n\n\t\tif (!newDirName) throw new FileSystemError('Cannot create directory with empty name', FileSystemErrorCode.EINVAL);\n\n\t\tlet parentNode = await this._getNodeByPath(parentPath, em);\n\n\t\tif (!parentNode) {\n\t\t\tif (options.recursive) {\n\t\t\t\t// 递归创建父目录\n\t\t\t\tawait this._mkdirInTransaction(parentPath, options, em);\n\t\t\t\tparentNode = await this._getNodeByPath(parentPath, em);\n\t\t\t} else {\n\t\t\t\tthrow new FileSystemError(`Parent directory not found: ${parentPath}`, FileSystemErrorCode.ENOENT);\n\t\t\t}\n\t\t}\n\n\t\tif (!parentNode)\n\t\t\tthrow new FileSystemError('Failed to create parent directory structure', FileSystemErrorCode.EINVAL);\n\n\t\t// Check if directory already exists using QueryBuilder\n\t\tconst existingQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\texistingQb.where({ parent: parentNode, filename: newDirName });\n\t\tconst existing = await existingQb.getSingleResult();\n\n\t\tif (existing) {\n\t\t\tif (existing.kind === FileKind.directory) {\n\t\t\t\t// Directory already exists, return silently\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new FileSystemError(`A file with the same name already exists: ${path}`, FileSystemErrorCode.EEXIST);\n\t\t}\n\n\t\t// Create directory using EntityManager\n\t\tconst now = new Date();\n\t\tconst newDir = em.create(FileNodeMetaEntity, {\n\t\t\ttid: parentNode.tid,\n\t\t\tparent: parentNode,\n\t\t\tfilename: newDirName,\n\t\t\tkind: FileKind.directory,\n\t\t\tsize: 0,\n\t\t\tatime: now,\n\t\t\tbtime: now,\n\t\t\tctime: now,\n\t\t\tmtime: now,\n\t\t});\n\t\tawait em.persistAndFlush(newDir);\n\t}\n\n\treadFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;\n\n\treadFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;\n\n\tasync readFile(\n\t\tpath: string,\n\t\toptions?: ReadFileOptions & {\n\t\t\tencoding?: 'text' | 'binary' | string;\n\t\t},\n\t): Promise<string | Uint8Array> {\n\t\tconst em = this.em;\n\t\tconst node = await this._getNodeByPath(path, em);\n\n\t\tif (!node) throw new FileSystemError(`File not found: ${path}`, FileSystemErrorCode.ENOENT);\n\t\tif (node.kind !== FileKind.file)\n\t\t\tthrow new FileSystemError(`Path is not a file: ${path}`, FileSystemErrorCode.EISDIR);\n\n\t\tlet buffer: Buffer;\n\t\tif (node.content) {\n\t\t\t// 小文件优化 - content is already loaded\n\t\t\tbuffer = node.content;\n\t\t} else {\n\t\t\t// Large file: load from file_node_content table using QueryBuilder\n\t\t\tconst fileContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\tfileContentQb.where({ node: node });\n\t\t\tconst fileContent = await fileContentQb.getSingleResult();\n\t\t\tif (!fileContent) throw new FileSystemError('File content is missing', FileSystemErrorCode.ENOENT);\n\t\t\tbuffer = fileContent.content;\n\t\t}\n\n\t\treturn options?.encoding === 'text' ? buffer.toString('utf-8') : buffer;\n\t}\n\n\tasync writeFile(path: string, data: string | Buffer, options: WriteFileOptions = {}): Promise<void> {\n\t\t// Validate input\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new FileSystemError('Invalid path', FileSystemErrorCode.EINVAL);\n\t\t}\n\t\tif (data === null || data === undefined) {\n\t\t\tthrow new FileSystemError('Invalid data', FileSystemErrorCode.EINVAL);\n\t\t}\n\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst { overwrite = true } = options;\n\t\t\tconst bufferData = Buffer.isBuffer(data) ? data : Buffer.from(data, 'utf-8');\n\t\t\tconst size = bufferData.length;\n\n\t\t\tconst parentPath = dirname(path);\n\t\t\tconst filename = basename(path);\n\n\t\t\t// Validate filename\n\t\t\tif (!filename) {\n\t\t\t\tthrow new FileSystemError('filename cannot be empty', FileSystemErrorCode.EINVAL);\n\t\t\t}\n\n\t\t\t// 确保父目录存在 - create it within the transaction\n\t\t\tawait this._mkdirInTransaction(parentPath, { recursive: true }, em);\n\t\t\tconst parentNode = await this._getNodeByPath(parentPath, em);\n\t\t\tif (!parentNode) throw new FileSystemError('Failed to establish parent directory', FileSystemErrorCode.EINVAL);\n\n\t\t\t// Find existing node using QueryBuilder\n\t\t\tconst nodeQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tnodeQb.where({ parent: parentNode, filename });\n\t\t\tlet node = await nodeQb.getSingleResult();\n\n\t\t\tif (node) {\n\t\t\t\t// 文件已存在\n\t\t\t\tif (!overwrite) throw new FileSystemError(`File already exists: ${path}`, FileSystemErrorCode.EEXIST);\n\t\t\t\tif (node.kind === FileKind.directory)\n\t\t\t\t\tthrow new FileSystemError(`Cannot overwrite a directory with a file: ${path}`, FileSystemErrorCode.EISDIR);\n\n\t\t\t\t// 更新节点\n\t\t\t\tnode.size = size;\n\t\t\t\tnode.mtime = new Date();\n\t\t\t\t// ... 其他时间戳\n\t\t\t} else {\n\t\t\t\t// 新建文件\n\t\t\t\tconst now = new Date();\n\t\t\t\tnode = em.create(FileNodeMetaEntity, {\n\t\t\t\t\ttid: parentNode.tid,\n\t\t\t\t\tfilename,\n\t\t\t\t\tparent: parentNode,\n\t\t\t\t\tkind: FileKind.file,\n\t\t\t\t\tsize,\n\t\t\t\t\tatime: now,\n\t\t\t\t\tbtime: now,\n\t\t\t\t\tctime: now,\n\t\t\t\t\tmtime: now,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// 处理文件内容\n\t\t\tif (size <= this.options.smallFileThreshold!) {\n\t\t\t\t// Small file: store in file_node_meta.content\n\t\t\t\tnode.content = bufferData;\n\t\t\t\t// If there was large file content, delete it\n\t\t\t\t// Use QueryBuilder to avoid relationship issues\n\t\t\t\tconst existingContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\t\texistingContentQb.where({ node: node });\n\t\t\t\tconst existingContent = await existingContentQb.getSingleResult();\n\t\t\t\tif (existingContent) {\n\t\t\t\t\tawait em.removeAndFlush(existingContent);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Large file: store in file_node_content table\n\t\t\t\tnode.content = undefined; // Clear small file content\n\t\t\t\tconst md5 = crypto.createHash('md5').update(bufferData).digest('hex');\n\t\t\t\tconst sha256 = crypto.createHash('sha256').update(bufferData).digest('hex');\n\n\t\t\t\t// Check if fileContent already exists using QueryBuilder\n\t\t\t\tconst fileContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\t\tfileContentQb.where({ node: node });\n\t\t\t\tlet fileContent = await fileContentQb.getSingleResult();\n\n\t\t\t\tif (fileContent) {\n\t\t\t\t\t// Update existing content\n\t\t\t\t\tfileContent.content = bufferData;\n\t\t\t\t\tfileContent.size = size;\n\t\t\t\t\tfileContent.md5 = md5;\n\t\t\t\t\tfileContent.sha256 = sha256;\n\t\t\t\t} else {\n\t\t\t\t\t// Create new content entity\n\t\t\t\t\tfileContent = em.create(FileNodeContentEntity, {\n\t\t\t\t\t\tnode: node, // Use node relationship as primary key\n\t\t\t\t\t\ttid: node.tid,\n\t\t\t\t\t\tcontent: bufferData,\n\t\t\t\t\t\tsize: size,\n\t\t\t\t\t\tmd5: md5,\n\t\t\t\t\t\tsha256: sha256,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait em.persistAndFlush(node);\n\t\t});\n\t}\n\n\tasync rm(path: string, options: RmOptions = {}): Promise<void> {\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst node = await this._getNodeByPath(path, em);\n\t\t\tif (!node) {\n\t\t\t\tif (options.force) return; // force=true, 不存在也算成功\n\t\t\t\tthrow new FileSystemError(`Path not found: ${path}`, FileSystemErrorCode.ENOENT);\n\t\t\t}\n\n\t\t\tif (node.kind === FileKind.directory && !options.recursive) {\n\t\t\t\t// Check if directory has children using QueryBuilder\n\t\t\t\tconst childrenQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\t\tchildrenQb.where({ parent: node });\n\t\t\t\tchildrenQb.select('id');\n\t\t\t\tconst children = await childrenQb.getResult();\n\t\t\t\tif (children.length > 0) {\n\t\t\t\t\tthrow new FileSystemError(`Directory not empty: ${path}`, FileSystemErrorCode.ENOTEMPTY);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 使用 orphanRemoval: true, ORM会自动处理子节点和内容的删除\n\t\t\tawait em.removeAndFlush(node);\n\t\t});\n\t}\n\n\tasync rename(oldPath: string, newPath: string, options: RenameOptions = {}): Promise<void> {\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst node = await this._getNodeByPath(oldPath, em);\n\t\t\tif (!node) throw new FileSystemError(`Source path not found: ${oldPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst newParentPath = dirname(newPath);\n\t\t\tconst newFilename = basename(newPath);\n\n\t\t\tconst newParentNode = await this._getNodeByPath(newParentPath, em);\n\t\t\tif (!newParentNode)\n\t\t\t\tthrow new FileSystemError(`Destination directory not found: ${newParentPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst existingDestQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\texistingDestQb.where({ parent: newParentNode, filename: newFilename });\n\t\t\tconst existingDest = await existingDestQb.getSingleResult();\n\t\t\tif (existingDest) {\n\t\t\t\tif (!options.overwrite)\n\t\t\t\t\tthrow new FileSystemError(`Destination path already exists: ${newPath}`, FileSystemErrorCode.EEXIST);\n\t\t\t\tif (node.id === existingDest.id) return; // 移动到原位置,什么都不做\n\t\t\t\tawait em.removeAndFlush(existingDest);\n\t\t\t}\n\n\t\t\tnode.parent = newParentNode;\n\t\t\tnode.filename = newFilename;\n\t\t\tnode.mtime = new Date();\n\n\t\t\tawait em.flush();\n\t\t});\n\t}\n\n\tasync copy(srcPath: string, destPath: string, options: CopyOptions = {}): Promise<void> {\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst srcNode = await this._getNodeByPath(srcPath, em);\n\t\t\tif (!srcNode) throw new FileSystemError(`Source path not found: ${srcPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst destParentPath = dirname(destPath);\n\t\t\tconst destFilename = basename(destPath);\n\n\t\t\tconst destParentNode = await this._getNodeByPath(destParentPath, em);\n\t\t\tif (!destParentNode)\n\t\t\t\tthrow new FileSystemError(`Destination directory not found: ${destParentPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst existingDestQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\texistingDestQb.where({ parent: destParentNode, filename: destFilename });\n\t\t\tconst existingDest = await existingDestQb.getSingleResult();\n\t\t\tif (existingDest) {\n\t\t\t\tif (!options.overwrite)\n\t\t\t\t\tthrow new FileSystemError(`Destination path already exists: ${destPath}`, FileSystemErrorCode.EEXIST);\n\t\t\t\t// Delete existing destination within the same transaction\n\t\t\t\tawait em.removeAndFlush(existingDest);\n\t\t\t}\n\n\t\t\tawait this._copyNode(srcNode, destParentNode, destFilename, em);\n\t\t});\n\t}\n\n\tcreateReadStream(path: string, options?: CreateReadStreamOptions): never {\n\t\tthrow new Error('Streaming read is not supported by DBFS yet.');\n\t}\n\n\tcreateWriteStream(path: string, options?: CreateWriteStreamOptions): never {\n\t\tthrow new Error('Streaming write is not supported by DBFS yet.');\n\t}\n\n\tcreateReadableStream(path: string, options?: CreateReadStreamOptions): ReadableStream {\n\t\tthrow new Error('ReadableStream is not supported by DBFS yet.');\n\t}\n\n\tcreateWritableStream(path: string, options?: CreateWriteStreamOptions): WritableStream {\n\t\tthrow new Error('WritableStream is not supported by DBFS yet.');\n\t}\n\n\t/**\n\t * 将路径字符串解析为数据库中的节点。这是大部分操作的基础。\n\t * @param pathStr 绝对路径, e.g., /home/user/file.txt\n\t * @param em EntityManager 实例\n\t * @returns 找到的节点或 null\n\t */\n\tprivate async _getNodeByPath(pathStr: string, em: EntityManager): Promise<FileNodeMetaEntity | null> {\n\t\tconst normalized = normalize(pathStr);\n\n\t\tif (normalized === '/') {\n\t\t\t// Use QueryBuilder to avoid automatic relationship loading\n\t\t\tconst qb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tqb.where({ parent: null });\n\t\t\tconst rootNode = await qb.getSingleResult();\n\t\t\treturn rootNode || null;\n\t\t}\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\n\t\t// Get root node\n\t\tconst rootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\trootQb.where({ parent: null });\n\t\tlet currentNode = await rootQb.getSingleResult();\n\t\tif (!currentNode) return null;\n\n\t\t// Traverse path parts\n\t\tfor (const part of parts) {\n\t\t\tconst childQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tchildQb.where({ parent: currentNode, filename: part });\n\t\t\tconst child = await childQb.getSingleResult();\n\t\t\tif (!child) return null;\n\t\t\tcurrentNode = child;\n\t\t}\n\n\t\treturn currentNode;\n\t}\n\n\t/**\n\t * 将数据库实体转换为 IFileStat 接口\n\t */\n\tprivate _toFileStat(node: FileNodeMetaEntity, path: string): IFileStat {\n\t\t// Handle mtime - it might be a Date object or a string from raw query\n\t\tlet mtime: number;\n\t\tif (node.mtime instanceof Date) {\n\t\t\tmtime = node.mtime.getTime();\n\t\t} else if (typeof node.mtime === 'string') {\n\t\t\tmtime = new Date(node.mtime).getTime();\n\t\t} else {\n\t\t\tmtime = Date.now();\n\t\t}\n\n\t\t// Handle size - convert bigint to number if needed\n\t\tlet size: number;\n\t\tif (typeof node.size === 'bigint') {\n\t\t\tsize = Number(node.size);\n\t\t} else {\n\t\t\tsize = node.size;\n\t\t}\n\n\t\treturn {\n\t\t\tpath: path,\n\t\t\tname: node.filename,\n\t\t\tkind: node.kind,\n\t\t\tsize: size,\n\t\t\tmtime: mtime,\n\t\t\tmeta: node.metadata || {},\n\t\t\t// `directory` 字段可以根据 path 动态计算\n\t\t\tdirectory: dirname(path),\n\t\t};\n\t}\n\n\tprivate async _copyNode(\n\t\tsrcNode: FileNodeMetaEntity,\n\t\tdestParent: FileNodeMetaEntity,\n\t\tnewName: string,\n\t\tem: EntityManager,\n\t): Promise<void> {\n\t\t// 1. 复制节点本身\n\t\tconst now = new Date();\n\t\tconst newNode = em.create(FileNodeMetaEntity, {\n\t\t\ttid: srcNode.tid,\n\t\t\tfilename: newName,\n\t\t\tparent: destParent,\n\t\t\tkind: srcNode.kind,\n\t\t\tsize: srcNode.size,\n\t\t\tmetadata: srcNode.metadata, // deep copy metadata\n\t\t\tcontent: srcNode.content, // copy small file content\n\t\t\tatime: now,\n\t\t\tbtime: now,\n\t\t\tctime: now,\n\t\t\tmtime: now,\n\t\t});\n\n\t\t// 2. 复制大文件内容 (如果存在) - use QueryBuilder to avoid relationship loading\n\t\tif (!srcNode.content) {\n\t\t\tconst srcFileContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\tsrcFileContentQb.where({ node: srcNode });\n\t\t\tconst srcFileContent = await srcFileContentQb.getSingleResult();\n\t\t\tif (srcFileContent) {\n\t\t\t\tconst newContent = em.create(FileNodeContentEntity, {\n\t\t\t\t\tnode: newNode, // Use node relationship as primary key\n\t\t\t\t\ttid: srcNode.tid,\n\t\t\t\t\tcontent: srcFileContent.content,\n\t\t\t\t\tsize: srcFileContent.size,\n\t\t\t\t\tmd5: srcFileContent.md5,\n\t\t\t\t\tsha256: srcFileContent.sha256,\n\t\t\t\t\tmimeType: srcFileContent.mimeType,\n\t\t\t\t\tmetadata: srcFileContent.metadata,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait em.persistAndFlush(newNode);\n\n\t\t// 3. 如果是目录,递归复制子节点\n\t\tif (srcNode.kind === FileKind.directory) {\n\t\t\tconst childrenQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tchildrenQb.where({ parent: srcNode });\n\t\t\tconst children = await childrenQb.getResult();\n\t\t\tfor (const child of children) {\n\t\t\t\tawait this._copyNode(child, newNode, child.filename, em);\n\t\t\t}\n\t\t}\n\t}\n}\n\n@Entity({ tableName: 'file_node_meta' })\n@Unique({ properties: ['tid', 'parent', 'filename'] })\nexport class FileNodeMetaEntity extends TenantBaseEntity {\n\t@Property({ type: types.string, nullable: false, comment: '文件名' })\n\tfilename!: string;\n\t@Property({ type: types.bigint, nullable: false, default: 0, comment: '文件大小' })\n\tsize!: number & Opt;\n\t@Property({ type: types.string, nullable: false, comment: '文件类型' })\n\tkind!: FileKind;\n\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tatime!: Date & Opt;\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tbtime!: Date & Opt;\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tctime!: Date & Opt;\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tmtime!: Date & Opt;\n\n\t@Property({ type: types.json, nullable: false, defaultRaw: '{}' })\n\tmetadata!: Record<string, any>;\n\n\t@ManyToOne(() => FileNodeMetaEntity, { nullable: true, cascade: [] })\n\tparent?: Rel<FileNodeMetaEntity>;\n\n\t@OneToMany({ entity: () => FileNodeMetaEntity, mappedBy: 'parent', orphanRemoval: true })\n\tchildren = new Collection<FileNodeMetaEntity>(this);\n\n\t@OneToOne({\n\t\tentity: () => FileNodeContentEntity,\n\t\tmappedBy: 'node',\n\t\torphanRemoval: true,\n\t\tnullable: true,\n\t\tcascade: [Cascade.ALL],\n\t})\n\tfileContent?: Rel<FileNodeContentEntity>;\n\t@Property({ type: types.blob, nullable: true, comment: '文件内容' })\n\tcontent?: Buffer; // for small file, e.g. < 64k\n\n\t//region content\n\n\tget parentId() {\n\t\treturn this.parent?.id as Opt<string | undefined>;\n\t}\n\n\t//endregion\n}\n\n@Entity({ tableName: 'file_node_content' })\nexport class FileNodeContentEntity extends TenantBaseEntity {\n\t@OneToOne({ entity: () => FileNodeMetaEntity, owner: true, joinColumn: 'node_id' })\n\tnode!: Rel<FileNodeMetaEntity>;\n\n\t@Property({ type: types.integer, nullable: false })\n\tsize!: number; // 保留 size 方便查询分析\n\n\t@Property({ type: types.blob, lazy: true, comment: '文件内容' })\n\tcontent!: Buffer;\n\n\t@Property({ type: types.string, nullable: true })\n\tmimeType?: string;\n\n\t@Property({ type: types.string, nullable: false })\n\tmd5?: string;\n\t@Property({ type: types.string, nullable: false })\n\tsha256?: string;\n\n\t@Property({ type: types.string, nullable: true })\n\ttext?: string;\n\t@Property({ type: types.integer, nullable: true })\n\twidth?: number;\n\t@Property({ type: types.integer, nullable: true })\n\theight?: number;\n\t// @Property({ type: types.integer, nullable: true })\n\t// length?: number;\n\n\t@Property({ type: types.json, nullable: false, defaultRaw: '{}' })\n\tmetadata!: Record<string, any>;\n}\n"],"names":["crypto","basename","dirname","join","normalize","Cascade","Collection","Entity","ManyToOne","OneToMany","OneToOne","Property","types","Unique","TenantBaseEntity","getEntityManager","FileSystemError","FileSystemErrorCode","FileKind","createDatabaseFileSystem","options","DBFS","fork","smallFileThreshold","em","ensureRootNode","rootQb","createQueryBuilder","FileNodeMetaEntity","where","parent","rootNode","getSingleResult","now","Date","rootDir","create","filename","kind","directory","size","atime","btime","ctime","mtime","persistAndFlush","error","message","includes","existingRootQb","existingRoot","stat","path","EINVAL","node","_getNodeByPath","ENOENT","_toFileStat","exists","readdir","dir","parentNode","ENOTDIR","qb","children","getResult","map","child","mkdir","_mkdirInTransaction","normalized","parentPath","newDirName","recursive","existingQb","existing","EEXIST","newDir","tid","readFile","file","EISDIR","buffer","content","fileContentQb","FileNodeContentEntity","fileContent","encoding","toString","writeFile","data","undefined","transactional","overwrite","bufferData","Buffer","isBuffer","from","length","nodeQb","existingContentQb","existingContent","removeAndFlush","md5","createHash","update","digest","sha256","rm","force","childrenQb","select","ENOTEMPTY","rename","oldPath","newPath","newParentPath","newFilename","newParentNode","existingDestQb","existingDest","id","flush","copy","srcPath","destPath","srcNode","destParentPath","destFilename","destParentNode","_copyNode","createReadStream","Error","createWriteStream","createReadableStream","createWritableStream","pathStr","parts","split","filter","p","currentNode","part","childQb","getTime","Number","name","meta","metadata","destParent","newName","newNode","srcFileContentQb","srcFileContent","newContent","mimeType","parentId","type","string","nullable","comment","bigint","default","datetime","defaultRaw","json","cascade","entity","mappedBy","orphanRemoval","ALL","blob","tableName","properties","text","width","height","owner","joinColumn","integer","lazy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/fs/server/createDatabaseFileSystem.ts"],"sourcesContent":["import * as crypto from 'node:crypto';\nimport { basename, dirname, join, normalize } from 'node:path';\nimport {\n\tCascade,\n\tCollection,\n\tEntity,\n\tManyToOne,\n\tOneToMany,\n\tOneToOne,\n\tProperty,\n\ttypes,\n\tUnique,\n\ttype Opt,\n\ttype Rel,\n} from '@mikro-orm/core';\nimport type { EntityManager } from '@mikro-orm/knex';\nimport { TenantBaseEntity } from '@wener/server/entity';\nimport { getEntityManager } from '@wener/server/mikro-orm';\nimport type { CopyOptions } from 'fs-extra';\nimport { FileSystemError, FileSystemErrorCode } from '../FileSystemError';\nimport type {\n\tCreateReadStreamOptions,\n\tCreateWriteStreamOptions,\n\tIFileStat,\n\tIFileSystem,\n\tMkdirOptions,\n\tReaddirOptions,\n\tReadFileOptions,\n\tRenameOptions,\n\tRmOptions,\n\tStatOptions,\n\tWriteFileOptions,\n} from '../IFileSystem';\nimport { FileKind } from '../types';\n\nexport function createDatabaseFileSystem(options: Partial<IDatabaseFileSystemOptions> = {}): IDatabaseFileSystem {\n\treturn new DBFS(options);\n}\n\ntype IDatabaseFileSystem = IFileSystem & {\n\tensureRootNode(): Promise<FileNodeMetaEntity>;\n};\ntype IDatabaseFileSystemOptions = {\n\tgetEntityManager: () => EntityManager;\n\tsmallFileThreshold?: number;\n};\n\nclass DBFS implements IFileSystem {\n\toptions: IDatabaseFileSystemOptions;\n\n\tconstructor(options: Partial<IDatabaseFileSystemOptions> = {}) {\n\t\tthis.options = {\n\t\t\tgetEntityManager: () => getEntityManager<EntityManager>().fork(),\n\t\t\tsmallFileThreshold: 512,\n\t\t\t...options,\n\t\t};\n\t}\n\n\tget em() {\n\t\treturn this.options.getEntityManager();\n\t}\n\n\t/**\n\t * Ensure root node exists, create it if it doesn't exist\n\t * @returns The root FileNodeMetaEntity\n\t */\n\tasync ensureRootNode(): Promise<FileNodeMetaEntity> {\n\t\tconst em = this.em;\n\t\tconst rootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\trootQb.where({ parent: null });\n\t\tconst rootNode = await rootQb.getSingleResult();\n\n\t\tif (rootNode) {\n\t\t\treturn rootNode;\n\t\t}\n\n\t\t// Create root directory (parent is null, filename is empty string)\n\t\tconst now = new Date();\n\t\tconst rootDir = em.create(FileNodeMetaEntity, {\n\t\t\tfilename: '',\n\t\t\tparent: null,\n\t\t\tkind: FileKind.directory,\n\t\t\tsize: 0,\n\t\t\tatime: now,\n\t\t\tbtime: now,\n\t\t\tctime: now,\n\t\t\tmtime: now,\n\t\t});\n\t\ttry {\n\t\t\tawait em.persistAndFlush(rootDir);\n\t\t\treturn rootDir;\n\t\t} catch (error: any) {\n\t\t\t// If root already exists (race condition), fetch and return it\n\t\t\tif (error.message?.includes('UNIQUE constraint') || error.message?.includes('duplicate')) {\n\t\t\t\tconst existingRootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\t\texistingRootQb.where({ parent: null });\n\t\t\t\tconst existingRoot = await existingRootQb.getSingleResult();\n\t\t\t\tif (existingRoot) {\n\t\t\t\t\treturn existingRoot;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync stat(path: string, _options?: StatOptions): Promise<IFileStat> {\n\t\t// Validate input\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new FileSystemError('Invalid path', FileSystemErrorCode.EINVAL);\n\t\t}\n\n\t\tconst em = this.em;\n\t\tconst node = await this._getNodeByPath(path, em);\n\t\tif (!node) {\n\t\t\tthrow new FileSystemError(`Path not found: ${path}`, FileSystemErrorCode.ENOENT);\n\t\t}\n\t\treturn this._toFileStat(node, path);\n\t}\n\n\tasync exists(path: string): Promise<boolean> {\n\t\treturn !!(await this._getNodeByPath(path, this.em));\n\t}\n\n\tasync readdir(dir: string, _options?: ReaddirOptions): Promise<IFileStat[]> {\n\t\tconst em = this.em;\n\t\tconst parentNode = await this._getNodeByPath(dir, em);\n\n\t\tif (!parentNode) {\n\t\t\tthrow new FileSystemError(`Directory not found: ${dir}`, FileSystemErrorCode.ENOENT);\n\t\t}\n\t\tif (parentNode.kind !== FileKind.directory) {\n\t\t\tthrow new FileSystemError(`Path is not a directory: ${dir}`, FileSystemErrorCode.ENOTDIR);\n\t\t}\n\n\t\t// Use QueryBuilder to avoid automatic relationship loading\n\t\tconst qb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\tqb.where({ parent: parentNode });\n\t\tconst children = await qb.getResult();\n\n\t\treturn children.map((child) => this._toFileStat(child, join(dir, child.filename)));\n\t}\n\n\tasync mkdir(path: string, options: MkdirOptions = {}): Promise<void> {\n\t\tawait this._mkdirInTransaction(path, options, this.em);\n\t}\n\n\tprivate async _mkdirInTransaction(path: string, options: MkdirOptions, em: EntityManager): Promise<void> {\n\t\tconst normalized = normalize(path);\n\n\t\t// Special handling for root directory\n\t\tif (normalized === '/') {\n\t\t\tconst rootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\trootQb.where({ parent: null });\n\t\t\tconst rootNode = await rootQb.getSingleResult();\n\t\t\tif (rootNode) {\n\t\t\t\t// Root directory already exists\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Create root directory (parent is null, filename is empty string)\n\t\t\tconst now = new Date();\n\t\t\tconst rootDir = em.create(FileNodeMetaEntity, {\n\t\t\t\tfilename: '',\n\t\t\t\tparent: null,\n\t\t\t\tkind: FileKind.directory,\n\t\t\t\tsize: 0,\n\t\t\t\tatime: now,\n\t\t\t\tbtime: now,\n\t\t\t\tctime: now,\n\t\t\t\tmtime: now,\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tawait em.persistAndFlush(rootDir);\n\t\t\t} catch (error: any) {\n\t\t\t\t// If root already exists (race condition), ignore the error\n\t\t\t\tif (!error.message?.includes('UNIQUE constraint') && !error.message?.includes('duplicate')) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst parentPath = dirname(normalized);\n\t\tconst newDirName = basename(normalized);\n\n\t\tif (!newDirName) throw new FileSystemError('Cannot create directory with empty name', FileSystemErrorCode.EINVAL);\n\n\t\tlet parentNode = await this._getNodeByPath(parentPath, em);\n\n\t\tif (!parentNode) {\n\t\t\tif (options.recursive) {\n\t\t\t\t// 递归创建父目录\n\t\t\t\tawait this._mkdirInTransaction(parentPath, options, em);\n\t\t\t\tparentNode = await this._getNodeByPath(parentPath, em);\n\t\t\t} else {\n\t\t\t\tthrow new FileSystemError(`Parent directory not found: ${parentPath}`, FileSystemErrorCode.ENOENT);\n\t\t\t}\n\t\t}\n\n\t\tif (!parentNode)\n\t\t\tthrow new FileSystemError('Failed to create parent directory structure', FileSystemErrorCode.EINVAL);\n\n\t\t// Check if directory already exists using QueryBuilder\n\t\tconst existingQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\texistingQb.where({ parent: parentNode, filename: newDirName });\n\t\tconst existing = await existingQb.getSingleResult();\n\n\t\tif (existing) {\n\t\t\tif (existing.kind === FileKind.directory) {\n\t\t\t\t// Directory already exists, return silently\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new FileSystemError(`A file with the same name already exists: ${path}`, FileSystemErrorCode.EEXIST);\n\t\t}\n\n\t\t// Create directory using EntityManager\n\t\tconst now = new Date();\n\t\tconst newDir = em.create(FileNodeMetaEntity, {\n\t\t\ttid: parentNode.tid,\n\t\t\tparent: parentNode,\n\t\t\tfilename: newDirName,\n\t\t\tkind: FileKind.directory,\n\t\t\tsize: 0,\n\t\t\tatime: now,\n\t\t\tbtime: now,\n\t\t\tctime: now,\n\t\t\tmtime: now,\n\t\t});\n\t\tawait em.persistAndFlush(newDir);\n\t}\n\n\treadFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;\n\n\treadFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;\n\n\tasync readFile(\n\t\tpath: string,\n\t\toptions?: ReadFileOptions & {\n\t\t\tencoding?: 'text' | 'binary' | string;\n\t\t},\n\t): Promise<string | Uint8Array> {\n\t\tconst em = this.em;\n\t\tconst node = await this._getNodeByPath(path, em);\n\n\t\tif (!node) throw new FileSystemError(`File not found: ${path}`, FileSystemErrorCode.ENOENT);\n\t\tif (node.kind !== FileKind.file)\n\t\t\tthrow new FileSystemError(`Path is not a file: ${path}`, FileSystemErrorCode.EISDIR);\n\n\t\tlet buffer: Buffer;\n\t\tif (node.content) {\n\t\t\t// 小文件优化 - content is already loaded\n\t\t\tbuffer = node.content;\n\t\t} else {\n\t\t\t// Large file: load from file_node_content table using QueryBuilder\n\t\t\tconst fileContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\tfileContentQb.where({ node: node });\n\t\t\tconst fileContent = await fileContentQb.getSingleResult();\n\t\t\tif (!fileContent) throw new FileSystemError('File content is missing', FileSystemErrorCode.ENOENT);\n\t\t\tbuffer = fileContent.content;\n\t\t}\n\n\t\treturn options?.encoding === 'text' ? buffer.toString('utf-8') : buffer;\n\t}\n\n\tasync writeFile(path: string, data: string | Buffer, options: WriteFileOptions = {}): Promise<void> {\n\t\t// Validate input\n\t\tif (!path || typeof path !== 'string') {\n\t\t\tthrow new FileSystemError('Invalid path', FileSystemErrorCode.EINVAL);\n\t\t}\n\t\tif (data === null || data === undefined) {\n\t\t\tthrow new FileSystemError('Invalid data', FileSystemErrorCode.EINVAL);\n\t\t}\n\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst { overwrite = true } = options;\n\t\t\tconst bufferData = Buffer.isBuffer(data) ? data : Buffer.from(data, 'utf-8');\n\t\t\tconst size = bufferData.length;\n\n\t\t\tconst parentPath = dirname(path);\n\t\t\tconst filename = basename(path);\n\n\t\t\t// Validate filename\n\t\t\tif (!filename) {\n\t\t\t\tthrow new FileSystemError('filename cannot be empty', FileSystemErrorCode.EINVAL);\n\t\t\t}\n\n\t\t\t// 确保父目录存在 - create it within the transaction\n\t\t\tawait this._mkdirInTransaction(parentPath, { recursive: true }, em);\n\t\t\tconst parentNode = await this._getNodeByPath(parentPath, em);\n\t\t\tif (!parentNode) throw new FileSystemError('Failed to establish parent directory', FileSystemErrorCode.EINVAL);\n\n\t\t\t// Find existing node using QueryBuilder\n\t\t\tconst nodeQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tnodeQb.where({ parent: parentNode, filename });\n\t\t\tlet node = await nodeQb.getSingleResult();\n\n\t\t\tif (node) {\n\t\t\t\t// 文件已存在\n\t\t\t\tif (!overwrite) throw new FileSystemError(`File already exists: ${path}`, FileSystemErrorCode.EEXIST);\n\t\t\t\tif (node.kind === FileKind.directory)\n\t\t\t\t\tthrow new FileSystemError(`Cannot overwrite a directory with a file: ${path}`, FileSystemErrorCode.EISDIR);\n\n\t\t\t\t// 更新节点\n\t\t\t\tnode.size = size;\n\t\t\t\tnode.mtime = new Date();\n\t\t\t\t// ... 其他时间戳\n\t\t\t} else {\n\t\t\t\t// 新建文件\n\t\t\t\tconst now = new Date();\n\t\t\t\tnode = em.create(FileNodeMetaEntity, {\n\t\t\t\t\ttid: parentNode.tid,\n\t\t\t\t\tfilename,\n\t\t\t\t\tparent: parentNode,\n\t\t\t\t\tkind: FileKind.file,\n\t\t\t\t\tsize,\n\t\t\t\t\tatime: now,\n\t\t\t\t\tbtime: now,\n\t\t\t\t\tctime: now,\n\t\t\t\t\tmtime: now,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// 处理文件内容\n\t\t\tif (size <= this.options.smallFileThreshold!) {\n\t\t\t\t// Small file: store in file_node_meta.content\n\t\t\t\tnode.content = bufferData;\n\t\t\t\t// If there was large file content, delete it\n\t\t\t\t// Use QueryBuilder to avoid relationship issues\n\t\t\t\tconst existingContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\t\texistingContentQb.where({ node: node });\n\t\t\t\tconst existingContent = await existingContentQb.getSingleResult();\n\t\t\t\tif (existingContent) {\n\t\t\t\t\tawait em.removeAndFlush(existingContent);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Large file: store in file_node_content table\n\t\t\t\tnode.content = undefined; // Clear small file content\n\t\t\t\tconst md5 = crypto.createHash('md5').update(bufferData).digest('hex');\n\t\t\t\tconst sha256 = crypto.createHash('sha256').update(bufferData).digest('hex');\n\n\t\t\t\t// Check if fileContent already exists using QueryBuilder\n\t\t\t\tconst fileContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\t\tfileContentQb.where({ node: node });\n\t\t\t\tlet fileContent = await fileContentQb.getSingleResult();\n\n\t\t\t\tif (fileContent) {\n\t\t\t\t\t// Update existing content\n\t\t\t\t\tfileContent.content = bufferData;\n\t\t\t\t\tfileContent.size = size;\n\t\t\t\t\tfileContent.md5 = md5;\n\t\t\t\t\tfileContent.sha256 = sha256;\n\t\t\t\t} else {\n\t\t\t\t\t// Create new content entity\n\t\t\t\t\tfileContent = em.create(FileNodeContentEntity, {\n\t\t\t\t\t\tnode: node, // Use node relationship as primary key\n\t\t\t\t\t\ttid: node.tid,\n\t\t\t\t\t\tcontent: bufferData,\n\t\t\t\t\t\tsize: size,\n\t\t\t\t\t\tmd5: md5,\n\t\t\t\t\t\tsha256: sha256,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait em.persistAndFlush(node);\n\t\t});\n\t}\n\n\tasync rm(path: string, options: RmOptions = {}): Promise<void> {\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst node = await this._getNodeByPath(path, em);\n\t\t\tif (!node) {\n\t\t\t\tif (options.force) return; // force=true, 不存在也算成功\n\t\t\t\tthrow new FileSystemError(`Path not found: ${path}`, FileSystemErrorCode.ENOENT);\n\t\t\t}\n\n\t\t\tif (node.kind === FileKind.directory && !options.recursive) {\n\t\t\t\t// Check if directory has children using QueryBuilder\n\t\t\t\tconst childrenQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\t\tchildrenQb.where({ parent: node });\n\t\t\t\tchildrenQb.select('id');\n\t\t\t\tconst children = await childrenQb.getResult();\n\t\t\t\tif (children.length > 0) {\n\t\t\t\t\tthrow new FileSystemError(`Directory not empty: ${path}`, FileSystemErrorCode.ENOTEMPTY);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 使用 orphanRemoval: true, ORM会自动处理子节点和内容的删除\n\t\t\tawait em.removeAndFlush(node);\n\t\t});\n\t}\n\n\tasync rename(oldPath: string, newPath: string, options: RenameOptions = {}): Promise<void> {\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst node = await this._getNodeByPath(oldPath, em);\n\t\t\tif (!node) throw new FileSystemError(`Source path not found: ${oldPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst newParentPath = dirname(newPath);\n\t\t\tconst newFilename = basename(newPath);\n\n\t\t\tconst newParentNode = await this._getNodeByPath(newParentPath, em);\n\t\t\tif (!newParentNode)\n\t\t\t\tthrow new FileSystemError(`Destination directory not found: ${newParentPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst existingDestQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\texistingDestQb.where({ parent: newParentNode, filename: newFilename });\n\t\t\tconst existingDest = await existingDestQb.getSingleResult();\n\t\t\tif (existingDest) {\n\t\t\t\tif (!options.overwrite)\n\t\t\t\t\tthrow new FileSystemError(`Destination path already exists: ${newPath}`, FileSystemErrorCode.EEXIST);\n\t\t\t\tif (node.id === existingDest.id) return; // 移动到原位置,什么都不做\n\t\t\t\tawait em.removeAndFlush(existingDest);\n\t\t\t}\n\n\t\t\tnode.parent = newParentNode;\n\t\t\tnode.filename = newFilename;\n\t\t\tnode.mtime = new Date();\n\n\t\t\tawait em.flush();\n\t\t});\n\t}\n\n\tasync copy(srcPath: string, destPath: string, options: CopyOptions = {}): Promise<void> {\n\t\tawait this.em.transactional(async (em) => {\n\t\t\tconst srcNode = await this._getNodeByPath(srcPath, em);\n\t\t\tif (!srcNode) throw new FileSystemError(`Source path not found: ${srcPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst destParentPath = dirname(destPath);\n\t\t\tconst destFilename = basename(destPath);\n\n\t\t\tconst destParentNode = await this._getNodeByPath(destParentPath, em);\n\t\t\tif (!destParentNode)\n\t\t\t\tthrow new FileSystemError(`Destination directory not found: ${destParentPath}`, FileSystemErrorCode.ENOENT);\n\n\t\t\tconst existingDestQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\texistingDestQb.where({ parent: destParentNode, filename: destFilename });\n\t\t\tconst existingDest = await existingDestQb.getSingleResult();\n\t\t\tif (existingDest) {\n\t\t\t\tif (!options.overwrite)\n\t\t\t\t\tthrow new FileSystemError(`Destination path already exists: ${destPath}`, FileSystemErrorCode.EEXIST);\n\t\t\t\t// Delete existing destination within the same transaction\n\t\t\t\tawait em.removeAndFlush(existingDest);\n\t\t\t}\n\n\t\t\tawait this._copyNode(srcNode, destParentNode, destFilename, em);\n\t\t});\n\t}\n\n\tcreateReadStream(_path: string, _options?: CreateReadStreamOptions): never {\n\t\tthrow new Error('Streaming read is not supported by DBFS yet.');\n\t}\n\n\tcreateWriteStream(_path: string, _options?: CreateWriteStreamOptions): never {\n\t\tthrow new Error('Streaming write is not supported by DBFS yet.');\n\t}\n\n\tcreateReadableStream(_path: string, _options?: CreateReadStreamOptions): ReadableStream {\n\t\tthrow new Error('ReadableStream is not supported by DBFS yet.');\n\t}\n\n\tcreateWritableStream(_path: string, _options?: CreateWriteStreamOptions): WritableStream {\n\t\tthrow new Error('WritableStream is not supported by DBFS yet.');\n\t}\n\n\t/**\n\t * 将路径字符串解析为数据库中的节点。这是大部分操作的基础。\n\t * @param pathStr 绝对路径, e.g., /home/user/file.txt\n\t * @param em EntityManager 实例\n\t * @returns 找到的节点或 null\n\t */\n\tprivate async _getNodeByPath(pathStr: string, em: EntityManager): Promise<FileNodeMetaEntity | null> {\n\t\tconst normalized = normalize(pathStr);\n\n\t\tif (normalized === '/') {\n\t\t\t// Use QueryBuilder to avoid automatic relationship loading\n\t\t\tconst qb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tqb.where({ parent: null });\n\t\t\tconst rootNode = await qb.getSingleResult();\n\t\t\treturn rootNode || null;\n\t\t}\n\n\t\tconst parts = normalized.split('/').filter((p) => p);\n\n\t\t// Get root node\n\t\tconst rootQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\trootQb.where({ parent: null });\n\t\tlet currentNode = await rootQb.getSingleResult();\n\t\tif (!currentNode) return null;\n\n\t\t// Traverse path parts\n\t\tfor (const part of parts) {\n\t\t\tconst childQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tchildQb.where({ parent: currentNode, filename: part });\n\t\t\tconst child = await childQb.getSingleResult();\n\t\t\tif (!child) return null;\n\t\t\tcurrentNode = child;\n\t\t}\n\n\t\treturn currentNode;\n\t}\n\n\t/**\n\t * 将数据库实体转换为 IFileStat 接口\n\t */\n\tprivate _toFileStat(node: FileNodeMetaEntity, path: string): IFileStat {\n\t\t// Handle mtime - it might be a Date object or a string from raw query\n\t\tlet mtime: number;\n\t\tif (node.mtime instanceof Date) {\n\t\t\tmtime = node.mtime.getTime();\n\t\t} else if (typeof node.mtime === 'string') {\n\t\t\tmtime = new Date(node.mtime).getTime();\n\t\t} else {\n\t\t\tmtime = Date.now();\n\t\t}\n\n\t\t// Handle size - convert bigint to number if needed\n\t\tlet size: number;\n\t\tif (typeof node.size === 'bigint') {\n\t\t\tsize = Number(node.size);\n\t\t} else {\n\t\t\tsize = node.size;\n\t\t}\n\n\t\treturn {\n\t\t\tpath: path,\n\t\t\tname: node.filename,\n\t\t\tkind: node.kind,\n\t\t\tsize: size,\n\t\t\tmtime: mtime,\n\t\t\tmeta: node.metadata || {},\n\t\t\t// `directory` 字段可以根据 path 动态计算\n\t\t\tdirectory: dirname(path),\n\t\t};\n\t}\n\n\tprivate async _copyNode(\n\t\tsrcNode: FileNodeMetaEntity,\n\t\tdestParent: FileNodeMetaEntity,\n\t\tnewName: string,\n\t\tem: EntityManager,\n\t): Promise<void> {\n\t\t// 1. 复制节点本身\n\t\tconst now = new Date();\n\t\tconst newNode = em.create(FileNodeMetaEntity, {\n\t\t\ttid: srcNode.tid,\n\t\t\tfilename: newName,\n\t\t\tparent: destParent,\n\t\t\tkind: srcNode.kind,\n\t\t\tsize: srcNode.size,\n\t\t\tmetadata: srcNode.metadata, // deep copy metadata\n\t\t\tcontent: srcNode.content, // copy small file content\n\t\t\tatime: now,\n\t\t\tbtime: now,\n\t\t\tctime: now,\n\t\t\tmtime: now,\n\t\t});\n\n\t\t// 2. 复制大文件内容 (如果存在) - use QueryBuilder to avoid relationship loading\n\t\tif (!srcNode.content) {\n\t\t\tconst srcFileContentQb = em.createQueryBuilder(FileNodeContentEntity, 'fc');\n\t\t\tsrcFileContentQb.where({ node: srcNode });\n\t\t\tconst srcFileContent = await srcFileContentQb.getSingleResult();\n\t\t\tif (srcFileContent) {\n\t\t\t\tconst _newContent = em.create(FileNodeContentEntity, {\n\t\t\t\t\tnode: newNode, // Use node relationship as primary key\n\t\t\t\t\ttid: srcNode.tid,\n\t\t\t\t\tcontent: srcFileContent.content,\n\t\t\t\t\tsize: srcFileContent.size,\n\t\t\t\t\tmd5: srcFileContent.md5,\n\t\t\t\t\tsha256: srcFileContent.sha256,\n\t\t\t\t\tmimeType: srcFileContent.mimeType,\n\t\t\t\t\tmetadata: srcFileContent.metadata,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tawait em.persistAndFlush(newNode);\n\n\t\t// 3. 如果是目录,递归复制子节点\n\t\tif (srcNode.kind === FileKind.directory) {\n\t\t\tconst childrenQb = em.createQueryBuilder(FileNodeMetaEntity, 'f');\n\t\t\tchildrenQb.where({ parent: srcNode });\n\t\t\tconst children = await childrenQb.getResult();\n\t\t\tfor (const child of children) {\n\t\t\t\tawait this._copyNode(child, newNode, child.filename, em);\n\t\t\t}\n\t\t}\n\t}\n}\n\n@Entity({ tableName: 'file_node_meta' })\n@Unique({ properties: ['tid', 'parent', 'filename'] })\nexport class FileNodeMetaEntity extends TenantBaseEntity {\n\t@Property({ type: types.string, nullable: false, comment: '文件名' })\n\tfilename!: string;\n\t@Property({ type: types.bigint, nullable: false, default: 0, comment: '文件大小' })\n\tsize!: number & Opt;\n\t@Property({ type: types.string, nullable: false, comment: '文件类型' })\n\tkind!: FileKind;\n\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tatime!: Date & Opt;\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tbtime!: Date & Opt;\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tctime!: Date & Opt;\n\t@Property({ type: types.datetime, nullable: false, defaultRaw: 'CURRENT_TIMESTAMP' })\n\tmtime!: Date & Opt;\n\n\t@Property({ type: types.json, nullable: false, defaultRaw: '{}' })\n\tmetadata!: Record<string, any>;\n\n\t@ManyToOne(() => FileNodeMetaEntity, { nullable: true, cascade: [] })\n\tparent?: Rel<FileNodeMetaEntity>;\n\n\t@OneToMany({ entity: () => FileNodeMetaEntity, mappedBy: 'parent', orphanRemoval: true })\n\tchildren = new Collection<FileNodeMetaEntity>(this);\n\n\t@OneToOne({\n\t\tentity: () => FileNodeContentEntity,\n\t\tmappedBy: 'node',\n\t\torphanRemoval: true,\n\t\tnullable: true,\n\t\tcascade: [Cascade.ALL],\n\t})\n\tfileContent?: Rel<FileNodeContentEntity>;\n\t@Property({ type: types.blob, nullable: true, comment: '文件内容' })\n\tcontent?: Buffer; // for small file, e.g. < 64k\n\n\t//region content\n\n\tget parentId() {\n\t\treturn this.parent?.id as Opt<string | undefined>;\n\t}\n\n\t//endregion\n}\n\n@Entity({ tableName: 'file_node_content' })\nexport class FileNodeContentEntity extends TenantBaseEntity {\n\t@OneToOne({ entity: () => FileNodeMetaEntity, owner: true, joinColumn: 'node_id' })\n\tnode!: Rel<FileNodeMetaEntity>;\n\n\t@Property({ type: types.integer, nullable: false })\n\tsize!: number; // 保留 size 方便查询分析\n\n\t@Property({ type: types.blob, lazy: true, comment: '文件内容' })\n\tcontent!: Buffer;\n\n\t@Property({ type: types.string, nullable: true })\n\tmimeType?: string;\n\n\t@Property({ type: types.string, nullable: false })\n\tmd5?: string;\n\t@Property({ type: types.string, nullable: false })\n\tsha256?: string;\n\n\t@Property({ type: types.string, nullable: true })\n\ttext?: string;\n\t@Property({ type: types.integer, nullable: true })\n\twidth?: number;\n\t@Property({ type: types.integer, nullable: true })\n\theight?: number;\n\t// @Property({ type: types.integer, nullable: true })\n\t// length?: number;\n\n\t@Property({ type: types.json, nullable: false, defaultRaw: '{}' })\n\tmetadata!: Record<string, any>;\n}\n"],"names":["crypto","basename","dirname","join","normalize","Cascade","Collection","Entity","ManyToOne","OneToMany","OneToOne","Property","types","Unique","TenantBaseEntity","getEntityManager","FileSystemError","FileSystemErrorCode","FileKind","createDatabaseFileSystem","options","DBFS","fork","smallFileThreshold","em","ensureRootNode","rootQb","createQueryBuilder","FileNodeMetaEntity","where","parent","rootNode","getSingleResult","now","Date","rootDir","create","filename","kind","directory","size","atime","btime","ctime","mtime","persistAndFlush","error","message","includes","existingRootQb","existingRoot","stat","path","_options","EINVAL","node","_getNodeByPath","ENOENT","_toFileStat","exists","readdir","dir","parentNode","ENOTDIR","qb","children","getResult","map","child","mkdir","_mkdirInTransaction","normalized","parentPath","newDirName","recursive","existingQb","existing","EEXIST","newDir","tid","readFile","file","EISDIR","buffer","content","fileContentQb","FileNodeContentEntity","fileContent","encoding","toString","writeFile","data","undefined","transactional","overwrite","bufferData","Buffer","isBuffer","from","length","nodeQb","existingContentQb","existingContent","removeAndFlush","md5","createHash","update","digest","sha256","rm","force","childrenQb","select","ENOTEMPTY","rename","oldPath","newPath","newParentPath","newFilename","newParentNode","existingDestQb","existingDest","id","flush","copy","srcPath","destPath","srcNode","destParentPath","destFilename","destParentNode","_copyNode","createReadStream","_path","Error","createWriteStream","createReadableStream","createWritableStream","pathStr","parts","split","filter","p","currentNode","part","childQb","getTime","Number","name","meta","metadata","destParent","newName","newNode","srcFileContentQb","srcFileContent","_newContent","mimeType","parentId","type","string","nullable","comment","bigint","default","datetime","defaultRaw","json","cascade","entity","mappedBy","orphanRemoval","ALL","blob","tableName","properties","text","width","height","owner","joinColumn","integer","lazy"],"mappings":"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"}
|