@harness-engineering/eslint-plugin 0.3.0 → 0.3.1
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 +12 -0
- package/dist/index.js +53 -26
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -99,6 +99,9 @@ declare const plugin: {
|
|
|
99
99
|
'@harness-engineering/no-forbidden-imports': string;
|
|
100
100
|
'@harness-engineering/require-boundary-schema': string;
|
|
101
101
|
'@harness-engineering/enforce-doc-exports': string;
|
|
102
|
+
'@harness-engineering/no-nested-loops-in-critical': string;
|
|
103
|
+
'@harness-engineering/no-sync-io-in-async': string;
|
|
104
|
+
'@harness-engineering/no-unbounded-array-chains': string;
|
|
102
105
|
'@harness-engineering/no-unix-shell-command': string;
|
|
103
106
|
'@harness-engineering/no-hardcoded-path-separator': string;
|
|
104
107
|
'@harness-engineering/no-process-env-in-spawn': string;
|
|
@@ -115,6 +118,9 @@ declare const plugin: {
|
|
|
115
118
|
'@harness-engineering/no-forbidden-imports': string;
|
|
116
119
|
'@harness-engineering/require-boundary-schema': string;
|
|
117
120
|
'@harness-engineering/enforce-doc-exports': string;
|
|
121
|
+
'@harness-engineering/no-nested-loops-in-critical': string;
|
|
122
|
+
'@harness-engineering/no-sync-io-in-async': string;
|
|
123
|
+
'@harness-engineering/no-unbounded-array-chains': string;
|
|
118
124
|
'@harness-engineering/no-unix-shell-command': string;
|
|
119
125
|
'@harness-engineering/no-hardcoded-path-separator': string;
|
|
120
126
|
'@harness-engineering/no-process-env-in-spawn': string;
|
|
@@ -182,6 +188,9 @@ declare const configs: {
|
|
|
182
188
|
'@harness-engineering/no-forbidden-imports': string;
|
|
183
189
|
'@harness-engineering/require-boundary-schema': string;
|
|
184
190
|
'@harness-engineering/enforce-doc-exports': string;
|
|
191
|
+
'@harness-engineering/no-nested-loops-in-critical': string;
|
|
192
|
+
'@harness-engineering/no-sync-io-in-async': string;
|
|
193
|
+
'@harness-engineering/no-unbounded-array-chains': string;
|
|
185
194
|
'@harness-engineering/no-unix-shell-command': string;
|
|
186
195
|
'@harness-engineering/no-hardcoded-path-separator': string;
|
|
187
196
|
'@harness-engineering/no-process-env-in-spawn': string;
|
|
@@ -245,6 +254,9 @@ declare const configs: {
|
|
|
245
254
|
'@harness-engineering/no-forbidden-imports': string;
|
|
246
255
|
'@harness-engineering/require-boundary-schema': string;
|
|
247
256
|
'@harness-engineering/enforce-doc-exports': string;
|
|
257
|
+
'@harness-engineering/no-nested-loops-in-critical': string;
|
|
258
|
+
'@harness-engineering/no-sync-io-in-async': string;
|
|
259
|
+
'@harness-engineering/no-unbounded-array-chains': string;
|
|
248
260
|
'@harness-engineering/no-unix-shell-command': string;
|
|
249
261
|
'@harness-engineering/no-hardcoded-path-separator': string;
|
|
250
262
|
'@harness-engineering/no-process-env-in-spawn': string;
|
package/dist/index.js
CHANGED
|
@@ -308,17 +308,27 @@ function getConfig(filePath) {
|
|
|
308
308
|
return null;
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
|
+
function getConfigRoot(filePath) {
|
|
312
|
+
const configPath = findConfigFile(path2.dirname(filePath));
|
|
313
|
+
return configPath ? path2.dirname(configPath) : null;
|
|
314
|
+
}
|
|
311
315
|
|
|
312
316
|
// src/utils/path-utils.ts
|
|
313
317
|
import * as path3 from "path";
|
|
314
318
|
import { minimatch } from "minimatch";
|
|
315
|
-
function resolveImportPath(importPath, importingFile) {
|
|
319
|
+
function resolveImportPath(importPath, importingFile, projectRoot) {
|
|
316
320
|
if (!importPath.startsWith(".")) {
|
|
317
321
|
return importPath;
|
|
318
322
|
}
|
|
319
323
|
const importingDir = path3.dirname(importingFile);
|
|
320
324
|
const resolved = path3.resolve(importingDir, importPath);
|
|
321
325
|
const normalized = resolved.replace(/\\/g, "/");
|
|
326
|
+
if (projectRoot) {
|
|
327
|
+
const root = projectRoot.replace(/\\/g, "/").replace(/\/$/, "");
|
|
328
|
+
if (normalized.startsWith(root + "/")) {
|
|
329
|
+
return normalized.slice(root.length + 1);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
322
332
|
const srcIndex = normalized.indexOf("/src/");
|
|
323
333
|
if (srcIndex !== -1) {
|
|
324
334
|
return normalized.slice(srcIndex + 1);
|
|
@@ -341,8 +351,14 @@ function getLayerForFile(filePath, layers) {
|
|
|
341
351
|
function getLayerByName(name, layers) {
|
|
342
352
|
return layers.find((l) => l.name === name);
|
|
343
353
|
}
|
|
344
|
-
function normalizePath2(filePath) {
|
|
354
|
+
function normalizePath2(filePath, projectRoot) {
|
|
345
355
|
const normalized = filePath.replace(/\\/g, "/");
|
|
356
|
+
if (projectRoot) {
|
|
357
|
+
const root = projectRoot.replace(/\\/g, "/").replace(/\/$/, "");
|
|
358
|
+
if (normalized.startsWith(root + "/")) {
|
|
359
|
+
return normalized.slice(root.length + 1);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
346
362
|
const srcIndex = normalized.indexOf("/src/");
|
|
347
363
|
if (srcIndex !== -1) {
|
|
348
364
|
return normalized.slice(srcIndex + 1);
|
|
@@ -370,9 +386,9 @@ function findViolatedRule(applicableRules, importPath, resolvedImport) {
|
|
|
370
386
|
function buildForbiddenMessage(rule, importPath) {
|
|
371
387
|
return rule.message ?? `Import "${importPath}" is forbidden in files matching "${rule.from}"`;
|
|
372
388
|
}
|
|
373
|
-
function checkImportDeclaration2(node, applicableRules, filename, report) {
|
|
389
|
+
function checkImportDeclaration2(node, applicableRules, filename, projectRoot, report) {
|
|
374
390
|
const importPath = node.source.value;
|
|
375
|
-
const resolvedImport = resolveImportPath(importPath, filename);
|
|
391
|
+
const resolvedImport = resolveImportPath(importPath, filename, projectRoot ?? void 0);
|
|
376
392
|
const violatedRule = findViolatedRule(applicableRules, importPath, resolvedImport);
|
|
377
393
|
if (violatedRule) {
|
|
378
394
|
report({
|
|
@@ -400,7 +416,8 @@ var no_forbidden_imports_default = createRule3({
|
|
|
400
416
|
if (!config?.forbiddenImports?.length) {
|
|
401
417
|
return {};
|
|
402
418
|
}
|
|
403
|
-
const
|
|
419
|
+
const projectRoot = getConfigRoot(context.filename);
|
|
420
|
+
const filePath = normalizePath2(context.filename, projectRoot ?? void 0);
|
|
404
421
|
const applicableRules = config.forbiddenImports.filter(
|
|
405
422
|
(rule) => matchesPattern(filePath, rule.from)
|
|
406
423
|
);
|
|
@@ -410,7 +427,7 @@ var no_forbidden_imports_default = createRule3({
|
|
|
410
427
|
const report = context.report.bind(context);
|
|
411
428
|
return {
|
|
412
429
|
ImportDeclaration(node) {
|
|
413
|
-
checkImportDeclaration2(node, applicableRules, context.filename, report);
|
|
430
|
+
checkImportDeclaration2(node, applicableRules, context.filename, projectRoot, report);
|
|
414
431
|
}
|
|
415
432
|
};
|
|
416
433
|
}
|
|
@@ -424,13 +441,13 @@ var createRule4 = ESLintUtils4.RuleCreator(
|
|
|
424
441
|
function isLayerViolation(importLayer, currentLayer, currentLayerDef) {
|
|
425
442
|
return importLayer !== currentLayer && !currentLayerDef.allowedDependencies.includes(importLayer);
|
|
426
443
|
}
|
|
427
|
-
function resolveImportLayer(importPath, filename, layers) {
|
|
444
|
+
function resolveImportLayer(importPath, filename, layers, projectRoot) {
|
|
428
445
|
if (!importPath.startsWith(".")) return null;
|
|
429
|
-
const resolvedImport = resolveImportPath(importPath, filename);
|
|
446
|
+
const resolvedImport = resolveImportPath(importPath, filename, projectRoot ?? void 0);
|
|
430
447
|
return getLayerForFile(resolvedImport, layers) ?? null;
|
|
431
448
|
}
|
|
432
|
-
function checkLayerImport(node, context, currentLayer, currentLayerDef, layers) {
|
|
433
|
-
const importLayer = resolveImportLayer(node.source.value, context.filename, layers);
|
|
449
|
+
function checkLayerImport(node, context, currentLayer, currentLayerDef, layers, projectRoot) {
|
|
450
|
+
const importLayer = resolveImportLayer(node.source.value, context.filename, layers, projectRoot);
|
|
434
451
|
if (!importLayer) return;
|
|
435
452
|
if (isLayerViolation(importLayer, currentLayer, currentLayerDef)) {
|
|
436
453
|
context.report({
|
|
@@ -458,7 +475,8 @@ var no_layer_violation_default = createRule4({
|
|
|
458
475
|
if (!config?.layers?.length) {
|
|
459
476
|
return {};
|
|
460
477
|
}
|
|
461
|
-
const
|
|
478
|
+
const projectRoot = getConfigRoot(context.filename);
|
|
479
|
+
const filePath = normalizePath2(context.filename, projectRoot ?? void 0);
|
|
462
480
|
const currentLayer = getLayerForFile(filePath, config.layers);
|
|
463
481
|
if (!currentLayer) {
|
|
464
482
|
return {};
|
|
@@ -470,7 +488,7 @@ var no_layer_violation_default = createRule4({
|
|
|
470
488
|
const layers = config.layers;
|
|
471
489
|
return {
|
|
472
490
|
ImportDeclaration(node) {
|
|
473
|
-
checkLayerImport(node, context, currentLayer, currentLayerDef, layers);
|
|
491
|
+
checkLayerImport(node, context, currentLayer, currentLayerDef, layers, projectRoot);
|
|
474
492
|
}
|
|
475
493
|
};
|
|
476
494
|
}
|
|
@@ -964,6 +982,14 @@ function hasProcessEnvProperty(node) {
|
|
|
964
982
|
}
|
|
965
983
|
return void 0;
|
|
966
984
|
}
|
|
985
|
+
function findEnvViolation(args) {
|
|
986
|
+
for (const arg of args) {
|
|
987
|
+
if (arg.type !== "ObjectExpression") continue;
|
|
988
|
+
const envProp = hasProcessEnvProperty(arg);
|
|
989
|
+
if (envProp) return envProp;
|
|
990
|
+
}
|
|
991
|
+
return void 0;
|
|
992
|
+
}
|
|
967
993
|
var no_process_env_in_spawn_default = createRule11({
|
|
968
994
|
name: "no-process-env-in-spawn",
|
|
969
995
|
meta: {
|
|
@@ -978,20 +1004,15 @@ var no_process_env_in_spawn_default = createRule11({
|
|
|
978
1004
|
},
|
|
979
1005
|
defaultOptions: [],
|
|
980
1006
|
create(context) {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
const envProp = hasProcessEnvProperty(arg);
|
|
988
|
-
if (envProp) {
|
|
989
|
-
context.report({ node: envProp, messageId: "processEnvInSpawn", data: { name } });
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
}
|
|
1007
|
+
function checkCall(node) {
|
|
1008
|
+
const name = getSpawnFunctionName(node);
|
|
1009
|
+
if (!name) return;
|
|
1010
|
+
const violation = findEnvViolation(node.arguments);
|
|
1011
|
+
if (violation) {
|
|
1012
|
+
context.report({ node: violation, messageId: "processEnvInSpawn", data: { name } });
|
|
993
1013
|
}
|
|
994
|
-
}
|
|
1014
|
+
}
|
|
1015
|
+
return { CallExpression: checkCall };
|
|
995
1016
|
}
|
|
996
1017
|
});
|
|
997
1018
|
|
|
@@ -1072,7 +1093,7 @@ var rules = {
|
|
|
1072
1093
|
var plugin = {
|
|
1073
1094
|
meta: {
|
|
1074
1095
|
name: "@harness-engineering/eslint-plugin",
|
|
1075
|
-
version: "0.
|
|
1096
|
+
version: "0.3.0"
|
|
1076
1097
|
},
|
|
1077
1098
|
rules,
|
|
1078
1099
|
configs: {
|
|
@@ -1088,6 +1109,9 @@ var plugin = {
|
|
|
1088
1109
|
"@harness-engineering/no-forbidden-imports": "error",
|
|
1089
1110
|
"@harness-engineering/require-boundary-schema": "warn",
|
|
1090
1111
|
"@harness-engineering/enforce-doc-exports": "warn",
|
|
1112
|
+
"@harness-engineering/no-nested-loops-in-critical": "warn",
|
|
1113
|
+
"@harness-engineering/no-sync-io-in-async": "warn",
|
|
1114
|
+
"@harness-engineering/no-unbounded-array-chains": "warn",
|
|
1091
1115
|
"@harness-engineering/no-unix-shell-command": "warn",
|
|
1092
1116
|
"@harness-engineering/no-hardcoded-path-separator": "warn",
|
|
1093
1117
|
"@harness-engineering/no-process-env-in-spawn": "error",
|
|
@@ -1106,6 +1130,9 @@ var plugin = {
|
|
|
1106
1130
|
"@harness-engineering/no-forbidden-imports": "error",
|
|
1107
1131
|
"@harness-engineering/require-boundary-schema": "error",
|
|
1108
1132
|
"@harness-engineering/enforce-doc-exports": "error",
|
|
1133
|
+
"@harness-engineering/no-nested-loops-in-critical": "error",
|
|
1134
|
+
"@harness-engineering/no-sync-io-in-async": "error",
|
|
1135
|
+
"@harness-engineering/no-unbounded-array-chains": "error",
|
|
1109
1136
|
"@harness-engineering/no-unix-shell-command": "error",
|
|
1110
1137
|
"@harness-engineering/no-hardcoded-path-separator": "error",
|
|
1111
1138
|
"@harness-engineering/no-process-env-in-spawn": "error",
|