Commit 4fd20fd
Add optional schema validation at function boundaries
Introduces an opt-in validation hook so Composable functions can declare
input and output schemas. When declared, the ServiceManager validates the
event body before handleEvent() is invoked and the resolved return value
after, surfacing failures as AppException(400) and AppException(500)
respectively. Functions without schemas are unaffected (single truthy
check per dispatch, no behaviour change).
The protocol is intentionally library-agnostic: a minimal Validator<T>
interface requiring only a .parse(value) method that throws on invalid
input. Zod schemas satisfy it natively, and hand-rolled validators or
TypeBox adapters work with zero framework changes. No new runtime
dependencies are added.
- src/models/composable.ts: add Validator<T> and Infer<V>; extend
Composable with optional inputSchema and outputSchema
- src/system/function-registry.ts: capture schemas into metadata at save()
- src/system/platform.ts: ServiceManager accepts schemas, validates input
before dispatch and output after; interceptors skip output validation
(their return value is already discarded); EventEnvelope returns have
their body validated in place
- src/index.ts: export Validator and Infer
- tests/po.test.ts: add SchemaValidatedService with hand-rolled validators
and three tests covering happy path, 400 on bad input, 500 on bad output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>1 parent 734d0c0 commit 4fd20fd
13 files changed
Lines changed: 277 additions & 18 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
2 | 18 | | |
3 | 19 | | |
4 | 20 | | |
| |||
25 | 41 | | |
26 | 42 | | |
27 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
28 | 59 | | |
29 | 60 | | |
30 | 61 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
0 commit comments