3.0 KiB
3.0 KiB
NEXT_STEPS_424.md
Status
v1.1 released 2026-04-24. All planned features complete. 468 tests passing.
Completed
| Feature | Tests | Files |
|---|---|---|
| Core Extension Points | 14 | src/extension/types.ts, src/extension/registry.ts, src/formula/parser.ts |
| Multipart Uploads | 9 | src/types.ts, src/domain/schema-to-arbitrary.ts, src/domain/request-builder.ts, src/infrastructure/http-executor.ts, src/formula/evaluator.ts |
| Streaming / NDJSON | 7 | src/types.ts, src/infrastructure/http-executor.ts, src/formula/evaluator.ts |
| Extension System Polish | 5 | src/plugin/index.ts, src/domain/contract-validation.ts |
| SSE Extension | 7 | src/extensions/sse/ |
| Serializers Extension | 4 | src/extensions/serializers/ |
| WebSockets Extension | 5 | src/extensions/websocket/ |
| Code Cleanup | 5 | src/formula/evaluator.ts, src/domain/error-suggestions.ts, src/extension/registry.ts, src/test/helpers.ts, src/test/runner-utils.ts |
Architecture
Core vs Extensions
Core features require changes to the schema-to-arbitrary pipeline or HTTP executor:
- Multipart uploads
- Streaming/NDJSON
- Timeouts, redirects
Extensions are opt-in modules:
- SSE: specialized parser
- Serializers: external dependencies (protobuf, msgpack)
- WebSockets: different protocol
Extension Registration
await fastify.register(apophis, {
extensions: [
sseExtension,
createSerializerExtension(registry),
websocketExtension,
]
})
Each extension provides:
headers: APOSTL operations for parser validationpredicates: custom formula evaluationonBuildRequest/onBeforeRequest/onAfterRequest: lifecycle hooksonSuiteStart/onSuiteEnd: suite-level hooks
Test Strategy
First-Class Features
Red-green-refactor cycle:
- Add operation to parser
- Add parser test
- Add operation to evaluator
- Add evaluator test
- Add HTTP executor support
- Add integration test with Fastify
- Add schema-to-arbitrary support (for multipart)
- Add generation test
- Add request builder support
- Add end-to-end test
Extensions
Self-contained modules with own test suites:
// src/extensions/NAME/test.ts
import { test } from 'node:test'
import assert from 'node:assert'
import { extension } from './extension.js'
test('predicate returns correct value', () => {
const resolver = extension.predicates!.predicate_name
const result = resolver(mockContext)
assert.strictEqual(result.value, expected)
})
Migration
v1.0 → v1.1
No breaking changes.
To use new features:
- Multipart: add
x-content-type: multipart/form-datato schema - Streaming: add
x-streaming: trueto response schema - Extensions: import and register via
extensions: [...]option
Reference
- Architecture:
docs/extensions/EXTENSION-ARCHITECTURE.md - Quick Reference:
docs/extensions/QUICK-REFERENCE.md - Extension Specs:
docs/extensions/WEBSOCKETS.md,HTTP-EXTENSIONS.md - API Design:
docs/API_REDESIGN_V1.md