@mimik/eslint-plugin-document-env 2.0.8 → 2.0.9
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/README.md +133 -20
- package/index.js +57 -16
- package/package.json +19 -13
- package/eslint.config.js +0 -58
- package/test/validate-document-env.test.js +0 -69
package/README.md
CHANGED
|
@@ -1,31 +1,144 @@
|
|
|
1
|
-
# eslint-plugin-document-env
|
|
2
|
-
|
|
1
|
+
# @mimik/eslint-plugin-document-env
|
|
2
|
+
|
|
3
|
+
An ESLint plugin that validates that all `process.env` usages are properly documented in markdown-style block comments.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install --save-dev @mimik/eslint-plugin-document-env
|
|
9
|
+
```
|
|
10
|
+
|
|
3
11
|
## Usage
|
|
4
12
|
|
|
5
|
-
|
|
6
|
-
|
|
13
|
+
Add the plugin to your `eslint.config.js`:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import documentEnv from '@mimik/eslint-plugin-document-env';
|
|
17
|
+
|
|
18
|
+
export default [
|
|
19
|
+
{
|
|
20
|
+
plugins: {
|
|
21
|
+
'@mimik/document-env': documentEnv,
|
|
22
|
+
},
|
|
23
|
+
rules: {
|
|
24
|
+
'@mimik/document-env/validate-document-env': 'error',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
];
|
|
7
28
|
```
|
|
8
29
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"plugins": [
|
|
14
|
-
"@mimik/document-env"
|
|
15
|
-
],
|
|
16
|
-
"rules": {
|
|
17
|
-
"@mimik/document-env/validate-document-env": 2
|
|
18
|
-
}
|
|
19
|
-
}
|
|
30
|
+
## Rule: `validate-document-env`
|
|
31
|
+
|
|
32
|
+
Verifies that when an environment variable is used via `process.env`, there is a corresponding documentation entry in a block comment with the following table header:
|
|
33
|
+
|
|
20
34
|
```
|
|
21
|
-
|
|
35
|
+
* | Env variable name | Description | Default | Comments |
|
|
36
|
+
* | ----------------- | ----------- | ------- | -------- |
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### What Gets Checked
|
|
40
|
+
|
|
41
|
+
- Every `process.env.VAR_NAME` or `process.env['VAR_NAME']` access must have a matching row in a documentation table
|
|
42
|
+
- The description column must not be empty or blank
|
|
43
|
+
- The variable must not be documented more than once (across separate tables or within the same table)
|
|
44
|
+
|
|
45
|
+
### Messages
|
|
22
46
|
|
|
23
|
-
|
|
47
|
+
| Message ID | Description |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `unDocumentedProcessEnv` | No documentation table entry found for the variable |
|
|
50
|
+
| `unDescribedProcessEnv` | Table entry exists but the description column is empty |
|
|
51
|
+
| `duplicatedProcessEnv` | Variable is documented in multiple tables or multiple rows |
|
|
24
52
|
|
|
25
|
-
###
|
|
53
|
+
### Example
|
|
26
54
|
|
|
27
|
-
|
|
55
|
+
```js
|
|
56
|
+
/**
|
|
28
57
|
* | Env variable name | Description | Default | Comments |
|
|
29
58
|
* | ----------------- | ----------- | ------- | -------- |
|
|
59
|
+
* | PORT | The port the server listens on | 3000 | |
|
|
60
|
+
* | NODE_ENV | Runtime environment | development | |
|
|
61
|
+
*/
|
|
62
|
+
const port = process.env.PORT; // OK
|
|
63
|
+
const env = process.env.NODE_ENV; // OK
|
|
64
|
+
const secret = process.env.SECRET; // Error: Undocumented environment variable: SECRET
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API Reference
|
|
68
|
+
|
|
69
|
+
## Functions
|
|
70
|
+
|
|
71
|
+
<dl>
|
|
72
|
+
<dt><a href="#isProcessEnvAccess">isProcessEnvAccess(node)</a> ⇒ <code>boolean</code></dt>
|
|
73
|
+
<dd><p>Checks whether an AST node represents a <code>process.env</code> member expression.</p>
|
|
74
|
+
</dd>
|
|
75
|
+
<dt><a href="#regular">regular(propName)</a> ⇒ <code>RegExp</code></dt>
|
|
76
|
+
<dd><p>Builds a regex that matches a documentation table row for the given env variable name.</p>
|
|
77
|
+
</dd>
|
|
78
|
+
<dt><a href="#extractEnvVarName">extractEnvVarName(node, context)</a> ⇒ <code>string</code> | <code>undefined</code></dt>
|
|
79
|
+
<dd><p>Extracts the environment variable name from a <code>process.env.X</code> or <code>process.env['X']</code> access.
|
|
80
|
+
For computed access with a non-literal key (e.g. <code>process.env[varName]</code>), falls back to
|
|
81
|
+
extracting the source text of the computed expression.</p>
|
|
82
|
+
</dd>
|
|
83
|
+
<dt><a href="#findEnvDocInComments">findEnvDocInComments(comments, regex)</a> ⇒ <code>Array.<Object></code></dt>
|
|
84
|
+
<dd><p>Finds block comments that contain a documentation table entry for the given env variable.</p>
|
|
85
|
+
</dd>
|
|
86
|
+
</dl>
|
|
87
|
+
|
|
88
|
+
<a name="isProcessEnvAccess"></a>
|
|
89
|
+
|
|
90
|
+
## isProcessEnvAccess(node) ⇒ <code>boolean</code>
|
|
91
|
+
Checks whether an AST node represents a `process.env` member expression.
|
|
92
|
+
|
|
93
|
+
**Kind**: global function
|
|
94
|
+
**Returns**: <code>boolean</code> - `true` if the node is a non-computed `process.env` access.
|
|
95
|
+
|
|
96
|
+
| Param | Type | Description |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| node | <code>Object</code> | The AST MemberExpression node to check. |
|
|
99
|
+
|
|
100
|
+
<a name="regular"></a>
|
|
101
|
+
|
|
102
|
+
## regular(propName) ⇒ <code>RegExp</code>
|
|
103
|
+
Builds a regex that matches a documentation table row for the given env variable name.
|
|
104
|
+
|
|
105
|
+
**Kind**: global function
|
|
106
|
+
**Returns**: <code>RegExp</code> - A multiline, global, unicode regex with two capture groups:
|
|
107
|
+
(1) the variable name and (2) the description cell content.
|
|
108
|
+
|
|
109
|
+
| Param | Type | Description |
|
|
110
|
+
| --- | --- | --- |
|
|
111
|
+
| propName | <code>string</code> | The environment variable name to search for. |
|
|
112
|
+
|
|
113
|
+
<a name="extractEnvVarName"></a>
|
|
114
|
+
|
|
115
|
+
## extractEnvVarName(node, context) ⇒ <code>string</code> \| <code>undefined</code>
|
|
116
|
+
Extracts the environment variable name from a `process.env.X` or `process.env['X']` access.
|
|
117
|
+
For computed access with a non-literal key (e.g. `process.env[varName]`), falls back to
|
|
118
|
+
extracting the source text of the computed expression.
|
|
119
|
+
|
|
120
|
+
**Kind**: global function
|
|
121
|
+
**Returns**: <code>string</code> \| <code>undefined</code> - The env variable name, or `undefined` if the property node is missing.
|
|
122
|
+
|
|
123
|
+
| Param | Type | Description |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| node | <code>Object</code> | The `process.env` MemberExpression node. |
|
|
126
|
+
| context | <code>Object</code> | The ESLint rule context. |
|
|
127
|
+
|
|
128
|
+
<a name="findEnvDocInComments"></a>
|
|
129
|
+
|
|
130
|
+
## findEnvDocInComments(comments, regex) ⇒ <code>Array.<Object></code>
|
|
131
|
+
Finds block comments that contain a documentation table entry for the given env variable.
|
|
132
|
+
|
|
133
|
+
**Kind**: global function
|
|
134
|
+
**Returns**: <code>Array.<Object></code> - Matching block comments.
|
|
135
|
+
|
|
136
|
+
| Param | Type | Description |
|
|
137
|
+
| --- | --- | --- |
|
|
138
|
+
| comments | <code>Array.<Object></code> | All comments in the source file. |
|
|
139
|
+
| regex | <code>RegExp</code> | The regex to match the env variable documentation row. |
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
## License
|
|
30
143
|
|
|
31
|
-
|
|
144
|
+
MIT
|
package/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
|
|
3
|
+
const { version, name } = createRequire(import.meta.url)('./package.json');
|
|
4
|
+
|
|
1
5
|
const HEADER = ' * | Env variable name | Description | Default | Comments |\n';
|
|
2
6
|
const LINE = ' * | ----------------- | ----------- | ------- | -------- |\n';
|
|
3
7
|
const SINGLE = 1;
|
|
@@ -5,42 +9,80 @@ const NO_DESCRIPTION = 2;
|
|
|
5
9
|
const FIRST = 0;
|
|
6
10
|
const EMPTY = 0;
|
|
7
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Checks whether an AST node represents a `process.env` member expression.
|
|
14
|
+
* @param {Object} node - The AST MemberExpression node to check.
|
|
15
|
+
* @returns {boolean} `true` if the node is a non-computed `process.env` access.
|
|
16
|
+
*/
|
|
8
17
|
const isProcessEnvAccess = node => (
|
|
9
18
|
node.object?.name === 'process'
|
|
10
19
|
&& !node.computed
|
|
11
20
|
&& node.property?.name === 'env'
|
|
12
21
|
);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Builds a regex that matches a documentation table row for the given env variable name.
|
|
25
|
+
* @param {string} propName - The environment variable name to search for.
|
|
26
|
+
* @returns {RegExp} A multiline, global, unicode regex with two capture groups:
|
|
27
|
+
* (1) the variable name and (2) the description cell content.
|
|
28
|
+
*/
|
|
13
29
|
const regular = propName => new RegExp(
|
|
14
|
-
`^ \\* \\| (${propName.replace(/[|\\{}()[\]^$+*?.]/gu, '\\$&')}) \\| *([
|
|
30
|
+
`^ \\* \\| (${propName.replace(/[|\\{}()[\]^$+*?.]/gu, '\\$&')}) \\| *([^|]*)`,
|
|
15
31
|
'mgu',
|
|
16
32
|
);
|
|
17
|
-
const extractEnvVarName = (node, context) => node.parent?.property?.name
|
|
18
|
-
|| context.getSourceCode().text.slice(node.parent.property.start, node.parent.property.end);
|
|
19
|
-
const findEnvDocInComments = (comments, propName) => {
|
|
20
|
-
const regex = regular(propName);
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Extracts the environment variable name from a `process.env.X` or `process.env['X']` access.
|
|
36
|
+
* For computed access with a non-literal key (e.g. `process.env[varName]`), falls back to
|
|
37
|
+
* extracting the source text of the computed expression.
|
|
38
|
+
* @param {Object} node - The `process.env` MemberExpression node.
|
|
39
|
+
* @param {Object} context - The ESLint rule context.
|
|
40
|
+
* @returns {string|undefined} The env variable name, or `undefined` if the property node is missing.
|
|
41
|
+
*/
|
|
42
|
+
const extractEnvVarName = (node, context) => {
|
|
43
|
+
const prop = node.parent?.property;
|
|
44
|
+
|
|
45
|
+
if (!prop) return undefined;
|
|
46
|
+
if (prop.name) return prop.name;
|
|
47
|
+
if (prop.value) return String(prop.value);
|
|
48
|
+
|
|
49
|
+
return context.sourceCode.text.slice(prop.range[FIRST], prop.range[SINGLE]);
|
|
28
50
|
};
|
|
29
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Finds block comments that contain a documentation table entry for the given env variable.
|
|
54
|
+
* @param {Array.<Object>} comments - All comments in the source file.
|
|
55
|
+
* @param {RegExp} regex - The regex to match the env variable documentation row.
|
|
56
|
+
* @returns {Array.<Object>} Matching block comments.
|
|
57
|
+
*/
|
|
58
|
+
const findEnvDocInComments = (comments, regex) => comments.filter(comment =>
|
|
59
|
+
comment.type === 'Block'
|
|
60
|
+
&& comment.value.includes(HEADER)
|
|
61
|
+
&& comment.value.includes(LINE)
|
|
62
|
+
&& comment.value.match(regex),
|
|
63
|
+
);
|
|
64
|
+
|
|
30
65
|
const plugin = {
|
|
66
|
+
meta: {
|
|
67
|
+
name,
|
|
68
|
+
version,
|
|
69
|
+
},
|
|
31
70
|
rules: {
|
|
32
71
|
'validate-document-env': {
|
|
33
72
|
create(context) {
|
|
34
|
-
const { comments } = context.
|
|
73
|
+
const { comments } = context.sourceCode.ast;
|
|
35
74
|
|
|
36
75
|
return {
|
|
37
76
|
MemberExpression(node) {
|
|
38
77
|
if (!isProcessEnvAccess(node) || !node.parent?.property) return;
|
|
39
78
|
|
|
40
79
|
const propName = extractEnvVarName(node, context);
|
|
41
|
-
const matchedComment = findEnvDocInComments(comments, propName);
|
|
42
80
|
|
|
43
|
-
if (!
|
|
81
|
+
if (!propName) return;
|
|
82
|
+
const regex = regular(propName);
|
|
83
|
+
const matchedComment = findEnvDocInComments(comments, regex);
|
|
84
|
+
|
|
85
|
+
if (matchedComment.length === EMPTY) {
|
|
44
86
|
context.report({
|
|
45
87
|
node,
|
|
46
88
|
messageId: 'unDocumentedProcessEnv',
|
|
@@ -56,7 +98,6 @@ const plugin = {
|
|
|
56
98
|
});
|
|
57
99
|
return;
|
|
58
100
|
}
|
|
59
|
-
const regex = regular(propName);
|
|
60
101
|
let match = matchedComment[FIRST].value.match(regex);
|
|
61
102
|
|
|
62
103
|
if (match?.length > SINGLE) {
|
|
@@ -68,7 +109,7 @@ const plugin = {
|
|
|
68
109
|
}
|
|
69
110
|
else {
|
|
70
111
|
match = regex.exec(matchedComment[FIRST].value);
|
|
71
|
-
if (!match[NO_DESCRIPTION]) {
|
|
112
|
+
if (!match || !match[NO_DESCRIPTION]) {
|
|
72
113
|
context.report({
|
|
73
114
|
node,
|
|
74
115
|
messageId: 'unDescribedProcessEnv',
|
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mimik/eslint-plugin-document-env",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"description": "validation of environment variable documentation",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"exports": "./index.js",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=24.0.0"
|
|
10
|
+
},
|
|
7
11
|
"scripts": {
|
|
12
|
+
"docs": "jsdoc2md --template docs/README.hbs index.js > README.md",
|
|
8
13
|
"lint": "eslint . --no-error-on-unmatched-pattern",
|
|
9
|
-
"test": "
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"hooks": {
|
|
14
|
-
"pre-commit": "npm run commit-ready",
|
|
15
|
-
"pre-push": "npm run test"
|
|
16
|
-
}
|
|
14
|
+
"test": "mocha --reporter mochawesome --bail --exit --check-leaks test/",
|
|
15
|
+
"test-ci": "c8 --reporter=lcov --reporter=text npm test",
|
|
16
|
+
"prepublishOnly": "npm run docs && npm run lint && npm run test-ci",
|
|
17
|
+
"commit-ready": "npm run docs && npm run lint && npm run test-ci"
|
|
17
18
|
},
|
|
18
19
|
"keywords": [
|
|
19
20
|
"mimik",
|
|
@@ -29,10 +30,15 @@
|
|
|
29
30
|
"url": "git+https://bitbucket.org/mimiktech/eslint-plugin-document-env.git"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
|
-
"@eslint/js": "9.
|
|
33
|
-
"@stylistic/eslint-plugin": "5.
|
|
34
|
-
"
|
|
33
|
+
"@eslint/js": "9.39.4",
|
|
34
|
+
"@stylistic/eslint-plugin": "5.10.0",
|
|
35
|
+
"c8": "11.0.0",
|
|
36
|
+
"eslint": "9.39.4",
|
|
35
37
|
"eslint-plugin-import": "2.32.0",
|
|
36
|
-
"
|
|
38
|
+
"globals": "17.4.0",
|
|
39
|
+
"husky": "9.1.7",
|
|
40
|
+
"jsdoc-to-markdown": "9.1.3",
|
|
41
|
+
"mocha": "11.7.5",
|
|
42
|
+
"mochawesome": "7.1.4"
|
|
37
43
|
}
|
|
38
44
|
}
|
package/eslint.config.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import importPlugin from 'eslint-plugin-import';
|
|
2
|
-
import js from '@eslint/js';
|
|
3
|
-
import stylistic from '@stylistic/eslint-plugin';
|
|
4
|
-
|
|
5
|
-
const MAX_LENGTH_LINE = 180;
|
|
6
|
-
const MAX_FUNCTION_PARAMETERS = 6;
|
|
7
|
-
const MAX_LINES_IN_FILES = 600;
|
|
8
|
-
const MAX_LINES_IN_FUNCTION = 150;
|
|
9
|
-
const MAX_STATEMENTS_IN_FUNCTION = 45;
|
|
10
|
-
const MIN_KEYS_IN_OBJECT = 10;
|
|
11
|
-
const MAX_COMPLEXITY = 30;
|
|
12
|
-
|
|
13
|
-
export default [
|
|
14
|
-
{
|
|
15
|
-
ignores: ['mochawesome-report/**', 'node_modules/**', 'dist/**'],
|
|
16
|
-
},
|
|
17
|
-
importPlugin.flatConfigs.recommended,
|
|
18
|
-
stylistic.configs['recommended-flat'],
|
|
19
|
-
js.configs.all,
|
|
20
|
-
{
|
|
21
|
-
languageOptions: {
|
|
22
|
-
ecmaVersion: 2022,
|
|
23
|
-
globals: {
|
|
24
|
-
console: 'readonly',
|
|
25
|
-
describe: 'readonly',
|
|
26
|
-
it: 'readonly',
|
|
27
|
-
require: 'readonly',
|
|
28
|
-
},
|
|
29
|
-
sourceType: 'module',
|
|
30
|
-
},
|
|
31
|
-
rules: {
|
|
32
|
-
'@stylistic/brace-style': ['warn', 'stroustrup', { allowSingleLine: true }],
|
|
33
|
-
'@stylistic/line-comment-position': ['off'],
|
|
34
|
-
'@stylistic/semi': ['error', 'always'],
|
|
35
|
-
'capitalized-comments': ['off'],
|
|
36
|
-
'complexity': ['error', MAX_COMPLEXITY],
|
|
37
|
-
'curly': ['off'],
|
|
38
|
-
'id-length': ['error', { exceptions: ['x', 'y', 'z', 'i', 'j', 'k'] }],
|
|
39
|
-
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
|
|
40
|
-
'import/no-unresolved': ['error', { amd: true, caseSensitiveStrict: true, commonjs: true }],
|
|
41
|
-
'init-declarations': ['off'],
|
|
42
|
-
'linebreak-style': ['off'],
|
|
43
|
-
'max-len': ['warn', MAX_LENGTH_LINE, { ignoreComments: true }],
|
|
44
|
-
'max-lines': ['warn', { max: MAX_LINES_IN_FILES, skipComments: true }],
|
|
45
|
-
'max-lines-per-function': ['warn', { max: MAX_LINES_IN_FUNCTION, skipComments: true }],
|
|
46
|
-
'max-params': ['error', MAX_FUNCTION_PARAMETERS],
|
|
47
|
-
'max-statements': ['warn', MAX_STATEMENTS_IN_FUNCTION],
|
|
48
|
-
'no-confusing-arrow': ['off'], // arrow isnt confusing
|
|
49
|
-
'no-inline-comments': ['off'],
|
|
50
|
-
'no-process-env': ['error'],
|
|
51
|
-
'no-ternary': ['off'],
|
|
52
|
-
'no-undefined': ['off'],
|
|
53
|
-
'one-var': ['error', 'never'],
|
|
54
|
-
'quotes': ['warn', 'single'],
|
|
55
|
-
'sort-keys': ['error', 'asc', { caseSensitive: true, minKeys: MIN_KEYS_IN_OBJECT, natural: false }],
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
];
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { RuleTester } from 'eslint';
|
|
2
|
-
import rule from '../index.js';
|
|
3
|
-
|
|
4
|
-
const tester = new RuleTester({
|
|
5
|
-
languageOptions: { ecmaVersion: 2022, sourceType: 'module' },
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
tester.run('validate-document-env', rule.rules['validate-document-env'], {
|
|
9
|
-
valid: [
|
|
10
|
-
{
|
|
11
|
-
code: `
|
|
12
|
-
/**
|
|
13
|
-
* | Env variable name | Description | Default | Comments |
|
|
14
|
-
* | ----------------- | ----------- | ------- | -------- |
|
|
15
|
-
* | MY_VAR | when existent on non null, will translate an IPV6 address into IPV4 address when possible | |
|
|
16
|
-
*/
|
|
17
|
-
const v = process.env.MY_VAR;
|
|
18
|
-
`,
|
|
19
|
-
},
|
|
20
|
-
],
|
|
21
|
-
invalid: [
|
|
22
|
-
{
|
|
23
|
-
code: `
|
|
24
|
-
const v = process.env.UNDOCUMENTED_VAR;
|
|
25
|
-
`,
|
|
26
|
-
errors: [{ messageId: 'unDocumentedProcessEnv' }],
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
code: `
|
|
30
|
-
/**
|
|
31
|
-
* | Env variable name | Description | Default | Comments |
|
|
32
|
-
* | ----------------- | ----------- | ------- | -------- |
|
|
33
|
-
* | UNDESCRIBED_VAR | | none | - |
|
|
34
|
-
*/
|
|
35
|
-
const v = process.env.UNDESCRIBED_VAR;
|
|
36
|
-
`,
|
|
37
|
-
errors: [{ messageId: 'unDescribedProcessEnv' }],
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
code: `
|
|
41
|
-
/**
|
|
42
|
-
* | Env variable name | Description | Default | Comments |
|
|
43
|
-
* | ----------------- | ----------- | ------- | -------- |
|
|
44
|
-
* | DUP_VAR | a | none | - |
|
|
45
|
-
*/
|
|
46
|
-
const separation = 'test';
|
|
47
|
-
/**
|
|
48
|
-
* | Env variable name | Description | Default | Comments |
|
|
49
|
-
* | ----------------- | ----------- | ------- | -------- |
|
|
50
|
-
* | DUP_VAR | b | none | - |
|
|
51
|
-
*/
|
|
52
|
-
const v = process.env.DUP_VAR;
|
|
53
|
-
`,
|
|
54
|
-
errors: [{ messageId: 'duplicatedProcessEnv' }],
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
code: `
|
|
58
|
-
/**
|
|
59
|
-
* | Env variable name | Description | Default | Comments |
|
|
60
|
-
* | ----------------- | ----------- | ------- | -------- |
|
|
61
|
-
* | DUP_VAR | a | none | - |
|
|
62
|
-
* | DUP_VAR | b | none | - |
|
|
63
|
-
*/
|
|
64
|
-
const v = process.env.DUP_VAR;
|
|
65
|
-
`,
|
|
66
|
-
errors: [{ messageId: 'duplicatedProcessEnv' }],
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
});
|