docxmlater 10.3.0 → 10.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipManager.d.ts","sourceRoot":"","sources":["../../src/core/RelationshipManager.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAMhE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,MAAM,CAAS;;IAevB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY;IAmBzD,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAOrD,mBAAmB,IAAI,YAAY,EAAE;IAQrC,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,YAAY,EAAE;IAQvE,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IASpC,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAOvC,QAAQ,IAAI,MAAM;IAOlB,KAAK,IAAI,IAAI;IAUb,UAAU,IAAI,MAAM;IAQpB,SAAS,IAAI,YAAY;IASzB,YAAY,IAAI,YAAY;IAS5B,YAAY,IAAI,YAAY;IAS5B,WAAW,IAAI,YAAY;IAS3B,cAAc,IAAI,YAAY;IAS9B,QAAQ,IAAI,YAAY;IAUxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAUtC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAUvC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAUvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY;IAgBvC,qBAAqB,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAyBtE,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAgBlE,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY;IAqB/C,wBAAwB,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM;IAyB5D,WAAW,IAAI,YAAY;IAS3B,YAAY,IAAI,YAAY;IAS5B,WAAW,IAAI,YAAY;IAS3B,SAAS,IAAI,YAAY;IASzB,WAAW,IAAI,MAAM;IAmBrB,MAAM,CAAC,iBAAiB,IAAI,mBAAmB;IAe/C,MAAM,CAAC,MAAM,IAAI,mBAAmB;IASpC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB;CAgDjD"}
1
+ {"version":3,"file":"RelationshipManager.d.ts","sourceRoot":"","sources":["../../src/core/RelationshipManager.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAOhE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,MAAM,CAAS;;IAevB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY;IAmBzD,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAOrD,mBAAmB,IAAI,YAAY,EAAE;IAQrC,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,YAAY,EAAE;IAQvE,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IASpC,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAOvC,QAAQ,IAAI,MAAM;IAOlB,KAAK,IAAI,IAAI;IAUb,UAAU,IAAI,MAAM;IAQpB,SAAS,IAAI,YAAY;IASzB,YAAY,IAAI,YAAY;IAS5B,YAAY,IAAI,YAAY;IAS5B,WAAW,IAAI,YAAY;IAS3B,cAAc,IAAI,YAAY;IAS9B,QAAQ,IAAI,YAAY;IAUxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAUtC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAUvC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAUvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY;IAgBvC,qBAAqB,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAyBtE,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAgBlE,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY;IAqB/C,wBAAwB,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM;IAyB5D,WAAW,IAAI,YAAY;IAS3B,YAAY,IAAI,YAAY;IAS5B,WAAW,IAAI,YAAY;IAS3B,SAAS,IAAI,YAAY;IASzB,WAAW,IAAI,MAAM;IAmBrB,MAAM,CAAC,iBAAiB,IAAI,mBAAmB;IAe/C,MAAM,CAAC,MAAM,IAAI,mBAAmB;IASpC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB;CAyDjD"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RelationshipManager = void 0;
4
4
  const Relationship_1 = require("./Relationship");
5
5
  const XMLParser_1 = require("../xml/XMLParser");
6
+ const validation_1 = require("../utils/validation");
6
7
  class RelationshipManager {
7
8
  relationships;
8
9
  nextId;
@@ -181,10 +182,17 @@ class RelationshipManager {
181
182
  const validatedTargetMode = targetMode === 'Internal' || targetMode === 'External' || targetMode === undefined
182
183
  ? targetMode
183
184
  : undefined;
185
+ let sanitizedTarget = target;
186
+ if (type.endsWith('/hyperlink')) {
187
+ const result = (0, validation_1.sanitizeHyperlinkUrl)(target);
188
+ if (result) {
189
+ sanitizedTarget = result.url;
190
+ }
191
+ }
184
192
  const relationship = Relationship_1.Relationship.create({
185
193
  id,
186
194
  type,
187
- target,
195
+ target: sanitizedTarget,
188
196
  targetMode: validatedTargetMode || 'Internal',
189
197
  });
190
198
  manager.addRelationship(relationship);
@@ -1 +1 @@
1
- {"version":3,"file":"RelationshipManager.js","sourceRoot":"","sources":["../../src/core/RelationshipManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RelationshipManager - Manages collections of relationships\n *\n * Handles relationship creation, tracking, and XML generation for various\n * document parts (document.xml, header.xml, footer.xml, etc.)\n */\n\nimport { Relationship, RelationshipType } from './Relationship';\nimport { XMLParser } from '../xml/XMLParser';\n\n/**\n * Manages relationships for a document or document part\n */\nexport class RelationshipManager {\n private relationships: Map<string, Relationship>;\n private nextId: number;\n\n /**\n * Creates a new relationship manager\n */\n constructor() {\n this.relationships = new Map();\n this.nextId = 1;\n }\n\n /**\n * Adds a relationship\n * @param relationship The relationship to add\n * @returns The relationship that was added\n */\n addRelationship(relationship: Relationship): Relationship {\n this.relationships.set(relationship.getId(), relationship);\n\n // Update next ID if necessary\n const idMatch = /^rId(\\d+)$/.exec(relationship.getId());\n if (idMatch?.[1]) {\n const idNum = parseInt(idMatch[1], 10);\n if (idNum >= this.nextId) {\n this.nextId = idNum + 1;\n }\n }\n\n return relationship;\n }\n\n /**\n * Gets a relationship by ID\n * @param id The relationship ID\n */\n getRelationship(id: string): Relationship | undefined {\n return this.relationships.get(id);\n }\n\n /**\n * Gets all relationships\n */\n getAllRelationships(): Relationship[] {\n return Array.from(this.relationships.values());\n }\n\n /**\n * Gets relationships of a specific type\n * @param type The relationship type\n */\n getRelationshipsByType(type: string | RelationshipType): Relationship[] {\n return this.getAllRelationships().filter((rel) => rel.getType() === type);\n }\n\n /**\n * Checks if a relationship exists\n * @param id The relationship ID\n */\n hasRelationship(id: string): boolean {\n return this.relationships.has(id);\n }\n\n /**\n * Removes a relationship\n * @param id The relationship ID\n * @returns True if removed, false if not found\n */\n removeRelationship(id: string): boolean {\n return this.relationships.delete(id);\n }\n\n /**\n * Gets the number of relationships\n */\n getCount(): number {\n return this.relationships.size;\n }\n\n /**\n * Clears all relationships\n */\n clear(): this {\n this.relationships.clear();\n this.nextId = 1;\n return this;\n }\n\n /**\n * Generates a new unique relationship ID\n * @returns New relationship ID (e.g., 'rId1', 'rId2')\n */\n generateId(): string {\n return `rId${this.nextId++}`;\n }\n\n /**\n * Adds a styles relationship\n * @returns The created relationship\n */\n addStyles(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createStyles(id));\n }\n\n /**\n * Adds a numbering relationship\n * @returns The created relationship\n */\n addNumbering(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createNumbering(id));\n }\n\n /**\n * Adds a fontTable relationship\n * @returns The created relationship\n */\n addFontTable(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createFontTable(id));\n }\n\n /**\n * Adds a settings relationship\n * @returns The created relationship\n */\n addSettings(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createSettings(id));\n }\n\n /**\n * Adds a webSettings relationship\n * @returns The created relationship\n */\n addWebSettings(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createWebSettings(id));\n }\n\n /**\n * Adds a theme relationship\n * @returns The created relationship\n */\n addTheme(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createTheme(id));\n }\n\n /**\n * Adds an image relationship\n * @param target Image path relative to the part (e.g., 'media/image1.png')\n * @returns The created relationship\n */\n addImage(target: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createImage(id, target));\n }\n\n /**\n * Adds a header relationship\n * @param target Header file path (e.g., 'header1.xml')\n * @returns The created relationship\n */\n addHeader(target: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createHeader(id, target));\n }\n\n /**\n * Adds a footer relationship\n * @param target Footer file path (e.g., 'footer1.xml')\n * @returns The created relationship\n */\n addFooter(target: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createFooter(id, target));\n }\n\n /**\n * Adds a hyperlink relationship\n * @param url The hyperlink URL\n * @returns The created relationship\n */\n addHyperlink(url: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createHyperlink(id, url));\n }\n\n /**\n * Updates the target URL of an existing hyperlink relationship\n *\n * This method modifies an existing relationship's target in-place, maintaining\n * the same relationship ID. This is crucial for proper OpenXML compliance\n * per ECMA-376 §17.16.22, as it prevents orphaned relationships.\n *\n * @param relationshipId The ID of the relationship to update\n * @param newUrl The new URL to set\n * @returns True if updated, false if relationship not found\n */\n updateHyperlinkTarget(relationshipId: string, newUrl: string): boolean {\n const relationship = this.getRelationship(relationshipId);\n if (!relationship) {\n return false;\n }\n\n // Verify this is a hyperlink relationship\n if (relationship.getType() !== RelationshipType.HYPERLINK) {\n throw new Error(\n `Relationship ${relationshipId} is not a hyperlink relationship. ` +\n `Type is ${relationship.getType()}, expected ${RelationshipType.HYPERLINK}`\n );\n }\n\n // Update the target URL\n relationship.setTarget(newUrl);\n return true;\n }\n\n /**\n * Finds a hyperlink relationship by its target URL\n *\n * @param targetUrl The URL to search for\n * @returns The matching relationship, or undefined if not found\n */\n findHyperlinkByTarget(targetUrl: string): Relationship | undefined {\n return this.getAllRelationships().find(\n (rel) => rel.getType() === RelationshipType.HYPERLINK && rel.getTarget() === targetUrl\n );\n }\n\n /**\n * Gets or creates a hyperlink relationship for the given URL\n *\n * This method ensures we don't create duplicate relationships for the same URL.\n * If a relationship already exists for the URL, it returns the existing one.\n * Otherwise, it creates a new relationship.\n *\n * @param url The hyperlink URL\n * @returns The existing or newly created relationship\n */\n getOrCreateHyperlink(url: string): Relationship {\n // Check if relationship already exists for this URL\n const existing = this.findHyperlinkByTarget(url);\n if (existing) {\n return existing;\n }\n\n // Create new relationship\n return this.addHyperlink(url);\n }\n\n /**\n * Removes orphaned hyperlink relationships\n *\n * This method removes hyperlink relationships that are no longer referenced\n * by any hyperlink in the document. Call this after updating URLs to clean\n * up any orphaned relationships.\n *\n * @param referencedIds Set of relationship IDs that are still in use\n * @returns Number of relationships removed\n */\n removeOrphanedHyperlinks(referencedIds: Set<string>): number {\n let removed = 0;\n const toRemove: string[] = [];\n\n // Find orphaned relationships\n for (const rel of this.getAllRelationships()) {\n if (rel.getType() === RelationshipType.HYPERLINK && !referencedIds.has(rel.getId())) {\n toRemove.push(rel.getId());\n }\n }\n\n // Remove orphaned relationships\n for (const id of toRemove) {\n if (this.removeRelationship(id)) {\n removed++;\n }\n }\n\n return removed;\n }\n\n /**\n * Adds a comments relationship\n * @returns The created relationship\n */\n addComments(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createComments(id));\n }\n\n /**\n * Adds a footnotes relationship\n * @returns The created relationship\n */\n addFootnotes(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createFootnotes(id));\n }\n\n /**\n * Adds an endnotes relationship\n * @returns The created relationship\n */\n addEndnotes(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createEndnotes(id));\n }\n\n /**\n * Adds a people relationship (track changes authors)\n * @returns The created relationship\n */\n addPeople(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createPeople(id));\n }\n\n /**\n * Generates the relationships XML file content\n * @returns Complete XML string for .rels file\n */\n generateXml(): string {\n const relationships = this.getAllRelationships();\n\n let xml = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n xml += '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\\n';\n\n for (const rel of relationships) {\n xml += rel.toXML() + '\\n';\n }\n\n xml += '</Relationships>';\n\n return xml;\n }\n\n /**\n * Creates a new relationship manager with common document relationships\n * @returns RelationshipManager with styles, numbering, fontTable, settings, and theme relationships\n */\n static createForDocument(): RelationshipManager {\n const manager = new RelationshipManager();\n manager.addStyles();\n manager.addNumbering();\n manager.addFontTable();\n manager.addSettings();\n manager.addWebSettings();\n manager.addTheme();\n return manager;\n }\n\n /**\n * Creates an empty relationship manager\n * @returns Empty RelationshipManager\n */\n static create(): RelationshipManager {\n return new RelationshipManager();\n }\n\n /**\n * Parses relationships from XML string and creates a populated manager\n * @param xml The relationships XML content (.rels file)\n * @returns RelationshipManager with parsed relationships\n */\n static fromXml(xml: string): RelationshipManager {\n const manager = new RelationshipManager();\n\n // Prevent ReDoS: validate input size (typical .rels files are < 10KB)\n if (xml.length > 100000) {\n throw new Error(\n 'Relationships XML file too large (>100KB). Possible malicious input or corrupted file.'\n );\n }\n\n // Use XMLParser to extract all Relationship elements\n const relationshipElements = XMLParser.extractElements(xml, 'Relationship');\n\n // Prevent infinite loops: check relationship count\n if (relationshipElements.length > 1000) {\n throw new Error('Too many relationships in XML file (>1000). Possible malicious input.');\n }\n\n // Process each relationship element\n for (const relationshipElement of relationshipElements) {\n // Extract attributes using XMLParser\n const id = XMLParser.extractAttribute(relationshipElement, 'Id');\n const type = XMLParser.extractAttribute(relationshipElement, 'Type');\n const target = XMLParser.extractAttribute(relationshipElement, 'Target');\n const targetMode = XMLParser.extractAttribute(relationshipElement, 'TargetMode');\n\n // Only create relationship if all required attributes present\n if (id && type && target) {\n // Validate targetMode before type assertion\n const validatedTargetMode =\n targetMode === 'Internal' || targetMode === 'External' || targetMode === undefined\n ? targetMode\n : undefined;\n\n // Create and add relationship\n const relationship = Relationship.create({\n id,\n type,\n target,\n targetMode: validatedTargetMode || 'Internal',\n });\n\n manager.addRelationship(relationship);\n }\n }\n\n return manager;\n }\n}\n"]}
1
+ {"version":3,"file":"RelationshipManager.js","sourceRoot":"","sources":["../../src/core/RelationshipManager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RelationshipManager - Manages collections of relationships\n *\n * Handles relationship creation, tracking, and XML generation for various\n * document parts (document.xml, header.xml, footer.xml, etc.)\n */\n\nimport { Relationship, RelationshipType } from './Relationship';\nimport { XMLParser } from '../xml/XMLParser';\nimport { sanitizeHyperlinkUrl } from '../utils/validation';\n\n/**\n * Manages relationships for a document or document part\n */\nexport class RelationshipManager {\n private relationships: Map<string, Relationship>;\n private nextId: number;\n\n /**\n * Creates a new relationship manager\n */\n constructor() {\n this.relationships = new Map();\n this.nextId = 1;\n }\n\n /**\n * Adds a relationship\n * @param relationship The relationship to add\n * @returns The relationship that was added\n */\n addRelationship(relationship: Relationship): Relationship {\n this.relationships.set(relationship.getId(), relationship);\n\n // Update next ID if necessary\n const idMatch = /^rId(\\d+)$/.exec(relationship.getId());\n if (idMatch?.[1]) {\n const idNum = parseInt(idMatch[1], 10);\n if (idNum >= this.nextId) {\n this.nextId = idNum + 1;\n }\n }\n\n return relationship;\n }\n\n /**\n * Gets a relationship by ID\n * @param id The relationship ID\n */\n getRelationship(id: string): Relationship | undefined {\n return this.relationships.get(id);\n }\n\n /**\n * Gets all relationships\n */\n getAllRelationships(): Relationship[] {\n return Array.from(this.relationships.values());\n }\n\n /**\n * Gets relationships of a specific type\n * @param type The relationship type\n */\n getRelationshipsByType(type: string | RelationshipType): Relationship[] {\n return this.getAllRelationships().filter((rel) => rel.getType() === type);\n }\n\n /**\n * Checks if a relationship exists\n * @param id The relationship ID\n */\n hasRelationship(id: string): boolean {\n return this.relationships.has(id);\n }\n\n /**\n * Removes a relationship\n * @param id The relationship ID\n * @returns True if removed, false if not found\n */\n removeRelationship(id: string): boolean {\n return this.relationships.delete(id);\n }\n\n /**\n * Gets the number of relationships\n */\n getCount(): number {\n return this.relationships.size;\n }\n\n /**\n * Clears all relationships\n */\n clear(): this {\n this.relationships.clear();\n this.nextId = 1;\n return this;\n }\n\n /**\n * Generates a new unique relationship ID\n * @returns New relationship ID (e.g., 'rId1', 'rId2')\n */\n generateId(): string {\n return `rId${this.nextId++}`;\n }\n\n /**\n * Adds a styles relationship\n * @returns The created relationship\n */\n addStyles(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createStyles(id));\n }\n\n /**\n * Adds a numbering relationship\n * @returns The created relationship\n */\n addNumbering(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createNumbering(id));\n }\n\n /**\n * Adds a fontTable relationship\n * @returns The created relationship\n */\n addFontTable(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createFontTable(id));\n }\n\n /**\n * Adds a settings relationship\n * @returns The created relationship\n */\n addSettings(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createSettings(id));\n }\n\n /**\n * Adds a webSettings relationship\n * @returns The created relationship\n */\n addWebSettings(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createWebSettings(id));\n }\n\n /**\n * Adds a theme relationship\n * @returns The created relationship\n */\n addTheme(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createTheme(id));\n }\n\n /**\n * Adds an image relationship\n * @param target Image path relative to the part (e.g., 'media/image1.png')\n * @returns The created relationship\n */\n addImage(target: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createImage(id, target));\n }\n\n /**\n * Adds a header relationship\n * @param target Header file path (e.g., 'header1.xml')\n * @returns The created relationship\n */\n addHeader(target: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createHeader(id, target));\n }\n\n /**\n * Adds a footer relationship\n * @param target Footer file path (e.g., 'footer1.xml')\n * @returns The created relationship\n */\n addFooter(target: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createFooter(id, target));\n }\n\n /**\n * Adds a hyperlink relationship\n * @param url The hyperlink URL\n * @returns The created relationship\n */\n addHyperlink(url: string): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createHyperlink(id, url));\n }\n\n /**\n * Updates the target URL of an existing hyperlink relationship\n *\n * This method modifies an existing relationship's target in-place, maintaining\n * the same relationship ID. This is crucial for proper OpenXML compliance\n * per ECMA-376 §17.16.22, as it prevents orphaned relationships.\n *\n * @param relationshipId The ID of the relationship to update\n * @param newUrl The new URL to set\n * @returns True if updated, false if relationship not found\n */\n updateHyperlinkTarget(relationshipId: string, newUrl: string): boolean {\n const relationship = this.getRelationship(relationshipId);\n if (!relationship) {\n return false;\n }\n\n // Verify this is a hyperlink relationship\n if (relationship.getType() !== RelationshipType.HYPERLINK) {\n throw new Error(\n `Relationship ${relationshipId} is not a hyperlink relationship. ` +\n `Type is ${relationship.getType()}, expected ${RelationshipType.HYPERLINK}`\n );\n }\n\n // Update the target URL\n relationship.setTarget(newUrl);\n return true;\n }\n\n /**\n * Finds a hyperlink relationship by its target URL\n *\n * @param targetUrl The URL to search for\n * @returns The matching relationship, or undefined if not found\n */\n findHyperlinkByTarget(targetUrl: string): Relationship | undefined {\n return this.getAllRelationships().find(\n (rel) => rel.getType() === RelationshipType.HYPERLINK && rel.getTarget() === targetUrl\n );\n }\n\n /**\n * Gets or creates a hyperlink relationship for the given URL\n *\n * This method ensures we don't create duplicate relationships for the same URL.\n * If a relationship already exists for the URL, it returns the existing one.\n * Otherwise, it creates a new relationship.\n *\n * @param url The hyperlink URL\n * @returns The existing or newly created relationship\n */\n getOrCreateHyperlink(url: string): Relationship {\n // Check if relationship already exists for this URL\n const existing = this.findHyperlinkByTarget(url);\n if (existing) {\n return existing;\n }\n\n // Create new relationship\n return this.addHyperlink(url);\n }\n\n /**\n * Removes orphaned hyperlink relationships\n *\n * This method removes hyperlink relationships that are no longer referenced\n * by any hyperlink in the document. Call this after updating URLs to clean\n * up any orphaned relationships.\n *\n * @param referencedIds Set of relationship IDs that are still in use\n * @returns Number of relationships removed\n */\n removeOrphanedHyperlinks(referencedIds: Set<string>): number {\n let removed = 0;\n const toRemove: string[] = [];\n\n // Find orphaned relationships\n for (const rel of this.getAllRelationships()) {\n if (rel.getType() === RelationshipType.HYPERLINK && !referencedIds.has(rel.getId())) {\n toRemove.push(rel.getId());\n }\n }\n\n // Remove orphaned relationships\n for (const id of toRemove) {\n if (this.removeRelationship(id)) {\n removed++;\n }\n }\n\n return removed;\n }\n\n /**\n * Adds a comments relationship\n * @returns The created relationship\n */\n addComments(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createComments(id));\n }\n\n /**\n * Adds a footnotes relationship\n * @returns The created relationship\n */\n addFootnotes(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createFootnotes(id));\n }\n\n /**\n * Adds an endnotes relationship\n * @returns The created relationship\n */\n addEndnotes(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createEndnotes(id));\n }\n\n /**\n * Adds a people relationship (track changes authors)\n * @returns The created relationship\n */\n addPeople(): Relationship {\n const id = this.generateId();\n return this.addRelationship(Relationship.createPeople(id));\n }\n\n /**\n * Generates the relationships XML file content\n * @returns Complete XML string for .rels file\n */\n generateXml(): string {\n const relationships = this.getAllRelationships();\n\n let xml = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n xml += '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\\n';\n\n for (const rel of relationships) {\n xml += rel.toXML() + '\\n';\n }\n\n xml += '</Relationships>';\n\n return xml;\n }\n\n /**\n * Creates a new relationship manager with common document relationships\n * @returns RelationshipManager with styles, numbering, fontTable, settings, and theme relationships\n */\n static createForDocument(): RelationshipManager {\n const manager = new RelationshipManager();\n manager.addStyles();\n manager.addNumbering();\n manager.addFontTable();\n manager.addSettings();\n manager.addWebSettings();\n manager.addTheme();\n return manager;\n }\n\n /**\n * Creates an empty relationship manager\n * @returns Empty RelationshipManager\n */\n static create(): RelationshipManager {\n return new RelationshipManager();\n }\n\n /**\n * Parses relationships from XML string and creates a populated manager\n * @param xml The relationships XML content (.rels file)\n * @returns RelationshipManager with parsed relationships\n */\n static fromXml(xml: string): RelationshipManager {\n const manager = new RelationshipManager();\n\n // Prevent ReDoS: validate input size (typical .rels files are < 10KB)\n if (xml.length > 100000) {\n throw new Error(\n 'Relationships XML file too large (>100KB). Possible malicious input or corrupted file.'\n );\n }\n\n // Use XMLParser to extract all Relationship elements\n const relationshipElements = XMLParser.extractElements(xml, 'Relationship');\n\n // Prevent infinite loops: check relationship count\n if (relationshipElements.length > 1000) {\n throw new Error('Too many relationships in XML file (>1000). Possible malicious input.');\n }\n\n // Process each relationship element\n for (const relationshipElement of relationshipElements) {\n // Extract attributes using XMLParser\n const id = XMLParser.extractAttribute(relationshipElement, 'Id');\n const type = XMLParser.extractAttribute(relationshipElement, 'Type');\n const target = XMLParser.extractAttribute(relationshipElement, 'Target');\n const targetMode = XMLParser.extractAttribute(relationshipElement, 'TargetMode');\n\n // Only create relationship if all required attributes present\n if (id && type && target) {\n // Validate targetMode before type assertion\n const validatedTargetMode =\n targetMode === 'Internal' || targetMode === 'External' || targetMode === undefined\n ? targetMode\n : undefined;\n\n // Sanitize hyperlink URLs (strip browser extension prefixes)\n let sanitizedTarget = target;\n if (type.endsWith('/hyperlink')) {\n const result = sanitizeHyperlinkUrl(target);\n if (result) {\n sanitizedTarget = result.url;\n }\n }\n\n // Create and add relationship\n const relationship = Relationship.create({\n id,\n type,\n target: sanitizedTarget,\n targetMode: validatedTargetMode || 'Internal',\n });\n\n manager.addRelationship(relationship);\n }\n }\n\n return manager;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Hyperlink.d.ts","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Hyperlink.d.ts","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"AAkDA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAQ3C,MAAM,WAAW,mBAAmB;IAElC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,aAAa,CAAC;IAE3B,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAKD,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAC,CAAS;IACrB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,UAAU,CAAgB;IAElC,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAE1B,OAAO,CAAC,OAAO,CAAC,CAAS;IAEzB,OAAO,CAAC,WAAW,CAAC,CAAS;IAE7B,OAAO,CAAC,eAAe,CAAC,CAAwD;IAEhF,OAAO,CAAC,gBAAgB,CAAC,CAAkC;IAE3D,OAAO,CAAC,sBAAsB,CAAC,CAAgB;gBAUnC,UAAU,EAAE,mBAAmB;IA8D3C,mBAAmB,CAAC,OAAO,EAAE,OAAO,6BAA6B,EAAE,eAAe,GAAG,IAAI;IASzF,mBAAmB,CAAC,SAAS,EAAE,OAAO,aAAa,EAAE,SAAS,GAAG,IAAI;IAQrE,mBAAmB,IAAI,OAAO,aAAa,EAAE,SAAS,GAAG,SAAS;IAclE,OAAO,CAAC,yBAAyB;IA2CjC,MAAM,IAAI,MAAM,GAAG,SAAS;IAkC5B,UAAU,IAAI,MAAM,GAAG,SAAS;IAUhC,SAAS,IAAI,MAAM,GAAG,SAAS;IAQ/B,OAAO,IAAI,OAAO;IAOlB,WAAW,IAAI,MAAM,GAAG,SAAS;IAOjC,UAAU,IAAI,MAAM,GAAG,SAAS;IAQhC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAS/C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAQ7C,cAAc,IAAI,MAAM,GAAG,SAAS;IAQpC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAcrD,OAAO,IAAI,MAAM;IAOjB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAyD3B,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAStB,UAAU,IAAI,MAAM,GAAG,SAAS;IAOhC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IA2CjC,iBAAiB,IAAI,MAAM,GAAG,SAAS;IAOvC,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IA2BnC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IA4ErC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAgF3C,MAAM,IAAI,GAAG;IAqBb,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IA6B/E,aAAa,IAAI,IAAI;IAQrB,gBAAgB,IAAI,aAAa;IAYjC,QAAQ,IAAI,MAAM,GAAG,SAAS;IAQ9B,YAAY,IAAI,MAAM,GAAG,OAAO,GAAG,SAAS;IAQ5C,OAAO,IAAI,OAAO;IAQlB,SAAS,IAAI,OAAO;IAQpB,OAAO,IAAI,MAAM,GAAG,SAAS;IAQ7B,OAAO,IAAI,MAAM,GAAG,SAAS;IAS7B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAe7B,YAAY,CAAC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI;IAe1F,OAAO,CAAC,IAAI,UAAO,GAAG,IAAI;IAe1B,SAAS,CAAC,MAAM,UAAO,GAAG,IAAI;IAe9B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAe3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAmDrB,cAAc,CAAC,OAAO,CAAC,EAAE;QAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE;YAAE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC;KAC1D,GAAG,OAAO,CAAC;QACV,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAgJF,yBAAyB,IAAI,IAAI;IAkBjC,UAAU,IAAI,OAAO;IAOrB,UAAU,IAAI,OAAO;IAyBrB,KAAK,IAAI,SAAS;IAqClB,KAAK,IAAI,UAAU;IAgFnB,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,SAAS;IAUvF,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,SAAS;IAU1F,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,SAAS;IAcvF,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,aAAa,GAAG,SAAS;IAYvF,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,mBAAmB,GAAG,SAAS;CAG1D"}
@@ -396,6 +396,11 @@ class Hyperlink {
396
396
  return { valid: false, issues, fixed, originalUrl };
397
397
  }
398
398
  if (fixCommonIssues && fixedUrl) {
399
+ const sanitizeResult = (0, validation_1.sanitizeHyperlinkUrl)(fixedUrl);
400
+ if (sanitizeResult) {
401
+ fixedUrl = sanitizeResult.url;
402
+ fixed.push(...sanitizeResult.fixes);
403
+ }
399
404
  if (!/^[a-z]+:\/\//i.exec(fixedUrl)) {
400
405
  fixedUrl = 'https://' + fixedUrl;
401
406
  fixed.push('Added missing protocol (https://)');
@@ -1 +1 @@
1
- {"version":3,"file":"Hyperlink.js","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hyperlink - Represents a hyperlink in a Word document\n *\n * Hyperlinks can be external (to websites, files) or internal (to bookmarks within the document).\n * They are represented using the `<w:hyperlink>` element.\n *\n * ## Important: Relationship ID Requirement\n *\n * **External hyperlinks REQUIRE a relationship ID to be set before XML generation.**\n * Per ECMA-376 Part 1 §17.16.22, `<w:hyperlink>` elements with external targets must have\n * an `r:id` attribute that references a relationship in `word/_rels/document.xml.rels`.\n *\n * ### Correct Usage Pattern:\n *\n * ```typescript\n * // RECOMMENDED: Use Document.save() - automatically handles relationships\n * const doc = Document.create();\n * const para = doc.createParagraph();\n * para.addHyperlink(Hyperlink.createExternal('https://example.com', 'Link'));\n * await doc.save('document.docx'); // ✅ Relationships auto-registered\n * ```\n *\n * ### Manual Relationship Registration (Advanced):\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * const relationship = relationshipManager.addHyperlink('https://example.com');\n * link.setRelationshipId(relationship.getId());\n * link.toXML(); // ✅ Now valid\n * ```\n *\n * ### What NOT to Do:\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * link.toXML(); // ❌ ERROR: Missing relationship ID\n * ```\n *\n * ## Internal Hyperlinks\n *\n * Internal hyperlinks (bookmarks) do NOT require relationships:\n *\n * ```typescript\n * const link = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link.toXML(); // ✅ Valid - uses w:anchor attribute\n * ```\n *\n * @see {@link https://www.ecma-international.org/publications-and-standards/standards/ecma-376/ | ECMA-376 Part 1 §17.16.22}\n */\n\nimport { XMLElement } from '../xml/XMLBuilder';\nimport { Run, RunFormatting } from './Run';\nimport { Revision } from './Revision';\nimport { validateRunText } from '../utils/validation';\nimport { defaultLogger } from '../utils/logger';\n\n/**\n * Hyperlink properties\n */\nexport interface HyperlinkProperties {\n /** Hyperlink URL (for external links) */\n url?: string;\n /** Bookmark anchor (for internal links) */\n anchor?: string;\n /** Display text (optional for empty/invisible hyperlinks) */\n text?: string;\n /** Text formatting */\n formatting?: RunFormatting;\n /** Tooltip text */\n tooltip?: string;\n /** Relationship ID (set by Document when saving) */\n relationshipId?: string;\n /** Whether this is an empty/invisible hyperlink with no display text */\n isEmpty?: boolean;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n tgtFrame?: string;\n /** History tracking attribute */\n history?: string;\n /** Document location for within-document navigation in external files (ECMA-376 §17.16.22) */\n docLocation?: string;\n}\n\n/**\n * Represents a hyperlink\n */\nexport class Hyperlink {\n private url?: string;\n private anchor?: string;\n private text: string;\n private run: Run;\n private tooltip?: string;\n private relationshipId?: string;\n private formatting: RunFormatting;\n /** Whether this is an empty/invisible hyperlink with no display text */\n private _isEmpty = false;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n private tgtFrame?: string;\n /** History tracking attribute */\n private history?: string;\n /** Document location for within-document navigation in external files */\n private docLocation?: string;\n /** Tracking context for automatic change tracking */\n private trackingContext?: import('../tracking/TrackingContext').TrackingContext;\n /** Parent paragraph reference for automatic tracking */\n private _parentParagraph?: import('./Paragraph').Paragraph;\n /** Baseline formatting captured before first tracked formatting change */\n private _preTrackingFormatting?: RunFormatting;\n\n /**\n * Creates a new hyperlink\n *\n * **Note:** A hyperlink must have either a URL (external) or anchor (internal), but not both.\n * If both are provided, the URL takes precedence and a warning is logged.\n *\n * @param properties Hyperlink properties\n */\n constructor(properties: HyperlinkProperties) {\n this.url = properties.url;\n this.anchor = properties.anchor;\n this.tooltip = properties.tooltip;\n this.relationshipId = properties.relationshipId;\n this.tgtFrame = properties.tgtFrame;\n this.history = properties.history;\n this.docLocation = properties.docLocation;\n this._isEmpty = properties.isEmpty ?? false;\n\n // VALIDATION: Warn about hybrid links (url + anchor)\n if (this.url && this.anchor) {\n defaultLogger.warn(\n `DocXML Warning: Hyperlink has both URL (\"${this.url}\") and anchor (\"${this.anchor}\"). ` +\n `This is ambiguous per ECMA-376 spec. URL will take precedence. ` +\n `Use Hyperlink.createExternal() or Hyperlink.createInternal() to avoid ambiguity.`\n );\n }\n\n // Handle empty/invisible hyperlinks (no display text)\n if (this._isEmpty) {\n this.text = '';\n this.formatting = {};\n this.run = new Run('', {});\n return;\n }\n\n // Text fallback: properties.text → url → 'Link'\n // NOTE: Do NOT use anchor (bookmark ID) as display text - it should only be used for navigation\n // Using bookmark IDs as visible text causes TOC corruption (Issue: TOC shows \"HEADING=II.MNKE7E8NA385_\" instead of proper headings)\n this.text = properties.text || this.url || 'Link';\n\n // Validate text for XML patterns\n // Default to auto-cleaning XML patterns unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(this.text, {\n context: 'Hyperlink text',\n autoClean: properties.formatting?.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available and cleaning was requested\n if (validation.cleanedText) {\n this.text = validation.cleanedText;\n }\n\n // Create run with default hyperlink styling (Verdana 12pt blue underlined)\n this.formatting = {\n font: 'Verdana',\n size: 12,\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n ...properties.formatting,\n };\n\n this.run = new Run(this.text, this.formatting);\n }\n\n /**\n * Sets the tracking context for automatic change tracking.\n * Called by Document when track changes is enabled.\n * @internal\n */\n _setTrackingContext(context: import('../tracking/TrackingContext').TrackingContext): void {\n this.trackingContext = context;\n }\n\n /**\n * Sets the parent paragraph reference for automatic tracking.\n * Called by Paragraph when hyperlink is added.\n * @internal\n */\n _setParentParagraph(paragraph: import('./Paragraph').Paragraph): void {\n this._parentParagraph = paragraph;\n }\n\n /**\n * Gets the parent paragraph reference.\n * @internal\n */\n _getParentParagraph(): import('./Paragraph').Paragraph | undefined {\n return this._parentParagraph;\n }\n\n /**\n * Applies an rPrChange to the inner Run, tracking the delta between\n * the baseline formatting and the current formatting.\n *\n * On first call, captures `previousFormatting` as the baseline.\n * Subsequent calls always compare against the same baseline so that\n * multiple sequential formatting changes produce a single merged rPrChange.\n *\n * @internal\n */\n private _applyFormattingRPrChange(previousFormatting: RunFormatting): void {\n // Capture baseline on first tracked formatting change\n if (!this._preTrackingFormatting) {\n this._preTrackingFormatting = { ...previousFormatting };\n }\n\n // Build previousProperties from the baseline (only changed keys)\n const baseline = this._preTrackingFormatting;\n const current = this.formatting;\n const previousProperties: Partial<RunFormatting> = {};\n let hasChanges = false;\n\n for (const key of Object.keys(baseline) as (keyof RunFormatting)[]) {\n if (baseline[key] !== current[key]) {\n (previousProperties as Record<string, unknown>)[key] = baseline[key];\n hasChanges = true;\n }\n }\n // Also check for keys in current that weren't in baseline (new properties)\n for (const key of Object.keys(current) as (keyof RunFormatting)[]) {\n if (!(key in baseline) && current[key] !== undefined) {\n // Property didn't exist before — previous value is undefined\n (previousProperties as Record<string, unknown>)[key] = undefined;\n hasChanges = true;\n }\n }\n\n if (!hasChanges) return;\n\n const revisionId = this.trackingContext!.getRevisionManager().consumeNextId();\n const author = this.trackingContext!.getAuthor();\n\n this.run.setPropertyChangeRevision({\n id: revisionId,\n author,\n date: new Date(),\n previousProperties,\n });\n }\n\n /**\n * Gets the hyperlink URL\n */\n getUrl(): string | undefined {\n return this.url;\n }\n\n /**\n * Gets the complete URL including any anchor fragment.\n *\n * For external links that also have an anchor (e.g., internal bookmark within external page),\n * this returns the URL with the anchor appended as a fragment.\n * For internal-only links (anchor without URL), returns undefined.\n *\n * Note: As of v7.2.0, DocumentParser automatically combines external URLs with anchors\n * during parsing, so getUrl() typically returns the full URL. This method is provided\n * for cases where URL and anchor are set separately via the API.\n *\n * @returns The complete URL with fragment, or undefined for internal-only links\n *\n * @example\n * ```typescript\n * // External link with anchor fragment\n * const link = new Hyperlink({ url: 'https://example.com/', anchor: '!/view?id=123', text: 'Link' });\n * link.getUrl(); // 'https://example.com/'\n * link.getAnchor(); // '!/view?id=123'\n * link.getFullUrl(); // 'https://example.com/#!/view?id=123'\n *\n * // External link without anchor\n * const link2 = Hyperlink.createExternal('https://example.com/page', 'Link');\n * link2.getFullUrl(); // 'https://example.com/page'\n *\n * // Internal link (bookmark reference)\n * const link3 = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link3.getFullUrl(); // undefined\n * ```\n */\n getFullUrl(): string | undefined {\n if (this.url && this.anchor) {\n return this.url + '#' + this.anchor;\n }\n return this.url;\n }\n\n /**\n * Gets the anchor (for internal links)\n */\n getAnchor(): string | undefined {\n return this.anchor;\n }\n\n /**\n * Returns whether this is an empty/invisible hyperlink (has no display text).\n * Empty hyperlinks are self-closing elements in the XML.\n */\n isEmpty(): boolean {\n return this._isEmpty;\n }\n\n /**\n * Gets the target frame attribute (e.g., \"_blank\" for new window)\n */\n getTgtFrame(): string | undefined {\n return this.tgtFrame;\n }\n\n /**\n * Gets the history tracking attribute\n */\n getHistory(): string | undefined {\n return this.history;\n }\n\n /**\n * Sets the target frame attribute\n * @param tgtFrame Target frame (e.g., \"_blank\" for new window)\n */\n setTgtFrame(tgtFrame: string | undefined): this {\n this.tgtFrame = tgtFrame;\n return this;\n }\n\n /**\n * Sets the history tracking attribute\n * @param history History value (e.g., \"1\" to add to history)\n */\n setHistory(history: string | undefined): this {\n this.history = history;\n return this;\n }\n\n /**\n * Gets the document location attribute (ECMA-376 §17.16.22)\n */\n getDocLocation(): string | undefined {\n return this.docLocation;\n }\n\n /**\n * Sets the document location for within-document navigation in external files\n * @param docLocation Location string\n */\n setDocLocation(docLocation: string | undefined): this {\n this.docLocation = docLocation;\n return this;\n }\n\n /**\n * Gets the display text\n *\n * This method delegates to the internal run to ensure the returned text\n * is always accurate and matches what will be in the generated XML,\n * per ECMA-376 Part 1 §17.16.22.\n *\n * @returns The display text including any special characters (tabs, breaks, etc.)\n */\n getText(): string {\n return this.run.getText();\n }\n\n /**\n * Sets the display text\n */\n setText(text: string): this {\n // Validate text for XML patterns\n // Default to auto-cleaning unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(text, {\n context: 'Hyperlink.setText',\n autoClean: this.formatting.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available\n const cleanedText = validation.cleanedText || text;\n\n const previousValue = this.text;\n\n // Skip if text unchanged\n if (previousValue === cleanedText) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.text = cleanedText;\n this.run.setText(cleanedText);\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.text = cleanedText;\n this.run.setText(cleanedText);\n return this;\n }\n\n /**\n * Sets the internal run directly (for advanced use cases like TOC parsing)\n * Used by DocumentParser to preserve run content (tabs, breaks, etc.)\n * @param run - The run to use for this hyperlink\n */\n setRun(run: Run): this {\n this.run = run;\n this.text = run.getText();\n return this;\n }\n\n /**\n * Gets the tooltip\n */\n getTooltip(): string | undefined {\n return this.tooltip;\n }\n\n /**\n * Sets the tooltip\n */\n setTooltip(tooltip: string): this {\n const previousValue = this.tooltip;\n\n // Skip if tooltip unchanged\n if (previousValue === tooltip) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n // Tooltip is a w:hyperlink attribute — no OOXML property-change element exists for it\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.tooltip = tooltip;\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path\n this.tooltip = tooltip;\n return this;\n }\n\n /**\n * Gets the relationship ID\n */\n getRelationshipId(): string | undefined {\n return this.relationshipId;\n }\n\n /**\n * Sets the relationship ID (called by Document during save)\n */\n setRelationshipId(id: string): this {\n this.relationshipId = id;\n return this;\n }\n\n /**\n * Sets or updates the hyperlink URL\n *\n * When URL is updated, we mark that the relationship needs updating.\n * The actual relationship update happens during Document.save() to ensure\n * proper coordination with the RelationshipManager.\n *\n * **Important:** This method maintains the relationship ID but flags it for update.\n * The RelationshipManager will update the existing relationship's target URL\n * during save, preventing orphaned relationships per ECMA-376 §17.16.22.\n *\n * @param url - The new URL (or undefined to clear)\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing URL would create empty hyperlink (no URL and no anchor)\n *\n * @example\n * ```typescript\n * const link = Hyperlink.createExternal('https://old.com', 'Link');\n * link.setUrl('https://new.com'); // Marks for relationship update\n * await doc.save('updated.docx'); // Updates relationship target\n * ```\n */\n setUrl(url: string | undefined): this {\n // Validate that clearing URL doesn't create empty hyperlink\n if (!url && !this.anchor) {\n throw new Error(\n `Cannot set URL to undefined: Hyperlink \"${this.run.getText()}\" has no anchor. ` +\n `Clearing the URL would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new URL or delete the hyperlink entirely.`\n );\n }\n\n // Save old URL before updating (for text fallback logic)\n const oldUrl = this.url;\n\n // Skip if URL unchanged (optimization)\n if (oldUrl === url) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.url = url;\n this.relationshipId = undefined;\n if (this.run.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.run.setText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.url = url;\n\n // Clear the relationship ID so it will be re-registered during save\n // This ensures the relationship target is updated to point to the new URL\n this.relationshipId = undefined;\n\n // Update text ONLY if it was auto-generated from the old URL\n // This preserves user-provided text (even if it's \"Link\")\n // Use run.getText() to ensure we check the actual current text, not stale cache\n if (this.run.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.run.setText(this.text);\n }\n\n return this;\n }\n\n /**\n * Sets the anchor (for internal links)\n * @param anchor Bookmark name to link to\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing anchor would create empty hyperlink (no URL and no anchor)\n * @example\n * ```typescript\n * const link = Hyperlink.createInternal('OldBookmark', 'Go there');\n * link.setAnchor('NewBookmark'); // Update internal link target\n * ```\n */\n setAnchor(anchor: string | undefined): this {\n // Validate that clearing anchor doesn't create empty hyperlink\n if (!anchor && !this.url) {\n throw new Error(\n `Cannot set anchor to undefined: Hyperlink \"${this.run.getText()}\" has no URL. ` +\n `Clearing the anchor would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new anchor or delete the hyperlink entirely.`\n );\n }\n\n // Save old anchor before updating\n const oldAnchor = this.anchor;\n\n // Skip if anchor unchanged (optimization)\n if (oldAnchor === anchor) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.anchor = anchor;\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n if (this.run.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.run.setText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.anchor = anchor;\n\n // If converting from external to internal, clear URL and relationship\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n\n // Update text ONLY if it was auto-generated from the old anchor\n // Use run.getText() to ensure we check the actual current text, not stale cache\n if (this.run.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.run.setText(this.text);\n }\n\n return this;\n }\n\n /**\n * Gets the run\n */\n getRun(): Run {\n return this.run;\n }\n\n /**\n * Sets run formatting\n *\n * @param formatting - The formatting to apply\n * @param options - Optional settings\n * @param options.replace - If true, replaces ALL existing formatting instead of merging.\n * Use this when you want to clear inherited styles like characterStyle.\n *\n * @example\n * ```typescript\n * // Merge mode (default): adds/updates properties while preserving others\n * hyperlink.setFormatting({ bold: true });\n *\n * // Replace mode: clears all existing formatting and applies only the new properties\n * hyperlink.setFormatting({ font: \"Verdana\", size: 12 }, { replace: true });\n * ```\n */\n setFormatting(formatting: RunFormatting, options?: { replace?: boolean }): this {\n // Update stored formatting\n const previousFormatting = { ...this.formatting };\n if (options?.replace) {\n // Replace mode: new formatting replaces ALL existing properties\n this.formatting = { ...formatting };\n } else {\n // Merge mode (default, backwards-compatible): merge with existing\n this.formatting = { ...this.formatting, ...formatting };\n }\n // Create new run with updated formatting, preserving current text\n const currentText = this.run.getText();\n this.run = new Run(currentText, this.formatting);\n this.text = currentText; // Keep cache in sync\n if (this.trackingContext?.isEnabled()) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Gets run formatting (returns this hyperlink for fluent API)\n * @returns This hyperlink for method chaining\n *\n * @example\n * ```typescript\n * hyperlink.getFormatting().setColor('0563C1').setUnderline('single');\n * ```\n */\n getFormatting(): this {\n return this;\n }\n\n /**\n * Gets the raw formatting object (for direct access)\n * @returns RunFormatting object\n */\n getRawFormatting(): RunFormatting {\n return this.formatting;\n }\n\n // ============================================================================\n // Individual Formatting Getters\n // ============================================================================\n\n /**\n * Gets the text color\n * @returns Color hex string or undefined\n */\n getColor(): string | undefined {\n return this.formatting.color;\n }\n\n /**\n * Gets the underline style\n * @returns Underline style or undefined\n */\n getUnderline(): string | boolean | undefined {\n return this.formatting.underline;\n }\n\n /**\n * Gets whether the hyperlink is bold\n * @returns True if bold, false otherwise\n */\n getBold(): boolean {\n return this.formatting.bold ?? false;\n }\n\n /**\n * Gets whether the hyperlink is italic\n * @returns True if italic, false otherwise\n */\n getItalic(): boolean {\n return this.formatting.italic ?? false;\n }\n\n /**\n * Gets the font family\n * @returns Font name or undefined\n */\n getFont(): string | undefined {\n return this.formatting.font;\n }\n\n /**\n * Gets the font size\n * @returns Font size in points or undefined\n */\n getSize(): number | undefined {\n return this.formatting.size;\n }\n\n /**\n * Sets text color\n * @param color Color in hex format (e.g., '0563C1')\n * @returns This hyperlink for chaining\n */\n setColor(color: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.color = color;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.color !== color) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets underline style\n * @param underline Underline style ('single', 'double', etc.)\n * @returns This hyperlink for chaining\n */\n setUnderline(underline: boolean | 'single' | 'double' | 'dotted' | 'thick' | 'dash'): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.underline = underline;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.underline !== underline) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets bold formatting\n * @param bold Bold state (default: true)\n * @returns This hyperlink for chaining\n */\n setBold(bold = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.bold = bold;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.bold !== bold) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets italic formatting\n * @param italic Italic state (default: true)\n * @returns This hyperlink for chaining\n */\n setItalic(italic = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.italic = italic;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.italic !== italic) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font family\n * @param font Font name (e.g., 'Arial', 'Verdana')\n * @returns This hyperlink for chaining\n */\n setFont(font: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.font = font;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.font !== font) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font size\n * @param size Font size in points (e.g., 12, 14)\n * @returns This hyperlink for chaining\n */\n setSize(size: number): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.size = size;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.size !== size) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Validates the hyperlink URL and optionally fixes common issues\n *\n * Performs validation and fixing of hyperlink URLs including:\n * - Checking URL accessibility (HTTP HEAD request for external links)\n * - Fixing common URL issues (missing protocol, double slashes, spaces)\n * - Validating internal bookmark references\n * - Detecting broken links\n *\n * **Note:** This method is async due to network requests for accessibility checks.\n *\n * @param options - Validation options\n * @returns Promise with validation results\n *\n * @example\n * ```typescript\n * // Basic URL fixing without network check\n * const result = await link.validateAndFix({\n * fixCommonIssues: true,\n * checkAccessibility: false\n * });\n * console.log(`Fixed: ${result.fixed.join(', ')}`);\n *\n * // Full validation with accessibility check\n * const validation = await link.validateAndFix({\n * checkAccessibility: true,\n * timeout: 5000\n * });\n * if (!validation.valid) {\n * console.log(`Issues: ${validation.issues.join(', ')}`);\n * }\n *\n * // Batch validate all hyperlinks in document\n * for (const { hyperlink } of doc.getHyperlinks()) {\n * const result = await hyperlink.validateAndFix();\n * if (result.fixed.length > 0) {\n * console.log(`Fixed ${hyperlink.getUrl()}: ${result.fixed.join(', ')}`);\n * }\n * }\n * ```\n */\n async validateAndFix(options?: {\n checkAccessibility?: boolean;\n fixCommonIssues?: boolean;\n timeout?: number;\n bookmarkManager?: { hasBookmark(name: string): boolean };\n }): Promise<{\n valid: boolean;\n issues: string[];\n fixed: string[];\n originalUrl?: string;\n fixedUrl?: string;\n }> {\n const {\n checkAccessibility = false,\n fixCommonIssues = true,\n timeout = 5000,\n bookmarkManager,\n } = options || {};\n\n const issues: string[] = [];\n const fixed: string[] = [];\n let fixedUrl = this.url;\n const originalUrl = this.url;\n\n // Internal link validation (bookmarks)\n if (this.anchor) {\n if (bookmarkManager) {\n const bookmarkExists = bookmarkManager.hasBookmark(this.anchor);\n if (!bookmarkExists) {\n issues.push(`Internal bookmark \"${this.anchor}\" not found`);\n }\n }\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n };\n }\n\n // External link validation\n if (!this.url) {\n issues.push('No URL or anchor specified');\n return { valid: false, issues, fixed, originalUrl };\n }\n\n // Fix common issues\n if (fixCommonIssues && fixedUrl) {\n // Fix 1: Add missing protocol\n if (!/^[a-z]+:\\/\\//i.exec(fixedUrl)) {\n fixedUrl = 'https://' + fixedUrl;\n fixed.push('Added missing protocol (https://)');\n }\n\n // Fix 2: Fix double slashes (except after protocol)\n const protocolMatch = /^([a-z]+:\\/\\/)/i.exec(fixedUrl);\n if (protocolMatch?.[1]) {\n const protocol = protocolMatch[1];\n const rest = fixedUrl.substring(protocol.length);\n const fixedRest = rest.replace(/\\/\\//g, '/');\n if (rest !== fixedRest) {\n fixedUrl = protocol + fixedRest;\n fixed.push('Fixed double slashes');\n }\n }\n\n // Fix 3: Encode spaces\n if (fixedUrl.includes(' ')) {\n fixedUrl = fixedUrl.replace(/ /g, '%20');\n fixed.push('Encoded spaces as %20');\n }\n\n // Fix 4: Remove trailing slashes for non-root URLs\n if (/^https?:\\/\\/[^/]+\\/.+\\/$/.exec(fixedUrl)) {\n fixedUrl = fixedUrl.replace(/\\/$/, '');\n fixed.push('Removed trailing slash');\n }\n\n // Fix 5: Fix common typos\n fixedUrl = fixedUrl.replace(/^http:\\/\\//i, 'https://'); // Prefer HTTPS\n if (fixedUrl !== this.url && fixedUrl.startsWith('https://')) {\n fixed.push('Upgraded HTTP to HTTPS');\n }\n\n // Update URL if fixes were applied\n if (fixedUrl !== this.url) {\n this.setUrl(fixedUrl);\n }\n }\n\n // Check accessibility (HTTP HEAD request)\n if (checkAccessibility && fixedUrl?.match(/^https?:\\/\\//i)) {\n // Check if fetch is available (Node.js 18+ or browser)\n if (typeof fetch === 'undefined') {\n issues.push('Network validation unavailable: fetch API not supported in this environment');\n } else {\n try {\n // Use fetch with AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(fixedUrl, {\n method: 'HEAD',\n signal: controller.signal,\n redirect: 'follow',\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n issues.push(`HTTP ${response.status}: ${response.statusText || 'Error'}`);\n }\n } catch (error: unknown) {\n // Type guard for error objects with name and message properties\n const isErrorWithName = (err: unknown): err is { name: string } => {\n return typeof err === 'object' && err !== null && 'name' in err;\n };\n const isErrorWithMessage = (err: unknown): err is { message: string } => {\n return typeof err === 'object' && err !== null && 'message' in err;\n };\n\n if (isErrorWithName(error) && error.name === 'AbortError') {\n issues.push(`Timeout after ${timeout}ms`);\n } else if (isErrorWithMessage(error) && error.message?.includes('fetch')) {\n issues.push(`Unreachable: ${error.message}`);\n } else if (isErrorWithMessage(error)) {\n issues.push(`Network error: ${error.message}`);\n } else {\n issues.push('Network error: Unknown error');\n }\n }\n }\n }\n\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n fixedUrl: fixedUrl !== originalUrl ? fixedUrl : undefined,\n };\n }\n\n /**\n * Resets hyperlink formatting to standard style (Calibri, blue, underline)\n * This is useful for fixing corrupted hyperlinks from Google Docs or other sources\n * @returns this for method chaining\n */\n resetToStandardFormatting(): this {\n const standardFormatting: RunFormatting = {\n font: 'Verdana',\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n // Clear any other formatting that might be causing issues\n bold: false,\n italic: false,\n strike: false,\n };\n\n this.setFormatting(standardFormatting);\n return this;\n }\n\n /**\n * Checks if this is an external link\n */\n isExternal(): boolean {\n return this.url !== undefined;\n }\n\n /**\n * Checks if this is an internal link (anchor)\n */\n isInternal(): boolean {\n return this.anchor !== undefined;\n }\n\n /**\n * Creates a deep copy of this hyperlink\n *\n * This is useful for preserving the original state before modifications,\n * particularly when creating tracked changes (revisions) where both the\n * old and new states need to be preserved.\n *\n * @returns A new Hyperlink instance with the same properties\n *\n * @example\n * ```typescript\n * // Clone before modifying for tracked changes\n * const originalLink = hyperlink.clone();\n * hyperlink.setUrl('https://new-url.com');\n * hyperlink.setText('New Text');\n *\n * // Now originalLink has old URL/text, hyperlink has new\n * const deletion = Revision.createDeletion(author, [originalLink]);\n * const insertion = Revision.createInsertion(author, [hyperlink]);\n * ```\n */\n clone(): Hyperlink {\n const cloned = new Hyperlink({\n url: this.url,\n anchor: this.anchor,\n text: this.text,\n tooltip: this.tooltip,\n relationshipId: this.relationshipId,\n formatting: { ...this.formatting },\n tgtFrame: this.tgtFrame,\n history: this.history,\n docLocation: this.docLocation,\n });\n\n // Copy the run with its formatting\n if (this.run) {\n cloned.run = new Run(this.run.getText(), { ...this.run.getFormatting() });\n\n // Preserve rPrChange from the original run (formatting tracked changes)\n const existingRPrChange = this.run.getPropertyChangeRevision();\n if (existingRPrChange) {\n cloned.run.setPropertyChangeRevision({ ...existingRPrChange });\n }\n }\n\n return cloned;\n }\n\n /**\n * Generates XML for the hyperlink\n *\n * **CRITICAL:** For external links, relationshipId MUST be set before calling toXML().\n * This happens automatically when saving via Document.save(), but manual usage requires\n * registering the hyperlink with RelationshipManager first.\n *\n * @throws {Error} If external link (has url) is missing relationshipId\n * @throws {Error} If hyperlink has neither url nor anchor (empty hyperlink)\n */\n toXML(): XMLElement {\n // VALIDATION: Hyperlink must have url OR anchor (unless it's an empty hyperlink with relationshipId)\n if (!this.url && !this.anchor && !this.relationshipId) {\n throw new Error(\n 'CRITICAL: Hyperlink must have either a URL (external link), anchor (internal link), or relationshipId. ' +\n 'Cannot generate valid XML for hyperlink without destination.'\n );\n }\n\n // VALIDATION: External links MUST have relationship ID\n // Per ECMA-376 Part 1 §17.16.22, <w:hyperlink> with external target requires r:id attribute\n if (this.url && !this.relationshipId) {\n throw new Error(\n `CRITICAL: External hyperlink to \"${this.url}\" is missing relationship ID. ` +\n `This would create an invalid OpenXML document per ECMA-376 §17.16.22. ` +\n `Solution: Use Document.save() which automatically registers relationships, ` +\n `or manually call relationshipManager.addHyperlink(url) and set the relationship ID.`\n );\n }\n\n const attributes: Record<string, string> = {};\n\n // External link - add relationship ID\n if (this.relationshipId) {\n attributes['r:id'] = this.relationshipId;\n }\n\n // Internal link - uses anchor\n if (this.anchor) {\n attributes['w:anchor'] = this.anchor;\n }\n\n // Tooltip - explicitly escape attribute value for safety\n // XMLBuilder will handle escaping, but we document this for clarity\n if (this.tooltip) {\n // Note: XMLBuilder.elementToString() will escape this via escapeXmlAttribute()\n // when generating the actual XML string. We store the raw value here.\n attributes['w:tooltip'] = this.tooltip;\n }\n\n // Target frame attribute (e.g., \"_blank\" for new window)\n if (this.tgtFrame) {\n attributes['w:tgtFrame'] = this.tgtFrame;\n }\n\n // History tracking attribute\n if (this.history) {\n attributes['w:history'] = this.history;\n }\n\n // Document location attribute (ECMA-376 §17.16.22)\n if (this.docLocation) {\n attributes['w:docLocation'] = this.docLocation;\n }\n\n // Empty/invisible hyperlinks have no children (self-closing element)\n if (this._isEmpty) {\n return {\n name: 'w:hyperlink',\n attributes,\n children: [],\n };\n }\n\n // Generate run XML\n const runXml = this.run.toXML();\n\n return {\n name: 'w:hyperlink',\n attributes,\n children: [runXml],\n };\n }\n\n /**\n * Creates an external hyperlink\n * @param url The URL\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createExternal(url: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ url, text, formatting });\n }\n\n /**\n * Creates an internal hyperlink (to a bookmark)\n * @param anchor Bookmark name\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createInternal(anchor: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ anchor, text, formatting });\n }\n\n /**\n * Creates a web link (convenience method for URLs)\n * @param url The URL\n * @param text Display text (defaults to URL)\n * @param formatting Optional formatting\n */\n static createWebLink(url: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url,\n text: text || url,\n formatting,\n });\n }\n\n /**\n * Creates an email link\n * @param email Email address\n * @param text Display text (defaults to email)\n * @param formatting Optional formatting\n */\n static createEmail(email: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url: `mailto:${email}`,\n text: text || email,\n formatting,\n });\n }\n\n /**\n * Creates a hyperlink with properties\n * @param properties Hyperlink properties\n */\n static create(properties: HyperlinkProperties): Hyperlink {\n return new Hyperlink(properties);\n }\n}\n"]}
1
+ {"version":3,"file":"Hyperlink.js","sourceRoot":"","sources":["../../src/elements/Hyperlink.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hyperlink - Represents a hyperlink in a Word document\n *\n * Hyperlinks can be external (to websites, files) or internal (to bookmarks within the document).\n * They are represented using the `<w:hyperlink>` element.\n *\n * ## Important: Relationship ID Requirement\n *\n * **External hyperlinks REQUIRE a relationship ID to be set before XML generation.**\n * Per ECMA-376 Part 1 §17.16.22, `<w:hyperlink>` elements with external targets must have\n * an `r:id` attribute that references a relationship in `word/_rels/document.xml.rels`.\n *\n * ### Correct Usage Pattern:\n *\n * ```typescript\n * // RECOMMENDED: Use Document.save() - automatically handles relationships\n * const doc = Document.create();\n * const para = doc.createParagraph();\n * para.addHyperlink(Hyperlink.createExternal('https://example.com', 'Link'));\n * await doc.save('document.docx'); // ✅ Relationships auto-registered\n * ```\n *\n * ### Manual Relationship Registration (Advanced):\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * const relationship = relationshipManager.addHyperlink('https://example.com');\n * link.setRelationshipId(relationship.getId());\n * link.toXML(); // ✅ Now valid\n * ```\n *\n * ### What NOT to Do:\n *\n * ```typescript\n * const link = Hyperlink.createExternal('https://example.com', 'Link');\n * link.toXML(); // ❌ ERROR: Missing relationship ID\n * ```\n *\n * ## Internal Hyperlinks\n *\n * Internal hyperlinks (bookmarks) do NOT require relationships:\n *\n * ```typescript\n * const link = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link.toXML(); // ✅ Valid - uses w:anchor attribute\n * ```\n *\n * @see {@link https://www.ecma-international.org/publications-and-standards/standards/ecma-376/ | ECMA-376 Part 1 §17.16.22}\n */\n\nimport { XMLElement } from '../xml/XMLBuilder';\nimport { Run, RunFormatting } from './Run';\nimport { Revision } from './Revision';\nimport { validateRunText, sanitizeHyperlinkUrl } from '../utils/validation';\nimport { defaultLogger } from '../utils/logger';\n\n/**\n * Hyperlink properties\n */\nexport interface HyperlinkProperties {\n /** Hyperlink URL (for external links) */\n url?: string;\n /** Bookmark anchor (for internal links) */\n anchor?: string;\n /** Display text (optional for empty/invisible hyperlinks) */\n text?: string;\n /** Text formatting */\n formatting?: RunFormatting;\n /** Tooltip text */\n tooltip?: string;\n /** Relationship ID (set by Document when saving) */\n relationshipId?: string;\n /** Whether this is an empty/invisible hyperlink with no display text */\n isEmpty?: boolean;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n tgtFrame?: string;\n /** History tracking attribute */\n history?: string;\n /** Document location for within-document navigation in external files (ECMA-376 §17.16.22) */\n docLocation?: string;\n}\n\n/**\n * Represents a hyperlink\n */\nexport class Hyperlink {\n private url?: string;\n private anchor?: string;\n private text: string;\n private run: Run;\n private tooltip?: string;\n private relationshipId?: string;\n private formatting: RunFormatting;\n /** Whether this is an empty/invisible hyperlink with no display text */\n private _isEmpty = false;\n /** Target frame attribute (e.g., \"_blank\" for new window) */\n private tgtFrame?: string;\n /** History tracking attribute */\n private history?: string;\n /** Document location for within-document navigation in external files */\n private docLocation?: string;\n /** Tracking context for automatic change tracking */\n private trackingContext?: import('../tracking/TrackingContext').TrackingContext;\n /** Parent paragraph reference for automatic tracking */\n private _parentParagraph?: import('./Paragraph').Paragraph;\n /** Baseline formatting captured before first tracked formatting change */\n private _preTrackingFormatting?: RunFormatting;\n\n /**\n * Creates a new hyperlink\n *\n * **Note:** A hyperlink must have either a URL (external) or anchor (internal), but not both.\n * If both are provided, the URL takes precedence and a warning is logged.\n *\n * @param properties Hyperlink properties\n */\n constructor(properties: HyperlinkProperties) {\n this.url = properties.url;\n this.anchor = properties.anchor;\n this.tooltip = properties.tooltip;\n this.relationshipId = properties.relationshipId;\n this.tgtFrame = properties.tgtFrame;\n this.history = properties.history;\n this.docLocation = properties.docLocation;\n this._isEmpty = properties.isEmpty ?? false;\n\n // VALIDATION: Warn about hybrid links (url + anchor)\n if (this.url && this.anchor) {\n defaultLogger.warn(\n `DocXML Warning: Hyperlink has both URL (\"${this.url}\") and anchor (\"${this.anchor}\"). ` +\n `This is ambiguous per ECMA-376 spec. URL will take precedence. ` +\n `Use Hyperlink.createExternal() or Hyperlink.createInternal() to avoid ambiguity.`\n );\n }\n\n // Handle empty/invisible hyperlinks (no display text)\n if (this._isEmpty) {\n this.text = '';\n this.formatting = {};\n this.run = new Run('', {});\n return;\n }\n\n // Text fallback: properties.text → url → 'Link'\n // NOTE: Do NOT use anchor (bookmark ID) as display text - it should only be used for navigation\n // Using bookmark IDs as visible text causes TOC corruption (Issue: TOC shows \"HEADING=II.MNKE7E8NA385_\" instead of proper headings)\n this.text = properties.text || this.url || 'Link';\n\n // Validate text for XML patterns\n // Default to auto-cleaning XML patterns unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(this.text, {\n context: 'Hyperlink text',\n autoClean: properties.formatting?.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available and cleaning was requested\n if (validation.cleanedText) {\n this.text = validation.cleanedText;\n }\n\n // Create run with default hyperlink styling (Verdana 12pt blue underlined)\n this.formatting = {\n font: 'Verdana',\n size: 12,\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n ...properties.formatting,\n };\n\n this.run = new Run(this.text, this.formatting);\n }\n\n /**\n * Sets the tracking context for automatic change tracking.\n * Called by Document when track changes is enabled.\n * @internal\n */\n _setTrackingContext(context: import('../tracking/TrackingContext').TrackingContext): void {\n this.trackingContext = context;\n }\n\n /**\n * Sets the parent paragraph reference for automatic tracking.\n * Called by Paragraph when hyperlink is added.\n * @internal\n */\n _setParentParagraph(paragraph: import('./Paragraph').Paragraph): void {\n this._parentParagraph = paragraph;\n }\n\n /**\n * Gets the parent paragraph reference.\n * @internal\n */\n _getParentParagraph(): import('./Paragraph').Paragraph | undefined {\n return this._parentParagraph;\n }\n\n /**\n * Applies an rPrChange to the inner Run, tracking the delta between\n * the baseline formatting and the current formatting.\n *\n * On first call, captures `previousFormatting` as the baseline.\n * Subsequent calls always compare against the same baseline so that\n * multiple sequential formatting changes produce a single merged rPrChange.\n *\n * @internal\n */\n private _applyFormattingRPrChange(previousFormatting: RunFormatting): void {\n // Capture baseline on first tracked formatting change\n if (!this._preTrackingFormatting) {\n this._preTrackingFormatting = { ...previousFormatting };\n }\n\n // Build previousProperties from the baseline (only changed keys)\n const baseline = this._preTrackingFormatting;\n const current = this.formatting;\n const previousProperties: Partial<RunFormatting> = {};\n let hasChanges = false;\n\n for (const key of Object.keys(baseline) as (keyof RunFormatting)[]) {\n if (baseline[key] !== current[key]) {\n (previousProperties as Record<string, unknown>)[key] = baseline[key];\n hasChanges = true;\n }\n }\n // Also check for keys in current that weren't in baseline (new properties)\n for (const key of Object.keys(current) as (keyof RunFormatting)[]) {\n if (!(key in baseline) && current[key] !== undefined) {\n // Property didn't exist before — previous value is undefined\n (previousProperties as Record<string, unknown>)[key] = undefined;\n hasChanges = true;\n }\n }\n\n if (!hasChanges) return;\n\n const revisionId = this.trackingContext!.getRevisionManager().consumeNextId();\n const author = this.trackingContext!.getAuthor();\n\n this.run.setPropertyChangeRevision({\n id: revisionId,\n author,\n date: new Date(),\n previousProperties,\n });\n }\n\n /**\n * Gets the hyperlink URL\n */\n getUrl(): string | undefined {\n return this.url;\n }\n\n /**\n * Gets the complete URL including any anchor fragment.\n *\n * For external links that also have an anchor (e.g., internal bookmark within external page),\n * this returns the URL with the anchor appended as a fragment.\n * For internal-only links (anchor without URL), returns undefined.\n *\n * Note: As of v7.2.0, DocumentParser automatically combines external URLs with anchors\n * during parsing, so getUrl() typically returns the full URL. This method is provided\n * for cases where URL and anchor are set separately via the API.\n *\n * @returns The complete URL with fragment, or undefined for internal-only links\n *\n * @example\n * ```typescript\n * // External link with anchor fragment\n * const link = new Hyperlink({ url: 'https://example.com/', anchor: '!/view?id=123', text: 'Link' });\n * link.getUrl(); // 'https://example.com/'\n * link.getAnchor(); // '!/view?id=123'\n * link.getFullUrl(); // 'https://example.com/#!/view?id=123'\n *\n * // External link without anchor\n * const link2 = Hyperlink.createExternal('https://example.com/page', 'Link');\n * link2.getFullUrl(); // 'https://example.com/page'\n *\n * // Internal link (bookmark reference)\n * const link3 = Hyperlink.createInternal('Section1', 'Go to Section 1');\n * link3.getFullUrl(); // undefined\n * ```\n */\n getFullUrl(): string | undefined {\n if (this.url && this.anchor) {\n return this.url + '#' + this.anchor;\n }\n return this.url;\n }\n\n /**\n * Gets the anchor (for internal links)\n */\n getAnchor(): string | undefined {\n return this.anchor;\n }\n\n /**\n * Returns whether this is an empty/invisible hyperlink (has no display text).\n * Empty hyperlinks are self-closing elements in the XML.\n */\n isEmpty(): boolean {\n return this._isEmpty;\n }\n\n /**\n * Gets the target frame attribute (e.g., \"_blank\" for new window)\n */\n getTgtFrame(): string | undefined {\n return this.tgtFrame;\n }\n\n /**\n * Gets the history tracking attribute\n */\n getHistory(): string | undefined {\n return this.history;\n }\n\n /**\n * Sets the target frame attribute\n * @param tgtFrame Target frame (e.g., \"_blank\" for new window)\n */\n setTgtFrame(tgtFrame: string | undefined): this {\n this.tgtFrame = tgtFrame;\n return this;\n }\n\n /**\n * Sets the history tracking attribute\n * @param history History value (e.g., \"1\" to add to history)\n */\n setHistory(history: string | undefined): this {\n this.history = history;\n return this;\n }\n\n /**\n * Gets the document location attribute (ECMA-376 §17.16.22)\n */\n getDocLocation(): string | undefined {\n return this.docLocation;\n }\n\n /**\n * Sets the document location for within-document navigation in external files\n * @param docLocation Location string\n */\n setDocLocation(docLocation: string | undefined): this {\n this.docLocation = docLocation;\n return this;\n }\n\n /**\n * Gets the display text\n *\n * This method delegates to the internal run to ensure the returned text\n * is always accurate and matches what will be in the generated XML,\n * per ECMA-376 Part 1 §17.16.22.\n *\n * @returns The display text including any special characters (tabs, breaks, etc.)\n */\n getText(): string {\n return this.run.getText();\n }\n\n /**\n * Sets the display text\n */\n setText(text: string): this {\n // Validate text for XML patterns\n // Default to auto-cleaning unless explicitly disabled (matches Run behavior)\n const validation = validateRunText(text, {\n context: 'Hyperlink.setText',\n autoClean: this.formatting.cleanXmlFromText !== false,\n warnToConsole: true,\n });\n\n // Use cleaned text if available\n const cleanedText = validation.cleanedText || text;\n\n const previousValue = this.text;\n\n // Skip if text unchanged\n if (previousValue === cleanedText) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.text = cleanedText;\n this.run.setText(cleanedText);\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.text = cleanedText;\n this.run.setText(cleanedText);\n return this;\n }\n\n /**\n * Sets the internal run directly (for advanced use cases like TOC parsing)\n * Used by DocumentParser to preserve run content (tabs, breaks, etc.)\n * @param run - The run to use for this hyperlink\n */\n setRun(run: Run): this {\n this.run = run;\n this.text = run.getText();\n return this;\n }\n\n /**\n * Gets the tooltip\n */\n getTooltip(): string | undefined {\n return this.tooltip;\n }\n\n /**\n * Sets the tooltip\n */\n setTooltip(tooltip: string): this {\n const previousValue = this.tooltip;\n\n // Skip if tooltip unchanged\n if (previousValue === tooltip) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create delete/insert revision pair\n // Tooltip is a w:hyperlink attribute — no OOXML property-change element exists for it\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.tooltip = tooltip;\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n // Clear baseline formatting (fresh start inside insertion)\n this._preTrackingFormatting = undefined;\n\n return this;\n }\n\n // Non-tracking path\n this.tooltip = tooltip;\n return this;\n }\n\n /**\n * Gets the relationship ID\n */\n getRelationshipId(): string | undefined {\n return this.relationshipId;\n }\n\n /**\n * Sets the relationship ID (called by Document during save)\n */\n setRelationshipId(id: string): this {\n this.relationshipId = id;\n return this;\n }\n\n /**\n * Sets or updates the hyperlink URL\n *\n * When URL is updated, we mark that the relationship needs updating.\n * The actual relationship update happens during Document.save() to ensure\n * proper coordination with the RelationshipManager.\n *\n * **Important:** This method maintains the relationship ID but flags it for update.\n * The RelationshipManager will update the existing relationship's target URL\n * during save, preventing orphaned relationships per ECMA-376 §17.16.22.\n *\n * @param url - The new URL (or undefined to clear)\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing URL would create empty hyperlink (no URL and no anchor)\n *\n * @example\n * ```typescript\n * const link = Hyperlink.createExternal('https://old.com', 'Link');\n * link.setUrl('https://new.com'); // Marks for relationship update\n * await doc.save('updated.docx'); // Updates relationship target\n * ```\n */\n setUrl(url: string | undefined): this {\n // Validate that clearing URL doesn't create empty hyperlink\n if (!url && !this.anchor) {\n throw new Error(\n `Cannot set URL to undefined: Hyperlink \"${this.run.getText()}\" has no anchor. ` +\n `Clearing the URL would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new URL or delete the hyperlink entirely.`\n );\n }\n\n // Save old URL before updating (for text fallback logic)\n const oldUrl = this.url;\n\n // Skip if URL unchanged (optimization)\n if (oldUrl === url) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.url = url;\n this.relationshipId = undefined;\n if (this.run.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.run.setText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.url = url;\n\n // Clear the relationship ID so it will be re-registered during save\n // This ensures the relationship target is updated to point to the new URL\n this.relationshipId = undefined;\n\n // Update text ONLY if it was auto-generated from the old URL\n // This preserves user-provided text (even if it's \"Link\")\n // Use run.getText() to ensure we check the actual current text, not stale cache\n if (this.run.getText() === oldUrl) {\n this.text = url || this.anchor || 'Link';\n this.run.setText(this.text);\n }\n\n return this;\n }\n\n /**\n * Sets the anchor (for internal links)\n * @param anchor Bookmark name to link to\n * @returns This hyperlink for chaining\n * @throws {Error} If clearing anchor would create empty hyperlink (no URL and no anchor)\n * @example\n * ```typescript\n * const link = Hyperlink.createInternal('OldBookmark', 'Go there');\n * link.setAnchor('NewBookmark'); // Update internal link target\n * ```\n */\n setAnchor(anchor: string | undefined): this {\n // Validate that clearing anchor doesn't create empty hyperlink\n if (!anchor && !this.url) {\n throw new Error(\n `Cannot set anchor to undefined: Hyperlink \"${this.run.getText()}\" has no URL. ` +\n `Clearing the anchor would create an invalid hyperlink per ECMA-376 §17.16.22. ` +\n `Either provide a new anchor or delete the hyperlink entirely.`\n );\n }\n\n // Save old anchor before updating\n const oldAnchor = this.anchor;\n\n // Skip if anchor unchanged (optimization)\n if (oldAnchor === anchor) {\n return this;\n }\n\n // If tracking enabled AND has parent paragraph, create revision pair\n // OOXML has no w:hyperlinkChange element - Word tracks hyperlink changes as delete/insert pairs\n if (this.trackingContext?.isEnabled() && this._parentParagraph) {\n const author = this.trackingContext.getAuthor();\n\n // Clone current state for deletion (before applying changes)\n const oldHyperlink = this.clone();\n\n // Apply the change to this hyperlink\n this.anchor = anchor;\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n if (this.run.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.run.setText(this.text);\n }\n\n // Create delete/insert revision pair\n const deletion = Revision.createDeletion(author, [oldHyperlink]);\n const insertion = Revision.createInsertion(author, [this]);\n\n // Replace this hyperlink with the revision pair in parent paragraph\n this._parentParagraph.replaceContent(this, [deletion, insertion]);\n\n // Clear parent reference since we're now inside a revision\n this._parentParagraph = undefined;\n\n return this;\n }\n\n // Non-tracking path (original behavior)\n this.anchor = anchor;\n\n // If converting from external to internal, clear URL and relationship\n if (anchor && this.url) {\n defaultLogger.warn(\n `DocXML Warning: Setting anchor \"${anchor}\" on hyperlink that has URL \"${this.url}\". ` +\n `Clearing URL to make this an internal link. Use separate hyperlinks for external and internal links.`\n );\n this.url = undefined;\n this.relationshipId = undefined;\n }\n\n // Update text ONLY if it was auto-generated from the old anchor\n // Use run.getText() to ensure we check the actual current text, not stale cache\n if (this.run.getText() === oldAnchor) {\n this.text = anchor || this.url || 'Link';\n this.run.setText(this.text);\n }\n\n return this;\n }\n\n /**\n * Gets the run\n */\n getRun(): Run {\n return this.run;\n }\n\n /**\n * Sets run formatting\n *\n * @param formatting - The formatting to apply\n * @param options - Optional settings\n * @param options.replace - If true, replaces ALL existing formatting instead of merging.\n * Use this when you want to clear inherited styles like characterStyle.\n *\n * @example\n * ```typescript\n * // Merge mode (default): adds/updates properties while preserving others\n * hyperlink.setFormatting({ bold: true });\n *\n * // Replace mode: clears all existing formatting and applies only the new properties\n * hyperlink.setFormatting({ font: \"Verdana\", size: 12 }, { replace: true });\n * ```\n */\n setFormatting(formatting: RunFormatting, options?: { replace?: boolean }): this {\n // Update stored formatting\n const previousFormatting = { ...this.formatting };\n if (options?.replace) {\n // Replace mode: new formatting replaces ALL existing properties\n this.formatting = { ...formatting };\n } else {\n // Merge mode (default, backwards-compatible): merge with existing\n this.formatting = { ...this.formatting, ...formatting };\n }\n // Create new run with updated formatting, preserving current text\n const currentText = this.run.getText();\n this.run = new Run(currentText, this.formatting);\n this.text = currentText; // Keep cache in sync\n if (this.trackingContext?.isEnabled()) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Gets run formatting (returns this hyperlink for fluent API)\n * @returns This hyperlink for method chaining\n *\n * @example\n * ```typescript\n * hyperlink.getFormatting().setColor('0563C1').setUnderline('single');\n * ```\n */\n getFormatting(): this {\n return this;\n }\n\n /**\n * Gets the raw formatting object (for direct access)\n * @returns RunFormatting object\n */\n getRawFormatting(): RunFormatting {\n return this.formatting;\n }\n\n // ============================================================================\n // Individual Formatting Getters\n // ============================================================================\n\n /**\n * Gets the text color\n * @returns Color hex string or undefined\n */\n getColor(): string | undefined {\n return this.formatting.color;\n }\n\n /**\n * Gets the underline style\n * @returns Underline style or undefined\n */\n getUnderline(): string | boolean | undefined {\n return this.formatting.underline;\n }\n\n /**\n * Gets whether the hyperlink is bold\n * @returns True if bold, false otherwise\n */\n getBold(): boolean {\n return this.formatting.bold ?? false;\n }\n\n /**\n * Gets whether the hyperlink is italic\n * @returns True if italic, false otherwise\n */\n getItalic(): boolean {\n return this.formatting.italic ?? false;\n }\n\n /**\n * Gets the font family\n * @returns Font name or undefined\n */\n getFont(): string | undefined {\n return this.formatting.font;\n }\n\n /**\n * Gets the font size\n * @returns Font size in points or undefined\n */\n getSize(): number | undefined {\n return this.formatting.size;\n }\n\n /**\n * Sets text color\n * @param color Color in hex format (e.g., '0563C1')\n * @returns This hyperlink for chaining\n */\n setColor(color: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.color = color;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.color !== color) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets underline style\n * @param underline Underline style ('single', 'double', etc.)\n * @returns This hyperlink for chaining\n */\n setUnderline(underline: boolean | 'single' | 'double' | 'dotted' | 'thick' | 'dash'): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.underline = underline;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.underline !== underline) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets bold formatting\n * @param bold Bold state (default: true)\n * @returns This hyperlink for chaining\n */\n setBold(bold = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.bold = bold;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.bold !== bold) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets italic formatting\n * @param italic Italic state (default: true)\n * @returns This hyperlink for chaining\n */\n setItalic(italic = true): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.italic = italic;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.italic !== italic) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font family\n * @param font Font name (e.g., 'Arial', 'Verdana')\n * @returns This hyperlink for chaining\n */\n setFont(font: string): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.font = font;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.font !== font) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Sets font size\n * @param size Font size in points (e.g., 12, 14)\n * @returns This hyperlink for chaining\n */\n setSize(size: number): this {\n const previousFormatting = { ...this.formatting };\n this.formatting.size = size;\n this.run = new Run(this.text, this.formatting);\n if (this.trackingContext?.isEnabled() && previousFormatting.size !== size) {\n this._applyFormattingRPrChange(previousFormatting);\n }\n return this;\n }\n\n /**\n * Validates the hyperlink URL and optionally fixes common issues\n *\n * Performs validation and fixing of hyperlink URLs including:\n * - Checking URL accessibility (HTTP HEAD request for external links)\n * - Fixing common URL issues (missing protocol, double slashes, spaces)\n * - Validating internal bookmark references\n * - Detecting broken links\n *\n * **Note:** This method is async due to network requests for accessibility checks.\n *\n * @param options - Validation options\n * @returns Promise with validation results\n *\n * @example\n * ```typescript\n * // Basic URL fixing without network check\n * const result = await link.validateAndFix({\n * fixCommonIssues: true,\n * checkAccessibility: false\n * });\n * console.log(`Fixed: ${result.fixed.join(', ')}`);\n *\n * // Full validation with accessibility check\n * const validation = await link.validateAndFix({\n * checkAccessibility: true,\n * timeout: 5000\n * });\n * if (!validation.valid) {\n * console.log(`Issues: ${validation.issues.join(', ')}`);\n * }\n *\n * // Batch validate all hyperlinks in document\n * for (const { hyperlink } of doc.getHyperlinks()) {\n * const result = await hyperlink.validateAndFix();\n * if (result.fixed.length > 0) {\n * console.log(`Fixed ${hyperlink.getUrl()}: ${result.fixed.join(', ')}`);\n * }\n * }\n * ```\n */\n async validateAndFix(options?: {\n checkAccessibility?: boolean;\n fixCommonIssues?: boolean;\n timeout?: number;\n bookmarkManager?: { hasBookmark(name: string): boolean };\n }): Promise<{\n valid: boolean;\n issues: string[];\n fixed: string[];\n originalUrl?: string;\n fixedUrl?: string;\n }> {\n const {\n checkAccessibility = false,\n fixCommonIssues = true,\n timeout = 5000,\n bookmarkManager,\n } = options || {};\n\n const issues: string[] = [];\n const fixed: string[] = [];\n let fixedUrl = this.url;\n const originalUrl = this.url;\n\n // Internal link validation (bookmarks)\n if (this.anchor) {\n if (bookmarkManager) {\n const bookmarkExists = bookmarkManager.hasBookmark(this.anchor);\n if (!bookmarkExists) {\n issues.push(`Internal bookmark \"${this.anchor}\" not found`);\n }\n }\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n };\n }\n\n // External link validation\n if (!this.url) {\n issues.push('No URL or anchor specified');\n return { valid: false, issues, fixed, originalUrl };\n }\n\n // Fix common issues\n if (fixCommonIssues && fixedUrl) {\n // Fix 0: Strip browser extension URL prefixes\n const sanitizeResult = sanitizeHyperlinkUrl(fixedUrl);\n if (sanitizeResult) {\n fixedUrl = sanitizeResult.url;\n fixed.push(...sanitizeResult.fixes);\n }\n\n // Fix 1: Add missing protocol\n if (!/^[a-z]+:\\/\\//i.exec(fixedUrl)) {\n fixedUrl = 'https://' + fixedUrl;\n fixed.push('Added missing protocol (https://)');\n }\n\n // Fix 2: Fix double slashes (except after protocol)\n const protocolMatch = /^([a-z]+:\\/\\/)/i.exec(fixedUrl);\n if (protocolMatch?.[1]) {\n const protocol = protocolMatch[1];\n const rest = fixedUrl.substring(protocol.length);\n const fixedRest = rest.replace(/\\/\\//g, '/');\n if (rest !== fixedRest) {\n fixedUrl = protocol + fixedRest;\n fixed.push('Fixed double slashes');\n }\n }\n\n // Fix 3: Encode spaces\n if (fixedUrl.includes(' ')) {\n fixedUrl = fixedUrl.replace(/ /g, '%20');\n fixed.push('Encoded spaces as %20');\n }\n\n // Fix 4: Remove trailing slashes for non-root URLs\n if (/^https?:\\/\\/[^/]+\\/.+\\/$/.exec(fixedUrl)) {\n fixedUrl = fixedUrl.replace(/\\/$/, '');\n fixed.push('Removed trailing slash');\n }\n\n // Fix 5: Fix common typos\n fixedUrl = fixedUrl.replace(/^http:\\/\\//i, 'https://'); // Prefer HTTPS\n if (fixedUrl !== this.url && fixedUrl.startsWith('https://')) {\n fixed.push('Upgraded HTTP to HTTPS');\n }\n\n // Update URL if fixes were applied\n if (fixedUrl !== this.url) {\n this.setUrl(fixedUrl);\n }\n }\n\n // Check accessibility (HTTP HEAD request)\n if (checkAccessibility && fixedUrl?.match(/^https?:\\/\\//i)) {\n // Check if fetch is available (Node.js 18+ or browser)\n if (typeof fetch === 'undefined') {\n issues.push('Network validation unavailable: fetch API not supported in this environment');\n } else {\n try {\n // Use fetch with AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n const response = await fetch(fixedUrl, {\n method: 'HEAD',\n signal: controller.signal,\n redirect: 'follow',\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n issues.push(`HTTP ${response.status}: ${response.statusText || 'Error'}`);\n }\n } catch (error: unknown) {\n // Type guard for error objects with name and message properties\n const isErrorWithName = (err: unknown): err is { name: string } => {\n return typeof err === 'object' && err !== null && 'name' in err;\n };\n const isErrorWithMessage = (err: unknown): err is { message: string } => {\n return typeof err === 'object' && err !== null && 'message' in err;\n };\n\n if (isErrorWithName(error) && error.name === 'AbortError') {\n issues.push(`Timeout after ${timeout}ms`);\n } else if (isErrorWithMessage(error) && error.message?.includes('fetch')) {\n issues.push(`Unreachable: ${error.message}`);\n } else if (isErrorWithMessage(error)) {\n issues.push(`Network error: ${error.message}`);\n } else {\n issues.push('Network error: Unknown error');\n }\n }\n }\n }\n\n return {\n valid: issues.length === 0,\n issues,\n fixed,\n originalUrl,\n fixedUrl: fixedUrl !== originalUrl ? fixedUrl : undefined,\n };\n }\n\n /**\n * Resets hyperlink formatting to standard style (Calibri, blue, underline)\n * This is useful for fixing corrupted hyperlinks from Google Docs or other sources\n * @returns this for method chaining\n */\n resetToStandardFormatting(): this {\n const standardFormatting: RunFormatting = {\n font: 'Verdana',\n color: '0000FF', // Standard hyperlink blue\n underline: 'single',\n // Clear any other formatting that might be causing issues\n bold: false,\n italic: false,\n strike: false,\n };\n\n this.setFormatting(standardFormatting);\n return this;\n }\n\n /**\n * Checks if this is an external link\n */\n isExternal(): boolean {\n return this.url !== undefined;\n }\n\n /**\n * Checks if this is an internal link (anchor)\n */\n isInternal(): boolean {\n return this.anchor !== undefined;\n }\n\n /**\n * Creates a deep copy of this hyperlink\n *\n * This is useful for preserving the original state before modifications,\n * particularly when creating tracked changes (revisions) where both the\n * old and new states need to be preserved.\n *\n * @returns A new Hyperlink instance with the same properties\n *\n * @example\n * ```typescript\n * // Clone before modifying for tracked changes\n * const originalLink = hyperlink.clone();\n * hyperlink.setUrl('https://new-url.com');\n * hyperlink.setText('New Text');\n *\n * // Now originalLink has old URL/text, hyperlink has new\n * const deletion = Revision.createDeletion(author, [originalLink]);\n * const insertion = Revision.createInsertion(author, [hyperlink]);\n * ```\n */\n clone(): Hyperlink {\n const cloned = new Hyperlink({\n url: this.url,\n anchor: this.anchor,\n text: this.text,\n tooltip: this.tooltip,\n relationshipId: this.relationshipId,\n formatting: { ...this.formatting },\n tgtFrame: this.tgtFrame,\n history: this.history,\n docLocation: this.docLocation,\n });\n\n // Copy the run with its formatting\n if (this.run) {\n cloned.run = new Run(this.run.getText(), { ...this.run.getFormatting() });\n\n // Preserve rPrChange from the original run (formatting tracked changes)\n const existingRPrChange = this.run.getPropertyChangeRevision();\n if (existingRPrChange) {\n cloned.run.setPropertyChangeRevision({ ...existingRPrChange });\n }\n }\n\n return cloned;\n }\n\n /**\n * Generates XML for the hyperlink\n *\n * **CRITICAL:** For external links, relationshipId MUST be set before calling toXML().\n * This happens automatically when saving via Document.save(), but manual usage requires\n * registering the hyperlink with RelationshipManager first.\n *\n * @throws {Error} If external link (has url) is missing relationshipId\n * @throws {Error} If hyperlink has neither url nor anchor (empty hyperlink)\n */\n toXML(): XMLElement {\n // VALIDATION: Hyperlink must have url OR anchor (unless it's an empty hyperlink with relationshipId)\n if (!this.url && !this.anchor && !this.relationshipId) {\n throw new Error(\n 'CRITICAL: Hyperlink must have either a URL (external link), anchor (internal link), or relationshipId. ' +\n 'Cannot generate valid XML for hyperlink without destination.'\n );\n }\n\n // VALIDATION: External links MUST have relationship ID\n // Per ECMA-376 Part 1 §17.16.22, <w:hyperlink> with external target requires r:id attribute\n if (this.url && !this.relationshipId) {\n throw new Error(\n `CRITICAL: External hyperlink to \"${this.url}\" is missing relationship ID. ` +\n `This would create an invalid OpenXML document per ECMA-376 §17.16.22. ` +\n `Solution: Use Document.save() which automatically registers relationships, ` +\n `or manually call relationshipManager.addHyperlink(url) and set the relationship ID.`\n );\n }\n\n const attributes: Record<string, string> = {};\n\n // External link - add relationship ID\n if (this.relationshipId) {\n attributes['r:id'] = this.relationshipId;\n }\n\n // Internal link - uses anchor\n if (this.anchor) {\n attributes['w:anchor'] = this.anchor;\n }\n\n // Tooltip - explicitly escape attribute value for safety\n // XMLBuilder will handle escaping, but we document this for clarity\n if (this.tooltip) {\n // Note: XMLBuilder.elementToString() will escape this via escapeXmlAttribute()\n // when generating the actual XML string. We store the raw value here.\n attributes['w:tooltip'] = this.tooltip;\n }\n\n // Target frame attribute (e.g., \"_blank\" for new window)\n if (this.tgtFrame) {\n attributes['w:tgtFrame'] = this.tgtFrame;\n }\n\n // History tracking attribute\n if (this.history) {\n attributes['w:history'] = this.history;\n }\n\n // Document location attribute (ECMA-376 §17.16.22)\n if (this.docLocation) {\n attributes['w:docLocation'] = this.docLocation;\n }\n\n // Empty/invisible hyperlinks have no children (self-closing element)\n if (this._isEmpty) {\n return {\n name: 'w:hyperlink',\n attributes,\n children: [],\n };\n }\n\n // Generate run XML\n const runXml = this.run.toXML();\n\n return {\n name: 'w:hyperlink',\n attributes,\n children: [runXml],\n };\n }\n\n /**\n * Creates an external hyperlink\n * @param url The URL\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createExternal(url: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ url, text, formatting });\n }\n\n /**\n * Creates an internal hyperlink (to a bookmark)\n * @param anchor Bookmark name\n * @param text Display text\n * @param formatting Optional formatting\n */\n static createInternal(anchor: string, text: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({ anchor, text, formatting });\n }\n\n /**\n * Creates a web link (convenience method for URLs)\n * @param url The URL\n * @param text Display text (defaults to URL)\n * @param formatting Optional formatting\n */\n static createWebLink(url: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url,\n text: text || url,\n formatting,\n });\n }\n\n /**\n * Creates an email link\n * @param email Email address\n * @param text Display text (defaults to email)\n * @param formatting Optional formatting\n */\n static createEmail(email: string, text?: string, formatting?: RunFormatting): Hyperlink {\n return new Hyperlink({\n url: `mailto:${email}`,\n text: text || email,\n formatting,\n });\n }\n\n /**\n * Creates a hyperlink with properties\n * @param properties Hyperlink properties\n */\n static create(properties: HyperlinkProperties): Hyperlink {\n return new Hyperlink(properties);\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -60,7 +60,7 @@ export { DocumentProtection, RevisionViewSettings, TrackChangesSettings, WebSett
60
60
  export { CompatibilityUpgrader, UpgradeReport } from './utils/CompatibilityUpgrader';
61
61
  export { LEGACY_COMPAT_ELEMENTS, LEGACY_COMPAT_ELEMENT_NAMES, MODERN_COMPAT_SETTINGS, MS_WORD_COMPAT_URI, } from './constants/legacyCompatFlags';
62
62
  export { STANDARD_DPI, UNITS, PAGE_SIZES, COMMON_MARGINS, twipsToPoints, twipsToInches, twipsToCm, twipsToEmus, emusToTwips, emusToInches, emusToCm, emusToPoints, emusToPixels, pointsToTwips, pointsToEmus, pointsToInches, pointsToCm, pointsToHalfPoints, halfPointsToPoints, inchesToTwips, inchesToEmus, inchesToPoints, inchesToCm, inchesToPixels, cmToTwips, cmToEmus, cmToInches, cmToPoints, cmToPixels, pixelsToEmus, pixelsToInches, pixelsToTwips, pixelsToCm, pixelsToPoints, } from './utils/units';
63
- export { validateDocxStructure, isBinaryFile, normalizePath, isValidZipBuffer, isTextContent, validateTwips, validateColor, validateHexColor, normalizeColor, validateNumberingId, validateLevel, validateAlignment, validateFontSize, validateNonEmptyString, validatePercentage, validateEmus, detectXmlInText, cleanXmlFromText, validateRunText, TextValidationResult, } from './utils/validation';
63
+ export { validateDocxStructure, isBinaryFile, normalizePath, isValidZipBuffer, isTextContent, validateTwips, validateColor, validateHexColor, normalizeColor, validateNumberingId, validateLevel, validateAlignment, validateFontSize, validateNonEmptyString, validatePercentage, validateEmus, detectXmlInText, cleanXmlFromText, validateRunText, sanitizeHyperlinkUrl, SanitizeHyperlinkUrlResult, TextValidationResult, } from './utils/validation';
64
64
  export { detectCorruptionInDocument, detectCorruptionInText, suggestFix, looksCorrupted, CorruptionReport, CorruptionLocation, CorruptionType, } from './utils/corruptionDetection';
65
65
  export { isError, toError, wrapError, getErrorMessage } from './utils/errorHandling';
66
66
  export { REVISION_RULES, ValidationSeverity, ValidationIssue, ValidationRule, ValidationOptions, AutoFixOptions, ValidationResult as RevisionValidationResult, FixAction, AutoFixResult, createIssueFromRule, getRuleByCode, getRulesBySeverity, getAutoFixableRules, RevisionValidator, RevisionAutoFixer, } from './validation';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PreservedElement = exports.CustomXmlBlock = exports.MathExpression = exports.MathParagraph = exports.AlternateContent = exports.TableOfContentsElement = exports.TableOfContents = exports.StructuredDocumentTag = exports.isHyperlinkInstruction = exports.buildHyperlinkInstruction = exports.parseHyperlinkInstruction = exports.createNestedField = exports.createIFField = exports.createRefField = exports.createMergeField = exports.createNestedIFMergeField = exports.createTOCField = exports.ComplexField = exports.Field = exports.EndnoteType = exports.Endnote = exports.FootnoteType = exports.Footnote = exports.Comment = exports.RangeMarker = exports.Bookmark = exports.Hyperlink = exports.Footer = exports.Header = exports.TextBox = exports.Shape = exports.ImageRun = exports.Image = exports.TableGridChange = exports.TableCell = exports.TableRow = exports.Table = exports.Section = exports.Run = exports.isTextBox = exports.isShape = exports.isRangeMarker = exports.isRevision = exports.isHyperlink = exports.isComplexField = exports.isSimpleField = exports.isField = exports.isRun = exports.Paragraph = exports.Document = void 0;
4
4
  exports.UNITS = exports.STANDARD_DPI = exports.MS_WORD_COMPAT_URI = exports.MODERN_COMPAT_SETTINGS = exports.LEGACY_COMPAT_ELEMENT_NAMES = exports.LEGACY_COMPAT_ELEMENTS = exports.CompatibilityUpgrader = exports.CompatibilityMode = exports.NO_BORDER = exports.DEFAULT_BORDER = exports.isWidthType = exports.isParagraphAlignment = exports.isVerticalAlignment = exports.isHorizontalAlignment = exports.isBorderStyle = exports.isShadingPattern = exports.buildShadingAttributes = exports.DrawingManager = exports.FontManager = exports.HeaderFooterManager = exports.EndnoteManager = exports.FootnoteManager = exports.CommentManager = exports.BookmarkManager = exports.ImageManager = exports.RevisionManager = exports.NumberingManager = exports.NumberingInstance = exports.AbstractNumbering = exports.WORD_NATIVE_BULLETS = exports.NumberingLevel = exports.StylesManager = exports.Style = exports.ChangelogGenerator = exports.RevisionAwareProcessor = exports.SelectiveRevisionAcceptor = exports.MoveOperationHelper = exports.stripRevisionsFromXml = exports.countRevisionsByType = exports.getRevisionsFromParagraph = exports.paragraphHasRevisions = exports.acceptRevisionsInMemory = exports.isNumberingChange = exports.isSectionPropertyChange = exports.isTablePropertyChange = exports.isParagraphPropertyChange = exports.isRunPropertyChange = exports.isHyperlinkContent = exports.isRunContent = exports.Revision = void 0;
5
5
  exports.cleanXmlFromText = exports.detectXmlInText = exports.validateEmus = exports.validatePercentage = exports.validateNonEmptyString = exports.validateFontSize = exports.validateAlignment = exports.validateLevel = exports.validateNumberingId = exports.normalizeColor = exports.validateHexColor = exports.validateColor = exports.validateTwips = exports.isTextContent = exports.isValidZipBuffer = exports.normalizePath = exports.isBinaryFile = exports.validateDocxStructure = exports.pixelsToPoints = exports.pixelsToCm = exports.pixelsToTwips = exports.pixelsToInches = exports.pixelsToEmus = exports.cmToPixels = exports.cmToPoints = exports.cmToInches = exports.cmToEmus = exports.cmToTwips = exports.inchesToPixels = exports.inchesToCm = exports.inchesToPoints = exports.inchesToEmus = exports.inchesToTwips = exports.halfPointsToPoints = exports.pointsToHalfPoints = exports.pointsToCm = exports.pointsToInches = exports.pointsToEmus = exports.pointsToTwips = exports.emusToPixels = exports.emusToPoints = exports.emusToCm = exports.emusToInches = exports.emusToTwips = exports.twipsToEmus = exports.twipsToCm = exports.twipsToInches = exports.twipsToPoints = exports.COMMON_MARGINS = exports.PAGE_SIZES = void 0;
6
- exports.setGlobalLogger = exports.getGlobalLogger = exports.createComponentLogger = exports.createScopedLogger = exports.defaultLogger = exports.CollectingLogger = exports.SilentLogger = exports.ConsoleLogger = exports.LogLevel = exports.FORMAT_TO_LEVEL = exports.PATTERN_TO_CATEGORY = exports.TYPED_LIST_PATTERNS = exports.getLevelFromFormat = exports.getListCategoryFromFormat = exports.validateListSequence = exports.getParagraphIndentation = exports.inferLevelFromIndentation = exports.detectListType = exports.detectTypedPrefix = exports.XML_CONTROL_CHARS = exports.hasInvalidXmlChars = exports.findInvalidXmlChars = exports.removeInvalidXmlChars = exports.parseOnOffAttribute = exports.parseNumericAttribute = exports.isExplicitlySet = exports.parseOoxmlBoolean = exports.safeParseInt = exports.applyDefaults = exports.isEqualFormatting = exports.cleanFormatting = exports.hasFormatting = exports.cloneFormatting = exports.mergeFormatting = exports.RevisionAutoFixer = exports.RevisionValidator = exports.getAutoFixableRules = exports.getRulesBySeverity = exports.getRuleByCode = exports.createIssueFromRule = exports.REVISION_RULES = exports.getErrorMessage = exports.wrapError = exports.toError = exports.isError = exports.looksCorrupted = exports.suggestFix = exports.detectCorruptionInText = exports.detectCorruptionInDocument = exports.validateRunText = void 0;
7
- exports.LIMITS = exports.DocumentContent = exports.DocumentIdManager = exports.DocumentValidator = exports.DocumentGenerator = exports.DocumentParser = exports.RelationshipManager = exports.RelationshipType = exports.Relationship = exports.DEFAULT_MAX_NESTING_DEPTH = exports.XMLParser = exports.XMLBuilder = exports.FileOperationError = exports.MissingRequiredFileError = exports.CorruptedArchiveError = exports.InvalidDocxError = exports.DocxNotFoundError = exports.DocxError = exports.DOCX_PATHS = exports.REQUIRED_DOCX_FILES = exports.DEFAULT_SIZE_LIMITS = exports.ZipWriter = exports.ZipReader = exports.ZipHandler = exports.CleanupHelper = exports.getActiveConditionalsInPriorityOrder = exports.decodeCnfStyle = exports.resolveCellShading = exports.RevisionWalker = exports.resetGlobalLogger = void 0;
6
+ exports.getGlobalLogger = exports.createComponentLogger = exports.createScopedLogger = exports.defaultLogger = exports.CollectingLogger = exports.SilentLogger = exports.ConsoleLogger = exports.LogLevel = exports.FORMAT_TO_LEVEL = exports.PATTERN_TO_CATEGORY = exports.TYPED_LIST_PATTERNS = exports.getLevelFromFormat = exports.getListCategoryFromFormat = exports.validateListSequence = exports.getParagraphIndentation = exports.inferLevelFromIndentation = exports.detectListType = exports.detectTypedPrefix = exports.XML_CONTROL_CHARS = exports.hasInvalidXmlChars = exports.findInvalidXmlChars = exports.removeInvalidXmlChars = exports.parseOnOffAttribute = exports.parseNumericAttribute = exports.isExplicitlySet = exports.parseOoxmlBoolean = exports.safeParseInt = exports.applyDefaults = exports.isEqualFormatting = exports.cleanFormatting = exports.hasFormatting = exports.cloneFormatting = exports.mergeFormatting = exports.RevisionAutoFixer = exports.RevisionValidator = exports.getAutoFixableRules = exports.getRulesBySeverity = exports.getRuleByCode = exports.createIssueFromRule = exports.REVISION_RULES = exports.getErrorMessage = exports.wrapError = exports.toError = exports.isError = exports.looksCorrupted = exports.suggestFix = exports.detectCorruptionInText = exports.detectCorruptionInDocument = exports.sanitizeHyperlinkUrl = exports.validateRunText = void 0;
7
+ exports.LIMITS = exports.DocumentContent = exports.DocumentIdManager = exports.DocumentValidator = exports.DocumentGenerator = exports.DocumentParser = exports.RelationshipManager = exports.RelationshipType = exports.Relationship = exports.DEFAULT_MAX_NESTING_DEPTH = exports.XMLParser = exports.XMLBuilder = exports.FileOperationError = exports.MissingRequiredFileError = exports.CorruptedArchiveError = exports.InvalidDocxError = exports.DocxNotFoundError = exports.DocxError = exports.DOCX_PATHS = exports.REQUIRED_DOCX_FILES = exports.DEFAULT_SIZE_LIMITS = exports.ZipWriter = exports.ZipReader = exports.ZipHandler = exports.CleanupHelper = exports.getActiveConditionalsInPriorityOrder = exports.decodeCnfStyle = exports.resolveCellShading = exports.RevisionWalker = exports.resetGlobalLogger = exports.setGlobalLogger = void 0;
8
8
  var Document_1 = require("./core/Document");
9
9
  Object.defineProperty(exports, "Document", { enumerable: true, get: function () { return Document_1.Document; } });
10
10
  var Paragraph_1 = require("./elements/Paragraph");
@@ -214,6 +214,7 @@ Object.defineProperty(exports, "validateEmus", { enumerable: true, get: function
214
214
  Object.defineProperty(exports, "detectXmlInText", { enumerable: true, get: function () { return validation_1.detectXmlInText; } });
215
215
  Object.defineProperty(exports, "cleanXmlFromText", { enumerable: true, get: function () { return validation_1.cleanXmlFromText; } });
216
216
  Object.defineProperty(exports, "validateRunText", { enumerable: true, get: function () { return validation_1.validateRunText; } });
217
+ Object.defineProperty(exports, "sanitizeHyperlinkUrl", { enumerable: true, get: function () { return validation_1.sanitizeHyperlinkUrl; } });
217
218
  var corruptionDetection_1 = require("./utils/corruptionDetection");
218
219
  Object.defineProperty(exports, "detectCorruptionInDocument", { enumerable: true, get: function () { return corruptionDetection_1.detectCorruptionInDocument; } });
219
220
  Object.defineProperty(exports, "detectCorruptionInText", { enumerable: true, get: function () { return corruptionDetection_1.detectCorruptionInText; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DocXML - DOCX Editing Framework\n * Main entry point\n */\n\n// =============================================================================\n// PUBLIC API — Core Document Classes\n// =============================================================================\n\nexport {\n Document,\n DocumentProperties,\n DocumentOptions,\n DocumentLoadOptions,\n DocumentPart,\n} from './core/Document';\n\n// =============================================================================\n// PUBLIC API — Document Elements\n// =============================================================================\n\nexport {\n Paragraph,\n ParagraphAlignment,\n ParagraphFormatting,\n ParagraphContent,\n FieldLike,\n isRun,\n isField,\n isSimpleField,\n isComplexField,\n isHyperlink,\n isRevision,\n isRangeMarker,\n isShape,\n isTextBox,\n} from './elements/Paragraph';\nexport { Run, RunFormatting, ThemeColorValue } from './elements/Run';\nexport {\n Section,\n PageOrientation,\n SectionType,\n PageNumberFormat,\n PageSize,\n Margins,\n Columns,\n PageNumbering,\n SectionProperties,\n LineNumbering,\n LineNumberingRestart,\n} from './elements/Section';\nexport {\n Table,\n TableAlignment,\n TableLayout,\n TableBorder,\n TableBorders,\n TableFormatting,\n} from './elements/Table';\nexport { TableRow, RowFormatting } from './elements/TableRow';\nexport {\n TableCell,\n CellBorder,\n CellBorders,\n CellShading,\n CellFormatting,\n} from './elements/TableCell';\nexport { TableGridChange, GridColumn, TableGridChangeProperties } from './elements/TableGridChange';\nexport {\n Image,\n ImageFormat,\n ImageProperties,\n ImageBorder,\n ImageEffects,\n PresetGeometry,\n BlipCompressionState,\n PicLockAttribute,\n PicNonVisualProperties,\n} from './elements/Image';\nexport { ImageRun } from './elements/ImageRun';\nexport { Shape, ShapeType, ShapeProperties, ShapeFill, ShapeOutline } from './elements/Shape';\nexport { TextBox, TextBoxProperties, TextBoxFill, TextBoxMargins } from './elements/TextBox';\nexport { Header, HeaderType, HeaderProperties } from './elements/Header';\nexport { Footer, FooterType, FooterProperties } from './elements/Footer';\nexport { Hyperlink, HyperlinkProperties } from './elements/Hyperlink';\nexport { Bookmark, BookmarkProperties } from './elements/Bookmark';\nexport { RangeMarker, RangeMarkerType, RangeMarkerProperties } from './elements/RangeMarker';\nexport { Comment, CommentProperties } from './elements/Comment';\nexport { Footnote, FootnoteType, FootnoteProperties } from './elements/Footnote';\nexport { Endnote, EndnoteType, EndnoteProperties } from './elements/Endnote';\nexport {\n Field,\n FieldType,\n FieldProperties,\n ComplexField,\n ComplexFieldProperties,\n FieldCharType,\n TOCFieldOptions,\n createTOCField,\n} from './elements/Field';\nexport {\n createNestedIFMergeField,\n createMergeField,\n createRefField,\n createIFField,\n createNestedField,\n parseHyperlinkInstruction,\n buildHyperlinkInstruction,\n isHyperlinkInstruction,\n ParsedHyperlinkInstruction,\n} from './elements/FieldHelpers';\nexport {\n StructuredDocumentTag,\n SDTProperties,\n SDTLockType,\n SDTContent,\n SDTPlaceholder,\n SDTDataBinding,\n ContentControlType,\n} from './elements/StructuredDocumentTag';\nexport { TableOfContents, TOCProperties } from './elements/TableOfContents';\nexport { TableOfContentsElement } from './elements/TableOfContentsElement';\nexport { AlternateContent } from './elements/AlternateContent';\nexport { MathParagraph, MathExpression } from './elements/MathElement';\nexport { CustomXmlBlock } from './elements/CustomXml';\nexport { PreservedElement, PreservedElementContext } from './elements/PreservedElement';\n\n// =============================================================================\n// PUBLIC API — Track Changes / Revisions\n// =============================================================================\n\nexport { Revision, RevisionType, RevisionProperties, FieldContext } from './elements/Revision';\nexport { RevisionContent, isRunContent, isHyperlinkContent } from './elements/RevisionContent';\nexport {\n RevisionLocation,\n RunPropertyChange,\n ParagraphPropertyChange,\n ParagraphFormattingPartial,\n ParagraphBorderDef,\n ParagraphBorders,\n ParagraphShading,\n TabStopDef,\n PropertyChangeBase,\n TablePropertyChange,\n TablePropertyChangeType,\n SectionPropertyChange,\n NumberingChange,\n AnyPropertyChange,\n isRunPropertyChange,\n isParagraphPropertyChange,\n isTablePropertyChange,\n isSectionPropertyChange,\n isNumberingChange,\n} from './elements/PropertyChangeTypes';\nexport {\n acceptRevisionsInMemory,\n AcceptRevisionsOptions,\n AcceptRevisionsResult,\n paragraphHasRevisions,\n getRevisionsFromParagraph,\n countRevisionsByType,\n stripRevisionsFromXml,\n} from './utils/InMemoryRevisionAcceptor';\nexport {\n MoveOperationHelper,\n MoveOperationOptions,\n MoveOperationResult,\n} from './utils/MoveOperationHelper';\nexport {\n SelectiveRevisionAcceptor,\n SelectiveAcceptResult,\n} from './utils/SelectiveRevisionAcceptor';\nexport {\n RevisionAwareProcessor,\n RevisionHandlingMode,\n RevisionProcessingOptions,\n SelectionCriteria,\n RevisionProcessingResult,\n ConflictInfo,\n ProcessingLogEntry,\n} from './utils/RevisionAwareProcessor';\nexport {\n ChangelogGenerator,\n ChangeEntry,\n ChangeCategory,\n ChangeLocation,\n ChangelogOptions,\n ChangelogFormat,\n ConsolidatedChange,\n ChangelogSummary,\n} from './utils/ChangelogGenerator';\n\n// =============================================================================\n// PUBLIC API — Formatting / Styles / Numbering\n// =============================================================================\n\nexport { Style, StyleType, StyleProperties } from './formatting/Style';\nexport {\n StylesManager,\n ValidationResult,\n LatentStylesConfig,\n LatentStyleException,\n} from './formatting/StylesManager';\nexport {\n NumberingLevel,\n NumberFormat,\n NumberAlignment,\n NumberingLevelProperties,\n WORD_NATIVE_BULLETS,\n WordNativeBullet,\n} from './formatting/NumberingLevel';\nexport { AbstractNumbering, AbstractNumberingProperties } from './formatting/AbstractNumbering';\nexport { NumberingInstance, NumberingInstanceProperties } from './formatting/NumberingInstance';\nexport {\n NumberingManager,\n NumberingConsolidationOptions,\n NumberingConsolidationResult,\n} from './formatting/NumberingManager';\nexport {\n StyleRunFormatting,\n StyleParagraphFormatting,\n Heading2TableOptions,\n StyleConfig,\n Heading2Config,\n ApplyCustomFormattingOptions,\n} from './types/styleConfig';\nexport { FormatOptions, StyleApplyOptions, EmphasisType, ListPrefix } from './types/formatting';\n\n// =============================================================================\n// PUBLIC API — Managers\n// =============================================================================\n\nexport { RevisionManager, RevisionCategory, RevisionSummary } from './elements/RevisionManager';\nexport { ImageManager } from './elements/ImageManager';\nexport { BookmarkManager } from './elements/BookmarkManager';\nexport { CommentManager } from './elements/CommentManager';\nexport { FootnoteManager } from './elements/FootnoteManager';\nexport { EndnoteManager } from './elements/EndnoteManager';\nexport { HeaderFooterManager } from './elements/HeaderFooterManager';\nexport { FontManager, FontFormat, FontEntry } from './elements/FontManager';\nexport {\n DrawingManager,\n DrawingElement,\n DrawingType,\n PreservedDrawing,\n} from './managers/DrawingManager';\n\n// =============================================================================\n// PUBLIC API — Image Optimization\n// =============================================================================\n\nexport type { ImageOptimizationResult } from './images/ImageOptimizer';\n\n// =============================================================================\n// TYPES — Common / Shared Type Definitions\n// =============================================================================\n\nexport {\n ShadingPattern,\n BasicShadingPattern,\n BorderStyle,\n ExtendedBorderStyle,\n FullBorderStyle,\n BorderDefinition,\n FourSidedBorders,\n TableBorderDefinitions,\n HorizontalAlignment,\n VerticalAlignment,\n PageVerticalAlignment,\n CellVerticalAlignment,\n ParagraphAlignment as CommonParagraphAlignment,\n TableAlignment as CommonTableAlignment,\n RowJustification,\n TextVerticalAlignment,\n TabAlignment,\n PositionAnchor,\n HorizontalAnchor,\n VerticalAnchor,\n TextDirection,\n SectionTextDirection,\n WidthType,\n ShadingConfig,\n buildShadingAttributes,\n TabLeader,\n TabStop,\n isShadingPattern,\n isBorderStyle,\n isHorizontalAlignment,\n isVerticalAlignment,\n isParagraphAlignment,\n isWidthType,\n DEFAULT_BORDER,\n NO_BORDER,\n} from './elements/CommonTypes';\nexport {\n ListCategory,\n NumberFormat as ListNumberFormat,\n BulletFormat,\n ListDetectionResult,\n ListAnalysis,\n ListNormalizationOptions,\n ListNormalizationReport,\n IndentationLevel,\n} from './types/list-types';\n\nexport { CompatibilityMode, CompatibilityInfo, CompatSetting } from './types/compatibility-types';\n\nexport {\n DocumentProtection,\n RevisionViewSettings,\n TrackChangesSettings,\n WebSettingsInfo,\n} from './types/settings-types';\n\n// =============================================================================\n// TYPES — Compatibility Upgrade\n// =============================================================================\n\nexport { CompatibilityUpgrader, UpgradeReport } from './utils/CompatibilityUpgrader';\nexport {\n LEGACY_COMPAT_ELEMENTS,\n LEGACY_COMPAT_ELEMENT_NAMES,\n MODERN_COMPAT_SETTINGS,\n MS_WORD_COMPAT_URI,\n} from './constants/legacyCompatFlags';\n\n// =============================================================================\n// UTILITIES — Unit Conversions\n// =============================================================================\n\nexport {\n STANDARD_DPI,\n UNITS,\n PAGE_SIZES,\n COMMON_MARGINS,\n twipsToPoints,\n twipsToInches,\n twipsToCm,\n twipsToEmus,\n emusToTwips,\n emusToInches,\n emusToCm,\n emusToPoints,\n emusToPixels,\n pointsToTwips,\n pointsToEmus,\n pointsToInches,\n pointsToCm,\n pointsToHalfPoints,\n halfPointsToPoints,\n inchesToTwips,\n inchesToEmus,\n inchesToPoints,\n inchesToCm,\n inchesToPixels,\n cmToTwips,\n cmToEmus,\n cmToInches,\n cmToPoints,\n cmToPixels,\n pixelsToEmus,\n pixelsToInches,\n pixelsToTwips,\n pixelsToCm,\n pixelsToPoints,\n} from './utils/units';\n\n// =============================================================================\n// UTILITIES — Validation, Corruption Detection, Error Handling\n// =============================================================================\n\nexport {\n validateDocxStructure,\n isBinaryFile,\n normalizePath,\n isValidZipBuffer,\n isTextContent,\n validateTwips,\n validateColor,\n validateHexColor,\n normalizeColor,\n validateNumberingId,\n validateLevel,\n validateAlignment,\n validateFontSize,\n validateNonEmptyString,\n validatePercentage,\n validateEmus,\n detectXmlInText,\n cleanXmlFromText,\n validateRunText,\n TextValidationResult,\n} from './utils/validation';\nexport {\n detectCorruptionInDocument,\n detectCorruptionInText,\n suggestFix,\n looksCorrupted,\n CorruptionReport,\n CorruptionLocation,\n CorruptionType,\n} from './utils/corruptionDetection';\nexport { isError, toError, wrapError, getErrorMessage } from './utils/errorHandling';\nexport {\n REVISION_RULES,\n ValidationSeverity,\n ValidationIssue,\n ValidationRule,\n ValidationOptions,\n AutoFixOptions,\n ValidationResult as RevisionValidationResult,\n FixAction,\n AutoFixResult,\n createIssueFromRule,\n getRuleByCode,\n getRulesBySeverity,\n getAutoFixableRules,\n RevisionValidator,\n RevisionAutoFixer,\n} from './validation';\n\n// =============================================================================\n// UTILITIES — Formatting, Parsing, Sanitization\n// =============================================================================\n\nexport {\n mergeFormatting,\n cloneFormatting,\n hasFormatting,\n cleanFormatting,\n isEqualFormatting,\n applyDefaults,\n} from './utils/formatting';\nexport {\n safeParseInt,\n parseOoxmlBoolean,\n isExplicitlySet,\n parseNumericAttribute,\n parseOnOffAttribute,\n} from './utils/parsingHelpers';\nexport {\n removeInvalidXmlChars,\n findInvalidXmlChars,\n hasInvalidXmlChars,\n XML_CONTROL_CHARS,\n} from './utils/xmlSanitization';\n\n// =============================================================================\n// UTILITIES — List Detection (kept for basic detection; normalization moved to consumer)\n// =============================================================================\n\nexport {\n detectTypedPrefix,\n detectListType,\n inferLevelFromIndentation,\n getParagraphIndentation,\n validateListSequence,\n getListCategoryFromFormat,\n getLevelFromFormat,\n TYPED_LIST_PATTERNS,\n PATTERN_TO_CATEGORY,\n FORMAT_TO_LEVEL,\n} from './utils/list-detection';\n\n// =============================================================================\n// UTILITIES — Logging\n// =============================================================================\n\nexport {\n ILogger,\n LogLevel,\n LogEntry,\n ConsoleLogger,\n SilentLogger,\n CollectingLogger,\n defaultLogger,\n createScopedLogger,\n createComponentLogger,\n getGlobalLogger,\n setGlobalLogger,\n resetGlobalLogger,\n} from './utils/logger';\n\n// =============================================================================\n// UTILITIES — Revision Walker\n// =============================================================================\n\nexport { RevisionWalker, RevisionWalkerOptions } from './utils/RevisionWalker';\nexport { resolveCellShading } from './utils/ShadingResolver';\nexport { decodeCnfStyle, getActiveConditionalsInPriorityOrder } from './utils/cnfStyleDecoder';\n\n// =============================================================================\n// UTILITIES — Cleanup\n// =============================================================================\n\nexport { CleanupHelper, CleanupOptions, CleanupReport } from './helpers/CleanupHelper';\n\n// =============================================================================\n// INTERNAL — ZIP Handling (advanced usage)\n// =============================================================================\n\nexport { ZipHandler } from './zip/ZipHandler';\nexport { ZipReader } from './zip/ZipReader';\nexport { ZipWriter } from './zip/ZipWriter';\nexport {\n ZipFile,\n FileMap,\n LoadOptions,\n SaveOptions,\n AddFileOptions,\n SizeLimitOptions,\n DEFAULT_SIZE_LIMITS,\n REQUIRED_DOCX_FILES,\n DOCX_PATHS,\n} from './zip/types';\nexport {\n DocxError,\n DocxNotFoundError,\n InvalidDocxError,\n CorruptedArchiveError,\n MissingRequiredFileError,\n FileOperationError,\n} from './zip/errors';\n\n// =============================================================================\n// INTERNAL — XML Builder and Parser (advanced usage)\n// =============================================================================\n\nexport { XMLBuilder, XMLElement } from './xml/XMLBuilder';\nexport {\n XMLParser,\n ParseToObjectOptions,\n ParsedXMLValue,\n ParsedXMLObject,\n DEFAULT_MAX_NESTING_DEPTH,\n} from './xml/XMLParser';\n\n// =============================================================================\n// INTERNAL — Parser, Generator, Validator (advanced usage)\n// =============================================================================\n\nexport { Relationship, RelationshipType, RelationshipProperties } from './core/Relationship';\nexport { RelationshipManager } from './core/RelationshipManager';\nexport { DocumentParser, ParseError } from './core/DocumentParser';\nexport { DocumentGenerator, IZipHandlerReader } from './core/DocumentGenerator';\nexport { DocumentValidator, SizeEstimate, MemoryOptions } from './core/DocumentValidator';\nexport { DocumentIdManager } from './core/DocumentIdManager';\n\n// =============================================================================\n// INTERNAL — Document Subsystem Classes (advanced usage)\n// =============================================================================\n\nexport { DocumentContent, BodyElement } from './core/DocumentContent';\n\n// =============================================================================\n// INTERNAL — Constants\n// =============================================================================\n\nexport { LIMITS } from './constants/limits';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DocXML - DOCX Editing Framework\n * Main entry point\n */\n\n// =============================================================================\n// PUBLIC API — Core Document Classes\n// =============================================================================\n\nexport {\n Document,\n DocumentProperties,\n DocumentOptions,\n DocumentLoadOptions,\n DocumentPart,\n} from './core/Document';\n\n// =============================================================================\n// PUBLIC API — Document Elements\n// =============================================================================\n\nexport {\n Paragraph,\n ParagraphAlignment,\n ParagraphFormatting,\n ParagraphContent,\n FieldLike,\n isRun,\n isField,\n isSimpleField,\n isComplexField,\n isHyperlink,\n isRevision,\n isRangeMarker,\n isShape,\n isTextBox,\n} from './elements/Paragraph';\nexport { Run, RunFormatting, ThemeColorValue } from './elements/Run';\nexport {\n Section,\n PageOrientation,\n SectionType,\n PageNumberFormat,\n PageSize,\n Margins,\n Columns,\n PageNumbering,\n SectionProperties,\n LineNumbering,\n LineNumberingRestart,\n} from './elements/Section';\nexport {\n Table,\n TableAlignment,\n TableLayout,\n TableBorder,\n TableBorders,\n TableFormatting,\n} from './elements/Table';\nexport { TableRow, RowFormatting } from './elements/TableRow';\nexport {\n TableCell,\n CellBorder,\n CellBorders,\n CellShading,\n CellFormatting,\n} from './elements/TableCell';\nexport { TableGridChange, GridColumn, TableGridChangeProperties } from './elements/TableGridChange';\nexport {\n Image,\n ImageFormat,\n ImageProperties,\n ImageBorder,\n ImageEffects,\n PresetGeometry,\n BlipCompressionState,\n PicLockAttribute,\n PicNonVisualProperties,\n} from './elements/Image';\nexport { ImageRun } from './elements/ImageRun';\nexport { Shape, ShapeType, ShapeProperties, ShapeFill, ShapeOutline } from './elements/Shape';\nexport { TextBox, TextBoxProperties, TextBoxFill, TextBoxMargins } from './elements/TextBox';\nexport { Header, HeaderType, HeaderProperties } from './elements/Header';\nexport { Footer, FooterType, FooterProperties } from './elements/Footer';\nexport { Hyperlink, HyperlinkProperties } from './elements/Hyperlink';\nexport { Bookmark, BookmarkProperties } from './elements/Bookmark';\nexport { RangeMarker, RangeMarkerType, RangeMarkerProperties } from './elements/RangeMarker';\nexport { Comment, CommentProperties } from './elements/Comment';\nexport { Footnote, FootnoteType, FootnoteProperties } from './elements/Footnote';\nexport { Endnote, EndnoteType, EndnoteProperties } from './elements/Endnote';\nexport {\n Field,\n FieldType,\n FieldProperties,\n ComplexField,\n ComplexFieldProperties,\n FieldCharType,\n TOCFieldOptions,\n createTOCField,\n} from './elements/Field';\nexport {\n createNestedIFMergeField,\n createMergeField,\n createRefField,\n createIFField,\n createNestedField,\n parseHyperlinkInstruction,\n buildHyperlinkInstruction,\n isHyperlinkInstruction,\n ParsedHyperlinkInstruction,\n} from './elements/FieldHelpers';\nexport {\n StructuredDocumentTag,\n SDTProperties,\n SDTLockType,\n SDTContent,\n SDTPlaceholder,\n SDTDataBinding,\n ContentControlType,\n} from './elements/StructuredDocumentTag';\nexport { TableOfContents, TOCProperties } from './elements/TableOfContents';\nexport { TableOfContentsElement } from './elements/TableOfContentsElement';\nexport { AlternateContent } from './elements/AlternateContent';\nexport { MathParagraph, MathExpression } from './elements/MathElement';\nexport { CustomXmlBlock } from './elements/CustomXml';\nexport { PreservedElement, PreservedElementContext } from './elements/PreservedElement';\n\n// =============================================================================\n// PUBLIC API — Track Changes / Revisions\n// =============================================================================\n\nexport { Revision, RevisionType, RevisionProperties, FieldContext } from './elements/Revision';\nexport { RevisionContent, isRunContent, isHyperlinkContent } from './elements/RevisionContent';\nexport {\n RevisionLocation,\n RunPropertyChange,\n ParagraphPropertyChange,\n ParagraphFormattingPartial,\n ParagraphBorderDef,\n ParagraphBorders,\n ParagraphShading,\n TabStopDef,\n PropertyChangeBase,\n TablePropertyChange,\n TablePropertyChangeType,\n SectionPropertyChange,\n NumberingChange,\n AnyPropertyChange,\n isRunPropertyChange,\n isParagraphPropertyChange,\n isTablePropertyChange,\n isSectionPropertyChange,\n isNumberingChange,\n} from './elements/PropertyChangeTypes';\nexport {\n acceptRevisionsInMemory,\n AcceptRevisionsOptions,\n AcceptRevisionsResult,\n paragraphHasRevisions,\n getRevisionsFromParagraph,\n countRevisionsByType,\n stripRevisionsFromXml,\n} from './utils/InMemoryRevisionAcceptor';\nexport {\n MoveOperationHelper,\n MoveOperationOptions,\n MoveOperationResult,\n} from './utils/MoveOperationHelper';\nexport {\n SelectiveRevisionAcceptor,\n SelectiveAcceptResult,\n} from './utils/SelectiveRevisionAcceptor';\nexport {\n RevisionAwareProcessor,\n RevisionHandlingMode,\n RevisionProcessingOptions,\n SelectionCriteria,\n RevisionProcessingResult,\n ConflictInfo,\n ProcessingLogEntry,\n} from './utils/RevisionAwareProcessor';\nexport {\n ChangelogGenerator,\n ChangeEntry,\n ChangeCategory,\n ChangeLocation,\n ChangelogOptions,\n ChangelogFormat,\n ConsolidatedChange,\n ChangelogSummary,\n} from './utils/ChangelogGenerator';\n\n// =============================================================================\n// PUBLIC API — Formatting / Styles / Numbering\n// =============================================================================\n\nexport { Style, StyleType, StyleProperties } from './formatting/Style';\nexport {\n StylesManager,\n ValidationResult,\n LatentStylesConfig,\n LatentStyleException,\n} from './formatting/StylesManager';\nexport {\n NumberingLevel,\n NumberFormat,\n NumberAlignment,\n NumberingLevelProperties,\n WORD_NATIVE_BULLETS,\n WordNativeBullet,\n} from './formatting/NumberingLevel';\nexport { AbstractNumbering, AbstractNumberingProperties } from './formatting/AbstractNumbering';\nexport { NumberingInstance, NumberingInstanceProperties } from './formatting/NumberingInstance';\nexport {\n NumberingManager,\n NumberingConsolidationOptions,\n NumberingConsolidationResult,\n} from './formatting/NumberingManager';\nexport {\n StyleRunFormatting,\n StyleParagraphFormatting,\n Heading2TableOptions,\n StyleConfig,\n Heading2Config,\n ApplyCustomFormattingOptions,\n} from './types/styleConfig';\nexport { FormatOptions, StyleApplyOptions, EmphasisType, ListPrefix } from './types/formatting';\n\n// =============================================================================\n// PUBLIC API — Managers\n// =============================================================================\n\nexport { RevisionManager, RevisionCategory, RevisionSummary } from './elements/RevisionManager';\nexport { ImageManager } from './elements/ImageManager';\nexport { BookmarkManager } from './elements/BookmarkManager';\nexport { CommentManager } from './elements/CommentManager';\nexport { FootnoteManager } from './elements/FootnoteManager';\nexport { EndnoteManager } from './elements/EndnoteManager';\nexport { HeaderFooterManager } from './elements/HeaderFooterManager';\nexport { FontManager, FontFormat, FontEntry } from './elements/FontManager';\nexport {\n DrawingManager,\n DrawingElement,\n DrawingType,\n PreservedDrawing,\n} from './managers/DrawingManager';\n\n// =============================================================================\n// PUBLIC API — Image Optimization\n// =============================================================================\n\nexport type { ImageOptimizationResult } from './images/ImageOptimizer';\n\n// =============================================================================\n// TYPES — Common / Shared Type Definitions\n// =============================================================================\n\nexport {\n ShadingPattern,\n BasicShadingPattern,\n BorderStyle,\n ExtendedBorderStyle,\n FullBorderStyle,\n BorderDefinition,\n FourSidedBorders,\n TableBorderDefinitions,\n HorizontalAlignment,\n VerticalAlignment,\n PageVerticalAlignment,\n CellVerticalAlignment,\n ParagraphAlignment as CommonParagraphAlignment,\n TableAlignment as CommonTableAlignment,\n RowJustification,\n TextVerticalAlignment,\n TabAlignment,\n PositionAnchor,\n HorizontalAnchor,\n VerticalAnchor,\n TextDirection,\n SectionTextDirection,\n WidthType,\n ShadingConfig,\n buildShadingAttributes,\n TabLeader,\n TabStop,\n isShadingPattern,\n isBorderStyle,\n isHorizontalAlignment,\n isVerticalAlignment,\n isParagraphAlignment,\n isWidthType,\n DEFAULT_BORDER,\n NO_BORDER,\n} from './elements/CommonTypes';\nexport {\n ListCategory,\n NumberFormat as ListNumberFormat,\n BulletFormat,\n ListDetectionResult,\n ListAnalysis,\n ListNormalizationOptions,\n ListNormalizationReport,\n IndentationLevel,\n} from './types/list-types';\n\nexport { CompatibilityMode, CompatibilityInfo, CompatSetting } from './types/compatibility-types';\n\nexport {\n DocumentProtection,\n RevisionViewSettings,\n TrackChangesSettings,\n WebSettingsInfo,\n} from './types/settings-types';\n\n// =============================================================================\n// TYPES — Compatibility Upgrade\n// =============================================================================\n\nexport { CompatibilityUpgrader, UpgradeReport } from './utils/CompatibilityUpgrader';\nexport {\n LEGACY_COMPAT_ELEMENTS,\n LEGACY_COMPAT_ELEMENT_NAMES,\n MODERN_COMPAT_SETTINGS,\n MS_WORD_COMPAT_URI,\n} from './constants/legacyCompatFlags';\n\n// =============================================================================\n// UTILITIES — Unit Conversions\n// =============================================================================\n\nexport {\n STANDARD_DPI,\n UNITS,\n PAGE_SIZES,\n COMMON_MARGINS,\n twipsToPoints,\n twipsToInches,\n twipsToCm,\n twipsToEmus,\n emusToTwips,\n emusToInches,\n emusToCm,\n emusToPoints,\n emusToPixels,\n pointsToTwips,\n pointsToEmus,\n pointsToInches,\n pointsToCm,\n pointsToHalfPoints,\n halfPointsToPoints,\n inchesToTwips,\n inchesToEmus,\n inchesToPoints,\n inchesToCm,\n inchesToPixels,\n cmToTwips,\n cmToEmus,\n cmToInches,\n cmToPoints,\n cmToPixels,\n pixelsToEmus,\n pixelsToInches,\n pixelsToTwips,\n pixelsToCm,\n pixelsToPoints,\n} from './utils/units';\n\n// =============================================================================\n// UTILITIES — Validation, Corruption Detection, Error Handling\n// =============================================================================\n\nexport {\n validateDocxStructure,\n isBinaryFile,\n normalizePath,\n isValidZipBuffer,\n isTextContent,\n validateTwips,\n validateColor,\n validateHexColor,\n normalizeColor,\n validateNumberingId,\n validateLevel,\n validateAlignment,\n validateFontSize,\n validateNonEmptyString,\n validatePercentage,\n validateEmus,\n detectXmlInText,\n cleanXmlFromText,\n validateRunText,\n sanitizeHyperlinkUrl,\n SanitizeHyperlinkUrlResult,\n TextValidationResult,\n} from './utils/validation';\nexport {\n detectCorruptionInDocument,\n detectCorruptionInText,\n suggestFix,\n looksCorrupted,\n CorruptionReport,\n CorruptionLocation,\n CorruptionType,\n} from './utils/corruptionDetection';\nexport { isError, toError, wrapError, getErrorMessage } from './utils/errorHandling';\nexport {\n REVISION_RULES,\n ValidationSeverity,\n ValidationIssue,\n ValidationRule,\n ValidationOptions,\n AutoFixOptions,\n ValidationResult as RevisionValidationResult,\n FixAction,\n AutoFixResult,\n createIssueFromRule,\n getRuleByCode,\n getRulesBySeverity,\n getAutoFixableRules,\n RevisionValidator,\n RevisionAutoFixer,\n} from './validation';\n\n// =============================================================================\n// UTILITIES — Formatting, Parsing, Sanitization\n// =============================================================================\n\nexport {\n mergeFormatting,\n cloneFormatting,\n hasFormatting,\n cleanFormatting,\n isEqualFormatting,\n applyDefaults,\n} from './utils/formatting';\nexport {\n safeParseInt,\n parseOoxmlBoolean,\n isExplicitlySet,\n parseNumericAttribute,\n parseOnOffAttribute,\n} from './utils/parsingHelpers';\nexport {\n removeInvalidXmlChars,\n findInvalidXmlChars,\n hasInvalidXmlChars,\n XML_CONTROL_CHARS,\n} from './utils/xmlSanitization';\n\n// =============================================================================\n// UTILITIES — List Detection (kept for basic detection; normalization moved to consumer)\n// =============================================================================\n\nexport {\n detectTypedPrefix,\n detectListType,\n inferLevelFromIndentation,\n getParagraphIndentation,\n validateListSequence,\n getListCategoryFromFormat,\n getLevelFromFormat,\n TYPED_LIST_PATTERNS,\n PATTERN_TO_CATEGORY,\n FORMAT_TO_LEVEL,\n} from './utils/list-detection';\n\n// =============================================================================\n// UTILITIES — Logging\n// =============================================================================\n\nexport {\n ILogger,\n LogLevel,\n LogEntry,\n ConsoleLogger,\n SilentLogger,\n CollectingLogger,\n defaultLogger,\n createScopedLogger,\n createComponentLogger,\n getGlobalLogger,\n setGlobalLogger,\n resetGlobalLogger,\n} from './utils/logger';\n\n// =============================================================================\n// UTILITIES — Revision Walker\n// =============================================================================\n\nexport { RevisionWalker, RevisionWalkerOptions } from './utils/RevisionWalker';\nexport { resolveCellShading } from './utils/ShadingResolver';\nexport { decodeCnfStyle, getActiveConditionalsInPriorityOrder } from './utils/cnfStyleDecoder';\n\n// =============================================================================\n// UTILITIES — Cleanup\n// =============================================================================\n\nexport { CleanupHelper, CleanupOptions, CleanupReport } from './helpers/CleanupHelper';\n\n// =============================================================================\n// INTERNAL — ZIP Handling (advanced usage)\n// =============================================================================\n\nexport { ZipHandler } from './zip/ZipHandler';\nexport { ZipReader } from './zip/ZipReader';\nexport { ZipWriter } from './zip/ZipWriter';\nexport {\n ZipFile,\n FileMap,\n LoadOptions,\n SaveOptions,\n AddFileOptions,\n SizeLimitOptions,\n DEFAULT_SIZE_LIMITS,\n REQUIRED_DOCX_FILES,\n DOCX_PATHS,\n} from './zip/types';\nexport {\n DocxError,\n DocxNotFoundError,\n InvalidDocxError,\n CorruptedArchiveError,\n MissingRequiredFileError,\n FileOperationError,\n} from './zip/errors';\n\n// =============================================================================\n// INTERNAL — XML Builder and Parser (advanced usage)\n// =============================================================================\n\nexport { XMLBuilder, XMLElement } from './xml/XMLBuilder';\nexport {\n XMLParser,\n ParseToObjectOptions,\n ParsedXMLValue,\n ParsedXMLObject,\n DEFAULT_MAX_NESTING_DEPTH,\n} from './xml/XMLParser';\n\n// =============================================================================\n// INTERNAL — Parser, Generator, Validator (advanced usage)\n// =============================================================================\n\nexport { Relationship, RelationshipType, RelationshipProperties } from './core/Relationship';\nexport { RelationshipManager } from './core/RelationshipManager';\nexport { DocumentParser, ParseError } from './core/DocumentParser';\nexport { DocumentGenerator, IZipHandlerReader } from './core/DocumentGenerator';\nexport { DocumentValidator, SizeEstimate, MemoryOptions } from './core/DocumentValidator';\nexport { DocumentIdManager } from './core/DocumentIdManager';\n\n// =============================================================================\n// INTERNAL — Document Subsystem Classes (advanced usage)\n// =============================================================================\n\nexport { DocumentContent, BodyElement } from './core/DocumentContent';\n\n// =============================================================================\n// INTERNAL — Constants\n// =============================================================================\n\nexport { LIMITS } from './constants/limits';\n"]}
@@ -28,4 +28,9 @@ export declare function validateRunText(text: string, options?: {
28
28
  aggressive?: boolean;
29
29
  warnToConsole?: boolean;
30
30
  }): TextValidationResult;
31
+ export interface SanitizeHyperlinkUrlResult {
32
+ url: string;
33
+ fixes: string[];
34
+ }
35
+ export declare function sanitizeHyperlinkUrl(url: string): SanitizeHyperlinkUrlResult | null;
31
36
  //# sourceMappingURL=validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAaA,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAQ/D;AAOD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoBtD;AAgBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA6ClD;AAQD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAWxD;AAOD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAa/D;AAUD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,IAAI,CActE;AAmBD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAwBpD;AASD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,IAAI,CAatE;AAKD,eAAO,MAAM,gBAAgB,sBAAgB,CAAC;AAQ9C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAiB,GAAG,IAAI,CAcnF;AASD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,EAAE,QAAQ,SAAI,GAAG,IAAI,CAQpF;AASD,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,SAAc,GACtB,IAAI,CAQN;AASD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAc,GAAG,IAAI,CAkB5E;AAQD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,IAAI,CAQ/E;AAQD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAe,GAAG,IAAI,CAQhF;AAUD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,IAAI,CAkBpE;AAKD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAuDpF;AAaD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,UAAQ,GAAG,MAAM,CAyBzE;AAaD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACpB,GACL,oBAAoB,CA0BtB"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAaA,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAQ/D;AAOD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoBtD;AAgBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA6ClD;AAQD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAWxD;AAOD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAa/D;AAUD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,IAAI,CActE;AAmBD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAwBpD;AASD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,IAAI,CAatE;AAKD,eAAO,MAAM,gBAAgB,sBAAgB,CAAC;AAQ9C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAiB,GAAG,IAAI,CAcnF;AASD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,EAAE,QAAQ,SAAI,GAAG,IAAI,CAQpF;AASD,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,SAAc,GACtB,IAAI,CAQN;AASD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAc,GAAG,IAAI,CAkB5E;AAQD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,IAAI,CAQ/E;AAQD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAe,GAAG,IAAI,CAQhF;AAUD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,IAAI,CAkBpE;AAKD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAuDpF;AAaD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,UAAQ,GAAG,MAAM,CAyBzE;AAaD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACpB,GACL,oBAAoB,CA0BtB;AAKD,MAAM,WAAW,0BAA0B;IAEzC,GAAG,EAAE,MAAM,CAAC;IAEZ,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAeD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI,CAoCnF"}
@@ -19,6 +19,7 @@ exports.validateEmus = validateEmus;
19
19
  exports.detectXmlInText = detectXmlInText;
20
20
  exports.cleanXmlFromText = cleanXmlFromText;
21
21
  exports.validateRunText = validateRunText;
22
+ exports.sanitizeHyperlinkUrl = sanitizeHyperlinkUrl;
22
23
  const types_1 = require("../zip/types");
23
24
  const errors_1 = require("../zip/errors");
24
25
  const logger_1 = require("./logger");
@@ -272,4 +273,35 @@ function validateRunText(text, options = {}) {
272
273
  }
273
274
  return result;
274
275
  }
276
+ function sanitizeHyperlinkUrl(url) {
277
+ if (!url)
278
+ return null;
279
+ const fixes = [];
280
+ let sanitized = url;
281
+ const extensionPrefixes = [
282
+ { pattern: /^chrome-extension:\/\/[a-z]{32}\//i, name: 'Chrome extension' },
283
+ {
284
+ pattern: /^moz-extension:\/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\//i,
285
+ name: 'Firefox extension',
286
+ },
287
+ { pattern: /^extension:\/\/[a-z0-9]{32}\//i, name: 'Edge extension' },
288
+ ];
289
+ for (const { pattern, name } of extensionPrefixes) {
290
+ const match = pattern.exec(sanitized);
291
+ if (match) {
292
+ sanitized = sanitized.substring(match[0].length);
293
+ fixes.push(`Stripped ${name} URL prefix`);
294
+ break;
295
+ }
296
+ }
297
+ const brokenProtocol = /^(https?:\/)([^/])/i.exec(sanitized);
298
+ if (brokenProtocol) {
299
+ sanitized =
300
+ brokenProtocol[1] + '/' + brokenProtocol[2] + sanitized.substring(brokenProtocol[0].length);
301
+ fixes.push('Fixed broken protocol (added missing slash)');
302
+ }
303
+ if (fixes.length === 0)
304
+ return null;
305
+ return { url: sanitized, fixes };
306
+ }
275
307
  //# sourceMappingURL=validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validation utilities for DOCX files\n */\n\nimport { REQUIRED_DOCX_FILES } from '../zip/types';\nimport { MissingRequiredFileError } from '../zip/errors';\nimport { defaultLogger } from './logger';\n\n/**\n * Validates that all required DOCX files are present\n * @param filePaths - Array of file paths in the archive\n * @throws {MissingRequiredFileError} If a required file is missing\n */\nexport function validateDocxStructure(filePaths: string[]): void {\n const fileSet = new Set(filePaths);\n\n for (const requiredFile of REQUIRED_DOCX_FILES) {\n if (!fileSet.has(requiredFile)) {\n throw new MissingRequiredFileError(requiredFile);\n }\n }\n}\n\n/**\n * Checks if a file path represents a binary file based on extension\n * @param filePath - The file path to check\n * @returns True if the file is likely binary\n */\nexport function isBinaryFile(filePath: string): boolean {\n const binaryExtensions = [\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.bmp',\n '.tiff',\n '.ico',\n '.emf',\n '.wmf',\n '.bin',\n '.dat',\n '.ttf',\n '.otf',\n '.woff',\n ];\n\n const extension = filePath.substring(filePath.lastIndexOf('.')).toLowerCase();\n return binaryExtensions.includes(extension);\n}\n\n/**\n * Normalizes a file path for consistent comparisons\n * Converts backslashes to forward slashes and removes leading slashes\n * Also validates against path traversal attacks\n *\n * **Security:** This function validates paths to prevent:\n * - Path traversal attacks (../, ..\\, URL-encoded variants)\n * - Absolute paths (C:\\, /etc/, etc.)\n * - Malicious DOCX files attempting directory escape\n *\n * @param path - The path to normalize\n * @returns Normalized path\n * @throws {Error} If path contains path traversal sequences, absolute paths, or URL-encoded attacks\n */\nexport function normalizePath(path: string): string {\n // First convert all backslashes to forward slashes for consistent checking\n const normalized = path.replace(/\\\\/g, '/').replace(/^\\/+/, '');\n\n // Security: Reject URL-encoded path traversal attempts\n // Attackers might try: %2e%2e%2f (%2e = . and %2f = /)\n if (/%2[eE]|%2[fF]|%5[cC]/.test(path)) {\n throw new Error(\n `Invalid file path: \"${path}\" contains URL-encoded characters (%2E, %2F, %5C). ` +\n `This could be an attempt to bypass path validation. ` +\n `Only plain characters are allowed in DOCX file paths.`\n );\n }\n\n // Security: Prevent path traversal attacks\n // Check AFTER normalization when all paths use forward slashes\n // This catches: ../, /.., or standalone \"..\"\n if (normalized.includes('../') || normalized.includes('/..') || normalized === '..') {\n throw new Error(\n `Invalid file path: \"${path}\" contains path traversal sequence (..). ` +\n `This could be a malicious DOCX file attempting directory traversal. ` +\n `DOCX archives must only contain relative paths within the archive.`\n );\n }\n\n // Security: Prevent absolute paths (Windows drive letters)\n // Examples: C:/, C:\\, D:, etc.\n if (/^[a-zA-Z]:/.test(normalized)) {\n throw new Error(\n `Invalid file path: \"${path}\" appears to be an absolute Windows path. ` +\n `Absolute paths are not allowed in DOCX archives. ` +\n `Only relative paths within the archive are permitted.`\n );\n }\n\n // Security: Prevent Unix absolute paths\n // After removing leading slashes, if it starts with / it's suspicious\n if (path.startsWith('/') && normalized.startsWith('/')) {\n throw new Error(\n `Invalid file path: \"${path}\" appears to be an absolute Unix path. ` +\n `Only relative paths are allowed in DOCX archives.`\n );\n }\n\n return normalized;\n}\n\n/**\n * Validates that a buffer contains a valid ZIP file signature\n * ZIP files start with the signature 'PK' (0x50 0x4B)\n * @param buffer - The buffer to validate\n * @returns True if the buffer appears to be a ZIP file\n */\nexport function isValidZipBuffer(buffer: Buffer): boolean {\n if (buffer.length < 4) {\n return false;\n }\n\n // Check for ZIP signature: PK\\x03\\x04 or PK\\x05\\x06 (for empty archives)\n return (\n buffer[0] === 0x50 &&\n buffer[1] === 0x4b &&\n ((buffer[2] === 0x03 && buffer[3] === 0x04) || (buffer[2] === 0x05 && buffer[3] === 0x06))\n );\n}\n\n/**\n * Checks if a string is valid UTF-8 text\n * @param content - The content to check\n * @returns True if the content is valid text\n */\nexport function isTextContent(content: Buffer | string): boolean {\n if (typeof content === 'string') {\n return true;\n }\n\n // Try to decode as UTF-8 and check for null bytes\n try {\n const text = content.toString('utf8');\n // Binary files often contain null bytes\n return !text.includes('\\0');\n } catch {\n return false;\n }\n}\n\n/**\n * Validates a twips value (used for spacing, indentation, margins)\n * Twips: 1/20th of a point, 1440 twips = 1 inch\n * Reasonable range: -31680 to 31680 (±22 inches)\n * @param value - The twips value to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the value is invalid\n */\nexport function validateTwips(value: number, fieldName = 'value'): void {\n if (!Number.isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number, got ${value}`);\n }\n\n // Reasonable range: ±22 inches (31680 twips)\n const MIN_TWIPS = -31680;\n const MAX_TWIPS = 31680;\n\n if (value < MIN_TWIPS || value > MAX_TWIPS) {\n throw new Error(\n `${fieldName} out of range: ${value} twips (allowed: ${MIN_TWIPS} to ${MAX_TWIPS}, ±22 inches)`\n );\n }\n}\n\n/**\n * Normalizes a color to uppercase 6-character hex format\n * Accepts 3-character or 6-character hex colors with or without '#' prefix\n * Follows Microsoft Word convention of uppercase hex colors\n *\n * @param color - Color to normalize (e.g., '#F00', 'FF0000', '#FF0000', 'f00')\n * @returns Normalized color (e.g., 'FF0000')\n * @throws Error if color format is invalid\n *\n * @example\n * ```typescript\n * normalizeColor('#F00') // Returns: 'FF0000'\n * normalizeColor('FF0000') // Returns: 'FF0000'\n * normalizeColor('#ff0000') // Returns: 'FF0000'\n * normalizeColor('f00') // Returns: 'FF0000'\n * ```\n */\nexport function normalizeColor(color: string): string {\n const hex = color.replace(/^#/, '');\n\n // Validate hex format\n if (!/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(hex)) {\n throw new Error(\n `Invalid color format: \"${color}\". Expected 3 or 6-character hex ` +\n `(e.g., \"FF0000\", \"#FF0000\", \"F00\", or \"#F00\")`\n );\n }\n\n // Expand 3-character to 6-character\n if (hex.length === 3) {\n return (\n hex.charAt(0) +\n hex.charAt(0) +\n hex.charAt(1) +\n hex.charAt(1) +\n hex.charAt(2) +\n hex.charAt(2)\n ).toUpperCase();\n }\n\n return hex.toUpperCase();\n}\n\n/**\n * Validates a hexadecimal color value\n * Must be 6 characters (RRGGBB format)\n * @param color - The color hex string to validate (without #)\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the color is invalid\n */\nexport function validateColor(color: string, fieldName = 'color'): void {\n if (typeof color !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof color}`);\n }\n\n // Allow both with and without # prefix\n const cleanColor = color.startsWith('#') ? color.substring(1) : color;\n\n if (!/^[0-9A-Fa-f]{6}$/.test(cleanColor)) {\n throw new Error(\n `${fieldName} must be a 6-digit hex color (e.g., 'FF0000' or '#FF0000'), got '${color}'`\n );\n }\n}\n\n/**\n * Alias for validateColor for backwards compatibility\n */\nexport const validateHexColor = validateColor;\n\n/**\n * Validates a numbering ID (must be non-negative integer)\n * @param numId - The numbering ID to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the ID is invalid\n */\nexport function validateNumberingId(numId: number, fieldName = 'numbering ID'): void {\n if (!Number.isInteger(numId)) {\n throw new Error(`${fieldName} must be an integer, got ${numId}`);\n }\n\n if (numId < 0) {\n throw new Error(`${fieldName} must be non-negative, got ${numId}`);\n }\n\n // Word supports numbering IDs up to 2147483647\n const MAX_NUM_ID = 2147483647;\n if (numId > MAX_NUM_ID) {\n throw new Error(`${fieldName} exceeds maximum value ${MAX_NUM_ID}, got ${numId}`);\n }\n}\n\n/**\n * Validates a numbering level (0-8 for Word)\n * @param level - The level to validate\n * @param fieldName - Name of the field (for error messages)\n * @param maxLevel - Maximum allowed level (default 8)\n * @throws {Error} If the level is invalid\n */\nexport function validateLevel(level: number, fieldName = 'level', maxLevel = 8): void {\n if (!Number.isInteger(level)) {\n throw new Error(`${fieldName} must be an integer, got ${level}`);\n }\n\n if (level < 0 || level > maxLevel) {\n throw new Error(`${fieldName} must be between 0 and ${maxLevel}, got ${level}`);\n }\n}\n\n/**\n * Validates an alignment value against allowed values\n * @param alignment - The alignment value to validate\n * @param allowed - Array of allowed alignment values\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the alignment is invalid\n */\nexport function validateAlignment(\n alignment: string,\n allowed: readonly string[],\n fieldName = 'alignment'\n): void {\n if (typeof alignment !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof alignment}`);\n }\n\n if (!allowed.includes(alignment)) {\n throw new Error(`Invalid ${fieldName}: '${alignment}' (allowed: ${allowed.join(', ')})`);\n }\n}\n\n/**\n * Validates a font size (in half-points for Word)\n * Reasonable range: 2-1638 (1-819 points)\n * @param size - The font size in half-points to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the size is invalid\n */\nexport function validateFontSize(size: number, fieldName = 'font size'): void {\n if (!Number.isFinite(size)) {\n throw new Error(`${fieldName} must be a finite number, got ${size}`);\n }\n\n if (!Number.isInteger(size)) {\n throw new Error(`${fieldName} must be an integer (in half-points), got ${size}`);\n }\n\n // Reasonable range: 2-1638 half-points (1-819 points)\n const MIN_SIZE = 2;\n const MAX_SIZE = 1638;\n\n if (size < MIN_SIZE || size > MAX_SIZE) {\n throw new Error(\n `${fieldName} out of range: ${size} half-points (allowed: ${MIN_SIZE}-${MAX_SIZE}, or ${MIN_SIZE / 2}-${MAX_SIZE / 2} points)`\n );\n }\n}\n\n/**\n * Validates that a string is not empty\n * @param value - The string to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the string is empty or not a string\n */\nexport function validateNonEmptyString(value: string, fieldName = 'value'): void {\n if (typeof value !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof value}`);\n }\n\n if (value.trim().length === 0) {\n throw new Error(`${fieldName} cannot be empty`);\n }\n}\n\n/**\n * Validates a percentage value (0-100)\n * @param value - The percentage to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the percentage is invalid\n */\nexport function validatePercentage(value: number, fieldName = 'percentage'): void {\n if (!Number.isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number, got ${value}`);\n }\n\n if (value < 0 || value > 100) {\n throw new Error(`${fieldName} must be between 0 and 100, got ${value}`);\n }\n}\n\n/**\n * Validates EMUs (English Metric Units) value\n * Used for image dimensions: 914400 EMUs = 1 inch\n * Reasonable range: 0 to 50 million (about 55 inches)\n * @param value - The EMUs value to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the value is invalid\n */\nexport function validateEmus(value: number, fieldName = 'EMUs'): void {\n if (!Number.isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number, got ${value}`);\n }\n\n if (!Number.isInteger(value)) {\n throw new Error(`${fieldName} must be an integer, got ${value}`);\n }\n\n if (value < 0) {\n throw new Error(`${fieldName} must be non-negative, got ${value}`);\n }\n\n // Reasonable maximum: 50 million EMUs (about 55 inches)\n const MAX_EMUS = 50000000;\n if (value > MAX_EMUS) {\n throw new Error(`${fieldName} exceeds maximum ${MAX_EMUS} (about 55 inches), got ${value}`);\n }\n}\n\n/**\n * Result of text validation for XML-like content\n */\nexport interface TextValidationResult {\n isValid: boolean;\n hasXmlPatterns: boolean;\n warnings: string[];\n cleanedText?: string;\n}\n\n/**\n * Detects XML-like patterns in text that might cause display issues\n *\n * This function checks for patterns that look like XML markup which,\n * when properly escaped in XML output, will display as literal text\n * in Word documents rather than being interpreted as markup.\n *\n * @param text - The text to validate\n * @param context - Optional context for better warning messages (e.g., \"hyperlink text\")\n * @returns Validation result with warnings and optional cleaned text\n */\nexport function detectXmlInText(text: string, context?: string): TextValidationResult {\n const warnings: string[] = [];\n let hasXmlPatterns = false;\n\n // Check for common XML element patterns\n const xmlElementPattern = /<\\/?w:[^>]+>|<w:[^>]+\\/>/g;\n const escapedXmlPattern = /&lt;.*?&gt;|&quot;|&apos;/g;\n\n // Check for specific problematic patterns we've seen\n const problematicPatterns = [\n /<w:t\\s+xml:space=\"preserve\">/,\n /<w:t\\s+xml:space=[\"']preserve[\"']>/,\n /<\\/w:t>/,\n /&lt;w:t\\s+xml:space=&quot;preserve&quot;&gt;/,\n ];\n\n // Check for any XML-like tags\n if (xmlElementPattern.test(text)) {\n hasXmlPatterns = true;\n const contextStr = context ? ` in ${context}` : '';\n warnings.push(\n `Text${contextStr} contains XML-like markup: \"${text.substring(0, 100)}${text.length > 100 ? '...' : ''}\". ` +\n `This will be displayed as literal text in the document. ` +\n `If you intended to add formatting, use the appropriate API methods instead.`\n );\n }\n\n // Check for already-escaped XML entities\n if (escapedXmlPattern.test(text)) {\n hasXmlPatterns = true;\n const contextStr = context ? ` in ${context}` : '';\n warnings.push(\n `Text${contextStr} contains escaped XML entities (e.g., &lt;, &gt;, &quot;). ` +\n `These will appear as literal characters in the document.`\n );\n }\n\n // Check for specific known problematic patterns\n for (const pattern of problematicPatterns) {\n if (pattern.test(text)) {\n hasXmlPatterns = true;\n const contextStr = context ? ` in ${context}` : '';\n warnings.push(\n `Text${contextStr} contains a known problematic XML pattern that suggests ` +\n `the text may have been corrupted by previous processing.`\n );\n break;\n }\n }\n\n return {\n isValid: true, // Text is always \"valid\" - we just warn about potential issues\n hasXmlPatterns,\n warnings,\n };\n}\n\n/**\n * Cleans XML-like patterns from text\n *\n * This function removes or cleans various XML patterns that might\n * appear in text content, typically from corrupted or improperly\n * processed documents.\n *\n * @param text - The text to clean\n * @param aggressive - If true, removes all angle brackets; if false, only removes clear XML tags\n * @returns Cleaned text with XML patterns removed\n */\nexport function cleanXmlFromText(text: string, aggressive = false): string {\n let cleaned = text;\n\n // First, unescape any HTML/XML entities\n cleaned = cleaned\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&amp;/g, '&');\n\n // Remove specific Word XML patterns\n // This targets patterns like <w:t xml:space=\"preserve\">\n cleaned = cleaned.replace(/<w:[^>]+>/g, '');\n cleaned = cleaned.replace(/<\\/w:[^>]+>/g, '');\n\n // Remove any remaining XML-like tags if aggressive mode\n if (aggressive) {\n cleaned = cleaned.replace(/<[^>]+>/g, '');\n }\n\n // Clean up any double spaces left behind\n cleaned = cleaned.replace(/\\s+/g, ' ').trim();\n\n return cleaned;\n}\n\n/**\n * Validates text for use in Run or Hyperlink elements\n *\n * This is the main validation function that should be called when\n * setting text content in Run or Hyperlink elements. It provides\n * warnings about problematic content and optionally cleans the text.\n *\n * @param text - The text to validate\n * @param options - Validation options\n * @returns Validation result with warnings and optionally cleaned text\n */\nexport function validateRunText(\n text: string,\n options: {\n context?: string;\n autoClean?: boolean;\n aggressive?: boolean;\n warnToConsole?: boolean;\n } = {}\n): TextValidationResult {\n const { context, autoClean = false, aggressive = false, warnToConsole = true } = options;\n\n // Detect XML patterns\n const result = detectXmlInText(text, context);\n\n // If auto-cleaning is enabled and XML patterns were found\n if (autoClean && result.hasXmlPatterns) {\n result.cleanedText = cleanXmlFromText(text, aggressive);\n\n // Add a note about cleaning\n result.warnings.push(\n `Text has been automatically cleaned. ` +\n `Original: \"${text.substring(0, 50)}${text.length > 50 ? '...' : ''}\" ` +\n `Cleaned: \"${result.cleanedText.substring(0, 50)}${result.cleanedText.length > 50 ? '...' : ''}\"`\n );\n }\n\n // Log warnings to console in development if requested\n if (warnToConsole && result.warnings.length > 0 && typeof console !== 'undefined') {\n const contextStr = context ? ` [${context}]` : '';\n defaultLogger.warn(`DocXML Text Validation Warning${contextStr}:`);\n result.warnings.forEach((warning) => defaultLogger.warn(` - ${warning}`));\n }\n\n return result;\n}\n"]}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validation utilities for DOCX files\n */\n\nimport { REQUIRED_DOCX_FILES } from '../zip/types';\nimport { MissingRequiredFileError } from '../zip/errors';\nimport { defaultLogger } from './logger';\n\n/**\n * Validates that all required DOCX files are present\n * @param filePaths - Array of file paths in the archive\n * @throws {MissingRequiredFileError} If a required file is missing\n */\nexport function validateDocxStructure(filePaths: string[]): void {\n const fileSet = new Set(filePaths);\n\n for (const requiredFile of REQUIRED_DOCX_FILES) {\n if (!fileSet.has(requiredFile)) {\n throw new MissingRequiredFileError(requiredFile);\n }\n }\n}\n\n/**\n * Checks if a file path represents a binary file based on extension\n * @param filePath - The file path to check\n * @returns True if the file is likely binary\n */\nexport function isBinaryFile(filePath: string): boolean {\n const binaryExtensions = [\n '.png',\n '.jpg',\n '.jpeg',\n '.gif',\n '.bmp',\n '.tiff',\n '.ico',\n '.emf',\n '.wmf',\n '.bin',\n '.dat',\n '.ttf',\n '.otf',\n '.woff',\n ];\n\n const extension = filePath.substring(filePath.lastIndexOf('.')).toLowerCase();\n return binaryExtensions.includes(extension);\n}\n\n/**\n * Normalizes a file path for consistent comparisons\n * Converts backslashes to forward slashes and removes leading slashes\n * Also validates against path traversal attacks\n *\n * **Security:** This function validates paths to prevent:\n * - Path traversal attacks (../, ..\\, URL-encoded variants)\n * - Absolute paths (C:\\, /etc/, etc.)\n * - Malicious DOCX files attempting directory escape\n *\n * @param path - The path to normalize\n * @returns Normalized path\n * @throws {Error} If path contains path traversal sequences, absolute paths, or URL-encoded attacks\n */\nexport function normalizePath(path: string): string {\n // First convert all backslashes to forward slashes for consistent checking\n const normalized = path.replace(/\\\\/g, '/').replace(/^\\/+/, '');\n\n // Security: Reject URL-encoded path traversal attempts\n // Attackers might try: %2e%2e%2f (%2e = . and %2f = /)\n if (/%2[eE]|%2[fF]|%5[cC]/.test(path)) {\n throw new Error(\n `Invalid file path: \"${path}\" contains URL-encoded characters (%2E, %2F, %5C). ` +\n `This could be an attempt to bypass path validation. ` +\n `Only plain characters are allowed in DOCX file paths.`\n );\n }\n\n // Security: Prevent path traversal attacks\n // Check AFTER normalization when all paths use forward slashes\n // This catches: ../, /.., or standalone \"..\"\n if (normalized.includes('../') || normalized.includes('/..') || normalized === '..') {\n throw new Error(\n `Invalid file path: \"${path}\" contains path traversal sequence (..). ` +\n `This could be a malicious DOCX file attempting directory traversal. ` +\n `DOCX archives must only contain relative paths within the archive.`\n );\n }\n\n // Security: Prevent absolute paths (Windows drive letters)\n // Examples: C:/, C:\\, D:, etc.\n if (/^[a-zA-Z]:/.test(normalized)) {\n throw new Error(\n `Invalid file path: \"${path}\" appears to be an absolute Windows path. ` +\n `Absolute paths are not allowed in DOCX archives. ` +\n `Only relative paths within the archive are permitted.`\n );\n }\n\n // Security: Prevent Unix absolute paths\n // After removing leading slashes, if it starts with / it's suspicious\n if (path.startsWith('/') && normalized.startsWith('/')) {\n throw new Error(\n `Invalid file path: \"${path}\" appears to be an absolute Unix path. ` +\n `Only relative paths are allowed in DOCX archives.`\n );\n }\n\n return normalized;\n}\n\n/**\n * Validates that a buffer contains a valid ZIP file signature\n * ZIP files start with the signature 'PK' (0x50 0x4B)\n * @param buffer - The buffer to validate\n * @returns True if the buffer appears to be a ZIP file\n */\nexport function isValidZipBuffer(buffer: Buffer): boolean {\n if (buffer.length < 4) {\n return false;\n }\n\n // Check for ZIP signature: PK\\x03\\x04 or PK\\x05\\x06 (for empty archives)\n return (\n buffer[0] === 0x50 &&\n buffer[1] === 0x4b &&\n ((buffer[2] === 0x03 && buffer[3] === 0x04) || (buffer[2] === 0x05 && buffer[3] === 0x06))\n );\n}\n\n/**\n * Checks if a string is valid UTF-8 text\n * @param content - The content to check\n * @returns True if the content is valid text\n */\nexport function isTextContent(content: Buffer | string): boolean {\n if (typeof content === 'string') {\n return true;\n }\n\n // Try to decode as UTF-8 and check for null bytes\n try {\n const text = content.toString('utf8');\n // Binary files often contain null bytes\n return !text.includes('\\0');\n } catch {\n return false;\n }\n}\n\n/**\n * Validates a twips value (used for spacing, indentation, margins)\n * Twips: 1/20th of a point, 1440 twips = 1 inch\n * Reasonable range: -31680 to 31680 (±22 inches)\n * @param value - The twips value to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the value is invalid\n */\nexport function validateTwips(value: number, fieldName = 'value'): void {\n if (!Number.isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number, got ${value}`);\n }\n\n // Reasonable range: ±22 inches (31680 twips)\n const MIN_TWIPS = -31680;\n const MAX_TWIPS = 31680;\n\n if (value < MIN_TWIPS || value > MAX_TWIPS) {\n throw new Error(\n `${fieldName} out of range: ${value} twips (allowed: ${MIN_TWIPS} to ${MAX_TWIPS}, ±22 inches)`\n );\n }\n}\n\n/**\n * Normalizes a color to uppercase 6-character hex format\n * Accepts 3-character or 6-character hex colors with or without '#' prefix\n * Follows Microsoft Word convention of uppercase hex colors\n *\n * @param color - Color to normalize (e.g., '#F00', 'FF0000', '#FF0000', 'f00')\n * @returns Normalized color (e.g., 'FF0000')\n * @throws Error if color format is invalid\n *\n * @example\n * ```typescript\n * normalizeColor('#F00') // Returns: 'FF0000'\n * normalizeColor('FF0000') // Returns: 'FF0000'\n * normalizeColor('#ff0000') // Returns: 'FF0000'\n * normalizeColor('f00') // Returns: 'FF0000'\n * ```\n */\nexport function normalizeColor(color: string): string {\n const hex = color.replace(/^#/, '');\n\n // Validate hex format\n if (!/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(hex)) {\n throw new Error(\n `Invalid color format: \"${color}\". Expected 3 or 6-character hex ` +\n `(e.g., \"FF0000\", \"#FF0000\", \"F00\", or \"#F00\")`\n );\n }\n\n // Expand 3-character to 6-character\n if (hex.length === 3) {\n return (\n hex.charAt(0) +\n hex.charAt(0) +\n hex.charAt(1) +\n hex.charAt(1) +\n hex.charAt(2) +\n hex.charAt(2)\n ).toUpperCase();\n }\n\n return hex.toUpperCase();\n}\n\n/**\n * Validates a hexadecimal color value\n * Must be 6 characters (RRGGBB format)\n * @param color - The color hex string to validate (without #)\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the color is invalid\n */\nexport function validateColor(color: string, fieldName = 'color'): void {\n if (typeof color !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof color}`);\n }\n\n // Allow both with and without # prefix\n const cleanColor = color.startsWith('#') ? color.substring(1) : color;\n\n if (!/^[0-9A-Fa-f]{6}$/.test(cleanColor)) {\n throw new Error(\n `${fieldName} must be a 6-digit hex color (e.g., 'FF0000' or '#FF0000'), got '${color}'`\n );\n }\n}\n\n/**\n * Alias for validateColor for backwards compatibility\n */\nexport const validateHexColor = validateColor;\n\n/**\n * Validates a numbering ID (must be non-negative integer)\n * @param numId - The numbering ID to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the ID is invalid\n */\nexport function validateNumberingId(numId: number, fieldName = 'numbering ID'): void {\n if (!Number.isInteger(numId)) {\n throw new Error(`${fieldName} must be an integer, got ${numId}`);\n }\n\n if (numId < 0) {\n throw new Error(`${fieldName} must be non-negative, got ${numId}`);\n }\n\n // Word supports numbering IDs up to 2147483647\n const MAX_NUM_ID = 2147483647;\n if (numId > MAX_NUM_ID) {\n throw new Error(`${fieldName} exceeds maximum value ${MAX_NUM_ID}, got ${numId}`);\n }\n}\n\n/**\n * Validates a numbering level (0-8 for Word)\n * @param level - The level to validate\n * @param fieldName - Name of the field (for error messages)\n * @param maxLevel - Maximum allowed level (default 8)\n * @throws {Error} If the level is invalid\n */\nexport function validateLevel(level: number, fieldName = 'level', maxLevel = 8): void {\n if (!Number.isInteger(level)) {\n throw new Error(`${fieldName} must be an integer, got ${level}`);\n }\n\n if (level < 0 || level > maxLevel) {\n throw new Error(`${fieldName} must be between 0 and ${maxLevel}, got ${level}`);\n }\n}\n\n/**\n * Validates an alignment value against allowed values\n * @param alignment - The alignment value to validate\n * @param allowed - Array of allowed alignment values\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the alignment is invalid\n */\nexport function validateAlignment(\n alignment: string,\n allowed: readonly string[],\n fieldName = 'alignment'\n): void {\n if (typeof alignment !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof alignment}`);\n }\n\n if (!allowed.includes(alignment)) {\n throw new Error(`Invalid ${fieldName}: '${alignment}' (allowed: ${allowed.join(', ')})`);\n }\n}\n\n/**\n * Validates a font size (in half-points for Word)\n * Reasonable range: 2-1638 (1-819 points)\n * @param size - The font size in half-points to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the size is invalid\n */\nexport function validateFontSize(size: number, fieldName = 'font size'): void {\n if (!Number.isFinite(size)) {\n throw new Error(`${fieldName} must be a finite number, got ${size}`);\n }\n\n if (!Number.isInteger(size)) {\n throw new Error(`${fieldName} must be an integer (in half-points), got ${size}`);\n }\n\n // Reasonable range: 2-1638 half-points (1-819 points)\n const MIN_SIZE = 2;\n const MAX_SIZE = 1638;\n\n if (size < MIN_SIZE || size > MAX_SIZE) {\n throw new Error(\n `${fieldName} out of range: ${size} half-points (allowed: ${MIN_SIZE}-${MAX_SIZE}, or ${MIN_SIZE / 2}-${MAX_SIZE / 2} points)`\n );\n }\n}\n\n/**\n * Validates that a string is not empty\n * @param value - The string to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the string is empty or not a string\n */\nexport function validateNonEmptyString(value: string, fieldName = 'value'): void {\n if (typeof value !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof value}`);\n }\n\n if (value.trim().length === 0) {\n throw new Error(`${fieldName} cannot be empty`);\n }\n}\n\n/**\n * Validates a percentage value (0-100)\n * @param value - The percentage to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the percentage is invalid\n */\nexport function validatePercentage(value: number, fieldName = 'percentage'): void {\n if (!Number.isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number, got ${value}`);\n }\n\n if (value < 0 || value > 100) {\n throw new Error(`${fieldName} must be between 0 and 100, got ${value}`);\n }\n}\n\n/**\n * Validates EMUs (English Metric Units) value\n * Used for image dimensions: 914400 EMUs = 1 inch\n * Reasonable range: 0 to 50 million (about 55 inches)\n * @param value - The EMUs value to validate\n * @param fieldName - Name of the field (for error messages)\n * @throws {Error} If the value is invalid\n */\nexport function validateEmus(value: number, fieldName = 'EMUs'): void {\n if (!Number.isFinite(value)) {\n throw new Error(`${fieldName} must be a finite number, got ${value}`);\n }\n\n if (!Number.isInteger(value)) {\n throw new Error(`${fieldName} must be an integer, got ${value}`);\n }\n\n if (value < 0) {\n throw new Error(`${fieldName} must be non-negative, got ${value}`);\n }\n\n // Reasonable maximum: 50 million EMUs (about 55 inches)\n const MAX_EMUS = 50000000;\n if (value > MAX_EMUS) {\n throw new Error(`${fieldName} exceeds maximum ${MAX_EMUS} (about 55 inches), got ${value}`);\n }\n}\n\n/**\n * Result of text validation for XML-like content\n */\nexport interface TextValidationResult {\n isValid: boolean;\n hasXmlPatterns: boolean;\n warnings: string[];\n cleanedText?: string;\n}\n\n/**\n * Detects XML-like patterns in text that might cause display issues\n *\n * This function checks for patterns that look like XML markup which,\n * when properly escaped in XML output, will display as literal text\n * in Word documents rather than being interpreted as markup.\n *\n * @param text - The text to validate\n * @param context - Optional context for better warning messages (e.g., \"hyperlink text\")\n * @returns Validation result with warnings and optional cleaned text\n */\nexport function detectXmlInText(text: string, context?: string): TextValidationResult {\n const warnings: string[] = [];\n let hasXmlPatterns = false;\n\n // Check for common XML element patterns\n const xmlElementPattern = /<\\/?w:[^>]+>|<w:[^>]+\\/>/g;\n const escapedXmlPattern = /&lt;.*?&gt;|&quot;|&apos;/g;\n\n // Check for specific problematic patterns we've seen\n const problematicPatterns = [\n /<w:t\\s+xml:space=\"preserve\">/,\n /<w:t\\s+xml:space=[\"']preserve[\"']>/,\n /<\\/w:t>/,\n /&lt;w:t\\s+xml:space=&quot;preserve&quot;&gt;/,\n ];\n\n // Check for any XML-like tags\n if (xmlElementPattern.test(text)) {\n hasXmlPatterns = true;\n const contextStr = context ? ` in ${context}` : '';\n warnings.push(\n `Text${contextStr} contains XML-like markup: \"${text.substring(0, 100)}${text.length > 100 ? '...' : ''}\". ` +\n `This will be displayed as literal text in the document. ` +\n `If you intended to add formatting, use the appropriate API methods instead.`\n );\n }\n\n // Check for already-escaped XML entities\n if (escapedXmlPattern.test(text)) {\n hasXmlPatterns = true;\n const contextStr = context ? ` in ${context}` : '';\n warnings.push(\n `Text${contextStr} contains escaped XML entities (e.g., &lt;, &gt;, &quot;). ` +\n `These will appear as literal characters in the document.`\n );\n }\n\n // Check for specific known problematic patterns\n for (const pattern of problematicPatterns) {\n if (pattern.test(text)) {\n hasXmlPatterns = true;\n const contextStr = context ? ` in ${context}` : '';\n warnings.push(\n `Text${contextStr} contains a known problematic XML pattern that suggests ` +\n `the text may have been corrupted by previous processing.`\n );\n break;\n }\n }\n\n return {\n isValid: true, // Text is always \"valid\" - we just warn about potential issues\n hasXmlPatterns,\n warnings,\n };\n}\n\n/**\n * Cleans XML-like patterns from text\n *\n * This function removes or cleans various XML patterns that might\n * appear in text content, typically from corrupted or improperly\n * processed documents.\n *\n * @param text - The text to clean\n * @param aggressive - If true, removes all angle brackets; if false, only removes clear XML tags\n * @returns Cleaned text with XML patterns removed\n */\nexport function cleanXmlFromText(text: string, aggressive = false): string {\n let cleaned = text;\n\n // First, unescape any HTML/XML entities\n cleaned = cleaned\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&amp;/g, '&');\n\n // Remove specific Word XML patterns\n // This targets patterns like <w:t xml:space=\"preserve\">\n cleaned = cleaned.replace(/<w:[^>]+>/g, '');\n cleaned = cleaned.replace(/<\\/w:[^>]+>/g, '');\n\n // Remove any remaining XML-like tags if aggressive mode\n if (aggressive) {\n cleaned = cleaned.replace(/<[^>]+>/g, '');\n }\n\n // Clean up any double spaces left behind\n cleaned = cleaned.replace(/\\s+/g, ' ').trim();\n\n return cleaned;\n}\n\n/**\n * Validates text for use in Run or Hyperlink elements\n *\n * This is the main validation function that should be called when\n * setting text content in Run or Hyperlink elements. It provides\n * warnings about problematic content and optionally cleans the text.\n *\n * @param text - The text to validate\n * @param options - Validation options\n * @returns Validation result with warnings and optionally cleaned text\n */\nexport function validateRunText(\n text: string,\n options: {\n context?: string;\n autoClean?: boolean;\n aggressive?: boolean;\n warnToConsole?: boolean;\n } = {}\n): TextValidationResult {\n const { context, autoClean = false, aggressive = false, warnToConsole = true } = options;\n\n // Detect XML patterns\n const result = detectXmlInText(text, context);\n\n // If auto-cleaning is enabled and XML patterns were found\n if (autoClean && result.hasXmlPatterns) {\n result.cleanedText = cleanXmlFromText(text, aggressive);\n\n // Add a note about cleaning\n result.warnings.push(\n `Text has been automatically cleaned. ` +\n `Original: \"${text.substring(0, 50)}${text.length > 50 ? '...' : ''}\" ` +\n `Cleaned: \"${result.cleanedText.substring(0, 50)}${result.cleanedText.length > 50 ? '...' : ''}\"`\n );\n }\n\n // Log warnings to console in development if requested\n if (warnToConsole && result.warnings.length > 0 && typeof console !== 'undefined') {\n const contextStr = context ? ` [${context}]` : '';\n defaultLogger.warn(`DocXML Text Validation Warning${contextStr}:`);\n result.warnings.forEach((warning) => defaultLogger.warn(` - ${warning}`));\n }\n\n return result;\n}\n\n/**\n * Result of URL sanitization\n */\nexport interface SanitizeHyperlinkUrlResult {\n /** The sanitized URL */\n url: string;\n /** List of fixes that were applied */\n fixes: string[];\n}\n\n/**\n * Sanitizes hyperlink URLs by removing browser extension prefixes and fixing\n * broken protocols that result from the stripping.\n *\n * Known corruptions:\n * - Chrome extensions (e.g. Adobe Acrobat) wrap URLs with `chrome-extension://[id]/`\n * - Firefox extensions wrap URLs with `moz-extension://[uuid]/`\n * - Edge extensions wrap URLs with `extension://[id]/`\n * - After stripping, protocol may be broken (`https:/` instead of `https://`)\n *\n * @param url - The URL to sanitize\n * @returns Object with sanitized URL and list of fixes, or null if no changes needed\n */\nexport function sanitizeHyperlinkUrl(url: string): SanitizeHyperlinkUrlResult | null {\n if (!url) return null;\n\n const fixes: string[] = [];\n let sanitized = url;\n\n // Strip known browser extension URL prefixes\n const extensionPrefixes = [\n { pattern: /^chrome-extension:\\/\\/[a-z]{32}\\//i, name: 'Chrome extension' },\n {\n pattern: /^moz-extension:\\/\\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\//i,\n name: 'Firefox extension',\n },\n { pattern: /^extension:\\/\\/[a-z0-9]{32}\\//i, name: 'Edge extension' },\n ];\n\n for (const { pattern, name } of extensionPrefixes) {\n const match = pattern.exec(sanitized);\n if (match) {\n sanitized = sanitized.substring(match[0].length);\n fixes.push(`Stripped ${name} URL prefix`);\n break;\n }\n }\n\n // Fix broken protocol after stripping (https:/ -> https://, http:/ -> http://)\n const brokenProtocol = /^(https?:\\/)([^/])/i.exec(sanitized);\n if (brokenProtocol) {\n sanitized =\n brokenProtocol[1] + '/' + brokenProtocol[2] + sanitized.substring(brokenProtocol[0].length);\n fixes.push('Fixed broken protocol (added missing slash)');\n }\n\n if (fixes.length === 0) return null;\n\n return { url: sanitized, fixes };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docxmlater",
3
- "version": "10.3.0",
3
+ "version": "10.3.1",
4
4
  "description": "A comprehensive DOCX editing framework for creating, reading, and manipulating Microsoft Word documents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -7,6 +7,7 @@
7
7
 
8
8
  import { Relationship, RelationshipType } from './Relationship';
9
9
  import { XMLParser } from '../xml/XMLParser';
10
+ import { sanitizeHyperlinkUrl } from '../utils/validation';
10
11
 
11
12
  /**
12
13
  * Manages relationships for a document or document part
@@ -412,11 +413,20 @@ export class RelationshipManager {
412
413
  ? targetMode
413
414
  : undefined;
414
415
 
416
+ // Sanitize hyperlink URLs (strip browser extension prefixes)
417
+ let sanitizedTarget = target;
418
+ if (type.endsWith('/hyperlink')) {
419
+ const result = sanitizeHyperlinkUrl(target);
420
+ if (result) {
421
+ sanitizedTarget = result.url;
422
+ }
423
+ }
424
+
415
425
  // Create and add relationship
416
426
  const relationship = Relationship.create({
417
427
  id,
418
428
  type,
419
- target,
429
+ target: sanitizedTarget,
420
430
  targetMode: validatedTargetMode || 'Internal',
421
431
  });
422
432
 
@@ -51,7 +51,7 @@
51
51
  import { XMLElement } from '../xml/XMLBuilder';
52
52
  import { Run, RunFormatting } from './Run';
53
53
  import { Revision } from './Revision';
54
- import { validateRunText } from '../utils/validation';
54
+ import { validateRunText, sanitizeHyperlinkUrl } from '../utils/validation';
55
55
  import { defaultLogger } from '../utils/logger';
56
56
 
57
57
  /**
@@ -969,6 +969,13 @@ export class Hyperlink {
969
969
 
970
970
  // Fix common issues
971
971
  if (fixCommonIssues && fixedUrl) {
972
+ // Fix 0: Strip browser extension URL prefixes
973
+ const sanitizeResult = sanitizeHyperlinkUrl(fixedUrl);
974
+ if (sanitizeResult) {
975
+ fixedUrl = sanitizeResult.url;
976
+ fixed.push(...sanitizeResult.fixes);
977
+ }
978
+
972
979
  // Fix 1: Add missing protocol
973
980
  if (!/^[a-z]+:\/\//i.exec(fixedUrl)) {
974
981
  fixedUrl = 'https://' + fixedUrl;
package/src/index.ts CHANGED
@@ -389,6 +389,8 @@ export {
389
389
  detectXmlInText,
390
390
  cleanXmlFromText,
391
391
  validateRunText,
392
+ sanitizeHyperlinkUrl,
393
+ SanitizeHyperlinkUrlResult,
392
394
  TextValidationResult,
393
395
  } from './utils/validation';
394
396
  export {
@@ -551,3 +551,64 @@ export function validateRunText(
551
551
 
552
552
  return result;
553
553
  }
554
+
555
+ /**
556
+ * Result of URL sanitization
557
+ */
558
+ export interface SanitizeHyperlinkUrlResult {
559
+ /** The sanitized URL */
560
+ url: string;
561
+ /** List of fixes that were applied */
562
+ fixes: string[];
563
+ }
564
+
565
+ /**
566
+ * Sanitizes hyperlink URLs by removing browser extension prefixes and fixing
567
+ * broken protocols that result from the stripping.
568
+ *
569
+ * Known corruptions:
570
+ * - Chrome extensions (e.g. Adobe Acrobat) wrap URLs with `chrome-extension://[id]/`
571
+ * - Firefox extensions wrap URLs with `moz-extension://[uuid]/`
572
+ * - Edge extensions wrap URLs with `extension://[id]/`
573
+ * - After stripping, protocol may be broken (`https:/` instead of `https://`)
574
+ *
575
+ * @param url - The URL to sanitize
576
+ * @returns Object with sanitized URL and list of fixes, or null if no changes needed
577
+ */
578
+ export function sanitizeHyperlinkUrl(url: string): SanitizeHyperlinkUrlResult | null {
579
+ if (!url) return null;
580
+
581
+ const fixes: string[] = [];
582
+ let sanitized = url;
583
+
584
+ // Strip known browser extension URL prefixes
585
+ const extensionPrefixes = [
586
+ { pattern: /^chrome-extension:\/\/[a-z]{32}\//i, name: 'Chrome extension' },
587
+ {
588
+ pattern: /^moz-extension:\/\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\//i,
589
+ name: 'Firefox extension',
590
+ },
591
+ { pattern: /^extension:\/\/[a-z0-9]{32}\//i, name: 'Edge extension' },
592
+ ];
593
+
594
+ for (const { pattern, name } of extensionPrefixes) {
595
+ const match = pattern.exec(sanitized);
596
+ if (match) {
597
+ sanitized = sanitized.substring(match[0].length);
598
+ fixes.push(`Stripped ${name} URL prefix`);
599
+ break;
600
+ }
601
+ }
602
+
603
+ // Fix broken protocol after stripping (https:/ -> https://, http:/ -> http://)
604
+ const brokenProtocol = /^(https?:\/)([^/])/i.exec(sanitized);
605
+ if (brokenProtocol) {
606
+ sanitized =
607
+ brokenProtocol[1] + '/' + brokenProtocol[2] + sanitized.substring(brokenProtocol[0].length);
608
+ fixes.push('Fixed broken protocol (added missing slash)');
609
+ }
610
+
611
+ if (fixes.length === 0) return null;
612
+
613
+ return { url: sanitized, fixes };
614
+ }