Skip to content

Commit 7ba6c81

Browse files
committed
feat(tsl-module): add noDuplicateImport rule to disallow duplicate imports
chore(tsl-module): initialize package.json and add necessary configurations feat(tsl-module): implement no-duplicate-import rule logic docs(tsl-module): add README and documentation for noDuplicateImport variable chore(tsl-module): add TypeScript configuration and build scripts chore: update tsdown to version 0.19.0-beta.2 in pnpm-lock.yaml
1 parent 0d5750d commit 7ba6c81

File tree

15 files changed

+519
-16
lines changed

15 files changed

+519
-16
lines changed

.pkgs/function-rules/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
},
2626
"devDependencies": {
2727
"eslint": "^9.39.2",
28-
"tsdown": "^0.19.0-beta.1"
28+
"tsdown": "^0.19.0-beta.2"
2929
},
3030
"peerDependencies": {
3131
"eslint": "^9.39.2",

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"url": "git+https://github.com/Rel1cx/dx.git"
1313
},
1414
"license": "MIT",
15-
"author": "Rel1cx<rel1cx@proton.me>",
15+
"author": "Rel1cx<let@ik.me>",
1616
"type": "module",
1717
"scripts": {
1818
"build": "pnpm run build:pkgs && pnpm run build:packages",
@@ -52,7 +52,7 @@
5252
"sort-package-json": "^3.6.0",
5353
"tinyglobby": "^0.2.15",
5454
"ts-pattern": "^5.9.0",
55-
"tsdown": "^0.19.0-beta.1",
55+
"tsdown": "^0.19.0-beta.2",
5656
"tsx": "^4.21.0",
5757
"typedoc": "^0.28.15",
5858
"typedoc-plugin-markdown": "^4.9.0",

packages/eff/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"url": "git+https://github.com/Rel1cx/dx.git"
1212
},
1313
"license": "MIT",
14-
"author": "Rel1cx<rel1cx@proton.me>",
14+
"author": "Rel1cx<let@ik.me>",
1515
"type": "module",
1616
"exports": {
1717
".": "./dist/index.js",

packages/eslint-plugin-function-rule/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"url": "git+https://github.com/Rel1cx/dx.git"
1212
},
1313
"license": "MIT",
14-
"author": "Rel1cx<rel1cx@proton.me>",
14+
"author": "Rel1cx<let@ik.me>",
1515
"sideEffects": false,
1616
"type": "module",
1717
"exports": {

packages/eslint-plugin-function/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"url": "git+https://github.com/Rel1cx/dx.git"
1313
},
1414
"license": "MIT",
15-
"author": "Rel1cx<rel1cx@proton.me>",
15+
"author": "Rel1cx<let@ik.me>",
1616
"sideEffects": false,
1717
"type": "module",
1818
"exports": {
@@ -49,7 +49,7 @@
4949
"@typescript-eslint/rule-tester": "^8.51.0",
5050
"dedent": "^1.7.1",
5151
"eslint": "^9.39.2",
52-
"tsdown": "^0.19.0-beta.1"
52+
"tsdown": "^0.19.0-beta.2"
5353
},
5454
"peerDependencies": {
5555
"eslint": "^9.39.2",

packages/tsl-module/docs/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# tsl-module
2+
3+
## Variables
4+
5+
| Variable | Description |
6+
| ------ | ------ |
7+
| [noDuplicateImport](variables/noDuplicateImport.md) | Rule to disallow duplicate imports from the same module. |
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[tsl-module](../README.md) / noDuplicateImport
2+
3+
# Variable: noDuplicateImport()
4+
5+
```ts
6+
const noDuplicateImport: (options?: "off") => Rule<unknown>;
7+
```
8+
9+
Rule to disallow duplicate imports from the same module.
10+
11+
## Parameters
12+
13+
| Parameter | Type |
14+
| ------ | ------ |
15+
| `options?` | `"off"` |
16+
17+
## Returns
18+
19+
`Rule`\<`unknown`\>
20+
21+
## Examples
22+
23+
```ts
24+
// Incorrect
25+
import { A } from 'module';
26+
import { B } from 'module';
27+
```
28+
29+
```ts
30+
// Correct
31+
import { A, B } from 'module';
32+
```

packages/tsl-module/package.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "tsl-module",
3+
"version": "0.1.3",
4+
"description": "A TSL plugin for JavaScript and TypeScript module syntax linting and transformations.",
5+
"keywords": [
6+
"tsl",
7+
"tsl-module"
8+
],
9+
"license": "MIT",
10+
"author": "Rel1cx<let@ik.me>",
11+
"sideEffects": false,
12+
"type": "module",
13+
"exports": {
14+
".": {
15+
"types": "./dist/index.d.ts",
16+
"import": "./dist/index.js"
17+
},
18+
"./package.json": "./package.json"
19+
},
20+
"files": [
21+
"dist",
22+
"./package.json"
23+
],
24+
"scripts": {
25+
"build": "tsdown --dts-resolve",
26+
"build:docs": "typedoc",
27+
"lint:publish": "pnpm publint",
28+
"lint:ts": "tsl",
29+
"publish": "pnpm run build && pnpm run lint:publish"
30+
},
31+
"dependencies": {
32+
"@let/eff": "jsr:^0.1.2"
33+
},
34+
"devDependencies": {
35+
"@local/configs": "workspace:*",
36+
"tsdown": "^0.19.0-beta.2"
37+
},
38+
"peerDependencies": {
39+
"tsl": "^1.0.28",
40+
"typescript": "^4.9.5 || ^5.4.5"
41+
},
42+
"engines": {
43+
"bun": ">=1.2.18",
44+
"node": ">=24.6.0"
45+
},
46+
"publishConfig": {
47+
"access": "public"
48+
}
49+
}

packages/tsl-module/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { noDuplicateImport } from "./rules/no-duplicate-import";
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { defineRule } from "tsl";
2+
import ts from "typescript";
3+
4+
export const messages = {
5+
noDuplicateImport: (p: { name: string }) => `Duplicate import of module '${p.name}'.`,
6+
} as const;
7+
8+
/**
9+
* Rule to disallow duplicate imports from the same module.
10+
*
11+
* @example
12+
*
13+
* ```ts
14+
* // Incorrect
15+
* import { A } from 'module';
16+
* import { B } from 'module';
17+
* ```
18+
* @example
19+
*
20+
* ```ts
21+
* // Correct
22+
* import { A, B } from 'module';
23+
* ```
24+
*
25+
* ```ts
26+
* // Correct
27+
* import { A } from 'moduleA';
28+
* import type { B } from 'moduleA';
29+
* ```
30+
*/
31+
export const noDuplicateImport = defineRule(() => {
32+
return {
33+
name: "module/no-duplicate-import",
34+
createData() {
35+
return {
36+
importedModules: new Set<string>(),
37+
};
38+
},
39+
visitor: {
40+
ImportDeclaration(ctx, node) {
41+
if (node.importClause?.phaseModifier === ts.SyntaxKind.TypeKeyword) return;
42+
const moduleName = node.moduleSpecifier.getText().slice(1, -1);
43+
const importedModules = ctx.data.importedModules;
44+
if (importedModules.has(moduleName)) {
45+
ctx.report({
46+
node,
47+
message: messages.noDuplicateImport({ name: moduleName }),
48+
});
49+
return;
50+
}
51+
importedModules.add(moduleName);
52+
},
53+
},
54+
};
55+
});

0 commit comments

Comments
 (0)