@adeu/core 1.12.1 → 1.14.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/dist/index.cjs +16 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine.bugs.test.ts +20 -0
- package/src/engine.ts +28 -0
package/package.json
CHANGED
package/src/engine.bugs.test.ts
CHANGED
|
@@ -531,4 +531,24 @@ describe("Resolved Bugs Core Engine Verification", () => {
|
|
|
531
531
|
const final_comment_parts = doc.pkg.parts.filter(p => p.contentType.includes("comments"));
|
|
532
532
|
expect(final_comment_parts.length).toBe(0);
|
|
533
533
|
});
|
|
534
|
+
|
|
535
|
+
it("Double-Serialization Core: process_batch successfully processes double-serialized JSON strings", async () => {
|
|
536
|
+
const doc = await createTestDocument();
|
|
537
|
+
addParagraph(doc, "original text");
|
|
538
|
+
const engine = new RedlineEngine(doc);
|
|
539
|
+
|
|
540
|
+
// On unpatched code, this will throw a raw TypeError: Cannot create property '_applied_status' on string
|
|
541
|
+
// On patched code, it will successfully parse and apply the modify change
|
|
542
|
+
engine.process_batch([
|
|
543
|
+
JSON.stringify({
|
|
544
|
+
type: "modify",
|
|
545
|
+
target_text: "original text",
|
|
546
|
+
new_text: "updated text",
|
|
547
|
+
}),
|
|
548
|
+
] as any);
|
|
549
|
+
|
|
550
|
+
const buf = await doc.save();
|
|
551
|
+
const text = await extractTextFromBuffer(buf, true);
|
|
552
|
+
expect(text).toContain("updated text");
|
|
553
|
+
});
|
|
534
554
|
});
|
package/src/engine.ts
CHANGED
|
@@ -1399,6 +1399,34 @@ export class RedlineEngine {
|
|
|
1399
1399
|
changes: DocumentChange[],
|
|
1400
1400
|
dry_run: boolean = false,
|
|
1401
1401
|
): any {
|
|
1402
|
+
// Defensive sanitization: some LLM clients "double-serialize" nested
|
|
1403
|
+
// arrays, delivering each element of `changes` as a JSON string instead of
|
|
1404
|
+
// a parsed object. Downstream code mutates state trackers (e.g.
|
|
1405
|
+
// `edit._applied_status`) and reads `change.type` on these elements, which
|
|
1406
|
+
// throws a TypeError on string primitives. Parse stringified elements back
|
|
1407
|
+
// into objects here, leaving genuine objects (and unparseable strings)
|
|
1408
|
+
// untouched so validation can surface a clear error rather than crashing.
|
|
1409
|
+
if (Array.isArray(changes)) {
|
|
1410
|
+
changes = changes.map((item: any) => {
|
|
1411
|
+
if (typeof item === "string") {
|
|
1412
|
+
try {
|
|
1413
|
+
const parsed = JSON.parse(item);
|
|
1414
|
+
// Only swap in the parsed value if it is an object; a string that
|
|
1415
|
+
// parses to a scalar (e.g. "42") is not a valid change.
|
|
1416
|
+
if (parsed !== null && typeof parsed === "object") {
|
|
1417
|
+
return parsed;
|
|
1418
|
+
}
|
|
1419
|
+
return item;
|
|
1420
|
+
} catch {
|
|
1421
|
+
// Leave malformed strings as-is; the validation pass downstream
|
|
1422
|
+
// will report them rather than crashing on a raw TypeError.
|
|
1423
|
+
return item;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return item;
|
|
1427
|
+
}) as DocumentChange[];
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1402
1430
|
if (dry_run) {
|
|
1403
1431
|
const baselines = new Map<any, Element>();
|
|
1404
1432
|
for (const part of this.doc.pkg.parts) {
|