@getguru/import-engine 0.1.2 → 0.1.4

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/docx-import-cli.js +151 -7
  2. package/package.json +1 -1
@@ -98755,6 +98755,34 @@ var importType = typeArgIndex !== -1 ? process.argv[typeArgIndex + 1] : "";
98755
98755
  var dom = new import_jsdom.JSDOM("", {
98756
98756
  url: `http://localhost:8000/docx-import/index.html?type=${importType}&embed=`
98757
98757
  });
98758
+ var UNUSED_INPUT_EVENTS = /* @__PURE__ */ new Set([
98759
+ "focus",
98760
+ "focusin",
98761
+ "keydown",
98762
+ "keyup",
98763
+ "mouseover",
98764
+ "mousedown",
98765
+ "mouseup",
98766
+ "click",
98767
+ "mouseout"
98768
+ ]);
98769
+ var addWindowListener = dom.window.addEventListener;
98770
+ dom.window.addEventListener = function(type2, ...rest2) {
98771
+ if (UNUSED_INPUT_EVENTS.has(type2)) {
98772
+ return void 0;
98773
+ }
98774
+ return addWindowListener.call(this, type2, ...rest2);
98775
+ };
98776
+ var windowProperties = require("jsdom/lib/jsdom/living/window-properties.js");
98777
+ for (const hook of ["elementAttached", "elementDetached", "elementAttributeModified"]) {
98778
+ const track = windowProperties[hook];
98779
+ windowProperties[hook] = function(element, ...rest2) {
98780
+ if (!element._ownerDocument._defaultView) {
98781
+ return void 0;
98782
+ }
98783
+ return track.call(this, element, ...rest2);
98784
+ };
98785
+ }
98758
98786
  var ALLOWED_GLOBALS = [
98759
98787
  "window",
98760
98788
  "document",
@@ -102636,6 +102664,52 @@ function markLinkRecorded(doc, link2) {
102636
102664
  function isLinkRecorded(doc, link2) {
102637
102665
  return !!doc.recordedLinks && doc.recordedLinks.has(link2);
102638
102666
  }
102667
+ var RECORDED_LINK_ATTRIBUTE = "data-guru-import-recorded-link";
102668
+ function serializeDoctype(doctype) {
102669
+ if (!doctype) {
102670
+ return "";
102671
+ }
102672
+ const quote = (id) => id.includes('"') ? `'${id}'` : `"${id}"`;
102673
+ if (doctype.publicId) {
102674
+ return `<!DOCTYPE ${doctype.name} PUBLIC ${quote(doctype.publicId)}${doctype.systemId ? " " + quote(doctype.systemId) : ""}>`;
102675
+ }
102676
+ if (doctype.systemId) {
102677
+ return `<!DOCTYPE ${doctype.name} SYSTEM ${quote(doctype.systemId)}>`;
102678
+ }
102679
+ return `<!DOCTYPE ${doctype.name}>`;
102680
+ }
102681
+ function serializeDocTree(div, doc) {
102682
+ for (const element of div.querySelectorAll("pre, textarea, listing")) {
102683
+ const first2 = element.firstChild;
102684
+ if (first2 && first2.nodeType === 3 && first2.data.startsWith("\n")) {
102685
+ first2.data = "\n" + first2.data;
102686
+ }
102687
+ }
102688
+ if (doc.recordedLinks) {
102689
+ for (const element of div.querySelectorAll("*")) {
102690
+ if (doc.recordedLinks.has(element)) {
102691
+ element.setAttribute(RECORDED_LINK_ATTRIBUTE, "");
102692
+ }
102693
+ }
102694
+ }
102695
+ return flattenString(serializeDoctype(div.ownerDocument.doctype) + div.outerHTML);
102696
+ }
102697
+ function flattenString(string) {
102698
+ string.charCodeAt(0);
102699
+ return string;
102700
+ }
102701
+ function parseDocTree(source, doc) {
102702
+ const div = new DOMParser().parseFromString(source, "text/html").documentElement;
102703
+ const hadRecordedLinks = !!doc.recordedLinks;
102704
+ delete doc.recordedLinks;
102705
+ if (hadRecordedLinks) {
102706
+ for (const element of div.querySelectorAll(`[${RECORDED_LINK_ATTRIBUTE}]`)) {
102707
+ element.removeAttribute(RECORDED_LINK_ATTRIBUTE);
102708
+ markLinkRecorded(doc, element);
102709
+ }
102710
+ }
102711
+ return div;
102712
+ }
102639
102713
  function safeDecode(string) {
102640
102714
  try {
102641
102715
  return decodeURIComponent(string);
@@ -108438,6 +108512,12 @@ var card_schema_default = {
108438
108512
  strikethrough: {
108439
108513
  type: "boolean"
108440
108514
  },
108515
+ superscript: {
108516
+ type: "boolean"
108517
+ },
108518
+ subscript: {
108519
+ type: "boolean"
108520
+ },
108441
108521
  underline: {
108442
108522
  type: "boolean"
108443
108523
  },
@@ -111340,11 +111420,17 @@ function buildSlabPostSlugIndex(allDocs, zip) {
111340
111420
  }
111341
111421
  return index;
111342
111422
  }
111423
+ function getSlabPostSlugIndex(zip, allDocs) {
111424
+ if (!zip.slabPostSlugIndex) {
111425
+ zip.slabPostSlugIndex = buildSlabPostSlugIndex(allDocs, zip);
111426
+ }
111427
+ return zip.slabPostSlugIndex;
111428
+ }
111343
111429
  function resolveSlabPostLinks(div, doc, allDocs) {
111344
111430
  if (!doc.zip?.isSlabExport) {
111345
111431
  return;
111346
111432
  }
111347
- const index = buildSlabPostSlugIndex(allDocs, doc.zip);
111433
+ const index = getSlabPostSlugIndex(doc.zip, allDocs);
111348
111434
  Array.from(div.querySelectorAll("a[href]")).forEach((link2) => {
111349
111435
  const href = link2.getAttribute("href");
111350
111436
  if (!href || SLAB_TOPIC_URL_PATTERN.test(href)) {
@@ -111445,6 +111531,32 @@ var STYLE_ATTRIBUTES_TO_KEEP = [
111445
111531
  "text-align",
111446
111532
  "text-decoration"
111447
111533
  ];
111534
+ var VERTICAL_ALIGN_BLOCK_SELECTOR = "p, div, h1, h2, h3, h4, h5, h6, ul, ol, li, table, blockquote, pre";
111535
+ function convertVerticalAlignToTags(root2) {
111536
+ Array.from(root2.querySelectorAll("[style]")).forEach(function(el) {
111537
+ if (el.closest(".ghq-card-content__markdown")) {
111538
+ return;
111539
+ }
111540
+ const values2 = parseStyleString(el.getAttribute("style"));
111541
+ const key = Object.keys(values2).find((k) => k.toLowerCase() === "vertical-align");
111542
+ if (!key) {
111543
+ return;
111544
+ }
111545
+ const value = values2[key].replace(/!\s*important\s*$/i, "").trim().toLowerCase();
111546
+ if (value !== "super" && value !== "sub") {
111547
+ return;
111548
+ }
111549
+ const tagName = value === "super" ? "sup" : "sub";
111550
+ if (el.closest(tagName) || !el.textContent.trim() && !el.firstElementChild || el.querySelector(VERTICAL_ALIGN_BLOCK_SELECTOR)) {
111551
+ return;
111552
+ }
111553
+ const tag = el.ownerDocument.createElement(tagName);
111554
+ while (el.firstChild) {
111555
+ tag.appendChild(el.firstChild);
111556
+ }
111557
+ el.appendChild(tag);
111558
+ });
111559
+ }
111448
111560
  function parseStyleString(text2) {
111449
111561
  const result3 = {};
111450
111562
  const pairs3 = text2.split(";");
@@ -112030,6 +112142,7 @@ function cleanUpHtml(element, doc = {}) {
112030
112142
  );
112031
112143
  }
112032
112144
  });
112145
+ convertVerticalAlignToTags(element);
112033
112146
  Array.from(element.querySelectorAll("[style]")).forEach(function(element2) {
112034
112147
  if (element2.closest(".ghq-card-content__markdown")) {
112035
112148
  return;
@@ -114320,7 +114433,7 @@ var import_jszip5 = __toESM(require_lib3());
114320
114433
  var import_url_join6 = __toESM(require_url_join());
114321
114434
 
114322
114435
  // packages/import-engine/package.json
114323
- var version = "0.1.2";
114436
+ var version = "0.1.4";
114324
114437
 
114325
114438
  // src/docx-import/detectors.js
114326
114439
  function isGoogleSitesDoc(div) {
@@ -114344,7 +114457,7 @@ var showError;
114344
114457
  var updateLoader;
114345
114458
  var showReport;
114346
114459
  var docLinkIndex = /* @__PURE__ */ new Map();
114347
- var toolVersion = true ? `${version}+${"4d61d22"}` : version;
114460
+ var toolVersion = true ? `${version}+${"b8fcb63"}` : version;
114348
114461
  var pendingUpload = null;
114349
114462
  function confirmPendingUpload() {
114350
114463
  const upload = pendingUpload;
@@ -114508,6 +114621,21 @@ async function processImage(doc, image2, imageIndex, newZip, resourceLookup = {}
114508
114621
  }
114509
114622
  });
114510
114623
  }
114624
+ var resourceLookupSizes = /* @__PURE__ */ new WeakMap();
114625
+ function getResourceLookupSize(resourceLookup) {
114626
+ if (!resourceLookupSizes.has(resourceLookup)) {
114627
+ resourceLookupSizes.set(resourceLookup, Object.keys(resourceLookup).length);
114628
+ }
114629
+ return resourceLookupSizes.get(resourceLookup);
114630
+ }
114631
+ function addToResourceLookup(resourceLookup, unsafeResourceName, safeResourceName) {
114632
+ const size2 = getResourceLookupSize(resourceLookup);
114633
+ const isNewKey = !Object.hasOwn(resourceLookup, unsafeResourceName);
114634
+ resourceLookup[unsafeResourceName] = safeResourceName;
114635
+ if (isNewKey && Object.hasOwn(resourceLookup, unsafeResourceName)) {
114636
+ resourceLookupSizes.set(resourceLookup, size2 + 1);
114637
+ }
114638
+ }
114511
114639
  async function resolveResource(element, doc, newZip, resourceLookup = {}) {
114512
114640
  return new Promise(async function(resolve, reject2) {
114513
114641
  try {
@@ -114536,10 +114664,10 @@ async function resolveResource(element, doc, newZip, resourceLookup = {}) {
114536
114664
  } else {
114537
114665
  safeResourceName = sanitizeFilename(unsafeResourceName);
114538
114666
  if (safeResourceName !== unsafeResourceName) {
114539
- const nextIndex = Object.keys(resourceLookup).length;
114667
+ const nextIndex = getResourceLookupSize(resourceLookup);
114540
114668
  safeResourceName = `file${nextIndex}_${safeResourceName}`;
114541
114669
  }
114542
- resourceLookup[unsafeResourceName] = safeResourceName;
114670
+ addToResourceLookup(resourceLookup, unsafeResourceName, safeResourceName);
114543
114671
  }
114544
114672
  const resourcePath = "resources/" + safeResourceName;
114545
114673
  const fileData = await (import_jszip5.default.support.uint8array ? file.async("uint8array") : file.async("base64"));
@@ -114774,7 +114902,7 @@ async function preProcessDoc(doc, docTitleLookup = {}) {
114774
114902
  doc.zip.source = source;
114775
114903
  }
114776
114904
  }
114777
- doc.htmlContent = div;
114905
+ doc.htmlSource = serializeDocTree(div, doc);
114778
114906
  updateLoader({
114779
114907
  step: 1,
114780
114908
  docIndex: doc.index,
@@ -114805,7 +114933,8 @@ async function postProcessDoc(newZip, doc, resourceLookup = {}, externalLookup =
114805
114933
  writeCardToZip(newZip, doc, "");
114806
114934
  return;
114807
114935
  }
114808
- const div = doc.htmlContent;
114936
+ const div = parseDocTree(doc.htmlSource, doc);
114937
+ delete doc.htmlSource;
114809
114938
  updateLoader({
114810
114939
  step: 1,
114811
114940
  docIndex: doc.index,
@@ -114874,6 +115003,14 @@ async function postProcessDoc(newZip, doc, resourceLookup = {}, externalLookup =
114874
115003
  }
114875
115004
  writeCardToZip(newZip, doc, cleanUpHtml(div, doc));
114876
115005
  }
115006
+ function releaseDocContent(doc, buffersReadFromZip) {
115007
+ delete doc.htmlSource;
115008
+ delete doc.originalContent;
115009
+ delete doc.recordedLinks;
115010
+ if (buffersReadFromZip.has(doc)) {
115011
+ delete doc.buffer;
115012
+ }
115013
+ }
114877
115014
  function makeErrorHandler(progress) {
114878
115015
  return function handleError(event) {
114879
115016
  const message = event.reason?.message || event.message || event.error?.message || "Unknown error";
@@ -114957,6 +115094,7 @@ async function runProcessDocs(params, progress) {
114957
115094
  zipToCheck.docxAnchorIndex = buildDocxAnchorIndex(docs, zipToCheck);
114958
115095
  }
114959
115096
  }
115097
+ const buffersReadFromZip = /* @__PURE__ */ new WeakSet();
114960
115098
  await doAll(docs, async function(doc, docIndex, nextDoc) {
114961
115099
  doc.index = docIndex;
114962
115100
  try {
@@ -114965,6 +115103,7 @@ async function runProcessDocs(params, progress) {
114965
115103
  } else if (doc.zip) {
114966
115104
  const buffer = await doc.zip.file(doc.filename).async("arraybuffer");
114967
115105
  doc.buffer = buffer;
115106
+ buffersReadFromZip.add(doc);
114968
115107
  await preProcessDoc(doc, docTitleLookup);
114969
115108
  } else {
114970
115109
  await preProcessDoc(doc);
@@ -114972,6 +115111,7 @@ async function runProcessDocs(params, progress) {
114972
115111
  } catch (err) {
114973
115112
  recordFailure(doc, err);
114974
115113
  } finally {
115114
+ delete doc.div;
114975
115115
  nextDoc();
114976
115116
  }
114977
115117
  });
@@ -114981,6 +115121,9 @@ async function runProcessDocs(params, progress) {
114981
115121
  if (zipToCheck.source === "confluence") {
114982
115122
  zipToCheck.confluencePageIndex = buildConfluencePageIndex(docs, zipToCheck);
114983
115123
  }
115124
+ if (zipToCheck.isSlabExport) {
115125
+ zipToCheck.slabPostSlugIndex = buildSlabPostSlugIndex(docs, zipToCheck);
115126
+ }
114984
115127
  }
114985
115128
  await doAll(docs, async function(doc, docIndex, nextDoc) {
114986
115129
  try {
@@ -114988,6 +115131,7 @@ async function runProcessDocs(params, progress) {
114988
115131
  } catch (err) {
114989
115132
  recordFailure(doc, err);
114990
115133
  } finally {
115134
+ releaseDocContent(doc, buffersReadFromZip);
114991
115135
  nextDoc();
114992
115136
  }
114993
115137
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getguru/import-engine",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Command-line engine that turns Notion, Confluence, Google, Word, PDF, Markdown and spreadsheet exports into Guru import zips.",
5
5
  "bin": {
6
6
  "guru-import-engine": "docx-import-cli.js"