@nx/eslint-plugin 0.0.0-pr-29314-e664f92 → 0.0.0-pr-29314-bfd9d0c

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/nx.d.ts CHANGED
@@ -18,6 +18,7 @@ declare const plugin: {
18
18
  migrationsJson?: string;
19
19
  packageJson?: string;
20
20
  allowedVersionStrings: string[];
21
+ tsConfig?: string;
21
22
  }], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
22
23
  "dependency-checks": import("@typescript-eslint/utils/ts-eslint").RuleModule<import("./src/rules/dependency-checks").MessageIds, import("./src/rules/dependency-checks").Options, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
23
24
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint-plugin",
3
- "version": "0.0.0-pr-29314-e664f92",
3
+ "version": "0.0.0-pr-29314-bfd9d0c",
4
4
  "private": false,
5
5
  "description": "The eslint-plugin package is an ESLint plugin that contains a collection of recommended ESLint rule configurations which you can extend from in your own ESLint configs, as well as an Nx-specific lint rule called enforce-module-boundaries.",
6
6
  "repository": {
@@ -34,8 +34,8 @@
34
34
  }
35
35
  },
36
36
  "dependencies": {
37
- "@nx/devkit": "0.0.0-pr-29314-e664f92",
38
- "@nx/js": "0.0.0-pr-29314-e664f92",
37
+ "@nx/devkit": "0.0.0-pr-29314-bfd9d0c",
38
+ "@nx/js": "0.0.0-pr-29314-bfd9d0c",
39
39
  "@typescript-eslint/type-utils": "^8.0.0",
40
40
  "@typescript-eslint/utils": "^8.0.0",
41
41
  "chalk": "^4.1.0",
@@ -7,15 +7,20 @@ type Options = [
7
7
  migrationsJson?: string;
8
8
  packageJson?: string;
9
9
  allowedVersionStrings: string[];
10
+ tsConfig?: string;
10
11
  }
11
12
  ];
13
+ type NormalizedOptions = Options[0] & {
14
+ rootDir?: string;
15
+ outDir?: string;
16
+ };
12
17
  export type MessageIds = 'missingRequiredSchema' | 'invalidSchemaPath' | 'missingImplementation' | 'invalidImplementationPath' | 'invalidImplementationModule' | 'unableToReadImplementationExports' | 'invalidVersion' | 'missingVersion' | 'noGeneratorsOrSchematicsFound' | 'noExecutorsOrBuildersFound' | 'valueShouldBeObject';
13
18
  export declare const RULE_NAME = "nx-plugin-checks";
14
19
  declare const _default: TSESLint.RuleModule<MessageIds, Options, unknown, TSESLint.RuleListener>;
15
20
  export default _default;
16
- export declare function checkCollectionFileNode(baseNode: AST.JSONObjectExpression, mode: 'migration' | 'generator' | 'executor', context: TSESLint.RuleContext<MessageIds, Options>): void;
17
- export declare function checkCollectionNode(baseNode: AST.JSONObjectExpression, mode: 'migration' | 'generator' | 'executor', context: TSESLint.RuleContext<MessageIds, Options>): void;
18
- export declare function validateEntry(baseNode: AST.JSONObjectExpression, key: string, mode: 'migration' | 'generator' | 'executor', context: TSESLint.RuleContext<MessageIds, Options>): void;
19
- export declare function validateImplemenationNode(implementationNode: AST.JSONProperty, key: string, context: TSESLint.RuleContext<MessageIds, Options>): void;
21
+ export declare function checkCollectionFileNode(baseNode: AST.JSONObjectExpression, mode: 'migration' | 'generator' | 'executor', context: TSESLint.RuleContext<MessageIds, Options>, options: NormalizedOptions): void;
22
+ export declare function checkCollectionNode(baseNode: AST.JSONObjectExpression, mode: 'migration' | 'generator' | 'executor', context: TSESLint.RuleContext<MessageIds, Options>, options: NormalizedOptions): void;
23
+ export declare function validateEntry(baseNode: AST.JSONObjectExpression, key: string, mode: 'migration' | 'generator' | 'executor', context: TSESLint.RuleContext<MessageIds, Options>, options: NormalizedOptions): void;
24
+ export declare function validateImplementationNode(implementationNode: AST.JSONProperty, key: string, context: TSESLint.RuleContext<MessageIds, Options>, options: NormalizedOptions): void;
20
25
  export declare function validatePackageGroup(baseNode: AST.JSONObjectExpression, context: TSESLint.RuleContext<MessageIds, Options>): void;
21
26
  export declare function validateVersionJsonExpression(node: AST.JSONExpression, context: TSESLint.RuleContext<MessageIds, Options>): string | boolean;
@@ -4,7 +4,7 @@ exports.RULE_NAME = void 0;
4
4
  exports.checkCollectionFileNode = checkCollectionFileNode;
5
5
  exports.checkCollectionNode = checkCollectionNode;
6
6
  exports.validateEntry = validateEntry;
7
- exports.validateImplemenationNode = validateImplemenationNode;
7
+ exports.validateImplementationNode = validateImplementationNode;
8
8
  exports.validatePackageGroup = validatePackageGroup;
9
9
  exports.validateVersionJsonExpression = validateVersionJsonExpression;
10
10
  const tslib_1 = require("tslib");
@@ -12,7 +12,6 @@ const utils_1 = require("@typescript-eslint/utils");
12
12
  const devkit_1 = require("@nx/devkit");
13
13
  const js_1 = require("@nx/js");
14
14
  const internal_1 = require("@nx/js/src/internal");
15
- const fs_1 = require("fs");
16
15
  const path = tslib_1.__importStar(require("path"));
17
16
  const semver_1 = require("semver");
18
17
  const project_graph_utils_1 = require("../utils/project-graph-utils");
@@ -23,6 +22,7 @@ const DEFAULT_OPTIONS = {
23
22
  migrationsJson: 'migrations.json',
24
23
  packageJson: 'package.json',
25
24
  allowedVersionStrings: ['*', 'latest', 'next'],
25
+ tsConfig: 'tsconfig.lib.json',
26
26
  };
27
27
  exports.RULE_NAME = 'nx-plugin-checks';
28
28
  exports.default = utils_1.ESLintUtils.RuleCreator(() => ``)({
@@ -56,6 +56,10 @@ exports.default = utils_1.ESLintUtils.RuleCreator(() => ``)({
56
56
  description: 'A list of specifiers that are valid for versions within package group. Defaults to ["*", "latest", "next"]',
57
57
  items: { type: 'string' },
58
58
  },
59
+ tsConfig: {
60
+ type: 'string',
61
+ description: 'The path to the tsconfig file used to build the plugin. Defaults to "tsconfig.lib.json".',
62
+ },
59
63
  },
60
64
  additionalProperties: false,
61
65
  },
@@ -101,13 +105,13 @@ exports.default = utils_1.ESLintUtils.RuleCreator(() => ``)({
101
105
  return {
102
106
  ['JSONExpressionStatement > JSONObjectExpression'](node) {
103
107
  if (sourceFilePath === generatorsJson) {
104
- checkCollectionFileNode(node, 'generator', context);
108
+ checkCollectionFileNode(node, 'generator', context, options);
105
109
  }
106
110
  else if (sourceFilePath === migrationsJson) {
107
- checkCollectionFileNode(node, 'migration', context);
111
+ checkCollectionFileNode(node, 'migration', context, options);
108
112
  }
109
113
  else if (sourceFilePath === executorsJson) {
110
- checkCollectionFileNode(node, 'executor', context);
114
+ checkCollectionFileNode(node, 'executor', context, options);
111
115
  }
112
116
  else if (sourceFilePath === packageJson) {
113
117
  validatePackageGroup(node, context);
@@ -117,7 +121,19 @@ exports.default = utils_1.ESLintUtils.RuleCreator(() => ``)({
117
121
  },
118
122
  });
119
123
  function normalizeOptions(sourceProject, options) {
124
+ let rootDir;
125
+ let outDir;
120
126
  const base = { ...DEFAULT_OPTIONS, ...options };
127
+ let runtimeTsConfig;
128
+ try {
129
+ runtimeTsConfig = require.resolve(path.join(sourceProject.data.root, base.tsConfig));
130
+ const tsConfig = (0, devkit_1.readJsonFile)(runtimeTsConfig);
131
+ rootDir = tsConfig.compilerOptions?.rootDir;
132
+ outDir = tsConfig.compilerOptions?.outDir;
133
+ }
134
+ catch {
135
+ // nothing
136
+ }
121
137
  const pathPrefix = sourceProject.data.root !== '.' ? `${sourceProject.data.root}/` : '';
122
138
  return {
123
139
  ...base,
@@ -133,9 +149,11 @@ function normalizeOptions(sourceProject, options) {
133
149
  packageJson: base.packageJson
134
150
  ? `${pathPrefix}${base.packageJson}`
135
151
  : undefined,
152
+ rootDir: rootDir ? path.join(sourceProject.data.root, rootDir) : undefined,
153
+ outDir: outDir ? path.join(sourceProject.data.root, outDir) : undefined,
136
154
  };
137
155
  }
138
- function checkCollectionFileNode(baseNode, mode, context) {
156
+ function checkCollectionFileNode(baseNode, mode, context, options) {
139
157
  const schematicsRootNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'schematics');
140
158
  const generatorsRootNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'generators');
141
159
  const executorsRootNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'executors');
@@ -169,11 +187,11 @@ function checkCollectionFileNode(baseNode, mode, context) {
169
187
  });
170
188
  }
171
189
  else {
172
- checkCollectionNode(collectionNode.value, mode, context);
190
+ checkCollectionNode(collectionNode.value, mode, context, options);
173
191
  }
174
192
  }
175
193
  }
176
- function checkCollectionNode(baseNode, mode, context) {
194
+ function checkCollectionNode(baseNode, mode, context, options) {
177
195
  const entries = baseNode.properties;
178
196
  for (const entryNode of entries) {
179
197
  if (entryNode.value.type !== 'JSONObjectExpression') {
@@ -184,11 +202,11 @@ function checkCollectionNode(baseNode, mode, context) {
184
202
  });
185
203
  }
186
204
  else if (entryNode.key.type === 'JSONLiteral') {
187
- validateEntry(entryNode.value, entryNode.key.value.toString(), mode, context);
205
+ validateEntry(entryNode.value, entryNode.key.value.toString(), mode, context, options);
188
206
  }
189
207
  }
190
208
  }
191
- function validateEntry(baseNode, key, mode, context) {
209
+ function validateEntry(baseNode, key, mode, context, options) {
192
210
  const schemaNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'schema');
193
211
  if (mode !== 'migration' && !schemaNode) {
194
212
  context.report({
@@ -208,24 +226,28 @@ function validateEntry(baseNode, key, mode, context) {
208
226
  });
209
227
  }
210
228
  else {
229
+ let validJsonFound = false;
211
230
  const schemaFilePath = path.join(path.dirname(context.filename ?? context.getFilename()), schemaNode.value.value);
212
- if (!(0, fs_1.existsSync)(schemaFilePath)) {
213
- context.report({
214
- messageId: 'invalidSchemaPath',
215
- node: schemaNode.value,
216
- });
231
+ try {
232
+ (0, devkit_1.readJsonFile)(schemaFilePath);
233
+ validJsonFound = true;
217
234
  }
218
- else {
235
+ catch {
219
236
  try {
220
- (0, devkit_1.readJsonFile)(schemaFilePath);
237
+ // Try to map back to source, which will be the case with TS solution setup.
238
+ (0, devkit_1.readJsonFile)(schemaFilePath.replace(options.outDir, options.rootDir));
239
+ validJsonFound = true;
221
240
  }
222
- catch (e) {
223
- context.report({
224
- messageId: 'invalidSchemaPath',
225
- node: schemaNode.value,
226
- });
241
+ catch {
242
+ // nothing, will be reported below
227
243
  }
228
244
  }
245
+ if (!validJsonFound) {
246
+ context.report({
247
+ messageId: 'invalidSchemaPath',
248
+ node: schemaNode.value,
249
+ });
250
+ }
229
251
  }
230
252
  }
231
253
  const implementationNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' &&
@@ -240,7 +262,7 @@ function validateEntry(baseNode, key, mode, context) {
240
262
  });
241
263
  }
242
264
  else {
243
- validateImplemenationNode(implementationNode, key, context);
265
+ validateImplementationNode(implementationNode, key, context, options);
244
266
  }
245
267
  if (mode === 'migration') {
246
268
  const versionNode = baseNode.properties.find((x) => x.key.type === 'JSONLiteral' && x.key.value === 'version');
@@ -277,7 +299,7 @@ function validateEntry(baseNode, key, mode, context) {
277
299
  }
278
300
  }
279
301
  }
280
- function validateImplemenationNode(implementationNode, key, context) {
302
+ function validateImplementationNode(implementationNode, key, context, options) {
281
303
  if (implementationNode.value.type !== 'JSONLiteral' ||
282
304
  typeof implementationNode.value.value !== 'string') {
283
305
  context.report({
@@ -295,7 +317,15 @@ function validateImplemenationNode(implementationNode, key, context) {
295
317
  try {
296
318
  resolvedPath = require.resolve(modulePath);
297
319
  }
298
- catch (e) {
320
+ catch {
321
+ try {
322
+ resolvedPath = require.resolve(modulePath.replace(options.outDir, options.rootDir));
323
+ }
324
+ catch {
325
+ // nothing, will be reported below
326
+ }
327
+ }
328
+ if (!resolvedPath) {
299
329
  context.report({
300
330
  messageId: 'invalidImplementationPath',
301
331
  data: {