mirror of
https://git.openapi.site/https://github.com/desirecore/registry.git
synced 2026-10-21 05:13:20 +08:00
feat: 以原生应用上架 DesireCore Control 1.4.0 (#6)
This commit is contained in:
63
scripts/native-app.test.mjs
Normal file
63
scripts/native-app.test.mjs
Normal file
@@ -0,0 +1,63 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { test, afterEach } from 'node:test'
|
||||
import { cpSync, readFileSync, writeFileSync, mkdtempSync, rmSync } from 'node:fs'
|
||||
import { join, dirname } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { validateRegistry } from './catalog/validator.mjs'
|
||||
|
||||
const source = join(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const temporary = []
|
||||
afterEach(() => { for (const root of temporary.splice(0)) rmSync(root, { recursive: true, force: true }) })
|
||||
function fixture() {
|
||||
const root = mkdtempSync(join(tmpdir(), 'registry-native-'))
|
||||
temporary.push(root)
|
||||
cpSync(join(source, 'schemas'), join(root, 'schemas'), { recursive: true })
|
||||
cpSync(join(source, 'entries/desirecore-control'), join(root, 'entries/desirecore-control'), { recursive: true })
|
||||
const manifest = JSON.parse(readFileSync(join(source, 'manifest.json'), 'utf8'))
|
||||
manifest.stats = { totalEntries: 1, dockerApps: 0, nativeApps: 1, mcpServices: 0, httpApis: 0, externalIntegrations: 0 }
|
||||
writeFileSync(join(root, 'manifest.json'), JSON.stringify(manifest))
|
||||
writeFileSync(join(root, 'SCHEMA_VERSION'), '4.1.0\n')
|
||||
return root
|
||||
}
|
||||
function mutate(root, file, change) {
|
||||
const path = join(root, file)
|
||||
const data = JSON.parse(readFileSync(path, 'utf8'))
|
||||
change(data)
|
||||
writeFileSync(path, JSON.stringify(data))
|
||||
}
|
||||
const entry = 'entries/desirecore-control/'
|
||||
test('真实原生应用条目是 App,固定 1.4.0 制品,不包含内部 MCP 配置', () => {
|
||||
const root = fixture()
|
||||
const report = validateRegistry(root)
|
||||
assert.equal(report.ok, true, JSON.stringify(report.errors))
|
||||
assert.equal(report.counts.nativeApps, 1)
|
||||
assert.equal(report.counts.mcpServices, 0)
|
||||
const manifest = JSON.parse(readFileSync(join(root, entry, 'manifest.json'), 'utf8'))
|
||||
assert.equal(manifest.type, 'native-app')
|
||||
assert.equal(manifest.install.method, 'native-node')
|
||||
assert.equal(manifest.install.requirements.docker, false)
|
||||
assert.equal(manifest.version, '1.4.0')
|
||||
assert.equal(manifest.connection, undefined)
|
||||
assert.equal(manifest.exposes, undefined)
|
||||
})
|
||||
for (const field of ['connection', 'exposes', 'toolCount', 'capabilities']) test('拒绝原生应用内部服务字段 ' + field, () => {
|
||||
const root = fixture()
|
||||
mutate(root, entry + 'manifest.json', data => { data[field] = field === 'toolCount' ? 5 : field === 'connection' ? { transport: 'stdio', command: 'node' } : [] })
|
||||
assert.equal(validateRegistry(root).ok, false)
|
||||
})
|
||||
test('摘要、最低客户端版本和统计必须与目录事实一致', () => {
|
||||
for (const change of [data => { data.provenance.content.sha256 = '0'.repeat(64) }, data => { data.compatibility.requiredClientVersion = '0.0.0' }]) {
|
||||
const root = fixture()
|
||||
mutate(root, entry + 'catalog-metadata.v1.json', change)
|
||||
assert.equal(validateRegistry(root).ok, false)
|
||||
}
|
||||
const root = fixture()
|
||||
mutate(root, 'manifest.json', data => { data.stats.nativeApps = 0 })
|
||||
assert.equal(validateRegistry(root).ok, false)
|
||||
})
|
||||
test('字段顺序不是治理身份,值相同时允许序列化重排', () => {
|
||||
const root = fixture()
|
||||
mutate(root, entry + 'manifest.json', data => { data.source = Object.fromEntries(Object.entries(data.source).reverse()) })
|
||||
assert.equal(validateRegistry(root).ok, true)
|
||||
})
|
||||
Reference in New Issue
Block a user