Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to ESM, remove index.d.ts requirement #186

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

10 changes: 0 additions & 10 deletions .eslintrc

This file was deleted.

7 changes: 3 additions & 4 deletions .github/workflows/main.yaml → .github/workflows/main.yml
Expand Up @@ -10,13 +10,12 @@ jobs:
fail-fast: false
matrix:
node-version:
- 21
- 20
- 18
- 16
- 14
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
node_modules
yarn.lock
dist/
.tsimp
85 changes: 50 additions & 35 deletions package.json
Expand Up @@ -9,20 +9,19 @@
"email": "[email protected]",
"url": "https://github.com/SamVerschueren"
},
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"exports": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"bin": "./dist/cli.js",
"engines": {
"node": ">=14.16"
"node": ">=18"
},
"scripts": {
"prepublishOnly": "npm run build",
"pretest": "npm run build && cpy \"./**/**\" \"../../../dist/test/fixtures/\" --parents --cwd=source/test/fixtures",
"test": "npm run lint && ava",
"build": "npm run clean && tsc --project tsconfig.tsd.json && chmod +x dist/cli.js",
"clean": "del-cli dist",
"lint": "eslint \"source/**/*\"",
"lint:fix": "eslint --fix \"source/**/*\""
"test": "xo && tsc --project tsconfig.tsd.json --noEmit && ava",
"build": "tsc --project tsconfig.build.json && chmod +x dist/cli.js && tsup"
},
"files": [
"dist/**/*.js",
Expand All @@ -40,41 +39,57 @@
],
"dependencies": {
"@tsd/typescript": "~5.3.3",
"eslint-formatter-pretty": "^4.1.0",
"globby": "^11.0.1",
"jest-diff": "^29.0.3",
"meow": "^9.0.0",
"path-exists": "^4.0.0",
"read-pkg-up": "^7.0.0"
"eslint-formatter-pretty": "^6.0.1",
"globby": "^14.0.1",
"jest-diff": "^29.7.0",
"meow": "^13.2.0",
"p-map": "^7.0.1",
"path-exists": "^5.0.0",
"read-package-up": "^11.0.0"
},
"devDependencies": {
"@ava/typescript": "^1.1.1",
"@types/node": "^14.18.21",
"@types/react": "^16.9.2",
"@typescript-eslint/eslint-plugin": "^4.26.0",
"@typescript-eslint/parser": "^4.26.0",
"ava": "^3.8.2",
"cpy-cli": "^3.0.0",
"del-cli": "^3.0.0",
"eslint": "^7.27.0",
"eslint-config-xo": "^0.36.0",
"eslint-config-xo-typescript": "^0.41.1",
"execa": "^5.0.0",
"@sindresorhus/tsconfig": "^5.0.0",
"@types/common-tags": "^1.8.4",
"@types/node": "^18",
"@types/react": "^18",
"ava": "^6.1.1",
"common-tags": "^1.8.2",
"eslint": "^8.56.0",
"execa": "^8.0.1",
"react": "^16.9.0",
"resolve-from": "^5.0.0",
"rxjs": "^6.5.3",
"typescript": "~4.9.5"
"tsimp": "^2.0.11",
"tsup": "^8.0.2",
"typescript": "~5.3.3",
"xo": "^0.57.0"
},
"ava": {
"timeout": "2m",
"files": [
"source/test/**/*",
"!source/test/fixtures/**/*"
"extensions": {
"ts": "module"
},
"nodeArguments": [
"--import=tsimp"
],
"environmentVariables": {
"ESBK_TSCONFIG_PATH": "tsconfig.tsd.json"
}
},
"xo": {
"ignores": [
"source/test/fixtures"
],
"typescript": {
"rewritePaths": {
"source/": "dist/"
}
"parserOptions": {
"project": "./tsconfig.tsd.json"
},
"rules": {
"no-bitwise": "off",
"unicorn/prevent-abbreviations": ["error", {
"replacements": {
"doc": false
}
}]
}
}
}
63 changes: 29 additions & 34 deletions source/cli.ts 100644 → 100755
@@ -1,42 +1,39 @@
#!/usr/bin/env node
#!/usr/bin/env tsimp
import process from 'node:process';
import meow from 'meow';
import {TsdError} from './lib/interfaces';
import formatter from './lib/formatter';
import tsd from './lib';
import {TsdError} from './lib/interfaces.js';
import formatter from './lib/formatter.js';
import tsd from './lib/index.js';

const cli = meow(`
Usage
$ tsd [path]

The given directory must contain a package.json and a typings file.
The given directory must contain a package.json.

Info
--help Display help text
--version Display version info

Options
--typings -t Type definition file to test [Default: "types" property in package.json]
--files -f Glob of files to test [Default: '/path/test-d/**/*.test-d.ts' or '.tsx']
--show-diff Show type error diffs [Default: don't show]
--files -f Glob of files to test [Default: 'path/test-d/**/*.test-d.ts']
--show-diff Show type error diffs [Default: don't show]

Examples
$ tsd /path/to/project
$ tsd path/to/project

$ tsd --files /test/some/folder/*.ts --files /test/other/folder/*.tsx
$ tsd --files test/some/folder/*.ts --files test/other/folder/*.tsx

$ tsd

index.test-d.ts
✖ 10:20 Argument of type string is not assignable to parameter of type number.
`, {
importMeta: import.meta,
flags: {
typings: {
type: 'string',
alias: 't',
},
files: {
type: 'string',
alias: 'f',
shortFlag: 'f',
isMultiple: true,
},
showDiff: {
Expand All @@ -61,28 +58,26 @@ const exit = (message: string, {isError = true}: {isError?: boolean} = {}) => {
}
};

(async () => {
try {
const cwd = cli.input.length > 0 ? cli.input[0] : process.cwd();
const {typings: typingsFile, files: testFiles, showDiff} = cli.flags;
try {
const cwd = cli.input.at(0) ?? process.cwd();
const {files: testFiles, showDiff} = cli.flags;

const diagnostics = await tsd({cwd, typingsFile, testFiles});
const diagnostics = await tsd({cwd, testFiles});

if (diagnostics.length > 0) {
const hasErrors = diagnostics.some(diagnostic => diagnostic.severity === 'error');
const formattedDiagnostics = formatter(diagnostics, showDiff);
if (diagnostics.length > 0) {
const hasErrors = diagnostics.some(diagnostic => diagnostic.severity === 'error');
const formattedDiagnostics = formatter(diagnostics, showDiff);

exit(formattedDiagnostics, {isError: hasErrors});
}
} catch (error: unknown) {
const potentialError = error as Error | undefined;
exit(formattedDiagnostics, {isError: hasErrors});
}
} catch (error) {
const potentialError = error as Error | undefined;

if (potentialError instanceof TsdError) {
exit(potentialError.message);
}
if (potentialError instanceof TsdError) {
exit(potentialError.message);
}

const errorMessage = potentialError?.stack ?? potentialError?.message ?? 'tsd unexpectedly crashed.';
const errorMessage = potentialError?.stack ?? potentialError?.message ?? 'tsd unexpectedly crashed.';

exit(`Error running tsd:\n${errorMessage}`);
}
})();
exit(`Error running tsd:\n${errorMessage}`);
}
8 changes: 3 additions & 5 deletions source/index.ts
@@ -1,5 +1,3 @@
import tsd from './lib';

export * from './lib/assertions/assert';
export {default as formatter} from './lib/formatter';
export default tsd;
export * from './lib/assertions/assert.js';
export {default as formatter} from './lib/formatter.js';
export {default} from './lib/index.js';
57 changes: 13 additions & 44 deletions source/lib/assertions/assert.ts
@@ -1,76 +1,53 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

/**
* Asserts that the type of `expression` is identical to type `T`.
*
* @param expression - Expression that should be identical to type `T`.
*/
// @ts-expect-error
export const expectType = <T>(expression: T) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const expectType: <T>(expression: T) => void;

/**
* Asserts that the type of `expression` is not identical to type `T`.
*
* @param expression - Expression that should not be identical to type `T`.
*/
// @ts-expect-error
export const expectNotType = <T>(expression: any) => {
// eslint-disable-next-line no-warning-comments
// TODO Use a `not T` type when possible https://github.com/microsoft/TypeScript/pull/29317
// Do nothing, the TypeScript compiler handles this for us
};
*/
// eslint-disable-next-line no-warning-comments
// TODO Use a `not T` type when possible https://github.com/microsoft/TypeScript/pull/29317
export declare const expectNotType: <T>(expression: any) => void;

/**
* Asserts that the type of `expression` is assignable to type `T`.
*
* @param expression - Expression that should be assignable to type `T`.
*/
// @ts-expect-error
export const expectAssignable = <T>(expression: T) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const expectAssignable: <T>(expression: T) => void;

/**
* Asserts that the type of `expression` is not assignable to type `T`.
*
* @param expression - Expression that should not be assignable to type `T`.
*/
// @ts-expect-error
export const expectNotAssignable = <T>(expression: any) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const expectNotAssignable: <T>(expression: any) => void;

/**
* Asserts that `expression` throws an error. Will not ignore syntax errors.
*
* @param expression - Expression that should throw an error.
*/
// @ts-expect-error
export const expectError = <T = any>(expression: T) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const expectError: <T = any>(expression: T) => void;

/**
* Asserts that `expression` is marked as `@deprecated`.
*
* @param expression - Expression that should be marked as `@deprecated`.
*/
// @ts-expect-error
export const expectDeprecated = (expression: any) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const expectDeprecated: (expression: any) => void;

/**
* Asserts that `expression` is not marked as `@deprecated`.
*
* @param expression - Expression that should not be marked as `@deprecated`.
*/
// @ts-expect-error
export const expectNotDeprecated = (expression: any) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const expectNotDeprecated: (expression: any) => void;

/**
* Asserts that the type and return type of `expression` is `never`.
Expand All @@ -79,26 +56,18 @@ export const expectNotDeprecated = (expression: any) => {
*
* @param expression - Expression that should be `never`.
*/
export const expectNever = (expression: never): never => {
return expression;
};
export const expectNever = (expression: never): never => expression;

/**
* Prints the type of `expression` as a warning.
*
* @param expression - Expression whose type should be printed as a warning.
*/
// @ts-expect-error
export const printType = (expression: any) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const printType: (expression: any) => void;

/**
* Asserts that the documentation comment of `expression` includes string literal type `T`.
*
* @param expression - Expression whose documentation comment should include string literal type `T`.
*/
// @ts-expect-error
export const expectDocCommentIncludes = <T>(expression: any) => {
// Do nothing, the TypeScript compiler handles this for us
};
export declare const expectDocCommentIncludes: <T>(expression: any) => void;
6 changes: 3 additions & 3 deletions source/lib/assertions/handlers/assignability.ts
@@ -1,6 +1,6 @@
import {CallExpression, TypeChecker} from '@tsd/typescript';
import {Diagnostic} from '../../interfaces';
import {makeDiagnosticWithDiff} from '../../utils';
import type {CallExpression, TypeChecker} from '@tsd/typescript';
import type {Diagnostic} from '../../interfaces.js';
import {makeDiagnosticWithDiff} from '../../utils/index.js';

/**
* Asserts that the argument of the assertion is not assignable to the generic type of the assertion.
Expand Down