@ts-runtypes/devtools 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +104 -0
- package/README.md +76 -0
- package/dist/apply-edits.d.ts +8 -0
- package/dist/apply-edits.d.ts.map +1 -0
- package/dist/apply-edits.js +24 -0
- package/dist/apply-edits.js.map +1 -0
- package/dist/diagnosticCatalog.d.ts +7 -0
- package/dist/diagnosticCatalog.d.ts.map +1 -0
- package/dist/diagnosticCatalog.generated.d.ts +6 -0
- package/dist/diagnosticCatalog.generated.d.ts.map +1 -0
- package/dist/diagnosticCatalog.generated.js +552 -0
- package/dist/diagnosticCatalog.generated.js.map +1 -0
- package/dist/diagnosticCatalog.js +34 -0
- package/dist/diagnosticCatalog.js.map +1 -0
- package/dist/edit-buffer.d.ts +26 -0
- package/dist/edit-buffer.d.ts.map +1 -0
- package/dist/edit-buffer.js +209 -0
- package/dist/edit-buffer.js.map +1 -0
- package/dist/esbuild.d.ts +4 -0
- package/dist/esbuild.d.ts.map +1 -0
- package/dist/esbuild.js +4 -0
- package/dist/esbuild.js.map +1 -0
- package/dist/eslint/diagnosticRouting.d.ts +21 -0
- package/dist/eslint/diagnosticRouting.d.ts.map +1 -0
- package/dist/eslint/diagnosticRouting.js +68 -0
- package/dist/eslint/diagnosticRouting.js.map +1 -0
- package/dist/eslint/index.d.ts +47 -0
- package/dist/eslint/index.d.ts.map +1 -0
- package/dist/eslint/index.js +83 -0
- package/dist/eslint/index.js.map +1 -0
- package/dist/eslint/lint-worker.d.ts +2 -0
- package/dist/eslint/lint-worker.d.ts.map +1 -0
- package/dist/eslint/lint-worker.js +97 -0
- package/dist/eslint/lint-worker.js.map +1 -0
- package/dist/eslint/prefilter.d.ts +4 -0
- package/dist/eslint/prefilter.d.ts.map +1 -0
- package/dist/eslint/prefilter.js +13 -0
- package/dist/eslint/prefilter.js.map +1 -0
- package/dist/eslint/session-protocol.d.ts +26 -0
- package/dist/eslint/session-protocol.d.ts.map +1 -0
- package/dist/eslint/session-protocol.js +2 -0
- package/dist/eslint/session-protocol.js.map +1 -0
- package/dist/eslint/session.d.ts +26 -0
- package/dist/eslint/session.d.ts.map +1 -0
- package/dist/eslint/session.js +142 -0
- package/dist/eslint/session.js.map +1 -0
- package/dist/eslint/spawn-shim.d.ts +2 -0
- package/dist/eslint/spawn-shim.d.ts.map +1 -0
- package/dist/eslint/spawn-shim.js +23 -0
- package/dist/eslint/spawn-shim.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/packages/ts-runtypes-devtools/tsconfig.test.tsbuildinfo +1 -0
- package/dist/protocol.d.ts +236 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +53 -0
- package/dist/protocol.js.map +1 -0
- package/dist/resolver-client.d.ts +128 -0
- package/dist/resolver-client.d.ts.map +1 -0
- package/dist/resolver-client.js +245 -0
- package/dist/resolver-client.js.map +1 -0
- package/dist/rolldown.d.ts +4 -0
- package/dist/rolldown.d.ts.map +1 -0
- package/dist/rolldown.js +4 -0
- package/dist/rolldown.js.map +1 -0
- package/dist/rollup.d.ts +4 -0
- package/dist/rollup.d.ts.map +1 -0
- package/dist/rollup.js +4 -0
- package/dist/rollup.js.map +1 -0
- package/dist/rspack.d.ts +4 -0
- package/dist/rspack.d.ts.map +1 -0
- package/dist/rspack.js +4 -0
- package/dist/rspack.js.map +1 -0
- package/dist/runtypes-constants.generated.d.ts +184 -0
- package/dist/runtypes-constants.generated.d.ts.map +1 -0
- package/dist/runtypes-constants.generated.js +136 -0
- package/dist/runtypes-constants.generated.js.map +1 -0
- package/dist/scan-batcher.d.ts +6 -0
- package/dist/scan-batcher.d.ts.map +1 -0
- package/dist/scan-batcher.js +36 -0
- package/dist/scan-batcher.js.map +1 -0
- package/dist/unplugin.d.ts +25 -0
- package/dist/unplugin.d.ts.map +1 -0
- package/dist/unplugin.js +215 -0
- package/dist/unplugin.js.map +1 -0
- package/dist/vite.d.ts +4 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +4 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpack.d.ts +4 -0
- package/dist/webpack.d.ts.map +1 -0
- package/dist/webpack.js +4 -0
- package/dist/webpack.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
export const DIAGNOSTIC_CATALOG = {
|
|
2
|
+
CLS001: {
|
|
3
|
+
headline: 'class `{0}` is serialized structurally; register it via `registerClassSerializer({0}, { deserialize })` to round-trip a real instance.',
|
|
4
|
+
detail: "By default a user class is serialized by its declared properties and\ndecoded back to a prototype-less plain object — `instanceof {0}` is\nfalse on the decoded value, and any class methods / getters are gone.\nThis is fine when you only care about the data.\n\nTo round-trip a real `{0}` instance, register it once, passing the class\nitself (not a name string):\n import {registerClassSerializer} from '@ts-runtypes/core';\n\n // zero-arg constructor: nothing else needed\n registerClassSerializer({0});\n\n // non-empty constructor: only `deserialize` is required\n registerClassSerializer({0}, {\n deserialize: (data) => new {0}(/* rebuild from data */),\n });\n\n`serialize` is optional (default: structural, same as any interface);\n`deserialize` is optional for a zero-arg class (default:\n`Object.assign(new {0}(), data)`). The same registration is used by the\nJSON and binary families. `validate` / `getValidationErrors` are\nunaffected — they always validate structurally.",
|
|
5
|
+
},
|
|
6
|
+
CTA001: {
|
|
7
|
+
headline: '`CompTimeArgs<T>` argument must be a literal at the call site, or a `const` whose initializer is itself entirely literal (a same-module or imported `const` both work).',
|
|
8
|
+
detail: "The build resolves the argument before running, so it needs to read its\nvalue from the source. Function-call results, property accesses, ternary\nexpressions, and `let`/`var` bindings can't be evaluated at build time.\nAccepted: an inline literal, or a `const` whose initializer is itself\nfully literal — including a `const` imported from another module. (An\nobject `const` must be `as const` so its members stay literal; see CTA004.)\n\nFix — inline at the call site:\n- const opts = getOpts();\n- const isUser = createValidate<User>(undefined, opts);\n+ const isUser = createValidate<User>(undefined, {mode: 'unsafe'});\n\nFix — use a const of literals (here or in another module):\n const opts = {mode: 'unsafe'} as const; // literal initializer ✓\n const isUser = createValidate<User>(undefined, opts);",
|
|
9
|
+
},
|
|
10
|
+
CTA002: {
|
|
11
|
+
headline: '`CompTimeArgs<T>` literal nesting exceeds the depth cap (16) — refactor to flatten.',
|
|
12
|
+
detail: 'Deeply nested literal walks are capped at 16 levels to keep the build\npredictable. If you hit this, the value is almost certainly not what\nyou want at compile time — split it across multiple smaller\n`CompTimeArgs<T>` arguments, or flatten the nesting.',
|
|
13
|
+
},
|
|
14
|
+
CTA003: {
|
|
15
|
+
headline: '`CompTimeArgs<T>` literal contains a forbidden construct ({0}). Only literals and nested literals are allowed.',
|
|
16
|
+
detail: "The Go scanner cannot statically evaluate computed property names,\nfunction calls, ternary expressions, or template-string substitutions.\nInside a `CompTimeArgs<T>` literal every node must be a direct literal\n(string / number / bigint / boolean / null / undefined / regex / arrow /\nobject literal / array literal) or a const-traced identifier that\nresolves to one.\n\nSpread IS allowed when its operand resolves to a literal container of the\nmatching kind — a `const`-bound (or imported) object literal for an\nobject spread, an array literal for an array spread:\n const base = {strict: true};\n const a = {...base, mode: 'unsafe'}; // ok — merges a const fragment\n\nA spread is still rejected when the operand can't be statically merged —\na dynamic value, or a shape mismatch:\n - const a = {...getDefaults(), mode: 'unsafe'}; // dynamic operand\n - const a = {...[1, 2], mode: 'unsafe'}; // object spread of an array",
|
|
17
|
+
},
|
|
18
|
+
CTA004: {
|
|
19
|
+
headline: '`CompTimeArgs<T>` value comes from a `const` with a widened (non-literal) member ({0}) — declare the const `as const`.',
|
|
20
|
+
detail: "A `const` used as a CompTimeArgs / CompTimeFnArgs argument (a whole option\nbag, or a builder child) must carry LITERAL value types, so the value the\nbuild reads matches the type TypeScript resolves the call against. Without\n`as const`, an object literal's members widen — `{strategy: 'mutate'}`\nbecomes `{strategy: string}` — which can let the type system select one\nfunction variant while the build injects another.\n\nWhole imported consts now resolve cross-module (like a spread fragment), so\nthis rule keeps that path sound.\n\nFix — add `as const`:\n- const preset = {strategy: 'mutate'};\n+ const preset = {strategy: 'mutate'} as const;\n createJsonEncoder(undefined, preset);",
|
|
21
|
+
},
|
|
22
|
+
FB001: {
|
|
23
|
+
headline: 'Cannot deserialise `{0}` from binary.',
|
|
24
|
+
detail: "`never` is the empty type — no value can ever inhabit it. A field\ntyped `never` cannot carry a runtime value, so there is nothing to\nencode/decode/validate.\n\nFix — use `unknown` if you really want to accept any value:\n interface User {\n- tag: never;\n+ tag: unknown; // narrow before use\n }\n\nFix — pick a concrete type matching your real data:\n interface User {\n- tag: never;\n+ tag: 'pending' | 'active' | 'done';\n }",
|
|
25
|
+
},
|
|
26
|
+
FB002: {
|
|
27
|
+
headline: 'Cannot deserialise `{0}` from binary.',
|
|
28
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
29
|
+
},
|
|
30
|
+
FB003: {
|
|
31
|
+
headline: 'Cannot deserialise `{0}` from binary.',
|
|
32
|
+
detail: "Functions have no value form to serialise — their closure, prototype,\nand bound state aren't representable in JSON or binary.\n\nFix — drop the function from your type, or replace it with the data the\nfunction would produce:\n interface User {\n- getName: () => string;\n+ name: string;\n }",
|
|
33
|
+
},
|
|
34
|
+
FB004: {
|
|
35
|
+
headline: 'Cannot deserialise `{0}` from binary.',
|
|
36
|
+
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded — every element would need to be\nrepresentable, and these aren't. Dropping individual elements would\nchange the array length, so the encoder refuses rather than silently\nshipping a different shape.\n\nFix — change the element type to something serialisable:\n - type Items = (() => void)[];\n+ type Items = string[];",
|
|
37
|
+
},
|
|
38
|
+
FB005: {
|
|
39
|
+
headline: 'Cannot deserialise `{0}` from binary.',
|
|
40
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
41
|
+
},
|
|
42
|
+
FB006: {
|
|
43
|
+
headline: 'Cannot deserialise `{0}` from binary.',
|
|
44
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
45
|
+
},
|
|
46
|
+
FB010: {
|
|
47
|
+
headline: 'Property `{0}` is a function — `fromBinary` does not handle function values, so this property is silently not deserialised.',
|
|
48
|
+
detail: '`fromBinary` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
49
|
+
},
|
|
50
|
+
FB011: {
|
|
51
|
+
headline: "Method `{0}` is silently not deserialised by `fromBinary` — methods aren't data.",
|
|
52
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`fromBinary` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
53
|
+
},
|
|
54
|
+
FB012: {
|
|
55
|
+
headline: "Static member `{0}` is silently not deserialised by `fromBinary` — statics aren't part of instance data.",
|
|
56
|
+
detail: 'Class static members live on the class, not on individual instances.\n`fromBinary` operates on instance shape, so statics are excluded.',
|
|
57
|
+
},
|
|
58
|
+
FB013: {
|
|
59
|
+
headline: "Symbol-keyed property `{0}` is silently not deserialised by `fromBinary` — symbol keys aren't JSON-representable.",
|
|
60
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `fromBinary` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
61
|
+
},
|
|
62
|
+
FB014: {
|
|
63
|
+
headline: "Union member(s) of type `{0}` can't be represented as data — `fromBinary` drops them, so the union is deserialised as its remaining members.",
|
|
64
|
+
detail: 'A union projects to its serialisable members only: `DataOnly<Date | symbol>`\nis `Date`. The dropped member(s) ({0}) carry no JSON-shaped value (symbol,\nfunction, Promise, or a non-serialisable built-in like `Map` / `Set` /\ntyped arrays), so `fromBinary` deserialised only the members that remain.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If EVERY member of the union is non-serialisable the\nprojection is `never`, and `fromBinary` throws at build time instead.',
|
|
65
|
+
},
|
|
66
|
+
FB015: {
|
|
67
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `fromBinary` drops it, so this property is silently not deserialised.',
|
|
68
|
+
detail: '`fromBinary` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `fromBinary` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
69
|
+
},
|
|
70
|
+
FMT001: {
|
|
71
|
+
headline: 'TypeFormat mockSample "{0}" does not match its pattern /{1}/ — fix the sample or the pattern.',
|
|
72
|
+
},
|
|
73
|
+
FMT002: {
|
|
74
|
+
headline: 'Invalid type-format params — {0}',
|
|
75
|
+
},
|
|
76
|
+
FT002: {
|
|
77
|
+
headline: 'Unknown field `{0}` — the type does not declare it, so this FriendlyText entry is dead.',
|
|
78
|
+
detail: "The FriendlyText map names a field the source type does not have\n(removed, renamed, or a typo). Its labels and messages can never be\nused.\n\nExample — `nick` no longer exists on the type:\n interface User { name: string }\n export const friendlyUser: FriendlyText<User> = {\n name: {rt$label: 'Name'},\n- nick: {rt$label: 'Nickname'},\n };\n\nFix — remove the entry, or re-run the reconcile so the mirror follows\nthe type (a renamed field carries its authored values along):\n ts-runtypes gen <source.ts> <Type> --update",
|
|
79
|
+
},
|
|
80
|
+
FT003: {
|
|
81
|
+
headline: 'Error key `{0}` is not a declared constraint of this field — the message can never fire.',
|
|
82
|
+
detail: "`rt$errors` keys must name a failure the field can actually produce:\n`type`, `rt$default`, or one of the field's declared format constraints\n(`minLength`, `pattern`, `min`, …). An undeclared key is dead\nconfiguration.\n\nExample — the field has no `maxLength` constraint:\n interface User { name: string & FormatString<{minLength: 2}> }\n export const friendlyUser: FriendlyText<User> = {\n name: {\n rt$errors: {\n minLength: 'Name needs at least 2 characters',\n- maxLength: 'Name is too long',\n },\n },\n };\n\nFix — remove the key, or declare the matching constraint on the field's\nTypeFormat so the message has a failure to describe.",
|
|
83
|
+
},
|
|
84
|
+
FT005: {
|
|
85
|
+
headline: 'Unknown placeholder `$[{0}]` — expected one of `$[label]`, `$[val]`, `$[path]`, `$[index]`.',
|
|
86
|
+
detail: "Error-message templates substitute a fixed placeholder set; an unknown\nname renders literally instead of substituting.\n\nExample:\n- rt$errors: {minLength: '$[name] is too short'}\n+ rt$errors: {minLength: '$[label] is too short'}\n\nFix — use one of the recognised placeholders, or write the literal text\nwithout the `$[…]` wrapper.",
|
|
87
|
+
},
|
|
88
|
+
FT006: {
|
|
89
|
+
headline: 'Plural error template is missing the mandatory `other` arm — the render has no backstop.',
|
|
90
|
+
detail: "Plural templates render the CLDR arm matching the count, and `other` is\nthe arm every locale falls back to. Without it some counts have no\nmessage at all.\n\nExample:\n rt$errors: {\n minLength: {\n one: 'Needs one more character',\n+ other: 'Needs $[val] more characters',\n },\n }\n\nFix — add the `other` arm to the plural object.",
|
|
91
|
+
},
|
|
92
|
+
FT007: {
|
|
93
|
+
headline: 'Unknown plural arm `{0}` — CLDR categories are `zero`, `one`, `two`, `few`, `many`, `other`.',
|
|
94
|
+
detail: "Plural template keys must be CLDR plural categories; anything else can\nnever be selected by any locale's plural rules.\n\nExample:\n rt$errors: {\n minLength: {\n- single: 'Needs one more character',\n+ one: 'Needs one more character',\n other: 'Needs $[val] more characters',\n },\n }\n\nFix — rename the arm to one of the six categories, or remove it.",
|
|
95
|
+
},
|
|
96
|
+
FT008: {
|
|
97
|
+
headline: 'Constraint `{0}` carries no count — a plural template here has dead arms; use a plain string.',
|
|
98
|
+
detail: "Only count-bearing constraints (`minLength`, `maxLength`, `min`, `max`,\n…) can select a plural arm. On a non-count constraint only `other` ever\nrenders, so the remaining arms are dead configuration.\n\nExample — `pattern` has no count:\n rt$errors: {\n- pattern: {one: 'One bad character', other: 'Invalid characters'},\n+ pattern: 'Only letters and numbers are allowed',\n }\n\nFix — replace the plural object with a plain string message.",
|
|
99
|
+
},
|
|
100
|
+
FT009: {
|
|
101
|
+
headline: '`rt$default` is mutually exclusive with per-constraint messages — use one mode or the other.',
|
|
102
|
+
detail: "An `rt$errors` record is either ONE `rt$default` catch-all or a set of\nper-constraint keys, mirroring the TypeScript union. Mixing them makes\nthe intent ambiguous (which message wins?).\n\nExample:\n rt$errors: {\n- rt$default: 'Invalid name',\n minLength: 'Name is too short',\n }\n\nFix — keep `{rt$default: '…'}` alone, or keep the per-constraint keys\nand drop `rt$default`.",
|
|
103
|
+
},
|
|
104
|
+
FT011: {
|
|
105
|
+
headline: 'Property `{0}` collides with the reserved `rt$` enrichment prefix — the type cannot be enriched.',
|
|
106
|
+
detail: '`rt$`-prefixed keys are reserved for enrichment meta (`rt$label`,\n`rt$errors`, `rt$items`, …); a source property with that prefix is\nindistinguishable from node meta, so gen refuses the type and the\nFriendlyType checker reports it here.\n\nFix — rename the property (a plain `$` prefix is fine; only `rt$` is\nreserved):\n interface Config {\n- rt$mode: string;\n+ $mode: string;\n }',
|
|
107
|
+
},
|
|
108
|
+
FT020: {
|
|
109
|
+
headline: 'Unfilled `@todo` placeholder — fill in the real labels/messages, then delete the `@todo` line.',
|
|
110
|
+
detail: "The generator stamps a `@todo` line on every freshly-scaffolded const in\na FriendlyText mirror file. It means \"this skeleton still carries\ngenerated blanks\". A clean, committed mirror has none.\n\nExample — a fresh scaffold:\n /** @rtType User#a1b2c3 @rtIds {name: d4e5f6} */\n- // @todo: generated skeleton — fill in real data, then delete this line\n export const friendlyUser: FriendlyText<User> = {\n- name: {rt$label: ''},\n+ name: {rt$label: 'Name'},\n };\n\nFix — author the real labels and error messages for the const, then\ndelete the whole `@todo` line (the compiler never removes it for you).",
|
|
111
|
+
},
|
|
112
|
+
FT021: {
|
|
113
|
+
headline: 'Stale `@rtOrphan` carcass — run `ts-runtypes gen --prune` to remove it (or restore the type).',
|
|
114
|
+
detail: 'The reconcile commented this FriendlyText const out because its source\ntype was deleted or renamed. The carcass preserves your authored labels\nand messages so a reappearing type can restore them — but a clean,\ncommitted mirror has none.\n\nFix — if the type is really gone, prune the carcass:\n ts-runtypes gen --prune\n\nFix — if the type was renamed, re-run the reconcile; a matching carcass\nis restored with your values intact:\n ts-runtypes gen <source.ts> <NewName> --update',
|
|
115
|
+
},
|
|
116
|
+
FT022: {
|
|
117
|
+
headline: 'Stale `@rtOrphanChild` field carcass — run `ts-runtypes gen --prune` to remove it (or restore the field).',
|
|
118
|
+
detail: "The reconcile commented this field out because the source type no longer\ndeclares it. The carcass preserves your authored value inline — but a\nclean, committed mirror has none.\n\nExample:\n export const friendlyUser: FriendlyText<User> = {\n- /* @rtOrphanChild nick: {rt$label: 'Nickname'}, */\n name: {rt$label: 'Name'},\n };\n\nFix — if the field is really gone: `ts-runtypes gen --prune`.\nFix — if the field was renamed, re-run `--update`; the authored value\nmoves to the renamed field when the ids match.",
|
|
119
|
+
},
|
|
120
|
+
GE000: {
|
|
121
|
+
headline: 'Cannot read enrichment mirror file: {0}',
|
|
122
|
+
detail: 'The drift check could not read this mirror file (permissions, a broken\nsymlink, or a race with a concurrent write).\n\nFix — make the file readable and re-run `ts-runtypes gen --check`.',
|
|
123
|
+
},
|
|
124
|
+
GE001: {
|
|
125
|
+
headline: 'Mirror location drift — the source maps to `{0}` but this file lives at `{1}`; re-run `ts-runtypes gen` to relocate.',
|
|
126
|
+
detail: 'Each source file mirrors to ONE computed path per family under the\nenrich root (friendly/… and mock/…, plus per-locale translation twins).\nThis file is not at its computed location — usually after a source move,\nan enrich-dir change, or a pre-split combined mirror that still needs\nmigrating.\n\nFix — re-run the generator; it writes the per-family files at the right\npaths and migrates a legacy combined mirror:\n ts-runtypes gen <source.ts> <Type> --update',
|
|
127
|
+
},
|
|
128
|
+
GE002: {
|
|
129
|
+
headline: 'Breadcrumb source `{0}` no longer exists ({1}) — the mirror is orphaned; delete it or re-run `ts-runtypes gen`.',
|
|
130
|
+
detail: "The mirror's `import type { … } from '<source>'` breadcrumb resolves to\na file that is gone. Its consts describe types that no longer exist\nanywhere.\n\nFix — if the source was deleted, delete the mirror file (both family\nfiles and any translation twins).\nFix — if the source moved, re-run the generator from the new location\nand prune the old mirror.",
|
|
131
|
+
},
|
|
132
|
+
GE003: {
|
|
133
|
+
headline: 'Source {0} no longer declares type `{1}` — re-run `ts-runtypes gen`.',
|
|
134
|
+
detail: 'The mirror imports a type name its source file no longer declares (the\ntype was renamed or removed). The reconcile turns its consts into\n`@rtOrphan` carcasses so your authored values survive.\n\nFix — re-run the reconcile against the current source, then prune any\ncarcasses that should not come back:\n ts-runtypes gen <source.ts> <Type> --update\n ts-runtypes gen --prune',
|
|
135
|
+
},
|
|
136
|
+
HUK010: {
|
|
137
|
+
headline: 'Property `{0}` is a function — `hasUnknownKeys` does not handle function values, so this property is silently not checked.',
|
|
138
|
+
detail: '`hasUnknownKeys` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
139
|
+
},
|
|
140
|
+
JCP001: {
|
|
141
|
+
headline: 'Internal error: JSON composite `{0}` references primitive entry `{1}` which was never rendered — please file an issue.',
|
|
142
|
+
},
|
|
143
|
+
MD001: {
|
|
144
|
+
headline: 'Unknown field `{0}` — the type does not declare it, so this MockData entry is dead.',
|
|
145
|
+
detail: "The MockData map names a field the source type does not have (removed,\nrenamed, or a typo). Its pool/range can never feed a generated mock.\n\nExample — `nick` no longer exists on the type:\n interface User { name: string }\n export const mockUser: MockData<User> = {\n name: {pool: ['Ada', 'Linus']},\n- nick: {pool: ['ada99']},\n };\n\nFix — remove the entry, or re-run the reconcile so the mirror follows\nthe type:\n ts-runtypes gen <source.ts> <Type> --update",
|
|
146
|
+
},
|
|
147
|
+
MD011: {
|
|
148
|
+
headline: 'Property `{0}` collides with the reserved `rt$` enrichment prefix — the type cannot be enriched.',
|
|
149
|
+
detail: '`rt$`-prefixed keys are reserved for enrichment meta (`rt$items`,\n`rt$length`, `rt$optional`, …); a source property with that prefix is\nindistinguishable from node meta, so gen refuses the type and the\nMockData checker reports it here.\n\nFix — rename the property (a plain `$` prefix is fine; only `rt$` is\nreserved):\n interface Config {\n- rt$size: number;\n+ $size: number;\n }',
|
|
150
|
+
},
|
|
151
|
+
MD020: {
|
|
152
|
+
headline: 'Unfilled `@todo` placeholder — fill in the real sample pools/ranges, then delete the `@todo` line.',
|
|
153
|
+
detail: "The generator stamps a `@todo` line on every freshly-scaffolded const in\na MockData mirror file. It means \"this skeleton still carries generated\nblanks\". A clean, committed mirror has none.\n\nExample — a fresh scaffold:\n /** @rtType User#a1b2c3 @rtIds {name: d4e5f6} */\n- // @todo: generated skeleton — fill in real data, then delete this line\n export const mockUser: MockData<User> = {\n- name: {pool: []},\n+ name: {pool: ['Ada Lovelace', 'Linus Torvalds']},\n };\n\nFix — author realistic sample pools/ranges for the const, then delete\nthe whole `@todo` line (the compiler never removes it for you).",
|
|
154
|
+
},
|
|
155
|
+
MD021: {
|
|
156
|
+
headline: 'Stale `@rtOrphan` carcass — run `ts-runtypes gen --prune` to remove it (or restore the type).',
|
|
157
|
+
detail: 'The reconcile commented this MockData const out because its source type\nwas deleted or renamed. The carcass preserves your authored pools and\nranges so a reappearing type can restore them — but a clean, committed\nmirror has none.\n\nFix — if the type is really gone, prune the carcass:\n ts-runtypes gen --prune\n\nFix — if the type was renamed, re-run the reconcile; a matching carcass\nis restored with your values intact:\n ts-runtypes gen <source.ts> <NewName> --update',
|
|
158
|
+
},
|
|
159
|
+
MD022: {
|
|
160
|
+
headline: 'Stale `@rtOrphanChild` field carcass — run `ts-runtypes gen --prune` to remove it (or restore the field).',
|
|
161
|
+
detail: "The reconcile commented this field out because the source type no longer\ndeclares it. The carcass preserves your authored value inline — but a\nclean, committed mirror has none.\n\nExample:\n export const mockUser: MockData<User> = {\n- /* @rtOrphanChild nick: {pool: ['ada99']}, */\n name: {pool: ['Ada', 'Linus']},\n };\n\nFix — if the field is really gone: `ts-runtypes gen --prune`.\nFix — if the field was renamed, re-run `--update`; the authored value\nmoves to the renamed field when the ids match.",
|
|
162
|
+
},
|
|
163
|
+
MKR001: {
|
|
164
|
+
headline: '`{0}()` is being called at runtime just so the marker can read its return type — side effects, throws, or async work run for nothing.',
|
|
165
|
+
detail: 'Reflect-form markers (`createValidate(value)`, `getRunTypeId(value)`)\ninvoke their argument expression at runtime; the value is then discarded —\nonly its inferred type is used.\n\nFix — use the static form with `ReturnType<>`:\n - const isUser = createValidate({0}());\n+ const isUser = createValidate<ReturnType<typeof {0}>>();\n\nFix — pass an existing value of the desired type:\n const existingUser: User = ...;\n const isUser = getRunTypeId(existingUser);',
|
|
166
|
+
},
|
|
167
|
+
MKR003: {
|
|
168
|
+
headline: 'Marker call is inside a generic function — the type argument is unresolved, so no id can be computed at build time.',
|
|
169
|
+
detail: "The build can only compute an id for a concrete type (`User`,\n`{name: string}`, etc.). A type parameter like `T` is abstract — it\ntakes a different value at each call site of the surrounding function,\nso a single id can't represent it.\n\nFix — inline the marker at each concrete call site:\n function isUser(value: unknown) {\n return createValidate<User>()(value);\n }\n\nFix — accept a pre-computed id from the caller:\n function makeChecker<T>(id: InjectRunTypeId<T>) {\n return createValidate<T>(id);\n }\n const isUser = makeChecker<User>(getRunTypeId<User>());",
|
|
170
|
+
},
|
|
171
|
+
MKR004: {
|
|
172
|
+
headline: "`noLiterals: true` has no effect here — the type argument doesn't resolve to literal values.",
|
|
173
|
+
detail: "The `noLiterals` validate option skips the exact-value check that literal\ntypes (`'admin'`, `42`, `true`) compile to. This call's type argument\nresolves to a non-literal type, so there is no literal check to skip and\nthe option is a silent no-op.\n\nFix — drop the option:\n- const isRole = createValidate<string>({noLiterals: true});\n+ const isRole = createValidate<string>();\n\nOr, if you meant to relax a literal union, point the option at the type\nthat actually carries the literals:\n const isRole = createValidate<'admin' | 'user'>({noLiterals: true});",
|
|
174
|
+
},
|
|
175
|
+
MKR005: {
|
|
176
|
+
headline: '`noIsArrayCheck: true` has no effect here — the type argument is not an array type.',
|
|
177
|
+
detail: "The `noIsArrayCheck` validate option skips the `Array.isArray` guard that\narray types compile to. This call's type argument resolves to a non-array\ntype, so there is no guard to skip and the option is a silent no-op.\n\nFix — drop the option:\n- const isUser = createValidate<User>({noIsArrayCheck: true});\n+ const isUser = createValidate<User>();\n\nOr point it at the array type you meant:\n const isUsers = createValidate<User[]>({noIsArrayCheck: true});",
|
|
178
|
+
},
|
|
179
|
+
OVR001: {
|
|
180
|
+
headline: 'Duplicate override for `{0}` — there can be exactly one override per (type, function).',
|
|
181
|
+
detail: 'Two `overrideX<T>()` declarations target the same type and the same\nfunction family. Which one wins would depend on scan order, so a second\noverride is rejected regardless of its body. The Related: line above\npoints at the override that was registered first.\n\nFix — keep one canonical override and delete the other:\n- overrideValidate<User>((utl) => (value) => checkA(value)); // first\n- overrideValidate<User>((utl) => (value) => checkB(value)); // duplicate\n+ overrideValidate<User>((utl) => (value) => checkA(value) && checkB(value));',
|
|
182
|
+
},
|
|
183
|
+
OVR002: {
|
|
184
|
+
headline: 'Override entry `{0}` references compiled function `{1}` which did not render — this would throw at runtime, so the build stops.',
|
|
185
|
+
detail: "An override redirect body loads its compiled function from the cache\n(`usePureFn('cfn::…')`), but that module never rendered into the entry\ngraph. Calling the override would throw at runtime, so the build surfaces\nthe miss now. This is an internal emitter tripwire and should never fire\nin normal operation.\n\nFix — re-run with a clean cache first (delete the .runtypes cache dir /\nrestart the dev server). If it persists, the emitter dropped a module it\nshould have rendered: please open an issue with the type + override that\ntriggers it.",
|
|
186
|
+
},
|
|
187
|
+
OVR010: {
|
|
188
|
+
headline: 'Overriding `validate` for this type also changes how JSON and binary decoders narrow unions containing it.',
|
|
189
|
+
detail: "`validate` is a shared dependency across function families: JSON and\nbinary union decoders call the member validators to pick the matching\nbranch. An `overrideValidate<T>()` therefore reaches past\n`createValidate<T>()` — decoders of any union containing T now narrow\nwith YOUR function.\n\nThis is informational; the build proceeds. If the override should only\naffect direct validation, give the union members a discriminant so\ndecoders never fall back to member validation:\n type Event = {kind: 'click'; x: number} | {kind: 'key'; code: string};",
|
|
190
|
+
},
|
|
191
|
+
PFE9004: {
|
|
192
|
+
headline: 'Duplicate `registerPureFnFactory` for `{0}` with a different body — only one definition can win.',
|
|
193
|
+
detail: 'Two calls register the same `namespace::functionId` key but the factory\nbodies differ. The cache can only hold one definition, so one call site\nsilently loses its version at runtime.\n\nFix — make all registrations identical, or pick one canonical site and\ndelete the others. The Related: line above points at the first\nregistration the extractor saw.',
|
|
194
|
+
},
|
|
195
|
+
PFE9005: {
|
|
196
|
+
headline: 'Pure-fn factory `{0}` uses destructured parameters — only simple identifier params are supported.',
|
|
197
|
+
detail: "The build inlines parameter references by name when it materialises the\nfactory. Destructuring patterns (`({a, b})`, `([x, y])`) don't have a\nsingle name to substitute.\n\nFix — destructure inside the body:\n - registerPureFnFactory('ns::fn', (utl) => ({a, b}) => ...);\n+ registerPureFnFactory('ns::fn', (utl) => (params) => {\n+ const {a, b} = params;\n+ return ...;\n+ });",
|
|
198
|
+
},
|
|
199
|
+
PFE9006: {
|
|
200
|
+
headline: "`this` is not allowed inside a `registerPureFnFactory` factory body — pure functions can't depend on a calling context.",
|
|
201
|
+
detail: "Pure functions are materialised standalone at build time; there's no\n`this` to bind to.\n\nFix — replace `this` with an explicit parameter, or move the function\nout of the class/object method that owns the `this`:\n registerPureFnFactory('ns::fn', (utl) => (self, input) => {\n return self.field + input;\n });",
|
|
202
|
+
},
|
|
203
|
+
PFE9007: {
|
|
204
|
+
headline: '`async`/`await` is not allowed inside a `registerPureFnFactory` factory body.',
|
|
205
|
+
detail: "Pure functions must run synchronously so the build can call them at\ncompile time. `async` introduces a Promise that won't resolve until\nruntime.\n\nFix — make the factory synchronous; move async work to the caller:\n registerPureFnFactory('ns::fn', (utl) => {\n- return async (input) => { const r = await heavy(); return r; };\n+ return (resolvedValue) => transform(resolvedValue);\n });",
|
|
206
|
+
},
|
|
207
|
+
PFE9008: {
|
|
208
|
+
headline: '`yield` / generators are not allowed inside a `registerPureFnFactory` factory body.',
|
|
209
|
+
detail: "Generators carry resumption state that can't be materialised\nstatically.\n\nFix — return an array or a plain iterable instead:\n registerPureFnFactory('ns::fn', (utl) => (input) => {\n return [...computeAll(input)];\n });",
|
|
210
|
+
},
|
|
211
|
+
PFE9009: {
|
|
212
|
+
headline: '`import()` is not allowed inside a `registerPureFnFactory` factory body.',
|
|
213
|
+
detail: 'Dynamic imports load modules at runtime — the build needs every\ndependency available statically.\n\nFix — use a top-level `import` statement, or pass the imported module\nin as a parameter.',
|
|
214
|
+
},
|
|
215
|
+
PFE9010: {
|
|
216
|
+
headline: '`{0}` is not allowed inside a `registerPureFnFactory` factory body.',
|
|
217
|
+
detail: "Globals like `eval`, `Function`, `fetch`, `XMLHttpRequest`, `require`,\n`process`, `globalThis`, `window`, `document` are blocked from pure-fn\nbodies — they either execute arbitrary code or depend on a runtime\nenvironment the build can't reproduce.\n\nFix — remove the reference, or pass the needed value in as a parameter.",
|
|
218
|
+
},
|
|
219
|
+
PFE9011: {
|
|
220
|
+
headline: "`{0}` is captured from outer scope inside a `registerPureFnFactory` factory — pure functions can't reach outside their own body.",
|
|
221
|
+
detail: "The build inlines factory bodies without their lexical environment, so\nany free variable becomes `undefined` at runtime.\n\nFix — pass `{0}` in as a parameter:\n registerPureFnFactory('ns::fn', (utl) => ({0}, value) => ...);\n\nFix — inline its value if it's a known constant:\n registerPureFnFactory('ns::fn', (utl) => (value) => {\n const {0} = 42;\n ...\n });\n\nFix — import `{0}` directly inside the factory if it's a module export.",
|
|
222
|
+
},
|
|
223
|
+
PFE9012: {
|
|
224
|
+
headline: "Pure-fn `{0}` is referenced by a RT function but never registered — call `registerPureFnFactory('{1}::{2}', …)` first.",
|
|
225
|
+
detail: "A RT validator/encoder calls `utl.usePureFn('{0}')` (or similar) but\nno `registerPureFnFactory` call with that namespace+function pair was\nfound in any scanned source file.\n\nFix — register the function in the expected location ({3}, if known).\nMake sure the file is included in the scan set.",
|
|
226
|
+
},
|
|
227
|
+
PFE9013: {
|
|
228
|
+
headline: '`{0}.{1}` dependency argument must be a string literal or a same-scope `const` string.',
|
|
229
|
+
detail: "`utl.usePureFn` / `utl.getPureFn` need a static key so the build can\nverify the referenced pure-fn is registered.\n\nFix:\n - const key = buildKey();\n- return utl.usePureFn(key)(input);\n+ return utl.usePureFn('rt::myFn')(input);",
|
|
230
|
+
},
|
|
231
|
+
PFN001: {
|
|
232
|
+
headline: '`PureFunction<F>` argument must be an INLINE arrow or function expression.',
|
|
233
|
+
detail: "The build extracts and AOT-compiles the function body, so it must see the\nliteral inline at the call site. A named reference — even a module-private\n`const f = …` or `function f(){}` — is not accepted, because the literal\nmust have no handle anything else can reach; the compiled copy is then the\nonly one that can run. (An imported or exported literal is rejected as PFN002.)\n\nFix — inline the function at the call site:\n- const validate = (v: unknown) => typeof v === 'string';\n- registerValidator(validate);\n+ registerValidator((v: unknown) => typeof v === 'string');",
|
|
234
|
+
},
|
|
235
|
+
PFN002: {
|
|
236
|
+
headline: '`PureFunction<F>` literal must not be imported or exported — the compiled copy must be the only one that can run.',
|
|
237
|
+
detail: "The build extracts and AOT-compiles the function body, and the compiled\ncopy is the single source of truth. If the original literal stays reachable\nas a value — imported from another module, or exported so another module can\nimport it — a caller could invoke the un-compiled function and diverge from\nthe compiled behaviour.\n\nUnder the literal-only rule a named binding isn't allowed at all (see PFN001),\nso the fix is to inline the function at the call site:\n- import {validate} from './validators'; // imported — rejected\n- export const validate = (v) => …; // exported — rejected\n+ registerValidator((v: unknown) => typeof v === 'string'); // inline — ok",
|
|
238
|
+
},
|
|
239
|
+
PJ001: {
|
|
240
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
241
|
+
detail: "`never` is the empty type — no value can ever inhabit it. A field\ntyped `never` cannot carry a runtime value, so there is nothing to\nencode/decode/validate.\n\nFix — use `unknown` if you really want to accept any value:\n interface User {\n- tag: never;\n+ tag: unknown; // narrow before use\n }\n\nFix — pick a concrete type matching your real data:\n interface User {\n- tag: never;\n+ tag: 'pending' | 'active' | 'done';\n }",
|
|
242
|
+
},
|
|
243
|
+
PJ002: {
|
|
244
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
245
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
246
|
+
},
|
|
247
|
+
PJ003: {
|
|
248
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
249
|
+
detail: "Functions have no value form to serialise — their closure, prototype,\nand bound state aren't representable in JSON or binary.\n\nFix — drop the function from your type, or replace it with the data the\nfunction would produce:\n interface User {\n- getName: () => string;\n+ name: string;\n }",
|
|
250
|
+
},
|
|
251
|
+
PJ004: {
|
|
252
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
253
|
+
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded — every element would need to be\nrepresentable, and these aren't. Dropping individual elements would\nchange the array length, so the encoder refuses rather than silently\nshipping a different shape.\n\nFix — change the element type to something serialisable:\n - type Items = (() => void)[];\n+ type Items = string[];",
|
|
254
|
+
},
|
|
255
|
+
PJ005: {
|
|
256
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
257
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
258
|
+
},
|
|
259
|
+
PJ010: {
|
|
260
|
+
headline: 'Property `{0}` is a function — `prepareForJson` does not handle function values, so this property is silently not encoded.',
|
|
261
|
+
detail: '`prepareForJson` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
262
|
+
},
|
|
263
|
+
PJ011: {
|
|
264
|
+
headline: "Method `{0}` is silently not encoded by `prepareForJson` — methods aren't data.",
|
|
265
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`prepareForJson` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
266
|
+
},
|
|
267
|
+
PJ012: {
|
|
268
|
+
headline: "Static member `{0}` is silently not encoded by `prepareForJson` — statics aren't part of instance data.",
|
|
269
|
+
detail: 'Class static members live on the class, not on individual instances.\n`prepareForJson` operates on instance shape, so statics are excluded.',
|
|
270
|
+
},
|
|
271
|
+
PJ013: {
|
|
272
|
+
headline: "Symbol-keyed property `{0}` is silently not encoded by `prepareForJson` — symbol keys aren't JSON-representable.",
|
|
273
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `prepareForJson` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
274
|
+
},
|
|
275
|
+
PJ014: {
|
|
276
|
+
headline: "Union member(s) of type `{0}` can't be represented as data — `prepareForJson` drops them, so the union is encoded as its remaining members.",
|
|
277
|
+
detail: 'A union projects to its serialisable members only: `DataOnly<Date | symbol>`\nis `Date`. The dropped member(s) ({0}) carry no JSON-shaped value (symbol,\nfunction, Promise, or a non-serialisable built-in like `Map` / `Set` /\ntyped arrays), so `prepareForJson` encoded only the members that remain.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If EVERY member of the union is non-serialisable the\nprojection is `never`, and `prepareForJson` throws at build time instead.',
|
|
278
|
+
},
|
|
279
|
+
PJ015: {
|
|
280
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `prepareForJson` drops it, so this property is silently not encoded.',
|
|
281
|
+
detail: '`prepareForJson` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `prepareForJson` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
282
|
+
},
|
|
283
|
+
PJS001: {
|
|
284
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
285
|
+
detail: "`never` is the empty type — no value can ever inhabit it. A field\ntyped `never` cannot carry a runtime value, so there is nothing to\nencode/decode/validate.\n\nFix — use `unknown` if you really want to accept any value:\n interface User {\n- tag: never;\n+ tag: unknown; // narrow before use\n }\n\nFix — pick a concrete type matching your real data:\n interface User {\n- tag: never;\n+ tag: 'pending' | 'active' | 'done';\n }",
|
|
286
|
+
},
|
|
287
|
+
PJS002: {
|
|
288
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
289
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
290
|
+
},
|
|
291
|
+
PJS003: {
|
|
292
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
293
|
+
detail: "Functions have no value form to serialise — their closure, prototype,\nand bound state aren't representable in JSON or binary.\n\nFix — drop the function from your type, or replace it with the data the\nfunction would produce:\n interface User {\n- getName: () => string;\n+ name: string;\n }",
|
|
294
|
+
},
|
|
295
|
+
PJS004: {
|
|
296
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
297
|
+
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded — every element would need to be\nrepresentable, and these aren't. Dropping individual elements would\nchange the array length, so the encoder refuses rather than silently\nshipping a different shape.\n\nFix — change the element type to something serialisable:\n - type Items = (() => void)[];\n+ type Items = string[];",
|
|
298
|
+
},
|
|
299
|
+
PJS005: {
|
|
300
|
+
headline: 'Cannot encode `{0}` to JSON.',
|
|
301
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
302
|
+
},
|
|
303
|
+
PJS010: {
|
|
304
|
+
headline: 'Property `{0}` is a function — `prepareForJsonSafe` does not handle function values, so this property is silently not encoded.',
|
|
305
|
+
detail: '`prepareForJsonSafe` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
306
|
+
},
|
|
307
|
+
PJS011: {
|
|
308
|
+
headline: "Method `{0}` is silently not encoded by `prepareForJsonSafe` — methods aren't data.",
|
|
309
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`prepareForJsonSafe` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
310
|
+
},
|
|
311
|
+
PJS012: {
|
|
312
|
+
headline: "Static member `{0}` is silently not encoded by `prepareForJsonSafe` — statics aren't part of instance data.",
|
|
313
|
+
detail: 'Class static members live on the class, not on individual instances.\n`prepareForJsonSafe` operates on instance shape, so statics are excluded.',
|
|
314
|
+
},
|
|
315
|
+
PJS013: {
|
|
316
|
+
headline: "Symbol-keyed property `{0}` is silently not encoded by `prepareForJsonSafe` — symbol keys aren't JSON-representable.",
|
|
317
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `prepareForJsonSafe` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
318
|
+
},
|
|
319
|
+
PJS014: {
|
|
320
|
+
headline: "Union member(s) of type `{0}` can't be represented as data — `prepareForJsonSafe` drops them, so the union is encoded as its remaining members.",
|
|
321
|
+
detail: 'A union projects to its serialisable members only: `DataOnly<Date | symbol>`\nis `Date`. The dropped member(s) ({0}) carry no JSON-shaped value (symbol,\nfunction, Promise, or a non-serialisable built-in like `Map` / `Set` /\ntyped arrays), so `prepareForJsonSafe` encoded only the members that remain.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If EVERY member of the union is non-serialisable the\nprojection is `never`, and `prepareForJsonSafe` throws at build time instead.',
|
|
322
|
+
},
|
|
323
|
+
PJS015: {
|
|
324
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `prepareForJsonSafe` drops it, so this property is silently not encoded.',
|
|
325
|
+
detail: '`prepareForJsonSafe` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `prepareForJsonSafe` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
326
|
+
},
|
|
327
|
+
RJ001: {
|
|
328
|
+
headline: 'Cannot decode `{0}` from JSON.',
|
|
329
|
+
detail: "`never` is the empty type — no value can ever inhabit it. A field\ntyped `never` cannot carry a runtime value, so there is nothing to\nencode/decode/validate.\n\nFix — use `unknown` if you really want to accept any value:\n interface User {\n- tag: never;\n+ tag: unknown; // narrow before use\n }\n\nFix — pick a concrete type matching your real data:\n interface User {\n- tag: never;\n+ tag: 'pending' | 'active' | 'done';\n }",
|
|
330
|
+
},
|
|
331
|
+
RJ002: {
|
|
332
|
+
headline: 'Cannot decode `{0}` from JSON.',
|
|
333
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
334
|
+
},
|
|
335
|
+
RJ003: {
|
|
336
|
+
headline: 'Cannot decode `{0}` from JSON.',
|
|
337
|
+
detail: "Functions have no value form to serialise — their closure, prototype,\nand bound state aren't representable in JSON or binary.\n\nFix — drop the function from your type, or replace it with the data the\nfunction would produce:\n interface User {\n- getName: () => string;\n+ name: string;\n }",
|
|
338
|
+
},
|
|
339
|
+
RJ004: {
|
|
340
|
+
headline: 'Cannot decode `{0}` from JSON.',
|
|
341
|
+
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded — every element would need to be\nrepresentable, and these aren't. Dropping individual elements would\nchange the array length, so the encoder refuses rather than silently\nshipping a different shape.\n\nFix — change the element type to something serialisable:\n - type Items = (() => void)[];\n+ type Items = string[];",
|
|
342
|
+
},
|
|
343
|
+
RJ005: {
|
|
344
|
+
headline: 'Cannot decode `{0}` from JSON.',
|
|
345
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
346
|
+
},
|
|
347
|
+
RJ010: {
|
|
348
|
+
headline: 'Property `{0}` is a function — `restoreFromJson` does not handle function values, so this property is silently not decoded.',
|
|
349
|
+
detail: '`restoreFromJson` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
350
|
+
},
|
|
351
|
+
RJ011: {
|
|
352
|
+
headline: "Method `{0}` is silently not decoded by `restoreFromJson` — methods aren't data.",
|
|
353
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`restoreFromJson` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
354
|
+
},
|
|
355
|
+
RJ012: {
|
|
356
|
+
headline: "Static member `{0}` is silently not decoded by `restoreFromJson` — statics aren't part of instance data.",
|
|
357
|
+
detail: 'Class static members live on the class, not on individual instances.\n`restoreFromJson` operates on instance shape, so statics are excluded.',
|
|
358
|
+
},
|
|
359
|
+
RJ013: {
|
|
360
|
+
headline: "Symbol-keyed property `{0}` is silently not decoded by `restoreFromJson` — symbol keys aren't JSON-representable.",
|
|
361
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `restoreFromJson` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
362
|
+
},
|
|
363
|
+
RJ014: {
|
|
364
|
+
headline: "Union member(s) of type `{0}` can't be represented as data — `restoreFromJson` drops them, so the union is decoded as its remaining members.",
|
|
365
|
+
detail: 'A union projects to its serialisable members only: `DataOnly<Date | symbol>`\nis `Date`. The dropped member(s) ({0}) carry no JSON-shaped value (symbol,\nfunction, Promise, or a non-serialisable built-in like `Map` / `Set` /\ntyped arrays), so `restoreFromJson` decoded only the members that remain.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If EVERY member of the union is non-serialisable the\nprojection is `never`, and `restoreFromJson` throws at build time instead.',
|
|
366
|
+
},
|
|
367
|
+
RJ015: {
|
|
368
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `restoreFromJson` drops it, so this property is silently not decoded.',
|
|
369
|
+
detail: '`restoreFromJson` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `restoreFromJson` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
370
|
+
},
|
|
371
|
+
SJ001: {
|
|
372
|
+
headline: 'Cannot stringify `{0}` to a JSON string.',
|
|
373
|
+
detail: "`never` is the empty type — no value can ever inhabit it. A field\ntyped `never` cannot carry a runtime value, so there is nothing to\nencode/decode/validate.\n\nFix — use `unknown` if you really want to accept any value:\n interface User {\n- tag: never;\n+ tag: unknown; // narrow before use\n }\n\nFix — pick a concrete type matching your real data:\n interface User {\n- tag: never;\n+ tag: 'pending' | 'active' | 'done';\n }",
|
|
374
|
+
},
|
|
375
|
+
SJ002: {
|
|
376
|
+
headline: 'Cannot stringify `{0}` to a JSON string.',
|
|
377
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
378
|
+
},
|
|
379
|
+
SJ003: {
|
|
380
|
+
headline: 'Cannot stringify `{0}` to a JSON string.',
|
|
381
|
+
detail: "Functions have no value form to serialise — their closure, prototype,\nand bound state aren't representable in JSON or binary.\n\nFix — drop the function from your type, or replace it with the data the\nfunction would produce:\n interface User {\n- getName: () => string;\n+ name: string;\n }",
|
|
382
|
+
},
|
|
383
|
+
SJ004: {
|
|
384
|
+
headline: 'Cannot stringify `{0}` to a JSON string.',
|
|
385
|
+
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded — every element would need to be\nrepresentable, and these aren't. Dropping individual elements would\nchange the array length, so the encoder refuses rather than silently\nshipping a different shape.\n\nFix — change the element type to something serialisable:\n - type Items = (() => void)[];\n+ type Items = string[];",
|
|
386
|
+
},
|
|
387
|
+
SJ005: {
|
|
388
|
+
headline: 'Cannot stringify `{0}` to a JSON string.',
|
|
389
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
390
|
+
},
|
|
391
|
+
SJ010: {
|
|
392
|
+
headline: 'Property `{0}` is a function — `stringifyJson` does not handle function values, so this property is silently not stringified.',
|
|
393
|
+
detail: '`stringifyJson` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
394
|
+
},
|
|
395
|
+
SJ011: {
|
|
396
|
+
headline: "Method `{0}` is silently not stringified by `stringifyJson` — methods aren't data.",
|
|
397
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`stringifyJson` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
398
|
+
},
|
|
399
|
+
SJ012: {
|
|
400
|
+
headline: "Static member `{0}` is silently not stringified by `stringifyJson` — statics aren't part of instance data.",
|
|
401
|
+
detail: 'Class static members live on the class, not on individual instances.\n`stringifyJson` operates on instance shape, so statics are excluded.',
|
|
402
|
+
},
|
|
403
|
+
SJ013: {
|
|
404
|
+
headline: "Symbol-keyed property `{0}` is silently not stringified by `stringifyJson` — symbol keys aren't JSON-representable.",
|
|
405
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `stringifyJson` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
406
|
+
},
|
|
407
|
+
SJ014: {
|
|
408
|
+
headline: "Union member(s) of type `{0}` can't be represented as data — `stringifyJson` drops them, so the union is stringified as its remaining members.",
|
|
409
|
+
detail: 'A union projects to its serialisable members only: `DataOnly<Date | symbol>`\nis `Date`. The dropped member(s) ({0}) carry no JSON-shaped value (symbol,\nfunction, Promise, or a non-serialisable built-in like `Map` / `Set` /\ntyped arrays), so `stringifyJson` stringified only the members that remain.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If EVERY member of the union is non-serialisable the\nprojection is `never`, and `stringifyJson` throws at build time instead.',
|
|
410
|
+
},
|
|
411
|
+
SJ015: {
|
|
412
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `stringifyJson` drops it, so this property is silently not stringified.',
|
|
413
|
+
detail: '`stringifyJson` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `stringifyJson` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
414
|
+
},
|
|
415
|
+
SUK010: {
|
|
416
|
+
headline: 'Property `{0}` is a function — `stripUnknownKeys` does not handle function values, so this property is silently not stripped.',
|
|
417
|
+
detail: '`stripUnknownKeys` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
418
|
+
},
|
|
419
|
+
TB001: {
|
|
420
|
+
headline: 'Cannot serialise `{0}` to binary.',
|
|
421
|
+
detail: "`never` is the empty type — no value can ever inhabit it. A field\ntyped `never` cannot carry a runtime value, so there is nothing to\nencode/decode/validate.\n\nFix — use `unknown` if you really want to accept any value:\n interface User {\n- tag: never;\n+ tag: unknown; // narrow before use\n }\n\nFix — pick a concrete type matching your real data:\n interface User {\n- tag: never;\n+ tag: 'pending' | 'active' | 'done';\n }",
|
|
422
|
+
},
|
|
423
|
+
TB002: {
|
|
424
|
+
headline: 'Cannot serialise `{0}` to binary.',
|
|
425
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
426
|
+
},
|
|
427
|
+
TB003: {
|
|
428
|
+
headline: 'Cannot serialise `{0}` to binary.',
|
|
429
|
+
detail: "Functions have no value form to serialise — their closure, prototype,\nand bound state aren't representable in JSON or binary.\n\nFix — drop the function from your type, or replace it with the data the\nfunction would produce:\n interface User {\n- getName: () => string;\n+ name: string;\n }",
|
|
430
|
+
},
|
|
431
|
+
TB004: {
|
|
432
|
+
headline: 'Cannot serialise `{0}` to binary.',
|
|
433
|
+
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded — every element would need to be\nrepresentable, and these aren't. Dropping individual elements would\nchange the array length, so the encoder refuses rather than silently\nshipping a different shape.\n\nFix — change the element type to something serialisable:\n - type Items = (() => void)[];\n+ type Items = string[];",
|
|
434
|
+
},
|
|
435
|
+
TB005: {
|
|
436
|
+
headline: 'Cannot serialise `{0}` to binary.',
|
|
437
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
438
|
+
},
|
|
439
|
+
TB006: {
|
|
440
|
+
headline: 'Cannot serialise `{0}` to binary.',
|
|
441
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
442
|
+
},
|
|
443
|
+
TB010: {
|
|
444
|
+
headline: 'Property `{0}` is a function — `toBinary` does not handle function values, so this property is silently not serialised.',
|
|
445
|
+
detail: '`toBinary` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
446
|
+
},
|
|
447
|
+
TB011: {
|
|
448
|
+
headline: "Method `{0}` is silently not serialised by `toBinary` — methods aren't data.",
|
|
449
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`toBinary` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
450
|
+
},
|
|
451
|
+
TB012: {
|
|
452
|
+
headline: "Static member `{0}` is silently not serialised by `toBinary` — statics aren't part of instance data.",
|
|
453
|
+
detail: 'Class static members live on the class, not on individual instances.\n`toBinary` operates on instance shape, so statics are excluded.',
|
|
454
|
+
},
|
|
455
|
+
TB013: {
|
|
456
|
+
headline: "Symbol-keyed property `{0}` is silently not serialised by `toBinary` — symbol keys aren't JSON-representable.",
|
|
457
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `toBinary` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
458
|
+
},
|
|
459
|
+
TB014: {
|
|
460
|
+
headline: "Union member(s) of type `{0}` can't be represented as data — `toBinary` drops them, so the union is serialised as its remaining members.",
|
|
461
|
+
detail: 'A union projects to its serialisable members only: `DataOnly<Date | symbol>`\nis `Date`. The dropped member(s) ({0}) carry no JSON-shaped value (symbol,\nfunction, Promise, or a non-serialisable built-in like `Map` / `Set` /\ntyped arrays), so `toBinary` serialised only the members that remain.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If EVERY member of the union is non-serialisable the\nprojection is `never`, and `toBinary` throws at build time instead.',
|
|
462
|
+
},
|
|
463
|
+
TB015: {
|
|
464
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `toBinary` drops it, so this property is silently not serialised.',
|
|
465
|
+
detail: '`toBinary` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `toBinary` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
466
|
+
},
|
|
467
|
+
TMP001: {
|
|
468
|
+
headline: "Temporal type `{0}` resolved to `any` — the Temporal lib isn't in your tsconfig `lib`, so the generated validator would accept any value.",
|
|
469
|
+
detail: 'ts-runtypes reads types through TypeScript\'s lib definitions, so it\ncan only validate `Temporal.*` types when the Temporal namespace is loaded.\nWith the lib missing, `{0}` silently degrades to `any` and the validator\nbecomes a no-op that accepts everything — almost never what you intended.\n\nFix — add "ESNext.Temporal" to your tsconfig:\n {\n "compilerOptions": {\n "lib": ["ES2023", "ESNext.Temporal"]\n }\n }',
|
|
470
|
+
},
|
|
471
|
+
UKE010: {
|
|
472
|
+
headline: 'Property `{0}` is a function — `unknownKeyErrors` does not handle function values, so this property is silently not checked.',
|
|
473
|
+
detail: '`unknownKeyErrors` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
474
|
+
},
|
|
475
|
+
UKU010: {
|
|
476
|
+
headline: 'Property `{0}` is a function — `unknownKeysToUndefined` does not handle function values, so this property is silently not cleared.',
|
|
477
|
+
detail: '`unknownKeysToUndefined` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
478
|
+
},
|
|
479
|
+
UKW010: {
|
|
480
|
+
headline: 'Property `{0}` is a function — `unknownKeysToUndefinedWire` does not handle function values, so this property is silently not cleared.',
|
|
481
|
+
detail: '`unknownKeysToUndefinedWire` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
482
|
+
},
|
|
483
|
+
VE001: {
|
|
484
|
+
headline: 'Cannot validate `{0}`.',
|
|
485
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
486
|
+
},
|
|
487
|
+
VE002: {
|
|
488
|
+
headline: 'Cannot validate `{0}`.',
|
|
489
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
490
|
+
},
|
|
491
|
+
VE010: {
|
|
492
|
+
headline: 'Property `{0}` is a function — `validationErrors` does not handle function values, so this property is silently not checked.',
|
|
493
|
+
detail: '`validationErrors` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
494
|
+
},
|
|
495
|
+
VE011: {
|
|
496
|
+
headline: "Method `{0}` is silently not checked by `validationErrors` — methods aren't data.",
|
|
497
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`validationErrors` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
498
|
+
},
|
|
499
|
+
VE012: {
|
|
500
|
+
headline: "Static member `{0}` is silently not checked by `validationErrors` — statics aren't part of instance data.",
|
|
501
|
+
detail: 'Class static members live on the class, not on individual instances.\n`validationErrors` operates on instance shape, so statics are excluded.',
|
|
502
|
+
},
|
|
503
|
+
VE013: {
|
|
504
|
+
headline: "Symbol-keyed property `{0}` is silently not checked by `validationErrors` — symbol keys aren't JSON-representable.",
|
|
505
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `validationErrors` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
506
|
+
},
|
|
507
|
+
VE015: {
|
|
508
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `validationErrors` drops it, so this property is silently not checked.',
|
|
509
|
+
detail: '`validationErrors` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `validationErrors` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
510
|
+
},
|
|
511
|
+
VE020: {
|
|
512
|
+
headline: '`validationErrors` on `any` / `unknown` always returns an empty error array — nothing is checked.',
|
|
513
|
+
detail: 'Same reason as VL021: `any` and `unknown` describe "anything", so the\nchecker has no structure to compare against. The returned error array\nwill always be empty.\n\nFix — narrow the type to the actual shape you expect:\n - const errors = createGetValidationErrors<unknown>()(value);\n+ const errors = createGetValidationErrors<User>()(value);',
|
|
514
|
+
},
|
|
515
|
+
VL001: {
|
|
516
|
+
headline: 'Cannot validate `{0}`.',
|
|
517
|
+
detail: "Built-in classes like `Map`, `Set`, `WeakMap`, `WeakSet`, `Int8Array`,\n`Uint8Array`, `Buffer`, and `Promise` carry runtime state that doesn't\nsurvive a JSON or binary round-trip. Their instance identity is lost the\nmoment they're serialised.\n\nFix — convert to a plain object/array before serialising:\n // for Map<K, V>:\n const data = Object.fromEntries(yourMap);\n // for Set<T>:\n const data = [...yourSet];\n // for typed arrays:\n const data = Array.from(yourBuffer);\n\nFix — change the field type to a serialisable shape:\n interface User {\n- tags: Set<string>;\n+ tags: string[];\n }",
|
|
518
|
+
},
|
|
519
|
+
VL002: {
|
|
520
|
+
headline: 'Cannot validate `{0}`.',
|
|
521
|
+
detail: "Every `symbol` value carries a unique runtime identity (`Symbol() !==\nSymbol()` even with the same description). That identity disappears the\nmoment it's serialised, and two symbols can't be compared across realms,\nworkers, or process boundaries. A validator that asserts \"this is a\nsymbol\" gives a false sense of safety — the value can't actually\nround-trip.\n\nFix — use a stable string key (often a literal union):\n - type Status = symbol;\n+ type Status = 'pending' | 'active' | 'done';",
|
|
522
|
+
},
|
|
523
|
+
VL010: {
|
|
524
|
+
headline: 'Property `{0}` is a function — `validate` does not handle function values, so this property is silently not validated.',
|
|
525
|
+
detail: '`validate` works on JSON-shaped data; functions don\'t survive JSON, so\nthe emitter drops them. The rest of the object\'s behaviour is unaffected.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If you need a stricter checker that fails on\nmissing/extra function-typed members, watch the project roadmap.',
|
|
526
|
+
},
|
|
527
|
+
VL011: {
|
|
528
|
+
headline: "Method `{0}` is silently not validated by `validate` — methods aren't data.",
|
|
529
|
+
detail: "Class and object methods aren't part of the serialisable shape, so\n`validate` excludes them. The rest of the type still works.\n\nIf you wanted the method's return value validated/serialised, expose it\nas a data property instead.",
|
|
530
|
+
},
|
|
531
|
+
VL012: {
|
|
532
|
+
headline: "Static member `{0}` is silently not validated by `validate` — statics aren't part of instance data.",
|
|
533
|
+
detail: 'Class static members live on the class, not on individual instances.\n`validate` operates on instance shape, so statics are excluded.',
|
|
534
|
+
},
|
|
535
|
+
VL013: {
|
|
536
|
+
headline: "Symbol-keyed property `{0}` is silently not validated by `validate` — symbol keys aren't JSON-representable.",
|
|
537
|
+
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `validate` follows the same rule.\n\nFix — use a string key:\n - [Symbol.for('id')]: string;\n+ id: string;",
|
|
538
|
+
},
|
|
539
|
+
VL014: {
|
|
540
|
+
headline: "Union member(s) of type `{0}` can't be represented as data — `validate` drops them, so the union is validated as its remaining members.",
|
|
541
|
+
detail: 'A union projects to its serialisable members only: `DataOnly<Date | symbol>`\nis `Date`. The dropped member(s) ({0}) carry no JSON-shaped value (symbol,\nfunction, Promise, or a non-serialisable built-in like `Map` / `Set` /\ntyped arrays), so `validate` validated only the members that remain.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md. If EVERY member of the union is non-serialisable the\nprojection is `never`, and `validate` throws at build time instead.',
|
|
542
|
+
},
|
|
543
|
+
VL015: {
|
|
544
|
+
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in) — `validate` drops it, so this property is silently not validated.',
|
|
545
|
+
detail: '`validate` works on JSON-shaped data. A property whose value is a symbol,\na Promise, or a non-serialisable built-in (typed array, ArrayBuffer, …) carries\nno JSON-shaped value, so it is dropped: `DataOnly<{ {0}: symbol }>` is `{}`.\nThe rest of the object\'s behaviour is unaffected.\n\nNote the difference from a property that is only STRUCTURALLY unserialisable —\n`{0}: symbol[]` or `{0}: Map<string, symbol>` — which CANNOT be safely\ndropped (DataOnly keeps it as `never[]`): there `validate` throws at build\ntime instead.\n\nThis is by design — see the "validate contract — serializable data only"\nsection in CLAUDE.md.',
|
|
546
|
+
},
|
|
547
|
+
VL021: {
|
|
548
|
+
headline: '`validate` on `any` / `unknown` always returns true — the validator accepts every value.',
|
|
549
|
+
detail: '`any` and `unknown` describe "anything", so a structural validator has\nnothing to check. The resulting function passes for every input —\nincluding the ones you probably wanted to reject.\n\nFix — narrow the type to the actual shape you expect:\n - const isUser = createValidate<unknown>();\n+ const isUser = createValidate<User>();',
|
|
550
|
+
},
|
|
551
|
+
};
|
|
552
|
+
//# sourceMappingURL=diagnosticCatalog.generated.js.map
|