@adeu/core 1.10.0 → 1.10.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adeu/core",
3
- "version": "1.10.0",
3
+ "version": "1.10.1",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/src/engine.ts CHANGED
@@ -255,7 +255,9 @@ export class RedlineEngine {
255
255
  return null;
256
256
  }
257
257
 
258
- private _build_edit_context_previews(edit: any): [string | null, string | null] {
258
+ private _build_edit_context_previews(
259
+ edit: any,
260
+ ): [string | null, string | null] {
259
261
  if (edit.type !== "modify") return [null, null];
260
262
  if (edit._resolved_proxy_edit) {
261
263
  edit = edit._resolved_proxy_edit;
@@ -271,7 +273,10 @@ export class RedlineEngine {
271
273
 
272
274
  const before_start = Math.max(0, start_idx - 30);
273
275
  const context_before = full_text.substring(before_start, start_idx);
274
- const context_after = full_text.substring(start_idx + length, start_idx + length + 30);
276
+ const context_after = full_text.substring(
277
+ start_idx + length,
278
+ start_idx + length + 30,
279
+ );
275
280
 
276
281
  const critic_markup = `${context_before}{--${target_text}--}{++${new_text}++}${context_after}`;
277
282
 
@@ -337,7 +342,7 @@ export class RedlineEngine {
337
342
  for (const tag of ["w:t", "w:tab", "w:br"]) {
338
343
  for (const child of findAllDescendants(p, tag)) {
339
344
  if (tag === "w:t" && !child.textContent) continue;
340
-
345
+
341
346
  let is_deleted = false;
342
347
  let curr = child.parentNode as Element | null;
343
348
  while (curr && curr !== p) {
@@ -401,7 +406,10 @@ export class RedlineEngine {
401
406
  if (parent) {
402
407
  if (parent.tagName === "w:r" || parent.tagName.endsWith(":r")) {
403
408
  const nonRprChildren = Array.from(parent.childNodes).filter(
404
- (c) => c.nodeType === 1 && (c as Element).tagName !== "w:rPr" && (c as Element).tagName !== "rPr"
409
+ (c) =>
410
+ c.nodeType === 1 &&
411
+ (c as Element).tagName !== "w:rPr" &&
412
+ (c as Element).tagName !== "rPr",
405
413
  );
406
414
  if (nonRprChildren.length <= 1) {
407
415
  parent.parentNode?.removeChild(parent);
@@ -420,8 +428,12 @@ export class RedlineEngine {
420
428
  for (const part of pkg.parts) {
421
429
  if (part.partname.toLowerCase().includes("comments")) {
422
430
  comment_partnames.add(part.partname);
423
- const withSlash = part.partname.startsWith("/") ? part.partname : "/" + part.partname;
424
- const withoutSlash = part.partname.startsWith("/") ? part.partname.substring(1) : part.partname;
431
+ const withSlash = part.partname.startsWith("/")
432
+ ? part.partname
433
+ : "/" + part.partname;
434
+ const withoutSlash = part.partname.startsWith("/")
435
+ ? part.partname.substring(1)
436
+ : part.partname;
425
437
  comment_partnames.add(withSlash);
426
438
  comment_partnames.add(withoutSlash);
427
439
  }
@@ -437,8 +449,10 @@ export class RedlineEngine {
437
449
  const target = rel.getAttribute("Target") || "";
438
450
  if (target.toLowerCase().includes("comments")) {
439
451
  toRemove.push(rel);
440
-
441
- const sourcePath = part.partname.replace("/_rels/", "/").replace(".rels", "");
452
+
453
+ const sourcePath = part.partname
454
+ .replace("/_rels/", "/")
455
+ .replace(".rels", "");
442
456
  const sourcePart = pkg.getPartByPath(sourcePath);
443
457
  if (sourcePart) {
444
458
  const relId = rel.getAttribute("Id");
@@ -459,7 +473,10 @@ export class RedlineEngine {
459
473
  const toRemove: Element[] = [];
460
474
  for (const override of overrides) {
461
475
  const partName = override.getAttribute("PartName") || "";
462
- if (comment_partnames.has(partName) || partName.toLowerCase().includes("comments")) {
476
+ if (
477
+ comment_partnames.has(partName) ||
478
+ partName.toLowerCase().includes("comments")
479
+ ) {
463
480
  toRemove.push(override);
464
481
  }
465
482
  }
@@ -469,7 +486,9 @@ export class RedlineEngine {
469
486
  }
470
487
 
471
488
  // Remove comment parts from pkg.parts
472
- pkg.parts = pkg.parts.filter(p => !p.partname.toLowerCase().includes("comments"));
489
+ pkg.parts = pkg.parts.filter(
490
+ (p) => !p.partname.toLowerCase().includes("comments"),
491
+ );
473
492
 
474
493
  // Remove comment files from pkg.unzipped
475
494
  for (const key of Object.keys(pkg.unzipped)) {
@@ -1230,18 +1249,29 @@ export class RedlineEngine {
1230
1249
  const [pfx, sfx] = trim_common_context(matched, edit.new_text || "");
1231
1250
  const t_end = matched.length - sfx;
1232
1251
  const final_target = matched.substring(pfx, t_end);
1233
- const final_new = (edit.new_text || "").substring(pfx, (edit.new_text || "").length - sfx);
1252
+ const final_new = (edit.new_text || "").substring(
1253
+ pfx,
1254
+ (edit.new_text || "").length - sfx,
1255
+ );
1234
1256
  if (final_target.includes("\n\n")) {
1235
1257
  if (final_new.includes("\n\n")) {
1236
1258
  const parts = matched.split("\n\n");
1237
- if (parts.length >= 2 && parts[0].trim() !== "" && parts[parts.length - 1].trim() !== "") {
1259
+ if (
1260
+ parts.length >= 2 &&
1261
+ parts[0].trim() !== "" &&
1262
+ parts[parts.length - 1].trim() !== ""
1263
+ ) {
1238
1264
  errors.push(
1239
1265
  `- Edit ${i + 1} Failed: target_text spans a paragraph boundary with body text on both sides. The paragraph break is a structural element, not literal text, so it cannot be replaced as a single span without corrupting the document. Split this into one edit per paragraph.`,
1240
1266
  );
1241
1267
  }
1242
1268
  } else {
1243
1269
  const parts = final_target.split("\n\n");
1244
- if (parts.length >= 2 && parts[0].trim() !== "" && parts[parts.length - 1].trim() !== "") {
1270
+ if (
1271
+ parts.length >= 2 &&
1272
+ parts[0].trim() !== "" &&
1273
+ parts[parts.length - 1].trim() !== ""
1274
+ ) {
1245
1275
  errors.push(
1246
1276
  `- Edit ${i + 1} Failed: target_text spans a paragraph boundary with body text on both sides. The paragraph break is a structural element, not literal text, so it cannot be replaced as a single span without corrupting the document. Split this into one edit per paragraph.`,
1247
1277
  );
@@ -1318,7 +1348,10 @@ export class RedlineEngine {
1318
1348
  return errors;
1319
1349
  }
1320
1350
 
1321
- public process_batch(changes: DocumentChange[], dry_run: boolean = false): any {
1351
+ public process_batch(
1352
+ changes: DocumentChange[],
1353
+ dry_run: boolean = false,
1354
+ ): any {
1322
1355
  if (dry_run) {
1323
1356
  const baselines = new Map<any, Element>();
1324
1357
  for (const part of this.doc.pkg.parts) {
@@ -1345,7 +1378,10 @@ export class RedlineEngine {
1345
1378
  }
1346
1379
  }
1347
1380
 
1348
- private _process_batch_internal(changes: DocumentChange[], dry_run_mode: boolean = false): any {
1381
+ private _process_batch_internal(
1382
+ changes: DocumentChange[],
1383
+ dry_run_mode: boolean = false,
1384
+ ): any {
1349
1385
  this.skipped_details = [];
1350
1386
  const actions = changes.filter((c) =>
1351
1387
  ["accept", "reject", "reply"].includes(c.type),
@@ -1398,7 +1434,9 @@ export class RedlineEngine {
1398
1434
  if (dry_run_mode) {
1399
1435
  for (const edit of edits) {
1400
1436
  const single_errors = this.validate_edits([edit]);
1401
- const warning = this._check_punctuation_warning((edit as any).target_text || "");
1437
+ const warning = this._check_punctuation_warning(
1438
+ (edit as any).target_text || "",
1439
+ );
1402
1440
  if (single_errors.length > 0) {
1403
1441
  skipped_edits++;
1404
1442
  edits_reports.push({
@@ -1428,7 +1466,10 @@ export class RedlineEngine {
1428
1466
  });
1429
1467
  } else {
1430
1468
  skipped_edits++;
1431
- const error_msg = this.skipped_details.length > 0 ? this.skipped_details[this.skipped_details.length - 1] : "Failed to apply edit";
1469
+ const error_msg =
1470
+ this.skipped_details.length > 0
1471
+ ? this.skipped_details[this.skipped_details.length - 1]
1472
+ : "Failed to apply edit";
1432
1473
  edits_reports.push({
1433
1474
  status: "failed",
1434
1475
  target_text: (edit as any).target_text || "",
@@ -1445,7 +1486,7 @@ export class RedlineEngine {
1445
1486
  if (errors.length > 0) {
1446
1487
  throw new BatchValidationError(errors);
1447
1488
  }
1448
- const cloned_edits = edits.map(e => JSON.parse(JSON.stringify(e)));
1489
+ const cloned_edits = edits.map((e) => JSON.parse(JSON.stringify(e)));
1449
1490
  const res = this.apply_edits(cloned_edits);
1450
1491
  applied_edits = res[0];
1451
1492
  skipped_edits = res[1];
@@ -1453,7 +1494,9 @@ export class RedlineEngine {
1453
1494
  for (const edit of cloned_edits) {
1454
1495
  const success = (edit as any)._applied_status || false;
1455
1496
  const error_msg = (edit as any)._error_msg || null;
1456
- const warning = this._check_punctuation_warning((edit as any).target_text || "");
1497
+ const warning = this._check_punctuation_warning(
1498
+ (edit as any).target_text || "",
1499
+ );
1457
1500
  let critic_markup = null;
1458
1501
  let clean_text = null;
1459
1502
  if (success) {
@@ -1482,7 +1525,7 @@ export class RedlineEngine {
1482
1525
  skipped_details: this.skipped_details,
1483
1526
  edits: edits_reports,
1484
1527
  engine: "node",
1485
- version: "1.9.0",
1528
+ version: "1.10.0",
1486
1529
  };
1487
1530
  }
1488
1531
 
@@ -1523,7 +1566,9 @@ export class RedlineEngine {
1523
1566
  } else {
1524
1567
  skipped++;
1525
1568
  edit._applied_status = false;
1526
- const target_snippet = (edit.target_text || "").trim().substring(0, 40);
1569
+ const target_snippet = (edit.target_text || "")
1570
+ .trim()
1571
+ .substring(0, 40);
1527
1572
  const msg = `- Failed to locate row target: '${target_snippet}...'`;
1528
1573
  this.skipped_details.push(msg);
1529
1574
  edit._error_msg = msg;
@@ -1535,7 +1580,10 @@ export class RedlineEngine {
1535
1580
  for (const r of resolved) {
1536
1581
  r._resolved_start_idx = r._match_start_index;
1537
1582
  r._parent_edit_ref = edit;
1538
- if (edit._resolved_start_idx === undefined || edit._resolved_start_idx === null) {
1583
+ if (
1584
+ edit._resolved_start_idx === undefined ||
1585
+ edit._resolved_start_idx === null
1586
+ ) {
1539
1587
  edit._resolved_start_idx = r._resolved_start_idx;
1540
1588
  }
1541
1589
  if (!edit._resolved_proxy_edit) {
@@ -1563,7 +1611,8 @@ export class RedlineEngine {
1563
1611
  }
1564
1612
 
1565
1613
  resolved_edits.sort(
1566
- (a, b) => (b[0]._resolved_start_idx || 0) - (a[0]._resolved_start_idx || 0),
1614
+ (a, b) =>
1615
+ (b[0]._resolved_start_idx || 0) - (a[0]._resolved_start_idx || 0),
1567
1616
  );
1568
1617
  const occupied_ranges: [number, number][] = [];
1569
1618
 
@@ -1722,7 +1771,11 @@ export class RedlineEngine {
1722
1771
  }
1723
1772
 
1724
1773
  private _apply_table_edit(edit: any, rebuild_map: boolean): boolean {
1725
- const start_idx = edit._resolved_start_idx !== undefined && edit._resolved_start_idx !== null ? edit._resolved_start_idx : (edit._match_start_index || 0);
1774
+ const start_idx =
1775
+ edit._resolved_start_idx !== undefined &&
1776
+ edit._resolved_start_idx !== null
1777
+ ? edit._resolved_start_idx
1778
+ : edit._match_start_index || 0;
1726
1779
  const [anchor_run, anchor_para] = this.mapper.get_insertion_anchor(
1727
1780
  start_idx,
1728
1781
  rebuild_map,
@@ -1877,7 +1930,11 @@ export class RedlineEngine {
1877
1930
  ): boolean {
1878
1931
  let op = edit._internal_op;
1879
1932
  const active_mapper = edit._active_mapper_ref || this.mapper;
1880
- const start_idx = edit._resolved_start_idx !== undefined && edit._resolved_start_idx !== null ? edit._resolved_start_idx : (edit._match_start_index || 0);
1933
+ const start_idx =
1934
+ edit._resolved_start_idx !== undefined &&
1935
+ edit._resolved_start_idx !== null
1936
+ ? edit._resolved_start_idx
1937
+ : edit._match_start_index || 0;
1881
1938
  const length = edit.target_text ? edit.target_text.length : 0;
1882
1939
 
1883
1940
  const del_id = ["DELETION", "MODIFICATION"].includes(op)
@@ -1967,7 +2024,9 @@ export class RedlineEngine {
1967
2024
  ) {
1968
2025
  const body = _bug233_target_para.parentNode as Element;
1969
2026
  const xmlDoc = this.doc.part._element.ownerDocument!;
1970
- const lines = _bug233_new.split(/[\r\n]+/).filter((l: string) => l !== "");
2027
+ const lines = _bug233_new
2028
+ .split(/[\r\n]+/)
2029
+ .filter((l: string) => l !== "");
1971
2030
  let firstNew: Element | null = null;
1972
2031
  let lastNew: Element | null = null;
1973
2032
  let lastIns: Element | null = null;
@@ -2069,7 +2128,9 @@ export class RedlineEngine {
2069
2128
  if (start_p) {
2070
2129
  let first_anchor_target = result.first_node;
2071
2130
  if (result.first_node.tagName === "w:p") {
2072
- first_anchor_target = findAllDescendants(result.first_node, "w:ins")[0] || result.first_node;
2131
+ first_anchor_target =
2132
+ findAllDescendants(result.first_node, "w:ins")[0] ||
2133
+ result.first_node;
2073
2134
  }
2074
2135
  const start_anchor = ascend_to_paragraph_child(
2075
2136
  first_anchor_target,
@@ -2086,22 +2147,27 @@ export class RedlineEngine {
2086
2147
  end_anchor,
2087
2148
  edit.comment,
2088
2149
  );
2089
- }
2090
- } else {
2091
- // Inline only: anchor around first_node in its host paragraph.
2092
- let host_p: Element | null = result.first_node;
2093
- while (host_p && host_p.tagName !== "w:p")
2150
+ }
2151
+ } else {
2152
+ // Inline only: anchor around first_node in its host paragraph.
2153
+ let host_p: Element | null = result.first_node;
2154
+ while (host_p && host_p.tagName !== "w:p")
2094
2155
  host_p = host_p.parentNode as Element;
2095
- if (host_p) {
2156
+ if (host_p) {
2096
2157
  let first_anchor_target = result.first_node;
2097
2158
  if (result.first_node.tagName === "w:p") {
2098
- first_anchor_target = findAllDescendants(result.first_node, "w:ins")[0] || result.first_node;
2159
+ first_anchor_target =
2160
+ findAllDescendants(result.first_node, "w:ins")[0] ||
2161
+ result.first_node;
2099
2162
  }
2100
- const anchor = ascend_to_paragraph_child(first_anchor_target, host_p);
2163
+ const anchor = ascend_to_paragraph_child(
2164
+ first_anchor_target,
2165
+ host_p,
2166
+ );
2101
2167
  this._attach_comment(host_p, anchor, anchor, edit.comment);
2102
- }
2103
2168
  }
2104
2169
  }
2170
+ }
2105
2171
  return true;
2106
2172
  }
2107
2173
 
@@ -2111,7 +2177,10 @@ export class RedlineEngine {
2111
2177
  length,
2112
2178
  rebuild_map,
2113
2179
  );
2114
- const virtual_spans = active_mapper.get_virtual_spans_in_range(start_idx, length);
2180
+ const virtual_spans = active_mapper.get_virtual_spans_in_range(
2181
+ start_idx,
2182
+ length,
2183
+ );
2115
2184
 
2116
2185
  if (target_runs.length === 0 && virtual_spans.length === 0) return false;
2117
2186
 
@@ -2187,18 +2256,26 @@ export class RedlineEngine {
2187
2256
 
2188
2257
  // PHASE 2: OOXML Paragraph Merge Protocol
2189
2258
  if (op === "DELETION" || op === "MODIFICATION") {
2190
- if (op === "MODIFICATION" && target_runs.length === 0 && virtual_spans.length > 0 && edit.new_text) {
2259
+ if (
2260
+ op === "MODIFICATION" &&
2261
+ target_runs.length === 0 &&
2262
+ virtual_spans.length > 0 &&
2263
+ edit.new_text
2264
+ ) {
2191
2265
  const first_span = virtual_spans[0];
2192
2266
  if (first_span.paragraph) {
2193
2267
  const p1_el = first_span.paragraph._element;
2194
2268
  const last_runs = findAllDescendants(p1_el, "w:r");
2195
- const anchor = last_runs.length > 0 ? new Run(last_runs[last_runs.length - 1], first_span.paragraph) : null;
2196
-
2269
+ const anchor =
2270
+ last_runs.length > 0
2271
+ ? new Run(last_runs[last_runs.length - 1], first_span.paragraph)
2272
+ : null;
2273
+
2197
2274
  const result = this._track_insert_multiline(
2198
2275
  edit.new_text,
2199
2276
  anchor,
2200
2277
  first_span.paragraph,
2201
- ins_id!
2278
+ ins_id!,
2202
2279
  );
2203
2280
  if (result.first_node) {
2204
2281
  p1_el.appendChild(result.first_node);
@@ -2218,7 +2295,10 @@ export class RedlineEngine {
2218
2295
  let pPr = findChild(p1_element, "w:pPr");
2219
2296
  if (!pPr) {
2220
2297
  pPr = p1_element.ownerDocument!.createElement("w:pPr") as Element;
2221
- p1_element.insertBefore(pPr, p1_element.firstChild as Node | null);
2298
+ p1_element.insertBefore(
2299
+ pPr,
2300
+ p1_element.firstChild as Node | null,
2301
+ );
2222
2302
  }
2223
2303
  let rPr = findChild(pPr!, "w:rPr");
2224
2304
  if (!rPr) {
@@ -2230,7 +2310,10 @@ export class RedlineEngine {
2230
2310
 
2231
2311
  const children = Array.from(p2_element.childNodes);
2232
2312
  for (const child of children) {
2233
- if (child.nodeType === 1 && (child as Element).tagName === "w:pPr") {
2313
+ if (
2314
+ child.nodeType === 1 &&
2315
+ (child as Element).tagName === "w:pPr"
2316
+ ) {
2234
2317
  continue;
2235
2318
  }
2236
2319
  p1_element.appendChild(child);