@noeos/verification-engine 0.0.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.
Files changed (184) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +11 -0
  4. package/README.md +7 -0
  5. package/dist/cjs/api/engine.js +271 -0
  6. package/dist/cjs/api/types.js +10 -0
  7. package/dist/cjs/chains/chain-builder.js +541 -0
  8. package/dist/cjs/chains/duplicate-detector.js +208 -0
  9. package/dist/cjs/chains/verify-chain.js +656 -0
  10. package/dist/cjs/contracts/generated.js +512 -0
  11. package/dist/cjs/contracts/schema-assets.js +6 -0
  12. package/dist/cjs/contracts/vector-assets.js +6 -0
  13. package/dist/cjs/domain/algorithm-id.js +5 -0
  14. package/dist/cjs/domain/byte-view.js +7 -0
  15. package/dist/cjs/domain/chain.js +3 -0
  16. package/dist/cjs/domain/diagnostic.js +6 -0
  17. package/dist/cjs/domain/digest.js +37 -0
  18. package/dist/cjs/domain/duplicate-policy.js +3 -0
  19. package/dist/cjs/domain/evidence.js +10 -0
  20. package/dist/cjs/domain/identifiers.js +52 -0
  21. package/dist/cjs/domain/json-value.js +3 -0
  22. package/dist/cjs/domain/limits.js +24 -0
  23. package/dist/cjs/domain/operation-result.js +19 -0
  24. package/dist/cjs/domain/position.js +16 -0
  25. package/dist/cjs/domain/protocol-version.js +5 -0
  26. package/dist/cjs/domain/rule.js +3 -0
  27. package/dist/cjs/domain/stream.js +3 -0
  28. package/dist/cjs/domain/version.js +16 -0
  29. package/dist/cjs/evidence/digest-evidence.js +22 -0
  30. package/dist/cjs/evidence/evidence-parser.js +288 -0
  31. package/dist/cjs/framing/frame-builders.js +124 -0
  32. package/dist/cjs/framing/frame-encoder.js +238 -0
  33. package/dist/cjs/framing/frame-parser.js +173 -0
  34. package/dist/cjs/framing/frame-types.js +3 -0
  35. package/dist/cjs/hashing/hash-adapter.js +90 -0
  36. package/dist/cjs/hashing/hash-frame.js +16 -0
  37. package/dist/cjs/index.js +16 -0
  38. package/dist/cjs/normalization/byte-sink.js +70 -0
  39. package/dist/cjs/normalization/jcs-profile.js +154 -0
  40. package/dist/cjs/normalization/normalize.js +56 -0
  41. package/dist/cjs/normalization/profile-registry.js +66 -0
  42. package/dist/cjs/normalization/profile.js +3 -0
  43. package/dist/cjs/normalization/raw-bytes-profile.js +27 -0
  44. package/dist/cjs/package.json +3 -0
  45. package/dist/cjs/profiles.js +9 -0
  46. package/dist/cjs/records/record-service.js +278 -0
  47. package/dist/cjs/rules/rule-set.js +211 -0
  48. package/dist/cjs/schemas.js +6 -0
  49. package/dist/cjs/validation/algorithm-validation.js +12 -0
  50. package/dist/cjs/validation/diagnostic-collector.js +159 -0
  51. package/dist/cjs/validation/digest-validation.js +48 -0
  52. package/dist/cjs/validation/identifier-validation.js +33 -0
  53. package/dist/cjs/validation/json-text-parser.js +297 -0
  54. package/dist/cjs/validation/json-value-validation.js +155 -0
  55. package/dist/cjs/validation/limit-validation.js +75 -0
  56. package/dist/cjs/validation/object-inspection.js +60 -0
  57. package/dist/cjs/validation/position-validation.js +13 -0
  58. package/dist/cjs/validation/result-helpers.js +9 -0
  59. package/dist/cjs/validation/utf8-validation.js +69 -0
  60. package/dist/cjs/validation/version-validation.js +31 -0
  61. package/dist/cjs/vectors.js +6 -0
  62. package/dist/esm/api/engine.js +266 -0
  63. package/dist/esm/api/types.js +4 -0
  64. package/dist/esm/chains/chain-builder.js +536 -0
  65. package/dist/esm/chains/duplicate-detector.js +204 -0
  66. package/dist/esm/chains/verify-chain.js +652 -0
  67. package/dist/esm/contracts/generated.js +509 -0
  68. package/dist/esm/contracts/schema-assets.js +2 -0
  69. package/dist/esm/contracts/vector-assets.js +2 -0
  70. package/dist/esm/domain/algorithm-id.js +2 -0
  71. package/dist/esm/domain/byte-view.js +4 -0
  72. package/dist/esm/domain/chain.js +2 -0
  73. package/dist/esm/domain/diagnostic.js +3 -0
  74. package/dist/esm/domain/digest.js +32 -0
  75. package/dist/esm/domain/duplicate-policy.js +2 -0
  76. package/dist/esm/domain/evidence.js +7 -0
  77. package/dist/esm/domain/identifiers.js +45 -0
  78. package/dist/esm/domain/json-value.js +2 -0
  79. package/dist/esm/domain/limits.js +21 -0
  80. package/dist/esm/domain/operation-result.js +15 -0
  81. package/dist/esm/domain/position.js +12 -0
  82. package/dist/esm/domain/protocol-version.js +2 -0
  83. package/dist/esm/domain/rule.js +2 -0
  84. package/dist/esm/domain/stream.js +2 -0
  85. package/dist/esm/domain/version.js +12 -0
  86. package/dist/esm/evidence/digest-evidence.js +19 -0
  87. package/dist/esm/evidence/evidence-parser.js +281 -0
  88. package/dist/esm/framing/frame-builders.js +114 -0
  89. package/dist/esm/framing/frame-encoder.js +234 -0
  90. package/dist/esm/framing/frame-parser.js +170 -0
  91. package/dist/esm/framing/frame-types.js +2 -0
  92. package/dist/esm/hashing/hash-adapter.js +84 -0
  93. package/dist/esm/hashing/hash-frame.js +12 -0
  94. package/dist/esm/index.js +5 -0
  95. package/dist/esm/normalization/byte-sink.js +66 -0
  96. package/dist/esm/normalization/jcs-profile.js +151 -0
  97. package/dist/esm/normalization/normalize.js +52 -0
  98. package/dist/esm/normalization/profile-registry.js +62 -0
  99. package/dist/esm/normalization/profile.js +2 -0
  100. package/dist/esm/normalization/raw-bytes-profile.js +24 -0
  101. package/dist/esm/profiles.js +6 -0
  102. package/dist/esm/records/record-service.js +270 -0
  103. package/dist/esm/rules/rule-set.js +206 -0
  104. package/dist/esm/schemas.js +2 -0
  105. package/dist/esm/validation/algorithm-validation.js +9 -0
  106. package/dist/esm/validation/diagnostic-collector.js +154 -0
  107. package/dist/esm/validation/digest-validation.js +43 -0
  108. package/dist/esm/validation/identifier-validation.js +27 -0
  109. package/dist/esm/validation/json-text-parser.js +294 -0
  110. package/dist/esm/validation/json-value-validation.js +152 -0
  111. package/dist/esm/validation/limit-validation.js +71 -0
  112. package/dist/esm/validation/object-inspection.js +54 -0
  113. package/dist/esm/validation/position-validation.js +10 -0
  114. package/dist/esm/validation/result-helpers.js +6 -0
  115. package/dist/esm/validation/utf8-validation.js +63 -0
  116. package/dist/esm/validation/version-validation.js +26 -0
  117. package/dist/esm/vectors.js +2 -0
  118. package/dist/types/api/engine.d.ts +8 -0
  119. package/dist/types/api/types.d.ts +124 -0
  120. package/dist/types/chains/chain-builder.d.ts +42 -0
  121. package/dist/types/chains/duplicate-detector.d.ts +18 -0
  122. package/dist/types/chains/verify-chain.d.ts +9 -0
  123. package/dist/types/contracts/generated.d.ts +442 -0
  124. package/dist/types/contracts/schema-assets.d.ts +2 -0
  125. package/dist/types/contracts/vector-assets.d.ts +2 -0
  126. package/dist/types/domain/algorithm-id.d.ts +4 -0
  127. package/dist/types/domain/byte-view.d.ts +1 -0
  128. package/dist/types/domain/chain.d.ts +43 -0
  129. package/dist/types/domain/diagnostic.d.ts +23 -0
  130. package/dist/types/domain/digest.d.ts +12 -0
  131. package/dist/types/domain/duplicate-policy.d.ts +26 -0
  132. package/dist/types/domain/evidence.d.ts +100 -0
  133. package/dist/types/domain/identifiers.d.ts +29 -0
  134. package/dist/types/domain/json-value.d.ts +6 -0
  135. package/dist/types/domain/limits.d.ts +13 -0
  136. package/dist/types/domain/operation-result.d.ts +12 -0
  137. package/dist/types/domain/position.d.ts +8 -0
  138. package/dist/types/domain/protocol-version.d.ts +2 -0
  139. package/dist/types/domain/rule.d.ts +34 -0
  140. package/dist/types/domain/stream.d.ts +5 -0
  141. package/dist/types/domain/version.d.ts +8 -0
  142. package/dist/types/evidence/digest-evidence.d.ts +4 -0
  143. package/dist/types/evidence/evidence-parser.d.ts +8 -0
  144. package/dist/types/framing/frame-builders.d.ts +40 -0
  145. package/dist/types/framing/frame-encoder.d.ts +6 -0
  146. package/dist/types/framing/frame-parser.d.ts +4 -0
  147. package/dist/types/framing/frame-types.d.ts +27 -0
  148. package/dist/types/hashing/hash-adapter.d.ts +12 -0
  149. package/dist/types/hashing/hash-frame.d.ts +6 -0
  150. package/dist/types/index.d.ts +8 -0
  151. package/dist/types/normalization/byte-sink.d.ts +19 -0
  152. package/dist/types/normalization/jcs-profile.d.ts +3 -0
  153. package/dist/types/normalization/normalize.d.ts +11 -0
  154. package/dist/types/normalization/profile-registry.d.ts +26 -0
  155. package/dist/types/normalization/profile.d.ts +22 -0
  156. package/dist/types/normalization/raw-bytes-profile.d.ts +2 -0
  157. package/dist/types/profiles.d.ts +8 -0
  158. package/dist/types/records/record-service.d.ts +38 -0
  159. package/dist/types/rules/rule-set.d.ts +13 -0
  160. package/dist/types/schemas.d.ts +2 -0
  161. package/dist/types/validation/algorithm-validation.d.ts +3 -0
  162. package/dist/types/validation/diagnostic-collector.d.ts +24 -0
  163. package/dist/types/validation/digest-validation.d.ts +6 -0
  164. package/dist/types/validation/identifier-validation.d.ts +6 -0
  165. package/dist/types/validation/json-text-parser.d.ts +4 -0
  166. package/dist/types/validation/json-value-validation.d.ts +4 -0
  167. package/dist/types/validation/limit-validation.d.ts +4 -0
  168. package/dist/types/validation/object-inspection.d.ts +11 -0
  169. package/dist/types/validation/position-validation.d.ts +3 -0
  170. package/dist/types/validation/result-helpers.d.ts +3 -0
  171. package/dist/types/validation/utf8-validation.d.ts +5 -0
  172. package/dist/types/validation/version-validation.d.ts +9 -0
  173. package/dist/types/vectors.d.ts +2 -0
  174. package/package.json +61 -0
  175. package/schemas/chain-summary.v1.schema.json +156 -0
  176. package/schemas/diagnostic.v1.schema.json +107 -0
  177. package/schemas/link-evidence.v1.schema.json +165 -0
  178. package/schemas/record-evidence.v1.schema.json +91 -0
  179. package/schemas/vector-set.v1.schema.json +52 -0
  180. package/vectors/evidence.json +26 -0
  181. package/vectors/framing.json +136 -0
  182. package/vectors/hashing.json +58 -0
  183. package/vectors/invalid.json +56 -0
  184. package/vectors/manifest.json +46 -0
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.parseJsonText = parseJsonText;
5
+ const node_util_1 = require("node:util");
6
+ const operation_result_js_1 = require("../domain/operation-result.js");
7
+ const diagnostic_collector_js_1 = require("./diagnostic-collector.js");
8
+ const json_value_validation_js_1 = require("./json-value-validation.js");
9
+ const utf8_validation_js_1 = require("./utf8-validation.js");
10
+ const result_helpers_js_1 = require("./result-helpers.js");
11
+ function parseJsonText(input, limits) {
12
+ const source = decodeInput(input, limits);
13
+ if (!source.ok)
14
+ return source;
15
+ const parser = new JsonTextParser(source.value, limits);
16
+ const parsed = parser.parse();
17
+ if (!parsed.ok)
18
+ return parsed;
19
+ return (0, json_value_validation_js_1.validateJsonValue)(parsed.value, limits);
20
+ }
21
+ function decodeInput(input, limits) {
22
+ if (node_util_1.types.isProxy(input))
23
+ return failureWithSyntax();
24
+ if (input instanceof Uint8Array) {
25
+ if (input.length > limits.maxPayloadBytes)
26
+ return (0, result_helpers_js_1.failureWithCode)("INPUT_LIMIT_EXCEEDED", "input");
27
+ return (0, utf8_validation_js_1.decodeUtf8)(input);
28
+ }
29
+ if (typeof input !== "string")
30
+ return failureWithSyntax();
31
+ if (!(0, utf8_validation_js_1.hasWellFormedUnicode)(input))
32
+ return failureWithSyntax();
33
+ const encoded = (0, utf8_validation_js_1.encodeUtf8)(input, limits.maxPayloadBytes);
34
+ if (!encoded.ok)
35
+ return encoded;
36
+ return (0, operation_result_js_1.success)(input);
37
+ }
38
+ function failureWithSyntax() {
39
+ return (0, result_helpers_js_1.failureWithCode)("JSON_SYNTAX_INVALID", "input");
40
+ }
41
+ class JsonTextParser {
42
+ source;
43
+ limits;
44
+ offset = 0;
45
+ constructor(source, limits) {
46
+ this.source = source;
47
+ this.limits = limits;
48
+ }
49
+ parse() {
50
+ try {
51
+ this.skipWhitespace();
52
+ const value = this.parseValue(0, "");
53
+ this.skipWhitespace();
54
+ if (this.offset !== this.source.length)
55
+ return this.syntaxFailure();
56
+ return (0, operation_result_js_1.success)(value);
57
+ }
58
+ catch (error) {
59
+ if (error instanceof JsonParseFailure) {
60
+ const collector = new diagnostic_collector_js_1.DiagnosticCollector(this.limits);
61
+ collector.addCode(error.code, "input", { path: error.path, position: this.offset });
62
+ return (0, operation_result_js_1.failure)(collector.finish());
63
+ }
64
+ const collector = new diagnostic_collector_js_1.DiagnosticCollector(this.limits);
65
+ collector.addCode("JSON_SYNTAX_INVALID", "input", { position: this.offset });
66
+ return (0, operation_result_js_1.failure)(collector.finish());
67
+ }
68
+ }
69
+ parseValue(depth, path) {
70
+ if (depth > this.limits.maxJsonDepth)
71
+ this.fail("INPUT_LIMIT_EXCEEDED", path);
72
+ const character = this.source[this.offset];
73
+ if (character === "{")
74
+ return this.parseObject(depth, path);
75
+ if (character === "[")
76
+ return this.parseArray(depth, path);
77
+ if (character === '"')
78
+ return this.parseString(path);
79
+ if (character === "t")
80
+ return this.parseLiteral("true", true);
81
+ if (character === "f")
82
+ return this.parseLiteral("false", false);
83
+ if (character === "n")
84
+ return this.parseLiteral("null", null);
85
+ if (character === "-" || isDigit(character))
86
+ return this.parseNumber(path);
87
+ this.fail("JSON_SYNTAX_INVALID", path);
88
+ }
89
+ parseObject(depth, path) {
90
+ this.offset += 1;
91
+ const output = {};
92
+ const names = new Set();
93
+ this.skipWhitespace();
94
+ if (this.consume("}"))
95
+ return Object.freeze(output);
96
+ let propertyCount = 0;
97
+ while (this.offset < this.source.length) {
98
+ if (propertyCount >= this.limits.maxObjectProperties)
99
+ this.fail("INPUT_LIMIT_EXCEEDED", path);
100
+ if (this.source[this.offset] !== '"')
101
+ this.fail("JSON_SYNTAX_INVALID", path);
102
+ const key = this.parseString(path);
103
+ if (names.has(key))
104
+ this.fail("JSON_DUPLICATE_KEY", `${path}/${escapeJsonPointer(key)}`);
105
+ names.add(key);
106
+ this.skipWhitespace();
107
+ if (!this.consume(":"))
108
+ this.fail("JSON_SYNTAX_INVALID", path);
109
+ this.skipWhitespace();
110
+ const childPath = `${path}/${escapeJsonPointer(key)}`;
111
+ const value = this.parseValue(depth + 1, childPath);
112
+ Object.defineProperty(output, key, {
113
+ configurable: false,
114
+ enumerable: true,
115
+ value,
116
+ writable: false,
117
+ });
118
+ propertyCount += 1;
119
+ this.skipWhitespace();
120
+ if (this.consume("}"))
121
+ return Object.freeze(output);
122
+ if (!this.consume(","))
123
+ this.fail("JSON_SYNTAX_INVALID", path);
124
+ this.skipWhitespace();
125
+ }
126
+ this.fail("JSON_SYNTAX_INVALID", path);
127
+ }
128
+ parseArray(depth, path) {
129
+ this.offset += 1;
130
+ const output = [];
131
+ this.skipWhitespace();
132
+ if (this.consume("]"))
133
+ return Object.freeze(output);
134
+ while (this.offset < this.source.length) {
135
+ if (output.length >= this.limits.maxArrayElements)
136
+ this.fail("INPUT_LIMIT_EXCEEDED", path);
137
+ output.push(this.parseValue(depth + 1, `${path}/${String(output.length)}`));
138
+ this.skipWhitespace();
139
+ if (this.consume("]"))
140
+ return Object.freeze(output);
141
+ if (!this.consume(","))
142
+ this.fail("JSON_SYNTAX_INVALID", path);
143
+ this.skipWhitespace();
144
+ }
145
+ this.fail("JSON_SYNTAX_INVALID", path);
146
+ }
147
+ parseString(path) {
148
+ if (!this.consume('"'))
149
+ this.fail("JSON_SYNTAX_INVALID", path);
150
+ let output = "";
151
+ while (this.offset < this.source.length) {
152
+ const character = this.source.charAt(this.offset);
153
+ this.offset += 1;
154
+ if (character === '"') {
155
+ if (!(0, utf8_validation_js_1.hasWellFormedUnicode)(output))
156
+ this.fail("UTF8_INVALID", path);
157
+ const encoded = (0, utf8_validation_js_1.encodeUtf8)(output, this.limits.maxStringBytes);
158
+ if (!encoded.ok)
159
+ this.fail("INPUT_LIMIT_EXCEEDED", path);
160
+ return output;
161
+ }
162
+ if (character === "\\") {
163
+ output += this.parseEscape(path);
164
+ continue;
165
+ }
166
+ if (character.charCodeAt(0) <= 0x1f) {
167
+ this.fail("JSON_SYNTAX_INVALID", path);
168
+ }
169
+ output += character;
170
+ }
171
+ this.fail("JSON_SYNTAX_INVALID", path);
172
+ }
173
+ parseEscape(path) {
174
+ const escape = this.source[this.offset];
175
+ this.offset += 1;
176
+ const simple = {
177
+ '"': '"',
178
+ "\\": "\\",
179
+ "/": "/",
180
+ b: "\b",
181
+ f: "\f",
182
+ n: "\n",
183
+ r: "\r",
184
+ t: "\t",
185
+ };
186
+ const simpleValue = escape === undefined ? undefined : simple[escape];
187
+ if (simpleValue !== undefined)
188
+ return simpleValue;
189
+ if (escape !== "u")
190
+ this.fail("JSON_SYNTAX_INVALID", path);
191
+ const codePoint = this.parseHexCodeUnit(path);
192
+ if (codePoint >= 0xd800 && codePoint <= 0xdbff) {
193
+ if (this.source[this.offset] !== "\\" || this.source[this.offset + 1] !== "u") {
194
+ this.fail("UTF8_INVALID", path);
195
+ }
196
+ this.offset += 2;
197
+ const low = this.parseHexCodeUnit(path);
198
+ if (low < 0xdc00 || low > 0xdfff)
199
+ this.fail("UTF8_INVALID", path);
200
+ return String.fromCodePoint(0x10000 + ((codePoint - 0xd800) << 10) + low - 0xdc00);
201
+ }
202
+ if (codePoint >= 0xdc00 && codePoint <= 0xdfff)
203
+ this.fail("UTF8_INVALID", path);
204
+ return String.fromCharCode(codePoint);
205
+ }
206
+ parseHexCodeUnit(path) {
207
+ const value = this.source.slice(this.offset, this.offset + 4);
208
+ if (!/^[0-9a-fA-F]{4}$/u.test(value))
209
+ this.fail("JSON_SYNTAX_INVALID", path);
210
+ this.offset += 4;
211
+ return Number.parseInt(value, 16);
212
+ }
213
+ parseNumber(path) {
214
+ const start = this.offset;
215
+ if (this.consume("-")) {
216
+ if (!isDigit(this.source[this.offset]))
217
+ this.fail("JSON_SYNTAX_INVALID", path);
218
+ }
219
+ if (this.consume("0")) {
220
+ if (isDigit(this.source[this.offset]))
221
+ this.fail("JSON_SYNTAX_INVALID", path);
222
+ }
223
+ else {
224
+ if (!isNonZeroDigit(this.source[this.offset]))
225
+ this.fail("JSON_SYNTAX_INVALID", path);
226
+ while (isDigit(this.source[this.offset]))
227
+ this.offset += 1;
228
+ }
229
+ if (this.consume(".")) {
230
+ if (!isDigit(this.source[this.offset]))
231
+ this.fail("JSON_SYNTAX_INVALID", path);
232
+ while (isDigit(this.source[this.offset]))
233
+ this.offset += 1;
234
+ }
235
+ if (this.source[this.offset] === "e" || this.source[this.offset] === "E") {
236
+ this.offset += 1;
237
+ if (this.source[this.offset] === "+" || this.source[this.offset] === "-")
238
+ this.offset += 1;
239
+ if (!isDigit(this.source[this.offset]))
240
+ this.fail("JSON_SYNTAX_INVALID", path);
241
+ while (isDigit(this.source[this.offset]))
242
+ this.offset += 1;
243
+ }
244
+ const value = Number(this.source.slice(start, this.offset));
245
+ if (!Number.isFinite(value) || (Number.isInteger(value) && !Number.isSafeInteger(value))) {
246
+ this.fail("JSON_NUMBER_UNSAFE", path);
247
+ }
248
+ return value;
249
+ }
250
+ parseLiteral(literal, value) {
251
+ if (this.source.slice(this.offset, this.offset + literal.length) !== literal) {
252
+ this.fail("JSON_SYNTAX_INVALID", "");
253
+ }
254
+ this.offset += literal.length;
255
+ return value;
256
+ }
257
+ skipWhitespace() {
258
+ while (this.source[this.offset] === " " ||
259
+ this.source[this.offset] === "\n" ||
260
+ this.source[this.offset] === "\r" ||
261
+ this.source[this.offset] === "\t") {
262
+ this.offset += 1;
263
+ }
264
+ }
265
+ consume(expected) {
266
+ if (this.source[this.offset] !== expected)
267
+ return false;
268
+ this.offset += 1;
269
+ return true;
270
+ }
271
+ fail(code, path) {
272
+ throw new JsonParseFailure(code, path);
273
+ }
274
+ syntaxFailure() {
275
+ const collector = new diagnostic_collector_js_1.DiagnosticCollector(this.limits);
276
+ collector.addCode("JSON_SYNTAX_INVALID", "input", { position: this.offset });
277
+ return (0, operation_result_js_1.failure)(collector.finish());
278
+ }
279
+ }
280
+ class JsonParseFailure extends Error {
281
+ code;
282
+ path;
283
+ constructor(code, path) {
284
+ super(code);
285
+ this.code = code;
286
+ this.path = path;
287
+ }
288
+ }
289
+ function isDigit(value) {
290
+ return value !== undefined && value >= "0" && value <= "9";
291
+ }
292
+ function isNonZeroDigit(value) {
293
+ return value !== undefined && value >= "1" && value <= "9";
294
+ }
295
+ function escapeJsonPointer(value) {
296
+ return value.replaceAll("~", "~0").replaceAll("/", "~1");
297
+ }
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.validateJsonValue = validateJsonValue;
5
+ const node_util_1 = require("node:util");
6
+ const operation_result_js_1 = require("../domain/operation-result.js");
7
+ const diagnostic_collector_js_1 = require("./diagnostic-collector.js");
8
+ const object_inspection_js_1 = require("./object-inspection.js");
9
+ const utf8_validation_js_1 = require("./utf8-validation.js");
10
+ function validateJsonValue(value, limits) {
11
+ const collector = new diagnostic_collector_js_1.DiagnosticCollector(limits);
12
+ const active = new WeakSet();
13
+ const validated = validateValue(value, "", 0, limits, collector, active);
14
+ const diagnostics = collector.finish();
15
+ if (validated === undefined || collector.hasErrors())
16
+ return (0, operation_result_js_1.failure)(diagnostics);
17
+ return (0, operation_result_js_1.success)(validated, diagnostics);
18
+ }
19
+ function validateValue(value, path, depth, limits, collector, active) {
20
+ if (depth > limits.maxJsonDepth) {
21
+ collector.addCode("INPUT_LIMIT_EXCEEDED", "input", { path });
22
+ return undefined;
23
+ }
24
+ if (value === null || typeof value === "boolean")
25
+ return value;
26
+ if (typeof value === "string")
27
+ return validateString(value, path, limits, collector);
28
+ if (typeof value === "number")
29
+ return validateNumber(value, path, collector);
30
+ if (typeof value !== "object") {
31
+ collector.addCode("JSON_VALUE_UNSUPPORTED", "input", { path });
32
+ return undefined;
33
+ }
34
+ if (node_util_1.types.isProxy(value) || active.has(value)) {
35
+ collector.addCode("JSON_VALUE_UNSUPPORTED", "input", { path });
36
+ return undefined;
37
+ }
38
+ active.add(value);
39
+ try {
40
+ if (Array.isArray(value))
41
+ return validateArray(value, path, depth, limits, collector, active);
42
+ return validateObject(value, path, depth, limits, collector, active);
43
+ }
44
+ finally {
45
+ active.delete(value);
46
+ }
47
+ }
48
+ function validateString(value, path, limits, collector) {
49
+ const byteLength = (0, utf8_validation_js_1.utf8ByteLength)(value);
50
+ if (byteLength === undefined) {
51
+ collector.addCode("UTF8_INVALID", "input", { path });
52
+ return undefined;
53
+ }
54
+ if (byteLength > limits.maxStringBytes) {
55
+ collector.addCode("INPUT_LIMIT_EXCEEDED", "input", { path });
56
+ return undefined;
57
+ }
58
+ return value;
59
+ }
60
+ function validateNumber(value, path, collector) {
61
+ if (!Number.isFinite(value)) {
62
+ collector.addCode("JSON_NUMBER_UNSAFE", "input", { path });
63
+ return undefined;
64
+ }
65
+ if (Number.isInteger(value) && !Number.isSafeInteger(value)) {
66
+ collector.addCode("JSON_NUMBER_UNSAFE", "input", { path });
67
+ return undefined;
68
+ }
69
+ return value;
70
+ }
71
+ function validateArray(value, path, depth, limits, collector, active) {
72
+ const descriptors = Object.getOwnPropertyDescriptors(value);
73
+ const symbols = Object.getOwnPropertySymbols(value);
74
+ const lengthDescriptor = Object.getOwnPropertyDescriptor(value, "length");
75
+ if (symbols.length !== 0 ||
76
+ lengthDescriptor === undefined ||
77
+ !(0, object_inspection_js_1.isDataPropertyDescriptor)(lengthDescriptor)) {
78
+ collector.addCode("JSON_VALUE_UNSUPPORTED", "input", { path });
79
+ return undefined;
80
+ }
81
+ const length = lengthDescriptor.value;
82
+ if (typeof length !== "number" ||
83
+ !Number.isSafeInteger(length) ||
84
+ length > limits.maxArrayElements) {
85
+ collector.addCode("INPUT_LIMIT_EXCEEDED", "input", { path });
86
+ return undefined;
87
+ }
88
+ for (const [name, descriptor] of Object.entries(descriptors)) {
89
+ if (name === "length")
90
+ continue;
91
+ if (!isArrayIndex(name) ||
92
+ descriptor.enumerable !== true ||
93
+ descriptor.get !== undefined ||
94
+ descriptor.set !== undefined) {
95
+ collector.addCode("JSON_VALUE_UNSUPPORTED", "input", { path });
96
+ return undefined;
97
+ }
98
+ }
99
+ const output = [];
100
+ for (let index = 0; index < length; index += 1) {
101
+ const descriptor = descriptors[String(index)];
102
+ if (descriptor === undefined || !(0, object_inspection_js_1.isDataPropertyDescriptor)(descriptor)) {
103
+ collector.addCode("JSON_VALUE_UNSUPPORTED", "input", { path });
104
+ return undefined;
105
+ }
106
+ const itemPath = `${path}/${String(index)}`;
107
+ const item = validateValue(descriptor.value, itemPath, depth + 1, limits, collector, active);
108
+ if (item === undefined)
109
+ return undefined;
110
+ output.push(item);
111
+ }
112
+ return Object.freeze(output);
113
+ }
114
+ function validateObject(value, path, depth, limits, collector, active) {
115
+ const properties = (0, object_inspection_js_1.inspectPlainObject)(value);
116
+ if (properties === undefined) {
117
+ collector.addCode("JSON_VALUE_UNSUPPORTED", "input", { path });
118
+ return undefined;
119
+ }
120
+ if (properties.length > limits.maxObjectProperties) {
121
+ collector.addCode("INPUT_LIMIT_EXCEEDED", "input", { path });
122
+ return undefined;
123
+ }
124
+ const output = {};
125
+ for (const [name, property] of properties) {
126
+ const key = validateString(name, path, limits, collector);
127
+ if (key === undefined)
128
+ return undefined;
129
+ const propertyPath = `${path}/${escapeJsonPointer(key)}`;
130
+ const item = validateValue(property, propertyPath, depth + 1, limits, collector, active);
131
+ if (item === undefined)
132
+ return undefined;
133
+ if (key === "__proto__") {
134
+ Object.defineProperty(output, key, {
135
+ configurable: false,
136
+ enumerable: true,
137
+ value: item,
138
+ writable: false,
139
+ });
140
+ }
141
+ else {
142
+ output[key] = item;
143
+ }
144
+ }
145
+ return Object.freeze(output);
146
+ }
147
+ function isArrayIndex(name) {
148
+ if (!/^(?:0|[1-9][0-9]*)$/u.test(name))
149
+ return false;
150
+ const value = Number(name);
151
+ return (Number.isSafeInteger(value) && value >= 0 && value < 4_294_967_295 && String(value) === name);
152
+ }
153
+ function escapeJsonPointer(value) {
154
+ return value.replaceAll("~", "~0").replaceAll("/", "~1");
155
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.validateLimits = validateLimits;
5
+ exports.validateLimitValue = validateLimitValue;
6
+ const limits_js_1 = require("../domain/limits.js");
7
+ const operation_result_js_1 = require("../domain/operation-result.js");
8
+ const diagnostic_collector_js_1 = require("./diagnostic-collector.js");
9
+ const result_helpers_js_1 = require("./result-helpers.js");
10
+ const object_inspection_js_1 = require("./object-inspection.js");
11
+ const limitKeys = Object.freeze([
12
+ "maxPayloadBytes",
13
+ "maxJsonDepth",
14
+ "maxObjectProperties",
15
+ "maxArrayElements",
16
+ "maxStringBytes",
17
+ "maxNdjsonLineBytes",
18
+ "maxDiagnostics",
19
+ "maxFullRecords",
20
+ ]);
21
+ function validateLimits(value) {
22
+ if (value === undefined)
23
+ return (0, operation_result_js_1.success)(limits_js_1.DEFAULT_LIMITS);
24
+ const properties = (0, object_inspection_js_1.inspectPlainObject)(value);
25
+ if (properties === undefined)
26
+ return (0, result_helpers_js_1.failureWithCode)("INPUT_TYPE_INVALID", "input");
27
+ const provided = new Map(properties);
28
+ for (const name of provided.keys()) {
29
+ if (!isLimitKey(name))
30
+ return (0, result_helpers_js_1.failureWithCode)("INPUT_TYPE_INVALID", "input");
31
+ }
32
+ const entries = {
33
+ maxPayloadBytes: limits_js_1.DEFAULT_LIMITS.maxPayloadBytes,
34
+ maxJsonDepth: limits_js_1.DEFAULT_LIMITS.maxJsonDepth,
35
+ maxObjectProperties: limits_js_1.DEFAULT_LIMITS.maxObjectProperties,
36
+ maxArrayElements: limits_js_1.DEFAULT_LIMITS.maxArrayElements,
37
+ maxStringBytes: limits_js_1.DEFAULT_LIMITS.maxStringBytes,
38
+ maxNdjsonLineBytes: limits_js_1.DEFAULT_LIMITS.maxNdjsonLineBytes,
39
+ maxDiagnostics: limits_js_1.DEFAULT_LIMITS.maxDiagnostics,
40
+ maxFullRecords: limits_js_1.DEFAULT_LIMITS.maxFullRecords,
41
+ };
42
+ for (const name of limitKeys) {
43
+ const candidate = provided.has(name) ? provided.get(name) : limits_js_1.DEFAULT_LIMITS[name];
44
+ if (typeof candidate !== "number" ||
45
+ !Number.isSafeInteger(candidate) ||
46
+ candidate <= 0 ||
47
+ candidate > limits_js_1.HARD_LIMITS[name]) {
48
+ return (0, result_helpers_js_1.failureWithCode)("INPUT_LIMIT_EXCEEDED", "input");
49
+ }
50
+ entries[name] = candidate;
51
+ }
52
+ const limits = {
53
+ maxPayloadBytes: entries.maxPayloadBytes,
54
+ maxJsonDepth: entries.maxJsonDepth,
55
+ maxObjectProperties: entries.maxObjectProperties,
56
+ maxArrayElements: entries.maxArrayElements,
57
+ maxStringBytes: entries.maxStringBytes,
58
+ maxNdjsonLineBytes: entries.maxNdjsonLineBytes,
59
+ maxDiagnostics: entries.maxDiagnostics,
60
+ maxFullRecords: entries.maxFullRecords,
61
+ };
62
+ return (0, operation_result_js_1.success)(Object.freeze(limits));
63
+ }
64
+ function isLimitKey(value) {
65
+ return limitKeys.includes(value);
66
+ }
67
+ function validateLimitValue(value, maximum) {
68
+ if (!Number.isSafeInteger(value) || value <= 0 || value > maximum) {
69
+ return {
70
+ ok: false,
71
+ diagnostics: Object.freeze([(0, diagnostic_collector_js_1.createDiagnostic)("INPUT_LIMIT_EXCEEDED", "input")]),
72
+ };
73
+ }
74
+ return (0, operation_result_js_1.success)(value);
75
+ }
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.inspectPlainObject = inspectPlainObject;
5
+ exports.inspectExactProperties = inspectExactProperties;
6
+ exports.isDataPropertyDescriptor = isDataPropertyDescriptor;
7
+ exports.isPlainObject = isPlainObject;
8
+ const node_util_1 = require("node:util");
9
+ function inspectPlainObject(value) {
10
+ if (!isPlainObject(value))
11
+ return undefined;
12
+ if (Object.getOwnPropertySymbols(value).length !== 0)
13
+ return undefined;
14
+ const descriptors = Object.getOwnPropertyDescriptors(value);
15
+ const entries = [];
16
+ for (const [name, descriptor] of Object.entries(descriptors)) {
17
+ if (descriptor.enumerable !== true ||
18
+ descriptor.get !== undefined ||
19
+ descriptor.set !== undefined ||
20
+ !isDataPropertyDescriptor(descriptor)) {
21
+ return undefined;
22
+ }
23
+ entries.push([name, descriptor.value]);
24
+ }
25
+ return Object.freeze(entries);
26
+ }
27
+ /** Internal fixed-shape inspection that preserves the no-getter/no-proxy boundary. */
28
+ function inspectExactProperties(value, names) {
29
+ if (!isPlainObject(value))
30
+ return undefined;
31
+ if (Object.getOwnPropertySymbols(value).length !== 0)
32
+ return undefined;
33
+ const ownNames = Object.getOwnPropertyNames(value);
34
+ if (ownNames.length !== names.length)
35
+ return undefined;
36
+ const descriptors = Object.getOwnPropertyDescriptors(value);
37
+ const values = [];
38
+ for (const name of names) {
39
+ const descriptor = descriptors[name];
40
+ if (descriptor === undefined)
41
+ return undefined;
42
+ if (descriptor.enumerable !== true ||
43
+ descriptor.get !== undefined ||
44
+ descriptor.set !== undefined ||
45
+ !isDataPropertyDescriptor(descriptor)) {
46
+ return undefined;
47
+ }
48
+ values.push(descriptor.value);
49
+ }
50
+ return values;
51
+ }
52
+ function isDataPropertyDescriptor(descriptor) {
53
+ return "value" in descriptor;
54
+ }
55
+ function isPlainObject(value) {
56
+ if (typeof value !== "object" || value === null || node_util_1.types.isProxy(value))
57
+ return false;
58
+ const prototype = Reflect.getPrototypeOf(value);
59
+ return prototype === Object.prototype || prototype === null;
60
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.validatePosition = validatePosition;
5
+ const position_js_1 = require("../domain/position.js");
6
+ const operation_result_js_1 = require("../domain/operation-result.js");
7
+ const result_helpers_js_1 = require("./result-helpers.js");
8
+ function validatePosition(value) {
9
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
10
+ return (0, result_helpers_js_1.failureWithCode)("INPUT_TYPE_INVALID", "input");
11
+ }
12
+ return (0, operation_result_js_1.success)(position_js_1.Position.fromValidated(value));
13
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.failureWithCode = failureWithCode;
5
+ const operation_result_js_1 = require("../domain/operation-result.js");
6
+ const diagnostic_collector_js_1 = require("./diagnostic-collector.js");
7
+ function failureWithCode(code, phase) {
8
+ return (0, operation_result_js_1.failure)([(0, diagnostic_collector_js_1.createDiagnostic)(code, phase)]);
9
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.hasWellFormedUnicode = hasWellFormedUnicode;
5
+ exports.utf8ByteLength = utf8ByteLength;
6
+ exports.encodeUtf8 = encodeUtf8;
7
+ exports.decodeUtf8 = decodeUtf8;
8
+ const operation_result_js_1 = require("../domain/operation-result.js");
9
+ const result_helpers_js_1 = require("./result-helpers.js");
10
+ const encoder = new TextEncoder();
11
+ const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: false });
12
+ function hasWellFormedUnicode(value) {
13
+ for (let index = 0; index < value.length; index += 1) {
14
+ const codeUnit = value.charCodeAt(index);
15
+ if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
16
+ const next = value.charCodeAt(index + 1);
17
+ if (Number.isNaN(next) || next < 0xdc00 || next > 0xdfff)
18
+ return false;
19
+ index += 1;
20
+ }
21
+ else if (codeUnit >= 0xdc00 && codeUnit <= 0xdfff) {
22
+ return false;
23
+ }
24
+ }
25
+ return true;
26
+ }
27
+ function utf8ByteLength(value) {
28
+ let length = 0;
29
+ for (let index = 0; index < value.length; index += 1) {
30
+ const codeUnit = value.charCodeAt(index);
31
+ if (codeUnit <= 0x7f)
32
+ length += 1;
33
+ else if (codeUnit <= 0x7ff)
34
+ length += 2;
35
+ else if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
36
+ const next = value.charCodeAt(index + 1);
37
+ if (Number.isNaN(next) || next < 0xdc00 || next > 0xdfff)
38
+ return undefined;
39
+ length += 4;
40
+ index += 1;
41
+ }
42
+ else if (codeUnit >= 0xdc00 && codeUnit <= 0xdfff)
43
+ return undefined;
44
+ else
45
+ length += 3;
46
+ }
47
+ return length;
48
+ }
49
+ function encodeUtf8(value, maxBytes) {
50
+ if (typeof value !== "string" || !hasWellFormedUnicode(value)) {
51
+ return (0, result_helpers_js_1.failureWithCode)("UTF8_INVALID", "input");
52
+ }
53
+ const bytes = encoder.encode(value);
54
+ if (bytes.length > maxBytes)
55
+ return (0, result_helpers_js_1.failureWithCode)("INPUT_LIMIT_EXCEEDED", "input");
56
+ return (0, operation_result_js_1.success)(bytes);
57
+ }
58
+ function decodeUtf8(value) {
59
+ if (value.length >= 3 && value[0] === 0xef && value[1] === 0xbb && value[2] === 0xbf) {
60
+ return (0, result_helpers_js_1.failureWithCode)("UTF8_INVALID", "input");
61
+ }
62
+ try {
63
+ const decoded = decoder.decode(value);
64
+ return (0, operation_result_js_1.success)(decoded);
65
+ }
66
+ catch {
67
+ return (0, result_helpers_js_1.failureWithCode)("UTF8_INVALID", "input");
68
+ }
69
+ }