@harbour-enterprises/superdoc 1.15.0-next.26 → 1.15.0-next.28

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 (31) hide show
  1. package/dist/chunks/{DocxZipper-Coos-D5G.cjs → DocxZipper-Bm8hUtvb.cjs} +16 -7
  2. package/dist/chunks/{DocxZipper-VLFQ-N1D.es.js → DocxZipper-wbdb-lrZ.es.js} +14 -5
  3. package/dist/chunks/{SuperConverter-Dz7jNJpY.es.js → SuperConverter-BWh7d4KV.es.js} +91 -179
  4. package/dist/chunks/{SuperConverter-DvOu0a_D.cjs → SuperConverter-DL_5v035.cjs} +266 -358
  5. package/dist/chunks/{helpers-Cs_Zz44i.cjs → constants-CpniKo9Z.cjs} +45 -0
  6. package/dist/chunks/{helpers-BGD_wEOi.es.js → constants-DBKi0Amm.es.js} +16 -1
  7. package/dist/chunks/{src-C8JxCjao.cjs → src-DALK5mTO.cjs} +69 -74
  8. package/dist/chunks/{src-C374LFvx.es.js → src-DxmW0glw.es.js} +32 -37
  9. package/dist/super-editor/converter.cjs +2 -2
  10. package/dist/super-editor/converter.es.js +2 -2
  11. package/dist/super-editor/docx-zipper.cjs +2 -2
  12. package/dist/super-editor/docx-zipper.es.js +2 -2
  13. package/dist/super-editor/src/core/DocxZipper.d.ts.map +1 -1
  14. package/dist/super-editor/src/core/Editor.d.ts +1 -1
  15. package/dist/super-editor/src/core/Editor.d.ts.map +1 -1
  16. package/dist/super-editor/src/core/presentation-editor/PresentationEditor.d.ts.map +1 -1
  17. package/dist/super-editor/src/core/super-converter/SuperConverter.d.ts.map +1 -1
  18. package/dist/super-editor/src/core/super-converter/constants.d.ts +3 -0
  19. package/dist/super-editor/src/core/super-converter/constants.d.ts.map +1 -1
  20. package/dist/super-editor/src/core/super-converter/exporter-docx-defs.d.ts +0 -44
  21. package/dist/super-editor/src/core/super-converter/exporter-docx-defs.d.ts.map +1 -1
  22. package/dist/super-editor/src/core/super-converter/v2/exporter/commentsExporter.d.ts +13 -7
  23. package/dist/super-editor/src/core/super-converter/v2/exporter/commentsExporter.d.ts.map +1 -1
  24. package/dist/super-editor/src/extensions/collaboration/collaboration-helpers.d.ts.map +1 -1
  25. package/dist/super-editor.cjs +4 -4
  26. package/dist/super-editor.es.js +4 -4
  27. package/dist/superdoc.cjs +5 -5
  28. package/dist/superdoc.es.js +5 -5
  29. package/dist/superdoc.umd.js +144 -216
  30. package/dist/superdoc.umd.js.map +1 -1
  31. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-Dp2H1eGw.cjs");
2
2
  const require_jszip = require("./jszip-DCT9QYaK.cjs");
3
3
  const require_xml_js = require("./xml-js--DznO7Gk.cjs");
4
- const require_helpers = require("./helpers-Cs_Zz44i.cjs");
4
+ const require_constants = require("./constants-CpniKo9Z.cjs");
5
5
  const DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
6
6
  const PDF = "application/pdf";
7
7
  const HTML = "text/html";
@@ -1530,7 +1530,7 @@ var DocxZipper = class {
1530
1530
  else contentTypesXml = docx.files?.[contentTypesPath] || "";
1531
1531
  else contentTypesXml = await docx.file(contentTypesPath).async("string");
1532
1532
  let typesString = "";
1533
- const defaultMediaTypes = require_helpers.getContentTypesFromXml(contentTypesXml);
1533
+ const defaultMediaTypes = require_constants.getContentTypesFromXml(contentTypesXml);
1534
1534
  const seenTypes = /* @__PURE__ */ new Set();
1535
1535
  for (let type of newMediaTypes) {
1536
1536
  if (defaultMediaTypes.includes(type)) continue;
@@ -1545,7 +1545,7 @@ var DocxZipper = class {
1545
1545
  const hasCommentsIds = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/commentsIds.xml");
1546
1546
  const hasCommentsExtensible = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/commentsExtensible.xml");
1547
1547
  const hasFile = (filename) => {
1548
- if (updatedDocs && Object.prototype.hasOwnProperty.call(updatedDocs, filename)) return true;
1548
+ if (updatedDocs && Object.prototype.hasOwnProperty.call(updatedDocs, filename)) return updatedDocs[filename] !== null;
1549
1549
  if (!docx?.files) return false;
1550
1550
  if (!fromJson) return Boolean(docx.files[filename]);
1551
1551
  if (Array.isArray(docx.files)) return docx.files.some((file) => file.name === filename);
@@ -1582,8 +1582,16 @@ var DocxZipper = class {
1582
1582
  const extendedDef = `<Override PartName="/${name}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${name.includes("header") ? "header" : "footer"}+xml"/>`;
1583
1583
  if (!hasExtensible) typesString += extendedDef;
1584
1584
  });
1585
+ const staleOverridePartNames = require_constants.COMMENT_FILE_BASENAMES.map((name) => `/word/${name}`).filter((partName) => {
1586
+ return !hasFile(partName.slice(1));
1587
+ });
1585
1588
  const beginningString = "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">";
1586
1589
  let updatedContentTypesXml = contentTypesXml.replace(beginningString, `${beginningString}${typesString}`);
1590
+ for (const partName of staleOverridePartNames) {
1591
+ const escapedPartName = partName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1592
+ const overrideRegex = new RegExp(`\\s*<Override[^>]*PartName="${escapedPartName}"[^>]*/>`, "g");
1593
+ updatedContentTypesXml = updatedContentTypesXml.replace(overrideRegex, "");
1594
+ }
1587
1595
  let relationshipsXml = updatedDocs["word/_rels/document.xml.rels"];
1588
1596
  if (!relationshipsXml) if (fromJson) if (Array.isArray(docx.files)) relationshipsXml = docx.files.find((file) => file.name === "word/_rels/document.xml.rels")?.content;
1589
1597
  else relationshipsXml = docx.files?.["word/_rels/document.xml.rels"];
@@ -1637,12 +1645,12 @@ var DocxZipper = class {
1637
1645
  zip.file(file.name, content);
1638
1646
  }
1639
1647
  Object.keys(updatedDocs).forEach((key) => {
1640
- const content = updatedDocs[key];
1641
- zip.file(key, content);
1648
+ if (updatedDocs[key] === null) zip.remove(key);
1649
+ else zip.file(key, updatedDocs[key]);
1642
1650
  });
1643
1651
  Object.keys(media).forEach((path) => {
1644
1652
  const value = media[path];
1645
- const binaryData = typeof value === "string" ? require_helpers.base64ToUint8Array(value) : value;
1653
+ const binaryData = typeof value === "string" ? require_constants.base64ToUint8Array(value) : value;
1646
1654
  zip.file(path, binaryData);
1647
1655
  });
1648
1656
  for (const [fontName, fontUintArray] of Object.entries(fonts)) zip.file(fontName, fontUintArray);
@@ -1660,7 +1668,8 @@ var DocxZipper = class {
1660
1668
  });
1661
1669
  await Promise.all(filePromises);
1662
1670
  Object.keys(updatedDocs).forEach((key) => {
1663
- unzippedOriginalDocx.file(key, updatedDocs[key]);
1671
+ if (updatedDocs[key] === null) unzippedOriginalDocx.remove(key);
1672
+ else unzippedOriginalDocx.file(key, updatedDocs[key]);
1664
1673
  });
1665
1674
  Object.keys(media).forEach((path) => {
1666
1675
  unzippedOriginalDocx.file(path, media[path]);
@@ -1,7 +1,7 @@
1
1
  import { o as __toESM } from "./rolldown-runtime-B2q5OVn9.es.js";
2
2
  import { t as require_jszip_min } from "./jszip-ChlR43oI.es.js";
3
3
  import { t as require_lib } from "./xml-js-DLE8mr0n.es.js";
4
- import { l as getContentTypesFromXml, t as base64ToUint8Array } from "./helpers-BGD_wEOi.es.js";
4
+ import { m as getContentTypesFromXml, o as base64ToUint8Array, t as COMMENT_FILE_BASENAMES } from "./constants-DBKi0Amm.es.js";
5
5
  const DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
6
6
  const PDF = "application/pdf";
7
7
  const HTML = "text/html";
@@ -1545,7 +1545,7 @@ var DocxZipper = class {
1545
1545
  const hasCommentsIds = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/commentsIds.xml");
1546
1546
  const hasCommentsExtensible = types.elements?.some((el) => el.name === "Override" && el.attributes.PartName === "/word/commentsExtensible.xml");
1547
1547
  const hasFile = (filename) => {
1548
- if (updatedDocs && Object.prototype.hasOwnProperty.call(updatedDocs, filename)) return true;
1548
+ if (updatedDocs && Object.prototype.hasOwnProperty.call(updatedDocs, filename)) return updatedDocs[filename] !== null;
1549
1549
  if (!docx?.files) return false;
1550
1550
  if (!fromJson) return Boolean(docx.files[filename]);
1551
1551
  if (Array.isArray(docx.files)) return docx.files.some((file) => file.name === filename);
@@ -1582,8 +1582,16 @@ var DocxZipper = class {
1582
1582
  const extendedDef = `<Override PartName="/${name}" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.${name.includes("header") ? "header" : "footer"}+xml"/>`;
1583
1583
  if (!hasExtensible) typesString += extendedDef;
1584
1584
  });
1585
+ const staleOverridePartNames = COMMENT_FILE_BASENAMES.map((name) => `/word/${name}`).filter((partName) => {
1586
+ return !hasFile(partName.slice(1));
1587
+ });
1585
1588
  const beginningString = "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">";
1586
1589
  let updatedContentTypesXml = contentTypesXml.replace(beginningString, `${beginningString}${typesString}`);
1590
+ for (const partName of staleOverridePartNames) {
1591
+ const escapedPartName = partName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1592
+ const overrideRegex = new RegExp(`\\s*<Override[^>]*PartName="${escapedPartName}"[^>]*/>`, "g");
1593
+ updatedContentTypesXml = updatedContentTypesXml.replace(overrideRegex, "");
1594
+ }
1587
1595
  let relationshipsXml = updatedDocs["word/_rels/document.xml.rels"];
1588
1596
  if (!relationshipsXml) if (fromJson) if (Array.isArray(docx.files)) relationshipsXml = docx.files.find((file) => file.name === "word/_rels/document.xml.rels")?.content;
1589
1597
  else relationshipsXml = docx.files?.["word/_rels/document.xml.rels"];
@@ -1637,8 +1645,8 @@ var DocxZipper = class {
1637
1645
  zip.file(file.name, content);
1638
1646
  }
1639
1647
  Object.keys(updatedDocs).forEach((key) => {
1640
- const content = updatedDocs[key];
1641
- zip.file(key, content);
1648
+ if (updatedDocs[key] === null) zip.remove(key);
1649
+ else zip.file(key, updatedDocs[key]);
1642
1650
  });
1643
1651
  Object.keys(media).forEach((path) => {
1644
1652
  const value = media[path];
@@ -1660,7 +1668,8 @@ var DocxZipper = class {
1660
1668
  });
1661
1669
  await Promise.all(filePromises);
1662
1670
  Object.keys(updatedDocs).forEach((key) => {
1663
- unzippedOriginalDocx.file(key, updatedDocs[key]);
1671
+ if (updatedDocs[key] === null) unzippedOriginalDocx.remove(key);
1672
+ else unzippedOriginalDocx.file(key, updatedDocs[key]);
1664
1673
  });
1665
1674
  Object.keys(media).forEach((path) => {
1666
1675
  unzippedOriginalDocx.file(path, media[path]);
@@ -2,7 +2,7 @@ import { o as __toESM, r as __export, t as __commonJSMin } from "./rolldown-runt
2
2
  import { a as init_dist, i as global } from "./jszip-ChlR43oI.es.js";
3
3
  import { t as require_lib } from "./xml-js-DLE8mr0n.es.js";
4
4
  import { t as v4_default } from "./uuid-2IzDu5nl.es.js";
5
- import { A as twipsToLines, C as polygonToObj, D as rgbToHex, E as resolveShadingFillColor, M as twipsToPt, O as rotToDegrees, S as pointsToTwips, T as resolveOpcTargetPath, _ as normalizeHexColor, a as deobfuscateFont, b as pixelsToEmu, c as getArrayBufferFromUrl, d as getHexColorFromDocxSystem, f as halfPointToPoints, g as linesToTwips, h as isValidHexColor, i as degreesToRot, j as twipsToPixels, k as twipsToInches, m as inchesToTwips, n as computeCrc32Hex, o as eighthPointsToPixels, s as emuToPixels, t as base64ToUint8Array, u as getDocxHighlightKeywordFromHex, v as objToPolygon, w as ptToTwips, x as pixelsToTwips, y as pixelsToEightPoints } from "./helpers-BGD_wEOi.es.js";
5
+ import { A as resolveOpcTargetPath, C as objToPolygon, D as pointsToTwips, E as pixelsToTwips, F as twipsToLines, I as twipsToPixels, L as twipsToPt, M as rgbToHex, N as rotToDegrees, O as polygonToObj, P as twipsToInches, S as normalizeHexColor, T as pixelsToEmu, _ as halfPointToPoints, a as HYPERLINK_RELATIONSHIP_TYPE, b as isValidHexColor, d as eighthPointsToPixels, f as emuToPixels, g as getHexColorFromDocxSystem, h as getDocxHighlightKeywordFromHex, i as HEADER_RELATIONSHIP_TYPE, j as resolveShadingFillColor, k as ptToTwips, l as degreesToRot, n as COMMENT_RELATIONSHIP_TYPES, o as base64ToUint8Array, p as getArrayBufferFromUrl, r as FOOTER_RELATIONSHIP_TYPE, s as computeCrc32Hex, t as COMMENT_FILE_BASENAMES, u as deobfuscateFont, w as pixelsToEightPoints, x as linesToTwips, y as inchesToTwips } from "./constants-DBKi0Amm.es.js";
6
6
  function getExtensionConfigField(extension, field, context = { name: "" }) {
7
7
  const fieldValue = extension.config[field];
8
8
  if (typeof fieldValue === "function") return fieldValue.bind({ ...context });
@@ -3297,148 +3297,6 @@ const COMMENTS_XML_DEFINITIONS = {
3297
3297
  elements: []
3298
3298
  }]
3299
3299
  }]
3300
- },
3301
- CONTENT_TYPES: {
3302
- declaration: { attributes: {
3303
- version: "1.0",
3304
- encoding: "UTF-8",
3305
- standalone: "yes"
3306
- } },
3307
- elements: [{
3308
- type: "element",
3309
- name: "Types",
3310
- attributes: { xmlns: "http://schemas.openxmlformats.org/package/2006/content-types" },
3311
- elements: [
3312
- {
3313
- type: "element",
3314
- name: "Default",
3315
- attributes: {
3316
- Extension: "rels",
3317
- ContentType: "application/vnd.openxmlformats-package.relationships+xml"
3318
- }
3319
- },
3320
- {
3321
- type: "element",
3322
- name: "Default",
3323
- attributes: {
3324
- Extension: "xml",
3325
- ContentType: "application/xml"
3326
- }
3327
- },
3328
- {
3329
- type: "element",
3330
- name: "Override",
3331
- attributes: {
3332
- PartName: "/word/document.xml",
3333
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"
3334
- }
3335
- },
3336
- {
3337
- type: "element",
3338
- name: "Override",
3339
- attributes: {
3340
- PartName: "/word/styles.xml",
3341
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"
3342
- }
3343
- },
3344
- {
3345
- type: "element",
3346
- name: "Override",
3347
- attributes: {
3348
- PartName: "/word/settings.xml",
3349
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"
3350
- }
3351
- },
3352
- {
3353
- type: "element",
3354
- name: "Override",
3355
- attributes: {
3356
- PartName: "/word/webSettings.xml",
3357
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"
3358
- }
3359
- },
3360
- {
3361
- type: "element",
3362
- name: "Override",
3363
- attributes: {
3364
- PartName: "/word/comments.xml",
3365
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml"
3366
- }
3367
- },
3368
- {
3369
- type: "element",
3370
- name: "Override",
3371
- attributes: {
3372
- PartName: "/word/commentsExtended.xml",
3373
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml"
3374
- }
3375
- },
3376
- {
3377
- type: "element",
3378
- name: "Override",
3379
- attributes: {
3380
- PartName: "/word/commentsIds.xml",
3381
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsIds+xml"
3382
- }
3383
- },
3384
- {
3385
- type: "element",
3386
- name: "Override",
3387
- attributes: {
3388
- PartName: "/word/commentsExtensible.xml",
3389
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtensible+xml"
3390
- }
3391
- },
3392
- {
3393
- type: "element",
3394
- name: "Override",
3395
- attributes: {
3396
- PartName: "/word/fontTable.xml",
3397
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"
3398
- }
3399
- },
3400
- {
3401
- type: "element",
3402
- name: "Override",
3403
- attributes: {
3404
- PartName: "/word/people.xml",
3405
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.people+xml"
3406
- }
3407
- },
3408
- {
3409
- type: "element",
3410
- name: "Override",
3411
- attributes: {
3412
- PartName: "/word/theme/theme1.xml",
3413
- ContentType: "application/vnd.openxmlformats-officedocument.theme+xml"
3414
- }
3415
- },
3416
- {
3417
- type: "element",
3418
- name: "Override",
3419
- attributes: {
3420
- PartName: "/docProps/core.xml",
3421
- ContentType: "application/vnd.openxmlformats-package.core-properties+xml"
3422
- }
3423
- },
3424
- {
3425
- type: "element",
3426
- name: "Override",
3427
- attributes: {
3428
- PartName: "/docProps/app.xml",
3429
- ContentType: "application/vnd.openxmlformats-officedocument.extended-properties+xml"
3430
- }
3431
- },
3432
- {
3433
- type: "element",
3434
- name: "Override",
3435
- attributes: {
3436
- PartName: "/word/numbering.xml",
3437
- ContentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml"
3438
- }
3439
- }
3440
- ]
3441
- }]
3442
3300
  }
3443
3301
  };
3444
3302
  function translateChildNodes(params) {
@@ -33284,30 +33142,28 @@ const updateCommentsExtendedXml = (comments = [], commentsExtendedXml, threading
33284
33142
  return xmlCopy;
33285
33143
  };
33286
33144
  const updateCommentsIdsAndExtensible = (comments = [], commentsIds, extensible) => {
33287
- const documentIdsUpdated = carbonCopy(commentsIds);
33288
- const extensibleUpdated = carbonCopy(extensible);
33289
- documentIdsUpdated.elements[0].elements = [];
33290
- extensibleUpdated.elements[0].elements = [];
33145
+ const documentIdsUpdated = commentsIds ? carbonCopy(commentsIds) : null;
33146
+ const extensibleUpdated = extensible ? carbonCopy(extensible) : null;
33147
+ if (documentIdsUpdated) documentIdsUpdated.elements[0].elements = [];
33148
+ if (extensibleUpdated) extensibleUpdated.elements[0].elements = [];
33291
33149
  comments.forEach((comment) => {
33292
33150
  const newDurableId = generateRandom32BitHex();
33293
- const newCommentIdDef = {
33151
+ if (documentIdsUpdated) documentIdsUpdated.elements[0].elements.push({
33294
33152
  type: "element",
33295
33153
  name: "w16cid:commentId",
33296
33154
  attributes: {
33297
33155
  "w16cid:paraId": comment.commentParaId,
33298
33156
  "w16cid:durableId": newDurableId
33299
33157
  }
33300
- };
33301
- documentIdsUpdated.elements[0].elements.push(newCommentIdDef);
33302
- const newExtensible = {
33158
+ });
33159
+ if (extensibleUpdated) extensibleUpdated.elements[0].elements.push({
33303
33160
  type: "element",
33304
33161
  name: "w16cex:commentExtensible",
33305
33162
  attributes: {
33306
33163
  "w16cex:durableId": newDurableId,
33307
33164
  "w16cex:dateUtc": toIsoNoFractional(comment.createdTime)
33308
33165
  }
33309
- };
33310
- extensibleUpdated.elements[0].elements.push(newExtensible);
33166
+ });
33311
33167
  });
33312
33168
  return {
33313
33169
  documentIdsUpdated,
@@ -33322,7 +33178,6 @@ const generateConvertedXmlWithCommentFiles = (convertedXml, fileSet = null) => {
33322
33178
  newXml["word/commentsExtended.xml"] = COMMENTS_XML_DEFINITIONS.COMMENTS_EXTENDED_XML_DEF;
33323
33179
  if (includeExtensible) newXml["word/commentsExtensible.xml"] = COMMENTS_XML_DEFINITIONS.COMMENTS_EXTENSIBLE_XML_DEF;
33324
33180
  if (includeIds) newXml["word/commentsIds.xml"] = COMMENTS_XML_DEFINITIONS.COMMENTS_IDS_XML_DEF;
33325
- newXml["[Content_Types].xml"] = COMMENTS_XML_DEFINITIONS.CONTENT_TYPES;
33326
33181
  return newXml;
33327
33182
  };
33328
33183
  const removeCommentsFilesFromConvertedXml = (convertedXml) => {
@@ -33336,31 +33191,69 @@ const removeCommentsFilesFromConvertedXml = (convertedXml) => {
33336
33191
  const generateRelationship = (target) => {
33337
33192
  return { ...COMMENTS_XML_DEFINITIONS.DOCUMENT_RELS_XML_DEF.elements[0].elements.find((rel) => rel.attributes.Target === target) };
33338
33193
  };
33194
+ var ALL_COMMENT_TARGETS = COMMENT_FILE_BASENAMES;
33339
33195
  const prepareCommentsXmlFilesForExport = ({ convertedXml, defs, commentsWithParaIds, exportType, threadingProfile }) => {
33340
33196
  const relationships = [];
33197
+ const warnings = [];
33341
33198
  if (exportType === "clean") return {
33342
33199
  documentXml: removeCommentsFilesFromConvertedXml(convertedXml),
33343
- relationships
33344
- };
33200
+ relationships,
33201
+ removedTargets: ALL_COMMENT_TARGETS,
33202
+ warnings
33203
+ };
33204
+ const hasComments = commentsWithParaIds && commentsWithParaIds.length > 0;
33205
+ if (!hasComments) {
33206
+ const documentXml = removeCommentsFilesFromConvertedXml(convertedXml);
33207
+ const removedTargets = [...ALL_COMMENT_TARGETS];
33208
+ if (threadingProfile?.fileSet) warnings.push("All comments removed — cleaning up imported comment support files");
33209
+ return {
33210
+ documentXml,
33211
+ relationships,
33212
+ removedTargets,
33213
+ warnings
33214
+ };
33215
+ }
33216
+ const emittedTargets = /* @__PURE__ */ new Set();
33345
33217
  const exportStrategy = determineExportStrategy(commentsWithParaIds);
33346
33218
  const updatedXml = generateConvertedXmlWithCommentFiles(convertedXml, threadingProfile?.fileSet);
33347
33219
  updatedXml["word/comments.xml"] = updateCommentsXml(defs, updatedXml["word/comments.xml"]);
33348
33220
  relationships.push(generateRelationship("comments.xml"));
33221
+ emittedTargets.add("comments.xml");
33349
33222
  const commentsExtendedXml = updateCommentsExtendedXml(commentsWithParaIds, updatedXml["word/commentsExtended.xml"], threadingProfile || exportStrategy);
33350
33223
  if (commentsExtendedXml !== null) {
33351
33224
  updatedXml["word/commentsExtended.xml"] = commentsExtendedXml;
33352
33225
  relationships.push(generateRelationship("commentsExtended.xml"));
33353
- } else delete updatedXml["word/commentsExtended.xml"];
33354
- if (updatedXml["word/commentsIds.xml"] && updatedXml["word/commentsExtensible.xml"]) {
33355
- const { documentIdsUpdated, extensibleUpdated } = updateCommentsIdsAndExtensible(commentsWithParaIds, updatedXml["word/commentsIds.xml"], updatedXml["word/commentsExtensible.xml"]);
33356
- updatedXml["word/commentsIds.xml"] = documentIdsUpdated;
33357
- updatedXml["word/commentsExtensible.xml"] = extensibleUpdated;
33358
- relationships.push(generateRelationship("commentsIds.xml"));
33359
- relationships.push(generateRelationship("commentsExtensible.xml"));
33360
- }
33226
+ emittedTargets.add("commentsExtended.xml");
33227
+ } else {
33228
+ delete updatedXml["word/commentsExtended.xml"];
33229
+ if (threadingProfile?.fileSet?.hasCommentsExtended) warnings.push("commentsExtended.xml removed — export strategy does not require it");
33230
+ }
33231
+ const hasIds = !!updatedXml["word/commentsIds.xml"];
33232
+ const hasExtensible = !!updatedXml["word/commentsExtensible.xml"];
33233
+ if (hasIds !== hasExtensible) {
33234
+ const present = hasIds ? "commentsIds.xml" : "commentsExtensible.xml";
33235
+ const absent = hasIds ? "commentsExtensible.xml" : "commentsIds.xml";
33236
+ warnings.push(`Partial comment file-set: ${present} present without ${absent}`);
33237
+ }
33238
+ if (hasIds || hasExtensible) {
33239
+ const { documentIdsUpdated, extensibleUpdated } = updateCommentsIdsAndExtensible(commentsWithParaIds, hasIds ? updatedXml["word/commentsIds.xml"] : null, hasExtensible ? updatedXml["word/commentsExtensible.xml"] : null);
33240
+ if (documentIdsUpdated) {
33241
+ updatedXml["word/commentsIds.xml"] = documentIdsUpdated;
33242
+ relationships.push(generateRelationship("commentsIds.xml"));
33243
+ emittedTargets.add("commentsIds.xml");
33244
+ }
33245
+ if (extensibleUpdated) {
33246
+ updatedXml["word/commentsExtensible.xml"] = extensibleUpdated;
33247
+ relationships.push(generateRelationship("commentsExtensible.xml"));
33248
+ emittedTargets.add("commentsExtensible.xml");
33249
+ }
33250
+ }
33251
+ if (!threadingProfile && hasComments) warnings.push("Comments exist but no threading profile detected — using default export shape");
33361
33252
  return {
33362
33253
  relationships,
33363
- documentXml: updatedXml
33254
+ documentXml: updatedXml,
33255
+ removedTargets: ALL_COMMENT_TARGETS.filter((target) => !emittedTargets.has(target)),
33256
+ warnings
33364
33257
  };
33365
33258
  };
33366
33259
  var REL_ID_NUMERIC_PATTERN = /rId|mi/g;
@@ -33776,6 +33669,7 @@ var SuperConverter = class SuperConverter {
33776
33669
  this.footnoteProperties = null;
33777
33670
  this.inlineDocumentFonts = [];
33778
33671
  this.commentThreadingProfile = null;
33672
+ this.exportWarnings = [];
33779
33673
  this.docHiglightColors = /* @__PURE__ */ new Set([]);
33780
33674
  this.xml = params?.xml;
33781
33675
  this.declaration = null;
@@ -33935,7 +33829,7 @@ var SuperConverter = class SuperConverter {
33935
33829
  static getStoredSuperdocVersion(docx) {
33936
33830
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
33937
33831
  }
33938
- static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.15.0-next.26") {
33832
+ static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.15.0-next.28") {
33939
33833
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version, false);
33940
33834
  }
33941
33835
  static generateWordTimestamp() {
@@ -34204,6 +34098,7 @@ var SuperConverter = class SuperConverter {
34204
34098
  return new DocxExporter(this).schemaToXml(data, debug);
34205
34099
  }
34206
34100
  async exportToDocx(jsonData, editorSchema, documentMedia, isFinalDoc = false, commentsExportType, comments = [], editor, exportJsonOnly = false, fieldsHighlightColor) {
34101
+ this.exportWarnings = [];
34207
34102
  const exportableComments = comments.filter((c) => !c.trackedChange);
34208
34103
  const commentsWithParaIds = exportableComments.map((c) => prepareCommentParaIds(c));
34209
34104
  const commentDefinitions = commentsWithParaIds.map((c, index) => getCommentDefinition(c, index, commentsWithParaIds, editor));
@@ -34235,21 +34130,20 @@ var SuperConverter = class SuperConverter {
34235
34130
  ...footnotesMedia,
34236
34131
  ...this.media
34237
34132
  }, editor);
34238
- let updatedXml = { ...this.convertedXml };
34239
- let commentsRels = [];
34240
- if (comments.length) {
34241
- const { documentXml, relationships } = this.#prepareCommentsXmlFilesForExport({
34242
- defs: params.exportedCommentDefs,
34243
- exportType: commentsExportType,
34244
- commentsWithParaIds
34245
- });
34246
- updatedXml = { ...documentXml };
34247
- commentsRels = relationships;
34248
- }
34133
+ const { documentXml, relationships: commentsRels, removedTargets } = this.#prepareCommentsXmlFilesForExport({
34134
+ defs: params.exportedCommentDefs,
34135
+ exportType: commentsExportType,
34136
+ commentsWithParaIds
34137
+ });
34138
+ const updatedXml = { ...documentXml };
34249
34139
  this.convertedXml = {
34250
34140
  ...this.convertedXml,
34251
34141
  ...updatedXml
34252
34142
  };
34143
+ if (removedTargets?.length) for (const target of removedTargets) {
34144
+ const key = target.startsWith("word/") ? target : `word/${target}`;
34145
+ delete this.convertedXml[key];
34146
+ }
34253
34147
  const headFootRels = this.#exportProcessHeadersFooters({ isFinalDoc });
34254
34148
  this.#exportProcessNewRelationships([
34255
34149
  ...params.relationships,
@@ -34257,6 +34151,7 @@ var SuperConverter = class SuperConverter {
34257
34151
  ...footnotesRels,
34258
34152
  ...headFootRels
34259
34153
  ]);
34154
+ if (removedTargets?.length) this.#pruneCommentRelationships(removedTargets);
34260
34155
  SuperConverter.setStoredSuperdocVersion(this.convertedXml);
34261
34156
  if (this.documentModified || this.documentGuid) {
34262
34157
  if (!this.documentGuid) this.documentGuid = this.getMicrosoftDocId() || v4_default();
@@ -34300,16 +34195,18 @@ var SuperConverter = class SuperConverter {
34300
34195
  this.convertedXml[numberingPath] = numberingXml;
34301
34196
  }
34302
34197
  #prepareCommentsXmlFilesForExport({ defs, exportType, commentsWithParaIds }) {
34303
- const { documentXml, relationships } = prepareCommentsXmlFilesForExport({
34198
+ const { documentXml, relationships, removedTargets = [], warnings = [] } = prepareCommentsXmlFilesForExport({
34304
34199
  exportType,
34305
34200
  convertedXml: this.convertedXml,
34306
34201
  defs,
34307
34202
  commentsWithParaIds,
34308
34203
  threadingProfile: this.commentThreadingProfile
34309
34204
  });
34205
+ if (warnings.length) this.exportWarnings.push(...warnings);
34310
34206
  return {
34311
34207
  documentXml,
34312
- relationships
34208
+ relationships,
34209
+ removedTargets
34313
34210
  };
34314
34211
  }
34315
34212
  #exportProcessHeadersFooters({ isFinalDoc = false }) {
@@ -34415,6 +34312,21 @@ var SuperConverter = class SuperConverter {
34415
34312
  const relationships = this.convertedXml["word/_rels/document.xml.rels"].elements.find((x$1) => x$1.name === "Relationships");
34416
34313
  relationships.elements = mergeRelationshipElements(relationships.elements, rels);
34417
34314
  }
34315
+ #pruneCommentRelationships(removedTargets) {
34316
+ const relationships = this.convertedXml["word/_rels/document.xml.rels"].elements.find((x$1) => x$1.name === "Relationships");
34317
+ if (!relationships?.elements) return;
34318
+ const normalizeTarget = (target) => {
34319
+ if (!target) return "";
34320
+ return target.replace(/^\.\//, "").replace(/^\//, "").replace(/^word\//, "");
34321
+ };
34322
+ const removedSet = new Set(removedTargets.map(normalizeTarget));
34323
+ relationships.elements = relationships.elements.filter((rel) => {
34324
+ const type = rel.attributes?.Type;
34325
+ const target = normalizeTarget(rel.attributes?.Target);
34326
+ if (COMMENT_RELATIONSHIP_TYPES.has(type) && removedSet.has(target)) return false;
34327
+ return true;
34328
+ });
34329
+ }
34418
34330
  async #exportProcessMediaFiles(media = {}) {
34419
34331
  const processedData = { ...this.convertedXml.media || {} };
34420
34332
  for (const [filePath, value] of Object.entries(media)) {