@bfra.me/doc-sync 0.1.1 → 0.1.3
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/lib/{chunk-LOB73H77.js → chunk-CUBMCGAY.js} +5 -2
- package/lib/{chunk-NC7YTZAL.js → chunk-DTXB5PMR.js} +3 -3
- package/lib/{chunk-6NKAJT2M.js → chunk-VHUUC45J.js} +35 -3
- package/lib/cli/index.js +3 -3
- package/lib/generators/index.js +1 -1
- package/lib/index.js +3 -3
- package/lib/orchestrator/index.js +3 -3
- package/lib/parsers/index.js +1 -1
- package/package.json +2 -2
- package/src/generators/component-mapper.ts +11 -1
- package/src/parsers/readme-parser.ts +55 -2
|
@@ -497,6 +497,9 @@ function isFeatureSection(heading, featureSections) {
|
|
|
497
497
|
function isInstallationSection(heading, tabSections) {
|
|
498
498
|
return tabSections.some((tab) => heading.includes(tab.toLowerCase()));
|
|
499
499
|
}
|
|
500
|
+
function escapeAngleBrackets(text) {
|
|
501
|
+
return text.replaceAll("<", "<").replaceAll(">", ">");
|
|
502
|
+
}
|
|
500
503
|
function mapFeatureSection(section) {
|
|
501
504
|
const lines = [];
|
|
502
505
|
lines.push(`## ${section.heading}`);
|
|
@@ -507,7 +510,7 @@ function mapFeatureSection(section) {
|
|
|
507
510
|
for (const feature of features) {
|
|
508
511
|
const icon = inferFeatureIcon(feature.title, feature.emoji);
|
|
509
512
|
lines.push(` <Card title="${sanitizeAttribute(feature.title)}" icon="${icon}">`);
|
|
510
|
-
lines.push(` ${feature.description}`);
|
|
513
|
+
lines.push(` ${escapeAngleBrackets(feature.description)}`);
|
|
511
514
|
lines.push(" </Card>");
|
|
512
515
|
}
|
|
513
516
|
lines.push("</CardGrid>");
|
|
@@ -1315,4 +1318,4 @@ export {
|
|
|
1315
1318
|
sanitizeTextContent,
|
|
1316
1319
|
validateMDXSyntax
|
|
1317
1320
|
};
|
|
1318
|
-
//# sourceMappingURL=chunk-
|
|
1321
|
+
//# sourceMappingURL=chunk-CUBMCGAY.js.map
|
|
@@ -2,12 +2,12 @@ import {
|
|
|
2
2
|
generateMDXDocument,
|
|
3
3
|
mergeContent,
|
|
4
4
|
validateMDXSyntax
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-CUBMCGAY.js";
|
|
6
6
|
import {
|
|
7
7
|
analyzePublicAPI,
|
|
8
8
|
parsePackageComplete,
|
|
9
9
|
parseReadmeFile
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-VHUUC45J.js";
|
|
11
11
|
import {
|
|
12
12
|
createHeadingPattern,
|
|
13
13
|
extractCodeBlocks,
|
|
@@ -710,4 +710,4 @@ export {
|
|
|
710
710
|
createSyncOrchestrator,
|
|
711
711
|
isValidFilePath
|
|
712
712
|
};
|
|
713
|
-
//# sourceMappingURL=chunk-
|
|
713
|
+
//# sourceMappingURL=chunk-DTXB5PMR.js.map
|
|
@@ -1074,11 +1074,11 @@ function extractTextFromNode(node) {
|
|
|
1074
1074
|
}
|
|
1075
1075
|
function serializeNode(node) {
|
|
1076
1076
|
if (node.type === "paragraph") {
|
|
1077
|
-
return
|
|
1077
|
+
return serializeInlineContent(node);
|
|
1078
1078
|
}
|
|
1079
1079
|
if (node.type === "heading") {
|
|
1080
1080
|
const prefix = "#".repeat(node.depth);
|
|
1081
|
-
return `${prefix} ${
|
|
1081
|
+
return `${prefix} ${serializeInlineContent(node)}`;
|
|
1082
1082
|
}
|
|
1083
1083
|
if (node.type === "code") {
|
|
1084
1084
|
return `\`\`\`${node.lang ?? ""}
|
|
@@ -1108,6 +1108,38 @@ ${node.value}
|
|
|
1108
1108
|
}
|
|
1109
1109
|
return extractTextFromNode(node);
|
|
1110
1110
|
}
|
|
1111
|
+
function serializeInlineContent(node) {
|
|
1112
|
+
if ("value" in node && typeof node.value === "string") {
|
|
1113
|
+
return node.value;
|
|
1114
|
+
}
|
|
1115
|
+
if (!("children" in node) || !Array.isArray(node.children)) {
|
|
1116
|
+
return "";
|
|
1117
|
+
}
|
|
1118
|
+
return node.children.map((child) => {
|
|
1119
|
+
if (child.type === "strong") {
|
|
1120
|
+
return `**${serializeInlineContent(child)}**`;
|
|
1121
|
+
}
|
|
1122
|
+
if (child.type === "emphasis") {
|
|
1123
|
+
return `*${serializeInlineContent(child)}*`;
|
|
1124
|
+
}
|
|
1125
|
+
if (child.type === "inlineCode") {
|
|
1126
|
+
return `\`${"value" in child ? child.value : ""}\``;
|
|
1127
|
+
}
|
|
1128
|
+
if (child.type === "link") {
|
|
1129
|
+
const text = serializeInlineContent(child);
|
|
1130
|
+
return `[${text}](${"url" in child ? child.url : ""})`;
|
|
1131
|
+
}
|
|
1132
|
+
if (child.type === "image") {
|
|
1133
|
+
const alt = "alt" in child ? child.alt : "";
|
|
1134
|
+
const url = "url" in child ? child.url : "";
|
|
1135
|
+
return ``;
|
|
1136
|
+
}
|
|
1137
|
+
if ("value" in child && typeof child.value === "string") {
|
|
1138
|
+
return child.value;
|
|
1139
|
+
}
|
|
1140
|
+
return serializeInlineContent(child);
|
|
1141
|
+
}).join("");
|
|
1142
|
+
}
|
|
1111
1143
|
function serializeTable(node) {
|
|
1112
1144
|
if (node.type !== "table" || !("children" in node)) {
|
|
1113
1145
|
return "";
|
|
@@ -1230,4 +1262,4 @@ export {
|
|
|
1230
1262
|
flattenSections,
|
|
1231
1263
|
getTableOfContents
|
|
1232
1264
|
};
|
|
1233
|
-
//# sourceMappingURL=chunk-
|
|
1265
|
+
//# sourceMappingURL=chunk-VHUUC45J.js.map
|
package/lib/cli/index.js
CHANGED
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
createPackageScanner,
|
|
4
4
|
createSyncOrchestrator,
|
|
5
5
|
createValidationPipeline
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-DTXB5PMR.js";
|
|
7
7
|
import {
|
|
8
8
|
generateMDXDocument,
|
|
9
9
|
mergeContent
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-CUBMCGAY.js";
|
|
11
11
|
import "../chunk-ROLA7SBB.js";
|
|
12
12
|
import {
|
|
13
13
|
getUnscopedName
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-VHUUC45J.js";
|
|
15
15
|
import "../chunk-GZ2MP3VN.js";
|
|
16
16
|
import "../chunk-45NROJIG.js";
|
|
17
17
|
|
package/lib/generators/index.js
CHANGED
package/lib/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isValidFilePath,
|
|
9
9
|
validateContentString,
|
|
10
10
|
validateDocument
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DTXB5PMR.js";
|
|
12
12
|
import {
|
|
13
13
|
cleanCodeExample,
|
|
14
14
|
createBadge,
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
validateMarkerPairing,
|
|
46
46
|
wrapAutoSection,
|
|
47
47
|
wrapManualSection
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-CUBMCGAY.js";
|
|
49
49
|
import {
|
|
50
50
|
SENTINEL_MARKERS
|
|
51
51
|
} from "./chunk-ROLA7SBB.js";
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
parseReadmeFile,
|
|
105
105
|
parseSourceContent,
|
|
106
106
|
parseSourceFile
|
|
107
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-VHUUC45J.js";
|
|
108
108
|
import "./chunk-DRBRT57F.js";
|
|
109
109
|
import {
|
|
110
110
|
createHeadingPattern,
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
isValidFilePath,
|
|
9
9
|
validateContentString,
|
|
10
10
|
validateDocument
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
11
|
+
} from "../chunk-DTXB5PMR.js";
|
|
12
|
+
import "../chunk-CUBMCGAY.js";
|
|
13
13
|
import "../chunk-ROLA7SBB.js";
|
|
14
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-VHUUC45J.js";
|
|
15
15
|
import "../chunk-GZ2MP3VN.js";
|
|
16
16
|
import "../chunk-45NROJIG.js";
|
|
17
17
|
export {
|
package/lib/parsers/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bfra.me/doc-sync",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Intelligent documentation synchronization engine for automatic Astro Starlight site updates",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"remark-parse": "11.0.0",
|
|
83
83
|
"ts-morph": "27.0.2",
|
|
84
84
|
"unified": "11.0.5",
|
|
85
|
-
"zod": "4.1
|
|
85
|
+
"zod": "4.2.1",
|
|
86
86
|
"@bfra.me/es": "0.1.0"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
@@ -111,6 +111,16 @@ function isInstallationSection(heading: string, tabSections: readonly string[]):
|
|
|
111
111
|
return tabSections.some(tab => heading.includes(tab.toLowerCase()))
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Escape angle brackets in text to prevent MDX JSX tag misinterpretation
|
|
116
|
+
* This is applied to section content to prevent TypeScript generics like Result<T, E>
|
|
117
|
+
* from being interpreted as unclosed JSX tags
|
|
118
|
+
*/
|
|
119
|
+
function escapeAngleBrackets(text: string): string {
|
|
120
|
+
// Escape all < and > to HTML entities
|
|
121
|
+
return text.replaceAll('<', '<').replaceAll('>', '>')
|
|
122
|
+
}
|
|
123
|
+
|
|
114
124
|
function mapFeatureSection(section: ReadmeSection): string {
|
|
115
125
|
const lines: string[] = []
|
|
116
126
|
|
|
@@ -124,7 +134,7 @@ function mapFeatureSection(section: ReadmeSection): string {
|
|
|
124
134
|
for (const feature of features) {
|
|
125
135
|
const icon = inferFeatureIcon(feature.title, feature.emoji)
|
|
126
136
|
lines.push(` <Card title="${sanitizeAttribute(feature.title)}" icon="${icon}">`)
|
|
127
|
-
lines.push(` ${feature.description}`)
|
|
137
|
+
lines.push(` ${escapeAngleBrackets(feature.description)}`)
|
|
128
138
|
lines.push(' </Card>')
|
|
129
139
|
}
|
|
130
140
|
lines.push('</CardGrid>')
|
|
@@ -183,12 +183,12 @@ function extractTextFromNode(node: RootContent): string {
|
|
|
183
183
|
|
|
184
184
|
function serializeNode(node: RootContent): string {
|
|
185
185
|
if (node.type === 'paragraph') {
|
|
186
|
-
return
|
|
186
|
+
return serializeInlineContent(node)
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
if (node.type === 'heading') {
|
|
190
190
|
const prefix = '#'.repeat(node.depth)
|
|
191
|
-
return `${prefix} ${
|
|
191
|
+
return `${prefix} ${serializeInlineContent(node)}`
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
if (node.type === 'code') {
|
|
@@ -227,6 +227,59 @@ function serializeNode(node: RootContent): string {
|
|
|
227
227
|
return extractTextFromNode(node)
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Serialize inline content preserving markdown formatting like **bold**, *italic*, `code`, etc.
|
|
232
|
+
*/
|
|
233
|
+
function serializeInlineContent(node: RootContent): string {
|
|
234
|
+
if ('value' in node && typeof node.value === 'string') {
|
|
235
|
+
return node.value
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (!('children' in node) || !Array.isArray(node.children)) {
|
|
239
|
+
return ''
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return (node.children as RootContent[])
|
|
243
|
+
.map(child => {
|
|
244
|
+
// Handle strong (bold) text
|
|
245
|
+
if (child.type === 'strong') {
|
|
246
|
+
return `**${serializeInlineContent(child)}**`
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Handle emphasis (italic) text
|
|
250
|
+
if (child.type === 'emphasis') {
|
|
251
|
+
return `*${serializeInlineContent(child)}*`
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Handle inline code
|
|
255
|
+
if (child.type === 'inlineCode') {
|
|
256
|
+
return `\`${'value' in child ? child.value : ''}\``
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Handle links
|
|
260
|
+
if (child.type === 'link') {
|
|
261
|
+
const text = serializeInlineContent(child)
|
|
262
|
+
return `[${text}](${'url' in child ? child.url : ''})`
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Handle images
|
|
266
|
+
if (child.type === 'image') {
|
|
267
|
+
const alt = 'alt' in child ? child.alt : ''
|
|
268
|
+
const url = 'url' in child ? child.url : ''
|
|
269
|
+
return ``
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Handle plain text
|
|
273
|
+
if ('value' in child && typeof child.value === 'string') {
|
|
274
|
+
return child.value
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Recursively handle other inline elements
|
|
278
|
+
return serializeInlineContent(child)
|
|
279
|
+
})
|
|
280
|
+
.join('')
|
|
281
|
+
}
|
|
282
|
+
|
|
230
283
|
function serializeTable(node: RootContent): string {
|
|
231
284
|
if (node.type !== 'table' || !('children' in node)) {
|
|
232
285
|
return ''
|