@futdevpro/dynamo-eslint 1.15.19 → 1.15.21
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/.dynamo/pipeline.cicd.config.json +3 -3
- package/build/plugin/rules/prefer-interface-over-duplicate-types.d.ts.map +1 -1
- package/build/plugin/rules/prefer-interface-over-duplicate-types.js +44 -10
- package/build/plugin/rules/prefer-interface-over-duplicate-types.js.map +1 -1
- package/package.json +1 -1
- package/src/plugin/rules/prefer-interface-over-duplicate-types.spec.ts +36 -6
- package/src/plugin/rules/prefer-interface-over-duplicate-types.ts +53 -15
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
153
|
"label": "pipeline-report",
|
|
154
|
-
"command": "fdp pipeline-report --report ./logs/cicd-pipeline/cicd-report.json --overseer-
|
|
154
|
+
"command": "fdp pipeline-report --report ./logs/cicd-pipeline/cicd-report.json --overseer-secret $OVERSEER_SECRET_KEY --branch $GITHUB_REF_NAME",
|
|
155
155
|
"fatal": false,
|
|
156
156
|
"always": true,
|
|
157
157
|
"discord": {
|
|
@@ -160,13 +160,13 @@
|
|
|
160
160
|
},
|
|
161
161
|
"condition": {
|
|
162
162
|
"envSet": [
|
|
163
|
-
"
|
|
163
|
+
"OVERSEER_SECRET_KEY"
|
|
164
164
|
]
|
|
165
165
|
}
|
|
166
166
|
},
|
|
167
167
|
{
|
|
168
168
|
"label": "discord-result",
|
|
169
|
-
"command": "fdp pipeline-notify --report ./logs/cicd-pipeline/cicd-report.json --config ./pipeline.cicd.config.json --app-name Dynamo-ESLint --app-emoji 🔧 --webhook-id $DISCORD_WEBHOOK_ID --webhook-token $DISCORD_WEBHOOK_TOKEN
|
|
169
|
+
"command": "fdp pipeline-notify --report ./logs/cicd-pipeline/cicd-report.json --config ./pipeline.cicd.config.json --app-name Dynamo-ESLint --app-emoji 🔧 --webhook-id $DISCORD_WEBHOOK_ID --webhook-token $DISCORD_WEBHOOK_TOKEN",
|
|
170
170
|
"fatal": false,
|
|
171
171
|
"retryOnFail": 2,
|
|
172
172
|
"retryDelaySec": 5,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-interface-over-duplicate-types.d.ts","sourceRoot":"","sources":["../../../src/plugin/rules/prefer-interface-over-duplicate-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAY9B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"prefer-interface-over-duplicate-types.d.ts","sourceRoot":"","sources":["../../../src/plugin/rules/prefer-interface-over-duplicate-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAY9B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA2ShB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -23,6 +23,10 @@ const rule = {
|
|
|
23
23
|
messages: {
|
|
24
24
|
preferInterface: 'Object type used {{count}} times. Consider creating interface "{{interfaceName}}"}}',
|
|
25
25
|
},
|
|
26
|
+
// BFR-ADVENTOR-009 (2. lépcső): a fixer forrás-szöveg-megőrzőre átírva (`sourceCode.getText` per property)
|
|
27
|
+
// → a komplex/union/qualified/function típusok EXAKT megőrződnek, a generált interface ÉRVÉNYES TS. Ezért
|
|
28
|
+
// az auto-fix (`fixable:'code'`) VISSZA — a bulk `eslint --fix` biztonságosan futtathatja (nem generál
|
|
29
|
+
// többé `reference`/`complex` literál-hibát). (1. lépcső: suggestion-degrade, most feloldva.)
|
|
26
30
|
fixable: 'code',
|
|
27
31
|
},
|
|
28
32
|
create(context) {
|
|
@@ -139,6 +143,40 @@ const rule = {
|
|
|
139
143
|
}
|
|
140
144
|
return name;
|
|
141
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* BFR-ADVENTOR-009 (2. lépcső): az interface-törzs a FORRÁS-SZÖVEGBŐL épül (sourceCode.getText per
|
|
148
|
+
* member), NEM a lossy normalizált signature-ből → a komplex/union/qualified/function típusok EXAKT
|
|
149
|
+
* megőrződnek (a korábbi `reference`/`complex`/`union` literál-hibák megszűnnek). A `getText` az eredeti
|
|
150
|
+
* property-szöveget adja (pl. `onError: (e: Error) => void`); a záró `;`/`,`-t normalizáljuk.
|
|
151
|
+
*/
|
|
152
|
+
function buildInterfaceBody(node) {
|
|
153
|
+
const members = Array.isArray(node?.members) ? node.members : [];
|
|
154
|
+
return members
|
|
155
|
+
.map((member) => {
|
|
156
|
+
const text = sourceCode.getText(member).trim().replace(/[;,]\s*$/, '');
|
|
157
|
+
return ` ${text};`;
|
|
158
|
+
})
|
|
159
|
+
.join('\n');
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Beszédes interface-név a property-kulcsokból (BFR-ADVENTOR-009): a nem-beszédes, ütköző
|
|
163
|
+
* `GeneratedInterfaceN` helyett az első 1-3 kulcsból PascalCase + `Params_Interface` (a projekt-konvenció).
|
|
164
|
+
*/
|
|
165
|
+
function deriveInterfaceName(node) {
|
|
166
|
+
const members = Array.isArray(node?.members) ? node.members : [];
|
|
167
|
+
const keys = members
|
|
168
|
+
.filter((m) => m.type === 'TSPropertySignature')
|
|
169
|
+
.map((m) => String(m.key?.name ?? m.key?.value ?? ''))
|
|
170
|
+
.filter((k) => !!k)
|
|
171
|
+
.slice(0, 3);
|
|
172
|
+
if (!keys.length) {
|
|
173
|
+
return 'Generated_Interface';
|
|
174
|
+
}
|
|
175
|
+
const pascal = keys
|
|
176
|
+
.map((k) => k.charAt(0).toUpperCase() + k.slice(1))
|
|
177
|
+
.join('');
|
|
178
|
+
return `${pascal}_Interface`;
|
|
179
|
+
}
|
|
142
180
|
return {
|
|
143
181
|
TSTypeLiteral(node, _context, _sourceCode) {
|
|
144
182
|
try {
|
|
@@ -164,7 +202,10 @@ const rule = {
|
|
|
164
202
|
// Process all collected type usages
|
|
165
203
|
for (const [signature, usages] of typeUsages) {
|
|
166
204
|
if (usages.length >= threshold) {
|
|
167
|
-
|
|
205
|
+
// beszédes név a property-kulcsokból (ütközés-mentesre pontosítva)
|
|
206
|
+
const interfaceName = generateUniqueInterfaceName(deriveInterfaceName(usages[0].node));
|
|
207
|
+
// a törzs a FORRÁS-SZÖVEGBŐL (getText) — a komplex/union/qualified típusok EXAKT megőrződnek
|
|
208
|
+
const interfaceBody = buildInterfaceBody(usages[0].node);
|
|
168
209
|
// Report on each usage
|
|
169
210
|
for (const usage of usages) {
|
|
170
211
|
context.report({
|
|
@@ -176,12 +217,7 @@ const rule = {
|
|
|
176
217
|
},
|
|
177
218
|
fix(fixer) {
|
|
178
219
|
try {
|
|
179
|
-
|
|
180
|
-
const properties = signature.split(';').map(prop => {
|
|
181
|
-
const [key, type] = prop.split(':');
|
|
182
|
-
return ` ${key}: ${type};`;
|
|
183
|
-
}).join('\n');
|
|
184
|
-
const interfaceDeclaration = `interface ${interfaceName} {\n${properties}\n}`;
|
|
220
|
+
const interfaceDeclaration = `interface ${interfaceName} {\n${interfaceBody}\n}`;
|
|
185
221
|
// Find insertion point (after imports, before other code)
|
|
186
222
|
const firstNode = sourceCode.ast.body[0];
|
|
187
223
|
let insertPosition = 0;
|
|
@@ -204,9 +240,7 @@ const rule = {
|
|
|
204
240
|
];
|
|
205
241
|
// Replace all usages with interface reference
|
|
206
242
|
for (const usage of usages) {
|
|
207
|
-
|
|
208
|
-
const replacement = interfaceName;
|
|
209
|
-
fixes.push(fixer.replaceText(usage.node, replacement));
|
|
243
|
+
fixes.push(fixer.replaceText(usage.node, interfaceName));
|
|
210
244
|
}
|
|
211
245
|
return fixes;
|
|
212
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-interface-over-duplicate-types.js","sourceRoot":"","sources":["../../../src/plugin/rules/prefer-interface-over-duplicate-types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"prefer-interface-over-duplicate-types.js","sourceRoot":"","sources":["../../../src/plugin/rules/prefer-interface-over-duplicate-types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
4
4
|
it('| should be a valid ESLint rule', () => {
|
|
5
5
|
expect(preferInterfaceRule.meta?.type).toBe('suggestion');
|
|
6
6
|
expect(preferInterfaceRule.meta?.docs?.description).toContain('Suggest creating interfaces');
|
|
7
|
+
// BFR-ADVENTOR-009 (2. lépcső): a forrás-megőrző fixer VISSZAKAPCSOLVA auto-fix-re (érvényes kódot ad).
|
|
7
8
|
expect(preferInterfaceRule.meta?.fixable).toBe('code');
|
|
8
9
|
});
|
|
9
10
|
|
|
@@ -238,15 +239,35 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
238
239
|
expect(reportCalled).toBe(true);
|
|
239
240
|
});
|
|
240
241
|
|
|
241
|
-
it('|
|
|
242
|
+
it('| auto-fix a FORRÁS-SZÖVEGBŐL épít (BFR-ADVENTOR-009 2. lépcső: komplex típus megőrizve, nem `reference`)', () => {
|
|
243
|
+
// egy komplex property-t szimulálunk: a member getText-je egy function-type — a régi lossy fixer
|
|
244
|
+
// ezt `reference`/`complex`-re redukálta (érvénytelen TS); az új fixer EXAKT megőrzi.
|
|
245
|
+
const complexMember: any = {
|
|
246
|
+
type: 'TSPropertySignature', key: { name: 'onError' },
|
|
247
|
+
};
|
|
248
|
+
const numberMember: any = {
|
|
249
|
+
type: 'TSPropertySignature', key: { name: 'count' },
|
|
250
|
+
};
|
|
251
|
+
const memberTexts: Map<any, string> = new Map([
|
|
252
|
+
[ complexMember, 'onError: (e: Error) => void' ],
|
|
253
|
+
[ numberMember, 'count: number' ],
|
|
254
|
+
]);
|
|
255
|
+
|
|
256
|
+
let insertedText: string = '';
|
|
257
|
+
const mockFixer: any = {
|
|
258
|
+
insertTextAfterRange: (_range: unknown, text: string): unknown => { insertedText = text; return {}; },
|
|
259
|
+
replaceText: (): unknown => ({}),
|
|
260
|
+
};
|
|
261
|
+
|
|
242
262
|
const mockContext = {
|
|
243
263
|
report: (options: any) => {
|
|
244
|
-
expect(options.fix).
|
|
245
|
-
|
|
264
|
+
expect(typeof options.fix).toBe('function'); // auto-fix VISSZA (nem suggestion)
|
|
265
|
+
options.fix(mockFixer);
|
|
246
266
|
},
|
|
247
267
|
options: [{ threshold: 2 }],
|
|
248
268
|
sourceCode: {
|
|
249
|
-
|
|
269
|
+
// a body-generátor a member-node getText-jét használja; a normalizáló getTypeString nem fut a fixerben
|
|
270
|
+
getText: (n: any): string => memberTexts.get(n) ?? '{ onError: fn; count: number }',
|
|
250
271
|
getScope: () => ({ variables: [] }),
|
|
251
272
|
ast: { body: [] },
|
|
252
273
|
},
|
|
@@ -257,14 +278,23 @@ describe('| prefer-interface-over-duplicate-types', () => {
|
|
|
257
278
|
const mockNode = {
|
|
258
279
|
type: 'TSTypeLiteral',
|
|
259
280
|
members: [
|
|
260
|
-
{
|
|
261
|
-
{
|
|
281
|
+
{ ...complexMember, typeAnnotation: { typeAnnotation: { type: 'TSFunctionType' } } },
|
|
282
|
+
{ ...numberMember, typeAnnotation: { typeAnnotation: { type: 'TSNumberKeyword' } } },
|
|
262
283
|
],
|
|
263
284
|
} as any;
|
|
285
|
+
// a getText a fenti two member-referenciákat kapja — a mockNode.members MÁSOK, ezért a getText-map
|
|
286
|
+
// kulcsait használjuk a mockNode.members-ként:
|
|
287
|
+
mockNode.members = [ complexMember, numberMember ];
|
|
264
288
|
|
|
265
289
|
rule.TSTypeLiteral(mockNode);
|
|
266
290
|
rule.TSTypeLiteral(mockNode);
|
|
267
291
|
rule['Program:exit']({} as any);
|
|
292
|
+
|
|
293
|
+
// a generált interface a MEGŐRZÖTT function-type-ot tartalmazza, NEM `reference`/`complex`-et
|
|
294
|
+
expect(insertedText).toContain('onError: (e: Error) => void;');
|
|
295
|
+
expect(insertedText).toContain('count: number;');
|
|
296
|
+
expect(insertedText).not.toContain('reference');
|
|
297
|
+
expect(insertedText).not.toContain('complex');
|
|
268
298
|
});
|
|
269
299
|
|
|
270
300
|
it('| should handle default threshold when no options provided', () => {
|
|
@@ -33,6 +33,10 @@ const rule: Rule.RuleModule = {
|
|
|
33
33
|
messages: {
|
|
34
34
|
preferInterface: 'Object type used {{count}} times. Consider creating interface "{{interfaceName}}"}}',
|
|
35
35
|
},
|
|
36
|
+
// BFR-ADVENTOR-009 (2. lépcső): a fixer forrás-szöveg-megőrzőre átírva (`sourceCode.getText` per property)
|
|
37
|
+
// → a komplex/union/qualified/function típusok EXAKT megőrződnek, a generált interface ÉRVÉNYES TS. Ezért
|
|
38
|
+
// az auto-fix (`fixable:'code'`) VISSZA — a bulk `eslint --fix` biztonságosan futtathatja (nem generál
|
|
39
|
+
// többé `reference`/`complex` literál-hibát). (1. lépcső: suggestion-degrade, most feloldva.)
|
|
36
40
|
fixable: 'code',
|
|
37
41
|
},
|
|
38
42
|
create(context) {
|
|
@@ -159,15 +163,55 @@ const rule: Rule.RuleModule = {
|
|
|
159
163
|
function generateUniqueInterfaceName(baseName: string): string {
|
|
160
164
|
let name = baseName;
|
|
161
165
|
let counter = 1;
|
|
162
|
-
|
|
166
|
+
|
|
163
167
|
while (isNameConflict(name)) {
|
|
164
168
|
name = `${baseName}${counter}`;
|
|
165
169
|
counter++;
|
|
166
170
|
}
|
|
167
|
-
|
|
171
|
+
|
|
168
172
|
return name;
|
|
169
173
|
}
|
|
170
174
|
|
|
175
|
+
/**
|
|
176
|
+
* BFR-ADVENTOR-009 (2. lépcső): az interface-törzs a FORRÁS-SZÖVEGBŐL épül (sourceCode.getText per
|
|
177
|
+
* member), NEM a lossy normalizált signature-ből → a komplex/union/qualified/function típusok EXAKT
|
|
178
|
+
* megőrződnek (a korábbi `reference`/`complex`/`union` literál-hibák megszűnnek). A `getText` az eredeti
|
|
179
|
+
* property-szöveget adja (pl. `onError: (e: Error) => void`); a záró `;`/`,`-t normalizáljuk.
|
|
180
|
+
*/
|
|
181
|
+
function buildInterfaceBody(node: any): string {
|
|
182
|
+
const members: any[] = Array.isArray(node?.members) ? node.members : [];
|
|
183
|
+
|
|
184
|
+
return members
|
|
185
|
+
.map((member: any): string => {
|
|
186
|
+
const text: string = sourceCode.getText(member).trim().replace(/[;,]\s*$/, '');
|
|
187
|
+
return ` ${text};`;
|
|
188
|
+
})
|
|
189
|
+
.join('\n');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Beszédes interface-név a property-kulcsokból (BFR-ADVENTOR-009): a nem-beszédes, ütköző
|
|
194
|
+
* `GeneratedInterfaceN` helyett az első 1-3 kulcsból PascalCase + `Params_Interface` (a projekt-konvenció).
|
|
195
|
+
*/
|
|
196
|
+
function deriveInterfaceName(node: any): string {
|
|
197
|
+
const members: any[] = Array.isArray(node?.members) ? node.members : [];
|
|
198
|
+
const keys: string[] = members
|
|
199
|
+
.filter((m: any): boolean => m.type === 'TSPropertySignature')
|
|
200
|
+
.map((m: any): string => String(m.key?.name ?? m.key?.value ?? ''))
|
|
201
|
+
.filter((k: string): boolean => !!k)
|
|
202
|
+
.slice(0, 3);
|
|
203
|
+
|
|
204
|
+
if (!keys.length) {
|
|
205
|
+
return 'Generated_Interface';
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const pascal: string = keys
|
|
209
|
+
.map((k: string): string => k.charAt(0).toUpperCase() + k.slice(1))
|
|
210
|
+
.join('');
|
|
211
|
+
|
|
212
|
+
return `${pascal}_Interface`;
|
|
213
|
+
}
|
|
214
|
+
|
|
171
215
|
return {
|
|
172
216
|
TSTypeLiteral(node: any, _context?: any, _sourceCode?: any): void {
|
|
173
217
|
try {
|
|
@@ -197,10 +241,14 @@ const rule: Rule.RuleModule = {
|
|
|
197
241
|
// Process all collected type usages
|
|
198
242
|
for (const [ signature, usages ] of typeUsages) {
|
|
199
243
|
if (usages.length >= threshold) {
|
|
244
|
+
// beszédes név a property-kulcsokból (ütközés-mentesre pontosítva)
|
|
200
245
|
const interfaceName = generateUniqueInterfaceName(
|
|
201
|
-
|
|
246
|
+
deriveInterfaceName(usages[0].node)
|
|
202
247
|
);
|
|
203
248
|
|
|
249
|
+
// a törzs a FORRÁS-SZÖVEGBŐL (getText) — a komplex/union/qualified típusok EXAKT megőrződnek
|
|
250
|
+
const interfaceBody: string = buildInterfaceBody(usages[0].node);
|
|
251
|
+
|
|
204
252
|
// Report on each usage
|
|
205
253
|
for (const usage of usages) {
|
|
206
254
|
context.report({
|
|
@@ -212,14 +260,7 @@ const rule: Rule.RuleModule = {
|
|
|
212
260
|
},
|
|
213
261
|
fix(fixer) {
|
|
214
262
|
try {
|
|
215
|
-
|
|
216
|
-
const properties = signature.split(';').map(prop => {
|
|
217
|
-
const [ key, type ] = prop.split(':');
|
|
218
|
-
|
|
219
|
-
return ` ${key}: ${type};`;
|
|
220
|
-
}).join('\n');
|
|
221
|
-
|
|
222
|
-
const interfaceDeclaration = `interface ${interfaceName} {\n${properties}\n}`;
|
|
263
|
+
const interfaceDeclaration = `interface ${interfaceName} {\n${interfaceBody}\n}`;
|
|
223
264
|
|
|
224
265
|
// Find insertion point (after imports, before other code)
|
|
225
266
|
const firstNode = sourceCode.ast.body[0];
|
|
@@ -246,11 +287,8 @@ const rule: Rule.RuleModule = {
|
|
|
246
287
|
|
|
247
288
|
// Replace all usages with interface reference
|
|
248
289
|
for (const usage of usages) {
|
|
249
|
-
const nodeText = sourceCode.getText(usage.node);
|
|
250
|
-
const replacement = interfaceName;
|
|
251
|
-
|
|
252
290
|
fixes.push(
|
|
253
|
-
fixer.replaceText(usage.node,
|
|
291
|
+
fixer.replaceText(usage.node, interfaceName)
|
|
254
292
|
);
|
|
255
293
|
}
|
|
256
294
|
|