@lucca/stylelint-config-prisme 19.2.0
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/LFDeprecatedProperties.mjs +30 -0
- package/LFDeprecatedSelectors.mjs +67 -0
- package/LFVersions.mjs +46 -0
- package/README.md +118 -0
- package/currentLFVersion.mjs +20 -0
- package/package.json +29 -0
- package/stylelint.config.mjs +154 -0
- package/stylelintForLF.mjs +148 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// WARNING!
|
|
2
|
+
// Always check for variables with regular expressions. A string will match all the value, not part of it.
|
|
3
|
+
|
|
4
|
+
export default [
|
|
5
|
+
{
|
|
6
|
+
objectPattern: /--commons-boxShadow-X*(S|M|L)/,
|
|
7
|
+
versionDeprecated: '17.3.0',
|
|
8
|
+
versionDeleted: '19.1.0',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
objectPattern: /--palettes-(grey|primary|secondary|lucca)-[0-9]{2,3}/,
|
|
12
|
+
versionDeprecated: '17.3.0',
|
|
13
|
+
versionDeleted: '20.1.0',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
objectPattern: /--spacings-X*(S|M|L)/,
|
|
17
|
+
versionDeprecated: '17.4.0',
|
|
18
|
+
versionDeleted: '19.1.0',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
objectPattern: /--colors-(black|white)-color/,
|
|
22
|
+
versionDeprecated: '18.2.0',
|
|
23
|
+
versionDeleted: '20.1.0',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
objectPattern: /--commons-navSide-compact-width/,
|
|
27
|
+
versionDeprecated: '18.3.0',
|
|
28
|
+
versionDeleted: '20.1.0',
|
|
29
|
+
},
|
|
30
|
+
];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export default [
|
|
2
|
+
{
|
|
3
|
+
// Any combination of .button and .mod-icon with any non-whitespace character between
|
|
4
|
+
objectPattern: /(\.button|\.mod-icon)[\S]*(\.button|\.mod-icon)/,
|
|
5
|
+
versionDeprecated: '17.2.0',
|
|
6
|
+
versionDeleted: '19.1.0',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
objectPattern: ['.u-comma', '.u-unit'],
|
|
10
|
+
versionDeprecated: '17.3.0',
|
|
11
|
+
versionDeleted: '19.1.0',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
objectPattern: /\.palette-(grey|primary|secondary|lucca)/,
|
|
15
|
+
versionDeprecated: '17.3.0',
|
|
16
|
+
versionDeleted: '20.1.0',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
objectPattern: /\.u-(padding|margin|gap)X*(S|M|L)/,
|
|
20
|
+
versionDeprecated: '17.4.0',
|
|
21
|
+
versionDeleted: '19.1.0',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
objectPattern: /\.u-elevate*/,
|
|
25
|
+
versionDeprecated: '19.1.0',
|
|
26
|
+
versionDeleted: '19.1.0',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
objectPattern: [
|
|
30
|
+
'.user-info',
|
|
31
|
+
'.user-tile-title',
|
|
32
|
+
'.user-tile-label',
|
|
33
|
+
'.user-tile-footnote',
|
|
34
|
+
'.columnSticky',
|
|
35
|
+
'.table-head-row-cell-sortableButton',
|
|
36
|
+
'.indexTable-head-row-cell-sortableButton',
|
|
37
|
+
'.table-head-row-cell.mod-sortable',
|
|
38
|
+
'.table-head-row-cell.sortedAscending',
|
|
39
|
+
'.table-head-row-cell.sortedDescending',
|
|
40
|
+
'.u-textLeft',
|
|
41
|
+
'.u-textCenter',
|
|
42
|
+
'.u-textRight',
|
|
43
|
+
],
|
|
44
|
+
versionDeprecated: '18.1.0',
|
|
45
|
+
versionDeleted: '20.1.0',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
objectPattern: /\.user-info.+/,
|
|
49
|
+
versionDeprecated: '18.1.0',
|
|
50
|
+
versionDeleted: '20.1.0',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
objectPattern: /\.user-tile.+/,
|
|
54
|
+
versionDeprecated: '18.1.0',
|
|
55
|
+
versionDeleted: '20.1.0',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
objectPattern: ['.picture', '.indexTable-body-row-cell-action'],
|
|
59
|
+
versionDeprecated: '18.1.0',
|
|
60
|
+
versionDeleted: '20.1.0',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
objectPattern: ['.comment-content-textContainer', '.dialog-form', '.dialog-formOptional', '.mod-withMenuCompact'],
|
|
64
|
+
versionDeprecated: '18.3.0',
|
|
65
|
+
versionDeleted: '20.1.0',
|
|
66
|
+
},
|
|
67
|
+
];
|
package/LFVersions.mjs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as os from 'node:os';
|
|
2
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from '@angular/compiler-cli';
|
|
4
|
+
|
|
5
|
+
let LFVersions = null;
|
|
6
|
+
|
|
7
|
+
const CACHE_FILE_PATH = join(os.tmpdir(), 'stylelint-LFVersions.json');
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
const cacheFile = readFileSync(CACHE_FILE_PATH, 'utf8');
|
|
11
|
+
const cache = JSON.parse(cacheFile);
|
|
12
|
+
// If cache is older than 1 hour, don't use it
|
|
13
|
+
if (cache.createdAt && Date.now() - cache.createdAt < 1000 * 60 * 60) {
|
|
14
|
+
LFVersions = cache.LFVersions;
|
|
15
|
+
}
|
|
16
|
+
console.log(`Using cached data in ${CACHE_FILE_PATH}…`);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
// Whatever, no cache file means we'll fetch anyways
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (LFVersions === null) {
|
|
22
|
+
LFVersions = {};
|
|
23
|
+
console.log(`Fetching from Github to ${CACHE_FILE_PATH}…`);
|
|
24
|
+
const githubMilestones = await fetch('https://api.github.com/repos/LuccaSA/lucca-front/milestones?state=all&sort=due_on&direction=desc');
|
|
25
|
+
|
|
26
|
+
if (githubMilestones.ok) {
|
|
27
|
+
const milestones = await githubMilestones.json();
|
|
28
|
+
|
|
29
|
+
for (const milestone of milestones) {
|
|
30
|
+
let version = milestone.title;
|
|
31
|
+
|
|
32
|
+
if (version) {
|
|
33
|
+
const date = new Date(milestone.due_on);
|
|
34
|
+
// If version doesn't have patch version, add it as .0
|
|
35
|
+
if (version.split('.').length === 2) {
|
|
36
|
+
version += '.0';
|
|
37
|
+
}
|
|
38
|
+
LFVersions[version] = date.toLocaleDateString();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
writeFileSync(CACHE_FILE_PATH, JSON.stringify({ LFVersions, createdAt: Date.now() }), 'utf8');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default LFVersions;
|
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# lucca-front / Stylelint config
|
|
2
|
+
|
|
3
|
+
This package is a shareable stylelint configuration.
|
|
4
|
+
|
|
5
|
+
[Stylelint](https://stylelint.io/) checks for common mistakes in CSS and CSS-like files, and allows to define rules for tools and developers.
|
|
6
|
+
|
|
7
|
+
[Prettier should be used](https://stylelint.io/#how-itll-help-you) to handle coding style-guides when possible.
|
|
8
|
+
|
|
9
|
+
- This configuration lints your code with default CSS & SCSS rules, and adapts some of them for Lucca Front specifics
|
|
10
|
+
- It will trigger warnings for deprecated LF features and errors for deleted LF features.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
npm i --save-dev stylelint @lucca/stylelint-config-prisme
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Avoid conflicts
|
|
19
|
+
|
|
20
|
+
Remove any pre-existing [configuration](https://stylelint.io/user-guide/configure) (file or statements in package.json).
|
|
21
|
+
|
|
22
|
+
## Configure
|
|
23
|
+
|
|
24
|
+
### For your local project
|
|
25
|
+
|
|
26
|
+
Use this package in a _stylelint.config.js_ file in your repository:
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
module.exports = {
|
|
30
|
+
extends: ['@lucca/stylelint-config-prisme'],
|
|
31
|
+
rules: {},
|
|
32
|
+
};
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### For your CI
|
|
36
|
+
|
|
37
|
+
Add the relevant script to lint the code in Jenkins.
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
"stylelint": "stylelint \"./**/*.scss\"",
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
You can be more specific and restrict the path of scss files being linted: `"stylelint": "stylelint \"./SOME_PATH/**/*.scss\""`,
|
|
44
|
+
|
|
45
|
+
### Breaking the rules
|
|
46
|
+
|
|
47
|
+
#### Overrides
|
|
48
|
+
|
|
49
|
+
You can [apply specific rules with overrides](https://stylelint.io/user-guide/configure/#overrides) as needed.
|
|
50
|
+
|
|
51
|
+
Rules can be disabled while incrementally fixing your code. Set them to `null`. The following example will ignore the `no-descending-specificity` rule in all SCSS files within `*some-path* :
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
module.exports = {
|
|
55
|
+
extends: ['@lucca/stylelint-config-prisme'],
|
|
56
|
+
overrides: [
|
|
57
|
+
{
|
|
58
|
+
files: ['some-path/**/*.scss'],
|
|
59
|
+
rules: {
|
|
60
|
+
'no-descending-specificity': null,
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
rules: {};
|
|
65
|
+
};
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Ignoring code inline
|
|
69
|
+
|
|
70
|
+
If needed, each rule can be ignored with [stylelint-(dis|en)able](https://stylelint.io/user-guide/ignore-code).
|
|
71
|
+
|
|
72
|
+
Please explain why with a comment if you're doing so. Use `styleling-disable[-*] -- Comment` and enable stylelint back as soon as possible: `styleling-enable`.
|
|
73
|
+
|
|
74
|
+
## Testing locally
|
|
75
|
+
|
|
76
|
+
1. From the root of this package, run `npm pack`. This will generate a _.tgz_ file.
|
|
77
|
+
2. From the root of the project you want to lint, run `npm i PATH_TO_LUCCA_FRONT_REPOSITORY/packages/stylelint-config/lucca-front-stylelint-config-0.0.0.tgz`.
|
|
78
|
+
|
|
79
|
+
The configuration from your local repository should be applied right away. _If in doubt, restart your editor._
|
|
80
|
+
|
|
81
|
+
## Configuring your editor
|
|
82
|
+
|
|
83
|
+
### VS Code
|
|
84
|
+
|
|
85
|
+
⚠️ A [VSCode extension bug](https://github.com/stylelint/vscode-stylelint/issues/490#issuecomment-1966934533) might prevent you from using stylelint 16+. See below for a fix through VS-code settings.
|
|
86
|
+
|
|
87
|
+
Those settings in _.vscode/settings.json_ should be fine, but you can also follow instructions on the [extension page](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint):
|
|
88
|
+
:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
"[scss]": {
|
|
92
|
+
"editor.formatOnSave": true,
|
|
93
|
+
"editor.defaultFormatter": "stylelint.vscode-stylelint",
|
|
94
|
+
"editor.codeActionsOnSave": {
|
|
95
|
+
"source.fixAll.stylelint": "explicit"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"stylelint.reportInvalidScopeDisables": true,
|
|
99
|
+
"stylelint.reportNeedlessDisables": true,
|
|
100
|
+
"stylelint.snippet": ["css", "scss"],
|
|
101
|
+
"stylelint.validate": ["css", "scss"],
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Please note **the VSCode extension does not take overrides into account**.
|
|
105
|
+
|
|
106
|
+
#### bug: double slash comments appended to the nearest property
|
|
107
|
+
|
|
108
|
+
A [hackfix](https://github.com/stylelint/vscode-stylelint/issues/490#issuecomment-2156218548) is available.
|
|
109
|
+
|
|
110
|
+
Add the following line in _.vscode/settings.json_ if the issue arises:
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
"stylelint.customSyntax": "postcss-scss"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### JetStorm
|
|
117
|
+
|
|
118
|
+
You might need to rename _stylelint.config.js_ to _stylelint.config.cjs_ (_CommonJS_) and [adapt the code in consequence](https://stylelint.io/user-guide/configure).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// We are keeping this hardcoded in LF for local stylelint usage
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
|
|
4
|
+
let version = null;
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
const LFFolder = import.meta.resolve('@lucca-front/scss');
|
|
8
|
+
|
|
9
|
+
if (LFFolder) {
|
|
10
|
+
const packageJson = await readFile(new URL('../package.json', LFFolder), {
|
|
11
|
+
encoding: 'utf-8',
|
|
12
|
+
});
|
|
13
|
+
version = JSON.parse(packageJson).version;
|
|
14
|
+
if (version === '0.0.0') {
|
|
15
|
+
version = null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
} catch (e) {}
|
|
19
|
+
|
|
20
|
+
export default version;
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lucca/stylelint-config-prisme",
|
|
3
|
+
"version": "19.2.0",
|
|
4
|
+
"description": "Lucca Front stylelint configuration",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/LuccaSA/lucca-front.git"
|
|
8
|
+
},
|
|
9
|
+
"main": "stylelint.config.mjs",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"stylelint",
|
|
12
|
+
"stylelint-config",
|
|
13
|
+
"lucca",
|
|
14
|
+
"scss",
|
|
15
|
+
"css"
|
|
16
|
+
],
|
|
17
|
+
"private": false,
|
|
18
|
+
"author": "The product design team <design@lucca.fr>",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/LuccaSA/lucca-front/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/LuccaSA/lucca-front#readme",
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"stylelint": "^16.14.1",
|
|
26
|
+
"stylelint-config-prettier-scss": "^1.0.0",
|
|
27
|
+
"stylelint-config-standard-scss": "^14.0.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/** @type {import('stylelint').Config} */
|
|
2
|
+
|
|
3
|
+
import LFDeprecatedProperties from './LFDeprecatedProperties.mjs';
|
|
4
|
+
import LFDeprecatedSelectors from './LFDeprecatedSelectors.mjs';
|
|
5
|
+
import { getDisallowedObjects, getDisallowedData } from './stylelintForLF.mjs';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
extends: ['stylelint-config-standard-scss', 'stylelint-config-prettier-scss'],
|
|
9
|
+
overrides: [
|
|
10
|
+
{
|
|
11
|
+
// Allow common component files to be empty.
|
|
12
|
+
files: ['**/vars.scss'],
|
|
13
|
+
rules: {
|
|
14
|
+
'custom-property-empty-line-before': null,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
rules: {
|
|
19
|
+
// SCSS specific
|
|
20
|
+
// ============================================================================================
|
|
21
|
+
'scss/at-function-pattern': [
|
|
22
|
+
'^(([a-z][a-zA-Z0-9]*)((-(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)|[A-Z]+)$',
|
|
23
|
+
{
|
|
24
|
+
message: (functionName) => `Expected "${functionName}" to match pattern foo(-bar(Baz)*)*`,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
'scss/at-mixin-pattern': [
|
|
28
|
+
'^(([a-z][a-zA-Z0-9]*)((-(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)|[A-Z]+)$',
|
|
29
|
+
{
|
|
30
|
+
message: `Expected @mixin name to match pattern foo(-bar(Baz)*)*`,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
'scss/at-rule-conditional-no-parentheses': null,
|
|
34
|
+
'scss/comment-no-empty': null,
|
|
35
|
+
'scss/dollar-variable-empty-line-before': [
|
|
36
|
+
'always',
|
|
37
|
+
{
|
|
38
|
+
except: ['first-nested'],
|
|
39
|
+
ignore: ['after-comment', 'after-dollar-variable'],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
'scss/dollar-variable-pattern': [
|
|
43
|
+
'^([a-z][a-zA-Z0-9]*)((-(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)$',
|
|
44
|
+
{
|
|
45
|
+
message: (variable) => `Expected "${variable}" to match pattern $foo(-bar(Baz)*)*`,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
'scss/percent-placeholder-pattern': [
|
|
49
|
+
'^([a-z][a-zA-Z0-9]*)((-(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)$',
|
|
50
|
+
{
|
|
51
|
+
message: (placeholder) => `Expected "${placeholder}" to match pattern %foo(-bar(Baz)*)*`,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
|
|
55
|
+
// Generic rules
|
|
56
|
+
// ============================================================================================
|
|
57
|
+
'alpha-value-notation': [
|
|
58
|
+
'number',
|
|
59
|
+
{
|
|
60
|
+
severity: 'warning',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
'at-rule-empty-line-before': [
|
|
64
|
+
'always',
|
|
65
|
+
{
|
|
66
|
+
except: ['first-nested'],
|
|
67
|
+
ignore: ['after-comment', 'blockless-after-same-name-blockless'],
|
|
68
|
+
ignoreAtRules: ['else'],
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
'block-no-empty': null,
|
|
72
|
+
'color-hex-length': null,
|
|
73
|
+
'custom-property-empty-line-before': [
|
|
74
|
+
'always',
|
|
75
|
+
{
|
|
76
|
+
severity: 'warning',
|
|
77
|
+
except: ['after-comment', 'after-custom-property', 'first-nested'],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
'custom-property-no-missing-var-function': true,
|
|
81
|
+
'custom-property-pattern': [
|
|
82
|
+
'^([a-z][a-zA-Z0-9]*)((-(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)$',
|
|
83
|
+
{
|
|
84
|
+
message: (customProperty) => `Expected "${customProperty}" to match pattern --foo(-bar(Baz)*)*`,
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
'declaration-block-no-redundant-longhand-properties': null,
|
|
88
|
+
'declaration-empty-line-before': [
|
|
89
|
+
'always',
|
|
90
|
+
{
|
|
91
|
+
severity: 'warning',
|
|
92
|
+
except: ['after-comment', 'after-declaration', 'first-nested'],
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
'declaration-property-value-disallowed-list': [
|
|
96
|
+
{ '/.*/': getDisallowedObjects(LFDeprecatedProperties) },
|
|
97
|
+
{
|
|
98
|
+
url: 'https://prisme.lucca.io/94310e217/p/40c515-cycle-de-vie-des-composants/b/95175f',
|
|
99
|
+
message: (property, value) => getDisallowedData(LFDeprecatedProperties, value).message,
|
|
100
|
+
severity: (property, value) => getDisallowedData(LFDeprecatedProperties, value).severity,
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
'keyframes-name-pattern': [
|
|
104
|
+
'^([a-z][a-zA-Z0-9]*)((-(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)$',
|
|
105
|
+
{
|
|
106
|
+
message: (keyframeName) => `Expected "${keyframeName}" to match pattern foo(-bar(Baz)*)*`,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
'number-max-precision': 5,
|
|
110
|
+
'property-disallowed-list': [
|
|
111
|
+
getDisallowedObjects(LFDeprecatedProperties),
|
|
112
|
+
{
|
|
113
|
+
url: 'https://prisme.lucca.io/94310e217/p/40c515-cycle-de-vie-des-composants/b/95175f',
|
|
114
|
+
message: (property) => getDisallowedData(LFDeprecatedProperties, property).message,
|
|
115
|
+
severity: (property) => getDisallowedData(LFDeprecatedProperties, property).severity,
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
'property-no-unknown': [
|
|
119
|
+
true,
|
|
120
|
+
{
|
|
121
|
+
ignoreProperties: ['scrollbar-3dlight-color'],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
'selector-class-pattern': [
|
|
125
|
+
'^([a-z][a-zA-Z0-9]*)(((-|_)(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)$',
|
|
126
|
+
{
|
|
127
|
+
message: (selectorClass) => `Expected "${selectorClass}" to match pattern .foo(-bar(Baz)*)*`,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
'selector-disallowed-list': [
|
|
131
|
+
getDisallowedObjects(LFDeprecatedSelectors),
|
|
132
|
+
{
|
|
133
|
+
splitList: true,
|
|
134
|
+
reportDisables: true,
|
|
135
|
+
url: 'https://prisme.lucca.io/94310e217/p/40c515-cycle-de-vie-des-composants/b/95175f',
|
|
136
|
+
message: (selector) => getDisallowedData(LFDeprecatedSelectors, selector).message,
|
|
137
|
+
severity: (selector) => getDisallowedData(LFDeprecatedSelectors, selector).severity,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
'selector-id-pattern': [
|
|
141
|
+
'^([a-z][a-zA-Z0-9]*)(((-|_)(([a-z0-9]+[a-zA-Z0-9]*)|([A-Z]+))+)*)$',
|
|
142
|
+
{
|
|
143
|
+
message: (selectorId) => `Expected "${selectorId}" to match pattern #foo(-bar(Baz)*)*`,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
'selector-pseudo-element-no-unknown': [
|
|
147
|
+
true,
|
|
148
|
+
{
|
|
149
|
+
ignorePseudoElements: ['ng-deep'],
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
'value-keyword-case': null,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import LFVersions from './LFVersions.mjs';
|
|
2
|
+
import currentLFVersion from './currentLFVersion.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get all blacklisted elements from all versions.
|
|
6
|
+
*
|
|
7
|
+
* @return {Array[Regex | String]}
|
|
8
|
+
*/
|
|
9
|
+
export function getDisallowedObjects(disallowedObjects) {
|
|
10
|
+
return disallowedObjects.reduce((output, object) => {
|
|
11
|
+
return output.concat(object.objectPattern);
|
|
12
|
+
}, []);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Get data related to object.
|
|
17
|
+
*
|
|
18
|
+
* @param {Array[Object{objectPattern, versionDeprecated, versionDeleted}]} disallowedObjects - List of disallowed objects
|
|
19
|
+
* @param {String} faultyPattern - Pattern provided by Stylelint, to check against list of custom patterns
|
|
20
|
+
* @return {{message: String, severity: String}}
|
|
21
|
+
*/
|
|
22
|
+
export function getDisallowedData(disallowedObjects, faultyPattern) {
|
|
23
|
+
let objectData = disallowedObjects.find((haystack) => {
|
|
24
|
+
// If the patterns are within an array, parse it.
|
|
25
|
+
if (Array.isArray(haystack.objectPattern)) {
|
|
26
|
+
return haystack.objectPattern.find((subHaystack) => {
|
|
27
|
+
return comparePatterns(faultyPattern, subHaystack);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return comparePatterns(faultyPattern, haystack.objectPattern);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
objectData = setDates(objectData);
|
|
35
|
+
objectData.faultyPattern = faultyPattern;
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
message: getMessage(objectData),
|
|
39
|
+
severity: getSeverity(objectData),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Set deprecation and deletion dates for an object.
|
|
45
|
+
*
|
|
46
|
+
* @param {Object} objectData - Object found in the list of disallowed objects
|
|
47
|
+
* @return {Object} - objectData with dates.
|
|
48
|
+
*/
|
|
49
|
+
function setDates(objectData) {
|
|
50
|
+
return {
|
|
51
|
+
...objectData,
|
|
52
|
+
dateDeprecated: getDateForVersion(objectData.versionDeprecated),
|
|
53
|
+
dateDeleted: getDateForVersion(objectData.versionDeleted),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Is the parameter a valid date?
|
|
59
|
+
*
|
|
60
|
+
* @param {*} date - Value to analise
|
|
61
|
+
* @return boolean
|
|
62
|
+
*/
|
|
63
|
+
function isValidDate(date) {
|
|
64
|
+
return date instanceof Date && !isNaN(date);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get date for the specified LF version.
|
|
69
|
+
*
|
|
70
|
+
* @param {string} version - semver formatted LF version
|
|
71
|
+
* @return {Date|undefined}
|
|
72
|
+
*/
|
|
73
|
+
function getDateForVersion(version) {
|
|
74
|
+
if (version && version in LFVersions) {
|
|
75
|
+
const date = new Date(LFVersions[version]);
|
|
76
|
+
|
|
77
|
+
if (isValidDate(date)) {
|
|
78
|
+
return date;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Compare the faulty pattern with disallowed patterns.
|
|
85
|
+
*
|
|
86
|
+
* @param {String} faultyPattern - faultyPattern returned by Stylelint
|
|
87
|
+
* @param {Array[RegExp | String] | RegExp | String} disallowedPattern - Custom pattern to match
|
|
88
|
+
* @return boolean
|
|
89
|
+
*/
|
|
90
|
+
function comparePatterns(faultyPattern, disallowedPattern) {
|
|
91
|
+
return typeof disallowedPattern === 'string' ? faultyPattern === disallowedPattern : disallowedPattern.test(faultyPattern);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Format message based on versions criticity.
|
|
96
|
+
*
|
|
97
|
+
* @param {Object} objectData
|
|
98
|
+
* @return {String}
|
|
99
|
+
*/
|
|
100
|
+
function getMessage(objectData) {
|
|
101
|
+
let pattern = `${objectData.faultyPattern}`;
|
|
102
|
+
let status = 'deprecated';
|
|
103
|
+
let messageDeprecated = '';
|
|
104
|
+
let messageDeleted = '';
|
|
105
|
+
let messageLFVersionWarning = '';
|
|
106
|
+
|
|
107
|
+
if (!currentLFVersion) {
|
|
108
|
+
messageLFVersionWarning = ' | LF version not found';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (objectData.dateDeprecated) {
|
|
112
|
+
const daysAgo = Math.ceil((objectData.dateDeprecated.getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24));
|
|
113
|
+
const daysAgoString = new Intl.RelativeTimeFormat().format(daysAgo, 'day');
|
|
114
|
+
|
|
115
|
+
messageDeprecated = ` | since ${objectData.dateDeprecated.toLocaleDateString()} (${daysAgoString}, LF ${objectData.versionDeprecated})`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (objectData.dateDeleted) {
|
|
119
|
+
const daysLeft = Math.ceil((objectData.dateDeleted.getTime() - new Date().getTime()) / (1000 * 60 * 60 * 24));
|
|
120
|
+
const dayString = new Intl.RelativeTimeFormat().format(daysLeft, 'day');
|
|
121
|
+
|
|
122
|
+
if (daysLeft <= 0) {
|
|
123
|
+
status = 'deleted';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
messageDeleted = ` | until ${objectData.dateDeleted.toLocaleDateString()} (${dayString}, LF ${objectData.versionDeleted})`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return `${status}${messageLFVersionWarning}${messageDeprecated}${messageDeleted} | ${pattern}`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get severity based on version used.
|
|
134
|
+
*
|
|
135
|
+
* @param {String} objectData
|
|
136
|
+
* @return {'warning'|'error'}
|
|
137
|
+
*/
|
|
138
|
+
function getSeverity(objectData) {
|
|
139
|
+
if (!currentLFVersion) {
|
|
140
|
+
return 'warning';
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (currentLFVersion < objectData.versionDeleted) {
|
|
144
|
+
return 'warning';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return 'error';
|
|
148
|
+
}
|