@crypto512/jicon-mcp 0.7.1 → 1.0.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/README.md +128 -395
- package/TOOL_LIST.md +810 -120
- package/dist/config/constants.d.ts +1 -0
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +1 -0
- package/dist/config/constants.js.map +1 -1
- package/dist/config/loader.d.ts +1 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +27 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/config/types.d.ts +8 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -1
- package/dist/confluence/client.d.ts +38 -0
- package/dist/confluence/client.d.ts.map +1 -1
- package/dist/confluence/client.js +117 -0
- package/dist/confluence/client.js.map +1 -1
- package/dist/confluence/tools.d.ts +102 -75
- package/dist/confluence/tools.d.ts.map +1 -1
- package/dist/confluence/tools.js +510 -151
- package/dist/confluence/tools.js.map +1 -1
- package/dist/confluence/types.d.ts +55 -1
- package/dist/confluence/types.d.ts.map +1 -1
- package/dist/index.js +88 -2
- package/dist/index.js.map +1 -1
- package/dist/jira/tools.d.ts +0 -5
- package/dist/jira/tools.d.ts.map +1 -1
- package/dist/jira/tools.js +40 -87
- package/dist/jira/tools.js.map +1 -1
- package/dist/permissions/filter.d.ts +5 -0
- package/dist/permissions/filter.d.ts.map +1 -1
- package/dist/permissions/filter.js +29 -12
- package/dist/permissions/filter.js.map +1 -1
- package/dist/permissions/tool-registry.d.ts +23 -25
- package/dist/permissions/tool-registry.d.ts.map +1 -1
- package/dist/permissions/tool-registry.js +41 -45
- package/dist/permissions/tool-registry.js.map +1 -1
- package/dist/permissions/write-home-validator.d.ts +35 -0
- package/dist/permissions/write-home-validator.d.ts.map +1 -0
- package/dist/permissions/write-home-validator.js +140 -0
- package/dist/permissions/write-home-validator.js.map +1 -0
- package/dist/tempo/tools.d.ts.map +1 -1
- package/dist/tempo/tools.js +43 -44
- package/dist/tempo/tools.js.map +1 -1
- package/dist/utils/buffer-tools.d.ts +119 -1
- package/dist/utils/buffer-tools.d.ts.map +1 -1
- package/dist/utils/buffer-tools.js +610 -3
- package/dist/utils/buffer-tools.js.map +1 -1
- package/dist/utils/content-buffer.d.ts +34 -0
- package/dist/utils/content-buffer.d.ts.map +1 -1
- package/dist/utils/content-buffer.js +79 -0
- package/dist/utils/content-buffer.js.map +1 -1
- package/dist/utils/http-client.d.ts.map +1 -1
- package/dist/utils/http-client.js +4 -4
- package/dist/utils/http-client.js.map +1 -1
- package/dist/utils/jicon-help.d.ts +29 -0
- package/dist/utils/jicon-help.d.ts.map +1 -0
- package/dist/utils/jicon-help.js +873 -0
- package/dist/utils/jicon-help.js.map +1 -0
- package/dist/utils/plantuml/client.d.ts +40 -0
- package/dist/utils/plantuml/client.d.ts.map +1 -0
- package/dist/utils/plantuml/client.js +306 -0
- package/dist/utils/plantuml/client.js.map +1 -0
- package/dist/utils/plantuml/docker-manager.d.ts +35 -0
- package/dist/utils/plantuml/docker-manager.d.ts.map +1 -0
- package/dist/utils/plantuml/docker-manager.js +280 -0
- package/dist/utils/plantuml/docker-manager.js.map +1 -0
- package/dist/utils/plantuml/index.d.ts +11 -0
- package/dist/utils/plantuml/index.d.ts.map +1 -0
- package/dist/utils/plantuml/index.js +16 -0
- package/dist/utils/plantuml/index.js.map +1 -0
- package/dist/utils/plantuml/service.d.ts +46 -0
- package/dist/utils/plantuml/service.d.ts.map +1 -0
- package/dist/utils/plantuml/service.js +96 -0
- package/dist/utils/plantuml/service.js.map +1 -0
- package/dist/utils/plantuml/tools.d.ts +65 -0
- package/dist/utils/plantuml/tools.d.ts.map +1 -0
- package/dist/utils/plantuml/tools.js +272 -0
- package/dist/utils/plantuml/tools.js.map +1 -0
- package/dist/utils/plantuml/types.d.ts +130 -0
- package/dist/utils/plantuml/types.d.ts.map +1 -0
- package/dist/utils/plantuml/types.js +66 -0
- package/dist/utils/plantuml/types.js.map +1 -0
- package/dist/utils/response-formatter.d.ts +14 -0
- package/dist/utils/response-formatter.d.ts.map +1 -1
- package/dist/utils/response-formatter.js +84 -1
- package/dist/utils/response-formatter.js.map +1 -1
- package/dist/utils/url-tools.d.ts +49 -0
- package/dist/utils/url-tools.d.ts.map +1 -0
- package/dist/utils/url-tools.js +141 -0
- package/dist/utils/url-tools.js.map +1 -0
- package/dist/utils/xhtml/confluence-schema.d.ts +55 -0
- package/dist/utils/xhtml/confluence-schema.d.ts.map +1 -0
- package/dist/utils/xhtml/confluence-schema.js +215 -0
- package/dist/utils/xhtml/confluence-schema.js.map +1 -0
- package/dist/utils/xhtml/index.d.ts +17 -0
- package/dist/utils/xhtml/index.d.ts.map +1 -0
- package/dist/utils/xhtml/index.js +21 -0
- package/dist/utils/xhtml/index.js.map +1 -0
- package/dist/utils/xhtml/operations.d.ts +100 -0
- package/dist/utils/xhtml/operations.d.ts.map +1 -0
- package/dist/utils/xhtml/operations.js +596 -0
- package/dist/utils/xhtml/operations.js.map +1 -0
- package/dist/utils/xhtml/parser.d.ts +64 -0
- package/dist/utils/xhtml/parser.d.ts.map +1 -0
- package/dist/utils/xhtml/parser.js +180 -0
- package/dist/utils/xhtml/parser.js.map +1 -0
- package/dist/utils/xhtml/plantuml.d.ts +112 -0
- package/dist/utils/xhtml/plantuml.d.ts.map +1 -0
- package/dist/utils/xhtml/plantuml.js +251 -0
- package/dist/utils/xhtml/plantuml.js.map +1 -0
- package/dist/utils/xhtml/selector.d.ts +35 -0
- package/dist/utils/xhtml/selector.d.ts.map +1 -0
- package/dist/utils/xhtml/selector.js +358 -0
- package/dist/utils/xhtml/selector.js.map +1 -0
- package/dist/utils/xhtml/serializer.d.ts +26 -0
- package/dist/utils/xhtml/serializer.d.ts.map +1 -0
- package/dist/utils/xhtml/serializer.js +170 -0
- package/dist/utils/xhtml/serializer.js.map +1 -0
- package/dist/utils/xhtml/types.d.ts +134 -0
- package/dist/utils/xhtml/types.d.ts.map +1 -0
- package/dist/utils/xhtml/types.js +65 -0
- package/dist/utils/xhtml/types.js.map +1 -0
- package/dist/utils/xhtml/validator.d.ts +67 -0
- package/dist/utils/xhtml/validator.d.ts.map +1 -0
- package/dist/utils/xhtml/validator.js +300 -0
- package/dist/utils/xhtml/validator.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/utils/xhtml/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAwB,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,eAAO,MAAM,qBAAqB;;;CAGxB,CAAC;AAsCX;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAW7F;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAuDvD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,CAWjE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAE3D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAGjF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAIrD"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XHTML Parser using linkedom
|
|
3
|
+
*
|
|
4
|
+
* Parses Confluence storage format (XHTML) with namespace support for ac: and ri: elements.
|
|
5
|
+
*/
|
|
6
|
+
import { parseHTML, DOMParser } from "linkedom";
|
|
7
|
+
// Confluence namespaces
|
|
8
|
+
export const CONFLUENCE_NAMESPACES = {
|
|
9
|
+
ac: "http://atlassian.com/content",
|
|
10
|
+
ri: "http://atlassian.com/resource/identifier",
|
|
11
|
+
};
|
|
12
|
+
// Root wrapper with namespace declarations
|
|
13
|
+
const ROOT_OPEN = `<xhtml-root xmlns:ac="${CONFLUENCE_NAMESPACES.ac}" xmlns:ri="${CONFLUENCE_NAMESPACES.ri}">`;
|
|
14
|
+
const ROOT_CLOSE = "</xhtml-root>";
|
|
15
|
+
/**
|
|
16
|
+
* Check if content already has namespace declarations
|
|
17
|
+
*/
|
|
18
|
+
function hasNamespaces(content) {
|
|
19
|
+
return content.includes("xmlns:ac") || content.includes("xmlns:ri");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check if content has a root element
|
|
23
|
+
*/
|
|
24
|
+
function hasRootElement(content) {
|
|
25
|
+
const trimmed = content.trim();
|
|
26
|
+
// Simple heuristic: if it starts with < and has a single root
|
|
27
|
+
if (!trimmed.startsWith("<"))
|
|
28
|
+
return false;
|
|
29
|
+
// Count top-level elements
|
|
30
|
+
const parser = new DOMParser();
|
|
31
|
+
try {
|
|
32
|
+
const doc = parser.parseFromString(`<wrapper>${trimmed}</wrapper>`, "text/html");
|
|
33
|
+
const wrapper = doc.querySelector("wrapper");
|
|
34
|
+
if (!wrapper)
|
|
35
|
+
return false;
|
|
36
|
+
let elementCount = 0;
|
|
37
|
+
for (const child of wrapper.childNodes) {
|
|
38
|
+
if (child.nodeType === 1)
|
|
39
|
+
elementCount++; // Element node
|
|
40
|
+
}
|
|
41
|
+
return elementCount === 1;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Unwrap CDATA sections to preserve their content during HTML parsing.
|
|
49
|
+
*
|
|
50
|
+
* The parseHTML function from linkedom treats CDATA as HTML comments and
|
|
51
|
+
* discards the content. This function converts CDATA sections to plain text
|
|
52
|
+
* before parsing, preserving the content as textContent of the element.
|
|
53
|
+
*
|
|
54
|
+
* @param content - XHTML content with potential CDATA sections
|
|
55
|
+
* @returns Content with CDATA markers removed but content preserved
|
|
56
|
+
*/
|
|
57
|
+
export function unwrapCdata(content) {
|
|
58
|
+
return content.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, "$1");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wrap content with namespace declarations if needed
|
|
62
|
+
*/
|
|
63
|
+
export function wrapWithNamespaces(content) {
|
|
64
|
+
// If already has namespaces and appears to be a complete document, don't wrap
|
|
65
|
+
if (hasNamespaces(content) && hasRootElement(content)) {
|
|
66
|
+
return { wrapped: content, needsUnwrap: false };
|
|
67
|
+
}
|
|
68
|
+
// Wrap with our root element that includes namespace declarations
|
|
69
|
+
return {
|
|
70
|
+
wrapped: `${ROOT_OPEN}${content}${ROOT_CLOSE}`,
|
|
71
|
+
needsUnwrap: true,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Parse XHTML content into a DOM Document
|
|
76
|
+
*
|
|
77
|
+
* @param content - XHTML content string (Confluence storage format)
|
|
78
|
+
* @returns ParseResult with document or error
|
|
79
|
+
*/
|
|
80
|
+
export function parseXhtml(content) {
|
|
81
|
+
try {
|
|
82
|
+
// Unwrap CDATA sections before parsing - linkedom's parseHTML treats
|
|
83
|
+
// CDATA as HTML comments and discards the content
|
|
84
|
+
const cdataUnwrapped = unwrapCdata(content);
|
|
85
|
+
const { wrapped, needsUnwrap } = wrapWithNamespaces(cdataUnwrapped);
|
|
86
|
+
// Use parseHTML from linkedom which handles XML/XHTML better
|
|
87
|
+
const { document } = parseHTML(wrapped);
|
|
88
|
+
// Store whether we need to unwrap when serializing
|
|
89
|
+
document.__needsUnwrap = needsUnwrap;
|
|
90
|
+
return { document, error: null };
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
94
|
+
// Try to extract line/column from error message
|
|
95
|
+
const lineMatch = message.match(/line\s*(\d+)/i);
|
|
96
|
+
const colMatch = message.match(/col(?:umn)?\s*(\d+)/i);
|
|
97
|
+
// Also try [row,col] format from some parsers
|
|
98
|
+
const rowColMatch = message.match(/\[row,col[^\]]*\]:\s*\[(\d+),(\d+)\]/i);
|
|
99
|
+
const line = lineMatch
|
|
100
|
+
? parseInt(lineMatch[1], 10)
|
|
101
|
+
: rowColMatch
|
|
102
|
+
? parseInt(rowColMatch[1], 10)
|
|
103
|
+
: undefined;
|
|
104
|
+
const column = colMatch
|
|
105
|
+
? parseInt(colMatch[1], 10)
|
|
106
|
+
: rowColMatch
|
|
107
|
+
? parseInt(rowColMatch[2], 10)
|
|
108
|
+
: undefined;
|
|
109
|
+
// Extract context snippet from the problematic line
|
|
110
|
+
let context;
|
|
111
|
+
if (line) {
|
|
112
|
+
const lines = content.split("\n");
|
|
113
|
+
if (lines[line - 1]) {
|
|
114
|
+
const errorLine = lines[line - 1];
|
|
115
|
+
// Show up to 100 chars, truncate if longer
|
|
116
|
+
context = errorLine.length > 100 ? errorLine.substring(0, 100) + "..." : errorLine;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
document: null,
|
|
121
|
+
error: {
|
|
122
|
+
message,
|
|
123
|
+
line,
|
|
124
|
+
column,
|
|
125
|
+
context,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get the root element for operations
|
|
132
|
+
*
|
|
133
|
+
* If we wrapped the content, returns the wrapper's children.
|
|
134
|
+
* Otherwise returns the document root.
|
|
135
|
+
*/
|
|
136
|
+
export function getContentRoot(document) {
|
|
137
|
+
const needsUnwrap = document.__needsUnwrap;
|
|
138
|
+
if (needsUnwrap) {
|
|
139
|
+
// Return our wrapper element so operations work on its children
|
|
140
|
+
const root = document.querySelector("xhtml-root");
|
|
141
|
+
return root;
|
|
142
|
+
}
|
|
143
|
+
// Return the document's root element
|
|
144
|
+
return document.documentElement;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Check if content is valid XHTML (well-formed XML)
|
|
148
|
+
*/
|
|
149
|
+
export function isValidXhtml(content) {
|
|
150
|
+
const result = parseXhtml(content);
|
|
151
|
+
return result.document !== null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Extract text content from an element, stripping all tags
|
|
155
|
+
*/
|
|
156
|
+
export function extractTextContent(element) {
|
|
157
|
+
return element.textContent || "";
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get the tag name including namespace prefix
|
|
161
|
+
*/
|
|
162
|
+
export function getQualifiedTagName(element) {
|
|
163
|
+
return element.tagName.toLowerCase();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Check if an element has a specific namespace prefix
|
|
167
|
+
*/
|
|
168
|
+
export function hasNamespacePrefix(element, prefix) {
|
|
169
|
+
const tagName = element.tagName.toLowerCase();
|
|
170
|
+
return tagName.startsWith(`${prefix}:`);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get the local name (tag name without namespace prefix)
|
|
174
|
+
*/
|
|
175
|
+
export function getLocalName(element) {
|
|
176
|
+
const tagName = element.tagName.toLowerCase();
|
|
177
|
+
const colonIndex = tagName.indexOf(":");
|
|
178
|
+
return colonIndex >= 0 ? tagName.slice(colonIndex + 1) : tagName;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/utils/xhtml/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlantUML Support for Confluence
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - PlantUML syntax validation using Docker-based PlantUML server
|
|
6
|
+
* - Automatic @startuml/@enduml wrapping
|
|
7
|
+
* - Confluence macro generation
|
|
8
|
+
*
|
|
9
|
+
* Note: This module provides synchronous macro building functions.
|
|
10
|
+
* For async validation with Docker, use the plantuml service directly.
|
|
11
|
+
*/
|
|
12
|
+
import type { Element } from "linkedom";
|
|
13
|
+
import type { PlantUmlValidationResult } from "./types.js";
|
|
14
|
+
/**
|
|
15
|
+
* Normalize PlantUML code by ensuring @startuml/@enduml markers
|
|
16
|
+
* (Local implementation for synchronous use)
|
|
17
|
+
*/
|
|
18
|
+
export declare function normalizePlantUml(code: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Detect the diagram type from PlantUML code
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectDiagramType(code: string): string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Extract the diagram content (without @startuml/@enduml)
|
|
25
|
+
*/
|
|
26
|
+
export declare function extractDiagramContent(code: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Validate PlantUML syntax (synchronous - basic validation only)
|
|
29
|
+
*
|
|
30
|
+
* This function performs basic structural validation synchronously.
|
|
31
|
+
* For full validation with the Docker PlantUML server, use:
|
|
32
|
+
* import { validate } from "../plantuml/service.js"
|
|
33
|
+
*
|
|
34
|
+
* @param code - PlantUML code (with or without @startuml/@enduml)
|
|
35
|
+
* @returns Validation result with normalized code
|
|
36
|
+
*/
|
|
37
|
+
export declare function validatePlantUml(code: string): PlantUmlValidationResult;
|
|
38
|
+
/**
|
|
39
|
+
* Generate a unique macro ID
|
|
40
|
+
*/
|
|
41
|
+
export declare function generateMacroId(): string;
|
|
42
|
+
/**
|
|
43
|
+
* Build Confluence PlantUML macro XHTML
|
|
44
|
+
*
|
|
45
|
+
* @param plantumlCode - PlantUML code (will be normalized)
|
|
46
|
+
* @param macroId - Optional macro ID (generated if not provided)
|
|
47
|
+
* @returns Complete ac:structured-macro XHTML for PlantUML
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildPlantUmlMacro(plantumlCode: string, macroId?: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Validate and build PlantUML macro in one step (synchronous)
|
|
52
|
+
*
|
|
53
|
+
* Uses basic synchronous validation. For full Docker-based validation,
|
|
54
|
+
* use the plantuml service directly.
|
|
55
|
+
*
|
|
56
|
+
* @param plantumlCode - PlantUML code
|
|
57
|
+
* @param macroId - Optional macro ID
|
|
58
|
+
* @returns Object with success/error and macro XHTML if successful
|
|
59
|
+
*/
|
|
60
|
+
export declare function validateAndBuildPlantUmlMacro(plantumlCode: string, macroId?: string): {
|
|
61
|
+
success: true;
|
|
62
|
+
macro: string;
|
|
63
|
+
diagramType?: string;
|
|
64
|
+
} | {
|
|
65
|
+
success: false;
|
|
66
|
+
error: PlantUmlValidationResult["error"];
|
|
67
|
+
diagramType?: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Result of PlantUML extraction with detailed error info
|
|
71
|
+
*/
|
|
72
|
+
export interface PlantUmlExtractionResult {
|
|
73
|
+
code: string | null;
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Extract PlantUML code from a Confluence macro element with detailed error info
|
|
78
|
+
*
|
|
79
|
+
* @param macroElement - The ac:structured-macro element
|
|
80
|
+
* @returns Extraction result with code or error
|
|
81
|
+
*/
|
|
82
|
+
export declare function extractPlantUmlFromMacroWithError(macroElement: Element): PlantUmlExtractionResult;
|
|
83
|
+
/**
|
|
84
|
+
* Extract PlantUML code from a Confluence macro element
|
|
85
|
+
*
|
|
86
|
+
* @param macroElement - The ac:structured-macro element
|
|
87
|
+
* @returns PlantUML code or null if not found
|
|
88
|
+
*/
|
|
89
|
+
export declare function extractPlantUmlFromMacro(macroElement: Element): string | null;
|
|
90
|
+
/**
|
|
91
|
+
* Update PlantUML code in a macro element
|
|
92
|
+
*
|
|
93
|
+
* @param macroElement - The ac:structured-macro element
|
|
94
|
+
* @param newCode - New PlantUML code
|
|
95
|
+
* @returns Updated element or null if update failed
|
|
96
|
+
*/
|
|
97
|
+
export declare function updatePlantUmlInMacro(macroElement: Element, newCode: string): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Check if content contains raw PlantUML code that needs proper wrapping.
|
|
100
|
+
*
|
|
101
|
+
* Returns match info if raw PlantUML is found outside of Confluence macros.
|
|
102
|
+
* This is used to detect when LLMs put raw @startuml blocks in content
|
|
103
|
+
* instead of using the buffer_edit_xhtml insert-plantuml operation.
|
|
104
|
+
*
|
|
105
|
+
* @param content - Content to check for raw PlantUML
|
|
106
|
+
* @returns Object with detected flag and hint, or null if no issues
|
|
107
|
+
*/
|
|
108
|
+
export declare function detectRawPlantUml(content: string): {
|
|
109
|
+
detected: boolean;
|
|
110
|
+
hint: string;
|
|
111
|
+
} | null;
|
|
112
|
+
//# sourceMappingURL=plantuml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plantuml.d.ts","sourceRoot":"","sources":["../../../src/utils/xhtml/plantuml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAU3D;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CAkEvE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAYjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAkB7I;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,YAAY,EAAE,OAAO,GAAG,wBAAwB,CAgCjG;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAG7E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAerF;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkB7F"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlantUML Support for Confluence
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - PlantUML syntax validation using Docker-based PlantUML server
|
|
6
|
+
* - Automatic @startuml/@enduml wrapping
|
|
7
|
+
* - Confluence macro generation
|
|
8
|
+
*
|
|
9
|
+
* Note: This module provides synchronous macro building functions.
|
|
10
|
+
* For async validation with Docker, use the plantuml service directly.
|
|
11
|
+
*/
|
|
12
|
+
import { randomBytes } from "crypto";
|
|
13
|
+
// Re-export normalizePlantUml and detectDiagramType from the plantuml service
|
|
14
|
+
// for consistency, but also provide local implementations for sync operations
|
|
15
|
+
import { normalizePlantUml as serviceNormalizePlantUml, detectDiagramType as serviceDetectDiagramType, } from "../plantuml/client.js";
|
|
16
|
+
/**
|
|
17
|
+
* Normalize PlantUML code by ensuring @startuml/@enduml markers
|
|
18
|
+
* (Local implementation for synchronous use)
|
|
19
|
+
*/
|
|
20
|
+
export function normalizePlantUml(code) {
|
|
21
|
+
return serviceNormalizePlantUml(code);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detect the diagram type from PlantUML code
|
|
25
|
+
*/
|
|
26
|
+
export function detectDiagramType(code) {
|
|
27
|
+
return serviceDetectDiagramType(code);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract the diagram content (without @startuml/@enduml)
|
|
31
|
+
*/
|
|
32
|
+
export function extractDiagramContent(code) {
|
|
33
|
+
return code
|
|
34
|
+
.replace(/^@startuml\b[^\n]*/im, "")
|
|
35
|
+
.replace(/@enduml\s*$/im, "")
|
|
36
|
+
.trim();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Validate PlantUML syntax (synchronous - basic validation only)
|
|
40
|
+
*
|
|
41
|
+
* This function performs basic structural validation synchronously.
|
|
42
|
+
* For full validation with the Docker PlantUML server, use:
|
|
43
|
+
* import { validate } from "../plantuml/service.js"
|
|
44
|
+
*
|
|
45
|
+
* @param code - PlantUML code (with or without @startuml/@enduml)
|
|
46
|
+
* @returns Validation result with normalized code
|
|
47
|
+
*/
|
|
48
|
+
export function validatePlantUml(code) {
|
|
49
|
+
const normalizedCode = normalizePlantUml(code);
|
|
50
|
+
const diagramType = detectDiagramType(code);
|
|
51
|
+
// Basic structural validation (synchronous)
|
|
52
|
+
// Check for @startuml/@enduml presence after normalization
|
|
53
|
+
const hasStart = /^@startuml\b/im.test(normalizedCode);
|
|
54
|
+
const hasEnd = /@enduml\s*$/im.test(normalizedCode);
|
|
55
|
+
if (!hasStart || !hasEnd) {
|
|
56
|
+
return {
|
|
57
|
+
valid: false,
|
|
58
|
+
normalizedCode,
|
|
59
|
+
error: {
|
|
60
|
+
message: "Missing @startuml or @enduml markers",
|
|
61
|
+
line: 1,
|
|
62
|
+
},
|
|
63
|
+
diagramType,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Check for external includes (not supported in Confluence)
|
|
67
|
+
const lines = normalizedCode.split("\n");
|
|
68
|
+
for (let i = 0; i < lines.length; i++) {
|
|
69
|
+
const line = lines[i];
|
|
70
|
+
const externalIncludeMatch = line.match(/!include\s+(https?:\/\/[^\s]+)/i);
|
|
71
|
+
if (externalIncludeMatch) {
|
|
72
|
+
return {
|
|
73
|
+
valid: false,
|
|
74
|
+
normalizedCode,
|
|
75
|
+
error: {
|
|
76
|
+
message: `External includes are not supported in Confluence. Found: !include ${externalIncludeMatch[1]}`,
|
|
77
|
+
line: i + 1,
|
|
78
|
+
suggestion: "Use native PlantUML syntax instead of C4 includes. See help(topic='plantuml') for examples.",
|
|
79
|
+
},
|
|
80
|
+
diagramType,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Check for common syntax errors
|
|
85
|
+
for (let i = 0; i < lines.length; i++) {
|
|
86
|
+
const line = lines[i];
|
|
87
|
+
// Check for unclosed strings
|
|
88
|
+
const quoteCount = (line.match(/"/g) || []).length;
|
|
89
|
+
if (quoteCount % 2 !== 0) {
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
normalizedCode,
|
|
93
|
+
error: {
|
|
94
|
+
message: "Unclosed string literal",
|
|
95
|
+
line: i + 1,
|
|
96
|
+
},
|
|
97
|
+
diagramType,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Basic validation passed
|
|
102
|
+
// Note: For full validation, use the async plantuml service
|
|
103
|
+
return {
|
|
104
|
+
valid: true,
|
|
105
|
+
normalizedCode,
|
|
106
|
+
diagramType,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Generate a unique macro ID
|
|
111
|
+
*/
|
|
112
|
+
export function generateMacroId() {
|
|
113
|
+
return `plantuml-${randomBytes(8).toString("hex")}`;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Build Confluence PlantUML macro XHTML
|
|
117
|
+
*
|
|
118
|
+
* @param plantumlCode - PlantUML code (will be normalized)
|
|
119
|
+
* @param macroId - Optional macro ID (generated if not provided)
|
|
120
|
+
* @returns Complete ac:structured-macro XHTML for PlantUML
|
|
121
|
+
*/
|
|
122
|
+
export function buildPlantUmlMacro(plantumlCode, macroId) {
|
|
123
|
+
const normalizedCode = normalizePlantUml(plantumlCode);
|
|
124
|
+
const id = macroId || generateMacroId();
|
|
125
|
+
// Build the macro structure
|
|
126
|
+
// Note: The newline before @startuml inside CDATA is important for Confluence
|
|
127
|
+
return `<ac:structured-macro ac:name="plantuml" ac:schema-version="1" ac:macro-id="${id}">
|
|
128
|
+
<ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
|
|
129
|
+
<ac:plain-text-body><![CDATA[
|
|
130
|
+
${normalizedCode}
|
|
131
|
+
]]></ac:plain-text-body>
|
|
132
|
+
</ac:structured-macro>`;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validate and build PlantUML macro in one step (synchronous)
|
|
136
|
+
*
|
|
137
|
+
* Uses basic synchronous validation. For full Docker-based validation,
|
|
138
|
+
* use the plantuml service directly.
|
|
139
|
+
*
|
|
140
|
+
* @param plantumlCode - PlantUML code
|
|
141
|
+
* @param macroId - Optional macro ID
|
|
142
|
+
* @returns Object with success/error and macro XHTML if successful
|
|
143
|
+
*/
|
|
144
|
+
export function validateAndBuildPlantUmlMacro(plantumlCode, macroId) {
|
|
145
|
+
const validation = validatePlantUml(plantumlCode);
|
|
146
|
+
if (!validation.valid) {
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
error: validation.error,
|
|
150
|
+
diagramType: validation.diagramType,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const macro = buildPlantUmlMacro(validation.normalizedCode, macroId);
|
|
154
|
+
return {
|
|
155
|
+
success: true,
|
|
156
|
+
macro,
|
|
157
|
+
diagramType: validation.diagramType,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Extract PlantUML code from a Confluence macro element with detailed error info
|
|
162
|
+
*
|
|
163
|
+
* @param macroElement - The ac:structured-macro element
|
|
164
|
+
* @returns Extraction result with code or error
|
|
165
|
+
*/
|
|
166
|
+
export function extractPlantUmlFromMacroWithError(macroElement) {
|
|
167
|
+
// Find the plain-text-body element
|
|
168
|
+
const bodyElement = macroElement.querySelector("ac\\:plain-text-body");
|
|
169
|
+
if (!bodyElement) {
|
|
170
|
+
return {
|
|
171
|
+
code: null,
|
|
172
|
+
error: "Missing <ac:plain-text-body> element. PlantUML macros must contain: <ac:plain-text-body><![CDATA[@startuml...@enduml]]></ac:plain-text-body>",
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// Get the text content (CDATA will be unwrapped by the parser)
|
|
176
|
+
const content = bodyElement.textContent;
|
|
177
|
+
if (!content || !content.trim()) {
|
|
178
|
+
return {
|
|
179
|
+
code: null,
|
|
180
|
+
error: "Empty <ac:plain-text-body>. Add your PlantUML code inside CDATA: <![CDATA[@startuml...@enduml]]>",
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
const trimmedContent = content.trim();
|
|
184
|
+
// Check for @startuml marker
|
|
185
|
+
if (!trimmedContent.includes("@startuml") && !trimmedContent.includes("@startmindmap") &&
|
|
186
|
+
!trimmedContent.includes("@startgantt") && !trimmedContent.includes("@startwbs") &&
|
|
187
|
+
!trimmedContent.includes("@startjson") && !trimmedContent.includes("@startyaml")) {
|
|
188
|
+
return {
|
|
189
|
+
code: null,
|
|
190
|
+
error: `Missing @startuml marker. Content found: "${trimmedContent.substring(0, 50)}${trimmedContent.length > 50 ? "..." : ""}". PlantUML must start with @startuml (or @startmindmap, etc.)`,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return { code: trimmedContent };
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Extract PlantUML code from a Confluence macro element
|
|
197
|
+
*
|
|
198
|
+
* @param macroElement - The ac:structured-macro element
|
|
199
|
+
* @returns PlantUML code or null if not found
|
|
200
|
+
*/
|
|
201
|
+
export function extractPlantUmlFromMacro(macroElement) {
|
|
202
|
+
const result = extractPlantUmlFromMacroWithError(macroElement);
|
|
203
|
+
return result.code;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Update PlantUML code in a macro element
|
|
207
|
+
*
|
|
208
|
+
* @param macroElement - The ac:structured-macro element
|
|
209
|
+
* @param newCode - New PlantUML code
|
|
210
|
+
* @returns Updated element or null if update failed
|
|
211
|
+
*/
|
|
212
|
+
export function updatePlantUmlInMacro(macroElement, newCode) {
|
|
213
|
+
// Find the plain-text-body element
|
|
214
|
+
const bodyElement = macroElement.querySelector("ac\\:plain-text-body");
|
|
215
|
+
if (!bodyElement) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
// Normalize the code
|
|
219
|
+
const normalizedCode = normalizePlantUml(newCode);
|
|
220
|
+
// Update the content with CDATA
|
|
221
|
+
// Note: Setting textContent will escape the CDATA properly in serialization
|
|
222
|
+
bodyElement.textContent = `\n${normalizedCode}\n`;
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Check if content contains raw PlantUML code that needs proper wrapping.
|
|
227
|
+
*
|
|
228
|
+
* Returns match info if raw PlantUML is found outside of Confluence macros.
|
|
229
|
+
* This is used to detect when LLMs put raw @startuml blocks in content
|
|
230
|
+
* instead of using the buffer_edit_xhtml insert-plantuml operation.
|
|
231
|
+
*
|
|
232
|
+
* @param content - Content to check for raw PlantUML
|
|
233
|
+
* @returns Object with detected flag and hint, or null if no issues
|
|
234
|
+
*/
|
|
235
|
+
export function detectRawPlantUml(content) {
|
|
236
|
+
// Check for raw @startuml blocks not already inside CDATA
|
|
237
|
+
const rawMatch = content.match(/(?<!\[CDATA\[\s*\n?)(@startuml[\s\S]*?@enduml)/);
|
|
238
|
+
// Also check for markdown-style plantuml blocks
|
|
239
|
+
const markdownMatch = content.match(/```plantuml\s*\n[\s\S]*?```/);
|
|
240
|
+
if (rawMatch || markdownMatch) {
|
|
241
|
+
// Make sure it's not already wrapped in a Confluence macro
|
|
242
|
+
if (!content.includes('<ac:structured-macro ac:name="plantuml"')) {
|
|
243
|
+
return {
|
|
244
|
+
detected: true,
|
|
245
|
+
hint: "Use buffer_edit_xhtml with operation='insert-plantuml' to add PlantUML diagrams. Call help(topic='plantuml') for the correct workflow.",
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=plantuml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plantuml.js","sourceRoot":"","sources":["../../../src/utils/xhtml/plantuml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS-like Selector Engine for Confluence XHTML
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Tag name: p, h1, table
|
|
6
|
+
* - Namespaced: ac:structured-macro, ri:page
|
|
7
|
+
* - Attributes: [ac:name="plantuml"], ac:structured-macro[ac:name="code"]
|
|
8
|
+
* - Pseudo-selectors: :nth-child(2), :first-child, :last-child
|
|
9
|
+
* - Descendants: table tbody tr
|
|
10
|
+
* - Direct children: ul > li
|
|
11
|
+
*/
|
|
12
|
+
import type { Document } from "linkedom";
|
|
13
|
+
import type { SelectorResult } from "./types.js";
|
|
14
|
+
/**
|
|
15
|
+
* Check if a selector contains unsupported pseudo-selectors
|
|
16
|
+
* Returns the unsupported pseudo name or null
|
|
17
|
+
*/
|
|
18
|
+
export declare function findUnsupportedPseudo(selector: string): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Execute a selector query on a document
|
|
21
|
+
*
|
|
22
|
+
* @param document - DOM Document to search
|
|
23
|
+
* @param selector - CSS-like selector string
|
|
24
|
+
* @returns SelectorResult with matches
|
|
25
|
+
*/
|
|
26
|
+
export declare function querySelector(document: Document, selector: string): SelectorResult;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a selector is valid
|
|
29
|
+
*/
|
|
30
|
+
export declare function isValidSelector(selector: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Get a human-readable description of a selector
|
|
33
|
+
*/
|
|
34
|
+
export declare function describeSelector(selector: string): string;
|
|
35
|
+
//# sourceMappingURL=selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../../src/utils/xhtml/selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,YAAY,CAAC;AA8LhE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWrE;AAqGD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAsClF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+BzD"}
|