|
| 1 | +'use strict' |
| 2 | + |
| 3 | +const { Parser } = require('acorn') |
| 4 | +const { importAssertions } = require('acorn-import-assertions'); |
| 5 | + |
| 6 | +const acornOpts = { |
| 7 | + ecmaVersion: 'latest', |
| 8 | + sourceType: 'module' |
| 9 | +} |
| 10 | + |
| 11 | +const parser = Parser.extend(importAssertions) |
| 12 | + |
| 13 | +function warn (txt) { |
| 14 | + process.emitWarning(txt, 'get-esm-exports') |
| 15 | +} |
| 16 | + |
| 17 | +function getEsmExports (moduleStr) { |
| 18 | + const exportedNames = new Set() |
| 19 | + const tree = parser.parse(moduleStr, acornOpts) |
| 20 | + for (const node of tree.body) { |
| 21 | + if (!node.type.startsWith('Export')) continue |
| 22 | + switch (node.type) { |
| 23 | + case 'ExportNamedDeclaration': |
| 24 | + if (node.declaration) { |
| 25 | + parseDeclaration(node, exportedNames) |
| 26 | + } else { |
| 27 | + parseSpecifiers(node, exportedNames) |
| 28 | + } |
| 29 | + break |
| 30 | + case 'ExportDefaultDeclaration': |
| 31 | + exportedNames.add('default') |
| 32 | + break |
| 33 | + case 'ExportAllDeclaration': |
| 34 | + if (node.exported) { |
| 35 | + exportedNames.add(node.exported.name) |
| 36 | + } else { |
| 37 | + exportedNames.add('*') |
| 38 | + } |
| 39 | + break |
| 40 | + default: |
| 41 | + warn('unrecognized export type: ' + node.type) |
| 42 | + } |
| 43 | + } |
| 44 | + return Array.from(exportedNames) |
| 45 | +} |
| 46 | + |
| 47 | +function parseDeclaration (node, exportedNames) { |
| 48 | + switch (node.declaration.type) { |
| 49 | + case 'FunctionDeclaration': |
| 50 | + exportedNames.add(node.declaration.id.name) |
| 51 | + break |
| 52 | + case 'VariableDeclaration': |
| 53 | + for (const varDecl of node.declaration.declarations) { |
| 54 | + parseVariableDeclaration(varDecl, exportedNames) |
| 55 | + } |
| 56 | + break |
| 57 | + case 'ClassDeclaration': |
| 58 | + exportedNames.add(node.declaration.id.name) |
| 59 | + break |
| 60 | + default: |
| 61 | + warn('unknown declaration type: ' + node.delcaration.type) |
| 62 | + } |
| 63 | +} |
| 64 | + |
| 65 | +function parseVariableDeclaration (node, exportedNames) { |
| 66 | + switch (node.id.type) { |
| 67 | + case 'Identifier': |
| 68 | + exportedNames.add(node.id.name) |
| 69 | + break |
| 70 | + case 'ObjectPattern': |
| 71 | + for (const prop of node.id.properties) { |
| 72 | + exportedNames.add(prop.value.name) |
| 73 | + } |
| 74 | + break |
| 75 | + case 'ArrayPattern': |
| 76 | + for (const elem of node.id.elements) { |
| 77 | + exportedNames.add(elem.name) |
| 78 | + } |
| 79 | + break |
| 80 | + default: |
| 81 | + warn('unknown variable declaration type: ' + node.id.type) |
| 82 | + } |
| 83 | +} |
| 84 | + |
| 85 | +function parseSpecifiers (node, exportedNames) { |
| 86 | + for (const specifier of node.specifiers) { |
| 87 | + if (specifier.exported.type === 'Identifier') { |
| 88 | + exportedNames.add(specifier.exported.name) |
| 89 | + } else if (specifier.exported.type === 'Literal') { |
| 90 | + exportedNames.add(specifier.exported.value) |
| 91 | + } else { |
| 92 | + warn('unrecognized specifier type: ' + specifier.exported.type) |
| 93 | + } |
| 94 | + } |
| 95 | +} |
| 96 | + |
| 97 | +module.exports = getEsmExports |
0 commit comments