@wener/common 2.0.2 → 2.0.5
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 +22 -15
- 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 +66 -146
- 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 +6 -8
- 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 +87 -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/drain3/Drain.js +356 -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 +204 -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 +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 +250 -0
- package/lib/fs/createBrowserFileSystem.js.map +1 -0
- package/lib/fs/createMemoryFileSystem.js +517 -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 +154 -0
- package/lib/fs/createWebDavFileSystem.js.map +1 -0
- package/lib/fs/createWebFileSystem.js +225 -0
- package/lib/fs/createWebFileSystem.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/minio/createMinioFileSystem.js +974 -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 +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 +753 -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 +426 -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 +319 -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/fs/webdav/index.js +2 -0
- package/lib/fs/webdav/index.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 +138 -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 +50 -293
- package/lib/schema/toJsonSchema.js.map +1 -0
- package/lib/schema/validate.js +34 -46
- 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 +80 -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 +9 -1
- package/src/cn/DivisionCode.test.ts +1 -1
- package/src/cn/DivisionCode.ts +8 -0
- package/src/cn/Mod11.ts +1 -1
- package/src/cn/UnifiedSocialCreditCode.test.ts +1 -1
- package/src/cn/UnifiedSocialCreditCode.ts +15 -0
- package/src/cn/__snapshots__/ChineseResidentIdNo.test.ts.snap +1 -1
- 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 +40 -12
- package/src/data/maybeNumber.ts +1 -1
- package/src/data/parseSort.test.ts +0 -1
- package/src/data/types.d.ts +2 -2
- package/src/dayjs/dayjs.ts +18 -18
- package/src/dayjs/formatDuration.ts +2 -2
- 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 +164 -0
- 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 +36 -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/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 +101 -0
- package/src/fs/MemoryFileSystem.test.ts +37 -0
- package/src/fs/createBrowserFileSystem.ts +293 -0
- package/src/fs/createMemoryFileSystem.ts +600 -0
- package/src/fs/createSandboxFileSystem.ts +136 -0
- package/src/fs/createWebDavFileSystem.ts +190 -0
- package/src/fs/createWebFileSystem.ts +242 -0
- package/src/fs/findMimeType.ts +20 -0
- package/src/fs/index.ts +8 -0
- package/src/fs/minio/createMinioFileSystem.ts +1148 -0
- package/src/fs/minio/index.ts +1 -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 +871 -0
- package/src/fs/s3/index.ts +1 -0
- package/src/fs/s3/s3fs.test.ts +441 -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 +518 -0
- package/src/fs/server/dbfs.test.ts +48 -0
- package/src/fs/server/index.ts +1 -0
- package/src/fs/server/loadTestDatabase.ts +131 -0
- package/src/fs/tests/runFileSystemTest.ts +289 -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/fs/webdav/index.ts +1 -0
- package/src/jsonschema/JsonSchema.ts +118 -110
- package/src/jsonschema/forEachJsonSchema.ts +50 -0
- package/src/jsonschema/index.ts +1 -0
- package/src/jsonschema/types.d.ts +1 -1
- package/src/meta/defineMetadata.ts +1 -1
- 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 +6 -6
- package/src/password/Password.test.ts +1 -1
- package/src/password/createArgon2PasswordAlgorithm.ts +1 -1
- package/src/password/createBase64PasswordAlgorithm.ts +2 -2
- package/src/password/createBcryptPasswordAlgorithm.ts +4 -2
- package/src/password/createPBKDF2PasswordAlgorithm.ts +4 -4
- package/src/password/createScryptPasswordAlgorithm.ts +4 -4
- package/src/resource/ListQuery.ts +4 -1
- package/src/resource/index.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/TypeSchema.d.ts +6 -6
- package/src/schema/createSchemaData.ts +4 -4
- package/src/schema/findJsonSchemaByPath.ts +4 -4
- package/src/schema/formatZodError.test.ts +197 -0
- package/src/schema/formatZodError.ts +139 -0
- package/src/schema/getSchemaOptions.ts +2 -2
- package/src/schema/index.ts +1 -1
- package/src/schema/toJsonSchema.ts +6 -6
- package/src/schema/validate.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,246 @@
|
|
|
1
|
+
import { Drain } from './Drain';
|
|
2
|
+
import type { LogCluster } from './LogCluster';
|
|
3
|
+
import type { PersistenceHandler } from './persistence/PersistenceHandler';
|
|
4
|
+
import type { ClusterUpdateType, ExtractedParameter, SearchStrategy } from './types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* High-level API for log template mining with persistence support.
|
|
8
|
+
*
|
|
9
|
+
* TemplateMiner wraps the Drain algorithm and provides convenience methods
|
|
10
|
+
* for extracting parameters and managing persistence.
|
|
11
|
+
*/
|
|
12
|
+
export class TemplateMiner {
|
|
13
|
+
constructor(
|
|
14
|
+
private drain: Drain,
|
|
15
|
+
private readonly persistence: PersistenceHandler,
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Adds a log message and returns the update type, cluster, template, and cluster count.
|
|
20
|
+
*
|
|
21
|
+
* @param content The log message content
|
|
22
|
+
* @returns Object containing updateType, cluster, templateMined, and clusterCount
|
|
23
|
+
*/
|
|
24
|
+
async addLogMessage(content: string): Promise<{
|
|
25
|
+
updateType: ClusterUpdateType;
|
|
26
|
+
cluster: LogCluster;
|
|
27
|
+
templateMined: string;
|
|
28
|
+
clusterCount: number;
|
|
29
|
+
}> {
|
|
30
|
+
const { cluster, updateType } = this.drain.addLogMessage(content);
|
|
31
|
+
|
|
32
|
+
const templateMined = cluster.getTemplate();
|
|
33
|
+
const clusterCount = this.drain.getClusters().length;
|
|
34
|
+
|
|
35
|
+
if (updateType !== 'none') {
|
|
36
|
+
await this.saveState();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
updateType,
|
|
41
|
+
cluster,
|
|
42
|
+
templateMined,
|
|
43
|
+
clusterCount,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Matches a log message against an already existing cluster.
|
|
49
|
+
*
|
|
50
|
+
* @param content Log message to match
|
|
51
|
+
* @param strategy Search strategy
|
|
52
|
+
* @returns Matched cluster or null
|
|
53
|
+
*/
|
|
54
|
+
match(content: string, strategy: SearchStrategy = 'never'): LogCluster | null {
|
|
55
|
+
return this.drain.match(content, strategy);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Extracts parameters from a log message according to a provided template.
|
|
60
|
+
*
|
|
61
|
+
* @param logTemplate Template generated by AddLogMessage
|
|
62
|
+
* @param logMessage The log message to extract parameters from
|
|
63
|
+
* @returns Array of extracted parameters, or null if template doesn't match
|
|
64
|
+
*/
|
|
65
|
+
extractParameters(logTemplate: string, logMessage: string): ExtractedParameter[] | null {
|
|
66
|
+
// Apply delimiters
|
|
67
|
+
let processedMessage = logMessage;
|
|
68
|
+
for (const delimiter of this.drain.extraDelimiters) {
|
|
69
|
+
// Escape delimiter for regex if it contains special characters
|
|
70
|
+
const escapedDelimiter = delimiter.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
71
|
+
processedMessage = processedMessage.replace(new RegExp(escapedDelimiter, 'g'), ' ');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const { templateRegex, paramGroupNameToMaskName } = this.getTemplateParameterExtractionRegex(logTemplate);
|
|
75
|
+
|
|
76
|
+
// Create regex from template
|
|
77
|
+
const regex = new RegExp(templateRegex);
|
|
78
|
+
|
|
79
|
+
// Match the log message against the template
|
|
80
|
+
const match = processedMessage.match(regex);
|
|
81
|
+
|
|
82
|
+
// Template doesn't match
|
|
83
|
+
if (match === null) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Extract named captures
|
|
88
|
+
const extractedParameters: ExtractedParameter[] = [];
|
|
89
|
+
|
|
90
|
+
// Get all named groups from the match
|
|
91
|
+
if (match.groups) {
|
|
92
|
+
for (const [groupName, value] of Object.entries(match.groups)) {
|
|
93
|
+
if (value !== undefined) {
|
|
94
|
+
const maskName = paramGroupNameToMaskName.get(groupName);
|
|
95
|
+
if (maskName !== undefined) {
|
|
96
|
+
extractedParameters.push({
|
|
97
|
+
value,
|
|
98
|
+
maskName,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Also check by index if groups are not available (fallback)
|
|
106
|
+
// The regex exec method provides better named group support
|
|
107
|
+
const execResult = regex.exec(processedMessage);
|
|
108
|
+
if (execResult !== null && execResult.groups === undefined) {
|
|
109
|
+
// Fallback: extract by order (less reliable but works)
|
|
110
|
+
const indices = Array.from({ length: execResult.length - 1 }, (_, i) => i + 1);
|
|
111
|
+
let paramIndex = 0;
|
|
112
|
+
for (const index of indices) {
|
|
113
|
+
const value = execResult[index];
|
|
114
|
+
if (value !== undefined) {
|
|
115
|
+
// Find corresponding mask name by order
|
|
116
|
+
// This is a fallback - ideally we should use named groups
|
|
117
|
+
const maskName = paramGroupNameToMaskName.get(`p_${paramIndex}`);
|
|
118
|
+
if (maskName !== undefined) {
|
|
119
|
+
extractedParameters.push({
|
|
120
|
+
value,
|
|
121
|
+
maskName,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
paramIndex++;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return extractedParameters.length > 0 ? extractedParameters : null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Gets the template parameter extraction regex and mapping.
|
|
134
|
+
*
|
|
135
|
+
* @param logTemplate The log template
|
|
136
|
+
* @returns Tuple of [templateRegex, paramGroupNameToMaskName]
|
|
137
|
+
*/
|
|
138
|
+
private getTemplateParameterExtractionRegex(logTemplate: string): {
|
|
139
|
+
templateRegex: string;
|
|
140
|
+
paramGroupNameToMaskName: Map<string, string>;
|
|
141
|
+
} {
|
|
142
|
+
const paramGroupNameToMaskName = new Map<string, string>();
|
|
143
|
+
let paramNameCounter = 0;
|
|
144
|
+
|
|
145
|
+
const getNextParamName = (): string => {
|
|
146
|
+
const paramGroupName = `p_${paramNameCounter}`;
|
|
147
|
+
paramNameCounter++;
|
|
148
|
+
return paramGroupName;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Create a named group with the respective patterns for the given mask-name
|
|
152
|
+
const createCaptureRegex = (maskName: string): string => {
|
|
153
|
+
const allowedPatterns: string[] = [];
|
|
154
|
+
|
|
155
|
+
if (maskName === '*') {
|
|
156
|
+
allowedPatterns.push('.+?');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Give each capture group a unique name to avoid conflict
|
|
160
|
+
const paramGroupName = getNextParamName();
|
|
161
|
+
paramGroupNameToMaskName.set(paramGroupName, maskName);
|
|
162
|
+
const joinedPatterns = allowedPatterns.join('|');
|
|
163
|
+
const captureRegex = `(?<${paramGroupName}>${joinedPatterns})`;
|
|
164
|
+
|
|
165
|
+
return captureRegex;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// For every mask in the template, replace it with a named group
|
|
169
|
+
const maskNames = new Set<string>();
|
|
170
|
+
// The drain catch-all mask
|
|
171
|
+
maskNames.add('*');
|
|
172
|
+
|
|
173
|
+
// Escape the template for regex
|
|
174
|
+
let templateRegex = this.escapeRegex(logTemplate);
|
|
175
|
+
|
|
176
|
+
// Replace each mask name with a proper regex that captures it
|
|
177
|
+
for (const maskName of maskNames) {
|
|
178
|
+
const searchStr = `<${this.escapeRegex(maskName)}>`;
|
|
179
|
+
|
|
180
|
+
// Replace one-by-one to get a new param group name for each replacement
|
|
181
|
+
while (true) {
|
|
182
|
+
const repStr = createCaptureRegex(maskName);
|
|
183
|
+
const templateRegexNew = templateRegex.replace(searchStr, repStr);
|
|
184
|
+
// Break when all replaces for this mask are done
|
|
185
|
+
if (templateRegexNew === templateRegex) {
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
templateRegex = templateRegexNew;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Match also messages with multiple spaces or other whitespace chars between tokens
|
|
193
|
+
templateRegex = templateRegex.replace(/\\ /g, '\\s+');
|
|
194
|
+
templateRegex = `^${templateRegex}$`;
|
|
195
|
+
|
|
196
|
+
return { templateRegex, paramGroupNameToMaskName };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Escapes special regex characters in a string.
|
|
201
|
+
*/
|
|
202
|
+
private escapeRegex(str: string): string {
|
|
203
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Loads the Drain state from persistence.
|
|
208
|
+
*
|
|
209
|
+
* @throws Error if loading fails
|
|
210
|
+
*/
|
|
211
|
+
async loadState(): Promise<void> {
|
|
212
|
+
const state = await this.persistence.load();
|
|
213
|
+
if (state === null || (typeof state === 'string' && state.length === 0)) {
|
|
214
|
+
throw new Error('saved state not found');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
const stateStr = typeof state === 'string' ? state : new TextDecoder().decode(state);
|
|
219
|
+
const data = JSON.parse(stateStr);
|
|
220
|
+
this.drain = Drain.fromJSON(data);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw new Error(`failed to unmarshal state: ${error instanceof Error ? error.message : String(error)}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Saves the Drain state to persistence.
|
|
228
|
+
*
|
|
229
|
+
* @throws Error if saving fails
|
|
230
|
+
*/
|
|
231
|
+
async saveState(): Promise<void> {
|
|
232
|
+
try {
|
|
233
|
+
const state = JSON.stringify(this.drain.toJSON());
|
|
234
|
+
await this.persistence.save(state);
|
|
235
|
+
} catch (error) {
|
|
236
|
+
throw new Error(`failed to save state: ${error instanceof Error ? error.message : String(error)}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Gets the underlying Drain instance.
|
|
242
|
+
*/
|
|
243
|
+
getDrain(): Drain {
|
|
244
|
+
return this.drain;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drain3 - A TypeScript implementation of the Drain log clustering algorithm.
|
|
3
|
+
*
|
|
4
|
+
* Drain is an online log parsing algorithm that groups log messages into clusters
|
|
5
|
+
* based on their structural similarity, extracting templates by parameterizing
|
|
6
|
+
* variable parts of the logs.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { Drain, TemplateMiner, MemoryPersistence } from '@wener/common/drain3';
|
|
11
|
+
*
|
|
12
|
+
* // Basic usage
|
|
13
|
+
* const drain = new Drain({
|
|
14
|
+
* logClusterDepth: 4,
|
|
15
|
+
* simTh: 0.4,
|
|
16
|
+
* maxClusters: 1000
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* const result = drain.addLogMessage('[INFO] User 123 logged in');
|
|
20
|
+
* console.log(result.cluster.getTemplate()); // [INFO] User <*> logged in
|
|
21
|
+
*
|
|
22
|
+
* // Advanced usage with persistence
|
|
23
|
+
* const miner = new TemplateMiner(drain, new MemoryPersistence());
|
|
24
|
+
* await miner.addLogMessage('[INFO] User 123 logged in');
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
export { Drain } from './Drain';
|
|
29
|
+
export { LogCluster } from './LogCluster';
|
|
30
|
+
export { Node } from './Node';
|
|
31
|
+
export { TemplateMiner } from './TemplateMiner';
|
|
32
|
+
|
|
33
|
+
export type { ClusterUpdateType, DrainOptions, ExtractedParameter, SearchStrategy } from './types';
|
|
34
|
+
|
|
35
|
+
export type { PersistenceHandler } from './persistence/PersistenceHandler';
|
|
36
|
+
export { MemoryPersistence } from './persistence/MemoryPersistence';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import type { PersistenceHandler } from './PersistenceHandler';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* File-based persistence handler that saves and loads state from the filesystem.
|
|
6
|
+
*/
|
|
7
|
+
export class FilePersistence implements PersistenceHandler {
|
|
8
|
+
constructor(private readonly filePath: string) {}
|
|
9
|
+
|
|
10
|
+
async save(state: Uint8Array | string): Promise<void> {
|
|
11
|
+
await writeFile(this.filePath, state, 'utf8');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async load(): Promise<string | null> {
|
|
15
|
+
try {
|
|
16
|
+
return await readFile(this.filePath, 'utf8');
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if ((error as { code?: string })?.code === 'ENOENT') {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { PersistenceHandler } from './PersistenceHandler';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In-memory persistence handler that stores state in memory.
|
|
5
|
+
* Useful for testing or when persistence is not needed.
|
|
6
|
+
*/
|
|
7
|
+
export class MemoryPersistence implements PersistenceHandler {
|
|
8
|
+
private state: Uint8Array | string | null = null;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Saves the state to memory.
|
|
12
|
+
*/
|
|
13
|
+
async save(state: Uint8Array | string): Promise<void> {
|
|
14
|
+
this.state = state;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Loads the state from memory.
|
|
19
|
+
*/
|
|
20
|
+
async load(): Promise<Uint8Array | string | null> {
|
|
21
|
+
return this.state;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for persistence handlers that can save and load Drain state.
|
|
3
|
+
*/
|
|
4
|
+
export interface PersistenceHandler {
|
|
5
|
+
/**
|
|
6
|
+
* Saves the Drain state.
|
|
7
|
+
*
|
|
8
|
+
* @param state Serialized state data
|
|
9
|
+
* @returns Promise that resolves when save is complete
|
|
10
|
+
*/
|
|
11
|
+
save(state: Uint8Array | string): Promise<void>;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Loads the Drain state.
|
|
15
|
+
*
|
|
16
|
+
* @returns Promise that resolves with the loaded state, or null if no state exists
|
|
17
|
+
*/
|
|
18
|
+
load(): Promise<Uint8Array | string | null>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cluster update type indicating what happened when a log message was processed.
|
|
3
|
+
*/
|
|
4
|
+
export type ClusterUpdateType = 'none' | 'created' | 'templateChanged';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Search strategy for matching log messages against existing clusters.
|
|
8
|
+
*
|
|
9
|
+
* - 'never': Fastest, always performs tree search [O(log(n))] but might produce false negatives
|
|
10
|
+
* - 'fallback': Performs linear search [O(n)] only if tree search found no match, should not have false negatives
|
|
11
|
+
* - 'always': Slowest, always evaluates all clusters and selects the best match with least wildcard parameters
|
|
12
|
+
*/
|
|
13
|
+
export type SearchStrategy = 'never' | 'fallback' | 'always';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Configuration options for Drain algorithm.
|
|
17
|
+
*/
|
|
18
|
+
export interface DrainOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Depth of the prefix tree for log clustering. Must be at least 3.
|
|
21
|
+
* @default 4
|
|
22
|
+
*/
|
|
23
|
+
logClusterDepth?: number;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Similarity threshold (0.0 to 1.0) for matching log messages to clusters.
|
|
27
|
+
* @default 0.4
|
|
28
|
+
*/
|
|
29
|
+
simTh?: number;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Maximum number of children nodes in the prefix tree.
|
|
33
|
+
* @default 100
|
|
34
|
+
*/
|
|
35
|
+
maxChildren?: number;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Maximum number of clusters to maintain in LRU cache.
|
|
39
|
+
* @default 1000
|
|
40
|
+
*/
|
|
41
|
+
maxClusters?: number;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Additional delimiters to replace with spaces during tokenization.
|
|
45
|
+
* @default []
|
|
46
|
+
*/
|
|
47
|
+
extraDelimiters?: string[];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* String used to represent parameterized tokens in templates.
|
|
51
|
+
* @default "<*>"
|
|
52
|
+
*/
|
|
53
|
+
paramStr?: string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Whether to automatically parameterize tokens containing numbers.
|
|
57
|
+
* @default true
|
|
58
|
+
*/
|
|
59
|
+
parametrizeNumericTokens?: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Extracted parameter from a log message based on a template.
|
|
64
|
+
*/
|
|
65
|
+
export interface ExtractedParameter {
|
|
66
|
+
/**
|
|
67
|
+
* The extracted parameter value.
|
|
68
|
+
*/
|
|
69
|
+
value: string;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The mask name (e.g., "*") that matched this parameter.
|
|
73
|
+
*/
|
|
74
|
+
maskName: string;
|
|
75
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createEmitter } from './emitter';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const FileSystemErrorCode = {
|
|
2
|
+
ENOENT: 'ENOENT',
|
|
3
|
+
ENOTDIR: 'ENOTDIR',
|
|
4
|
+
EEXIST: 'EEXIST',
|
|
5
|
+
EISDIR: 'EISDIR',
|
|
6
|
+
ENOTEMPTY: 'ENOTEMPTY',
|
|
7
|
+
EACCES: 'EACCES',
|
|
8
|
+
EPERM: 'EPERM',
|
|
9
|
+
EINVAL: 'EINVAL',
|
|
10
|
+
} as const;
|
|
11
|
+
|
|
12
|
+
export type FileSystemErrorCode = (typeof FileSystemErrorCode)[keyof typeof FileSystemErrorCode];
|
|
13
|
+
|
|
14
|
+
export class FileSystemError extends Error {
|
|
15
|
+
constructor(
|
|
16
|
+
message: string,
|
|
17
|
+
public readonly code: FileSystemErrorCode | string,
|
|
18
|
+
) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = 'FileSystemError';
|
|
21
|
+
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
22
|
+
if (Error.captureStackTrace) {
|
|
23
|
+
Error.captureStackTrace(this, FileSystemError);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { FileKind, FileUrlOptions } from './types';
|
|
2
|
+
|
|
3
|
+
// Base operation options
|
|
4
|
+
type OperationOptions = {
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Directory operations
|
|
9
|
+
export type ReaddirOptions = OperationOptions & {
|
|
10
|
+
glob?: string;
|
|
11
|
+
recursive?: boolean;
|
|
12
|
+
depth?: number;
|
|
13
|
+
kind?: FileKind;
|
|
14
|
+
hidden?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type MkdirOptions = OperationOptions & {
|
|
17
|
+
recursive?: boolean;
|
|
18
|
+
};
|
|
19
|
+
// File operations
|
|
20
|
+
export type ReadFileOptions = OperationOptions & {
|
|
21
|
+
encoding?: 'text' | 'binary';
|
|
22
|
+
onDownloadProgress?: (e: { loaded: number; total: number }) => void;
|
|
23
|
+
};
|
|
24
|
+
export type WriteFileOptions = OperationOptions & {
|
|
25
|
+
overwrite?: boolean;
|
|
26
|
+
onUploadProgress?: (e: { loaded: number; total: number }) => void;
|
|
27
|
+
};
|
|
28
|
+
export type RenameOptions = OperationOptions & {
|
|
29
|
+
overwrite?: boolean;
|
|
30
|
+
};
|
|
31
|
+
export type RmOptions = OperationOptions & {
|
|
32
|
+
recursive?: boolean;
|
|
33
|
+
force?: boolean;
|
|
34
|
+
};
|
|
35
|
+
export type CopyOptions = OperationOptions & {
|
|
36
|
+
overwrite?: boolean;
|
|
37
|
+
shallow?: boolean;
|
|
38
|
+
};
|
|
39
|
+
export type CreateReadStreamOptions = OperationOptions & {
|
|
40
|
+
range?: { start: number; end?: number };
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
};
|
|
43
|
+
export type CreateWriteStreamOptions = OperationOptions & {
|
|
44
|
+
overwrite?: boolean;
|
|
45
|
+
};
|
|
46
|
+
export type StatOptions = OperationOptions & {};
|
|
47
|
+
|
|
48
|
+
type WritableData = string | ArrayBuffer | ArrayBufferView<ArrayBufferLike> | ReadableStream;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Universal file system interface (browser & server compatible)
|
|
52
|
+
*/
|
|
53
|
+
export type IFileSystem = {
|
|
54
|
+
readdir(dir: string, options?: ReaddirOptions): Promise<IFileStat[]>;
|
|
55
|
+
stat(entry: string, options?: StatOptions): Promise<IFileStat>;
|
|
56
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
57
|
+
readFile(path: string, options?: ReadFileOptions & { encoding: 'text' }): Promise<string>;
|
|
58
|
+
readFile(path: string, options?: ReadFileOptions): Promise<Uint8Array>;
|
|
59
|
+
writeFile(path: string, data: WritableData, options?: WriteFileOptions): Promise<void>;
|
|
60
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
61
|
+
rename(oldPath: string, newPath: string, options?: RenameOptions): Promise<void>;
|
|
62
|
+
exists(path: string): Promise<boolean>;
|
|
63
|
+
copy(src: string, dest: string, options?: CopyOptions): Promise<void>;
|
|
64
|
+
|
|
65
|
+
getUrl?(path: IFileStat | string, options?: FileUrlOptions): string | undefined;
|
|
66
|
+
|
|
67
|
+
createReadableStream?(path: string, options?: CreateReadStreamOptions): ReadableStream;
|
|
68
|
+
createWritableStream?(path: string, options?: CreateWriteStreamOptions): WritableStream;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Server/Node.js specific file system interface with stream support
|
|
73
|
+
*/
|
|
74
|
+
export type IServerFileSystem = IFileSystem & {
|
|
75
|
+
createReadStream(path: string, options?: CreateReadStreamOptions): import('node:stream').Readable;
|
|
76
|
+
createWriteStream(path: string, options?: CreateWriteStreamOptions): import('node:stream').Writable;
|
|
77
|
+
writeFile(
|
|
78
|
+
path: string,
|
|
79
|
+
data: WritableData | Buffer | import('node:stream').Readable,
|
|
80
|
+
options?: WriteFileOptions,
|
|
81
|
+
): Promise<void>;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type IFileStat = {
|
|
85
|
+
/**
|
|
86
|
+
* parent path
|
|
87
|
+
*/
|
|
88
|
+
directory: string;
|
|
89
|
+
/**
|
|
90
|
+
* full path
|
|
91
|
+
*/
|
|
92
|
+
path: string;
|
|
93
|
+
/**
|
|
94
|
+
* basename
|
|
95
|
+
*/
|
|
96
|
+
name: string;
|
|
97
|
+
kind: 'directory' | 'file';
|
|
98
|
+
mtime: number;
|
|
99
|
+
meta: Record<string, any>;
|
|
100
|
+
size: number;
|
|
101
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { beforeEach, describe, test } from 'vitest';
|
|
2
|
+
import { createMemoryFileSystem } from './createMemoryFileSystem';
|
|
3
|
+
import { runFileSystemTest } from './tests/runFileSystemTest';
|
|
4
|
+
|
|
5
|
+
describe('MemoryFileSystem', () => {
|
|
6
|
+
let fs: ReturnType<typeof createMemoryFileSystem>;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
fs = createMemoryFileSystem({
|
|
10
|
+
root: {
|
|
11
|
+
path: '/',
|
|
12
|
+
directory: '',
|
|
13
|
+
name: '',
|
|
14
|
+
kind: 'directory',
|
|
15
|
+
meta: {},
|
|
16
|
+
mtime: Date.now(),
|
|
17
|
+
size: 0,
|
|
18
|
+
children: [
|
|
19
|
+
{
|
|
20
|
+
path: '/README.txt',
|
|
21
|
+
directory: '/',
|
|
22
|
+
name: 'README.txt',
|
|
23
|
+
kind: 'file',
|
|
24
|
+
content: 'Hello',
|
|
25
|
+
size: 5,
|
|
26
|
+
meta: {},
|
|
27
|
+
mtime: Date.now(),
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('common tests', async () => {
|
|
35
|
+
await runFileSystemTest(fs);
|
|
36
|
+
});
|
|
37
|
+
});
|