tsl-dx 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +45 -50
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -88,6 +88,6 @@ type nullishOptions = {
|
|
|
88
88
|
* if (x == null) { }
|
|
89
89
|
* ```
|
|
90
90
|
*/
|
|
91
|
-
declare const nullish: (options?: "off" |
|
|
91
|
+
declare const nullish: (options?: nullishOptions | "off" | undefined) => tsl.Rule<unknown>;
|
|
92
92
|
//#endregion
|
|
93
93
|
export { noDuplicateExports, noDuplicateImports, noMultilineTemplateExpressionWithoutAutoDedent, nullish };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineRule } from "tsl";
|
|
2
2
|
import ts, { SyntaxKind } from "typescript";
|
|
3
|
-
import {
|
|
3
|
+
import { match } from "ts-pattern";
|
|
4
4
|
|
|
5
5
|
//#region src/rules/no-duplicate-exports.ts
|
|
6
6
|
const messages$3 = { default: (p) => `Duplicate export from module ${p.source}.` };
|
|
@@ -37,7 +37,7 @@ const noDuplicateExports = defineRule(() => {
|
|
|
37
37
|
ctx.report({
|
|
38
38
|
node,
|
|
39
39
|
message: messages$3.default({ source }),
|
|
40
|
-
suggestions: buildSuggestions(duplicateExport, node)
|
|
40
|
+
suggestions: buildSuggestions$1(duplicateExport, node)
|
|
41
41
|
});
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
@@ -45,7 +45,7 @@ const noDuplicateExports = defineRule(() => {
|
|
|
45
45
|
} }
|
|
46
46
|
};
|
|
47
47
|
});
|
|
48
|
-
function buildSuggestions(a, b) {
|
|
48
|
+
function buildSuggestions$1(a, b) {
|
|
49
49
|
switch (true) {
|
|
50
50
|
case ts.isNamedExports(a.exportClause) && ts.isNamedExports(b.exportClause): {
|
|
51
51
|
const aElements = a.exportClause.elements.map((el) => el.getText());
|
|
@@ -69,10 +69,6 @@ function buildSuggestions(a, b) {
|
|
|
69
69
|
//#endregion
|
|
70
70
|
//#region ../../.pkgs/eff/dist/index.js
|
|
71
71
|
/**
|
|
72
|
-
* alias for `undefined`.
|
|
73
|
-
*/
|
|
74
|
-
const unit = void 0;
|
|
75
|
-
/**
|
|
76
72
|
* Creates a function that can be used in a data-last (aka `pipe`able) or
|
|
77
73
|
* data-first style.
|
|
78
74
|
*
|
|
@@ -211,64 +207,63 @@ const noDuplicateImports = defineRule(() => {
|
|
|
211
207
|
return {
|
|
212
208
|
name: "dx/no-duplicate-imports",
|
|
213
209
|
createData() {
|
|
214
|
-
return { imports: [
|
|
215
|
-
[],
|
|
216
|
-
[],
|
|
217
|
-
[]
|
|
218
|
-
] };
|
|
210
|
+
return { imports: new Map([
|
|
211
|
+
["value", []],
|
|
212
|
+
["type", []],
|
|
213
|
+
["defer", []]
|
|
214
|
+
]) };
|
|
219
215
|
},
|
|
220
216
|
visitor: { ImportDeclaration(ctx, node) {
|
|
221
217
|
if (node.importClause == null) return;
|
|
222
|
-
const importKind =
|
|
218
|
+
const importKind = match(node.importClause.phaseModifier).with(ts.SyntaxKind.TypeKeyword, () => "type").with(ts.SyntaxKind.DeferKeyword, () => "defer").otherwise(() => "value");
|
|
223
219
|
const importInfo = {
|
|
224
220
|
node,
|
|
225
221
|
source: node.moduleSpecifier.getText(),
|
|
226
222
|
kind: importKind,
|
|
227
|
-
|
|
223
|
+
defaultImport: node.importClause.name?.getText(),
|
|
224
|
+
bindings: match(node.importClause.namedBindings).with({ kind: ts.SyntaxKind.NamedImports }, (nb) => ({
|
|
225
|
+
kind: "named",
|
|
226
|
+
imports: nb.elements.map((el) => el.getText())
|
|
227
|
+
})).with({ kind: ts.SyntaxKind.NamespaceImport }, (nb) => ({
|
|
228
|
+
kind: "namespace",
|
|
229
|
+
name: nb.name.getText()
|
|
230
|
+
})).otherwise(() => ({
|
|
231
|
+
kind: "named",
|
|
232
|
+
imports: []
|
|
233
|
+
}))
|
|
228
234
|
};
|
|
229
|
-
const existingImports = ctx.data.imports
|
|
235
|
+
const existingImports = ctx.data.imports.get(importKind);
|
|
230
236
|
const duplicateImport = existingImports.find((imp) => imp.source === importInfo.source);
|
|
231
|
-
if (duplicateImport
|
|
232
|
-
|
|
233
|
-
node,
|
|
234
|
-
message: messages$2.default({ source: importInfo.source }),
|
|
235
|
-
suggestions: importKind > 1 ? [] : [{
|
|
236
|
-
message: "Merge duplicate imports",
|
|
237
|
-
changes: [{
|
|
238
|
-
node,
|
|
239
|
-
newText: ""
|
|
240
|
-
}, {
|
|
241
|
-
node: duplicateImport.node,
|
|
242
|
-
newText: buildMergedImport(duplicateImport, importInfo)
|
|
243
|
-
}]
|
|
244
|
-
}]
|
|
245
|
-
});
|
|
237
|
+
if (duplicateImport == null) {
|
|
238
|
+
existingImports.push(importInfo);
|
|
246
239
|
return;
|
|
247
240
|
}
|
|
248
|
-
|
|
241
|
+
ctx.report({
|
|
242
|
+
node,
|
|
243
|
+
message: messages$2.default({ source: importInfo.source }),
|
|
244
|
+
suggestions: buildSuggestions(duplicateImport, importInfo)
|
|
245
|
+
});
|
|
249
246
|
} }
|
|
250
247
|
};
|
|
251
248
|
});
|
|
252
|
-
function
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
function decodeImportClause(node) {
|
|
256
|
-
const { name, namedBindings } = node;
|
|
257
|
-
return {
|
|
258
|
-
defaultImport: name?.getText(),
|
|
259
|
-
namedImports: namedBindings != null && ts.isNamedImports(namedBindings) ? namedBindings.elements.map((el) => el.getText()) : [],
|
|
260
|
-
namespaceImport: namedBindings != null && ts.isNamespaceImport(namedBindings) ? namedBindings.name.getText() : unit
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
function buildMergedImport(a, b) {
|
|
249
|
+
function buildSuggestions(existing, incoming) {
|
|
250
|
+
if (incoming.kind === "defer" || incoming.bindings.kind === "namespace" || existing.bindings.kind === "namespace") return [];
|
|
264
251
|
const parts = [];
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
252
|
+
const defaultImport = existing.defaultImport ?? incoming.defaultImport;
|
|
253
|
+
if (defaultImport != null) parts.push(defaultImport);
|
|
254
|
+
const mergedImports = Array.from(new Set([...existing.bindings.imports, ...incoming.bindings.imports]));
|
|
255
|
+
if (mergedImports.length > 0) parts.push(`{ ${mergedImports.join(", ")} }`);
|
|
256
|
+
const importKindPrefix = incoming.kind === "value" ? "import" : "import type";
|
|
257
|
+
return [{
|
|
258
|
+
message: "Merge duplicate imports",
|
|
259
|
+
changes: [{
|
|
260
|
+
node: incoming.node,
|
|
261
|
+
newText: ""
|
|
262
|
+
}, {
|
|
263
|
+
node: existing.node,
|
|
264
|
+
newText: `${importKindPrefix} ${parts.join(", ")} from ${existing.source};`
|
|
265
|
+
}]
|
|
266
|
+
}];
|
|
272
267
|
}
|
|
273
268
|
|
|
274
269
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsl-dx",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "A tsl plugin for better JavaScript/TypeScript DX.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tsl",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"ts-pattern": "^5.9.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
+
"@liautaud/typezod": "^2.0.0",
|
|
27
28
|
"dedent": "^1.7.1",
|
|
28
29
|
"tsdown": "^0.20.3",
|
|
29
30
|
"tsl": "^1.0.29",
|