dorfteich/packages/plugin-sdk/src/api-version.test.ts
Claude Opus 4.8 ec6ca80c4d
All checks were successful
CD / Build and push images (push) Successful in 3m14s
CI / Lint, typecheck, test (push) Successful in 3m18s
CI / Auth e2e pack (push) Successful in 4m3s
CI / Import/export fidelity gate (push) Successful in 54s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 9s
CD / Smoke tests against Test (push) Successful in 1m9s
CD / Promote to Int (push) Has been skipped
Add plugin SDK: manifest schema, capabilities, and RPC protocol (#70)
The SDK is the contract every other M7 story builds on (ADR 0008,
plugin-architecture.md). New package `@dorfteich/plugin-sdk`, standalone
(only depends on zod) so a plugin author needs nothing else.

- Zod manifest schema (`validateManifest`/`parseManifest`) with actionable
  `{ path, message }` issues and cross-field rules (extension-point/kind
  match, unique ids, section_style declares no permissions). Fixtures:
  3 valid + 14 invalid variants, asserted individually.
- `checkApiVersion` compatibility helper against the host's supported range.
- Capability names + method→capability map as the single source of truth
  for the permission gate.
- Transport-agnostic postMessage RPC engine (`createRpcEndpoint`) with
  request/response ids, per-request timeouts, unknown-method and
  endpoint-disposed handling, plus a `windowTransport` adapter.
- Host side (`createHostBridge`): routes plugin capability calls through
  the manifest permission gate; drives plugin lifecycle (render/edit/destroy).
- Plugin side (`createPlugin`): answers lifecycle calls, exposes a typed
  `host` proxy. RPC roundtrip verified in a jsdom MessageChannel test
  (roundtrip, args, timeout, unknown method, undeclared capability, dispose).
- README documents the protocol with a mermaid sequence diagram.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
2026-07-10 16:12:00 +02:00

42 lines
1.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, it } from 'vitest';
import { checkApiVersion, HOST_API_VERSION, isApiVersionSupported } from './api-version';
describe('checkApiVersion', () => {
it('accepts a supported major', () => {
const result = checkApiVersion('1');
expect(result).toEqual({ compatible: true, version: 1 });
});
it('rejects a non-numeric version with a reason', () => {
const result = checkApiVersion('1.0');
expect(result.compatible).toBe(false);
expect(result.version).toBeNull();
expect(result.reason).toMatch(/whole-number major/i);
});
it('rejects a version above the host range', () => {
const result = checkApiVersion('2', { min: 1, max: 1 });
expect(result.compatible).toBe(false);
expect(result.version).toBe(2);
expect(result.reason).toMatch(/outside the supported range 11/);
});
it('rejects a version below the host range', () => {
const result = checkApiVersion('1', { min: 2, max: 3 });
expect(result.compatible).toBe(false);
expect(result.reason).toMatch(/outside the supported range 23/);
});
it('accepts any major inside a wider host range', () => {
expect(checkApiVersion('2', { min: 1, max: 3 }).compatible).toBe(true);
});
});
describe('isApiVersionSupported', () => {
it('mirrors checkApiVersion as a boolean', () => {
expect(isApiVersionSupported(String(HOST_API_VERSION))).toBe(true);
expect(isApiVersionSupported('99')).toBe(false);
});
});