import { tap, expect } from '@git.zone/tstest/tapbundle'; import { AppStoreResolver, parseDockerImageReference, parseServezoneAppStoreManifest, } from '../ts_client/index.js'; tap.test('parses docker image references', async () => { expect(parseDockerImageReference('nginx:alpine')).toEqual({ registry: 'registry-1.docker.io', repository: 'library/nginx', tag: 'alpine', digest: undefined, }); expect(parseDockerImageReference('code.foss.global/serve.zone/cloudly:latest')).toEqual({ registry: 'code.foss.global', repository: 'serve.zone/cloudly', tag: 'latest', digest: undefined, }); }); tap.test('validates servezone appstore manifests', async () => { const manifest = parseServezoneAppStoreManifest({ schemaVersion: 1, app: { id: 'cloudly', name: 'Cloudly', description: 'Control plane', category: 'Dev Tools', }, runtime: { image: 'code.foss.global/serve.zone/cloudly:latest', port: 80, }, }); expect(manifest.app.id).toEqual('cloudly'); }); tap.test('resolves repo manifests and digest tracked images', async () => { const baseUrl = 'https://appstore.example.test'; const manifestUrl = 'https://code.example.test/cloudly/servezone.appstore.json'; const digest = 'sha256:1234567890abcdef'; const fakeFetch: typeof fetch = async (inputArg, initArg) => { const url = inputArg instanceof Request ? inputArg.url : inputArg.toString(); const method = initArg?.method || 'GET'; if (url === `${baseUrl}/appstore.resolved.json`) { return new Response('not found', { status: 404 }); } if (url === `${baseUrl}/appstore.json`) { return Response.json({ schemaVersion: 1, updatedAt: '2026-05-25T00:00:00Z', apps: [ { id: 'cloudly', name: 'Cloudly', description: 'Curated listing metadata.', category: 'Dev Tools', latestVersion: 'latest', source: { type: 'repoManifest', url: manifestUrl, ref: 'main', }, }, ], }); } if (url === manifestUrl) { return Response.json({ schemaVersion: 1, app: { id: 'cloudly', name: 'Cloudly', description: 'Manifest-owned metadata.', category: 'Dev Tools', }, latestVersion: 'latest', source: { type: 'dockerImage', image: 'registry.example.test/serve.zone/cloudly:latest', tracking: 'digest', }, runtime: { image: 'registry.example.test/serve.zone/cloudly:latest', port: 80, }, }); } if ( url === 'https://registry.example.test/v2/serve.zone/cloudly/manifests/latest' && method === 'HEAD' ) { return new Response(null, { status: 200, headers: { 'docker-content-digest': digest }, }); } return new Response(`unexpected ${method} ${url}`, { status: 500 }); }; const resolver = new AppStoreResolver({ baseUrl, fetch: fakeFetch, now: () => new Date('2026-05-25T12:00:00Z'), }); const appStore = await resolver.getAppStoreIndex(); expect(appStore.apps[0].latestVersion).toEqual(`latest@${digest}`); expect(appStore.apps[0].resolvedSource?.manifestHash?.length).toEqual(64); expect(appStore.apps[0].upgradeStrategy).toEqual('dockerDigest'); const appMeta = await resolver.getAppMeta('cloudly'); expect(appMeta.latestVersion).toEqual(`latest@${digest}`); expect(appMeta.versions).toEqual([`latest@${digest}`]); const config = await resolver.getAppVersionConfig('cloudly', appMeta.latestVersion); expect(config.image).toEqual('registry.example.test/serve.zone/cloudly:latest'); expect(config.appStoreVersion).toEqual(`latest@${digest}`); expect(config.resolvedImageDigest).toEqual(digest); }); export default tap.start();