n8n-nodes-docx-track-changes 0.1.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.
- package/LICENSE +21 -0
- package/README.ja.md +252 -0
- package/README.md +252 -0
- package/dist/nodes/DocxRevisions/DocxRevisions.node.d.ts +5 -0
- package/dist/nodes/DocxRevisions/DocxRevisions.node.js +151 -0
- package/dist/nodes/DocxRevisions/DocxRevisions.node.js.map +1 -0
- package/dist/nodes/DocxRevisions/DocxRevisions.node.json +13 -0
- package/dist/nodes/DocxRevisions/docxRevisions.svg +9 -0
- package/dist/nodes/DocxRevisions/operations/extractComments.d.ts +2 -0
- package/dist/nodes/DocxRevisions/operations/extractComments.js +39 -0
- package/dist/nodes/DocxRevisions/operations/extractComments.js.map +1 -0
- package/dist/nodes/DocxRevisions/operations/extractRevisions.d.ts +2 -0
- package/dist/nodes/DocxRevisions/operations/extractRevisions.js +43 -0
- package/dist/nodes/DocxRevisions/operations/extractRevisions.js.map +1 -0
- package/dist/nodes/DocxRevisions/utils/commentParser.d.ts +28 -0
- package/dist/nodes/DocxRevisions/utils/commentParser.js +208 -0
- package/dist/nodes/DocxRevisions/utils/commentParser.js.map +1 -0
- package/dist/nodes/DocxRevisions/utils/docxParser.d.ts +10 -0
- package/dist/nodes/DocxRevisions/utils/docxParser.js +50 -0
- package/dist/nodes/DocxRevisions/utils/docxParser.js.map +1 -0
- package/dist/nodes/DocxRevisions/utils/revisionParser.d.ts +23 -0
- package/dist/nodes/DocxRevisions/utils/revisionParser.js +217 -0
- package/dist/nodes/DocxRevisions/utils/revisionParser.js.map +1 -0
- package/dist/package.json +52 -0
- package/package.json +66 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-docx-track-changes.docxRevisions",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": ["Data & Storage", "Productivity"],
|
|
6
|
+
"resources": {
|
|
7
|
+
"primaryDocumentation": [
|
|
8
|
+
{
|
|
9
|
+
"url": "https://github.com/ryoooo/n8n-nodes-docx-track-changes#readme"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48">
|
|
2
|
+
<rect x="8" y="4" width="32" height="40" rx="2" fill="#2B579A"/>
|
|
3
|
+
<rect x="12" y="12" width="24" height="2" fill="#fff"/>
|
|
4
|
+
<rect x="12" y="18" width="20" height="2" fill="#fff"/>
|
|
5
|
+
<rect x="12" y="24" width="22" height="2" fill="#fff"/>
|
|
6
|
+
<rect x="12" y="30" width="18" height="2" fill="#fff"/>
|
|
7
|
+
<path d="M30 34 L38 34 L38 42 L30 42 Z" fill="#4CAF50"/>
|
|
8
|
+
<path d="M32 38 L34 40 L37 36" stroke="#fff" stroke-width="1.5" fill="none"/>
|
|
9
|
+
</svg>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractComments = extractComments;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const docxParser_1 = require("../utils/docxParser");
|
|
6
|
+
const commentParser_1 = require("../utils/commentParser");
|
|
7
|
+
async function extractComments(itemIndex) {
|
|
8
|
+
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex);
|
|
9
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
10
|
+
const includeResolved = options.includeResolved ?? true;
|
|
11
|
+
const includeSummary = options.includeSummary ?? true;
|
|
12
|
+
const item = this.getInputData()[itemIndex];
|
|
13
|
+
if (!item.binary || !item.binary[binaryPropertyName]) {
|
|
14
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No binary data found in property "${binaryPropertyName}"`, { itemIndex });
|
|
15
|
+
}
|
|
16
|
+
const buffer = await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
|
|
17
|
+
let docxFiles;
|
|
18
|
+
try {
|
|
19
|
+
docxFiles = await (0, docxParser_1.parseDocx)(buffer);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (error instanceof docxParser_1.InvalidFileFormatError) {
|
|
23
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex });
|
|
24
|
+
}
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
const comments = (0, commentParser_1.parseComments)(docxFiles.comments, docxFiles.commentsExtended, docxFiles.document, {
|
|
28
|
+
includeReplies: true,
|
|
29
|
+
includeResolved,
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
json: {
|
|
33
|
+
comments,
|
|
34
|
+
summary: includeSummary ? (0, commentParser_1.generateCommentSummary)(comments) : null,
|
|
35
|
+
},
|
|
36
|
+
pairedItem: { item: itemIndex },
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=extractComments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractComments.js","sourceRoot":"","sources":["../../../../nodes/DocxRevisions/operations/extractComments.ts"],"names":[],"mappings":";;AAKA,0CAoDC;AAxDD,+CAAkD;AAClD,oDAAwE;AACxE,0DAA+E;AAExE,KAAK,UAAU,eAAe,CAEpC,SAAiB;IAEjB,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,SAAS,CAAW,CAAC;IAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,CAG7D,CAAC;IAEF,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC;IACxD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;IAEtD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC;IAE5C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,iCAAkB,CAC3B,IAAI,CAAC,OAAO,EAAE,EACd,qCAAqC,kBAAkB,GAAG,EAC1D,EAAE,SAAS,EAAE,CACb,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAErF,IAAI,SAAS,CAAC;IACd,IAAI,CAAC;QACJ,SAAS,GAAG,MAAM,IAAA,sBAAS,EAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,mCAAsB,EAAE,CAAC;YAC7C,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,6BAAa,EAC7B,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,gBAAgB,EAC1B,SAAS,CAAC,QAAQ,EAClB;QACC,cAAc,EAAE,IAAI;QACpB,eAAe;KACf,CACD,CAAC;IAEF,OAAO;QACN,IAAI,EAAE;YACL,QAAQ;YACR,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,IAAA,sCAAsB,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;SACjE;QACD,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;KAC/B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractRevisions = extractRevisions;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const docxParser_1 = require("../utils/docxParser");
|
|
6
|
+
const revisionParser_1 = require("../utils/revisionParser");
|
|
7
|
+
async function extractRevisions(itemIndex) {
|
|
8
|
+
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex);
|
|
9
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
10
|
+
const includeContext = options.includeContext ?? false;
|
|
11
|
+
const contextLength = options.contextLength ?? 50;
|
|
12
|
+
const includeSummary = options.includeSummary ?? true;
|
|
13
|
+
const item = this.getInputData()[itemIndex];
|
|
14
|
+
if (!item.binary || !item.binary[binaryPropertyName]) {
|
|
15
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No binary data found in property "${binaryPropertyName}"`, { itemIndex });
|
|
16
|
+
}
|
|
17
|
+
const buffer = await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
|
|
18
|
+
let docxFiles;
|
|
19
|
+
try {
|
|
20
|
+
docxFiles = await (0, docxParser_1.parseDocx)(buffer);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (error instanceof docxParser_1.InvalidFileFormatError) {
|
|
24
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), error.message, { itemIndex });
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
if (!docxFiles.document) {
|
|
29
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid .docx file: missing document.xml', { itemIndex });
|
|
30
|
+
}
|
|
31
|
+
const revisions = (0, revisionParser_1.parseRevisions)(docxFiles.document, {
|
|
32
|
+
includeContext,
|
|
33
|
+
contextLength,
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
json: {
|
|
37
|
+
revisions,
|
|
38
|
+
summary: includeSummary ? (0, revisionParser_1.generateRevisionSummary)(revisions) : null,
|
|
39
|
+
},
|
|
40
|
+
pairedItem: { item: itemIndex },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=extractRevisions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractRevisions.js","sourceRoot":"","sources":["../../../../nodes/DocxRevisions/operations/extractRevisions.ts"],"names":[],"mappings":";;AAKA,4CAyDC;AA7DD,+CAAkD;AAClD,oDAAwE;AACxE,4DAAkF;AAE3E,KAAK,UAAU,gBAAgB,CAErC,SAAiB;IAEjB,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,SAAS,CAAW,CAAC;IAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,CAI7D,CAAC;IAEF,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,KAAK,CAAC;IACvD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAClD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;IAEtD,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC;IAE5C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,iCAAkB,CAC3B,IAAI,CAAC,OAAO,EAAE,EACd,qCAAqC,kBAAkB,GAAG,EAC1D,EAAE,SAAS,EAAE,CACb,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAErF,IAAI,SAAS,CAAC;IACd,IAAI,CAAC;QACJ,SAAS,GAAG,MAAM,IAAA,sBAAS,EAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,mCAAsB,EAAE,CAAC;YAC7C,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;IAED,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,iCAAkB,CAC3B,IAAI,CAAC,OAAO,EAAE,EACd,0CAA0C,EAC1C,EAAE,SAAS,EAAE,CACb,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,IAAA,+BAAc,EAAC,SAAS,CAAC,QAAQ,EAAE;QACpD,cAAc;QACd,aAAa;KACb,CAAC,CAAC;IAEH,OAAO;QACN,IAAI,EAAE;YACL,SAAS;YACT,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,IAAA,wCAAuB,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;SACnE;QACD,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;KAC/B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface Comment {
|
|
2
|
+
id: string;
|
|
3
|
+
author: string;
|
|
4
|
+
date: string;
|
|
5
|
+
text: string;
|
|
6
|
+
targetText: string | null;
|
|
7
|
+
resolved: boolean;
|
|
8
|
+
replies: Reply[];
|
|
9
|
+
}
|
|
10
|
+
export interface Reply {
|
|
11
|
+
id: string;
|
|
12
|
+
author: string;
|
|
13
|
+
date: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CommentSummary {
|
|
17
|
+
totalComments: number;
|
|
18
|
+
totalReplies: number;
|
|
19
|
+
resolved: number;
|
|
20
|
+
unresolved: number;
|
|
21
|
+
authors: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface ParseCommentOptions {
|
|
24
|
+
includeReplies?: boolean;
|
|
25
|
+
includeResolved?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function parseComments(commentsXml: string | null, commentsExtendedXml: string | null, documentXml: string | null, options?: ParseCommentOptions): Comment[];
|
|
28
|
+
export declare function generateCommentSummary(comments: Comment[]): CommentSummary;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseComments = parseComments;
|
|
4
|
+
exports.generateCommentSummary = generateCommentSummary;
|
|
5
|
+
const fast_xml_parser_1 = require("fast-xml-parser");
|
|
6
|
+
const parser = new fast_xml_parser_1.XMLParser({
|
|
7
|
+
ignoreAttributes: false,
|
|
8
|
+
attributeNamePrefix: '@_',
|
|
9
|
+
preserveOrder: true,
|
|
10
|
+
});
|
|
11
|
+
function getTextContent(element) {
|
|
12
|
+
if (!element)
|
|
13
|
+
return '';
|
|
14
|
+
if (typeof element === 'string')
|
|
15
|
+
return element;
|
|
16
|
+
if (Array.isArray(element)) {
|
|
17
|
+
return element.map((e) => getTextContent(e)).join('');
|
|
18
|
+
}
|
|
19
|
+
if (typeof element === 'object') {
|
|
20
|
+
const obj = element;
|
|
21
|
+
let text = '';
|
|
22
|
+
if ('#text' in obj) {
|
|
23
|
+
text += obj['#text'];
|
|
24
|
+
}
|
|
25
|
+
for (const key of Object.keys(obj)) {
|
|
26
|
+
if (key === ':@' || key === '#text')
|
|
27
|
+
continue;
|
|
28
|
+
text += getTextContent(obj[key]);
|
|
29
|
+
}
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
function parseComments(commentsXml, commentsExtendedXml, documentXml, options = {}) {
|
|
35
|
+
const { includeReplies = true, includeResolved = true } = options;
|
|
36
|
+
if (!commentsXml) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
const parsed = parser.parse(commentsXml);
|
|
40
|
+
const comments = [];
|
|
41
|
+
const commentMap = new Map();
|
|
42
|
+
const resolvedIds = commentsExtendedXml ? parseResolvedComments(commentsExtendedXml) : new Set();
|
|
43
|
+
const parentMap = commentsExtendedXml ? parseParentRelations(commentsExtendedXml) : new Map();
|
|
44
|
+
const commentRanges = documentXml ? parseCommentRanges(documentXml) : new Map();
|
|
45
|
+
traverseComments(parsed, (commentElement, attrs) => {
|
|
46
|
+
const id = attrs?.['@_w:id'] || '';
|
|
47
|
+
const author = attrs?.['@_w:author'] || 'Unknown';
|
|
48
|
+
const date = attrs?.['@_w:date'] || '';
|
|
49
|
+
const text = getTextContent(commentElement);
|
|
50
|
+
const resolved = resolvedIds.has(id);
|
|
51
|
+
const comment = {
|
|
52
|
+
id,
|
|
53
|
+
author,
|
|
54
|
+
date,
|
|
55
|
+
text,
|
|
56
|
+
targetText: commentRanges.get(id) || null,
|
|
57
|
+
resolved,
|
|
58
|
+
replies: [],
|
|
59
|
+
};
|
|
60
|
+
commentMap.set(id, comment);
|
|
61
|
+
});
|
|
62
|
+
for (const [childId, parentId] of parentMap) {
|
|
63
|
+
const child = commentMap.get(childId);
|
|
64
|
+
const parent = commentMap.get(parentId);
|
|
65
|
+
if (child && parent && includeReplies) {
|
|
66
|
+
const reply = {
|
|
67
|
+
id: child.id,
|
|
68
|
+
author: child.author,
|
|
69
|
+
date: child.date,
|
|
70
|
+
text: child.text,
|
|
71
|
+
};
|
|
72
|
+
parent.replies.push(reply);
|
|
73
|
+
commentMap.delete(childId);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
for (const comment of commentMap.values()) {
|
|
77
|
+
if (!includeResolved && comment.resolved) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
comments.push(comment);
|
|
81
|
+
}
|
|
82
|
+
return comments;
|
|
83
|
+
}
|
|
84
|
+
function traverseComments(obj, callback) {
|
|
85
|
+
if (!obj)
|
|
86
|
+
return;
|
|
87
|
+
if (Array.isArray(obj)) {
|
|
88
|
+
for (const item of obj) {
|
|
89
|
+
traverseComments(item, callback);
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (typeof obj === 'object') {
|
|
94
|
+
const element = obj;
|
|
95
|
+
if ('w:comment' in element) {
|
|
96
|
+
const commentElement = element['w:comment'];
|
|
97
|
+
const attrs = element[':@'];
|
|
98
|
+
callback(commentElement, attrs);
|
|
99
|
+
}
|
|
100
|
+
for (const key of Object.keys(element)) {
|
|
101
|
+
if (key !== ':@') {
|
|
102
|
+
traverseComments(element[key], callback);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function parseResolvedComments(commentsExtendedXml) {
|
|
108
|
+
const resolvedIds = new Set();
|
|
109
|
+
const parsed = parser.parse(commentsExtendedXml);
|
|
110
|
+
traverseCommentsEx(parsed, (attrs) => {
|
|
111
|
+
const done = attrs?.['@_w15:done'];
|
|
112
|
+
const paraId = attrs?.['@_w15:paraId'];
|
|
113
|
+
if (done === '1' && paraId) {
|
|
114
|
+
resolvedIds.add(paraId);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return resolvedIds;
|
|
118
|
+
}
|
|
119
|
+
function parseParentRelations(commentsExtendedXml) {
|
|
120
|
+
const parentMap = new Map();
|
|
121
|
+
const parsed = parser.parse(commentsExtendedXml);
|
|
122
|
+
traverseCommentsEx(parsed, (attrs) => {
|
|
123
|
+
const paraId = attrs?.['@_w15:paraId'];
|
|
124
|
+
const parentParaId = attrs?.['@_w15:paraIdParent'];
|
|
125
|
+
if (paraId && parentParaId) {
|
|
126
|
+
parentMap.set(paraId, parentParaId);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return parentMap;
|
|
130
|
+
}
|
|
131
|
+
function traverseCommentsEx(obj, callback) {
|
|
132
|
+
if (!obj)
|
|
133
|
+
return;
|
|
134
|
+
if (Array.isArray(obj)) {
|
|
135
|
+
for (const item of obj) {
|
|
136
|
+
traverseCommentsEx(item, callback);
|
|
137
|
+
}
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (typeof obj === 'object') {
|
|
141
|
+
const element = obj;
|
|
142
|
+
if ('w15:commentEx' in element) {
|
|
143
|
+
const attrs = element[':@'];
|
|
144
|
+
callback(attrs);
|
|
145
|
+
}
|
|
146
|
+
for (const key of Object.keys(element)) {
|
|
147
|
+
if (key !== ':@') {
|
|
148
|
+
traverseCommentsEx(element[key], callback);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function parseCommentRanges(documentXml) {
|
|
154
|
+
const ranges = new Map();
|
|
155
|
+
const rangeStarts = new Map();
|
|
156
|
+
const rangeEnds = new Map();
|
|
157
|
+
let currentOffset = 0;
|
|
158
|
+
let fullText = '';
|
|
159
|
+
const regex = /<(w:commentRangeStart|w:commentRangeEnd|w:t)[^>]*(?:\/>|>([^<]*)<\/w:t>)/g;
|
|
160
|
+
let match;
|
|
161
|
+
while ((match = regex.exec(documentXml)) !== null) {
|
|
162
|
+
const tag = match[1];
|
|
163
|
+
const content = match[2] || '';
|
|
164
|
+
if (tag === 'w:t') {
|
|
165
|
+
fullText += content;
|
|
166
|
+
currentOffset = fullText.length;
|
|
167
|
+
}
|
|
168
|
+
else if (tag === 'w:commentRangeStart') {
|
|
169
|
+
const idMatch = match[0].match(/w:id="(\d+)"/);
|
|
170
|
+
if (idMatch) {
|
|
171
|
+
rangeStarts.set(idMatch[1], currentOffset);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else if (tag === 'w:commentRangeEnd') {
|
|
175
|
+
const idMatch = match[0].match(/w:id="(\d+)"/);
|
|
176
|
+
if (idMatch) {
|
|
177
|
+
rangeEnds.set(idMatch[1], currentOffset);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (const [id, startOffset] of rangeStarts) {
|
|
182
|
+
const endOffset = rangeEnds.get(id);
|
|
183
|
+
if (endOffset !== undefined) {
|
|
184
|
+
const targetText = fullText.substring(startOffset, endOffset);
|
|
185
|
+
ranges.set(id, targetText);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return ranges;
|
|
189
|
+
}
|
|
190
|
+
function generateCommentSummary(comments) {
|
|
191
|
+
const totalReplies = comments.reduce((sum, c) => sum + c.replies.length, 0);
|
|
192
|
+
const resolved = comments.filter((c) => c.resolved).length;
|
|
193
|
+
const authorsSet = new Set();
|
|
194
|
+
for (const comment of comments) {
|
|
195
|
+
authorsSet.add(comment.author);
|
|
196
|
+
for (const reply of comment.replies) {
|
|
197
|
+
authorsSet.add(reply.author);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
totalComments: comments.length,
|
|
202
|
+
totalReplies,
|
|
203
|
+
resolved,
|
|
204
|
+
unresolved: comments.length - resolved,
|
|
205
|
+
authors: Array.from(authorsSet),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=commentParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commentParser.js","sourceRoot":"","sources":["../../../../nodes/DocxRevisions/utils/commentParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface DocxFiles {
|
|
2
|
+
document: string | null;
|
|
3
|
+
comments: string | null;
|
|
4
|
+
commentsExtended: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare class InvalidFileFormatError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare function parseDocx(buffer: Buffer): Promise<DocxFiles>;
|
|
10
|
+
export declare function extractTextFromXml(xml: string): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.InvalidFileFormatError = void 0;
|
|
7
|
+
exports.parseDocx = parseDocx;
|
|
8
|
+
exports.extractTextFromXml = extractTextFromXml;
|
|
9
|
+
const jszip_1 = __importDefault(require("jszip"));
|
|
10
|
+
class InvalidFileFormatError extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'InvalidFileFormatError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.InvalidFileFormatError = InvalidFileFormatError;
|
|
17
|
+
async function parseDocx(buffer) {
|
|
18
|
+
let zip;
|
|
19
|
+
try {
|
|
20
|
+
zip = await jszip_1.default.loadAsync(buffer);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new InvalidFileFormatError('Failed to parse file as ZIP archive. Please provide a valid .docx file.');
|
|
24
|
+
}
|
|
25
|
+
const contentTypesFile = zip.file('[Content_Types].xml');
|
|
26
|
+
if (!contentTypesFile) {
|
|
27
|
+
throw new InvalidFileFormatError('Invalid .docx file: missing [Content_Types].xml');
|
|
28
|
+
}
|
|
29
|
+
const documentFile = zip.file('word/document.xml');
|
|
30
|
+
const commentsFile = zip.file('word/comments.xml');
|
|
31
|
+
const commentsExtendedFile = zip.file('word/commentsExtended.xml');
|
|
32
|
+
const document = documentFile ? await documentFile.async('string') : null;
|
|
33
|
+
const comments = commentsFile ? await commentsFile.async('string') : null;
|
|
34
|
+
const commentsExtended = commentsExtendedFile ? await commentsExtendedFile.async('string') : null;
|
|
35
|
+
return {
|
|
36
|
+
document,
|
|
37
|
+
comments,
|
|
38
|
+
commentsExtended,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function extractTextFromXml(xml) {
|
|
42
|
+
const textMatches = xml.match(/<w:t[^>]*>([^<]*)<\/w:t>/g) || [];
|
|
43
|
+
return textMatches
|
|
44
|
+
.map((match) => {
|
|
45
|
+
const textMatch = match.match(/<w:t[^>]*>([^<]*)<\/w:t>/);
|
|
46
|
+
return textMatch ? textMatch[1] : '';
|
|
47
|
+
})
|
|
48
|
+
.join('');
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=docxParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docxParser.js","sourceRoot":"","sources":["../../../../nodes/DocxRevisions/utils/docxParser.ts"],"names":[],"mappings":";;;;;;AAeA,8BA2BC;AAED,gDAQC;AApDD,kDAA0B;AAQ1B,MAAa,sBAAuB,SAAQ,KAAK;IAChD,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACtC,CAAC;CACD;AALD,wDAKC;AAEM,KAAK,UAAU,SAAS,CAAC,MAAc;IAC7C,IAAI,GAAU,CAAC;IAEf,IAAI,CAAC;QACJ,GAAG,GAAG,MAAM,eAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,sBAAsB,CAAC,yEAAyE,CAAC,CAAC;IAC7G,CAAC;IAED,MAAM,gBAAgB,GAAG,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACzD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvB,MAAM,IAAI,sBAAsB,CAAC,iDAAiD,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACnD,MAAM,oBAAoB,GAAG,GAAG,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAEnE,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,CAAC,CAAC,MAAM,oBAAoB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAElG,OAAO;QACN,QAAQ;QACR,QAAQ;QACR,gBAAgB;KAChB,CAAC;AACH,CAAC;AAED,SAAgB,kBAAkB,CAAC,GAAW;IAC7C,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC;IACjE,OAAO,WAAW;SAChB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACd,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC1D,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtC,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface Revision {
|
|
2
|
+
type: 'insert' | 'delete';
|
|
3
|
+
text: string;
|
|
4
|
+
author: string;
|
|
5
|
+
date: string;
|
|
6
|
+
paragraphIndex: number;
|
|
7
|
+
context: {
|
|
8
|
+
before: string;
|
|
9
|
+
after: string;
|
|
10
|
+
} | null;
|
|
11
|
+
}
|
|
12
|
+
export interface RevisionSummary {
|
|
13
|
+
totalRevisions: number;
|
|
14
|
+
insertions: number;
|
|
15
|
+
deletions: number;
|
|
16
|
+
authors: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface ParseRevisionOptions {
|
|
19
|
+
includeContext?: boolean;
|
|
20
|
+
contextLength?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function parseRevisions(documentXml: string, options?: ParseRevisionOptions): Revision[];
|
|
23
|
+
export declare function generateRevisionSummary(revisions: Revision[]): RevisionSummary;
|