Forge protocol defines local/browser-executed tRPC procedure contracts used by Forge web (forge.core.*).
core/core.router.tsvalidates sync payloads more defensively:kindmust be non-empty and at most 128 chars,targetsmust contain 1..64 entries,- each
targetsentry must be non-empty after trim and at most 128 chars, reasonmust be non-empty and at most 512 chars,- raw
kind/ eachtargetsentry /reasonreject Unicode control and format chars (Cc+Cf, including ASCII/C1 controls like\n,\t,\u0085and invisibles like\u200B) before trim-normalization so hidden bytes cannot slip through (error text now explicitly sayscontrol/format), - unexpected/unknown payload keys are rejected (
.strict()).
- Router guards missing/non-invokable
ctx.app.service.syncand throws a clear error before dispatch, including constructor-aware received runtime type details (for exampleundefined,null,object:Object,function:SyncHandler) to speed misconfiguration triage. - Missing-handler type diagnostics now sanitize control/format characters and cap constructor-name detail length, keeping protocol errors single-line and log-safe even under hostile/proxy constructor metadata.
- Router now also guards property-accessor failures while reading
ctx.app.service.sync, replacing opaque getter exceptions with a stable actionable error while preserving original throwable viaError.causefor debugging. - Router now normalizes whitespace-trimmed
kind/targets/reasoninto a clean dispatch payload before invokingsync, preventing whitespace drift into service handlers. - Router now also normalizes those strings to Unicode NFC so canonically equivalent input values dispatch consistently.
- Router rejects duplicate
targetsafter trim + Unicode normalization, preventing duplicate downstream sync execution for the same logical target. - Router normalizes non-
Errorthrowables/rejections fromctx.app.service.syncinto a stable protocol error, now including the received throwable runtime type (for examplestring,number) to speed triage while preventing raw non-Error values from leaking through the tRPC surface. - Jest coverage in
test/core.router.test.jsincludes schema-rejection and normalization cases (empty targets, blank kind/reason, mixed target arrays, unknown keys, duplicate targets, dispatch payload normalization, non-Error throwable/rejection normalization, control-character rejection).