@harbour-enterprises/superdoc 1.8.0-next.1 → 1.8.0-next.2

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.
@@ -27535,8 +27535,9 @@ const decode$l = (params) => {
27535
27535
  if (exportedCommentDefs?.length === 0) return;
27536
27536
  if (commentsExportType === "clean") return;
27537
27537
  const commentNodeId = node.attrs["w:id"];
27538
+ const nodeIdStr = String(commentNodeId);
27538
27539
  const originalComment = comments.find((comment) => {
27539
- return comment.commentId == commentNodeId;
27540
+ return String(comment.commentId) === nodeIdStr || String(comment.importedId) === nodeIdStr;
27540
27541
  });
27541
27542
  if (!originalComment) return;
27542
27543
  const parentCommentId = originalComment.parentCommentId;
@@ -29797,284 +29798,6 @@ const DocxHelpers = {
29797
29798
  getNewRelationshipId
29798
29799
  };
29799
29800
  const kebabCase = (str) => str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
29800
- function getCrypto() {
29801
- if (typeof globalThis === "undefined") {
29802
- return void 0;
29803
- }
29804
- const cryptoObj = globalThis.crypto ?? globalThis.msCrypto;
29805
- if (cryptoObj && typeof cryptoObj.getRandomValues === "function") {
29806
- return cryptoObj;
29807
- }
29808
- return void 0;
29809
- }
29810
- function randomBytes(length) {
29811
- const array = new Uint8Array(length);
29812
- const cryptoObj = getCrypto();
29813
- if (cryptoObj) {
29814
- cryptoObj.getRandomValues(array);
29815
- return array;
29816
- }
29817
- for (let i = 0; i < length; i++) {
29818
- array[i] = Math.floor(Math.random() * 256);
29819
- }
29820
- return array;
29821
- }
29822
- class Telemetry {
29823
- /**
29824
- * Initialize telemetry service
29825
- * @param config - Telemetry configuration
29826
- */
29827
- constructor(config2) {
29828
- this.statistics = {
29829
- nodeTypes: {},
29830
- markTypes: {},
29831
- attributes: {},
29832
- errorCount: 0
29833
- };
29834
- this.unknownElements = [];
29835
- this.errors = [];
29836
- this.fileStructure = {
29837
- totalFiles: 0,
29838
- maxDepth: 0,
29839
- totalNodes: 0,
29840
- files: []
29841
- };
29842
- this.documentInfo = null;
29843
- this.enabled = config2.enabled ?? true;
29844
- this.licenseKey = config2.licenseKey ?? Telemetry.COMMUNITY_LICENSE_KEY;
29845
- this.endpoint = config2.endpoint ?? Telemetry.DEFAULT_ENDPOINT;
29846
- this.documentGuid = config2.documentGuid;
29847
- this.documentIdentifier = config2.documentIdentifier;
29848
- this.superdocVersion = config2.superdocVersion;
29849
- this.sessionId = this.generateId();
29850
- }
29851
- static {
29852
- this.COMMUNITY_LICENSE_KEY = "community-and-eval-agplv3";
29853
- }
29854
- static {
29855
- this.DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
29856
- }
29857
- /**
29858
- * Get browser environment information
29859
- * @returns Browser information
29860
- */
29861
- getBrowserInfo() {
29862
- return {
29863
- userAgent: window.navigator.userAgent,
29864
- currentUrl: window.location.href,
29865
- hostname: window.location.hostname,
29866
- referrerUrl: document.referrer,
29867
- screenSize: {
29868
- width: window.screen.width,
29869
- height: window.screen.height
29870
- }
29871
- };
29872
- }
29873
- /**
29874
- * Track document usage event
29875
- * @param name - Event name (use TelemetryEventNames for standard events)
29876
- * @param properties - Additional properties
29877
- */
29878
- async trackUsage(name, properties = {}) {
29879
- if (!this.enabled) return;
29880
- const event = {
29881
- id: this.generateId(),
29882
- type: "usage",
29883
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
29884
- sessionId: this.sessionId,
29885
- documentGuid: this.documentGuid,
29886
- // Updated field name
29887
- documentIdentifier: this.documentIdentifier,
29888
- // Include both
29889
- superdocVersion: this.superdocVersion,
29890
- file: this.documentInfo,
29891
- browser: this.getBrowserInfo(),
29892
- name,
29893
- properties
29894
- };
29895
- await this.sendDataToTelemetry(event);
29896
- }
29897
- trackStatistic(categoryOrData, legacyData) {
29898
- let data;
29899
- if (typeof categoryOrData === "string") {
29900
- data = { ...legacyData, category: categoryOrData };
29901
- } else {
29902
- data = categoryOrData;
29903
- }
29904
- if (data.category === "node") {
29905
- this.statistics.nodeTypes[data.elementName] = (this.statistics.nodeTypes[data.elementName] || 0) + 1;
29906
- this.fileStructure.totalNodes++;
29907
- } else if (data.category === "unknown") {
29908
- const addedElement = this.unknownElements.find((e) => e.elementName === data.elementName);
29909
- if (addedElement) {
29910
- addedElement.count += 1;
29911
- addedElement.attributes = {
29912
- ...addedElement.attributes,
29913
- ...data.attributes
29914
- };
29915
- } else {
29916
- this.unknownElements.push({
29917
- elementName: data.elementName,
29918
- count: 1,
29919
- attributes: data.attributes
29920
- });
29921
- }
29922
- } else if (data.category === "error") {
29923
- this.errors.push(data);
29924
- this.statistics.errorCount++;
29925
- }
29926
- if (data.category === "node" && data.marks?.length) {
29927
- data.marks.forEach((mark) => {
29928
- this.statistics.markTypes[mark.type] = (this.statistics.markTypes[mark.type] || 0) + 1;
29929
- });
29930
- }
29931
- if (data.attributes && Object.keys(data.attributes).length) {
29932
- const styleAttributes = [
29933
- "textIndent",
29934
- "textAlign",
29935
- "spacing",
29936
- "lineHeight",
29937
- "indent",
29938
- "list-style-type",
29939
- "listLevel",
29940
- "textStyle",
29941
- "order",
29942
- "lvlText",
29943
- "lvlJc",
29944
- "listNumberingType",
29945
- "numId"
29946
- ];
29947
- Object.keys(data.attributes).forEach((attribute) => {
29948
- if (!styleAttributes.includes(attribute)) return;
29949
- this.statistics.attributes[attribute] = (this.statistics.attributes[attribute] || 0) + 1;
29950
- });
29951
- }
29952
- }
29953
- /**
29954
- * Track file structure
29955
- * @param structure - File structure information
29956
- * @param fileSource - original file
29957
- * @param documentId - document GUID
29958
- * @param documentIdentifier - document identifier (GUID or hash)
29959
- * @param internalId - document ID from settings.xml
29960
- */
29961
- async trackFileStructure(structure, fileSource, documentId, documentIdentifier, internalId) {
29962
- this.fileStructure = structure;
29963
- this.documentInfo = await this.processDocument(fileSource, {
29964
- guid: documentId,
29965
- // Updated parameter name
29966
- identifier: documentIdentifier,
29967
- // New parameter
29968
- internalId
29969
- });
29970
- }
29971
- /**
29972
- * Process document metadata
29973
- * @param file - Document file
29974
- * @param options - Additional options
29975
- * @returns Document metadata
29976
- */
29977
- async processDocument(file, options = {}) {
29978
- if (!file) {
29979
- console.warn("Telemetry: missing file source");
29980
- return null;
29981
- }
29982
- return {
29983
- guid: options.guid,
29984
- // Updated from 'id'
29985
- identifier: options.identifier,
29986
- // New field
29987
- name: file.name,
29988
- size: file.size,
29989
- lastModified: file.lastModified ? new Date(file.lastModified).toISOString() : null,
29990
- type: file.type || "docx",
29991
- internalId: options.internalId
29992
- // Microsoft's GUID if present
29993
- };
29994
- }
29995
- isTelemetryDataChanged() {
29996
- if (Object.keys(this.statistics.nodeTypes).length <= 1) return false;
29997
- return Object.keys(this.statistics.nodeTypes).length > 0 || Object.keys(this.statistics.markTypes).length > 0 || Object.keys(this.statistics.attributes).length > 0 || this.statistics.errorCount > 0 || this.fileStructure.totalFiles > 0 || this.fileStructure.maxDepth > 0 || this.fileStructure.totalNodes > 0 || this.fileStructure.files.length > 0 || this.errors.length > 0 || this.unknownElements.length > 0;
29998
- }
29999
- /**
30000
- * Sends current report
30001
- * @returns Promise that resolves when report is sent
30002
- */
30003
- async sendReport() {
30004
- if (!this.enabled || !this.isTelemetryDataChanged()) return;
30005
- const report = [
30006
- {
30007
- id: this.generateId(),
30008
- type: "parsing",
30009
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
30010
- sessionId: this.sessionId,
30011
- documentGuid: this.documentGuid,
30012
- documentIdentifier: this.documentIdentifier,
30013
- superdocVersion: this.superdocVersion,
30014
- file: this.documentInfo,
30015
- browser: this.getBrowserInfo(),
30016
- statistics: this.statistics,
30017
- fileStructure: this.fileStructure,
30018
- unknownElements: this.unknownElements,
30019
- errors: this.errors
30020
- }
30021
- ];
30022
- await this.sendDataToTelemetry(report);
30023
- }
30024
- /**
30025
- * Sends data to the service
30026
- * @param data - Payload to send
30027
- * @returns Promise that resolves when data is sent
30028
- */
30029
- async sendDataToTelemetry(data) {
30030
- try {
30031
- const response = await fetch(this.endpoint, {
30032
- method: "POST",
30033
- headers: {
30034
- "Content-Type": "application/json",
30035
- "X-License-Key": this.licenseKey
30036
- },
30037
- body: JSON.stringify(data)
30038
- });
30039
- if (!response.ok) {
30040
- throw new Error(`Upload failed: ${response.statusText}`);
30041
- } else {
30042
- this.resetStatistics();
30043
- }
30044
- } catch (error) {
30045
- console.error("Failed to upload telemetry:", error);
30046
- }
30047
- }
30048
- /**
30049
- * Generate unique identifier
30050
- * @returns Unique ID
30051
- * @private
30052
- */
30053
- generateId() {
30054
- const timestamp = Date.now();
30055
- const random = Array.from(randomBytes(4)).map((b2) => b2.toString(16).padStart(2, "0")).join("");
30056
- return `${timestamp}-${random}`;
30057
- }
30058
- /**
30059
- * Reset statistics
30060
- */
30061
- resetStatistics() {
30062
- this.statistics = {
30063
- nodeTypes: {},
30064
- markTypes: {},
30065
- attributes: {},
30066
- errorCount: 0
30067
- };
30068
- this.fileStructure = {
30069
- totalFiles: 0,
30070
- maxDepth: 0,
30071
- totalNodes: 0,
30072
- files: []
30073
- };
30074
- this.unknownElements = [];
30075
- this.errors = [];
30076
- }
30077
- }
30078
29801
  const getDefaultStyleDefinition = (defaultStyleId, docx) => {
30079
29802
  const result = { lineSpaceBefore: null, lineSpaceAfter: null };
30080
29803
  if (!defaultStyleId) return result;
@@ -30245,38 +29968,6 @@ const createDocumentJson = (docx, converter, editor) => {
30245
29968
  converter.documentOrigin = detectDocumentOrigin(docx);
30246
29969
  converter.commentThreadingProfile = detectCommentThreadingProfile(docx);
30247
29970
  }
30248
- if (converter?.telemetry) {
30249
- const files = Object.keys(docx).map((filePath) => {
30250
- const parts = filePath.split("/");
30251
- return {
30252
- filePath,
30253
- fileDepth: parts.length,
30254
- fileType: filePath.split(".").pop()
30255
- };
30256
- });
30257
- const trackStructure = (documentIdentifier = null) => converter.telemetry.trackFileStructure(
30258
- {
30259
- totalFiles: files.length,
30260
- maxDepth: Math.max(...files.map((f) => f.fileDepth)),
30261
- totalNodes: 0,
30262
- files
30263
- },
30264
- converter.fileSource,
30265
- converter.documentGuid ?? converter.documentId ?? null,
30266
- documentIdentifier ?? converter.documentId ?? null,
30267
- converter.documentInternalId
30268
- );
30269
- try {
30270
- const identifierResult = converter.getDocumentIdentifier?.();
30271
- if (identifierResult && typeof identifierResult.then === "function") {
30272
- identifierResult.then(trackStructure).catch(() => trackStructure());
30273
- } else {
30274
- trackStructure(identifierResult);
30275
- }
30276
- } catch {
30277
- trackStructure();
30278
- }
30279
- }
30280
29971
  const nodeListHandler = defaultNodeListHandler();
30281
29972
  const bodyNode = json.elements[0].elements.find((el) => el.name === "w:body");
30282
29973
  if (bodyNode) {
@@ -30319,12 +30010,6 @@ const createDocumentJson = (docx, converter, editor) => {
30319
30010
  ...bodySectPr ? { bodySectPr } : {}
30320
30011
  }
30321
30012
  };
30322
- if (result.content.length > 1) {
30323
- converter?.telemetry?.trackUsage("document_import", {
30324
- documentType: "docx",
30325
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
30326
- });
30327
- }
30328
30013
  return {
30329
30014
  pmDoc: result,
30330
30015
  savedTagsToRestore: node,
@@ -30447,16 +30132,8 @@ const createNodeListHandler = (nodeHandlers) => {
30447
30132
  );
30448
30133
  if (unhandled) {
30449
30134
  if (!context.elementName) continue;
30450
- converter?.telemetry?.trackStatistic("unknown", context);
30451
30135
  continue;
30452
30136
  } else {
30453
- converter?.telemetry?.trackStatistic("node", context);
30454
- if (context.type === "orderedList" || context.type === "bulletList") {
30455
- context.content.forEach((item) => {
30456
- const innerItemContext = getSafeElementContext([item], 0, item, `/word/${filename || "document.xml"}`);
30457
- converter?.telemetry?.trackStatistic("attributes", innerItemContext);
30458
- });
30459
- }
30460
30137
  const hasHighlightMark = nodes[0]?.marks?.find((mark) => mark.type === "highlight");
30461
30138
  if (hasHighlightMark) {
30462
30139
  converter?.docHiglightColors.add(hasHighlightMark.attrs.color.toUpperCase());
@@ -30478,26 +30155,12 @@ const createNodeListHandler = (nodeHandlers) => {
30478
30155
  } catch (error) {
30479
30156
  console.debug("Import error", error);
30480
30157
  editor?.emit("exception", { error, editor });
30481
- converter?.telemetry?.trackStatistic("error", {
30482
- type: "processing_error",
30483
- message: error.message,
30484
- name: error.name,
30485
- stack: error.stack,
30486
- fileName: `/word/${filename || "document.xml"}`
30487
- });
30488
30158
  }
30489
30159
  }
30490
30160
  return processedElements;
30491
30161
  } catch (error) {
30492
30162
  console.debug("Error during import", error);
30493
30163
  editor?.emit("exception", { error, editor });
30494
- converter?.telemetry?.trackStatistic("error", {
30495
- type: "fatal_error",
30496
- message: error.message,
30497
- name: error.name,
30498
- stack: error.stack,
30499
- fileName: `/word/${filename || "document.xml"}`
30500
- });
30501
30164
  throw error;
30502
30165
  }
30503
30166
  };
@@ -32907,7 +32570,6 @@ class SuperConverter {
32907
32570
  this.json = params?.json;
32908
32571
  this.tagsNotInSchema = ["w:body"];
32909
32572
  this.savedTagsToRestore = [];
32910
- this.telemetry = params?.telemetry || null;
32911
32573
  this.documentInternalId = null;
32912
32574
  this.fileSource = params?.fileSource || null;
32913
32575
  this.documentId = params?.documentId || null;
@@ -33200,7 +32862,7 @@ class SuperConverter {
33200
32862
  static getStoredSuperdocVersion(docx) {
33201
32863
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
33202
32864
  }
33203
- static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.8.0-next.1") {
32865
+ static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.8.0-next.2") {
33204
32866
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version, false);
33205
32867
  }
33206
32868
  /**
@@ -33267,7 +32929,7 @@ class SuperConverter {
33267
32929
  return null;
33268
32930
  }
33269
32931
  /**
33270
- * Generate document hash for telemetry (async, lazy)
32932
+ * Generate document hash (async, lazy)
33271
32933
  */
33272
32934
  async #generateDocumentHash() {
33273
32935
  if (!this.fileSource) return `HASH-${Date.now()}`;