@nx/eslint-plugin 23.1.0 → 23.1.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.
@@ -11,7 +11,7 @@ export type Options = [
11
11
  tsConfig?: string;
12
12
  }
13
13
  ];
14
- export type MessageIds = 'missingRequiredSchema' | 'invalidSchemaPath' | 'missingImplementation' | 'invalidImplementationPath' | 'invalidImplementationModule' | 'unableToReadImplementationExports' | 'invalidPromptPath' | 'invalidVersion' | 'missingVersion' | 'noGeneratorsOrSchematicsFound' | 'noExecutorsOrBuildersFound' | 'valueShouldBeObject';
14
+ export type MessageIds = 'missingRequiredSchema' | 'invalidSchemaPath' | 'missingImplementation' | 'invalidImplementationPath' | 'invalidImplementationModule' | 'unableToReadImplementationExports' | 'invalidPromptPath' | 'invalidVersion' | 'missingVersion' | 'noGeneratorsOrSchematicsFound' | 'noExecutorsOrBuildersFound' | 'valueShouldBeObject' | 'duplicateKey';
15
15
  export declare const RULE_NAME = "nx-plugin-checks";
16
16
  declare const _default: TSESLint.RuleModule<MessageIds, Options, unknown, TSESLint.RuleListener> & {
17
17
  name: string;
@@ -23,5 +23,12 @@ export declare function validateEntry(baseNode: AST.JSONObjectExpression, key: s
23
23
  export declare function validateImplementationNode(implementationNode: AST.JSONProperty, key: string, context: TSESLint.RuleContext<MessageIds, Options>, projects: Record<string, ProjectConfiguration>): void;
24
24
  export declare function validatePromptNode(promptNode: AST.JSONProperty, key: string, context: TSESLint.RuleContext<MessageIds, Options>): void;
25
25
  export declare function validatePackageGroup(baseNode: AST.JSONObjectExpression, context: TSESLint.RuleContext<MessageIds, Options>): void;
26
+ /**
27
+ * A duplicate key anywhere in these manifests silently drops data:
28
+ * JSON parsers keep only the last occurrence, so a duplicated generator,
29
+ * executor, or migration entry key discards the earlier definition with no
30
+ * error at runtime.
31
+ */
32
+ export declare function validateNoDuplicateKeys(node: AST.JSONObjectExpression | AST.JSONArrayExpression, context: TSESLint.RuleContext<MessageIds, Options>): void;
26
33
  export declare function validateVersionJsonExpression(node: AST.JSONExpression, context: TSESLint.RuleContext<MessageIds, Options>): string | boolean;
27
34
  export declare function checkIfIdentifierIsFunction(filePath: string, identifier: string): boolean;
@@ -7,6 +7,7 @@ exports.validateEntry = validateEntry;
7
7
  exports.validateImplementationNode = validateImplementationNode;
8
8
  exports.validatePromptNode = validatePromptNode;
9
9
  exports.validatePackageGroup = validatePackageGroup;
10
+ exports.validateNoDuplicateKeys = validateNoDuplicateKeys;
10
11
  exports.validateVersionJsonExpression = validateVersionJsonExpression;
11
12
  exports.checkIfIdentifierIsFunction = checkIfIdentifierIsFunction;
12
13
  const tslib_1 = require("tslib");
@@ -82,6 +83,7 @@ exports.default = utils_1.ESLintUtils.RuleCreator(() => ``)({
82
83
  missingImplementation: '{{ key }}: Missing required property - `implementation`',
83
84
  invalidPromptPath: '{{ key }}: Prompt path should point to a valid file',
84
85
  missingVersion: '{{ key }}: Missing required property - `version`',
86
+ duplicateKey: '{{ key }}: Duplicate key. JSON parsers keep only the last occurrence, silently dropping the earlier one',
85
87
  },
86
88
  },
87
89
  defaultOptions: [DEFAULT_OPTIONS],
@@ -109,6 +111,7 @@ exports.default = utils_1.ESLintUtils.RuleCreator(() => ``)({
109
111
  }
110
112
  return {
111
113
  ['JSONExpressionStatement > JSONObjectExpression'](node) {
114
+ validateNoDuplicateKeys(node, context);
112
115
  if (sourceFilePath === generatorsJson) {
113
116
  checkCollectionFileNode(node, 'generator', context, projects);
114
117
  }
@@ -425,6 +428,43 @@ function validatePackageGroup(baseNode, context) {
425
428
  }
426
429
  }
427
430
  }
431
+ /**
432
+ * A duplicate key anywhere in these manifests silently drops data:
433
+ * JSON parsers keep only the last occurrence, so a duplicated generator,
434
+ * executor, or migration entry key discards the earlier definition with no
435
+ * error at runtime.
436
+ */
437
+ function validateNoDuplicateKeys(node, context) {
438
+ if (node.type === 'JSONObjectExpression') {
439
+ const seen = new Set();
440
+ for (const property of node.properties) {
441
+ const key = property.key.type === 'JSONLiteral'
442
+ ? String(property.key.value)
443
+ : property.key.name;
444
+ if (seen.has(key)) {
445
+ context.report({
446
+ messageId: 'duplicateKey',
447
+ data: { key },
448
+ node: property.key,
449
+ });
450
+ }
451
+ seen.add(key);
452
+ if (property.value.type === 'JSONObjectExpression' ||
453
+ property.value.type === 'JSONArrayExpression') {
454
+ validateNoDuplicateKeys(property.value, context);
455
+ }
456
+ }
457
+ }
458
+ else {
459
+ for (const element of node.elements) {
460
+ if (element &&
461
+ (element.type === 'JSONObjectExpression' ||
462
+ element.type === 'JSONArrayExpression')) {
463
+ validateNoDuplicateKeys(element, context);
464
+ }
465
+ }
466
+ }
467
+ }
428
468
  function validateVersionJsonExpression(node, context) {
429
469
  return (node &&
430
470
  node.type === 'JSONLiteral' &&
@@ -2,9 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ensureGlobalProjectGraph = ensureGlobalProjectGraph;
4
4
  exports.readProjectGraph = readProjectGraph;
5
+ const tslib_1 = require("tslib");
5
6
  const devkit_1 = require("@nx/devkit");
6
7
  const runtime_lint_utils_1 = require("./runtime-lint-utils");
7
- const chalk = require("chalk");
8
+ const picocolors_1 = tslib_1.__importDefault(require("picocolors"));
8
9
  const find_project_for_path_1 = require("nx/src/project-graph/utils/find-project-for-path");
9
10
  const configuration_1 = require("nx/src/config/configuration");
10
11
  const internal_1 = require("@nx/js/internal");
@@ -32,8 +33,8 @@ function ensureGlobalProjectGraph(ruleName) {
32
33
  globalThis.targetProjectLocator = new internal_1.TargetProjectLocator(projectGraph.nodes, projectGraph.externalNodes);
33
34
  }
34
35
  catch {
35
- const WARNING_PREFIX = `${chalk.reset.keyword('orange')('warning')}`;
36
- const RULE_NAME_SUFFIX = `${chalk.reset.dim(`@nx/${ruleName}`)}`;
36
+ const WARNING_PREFIX = `${picocolors_1.default.reset(picocolors_1.default.yellow('warning'))}`;
37
+ const RULE_NAME_SUFFIX = `${picocolors_1.default.reset(picocolors_1.default.dim(`@nx/${ruleName}`))}`;
37
38
  process.stdout
38
39
  .write(`${WARNING_PREFIX} No cached ProjectGraph is available. The rule will be skipped.
39
40
  If you encounter this error as part of running standard \`nx\` commands then please open an issue on https://github.com/nrwl/nx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint-plugin",
3
- "version": "23.1.0",
3
+ "version": "23.1.1",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -95,17 +95,17 @@
95
95
  "@phenomnomnominal/tsquery": "~6.2.0",
96
96
  "@typescript-eslint/type-utils": "^8.0.0",
97
97
  "@typescript-eslint/utils": "^8.0.0",
98
- "chalk": "^4.1.0",
99
98
  "confusing-browser-globals": "^1.0.9",
100
99
  "globals": "^17.0.0",
101
100
  "jsonc-eslint-parser": "^2.1.0",
101
+ "picocolors": "^1.1.0",
102
102
  "semver": "^7.6.3",
103
103
  "tslib": "^2.3.0",
104
- "@nx/devkit": "23.1.0",
105
- "@nx/js": "23.1.0"
104
+ "@nx/devkit": "23.1.1",
105
+ "@nx/js": "23.1.1"
106
106
  },
107
107
  "devDependencies": {
108
- "nx": "23.1.0"
108
+ "nx": "23.1.1"
109
109
  },
110
110
  "publishConfig": {
111
111
  "access": "public"