@naeemo/capnp 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,549 @@
1
+ #!/usr/bin/env node
2
+ import { n as MessageBuilder, r as ElementSize, t as MessageReader } from "./message-reader-fw2PY8sU.js";
3
+ import { t as SchemaNodeType } from "./schema-types-B6M2jsM7.js";
4
+ import { readFileSync, writeFileSync } from "node:fs";
5
+
6
+ //#region src/json/index.ts
7
+ const bytesToBase64 = (bytes) => Buffer.from(bytes).toString("base64");
8
+ const base64ToBytes = (base64) => Buffer.from(base64, "base64");
9
+ /**
10
+ * Cap'n Proto to JSON converter
11
+ */
12
+ var CapnpToJson = class {
13
+ options;
14
+ schemaRegistry;
15
+ constructor(schemaRegistry, options = {}) {
16
+ this.schemaRegistry = schemaRegistry;
17
+ this.options = options;
18
+ }
19
+ /**
20
+ * Convert a Cap'n Proto struct to JSON
21
+ */
22
+ convert(reader, schema) {
23
+ if (schema.type !== SchemaNodeType.STRUCT || !schema.structInfo) throw new Error(`Cannot convert non-struct type to JSON: ${schema.type}`);
24
+ const result = {};
25
+ for (const field of schema.structInfo.fields) {
26
+ const fieldName = this.getJsonFieldName(field.name);
27
+ const value = this.readField(reader, field);
28
+ if (value !== null || this.options.includeNulls) result[fieldName] = value;
29
+ }
30
+ return result;
31
+ }
32
+ getJsonFieldName(capnpName) {
33
+ if (this.options.fieldNameMap?.[capnpName]) return this.options.fieldNameMap[capnpName];
34
+ if (this.options.preserveFieldNames) return capnpName;
35
+ return capnpName.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
36
+ }
37
+ readField(reader, field) {
38
+ const type = field.type;
39
+ if (this.isPointerType(type.kind.type)) {
40
+ const pointerIndex = field.codeOrder;
41
+ if (type.kind.type === "text") {
42
+ if (reader.getText(pointerIndex) === "") return "";
43
+ }
44
+ }
45
+ return this.readValue(reader, field);
46
+ }
47
+ isPointerType(type) {
48
+ return type === "text" || type === "data" || type === "list" || type === "struct";
49
+ }
50
+ readValue(reader, field) {
51
+ const kind = field.type.kind;
52
+ switch (kind.type) {
53
+ case "void": return null;
54
+ case "bool": return reader.getBool(field.offset * 8);
55
+ case "int8": return reader.getInt8(field.offset);
56
+ case "int16": return reader.getInt16(field.offset);
57
+ case "int32": return reader.getInt32(field.offset);
58
+ case "int64": return reader.getInt64(field.offset).toString();
59
+ case "uint8": return reader.getUint8(field.offset);
60
+ case "uint16": return reader.getUint16(field.offset);
61
+ case "uint32": return reader.getUint32(field.offset);
62
+ case "uint64": return reader.getUint64(field.offset).toString();
63
+ case "float32": return reader.getFloat32(field.offset);
64
+ case "float64": return reader.getFloat64(field.offset);
65
+ case "text": return reader.getText(field.codeOrder) ?? "";
66
+ case "data": {
67
+ const data = reader.getData(field.codeOrder);
68
+ if (data === void 0) return null;
69
+ return bytesToBase64(data);
70
+ }
71
+ case "list": {
72
+ const listReader = reader.getList(field.codeOrder, ElementSize.INLINE_COMPOSITE);
73
+ if (!listReader) return null;
74
+ return this.readList(listReader, kind.elementType);
75
+ }
76
+ case "struct": {
77
+ const nestedSchema = this.schemaRegistry.get(kind.typeId);
78
+ if (!nestedSchema) throw new Error(`Schema not found for struct type ${kind.typeId.toString(16)}`);
79
+ if (nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) throw new Error(`Invalid schema for struct type ${kind.typeId.toString(16)}`);
80
+ const nestedReader = reader.getStruct(field.codeOrder, nestedSchema.structInfo.dataWordCount, nestedSchema.structInfo.pointerCount);
81
+ if (!nestedReader) return null;
82
+ return this.convert(nestedReader, nestedSchema);
83
+ }
84
+ case "enum": return reader.getUint16(field.offset);
85
+ case "interface": return { $cap: `cap-${field.codeOrder}` };
86
+ case "anyPointer": return { $ptr: "[anyPointer]" };
87
+ default: return null;
88
+ }
89
+ }
90
+ readList(listReader, elementType) {
91
+ const length = listReader.length;
92
+ const result = [];
93
+ for (let i = 0; i < length; i++) switch (elementType.kind.type) {
94
+ case "void":
95
+ result.push(null);
96
+ break;
97
+ case "bool":
98
+ result.push(listReader.getPrimitive(i) !== 0);
99
+ break;
100
+ case "int8":
101
+ case "uint8":
102
+ result.push(Number(listReader.getPrimitive(i)));
103
+ break;
104
+ case "int16":
105
+ case "uint16":
106
+ result.push(Number(listReader.getPrimitive(i)));
107
+ break;
108
+ case "int32":
109
+ case "uint32":
110
+ result.push(Number(listReader.getPrimitive(i)));
111
+ break;
112
+ case "int64":
113
+ case "uint64":
114
+ result.push(listReader.getPrimitive(i).toString());
115
+ break;
116
+ case "float32":
117
+ case "float64":
118
+ result.push(Number(listReader.getPrimitive(i)));
119
+ break;
120
+ case "text": {
121
+ const structReader = listReader.getStruct(i);
122
+ if (!structReader) {
123
+ result.push(null);
124
+ break;
125
+ }
126
+ const text = structReader.getText(0);
127
+ result.push(text ?? "");
128
+ break;
129
+ }
130
+ case "data": {
131
+ const structReader = listReader.getStruct(i);
132
+ if (!structReader) {
133
+ result.push(null);
134
+ break;
135
+ }
136
+ const data = structReader.getData(0);
137
+ if (data === void 0) result.push(null);
138
+ else result.push(bytesToBase64(data));
139
+ break;
140
+ }
141
+ case "struct": {
142
+ const nestedSchema = this.schemaRegistry.get(elementType.kind.typeId);
143
+ if (!nestedSchema) throw new Error(`Schema not found for struct list element type ${elementType.kind.typeId.toString(16)}`);
144
+ if (nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) throw new Error(`Invalid schema for struct list element type ${elementType.kind.typeId.toString(16)}`);
145
+ const structReader = listReader.getStruct(i);
146
+ if (!structReader) {
147
+ result.push(null);
148
+ break;
149
+ }
150
+ result.push(this.convert(structReader, nestedSchema));
151
+ break;
152
+ }
153
+ case "enum":
154
+ result.push(Number(listReader.getPrimitive(i)));
155
+ break;
156
+ case "list": {
157
+ const structReader = listReader.getStruct(i);
158
+ if (!structReader) {
159
+ result.push(null);
160
+ break;
161
+ }
162
+ const nestedList = structReader.getList(0, ElementSize.INLINE_COMPOSITE);
163
+ if (!nestedList) result.push(null);
164
+ else result.push(this.readList(nestedList, elementType.kind.elementType));
165
+ break;
166
+ }
167
+ default: result.push(null);
168
+ }
169
+ return result;
170
+ }
171
+ /**
172
+ * Convert to JSON string
173
+ */
174
+ stringify(reader, schema) {
175
+ const json = this.convert(reader, schema);
176
+ const space = this.options.pretty ? this.options.indent ?? 2 : void 0;
177
+ return JSON.stringify(json, null, space);
178
+ }
179
+ };
180
+ /**
181
+ * JSON to Cap'n Proto converter
182
+ */
183
+ var JsonToCapnp = class {
184
+ options;
185
+ schemaRegistry;
186
+ constructor(schemaRegistry, options = {}) {
187
+ this.schemaRegistry = schemaRegistry;
188
+ this.options = options;
189
+ }
190
+ /**
191
+ * Convert JSON to Cap'n Proto struct
192
+ */
193
+ convert(json, schema, builder) {
194
+ if (schema.type !== SchemaNodeType.STRUCT || !schema.structInfo) throw new Error(`Cannot convert to non-struct type: ${schema.type}`);
195
+ if (typeof json !== "object" || json === null) throw new Error("JSON value must be an object");
196
+ const jsonObj = json;
197
+ for (const field of schema.structInfo.fields) {
198
+ const value = jsonObj[this.getJsonFieldName(field.name)];
199
+ if (value !== void 0 && value !== null) this.writeField(builder, field, value);
200
+ }
201
+ }
202
+ /**
203
+ * Convert JSON to new Cap'n Proto message
204
+ */
205
+ convertToMessage(json, schema) {
206
+ if (schema.type !== SchemaNodeType.STRUCT || !schema.structInfo) throw new Error(`Cannot convert to non-struct type: ${schema.type}`);
207
+ const builder = new MessageBuilder();
208
+ const structBuilder = builder.initRoot(schema.structInfo.dataWordCount, schema.structInfo.pointerCount);
209
+ this.convert(json, schema, structBuilder);
210
+ return builder;
211
+ }
212
+ getJsonFieldName(capnpName) {
213
+ if (this.options.fieldNameMap?.[capnpName]) return this.options.fieldNameMap[capnpName];
214
+ if (this.options.preserveFieldNames) return capnpName;
215
+ return capnpName.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
216
+ }
217
+ writeField(builder, field, value) {
218
+ const kind = field.type.kind;
219
+ switch (kind.type) {
220
+ case "void": break;
221
+ case "bool":
222
+ builder.setBool(field.offset * 8, Boolean(value));
223
+ break;
224
+ case "int8":
225
+ builder.setInt8(field.offset, Number(value));
226
+ break;
227
+ case "int16":
228
+ builder.setInt16(field.offset, Number(value));
229
+ break;
230
+ case "int32":
231
+ builder.setInt32(field.offset, Number(value));
232
+ break;
233
+ case "int64":
234
+ builder.setInt64(field.offset, BigInt(value));
235
+ break;
236
+ case "uint8":
237
+ builder.setUint8(field.offset, Number(value));
238
+ break;
239
+ case "uint16":
240
+ builder.setUint16(field.offset, Number(value));
241
+ break;
242
+ case "uint32":
243
+ builder.setUint32(field.offset, Number(value));
244
+ break;
245
+ case "uint64":
246
+ builder.setUint64(field.offset, BigInt(value));
247
+ break;
248
+ case "float32":
249
+ builder.setFloat32(field.offset, Number(value));
250
+ break;
251
+ case "float64":
252
+ builder.setFloat64(field.offset, Number(value));
253
+ break;
254
+ case "text":
255
+ builder.setText(field.codeOrder, String(value));
256
+ break;
257
+ case "data":
258
+ if (typeof value === "string") builder.setData(field.codeOrder, base64ToBytes(value));
259
+ break;
260
+ case "list":
261
+ if (Array.isArray(value)) this.writeList(builder, field, value, kind.elementType);
262
+ break;
263
+ case "struct": {
264
+ const nestedSchema = this.schemaRegistry.get(kind.typeId);
265
+ if (!nestedSchema) throw new Error(`Schema not found for struct type ${kind.typeId.toString(16)}`);
266
+ if (nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) throw new Error(`Invalid schema for struct type ${kind.typeId.toString(16)}`);
267
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Expected object for struct field ${field.name}`);
268
+ const nestedBuilder = builder.initStruct(field.codeOrder, nestedSchema.structInfo.dataWordCount, nestedSchema.structInfo.pointerCount);
269
+ this.convert(value, nestedSchema, nestedBuilder);
270
+ break;
271
+ }
272
+ case "enum":
273
+ if (typeof value === "number") builder.setUint16(field.offset, value);
274
+ else if (typeof value === "string") builder.setUint16(field.offset, 0);
275
+ break;
276
+ case "interface":
277
+ case "anyPointer": break;
278
+ }
279
+ }
280
+ writeList(builder, field, values, elementType) {
281
+ const elementCount = values.length;
282
+ if (elementCount === 0) return;
283
+ let elementSize;
284
+ let structSize;
285
+ switch (elementType.kind.type) {
286
+ case "bool":
287
+ elementSize = ElementSize.BIT;
288
+ break;
289
+ case "int8":
290
+ case "uint8":
291
+ elementSize = ElementSize.BYTE;
292
+ break;
293
+ case "int16":
294
+ case "uint16":
295
+ elementSize = ElementSize.TWO_BYTES;
296
+ break;
297
+ case "int32":
298
+ case "uint32":
299
+ case "float32":
300
+ elementSize = ElementSize.FOUR_BYTES;
301
+ break;
302
+ case "int64":
303
+ case "uint64":
304
+ case "float64":
305
+ elementSize = ElementSize.EIGHT_BYTES;
306
+ break;
307
+ case "text":
308
+ case "data":
309
+ elementSize = ElementSize.INLINE_COMPOSITE;
310
+ structSize = {
311
+ dataWords: 0,
312
+ pointerCount: 1
313
+ };
314
+ break;
315
+ case "struct": {
316
+ const nestedSchema = this.schemaRegistry.get(elementType.kind.typeId);
317
+ if (!nestedSchema || nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) throw new Error(`Schema not found for struct list element type ${elementType.kind.typeId.toString(16)}`);
318
+ elementSize = ElementSize.INLINE_COMPOSITE;
319
+ structSize = {
320
+ dataWords: nestedSchema.structInfo.dataWordCount,
321
+ pointerCount: nestedSchema.structInfo.pointerCount
322
+ };
323
+ break;
324
+ }
325
+ case "list":
326
+ elementSize = ElementSize.INLINE_COMPOSITE;
327
+ structSize = {
328
+ dataWords: 0,
329
+ pointerCount: 1
330
+ };
331
+ break;
332
+ default: elementSize = ElementSize.INLINE_COMPOSITE;
333
+ }
334
+ const listBuilder = builder.initList(field.codeOrder, elementSize, elementCount, structSize);
335
+ for (let i = 0; i < elementCount; i++) {
336
+ const value = values[i];
337
+ switch (elementType.kind.type) {
338
+ case "bool":
339
+ listBuilder.setPrimitive(i, value ? 1 : 0);
340
+ break;
341
+ case "int8":
342
+ case "uint8":
343
+ listBuilder.setPrimitive(i, Number(value));
344
+ break;
345
+ case "int16":
346
+ case "uint16":
347
+ listBuilder.setPrimitive(i, Number(value));
348
+ break;
349
+ case "int32":
350
+ case "uint32":
351
+ listBuilder.setPrimitive(i, Number(value));
352
+ break;
353
+ case "int64":
354
+ case "uint64":
355
+ listBuilder.setPrimitive(i, BigInt(value));
356
+ break;
357
+ case "float32":
358
+ case "float64":
359
+ listBuilder.setPrimitive(i, Number(value));
360
+ break;
361
+ case "text":
362
+ listBuilder.getStruct(i).setText(0, String(value));
363
+ break;
364
+ case "data": {
365
+ const structBuilder = listBuilder.getStruct(i);
366
+ if (typeof value === "string") structBuilder.setData(0, base64ToBytes(value));
367
+ break;
368
+ }
369
+ case "struct": {
370
+ const nestedSchema = this.schemaRegistry.get(elementType.kind.typeId);
371
+ if (!nestedSchema || nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) throw new Error(`Schema not found for struct list element type ${elementType.kind.typeId.toString(16)}`);
372
+ const structBuilder = listBuilder.getStruct(i);
373
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Expected object for struct list element at index ${i}`);
374
+ this.convert(value, nestedSchema, structBuilder);
375
+ break;
376
+ }
377
+ case "list": {
378
+ const structBuilder = listBuilder.getStruct(i);
379
+ if (!Array.isArray(value)) throw new Error(`Expected array for nested list at index ${i}`);
380
+ const syntheticField = {
381
+ name: "",
382
+ codeOrder: 0,
383
+ discriminantValue: 65535,
384
+ offset: 0,
385
+ type: { kind: elementType.kind },
386
+ hadExplicitDefault: false
387
+ };
388
+ this.writeList(structBuilder, syntheticField, value, elementType.kind.elementType);
389
+ break;
390
+ }
391
+ case "enum":
392
+ listBuilder.setPrimitive(i, Number(value));
393
+ break;
394
+ default: break;
395
+ }
396
+ }
397
+ }
398
+ /**
399
+ * Parse JSON string and convert to Cap'n Proto
400
+ */
401
+ parse(jsonString, schema) {
402
+ const json = JSON.parse(jsonString);
403
+ return this.convertToMessage(json, schema);
404
+ }
405
+ };
406
+
407
+ //#endregion
408
+ //#region src/json/cli.ts
409
+ /**
410
+ * JSON Codec CLI
411
+ *
412
+ * Convert between Cap'n Proto binary and JSON
413
+ *
414
+ * Usage: capnp json <command> [options]
415
+ */
416
+ const VERSION = "0.7.0";
417
+ function printUsage() {
418
+ console.log(`
419
+ Cap'n Proto JSON Codec v${VERSION}
420
+
421
+ Usage: capnp json <command> [options]
422
+
423
+ Commands:
424
+ to-json Convert Cap'n Proto binary to JSON
425
+ from-json Convert JSON to Cap'n Proto binary
426
+
427
+ Options:
428
+ -i, --input Input file path (required)
429
+ -o, --output Output file path (default: stdout for to-json, required for from-json)
430
+ -s, --schema Schema file path (JSON format, required)
431
+ -p, --pretty Pretty print JSON output (to-json only)
432
+ --preserve-names Preserve original field names (don't convert to camelCase)
433
+ --include-nulls Include null fields in JSON output (to-json only)
434
+ -h, --help Show this help
435
+
436
+ Examples:
437
+ capnp json to-json -i data.bin -s schema.json -o data.json
438
+ capnp json to-json -i data.bin -s schema.json -p
439
+ capnp json from-json -i data.json -s schema.json -o data.bin
440
+ `);
441
+ }
442
+ function parseArgs(args) {
443
+ const options = {};
444
+ for (let i = 0; i < args.length; i++) {
445
+ const arg = args[i];
446
+ switch (arg) {
447
+ case "to-json":
448
+ case "from-json":
449
+ options.command = arg;
450
+ break;
451
+ case "-i":
452
+ case "--input":
453
+ options.input = args[++i];
454
+ break;
455
+ case "-o":
456
+ case "--output":
457
+ options.output = args[++i];
458
+ break;
459
+ case "-s":
460
+ case "--schema":
461
+ options.schema = args[++i];
462
+ break;
463
+ case "-p":
464
+ case "--pretty":
465
+ options.pretty = true;
466
+ break;
467
+ case "--preserve-names":
468
+ options.preserveNames = true;
469
+ break;
470
+ case "--include-nulls":
471
+ options.includeNulls = true;
472
+ break;
473
+ case "-h":
474
+ case "--help":
475
+ printUsage();
476
+ process.exit(0);
477
+ }
478
+ }
479
+ return options;
480
+ }
481
+ function loadSchema(schemaPath) {
482
+ const schemaJson = readFileSync(schemaPath, "utf-8");
483
+ const schema = JSON.parse(schemaJson);
484
+ if (typeof schema.id === "string") schema.id = BigInt(schema.id);
485
+ if (schema.type !== SchemaNodeType.STRUCT) throw new Error(`Schema must be a struct type, got: ${schema.type}`);
486
+ return schema;
487
+ }
488
+ async function toJsonCommand(options) {
489
+ const schema = loadSchema(options.schema);
490
+ const structReader = new MessageReader(readFileSync(options.input)).getRoot(schema.structInfo?.dataWordCount ?? 0, schema.structInfo?.pointerCount ?? 0);
491
+ const schemaRegistry = /* @__PURE__ */ new Map();
492
+ schemaRegistry.set(schema.id, schema);
493
+ const json = new CapnpToJson(schemaRegistry, {
494
+ pretty: options.pretty,
495
+ preserveFieldNames: options.preserveNames,
496
+ includeNulls: options.includeNulls
497
+ }).stringify(structReader, schema);
498
+ if (options.output && options.output !== "-") {
499
+ writeFileSync(options.output, json);
500
+ console.error(`Written to ${options.output}`);
501
+ } else console.log(json);
502
+ }
503
+ async function fromJsonCommand(options) {
504
+ const schema = loadSchema(options.schema);
505
+ const jsonContent = readFileSync(options.input, "utf-8");
506
+ const schemaRegistry = /* @__PURE__ */ new Map();
507
+ schemaRegistry.set(schema.id, schema);
508
+ const messageBuilder = new JsonToCapnp(schemaRegistry, { preserveFieldNames: options.preserveNames }).parse(jsonContent, schema);
509
+ const buffer = Buffer.from(messageBuilder.toArrayBuffer());
510
+ if (options.output) {
511
+ writeFileSync(options.output, buffer);
512
+ console.error(`Written to ${options.output} (${buffer.length} bytes)`);
513
+ } else {
514
+ console.error("Error: Output file required for from-json (use -o)");
515
+ process.exit(1);
516
+ }
517
+ }
518
+ async function run(args) {
519
+ const options = parseArgs(args);
520
+ if (!options.command) {
521
+ console.error("Error: No command specified");
522
+ printUsage();
523
+ process.exit(1);
524
+ }
525
+ if (!options.input) {
526
+ console.error("Error: No input file specified (use -i)");
527
+ process.exit(1);
528
+ }
529
+ if (!options.schema) {
530
+ console.error("Error: No schema file specified (use -s)");
531
+ process.exit(1);
532
+ }
533
+ try {
534
+ if (options.command === "to-json") await toJsonCommand(options);
535
+ else if (options.command === "from-json") await fromJsonCommand(options);
536
+ else {
537
+ console.error(`Error: Unknown command: ${options.command}`);
538
+ printUsage();
539
+ process.exit(1);
540
+ }
541
+ } catch (err) {
542
+ console.error("Error:", err instanceof Error ? err.message : err);
543
+ process.exit(1);
544
+ }
545
+ }
546
+
547
+ //#endregion
548
+ export { run };
549
+ //# sourceMappingURL=cli-DwbiXeKw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-DwbiXeKw.js","names":[],"sources":["../src/json/index.ts","../src/json/cli.ts"],"sourcesContent":["/**\n * JSON Codec implementation for Cap'n Proto\n *\n * Bidirectional conversion between Cap'n Proto and JSON\n */\n\nimport type { ListBuilder, ListReader, StructBuilder, StructReader } from '../core/index.js';\nimport { MessageBuilder } from '../core/index.js';\nimport { ElementSize } from '../core/pointer.js';\nimport type { SchemaField, SchemaNode, SchemaType } from '../rpc/schema-types.js';\nimport { SchemaNodeType } from '../rpc/schema-types.js';\n\nexport interface JsonCodecOptions {\n /** Use field names from schema instead of JSON camelCase */\n preserveFieldNames?: boolean;\n /** Custom field name mappings */\n fieldNameMap?: Record<string, string>;\n /** Include null fields in output */\n includeNulls?: boolean;\n /** Pretty print JSON */\n pretty?: boolean;\n /** Indent size for pretty print */\n indent?: number;\n}\n\nexport type JsonValue =\n | null\n | boolean\n | number\n | string\n | JsonValue[]\n | { [key: string]: JsonValue };\n\n// ============================================================================\n// Base64 Helpers\n// ============================================================================\n\nconst bytesToBase64 = (bytes: Uint8Array): string => Buffer.from(bytes).toString('base64');\nconst base64ToBytes = (base64: string): Uint8Array => Buffer.from(base64, 'base64');\n\n// ============================================================================\n// Cap'n Proto to JSON\n// ============================================================================\n\n/**\n * Cap'n Proto to JSON converter\n */\nexport class CapnpToJson {\n private options: JsonCodecOptions;\n private schemaRegistry: Map<bigint, SchemaNode>;\n\n constructor(schemaRegistry: Map<bigint, SchemaNode>, options: JsonCodecOptions = {}) {\n this.schemaRegistry = schemaRegistry;\n this.options = options;\n }\n\n /**\n * Convert a Cap'n Proto struct to JSON\n */\n convert(reader: StructReader, schema: SchemaNode): JsonValue {\n if (schema.type !== SchemaNodeType.STRUCT || !schema.structInfo) {\n throw new Error(`Cannot convert non-struct type to JSON: ${schema.type}`);\n }\n\n const result: Record<string, JsonValue> = {};\n\n for (const field of schema.structInfo.fields) {\n const fieldName = this.getJsonFieldName(field.name);\n const value = this.readField(reader, field);\n\n if (value !== null || this.options.includeNulls) {\n result[fieldName] = value;\n }\n }\n\n return result;\n }\n\n private getJsonFieldName(capnpName: string): string {\n if (this.options.fieldNameMap?.[capnpName]) {\n return this.options.fieldNameMap[capnpName];\n }\n\n if (this.options.preserveFieldNames) {\n return capnpName;\n }\n\n // Convert snake_case to camelCase\n return capnpName.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n }\n\n private readField(reader: StructReader, field: SchemaField): JsonValue {\n const type = field.type;\n\n // Check if pointer field is null (text field returns empty string if not set)\n if (this.isPointerType(type.kind.type)) {\n const pointerIndex = field.codeOrder;\n if (type.kind.type === 'text') {\n const text = reader.getText(pointerIndex);\n // Simple heuristic: if text is empty, field might be null\n // This isn't perfect but works for most cases\n if (text === '') {\n // Could be null or empty string - return empty string\n return '';\n }\n }\n }\n\n return this.readValue(reader, field);\n }\n\n private isPointerType(type: string): boolean {\n return type === 'text' || type === 'data' || type === 'list' || type === 'struct';\n }\n\n private readValue(reader: StructReader, field: SchemaField): JsonValue {\n const kind = field.type.kind;\n\n switch (kind.type) {\n case 'void':\n return null;\n\n case 'bool':\n return reader.getBool(field.offset * 8);\n\n case 'int8':\n return reader.getInt8(field.offset);\n\n case 'int16':\n return reader.getInt16(field.offset);\n\n case 'int32':\n return reader.getInt32(field.offset);\n\n case 'int64':\n return reader.getInt64(field.offset).toString();\n\n case 'uint8':\n return reader.getUint8(field.offset);\n\n case 'uint16':\n return reader.getUint16(field.offset);\n\n case 'uint32':\n return reader.getUint32(field.offset);\n\n case 'uint64':\n return reader.getUint64(field.offset).toString();\n\n case 'float32':\n return reader.getFloat32(field.offset);\n\n case 'float64':\n return reader.getFloat64(field.offset);\n\n case 'text': {\n const text = reader.getText(field.codeOrder);\n return text ?? '';\n }\n\n case 'data': {\n const data = reader.getData(field.codeOrder);\n if (data === undefined) return null;\n return bytesToBase64(data);\n }\n\n case 'list': {\n const listReader = reader.getList<unknown>(field.codeOrder, ElementSize.INLINE_COMPOSITE);\n if (!listReader) return null;\n return this.readList(listReader, kind.elementType);\n }\n\n case 'struct': {\n const nestedSchema = this.schemaRegistry.get(kind.typeId);\n if (!nestedSchema) {\n throw new Error(`Schema not found for struct type ${kind.typeId.toString(16)}`);\n }\n if (nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) {\n throw new Error(`Invalid schema for struct type ${kind.typeId.toString(16)}`);\n }\n const nestedReader = reader.getStruct(\n field.codeOrder,\n nestedSchema.structInfo.dataWordCount,\n nestedSchema.structInfo.pointerCount\n );\n if (!nestedReader) return null;\n return this.convert(nestedReader, nestedSchema);\n }\n\n case 'enum': {\n // Return numeric value, could map to name if we had enum schema\n const value = reader.getUint16(field.offset);\n return value;\n }\n\n case 'interface':\n return { $cap: `cap-${field.codeOrder}` };\n\n case 'anyPointer':\n return { $ptr: '[anyPointer]' };\n\n default:\n return null;\n }\n }\n\n private readList(listReader: ListReader<unknown>, elementType: SchemaType): JsonValue[] {\n const length = listReader.length;\n const result: JsonValue[] = [];\n\n for (let i = 0; i < length; i++) {\n switch (elementType.kind.type) {\n case 'void':\n result.push(null);\n break;\n\n case 'bool':\n // BIT list uses primitive encoding\n result.push(listReader.getPrimitive(i) !== 0);\n break;\n\n case 'int8':\n case 'uint8':\n result.push(Number(listReader.getPrimitive(i)));\n break;\n\n case 'int16':\n case 'uint16':\n result.push(Number(listReader.getPrimitive(i)));\n break;\n\n case 'int32':\n case 'uint32':\n result.push(Number(listReader.getPrimitive(i)));\n break;\n\n case 'int64':\n case 'uint64':\n result.push(listReader.getPrimitive(i).toString());\n break;\n\n case 'float32':\n case 'float64':\n // Floats are stored as raw bytes, need special handling\n result.push(Number(listReader.getPrimitive(i)));\n break;\n\n case 'text': {\n // Text in list is stored as a pointer in each struct element\n const structReader = listReader.getStruct(i);\n if (!structReader) {\n result.push(null);\n break;\n }\n // Text is at pointer index 0 in the struct\n const text = structReader.getText(0);\n result.push(text ?? '');\n break;\n }\n\n case 'data': {\n const structReader = listReader.getStruct(i);\n if (!structReader) {\n result.push(null);\n break;\n }\n const data = structReader.getData(0);\n if (data === undefined) {\n result.push(null);\n } else {\n result.push(bytesToBase64(data));\n }\n break;\n }\n\n case 'struct': {\n const nestedSchema = this.schemaRegistry.get(elementType.kind.typeId);\n if (!nestedSchema) {\n throw new Error(\n `Schema not found for struct list element type ${elementType.kind.typeId.toString(16)}`\n );\n }\n if (nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) {\n throw new Error(\n `Invalid schema for struct list element type ${elementType.kind.typeId.toString(16)}`\n );\n }\n const structReader = listReader.getStruct(i);\n if (!structReader) {\n result.push(null);\n break;\n }\n result.push(this.convert(structReader, nestedSchema));\n break;\n }\n\n case 'enum': {\n result.push(Number(listReader.getPrimitive(i)));\n break;\n }\n\n case 'list': {\n // Nested list - get the list reader from pointer index 0\n const structReader = listReader.getStruct(i);\n if (!structReader) {\n result.push(null);\n break;\n }\n const nestedList = structReader.getList(0, ElementSize.INLINE_COMPOSITE);\n if (!nestedList) {\n result.push(null);\n } else {\n result.push(this.readList(nestedList, elementType.kind.elementType));\n }\n break;\n }\n\n default:\n result.push(null);\n }\n }\n\n return result;\n }\n\n /**\n * Convert to JSON string\n */\n stringify(reader: StructReader, schema: SchemaNode): string {\n const json = this.convert(reader, schema);\n const space = this.options.pretty ? (this.options.indent ?? 2) : undefined;\n return JSON.stringify(json, null, space);\n }\n}\n\n// ============================================================================\n// JSON to Cap'n Proto\n// ============================================================================\n\n/**\n * JSON to Cap'n Proto converter\n */\nexport class JsonToCapnp {\n private options: JsonCodecOptions;\n private schemaRegistry: Map<bigint, SchemaNode>;\n\n constructor(schemaRegistry: Map<bigint, SchemaNode>, options: JsonCodecOptions = {}) {\n this.schemaRegistry = schemaRegistry;\n this.options = options;\n }\n\n /**\n * Convert JSON to Cap'n Proto struct\n */\n convert(json: JsonValue, schema: SchemaNode, builder: StructBuilder): void {\n if (schema.type !== SchemaNodeType.STRUCT || !schema.structInfo) {\n throw new Error(`Cannot convert to non-struct type: ${schema.type}`);\n }\n\n if (typeof json !== 'object' || json === null) {\n throw new Error('JSON value must be an object');\n }\n\n const jsonObj = json as Record<string, JsonValue>;\n\n for (const field of schema.structInfo.fields) {\n const jsonFieldName = this.getJsonFieldName(field.name);\n const value = jsonObj[jsonFieldName];\n\n if (value !== undefined && value !== null) {\n this.writeField(builder, field, value);\n }\n }\n }\n\n /**\n * Convert JSON to new Cap'n Proto message\n */\n convertToMessage(json: JsonValue, schema: SchemaNode): MessageBuilder {\n if (schema.type !== SchemaNodeType.STRUCT || !schema.structInfo) {\n throw new Error(`Cannot convert to non-struct type: ${schema.type}`);\n }\n\n const builder = new MessageBuilder();\n const structBuilder = builder.initRoot(\n schema.structInfo.dataWordCount,\n schema.structInfo.pointerCount\n );\n\n this.convert(json, schema, structBuilder);\n return builder;\n }\n\n private getJsonFieldName(capnpName: string): string {\n if (this.options.fieldNameMap?.[capnpName]) {\n return this.options.fieldNameMap[capnpName];\n }\n\n if (this.options.preserveFieldNames) {\n return capnpName;\n }\n\n // Convert snake_case to camelCase\n return capnpName.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());\n }\n\n private writeField(builder: StructBuilder, field: SchemaField, value: JsonValue): void {\n const kind = field.type.kind;\n\n switch (kind.type) {\n case 'void':\n // Nothing to write\n break;\n\n case 'bool':\n builder.setBool(field.offset * 8, Boolean(value));\n break;\n\n case 'int8':\n builder.setInt8(field.offset, Number(value));\n break;\n\n case 'int16':\n builder.setInt16(field.offset, Number(value));\n break;\n\n case 'int32':\n builder.setInt32(field.offset, Number(value));\n break;\n\n case 'int64':\n builder.setInt64(field.offset, BigInt(value as string));\n break;\n\n case 'uint8':\n builder.setUint8(field.offset, Number(value));\n break;\n\n case 'uint16':\n builder.setUint16(field.offset, Number(value));\n break;\n\n case 'uint32':\n builder.setUint32(field.offset, Number(value));\n break;\n\n case 'uint64':\n builder.setUint64(field.offset, BigInt(value as string));\n break;\n\n case 'float32':\n builder.setFloat32(field.offset, Number(value));\n break;\n\n case 'float64':\n builder.setFloat64(field.offset, Number(value));\n break;\n\n case 'text':\n builder.setText(field.codeOrder, String(value));\n break;\n\n case 'data':\n if (typeof value === 'string') {\n builder.setData(field.codeOrder, base64ToBytes(value));\n }\n break;\n\n case 'list':\n if (Array.isArray(value)) {\n this.writeList(builder, field, value, kind.elementType);\n }\n break;\n\n case 'struct': {\n const nestedSchema = this.schemaRegistry.get(kind.typeId);\n if (!nestedSchema) {\n throw new Error(`Schema not found for struct type ${kind.typeId.toString(16)}`);\n }\n if (nestedSchema.type !== SchemaNodeType.STRUCT || !nestedSchema.structInfo) {\n throw new Error(`Invalid schema for struct type ${kind.typeId.toString(16)}`);\n }\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`Expected object for struct field ${field.name}`);\n }\n const nestedBuilder = builder.initStruct(\n field.codeOrder,\n nestedSchema.structInfo.dataWordCount,\n nestedSchema.structInfo.pointerCount\n );\n this.convert(value, nestedSchema, nestedBuilder);\n break;\n }\n\n case 'enum':\n if (typeof value === 'number') {\n builder.setUint16(field.offset, value);\n } else if (typeof value === 'string') {\n // Would need to look up enum value by name\n builder.setUint16(field.offset, 0);\n }\n break;\n\n case 'interface':\n case 'anyPointer':\n // Skip capability/pointer types\n break;\n }\n }\n\n private writeList(\n builder: StructBuilder,\n field: SchemaField,\n values: JsonValue[],\n elementType: SchemaType\n ): void {\n const elementCount = values.length;\n if (elementCount === 0) return;\n\n // Determine element size and struct size for complex types\n let elementSize: ElementSize;\n let structSize: { dataWords: number; pointerCount: number } | undefined;\n\n switch (elementType.kind.type) {\n case 'bool':\n elementSize = ElementSize.BIT;\n break;\n case 'int8':\n case 'uint8':\n elementSize = ElementSize.BYTE;\n break;\n case 'int16':\n case 'uint16':\n elementSize = ElementSize.TWO_BYTES;\n break;\n case 'int32':\n case 'uint32':\n case 'float32':\n elementSize = ElementSize.FOUR_BYTES;\n break;\n case 'int64':\n case 'uint64':\n case 'float64':\n elementSize = ElementSize.EIGHT_BYTES;\n break;\n case 'text':\n case 'data':\n // Text and data in lists are stored as pointers (1 pointer per element)\n elementSize = ElementSize.INLINE_COMPOSITE;\n structSize = { dataWords: 0, pointerCount: 1 };\n break;\n case 'struct': {\n const nestedSchema = this.schemaRegistry.get(elementType.kind.typeId);\n if (\n !nestedSchema ||\n nestedSchema.type !== SchemaNodeType.STRUCT ||\n !nestedSchema.structInfo\n ) {\n throw new Error(\n `Schema not found for struct list element type ${elementType.kind.typeId.toString(16)}`\n );\n }\n elementSize = ElementSize.INLINE_COMPOSITE;\n structSize = {\n dataWords: nestedSchema.structInfo.dataWordCount,\n pointerCount: nestedSchema.structInfo.pointerCount,\n };\n break;\n }\n case 'list':\n // Nested lists are stored as pointers\n elementSize = ElementSize.INLINE_COMPOSITE;\n structSize = { dataWords: 0, pointerCount: 1 };\n break;\n default:\n elementSize = ElementSize.INLINE_COMPOSITE;\n }\n\n const listBuilder = builder.initList(field.codeOrder, elementSize, elementCount, structSize);\n\n for (let i = 0; i < elementCount; i++) {\n const value = values[i];\n\n switch (elementType.kind.type) {\n case 'bool':\n // BIT list not directly supported in ListBuilder, use primitive\n listBuilder.setPrimitive(i, value ? 1 : 0);\n break;\n\n case 'int8':\n case 'uint8':\n listBuilder.setPrimitive(i, Number(value));\n break;\n\n case 'int16':\n case 'uint16':\n listBuilder.setPrimitive(i, Number(value));\n break;\n\n case 'int32':\n case 'uint32':\n listBuilder.setPrimitive(i, Number(value));\n break;\n\n case 'int64':\n case 'uint64':\n listBuilder.setPrimitive(i, BigInt(value as string));\n break;\n\n case 'float32':\n case 'float64':\n listBuilder.setPrimitive(i, Number(value));\n break;\n\n case 'text': {\n // Text in list: set text at pointer index 0 of the struct element\n const structBuilder = listBuilder.getStruct(i);\n structBuilder.setText(0, String(value));\n break;\n }\n\n case 'data': {\n // Data in list: set data at pointer index 0 of the struct element\n const structBuilder = listBuilder.getStruct(i);\n if (typeof value === 'string') {\n structBuilder.setData(0, base64ToBytes(value));\n }\n break;\n }\n\n case 'struct': {\n const nestedSchema = this.schemaRegistry.get(elementType.kind.typeId);\n if (\n !nestedSchema ||\n nestedSchema.type !== SchemaNodeType.STRUCT ||\n !nestedSchema.structInfo\n ) {\n throw new Error(\n `Schema not found for struct list element type ${elementType.kind.typeId.toString(16)}`\n );\n }\n const structBuilder = listBuilder.getStruct(i);\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`Expected object for struct list element at index ${i}`);\n }\n this.convert(value, nestedSchema, structBuilder);\n break;\n }\n\n case 'list': {\n // Nested list\n const structBuilder = listBuilder.getStruct(i);\n if (!Array.isArray(value)) {\n throw new Error(`Expected array for nested list at index ${i}`);\n }\n // Use writeList recursively - but we need the field info\n // Create a synthetic field for the nested list\n const syntheticField: SchemaField = {\n name: '',\n codeOrder: 0,\n discriminantValue: 0xffff,\n offset: 0,\n type: { kind: elementType.kind },\n hadExplicitDefault: false,\n };\n this.writeList(structBuilder, syntheticField, value, elementType.kind.elementType);\n break;\n }\n\n case 'enum': {\n listBuilder.setPrimitive(i, Number(value));\n break;\n }\n\n default:\n // Skip complex types for now\n break;\n }\n }\n }\n\n /**\n * Parse JSON string and convert to Cap'n Proto\n */\n parse(jsonString: string, schema: SchemaNode): MessageBuilder {\n const json = JSON.parse(jsonString) as JsonValue;\n return this.convertToMessage(json, schema);\n }\n}\n\n// ============================================================================\n// Utility functions\n// ============================================================================\n\n/**\n * Quick conversion function (Cap'n Proto -> JSON)\n */\nexport function toJson(\n reader: StructReader,\n schema: SchemaNode,\n options?: JsonCodecOptions\n): JsonValue {\n const registry = new Map<bigint, SchemaNode>();\n registry.set(schema.id, schema);\n\n const converter = new CapnpToJson(registry, options);\n return converter.convert(reader, schema);\n}\n\n/**\n * Quick stringify function (Cap'n Proto -> JSON string)\n */\nexport function stringify(\n reader: StructReader,\n schema: SchemaNode,\n options?: JsonCodecOptions\n): string {\n const registry = new Map<bigint, SchemaNode>();\n registry.set(schema.id, schema);\n\n const converter = new CapnpToJson(registry, options);\n return converter.stringify(reader, schema);\n}\n\n/**\n * Quick conversion function (JSON -> Cap'n Proto)\n */\nexport function fromJson(\n json: JsonValue,\n schema: SchemaNode,\n options?: JsonCodecOptions\n): MessageBuilder {\n const registry = new Map<bigint, SchemaNode>();\n registry.set(schema.id, schema);\n\n const converter = new JsonToCapnp(registry, options);\n return converter.convertToMessage(json, schema);\n}\n\n/**\n * Quick parse function (JSON string -> Cap'n Proto)\n */\nexport function parse(\n jsonString: string,\n schema: SchemaNode,\n options?: JsonCodecOptions\n): MessageBuilder {\n const registry = new Map<bigint, SchemaNode>();\n registry.set(schema.id, schema);\n\n const converter = new JsonToCapnp(registry, options);\n return converter.parse(jsonString, schema);\n}\n","/**\n * JSON Codec CLI\n *\n * Convert between Cap'n Proto binary and JSON\n *\n * Usage: capnp json <command> [options]\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { MessageReader } from '../core/index.js';\nimport type { SchemaNode } from '../rpc/schema-types.js';\nimport { SchemaNodeType } from '../rpc/schema-types.js';\nimport { CapnpToJson, JsonToCapnp } from './index.js';\n\nconst VERSION = '0.7.0';\n\nfunction printUsage() {\n console.log(`\nCap'n Proto JSON Codec v${VERSION}\n\nUsage: capnp json <command> [options]\n\nCommands:\n to-json Convert Cap'n Proto binary to JSON\n from-json Convert JSON to Cap'n Proto binary\n\nOptions:\n -i, --input Input file path (required)\n -o, --output Output file path (default: stdout for to-json, required for from-json)\n -s, --schema Schema file path (JSON format, required)\n -p, --pretty Pretty print JSON output (to-json only)\n --preserve-names Preserve original field names (don't convert to camelCase)\n --include-nulls Include null fields in JSON output (to-json only)\n -h, --help Show this help\n\nExamples:\n capnp json to-json -i data.bin -s schema.json -o data.json\n capnp json to-json -i data.bin -s schema.json -p\n capnp json from-json -i data.json -s schema.json -o data.bin\n`);\n}\n\nfunction parseArgs(args: string[]) {\n const options: {\n command?: string;\n input?: string;\n output?: string;\n schema?: string;\n pretty?: boolean;\n preserveNames?: boolean;\n includeNulls?: boolean;\n } = {};\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n switch (arg) {\n case 'to-json':\n case 'from-json':\n options.command = arg;\n break;\n case '-i':\n case '--input':\n options.input = args[++i];\n break;\n case '-o':\n case '--output':\n options.output = args[++i];\n break;\n case '-s':\n case '--schema':\n options.schema = args[++i];\n break;\n case '-p':\n case '--pretty':\n options.pretty = true;\n break;\n case '--preserve-names':\n options.preserveNames = true;\n break;\n case '--include-nulls':\n options.includeNulls = true;\n break;\n case '-h':\n case '--help':\n printUsage();\n process.exit(0);\n }\n }\n\n return options;\n}\n\nfunction loadSchema(schemaPath: string): SchemaNode {\n const schemaJson = readFileSync(schemaPath, 'utf-8');\n const schema = JSON.parse(schemaJson) as SchemaNode;\n\n // Convert string ID to bigint if needed\n if (typeof schema.id === 'string') {\n schema.id = BigInt(schema.id);\n }\n\n // Validate it's a struct schema\n if (schema.type !== SchemaNodeType.STRUCT) {\n throw new Error(`Schema must be a struct type, got: ${schema.type}`);\n }\n\n return schema;\n}\n\nasync function toJsonCommand(options: ReturnType<typeof parseArgs>) {\n // Load schema\n const schema = loadSchema(options.schema!);\n\n // Read binary input\n const buffer = readFileSync(options.input!);\n const messageReader = new MessageReader(buffer);\n\n // Get root struct\n const structReader = messageReader.getRoot(\n schema.structInfo?.dataWordCount ?? 0,\n schema.structInfo?.pointerCount ?? 0\n );\n\n // Convert to JSON\n const schemaRegistry = new Map<bigint, SchemaNode>();\n schemaRegistry.set(schema.id, schema);\n\n const converter = new CapnpToJson(schemaRegistry, {\n pretty: options.pretty,\n preserveFieldNames: options.preserveNames,\n includeNulls: options.includeNulls,\n });\n\n const json = converter.stringify(structReader, schema);\n\n // Output\n if (options.output && options.output !== '-') {\n writeFileSync(options.output, json);\n console.error(`Written to ${options.output}`);\n } else {\n console.log(json);\n }\n}\n\nasync function fromJsonCommand(options: ReturnType<typeof parseArgs>) {\n // Load schema\n const schema = loadSchema(options.schema!);\n\n // Read JSON input\n const jsonContent = readFileSync(options.input!, 'utf-8');\n\n // Convert to Cap'n Proto\n const schemaRegistry = new Map<bigint, SchemaNode>();\n schemaRegistry.set(schema.id, schema);\n\n const converter = new JsonToCapnp(schemaRegistry, {\n preserveFieldNames: options.preserveNames,\n });\n\n const messageBuilder = converter.parse(jsonContent, schema);\n\n // Output\n const buffer = Buffer.from(messageBuilder.toArrayBuffer());\n\n if (options.output) {\n writeFileSync(options.output, buffer);\n console.error(`Written to ${options.output} (${buffer.length} bytes)`);\n } else {\n console.error('Error: Output file required for from-json (use -o)');\n process.exit(1);\n }\n}\n\nexport async function run(args: string[]): Promise<void> {\n const options = parseArgs(args);\n\n if (!options.command) {\n console.error('Error: No command specified');\n printUsage();\n process.exit(1);\n }\n\n if (!options.input) {\n console.error('Error: No input file specified (use -i)');\n process.exit(1);\n }\n\n if (!options.schema) {\n console.error('Error: No schema file specified (use -s)');\n process.exit(1);\n }\n\n try {\n if (options.command === 'to-json') {\n await toJsonCommand(options);\n } else if (options.command === 'from-json') {\n await fromJsonCommand(options);\n } else {\n console.error(`Error: Unknown command: ${options.command}`);\n printUsage();\n process.exit(1);\n }\n } catch (err) {\n console.error('Error:', err instanceof Error ? err.message : err);\n process.exit(1);\n }\n}\n"],"mappings":"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"}