@o3r/eslint-plugin 9.4.0-alpha.32 → 9.4.0-alpha.33

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.
Files changed (22) hide show
  1. package/package.json +11 -4
  2. package/src/index.d.ts +1 -0
  3. package/src/index.js +12 -4
  4. package/src/public_api.d.ts +1 -0
  5. package/src/rules/json/json-dependency-versions-harmonize/json-dependency-versions-harmonize.d.ts +15 -0
  6. package/src/rules/json/json-dependency-versions-harmonize/json-dependency-versions-harmonize.js +122 -0
  7. package/src/rules/json/json-dependency-versions-harmonize/version-harmonize.d.ts +40 -0
  8. package/src/rules/json/json-dependency-versions-harmonize/version-harmonize.js +96 -0
  9. package/src/rules/json/utils.d.ts +39 -0
  10. package/src/rules/json/utils.js +60 -0
  11. package/src/rules/template/template-async-number-limitation/template-async-number-limitation.d.ts +7 -0
  12. package/src/rules/{template-async-number-limitation → template/template-async-number-limitation}/template-async-number-limitation.js +3 -3
  13. package/src/rules/template/utils.d.ts +41 -0
  14. package/src/rules/typescript/no-folder-import-for-module/no-folder-import-for-module.d.ts +4 -0
  15. package/src/rules/{no-folder-import-for-module → typescript/no-folder-import-for-module}/no-folder-import-for-module.js +1 -1
  16. package/src/rules/typescript/o3r-widget-tags/o3r-widget-tags.d.ts +16 -0
  17. package/src/rules/{o3r-widget-tags → typescript/o3r-widget-tags}/o3r-widget-tags.js +1 -1
  18. package/src/rules/utils.d.ts +3 -0
  19. package/tsconfig.tsbuildinfo +1 -0
  20. package/collection.json +0 -11
  21. package/schematics/ng-add/schema.json +0 -18
  22. /package/src/rules/{template-utils.js → template/utils.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@o3r/eslint-plugin",
3
- "version": "9.4.0-alpha.32",
3
+ "version": "9.4.0-alpha.33",
4
4
  "description": "The module provides in-house eslint plugins to use in your own eslint configuration.",
5
5
  "main": "./src/public_api.js",
6
6
  "keywords": [
@@ -22,11 +22,16 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@typescript-eslint/experimental-utils": "^5.3.0",
25
+ "globby": "^11.1.0",
26
+ "semver": "^7.5.2",
25
27
  "tslib": "^2.5.3"
26
28
  },
27
29
  "peerDependenciesMeta": {
28
30
  "@angular-eslint/template-parser": {
29
31
  "optional": true
32
+ },
33
+ "jsonc-eslint-parser": {
34
+ "optional": true
30
35
  }
31
36
  },
32
37
  "peerDependencies": {
@@ -35,7 +40,8 @@
35
40
  "@angular/compiler": "~16.2.0",
36
41
  "@typescript-eslint/eslint-plugin": "^5.60.1",
37
42
  "@typescript-eslint/parser": "^5.60.1",
38
- "eslint": "^8.22.0"
43
+ "eslint": "^8.22.0",
44
+ "jsonc-eslint-parser": "~2.3.0"
39
45
  },
40
46
  "devDependencies": {
41
47
  "@angular-devkit/core": "~16.2.0",
@@ -49,10 +55,10 @@
49
55
  "@compodoc/compodoc": "^1.1.19",
50
56
  "@nx/eslint-plugin": "~16.10.0",
51
57
  "@nx/jest": "~16.10.0",
52
- "@o3r/build-helpers": "^9.4.0-alpha.32",
53
- "@o3r/eslint-plugin": "^9.4.0-alpha.32",
58
+ "@o3r/build-helpers": "^9.4.0-alpha.33",
54
59
  "@types/jest": "~29.5.2",
55
60
  "@types/node": "^18.0.0",
61
+ "@types/semver": "^7.3.13",
56
62
  "@typescript-eslint/eslint-plugin": "^5.60.1",
57
63
  "@typescript-eslint/parser": "^5.60.1",
58
64
  "cpy-cli": "^4.2.0",
@@ -67,6 +73,7 @@
67
73
  "nx": "~16.10.0",
68
74
  "rimraf": "^5.0.1",
69
75
  "ts-jest": "~29.1.1",
76
+ "type-fest": "^3.12.0",
70
77
  "typescript": "~5.1.6"
71
78
  },
72
79
  "schematics": "./collection.json",
package/src/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/src/index.js CHANGED
@@ -1,17 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  /* eslint-disable @typescript-eslint/naming-convention */
4
- const no_folder_import_for_module_1 = require("./rules/no-folder-import-for-module/no-folder-import-for-module");
5
- const template_async_number_limitation_1 = require("./rules/template-async-number-limitation/template-async-number-limitation");
6
- const o3r_widget_tags_1 = require("./rules/o3r-widget-tags/o3r-widget-tags");
4
+ const no_folder_import_for_module_1 = require("./rules/typescript/no-folder-import-for-module/no-folder-import-for-module");
5
+ const o3r_widget_tags_1 = require("./rules/typescript/o3r-widget-tags/o3r-widget-tags");
6
+ const template_async_number_limitation_1 = require("./rules/template/template-async-number-limitation/template-async-number-limitation");
7
+ const json_dependency_versions_harmonize_1 = require("./rules/json/json-dependency-versions-harmonize/json-dependency-versions-harmonize");
7
8
  module.exports = {
8
9
  rules: {
9
10
  'no-folder-import-for-module': no_folder_import_for_module_1.default,
10
11
  'template-async-number-limitation': template_async_number_limitation_1.default,
11
- 'o3r-widget-tags': o3r_widget_tags_1.default
12
+ 'o3r-widget-tags': o3r_widget_tags_1.default,
13
+ 'json-dependency-versions-harmonize': json_dependency_versions_harmonize_1.default
12
14
  },
13
15
  configs: {
14
16
  '@o3r/no-folder-import-for-module': 'error',
17
+ '@o3r/json-dependency-versions-harmonize': 'error',
15
18
  '@o3r/template-async-number-limitation': 'warn',
16
19
  recommended: {
17
20
  rules: {
@@ -24,6 +27,11 @@ module.exports = {
24
27
  '@o3r/no-folder-import-for-module': 'error',
25
28
  '@o3r/template-async-number-limitation': 'warn'
26
29
  }
30
+ },
31
+ 'json-recommended': {
32
+ rules: {
33
+ '@o3r/json-dependency-versions-harmonize': 'error'
34
+ }
27
35
  }
28
36
  }
29
37
  };
@@ -0,0 +1 @@
1
+ export * from './index';
@@ -0,0 +1,15 @@
1
+ interface Options {
2
+ /** List of package name to ignore when determining the dependencies versions */
3
+ ignoredPackages: string[];
4
+ /** List of dependencies to ignore */
5
+ ignoredDependencies: string[];
6
+ /** List of dependency types to update */
7
+ dependencyTypes: string[];
8
+ /**
9
+ * Enforce to align the version of the dependencies with the latest range.
10
+ * If not set, the version will be aligned with the latest range if the latest range is not intersected with the current range.
11
+ */
12
+ alignPeerDependencies: boolean;
13
+ }
14
+ declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"error" | "versionUpdate", [Options, ...any[]], any>;
15
+ export default _default;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path = require("node:path");
4
+ const semver = require("semver");
5
+ const utils_1 = require("../../utils");
6
+ const utils_2 = require("../utils");
7
+ const version_harmonize_1 = require("./version-harmonize");
8
+ const defaultOptions = [{
9
+ ignoredDependencies: [],
10
+ dependencyTypes: ['optionalDependencies', 'dependencies', 'devDependencies', 'peerDependencies', 'generatorDependencies'],
11
+ alignPeerDependencies: false,
12
+ ignoredPackages: []
13
+ }];
14
+ exports.default = (0, utils_1.createRule)({
15
+ name: 'json-dependency-versions-harmonize',
16
+ meta: {
17
+ hasSuggestions: true,
18
+ type: 'problem',
19
+ docs: {
20
+ description: 'Ensure that the package dependency versions are aligned with the other package of the workspace.',
21
+ recommended: 'error'
22
+ },
23
+ schema: [
24
+ {
25
+ type: 'object',
26
+ properties: {
27
+ alignPeerDependencies: {
28
+ type: 'boolean',
29
+ description: 'Enforce to align the version of the dependencies with the latest range.'
30
+ },
31
+ dependencyTypes: {
32
+ type: 'array',
33
+ description: 'List of dependency types to update',
34
+ items: {
35
+ type: 'string'
36
+ }
37
+ },
38
+ ignoredDependencies: {
39
+ type: 'array',
40
+ description: 'List of dependencies to ignore',
41
+ items: {
42
+ type: 'string'
43
+ }
44
+ },
45
+ ignoredPackages: {
46
+ type: 'array',
47
+ description: 'List of package name to ignore when determining the dependencies versions',
48
+ items: {
49
+ type: 'string'
50
+ }
51
+ }
52
+ },
53
+ additionalProperties: false
54
+ }
55
+ ],
56
+ messages: {
57
+ versionUpdate: 'Set version {{version}}',
58
+ error: '{{depName}} should be updated to version {{version}} (from: {{packageJsonFile}})'
59
+ },
60
+ fixable: 'code'
61
+ },
62
+ defaultOptions,
63
+ create: (context, [options]) => {
64
+ const parserServices = (0, utils_2.getJsoncParserServices)(context);
65
+ const dirname = path.dirname(context.getFilename());
66
+ const workspace = (0, version_harmonize_1.findWorkspacePackageJsons)(dirname);
67
+ const bestRanges = workspace && (0, version_harmonize_1.getBestRanges)(options.dependencyTypes, workspace.packages.filter(({ content }) => !content.name || !options.ignoredPackages.includes(content.name)));
68
+ const ignoredDependencies = options.ignoredDependencies.map((dep) => new RegExp(dep.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*')));
69
+ if (parserServices.isJSON) {
70
+ return {
71
+ // eslint-disable-next-line @typescript-eslint/naming-convention
72
+ 'JSONExpressionStatement': (node) => {
73
+ if (node.expression.type === 'JSONObjectExpression') {
74
+ const deps = node.expression.properties
75
+ .filter(({ key }) => options.dependencyTypes.includes(key.type === 'JSONLiteral' ? key.value.toString() : key.name));
76
+ if (deps.length > 0 && bestRanges) {
77
+ deps
78
+ .map((depGroup) => depGroup.value)
79
+ .filter((depGroup) => depGroup.type === 'JSONObjectExpression')
80
+ .forEach((depGroup) => {
81
+ depGroup.properties.forEach((dep) => {
82
+ const name = dep.key.type === 'JSONLiteral' ? dep.key.value.toString() : dep.key.name;
83
+ if (ignoredDependencies.some((ignore) => ignore.test(name))) {
84
+ return;
85
+ }
86
+ const range = dep.value.type === 'JSONLiteral' ? dep.value.value : (dep.value.type === 'JSONIdentifier' ? dep.value.name : undefined);
87
+ const bestRange = (0, version_harmonize_1.getBestRange)(range, bestRanges[name]?.range);
88
+ if (bestRange && bestRange !== range) {
89
+ if (!options.alignPeerDependencies && depGroup.parent.type === 'JSONProperty' && range &&
90
+ (depGroup.parent.key.type === 'JSONLiteral' ? depGroup.parent.key.value.toString() : depGroup.parent.key.name) === 'peerDependencies' &&
91
+ semver.subset(bestRange, range)) {
92
+ return;
93
+ }
94
+ context.report({
95
+ loc: dep.value.loc,
96
+ messageId: 'error',
97
+ data: {
98
+ depName: name,
99
+ version: bestRange,
100
+ packageJsonFile: bestRanges[name].path
101
+ },
102
+ fix: (fixer) => fixer.replaceTextRange(dep.value.range, `"${bestRange}"`),
103
+ suggest: [
104
+ {
105
+ messageId: 'versionUpdate',
106
+ data: {
107
+ version: bestRange
108
+ },
109
+ fix: (fixer) => fixer.replaceTextRange(dep.value.range, `"${bestRange}"`)
110
+ }
111
+ ]
112
+ });
113
+ }
114
+ });
115
+ });
116
+ }
117
+ }
118
+ }
119
+ };
120
+ }
121
+ }
122
+ });
@@ -0,0 +1,40 @@
1
+ import type { PackageJson } from 'type-fest';
2
+ /** List of packages information resulting of a package.json discovery */
3
+ export interface PackageProperty {
4
+ /** List of package.json file information */
5
+ packages: {
6
+ /** Parsed package.json content */
7
+ content: PackageJson;
8
+ /** Path to the file */
9
+ path: string;
10
+ /** Determine if the package.json has a workspace information */
11
+ isWorkspace?: boolean;
12
+ }[];
13
+ /** Determine if the package.json collection is the result of a default strategy (in the case no matching workspace has been found) */
14
+ hasDefaulted?: boolean;
15
+ }
16
+ /** Range discovered for a given dependency */
17
+ export interface RangeInformation {
18
+ /** Range as specified in the package.json dependencies */
19
+ range: string;
20
+ /** Path to the original package.json */
21
+ path: string;
22
+ }
23
+ /**
24
+ * Find the closest package.json file containing workspace definition in the parent directories
25
+ * @param directory Current directory to search for
26
+ * @param rootDir First directory of the recursion
27
+ */
28
+ export declare const findWorkspacePackageJsons: (directory: string, rootDir?: string) => PackageProperty | undefined;
29
+ /**
30
+ * Compare and return the best range in the both given onces
31
+ * @param currentRange Current range in the memory stack
32
+ * @param range Range to compare the current one to
33
+ */
34
+ export declare const getBestRange: (currentRange?: string, range?: string) => string | undefined;
35
+ /**
36
+ * Retrieve the best ranges for each dependencies in the given package.json files
37
+ * @param dependencyTypes Type of dependency files to analyze
38
+ * @param packages List of the package.json files
39
+ */
40
+ export declare const getBestRanges: (dependencyTypes: string[], packages: PackageProperty['packages']) => Record<string, RangeInformation>;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBestRanges = exports.getBestRange = exports.findWorkspacePackageJsons = void 0;
4
+ const semver = require("semver");
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const globby_1 = require("globby");
8
+ /**
9
+ * Find the closest package.json file containing workspace definition in the parent directories
10
+ * @param directory Current directory to search for
11
+ * @param rootDir First directory of the recursion
12
+ */
13
+ const findWorkspacePackageJsons = (directory, rootDir) => {
14
+ const parentFolder = (0, node_path_1.dirname)(directory);
15
+ rootDir ||= directory;
16
+ if (parentFolder === directory) {
17
+ return undefined;
18
+ }
19
+ const packageJsonPath = (0, node_path_1.resolve)(directory, 'package.json');
20
+ const content = (0, node_fs_1.existsSync)(packageJsonPath) && JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, { encoding: 'utf-8' }));
21
+ if (!content || !content.workspaces) {
22
+ return (0, exports.findWorkspacePackageJsons)(parentFolder, rootDir);
23
+ }
24
+ const packagePaths = (0, globby_1.sync)((Array.isArray(content.workspaces) ? content.workspaces : content.workspaces.packages || []).map((f) => node_path_1.posix.join(f, 'package.json')), { cwd: directory, onlyFiles: false, absolute: true });
25
+ const isPackageWorkspace = packagePaths.some((workspacePath) => (0, node_path_1.normalize)(workspacePath) === rootDir);
26
+ const getPackages = () => ([
27
+ { content, path: packageJsonPath, isWorkspace: true },
28
+ ...packagePaths.map((subPackageJsonPath) => ({ content: JSON.parse((0, node_fs_1.readFileSync)(subPackageJsonPath, { encoding: 'utf-8' })), path: subPackageJsonPath }))
29
+ ]);
30
+ if (isPackageWorkspace) {
31
+ return {
32
+ packages: getPackages()
33
+ };
34
+ }
35
+ else { // In case we discover a workspace for which the package is not part of
36
+ const parent = (0, exports.findWorkspacePackageJsons)(parentFolder, rootDir);
37
+ if (!parent || parent.hasDefaulted) {
38
+ return {
39
+ hasDefaulted: true,
40
+ packages: getPackages()
41
+ };
42
+ }
43
+ }
44
+ };
45
+ exports.findWorkspacePackageJsons = findWorkspacePackageJsons;
46
+ /**
47
+ * Compare and return the best range in the both given onces
48
+ * @param currentRange Current range in the memory stack
49
+ * @param range Range to compare the current one to
50
+ */
51
+ const getBestRange = (currentRange, range) => {
52
+ if (!range || !semver.validRange(range)) {
53
+ return currentRange && semver.validRange(currentRange) ? currentRange : undefined;
54
+ }
55
+ if (!currentRange || !semver.validRange(currentRange)) {
56
+ return range;
57
+ }
58
+ if (currentRange !== range) {
59
+ const minVersion = semver.minVersion(range);
60
+ const currentMinVersion = semver.minVersion(currentRange);
61
+ if (semver.gt(minVersion, currentMinVersion)) {
62
+ return range;
63
+ }
64
+ else if (semver.eq(minVersion, currentMinVersion) && semver.subset(range, currentRange)) {
65
+ return range;
66
+ }
67
+ }
68
+ return currentRange;
69
+ };
70
+ exports.getBestRange = getBestRange;
71
+ /**
72
+ * Retrieve the best ranges for each dependencies in the given package.json files
73
+ * @param dependencyTypes Type of dependency files to analyze
74
+ * @param packages List of the package.json files
75
+ */
76
+ const getBestRanges = (dependencyTypes, packages) => {
77
+ return packages.reduce((acc, pck) => {
78
+ dependencyTypes.forEach((depType) => {
79
+ const dependencies = pck.content[depType];
80
+ if (dependencies) {
81
+ Object.entries(dependencies).forEach(([depName, range]) => {
82
+ if (!acc[depName]) {
83
+ if (range) {
84
+ acc[depName] = { range, path: (0, node_path_1.normalize)(pck.path) };
85
+ }
86
+ }
87
+ else if ((0, exports.getBestRange)(acc[depName].range, range) !== acc[depName].range) {
88
+ acc[depName] = { range: range, path: (0, node_path_1.normalize)(pck.path) };
89
+ }
90
+ });
91
+ }
92
+ });
93
+ return acc;
94
+ }, {});
95
+ };
96
+ exports.getBestRanges = getBestRanges;
@@ -0,0 +1,39 @@
1
+ import { ParserServices, TSESLint } from '@typescript-eslint/experimental-utils';
2
+ import type { AST } from 'jsonc-eslint-parser';
3
+ /** Basic interface for the Parser Services object provided by jsonc-eslint-parser */
4
+ interface JsoncParserServices extends ParserServices {
5
+ isJSON: boolean;
6
+ }
7
+ /**
8
+ * Determine if jsonc-eslint-parser is used
9
+ * @param parserServices Parser services object
10
+ */
11
+ export declare function isJsoncParserServices(parserServices: any): parserServices is JsoncParserServices;
12
+ /**
13
+ *
14
+ * @param node
15
+ * @param node.type
16
+ */
17
+ export declare function isProperty(node?: {
18
+ type: string;
19
+ }): node is AST.JSONProperty;
20
+ /**
21
+ *
22
+ * @param node
23
+ * @param node.type
24
+ */
25
+ export declare function isObjectExpression(node?: {
26
+ type: string;
27
+ }): node is AST.JSONObjectExpression;
28
+ /**
29
+ * Retrieve the json parser services object or throw if the invalid parser is used
30
+ * @param context Rule context
31
+ */
32
+ export declare function getJsoncParserServices(context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>): JsoncParserServices;
33
+ /**
34
+ * Utility for rule authors to ensure that their rule is correctly being used with jsonc-eslint-parser
35
+ * If jsonc-eslint-parser is not the configured parser when the function is invoked it will throw
36
+ * @param context
37
+ */
38
+ export declare function ensureJsoncParser(context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>): void;
39
+ export {};
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureJsoncParser = exports.getJsoncParserServices = exports.isObjectExpression = exports.isProperty = exports.isJsoncParserServices = void 0;
4
+ /**
5
+ * Determine if jsonc-eslint-parser is used
6
+ * @param parserServices Parser services object
7
+ */
8
+ function isJsoncParserServices(parserServices) {
9
+ return !!parserServices;
10
+ }
11
+ exports.isJsoncParserServices = isJsoncParserServices;
12
+ /**
13
+ *
14
+ * @param node
15
+ * @param node.type
16
+ */
17
+ function isProperty(node) {
18
+ return !!node && node.type !== 'JSONProperty';
19
+ }
20
+ exports.isProperty = isProperty;
21
+ /**
22
+ *
23
+ * @param node
24
+ * @param node.type
25
+ */
26
+ function isObjectExpression(node) {
27
+ return !!node && node.type !== 'JSONObjectExpression';
28
+ }
29
+ exports.isObjectExpression = isObjectExpression;
30
+ /**
31
+ * Retrieve the json parser services object or throw if the invalid parser is used
32
+ * @param context Rule context
33
+ */
34
+ function getJsoncParserServices(context) {
35
+ const parserService = context.parserServices;
36
+ if (!isJsoncParserServices(parserService)) {
37
+ /*
38
+ * The user needs to have configured "parser" in their eslint config and set it
39
+ * to jsonc-eslint-parser
40
+ */
41
+ throw new Error('You have used a rule which requires \'jsonc-eslint-parser\' to be used as the \'parser\' in your ESLint config.');
42
+ }
43
+ return parserService;
44
+ }
45
+ exports.getJsoncParserServices = getJsoncParserServices;
46
+ /**
47
+ * Utility for rule authors to ensure that their rule is correctly being used with jsonc-eslint-parser
48
+ * If jsonc-eslint-parser is not the configured parser when the function is invoked it will throw
49
+ * @param context
50
+ */
51
+ function ensureJsoncParser(context) {
52
+ if (!(context.parserServices)) {
53
+ /*
54
+ * The user needs to have configured "parser" in their eslint config and set it
55
+ * to jsonc-eslint-parser
56
+ */
57
+ throw new Error('You have used a rule which requires \'jsonc-eslint-parser\' to be used as the \'parser\' in your ESLint config.');
58
+ }
59
+ }
60
+ exports.ensureJsoncParser = ensureJsoncParser;
@@ -0,0 +1,7 @@
1
+ interface Options {
2
+ maximumAsyncOnTag: number;
3
+ }
4
+ /** Rule Name */
5
+ export declare const name = "template-async-number-limitation";
6
+ declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"tooManyAsyncOnTag", [Options, ...any[]], any>;
7
+ export default _default;
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.name = void 0;
4
- const template_utils_1 = require("../template-utils");
5
4
  const utils_1 = require("../utils");
5
+ const utils_2 = require("../../utils");
6
6
  /** Rule Name */
7
7
  exports.name = 'template-async-number-limitation';
8
8
  const defaultOptions = [{
9
9
  maximumAsyncOnTag: 5
10
10
  }];
11
- exports.default = (0, utils_1.createRule)({
11
+ exports.default = (0, utils_2.createRule)({
12
12
  name: exports.name,
13
13
  meta: {
14
14
  type: 'problem',
@@ -36,7 +36,7 @@ exports.default = (0, utils_1.createRule)({
36
36
  },
37
37
  defaultOptions,
38
38
  create: (context) => {
39
- const parserServices = (0, template_utils_1.getTemplateParserServices)(context);
39
+ const parserServices = (0, utils_1.getTemplateParserServices)(context);
40
40
  const options = context.options[0] || defaultOptions[0];
41
41
  const asyncRegExp = /\| *async\b/g;
42
42
  return {
@@ -0,0 +1,41 @@
1
+ import { ParserServices, TSESLint } from '@typescript-eslint/experimental-utils';
2
+ /** Position in source code */
3
+ interface SourceSpan {
4
+ /** starting position */
5
+ start: {
6
+ line: number;
7
+ col: any;
8
+ };
9
+ /** ending position */
10
+ end: {
11
+ line: number;
12
+ col: any;
13
+ };
14
+ }
15
+ /** Basic interface for the Parser Services object provided by @angular-eslint/template-parser */
16
+ interface TemplateParserServices extends ParserServices {
17
+ /** Set body visitor rule runner */
18
+ convertElementSourceSpanToLoc: (listenerObj: any) => any;
19
+ /** Determine the linter notification position based on the node */
20
+ convertNodeSourceSpanToLoc: (sourceSpan: SourceSpan) => any;
21
+ }
22
+ /**
23
+ * Determine if @angular-eslint/template-parser is used
24
+ *
25
+ * @param parserServices Parser services object
26
+ */
27
+ export declare function isTemplateParserServices(parserServices: any): parserServices is TemplateParserServices;
28
+ /**
29
+ * Retrieve the template parser services object or throw if the invalid parser is used
30
+ *
31
+ * @param context Rule context
32
+ */
33
+ export declare function getTemplateParserServices(context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>): TemplateParserServices;
34
+ /**
35
+ * Utility for rule authors to ensure that their rule is correctly being used with @angular-eslint/template-parser
36
+ * If @angular-eslint/template-parser is not the configured parser when the function is invoked it will throw
37
+ *
38
+ * @param context
39
+ */
40
+ export declare function ensureTemplateParser(context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>): void;
41
+ export {};
@@ -0,0 +1,4 @@
1
+ declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"error" | "indexFile", never[], {
2
+ ImportDeclaration: (node: import("@typescript-eslint/types/dist/generated/ast-spec").ImportDeclaration) => void;
3
+ }>;
4
+ export default _default;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const fs = require("node:fs");
4
4
  const path = require("node:path");
5
- const utils_1 = require("../utils");
5
+ const utils_1 = require("../../utils");
6
6
  exports.default = (0, utils_1.createRule)({
7
7
  name: 'no-folder-import-for-module',
8
8
  meta: {
@@ -0,0 +1,16 @@
1
+ import { TSESLint } from '@typescript-eslint/experimental-utils';
2
+ type O3rWidgetParamType = 'string' | 'number' | 'boolean' | 'string[]' | 'number[]' | 'boolean[]';
3
+ export interface O3rWidgetTagsRuleOption {
4
+ supportedInterfaceNames?: string[];
5
+ widgets: {
6
+ [widgetName: string]: {
7
+ [paramName: string]: {
8
+ type: O3rWidgetParamType;
9
+ required?: boolean;
10
+ };
11
+ };
12
+ };
13
+ }
14
+ type O3rWidgetRuleErrorId = 'notInConfigurationInterface' | 'notSupportedType' | 'notSupportedParamForType' | 'invalidParamValueType' | 'noParamWithoutWidget' | 'onlyOneWidgetAllowed' | 'duplicatedParam' | 'requiredParamMissing' | 'suggestParamMissing' | 'suggestRemoveDuplicatedO3rWidget' | 'suggestRemoveDuplicatedO3rWidgetParam' | 'suggestAddO3rWidgetTag' | 'suggestReplaceO3rWidgetType';
15
+ declare const _default: TSESLint.RuleModule<O3rWidgetRuleErrorId, O3rWidgetTagsRuleOption[], TSESLint.RuleListener>;
16
+ export default _default;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const experimental_utils_1 = require("@typescript-eslint/experimental-utils");
4
- const utils_1 = require("../utils");
4
+ const utils_1 = require("../../utils");
5
5
  const o3rWidgetParameterPattern = '^[a-zA-Z0-9-_:.]+$';
6
6
  const o3rWidgetParamTypes = ['string', 'number', 'boolean', 'string[]', 'number[]', 'boolean[]'];
7
7
  const createCommentString = (comment) => `/*${comment}*/`;
@@ -0,0 +1,3 @@
1
+ import { ESLintUtils } from '@typescript-eslint/experimental-utils';
2
+ /** ESLint rule generator */
3
+ export declare const createRule: <TOptions extends readonly unknown[], TMessageIds extends string, TRuleListener extends import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener = import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>({ name, meta, ...rule }: Readonly<ESLintUtils.RuleWithMetaAndName<TOptions, TMessageIds, TRuleListener>>) => import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<TMessageIds, TOptions, TRuleListener>;
@@ -0,0 +1 @@
1
+ {"version":"5.1.6"}
package/collection.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://raw.githubusercontent.com/angular/angular-cli/main/packages/angular_devkit/schematics/collection-schema.json",
3
- "schematics": {
4
- "ng-add": {
5
- "description": "Add Otter eslint-plugin to the project.",
6
- "factory": "./schematics/ng-add/index#ngAdd",
7
- "schema": "./schematics/ng-add/schema.json",
8
- "aliases": ["install", "i"]
9
- }
10
- }
11
- }
@@ -1,18 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/schema",
3
- "$id": "ngAddSchematicsSchema",
4
- "title": "Add Otter eslint-plugin ",
5
- "description": "ngAdd Otter eslint-plugin ",
6
- "properties": {
7
- "projectName": {
8
- "type": "string",
9
- "description": "Project name",
10
- "$default": {
11
- "$source": "projectName"
12
- }
13
- }
14
- },
15
- "additionalProperties": false,
16
- "required": [
17
- ]
18
- }