Skip to content

Commit dd7b71d

Browse files
committed
Fix nested entry point resolution
1 parent 8c6f698 commit dd7b71d

File tree

2 files changed

+106
-53
lines changed

2 files changed

+106
-53
lines changed

src/api-extractor.ts

+102-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import path from 'node:path'
22
import { glob } from 'tinyglobby'
33
import { handleError } from './errors'
4+
import {
5+
type ExportDeclaration,
6+
formatAggregationExports,
7+
formatDistributionExports,
8+
} from './exports'
49
import { loadPkg } from './load'
510
import { createLogger } from './log'
611
import {
@@ -9,7 +14,6 @@ import {
914
getApiExtractor,
1015
removeFiles,
1116
toAbsolutePath,
12-
toObjectEntry,
1317
writeFileSync,
1418
} from './utils'
1519
import type {
@@ -23,7 +27,7 @@ import type {
2327
IConfigFile,
2428
IExtractorConfigPrepareOptions,
2529
} from '@microsoft/api-extractor'
26-
import { formatAggregationExports, formatDistributionExports, type ExportDeclaration } from "./exports"
30+
import type { InputOption } from 'rollup'
2731

2832
const logger = createLogger()
2933

@@ -124,16 +128,11 @@ async function rollupDtsFiles(
124128
formatAggregationExports(exports, declarationDir),
125129
)
126130

127-
rollupDtsFile(
128-
dtsInputFilePath,
129-
dtsOutputFilePath,
130-
tsconfig,
131-
)
131+
rollupDtsFile(dtsInputFilePath, dtsOutputFilePath, tsconfig)
132132

133133
for (let [out, sourceFileName] of Object.entries(
134134
options.experimentalDts.entry,
135135
)) {
136-
out = path.basename(out)
137136
/**
138137
* **Source file name** (`src/index.ts`)
139138
*
@@ -208,6 +207,84 @@ export async function runDtsRollup(
208207
}
209208
}
210209

210+
/**
211+
* Converts an array of {@linkcode NormalizedOptions.entry | entry paths}
212+
* into an object where the keys represent the output
213+
* file names (without extensions) and the values
214+
* represent the corresponding input file paths.
215+
*
216+
* @param arrayOfEntries - An array of file path entries as strings.
217+
* @returns An object where the keys are the output file name and the values are the input file name.
218+
*
219+
* @example
220+
* <caption>### Convert an array of entry points to an entry point object</caption>
221+
*
222+
* ```ts
223+
* import { defineConfig } from 'tsup'
224+
*
225+
* export default defineConfig({
226+
* entry: ['src/index.ts', 'src/types.ts'], // Becomes `{ index: 'src/index.ts', types: 'src/types.ts' }`
227+
* format: ['esm', 'cjs'],
228+
* })
229+
* ```
230+
*
231+
* @internal
232+
*/
233+
const convertArrayEntriesToObjectEntries = (arrayOfEntries: string[]) => {
234+
const objectEntries = Object.fromEntries(
235+
arrayOfEntries.map(
236+
(entry) =>
237+
[
238+
path.posix.join(
239+
...entry
240+
.split(path.posix.sep)
241+
.slice(1, -1)
242+
.concat(path.parse(entry).name),
243+
),
244+
entry,
245+
] as const,
246+
),
247+
)
248+
249+
return objectEntries
250+
}
251+
252+
/**
253+
* Resolves and standardizes entry paths into an object format.
254+
* If the provided entry is a string or an array of strings, it resolves
255+
* any potential glob patterns using
256+
* {@linkcode glob | tiny-glob's glob function}
257+
* and converts the result into an entry object.
258+
* If the input is already an object, it is returned as-is.
259+
*
260+
* @param entryPaths - The entry paths to resolve. Can be a string, an array of strings, or an object.
261+
* @returns A {@linkcode Promise} that resolves to the standardized entry paths in object format.
262+
*
263+
* @example
264+
*
265+
* ```ts
266+
* import { defineConfig } from 'tsup'
267+
*
268+
* export default defineConfig({
269+
* entry: { index: 'src/index.ts' },
270+
* format: ['esm', 'cjs'],
271+
* experimentalDts: { entry: 'src/**\/*.ts' },
272+
* // experimentalDts: { entry: 'src/**\/*.ts' }
273+
* // becomes experimentalDts: { entry: { index: 'src/index.ts', types: 'src/types.ts } }
274+
* })
275+
* ```
276+
*
277+
* @internal
278+
*/
279+
const resolveEntryPaths = async (entryPaths: InputOption) => {
280+
const resolvedEntryPaths =
281+
typeof entryPaths === 'string' || Array.isArray(entryPaths)
282+
? convertArrayEntriesToObjectEntries(await glob(entryPaths))
283+
: entryPaths
284+
285+
return resolvedEntryPaths
286+
}
287+
211288
/**
212289
* Normalizes the
213290
* {@linkcode NormalizedExperimentalDtsConfig | experimental DTS options}
@@ -224,44 +301,21 @@ export const normalizeExperimentalDtsOptions = async (
224301
options: Partial<NormalizedOptions>,
225302
tsconfig: any,
226303
) => {
227-
if (options.entry == null) {
304+
if (!options.entry || !options.experimentalDts) {
228305
return
229306
}
230307

231-
const experimentalDtsEntry = options.experimentalDts?.entry || options.entry
232-
233-
/**
234-
* Resolves the entry paths for the experimental DTS configuration.
235-
* If the entry is a string or array of strings,
236-
* it uses {@linkcode glob | tinyglobby's glob function} to resolve
237-
* the potential glob patterns. If it's an `object`, it directly uses
238-
* the provided entry object.
239-
*
240-
* @example
241-
*
242-
* ```ts
243-
* import { defineConfig } from 'tsup'
244-
*
245-
* export default defineConfig({
246-
* entry: { index: 'src/index.ts' },
247-
* format: ['esm', 'cjs'],
248-
* experimentalDts: { entry: 'src/**\/*.ts' },
249-
* // experimentalDts: { entry: 'src/**\/*.ts' }
250-
* // becomes experimentalDts: { entry: { index: 'src/index.ts', types: 'src/types.ts } }
251-
* })
252-
* ```
253-
*/
254-
const resolvedEntryPaths =
255-
typeof experimentalDtsEntry === 'string' ||
256-
Array.isArray(experimentalDtsEntry)
257-
? await glob(experimentalDtsEntry)
258-
: experimentalDtsEntry
308+
const resolvedEntryPaths = await resolveEntryPaths(
309+
options.experimentalDts.entry || options.entry,
310+
)
259311

260312
// Fallback to `options.entry` if we end up with an empty object.
261313
const experimentalDtsObjectEntry =
262-
Object.keys(toObjectEntry(resolvedEntryPaths)).length === 0
263-
? toObjectEntry(options.entry)
264-
: toObjectEntry(resolvedEntryPaths)
314+
Object.keys(resolvedEntryPaths).length === 0
315+
? Array.isArray(options.entry)
316+
? convertArrayEntriesToObjectEntries(options.entry)
317+
: options.entry
318+
: resolvedEntryPaths
265319

266320
const normalizedExperimentalDtsOptions: NormalizedExperimentalDtsConfig = {
267321
compilerOptions: {
@@ -298,21 +352,22 @@ export const normalizeInitialExperimentalDtsOptions = async (
298352
if (experimentalDts == null) {
299353
return
300354
}
355+
301356
if (typeof experimentalDts === 'boolean')
302357
return experimentalDts ? { entry: {} } : undefined
358+
303359
if (typeof experimentalDts === 'string') {
304-
return { entry: toObjectEntry(await glob(experimentalDts)) }
360+
return {
361+
entry: convertArrayEntriesToObjectEntries(await glob(experimentalDts)),
362+
}
305363
}
364+
306365
return {
307366
...experimentalDts,
367+
308368
entry:
309369
experimentalDts?.entry == null
310370
? {}
311-
: toObjectEntry(
312-
typeof experimentalDts?.entry === 'string' ||
313-
Array.isArray(experimentalDts.entry)
314-
? await glob(experimentalDts.entry)
315-
: experimentalDts.entry,
316-
),
371+
: await resolveEntryPaths(experimentalDts.entry),
317372
}
318373
}

src/index.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,10 @@ const normalizeOptions = async (
140140
}
141141
}
142142

143-
if (options.experimentalDts) {
144-
options.experimentalDts = await normalizeExperimentalDtsOptions(
145-
options,
146-
tsconfig,
147-
)
148-
}
143+
options.experimentalDts = await normalizeExperimentalDtsOptions(
144+
options,
145+
tsconfig,
146+
)
149147

150148
if (!options.target) {
151149
options.target = tsconfig.data?.compilerOptions?.target?.toLowerCase()

0 commit comments

Comments
 (0)