@superdoc-dev/cli 0.2.0-next.74 → 0.2.0-next.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +643 -473
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -30728,7 +30728,7 @@ var init_remark_gfm_z_sDF4ss_es = __esm(() => {
30728
30728
  emptyOptions2 = {};
30729
30729
  });
30730
30730
 
30731
- // ../../packages/superdoc/dist/chunks/SuperConverter-B3_eOoDQ.es.js
30731
+ // ../../packages/superdoc/dist/chunks/SuperConverter-CDs2fwu4.es.js
30732
30732
  function getExtensionConfigField(extension$1, field, context = { name: "" }) {
30733
30733
  const fieldValue = extension$1.config[field];
30734
30734
  if (typeof fieldValue === "function")
@@ -39462,6 +39462,290 @@ function getHTMLFromFragment(fragment, schema, domDocument) {
39462
39462
  container.appendChild(documentFragment);
39463
39463
  return container.innerHTML;
39464
39464
  }
39465
+ function toProtocolSet(values) {
39466
+ const result = /* @__PURE__ */ new Set;
39467
+ if (!values)
39468
+ return result;
39469
+ values.forEach((value) => {
39470
+ if (typeof value === "string" && value.trim())
39471
+ result.add(value.trim().toLowerCase());
39472
+ });
39473
+ return result;
39474
+ }
39475
+ function buildAllowedProtocols$1(config$32 = {}) {
39476
+ const allowed = config$32.allowedProtocols?.length ? toProtocolSet(config$32.allowedProtocols) : new Set(DEFAULT_ALLOWED_PROTOCOLS);
39477
+ const optional = toProtocolSet(config$32.optionalProtocols);
39478
+ if (optional.size > 0)
39479
+ optional.forEach((protocol) => {
39480
+ if (OPTIONAL_PROTOCOLS.includes(protocol))
39481
+ allowed.add(protocol);
39482
+ });
39483
+ return allowed;
39484
+ }
39485
+ function normalizeBlocklist(values) {
39486
+ const hosts = /* @__PURE__ */ new Set;
39487
+ const urls = /* @__PURE__ */ new Set;
39488
+ if (!values)
39489
+ return {
39490
+ hosts,
39491
+ urls
39492
+ };
39493
+ values.forEach((entry) => {
39494
+ if (!entry || typeof entry !== "string")
39495
+ return;
39496
+ const trimmed = entry.trim().toLowerCase();
39497
+ if (!trimmed)
39498
+ return;
39499
+ if (trimmed.includes("://"))
39500
+ urls.add(trimmed);
39501
+ else
39502
+ hosts.add(trimmed);
39503
+ });
39504
+ return {
39505
+ hosts,
39506
+ urls
39507
+ };
39508
+ }
39509
+ function parseAnchorLink(trimmed) {
39510
+ if (!trimmed.startsWith("#"))
39511
+ return null;
39512
+ const anchor = trimmed.slice(1);
39513
+ if (!anchor || !ANCHOR_NAME_PATTERN.test(anchor))
39514
+ return null;
39515
+ return {
39516
+ href: `#${anchor}`,
39517
+ protocol: null,
39518
+ isExternal: false
39519
+ };
39520
+ }
39521
+ function isProtocolAllowed(scheme, allowedProtocols, blockedProtocols) {
39522
+ if (blockedProtocols.includes(scheme))
39523
+ return false;
39524
+ return allowedProtocols.has(scheme);
39525
+ }
39526
+ function isBlockedByRedirectList(normalizedHref, parsed, blocklist) {
39527
+ const { hosts, urls } = blocklist;
39528
+ const hostname2 = parsed.hostname ? parsed.hostname.toLowerCase() : "";
39529
+ if (hosts.size > 0 && hostname2 && hosts.has(hostname2))
39530
+ return true;
39531
+ if (urls.size > 0) {
39532
+ const hrefLower = normalizedHref.toLowerCase();
39533
+ for (const blockedUrl of urls)
39534
+ if (hrefLower.startsWith(blockedUrl))
39535
+ return true;
39536
+ }
39537
+ return false;
39538
+ }
39539
+ function sanitizeHref(raw, config$32 = {}) {
39540
+ if (typeof raw !== "string")
39541
+ return null;
39542
+ const trimmed = raw.trim();
39543
+ if (!trimmed)
39544
+ return null;
39545
+ const maxLength = typeof config$32.maxLength === "number" ? config$32.maxLength : DEFAULT_MAX_LENGTH;
39546
+ if (trimmed.length > maxLength)
39547
+ return null;
39548
+ const anchorResult = parseAnchorLink(trimmed);
39549
+ if (anchorResult !== null)
39550
+ return anchorResult;
39551
+ if (trimmed.startsWith("/") || trimmed.startsWith(".") || trimmed.startsWith("//") || /^www\./i.test(trimmed))
39552
+ return null;
39553
+ const schemeMatch = trimmed.match(/^([a-z0-9+.-]+):/i);
39554
+ if (!schemeMatch)
39555
+ return null;
39556
+ const scheme = schemeMatch[1].toLowerCase();
39557
+ if (!isProtocolAllowed(scheme, buildAllowedProtocols$1(config$32), BLOCKED_PROTOCOLS.concat(config$32.blockedProtocols ?? []).map((p) => p.toLowerCase())))
39558
+ return null;
39559
+ const hostStartIndex = trimmed.indexOf("://") + 3;
39560
+ let hostEndIndex = trimmed.indexOf("/", hostStartIndex);
39561
+ if (hostEndIndex === -1)
39562
+ hostEndIndex = trimmed.indexOf("?", hostStartIndex);
39563
+ if (hostEndIndex === -1)
39564
+ hostEndIndex = trimmed.indexOf("#", hostStartIndex);
39565
+ if (hostEndIndex === -1)
39566
+ hostEndIndex = trimmed.length;
39567
+ const rawHostname = trimmed.slice(hostStartIndex, hostEndIndex).toLowerCase();
39568
+ if (rawHostname && /[^\x00-\x7F]/.test(rawHostname)) {
39569
+ if (process$1.env.NODE_ENV === "development" || process$1.env.DEBUG_HYPERLINKS === "true")
39570
+ console.warn(`[URL Validation] Potential homograph attack detected in hostname: ${rawHostname.slice(0, 50)}`);
39571
+ }
39572
+ const queryStartIndex = trimmed.indexOf("?");
39573
+ if (queryStartIndex !== -1) {
39574
+ const queryString = trimmed.slice(queryStartIndex);
39575
+ if (/[<>"']/.test(queryString))
39576
+ return null;
39577
+ }
39578
+ let parsed;
39579
+ try {
39580
+ parsed = new URL(trimmed);
39581
+ } catch {
39582
+ return null;
39583
+ }
39584
+ const normalizedHref = trimmed;
39585
+ const blocklist = normalizeBlocklist(config$32.redirectBlocklist);
39586
+ if (isBlockedByRedirectList(normalizedHref, parsed, blocklist))
39587
+ return null;
39588
+ return {
39589
+ href: normalizedHref,
39590
+ protocol: scheme,
39591
+ isExternal: scheme === "http" || scheme === "https"
39592
+ };
39593
+ }
39594
+ function encodeTooltip(raw, maxLength = 500) {
39595
+ if (typeof raw !== "string")
39596
+ return null;
39597
+ const trimmed = raw.trim();
39598
+ if (!trimmed)
39599
+ return null;
39600
+ const limit = typeof maxLength === "number" && maxLength > 0 ? maxLength : 0;
39601
+ const wasTruncated = limit > 0 && trimmed.length > limit;
39602
+ return {
39603
+ text: limit > 0 && trimmed.length > limit ? trimmed.slice(0, limit) : trimmed,
39604
+ wasTruncated
39605
+ };
39606
+ }
39607
+ function maybeAddProtocol(text$2) {
39608
+ return /^www\./i.test(text$2) ? `https://${text$2}` : text$2;
39609
+ }
39610
+ function detectPasteUrl(text$2, protocols = []) {
39611
+ const trimmed = text$2?.trim();
39612
+ if (!trimmed)
39613
+ return null;
39614
+ if (/\s/.test(trimmed))
39615
+ return null;
39616
+ const result = sanitizeHref(maybeAddProtocol(trimmed), { allowedProtocols: buildAllowedProtocols(protocols) });
39617
+ return result ? { href: result.href } : null;
39618
+ }
39619
+ function canAllocateRels(editor) {
39620
+ return editor.options.mode === "docx" && !editor.options.isChildEditor && !editor.options.isHeaderOrFooter;
39621
+ }
39622
+ function handlePlainTextUrlPaste(editor, view, plainText, detected) {
39623
+ const { state } = view;
39624
+ const { selection } = state;
39625
+ if (!(selection instanceof TextSelection2))
39626
+ return false;
39627
+ const linkMarkType = editor.schema.marks.link;
39628
+ const underlineMarkType = editor.schema.marks.underline;
39629
+ if (!linkMarkType)
39630
+ return false;
39631
+ const rId = allocateRelationshipId(editor, detected.href);
39632
+ let tr = state.tr;
39633
+ let from = selection.from;
39634
+ let to = selection.to;
39635
+ const trimmedText = plainText.trim();
39636
+ if (selection.empty) {
39637
+ tr = tr.insertText(trimmedText, from);
39638
+ to = from + trimmedText.length;
39639
+ }
39640
+ tr = tr.addMark(from, to, linkMarkType.create({
39641
+ href: detected.href,
39642
+ rId
39643
+ }));
39644
+ if (underlineMarkType)
39645
+ tr = tr.addMark(from, to, underlineMarkType.create());
39646
+ view.dispatch(tr.scrollIntoView());
39647
+ return true;
39648
+ }
39649
+ function getChangedRangesFromTransaction(tr) {
39650
+ const maps = tr.mapping?.maps;
39651
+ if (!maps?.length)
39652
+ return [];
39653
+ const ranges = [];
39654
+ maps.forEach((map2) => {
39655
+ map2.forEach((oldStart, oldEnd, newStart, newEnd) => {
39656
+ ranges.push({
39657
+ from: newStart,
39658
+ to: newEnd
39659
+ });
39660
+ });
39661
+ });
39662
+ return mergeRanges(ranges, tr.doc.content.size);
39663
+ }
39664
+ function normalizePastedLinks(tr, editor, protocols) {
39665
+ const changedRanges = getChangedRangesFromTransaction(tr);
39666
+ if (!changedRanges.length)
39667
+ return;
39668
+ const linkMarkType = editor.schema.marks.link;
39669
+ if (!linkMarkType)
39670
+ return;
39671
+ const allowedProtocols = buildAllowedProtocols(protocols ?? resolveLinkProtocols(editor));
39672
+ for (const { from, to } of changedRanges)
39673
+ normalizeLinkMarksInRange(tr, editor, linkMarkType, from, to, allowedProtocols);
39674
+ }
39675
+ function resolveLinkProtocols(editor) {
39676
+ return editor.extensionService?.extensions?.find((e) => e.name === "link")?.options?.protocols ?? [];
39677
+ }
39678
+ function normalizeLinkMarksInRange(tr, editor, linkMarkType, from, to, allowedProtocols) {
39679
+ const linkSpans = [];
39680
+ tr.doc.nodesBetween(from, to, (node3, pos) => {
39681
+ if (!node3.isInline)
39682
+ return;
39683
+ const linkMark = node3.marks.find((m) => m.type === linkMarkType);
39684
+ if (!linkMark)
39685
+ return;
39686
+ linkSpans.push({
39687
+ from: pos,
39688
+ to: pos + node3.nodeSize,
39689
+ mark: linkMark
39690
+ });
39691
+ });
39692
+ for (let i2 = linkSpans.length - 1;i2 >= 0; i2--)
39693
+ normalizeOneLinkMark(tr, editor, linkMarkType, linkSpans[i2], allowedProtocols);
39694
+ }
39695
+ function normalizeOneLinkMark(tr, editor, linkMarkType, span, allowedProtocols) {
39696
+ const { from, to, mark } = span;
39697
+ const attrs = { ...mark.attrs };
39698
+ attrs.rId = null;
39699
+ const rawHref = attrs.href;
39700
+ const hasInternalRef = Boolean(attrs.anchor) || Boolean(attrs.name);
39701
+ if (!rawHref && hasInternalRef) {
39702
+ tr.removeMark(from, to, linkMarkType);
39703
+ tr.addMark(from, to, linkMarkType.create(attrs));
39704
+ return;
39705
+ }
39706
+ if (!rawHref) {
39707
+ tr.removeMark(from, to, linkMarkType);
39708
+ return;
39709
+ }
39710
+ const sanitized = sanitizeHref(maybeAddProtocol(rawHref), { allowedProtocols });
39711
+ if (!sanitized) {
39712
+ tr.removeMark(from, to, linkMarkType);
39713
+ return;
39714
+ }
39715
+ attrs.href = sanitized.href;
39716
+ if (canAllocateRels(editor))
39717
+ attrs.rId = allocateRelationshipId(editor, sanitized.href);
39718
+ tr.removeMark(from, to, linkMarkType);
39719
+ tr.addMark(from, to, linkMarkType.create(attrs));
39720
+ }
39721
+ function allocateRelationshipId(editor, href) {
39722
+ if (!canAllocateRels(editor))
39723
+ return null;
39724
+ try {
39725
+ const existing = findRelationshipIdFromTarget(href, editor);
39726
+ if (existing)
39727
+ return existing;
39728
+ return insertNewRelationship(href, "hyperlink", editor);
39729
+ } catch {
39730
+ return null;
39731
+ }
39732
+ }
39733
+ function buildAllowedProtocols(extras = []) {
39734
+ const normalized = normalizeProtocols(extras);
39735
+ return Array.from(new Set([...UrlValidationConstants.DEFAULT_ALLOWED_PROTOCOLS, ...normalized]));
39736
+ }
39737
+ function normalizeProtocols(protocols = []) {
39738
+ const result = [];
39739
+ for (const entry of protocols) {
39740
+ if (!entry)
39741
+ continue;
39742
+ if (typeof entry === "string" && entry.trim())
39743
+ result.push(entry.trim().toLowerCase());
39744
+ else if (typeof entry === "object" && typeof entry.scheme === "string" && entry.scheme.trim())
39745
+ result.push(entry.scheme.trim().toLowerCase());
39746
+ }
39747
+ return result;
39748
+ }
39465
39749
  function getStyleTagFromStyleId(styleId, docx) {
39466
39750
  const styles = docx["word/styles.xml"];
39467
39751
  if (!styles)
@@ -40095,12 +40379,19 @@ function handleHtmlPaste(html2, editor, source) {
40095
40379
  const isSingleParagraph = doc$1.childCount === 1 && doc$1.firstChild.type.name === "paragraph";
40096
40380
  if (isInParagraph && isSingleParagraph) {
40097
40381
  const paragraphContent = doc$1.firstChild.content;
40098
- dispatch(state.tr.replaceSelectionWith(paragraphContent, false));
40382
+ const tr = state.tr.replaceSelectionWith(paragraphContent, false);
40383
+ normalizePastedLinks(tr, editor);
40384
+ dispatch(tr);
40099
40385
  } else if (isInParagraph) {
40100
40386
  const slice = new Slice(doc$1.content, 0, 0);
40101
- dispatch(state.tr.replaceSelection(slice));
40102
- } else
40103
- dispatch(state.tr.replaceSelectionWith(doc$1, true));
40387
+ const tr = state.tr.replaceSelection(slice);
40388
+ normalizePastedLinks(tr, editor);
40389
+ dispatch(tr);
40390
+ } else {
40391
+ const tr = state.tr.replaceSelectionWith(doc$1, true);
40392
+ normalizePastedLinks(tr, editor);
40393
+ dispatch(tr);
40394
+ }
40104
40395
  return true;
40105
40396
  }
40106
40397
  function htmlHandler(html2, editor, domDocument) {
@@ -40140,7 +40431,7 @@ function sanitizeHtml(html2, forbiddenTags = [
40140
40431
  walkAndClean(container);
40141
40432
  return container;
40142
40433
  }
40143
- function handleClipboardPaste({ editor, view }, html2) {
40434
+ function handleClipboardPaste({ editor, view }, html2, plainText) {
40144
40435
  let source;
40145
40436
  if (!html2)
40146
40437
  source = "plain-text";
@@ -40151,8 +40442,12 @@ function handleClipboardPaste({ editor, view }, html2) {
40151
40442
  else
40152
40443
  source = "browser-html";
40153
40444
  switch (source) {
40154
- case "plain-text":
40155
- return false;
40445
+ case "plain-text": {
40446
+ const detected = detectPasteUrl(plainText, resolveLinkProtocols(editor));
40447
+ if (!detected)
40448
+ return false;
40449
+ return handlePlainTextUrlPaste(editor, view, plainText, detected);
40450
+ }
40156
40451
  case "word-html":
40157
40452
  if (editor.options.mode === "docx")
40158
40453
  return handleDocxPaste(html2, editor, view);
@@ -56127,6 +56422,165 @@ var isRegExp = (value) => {
56127
56422
  textBefore += node3.isAtom && !node3.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos));
56128
56423
  });
56129
56424
  return textBefore;
56425
+ }, DEFAULT_ALLOWED_PROTOCOLS, OPTIONAL_PROTOCOLS, BLOCKED_PROTOCOLS, DEFAULT_MAX_LENGTH = 2048, ANCHOR_NAME_PATTERN, UrlValidationConstants, RELATIONSHIP_TYPES, getDocumentRelationshipElements = (editor) => {
56426
+ const docx = editor.converter?.convertedXml;
56427
+ if (!docx)
56428
+ return [];
56429
+ const elements = docx["word/_rels/document.xml.rels"]?.elements;
56430
+ if (!Array.isArray(elements))
56431
+ return [];
56432
+ return elements.find((el) => el.name === "Relationships")?.elements || [];
56433
+ }, getMaxRelationshipIdInt = (relationships) => {
56434
+ const ids = [];
56435
+ relationships.forEach((rel) => {
56436
+ const splitId = rel.attributes.Id.split("rId");
56437
+ const parsedInt = parseInt(splitId[1], 10);
56438
+ if (Number.isInteger(parsedInt))
56439
+ ids.push(parsedInt);
56440
+ });
56441
+ if (ids.length === 0)
56442
+ return 0;
56443
+ return Math.max(...ids);
56444
+ }, findRelationshipIdFromTarget = (target, editor) => {
56445
+ if (!target)
56446
+ return null;
56447
+ if (target.startsWith("word/"))
56448
+ target = target.replace("word/", "");
56449
+ const existingLinkRel = getDocumentRelationshipElements(editor)?.find((rel) => rel.attributes.Target === target);
56450
+ if (existingLinkRel)
56451
+ return existingLinkRel.attributes.Id;
56452
+ }, insertNewRelationship = (target, type, editor) => {
56453
+ if (!target || typeof target !== "string")
56454
+ throw new Error("Target must be a non-empty string");
56455
+ if (!type || typeof type !== "string")
56456
+ throw new Error("Type must be a non-empty string");
56457
+ if (!editor)
56458
+ throw new Error("Editor instance is required");
56459
+ const mappedType = RELATIONSHIP_TYPES[type];
56460
+ if (!mappedType) {
56461
+ console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES).join(", ")}`);
56462
+ return null;
56463
+ }
56464
+ const existingRelId = findRelationshipIdFromTarget(target, editor);
56465
+ if (existingRelId) {
56466
+ console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
56467
+ return existingRelId;
56468
+ }
56469
+ const docx = editor.converter?.convertedXml;
56470
+ if (!docx) {
56471
+ console.error("No converted XML found in editor");
56472
+ return null;
56473
+ }
56474
+ const documentRels = docx["word/_rels/document.xml.rels"];
56475
+ if (!documentRels) {
56476
+ console.error("No document relationships found in the docx");
56477
+ return null;
56478
+ }
56479
+ const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
56480
+ if (!relationshipsTag) {
56481
+ console.error("No Relationships tag found in document relationships");
56482
+ return null;
56483
+ }
56484
+ if (!relationshipsTag.elements)
56485
+ relationshipsTag.elements = [];
56486
+ const newId = getNewRelationshipId(editor);
56487
+ if (!newId) {
56488
+ console.error("Failed to generate new relationship ID");
56489
+ return null;
56490
+ }
56491
+ const newRel = {
56492
+ type: "element",
56493
+ name: "Relationship",
56494
+ attributes: {
56495
+ Id: newId,
56496
+ Type: mappedType,
56497
+ Target: target
56498
+ }
56499
+ };
56500
+ if (type === "hyperlink")
56501
+ newRel.attributes.TargetMode = "External";
56502
+ relationshipsTag.elements.push(newRel);
56503
+ return newId;
56504
+ }, getNewRelationshipId = (editor) => {
56505
+ return `rId${getMaxRelationshipIdInt(getDocumentRelationshipElements(editor)) + 1}`;
56506
+ }, mergeRanges = (ranges, docSize) => {
56507
+ if (!ranges.length)
56508
+ return [];
56509
+ const sorted = ranges.map(({ from, to }) => ({
56510
+ from: Math.max(0, from),
56511
+ to: Math.min(docSize, to)
56512
+ })).filter(({ from, to }) => from < to).sort((a, b) => a.from - b.from);
56513
+ const merged = [];
56514
+ for (const range of sorted) {
56515
+ const last = merged[merged.length - 1];
56516
+ if (last && range.from <= last.to)
56517
+ last.to = Math.max(last.to, range.to);
56518
+ else
56519
+ merged.push({ ...range });
56520
+ }
56521
+ return merged;
56522
+ }, mapRangesThroughTransactions = (ranges, transactions, docSize) => {
56523
+ let mapped = ranges;
56524
+ transactions.forEach((tr) => {
56525
+ mapped = mapped.map(({ from, to }) => {
56526
+ const mappedFrom = tr.mapping.map(from, -1);
56527
+ const mappedTo = tr.mapping.map(to, 1);
56528
+ if (mappedFrom >= mappedTo)
56529
+ return null;
56530
+ return {
56531
+ from: mappedFrom,
56532
+ to: mappedTo
56533
+ };
56534
+ }).filter(Boolean);
56535
+ });
56536
+ return mergeRanges(mapped, docSize);
56537
+ }, collectChangedRangesThroughTransactions = (transactions, docSize, options = {}) => {
56538
+ const ranges = [];
56539
+ const extraRanges = Array.isArray(options.extraRanges) ? options.extraRanges : [];
56540
+ if (extraRanges.length) {
56541
+ const mappedExtras = mapRangesThroughTransactions(extraRanges, transactions, docSize);
56542
+ ranges.push(...mappedExtras);
56543
+ }
56544
+ transactions.forEach((tr, index2) => {
56545
+ if (!tr.docChanged)
56546
+ return;
56547
+ const perTransactionRanges = [];
56548
+ tr.steps.forEach((step$1) => {
56549
+ if (typeof step$1.from !== "number" || typeof step$1.to !== "number")
56550
+ return;
56551
+ const from = tr.mapping.map(step$1.from, 1);
56552
+ const to = tr.mapping.map(step$1.to, -1);
56553
+ if (from >= to)
56554
+ return;
56555
+ perTransactionRanges.push({
56556
+ from,
56557
+ to
56558
+ });
56559
+ });
56560
+ tr.mapping.maps.forEach((map2) => {
56561
+ map2.forEach((oldStart, oldEnd, newStart, newEnd) => {
56562
+ if (newStart !== oldStart || oldEnd !== newEnd)
56563
+ perTransactionRanges.push({
56564
+ from: newStart,
56565
+ to: newEnd
56566
+ });
56567
+ });
56568
+ });
56569
+ if (!perTransactionRanges.length)
56570
+ return;
56571
+ const mapped = mapRangesThroughTransactions(perTransactionRanges, transactions.slice(index2 + 1), docSize);
56572
+ ranges.push(...mapped);
56573
+ });
56574
+ return mergeRanges(ranges, docSize);
56575
+ }, clampRange = (start, end, docSize) => {
56576
+ const safeStart = Math.max(0, Math.min(start, docSize));
56577
+ const safeEnd = Math.max(0, Math.min(end, docSize));
56578
+ if (safeStart >= safeEnd)
56579
+ return null;
56580
+ return {
56581
+ start: safeStart,
56582
+ end: safeEnd
56583
+ };
56130
56584
  }, handleDecimal = (path2, lvlText) => generateNumbering(path2, lvlText, numberToStringFormatter), handleRoman = (path2, lvlText) => generateNumbering(path2, lvlText, intToRoman), handleLowerRoman = (path2, lvlText) => {
56131
56585
  const result = handleRoman(path2, lvlText);
56132
56586
  return result ? result.toLowerCase() : null;
@@ -57216,7 +57670,9 @@ var isRegExp = (value) => {
57216
57670
  const { dispatch } = editor.view;
57217
57671
  if (!dispatch)
57218
57672
  return false;
57219
- dispatch(view.state.tr.replaceSelectionWith(doc$1, true));
57673
+ const tr = view.state.tr.replaceSelectionWith(doc$1, true);
57674
+ normalizePastedLinks(tr, editor);
57675
+ dispatch(tr);
57220
57676
  return true;
57221
57677
  }, wrapTextsInRuns = (doc$1) => {
57222
57678
  const runType = doc$1.type?.schema?.nodes?.run;
@@ -57350,7 +57806,9 @@ var isRegExp = (value) => {
57350
57806
  const { dispatch } = editor.view;
57351
57807
  if (!dispatch)
57352
57808
  return false;
57353
- dispatch(view.state.tr.replaceSelectionWith(doc$1, true));
57809
+ const tr = view.state.tr.replaceSelectionWith(doc$1, true);
57810
+ normalizePastedLinks(tr, editor);
57811
+ dispatch(tr);
57354
57812
  return true;
57355
57813
  }, InputRule = class {
57356
57814
  match;
@@ -57484,13 +57942,15 @@ var isRegExp = (value) => {
57484
57942
  return false;
57485
57943
  },
57486
57944
  handlePaste(view, event, slice) {
57487
- const html2 = event.clipboardData.getData("text/html");
57945
+ const clipboard = event.clipboardData;
57946
+ const html2 = clipboard.getData("text/html");
57947
+ const plainText = clipboard.getData("text/plain");
57488
57948
  if (slice.content.content.filter((item) => item.type.name === "fieldAnnotation").length)
57489
57949
  return false;
57490
57950
  return handleClipboardPaste({
57491
57951
  editor,
57492
57952
  view
57493
- }, html2);
57953
+ }, html2, plainText);
57494
57954
  }
57495
57955
  },
57496
57956
  isInputRules: true
@@ -59948,87 +60408,6 @@ var isRegExp = (value) => {
59948
60408
  const copy$1 = JSON.parse(JSON.stringify(nodes));
59949
60409
  walk(copy$1);
59950
60410
  return copy$1;
59951
- }, RELATIONSHIP_TYPES, getDocumentRelationshipElements = (editor) => {
59952
- const docx = editor.converter?.convertedXml;
59953
- if (!docx)
59954
- return [];
59955
- const elements = docx["word/_rels/document.xml.rels"]?.elements;
59956
- if (!Array.isArray(elements))
59957
- return [];
59958
- return elements.find((el) => el.name === "Relationships")?.elements || [];
59959
- }, getMaxRelationshipIdInt = (relationships) => {
59960
- const ids = [];
59961
- relationships.forEach((rel) => {
59962
- const splitId = rel.attributes.Id.split("rId");
59963
- const parsedInt = parseInt(splitId[1], 10);
59964
- if (Number.isInteger(parsedInt))
59965
- ids.push(parsedInt);
59966
- });
59967
- if (ids.length === 0)
59968
- return 0;
59969
- return Math.max(...ids);
59970
- }, findRelationshipIdFromTarget = (target, editor) => {
59971
- if (!target)
59972
- return null;
59973
- if (target.startsWith("word/"))
59974
- target = target.replace("word/", "");
59975
- const existingLinkRel = getDocumentRelationshipElements(editor)?.find((rel) => rel.attributes.Target === target);
59976
- if (existingLinkRel)
59977
- return existingLinkRel.attributes.Id;
59978
- }, insertNewRelationship = (target, type, editor) => {
59979
- if (!target || typeof target !== "string")
59980
- throw new Error("Target must be a non-empty string");
59981
- if (!type || typeof type !== "string")
59982
- throw new Error("Type must be a non-empty string");
59983
- if (!editor)
59984
- throw new Error("Editor instance is required");
59985
- const mappedType = RELATIONSHIP_TYPES[type];
59986
- if (!mappedType) {
59987
- console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES).join(", ")}`);
59988
- return null;
59989
- }
59990
- const existingRelId = findRelationshipIdFromTarget(target, editor);
59991
- if (existingRelId) {
59992
- console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
59993
- return existingRelId;
59994
- }
59995
- const docx = editor.converter?.convertedXml;
59996
- if (!docx) {
59997
- console.error("No converted XML found in editor");
59998
- return null;
59999
- }
60000
- const documentRels = docx["word/_rels/document.xml.rels"];
60001
- if (!documentRels) {
60002
- console.error("No document relationships found in the docx");
60003
- return null;
60004
- }
60005
- const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
60006
- if (!relationshipsTag) {
60007
- console.error("No Relationships tag found in document relationships");
60008
- return null;
60009
- }
60010
- if (!relationshipsTag.elements)
60011
- relationshipsTag.elements = [];
60012
- const newId = getNewRelationshipId(editor);
60013
- if (!newId) {
60014
- console.error("Failed to generate new relationship ID");
60015
- return null;
60016
- }
60017
- const newRel = {
60018
- type: "element",
60019
- name: "Relationship",
60020
- attributes: {
60021
- Id: newId,
60022
- Type: mappedType,
60023
- Target: target
60024
- }
60025
- };
60026
- if (type === "hyperlink")
60027
- newRel.attributes.TargetMode = "External";
60028
- relationshipsTag.elements.push(newRel);
60029
- return newId;
60030
- }, getNewRelationshipId = (editor) => {
60031
- return `rId${getMaxRelationshipIdInt(getDocumentRelationshipElements(editor)) + 1}`;
60032
60411
  }, DocxHelpers, kebabCase = (str) => str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`), getDefaultStyleDefinition = (defaultStyleId, docx) => {
60033
60412
  const result = {
60034
60413
  lineSpaceBefore: null,
@@ -61165,7 +61544,7 @@ var isRegExp = (value) => {
61165
61544
  state.kern = kernNode.attributes["w:val"];
61166
61545
  }
61167
61546
  }, SuperConverter;
61168
- var init_SuperConverter_B3_eOoDQ_es = __esm(() => {
61547
+ var init_SuperConverter_CDs2fwu4_es = __esm(() => {
61169
61548
  init_rolldown_runtime_B2q5OVn9_es();
61170
61549
  init_jszip_ChlR43oI_es();
61171
61550
  init_xml_js_DLE8mr0n_es();
@@ -72063,6 +72442,39 @@ var init_SuperConverter_B3_eOoDQ_es = __esm(() => {
72063
72442
  SKIP_FIELD_PROCESSING_NODE_NAMES$1 = new Set(["w:drawing", "w:pict"]);
72064
72443
  SKIP_FIELD_PROCESSING_NODE_NAMES = new Set(["w:drawing", "w:pict"]);
72065
72444
  HEADER_FOOTER_FILENAME_PATTERN = /^(header|footer)\d*\.xml$/i;
72445
+ init_dist();
72446
+ DEFAULT_ALLOWED_PROTOCOLS = [
72447
+ "http",
72448
+ "https",
72449
+ "mailto",
72450
+ "tel",
72451
+ "sms"
72452
+ ];
72453
+ OPTIONAL_PROTOCOLS = [
72454
+ "ftp",
72455
+ "sftp",
72456
+ "irc"
72457
+ ];
72458
+ BLOCKED_PROTOCOLS = [
72459
+ "javascript",
72460
+ "data",
72461
+ "vbscript",
72462
+ "file",
72463
+ "ssh",
72464
+ "ws",
72465
+ "wss"
72466
+ ];
72467
+ ANCHOR_NAME_PATTERN = /^[A-Za-z0-9._-]+$/;
72468
+ UrlValidationConstants = {
72469
+ DEFAULT_ALLOWED_PROTOCOLS,
72470
+ OPTIONAL_PROTOCOLS,
72471
+ BLOCKED_PROTOCOLS,
72472
+ DEFAULT_MAX_LENGTH
72473
+ };
72474
+ RELATIONSHIP_TYPES = {
72475
+ image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
72476
+ hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
72477
+ };
72066
72478
  listIndexMap = {
72067
72479
  decimal: handleDecimal,
72068
72480
  decimalZero: handleDecimalZero,
@@ -78739,10 +79151,6 @@ var init_SuperConverter_B3_eOoDQ_es = __esm(() => {
78739
79151
  handlerName: "handlePictNode",
78740
79152
  handler: handlePictNode
78741
79153
  };
78742
- RELATIONSHIP_TYPES = {
78743
- image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
78744
- hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
78745
- };
78746
79154
  DocxHelpers = {
78747
79155
  findRelationshipIdFromTarget,
78748
79156
  insertNewRelationship,
@@ -106109,9 +106517,9 @@ var init_remark_gfm_CjV8kaUy_es = __esm(() => {
106109
106517
  init_remark_gfm_z_sDF4ss_es();
106110
106518
  });
106111
106519
 
106112
- // ../../packages/superdoc/dist/chunks/src-BU12K8Zl.es.js
106113
- var exports_src_BU12K8Zl_es = {};
106114
- __export(exports_src_BU12K8Zl_es, {
106520
+ // ../../packages/superdoc/dist/chunks/src-Di9XuGnD.es.js
106521
+ var exports_src_Di9XuGnD_es = {};
106522
+ __export(exports_src_Di9XuGnD_es, {
106115
106523
  zt: () => defineMark,
106116
106524
  z: () => cM,
106117
106525
  yt: () => removeAwarenessStates,
@@ -128792,148 +129200,6 @@ function applyAlphaToSVG$1(svg2, alphaData) {
128792
129200
  function generateGradientId(prefix$2 = "gradient") {
128793
129201
  return `${prefix$2}-${Date.now()}-${gradientIdCounter++}-${Math.random().toString(36).substring(2, 11)}`;
128794
129202
  }
128795
- function toProtocolSet(values) {
128796
- const result = /* @__PURE__ */ new Set;
128797
- if (!values)
128798
- return result;
128799
- values.forEach((value) => {
128800
- if (typeof value === "string" && value.trim())
128801
- result.add(value.trim().toLowerCase());
128802
- });
128803
- return result;
128804
- }
128805
- function buildAllowedProtocols(config2 = {}) {
128806
- const allowed = config2.allowedProtocols?.length ? toProtocolSet(config2.allowedProtocols) : new Set(DEFAULT_ALLOWED_PROTOCOLS);
128807
- const optional = toProtocolSet(config2.optionalProtocols);
128808
- if (optional.size > 0)
128809
- optional.forEach((protocol) => {
128810
- if (OPTIONAL_PROTOCOLS.includes(protocol))
128811
- allowed.add(protocol);
128812
- });
128813
- return allowed;
128814
- }
128815
- function normalizeBlocklist(values) {
128816
- const hosts = /* @__PURE__ */ new Set;
128817
- const urls = /* @__PURE__ */ new Set;
128818
- if (!values)
128819
- return {
128820
- hosts,
128821
- urls
128822
- };
128823
- values.forEach((entry) => {
128824
- if (!entry || typeof entry !== "string")
128825
- return;
128826
- const trimmed = entry.trim().toLowerCase();
128827
- if (!trimmed)
128828
- return;
128829
- if (trimmed.includes("://"))
128830
- urls.add(trimmed);
128831
- else
128832
- hosts.add(trimmed);
128833
- });
128834
- return {
128835
- hosts,
128836
- urls
128837
- };
128838
- }
128839
- function parseAnchorLink(trimmed) {
128840
- if (!trimmed.startsWith("#"))
128841
- return null;
128842
- const anchor = trimmed.slice(1);
128843
- if (!anchor || !ANCHOR_NAME_PATTERN.test(anchor))
128844
- return null;
128845
- return {
128846
- href: `#${anchor}`,
128847
- protocol: null,
128848
- isExternal: false
128849
- };
128850
- }
128851
- function isProtocolAllowed(scheme, allowedProtocols, blockedProtocols) {
128852
- if (blockedProtocols.includes(scheme))
128853
- return false;
128854
- return allowedProtocols.has(scheme);
128855
- }
128856
- function isBlockedByRedirectList(normalizedHref, parsed, blocklist) {
128857
- const { hosts, urls } = blocklist;
128858
- const hostname2 = parsed.hostname ? parsed.hostname.toLowerCase() : "";
128859
- if (hosts.size > 0 && hostname2 && hosts.has(hostname2))
128860
- return true;
128861
- if (urls.size > 0) {
128862
- const hrefLower = normalizedHref.toLowerCase();
128863
- for (const blockedUrl of urls)
128864
- if (hrefLower.startsWith(blockedUrl))
128865
- return true;
128866
- }
128867
- return false;
128868
- }
128869
- function sanitizeHref(raw, config2 = {}) {
128870
- if (typeof raw !== "string")
128871
- return null;
128872
- const trimmed = raw.trim();
128873
- if (!trimmed)
128874
- return null;
128875
- const maxLength = typeof config2.maxLength === "number" ? config2.maxLength : DEFAULT_MAX_LENGTH;
128876
- if (trimmed.length > maxLength)
128877
- return null;
128878
- const anchorResult = parseAnchorLink(trimmed);
128879
- if (anchorResult !== null)
128880
- return anchorResult;
128881
- if (trimmed.startsWith("/") || trimmed.startsWith(".") || trimmed.startsWith("//") || /^www\./i.test(trimmed))
128882
- return null;
128883
- const schemeMatch = trimmed.match(/^([a-z0-9+.-]+):/i);
128884
- if (!schemeMatch)
128885
- return null;
128886
- const scheme = schemeMatch[1].toLowerCase();
128887
- if (!isProtocolAllowed(scheme, buildAllowedProtocols(config2), BLOCKED_PROTOCOLS.concat(config2.blockedProtocols ?? []).map((p$12) => p$12.toLowerCase())))
128888
- return null;
128889
- const hostStartIndex = trimmed.indexOf("://") + 3;
128890
- let hostEndIndex = trimmed.indexOf("/", hostStartIndex);
128891
- if (hostEndIndex === -1)
128892
- hostEndIndex = trimmed.indexOf("?", hostStartIndex);
128893
- if (hostEndIndex === -1)
128894
- hostEndIndex = trimmed.indexOf("#", hostStartIndex);
128895
- if (hostEndIndex === -1)
128896
- hostEndIndex = trimmed.length;
128897
- const rawHostname = trimmed.slice(hostStartIndex, hostEndIndex).toLowerCase();
128898
- if (rawHostname && /[^\x00-\x7F]/.test(rawHostname)) {
128899
- if (process$1.env.NODE_ENV === "development" || process$1.env.DEBUG_HYPERLINKS === "true")
128900
- console.warn(`[URL Validation] Potential homograph attack detected in hostname: ${rawHostname.slice(0, 50)}`);
128901
- }
128902
- const queryStartIndex = trimmed.indexOf("?");
128903
- if (queryStartIndex !== -1) {
128904
- const queryString = trimmed.slice(queryStartIndex);
128905
- if (/[<>"']/.test(queryString))
128906
- return null;
128907
- }
128908
- let parsed;
128909
- try {
128910
- parsed = new URL(trimmed);
128911
- } catch {
128912
- return null;
128913
- }
128914
- const normalizedHref = trimmed;
128915
- const blocklist = normalizeBlocklist(config2.redirectBlocklist);
128916
- if (isBlockedByRedirectList(normalizedHref, parsed, blocklist))
128917
- return null;
128918
- return {
128919
- href: normalizedHref,
128920
- protocol: scheme,
128921
- isExternal: scheme === "http" || scheme === "https"
128922
- };
128923
- }
128924
- function encodeTooltip(raw, maxLength = 500) {
128925
- if (typeof raw !== "string")
128926
- return null;
128927
- const trimmed = raw.trim();
128928
- if (!trimmed)
128929
- return null;
128930
- const limit = typeof maxLength === "number" && maxLength > 0 ? maxLength : 0;
128931
- const wasTruncated = limit > 0 && trimmed.length > limit;
128932
- return {
128933
- text: limit > 0 && trimmed.length > limit ? trimmed.slice(0, limit) : trimmed,
128934
- wasTruncated
128935
- };
128936
- }
128937
129203
  function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
128938
129204
  const marker = wordLayout?.marker;
128939
129205
  if (!marker)
@@ -146294,7 +146560,7 @@ function createCascadeToggleCommands({ markName, setCommand, unsetCommand, toggl
146294
146560
  [toggleName]: () => ({ commands: commands$1 }) => commands$1.toggleMarkCascade(markName, cascadeOptions)
146295
146561
  };
146296
146562
  }
146297
- function normalizeProtocols(protocols = []) {
146563
+ function normalizeProtocols2(protocols = []) {
146298
146564
  const result = [];
146299
146565
  protocols.forEach((protocol) => {
146300
146566
  if (!protocol)
@@ -146309,7 +146575,7 @@ function normalizeProtocols(protocols = []) {
146309
146575
  function sanitizeLinkHref(href, protocols) {
146310
146576
  if (!href)
146311
146577
  return null;
146312
- const normalizedProtocols = Array.isArray(protocols) ? normalizeProtocols(protocols) : [];
146578
+ const normalizedProtocols = Array.isArray(protocols) ? normalizeProtocols2(protocols) : [];
146313
146579
  return sanitizeHref(href, { allowedProtocols: Array.from(new Set([...UrlValidationConstants.DEFAULT_ALLOWED_PROTOCOLS, ...normalizedProtocols])) });
146314
146580
  }
146315
146581
  function addLinkRelationship({ editor, href }) {
@@ -153004,10 +153270,10 @@ function getItems(context, customItems = [], includeDefaultItems = true) {
153004
153270
  if (typeof SelectionType.create === "function")
153005
153271
  view.dispatch(tr.setSelection(SelectionType.create(doc$2, safeFrom, safeTo)));
153006
153272
  }
153007
- if (!(html3 ? handleClipboardPaste({
153273
+ if (!handleClipboardPaste({
153008
153274
  editor: editor$1,
153009
153275
  view
153010
- }, html3) : false)) {
153276
+ }, html3, text5)) {
153011
153277
  const pasteEvent = createPasteEventShim({
153012
153278
  html: html3,
153013
153279
  text: text5
@@ -157309,84 +157575,6 @@ var Node$13 = class Node$14 {
157309
157575
  }
157310
157576
  return state;
157311
157577
  }
157312
- }, mergeRanges = (ranges, docSize) => {
157313
- if (!ranges.length)
157314
- return [];
157315
- const sorted = ranges.map(({ from: from$12, to }) => ({
157316
- from: Math.max(0, from$12),
157317
- to: Math.min(docSize, to)
157318
- })).filter(({ from: from$12, to }) => from$12 < to).sort((a2, b$1) => a2.from - b$1.from);
157319
- const merged = [];
157320
- for (const range of sorted) {
157321
- const last2 = merged[merged.length - 1];
157322
- if (last2 && range.from <= last2.to)
157323
- last2.to = Math.max(last2.to, range.to);
157324
- else
157325
- merged.push({ ...range });
157326
- }
157327
- return merged;
157328
- }, mapRangesThroughTransactions = (ranges, transactions, docSize) => {
157329
- let mapped = ranges;
157330
- transactions.forEach((tr) => {
157331
- mapped = mapped.map(({ from: from$12, to }) => {
157332
- const mappedFrom = tr.mapping.map(from$12, -1);
157333
- const mappedTo = tr.mapping.map(to, 1);
157334
- if (mappedFrom >= mappedTo)
157335
- return null;
157336
- return {
157337
- from: mappedFrom,
157338
- to: mappedTo
157339
- };
157340
- }).filter(Boolean);
157341
- });
157342
- return mergeRanges(mapped, docSize);
157343
- }, collectChangedRangesThroughTransactions = (transactions, docSize, options = {}) => {
157344
- const ranges = [];
157345
- const extraRanges = Array.isArray(options.extraRanges) ? options.extraRanges : [];
157346
- if (extraRanges.length) {
157347
- const mappedExtras = mapRangesThroughTransactions(extraRanges, transactions, docSize);
157348
- ranges.push(...mappedExtras);
157349
- }
157350
- transactions.forEach((tr, index2) => {
157351
- if (!tr.docChanged)
157352
- return;
157353
- const perTransactionRanges = [];
157354
- tr.steps.forEach((step3) => {
157355
- if (typeof step3.from !== "number" || typeof step3.to !== "number")
157356
- return;
157357
- const from$12 = tr.mapping.map(step3.from, 1);
157358
- const to = tr.mapping.map(step3.to, -1);
157359
- if (from$12 >= to)
157360
- return;
157361
- perTransactionRanges.push({
157362
- from: from$12,
157363
- to
157364
- });
157365
- });
157366
- tr.mapping.maps.forEach((map$22) => {
157367
- map$22.forEach((oldStart, oldEnd, newStart, newEnd) => {
157368
- if (newStart !== oldStart || oldEnd !== newEnd)
157369
- perTransactionRanges.push({
157370
- from: newStart,
157371
- to: newEnd
157372
- });
157373
- });
157374
- });
157375
- if (!perTransactionRanges.length)
157376
- return;
157377
- const mapped = mapRangesThroughTransactions(perTransactionRanges, transactions.slice(index2 + 1), docSize);
157378
- ranges.push(...mapped);
157379
- });
157380
- return mergeRanges(ranges, docSize);
157381
- }, clampRange = (start$1, end$1, docSize) => {
157382
- const safeStart = Math.max(0, Math.min(start$1, docSize));
157383
- const safeEnd = Math.max(0, Math.min(end$1, docSize));
157384
- if (safeStart >= safeEnd)
157385
- return null;
157386
- return {
157387
- start: safeStart,
157388
- end: safeEnd
157389
- };
157390
157578
  }, RUN_PROPERTIES_DERIVED_FROM_MARKS, RUN_PROPERTY_PRESERVE_META_KEY = "sdPreserveRunPropertiesKeys", calculateInlineRunPropertiesPlugin = (editor) => new Plugin({ appendTransaction(transactions, _oldState, newState) {
157391
157579
  const tr = newState.tr;
157392
157580
  if (!transactions.some((t) => t.docChanged))
@@ -164592,7 +164780,7 @@ var Node$13 = class Node$14 {
164592
164780
  styleEl.textContent = NATIVE_SELECTION_STYLES;
164593
164781
  doc$2.head?.appendChild(styleEl);
164594
164782
  nativeSelectionStylesInjected = true;
164595
- }, DEFAULT_ALLOWED_PROTOCOLS, OPTIONAL_PROTOCOLS, BLOCKED_PROTOCOLS, DEFAULT_MAX_LENGTH = 2048, ANCHOR_NAME_PATTERN, UrlValidationConstants, EMUS_PER_INCH = 914400, FONT_FAMILY_FALLBACKS2, DEFAULT_GENERIC_FALLBACK2 = "sans-serif", normalizeParts = (value) => (value || "").split(",").map((part) => part.trim()).filter(Boolean), splitOutsideQuotes = (str, delimiter) => {
164783
+ }, EMUS_PER_INCH = 914400, FONT_FAMILY_FALLBACKS2, DEFAULT_GENERIC_FALLBACK2 = "sans-serif", normalizeParts = (value) => (value || "").split(",").map((part) => part.trim()).filter(Boolean), splitOutsideQuotes = (str, delimiter) => {
164596
164784
  if (!str.includes('"') && !str.includes("'"))
164597
164785
  return str.split(delimiter).map((p$12) => p$12.trim()).filter(Boolean);
164598
164786
  const parts = [];
@@ -180924,9 +181112,9 @@ var Node$13 = class Node$14 {
180924
181112
  trackedChanges: context.trackedChanges ?? []
180925
181113
  });
180926
181114
  }, _hoisted_1$6, _hoisted_2$2, _hoisted_3, _hoisted_4, ContextMenu_default, _hoisted_1$5, BasicUpload_default, _hoisted_1$4, MIN_WIDTH = 200, PPI = 96, alignment = "flex-end", Ruler_default, GenericPopover_default, _hoisted_1$3, _hoisted_2$1, RESIZE_HANDLE_WIDTH_PX = 9, RESIZE_HANDLE_HEIGHT_PX = 9, RESIZE_HANDLE_OFFSET_PX = 4, DRAG_OVERLAY_EXTENSION_PX = 1000, MIN_DRAG_OVERLAY_WIDTH_PX = 2000, THROTTLE_INTERVAL_MS = 16, MIN_RESIZE_DELTA_PX = 1, TableResizeOverlay_default, _hoisted_1$2, OVERLAY_EXPANSION_PX = 2000, RESIZE_HANDLE_SIZE_PX = 12, MOUSE_MOVE_THROTTLE_MS = 16, DIMENSION_CHANGE_THRESHOLD_PX = 1, Z_INDEX_OVERLAY = 10, Z_INDEX_HANDLE = 15, Z_INDEX_GUIDELINE = 20, ImageResizeOverlay_default, LINK_CLICK_DEBOUNCE_MS = 300, CURSOR_UPDATE_TIMEOUT_MS = 10, POPOVER_VERTICAL_OFFSET_PX = 15, LinkClickHandler_default, _hoisted_1$1, _hoisted_2, DOCX2 = "application/vnd.openxmlformats-officedocument.wordprocessingml.document", TABLE_RESIZE_HOVER_THRESHOLD = 8, TABLE_RESIZE_THROTTLE_MS = 16, SuperEditor_default, _hoisted_1, SuperInput_default, SlashMenu, Extensions;
180927
- var init_src_BU12K8Zl_es = __esm(() => {
181115
+ var init_src_Di9XuGnD_es = __esm(() => {
180928
181116
  init_rolldown_runtime_B2q5OVn9_es();
180929
- init_SuperConverter_B3_eOoDQ_es();
181117
+ init_SuperConverter_CDs2fwu4_es();
180930
181118
  init_jszip_ChlR43oI_es();
180931
181119
  init_uuid_2IzDu5nl_es();
180932
181120
  init_constants_CqvgVEDh_es();
@@ -194683,35 +194871,6 @@ function print() { __p += __j.call(arguments, '') }
194683
194871
  outline-offset: 2px;
194684
194872
  }
194685
194873
  `;
194686
- init_dist();
194687
- DEFAULT_ALLOWED_PROTOCOLS = [
194688
- "http",
194689
- "https",
194690
- "mailto",
194691
- "tel",
194692
- "sms"
194693
- ];
194694
- OPTIONAL_PROTOCOLS = [
194695
- "ftp",
194696
- "sftp",
194697
- "irc"
194698
- ];
194699
- BLOCKED_PROTOCOLS = [
194700
- "javascript",
194701
- "data",
194702
- "vbscript",
194703
- "file",
194704
- "ssh",
194705
- "ws",
194706
- "wss"
194707
- ];
194708
- ANCHOR_NAME_PATTERN = /^[A-Za-z0-9._-]+$/;
194709
- UrlValidationConstants = {
194710
- DEFAULT_ALLOWED_PROTOCOLS,
194711
- OPTIONAL_PROTOCOLS,
194712
- BLOCKED_PROTOCOLS,
194713
- DEFAULT_MAX_LENGTH
194714
- };
194715
194874
  96 / EMUS_PER_INCH;
194716
194875
  EMUS_PER_INCH / 96;
194717
194876
  FONT_FAMILY_FALLBACKS2 = Object.freeze({
@@ -212430,8 +212589,8 @@ function print() { __p += __j.call(arguments, '') }
212430
212589
  return isObjectLike_default(value) && hasOwnProperty$8.call(value, "callee") && !propertyIsEnumerable$1.call(value, "callee");
212431
212590
  };
212432
212591
  stubFalse_default = stubFalse;
212433
- freeExports$2 = typeof exports_src_BU12K8Zl_es == "object" && exports_src_BU12K8Zl_es && !exports_src_BU12K8Zl_es.nodeType && exports_src_BU12K8Zl_es;
212434
- freeModule$2 = freeExports$2 && typeof module_src_BU12K8Zl_es == "object" && module_src_BU12K8Zl_es && !module_src_BU12K8Zl_es.nodeType && module_src_BU12K8Zl_es;
212592
+ freeExports$2 = typeof exports_src_Di9XuGnD_es == "object" && exports_src_Di9XuGnD_es && !exports_src_Di9XuGnD_es.nodeType && exports_src_Di9XuGnD_es;
212593
+ freeModule$2 = freeExports$2 && typeof module_src_Di9XuGnD_es == "object" && module_src_Di9XuGnD_es && !module_src_Di9XuGnD_es.nodeType && module_src_Di9XuGnD_es;
212435
212594
  Buffer$1 = freeModule$2 && freeModule$2.exports === freeExports$2 ? _root_default.Buffer : undefined;
212436
212595
  isBuffer_default = (Buffer$1 ? Buffer$1.isBuffer : undefined) || stubFalse_default;
212437
212596
  typedArrayTags = {};
@@ -212439,8 +212598,8 @@ function print() { __p += __j.call(arguments, '') }
212439
212598
  typedArrayTags[argsTag$1] = typedArrayTags[arrayTag$1] = typedArrayTags[arrayBufferTag$1] = typedArrayTags[boolTag$1] = typedArrayTags[dataViewTag$2] = typedArrayTags[dateTag$1] = typedArrayTags[errorTag$1] = typedArrayTags[funcTag] = typedArrayTags[mapTag$2] = typedArrayTags[numberTag$1] = typedArrayTags[objectTag$3] = typedArrayTags[regexpTag$1] = typedArrayTags[setTag$2] = typedArrayTags[stringTag$1] = typedArrayTags[weakMapTag$1] = false;
212440
212599
  _baseIsTypedArray_default = baseIsTypedArray;
212441
212600
  _baseUnary_default = baseUnary;
212442
- freeExports$1 = typeof exports_src_BU12K8Zl_es == "object" && exports_src_BU12K8Zl_es && !exports_src_BU12K8Zl_es.nodeType && exports_src_BU12K8Zl_es;
212443
- freeModule$1 = freeExports$1 && typeof module_src_BU12K8Zl_es == "object" && module_src_BU12K8Zl_es && !module_src_BU12K8Zl_es.nodeType && module_src_BU12K8Zl_es;
212601
+ freeExports$1 = typeof exports_src_Di9XuGnD_es == "object" && exports_src_Di9XuGnD_es && !exports_src_Di9XuGnD_es.nodeType && exports_src_Di9XuGnD_es;
212602
+ freeModule$1 = freeExports$1 && typeof module_src_Di9XuGnD_es == "object" && module_src_Di9XuGnD_es && !module_src_Di9XuGnD_es.nodeType && module_src_Di9XuGnD_es;
212444
212603
  freeProcess = freeModule$1 && freeModule$1.exports === freeExports$1 && _freeGlobal_default.process;
212445
212604
  _nodeUtil_default = function() {
212446
212605
  try {
@@ -212545,8 +212704,8 @@ function print() { __p += __j.call(arguments, '') }
212545
212704
  Stack.prototype.has = _stackHas_default;
212546
212705
  Stack.prototype.set = _stackSet_default;
212547
212706
  _Stack_default = Stack;
212548
- freeExports = typeof exports_src_BU12K8Zl_es == "object" && exports_src_BU12K8Zl_es && !exports_src_BU12K8Zl_es.nodeType && exports_src_BU12K8Zl_es;
212549
- freeModule = freeExports && typeof module_src_BU12K8Zl_es == "object" && module_src_BU12K8Zl_es && !module_src_BU12K8Zl_es.nodeType && module_src_BU12K8Zl_es;
212707
+ freeExports = typeof exports_src_Di9XuGnD_es == "object" && exports_src_Di9XuGnD_es && !exports_src_Di9XuGnD_es.nodeType && exports_src_Di9XuGnD_es;
212708
+ freeModule = freeExports && typeof module_src_Di9XuGnD_es == "object" && module_src_Di9XuGnD_es && !module_src_Di9XuGnD_es.nodeType && module_src_Di9XuGnD_es;
212550
212709
  Buffer4 = freeModule && freeModule.exports === freeExports ? _root_default.Buffer : undefined;
212551
212710
  allocUnsafe = Buffer4 ? Buffer4.allocUnsafe : undefined;
212552
212711
  _cloneBuffer_default = cloneBuffer;
@@ -220626,8 +220785,8 @@ var init_zipper_DqXT7uTa_es = __esm(() => {
220626
220785
 
220627
220786
  // ../../packages/superdoc/dist/super-editor.es.js
220628
220787
  var init_super_editor_es = __esm(() => {
220629
- init_src_BU12K8Zl_es();
220630
- init_SuperConverter_B3_eOoDQ_es();
220788
+ init_src_Di9XuGnD_es();
220789
+ init_SuperConverter_CDs2fwu4_es();
220631
220790
  init_jszip_ChlR43oI_es();
220632
220791
  init_xml_js_DLE8mr0n_es();
220633
220792
  init_constants_CqvgVEDh_es();
@@ -240100,6 +240259,122 @@ var init_CommandService = () => {};
240100
240259
 
240101
240260
  // ../../packages/super-editor/src/core/helpers/getHTMLFromFragment.js
240102
240261
  var init_getHTMLFromFragment = () => {};
240262
+ // ../../shared/url-validation/index.js
240263
+ var init_url_validation = () => {};
240264
+
240265
+ // ../../packages/super-editor/src/core/super-converter/docx-helpers/docx-constants.js
240266
+ var RELATIONSHIP_TYPES2;
240267
+ var init_docx_constants = __esm(() => {
240268
+ RELATIONSHIP_TYPES2 = {
240269
+ image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
240270
+ hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
240271
+ };
240272
+ });
240273
+
240274
+ // ../../packages/super-editor/src/core/super-converter/docx-helpers/document-rels.js
240275
+ var getDocumentRelationshipElements2 = (editor) => {
240276
+ const docx = editor.converter?.convertedXml;
240277
+ if (!docx)
240278
+ return [];
240279
+ const documentRels = docx["word/_rels/document.xml.rels"];
240280
+ const elements = documentRels?.elements;
240281
+ if (!Array.isArray(elements))
240282
+ return [];
240283
+ const relationshipTag = elements.find((el) => el.name === "Relationships");
240284
+ return relationshipTag?.elements || [];
240285
+ }, getMaxRelationshipIdInt2 = (relationships) => {
240286
+ const ids = [];
240287
+ relationships.forEach((rel) => {
240288
+ const splitId = rel.attributes.Id.split("rId");
240289
+ const parsedInt = parseInt(splitId[1], 10);
240290
+ if (Number.isInteger(parsedInt)) {
240291
+ ids.push(parsedInt);
240292
+ }
240293
+ });
240294
+ if (ids.length === 0)
240295
+ return 0;
240296
+ return Math.max(...ids);
240297
+ }, findRelationshipIdFromTarget2 = (target, editor) => {
240298
+ if (!target)
240299
+ return null;
240300
+ if (target.startsWith("word/"))
240301
+ target = target.replace("word/", "");
240302
+ const relationships = getDocumentRelationshipElements2(editor);
240303
+ const existingLinkRel = relationships?.find((rel) => rel.attributes.Target === target);
240304
+ if (existingLinkRel) {
240305
+ return existingLinkRel.attributes.Id;
240306
+ }
240307
+ }, insertNewRelationship2 = (target, type, editor) => {
240308
+ if (!target || typeof target !== "string") {
240309
+ throw new Error("Target must be a non-empty string");
240310
+ }
240311
+ if (!type || typeof type !== "string") {
240312
+ throw new Error("Type must be a non-empty string");
240313
+ }
240314
+ if (!editor) {
240315
+ throw new Error("Editor instance is required");
240316
+ }
240317
+ const mappedType = RELATIONSHIP_TYPES2[type];
240318
+ if (!mappedType) {
240319
+ console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES2).join(", ")}`);
240320
+ return null;
240321
+ }
240322
+ const existingRelId = findRelationshipIdFromTarget2(target, editor);
240323
+ if (existingRelId) {
240324
+ console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
240325
+ return existingRelId;
240326
+ }
240327
+ const docx = editor.converter?.convertedXml;
240328
+ if (!docx) {
240329
+ console.error("No converted XML found in editor");
240330
+ return null;
240331
+ }
240332
+ const documentRels = docx["word/_rels/document.xml.rels"];
240333
+ if (!documentRels) {
240334
+ console.error("No document relationships found in the docx");
240335
+ return null;
240336
+ }
240337
+ const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
240338
+ if (!relationshipsTag) {
240339
+ console.error("No Relationships tag found in document relationships");
240340
+ return null;
240341
+ }
240342
+ if (!relationshipsTag.elements) {
240343
+ relationshipsTag.elements = [];
240344
+ }
240345
+ const newId = getNewRelationshipId2(editor);
240346
+ if (!newId) {
240347
+ console.error("Failed to generate new relationship ID");
240348
+ return null;
240349
+ }
240350
+ const newRel = {
240351
+ type: "element",
240352
+ name: "Relationship",
240353
+ attributes: {
240354
+ Id: newId,
240355
+ Type: mappedType,
240356
+ Target: target
240357
+ }
240358
+ };
240359
+ if (type === "hyperlink") {
240360
+ newRel.attributes.TargetMode = "External";
240361
+ }
240362
+ relationshipsTag.elements.push(newRel);
240363
+ return newId;
240364
+ }, getNewRelationshipId2 = (editor) => {
240365
+ const relationships = getDocumentRelationshipElements2(editor);
240366
+ const maxIdInt = getMaxRelationshipIdInt2(relationships);
240367
+ return `rId${maxIdInt + 1}`;
240368
+ };
240369
+ var init_document_rels = __esm(() => {
240370
+ init_docx_constants();
240371
+ });
240372
+ // ../../packages/super-editor/src/core/inputRules/paste-link-normalizer.js
240373
+ var init_paste_link_normalizer = __esm(() => {
240374
+ init_url_validation();
240375
+ init_document_rels();
240376
+ });
240377
+
240103
240378
  // ../../packages/super-editor/src/core/helpers/pasteListHelpers.js
240104
240379
  function getStartNumber2(lvlText) {
240105
240380
  const match2 = lvlText.match(/^(\d+)/);
@@ -264994,114 +265269,6 @@ var init_documentFootnotesImporter = __esm(() => {
264994
265269
  init_docxImporter();
264995
265270
  });
264996
265271
 
264997
- // ../../packages/super-editor/src/core/super-converter/docx-helpers/docx-constants.js
264998
- var RELATIONSHIP_TYPES2;
264999
- var init_docx_constants = __esm(() => {
265000
- RELATIONSHIP_TYPES2 = {
265001
- image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
265002
- hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
265003
- };
265004
- });
265005
-
265006
- // ../../packages/super-editor/src/core/super-converter/docx-helpers/document-rels.js
265007
- var getDocumentRelationshipElements2 = (editor) => {
265008
- const docx = editor.converter?.convertedXml;
265009
- if (!docx)
265010
- return [];
265011
- const documentRels = docx["word/_rels/document.xml.rels"];
265012
- const elements = documentRels?.elements;
265013
- if (!Array.isArray(elements))
265014
- return [];
265015
- const relationshipTag = elements.find((el) => el.name === "Relationships");
265016
- return relationshipTag?.elements || [];
265017
- }, getMaxRelationshipIdInt2 = (relationships) => {
265018
- const ids = [];
265019
- relationships.forEach((rel) => {
265020
- const splitId = rel.attributes.Id.split("rId");
265021
- const parsedInt = parseInt(splitId[1], 10);
265022
- if (Number.isInteger(parsedInt)) {
265023
- ids.push(parsedInt);
265024
- }
265025
- });
265026
- if (ids.length === 0)
265027
- return 0;
265028
- return Math.max(...ids);
265029
- }, findRelationshipIdFromTarget2 = (target, editor) => {
265030
- if (!target)
265031
- return null;
265032
- if (target.startsWith("word/"))
265033
- target = target.replace("word/", "");
265034
- const relationships = getDocumentRelationshipElements2(editor);
265035
- const existingLinkRel = relationships?.find((rel) => rel.attributes.Target === target);
265036
- if (existingLinkRel) {
265037
- return existingLinkRel.attributes.Id;
265038
- }
265039
- }, insertNewRelationship2 = (target, type, editor) => {
265040
- if (!target || typeof target !== "string") {
265041
- throw new Error("Target must be a non-empty string");
265042
- }
265043
- if (!type || typeof type !== "string") {
265044
- throw new Error("Type must be a non-empty string");
265045
- }
265046
- if (!editor) {
265047
- throw new Error("Editor instance is required");
265048
- }
265049
- const mappedType = RELATIONSHIP_TYPES2[type];
265050
- if (!mappedType) {
265051
- console.warn(`Unsupported relationship type: ${type}. Available types: ${Object.keys(RELATIONSHIP_TYPES2).join(", ")}`);
265052
- return null;
265053
- }
265054
- const existingRelId = findRelationshipIdFromTarget2(target, editor);
265055
- if (existingRelId) {
265056
- console.info(`Reusing existing relationship for target: ${target} (ID: ${existingRelId})`);
265057
- return existingRelId;
265058
- }
265059
- const docx = editor.converter?.convertedXml;
265060
- if (!docx) {
265061
- console.error("No converted XML found in editor");
265062
- return null;
265063
- }
265064
- const documentRels = docx["word/_rels/document.xml.rels"];
265065
- if (!documentRels) {
265066
- console.error("No document relationships found in the docx");
265067
- return null;
265068
- }
265069
- const relationshipsTag = documentRels.elements?.find((el) => el.name === "Relationships");
265070
- if (!relationshipsTag) {
265071
- console.error("No Relationships tag found in document relationships");
265072
- return null;
265073
- }
265074
- if (!relationshipsTag.elements) {
265075
- relationshipsTag.elements = [];
265076
- }
265077
- const newId = getNewRelationshipId2(editor);
265078
- if (!newId) {
265079
- console.error("Failed to generate new relationship ID");
265080
- return null;
265081
- }
265082
- const newRel = {
265083
- type: "element",
265084
- name: "Relationship",
265085
- attributes: {
265086
- Id: newId,
265087
- Type: mappedType,
265088
- Target: target
265089
- }
265090
- };
265091
- if (type === "hyperlink") {
265092
- newRel.attributes.TargetMode = "External";
265093
- }
265094
- relationshipsTag.elements.push(newRel);
265095
- return newId;
265096
- }, getNewRelationshipId2 = (editor) => {
265097
- const relationships = getDocumentRelationshipElements2(editor);
265098
- const maxIdInt = getMaxRelationshipIdInt2(relationships);
265099
- return `rId${maxIdInt + 1}`;
265100
- };
265101
- var init_document_rels = __esm(() => {
265102
- init_docx_constants();
265103
- });
265104
-
265105
265272
  // ../../packages/super-editor/src/core/super-converter/docx-helpers/docx-helpers.js
265106
265273
  var DocxHelpers2;
265107
265274
  var init_docx_helpers = __esm(() => {
@@ -269933,6 +270100,7 @@ var wrapTextsInRuns2 = (doc4) => {
269933
270100
  var init_docx_paste = __esm(() => {
269934
270101
  init_dist3();
269935
270102
  init_InputRule();
270103
+ init_paste_link_normalizer();
269936
270104
  init_list_numbering_helpers();
269937
270105
  init_pasteListHelpers();
269938
270106
  init_list_numbering();
@@ -269958,6 +270126,7 @@ var init_html_helpers = __esm(() => {
269958
270126
  // ../../packages/super-editor/src/core/inputRules/google-docs-paste/google-docs-paste.js
269959
270127
  var init_google_docs_paste = __esm(() => {
269960
270128
  init_InputRule();
270129
+ init_paste_link_normalizer();
269961
270130
  init_list_numbering_helpers();
269962
270131
  init_html_helpers();
269963
270132
  init_pasteListHelpers();
@@ -269997,6 +270166,7 @@ var init_InputRule = __esm(() => {
269997
270166
  init_docx_paste();
269998
270167
  init_html_helpers();
269999
270168
  init_google_docs_paste();
270169
+ init_paste_link_normalizer();
270000
270170
  });
270001
270171
 
270002
270172
  // ../../packages/super-editor/src/core/helpers/catchAllSchema.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superdoc-dev/cli",
3
- "version": "0.2.0-next.74",
3
+ "version": "0.2.0-next.75",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "superdoc": "./dist/index.js"
@@ -30,11 +30,11 @@
30
30
  "access": "public"
31
31
  },
32
32
  "optionalDependencies": {
33
- "@superdoc-dev/cli-darwin-arm64": "0.2.0-next.74",
34
- "@superdoc-dev/cli-darwin-x64": "0.2.0-next.74",
35
- "@superdoc-dev/cli-linux-x64": "0.2.0-next.74",
36
- "@superdoc-dev/cli-linux-arm64": "0.2.0-next.74",
37
- "@superdoc-dev/cli-windows-x64": "0.2.0-next.74"
33
+ "@superdoc-dev/cli-darwin-arm64": "0.2.0-next.75",
34
+ "@superdoc-dev/cli-darwin-x64": "0.2.0-next.75",
35
+ "@superdoc-dev/cli-linux-x64": "0.2.0-next.75",
36
+ "@superdoc-dev/cli-linux-arm64": "0.2.0-next.75",
37
+ "@superdoc-dev/cli-windows-x64": "0.2.0-next.75"
38
38
  },
39
39
  "scripts": {
40
40
  "dev": "bun run src/index.ts",