chore(deps): update dependency @ts-runtypes/devtools to v0.12.2 - #2352
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
Contributor
Author
|
renovate
Bot
force-pushed
the
renovate/ts-runtypes-devtools-0.x
branch
9 times, most recently
from
September 12, 2026 22:29
f57e35f to
d67ad46
Compare
renovate
Bot
force-pushed
the
renovate/ts-runtypes-devtools-0.x
branch
from
September 21, 2026 04:26
d67ad46 to
03f9d26
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
0.10.0→0.12.2Release Notes
MionKit/ts-run-types (@ts-runtypes/devtools)
v0.12.2Compare Source
Next.js joins the supported bundlers, and the rest of the release is about a dev
server telling the truth. Turbopack has no plugin API at all, so the adapter takes
another route:
next.configstarts a single broker that owns the resolver and each ofTurbopack's ephemeral loader workers connects to it, rather than four workers each
starting their own whole-program build. Alongside it, three staleness bugs are fixed —
a type edit that invalidated nothing and left a dev server serving a validator for the
old shape, an incremental update that collapsed the resolver's program down to the
edited files, and a multi-function call site whose bindings all went to the first
family's bundle. The release plumbing gets the same treatment: the pre-publish image
is buildable again, and both container images now refuse to run once what they baked
has drifted.
Features
API at all. Turbopack runs no webpack plugins, but it does run webpack-style
loaders, and files-mode makes that enough: the generated modules are real files it
resolves natively. Loaders run in a pool of ephemeral worker processes, so a loader
that started the resolver itself started one per worker (measured: four resolvers,
four whole-program builds). Instead
next.configstarts one broker owning thesingle resolver and each worker connects over a socket, with ownership decided by an
atomic socket bind keyed per invocation — otherwise Next's detached telemetry flush,
which also loads the config, would leave a stale resolver behind to poison every
later run.
Bug Fixes
never stale. Those edges are invisible to every bundler — a type-only import is
erased, and an ambient
.d.tstype never had one — so editing the type invalidatednothing and a dev server kept serving a validator built for the old shape. Silently,
since a validator accepts data rather than erroring. The resolver now reports the
declaring files per rewrite and every host declares them through one mechanism.
setSourcesreplaces the resolver's overlay and rebuilds the program against exactly what it
receives, so sending only the edited files collapsed the program to those files: the
following generate emitted only their demand and deleted every other entry's module
from disk, and any other marker file then failed with "source file not in program".
Measured on a 62-module project, one two-file edit took it to 2. A host that
resolves lazily re-transforms its way out of that; one that resolves eagerly cannot.
host may register sources that exist nowhere on disk (a Vue SFC script as
Comp.vue.ts), and Vite's dev-modeaddWatchFilerecords what it is given as anextra import of the module being transformed, so declaring one failed the request
with "Failed to resolve import ./Comp.vue.ts". The index still records them; only
the bundler declaration is filtered.
moduleMode: 'allSingle'each fnId of a multi-function site isimported from its own family bundle. Every family is its own bundle there, but the
site carried a single basename matched against the scalar fnId, so a multi-function
site sent all its bindings to the first fnId's bundle and the rest were
unresolvable.
rtx release e2estops failing on a pulled image that has no next. Three independent blockers, none
of which a throwaway-container check hits: next was younger than the workspace's own
30-day
minimumReleaseAge; next pulls sharp, whose install script the allowBuildsallowlist rejects; and with no
@types/reactbaked,next buildauto-ranpnpm addinside the image, re-resolving and pruning the baked toolchains mid-build.ts-runtypes compileno longer crashes at random on a larger project.The compiler emits files in parallel, and the step that collected them was not
safe to run from several threads at once, so two files finishing together could
kill the whole command. It showed up as a build that failed once and then
succeeded on a retry, with nothing in the project to explain it.
pattern checker.
(x|y)+.*.*against a long run ofxnever returns from thematch, and the checker is single-threaded, so the build stalled for five seconds
and then gave up on every later pattern check. Matching is now bounded, and a
pattern that outruns the budget is reported against that one format instead of
taking the rest of the build down with it.
stale image cannot be run. A
_depschange never forced a republish and the imagehelper prefers the published image, so CI silently ran a drifted toolchain while a
local build quietly got a correct one. A run that would have used a drifted image
now builds locally instead, and a missing stamp counts as unknown rather than drift,
so images built before this keep working.
Testing
ts-runtypesprocess now leaves a full report behindinstead of a truncated one. The failure message keeps the first, most useful part
(what went wrong and where), and the complete output is saved to a file that CI
keeps, so one failed run is enough to work out the cause.
next build,which is the only place that path can be exercised.
so the staleness fix cannot silently regress.
Documentation
including the invariants that look like cleanups but are not.
a duplicated union explanation is dropped.
v0.12.1Compare Source
This release is mostly about what the build reports and what it leaves out.
Build-time diagnostics turned out to be quietly unreliable in three separate ways: a
warm cache hit dropped every finding, nested and union-member types raised nothing at
all, and a type demanded by several families reported the same finding once per
family. All three are fixed, and on a real consumer (mion's router suite) the net
effect is broader coverage with five times less noise. On the output side, a
value-first builder const whose only use is
typeofin type position no longer emitsa reflection graph at all, so a schema written to recover its type costs nothing at
runtime, and
registerClassSerializerstops dragging a class's whole type graph intothe bundle just to read one name. Bun becomes a first-party target, with an adapter
covering both of Bun's plugin hosts.
Features
@ts-runtypes/devtools/bun, a first-party Bun adapter for both ofBun's plugin hosts —
Bun.buildand the runtime loader (Bun.pluginfrom apreload). The runtime host is a strict subset that needed three gaps bridged,
including a readiness gate, so a host that registers the plugin without
awaitisstill correct instead of silently passing files through untransformed. A new
detachResolveroption unrefs the resolver child on that host, so a preloadedprocess can still exit.
builder call whose result is provably unused in its own file — discarded, or bound
to a non-exported const referenced only via
typeofin type position (theInferTypepattern) — emits no runtype graph. Always on, and default-deny: anyvalue use, export,
letbinding or unrecognized position keeps the graph.registerClassSerializerdemands a smallcsrname card instead of thereflection graph. The registration site used to read one string off the runtype
cache, forcing the class's whole type graph into the bundle; it now reads id and
name with zero reflection payload, and legacy tuples and manual string ids keep
resolving.
getRT(rtFnHash).binarySizeEstimateexposes the compile-timecold-start buffer estimate the Go emitter already bakes into every
tbentry.Bug Fixes
findings and a disk-cache hit skips the walker, so every warning a project had
appeared on the first build and then vanished on every build after it — it came
back only when someone wiped the cache, which made a cached build look like a clean
one. Entries now persist the findings their walk produced and a hit re-emits them,
always attributed to the current build's call sites.
type gets its own cache entry keyed by its own structural id, which no marker call
ever named, so it carried no provenance and anything unattributable was dropped. A
class warned at the root of an encoder but said nothing when nested or reached
through a union, which is how people normally write types. Provenance is now
inherited by every type a call site reaches.
family. A type demanded by several cache families is walked once per family, and
each walk's dedupe was blind to its siblings, so one class touched by the JSON
encoder and decoder reported the same finding four times.
createMockDataFnsites demand the format-transform entry, so mocks applydeclared format transforms. A
Lowercasepool sample like'MiXeD'used to shipas-is unless some other call site happened to compile the transform.
convert --to buildersrefuses embedded type references whose cycleneeds an escape, rather than emitting a spelling it cannot make good on.
CodeNSsentinel propagates through validate's structural-formatsplices.
gen-docsreadsresults/by shape instead of a per-reader blocklist.The stale copy of that list did not know about the audit lane's output and took the
whole website build, and with it the deploy, down on the first one.
stops classifying two runtime sources as binary and they can be diffed and merged
again.
Refactoring
knowsType, which counts registered fn entries, so acreateX-only type no longerflips behaviour depending on whether an unrelated file happened to reflect it.
Testing
compiles both spellings through the real resolver — fixture integrity,
byte-identical shared entries, the emission split, and a behaviour floor on the
static form, with negative controls proving every oracle fires.
resolver errors are captured as replayable findings.
CI
rtxregistry is the one lane list (the workflows derive theirmatrices from it) and every lane runs a quick tier on every PR, so findings arrive
while their cause is still in context instead of only at release time.
Documentation
InferTypeform, which is the shape the newelision rewards.
genuinely cannot land in the task, but fixing it in the current PR is now the
documented default.
Miscellaneous
resolved.
v0.12.0Compare Source
This release settles what JSON Schema means for RunTypes: it is an output, never an
input.
createJsonSchemaFn<T>()emits a per-type JSON Schema document from the samereflection graph every other family reads, and
createStandardSchemaserves theidentical document through Standard Schema's
~standard.jsonSchemaconverter. Afirst-class JSON Schema authoring door was prototyped, taken through the official
test suite, and then deliberately removed before ever shipping — types stay the
single source of truth. What survives from that detour is the part that made
validation better regardless: a much larger named-format roster with spec-grade
engines, JSON Schema keyword aliases on the formats, and regex
patternsupportwhose mock samples are generated from the pattern itself and verified on a real JS
engine. Around that: the value-first surface is renamed Type Builders and its
tuple/func builders move to named slot groups (breaking); a new
ts-runtypes convertverb rewrites marker call sites between the two authoring forms, and CIconverts the whole test-suite tree and re-runs it to prove the forms agree;
structural type IDs become canonical for recursive graphs, so equivalent recursive
types converge on one cache entry (hashes reshuffle once — caches regenerate on the
next build, no action needed).
Features
createJsonSchemaFn<T>()returns a per-type JSON Schema documentfn, backed by a new
jsccache family that emits schema documents only for thetypes its call sites demand.
createStandardSchema's~standard.jsonSchemaserves the same document,
stripDialect/buildJsonSchemaConverterareexported for consumers that post-process, and a document's
additionalPropertiesis derived from the declared encoder strategy, so theschema says what the wire actually does with unknown keys.
schema documents what the JSON encoder emits, not an idealized union.
JSONShape<T>, the JSON wire twin ofDataOnly<T>: whatTlookslike after a JSON round-trip (dates as strings, maps as arrays, functions gone).
ts-runtypes convert --to type|buildersCLI verb rewritesmarker call sites between the two authoring forms over the canonical reflection
graph — atomics through circular types, enums, classes, temporal, formats and
brand metadata — refusing with pointed CNV diagnostics anything it cannot
spell losslessly instead of guessing.
rt.tupleandrt.functake named slot groups —tuple({required, optional, rest}),func({params, ret})— and the positionalspelling is dropped; slots can carry labels that converge with type-first
labels, so a converted builder round-trips byte-identically.
RFC 3339 date/time layouts, IDNA / RFC 1123 hostnames, strict IPv4/IPv6 parsing
with localhost off by default, plus eight JSON Schema named formats.
keywords on numeric/date formats,
contentEncoding/contentMediaTypeinvalue-first spelling, and array/object keywords unified into
FormattedArray/FormattedObject.patternsupport that stays honest: patterns are validatedon a real JS engine via an embedded sidecar, mock samples are auto-generated
from the regex at build time, and a literal
mock.seedmakes the generatedpool deterministic.
markers.packages), so wrappersand internal republishes can carry the markers; a marker-named type from an
untrusted package reports MKR012 instead of silently resolving, and a marker
type that resolved to the checker's error type refuses with MKR013 instead of
hashing garbage.
ids are emitted from a bisimulation quotient, shared recursive containers
converge on one entry, a walk that latched the depth cap is never cached, and
mockSamplesno longer participate in format hashing (same shape, differentsamples — one cache entry). Existing
__runtypescaches regenerate on the nextbuild.
rt::countEnumKeyspicks its key counter per engine —for-inonV8,
Object.keyson JavaScriptCore — and the benchmark suite now runs undernode AND bun with a tripwire asserting the per-engine branch actually fired.
mockSamplesfor the samecache entry fail the build instead of last-write-wins.
Bug Fixes
node_modules sources stay out of program roots — fixing marker resolution in
projects that rely on ambient declarations.
(inference-based brand subtraction), and the
DataOnlyTemporal augmentationno longer collapses to
neverwhen the Temporal lib is absent.defaultParamValuescarries JS source, not runtime values,matching its own
CompiledFnArgscontract (#299).so their ids no longer depend on which lib declaration supplied them.
the compiler error-recovered from unparseable source can no longer spin
forever — the build reports the type as unresolvable instead of hanging.
every wire when the object also has an index signature. Its key stayed in the
index signature's sweep, so the index value's encoder ran over the function:
binary threw an uncontrolled
TypeErrorand JSON silently emitted thefunction's source text.
DataOnlyladder alias is recognised when composingTypeName.bodies, so a generic call inside a pure fn no longer leaks TS syntax into the
emitted JS.
the sample input resyncs when the type is edited.
Performance
findRTForTypeis memoized, so mocking is no longer O(registry)per format node; hoisted key sweeps and a pure-fn
uniqueItemscut repeatedscans in emitted validators.
Refactoring
@ts-runtypes/core/buildersis canonical and./schemastays as a deprecatedalias to the same module until 1.0.
sizeconfig object is renamedbinarySizing(tsconfig plugin block and bundler options), matching the binary family it
configures.
internal/reflectionand the schemavocabulary into
internal/schemadoc— the canonical model every pipeline stagenow shares.
Documentation
JSON Schema generation gets its own guide, source conversion gets a page, and
the JSON Schema keyword tables document the output mapping.
hand-typed.
Testing
re-run against identical assertions in the release gate, so a failure
can only mean the conversion changed behaviour; a printer slot-coverage
tripwire and two convert fuzz lanes (declaration sweep + CLI round-trip over
the real binary) guard the printers between releases.
and the schema-doc corpus is pinned as a golden.
of a pinned constant, and prints it with the command that replays it, so a run
is reproducible within a release and each version bump rotates the ground the
lanes explore.
CI
--soakbudget runs in the gate, onerunner per lane, seeded from the run id so each gate explores new ground (the
seed is echoed for verbatim replay).
draining a finding costs twelve short jobs rather than a whole gate, and the
lane lists in both workflows and the rtx registry are pinned equal by a
contract test.
v0.11.0Compare Source
This release renames the public factory surface and reshapes the CLI, both breaking.
Every factory that returns a callable now ends in
Fn—createValidateFn,createJsonEncoderFn,createMockDataFnand nine others — so the name says thetwo-step "factory returns a callable you call later" shape out loud; factories that
return an object keep their names. The binary answers to tsgo-style subcommands
(
serve,compile,enrich) instead of mixed flags and bare defaults,genandcheckcollapse into a singleenrichverb with a uniform--no-emit, anddescribeis gone. Around that, enrichment becomes something the bundler plugin candrive: an opt-in
enrichoption scaffolds and syncs the friendly / mock / i18nmirrors on source change, and the production build gate now enforces completeness, so
a release can no longer ship blank labels or mocks. tsconfig handling is TypeScript's
on every lane (one upward discovery from cwd, threaded everywhere), and every
project-semantic option is settable from both the tsconfig plugin entry and the
bundler options with a codegen'd drift guard. New on top: a
numberModevalidationoption for migrating off looser validators, seeded repeatable mock data, exported
compiled-fn structs for consumers that ship compiled functions over the wire, and a
generics-rejection model that says why a type cannot resolve instead of overflowing
the stack.
Features
Fnsuffix:
createValidateFn,createGetValidationErrorsFn,createHasUnknownKeysFn,createCloneExactShapeFn,createUnknownKeyErrorsFn,createFormatTransformFn,createJsonEncoderFn/createJsonDecoderFn,createBinaryEncoderFn/createBinarySizerFn/createBinaryDecoderFn, andcreateMockDataFn. Factoriesthat return an object are untouched (
createStandardSchema,createFriendlyText,createFriendlyTextI18n, the DataView serializers), as are the return-type aliases(
ValidateFn,JsonEncoderFn, …). Pure identifier rename — the scanner keys on themarker, not the JS name, so no cache key, hash or protocol changes.
args[0]command table replaces the mixedflag/subcommand dispatch:
servesubsumes the default stdio server, the inlineserver and the stdin-sources lanes behind
--sources project|stdin|ops,compilereplaces
--compile, and each command owns its own flag set.--daemonand itssocket transport are retired (no caller),
--jsonis uniform, and--cmd -hprintsself-documenting per-command help listing every flag.
genandcheckmerge into oneenrichverb: bare enrichscaffolds,
--no-emitturns any write lane into a diagnostics-only pass, andcompile --no-emitgets the same meaning.describeis removed — its indented typetree was near-identical to the source type, had no caller, and is superseded by the
enrich scaffold.
--require-completeis the completeness gate: unfilled@todoplaceholders and blank scaffold values (FT020/FT023, MD020/MD023) are reported by
--no-emitbut exit 0, while--require-completefails on them. Wrong or stalecontent (bad field, orphan carcass, drift) still fails both lanes.
--translateis renamed--i18nto line the flag up withthe config it reads (tsconfig
i18n, pluginenrich.i18n); it manages translationfiles and never translates. Sub-modes are unchanged.
PluginOptions.enrichobject(
friendly/mock/i18n/suppressHmr, all off by default) syncs theenrichment mirrors on source change through a new daemon op, auto-suppresses HMR for
its own writes, and runs a read-only drift gate on production builds. Under
failOnErrorthat gate now enforces completeness too, so a build fails on anunfilled
@todoor a blank value as well as on drift; dev and watch still tolerateblanks while you are authoring.
numberModeoption (isFinite|typeof|notNaN) selects theemitted base
numbercheck, settable per call site or project-wide via the plugin /tsconfig and merged per field. It eases migration from a looser validator:
typeofaccepts NaN and Infinity (like ajv, typia, JSON Schema),
notNaNrejects NaN butkeeps Infinity, and the default
isFiniteis unchanged — so existing cache keys staybyte-stable.
createMockDataFn({mock: {seed}})produces deterministic, repeatablevalues for every type. All mock randomness moves into one exported
MockRandom(amulberry32 PRNG under a seed, including UUID bytes and a fixed reference clock for
Date / Temporal), threaded through custom mock fns so consumer formats stay
reproducible. Without a seed, behaviour is byte-for-byte unchanged.
paramsOptionsis an alias oftupleOptions.(
CompiledFnData,CompiledTypeFn,CompiledPureFunction,PureFunctionData,CompiledFnArgs,InitializedTypeFn, plusbuildFactoryFromCode,buildPureFnFactoryFromCode,entryCode) so a host that ships compiled RT functionsover the wire and rebuilds them on the far side consumes ts-runtypes as the single
source of truth instead of reimplementing the structs. Additive re-exports: no
behaviour, hash or fingerprint change.
typeFormats(canonical formatname to
{name, kind}), theFormatNameunion andTypeFormatMeta, generated fromthe Go format registry and drift-guarded, so a consumer mapping a reflected prop's
formatAnnotation.nameonto something external keys off ts-runtypes.bare "too deeply nested": MKR009 names a self-instantiating generic, MKR010 points at
a free type parameter reached through a data position, and MKR011 catches a generic
written without its required type arguments. Defaulted generics used bare resolve
unchanged.
failOnError,hashLengthandsingleThreadedaresettable in both the tsconfig plugin entry and the bundler options with tsc-style
precedence, and a codegen'd guard fails CI if either side gains an option the other
lacks.
RT_BINoverrides the resolver binary lookup on every lane, so anunpublished build or a bisect can be pointed at directly; a value that is not an
executable throws instead of silently falling through.
settings.runtypes.binary(config beatsthe
RT_BINenv, matching the bundler lane), and unknown keys undersettings.runtypeswarn once per key instead of being a silent no-op.PASS records a sha256 per tarball and the publisher refuses bytes no receipt covers,
so a repack after the gate can no longer slip through. Stage-approval is now a single
interactive OTP prompt that approves leaves-first and auto-dispatches the website
deploy.
RT_WEBSITE_CA_CERTat run time, not onlyduring the build.
suite-data codegen), and the site build is gated on the benchmark pages rendering.
Bug Fixes
fresh checker type per member query (lib.esnext's
IteratorObjectfamily, aself-instantiating generic) defeated the pointer-identity cycle guard and recursed
into a fatal Go stack overflow; the walk now caps at a generous depth, commits a
benign placeholder instead of a truncated node, and raises MKR008 at the call site.
--tsconfigwins, otherwise theconfig is discovered upward from the working directory exactly as TypeScript does,
resolved once at process entry and threaded into the plugin-block read, the daemon
session, the one-shot,
compileand program construction; the JS side sheds itsconfig logic entirely. Full compiler-option adoption now applies on every lane, so
the lint lane and the bundler lane can no longer disagree with
tsc.a
buildEndrace that could drop in-flight work.singleThreaded: falseoverrides a tsconfigsingleThreaded: true.customConditions/pathsin ESLint inline-server mode.rt$defaultemits one message per field, not one per constraint.proxy.golang.org when go.dev is blocked, and wire the Go install onto the harness's
non-login PATH.
Performance
repeating it in every child.
Refactoring
rtx releaseprints help; the full chain answers tortx release all. The chain ends in an interactive publish that bumps, commits andtags, so it should answer to its own name. Internal dev CLI only — no CI impact.
enrichgenleaf package so the CLI verb and the daemonop plan through the same code and cannot drift, slim the daemon wire to files-only
with config on the spawn flags, and resolve like a build rather than forcing a source
condition.
CFG001 into the marker codes.
Documentation
and enrich as one idea with two owners, and calls
servethe daemon mode.--no-emithealth vs--require-completecompleteness split, and the plugin'senrichment sync.
NPM_TOKEN+ 2FA model.Testing
move onto the enrich verb and
--no-emit.settings.runtypes.tsconfigandRT_BINreach the resolver through areal oxlint config.
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.