@mintlify/common
Version:
Commonly shared code within Mintlify
113 lines (112 loc) • 5.8 kB
JavaScript
import { jsx, toJs } from 'estree-util-to-js';
import { visit } from 'unist-util-visit';
import { nodeIncludesExport } from './nodeIncludesExport.js';
import { addExportPrefix } from './resolveImport/addExportPrefix.js';
/**
*
* @returns map of export names and their content
*/
export const getExportMapFromTree = (tree) => {
var _a;
const exportMap = {};
visit(tree, (node) => {
if (!nodeIncludesExport(node))
return;
for (const bodyChild of node.data.estree.body) {
// Handle ExportDefaultDeclaration (export default ...)
if (bodyChild.type === 'ExportDefaultDeclaration') {
// If it's export default SomeIdentifier, find the original declaration
if (bodyChild.declaration.type === 'Identifier') {
const originalDeclaration = findDeclarationInTree(bodyChild.declaration.name, node);
if (originalDeclaration) {
const wrappedNode = structuredClone(node);
wrappedNode.data.estree.body = [originalDeclaration];
const value = toJs(wrappedNode.data.estree, { handlers: jsx }).value;
exportMap['default'] = value;
continue;
}
}
// Otherwise, use the export statement directly (for inline exports like export default function() {})
const isolatedExport = structuredClone(node);
isolatedExport.data.estree.body = [bodyChild];
const value = toJs(isolatedExport.data.estree, { handlers: jsx }).value;
exportMap['default'] = value;
continue;
}
// Handle ExportNamedDeclaration with specifiers (export { name })
if (bodyChild.type === 'ExportNamedDeclaration' && bodyChild.specifiers.length > 0) {
for (const specifier of bodyChild.specifiers) {
const localName = specifier.local.name;
const exportedName = specifier.exported.name;
// Find the original declaration
const originalDeclaration = findDeclarationInTree(localName, node);
if (originalDeclaration) {
const wrappedNode = structuredClone(node);
wrappedNode.data.estree.body = [originalDeclaration];
const value = toJs(wrappedNode.data.estree, { handlers: jsx }).value;
exportMap[exportedName] = value;
}
}
continue;
}
// Handle direct exports (export const/let/var/function/class ...)
if (bodyChild.type === 'ExportNamedDeclaration' && bodyChild.declaration) {
// Variable declarations
if (bodyChild.declaration.type === 'VariableDeclaration') {
for (const declaration of bodyChild.declaration.declarations) {
if (declaration.id.type !== 'Identifier')
continue;
if (declaration.init == null)
continue;
// Sometimes when more than one exports are defined next to each other, the body includes multiple exports so we isolate the export we are looking for.
const isolatedExport = structuredClone(node);
isolatedExport.data.estree.body = [bodyChild];
const value = toJs(isolatedExport.data.estree, { handlers: jsx }).value;
exportMap[declaration.id.name] = value;
}
}
// Function declarations
else if (bodyChild.declaration.type === 'FunctionDeclaration' && bodyChild.declaration.id) {
const isolatedExport = structuredClone(node);
isolatedExport.data.estree.body = [bodyChild];
const value = toJs(isolatedExport.data.estree, { handlers: jsx }).value;
exportMap[bodyChild.declaration.id.name] = value;
}
// Class declarations
else if (bodyChild.declaration.type === 'ClassDeclaration' && bodyChild.declaration.id) {
const isolatedExport = structuredClone(node);
isolatedExport.data.estree.body = [bodyChild];
const value = toJs(isolatedExport.data.estree, { handlers: jsx }).value;
exportMap[bodyChild.declaration.id.name] = value;
}
}
}
});
// Add "export " prefix to values that don't already start with "export"
for (const [key, value] of Object.entries(exportMap)) {
exportMap[key] = (_a = addExportPrefix(value)) !== null && _a !== void 0 ? _a : '';
}
return exportMap;
};
/**
* Find a declaration by name in the tree
*/
function findDeclarationInTree(name, node) {
var _a, _b;
for (const bodyChild of node.data.estree.body) {
if (bodyChild.type === 'VariableDeclaration') {
for (const declaration of bodyChild.declarations) {
if (declaration.id.type === 'Identifier' && declaration.id.name === name) {
return bodyChild;
}
}
}
else if (bodyChild.type === 'FunctionDeclaration' && ((_a = bodyChild.id) === null || _a === void 0 ? void 0 : _a.name) === name) {
return bodyChild;
}
else if (bodyChild.type === 'ClassDeclaration' && ((_b = bodyChild.id) === null || _b === void 0 ? void 0 : _b.name) === name) {
return bodyChild;
}
}
return null;
}