@sig-net/midnight-serde 0.23.0 → 0.24.0-rc.10

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/dist/validate.js DELETED
@@ -1,185 +0,0 @@
1
- // Strict runtime validation of CompactType descriptors. TypeScript checks
2
- // descriptors at compile time, but descriptors can also arrive from plain JS,
3
- // JSON, or casts, and Compact is a strict protocol: a malformed descriptor
4
- // must throw immediately with a path to the offending node, never produce
5
- // bytes. Every public entry point of this package validates its descriptor
6
- // through here before doing any work.
7
- import { MAX_UINT_BITS, MAX_UINT_BOUND } from "./types.js";
8
- /** The exact keys allowed on each descriptor kind: extra keys are rejected. */
9
- const KIND_KEYS = {
10
- boolean: ["kind"],
11
- uint: ["kind", "bits", "bound"],
12
- field: ["kind"],
13
- bytes: ["kind", "length"],
14
- enum: ["kind", "variants"],
15
- vector: ["kind", "length", "element"],
16
- tuple: ["kind", "elements"],
17
- struct: ["kind", "fields"],
18
- };
19
- function assertNonNegativeInteger(value, label) {
20
- // isSafeInteger, not isInteger: a length like 2^60 passes isInteger but
21
- // breaks the Number arithmetic packed sizes are computed with.
22
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
23
- throw new Error(`${label} must be a non-negative safe integer, got ${String(value)}`);
24
- }
25
- }
26
- /**
27
- * Cross-realm-safe Uint8Array check. `instanceof` fails for buffers created
28
- * in another realm (node:vm context, iframe), which are otherwise perfectly
29
- * valid inputs, so fall back to the brand check.
30
- *
31
- * @param value - The value to test.
32
- * @returns Whether the value is a Uint8Array from any realm.
33
- */
34
- export function isUint8Array(value) {
35
- return (value instanceof Uint8Array || Object.prototype.toString.call(value) === "[object Uint8Array]");
36
- }
37
- /**
38
- * Assert that `type` is a structurally valid {@link CompactType}, recursively.
39
- * Rejects unknown kinds, unexpected extra keys (typo protection), out-of-range
40
- * widths and lengths, empty or duplicate struct field names, and any
41
- * non-object node. Error messages carry the path to the offending node.
42
- *
43
- * @param type - The candidate descriptor.
44
- * @param label - Path prefix for error messages.
45
- * @throws {Error} If the descriptor is malformed at any depth.
46
- */
47
- export function assertCompactType(type, label = "type") {
48
- if (typeof type !== "object" || type === null || Array.isArray(type)) {
49
- throw new Error(`${label}: descriptor must be a plain object`);
50
- }
51
- const record = type;
52
- const kind = record.kind;
53
- // Object.hasOwn, not `in`: `in` walks the prototype chain, so kinds like
54
- // 'toString' would slip past and die later with a confusing TypeError.
55
- const allowedKeys = typeof kind === "string" ? KIND_KEYS[kind] : undefined;
56
- if (typeof kind !== "string" || !Object.hasOwn(KIND_KEYS, kind) || allowedKeys === undefined) {
57
- throw new Error(`${label}: unknown descriptor kind ${JSON.stringify(kind)} ` +
58
- `(expected 'boolean' | 'uint' | 'field' | 'bytes' | 'enum' | 'vector' | 'tuple' | 'struct')`);
59
- }
60
- for (const key of Object.keys(record)) {
61
- if (!allowedKeys.includes(key)) {
62
- throw new Error(`${label}: unexpected key '${key}' on a '${kind}' descriptor`);
63
- }
64
- }
65
- switch (kind) {
66
- case "boolean":
67
- case "field":
68
- return;
69
- case "uint": {
70
- // Own-property reads: a plain `record.bits` would resolve through the
71
- // prototype chain, letting `{ __proto__: { bits: 8 }, kind: 'uint' }`
72
- // slip past even though Object.keys sees no such key.
73
- const bits = Object.hasOwn(record, "bits") ? record.bits : undefined;
74
- const bound = Object.hasOwn(record, "bound") ? record.bound : undefined;
75
- const hasBits = bits !== undefined;
76
- const hasBound = bound !== undefined;
77
- if (hasBits === hasBound) {
78
- throw new Error(`${label}: a uint descriptor needs exactly one of 'bits' (sized Uint<w>) ` +
79
- `or 'bound' (bounded Uint<0..n>)`);
80
- }
81
- if (hasBits) {
82
- if (typeof bits !== "number" ||
83
- !Number.isInteger(bits) ||
84
- bits < 1 ||
85
- bits > MAX_UINT_BITS) {
86
- throw new Error(`${label}: uint bits must be an integer in 1..${String(MAX_UINT_BITS)}, got ${JSON.stringify(bits)}`);
87
- }
88
- return;
89
- }
90
- if (typeof bound === "number" && !Number.isSafeInteger(bound)) {
91
- throw new Error(`${label}: a number uint bound must be a safe integer (use a bigint ` +
92
- `beyond 2^53), got ${String(bound)}`);
93
- }
94
- if (typeof bound !== "number" && typeof bound !== "bigint") {
95
- throw new Error(`${label}: uint bound must be a number or bigint, got ${String(bound)}`);
96
- }
97
- if (BigInt(bound) < 1n || BigInt(bound) > MAX_UINT_BOUND) {
98
- throw new Error(`${label}: uint bound must be in 1..2^248 (the bound is EXCLUSIVE, ` +
99
- `matching Uint<0..n>), got ${String(bound)}`);
100
- }
101
- return;
102
- }
103
- case "bytes":
104
- assertNonNegativeInteger(record.length, `${label}: bytes length`);
105
- return;
106
- case "enum": {
107
- const variants = record.variants;
108
- if (typeof variants !== "number" || !Number.isSafeInteger(variants) || variants < 1) {
109
- throw new Error(`${label}: enum variants must be a positive integer, got ${String(variants)}`);
110
- }
111
- return;
112
- }
113
- case "vector":
114
- assertNonNegativeInteger(record.length, `${label}: vector length`);
115
- assertCompactType(record.element, `${label}.element`);
116
- return;
117
- case "tuple": {
118
- const elements = record.elements;
119
- if (!Array.isArray(elements)) {
120
- throw new Error(`${label}: tuple elements must be an array`);
121
- }
122
- elements.forEach((element, i) => {
123
- assertCompactType(element, `${label}.elements[${String(i)}]`);
124
- });
125
- return;
126
- }
127
- case "struct": {
128
- const fields = record.fields;
129
- if (!Array.isArray(fields)) {
130
- throw new Error(`${label}: struct fields must be an array`);
131
- }
132
- const seen = new Set();
133
- fields.forEach((field, i) => {
134
- const fieldLabel = `${label}.fields[${String(i)}]`;
135
- if (typeof field !== "object" || field === null || Array.isArray(field)) {
136
- throw new Error(`${fieldLabel}: field must be a plain object`);
137
- }
138
- const fieldRecord = field;
139
- for (const key of Object.keys(fieldRecord)) {
140
- if (key !== "name" && key !== "type") {
141
- throw new Error(`${fieldLabel}: unexpected key '${key}' on a struct field`);
142
- }
143
- }
144
- if (typeof fieldRecord.name !== "string" || fieldRecord.name.length === 0) {
145
- throw new Error(`${fieldLabel}: field name must be a non-empty string`);
146
- }
147
- if (seen.has(fieldRecord.name)) {
148
- throw new Error(`${fieldLabel}: duplicate field name '${fieldRecord.name}'`);
149
- }
150
- seen.add(fieldRecord.name);
151
- assertCompactType(fieldRecord.type, `${fieldLabel}.type`);
152
- });
153
- return;
154
- }
155
- }
156
- }
157
- /**
158
- * Boolean form of {@link assertCompactType}.
159
- *
160
- * @param type - The candidate descriptor.
161
- * @returns Whether the descriptor is structurally valid.
162
- */
163
- export function isCompactType(type) {
164
- try {
165
- assertCompactType(type);
166
- return true;
167
- }
168
- catch {
169
- return false;
170
- }
171
- }
172
- /**
173
- * Exhaustiveness backstop for descriptor switches. Statically `value` is
174
- * `never` (every kind handled); at runtime it still throws on anything that
175
- * slipped past validation instead of falling through to undefined behaviour.
176
- *
177
- * @param value - The descriptor every branch was meant to have handled.
178
- * @param label - Caller name, used in the error message.
179
- * @throws {Error} Always, naming the unhandled kind.
180
- */
181
- export function assertUnreachable(value, label) {
182
- const kind = value?.kind;
183
- throw new Error(`${label}: unhandled descriptor kind ${JSON.stringify(kind)}`);
184
- }
185
- //# sourceMappingURL=validate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}