@mintlify/common 1.0.648 → 1.0.650
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/dist/rss/constants.d.ts +1 -0
- package/dist/rss/constants.js +1 -0
- package/dist/rss/dates.d.ts +4 -0
- package/dist/rss/dates.js +49 -0
- package/dist/rss/encodeContentAsHtml.d.ts +1 -0
- package/dist/rss/encodeContentAsHtml.js +40 -0
- package/dist/rss/enhanceSnippetsWithImportNames.d.ts +3 -0
- package/dist/rss/enhanceSnippetsWithImportNames.js +28 -0
- package/dist/rss/getV4FeedUpdates.d.ts +2 -0
- package/dist/rss/getV4FeedUpdates.js +53 -0
- package/dist/rss/index.d.ts +7 -2
- package/dist/rss/index.js +86 -10
- package/dist/rss/processUpdateNode.d.ts +6 -0
- package/dist/rss/processUpdateNode.js +10 -0
- package/dist/rss/resolveSnippets.d.ts +3 -0
- package/dist/rss/resolveSnippets.js +60 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/rss.d.ts +23 -1
- package/package.json +7 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const UPDATE_MAX = 15;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const UPDATE_MAX = 15;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RootContent } from 'mdast';
|
|
2
|
+
import type { UpdateMDXComponent } from './index.js';
|
|
3
|
+
export declare const getDateForNode: (node: RootContent, lineBlame: Record<number, string>) => string;
|
|
4
|
+
export declare const getMostRepresentativeDate: (updateComponent: UpdateMDXComponent, lineBlame: Record<number, string>, defaultDate: string) => string;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export const getDateForNode = (node, lineBlame) => {
|
|
2
|
+
if (!node.position) {
|
|
3
|
+
return new Date().toISOString();
|
|
4
|
+
}
|
|
5
|
+
const startLine = node.position.start.line;
|
|
6
|
+
const blameDate = lineBlame[startLine];
|
|
7
|
+
if (blameDate) {
|
|
8
|
+
const parsedDate = new Date(blameDate);
|
|
9
|
+
if (!isNaN(parsedDate.getTime())) {
|
|
10
|
+
return parsedDate.toISOString();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return new Date().toISOString();
|
|
14
|
+
};
|
|
15
|
+
export const getMostRepresentativeDate = (updateComponent, lineBlame, defaultDate) => {
|
|
16
|
+
const dates = [];
|
|
17
|
+
const collectDates = (nodes) => {
|
|
18
|
+
for (const node of nodes) {
|
|
19
|
+
if (node.type !== 'heading' && node.position) {
|
|
20
|
+
const nodeDate = getDateForNode(node, lineBlame);
|
|
21
|
+
dates.push(nodeDate);
|
|
22
|
+
}
|
|
23
|
+
if ('children' in node && Array.isArray(node.children) && node.children.length > 0) {
|
|
24
|
+
collectDates(node.children);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
collectDates(updateComponent.children);
|
|
29
|
+
if (dates.length === 0) {
|
|
30
|
+
return defaultDate;
|
|
31
|
+
}
|
|
32
|
+
const dateCounts = new Map();
|
|
33
|
+
for (const date of dates) {
|
|
34
|
+
dateCounts.set(date, (dateCounts.get(date) || 0) + 1);
|
|
35
|
+
}
|
|
36
|
+
let mostCommonDate = defaultDate;
|
|
37
|
+
let maxCount = 0;
|
|
38
|
+
for (const [date, count] of dateCounts.entries()) {
|
|
39
|
+
if (count > maxCount) {
|
|
40
|
+
maxCount = count;
|
|
41
|
+
mostCommonDate = date;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const threshold = dates.length * 0.9;
|
|
45
|
+
if (maxCount >= threshold) {
|
|
46
|
+
return mostCommonDate;
|
|
47
|
+
}
|
|
48
|
+
return defaultDate;
|
|
49
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const encodeContentAsHtml: (content: string) => string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { fromHtml } from 'hast-util-from-html';
|
|
2
|
+
import rehypeStringify from 'rehype-stringify';
|
|
3
|
+
import remarkGfm from 'remark-gfm';
|
|
4
|
+
import remarkParse from 'remark-parse';
|
|
5
|
+
import remarkRehype from 'remark-rehype';
|
|
6
|
+
import { unified } from 'unified';
|
|
7
|
+
import { visit } from 'unist-util-visit';
|
|
8
|
+
const DANGEROUS_TAGS = ['script', 'iframe', 'object', 'embed', 'style'];
|
|
9
|
+
const rehypeRaw = () => {
|
|
10
|
+
return (tree) => {
|
|
11
|
+
visit(tree, 'raw', (raw, index, parent) => {
|
|
12
|
+
if ('value' in raw && parent && index !== undefined) {
|
|
13
|
+
const rawAst = fromHtml(raw.value, { fragment: true });
|
|
14
|
+
parent.children.splice(index, 1, ...rawAst.children);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const rehypeSanitizeDangerous = () => {
|
|
20
|
+
return (tree) => {
|
|
21
|
+
visit(tree, 'element', (node, index, parent) => {
|
|
22
|
+
if (parent && typeof index === 'number' && DANGEROUS_TAGS.includes(node.tagName)) {
|
|
23
|
+
parent.children.splice(index, 1);
|
|
24
|
+
return ['skip', index];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export const encodeContentAsHtml = (content) => {
|
|
30
|
+
const html = unified()
|
|
31
|
+
.use(remarkParse)
|
|
32
|
+
.use(remarkGfm)
|
|
33
|
+
.use(remarkRehype, { allowDangerousHtml: true })
|
|
34
|
+
.use(rehypeRaw)
|
|
35
|
+
.use(rehypeSanitizeDangerous)
|
|
36
|
+
.use(rehypeStringify, { allowDangerousHtml: true })
|
|
37
|
+
.processSync(content)
|
|
38
|
+
.toString();
|
|
39
|
+
return html;
|
|
40
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { findAndRemoveImports } from '../mdx/snippets/findAndRemoveImports.js';
|
|
11
|
+
export const enhanceSnippetsWithImportNames = (ast, snippets) => __awaiter(void 0, void 0, void 0, function* () {
|
|
12
|
+
const { importMap } = yield findAndRemoveImports(structuredClone(ast));
|
|
13
|
+
return snippets.map((snippet) => {
|
|
14
|
+
if (snippet.importNames && snippet.importNames.length > 0) {
|
|
15
|
+
return snippet;
|
|
16
|
+
}
|
|
17
|
+
let importSpecifiers = importMap[snippet.path];
|
|
18
|
+
if (!importSpecifiers) {
|
|
19
|
+
const pathWithSlash = snippet.path.startsWith('/') ? snippet.path : `/${snippet.path}`;
|
|
20
|
+
const pathWithoutSlash = snippet.path.startsWith('/') ? snippet.path.slice(1) : snippet.path;
|
|
21
|
+
importSpecifiers = importMap[pathWithSlash] || importMap[pathWithoutSlash];
|
|
22
|
+
}
|
|
23
|
+
if (importSpecifiers && importSpecifiers.length > 0) {
|
|
24
|
+
return Object.assign(Object.assign({}, snippet), { importNames: importSpecifiers.map((spec) => spec.name) });
|
|
25
|
+
}
|
|
26
|
+
return snippet;
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { getAST } from '../mdx/remark.js';
|
|
11
|
+
import { UPDATE_MAX } from './constants.js';
|
|
12
|
+
import { getDateForNode, getMostRepresentativeDate } from './dates.js';
|
|
13
|
+
import { enhanceSnippetsWithImportNames } from './enhanceSnippetsWithImportNames.js';
|
|
14
|
+
import { isUpdate } from './index.js';
|
|
15
|
+
import { processUpdateNode } from './processUpdateNode.js';
|
|
16
|
+
import { resolveSnippets } from './resolveSnippets.js';
|
|
17
|
+
export const getV4FeedUpdates = (rssFile) => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
const { content, lineBlame, snippets } = rssFile;
|
|
19
|
+
if (!content) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
const effectiveLineBlame = Object.keys(lineBlame).length > 0 ? lineBlame : { 1: new Date().toISOString() };
|
|
23
|
+
let ast;
|
|
24
|
+
try {
|
|
25
|
+
ast = getAST(content);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
if (snippets && snippets.length > 0) {
|
|
31
|
+
try {
|
|
32
|
+
const enhancedSnippets = yield enhanceSnippetsWithImportNames(ast, snippets);
|
|
33
|
+
ast = resolveSnippets(ast, enhancedSnippets);
|
|
34
|
+
}
|
|
35
|
+
catch (_a) { }
|
|
36
|
+
}
|
|
37
|
+
const updateComponents = ast.children.filter((child) => isUpdate(child));
|
|
38
|
+
if (updateComponents.length === 0) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
const allUpdates = [];
|
|
42
|
+
for (const updateComponent of updateComponents) {
|
|
43
|
+
const componentDate = getDateForNode(updateComponent, effectiveLineBlame);
|
|
44
|
+
const representativeDate = getMostRepresentativeDate(updateComponent, effectiveLineBlame, componentDate);
|
|
45
|
+
const updates = processUpdateNode({
|
|
46
|
+
updateNode: updateComponent,
|
|
47
|
+
date: representativeDate,
|
|
48
|
+
});
|
|
49
|
+
allUpdates.push(...updates);
|
|
50
|
+
}
|
|
51
|
+
const limitedUpdates = allUpdates.slice(0, UPDATE_MAX);
|
|
52
|
+
return limitedUpdates;
|
|
53
|
+
});
|
package/dist/rss/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { FrontmatterContent, Heading, Parent, Root, RootContent } from 'mdast';
|
|
2
2
|
import { MdxJsxFlowElement } from 'mdast-util-mdx-jsx';
|
|
3
|
-
import { RSSItemV2 } from '../types/rss.js';
|
|
4
|
-
export declare const UPDATE_MAX = 15;
|
|
3
|
+
import { RSSItemV2, SavedRssFileV4, SavedRssFileWithContent } from '../types/rss.js';
|
|
5
4
|
export type UpdateMDXComponent = MdxJsxFlowElement;
|
|
6
5
|
export declare const isFrontmatter: (node: RootContent | undefined) => node is FrontmatterContent;
|
|
7
6
|
export declare const isUpdate: (node: RootContent | undefined) => node is UpdateMDXComponent;
|
|
@@ -53,3 +52,9 @@ export declare const processUpdatePerMarkdownGroup: ({ updateNode, date, updates
|
|
|
53
52
|
date: string;
|
|
54
53
|
updatesByMarkdown: RootContent[][];
|
|
55
54
|
}) => RSSItemV2[];
|
|
55
|
+
export declare const isRSSFileV4: (rssFile: SavedRssFileWithContent | SavedRssFileV4) => rssFile is SavedRssFileV4;
|
|
56
|
+
export { enhanceSnippetsWithImportNames } from './enhanceSnippetsWithImportNames.js';
|
|
57
|
+
export { getV4FeedUpdates } from './getV4FeedUpdates.js';
|
|
58
|
+
export { resolveSnippets } from './resolveSnippets.js';
|
|
59
|
+
export { encodeContentAsHtml } from './encodeContentAsHtml.js';
|
|
60
|
+
export { UPDATE_MAX } from './constants.js';
|
package/dist/rss/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import slugify from '@sindresorhus/slugify';
|
|
2
2
|
import { stringifyTree } from '../mdx/index.js';
|
|
3
3
|
import { getArrayExpressionStringProperties, getObjectExpressionStringProperty, } from '../mdx/utils.js';
|
|
4
|
-
export const UPDATE_MAX = 15;
|
|
5
4
|
export const isFrontmatter = (node) => {
|
|
6
5
|
return (node === null || node === void 0 ? void 0 : node.type) === 'yaml';
|
|
7
6
|
};
|
|
@@ -14,15 +13,49 @@ export const isHeading = (node) => {
|
|
|
14
13
|
}
|
|
15
14
|
return node.type === 'heading';
|
|
16
15
|
};
|
|
16
|
+
// Standard HTML tags that should be included in RSS feeds
|
|
17
|
+
const STANDARD_HTML_TAGS = new Set([
|
|
18
|
+
'table',
|
|
19
|
+
'tr',
|
|
20
|
+
'td',
|
|
21
|
+
'th',
|
|
22
|
+
'thead',
|
|
23
|
+
'tbody',
|
|
24
|
+
'tfoot',
|
|
25
|
+
'p',
|
|
26
|
+
'div',
|
|
27
|
+
'span',
|
|
28
|
+
'a',
|
|
29
|
+
'br',
|
|
30
|
+
'hr',
|
|
31
|
+
'h1',
|
|
32
|
+
'h2',
|
|
33
|
+
'h3',
|
|
34
|
+
'h4',
|
|
35
|
+
'h5',
|
|
36
|
+
'h6',
|
|
37
|
+
'ul',
|
|
38
|
+
'ol',
|
|
39
|
+
'li',
|
|
40
|
+
'strong',
|
|
41
|
+
'em',
|
|
42
|
+
'b',
|
|
43
|
+
'i',
|
|
44
|
+
'u',
|
|
45
|
+
'img',
|
|
46
|
+
'figure',
|
|
47
|
+
'figcaption',
|
|
48
|
+
'blockquote',
|
|
49
|
+
'pre',
|
|
50
|
+
]);
|
|
17
51
|
export const isNormalMarkdown = (node) => {
|
|
18
52
|
if (!node) {
|
|
19
53
|
return false;
|
|
20
54
|
}
|
|
21
|
-
|
|
22
|
-
node.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
node.type !== 'inlineCode');
|
|
55
|
+
if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {
|
|
56
|
+
return STANDARD_HTML_TAGS.has(node.name || '');
|
|
57
|
+
}
|
|
58
|
+
return node.type !== 'code' && node.type !== 'inlineCode';
|
|
26
59
|
};
|
|
27
60
|
export const containsUpdates = (tree) => {
|
|
28
61
|
return tree.children.some((child) => isUpdate(child));
|
|
@@ -120,6 +153,42 @@ export const getMarkdownHeadingProps = (heading) => {
|
|
|
120
153
|
}
|
|
121
154
|
return { title, anchor };
|
|
122
155
|
};
|
|
156
|
+
const jsxToHtml = (node) => {
|
|
157
|
+
const tagName = node.name || 'div';
|
|
158
|
+
const attrs = node.attributes
|
|
159
|
+
.filter((attr) => attr.type === 'mdxJsxAttribute' && typeof attr.value === 'string')
|
|
160
|
+
.map((attr) => {
|
|
161
|
+
if (attr.type === 'mdxJsxAttribute' && attr.name !== 'className') {
|
|
162
|
+
return `${attr.name}="${attr.value}"`;
|
|
163
|
+
}
|
|
164
|
+
return '';
|
|
165
|
+
})
|
|
166
|
+
.filter(Boolean)
|
|
167
|
+
.join(' ');
|
|
168
|
+
const attrsStr = attrs ? ` ${attrs}` : '';
|
|
169
|
+
const childrenStr = node.children
|
|
170
|
+
.map((child) => {
|
|
171
|
+
if (child.type === 'mdxJsxFlowElement' || child.type === 'mdxJsxTextElement') {
|
|
172
|
+
return jsxToHtml(child);
|
|
173
|
+
}
|
|
174
|
+
if (child.type === 'text') {
|
|
175
|
+
return child.value;
|
|
176
|
+
}
|
|
177
|
+
return stringifyTree({ type: 'root', children: [child] }).trim();
|
|
178
|
+
})
|
|
179
|
+
.join('');
|
|
180
|
+
return `<${tagName}${attrsStr}>${childrenStr}</${tagName}>`;
|
|
181
|
+
};
|
|
182
|
+
const stringifyTreeForRSS = (tree) => {
|
|
183
|
+
return tree.children
|
|
184
|
+
.map((child) => {
|
|
185
|
+
if (child.type === 'mdxJsxFlowElement' || child.type === 'mdxJsxTextElement') {
|
|
186
|
+
return jsxToHtml(child);
|
|
187
|
+
}
|
|
188
|
+
return stringifyTree({ type: 'root', children: [child] }).trim();
|
|
189
|
+
})
|
|
190
|
+
.join('\n\n');
|
|
191
|
+
};
|
|
123
192
|
export const updateGroupToRSSItemV2 = ({ group, date, }) => {
|
|
124
193
|
const dateToUse = date || new Date().toISOString();
|
|
125
194
|
const heading = group[0];
|
|
@@ -128,7 +197,7 @@ export const updateGroupToRSSItemV2 = ({ group, date, }) => {
|
|
|
128
197
|
}
|
|
129
198
|
const { title, anchor } = getMarkdownHeadingProps(heading);
|
|
130
199
|
const content = group.slice(1);
|
|
131
|
-
const contentString =
|
|
200
|
+
const contentString = stringifyTreeForRSS({
|
|
132
201
|
type: 'root',
|
|
133
202
|
children: content,
|
|
134
203
|
});
|
|
@@ -155,13 +224,11 @@ export const getNewMarkdownUpdates = ({ newTree, previousTree, previousUpdates,
|
|
|
155
224
|
const firstUpdateInNewTree = newTree.children.find(isUpdate);
|
|
156
225
|
const firstUpdateInPreviousTree = previousTree.children.find(isUpdate);
|
|
157
226
|
if (!isUpdate(firstUpdateInNewTree) || !isUpdate(firstUpdateInPreviousTree)) {
|
|
158
|
-
// no last updates found to compare
|
|
159
227
|
return [];
|
|
160
228
|
}
|
|
161
229
|
const firstUpdateTitleInNewTree = getUpdateTitle(firstUpdateInNewTree);
|
|
162
230
|
const firstUpdateTitleInPreviousTree = getUpdateTitle(firstUpdateInPreviousTree);
|
|
163
231
|
if (firstUpdateTitleInNewTree !== firstUpdateTitleInPreviousTree) {
|
|
164
|
-
// last update component has changed
|
|
165
232
|
return [];
|
|
166
233
|
}
|
|
167
234
|
const newUpdates = splitChildrenAtHeadings(firstUpdateInNewTree.children);
|
|
@@ -191,6 +258,7 @@ export const containsMarkdownHeading = (updateNode, title) => {
|
|
|
191
258
|
child.children.some((child) => child.type === 'text' && child.value.includes(title)));
|
|
192
259
|
return containsHeading;
|
|
193
260
|
};
|
|
261
|
+
// soon to be deprecated, use processUpdateNode.ts instead
|
|
194
262
|
export const processUpdateNode = ({ updateNode, date, }) => {
|
|
195
263
|
const updates = [];
|
|
196
264
|
const nowOrOldDate = date || new Date().toISOString();
|
|
@@ -230,7 +298,7 @@ export const processUpdatePerNode = ({ updateNode, date, title, description, })
|
|
|
230
298
|
const anchor = slugify(label);
|
|
231
299
|
const categories = getTags(updateNode);
|
|
232
300
|
const contentNodes = updateNode.children.filter((child) => isNormalMarkdown(child));
|
|
233
|
-
const contentString =
|
|
301
|
+
const contentString = stringifyTreeForRSS({
|
|
234
302
|
type: 'root',
|
|
235
303
|
children: contentNodes,
|
|
236
304
|
});
|
|
@@ -256,3 +324,11 @@ export const processUpdatePerMarkdownGroup = ({ updateNode, date, updatesByMarkd
|
|
|
256
324
|
}
|
|
257
325
|
return updates;
|
|
258
326
|
};
|
|
327
|
+
export const isRSSFileV4 = (rssFile) => {
|
|
328
|
+
return rssFile.version === 'v4';
|
|
329
|
+
};
|
|
330
|
+
export { enhanceSnippetsWithImportNames } from './enhanceSnippetsWithImportNames.js';
|
|
331
|
+
export { getV4FeedUpdates } from './getV4FeedUpdates.js';
|
|
332
|
+
export { resolveSnippets } from './resolveSnippets.js';
|
|
333
|
+
export { encodeContentAsHtml } from './encodeContentAsHtml.js';
|
|
334
|
+
export { UPDATE_MAX } from './constants.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getRssPropsData, processUpdatePerNode } from './index.js';
|
|
2
|
+
export const processUpdateNode = ({ updateNode, date, }) => {
|
|
3
|
+
const { rssTitle, rssDescription } = getRssPropsData(updateNode);
|
|
4
|
+
return processUpdatePerNode({
|
|
5
|
+
updateNode,
|
|
6
|
+
date,
|
|
7
|
+
title: rssTitle,
|
|
8
|
+
description: rssDescription,
|
|
9
|
+
});
|
|
10
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { getAST } from '../mdx/remark.js';
|
|
2
|
+
export const resolveSnippets = (ast, snippets) => {
|
|
3
|
+
const snippetTreeMap = buildSnippetTreeMap(snippets);
|
|
4
|
+
const newChildren = [];
|
|
5
|
+
for (const child of ast.children) {
|
|
6
|
+
if (child.type === 'mdxJsxFlowElement' && 'name' in child && child.name) {
|
|
7
|
+
const componentName = String(child.name);
|
|
8
|
+
if (componentName === 'Snippet' && 'attributes' in child) {
|
|
9
|
+
const fileAttr = child.attributes.find((attr) => attr.type === 'mdxJsxAttribute' && attr.name === 'file');
|
|
10
|
+
if (fileAttr && fileAttr.value) {
|
|
11
|
+
const fileName = typeof fileAttr.value === 'string' ? fileAttr.value : fileAttr.value.value;
|
|
12
|
+
if (snippetTreeMap[fileName]) {
|
|
13
|
+
const snippetAst = snippetTreeMap[fileName];
|
|
14
|
+
newChildren.push(...snippetAst.children);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const fileNameOnly = fileName.split('/').pop();
|
|
18
|
+
if (fileNameOnly && snippetTreeMap[fileNameOnly]) {
|
|
19
|
+
const snippetAst = snippetTreeMap[fileNameOnly];
|
|
20
|
+
newChildren.push(...snippetAst.children);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (snippetTreeMap[componentName]) {
|
|
26
|
+
const snippetAst = snippetTreeMap[componentName];
|
|
27
|
+
newChildren.push(...snippetAst.children);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
newChildren.push(child);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
newChildren.push(child);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
ast.children = newChildren;
|
|
37
|
+
return ast;
|
|
38
|
+
};
|
|
39
|
+
const buildSnippetTreeMap = (snippets) => {
|
|
40
|
+
const map = {};
|
|
41
|
+
for (const snippet of snippets) {
|
|
42
|
+
try {
|
|
43
|
+
const snippetAst = getAST(snippet.content);
|
|
44
|
+
if ('importNames' in snippet && snippet.importNames && snippet.importNames.length > 0) {
|
|
45
|
+
for (const importName of snippet.importNames) {
|
|
46
|
+
map[importName] = snippetAst;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
map[snippet.path] = snippetAst;
|
|
50
|
+
const filename = snippet.path.split('/').pop();
|
|
51
|
+
if (filename && filename !== snippet.path) {
|
|
52
|
+
map[filename] = snippetAst;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error('Failed to parse snippet:', snippet.path, error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return map;
|
|
60
|
+
};
|