74 lines
3.6 KiB
JavaScript
74 lines
3.6 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import test from 'node:test';
|
|
import { execFileSync } from 'node:child_process';
|
|
import { pathToFileURL } from 'node:url';
|
|
import { emitDeclarations } from './emit-declarations.mjs';
|
|
|
|
const workspaceRoot = path.resolve(import.meta.dirname, '../..');
|
|
|
|
test('native declarations preserve relative imports, subpaths and maps, and fail on type errors', async () => {
|
|
const temporaryRoot = path.join(workspaceRoot, '.turbo');
|
|
await mkdir(temporaryRoot, { recursive: true });
|
|
const fixture = await mkdtemp(path.join(temporaryRoot, 'declaration-test-'));
|
|
const outDir = path.join(fixture, 'dist');
|
|
try {
|
|
await mkdir(path.join(fixture, 'src'));
|
|
await writeFile(path.join(fixture, 'package.json'), JSON.stringify({ type: 'module' }));
|
|
await writeFile(
|
|
path.join(fixture, 'tsconfig.build.json'),
|
|
JSON.stringify({
|
|
extends: path.join(workspaceRoot, 'tsconfig.base.json'),
|
|
compilerOptions: { rootDir: 'src', outDir: 'dist' },
|
|
include: ['src'],
|
|
})
|
|
);
|
|
await writeFile(
|
|
path.join(fixture, 'src/model.ts'),
|
|
'export class Model { private readonly id = 1; getId(): number { return this.id; } }\n'
|
|
);
|
|
await writeFile(path.join(fixture, 'src/index.ts'), "export { Model } from './model.js';\n");
|
|
await emitDeclarations({ options: { cwd: fixture, outDir } });
|
|
assert.match(await readFile(path.join(outDir, 'index.d.ts'), 'utf8'), /from ['"]\.\/model\.js['"]/u);
|
|
assert.match(await readFile(path.join(outDir, 'model.d.ts'), 'utf8'), /getId\(\): number/u);
|
|
const map = JSON.parse(await readFile(path.join(outDir, 'model.d.ts.map'), 'utf8'));
|
|
assert.deepEqual(map.sources, ['../src/model.ts']);
|
|
await assert.rejects(readFile(path.join(outDir, 'index.js')), { code: 'ENOENT' });
|
|
|
|
await writeFile(
|
|
path.join(fixture, 'package.json'),
|
|
JSON.stringify({ type: 'module', exports: { './*': './dist/src/*' } })
|
|
);
|
|
await emitDeclarations({ options: { cwd: fixture, outDir } });
|
|
assert.equal(await readFile(path.join(outDir, 'index.d.ts'), 'utf8'), "export * from './src/index.js';\n");
|
|
const { Model } = await import(pathToFileURL(path.join(outDir, 'src/model.js')).href);
|
|
assert.equal(new Model().getId(), 1);
|
|
await readFile(path.join(outDir, 'src/model.d.ts.map'));
|
|
await readFile(path.join(outDir, 'src/model.js.map'));
|
|
await writeFile(
|
|
path.join(fixture, 'consumer.ts'),
|
|
"import { Model } from './dist/index.js';\n" +
|
|
"import { Model as SubpathModel } from './dist/src/model.js';\n" +
|
|
'export const same: Model = new SubpathModel();\n'
|
|
);
|
|
await writeFile(
|
|
path.join(fixture, 'tsconfig.consumer.json'),
|
|
JSON.stringify({ extends: path.join(workspaceRoot, 'tsconfig.base.json'), files: ['consumer.ts'] })
|
|
);
|
|
execFileSync(
|
|
'pnpm',
|
|
['-w', 'tsc7', '-p', path.join(fixture, 'tsconfig.consumer.json'), '--noEmit', '--types', 'node'],
|
|
{
|
|
cwd: fixture,
|
|
stdio: 'pipe',
|
|
}
|
|
);
|
|
|
|
await writeFile(path.join(fixture, 'src/model.ts'), 'export const id: number = "invalid";\n');
|
|
await assert.rejects(emitDeclarations({ options: { cwd: fixture, outDir } }), /Declaration emission failed/u);
|
|
} finally {
|
|
await rm(fixture, { recursive: true, force: true });
|
|
}
|
|
});
|