diff --git a/README.md b/README.md index b3522cd..a0a2f3b 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,6 @@ import { } from 'mlly' const { } = require('mlly') ``` - - ## Resolving ESM modules Several utilities to make ESM resolution easier: @@ -286,8 +284,6 @@ const foo = await import('bar') ### `findExports` -**Note:** API Of this function might be broken in a breaking change for code matcher - ```js import { findExports } from 'mlly' @@ -322,6 +318,32 @@ Outputs: ] ``` +### `findExportNames` + +Same as `findExports` but returns array of export names. + +```js +import { findExportNames } from 'mlly' + +// [ "foo", "bar", "baz", "default" ] +console.log(findExportNames(` +export const foo = 'bar' +export { bar, baz } +export default something +`)) +``` + +## `resolveModuleExportNames` + +Resolves module and reads its contents to extract possible export names using static analyzes. + +```js +import { resolveModuleExportNames } from 'mlly' + +// ["basename", "dirname", ... ] +console.log(await resolveModuleExportNames('pathe')) +``` + ## Evaluating Modules Set of utilities to evaluate ESM modules using `data:` imports diff --git a/src/analyze.ts b/src/analyze.ts index ce5fbf6..280c0c4 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -1,5 +1,7 @@ import { tokenizer } from 'acorn' import { matchAll } from './_utils' +import { resolvePath, ResolveOptions } from './resolve' +import { loadURL } from './utils' export interface ESMImport { type: 'static' | 'dynamic' @@ -144,6 +146,17 @@ export function findExports (code: string): ESMExport[] { }) } +export function findExportNames (code: string): string[] { + return findExports(code).flatMap(exp => exp.names) +} + +export async function resolveModuleExportNames (id: string, opts?: ResolveOptions): Promise { + const url = await resolvePath(id, opts) + const code = await loadURL(url) + const exports = findExports(code) + return exports.flatMap(exp => exp.names) +} + // --- Internal --- interface TokenLocation { diff --git a/test/exports.test.ts b/test/exports.test.ts index 8e48ef9..3577472 100644 --- a/test/exports.test.ts +++ b/test/exports.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest' -import { ESMExport, findExports } from '../src' +import { ESMExport, findExports, findExportNames, resolveModuleExportNames } from '../src' describe('findExports', () => { const tests: Record> = { @@ -115,3 +115,43 @@ describe('findExports', () => { expect(matches).to.have.lengthOf(2) }) }) + +describe('fineExportNames', () => { + it('findExportNames', () => { + expect(findExportNames(` + export const foo = 'bar' + export { bar, baz } + export default something + `)).toMatchInlineSnapshot(` + [ + "foo", + "bar", + "baz", + "default", + ] + `) + }) +}) + +describe('resolveModuleExportNames', () => { + it('resolveModuleExportNames', async () => { + expect(await resolveModuleExportNames('pathe')).toMatchInlineSnapshot(` + [ + "basename", + "delimiter", + "dirname", + "extname", + "format", + "isAbsolute", + "join", + "normalize", + "normalizeString", + "parse", + "relative", + "resolve", + "sep", + "toNamespacedPath", + ] + `) + }) +})