@ts-runtypes/devtools 0.10.0 → 0.12.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/README.md +25 -66
- package/dist/eslint/diagnosticRouting.d.ts +1 -1
- package/dist/eslint/diagnosticRouting.d.ts.map +1 -1
- package/dist/eslint/diagnosticRouting.js +10 -1
- package/dist/eslint/diagnosticRouting.js.map +1 -1
- package/dist/eslint/index.d.ts.map +1 -1
- package/dist/eslint/index.js +23 -3
- package/dist/eslint/index.js.map +1 -1
- package/dist/eslint/lint-worker.js +29 -35
- package/dist/eslint/lint-worker.js.map +1 -1
- package/dist/eslint/prefilter.d.ts +8 -2
- package/dist/eslint/prefilter.d.ts.map +1 -1
- package/dist/eslint/prefilter.js +8 -5
- package/dist/eslint/prefilter.js.map +1 -1
- package/dist/eslint/session-protocol.d.ts +13 -0
- package/dist/eslint/session-protocol.d.ts.map +1 -1
- package/dist/eslint/session-protocol.js +2 -0
- package/dist/eslint/session-protocol.js.map +1 -1
- package/dist/eslint/session.d.ts.map +1 -1
- package/dist/eslint/session.js +7 -1
- package/dist/eslint/session.js.map +1 -1
- package/dist/go-generated/diagnosticCatalog.generated.d.ts.map +1 -1
- package/dist/go-generated/diagnosticCatalog.generated.js +317 -262
- package/dist/go-generated/diagnosticCatalog.generated.js.map +1 -1
- package/dist/go-generated/runtypes-constants.generated.d.ts +8 -0
- package/dist/go-generated/runtypes-constants.generated.d.ts.map +1 -1
- package/dist/go-generated/runtypes-constants.generated.js +4 -0
- package/dist/go-generated/runtypes-constants.generated.js.map +1 -1
- package/dist/go-generated/tsconfig-plugin-keys.generated.d.ts +3 -0
- package/dist/go-generated/tsconfig-plugin-keys.generated.d.ts.map +1 -0
- package/dist/go-generated/tsconfig-plugin-keys.generated.js +20 -0
- package/dist/go-generated/tsconfig-plugin-keys.generated.js.map +1 -0
- package/dist/packages/ts-runtypes-devtools/tsconfig.test.tsbuildinfo +1 -1
- package/dist/plugin-option-keys.d.ts +3 -0
- package/dist/plugin-option-keys.d.ts.map +1 -0
- package/dist/plugin-option-keys.js +27 -0
- package/dist/plugin-option-keys.js.map +1 -0
- package/dist/protocol.d.ts +8 -9
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js.map +1 -1
- package/dist/resolver-client.d.ts +51 -21
- package/dist/resolver-client.d.ts.map +1 -1
- package/dist/resolver-client.js +164 -69
- package/dist/resolver-client.js.map +1 -1
- package/dist/unplugin.d.ts +25 -2
- package/dist/unplugin.d.ts.map +1 -1
- package/dist/unplugin.js +150 -19
- package/dist/unplugin.js.map +1 -1
- package/oxlint-recommended.json +1 -0
- package/package.json +3 -3
|
@@ -1,340 +1,395 @@
|
|
|
1
1
|
export const DIAGNOSTIC_CATALOG = {
|
|
2
2
|
CES001: {
|
|
3
|
-
headline: '`cloneExactShape` does not support unions with object members
|
|
3
|
+
headline: '`cloneExactShape` does not support unions with object members: the emitter cannot know which declared shape to rebuild at runtime.',
|
|
4
4
|
severity: 'error',
|
|
5
|
-
detail: 'A clone built from the declared shape needs to know WHICH union arm the\nruntime value matches; v1 has no arm discrimination, and silently keeping\nunknown keys would defeat the strip guarantee, so the build fails instead.\n\nWorkarounds: narrow the value to one arm before cloning (one\n`
|
|
5
|
+
detail: 'A clone built from the declared shape needs to know WHICH union arm the\nruntime value matches; v1 has no arm discrimination, and silently keeping\nunknown keys would defeat the strip guarantee, so the build fails instead.\n\nWorkarounds: narrow the value to one arm before cloning (one\n`createCloneExactShapeFn<Arm>()` per arm), or restructure the union into a\nsingle object with optional properties.',
|
|
6
6
|
},
|
|
7
7
|
CES003: {
|
|
8
8
|
headline: '`cloneExactShape` cannot clone a function-typed value.',
|
|
9
9
|
severity: 'error',
|
|
10
|
-
detail: "Functions aren't data
|
|
10
|
+
detail: "Functions aren't data: there is no declared shape to rebuild. Function-typed\nPROPERTIES are dropped from the clone (CES010/CES011); a function at the root\nor a propagating position fails the build.",
|
|
11
11
|
},
|
|
12
12
|
CES010: {
|
|
13
|
-
headline: 'Property `{0}` is a function
|
|
13
|
+
headline: 'Property `{0}` is a function: `cloneExactShape` cannot rebuild it, so it is kept on the clone, SHARED BY REFERENCE.',
|
|
14
14
|
severity: 'warning',
|
|
15
|
-
detail: "Declared members are never dropped (only UNDECLARED keys are
|
|
15
|
+
detail: "Declared members are never dropped (only UNDECLARED keys are; that is the\nstrip guarantee). Functions cannot be rebuilt from a declared shape, so the\nclone's property points at the SAME function as the input's. Class METHODS\ndiffer: they ride the shared prototype and are not copied as own props\n(CES011).",
|
|
16
16
|
},
|
|
17
17
|
CES011: {
|
|
18
|
-
headline: "Method `{0}` is not copied onto the clone's own properties
|
|
18
|
+
headline: "Method `{0}` is not copied onto the clone's own properties: methods ride the prototype.",
|
|
19
19
|
severity: 'warning',
|
|
20
20
|
detail: 'For a plain class instance the clone preserves the PROTOTYPE\n(`Object.create(Object.getPrototypeOf(v))`), so methods keep working via the\nprototype chain; they are simply not copied as own properties. For object\nliterals a method-typed member is omitted like any function value.',
|
|
21
21
|
},
|
|
22
22
|
CES012: {
|
|
23
|
-
headline: 'Static member `{0}` is not part of instance data
|
|
23
|
+
headline: 'Static member `{0}` is not part of instance data: `cloneExactShape` skips it.',
|
|
24
24
|
severity: 'warning',
|
|
25
25
|
detail: 'Statics live on the class, not the instance; the clone rebuilds instance\ndata only.',
|
|
26
26
|
},
|
|
27
27
|
CES015: {
|
|
28
|
-
headline: 'Property `{0}` has a value type `cloneExactShape` cannot rebuild (symbol, Promise, or a non-serialisable built-in)
|
|
28
|
+
headline: 'Property `{0}` has a value type `cloneExactShape` cannot rebuild (symbol, Promise, or a non-serialisable built-in): it is kept on the clone, SHARED BY REFERENCE.',
|
|
29
29
|
severity: 'warning',
|
|
30
|
-
detail: "Declared members are never dropped (only UNDECLARED keys are
|
|
30
|
+
detail: "Declared members are never dropped (only UNDECLARED keys are; that is the\nstrip guarantee). A value the emitter cannot rebuild passes through by\nreference instead: the clone's property points at the SAME handle as the\ninput's, so mutations through it are visible on both sides. Register\n`overrideCloneExactShape<T>()` if this type needs custom copying.",
|
|
31
|
+
},
|
|
32
|
+
CFG001: {
|
|
33
|
+
headline: 'Project tsconfig failed to load ({0}): the build, the linter, and the CLI all read this config, so nothing can run until it loads.',
|
|
34
|
+
severity: 'error',
|
|
35
|
+
detail: 'RunTypes derives every type query from your project tsconfig, the same\nfile your build uses. A tsconfig that was named (or found next to your\nproject) but is missing or does not parse stops the operation, exactly\nlike `tsc --project` would, instead of silently falling back to defaults\nthat could resolve your types differently.\n\nFix: repair the tsconfig (the message names the first parse problem),\nor point the tooling at the right file (the plugin/lint `tsconfig`\nsetting, or the CLI `--tsconfig` flag).',
|
|
31
36
|
},
|
|
32
37
|
CLS001: {
|
|
33
38
|
headline: 'class `{0}` is serialized structurally; register it via `registerClassSerializer({0}, { deserialize })` to round-trip a real instance.',
|
|
34
39
|
severity: 'warning',
|
|
35
|
-
detail: "By default a user class is serialized by its declared properties and\ndecoded back to a prototype-less plain object
|
|
40
|
+
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.",
|
|
36
41
|
},
|
|
37
42
|
CTA001: {
|
|
38
43
|
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).',
|
|
39
44
|
severity: 'error',
|
|
40
|
-
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
|
|
45
|
+
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 = createValidateFn<User>(undefined, opts);\n+ const isUser = createValidateFn<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 = createValidateFn<User>(undefined, opts);",
|
|
41
46
|
},
|
|
42
47
|
CTA002: {
|
|
43
|
-
headline: '`CompTimeArgs<T>` literal nesting exceeds the depth cap (16)
|
|
48
|
+
headline: '`CompTimeArgs<T>` literal nesting exceeds the depth cap (16), refactor to flatten.',
|
|
44
49
|
severity: 'error',
|
|
45
|
-
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
|
|
50
|
+
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.',
|
|
46
51
|
},
|
|
47
52
|
CTA003: {
|
|
48
53
|
headline: '`CompTimeArgs<T>` literal contains a forbidden construct ({0}). Only literals and nested literals are allowed.',
|
|
49
54
|
severity: 'error',
|
|
50
|
-
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
|
|
55
|
+
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",
|
|
51
56
|
},
|
|
52
57
|
CTA004: {
|
|
53
|
-
headline: '`CompTimeArgs<T>` value comes from a `const` with a widened (non-literal) member ({0})
|
|
58
|
+
headline: '`CompTimeArgs<T>` value comes from a `const` with a widened (non-literal) member ({0}); declare the const `as const`.',
|
|
54
59
|
severity: 'error',
|
|
55
|
-
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
|
|
60
|
+
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 createJsonEncoderFn(undefined, preset);",
|
|
56
61
|
},
|
|
57
62
|
FB001: {
|
|
58
|
-
headline: 'Type `{0}` can never be deserialised from binary
|
|
63
|
+
headline: 'Type `{0}` can never be deserialised from binary: the generated function will always fail.',
|
|
59
64
|
severity: 'error',
|
|
60
|
-
detail: "`never` is the empty type
|
|
65
|
+
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 }",
|
|
61
66
|
},
|
|
62
67
|
FB002: {
|
|
63
|
-
headline: 'Type `{0}` can never be deserialised from binary
|
|
68
|
+
headline: 'Type `{0}` can never be deserialised from binary: the generated function will always fail.',
|
|
64
69
|
severity: 'error',
|
|
65
|
-
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
|
|
70
|
+
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 }",
|
|
66
71
|
},
|
|
67
72
|
FB003: {
|
|
68
|
-
headline: 'Type `{0}` can never be deserialised from binary
|
|
73
|
+
headline: 'Type `{0}` can never be deserialised from binary: the generated function will always fail.',
|
|
69
74
|
severity: 'error',
|
|
70
|
-
detail: "Functions have no value form to serialise
|
|
75
|
+
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 }",
|
|
71
76
|
},
|
|
72
77
|
FB004: {
|
|
73
|
-
headline: 'Type `{0}` can never be deserialised from binary
|
|
78
|
+
headline: 'Type `{0}` can never be deserialised from binary: the generated function will always fail.',
|
|
74
79
|
severity: 'error',
|
|
75
|
-
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded
|
|
80
|
+
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[];",
|
|
76
81
|
},
|
|
77
82
|
FB005: {
|
|
78
|
-
headline: 'Type `{0}` can never be deserialised from binary
|
|
83
|
+
headline: 'Type `{0}` can never be deserialised from binary: the generated function will always fail.',
|
|
79
84
|
severity: 'error',
|
|
80
|
-
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
|
|
85
|
+
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 }",
|
|
81
86
|
},
|
|
82
87
|
FB006: {
|
|
83
|
-
headline: 'Type `{0}` can never be deserialised from binary
|
|
88
|
+
headline: 'Type `{0}` can never be deserialised from binary: the generated function will always fail.',
|
|
84
89
|
severity: 'error',
|
|
85
|
-
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
|
|
90
|
+
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';",
|
|
86
91
|
},
|
|
87
92
|
FB010: {
|
|
88
|
-
headline: 'Property `{0}` is a function
|
|
93
|
+
headline: 'Property `{0}` is a function: `fromBinary` does not handle function values, so this property is silently not deserialised.',
|
|
89
94
|
severity: 'warning',
|
|
90
|
-
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
|
|
95
|
+
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 "one 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.',
|
|
91
96
|
},
|
|
92
97
|
FB011: {
|
|
93
|
-
headline: "Method `{0}` is silently not deserialised by `fromBinary
|
|
98
|
+
headline: "Method `{0}` is silently not deserialised by `fromBinary`: methods aren't data.",
|
|
94
99
|
severity: 'warning',
|
|
95
100
|
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.",
|
|
96
101
|
},
|
|
97
102
|
FB012: {
|
|
98
|
-
headline: "Static member `{0}` is silently not deserialised by `fromBinary
|
|
103
|
+
headline: "Static member `{0}` is silently not deserialised by `fromBinary`: statics aren't part of instance data.",
|
|
99
104
|
severity: 'warning',
|
|
100
105
|
detail: 'Class static members live on the class, not on individual instances.\n`fromBinary` operates on instance shape, so statics are excluded.',
|
|
101
106
|
},
|
|
102
107
|
FB013: {
|
|
103
|
-
headline: "Symbol-keyed property `{0}` is silently not deserialised by `fromBinary
|
|
108
|
+
headline: "Symbol-keyed property `{0}` is silently not deserialised by `fromBinary`: symbol keys aren't JSON-representable.",
|
|
104
109
|
severity: 'warning',
|
|
105
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `fromBinary` follows the same rule.\n\nFix
|
|
110
|
+
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;",
|
|
106
111
|
},
|
|
107
112
|
FB014: {
|
|
108
|
-
headline: "Union member(s) of type `{0}` can't be represented as data
|
|
113
|
+
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.",
|
|
109
114
|
severity: 'warning',
|
|
110
|
-
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
|
|
115
|
+
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 "one 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.',
|
|
111
116
|
},
|
|
112
117
|
FB015: {
|
|
113
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
118
|
+
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.',
|
|
114
119
|
severity: 'warning',
|
|
115
|
-
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
|
|
120
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
116
121
|
},
|
|
117
122
|
FMT001: {
|
|
118
|
-
headline: 'TypeFormat mockSample "{0}" does not match its pattern /{1}
|
|
123
|
+
headline: 'TypeFormat mockSample "{0}" does not match its pattern /{1}/; fix the sample or the pattern.',
|
|
119
124
|
severity: 'error',
|
|
120
125
|
},
|
|
121
126
|
FMT002: {
|
|
122
|
-
headline: 'Invalid type-format params
|
|
127
|
+
headline: 'Invalid type-format params: {0}',
|
|
123
128
|
severity: 'error',
|
|
124
129
|
},
|
|
125
130
|
FMT003: {
|
|
126
|
-
headline: 'TypeFormat mockSample violates a sibling constraint
|
|
131
|
+
headline: 'TypeFormat mockSample violates a sibling constraint: {0}',
|
|
127
132
|
severity: 'error',
|
|
128
|
-
detail: "A mockSample is meant to be a canonical VALID value for the format, so it\nmust satisfy the format's own statically checkable siblings (length /\nminLength / maxLength, and the plain-string allowedChars / disallowedChars /\ndisallowedValues ops). A sample that its siblings reject means\n`
|
|
133
|
+
detail: "A mockSample is meant to be a canonical VALID value for the format, so it\nmust satisfy the format's own statically checkable siblings (length /\nminLength / maxLength, and the plain-string allowedChars / disallowedChars /\ndisallowedValues ops). A sample that its siblings reject means\n`createMockDataFn` would either produce an invalid value or filter every\nsample out and throw at mock time.\n\nLengths are counted in UTF-16 code units, exactly as the emitted validator's\n`.length` check counts them.\n\nFix: adjust the offending sample(s), or relax the constraint:\n - String<{minLength: 5; pattern: {source: '^b+$'; mockSamples: ['b', 'bb']}}>\n+ String<{minLength: 1; pattern: {source: '^b+$'; mockSamples: ['b', 'bb']}}>",
|
|
129
134
|
},
|
|
130
135
|
FMT004: {
|
|
131
|
-
headline:
|
|
136
|
+
headline: 'TypeFormat pattern /{0}/ cannot be checked: {1}; pattern validation requires a JavaScript runtime; install one or pass --js-runtime.',
|
|
137
|
+
severity: 'error',
|
|
138
|
+
detail: "Pattern checks (does the regex compile, do the mockSamples match it) run on\na real JS engine (the same `new RegExp` the emitted validator uses at\nruntime), driven by the resolver as a small sidecar under a JavaScript\nruntime. No runtime could be started, so the pattern is unverifiable and\nthe build fails closed rather than ship samples it can't verify.\n\nFix: install node or bun (both are found automatically on PATH), or point\nthe --js-runtime flag or the RT_JS_RUNTIME environment variable at any\nother runtime that can run the bundled checker (deno and most\nnode-compatible runtimes work). Projects with no patterns never need this.",
|
|
139
|
+
},
|
|
140
|
+
FMT005: {
|
|
141
|
+
headline: 'Cannot auto-generate mockSamples for pattern /{0}/: {1}; declare mockSamples explicitly.',
|
|
142
|
+
severity: 'error',
|
|
143
|
+
detail: "A pattern with no declared mockSamples gets them generated at build time:\nthe JS engine draws candidate strings from the regex (patternSampleCount of\nthem, a fresh pool per build, or a reproducible one when a literal\n{mock: {seed}} rides a createMockDataFn call site) and keeps the ones the\nreal compiled pattern and the declared length bounds accept. This one\nproduced nothing: generation is disabled (patternSampleCount 0), the\ngenerator cannot handle a construct in the pattern (lookarounds are the\nusual case), or every draw in the retry budget (patternSampleCount ×\npatternSampleRetries) failed the pattern's own constraints.\n\nFix: declare the samples yourself; they are validated against the pattern\nat build time, so they stay trustworthy:\n- String<{pattern: {source: '(?<=x)y'}}>\n+ String<{pattern: {source: '(?<=x)y'; mockSamples: ['xy']}}>\n\nOr, if generation was disabled on purpose, re-enable it by raising\npatternSampleCount above 0 (and patternSampleRetries if the pattern is\nheavily constrained).",
|
|
144
|
+
},
|
|
145
|
+
FMT006: {
|
|
146
|
+
headline: 'Two sites share one cache entry for format `{0}` but declare different mockSamples: `{1}` here vs `{2}` at {3}. Make the pools identical, or declare one and leave the other out.',
|
|
132
147
|
severity: 'error',
|
|
133
|
-
detail: "
|
|
148
|
+
detail: "mockSamples describe how to GENERATE a sample value; they are not part of\nwhat the format validates. So two formats identical apart from their pools\nare the same validator, and they intern as ONE cache entry. That dedup is\ndeliberate, and it is why the samples are excluded from the structural id.\n\nThe catch is that one entry can only carry one pool. When both sites declare\none and the pools differ, the entry keeps whichever it saw first, so which\npool survives depends on scan order, and adding or reordering unrelated\ncode elsewhere can flip it. Rather than pick silently, the build stops here.\n\nFix: declare the same pool at both sites:\n- type A = String<{maxLength: 5; mockSamples: ['aaa']}>;\n- type B = String<{maxLength: 5; mockSamples: ['bbb']}>;\n+ type A = String<{maxLength: 5; mockSamples: ['aaa']}>;\n+ type B = String<{maxLength: 5; mockSamples: ['aaa']}>;\n\nFix: or declare it once and leave the other alone; a site that declares\nnothing is not an opinion, so the declared pool is adopted for the shared\nentry:\n type A = String<{maxLength: 5; mockSamples: ['aaa']}>;\n type B = String<{maxLength: 5}>;\n\nIf the two really are different types, give them something the id DOES\nfold (a distinct pattern, bound, or brand) so they stop sharing an entry.",
|
|
134
149
|
},
|
|
135
150
|
FT002: {
|
|
136
|
-
headline: 'Unknown field `{0}
|
|
151
|
+
headline: 'Unknown field `{0}`: the type does not declare it, so this FriendlyText entry is dead.',
|
|
137
152
|
severity: 'error',
|
|
138
|
-
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
|
|
153
|
+
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 enrich <source.ts> <Type> --update",
|
|
139
154
|
},
|
|
140
155
|
FT003: {
|
|
141
|
-
headline: 'Error key `{0}` is not a declared constraint of this field
|
|
156
|
+
headline: 'Error key `{0}` is not a declared constraint of this field: the message can never fire.',
|
|
142
157
|
severity: 'warning',
|
|
143
|
-
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
|
|
158
|
+
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.",
|
|
144
159
|
},
|
|
145
160
|
FT005: {
|
|
146
|
-
headline: 'Unknown placeholder `$[{0}]
|
|
161
|
+
headline: 'Unknown placeholder `$[{0}]`: expected one of `$[label]`, `$[val]`, `$[path]`, `$[index]`.',
|
|
147
162
|
severity: 'warning',
|
|
148
|
-
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
|
|
163
|
+
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.",
|
|
149
164
|
},
|
|
150
165
|
FT006: {
|
|
151
|
-
headline: 'Plural error template is missing the mandatory `other` arm
|
|
166
|
+
headline: 'Plural error template is missing the mandatory `other` arm: the render has no backstop.',
|
|
152
167
|
severity: 'error',
|
|
153
|
-
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
|
|
168
|
+
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.",
|
|
154
169
|
},
|
|
155
170
|
FT007: {
|
|
156
|
-
headline: 'Unknown plural arm `{0}
|
|
171
|
+
headline: 'Unknown plural arm `{0}`: CLDR categories are `zero`, `one`, `two`, `few`, `many`, `other`.',
|
|
157
172
|
severity: 'warning',
|
|
158
|
-
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
|
|
173
|
+
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.",
|
|
159
174
|
},
|
|
160
175
|
FT008: {
|
|
161
|
-
headline: 'Constraint `{0}` carries no count
|
|
176
|
+
headline: 'Constraint `{0}` carries no count: a plural template here has dead arms; use a plain string.',
|
|
162
177
|
severity: 'warning',
|
|
163
|
-
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
|
|
178
|
+
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.",
|
|
164
179
|
},
|
|
165
180
|
FT009: {
|
|
166
|
-
headline: '`rt$default` is mutually exclusive with per-constraint messages
|
|
181
|
+
headline: '`rt$default` is mutually exclusive with per-constraint messages; use one mode or the other.',
|
|
167
182
|
severity: 'error',
|
|
168
|
-
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
|
|
183
|
+
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`.",
|
|
169
184
|
},
|
|
170
185
|
FT011: {
|
|
171
|
-
headline: 'Property `{0}` collides with the reserved `rt$` enrichment prefix
|
|
186
|
+
headline: 'Property `{0}` collides with the reserved `rt$` enrichment prefix: the type cannot be enriched.',
|
|
172
187
|
severity: 'error',
|
|
173
|
-
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
|
|
188
|
+
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 }',
|
|
174
189
|
},
|
|
175
190
|
FT020: {
|
|
176
|
-
headline: 'Unfilled `@todo` placeholder
|
|
191
|
+
headline: 'Unfilled `@todo` placeholder; fill in the real labels/messages, then delete the `@todo` line.',
|
|
177
192
|
severity: 'error',
|
|
178
|
-
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
|
|
193
|
+
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).",
|
|
179
194
|
},
|
|
180
195
|
FT021: {
|
|
181
|
-
headline: 'Stale `@rtOrphan` carcass
|
|
196
|
+
headline: 'Stale `@rtOrphan` carcass; run `ts-runtypes enrich --prune` to remove it (or restore the type).',
|
|
182
197
|
severity: 'error',
|
|
183
|
-
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
|
|
198
|
+
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 enrich --prune\n\nFix: if the type was renamed, re-run the reconcile; a matching carcass\nis restored with your values intact:\n ts-runtypes enrich <source.ts> <NewName> --update',
|
|
184
199
|
},
|
|
185
200
|
FT022: {
|
|
186
|
-
headline: 'Stale `@rtOrphanChild` field carcass
|
|
201
|
+
headline: 'Stale `@rtOrphanChild` field carcass; run `ts-runtypes enrich --prune` to remove it (or restore the field).',
|
|
187
202
|
severity: 'error',
|
|
188
|
-
detail: "The reconcile commented this field out because the source type no longer\ndeclares it. The carcass preserves your authored value inline
|
|
203
|
+
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 enrich --prune`.\nFix: if the field was renamed, re-run `--update`; the authored value\nmoves to the renamed field when the ids match.",
|
|
204
|
+
},
|
|
205
|
+
FT023: {
|
|
206
|
+
headline: 'Unfilled blank value: a scaffolded label or message is still empty; fill in the real text.',
|
|
207
|
+
severity: 'error',
|
|
208
|
+
detail: "An empty string (`''`) at a `rt$label` / `rt$errors` slot is a generated\nblank that never got authored: it ships blank to the UI wherever the\nfriendly text is shown, so it is exactly as incomplete as a `@todo`\nmarker. This is why removing the `@todo` line without filling the values\nis not \"done\".\n\nExample:\n export const friendlyUser: FriendlyText<User> = {\n- name: {rt$label: ''},\n+ name: {rt$label: 'Name'},\n };\n\nFix: author the real label / message. Only the completeness gate\n(`ts-runtypes enrich --require-complete`) fails on it; a plain\n`--no-emit` health check reports it without failing.",
|
|
189
209
|
},
|
|
190
210
|
GE000: {
|
|
191
211
|
headline: 'Cannot read enrichment mirror file: {0}',
|
|
192
212
|
severity: 'error',
|
|
193
|
-
detail: 'The drift check could not read this mirror file (permissions, a broken\nsymlink, or a race with a concurrent write).\n\nFix
|
|
213
|
+
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 enrich --no-emit`.',
|
|
194
214
|
},
|
|
195
215
|
GE001: {
|
|
196
|
-
headline: 'Mirror location drift
|
|
216
|
+
headline: 'Mirror location drift: the source maps to `{0}` but this file lives at `{1}`; re-run `ts-runtypes enrich` to relocate.',
|
|
197
217
|
severity: 'warning',
|
|
198
|
-
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
|
|
218
|
+
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,\na genDir 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 enrich <source.ts> <Type> --update',
|
|
199
219
|
},
|
|
200
220
|
GE002: {
|
|
201
|
-
headline: 'Breadcrumb source `{0}` no longer exists ({1})
|
|
221
|
+
headline: 'Breadcrumb source `{0}` no longer exists ({1}): the mirror is orphaned; delete it or re-run `ts-runtypes enrich`.',
|
|
202
222
|
severity: 'error',
|
|
203
|
-
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
|
|
223
|
+
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.",
|
|
204
224
|
},
|
|
205
225
|
GE003: {
|
|
206
|
-
headline: 'Source {0} no longer declares type `{1}
|
|
226
|
+
headline: 'Source {0} no longer declares type `{1}`; re-run `ts-runtypes enrich`.',
|
|
207
227
|
severity: 'error',
|
|
208
|
-
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
|
|
228
|
+
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 enrich <source.ts> <Type> --update\n ts-runtypes enrich --prune',
|
|
209
229
|
},
|
|
210
230
|
HUK010: {
|
|
211
|
-
headline: 'Property `{0}` is a function
|
|
231
|
+
headline: 'Property `{0}` is a function: `hasUnknownKeys` does not handle function values, so this property is silently not checked.',
|
|
212
232
|
severity: 'warning',
|
|
213
|
-
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
|
|
233
|
+
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 "one 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.',
|
|
214
234
|
},
|
|
215
235
|
JCP001: {
|
|
216
|
-
headline: 'Internal error: JSON composite `{0}` references primitive entry `{1}` (type `{2}`) which was never rendered
|
|
236
|
+
headline: 'Internal error: JSON composite `{0}` references primitive entry `{1}` (type `{2}`) which was never rendered; please file an issue.',
|
|
217
237
|
severity: 'error',
|
|
218
238
|
},
|
|
219
239
|
MD001: {
|
|
220
|
-
headline: 'Unknown field `{0}
|
|
240
|
+
headline: 'Unknown field `{0}`: the type does not declare it, so this MockData entry is dead.',
|
|
221
241
|
severity: 'error',
|
|
222
|
-
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
|
|
242
|
+
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 enrich <source.ts> <Type> --update",
|
|
223
243
|
},
|
|
224
244
|
MD011: {
|
|
225
|
-
headline: 'Property `{0}` collides with the reserved `rt$` enrichment prefix
|
|
245
|
+
headline: 'Property `{0}` collides with the reserved `rt$` enrichment prefix: the type cannot be enriched.',
|
|
226
246
|
severity: 'error',
|
|
227
|
-
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
|
|
247
|
+
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 }',
|
|
228
248
|
},
|
|
229
249
|
MD020: {
|
|
230
|
-
headline: 'Unfilled `@todo` placeholder
|
|
250
|
+
headline: 'Unfilled `@todo` placeholder; fill in the real sample pools/ranges, then delete the `@todo` line.',
|
|
231
251
|
severity: 'error',
|
|
232
|
-
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
|
|
252
|
+
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).",
|
|
233
253
|
},
|
|
234
254
|
MD021: {
|
|
235
|
-
headline: 'Stale `@rtOrphan` carcass
|
|
255
|
+
headline: 'Stale `@rtOrphan` carcass; run `ts-runtypes enrich --prune` to remove it (or restore the type).',
|
|
236
256
|
severity: 'error',
|
|
237
|
-
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
|
|
257
|
+
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 enrich --prune\n\nFix: if the type was renamed, re-run the reconcile; a matching carcass\nis restored with your values intact:\n ts-runtypes enrich <source.ts> <NewName> --update',
|
|
238
258
|
},
|
|
239
259
|
MD022: {
|
|
240
|
-
headline: 'Stale `@rtOrphanChild` field carcass
|
|
260
|
+
headline: 'Stale `@rtOrphanChild` field carcass; run `ts-runtypes enrich --prune` to remove it (or restore the field).',
|
|
241
261
|
severity: 'error',
|
|
242
|
-
detail: "The reconcile commented this field out because the source type no longer\ndeclares it. The carcass preserves your authored value inline
|
|
262
|
+
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 enrich --prune`.\nFix: if the field was renamed, re-run `--update`; the authored value\nmoves to the renamed field when the ids match.",
|
|
263
|
+
},
|
|
264
|
+
MD023: {
|
|
265
|
+
headline: 'Unfilled blank value: a scaffolded sample pool or range is still empty; fill in real data.',
|
|
266
|
+
severity: 'error',
|
|
267
|
+
detail: "An empty pool (`pool: []`) is a generated blank that never got authored:\nit mocks nothing, so it is exactly as incomplete as a `@todo` marker.\nThis is why removing the `@todo` line without filling the values is not\n\"done\".\n\nExample:\n export const mockUser: MockData<User> = {\n- name: {pool: []},\n+ name: {pool: ['Ada Lovelace', 'Linus Torvalds']},\n };\n\nFix: author realistic sample data. Only the completeness gate\n(`ts-runtypes enrich --require-complete`) fails on it; a plain\n`--no-emit` health check reports it without failing.",
|
|
243
268
|
},
|
|
244
269
|
MKR001: {
|
|
245
|
-
headline: '`{0}()` is being called at runtime just so the marker can read its return type
|
|
270
|
+
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.',
|
|
246
271
|
severity: 'warning',
|
|
247
|
-
detail: 'Reflect-form markers (`
|
|
272
|
+
detail: 'Reflect-form markers (`createValidateFn(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 = createValidateFn({0}());\n+ const isUser = createValidateFn<ReturnType<typeof {0}>>();\n\nFix: pass an existing value of the desired type:\n const existingUser: User = ...;\n const isUser = getRunTypeId(existingUser);',
|
|
248
273
|
},
|
|
249
274
|
MKR003: {
|
|
250
|
-
headline: 'Marker call is inside a generic function
|
|
275
|
+
headline: 'Marker call is inside a generic function: the type argument is unresolved, so no id can be computed at build time.',
|
|
251
276
|
severity: 'error',
|
|
252
|
-
detail: "The build can only compute an id for a concrete type (`User`,\n`{name: string}`, etc.). A type parameter like `T` is abstract
|
|
277
|
+
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 createValidateFn<User>()(value);\n }\n\nFix: accept a pre-computed id from the caller:\n function makeChecker<T>(id: InjectRunTypeId<T>) {\n return createValidateFn<T>(id);\n }\n const isUser = makeChecker<User>(getRunTypeId<User>());",
|
|
253
278
|
},
|
|
254
279
|
MKR004: {
|
|
255
|
-
headline: "`noLiterals: true` has no effect here
|
|
280
|
+
headline: "`noLiterals: true` has no effect here: the type argument doesn't resolve to literal values.",
|
|
256
281
|
severity: 'warning',
|
|
257
|
-
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
|
|
282
|
+
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 = createValidateFn<string>({noLiterals: true});\n+ const isRole = createValidateFn<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 = createValidateFn<'admin' | 'user'>({noLiterals: true});",
|
|
258
283
|
},
|
|
259
284
|
MKR005: {
|
|
260
|
-
headline: '`noIsArrayCheck: true` has no effect here
|
|
285
|
+
headline: '`noIsArrayCheck: true` has no effect here: the type argument is not an array type.',
|
|
261
286
|
severity: 'warning',
|
|
262
|
-
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
|
|
287
|
+
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 = createValidateFn<User>({noIsArrayCheck: true});\n+ const isUser = createValidateFn<User>();\n\nOr point it at the array type you meant:\n const isUsers = createValidateFn<User[]>({noIsArrayCheck: true});",
|
|
263
288
|
},
|
|
264
289
|
MKR006: {
|
|
265
|
-
headline: '`InjectTypeFnArgs` names the function family `{0}` more than once
|
|
290
|
+
headline: '`InjectTypeFnArgs` names the function family `{0}` more than once; remove the duplicate key.',
|
|
266
291
|
severity: 'error',
|
|
267
|
-
detail: "An `InjectTypeFnArgs<T, …>` marker names each function family it needs for\n`T` once, in declaration order; the build injects one entry-module tuple\nper name and the wrapper forwards each to its factory. Naming a family\ntwice would inject a redundant identical tuple with no consumer, so it is\nalmost always a copy-paste slip and the build stops.\n\nFix
|
|
292
|
+
detail: "An `InjectTypeFnArgs<T, …>` marker names each function family it needs for\n`T` once, in declaration order; the build injects one entry-module tuple\nper name and the wrapper forwards each to its factory. Naming a family\ntwice would inject a redundant identical tuple with no consumer, so it is\nalmost always a copy-paste slip and the build stops.\n\nFix: name each family at most once:\n- id?: InjectTypeFnArgs<T, 'verr', 'jsonDecoder', 'verr'>;\n+ id?: InjectTypeFnArgs<T, 'verr', 'jsonDecoder', 'jsonEncoder'>;",
|
|
268
293
|
},
|
|
269
294
|
MKR007: {
|
|
270
|
-
headline: 'Marker type resolved to `any` because this file has an unresolved import (`{0}`)
|
|
295
|
+
headline: 'Marker type resolved to `any` because this file has an unresolved import (`{0}`): the generated functions would silently accept anything.',
|
|
296
|
+
severity: 'error',
|
|
297
|
+
detail: "TypeScript could not resolve the import, so the type it should have\nprovided checked as `any` at this marker call. A validator over `any` is\nthe always-true identity, a mock over `any` is `undefined`, and encoders\npass values through untouched, with no runtime signal that anything is\nwrong. This usually means the build tool and the type scanner resolve\nmodules differently (e.g. an extensionless relative import under\n`moduleResolution: NodeNext`, a missing dependency, or a `paths` alias the\nscan tsconfig doesn't declare).\n\nFix: make the import resolve for the type scanner:\n- import {User} from './user.runtype';\n+ import {User} from './user.runtype.ts';\n\nOr align the tsconfig the plugin scans with the one your bundler uses.\nIf the `any` is genuinely intentional, write the marker over an alias\ndeclared in resolving code (e.g. `type Loose = any`) in a file with no\nfailing imports.",
|
|
298
|
+
},
|
|
299
|
+
MKR008: {
|
|
300
|
+
headline: 'This type is too deeply nested to reflect: computing its structural id hit the recursion depth cap, so the build stops here instead of crashing.',
|
|
301
|
+
severity: 'error',
|
|
302
|
+
detail: 'The build computes a structural id by walking the type, and the walk is\ncapped at a depth far beyond any realistic shape. Hitting the cap with no\nsingle recurring type on the path means literally written (or generated)\nnesting hundreds of levels deep.\n\nFix: reflect a concrete, bounded projection of the type (e.g. the element\nor data type you actually send), or restructure the recursion so the same\nnamed type recurs by reference (a plain recursive interface is fine).',
|
|
303
|
+
},
|
|
304
|
+
MKR009: {
|
|
305
|
+
headline: 'Type `{0}` re-instantiates itself with fresh type arguments at every level (a self-instantiating generic), so its structural id never resolves. Reflect a monomorphic shape instead.',
|
|
306
|
+
severity: 'error',
|
|
307
|
+
detail: "A generic method's own type parameters (the `U` in `map<U>(fn: (x: T) => U):\nIter<U>`) are bound at each CALL of the method, so they can never be resolved\nwhile reflecting the containing type, and when such a method returns a fresh\ninstantiation of its own container, the type graph grows a new level forever.\nRenaming the type parameters does not resolve them; the fix is a monomorphic\n(fully resolved) recursive shape, which closes by reference:\n\n- interface Iter<T> { map<U>(fn: (x: T) => U): Iter<U> }\n+ interface NumberIter { map(fn: (x: string) => number): NumberIter }\n\nOrdinary generics are unaffected: instantiated types (Map<string, User>, a\nconcrete Iter<string>'s data members) and generic methods that do not\nre-instantiate their container reflect fine. Validators also drop methods\nentirely (methods aren't data), so reflecting just the data shape usually\nsidesteps the problem.",
|
|
308
|
+
},
|
|
309
|
+
MKR010: {
|
|
310
|
+
headline: 'Type argument contains the unresolved type parameter `{0}`: a generic must be fully resolved at the marker call, so no id can be computed. See Related for where `{0}` is declared.',
|
|
311
|
+
severity: 'error',
|
|
312
|
+
detail: "The build can only compute an id for a fully concrete type. `{0}` is a type\nparameter of the surrounding generic: it takes a different type at each call\nsite, so a single build-time id would alias every instantiation onto one\n(wrong) shape. A parameter DEFAULT does not help here: defaults resolve where\na caller omits the argument, never inside the generic's own body.\n\nFix: resolve the generic before reflecting it:\n interface Box<T> { value: T }\n type BoxString = Box<string>;\n const isBoxString = createValidateFn<BoxString>(); // resolved, ok\n\nFix: or accept a pre-computed id from the caller and inline the marker at\neach concrete call site (same patterns as MKR003):\n function makeChecker<T>(id: InjectRunTypeId<T>) {\n return createValidateFn<T>(id);\n }\n const isBox = makeChecker<Box<string>>(getRunTypeId<Box<string>>());\n\nGeneric METHODS on a concrete type (`find<T>(query: string): T[]`) are\nunaffected: their own type parameters are bound per call of the method and\nmethods aren't data.",
|
|
313
|
+
},
|
|
314
|
+
MKR011: {
|
|
315
|
+
headline: 'Generic type `{0}` is used without its required type argument(s): parameter `{1}` has no default, so the type cannot resolve to an id. See Related for where `{1}` is declared.',
|
|
316
|
+
severity: 'error',
|
|
317
|
+
detail: "TypeScript itself rejects this usage (TS2314), but dev-server builds don't\nrun the type checker, so the scan reads the written type arguments and stops\nthe build here instead of silently reflecting `any` (a validator over `any`\naccepts everything).\n\nFix: pass the missing type argument:\n- const isA = createValidateFn<A>();\n+ const isA = createValidateFn<A<string>>();\n\nFix: or give the parameter a default, which the compiler resolves at every\nbare use site:\n- interface A<S extends string> { a: S }\n+ interface A<S extends string = string> { a: S }\n const isA = createValidateFn<A>(); // now resolves to A<string>",
|
|
318
|
+
},
|
|
319
|
+
MKR012: {
|
|
320
|
+
headline: '`{0}` here was declared by `{1}`, which this project does not trust as a marker package, so the type argument was dropped and this call reflects `unknown`.',
|
|
321
|
+
severity: 'warning',
|
|
322
|
+
detail: 'A marker only counts when it is BOTH named correctly and declared by a\ntrusted package, so a same-named type of your own never drives rewrites.\nThis one has the right name but comes from a package that is not on the\nlist, so its type argument was ignored: the call still compiles and still\ngenerates a function, but for `unknown` rather than for your type — a\nvalidator over `unknown` accepts everything.\n\nFix: trust the package in your tsconfig plugin entry:\n {\n "name": "ts-runtypes",\n+ "markers": {"packages": ["{1}"]}\n }\n\nThe list is additive, so `@ts-runtypes/core` keeps working alongside it.\nThe same setting exists on the bundler plugin (`markers`) and as the\n`--marker-packages` CLI flag.\n\nIf the package re-exports the markers rather than declaring its own\n(`export type {InjectRunTypeId} from \'@ts-runtypes/core\'`), no setting is\nneeded — a re-export keeps RunTypes as the declaring package, so check\nwhether the package meant to re-export instead.',
|
|
323
|
+
},
|
|
324
|
+
MKR013: {
|
|
325
|
+
headline: 'Marker type resolved to `any` that was never written: `{0}` failed to resolve (or its declaration references a name that does not), so the generated functions would silently accept anything.',
|
|
271
326
|
severity: 'error',
|
|
272
|
-
detail: "
|
|
327
|
+
detail: "The type checker keeps a distinct internal ERROR type for names it could\nnot resolve; it behaves like `any`, so without this guard the validator\nbecomes the always-true identity, the mock `undefined`, and encoders pass\nvalues through — with exit code 0 and no signal. A deliberately written\n`any`, and an alias like `type Loose = any`, are the real `any` and never\ntrip this.\n\nCommon causes and fixes:\n- A typo in the type name: fix the spelling.\n- A dependency whose types are not installed: install/declare them.\n- An ambient declaration (`declare interface ...` in a `.d.ts`) that is\n not part of the scanned program: make sure the `.d.ts` is matched by the\n tsconfig `include`/`files` set. The dev server and lint read that file\n list when they start, so after ADDING a new `.d.ts`, restart the dev\n server (or the editor's lint process) for it to be seen.",
|
|
273
328
|
},
|
|
274
329
|
NE001: {
|
|
275
|
-
headline: 'Property `{0}` is tagged @nonEnumerable but is required
|
|
330
|
+
headline: 'Property `{0}` is tagged @nonEnumerable but is required: the guard only applies to optional properties, so the tag has no effect. Make it optional (`{0}?`) or remove the tag.',
|
|
276
331
|
severity: 'error',
|
|
277
|
-
detail: "The runtime enumerability guard (which lets a value omit a property from\nthe wire when it isn't an enumerable own property) is applied ONLY to\noptional properties. That keeps the decoder's `DataOnly<T>` return type\nhonest: a guarded property is always one the type already allows to be\nabsent. A `@nonEnumerable` tag on a REQUIRED property is therefore ignored
|
|
332
|
+
detail: "The runtime enumerability guard (which lets a value omit a property from\nthe wire when it isn't an enumerable own property) is applied ONLY to\noptional properties. That keeps the decoder's `DataOnly<T>` return type\nhonest: a guarded property is always one the type already allows to be\nabsent. A `@nonEnumerable` tag on a REQUIRED property is therefore ignored;\nthe property still serializes unconditionally.\n\nFix: make the property optional:\n- /** @nonEnumerable */ token: string;\n+ /** @nonEnumerable */ token?: string;",
|
|
278
333
|
},
|
|
279
334
|
OVR001: {
|
|
280
|
-
headline: 'Duplicate override for `{0}
|
|
335
|
+
headline: 'Duplicate override for `{0}`: there can be exactly one override per (type, function).',
|
|
281
336
|
severity: 'error',
|
|
282
|
-
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
|
|
337
|
+
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));',
|
|
283
338
|
},
|
|
284
339
|
OVR002: {
|
|
285
|
-
headline: 'Override entry `{0}` references compiled function `{1}` which did not render
|
|
340
|
+
headline: 'Override entry `{0}` references compiled function `{1}` which did not render: this would throw at runtime, so the build stops.',
|
|
286
341
|
severity: 'error',
|
|
287
|
-
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
|
|
342
|
+
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.",
|
|
288
343
|
},
|
|
289
344
|
OVR010: {
|
|
290
345
|
headline: 'Overriding `validate` for this type also changes how JSON and binary decoders narrow unions containing it.',
|
|
291
346
|
severity: 'warning',
|
|
292
|
-
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`
|
|
347
|
+
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`createValidateFn<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};",
|
|
293
348
|
},
|
|
294
349
|
PFE9004: {
|
|
295
|
-
headline: 'Duplicate `registerPureFnFactory` for `{0}` with a different body
|
|
350
|
+
headline: 'Duplicate `registerPureFnFactory` for `{0}` with a different body; only one definition can win.',
|
|
296
351
|
severity: 'error',
|
|
297
|
-
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
|
|
352
|
+
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.',
|
|
298
353
|
},
|
|
299
354
|
PFE9005: {
|
|
300
|
-
headline: 'Pure-fn factory `{0}` uses destructured parameters
|
|
355
|
+
headline: 'Pure-fn factory `{0}` uses destructured parameters; only simple identifier params are supported.',
|
|
301
356
|
severity: 'error',
|
|
302
|
-
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
|
|
357
|
+
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+ });",
|
|
303
358
|
},
|
|
304
359
|
PFE9006: {
|
|
305
|
-
headline: "`this` is not allowed inside a `registerPureFnFactory` factory body
|
|
360
|
+
headline: "`this` is not allowed inside a `registerPureFnFactory` factory body; pure functions can't depend on a calling context.",
|
|
306
361
|
severity: 'error',
|
|
307
|
-
detail: "Pure functions are materialised standalone at build time; there's no\n`this` to bind to.\n\nFix
|
|
362
|
+
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 });",
|
|
308
363
|
},
|
|
309
364
|
PFE9007: {
|
|
310
365
|
headline: '`async`/`await` is not allowed inside a `registerPureFnFactory` factory body.',
|
|
311
366
|
severity: 'error',
|
|
312
|
-
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
|
|
367
|
+
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 });",
|
|
313
368
|
},
|
|
314
369
|
PFE9008: {
|
|
315
370
|
headline: '`yield` / generators are not allowed inside a `registerPureFnFactory` factory body.',
|
|
316
371
|
severity: 'error',
|
|
317
|
-
detail: "Generators carry resumption state that can't be materialised\nstatically.\n\nFix
|
|
372
|
+
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 });",
|
|
318
373
|
},
|
|
319
374
|
PFE9009: {
|
|
320
375
|
headline: '`import()` is not allowed inside a `registerPureFnFactory` factory body.',
|
|
321
376
|
severity: 'error',
|
|
322
|
-
detail: 'Dynamic imports load modules at runtime
|
|
377
|
+
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.',
|
|
323
378
|
},
|
|
324
379
|
PFE9010: {
|
|
325
380
|
headline: '`{0}` is not allowed inside a `registerPureFnFactory` factory body.',
|
|
326
381
|
severity: 'error',
|
|
327
|
-
detail: "Globals like `eval`, `Function`, `fetch`, `XMLHttpRequest`, `require`,\n`process`, `globalThis`, `window`, `document` are blocked from pure-fn\nbodies
|
|
382
|
+
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.",
|
|
328
383
|
},
|
|
329
384
|
PFE9011: {
|
|
330
|
-
headline: "`{0}` is captured from outer scope inside a `registerPureFnFactory` factory
|
|
385
|
+
headline: "`{0}` is captured from outer scope inside a `registerPureFnFactory` factory; pure functions can't reach outside their own body.",
|
|
331
386
|
severity: 'error',
|
|
332
|
-
detail: "The build inlines factory bodies without their lexical environment, so\nany free variable becomes `undefined` at runtime.\n\nFix
|
|
387
|
+
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.",
|
|
333
388
|
},
|
|
334
389
|
PFE9012: {
|
|
335
|
-
headline: "Pure-fn `{0}` is referenced by a RT function but never registered
|
|
390
|
+
headline: "Pure-fn `{0}` is referenced by a RT function but never registered; call `registerPureFnFactory('{1}::{2}', …)` first.",
|
|
336
391
|
severity: 'error',
|
|
337
|
-
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
|
|
392
|
+
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.",
|
|
338
393
|
},
|
|
339
394
|
PFE9013: {
|
|
340
395
|
headline: '`{0}.{1}` dependency argument must be a string literal or a same-scope `const` string.',
|
|
@@ -344,397 +399,397 @@ export const DIAGNOSTIC_CATALOG = {
|
|
|
344
399
|
PFN001: {
|
|
345
400
|
headline: '`PureFunction<F>` argument must be an INLINE arrow or function expression.',
|
|
346
401
|
severity: 'error',
|
|
347
|
-
detail: "The build extracts and AOT-compiles the function body, so it must see the\nliteral inline at the call site. A named reference
|
|
402
|
+
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');",
|
|
348
403
|
},
|
|
349
404
|
PFN002: {
|
|
350
|
-
headline: '`PureFunction<F>` literal must not be imported or exported
|
|
405
|
+
headline: '`PureFunction<F>` literal must not be imported or exported: the compiled copy must be the only one that can run.',
|
|
351
406
|
severity: 'error',
|
|
352
|
-
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
|
|
407
|
+
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",
|
|
353
408
|
},
|
|
354
409
|
PJ001: {
|
|
355
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
410
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
356
411
|
severity: 'error',
|
|
357
|
-
detail: "`never` is the empty type
|
|
412
|
+
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 }",
|
|
358
413
|
},
|
|
359
414
|
PJ002: {
|
|
360
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
415
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
361
416
|
severity: 'error',
|
|
362
|
-
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
|
|
417
|
+
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 }",
|
|
363
418
|
},
|
|
364
419
|
PJ003: {
|
|
365
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
420
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
366
421
|
severity: 'error',
|
|
367
|
-
detail: "Functions have no value form to serialise
|
|
422
|
+
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 }",
|
|
368
423
|
},
|
|
369
424
|
PJ004: {
|
|
370
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
425
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
371
426
|
severity: 'error',
|
|
372
|
-
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded
|
|
427
|
+
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[];",
|
|
373
428
|
},
|
|
374
429
|
PJ005: {
|
|
375
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
430
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
376
431
|
severity: 'error',
|
|
377
|
-
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
|
|
432
|
+
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';",
|
|
378
433
|
},
|
|
379
434
|
PJ010: {
|
|
380
|
-
headline: 'Property `{0}` is a function
|
|
435
|
+
headline: 'Property `{0}` is a function: `prepareForJson` does not handle function values, so this property is silently not encoded.',
|
|
381
436
|
severity: 'warning',
|
|
382
|
-
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
|
|
437
|
+
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 "one 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.',
|
|
383
438
|
},
|
|
384
439
|
PJ011: {
|
|
385
|
-
headline: "Method `{0}` is silently not encoded by `prepareForJson
|
|
440
|
+
headline: "Method `{0}` is silently not encoded by `prepareForJson`: methods aren't data.",
|
|
386
441
|
severity: 'warning',
|
|
387
442
|
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.",
|
|
388
443
|
},
|
|
389
444
|
PJ012: {
|
|
390
|
-
headline: "Static member `{0}` is silently not encoded by `prepareForJson
|
|
445
|
+
headline: "Static member `{0}` is silently not encoded by `prepareForJson`: statics aren't part of instance data.",
|
|
391
446
|
severity: 'warning',
|
|
392
447
|
detail: 'Class static members live on the class, not on individual instances.\n`prepareForJson` operates on instance shape, so statics are excluded.',
|
|
393
448
|
},
|
|
394
449
|
PJ013: {
|
|
395
|
-
headline: "Symbol-keyed property `{0}` is silently not encoded by `prepareForJson
|
|
450
|
+
headline: "Symbol-keyed property `{0}` is silently not encoded by `prepareForJson`: symbol keys aren't JSON-representable.",
|
|
396
451
|
severity: 'warning',
|
|
397
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `prepareForJson` follows the same rule.\n\nFix
|
|
452
|
+
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;",
|
|
398
453
|
},
|
|
399
454
|
PJ014: {
|
|
400
|
-
headline: "Union member(s) of type `{0}` can't be represented as data
|
|
455
|
+
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.",
|
|
401
456
|
severity: 'warning',
|
|
402
|
-
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
|
|
457
|
+
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 "one 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.',
|
|
403
458
|
},
|
|
404
459
|
PJ015: {
|
|
405
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
460
|
+
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.',
|
|
406
461
|
severity: 'warning',
|
|
407
|
-
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
|
|
462
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
408
463
|
},
|
|
409
464
|
PJS001: {
|
|
410
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
465
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
411
466
|
severity: 'error',
|
|
412
|
-
detail: "`never` is the empty type
|
|
467
|
+
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 }",
|
|
413
468
|
},
|
|
414
469
|
PJS002: {
|
|
415
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
470
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
416
471
|
severity: 'error',
|
|
417
|
-
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
|
|
472
|
+
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 }",
|
|
418
473
|
},
|
|
419
474
|
PJS003: {
|
|
420
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
475
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
421
476
|
severity: 'error',
|
|
422
|
-
detail: "Functions have no value form to serialise
|
|
477
|
+
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 }",
|
|
423
478
|
},
|
|
424
479
|
PJS004: {
|
|
425
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
480
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
426
481
|
severity: 'error',
|
|
427
|
-
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded
|
|
482
|
+
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[];",
|
|
428
483
|
},
|
|
429
484
|
PJS005: {
|
|
430
|
-
headline: 'Type `{0}` can never be encoded to JSON
|
|
485
|
+
headline: 'Type `{0}` can never be encoded to JSON: the generated function will always fail.',
|
|
431
486
|
severity: 'error',
|
|
432
|
-
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
|
|
487
|
+
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';",
|
|
433
488
|
},
|
|
434
489
|
PJS010: {
|
|
435
|
-
headline: 'Property `{0}` is a function
|
|
490
|
+
headline: 'Property `{0}` is a function: `prepareForJsonSafe` does not handle function values, so this property is silently not encoded.',
|
|
436
491
|
severity: 'warning',
|
|
437
|
-
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
|
|
492
|
+
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 "one 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.',
|
|
438
493
|
},
|
|
439
494
|
PJS011: {
|
|
440
|
-
headline: "Method `{0}` is silently not encoded by `prepareForJsonSafe
|
|
495
|
+
headline: "Method `{0}` is silently not encoded by `prepareForJsonSafe`: methods aren't data.",
|
|
441
496
|
severity: 'warning',
|
|
442
497
|
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.",
|
|
443
498
|
},
|
|
444
499
|
PJS012: {
|
|
445
|
-
headline: "Static member `{0}` is silently not encoded by `prepareForJsonSafe
|
|
500
|
+
headline: "Static member `{0}` is silently not encoded by `prepareForJsonSafe`: statics aren't part of instance data.",
|
|
446
501
|
severity: 'warning',
|
|
447
502
|
detail: 'Class static members live on the class, not on individual instances.\n`prepareForJsonSafe` operates on instance shape, so statics are excluded.',
|
|
448
503
|
},
|
|
449
504
|
PJS013: {
|
|
450
|
-
headline: "Symbol-keyed property `{0}` is silently not encoded by `prepareForJsonSafe
|
|
505
|
+
headline: "Symbol-keyed property `{0}` is silently not encoded by `prepareForJsonSafe`: symbol keys aren't JSON-representable.",
|
|
451
506
|
severity: 'warning',
|
|
452
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `prepareForJsonSafe` follows the same rule.\n\nFix
|
|
507
|
+
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;",
|
|
453
508
|
},
|
|
454
509
|
PJS014: {
|
|
455
|
-
headline: "Union member(s) of type `{0}` can't be represented as data
|
|
510
|
+
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.",
|
|
456
511
|
severity: 'warning',
|
|
457
|
-
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
|
|
512
|
+
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 "one 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.',
|
|
458
513
|
},
|
|
459
514
|
PJS015: {
|
|
460
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
515
|
+
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.',
|
|
461
516
|
severity: 'warning',
|
|
462
|
-
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
|
|
517
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
463
518
|
},
|
|
464
519
|
RJ001: {
|
|
465
|
-
headline: 'Type `{0}` can never be decoded from JSON
|
|
520
|
+
headline: 'Type `{0}` can never be decoded from JSON: the generated function will always fail.',
|
|
466
521
|
severity: 'error',
|
|
467
|
-
detail: "`never` is the empty type
|
|
522
|
+
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 }",
|
|
468
523
|
},
|
|
469
524
|
RJ002: {
|
|
470
|
-
headline: 'Type `{0}` can never be decoded from JSON
|
|
525
|
+
headline: 'Type `{0}` can never be decoded from JSON: the generated function will always fail.',
|
|
471
526
|
severity: 'error',
|
|
472
|
-
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
|
|
527
|
+
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 }",
|
|
473
528
|
},
|
|
474
529
|
RJ003: {
|
|
475
|
-
headline: 'Type `{0}` can never be decoded from JSON
|
|
530
|
+
headline: 'Type `{0}` can never be decoded from JSON: the generated function will always fail.',
|
|
476
531
|
severity: 'error',
|
|
477
|
-
detail: "Functions have no value form to serialise
|
|
532
|
+
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 }",
|
|
478
533
|
},
|
|
479
534
|
RJ004: {
|
|
480
|
-
headline: 'Type `{0}` can never be decoded from JSON
|
|
535
|
+
headline: 'Type `{0}` can never be decoded from JSON: the generated function will always fail.',
|
|
481
536
|
severity: 'error',
|
|
482
|
-
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded
|
|
537
|
+
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[];",
|
|
483
538
|
},
|
|
484
539
|
RJ005: {
|
|
485
|
-
headline: 'Type `{0}` can never be decoded from JSON
|
|
540
|
+
headline: 'Type `{0}` can never be decoded from JSON: the generated function will always fail.',
|
|
486
541
|
severity: 'error',
|
|
487
|
-
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
|
|
542
|
+
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';",
|
|
488
543
|
},
|
|
489
544
|
RJ010: {
|
|
490
|
-
headline: 'Property `{0}` is a function
|
|
545
|
+
headline: 'Property `{0}` is a function: `restoreFromJson` does not handle function values, so this property is silently not decoded.',
|
|
491
546
|
severity: 'warning',
|
|
492
|
-
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
|
|
547
|
+
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 "one 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.',
|
|
493
548
|
},
|
|
494
549
|
RJ011: {
|
|
495
|
-
headline: "Method `{0}` is silently not decoded by `restoreFromJson
|
|
550
|
+
headline: "Method `{0}` is silently not decoded by `restoreFromJson`: methods aren't data.",
|
|
496
551
|
severity: 'warning',
|
|
497
552
|
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.",
|
|
498
553
|
},
|
|
499
554
|
RJ012: {
|
|
500
|
-
headline: "Static member `{0}` is silently not decoded by `restoreFromJson
|
|
555
|
+
headline: "Static member `{0}` is silently not decoded by `restoreFromJson`: statics aren't part of instance data.",
|
|
501
556
|
severity: 'warning',
|
|
502
557
|
detail: 'Class static members live on the class, not on individual instances.\n`restoreFromJson` operates on instance shape, so statics are excluded.',
|
|
503
558
|
},
|
|
504
559
|
RJ013: {
|
|
505
|
-
headline: "Symbol-keyed property `{0}` is silently not decoded by `restoreFromJson
|
|
560
|
+
headline: "Symbol-keyed property `{0}` is silently not decoded by `restoreFromJson`: symbol keys aren't JSON-representable.",
|
|
506
561
|
severity: 'warning',
|
|
507
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `restoreFromJson` follows the same rule.\n\nFix
|
|
562
|
+
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;",
|
|
508
563
|
},
|
|
509
564
|
RJ014: {
|
|
510
|
-
headline: "Union member(s) of type `{0}` can't be represented as data
|
|
565
|
+
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.",
|
|
511
566
|
severity: 'warning',
|
|
512
|
-
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
|
|
567
|
+
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 "one 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.',
|
|
513
568
|
},
|
|
514
569
|
RJ015: {
|
|
515
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
570
|
+
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.',
|
|
516
571
|
severity: 'warning',
|
|
517
|
-
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
|
|
572
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
518
573
|
},
|
|
519
574
|
SJ001: {
|
|
520
|
-
headline: 'Type `{0}` can never be stringified to JSON
|
|
575
|
+
headline: 'Type `{0}` can never be stringified to JSON: the generated function will always fail.',
|
|
521
576
|
severity: 'error',
|
|
522
|
-
detail: "`never` is the empty type
|
|
577
|
+
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 }",
|
|
523
578
|
},
|
|
524
579
|
SJ002: {
|
|
525
|
-
headline: 'Type `{0}` can never be stringified to JSON
|
|
580
|
+
headline: 'Type `{0}` can never be stringified to JSON: the generated function will always fail.',
|
|
526
581
|
severity: 'error',
|
|
527
|
-
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
|
|
582
|
+
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 }",
|
|
528
583
|
},
|
|
529
584
|
SJ003: {
|
|
530
|
-
headline: 'Type `{0}` can never be stringified to JSON
|
|
585
|
+
headline: 'Type `{0}` can never be stringified to JSON: the generated function will always fail.',
|
|
531
586
|
severity: 'error',
|
|
532
|
-
detail: "Functions have no value form to serialise
|
|
587
|
+
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 }",
|
|
533
588
|
},
|
|
534
589
|
SJ004: {
|
|
535
|
-
headline: 'Type `{0}` can never be stringified to JSON
|
|
590
|
+
headline: 'Type `{0}` can never be stringified to JSON: the generated function will always fail.',
|
|
536
591
|
severity: 'error',
|
|
537
|
-
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded
|
|
592
|
+
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[];",
|
|
538
593
|
},
|
|
539
594
|
SJ005: {
|
|
540
|
-
headline: 'Type `{0}` can never be stringified to JSON
|
|
595
|
+
headline: 'Type `{0}` can never be stringified to JSON: the generated function will always fail.',
|
|
541
596
|
severity: 'error',
|
|
542
|
-
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
|
|
597
|
+
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';",
|
|
543
598
|
},
|
|
544
599
|
SJ010: {
|
|
545
|
-
headline: 'Property `{0}` is a function
|
|
600
|
+
headline: 'Property `{0}` is a function: `stringifyJson` does not handle function values, so this property is silently not stringified.',
|
|
546
601
|
severity: 'warning',
|
|
547
|
-
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
|
|
602
|
+
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 "one 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.',
|
|
548
603
|
},
|
|
549
604
|
SJ011: {
|
|
550
|
-
headline: "Method `{0}` is silently not stringified by `stringifyJson
|
|
605
|
+
headline: "Method `{0}` is silently not stringified by `stringifyJson`: methods aren't data.",
|
|
551
606
|
severity: 'warning',
|
|
552
607
|
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.",
|
|
553
608
|
},
|
|
554
609
|
SJ012: {
|
|
555
|
-
headline: "Static member `{0}` is silently not stringified by `stringifyJson
|
|
610
|
+
headline: "Static member `{0}` is silently not stringified by `stringifyJson`: statics aren't part of instance data.",
|
|
556
611
|
severity: 'warning',
|
|
557
612
|
detail: 'Class static members live on the class, not on individual instances.\n`stringifyJson` operates on instance shape, so statics are excluded.',
|
|
558
613
|
},
|
|
559
614
|
SJ013: {
|
|
560
|
-
headline: "Symbol-keyed property `{0}` is silently not stringified by `stringifyJson
|
|
615
|
+
headline: "Symbol-keyed property `{0}` is silently not stringified by `stringifyJson`: symbol keys aren't JSON-representable.",
|
|
561
616
|
severity: 'warning',
|
|
562
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `stringifyJson` follows the same rule.\n\nFix
|
|
617
|
+
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;",
|
|
563
618
|
},
|
|
564
619
|
SJ014: {
|
|
565
|
-
headline: "Union member(s) of type `{0}` can't be represented as data
|
|
620
|
+
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.",
|
|
566
621
|
severity: 'warning',
|
|
567
|
-
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
|
|
622
|
+
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 "one 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.',
|
|
568
623
|
},
|
|
569
624
|
SJ015: {
|
|
570
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
625
|
+
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.',
|
|
571
626
|
severity: 'warning',
|
|
572
|
-
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
|
|
627
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
573
628
|
},
|
|
574
629
|
TB001: {
|
|
575
|
-
headline: 'Type `{0}` can never be serialised to binary
|
|
630
|
+
headline: 'Type `{0}` can never be serialised to binary: the generated function will always fail.',
|
|
576
631
|
severity: 'error',
|
|
577
|
-
detail: "`never` is the empty type
|
|
632
|
+
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 }",
|
|
578
633
|
},
|
|
579
634
|
TB002: {
|
|
580
|
-
headline: 'Type `{0}` can never be serialised to binary
|
|
635
|
+
headline: 'Type `{0}` can never be serialised to binary: the generated function will always fail.',
|
|
581
636
|
severity: 'error',
|
|
582
|
-
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
|
|
637
|
+
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 }",
|
|
583
638
|
},
|
|
584
639
|
TB003: {
|
|
585
|
-
headline: 'Type `{0}` can never be serialised to binary
|
|
640
|
+
headline: 'Type `{0}` can never be serialised to binary: the generated function will always fail.',
|
|
586
641
|
severity: 'error',
|
|
587
|
-
detail: "Functions have no value form to serialise
|
|
642
|
+
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 }",
|
|
588
643
|
},
|
|
589
644
|
TB004: {
|
|
590
|
-
headline: 'Type `{0}` can never be serialised to binary
|
|
645
|
+
headline: 'Type `{0}` can never be serialised to binary: the generated function will always fail.',
|
|
591
646
|
severity: 'error',
|
|
592
|
-
detail: "Arrays of un-serialisable elements (`symbol[]`, `(() => void)[]`,\n`Map<K, V>[]`, etc.) can't be encoded
|
|
647
|
+
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[];",
|
|
593
648
|
},
|
|
594
649
|
TB005: {
|
|
595
|
-
headline: 'Type `{0}` can never be serialised to binary
|
|
650
|
+
headline: 'Type `{0}` can never be serialised to binary: the generated function will always fail.',
|
|
596
651
|
severity: 'error',
|
|
597
|
-
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
|
|
652
|
+
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 }",
|
|
598
653
|
},
|
|
599
654
|
TB006: {
|
|
600
|
-
headline: 'Type `{0}` can never be serialised to binary
|
|
655
|
+
headline: 'Type `{0}` can never be serialised to binary: the generated function will always fail.',
|
|
601
656
|
severity: 'error',
|
|
602
|
-
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
|
|
657
|
+
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';",
|
|
603
658
|
},
|
|
604
659
|
TB010: {
|
|
605
|
-
headline: 'Property `{0}` is a function
|
|
660
|
+
headline: 'Property `{0}` is a function: `toBinary` does not handle function values, so this property is silently not serialised.',
|
|
606
661
|
severity: 'warning',
|
|
607
|
-
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
|
|
662
|
+
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 "one 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.',
|
|
608
663
|
},
|
|
609
664
|
TB011: {
|
|
610
|
-
headline: "Method `{0}` is silently not serialised by `toBinary
|
|
665
|
+
headline: "Method `{0}` is silently not serialised by `toBinary`: methods aren't data.",
|
|
611
666
|
severity: 'warning',
|
|
612
667
|
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.",
|
|
613
668
|
},
|
|
614
669
|
TB012: {
|
|
615
|
-
headline: "Static member `{0}` is silently not serialised by `toBinary
|
|
670
|
+
headline: "Static member `{0}` is silently not serialised by `toBinary`: statics aren't part of instance data.",
|
|
616
671
|
severity: 'warning',
|
|
617
672
|
detail: 'Class static members live on the class, not on individual instances.\n`toBinary` operates on instance shape, so statics are excluded.',
|
|
618
673
|
},
|
|
619
674
|
TB013: {
|
|
620
|
-
headline: "Symbol-keyed property `{0}` is silently not serialised by `toBinary
|
|
675
|
+
headline: "Symbol-keyed property `{0}` is silently not serialised by `toBinary`: symbol keys aren't JSON-representable.",
|
|
621
676
|
severity: 'warning',
|
|
622
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `toBinary` follows the same rule.\n\nFix
|
|
677
|
+
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;",
|
|
623
678
|
},
|
|
624
679
|
TB014: {
|
|
625
|
-
headline: "Union member(s) of type `{0}` can't be represented as data
|
|
680
|
+
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.",
|
|
626
681
|
severity: 'warning',
|
|
627
|
-
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
|
|
682
|
+
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 "one 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.',
|
|
628
683
|
},
|
|
629
684
|
TB015: {
|
|
630
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
685
|
+
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.',
|
|
631
686
|
severity: 'warning',
|
|
632
|
-
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
|
|
687
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
633
688
|
},
|
|
634
689
|
TMP001: {
|
|
635
|
-
headline: "Temporal type `{0}` resolved to `any
|
|
690
|
+
headline: "Temporal type `{0}` resolved to `any`: the Temporal lib isn't in your tsconfig `lib`, so the generated validator would accept any value.",
|
|
636
691
|
severity: 'error',
|
|
637
|
-
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
|
|
692
|
+
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 }',
|
|
638
693
|
},
|
|
639
694
|
UKE010: {
|
|
640
|
-
headline: 'Property `{0}` is a function
|
|
695
|
+
headline: 'Property `{0}` is a function: `unknownKeyErrors` does not handle function values, so this property is silently not checked.',
|
|
641
696
|
severity: 'warning',
|
|
642
|
-
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
|
|
697
|
+
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 "one 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.',
|
|
643
698
|
},
|
|
644
699
|
UKU010: {
|
|
645
|
-
headline: 'Property `{0}` is a function
|
|
700
|
+
headline: 'Property `{0}` is a function: `unknownKeysToUndefined` does not handle function values, so this property is silently not cleared.',
|
|
646
701
|
severity: 'warning',
|
|
647
|
-
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
|
|
702
|
+
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 "one 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.',
|
|
648
703
|
},
|
|
649
704
|
UKW010: {
|
|
650
|
-
headline: 'Property `{0}` is a function
|
|
705
|
+
headline: 'Property `{0}` is a function: `unknownKeysToUndefinedWire` does not handle function values, so this property is silently not cleared.',
|
|
651
706
|
severity: 'warning',
|
|
652
|
-
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
|
|
707
|
+
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 "one 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.',
|
|
653
708
|
},
|
|
654
709
|
VE001: {
|
|
655
|
-
headline: 'Type `{0}` can never be validated
|
|
710
|
+
headline: 'Type `{0}` can never be validated: the generated function will always fail.',
|
|
656
711
|
severity: 'error',
|
|
657
|
-
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
|
|
712
|
+
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 }",
|
|
658
713
|
},
|
|
659
714
|
VE002: {
|
|
660
|
-
headline: 'Type `{0}` can never be validated
|
|
715
|
+
headline: 'Type `{0}` can never be validated: the generated function will always fail.',
|
|
661
716
|
severity: 'error',
|
|
662
|
-
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
|
|
717
|
+
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';",
|
|
663
718
|
},
|
|
664
719
|
VE010: {
|
|
665
|
-
headline: 'Property `{0}` is a function
|
|
720
|
+
headline: 'Property `{0}` is a function: `validationErrors` does not handle function values, so this property is silently not checked.',
|
|
666
721
|
severity: 'warning',
|
|
667
|
-
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
|
|
722
|
+
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 "one 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.',
|
|
668
723
|
},
|
|
669
724
|
VE011: {
|
|
670
|
-
headline: "Method `{0}` is silently not checked by `validationErrors
|
|
725
|
+
headline: "Method `{0}` is silently not checked by `validationErrors`: methods aren't data.",
|
|
671
726
|
severity: 'warning',
|
|
672
727
|
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.",
|
|
673
728
|
},
|
|
674
729
|
VE012: {
|
|
675
|
-
headline: "Static member `{0}` is silently not checked by `validationErrors
|
|
730
|
+
headline: "Static member `{0}` is silently not checked by `validationErrors`: statics aren't part of instance data.",
|
|
676
731
|
severity: 'warning',
|
|
677
732
|
detail: 'Class static members live on the class, not on individual instances.\n`validationErrors` operates on instance shape, so statics are excluded.',
|
|
678
733
|
},
|
|
679
734
|
VE013: {
|
|
680
|
-
headline: "Symbol-keyed property `{0}` is silently not checked by `validationErrors
|
|
735
|
+
headline: "Symbol-keyed property `{0}` is silently not checked by `validationErrors`: symbol keys aren't JSON-representable.",
|
|
681
736
|
severity: 'warning',
|
|
682
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `validationErrors` follows the same rule.\n\nFix
|
|
737
|
+
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;",
|
|
683
738
|
},
|
|
684
739
|
VE015: {
|
|
685
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
740
|
+
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.',
|
|
686
741
|
severity: 'warning',
|
|
687
|
-
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
|
|
742
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
688
743
|
},
|
|
689
744
|
VE020: {
|
|
690
|
-
headline: '`validationErrors` on `any` / `unknown` always returns an empty error array
|
|
745
|
+
headline: '`validationErrors` on `any` / `unknown` always returns an empty error array: nothing is checked.',
|
|
691
746
|
severity: 'warning',
|
|
692
|
-
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
|
|
747
|
+
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 = createGetValidationErrorsFn<unknown>()(value);\n+ const errors = createGetValidationErrorsFn<User>()(value);',
|
|
693
748
|
},
|
|
694
749
|
VL001: {
|
|
695
|
-
headline: 'Type `{0}` can never be validated
|
|
750
|
+
headline: 'Type `{0}` can never be validated: the generated function will always fail.',
|
|
696
751
|
severity: 'error',
|
|
697
|
-
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
|
|
752
|
+
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 }",
|
|
698
753
|
},
|
|
699
754
|
VL002: {
|
|
700
|
-
headline: 'Type `{0}` can never be validated
|
|
755
|
+
headline: 'Type `{0}` can never be validated: the generated function will always fail.',
|
|
701
756
|
severity: 'error',
|
|
702
|
-
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
|
|
757
|
+
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';",
|
|
703
758
|
},
|
|
704
759
|
VL010: {
|
|
705
|
-
headline: 'Property `{0}` is a function
|
|
760
|
+
headline: 'Property `{0}` is a function: `validate` does not handle function values, so this property is silently not validated.',
|
|
706
761
|
severity: 'warning',
|
|
707
|
-
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
|
|
762
|
+
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 "one 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.',
|
|
708
763
|
},
|
|
709
764
|
VL011: {
|
|
710
|
-
headline: "Method `{0}` is silently not validated by `validate
|
|
765
|
+
headline: "Method `{0}` is silently not validated by `validate`: methods aren't data.",
|
|
711
766
|
severity: 'warning',
|
|
712
767
|
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.",
|
|
713
768
|
},
|
|
714
769
|
VL012: {
|
|
715
|
-
headline: "Static member `{0}` is silently not validated by `validate
|
|
770
|
+
headline: "Static member `{0}` is silently not validated by `validate`: statics aren't part of instance data.",
|
|
716
771
|
severity: 'warning',
|
|
717
772
|
detail: 'Class static members live on the class, not on individual instances.\n`validate` operates on instance shape, so statics are excluded.',
|
|
718
773
|
},
|
|
719
774
|
VL013: {
|
|
720
|
-
headline: "Symbol-keyed property `{0}` is silently not validated by `validate
|
|
775
|
+
headline: "Symbol-keyed property `{0}` is silently not validated by `validate`: symbol keys aren't JSON-representable.",
|
|
721
776
|
severity: 'warning',
|
|
722
|
-
detail: "JSON only supports string keys; symbol-keyed properties are dropped\nfrom the serialised form. `validate` follows the same rule.\n\nFix
|
|
777
|
+
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;",
|
|
723
778
|
},
|
|
724
779
|
VL014: {
|
|
725
|
-
headline: "Union member(s) of type `{0}` can't be represented as data
|
|
780
|
+
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.",
|
|
726
781
|
severity: 'warning',
|
|
727
|
-
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
|
|
782
|
+
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 "one 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.',
|
|
728
783
|
},
|
|
729
784
|
VL015: {
|
|
730
|
-
headline: 'Property `{0}` has a non-serialisable value type (symbol, Promise, or a non-serialisable built-in)
|
|
785
|
+
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.',
|
|
731
786
|
severity: 'warning',
|
|
732
|
-
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
|
|
787
|
+
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 "one contract: serializable data only"\nsection in CLAUDE.md.',
|
|
733
788
|
},
|
|
734
789
|
VL021: {
|
|
735
|
-
headline: '`validate` on `any` / `unknown` always returns true
|
|
790
|
+
headline: '`validate` on `any` / `unknown` always returns true: the validator accepts every value.',
|
|
736
791
|
severity: 'warning',
|
|
737
|
-
detail: '`any` and `unknown` describe "anything", so a structural validator has\nnothing to check. The resulting function passes for every input
|
|
792
|
+
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 = createValidateFn<unknown>();\n+ const isUser = createValidateFn<User>();',
|
|
738
793
|
},
|
|
739
794
|
};
|
|
740
795
|
//# sourceMappingURL=diagnosticCatalog.generated.js.map
|