Files
deepseek-harness/packages/sdk/plugin-fetch/tests/ids.spec.ts
imccyu 825a63ab01 feat(sdk): add dsh-plugin-fetch source + fetcher seam
Greenfield #2 "建插件" modules for the forthcoming `dsh-sdk create <source>`
command, in a new foundation-independent package so it touches none of the
dsh-scripts / dsh-helper / create-sdk hotspots the foundation refactor edits.

- `resolvePluginSource(spec)` parses `owner/repo[/subdir]#ref` (github) or
  `pkg@version` (npm) into a `PluginSource` discriminated union, failing loud on
  an ambiguous or malformed spec.
- `PluginFetcher<S>` seam + `fetchPlugin` tag dispatch returning a common
  `FetchedPlugin` (temp dir + immutable provenance).
- `GigetFetcher` (github) over @bluwy/giget-core: resolve `#ref` to a commit SHA
  first, download that SHA; provenance pins the SHA. Chosen over unjs/giget for
  its single runtime dep and absent install/action surface.
- `PacoteFetcher` (npm) over pacote: resolve the manifest, then extract the
  tarball verified against its registry integrity. Registry-only is enforced by
  the source resolver; extract runs no lifecycle scripts.
- Branded `CommitSha`/`Integrity`; network + temp-dir boundaries are injected so
  the logic is unit-tested at 100% per-file coverage without network.

Wiring (package.json pin, cordis.yml via ProjectEditSession with a confirmed
diff, install --ignore-scripts) and the launcher command registration land
later with the foundation.
2026-07-18 16:08:12 +08:00

40 lines
1.2 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { commitSha, integrity } from '../src/ids.ts'
describe('commitSha', () => {
it('accepts abbreviated and full lowercase hex object ids', () => {
expect(commitSha('abc1234')).toBe('abc1234')
expect(commitSha('a'.repeat(40))).toBe('a'.repeat(40))
expect(commitSha('0'.repeat(64))).toBe('0'.repeat(64))
})
it.each([
['too short', 'abc123'],
['uppercase', 'ABCDEF1'],
['non-hex', 'ghijklm'],
['too long', 'a'.repeat(65)],
['empty', ''],
])('rejects an invalid sha (%s)', (_label, value) => {
expect(() => commitSha(value)).toThrow(/invalid commit sha/)
})
})
describe('integrity', () => {
it.each([
'sha512-abcABC123+/==',
'sha384-abcABC123+/',
'sha256-Zm9vYmFy',
])('accepts a valid SRI entry (%s)', (value) => {
expect(integrity(value)).toBe(value)
})
it.each([
['missing algorithm', 'abcABC123'],
['unsupported algorithm', 'sha1-abcABC123'],
['illegal base64 char', 'sha512-abc*def'],
['empty', ''],
])('rejects an invalid integrity (%s)', (_label, value) => {
expect(() => integrity(value)).toThrow(/invalid subresource integrity/)
})
})