Skip to content

Commit

Permalink
Fix nested entry point resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
aryaemami59 committed Oct 22, 2024
1 parent b2755e2 commit 59e7805
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 47 deletions.
137 changes: 96 additions & 41 deletions src/api-extractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
getApiExtractor,
removeFiles,
toAbsolutePath,
toObjectEntry,
} from './utils'
import type {
ExperimentalDtsConfig,
Expand All @@ -22,6 +21,7 @@ import type {
IConfigFile,
IExtractorConfigPrepareOptions,
} from '@microsoft/api-extractor'
import type { InputOption } from 'rollup'

const logger = createLogger()

Expand Down Expand Up @@ -111,7 +111,6 @@ async function rollupDtsFiles(
for (let [out, sourceFileName] of Object.entries(
options.experimentalDts.entry,
)) {
out = path.basename(out)
/**
* **Source file name** (`src/index.ts`)
*
Expand Down Expand Up @@ -191,6 +190,84 @@ export async function runDtsRollup(
}
}

/**
* Converts an array of{@linkcode NormalizedOptions.entry | entry paths}
* into an object where the keys represent the output
* file names (without extensions) and the values
* represent the corresponding input file paths.
*
* @param arrayOfEntries - An array of file path entries as strings.
* @returns An object where the keys are the output file name and the values are the input file name.
*
* @example
* <caption>### Convert an array of entry points to an entry point object</caption>
*
* ```ts
* import { defineConfig } from 'tsup'
*
* export default defineConfig({
* entry: ['src/index.ts', 'src/types.ts'], // Becomes `{ index: 'src/index.ts', types: 'src/types.ts' }`
* format: ['esm', 'cjs'],
* })
* ```
*
* @internal
*/
const convertArrayEntriesToObjectEntries = (arrayOfEntries: string[]) => {
const objectEntries = Object.fromEntries(
arrayOfEntries.map(
(entry) =>
[
path.posix.join(
...entry
.split(path.posix.sep)
.slice(1, -1)
.concat(path.parse(entry).name),
),
entry,
] as const,
),
)

return objectEntries
}

/**
* Resolves and standardizes entry paths into an object format.
* If the provided entry is a string or an array of strings, it resolves
* any potential glob patterns using
* {@linkcode glob | tiny-glob's glob function}
* and converts the result into an entry object.
* If the input is already an object, it is returned as-is.
*
* @param entryPaths - The entry paths to resolve. Can be a string, an array of strings, or an object.
* @returns A {@linkcode Promise} that resolves to the standardized entry paths in object format.
*
* @example
*
* ```ts
* import { defineConfig } from 'tsup'
*
* export default defineConfig({
* entry: { index: 'src/index.ts' },
* format: ['esm', 'cjs'],
* experimentalDts: { entry: 'src/**\/*.ts' },
* // experimentalDts: { entry: 'src/**\/*.ts' }
* // becomes experimentalDts: { entry: { index: 'src/index.ts', types: 'src/types.ts } }
* })
* ```
*
* @internal
*/
const resolveEntryPaths = async (entryPaths: InputOption) => {
const resolvedEntryPaths =
typeof entryPaths === 'string' || Array.isArray(entryPaths)
? convertArrayEntriesToObjectEntries(await glob(entryPaths))
: entryPaths

return resolvedEntryPaths
}

/**
* Normalizes the
* {@linkcode NormalizedExperimentalDtsConfig | experimental DTS options}
Expand All @@ -207,44 +284,21 @@ export const normalizeExperimentalDtsOptions = async (
options: Partial<NormalizedOptions>,
tsconfig: any,
) => {
if (options.entry == null) {
if (!options.entry || !options.experimentalDts) {
return
}

const experimentalDtsEntry = options.experimentalDts?.entry || options.entry

/**
* Resolves the entry paths for the experimental DTS configuration.
* If the entry is a string or array of strings,
* it uses {@linkcode glob | tinyglobby's glob function} to resolve
* the potential glob patterns. If it's an `object`, it directly uses
* the provided entry object.
*
* @example
*
* ```ts
* import { defineConfig } from 'tsup'
*
* export default defineConfig({
* entry: { index: 'src/index.ts' },
* format: ['esm', 'cjs'],
* experimentalDts: { entry: 'src/**\/*.ts' },
* // experimentalDts: { entry: 'src/**\/*.ts' }
* // becomes experimentalDts: { entry: { index: 'src/index.ts', types: 'src/types.ts } }
* })
* ```
*/
const resolvedEntryPaths =
typeof experimentalDtsEntry === 'string' ||
Array.isArray(experimentalDtsEntry)
? await glob(experimentalDtsEntry)
: experimentalDtsEntry
const resolvedEntryPaths = await resolveEntryPaths(
options.experimentalDts.entry || options.entry,
)

// Fallback to `options.entry` if we end up with an empty object.
const experimentalDtsObjectEntry =
Object.keys(toObjectEntry(resolvedEntryPaths)).length === 0
? toObjectEntry(options.entry)
: toObjectEntry(resolvedEntryPaths)
Object.keys(resolvedEntryPaths).length === 0
? Array.isArray(options.entry)
? convertArrayEntriesToObjectEntries(options.entry)
: options.entry
: resolvedEntryPaths

const normalizedExperimentalDtsOptions: NormalizedExperimentalDtsConfig = {
compilerOptions: {
Expand Down Expand Up @@ -281,21 +335,22 @@ export const normalizeInitialExperimentalDtsOptions = async (
if (experimentalDts == null) {
return
}

if (typeof experimentalDts === 'boolean')
return experimentalDts ? { entry: {} } : undefined

if (typeof experimentalDts === 'string') {
return { entry: toObjectEntry(await glob(experimentalDts)) }
return {
entry: convertArrayEntriesToObjectEntries(await glob(experimentalDts)),
}
}

return {
...experimentalDts,

entry:
experimentalDts?.entry == null
? {}
: toObjectEntry(
typeof experimentalDts?.entry === 'string' ||
Array.isArray(experimentalDts.entry)
? await glob(experimentalDts.entry)
: experimentalDts.entry,
),
: await resolveEntryPaths(experimentalDts.entry),
}
}
10 changes: 4 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,10 @@ const normalizeOptions = async (
}
}

if (options.experimentalDts) {
options.experimentalDts = await normalizeExperimentalDtsOptions(
options,
tsconfig,
)
}
options.experimentalDts = await normalizeExperimentalDtsOptions(
options,
tsconfig,
)

if (!options.target) {
options.target = tsconfig.data?.compilerOptions?.target?.toLowerCase()
Expand Down

0 comments on commit 59e7805

Please sign in to comment.