Skip to content

Commit 2cd7e5c

Browse files
committed
fix: dts gen
1 parent 0443741 commit 2cd7e5c

14 files changed

Lines changed: 830 additions & 6 deletions

File tree

.changeset/swift-streets-cheat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"zile": patch
3+
---
4+
5+
Fixed `.d.ts` generation.

src/Package.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,23 @@ export async function build(options: build.Options): Promise<build.ReturnType> {
2525
await checkInput({ cwd, outDir })
2626

2727
const { assets, sources } = getEntries({ cwd, pkgJson })
28+
const sourceDir = getSourceDir({ cwd, sources })
2829

2930
if (!link) {
3031
const result = await transpile({ cwd, sources, tsgo })
3132
tsConfig = result.tsConfig
3233
}
3334

34-
await copyAssets({ assets, cwd, outDir })
35+
await copyAssets({ assets, cwd, outDir, sourceDir })
3536

3637
if (link) {
3738
await fs.rm(outDir, { recursive: true }).catch(() => {})
3839
await fs.mkdir(outDir, { recursive: true })
3940
}
4041

41-
const sourceDir = getSourceDir({ cwd, sources })
4242
const packageJson = await decoratePackageJson(pkgJson, { cwd, link, outDir, sourceDir, assets })
4343

44+
4445
await writePackageJson(cwd, packageJson)
4546

4647
return { packageJson, tsConfig }
@@ -159,10 +160,11 @@ export declare namespace checkPackageJson {
159160
* @returns Promise that resolves when assets are copied.
160161
*/
161162
export async function copyAssets(options: copyAssets.Options): Promise<void> {
162-
const { assets, cwd, outDir } = options
163+
const { assets, cwd, outDir, sourceDir } = options
164+
const relativeSourceDir = path.relative(cwd, sourceDir)
163165

164166
for (const asset of assets) {
165-
const relativePath = path.relative(cwd, asset)
167+
const relativePath = path.relative(cwd, asset).replace(`${relativeSourceDir}/`, '')
166168
const destPath = path.resolve(outDir, relativePath)
167169
await fs.mkdir(path.dirname(destPath), { recursive: true })
168170
await fs.copyFile(asset, destPath)
@@ -177,6 +179,8 @@ export declare namespace copyAssets {
177179
cwd: string
178180
/** Output directory. */
179181
outDir: string
182+
/** Source directory. */
183+
sourceDir: string
180184
}
181185
}
182186

@@ -196,7 +200,8 @@ export async function decoratePackageJson(
196200
const relativeOutDir = `./${path.relative(cwd, outDir)}`
197201
const relativeSourceDir = `./${path.relative(cwd, sourceDir)}`
198202

199-
const outAsset = (name: string) => `./${path.join(relativeOutDir, path.relative(cwd, name))}`
203+
const outAsset = (name: string) =>
204+
`./${path.join(relativeOutDir, path.relative(cwd, name).replace(`${relativeSourceDir.slice(2)}/`, ''))}`
200205
const outFile = (name: string, ext: string = '') =>
201206
'./' +
202207
path.join(
@@ -279,6 +284,20 @@ export async function decoratePackageJson(
279284
} catch {}
280285
}
281286

287+
function linkDtsExport(entry: string) {
288+
try {
289+
const destDtsAbsolute = path.resolve(cwd, outAsset(path.resolve(cwd, entry)))
290+
const dir = path.dirname(destDtsAbsolute)
291+
292+
if (!fsSync.existsSync(dir)) fsSync.mkdirSync(dir, { recursive: true })
293+
294+
const srcAbsolute = path.resolve(cwd, entry)
295+
const srcRelativeDts = path.relative(path.dirname(destDtsAbsolute), srcAbsolute)
296+
297+
fsSync.symlinkSync(srcRelativeDts, destDtsAbsolute, 'file')
298+
} catch {}
299+
}
300+
282301
// Transform single `package.json#exports` entrypoints. They
283302
// must point to the source file. Otherwise, an error is thrown.
284303
//
@@ -291,6 +310,14 @@ export async function decoratePackageJson(
291310
// }
292311
if (typeof value === 'string') {
293312
if (value.startsWith(relativeOutDir)) return [key, value]
313+
// Handle .d.ts files (type definitions only, no JS output)
314+
if (/\.d\.[mc]?ts$/.test(value)) {
315+
const absolutePath = path.resolve(cwd, value)
316+
if (link) linkDtsExport(value)
317+
if (assets.includes(absolutePath))
318+
return [key, { types: outAsset(absolutePath), src: value }]
319+
return [key, { types: outAsset(absolutePath), src: value }]
320+
}
294321
// Handle asset files (non-source files)
295322
if (!/\.(m|c)?[jt]sx?$/.test(value)) {
296323
const absolutePath = path.resolve(cwd, value)
@@ -326,6 +353,14 @@ export async function decoratePackageJson(
326353
typeof value.src === 'string'
327354
) {
328355
if (value.src.startsWith(relativeOutDir)) return [key, value]
356+
// Handle .d.ts files (type definitions only, no JS output)
357+
if (/\.d\.[mc]?ts$/.test(value.src)) {
358+
const absolutePath = path.resolve(cwd, value.src)
359+
if (link) linkDtsExport(value.src)
360+
if (assets.includes(absolutePath))
361+
return [key, { types: outAsset(absolutePath), src: value.src }]
362+
return [key, { types: outAsset(absolutePath), src: value.src }]
363+
}
329364
// Handle asset files (non-source files)
330365
if (!/\.(m|c)?[jt]sx?$/.test(value.src)) {
331366
if (link) return [key, value]
@@ -422,7 +457,9 @@ export function getEntries(options: getEntries.Options): getEntries.ReturnType {
422457
else throw new Error('`exports` field in package.json must have a `src` field')
423458

424459
const absolutePath = path.resolve(cwd, entryPath)
425-
if (/\.(m|c)?[jt]sx?$/.test(absolutePath)) sources.push(absolutePath)
460+
// .d.ts files are type definitions (assets), not source files to transpile
461+
if (/\.d\.[mc]?ts$/.test(absolutePath)) assets.push(absolutePath)
462+
else if (/\.(m|c)?[jt]sx?$/.test(absolutePath)) sources.push(absolutePath)
426463
else assets.push(absolutePath)
427464
}
428465
} else if (pkgJson.main) sources.push(path.resolve(cwd, pkgJson.main))

src/Packages.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ describe('Packages.find', () => {
2626
"/test/repos/error-exports-object-not-exists",
2727
"/test/repos/error-bin-string-not-exists",
2828
"/test/repos/error-bin-object-not-exists",
29+
"/test/repos/dts-exports-object",
30+
"/test/repos/dts-exports",
2931
"/test/repos/basic-object-exports",
3032
"/test/repos/basic",
3133
"/template",
@@ -54,6 +56,8 @@ describe('Packages.find', () => {
5456
"/test/repos/error-exports-object-not-exists",
5557
"/test/repos/error-bin-string-not-exists",
5658
"/test/repos/error-bin-object-not-exists",
59+
"/test/repos/dts-exports-object",
60+
"/test/repos/dts-exports",
5761
"/test/repos/basic-object-exports",
5862
"/test/repos/basic",
5963
]
@@ -103,6 +107,8 @@ describe('Packages.find', () => {
103107
"/test/repos/error-exports-object-not-exists",
104108
"/test/repos/error-bin-string-not-exists",
105109
"/test/repos/error-bin-object-not-exists",
110+
"/test/repos/dts-exports-object",
111+
"/test/repos/dts-exports",
106112
"/test/repos/basic-object-exports",
107113
"/test/repos/basic",
108114
]
@@ -175,6 +181,8 @@ describe('Packages.find', () => {
175181
"/test/repos/error-exports-object-not-exists",
176182
"/test/repos/error-bin-string-not-exists",
177183
"/test/repos/error-bin-object-not-exists",
184+
"/test/repos/dts-exports-object",
185+
"/test/repos/dts-exports",
178186
"/test/repos/basic-object-exports",
179187
"/test/repos/basic",
180188
"/template",

src/__snapshots__/Cli.test.ts.snap

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,182 @@ exports[`'/basic-object-exports': Cli.run > link > output 1`] = `
243243

244244
exports[`'/basic-object-exports': Cli.run > link > types-target 1`] = `"../index.ts"`;
245245

246+
exports[`'/dts-exports': Cli.run > default > main 1`] = `
247+
"export const foo = 'bar';
248+
//# sourceMappingURL=index.js.map"
249+
`;
250+
251+
exports[`'/dts-exports': Cli.run > default > output 1`] = `
252+
"{
253+
"name": "dts-exports",
254+
"version": "0.0.0",
255+
"type": "module",
256+
"main": "./dist/index.js",
257+
"exports": {
258+
".": {
259+
"src": "./src/index.ts",
260+
"types": "./dist/index.d.ts",
261+
"default": "./dist/index.js"
262+
},
263+
"./globals": {
264+
"types": "./dist/globals.d.ts",
265+
"src": "./src/globals.d.ts"
266+
}
267+
},
268+
"sideEffects": false,
269+
"module": "./dist/index.js",
270+
"types": "./dist/index.d.ts"
271+
}
272+
273+
274+
275+
├── dist
276+
│ ├── globals.d.ts
277+
│ ├── index.d.ts
278+
│ ├── index.d.ts.map
279+
│ ├── index.js
280+
│ └── index.js.map
281+
├── src
282+
│ ├── globals.d.ts
283+
│ └── index.ts
284+
├── package.json
285+
└── tsconfig.json
286+
"
287+
`;
288+
289+
exports[`'/dts-exports': Cli.run > default > types 1`] = `
290+
"export declare const foo = "bar";
291+
//# sourceMappingURL=index.d.ts.map"
292+
`;
293+
294+
exports[`'/dts-exports': Cli.run > link > main-target 1`] = `"../src/index.ts"`;
295+
296+
exports[`'/dts-exports': Cli.run > link > output 1`] = `
297+
"{
298+
"name": "dts-exports",
299+
"version": "0.0.0",
300+
"type": "module",
301+
"main": "./dist/index.js",
302+
"exports": {
303+
".": {
304+
"src": "./src/index.ts",
305+
"types": "./dist/index.d.ts",
306+
"default": "./dist/index.js"
307+
},
308+
"./globals": {
309+
"types": "./dist/globals.d.ts",
310+
"src": "./src/globals.d.ts"
311+
}
312+
},
313+
"sideEffects": false,
314+
"module": "./dist/index.js",
315+
"types": "./dist/index.d.ts"
316+
}
317+
318+
319+
320+
├── dist
321+
│ ├── globals.d.ts -> ../src/globals.d.ts
322+
│ ├── index.d.ts -> ../src/index.ts
323+
│ └── index.js -> ../src/index.ts
324+
├── src
325+
│ ├── globals.d.ts
326+
│ └── index.ts
327+
├── package.json
328+
└── tsconfig.json
329+
"
330+
`;
331+
332+
exports[`'/dts-exports': Cli.run > link > types-target 1`] = `"../src/index.ts"`;
333+
334+
exports[`'/dts-exports-object': Cli.run > default > main 1`] = `
335+
"export const foo = 'bar';
336+
//# sourceMappingURL=index.js.map"
337+
`;
338+
339+
exports[`'/dts-exports-object': Cli.run > default > output 1`] = `
340+
"{
341+
"name": "dts-exports-object",
342+
"version": "0.0.0",
343+
"type": "module",
344+
"main": "./dist/index.js",
345+
"exports": {
346+
".": {
347+
"src": "./src/index.ts",
348+
"types": "./dist/index.d.ts",
349+
"default": "./dist/index.js"
350+
},
351+
"./globals": {
352+
"types": "./dist/globals.d.ts",
353+
"src": "./src/globals.d.ts"
354+
}
355+
},
356+
"sideEffects": false,
357+
"module": "./dist/index.js",
358+
"types": "./dist/index.d.ts"
359+
}
360+
361+
362+
363+
├── dist
364+
│ ├── globals.d.ts
365+
│ ├── index.d.ts
366+
│ ├── index.d.ts.map
367+
│ ├── index.js
368+
│ └── index.js.map
369+
├── src
370+
│ ├── globals.d.ts
371+
│ └── index.ts
372+
├── package.json
373+
└── tsconfig.json
374+
"
375+
`;
376+
377+
exports[`'/dts-exports-object': Cli.run > default > types 1`] = `
378+
"export declare const foo = "bar";
379+
//# sourceMappingURL=index.d.ts.map"
380+
`;
381+
382+
exports[`'/dts-exports-object': Cli.run > link > main-target 1`] = `"../src/index.ts"`;
383+
384+
exports[`'/dts-exports-object': Cli.run > link > output 1`] = `
385+
"{
386+
"name": "dts-exports-object",
387+
"version": "0.0.0",
388+
"type": "module",
389+
"main": "./dist/index.js",
390+
"exports": {
391+
".": {
392+
"src": "./src/index.ts",
393+
"types": "./dist/index.d.ts",
394+
"default": "./dist/index.js"
395+
},
396+
"./globals": {
397+
"types": "./dist/globals.d.ts",
398+
"src": "./src/globals.d.ts"
399+
}
400+
},
401+
"sideEffects": false,
402+
"module": "./dist/index.js",
403+
"types": "./dist/index.d.ts"
404+
}
405+
406+
407+
408+
├── dist
409+
│ ├── globals.d.ts -> ../src/globals.d.ts
410+
│ ├── index.d.ts -> ../src/index.ts
411+
│ └── index.js -> ../src/index.ts
412+
├── src
413+
│ ├── globals.d.ts
414+
│ └── index.ts
415+
├── package.json
416+
└── tsconfig.json
417+
"
418+
`;
419+
420+
exports[`'/dts-exports-object': Cli.run > link > types-target 1`] = `"../src/index.ts"`;
421+
246422
exports[`'/multiple-entrypoint': Cli.run > default > main 1`] = `
247423
"import { bar as bar1, foo as foo1 } from './foo.js';
248424
export function foo(options = {}) {

0 commit comments

Comments
 (0)