@dsivd/prestations-ng 19.2.0-beta.1 → 19.2.0-beta.10
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/CHANGELOG.md +182 -0
- package/CONTRIBUTING.md +43 -3
- package/GOOD_PRACTICES.md +186 -29
- package/UPGRADING_V19.md +181 -1
- package/dsivd-prestations-ng-19.2.0-beta.10.tgz +0 -0
- package/eslint/configs/spec-ts-recommended.mjs +34 -0
- package/eslint/configs/template-recommended.mjs +2 -0
- package/eslint/configs/template-rules.mjs +6 -2
- package/eslint/configs/ts-recommended.mjs +2 -0
- package/eslint/configs/ts-rules.mjs +6 -2
- package/eslint/index.mjs +17 -0
- package/eslint/rules/no-direct-signal-mutation.mjs +1 -1
- package/fesm2022/dsivd-prestations-ng.mjs +1626 -1142
- package/fesm2022/dsivd-prestations-ng.mjs.map +1 -1
- package/package.json +1 -2
- package/schematics/ng-add/index.js +2 -4
- package/schematics/ng-update/migrations/update-13_2_0/index.js +7 -2
- package/schematics/utility/add-allowed-common-js-dependencies.js +39 -29
- package/schematics/utility/remove-emit-decorator-metadata.js +8 -9
- package/src/eslint/configs/__tests__/configs.test.mjs +46 -2
- package/src/eslint/configs/spec-ts-recommended.mjs +34 -0
- package/src/eslint/configs/template-recommended.mjs +2 -0
- package/src/eslint/configs/template-rules.mjs +6 -2
- package/src/eslint/configs/ts-recommended.mjs +2 -0
- package/src/eslint/configs/ts-rules.mjs +6 -2
- package/src/eslint/index.mjs +17 -0
- package/src/eslint/rules/no-direct-signal-mutation.mjs +1 -1
- package/types/dsivd-prestations-ng.d.ts +303 -147
- package/dsivd-prestations-ng-19.2.0-beta.1.tgz +0 -0
package/package.json
CHANGED
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
|
28
28
|
"@dsivd/foehn": "=2.0.14",
|
|
29
29
|
"rxjs": "^7.8.2",
|
|
30
|
-
"core-js": "^3.49.0",
|
|
31
30
|
"iban": "^0.0.14",
|
|
32
31
|
"ngx-image-cropper": "^9.1.6",
|
|
33
32
|
"dayjs": "^1.11.21",
|
|
@@ -40,7 +39,7 @@
|
|
|
40
39
|
"ng-update": {
|
|
41
40
|
"migrations": "./schematics/migration-collection.json"
|
|
42
41
|
},
|
|
43
|
-
"version": "19.2.0-beta.
|
|
42
|
+
"version": "19.2.0-beta.10",
|
|
44
43
|
"module": "fesm2022/dsivd-prestations-ng.mjs",
|
|
45
44
|
"typings": "types/dsivd-prestations-ng.d.ts",
|
|
46
45
|
"exports": {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
4
4
|
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
|
5
|
-
const add_allow_synthetic_default_imports_1 = require("../utility/add-allow-synthetic-default-imports");
|
|
6
5
|
const add_allowed_common_js_dependencies_1 = require("../utility/add-allowed-common-js-dependencies");
|
|
7
6
|
const migrate_to_karma_coverage_1 = require("../utility/migrate-to-karma-coverage");
|
|
8
7
|
const remove_emit_decorator_metadata_1 = require("../utility/remove-emit-decorator-metadata");
|
|
@@ -15,12 +14,11 @@ exports.default = () => (tree, context) => {
|
|
|
15
14
|
}
|
|
16
15
|
context.logger.info('Thank you for using our library prestations-ng');
|
|
17
16
|
(0, replace_browserslistrc_1.replaceBrowsersList)(tree);
|
|
18
|
-
(0, add_allowed_common_js_dependencies_1.addAllowedCommonJsDependencies)(tree);
|
|
17
|
+
(0, add_allowed_common_js_dependencies_1.addAllowedCommonJsDependencies)(tree, ['iban', 'dayjs']);
|
|
19
18
|
(0, remove_emit_decorator_metadata_1.removeEmitDecoratorMetadata)(tree);
|
|
20
19
|
if ((0, migrate_to_karma_coverage_1.migrateToKarmaCoverage)(tree)) {
|
|
21
20
|
context.addTask(new tasks_1.NodePackageInstallTask());
|
|
22
21
|
}
|
|
23
|
-
(0, add_allow_synthetic_default_imports_1.addAllowSyntheticDefaultImports)(tree);
|
|
24
22
|
return tree;
|
|
25
23
|
};
|
|
26
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
24
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9wcmVzdGF0aW9ucy1uZy9zY2hlbWF0aWNzL25nLWFkZC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDJEQUtvQztBQUNwQyw0REFBMEU7QUFFMUUsc0dBQStGO0FBQy9GLG9GQUE4RTtBQUM5RSw4RkFBd0Y7QUFDeEYsOEVBQXdFO0FBRXhFLGtCQUFlLEdBQVMsRUFBRSxDQUFDLENBQUMsSUFBVSxFQUFFLE9BQXlCLEVBQUUsRUFBRTtJQUNqRSxNQUFNLGFBQWEsR0FBRyxjQUFjLENBQUM7SUFDckMsZ0RBQWdEO0lBQ2hELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7UUFDOUIsTUFBTSxJQUFJLGdDQUFtQixDQUN6QixvRUFBb0UsQ0FDdkUsQ0FBQztJQUNOLENBQUM7SUFDRCxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO0lBRXRFLElBQUEsNENBQW1CLEVBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsSUFBQSxtRUFBOEIsRUFBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUN4RCxJQUFBLDREQUEyQixFQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLElBQUksSUFBQSxrREFBc0IsRUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQy9CLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSw4QkFBc0IsRUFBRSxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUMsQ0FBQyJ9
|
|
@@ -11,8 +11,13 @@ exports.default = () => (tree, context) => {
|
|
|
11
11
|
throw new schematics_1.SchematicsException('This is not an Angular workspace. Try again in an Angular project.');
|
|
12
12
|
}
|
|
13
13
|
context.logger.info(`Applying migration for prestations-ng for Angular to version ${version}`);
|
|
14
|
-
|
|
14
|
+
// The dependencies added by this version, even if some are no longer needed today
|
|
15
|
+
(0, add_allowed_common_js_dependencies_1.addAllowedCommonJsDependencies)(tree, [
|
|
16
|
+
'core-js/modules/es.array.includes',
|
|
17
|
+
'iban',
|
|
18
|
+
'zone.js/dist/zone-error',
|
|
19
|
+
]);
|
|
15
20
|
(0, remove_emit_decorator_metadata_1.removeEmitDecoratorMetadata)(tree);
|
|
16
21
|
return tree;
|
|
17
22
|
};
|
|
18
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9wcmVzdGF0aW9ucy1uZy9zY2hlbWF0aWNzL25nLXVwZGF0ZS9taWdyYXRpb25zL3VwZGF0ZS0xM18yXzAvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyREFLb0M7QUFFcEMsNEdBQXFHO0FBQ3JHLG9HQUE4RjtBQUU5RixNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUM7QUFFekIsa0JBQWUsR0FBUyxFQUFFLENBQUMsQ0FBQyxJQUFVLEVBQUUsT0FBeUIsRUFBRSxFQUFFO0lBQ2pFLE1BQU0sYUFBYSxHQUFHLGNBQWMsQ0FBQztJQUNyQyxnREFBZ0Q7SUFDaEQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztRQUM5QixNQUFNLElBQUksZ0NBQW1CLENBQ3pCLG9FQUFvRSxDQUN2RSxDQUFDO0lBQ04sQ0FBQztJQUNELE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUNmLGdFQUFnRSxPQUFPLEVBQUUsQ0FDNUUsQ0FBQztJQUNGLGtGQUFrRjtJQUNsRixJQUFBLG1FQUE4QixFQUFDLElBQUksRUFBRTtRQUNqQyxtQ0FBbUM7UUFDbkMsTUFBTTtRQUNOLHlCQUF5QjtLQUM1QixDQUFDLENBQUM7SUFDSCxJQUFBLDREQUEyQixFQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUMsQ0FBQyJ9
|
|
@@ -2,41 +2,51 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.addAllowedCommonJsDependencies = void 0;
|
|
4
4
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
-
const
|
|
5
|
+
const json_file_1 = require("@schematics/angular/utility/json-file");
|
|
6
|
+
/**
|
|
7
|
+
* Adds the dependencies missing from the `allowedCommonJsDependencies` of the build of the `defaultProject`,
|
|
8
|
+
* or of every application when there is no `defaultProject` (removed from angular.json since Angular 14).
|
|
9
|
+
*/
|
|
10
|
+
const addAllowedCommonJsDependencies = (tree, dependencies) => {
|
|
11
|
+
var _a;
|
|
6
12
|
const pathToAngularJson = 'angular.json';
|
|
7
|
-
|
|
8
|
-
if (!file) {
|
|
13
|
+
if (!tree.exists(pathToAngularJson)) {
|
|
9
14
|
// Should never happen because always check in rules
|
|
10
15
|
return;
|
|
11
16
|
}
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const arrayOfDependenciesToAdd = [
|
|
23
|
-
'core-js/modules/es.array.includes',
|
|
24
|
-
'iban',
|
|
25
|
-
'zone.js/dist/zone-error',
|
|
26
|
-
];
|
|
27
|
-
if (Object.hasOwn(buildOptions, 'allowedCommonJsDependencies')) {
|
|
28
|
-
// Do not add dependency if already exist
|
|
29
|
-
const existingDeps = [...buildOptions.allowedCommonJsDependencies];
|
|
30
|
-
arrayOfDependenciesToAdd.forEach((dep) => {
|
|
31
|
-
if (!existingDeps.includes(dep)) {
|
|
32
|
-
buildOptions.allowedCommonJsDependencies.push(dep);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
17
|
+
// JSONFile keeps the formatting and the comments of the file
|
|
18
|
+
const angularJson = new json_file_1.JSONFile(tree, pathToAngularJson);
|
|
19
|
+
const projects = ((_a = angularJson.get(['projects'])) !== null && _a !== void 0 ? _a : {});
|
|
20
|
+
const defaultProject = angularJson.get(['defaultProject']);
|
|
21
|
+
let projectNames;
|
|
22
|
+
if (typeof defaultProject === 'string') {
|
|
23
|
+
if (!projects[defaultProject]) {
|
|
24
|
+
throw new schematics_1.SchematicsException(`Sorry but we could not find project '${defaultProject}' in your angular.json file.`);
|
|
25
|
+
}
|
|
26
|
+
projectNames = [defaultProject];
|
|
35
27
|
}
|
|
36
28
|
else {
|
|
37
|
-
|
|
29
|
+
projectNames = Object.keys(projects).filter((name) => projects[name].projectType === 'application');
|
|
38
30
|
}
|
|
39
|
-
|
|
31
|
+
projectNames
|
|
32
|
+
.filter((name) => { var _a, _b; return (_b = (_a = projects[name].architect) === null || _a === void 0 ? void 0 : _a.build) === null || _b === void 0 ? void 0 : _b.options; })
|
|
33
|
+
.forEach((name) => {
|
|
34
|
+
var _a;
|
|
35
|
+
const path = [
|
|
36
|
+
'projects',
|
|
37
|
+
name,
|
|
38
|
+
'architect',
|
|
39
|
+
'build',
|
|
40
|
+
'options',
|
|
41
|
+
'allowedCommonJsDependencies',
|
|
42
|
+
];
|
|
43
|
+
const existingDeps = ((_a = angularJson.get(path)) !== null && _a !== void 0 ? _a : []);
|
|
44
|
+
// Do not add dependency if already exist
|
|
45
|
+
const missingDeps = dependencies.filter((dep) => !existingDeps.includes(dep));
|
|
46
|
+
if (missingDeps.length) {
|
|
47
|
+
angularJson.modify(path, [...existingDeps, ...missingDeps]);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
40
50
|
};
|
|
41
51
|
exports.addAllowedCommonJsDependencies = addAllowedCommonJsDependencies;
|
|
42
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLWFsbG93ZWQtY29tbW9uLWpzLWRlcGVuZGVuY2llcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3ByZXN0YXRpb25zLW5nL3NjaGVtYXRpY3MvdXRpbGl0eS9hZGQtYWxsb3dlZC1jb21tb24tanMtZGVwZW5kZW5jaWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJEQUF1RTtBQUN2RSxxRUFBaUU7QUFPakU7OztHQUdHO0FBQ0ksTUFBTSw4QkFBOEIsR0FBRyxDQUMxQyxJQUFVLEVBQ1YsWUFBc0IsRUFDbEIsRUFBRTs7SUFDTixNQUFNLGlCQUFpQixHQUFHLGNBQWMsQ0FBQztJQUN6QyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7UUFDbEMsb0RBQW9EO1FBQ3BELE9BQU87SUFDWCxDQUFDO0lBRUQsNkRBQTZEO0lBQzdELE1BQU0sV0FBVyxHQUFHLElBQUksb0JBQVEsQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUMxRCxNQUFNLFFBQVEsR0FBRyxDQUFDLE1BQUEsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLG1DQUFJLEVBQUUsQ0FHcEQsQ0FBQztJQUNGLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7SUFFM0QsSUFBSSxZQUFzQixDQUFDO0lBQzNCLElBQUksT0FBTyxjQUFjLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSxnQ0FBbUIsQ0FDekIsd0NBQXdDLGNBQWMsOEJBQThCLENBQ3ZGLENBQUM7UUFDTixDQUFDO1FBQ0QsWUFBWSxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDcEMsQ0FBQztTQUFNLENBQUM7UUFDSixZQUFZLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQ3ZDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxLQUFLLGFBQWEsQ0FDekQsQ0FBQztJQUNOLENBQUM7SUFFRCxZQUFZO1NBQ1AsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsZUFBQyxPQUFBLE1BQUEsTUFBQSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUywwQ0FBRSxLQUFLLDBDQUFFLE9BQU8sQ0FBQSxFQUFBLENBQUM7U0FDMUQsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7O1FBQ2QsTUFBTSxJQUFJLEdBQUc7WUFDVCxVQUFVO1lBQ1YsSUFBSTtZQUNKLFdBQVc7WUFDWCxPQUFPO1lBQ1AsU0FBUztZQUNULDZCQUE2QjtTQUNoQyxDQUFDO1FBQ0YsTUFBTSxZQUFZLEdBQUcsQ0FBQyxNQUFBLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLG1DQUFJLEVBQUUsQ0FBYSxDQUFDO1FBQy9ELHlDQUF5QztRQUN6QyxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUNuQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUN2QyxDQUFDO1FBQ0YsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLFlBQVksRUFBRSxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ1gsQ0FBQyxDQUFDO0FBcERXLFFBQUEsOEJBQThCLGtDQW9EekMifQ==
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.removeEmitDecoratorMetadata = void 0;
|
|
4
|
+
const json_file_1 = require("@schematics/angular/utility/json-file");
|
|
4
5
|
const removeEmitDecoratorMetadata = (tree) => {
|
|
5
6
|
const tsConfig = 'tsconfig.json';
|
|
6
|
-
|
|
7
|
-
if (!file) {
|
|
7
|
+
if (!tree.exists(tsConfig)) {
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
10
|
+
// JSONFile keeps the formatting and the comments of the file
|
|
11
|
+
new json_file_1.JSONFile(tree, tsConfig).remove([
|
|
12
|
+
'compilerOptions',
|
|
13
|
+
'emitDecoratorMetadata',
|
|
14
|
+
]);
|
|
16
15
|
};
|
|
17
16
|
exports.removeEmitDecoratorMetadata = removeEmitDecoratorMetadata;
|
|
18
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3ZlLWVtaXQtZGVjb3JhdG9yLW1ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvcHJlc3RhdGlvbnMtbmcvc2NoZW1hdGljcy91dGlsaXR5L3JlbW92ZS1lbWl0LWRlY29yYXRvci1tZXRhZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxRUFBaUU7QUFFMUQsTUFBTSwyQkFBMkIsR0FBRyxDQUFDLElBQVUsRUFBUSxFQUFFO0lBQzVELE1BQU0sUUFBUSxHQUFHLGVBQWUsQ0FBQztJQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE9BQU87SUFDWCxDQUFDO0lBRUQsNkRBQTZEO0lBQzdELElBQUksb0JBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ2hDLGlCQUFpQjtRQUNqQix1QkFBdUI7S0FDMUIsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDO0FBWFcsUUFBQSwyQkFBMkIsK0JBV3RDIn0=
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import vitest from '@vitest/eslint-plugin';
|
|
1
2
|
import { builtinRules } from 'eslint/use-at-your-own-risk';
|
|
2
3
|
import { describe, expect, it } from 'vitest';
|
|
3
4
|
|
|
@@ -6,6 +7,10 @@ import prestationsNg, { configs, plugin, rules } from '../../index.mjs';
|
|
|
6
7
|
const PLUGIN_KEY = '@dsivd/prestations-ng';
|
|
7
8
|
|
|
8
9
|
const configNames = Object.keys(configs);
|
|
10
|
+
// The configs of this library's plugin (the preset of the Vitest specs only configures @vitest/eslint-plugin)
|
|
11
|
+
const pluginConfigNames = configNames.filter(
|
|
12
|
+
(name) => name !== 'specTsRecommended',
|
|
13
|
+
);
|
|
9
14
|
|
|
10
15
|
// Configs that only register this library's rules, and the presets built on top of them.
|
|
11
16
|
const RULE_LAYERS = ['tsRules', 'templateRules'];
|
|
@@ -52,6 +57,7 @@ describe('eslint configs', () => {
|
|
|
52
57
|
'templateRecommended',
|
|
53
58
|
'tsRules',
|
|
54
59
|
'templateRules',
|
|
60
|
+
'specTsRecommended',
|
|
55
61
|
]);
|
|
56
62
|
});
|
|
57
63
|
|
|
@@ -88,7 +94,7 @@ describe('eslint configs', () => {
|
|
|
88
94
|
|
|
89
95
|
// Two entries declaring the same plugin key from different copies is a hard ESLint
|
|
90
96
|
// failure, so the preset must register ours exactly once.
|
|
91
|
-
it.each(
|
|
97
|
+
it.each(pluginConfigNames)('%s should register the plugin once', (name) => {
|
|
92
98
|
const declarations = configs[name]
|
|
93
99
|
.map((entry) => entry.plugins?.[PLUGIN_KEY])
|
|
94
100
|
.filter(Boolean);
|
|
@@ -101,7 +107,9 @@ describe('eslint configs', () => {
|
|
|
101
107
|
});
|
|
102
108
|
|
|
103
109
|
it('should enable every rule in at least one config', () => {
|
|
104
|
-
const enabled = new Set(
|
|
110
|
+
const enabled = new Set(
|
|
111
|
+
pluginConfigNames.flatMap((n) => ownIdsOf(configs[n])),
|
|
112
|
+
);
|
|
105
113
|
|
|
106
114
|
for (const ruleName of Object.keys(rules)) {
|
|
107
115
|
expect(enabled).toContain(`${PLUGIN_KEY}/${ruleName}`);
|
|
@@ -118,6 +126,42 @@ describe('eslint configs', () => {
|
|
|
118
126
|
);
|
|
119
127
|
});
|
|
120
128
|
|
|
129
|
+
describe('specTsRecommended', () => {
|
|
130
|
+
const rulesOf = (config) =>
|
|
131
|
+
Object.assign({}, ...config.map((entry) => entry.rules ?? {}));
|
|
132
|
+
|
|
133
|
+
it('should build on the recommended config of @vitest/eslint-plugin', () => {
|
|
134
|
+
expect(configs.specTsRecommended[0]).toBe(vitest.configs.recommended);
|
|
135
|
+
expect(pluginsOf(configs.specTsRecommended)).toEqual({ vitest });
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should count the assertions of the helpers and of the HttpTestingController', () => {
|
|
139
|
+
const [, options] = rulesOf(configs.specTsRecommended)[
|
|
140
|
+
'vitest/expect-expect'
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
expect(options.assertFunctionNames).toEqual(
|
|
144
|
+
expect.arrayContaining([
|
|
145
|
+
'expect',
|
|
146
|
+
'expect*',
|
|
147
|
+
'*.expectOne',
|
|
148
|
+
'*.verify',
|
|
149
|
+
]),
|
|
150
|
+
);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// An expect which may not run lets a test pass without asserting anything
|
|
154
|
+
it('should keep vitest/no-conditional-expect enabled', () => {
|
|
155
|
+
expect(
|
|
156
|
+
isOff(
|
|
157
|
+
rulesOf(configs.specTsRecommended)[
|
|
158
|
+
'vitest/no-conditional-expect'
|
|
159
|
+
],
|
|
160
|
+
),
|
|
161
|
+
).toBe(false);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
121
165
|
describe('eslint plugin', () => {
|
|
122
166
|
it('should be named after the npm package', () => {
|
|
123
167
|
expect(plugin.meta.name).toBe(PLUGIN_KEY);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The house preset of the Vitest specs: the recommended rules of `@vitest/eslint-plugin`, with the
|
|
3
|
+
* assertions also made by the helpers of the specs and by the `HttpTestingController`.
|
|
4
|
+
*
|
|
5
|
+
* Meant for the `extends` of a `**\/*.spec.ts` block (the Cypress `*.spec.cy.ts` files are not
|
|
6
|
+
* Vitest specs).
|
|
7
|
+
*
|
|
8
|
+
* @param {import('@vitest/eslint-plugin').default} vitest the `@vitest/eslint-plugin` module
|
|
9
|
+
* @returns {import('typescript-eslint').ConfigArray}
|
|
10
|
+
*/
|
|
11
|
+
const specTsRecommended = (vitest) => [
|
|
12
|
+
vitest.configs.recommended,
|
|
13
|
+
{
|
|
14
|
+
name: 'prestations-ng/spec-ts-recommended',
|
|
15
|
+
rules: {
|
|
16
|
+
'vitest/expect-expect': [
|
|
17
|
+
'error',
|
|
18
|
+
{
|
|
19
|
+
assertFunctionNames: [
|
|
20
|
+
'expect',
|
|
21
|
+
'expect*',
|
|
22
|
+
'assert*',
|
|
23
|
+
'test*',
|
|
24
|
+
'*.expectOne',
|
|
25
|
+
'*.expectNone',
|
|
26
|
+
'*.verify',
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
export default specTsRecommended;
|
|
@@ -8,6 +8,8 @@ import templateRules from './template-rules.mjs';
|
|
|
8
8
|
*
|
|
9
9
|
* Meant for the `extends` of a `**\/*.html` block. It brings its own parser and plugins,
|
|
10
10
|
* so do not spread `angular.configs.templateRecommended` alongside it.
|
|
11
|
+
*
|
|
12
|
+
* @returns {import('typescript-eslint').ConfigArray}
|
|
11
13
|
*/
|
|
12
14
|
const templateRecommended = (plugin) => [
|
|
13
15
|
...angular.configs.templateRecommended,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import templateBase from './template-base.mjs';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Only the rules written by this library. `templateRecommended` includes it, alongside
|
|
5
|
+
* the house style; use this layer directly to opt out of the latter.
|
|
6
|
+
*
|
|
7
|
+
* @returns {import('typescript-eslint').ConfigArray}
|
|
8
|
+
*/
|
|
5
9
|
const templateRules = (plugin) => [
|
|
6
10
|
templateBase(plugin),
|
|
7
11
|
{
|
|
@@ -14,6 +14,8 @@ import tsRules from './ts-rules.mjs';
|
|
|
14
14
|
* Meant for the `extends` of a `**\/*.ts` block. It brings its own parser and plugins,
|
|
15
15
|
* so do not spread `angular.configs.tsRecommended` alongside it — declaring the same
|
|
16
16
|
* plugin twice from two different copies makes ESLint fail outright.
|
|
17
|
+
*
|
|
18
|
+
* @returns {import('typescript-eslint').ConfigArray}
|
|
17
19
|
*/
|
|
18
20
|
const tsRecommended = (plugin) => [
|
|
19
21
|
eslint.configs.recommended,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import tsBase from './ts-base.mjs';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Only the rules written by this library. `tsRecommended` includes it, alongside the
|
|
5
|
+
* house style; use this layer directly to opt out of the latter.
|
|
6
|
+
*
|
|
7
|
+
* @returns {import('typescript-eslint').ConfigArray}
|
|
8
|
+
*/
|
|
5
9
|
const tsRules = (plugin) => [
|
|
6
10
|
tsBase(plugin),
|
|
7
11
|
{
|
package/src/eslint/index.mjs
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import specTsRecommended from './configs/spec-ts-recommended.mjs';
|
|
1
2
|
import templateRecommended from './configs/template-recommended.mjs';
|
|
2
3
|
import templateRules from './configs/template-rules.mjs';
|
|
3
4
|
import tsRecommended from './configs/ts-recommended.mjs';
|
|
4
5
|
import tsRules from './configs/ts-rules.mjs';
|
|
5
6
|
import rules from './rules/index.mjs';
|
|
6
7
|
|
|
8
|
+
// Only needed by the projects linting Vitest specs: the other configs can be used without it.
|
|
9
|
+
const vitest = await import('@vitest/eslint-plugin').then(
|
|
10
|
+
(module) => module.default,
|
|
11
|
+
() => null,
|
|
12
|
+
);
|
|
13
|
+
const specTsRecommendedConfig = vitest ? specTsRecommended(vitest) : null;
|
|
14
|
+
|
|
7
15
|
const plugin = {
|
|
8
16
|
meta: { name: '@dsivd/prestations-ng' },
|
|
9
17
|
rules,
|
|
@@ -16,6 +24,15 @@ const configs = {
|
|
|
16
24
|
// Only this library's own rules, for a project that supplies its own style.
|
|
17
25
|
tsRules: tsRules(plugin),
|
|
18
26
|
templateRules: templateRules(plugin),
|
|
27
|
+
// The preset of the Vitest specs (needs @vitest/eslint-plugin)
|
|
28
|
+
get specTsRecommended() {
|
|
29
|
+
if (!specTsRecommendedConfig) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
'prestationsNg.configs.specTsRecommended needs @vitest/eslint-plugin: npm install --save-dev @vitest/eslint-plugin@1',
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return specTsRecommendedConfig;
|
|
35
|
+
},
|
|
19
36
|
};
|
|
20
37
|
|
|
21
38
|
export { configs, plugin, rules };
|
|
@@ -241,7 +241,7 @@ function boundNameSignalKind(identifier, scopeContext, seen) {
|
|
|
241
241
|
scopeContext.sourceCode.getScope(identifier),
|
|
242
242
|
identifier.name,
|
|
243
243
|
);
|
|
244
|
-
if (
|
|
244
|
+
if (variable?.defs.length !== 1 || seen.has(variable)) {
|
|
245
245
|
return undefined;
|
|
246
246
|
}
|
|
247
247
|
seen.add(variable);
|