1 parent
7d656c0511
commit
ae0dfd1003
8 files changed
+23
-7
No files matched your search
@@ -21,8 +21,8 @@
|
||||
en: 1bceab0cdb2e8f8e
|
||||
zh: 7d14d0c1ad90e9e2
|
||||
/deepseek-ai-dsh-fs-local/use-this-package/minimal-configuration:
|
||||
en: 60678d0c5fbf3c56
|
||||
zh: 1698a9645c12578b
|
||||
en: 43a819d492ee1e64
|
||||
zh: 913c81168ea57cf4
|
||||
/deepseek-ai-dsh-fs-local/use-this-package/what-you-can-do:
|
||||
en: cff37f0ccf4cff2a
|
||||
zh: d26ce57570880789
|
||||
|
||||
@@ -33,7 +33,7 @@ Choose `fs-local` for ordinary host-file access in a single process. Choose [`fs
|
||||
|
||||
### Minimal configuration
|
||||
|
||||
Load the backend with a base directory; relative paths resolve against it, and absolute paths ignore it. A relative base is anchored to the provider process working directory, and display paths remain absolute. On POSIX, resolution follows filesystem semantics before lexical normalization: `symlink/..` reaches the parent of the link target, including when the final file does not exist yet. Directory listings preserve the same physical traversal in displayed child paths. Windows retains native drive-relative normalization.
|
||||
Load the backend with a base directory; relative paths resolve against it, and absolute paths ignore it. A leading `~`, `~/`, or `~\` names the host user's home directory. A relative base is anchored to the provider process working directory, and display paths remain absolute. On POSIX, resolution follows filesystem semantics before lexical normalization: `symlink/..` reaches the parent of the link target, including when the final file does not exist yet. Directory listings preserve the same physical traversal in displayed child paths. Windows retains native drive-relative normalization.
|
||||
|
||||
```yaml
|
||||
- name: '@deepseek-ai/dsh-fs-local'
|
||||
|
||||
@@ -33,7 +33,7 @@ kind: "package-reference"
|
||||
|
||||
### 最小配置
|
||||
|
||||
用一个基础目录加载后端;相对路径基于它解析,绝对路径则忽略它。相对基础目录以提供方进程工作目录为起点,展示路径始终保持绝对路径。在 POSIX 上,解析先遵循文件系统语义,再进行词法规范化:`symlink/..` 到达链接目标的父目录,即使最终文件尚不存在也如此。目录列表中的子项展示路径保留同样的物理遍历语义。Windows 保留原生的驱动器相对路径规范化行为。
|
||||
用一个基础目录加载后端;相对路径基于它解析,绝对路径则忽略它。开头的 `~`、`~/` 或 `~\` 表示宿主用户的主目录。相对基础目录以提供方进程工作目录为起点,展示路径始终保持绝对路径。在 POSIX 上,解析先遵循文件系统语义,再进行词法规范化:`symlink/..` 到达链接目标的父目录,即使最终文件尚不存在也如此。目录列表中的子项展示路径保留同样的物理遍历语义。Windows 保留原生的驱动器相对路径规范化行为。
|
||||
|
||||
```yaml
|
||||
- name: '@deepseek-ai/dsh-fs-local'
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"dependencies": {
|
||||
"chokidar": "5.0.0",
|
||||
"koffi": "3.1.1",
|
||||
"@deepseek-ai/dsh-home-paths": "workspace:*",
|
||||
"@deepseek-ai/schemastery": "workspace:~"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -12,6 +12,7 @@ import type { BigIntStats, Dirent, Stats } from 'node:fs'
|
||||
import { basename, dirname, isAbsolute, join, resolve, sep } from 'node:path'
|
||||
import { TextDecoder, promisify } from 'node:util'
|
||||
import { FsError, FsTargetKey, FsVersion } from '@deepseek-ai/dsh-fs'
|
||||
import { expandHomePath } from '@deepseek-ai/dsh-home-paths'
|
||||
import { copyFileDaclWin32, replaceFileWin32 } from './win32.ts'
|
||||
|
||||
const BINARY_SAMPLE_BYTES = 8192
|
||||
@@ -138,11 +139,13 @@ export interface LocalDirEntry {
|
||||
|
||||
/**
|
||||
* Anchor a path using native drive semantics and POSIX physical parent traversal.
|
||||
* A leading `~`, `~/`, or `~\` names the host user's home directory, not a child of `cwd`.
|
||||
* @param cwd - provider base directory for relative paths.
|
||||
* @param path - non-empty requested path.
|
||||
* @param requested - non-empty requested path.
|
||||
* @returns absolute display spelling shared by target resolution and no-follow metadata.
|
||||
*/
|
||||
export function localDisplayPath(cwd: string, path: string): string {
|
||||
export function localDisplayPath(cwd: string, requested: string): string {
|
||||
const path = expandHomePath(requested)
|
||||
const absoluteCwd = isAbsolute(cwd) ? cwd : `${process.cwd()}${sep}${cwd}`
|
||||
const raw = isAbsolute(path) ? path : `${absoluteCwd}${sep}${path}`
|
||||
const physicalSpelling = /(?:^|[\\/])\.\.(?:[\\/]|$)/u.test(raw) ? raw : resolve(cwd, path)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { chmod, mkdtemp, readFile, rename, rm, stat, symlink, unlink, writeFile, mkdir, readdir, realpath } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { homedir, tmpdir } from 'node:os'
|
||||
import { isAbsolute, join, parse, relative, resolve } from 'node:path'
|
||||
import { createServer } from 'node:net'
|
||||
import {
|
||||
@@ -89,6 +89,12 @@ describe('resolveLocalTarget', () => {
|
||||
expect(before.targetKey).toBe(after.targetKey)
|
||||
})
|
||||
|
||||
it('resolves a leading tilde against the home directory instead of cwd', async () => {
|
||||
expect((await resolveLocalTarget(dir, '~')).displayPath).toBe(homedir())
|
||||
expect((await resolveLocalTarget(dir, '~/dsh-missing.txt')).displayPath).toBe(join(homedir(), 'dsh-missing.txt'))
|
||||
expect((await resolveLocalTarget(dir, 'a/~/b.txt')).displayPath).toBe(join(dir, 'a', '~', 'b.txt'))
|
||||
})
|
||||
|
||||
it('rejects a blank path', async () => {
|
||||
await expect(resolveLocalTarget(dir, ' ')).rejects.toMatchObject({ code: 'FS_NOT_FOUND' })
|
||||
})
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
},
|
||||
{
|
||||
"path": "../fs"
|
||||
},
|
||||
{
|
||||
"path": "../../util/home-paths"
|
||||
}
|
||||
]
|
||||
}
|
||||
Generated
+3
@@ -10171,6 +10171,9 @@ importers:
|
||||
|
||||
packages/fs/fs-local:
|
||||
dependencies:
|
||||
'@deepseek-ai/dsh-home-paths':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/home-paths
|
||||
'@deepseek-ai/schemastery':
|
||||
specifier: link:../../../vendor/schemastery
|
||||
version: link:../../../vendor/schemastery
|
||||
|
||||
Reference in new issue
Block a user