@mintlify/common 1.0.939 → 1.0.940
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.
|
@@ -22,110 +22,208 @@ function getVisibilityFor(node) {
|
|
|
22
22
|
}
|
|
23
23
|
return undefined;
|
|
24
24
|
}
|
|
25
|
-
function getStringAttribute(node, name) {
|
|
26
|
-
for (const attr of node.attributes) {
|
|
27
|
-
if (attr.type === 'mdxJsxAttribute' && attr.name === name && typeof attr.value === 'string') {
|
|
28
|
-
return attr.value;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
25
|
// `export * from` is intentionally ignored: it exposes no statically-knowable
|
|
34
26
|
// names and creates no page-local JSX bindings in MDX, so there is nothing to
|
|
35
|
-
// collect
|
|
36
|
-
function collectEsmIdentifiers(
|
|
27
|
+
// collect.
|
|
28
|
+
function collectEsmIdentifiers(node) {
|
|
37
29
|
var _a, _b, _c;
|
|
38
30
|
const names = new Set();
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
names.add(specifier.local.name);
|
|
46
|
-
}
|
|
31
|
+
if (node.type !== 'mdxjsEsm')
|
|
32
|
+
return names;
|
|
33
|
+
for (const statement of (_c = (_b = (_a = node.data) === null || _a === void 0 ? void 0 : _a.estree) === null || _b === void 0 ? void 0 : _b.body) !== null && _c !== void 0 ? _c : []) {
|
|
34
|
+
if (statement.type === 'ImportDeclaration') {
|
|
35
|
+
for (const specifier of statement.specifiers) {
|
|
36
|
+
names.add(specifier.local.name);
|
|
47
37
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
38
|
+
}
|
|
39
|
+
if (statement.type === 'ExportNamedDeclaration') {
|
|
40
|
+
if (statement.declaration) {
|
|
41
|
+
if (statement.declaration.type === 'VariableDeclaration') {
|
|
42
|
+
for (const declarator of statement.declaration.declarations) {
|
|
43
|
+
if (declarator.id.type === 'Identifier') {
|
|
44
|
+
names.add(declarator.id.name);
|
|
55
45
|
}
|
|
56
46
|
}
|
|
57
|
-
else if (statement.declaration.id) {
|
|
58
|
-
names.add(statement.declaration.id.name);
|
|
59
|
-
}
|
|
60
47
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (specifier.local.type === 'Identifier') {
|
|
64
|
-
names.add(specifier.local.name);
|
|
65
|
-
}
|
|
66
|
-
if (specifier.exported.type === 'Identifier') {
|
|
67
|
-
names.add(specifier.exported.name);
|
|
68
|
-
}
|
|
48
|
+
else if (statement.declaration.id) {
|
|
49
|
+
names.add(statement.declaration.id.name);
|
|
69
50
|
}
|
|
70
51
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
|
|
52
|
+
// Re-exports: `export { Panel } from '...'` keep names in specifiers
|
|
53
|
+
for (const specifier of statement.specifiers) {
|
|
54
|
+
if (specifier.local.type === 'Identifier') {
|
|
55
|
+
names.add(specifier.local.name);
|
|
56
|
+
}
|
|
57
|
+
if (specifier.exported.type === 'Identifier') {
|
|
58
|
+
names.add(specifier.exported.name);
|
|
76
59
|
}
|
|
77
60
|
}
|
|
78
61
|
}
|
|
62
|
+
if (statement.type === 'ExportDefaultDeclaration') {
|
|
63
|
+
const declaration = statement.declaration;
|
|
64
|
+
if ((declaration.type === 'FunctionDeclaration' || declaration.type === 'ClassDeclaration') &&
|
|
65
|
+
declaration.id) {
|
|
66
|
+
names.add(declaration.id.name);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
79
69
|
}
|
|
80
70
|
return names;
|
|
81
71
|
}
|
|
82
|
-
function
|
|
83
|
-
return
|
|
72
|
+
function isRecord(value) {
|
|
73
|
+
return typeof value === 'object' && value !== null;
|
|
74
|
+
}
|
|
75
|
+
function getJsxReferenceBaseName(name) {
|
|
76
|
+
let current = name;
|
|
77
|
+
while (isRecord(current) && current.type === 'JSXMemberExpression') {
|
|
78
|
+
current = current.object;
|
|
79
|
+
}
|
|
80
|
+
if (isRecord(current) && current.type === 'JSXIdentifier' && typeof current.name === 'string') {
|
|
81
|
+
return current.name;
|
|
82
|
+
}
|
|
83
|
+
return undefined;
|
|
84
84
|
}
|
|
85
|
-
|
|
85
|
+
// Walks an estree for JSX component references, e.g. `<Logo />` within
|
|
86
|
+
// `export const Header = () => <Logo />` or `{<Demo />}` expressions.
|
|
87
|
+
function collectEstreeJsxNames(estree, names) {
|
|
88
|
+
const queue = [estree];
|
|
89
|
+
const seen = new Set();
|
|
90
|
+
while (queue.length > 0) {
|
|
91
|
+
const current = queue.pop();
|
|
92
|
+
if (Array.isArray(current)) {
|
|
93
|
+
queue.push(...current);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (!isRecord(current) || seen.has(current))
|
|
97
|
+
continue;
|
|
98
|
+
seen.add(current);
|
|
99
|
+
if (current.type === 'JSXOpeningElement') {
|
|
100
|
+
const baseName = getJsxReferenceBaseName(current.name);
|
|
101
|
+
// Lowercase JSX names are intrinsic elements, never component bindings.
|
|
102
|
+
if (baseName && /^[A-Z]/.test(baseName))
|
|
103
|
+
names.add(baseName);
|
|
104
|
+
}
|
|
105
|
+
queue.push(...Object.values(current));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// JSX rendered inside an ESM node's own declarations, so stripping `Header`
|
|
109
|
+
// can also pull in helpers that only exist to serve it.
|
|
110
|
+
function collectJsxReferences(node) {
|
|
86
111
|
var _a;
|
|
87
|
-
|
|
88
|
-
// ESM is dropped wholesale even when kept content references its components.
|
|
112
|
+
const names = new Set();
|
|
89
113
|
if (node.type === 'mdxjsEsm') {
|
|
90
|
-
|
|
114
|
+
collectEstreeJsxNames((_a = node.data) === null || _a === void 0 ? void 0 : _a.estree, names);
|
|
91
115
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
return names;
|
|
117
|
+
}
|
|
118
|
+
// Classifies every JSX component usage on the page: names used only inside
|
|
119
|
+
// `<Visibility for="humans">` land in `hiddenNames`, everything else in
|
|
120
|
+
// `visibleNames`. Usage inside an agents block counts as visible since that
|
|
121
|
+
// content survives into the markdown output.
|
|
122
|
+
function collectJsxUsage(nodes, insideHumans, hiddenNames, visibleNames) {
|
|
123
|
+
var _a, _b;
|
|
124
|
+
for (const node of nodes) {
|
|
125
|
+
let childInsideHumans = insideHumans;
|
|
126
|
+
if (isMdxJsxElement(node)) {
|
|
127
|
+
if (node.name === 'Visibility') {
|
|
128
|
+
if (getVisibilityFor(node) === 'humans')
|
|
129
|
+
childInsideHumans = true;
|
|
97
130
|
}
|
|
98
|
-
|
|
99
|
-
|
|
131
|
+
else {
|
|
132
|
+
const baseName = (_a = node.name) === null || _a === void 0 ? void 0 : _a.split('.')[0];
|
|
133
|
+
// Lowercase JSX names are intrinsic elements, never component bindings.
|
|
134
|
+
if (baseName && /^[A-Z]/.test(baseName)) {
|
|
135
|
+
(insideHumans ? hiddenNames : visibleNames).add(baseName);
|
|
136
|
+
}
|
|
100
137
|
}
|
|
101
138
|
}
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
139
|
+
// Expression-embedded usages like `{<Demo />}` live in estree, not mdast.
|
|
140
|
+
if (node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression') {
|
|
141
|
+
collectEstreeJsxNames((_b = node.data) === null || _b === void 0 ? void 0 : _b.estree, insideHumans ? hiddenNames : visibleNames);
|
|
142
|
+
}
|
|
143
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
144
|
+
collectJsxUsage(node.children, childInsideHumans, hiddenNames, visibleNames);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function transformChildren(children, esmToStrip) {
|
|
149
|
+
return children.flatMap((child) => transformNode(child, esmToStrip));
|
|
150
|
+
}
|
|
151
|
+
function transformNode(node, esmToStrip) {
|
|
152
|
+
// Snippet definitions are only stripped when every usage of the components
|
|
153
|
+
// they declare sits inside a `<Visibility for="humans">` block; JSX that the
|
|
154
|
+
// author left visible keeps its definition in the markdown output.
|
|
155
|
+
if (node.type === 'mdxjsEsm') {
|
|
156
|
+
return esmToStrip.has(node) ? [] : [node];
|
|
157
|
+
}
|
|
158
|
+
if (isMdxJsxElement(node) && node.name === 'Visibility') {
|
|
159
|
+
const audience = getVisibilityFor(node);
|
|
160
|
+
if (audience === 'humans') {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
if (audience === 'agents') {
|
|
164
|
+
return transformChildren(node.children, esmToStrip);
|
|
120
165
|
}
|
|
121
166
|
}
|
|
122
167
|
if ('children' in node && Array.isArray(node.children)) {
|
|
123
|
-
const next = transformChildren(node.children,
|
|
168
|
+
const next = transformChildren(node.children, esmToStrip);
|
|
124
169
|
node.children = next;
|
|
125
170
|
}
|
|
126
171
|
return [node];
|
|
127
172
|
}
|
|
128
173
|
export const remarkVisibilityForMarkdown = () => (tree) => {
|
|
129
|
-
|
|
130
|
-
|
|
174
|
+
var _a, _b, _c, _d;
|
|
175
|
+
const hiddenNames = new Set();
|
|
176
|
+
const visibleNames = new Set();
|
|
177
|
+
collectJsxUsage(tree.children, false, hiddenNames, visibleNames);
|
|
178
|
+
const esmNodes = tree.children.filter((child) => child.type === 'mdxjsEsm');
|
|
179
|
+
const declaredNames = new Map(esmNodes.map((node) => [node, [...collectEsmIdentifiers(node)]]));
|
|
180
|
+
const referencedNames = new Map(esmNodes.map((node) => [node, [...collectJsxReferences(node)]]));
|
|
181
|
+
const esmToStrip = new Set();
|
|
182
|
+
// Keep-alive fixed point: a node with any visibly-used name keeps every
|
|
183
|
+
// name it declares or renders visible, so a visible `<PanelAlias />` keeps
|
|
184
|
+
// the `export const Panel = ...` node it aliases, and a kept `Footer` keeps
|
|
185
|
+
// the `Logo` helper it renders, even when both live in separate ESM nodes.
|
|
186
|
+
let visibleChanged = true;
|
|
187
|
+
while (visibleChanged) {
|
|
188
|
+
visibleChanged = false;
|
|
189
|
+
for (const node of esmNodes) {
|
|
190
|
+
const declared = (_a = declaredNames.get(node)) !== null && _a !== void 0 ? _a : [];
|
|
191
|
+
if (!declared.some((name) => visibleNames.has(name)))
|
|
192
|
+
continue;
|
|
193
|
+
for (const name of [...declared, ...((_b = referencedNames.get(node)) !== null && _b !== void 0 ? _b : [])]) {
|
|
194
|
+
if (!visibleNames.has(name)) {
|
|
195
|
+
visibleNames.add(name);
|
|
196
|
+
visibleChanged = true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Fixed point: stripping a node marks everything it declares or renders as
|
|
202
|
+
// hidden, so `export { Panel as PanelAlias }` pulls in the `export const
|
|
203
|
+
// Panel = ...` it aliases, and a stripped `Header` pulls in the `Logo`
|
|
204
|
+
// helper rendered only inside its body, instead of leaking their source.
|
|
205
|
+
let changed = true;
|
|
206
|
+
while (changed) {
|
|
207
|
+
changed = false;
|
|
208
|
+
for (const node of esmNodes) {
|
|
209
|
+
if (esmToStrip.has(node))
|
|
210
|
+
continue;
|
|
211
|
+
const names = (_c = declaredNames.get(node)) !== null && _c !== void 0 ? _c : [];
|
|
212
|
+
// Declared-but-never-rendered names don't block stripping: when a node
|
|
213
|
+
// mixes a hidden component with unused names, hiding wins over leaking.
|
|
214
|
+
const hiddenOnly = names.some((name) => hiddenNames.has(name)) &&
|
|
215
|
+
!names.some((name) => visibleNames.has(name));
|
|
216
|
+
if (!hiddenOnly)
|
|
217
|
+
continue;
|
|
218
|
+
esmToStrip.add(node);
|
|
219
|
+
// Visible names stay out of hiddenNames so the two sets stay disjoint.
|
|
220
|
+
for (const name of [...names, ...((_d = referencedNames.get(node)) !== null && _d !== void 0 ? _d : [])]) {
|
|
221
|
+
if (!hiddenNames.has(name) && !visibleNames.has(name)) {
|
|
222
|
+
hiddenNames.add(name);
|
|
223
|
+
changed = true;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
tree.children = transformChildren(tree.children, esmToStrip);
|
|
131
229
|
};
|