isml-linter 5.41.0 → 5.42.1
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 +27 -8
- package/README.md +4 -2
- package/package.json +1 -1
- package/scaffold_files/ismllinter.config.js +1 -0
- package/src/IsmlLinter.js +3 -3
- package/src/isml_tree/IsmlNode.js +26 -16
- package/src/isml_tree/ParseUtils.js +2 -1
- package/src/isml_tree/TreeBuilder.js +12 -12
- package/src/publicApi.js +1 -1
- package/src/rules/line_by_line/max-lines.js +2 -2
- package/src/rules/line_by_line/no-space-only-lines.js +4 -4
- package/src/rules/line_by_line/no-tabs.js +3 -1
- package/src/rules/line_by_line/no-trailing-spaces.js +4 -5
- package/src/rules/prototypes/SingleLineRulePrototype.js +4 -4
- package/src/rules/prototypes/TreeRulePrototype.js +0 -16
- package/src/rules/tree/eslint-to-isscript.js +1 -2
- package/src/rules/tree/indent.js +7 -0
- package/src/rules/tree/leading-iscache.js +1 -2
- package/src/rules/tree/leading-iscontent.js +1 -2
- package/src/rules/tree/no-iselse-slash.js +1 -2
- package/src/rules/tree/one-element-per-line.js +1 -2
- package/src/rules/tree/strict-void-elements.js +46 -0
- package/src/util/ConsoleUtils.js +6 -4
- package/src/util/GeneralUtils.js +41 -1
- package/src/util/RuleUtils.js +15 -16
- package/src/util/TempRuleUtils.js +11 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.42.1] - 2023-01-28
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Keep template original linebreak if one is not explictly set in the ISML Linter configuration file. It was forcing a Unix linebreak;
|
|
7
|
+
|
|
8
|
+
## [5.42.0] - 2023-01-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Introducing ["strict-void-elements" rule][strict-void-elements-readme];
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Allow Closing Tags for Void Elements in AST. "strict-void-elements" rule will optionally handle that invalid scenario;
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- "indent" Rule - Add "line" Attribute to Quote Issue Report;
|
|
18
|
+
|
|
3
19
|
## [5.41.0] - 2023-01-21
|
|
4
20
|
|
|
5
21
|
### Added
|
|
@@ -1048,6 +1064,8 @@
|
|
|
1048
1064
|
### Added
|
|
1049
1065
|
- Linter is published;
|
|
1050
1066
|
|
|
1067
|
+
[5.42.1]: https://github.com/FabiowQuixada/isml-linter/compare/v5.42.0...v5.42.1
|
|
1068
|
+
[5.42.0]: https://github.com/FabiowQuixada/isml-linter/compare/v5.41.0...v5.42.0
|
|
1051
1069
|
[5.41.0]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.5...v5.41.0
|
|
1052
1070
|
[5.40.5]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.4...v5.40.5
|
|
1053
1071
|
[5.40.4]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.3...v5.40.4
|
|
@@ -1211,11 +1229,12 @@
|
|
|
1211
1229
|
[api-docs]: <docs/api.md>
|
|
1212
1230
|
[license]: <LICENSE>
|
|
1213
1231
|
|
|
1214
|
-
[
|
|
1215
|
-
[
|
|
1216
|
-
[no-
|
|
1217
|
-
[no-
|
|
1218
|
-
[
|
|
1219
|
-
[
|
|
1220
|
-
[
|
|
1221
|
-
[
|
|
1232
|
+
[strict-void-elements-readme]: <docs/rules/strict-void-elements.md>
|
|
1233
|
+
[disallow-tags-readme]: <docs/rules/disallow-tags.md>
|
|
1234
|
+
[no-br-readme]: <docs/rules/no-br.md>
|
|
1235
|
+
[no-inline-style-readme]: <docs/rules/no-br.md>
|
|
1236
|
+
[no-isscript-readme]: <docs/rules/no-isscript.md>
|
|
1237
|
+
[enforce-security-readme]: <docs/rules/enforce-security.md>
|
|
1238
|
+
[no-hardcode-readme]: <docs/rules/no-hardcode.md>
|
|
1239
|
+
[indent-readme]: <docs/rules/indent.md>
|
|
1240
|
+
[eslint-to-isscript-readme]: <docs/rules/eslint-to-isscript.md>
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ ISML Linter is a tool for examining if your project's templates follow a specifi
|
|
|
3
3
|
|
|
4
4
|
- Styles that are defined by your team;
|
|
5
5
|
- Syntactic errors related to `<is* >` tags;
|
|
6
|
-
- Coding conventions recommended by
|
|
6
|
+
- Coding conventions recommended by Salesforce;
|
|
7
7
|
- Git conflicts that may accidentally be left unresolved;
|
|
8
8
|
|
|
9
9
|
Please feel free to make suggestions and help make this linter better. :) The set of currently available rules can be found below.
|
|
@@ -161,7 +161,7 @@ Please check the [Generic Configurations for Rules][generic-rule-config] page.
|
|
|
161
161
|
| ------------------------------------------------------------------------------------ |:-----------------------------------------|
|
|
162
162
|
| :exclamation: [no-br][no-br-readme] | <span style="color:orange">[Deprecated]</span> Disallows `<br/>` tags. Enable this rule if you prefer to use CSS to handle vertical spacing |
|
|
163
163
|
| [no-git-conflict][no-git-conflict-readme] | Disallows unresolved Git conflicts |
|
|
164
|
-
| [no-import-package][no-import-package-readme] | Disallows `importPackage()` function. It is recommended by
|
|
164
|
+
| [no-import-package][no-import-package-readme] | Disallows `importPackage()` function. It is recommended by Salesforce to use `require()` instead |
|
|
165
165
|
| :exclamation: [no-isscript][no-isscript-readme] | <span style="color:orange">[Deprecated]</span> Disallows `<isscript/>` tag in template. Enable this rule if you prefer logic to be kept in a separate .ds/.js file |
|
|
166
166
|
| :wrench: [no-trailing-spaces][no-trailing-spaces-readme] | Disallows trailing blank spaces |
|
|
167
167
|
| :wrench: [no-space-only-lines][no-space-only-lines-readme] | Disallows lines that contain only blank spaces, i.e., unnecessarily indented |
|
|
@@ -189,6 +189,7 @@ Please check the [Generic Configurations for Rules][generic-rule-config] page.
|
|
|
189
189
|
| :small_orange_diamond: [align-isset][align-isset-readme] | Aligns contiguous `<isset>` tags attributes' columns |
|
|
190
190
|
| :small_orange_diamond: [enforce-security][enforce-security-readme] | Enforces security measures |
|
|
191
191
|
| :wrench: :small_orange_diamond: [no-redundant-context][no-redundant-context-readme] | Prevents use of unnecessary contexts, such as `dw.web.Resource` |
|
|
192
|
+
| :small_orange_diamond: [strict-void-elements][strict-void-elements-readme] | Disallows closing tags for void elements, such as `<input>` and `<img>` |
|
|
192
193
|
|
|
193
194
|
You are more than welcome to contribute with us! Please check the [contribute section][contribute-docs].
|
|
194
195
|
|
|
@@ -235,6 +236,7 @@ This project was conceived by its author without any financial support, with the
|
|
|
235
236
|
[disallow-tags-readme]: <docs/rules/disallow-tags.md>
|
|
236
237
|
[enforce-security-readme]: <docs/rules/enforce-security.md>
|
|
237
238
|
[no-redundant-context-readme]: <docs/rules/no-redundant-context.md>
|
|
239
|
+
[strict-void-elements-readme]: <docs/rules/strict-void-elements.md>
|
|
238
240
|
|
|
239
241
|
[api-docs]: <docs/api.md>
|
|
240
242
|
[cli-docs]: <docs/cli.md>
|
package/package.json
CHANGED
package/src/IsmlLinter.js
CHANGED
|
@@ -101,12 +101,12 @@ const getEmptyResult = () => {
|
|
|
101
101
|
};
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
-
const
|
|
104
|
+
const parseAndPossiblyFixTemplate = (templatePath, data, content, templateName) => {
|
|
105
105
|
const formattedTemplatePath = GeneralUtils.formatTemplatePath(templatePath);
|
|
106
106
|
const templateResults = getEmptyResult();
|
|
107
107
|
|
|
108
108
|
try {
|
|
109
|
-
const parseResult = RuleUtils.
|
|
109
|
+
const parseResult = RuleUtils.parseAndPossiblyFixTemplate(templatePath, data, content, templateName);
|
|
110
110
|
|
|
111
111
|
if (parseResult.fixed) {
|
|
112
112
|
templateResults.templatesFixed++;
|
|
@@ -232,7 +232,7 @@ Linter.run = (pathData, content, data = {}) => {
|
|
|
232
232
|
const isIgnored = FileUtils.isIgnored(templatePath);
|
|
233
233
|
|
|
234
234
|
if (!isIgnored) {
|
|
235
|
-
const templateResults =
|
|
235
|
+
const templateResults = parseAndPossiblyFixTemplate(templatePath, data, content, templateName);
|
|
236
236
|
|
|
237
237
|
finalResult = merge(finalResult, templateResults);
|
|
238
238
|
}
|
|
@@ -6,6 +6,7 @@ const SfccTagContainer = require('../enums/SfccTagContainer');
|
|
|
6
6
|
const ParseUtils = require('./ParseUtils');
|
|
7
7
|
const MaskUtils = require('./MaskUtils');
|
|
8
8
|
const ExceptionUtils = require('../util/ExceptionUtils');
|
|
9
|
+
const GeneralUtils = require('../util/GeneralUtils');
|
|
9
10
|
|
|
10
11
|
let ID_COUNTER = 0;
|
|
11
12
|
|
|
@@ -149,6 +150,7 @@ class IsmlNode {
|
|
|
149
150
|
newNode.isEmbeddedNode = this.isEmbeddedNode;
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
getChild(number) { return this.children[number]; }
|
|
152
154
|
getLastChild() { return this.children[this.children.length - 1]; }
|
|
153
155
|
getChildrenQty() { return this.children.length; }
|
|
154
156
|
hasChildren() { return this.children.length > 0; }
|
|
@@ -382,24 +384,11 @@ class IsmlNode {
|
|
|
382
384
|
return rootNode;
|
|
383
385
|
}
|
|
384
386
|
|
|
385
|
-
toString(
|
|
387
|
+
toString() {
|
|
386
388
|
|
|
387
|
-
|
|
388
|
-
return stream;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (!this.isRoot() && !this.isContainer()) {
|
|
392
|
-
stream += this.head;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
for (let i = 0; i < this.children.length; i++) {
|
|
396
|
-
const child = this.children[i];
|
|
397
|
-
stream = child.toString(stream);
|
|
398
|
-
}
|
|
389
|
+
let stream = privateToString(this);
|
|
399
390
|
|
|
400
|
-
|
|
401
|
-
stream += this.tail;
|
|
402
|
-
}
|
|
391
|
+
stream = GeneralUtils.applyLineBreak(stream, this.getRoot().tree.originalLineBreak);
|
|
403
392
|
|
|
404
393
|
return stream;
|
|
405
394
|
}
|
|
@@ -428,6 +417,27 @@ class IsmlNode {
|
|
|
428
417
|
* will be available for use only within IsmlNode methods;
|
|
429
418
|
*/
|
|
430
419
|
|
|
420
|
+
const privateToString = (node, stream = '') => {
|
|
421
|
+
if (!node.isContainer() && node.isEmpty() && !node.isLastChild()) {
|
|
422
|
+
return stream;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (!node.isRoot() && !node.isContainer()) {
|
|
426
|
+
stream += node.head;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
430
|
+
const child = node.children[i];
|
|
431
|
+
stream = privateToString(child, stream);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (!node.isRoot() && !node.isContainer()) {
|
|
435
|
+
stream += node.tail;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return stream;
|
|
439
|
+
};
|
|
440
|
+
|
|
431
441
|
const getAttributes = node => {
|
|
432
442
|
const trimmedHead = node.head.trim();
|
|
433
443
|
const nodeHead = trimmedHead.substring(1, trimmedHead.length - 1);
|
|
@@ -136,7 +136,7 @@ const parseNextElement = state => {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
state.elementList.push(newElement);
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
if (newElement.type === 'htmlTag' && newElement.value.indexOf('<isif') >= 0 && newElement.value.indexOf('</isif') < 0) {
|
|
141
141
|
throw ExceptionUtils.invalidNestedIsifError(
|
|
142
142
|
newElement.tagType,
|
|
@@ -275,6 +275,7 @@ const getNextClosingTagOrExpressionEndPos = content => {
|
|
|
275
275
|
};
|
|
276
276
|
|
|
277
277
|
const getInitialState = (templateContent, templatePath, isCrlfLineBreak) => {
|
|
278
|
+
// TODO Check if "GeneralUtils.toLF" can be removed;
|
|
278
279
|
const originalContent = GeneralUtils.toLF(templateContent);
|
|
279
280
|
const originalShadowContent = MaskUtils.maskIgnorableContent(originalContent, null, templatePath);
|
|
280
281
|
|
|
@@ -32,6 +32,10 @@ const parse = (content, templatePath, isCrlfLineBreak, isEmbeddedNode) => {
|
|
|
32
32
|
|
|
33
33
|
ParseUtils.checkBalance(rootNode, templatePath);
|
|
34
34
|
|
|
35
|
+
rootNode.tree = {
|
|
36
|
+
originalLineBreak : GeneralUtils.getFileLineBreakStyle(content),
|
|
37
|
+
};
|
|
38
|
+
|
|
35
39
|
return rootNode;
|
|
36
40
|
};
|
|
37
41
|
|
|
@@ -110,14 +114,8 @@ const parseContainerElements = (element, currentParent, newNode, templatePath) =
|
|
|
110
114
|
|
|
111
115
|
const parseNonContainerElements = (element, currentParent, newNode, templatePath) => {
|
|
112
116
|
if (element.isSelfClosing) {
|
|
113
|
-
if (element.isClosingTag
|
|
114
|
-
|
|
115
|
-
element.tagType,
|
|
116
|
-
element.lineNumber,
|
|
117
|
-
element.globalPos,
|
|
118
|
-
element.value.trim().length,
|
|
119
|
-
templatePath
|
|
120
|
-
);
|
|
117
|
+
if (element.isClosingTag && element.isVoidElement) {
|
|
118
|
+
currentParent.getLastChild().setTail(element.value, element.lineNumber, element.columnNumber, element.globalPos);
|
|
121
119
|
} else {
|
|
122
120
|
currentParent.addChild(newNode);
|
|
123
121
|
}
|
|
@@ -209,15 +207,17 @@ const build = (templatePath, content, isCrlfLineBreak) => {
|
|
|
209
207
|
|
|
210
208
|
const ParseStatus = require('../enums/ParseStatus');
|
|
211
209
|
|
|
212
|
-
const
|
|
210
|
+
const templateContent = content || fs.readFileSync(templatePath, 'utf-8');
|
|
211
|
+
const result = {
|
|
212
|
+
originalLineBreak : GeneralUtils.getFileLineBreakStyle(templateContent),
|
|
213
213
|
templatePath,
|
|
214
214
|
status : ParseStatus.NO_ERRORS
|
|
215
215
|
};
|
|
216
216
|
|
|
217
217
|
try {
|
|
218
|
-
const
|
|
219
|
-
result.rootNode
|
|
220
|
-
result.data
|
|
218
|
+
const formattedTemplateContent = templateContent;
|
|
219
|
+
result.rootNode = parse(formattedTemplateContent, templatePath, isCrlfLineBreak);
|
|
220
|
+
result.data = postProcess(result.rootNode);
|
|
221
221
|
|
|
222
222
|
result.rootNode.tree = result;
|
|
223
223
|
|
package/src/publicApi.js
CHANGED
|
@@ -24,7 +24,7 @@ module.exports = {
|
|
|
24
24
|
autofixConfig.autoFix = true;
|
|
25
25
|
IsmlLinter.setConfig(autofixConfig);
|
|
26
26
|
} else {
|
|
27
|
-
autofixConfig
|
|
27
|
+
autofixConfig = IsmlLinter.getConfig();
|
|
28
28
|
autofixConfig.autoFix = true;
|
|
29
29
|
IsmlLinter.setConfig(autofixConfig);
|
|
30
30
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const SingleLineRulePrototype = require('../prototypes/SingleLineRulePrototype');
|
|
2
|
-
const Constants = require('../../Constants');
|
|
3
2
|
const GeneralUtils = require('../../util/GeneralUtils');
|
|
4
3
|
|
|
5
4
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
@@ -21,8 +20,9 @@ Rule.getColumnNumber = function() {
|
|
|
21
20
|
|
|
22
21
|
Rule.check = function(templateContent) {
|
|
23
22
|
|
|
23
|
+
const lineBreak = GeneralUtils.getFileLineBreakStyle(templateContent);
|
|
24
24
|
const maxLines = this.getConfigs().max;
|
|
25
|
-
const lineArray =
|
|
25
|
+
const lineArray = templateContent.split(lineBreak);
|
|
26
26
|
const columnNumber = this.getColumnNumber();
|
|
27
27
|
const occurrenceList = [];
|
|
28
28
|
|
|
@@ -17,9 +17,9 @@ Rule.getColumnNumber = function() {
|
|
|
17
17
|
Rule.getFixedContent = function(templateContent) {
|
|
18
18
|
const GeneralUtils = require('../../util/GeneralUtils');
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
const lineArray
|
|
22
|
-
const result
|
|
20
|
+
const lineBreak = GeneralUtils.getFileLineBreakStyle(templateContent);
|
|
21
|
+
const lineArray = templateContent.split(lineBreak);
|
|
22
|
+
const result = [];
|
|
23
23
|
|
|
24
24
|
for (let i = 0; i < lineArray.length; i++) {
|
|
25
25
|
const line = lineArray[i];
|
|
@@ -27,7 +27,7 @@ Rule.getFixedContent = function(templateContent) {
|
|
|
27
27
|
result.push(line.trim() ? line : line.trim());
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
return result.join(
|
|
30
|
+
return GeneralUtils.applyLineBreak(result.join(lineBreak));
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
Rule.getFirstOccurrence = function(line) {
|
|
@@ -16,9 +16,11 @@ Rule.getColumnNumber = function(line) {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
Rule.getFixedContent = function(templateContent) {
|
|
19
|
+
const lineBreak = GeneralUtils.getFileLineBreakStyle(templateContent);
|
|
19
20
|
const indent = IndentRule.getIndentation();
|
|
20
21
|
const fixedContent = templateContent.replace(/\t/g, indent);
|
|
21
|
-
|
|
22
|
+
|
|
23
|
+
return GeneralUtils.applyLineBreak(fixedContent, lineBreak);
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
Rule.getFirstOccurrence = function(line) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const SingleLineRulePrototype = require('../prototypes/SingleLineRulePrototype');
|
|
2
|
-
const Constants = require('../../Constants');
|
|
3
2
|
const ParseUtils = require('../../isml_tree/ParseUtils');
|
|
4
3
|
|
|
5
4
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
@@ -19,9 +18,9 @@ Rule.getColumnNumber = function(line) {
|
|
|
19
18
|
Rule.getFixedContent = function(templateContent) {
|
|
20
19
|
const GeneralUtils = require('../../util/GeneralUtils');
|
|
21
20
|
|
|
22
|
-
const
|
|
23
|
-
const lineArray
|
|
24
|
-
const result
|
|
21
|
+
const lineBreak = GeneralUtils.getFileLineBreakStyle(templateContent);
|
|
22
|
+
const lineArray = templateContent.split(lineBreak);
|
|
23
|
+
const result = [];
|
|
25
24
|
|
|
26
25
|
for (let i = 0; i < lineArray.length; i++) {
|
|
27
26
|
const line = lineArray[i];
|
|
@@ -29,7 +28,7 @@ Rule.getFixedContent = function(templateContent) {
|
|
|
29
28
|
result.push(line.replace(/\s+$/g, ''));
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
return result.join(
|
|
31
|
+
return GeneralUtils.applyLineBreak(result.join(lineBreak), lineBreak);
|
|
33
32
|
};
|
|
34
33
|
|
|
35
34
|
Rule.getFirstOccurrence = function(line) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
const RulePrototype = require('./RulePrototype');
|
|
2
2
|
const ConfigUtils = require('../../util/ConfigUtils');
|
|
3
|
-
const Constants = require('../../Constants');
|
|
4
3
|
const GeneralUtils = require('../../util/GeneralUtils');
|
|
5
4
|
|
|
6
5
|
const SingleLineRulePrototype = Object.create(RulePrototype);
|
|
7
6
|
|
|
8
7
|
SingleLineRulePrototype.check = function(templateContent, data = { isCrlfLineBreak : false }) {
|
|
9
8
|
|
|
9
|
+
const lineBreak = GeneralUtils.getFileLineBreakStyle(templateContent);
|
|
10
10
|
const config = ConfigUtils.load();
|
|
11
|
-
const lineArray =
|
|
11
|
+
const lineArray = templateContent.split(lineBreak);
|
|
12
12
|
const occurrenceList = [];
|
|
13
13
|
let globalPos = 0;
|
|
14
14
|
|
|
@@ -41,10 +41,10 @@ SingleLineRulePrototype.check = function(templateContent, data = { isCrlfLineBre
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
return {
|
|
44
|
+
return {
|
|
45
45
|
occurrenceList,
|
|
46
46
|
fixedContent : templateContent
|
|
47
|
-
|
|
47
|
+
};
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
module.exports = SingleLineRulePrototype;
|
|
@@ -65,20 +65,4 @@ TreeRulePrototype.return = function(node, occurrenceList, config) {
|
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
-
TreeRulePrototype.fix = function(stream = '') {
|
|
69
|
-
|
|
70
|
-
if (!this.isRoot() && !this.isContainer()) {
|
|
71
|
-
stream += this.head;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
for (let i = 0; i < this.children.length; i++) {
|
|
75
|
-
const node = this.children[i];
|
|
76
|
-
stream = node.isBroken() ?
|
|
77
|
-
node.toString(stream) :
|
|
78
|
-
this.getFixedContent(node, stream);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return stream;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
68
|
module.exports = TreeRulePrototype;
|
|
@@ -2,7 +2,6 @@ const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
|
2
2
|
const ParseUtils = require('../../isml_tree/ParseUtils');
|
|
3
3
|
const Constants = require('../../Constants');
|
|
4
4
|
const ConfigUtils = require('../../util/ConfigUtils');
|
|
5
|
-
const GeneralUtils = require('../../util/GeneralUtils');
|
|
6
5
|
|
|
7
6
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
8
7
|
const description = 'Not eslint-valid';
|
|
@@ -121,7 +120,7 @@ Rule.getFixedContent = function(node) {
|
|
|
121
120
|
node.head = reIndent(content, ismlOffset);
|
|
122
121
|
}
|
|
123
122
|
|
|
124
|
-
return
|
|
123
|
+
return node.toString();
|
|
125
124
|
};
|
|
126
125
|
|
|
127
126
|
const unindent = (content, indentSize) => {
|
package/src/rules/tree/indent.js
CHANGED
|
@@ -161,8 +161,15 @@ Rule.isQuoteClosingCharBroken = function(node) {
|
|
|
161
161
|
'';
|
|
162
162
|
|
|
163
163
|
if (message) {
|
|
164
|
+
const lineBreak = node.getRoot().tree.originalLineBreak;
|
|
165
|
+
const line = node
|
|
166
|
+
.getRoot()
|
|
167
|
+
.toString()
|
|
168
|
+
.split(lineBreak)[lineNumber - 1];
|
|
169
|
+
|
|
164
170
|
result.push({
|
|
165
171
|
quoteChar : attribute.quoteChar,
|
|
172
|
+
line : line,
|
|
166
173
|
lineNumber : lineNumber,
|
|
167
174
|
columnNumber : columnNumber,
|
|
168
175
|
globalPos : globalPos,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
2
|
const RuleUtils = require('../../util/TempRuleUtils');
|
|
3
3
|
const Constants = require('../../Constants');
|
|
4
|
-
const GeneralUtils = require('../../util/GeneralUtils');
|
|
5
4
|
|
|
6
5
|
const TAG_TYPE = 'iscache';
|
|
7
6
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
@@ -33,7 +32,7 @@ Rule.getFixedContent = function(rootNode) {
|
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
return
|
|
35
|
+
return rootNode.toString();
|
|
37
36
|
};
|
|
38
37
|
|
|
39
38
|
module.exports = Rule;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
2
|
const Constants = require('../../Constants');
|
|
3
3
|
const RuleUtils = require('../../util/TempRuleUtils');
|
|
4
|
-
const GeneralUtils = require('../../util/GeneralUtils');
|
|
5
4
|
|
|
6
5
|
const TAG_TYPE = 'iscontent';
|
|
7
6
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
@@ -29,7 +28,7 @@ Rule.getFixedContent = function(rootNode) {
|
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
return
|
|
31
|
+
return rootNode.toString();
|
|
33
32
|
};
|
|
34
33
|
|
|
35
34
|
module.exports = Rule;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
2
|
const MaskUtils = require('../../isml_tree/MaskUtils');
|
|
3
|
-
const GeneralUtils = require('../../util/GeneralUtils');
|
|
4
3
|
|
|
5
4
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
6
5
|
const description = 'Slash is not allowed for "iselse" nor "iselseif" tags';
|
|
@@ -29,7 +28,7 @@ Rule.getFixedContent = function(node) {
|
|
|
29
28
|
this.getFixedContent(child);
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
return
|
|
31
|
+
return node.toString();
|
|
33
32
|
};
|
|
34
33
|
|
|
35
34
|
module.exports = Rule;
|
|
@@ -2,7 +2,6 @@ const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
|
2
2
|
const IndentRule = require('../tree/indent');
|
|
3
3
|
const ConfigUtils = require('../../util/ConfigUtils');
|
|
4
4
|
const Constants = require('../../Constants');
|
|
5
|
-
const GeneralUtils = require('../../util/GeneralUtils');
|
|
6
5
|
const TreeBuilder = require('../../isml_tree/TreeBuilder');
|
|
7
6
|
|
|
8
7
|
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
@@ -42,7 +41,7 @@ Rule.getFixedContent = rootNode => {
|
|
|
42
41
|
const newRootNode = TreeBuilder.build(null, stringifiedTree).rootNode;
|
|
43
42
|
const partialFixContent = IndentRule.getFixedContent(newRootNode);
|
|
44
43
|
|
|
45
|
-
return
|
|
44
|
+
return partialFixContent;
|
|
46
45
|
};
|
|
47
46
|
|
|
48
47
|
const addLineBreaks = node => {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const TreeRulePrototype = require('../prototypes/TreeRulePrototype');
|
|
2
|
+
|
|
3
|
+
const ruleId = require('path').basename(__filename).slice(0, -3);
|
|
4
|
+
const description = 'This is a void element, and as such, should not have a corresponding closing tag';
|
|
5
|
+
|
|
6
|
+
const Rule = Object.create(TreeRulePrototype);
|
|
7
|
+
|
|
8
|
+
Rule.init(ruleId, description);
|
|
9
|
+
|
|
10
|
+
Rule.isBroken = function(node) {
|
|
11
|
+
return node.isVoidElement() && node.tail.length > 0;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
Rule.check = function(node, data) {
|
|
15
|
+
|
|
16
|
+
const ruleConfig = this.getConfigs();
|
|
17
|
+
let occurrenceList = [];
|
|
18
|
+
|
|
19
|
+
occurrenceList = this.checkChildren(node, data);
|
|
20
|
+
|
|
21
|
+
if (this.isBroken(node)) {
|
|
22
|
+
const error = this.getError(
|
|
23
|
+
node.tail.trim(),
|
|
24
|
+
node.tailLineNumber,
|
|
25
|
+
node.tailColumnNumber,
|
|
26
|
+
node.tailGlobalPos,
|
|
27
|
+
node.tail.trim().length,
|
|
28
|
+
`"<${node.getType()}>" is a void element, and as such, should not have a corresponding closing tag`
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
occurrenceList.push(error);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return this.return(node, occurrenceList, ruleConfig);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
Rule.getFixedContent = node => {
|
|
38
|
+
|
|
39
|
+
if (node.isVoidElement()) {
|
|
40
|
+
node.setTail('', null, null, null);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return node.toString();
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
module.exports = Rule;
|
package/src/util/ConsoleUtils.js
CHANGED
|
@@ -126,6 +126,8 @@ const displayUnknownErrors = lintResult => {
|
|
|
126
126
|
return partialSum;
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
+
const getPluralTermString = (singularTerm, qty) => `${qty} ${singularTerm}${qty > 1 ? 's' : ''}`;
|
|
130
|
+
|
|
129
131
|
const displayOccurrenceList = lintResult => {
|
|
130
132
|
|
|
131
133
|
displayUnparseableErrors(lintResult);
|
|
@@ -148,19 +150,19 @@ const displayOccurrenceList = lintResult => {
|
|
|
148
150
|
console.log(Constants.EOL + chalk`{bold Linted ${lintResult.totalTemplatesQty} templates in ${lintResult.elapsedTime} seconds.}`);
|
|
149
151
|
|
|
150
152
|
if (occurrenceList.error.qty > 0) {
|
|
151
|
-
console.log(chalk`{bold ${occurrenceList.error.qty}
|
|
153
|
+
console.log(chalk`{bold ${getPluralTermString('error', occurrenceList.error.qty)} found.}`);
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
if (occurrenceList.warning.qty > 0) {
|
|
155
|
-
console.log(chalk`{bold ${occurrenceList.warning.qty}
|
|
157
|
+
console.log(chalk`{bold ${getPluralTermString('warning', occurrenceList.warning.qty)} found.}`);
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
if (occurrenceList.info.qty > 0) {
|
|
159
|
-
console.log(chalk`{bold ${occurrenceList.info.qty}
|
|
161
|
+
console.log(chalk`{bold ${getPluralTermString('info', occurrenceList.info.qty)} found.}`);
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
if (lintResult.INVALID_TEMPLATE && lintResult.INVALID_TEMPLATE.length > 0) {
|
|
163
|
-
console.log(chalk`{bold ${lintResult.INVALID_TEMPLATE.length}
|
|
165
|
+
console.log(chalk`{bold ${getPluralTermString('template', lintResult.INVALID_TEMPLATE.length)} have an invalid ISML tree.}`);
|
|
164
166
|
}
|
|
165
167
|
|
|
166
168
|
if (lintResult.UNKNOWN_ERROR && lintResult.UNKNOWN_ERROR.length > 0) {
|
package/src/util/GeneralUtils.js
CHANGED
|
@@ -34,12 +34,52 @@ const getActiveLineBreak = () => {
|
|
|
34
34
|
return configLineBreak || Constants.EOL;
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
const getFileLineBreakStyle = templateContent => {
|
|
38
|
+
const indexOfLF = templateContent.indexOf(Constants.lineBreak.unix, 1);
|
|
39
|
+
|
|
40
|
+
if (indexOfLF === -1) {
|
|
41
|
+
if (templateContent.indexOf('\r') !== -1) {
|
|
42
|
+
return '\r';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return Constants.lineBreak.unix;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (templateContent[indexOfLF - 1] === '\r') {
|
|
49
|
+
return Constants.lineBreak.windows;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return Constants.lineBreak.unix;
|
|
53
|
+
};
|
|
54
|
+
|
|
37
55
|
module.exports.formatTemplatePath = filePath => {
|
|
38
56
|
return filePath.replace(/\//g, path.sep);
|
|
39
57
|
};
|
|
40
58
|
|
|
41
59
|
module.exports.toLF = content => {
|
|
42
|
-
return content.replace(/\r\n/g,
|
|
60
|
+
return content.replace(/\r\n/g, Constants.lineBreak.unix);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
module.exports.getFileLineBreakStyle = getFileLineBreakStyle;
|
|
64
|
+
|
|
65
|
+
module.exports.applyLineBreak = (content, lineBreak) => {
|
|
66
|
+
const config = ConfigUtils.load();
|
|
67
|
+
const configLineBreak = config.linebreakStyle && Constants.lineBreak[config.linebreakStyle];
|
|
68
|
+
const templateHasWindowsLineBreak = content.indexOf(Constants.lineBreak.windows) >= 0;
|
|
69
|
+
|
|
70
|
+
if (configLineBreak) {
|
|
71
|
+
lineBreak = configLineBreak;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (lineBreak === Constants.lineBreak.windows && !templateHasWindowsLineBreak) {
|
|
75
|
+
return content
|
|
76
|
+
.replace(new RegExp(Constants.lineBreak.unix, 'g'), lineBreak);
|
|
77
|
+
} else if (lineBreak === Constants.lineBreak.unix && templateHasWindowsLineBreak) {
|
|
78
|
+
return content
|
|
79
|
+
.replace(new RegExp(Constants.lineBreak.windows, 'g'), lineBreak);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return content;
|
|
43
83
|
};
|
|
44
84
|
|
|
45
85
|
module.exports.applyActiveLineBreaks = content => {
|
package/src/util/RuleUtils.js
CHANGED
|
@@ -6,7 +6,6 @@ const ConfigUtils = require('./ConfigUtils');
|
|
|
6
6
|
const lowercaseFilenameRule = require('../rules/line_by_line/lowercase-filename');
|
|
7
7
|
const CustomTagContainer = require('./CustomTagContainer');
|
|
8
8
|
const CustomModulesRule = require('../rules/tree/custom-tags');
|
|
9
|
-
const GeneralUtils = require('./GeneralUtils');
|
|
10
9
|
const ConsoleUtils = require('./ConsoleUtils');
|
|
11
10
|
const ExceptionUtils = require('./ExceptionUtils');
|
|
12
11
|
|
|
@@ -64,7 +63,7 @@ const checkCustomTag = tag => {
|
|
|
64
63
|
}
|
|
65
64
|
};
|
|
66
65
|
|
|
67
|
-
const
|
|
66
|
+
const fixTemplateOrReportIssues = (config, ruleResult, templatePath, templateResults, rule) => {
|
|
68
67
|
if (config.autoFix && ruleResult.fixedContent) {
|
|
69
68
|
fs.writeFileSync(templatePath, ruleResult.fixedContent);
|
|
70
69
|
templateResults.fixed = true;
|
|
@@ -78,7 +77,7 @@ const applyRuleResult = (config, ruleResult, templatePath, templateResults, rule
|
|
|
78
77
|
}
|
|
79
78
|
};
|
|
80
79
|
|
|
81
|
-
const
|
|
80
|
+
const fixTemplateOrReportIssuesForRuleList = (ruleArray, templatePath, root, config, data) => {
|
|
82
81
|
const templateResults = {
|
|
83
82
|
fixed : false,
|
|
84
83
|
errors : {},
|
|
@@ -92,9 +91,9 @@ const applyRuleOnTemplate = (ruleArray, templatePath, root, config, data) => {
|
|
|
92
91
|
if (!rule.shouldIgnore(templatePath)) {
|
|
93
92
|
try {
|
|
94
93
|
ConsoleUtils.displayVerboseMessage(`Applying "${rule.id}" rule`, 1);
|
|
95
|
-
const ruleResults
|
|
94
|
+
const ruleResults = rule.check(root, templateResults.data);
|
|
96
95
|
templateResults.finalContent = ruleResults.fixedContent;
|
|
97
|
-
|
|
96
|
+
fixTemplateOrReportIssues(config, ruleResults, templatePath, templateResults, rule);
|
|
98
97
|
|
|
99
98
|
} catch (error) {
|
|
100
99
|
throw ExceptionUtils.ruleApplianceError(rule, error, templatePath);
|
|
@@ -112,10 +111,10 @@ const findNodeOfType = (node, type) => {
|
|
|
112
111
|
if (child.isOfType(type)) {
|
|
113
112
|
result = child;
|
|
114
113
|
return true;
|
|
115
|
-
} else {
|
|
116
|
-
result = findNodeOfType(child, type) || result;
|
|
117
114
|
}
|
|
118
115
|
|
|
116
|
+
result = findNodeOfType(child, type) || result;
|
|
117
|
+
|
|
119
118
|
return false;
|
|
120
119
|
});
|
|
121
120
|
|
|
@@ -170,7 +169,7 @@ const checkFileName = (filename, templateContent) => {
|
|
|
170
169
|
return templateResults;
|
|
171
170
|
};
|
|
172
171
|
|
|
173
|
-
const
|
|
172
|
+
const checkAndPossiblyFixTreeRules = (templatePath, templateContent, config, data) => {
|
|
174
173
|
if (!config.disableTreeParse) {
|
|
175
174
|
ConsoleUtils.displayVerboseMessage(`Building tree for "${templatePath}"`, 1);
|
|
176
175
|
const tree = TreeBuilder.build(templatePath, templateContent);
|
|
@@ -181,7 +180,7 @@ const checkTreeRules = (templatePath, templateContent, config, data) => {
|
|
|
181
180
|
|
|
182
181
|
const ruleArray = getEnabledTreeRules();
|
|
183
182
|
|
|
184
|
-
return
|
|
183
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
185
184
|
ruleArray,
|
|
186
185
|
templatePath,
|
|
187
186
|
tree.rootNode,
|
|
@@ -190,10 +189,10 @@ const checkTreeRules = (templatePath, templateContent, config, data) => {
|
|
|
190
189
|
}
|
|
191
190
|
};
|
|
192
191
|
|
|
193
|
-
const
|
|
192
|
+
const checkAndPossiblyFixLineByLineRules = (templatePath, templateContent, config, data) => {
|
|
194
193
|
const ruleArray = getEnabledLineRules();
|
|
195
194
|
|
|
196
|
-
return
|
|
195
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
197
196
|
ruleArray,
|
|
198
197
|
templatePath,
|
|
199
198
|
templateContent,
|
|
@@ -222,12 +221,12 @@ const checkCustomModules = () => {
|
|
|
222
221
|
return moduleResults;
|
|
223
222
|
};
|
|
224
223
|
|
|
225
|
-
const
|
|
224
|
+
const parseAndPossiblyFixTemplate = (templatePath, data, content = '', templateName = '') => {
|
|
226
225
|
ConsoleUtils.displayVerboseMessage(`\nChecking "${templatePath}" template`);
|
|
227
226
|
const config = ConfigUtils.load();
|
|
228
|
-
const templateContent =
|
|
229
|
-
const lineResults =
|
|
230
|
-
const treeResults =
|
|
227
|
+
const templateContent = content || fs.readFileSync(templatePath, 'utf-8');
|
|
228
|
+
const lineResults = checkAndPossiblyFixLineByLineRules(templatePath, templateContent, config, data);
|
|
229
|
+
const treeResults = checkAndPossiblyFixTreeRules(templatePath, lineResults.finalContent, config, data) || { errors : [] };
|
|
231
230
|
const filenameResults = checkFileName(templateName, templateContent);
|
|
232
231
|
|
|
233
232
|
return {
|
|
@@ -290,7 +289,7 @@ const getEnabledTreeRules = () => {
|
|
|
290
289
|
module.exports.getAllLineRules = () => lineByLineRules;
|
|
291
290
|
module.exports.findNodeOfType = findNodeOfType;
|
|
292
291
|
module.exports.isTypeAmongTheFirstElements = isTypeAmongTheFirstElements;
|
|
293
|
-
module.exports.
|
|
292
|
+
module.exports.parseAndPossiblyFixTemplate = parseAndPossiblyFixTemplate;
|
|
294
293
|
module.exports.checkCustomModules = checkCustomModules;
|
|
295
294
|
module.exports.getAvailableRulesQty = getAvailableRulesQty;
|
|
296
295
|
module.exports.getLevelGroup = getLevelGroup;
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
===========================================================================
|
|
7
7
|
**/
|
|
8
8
|
|
|
9
|
-
const path = require('path');
|
|
10
9
|
const fs = require('fs');
|
|
11
10
|
const Constants = require('../Constants');
|
|
12
11
|
const TreeBuilder = require('../isml_tree/TreeBuilder');
|
|
@@ -38,7 +37,7 @@ const checkCustomTag = tag => {
|
|
|
38
37
|
}
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
const
|
|
40
|
+
const fixTemplateOrReportIssues = (config, ruleResult, templatePath, templateResults, rule) => {
|
|
42
41
|
if (config.autoFix && ruleResult.fixedContent) {
|
|
43
42
|
fs.writeFileSync(templatePath, ruleResult.fixedContent);
|
|
44
43
|
templateResults.fixed = true;
|
|
@@ -49,7 +48,7 @@ const applyRuleResult = (config, ruleResult, templatePath, templateResults, rule
|
|
|
49
48
|
}
|
|
50
49
|
};
|
|
51
50
|
|
|
52
|
-
const
|
|
51
|
+
const fixTemplateOrReportIssuesForRuleList = (ruleArray, templatePath, root, config) => {
|
|
53
52
|
const templateResults = {
|
|
54
53
|
fixed : false,
|
|
55
54
|
errors : {}
|
|
@@ -59,7 +58,7 @@ const applyRuleOnTemplate = (ruleArray, templatePath, root, config) => {
|
|
|
59
58
|
const rule = ruleArray[i];
|
|
60
59
|
if (!rule.shouldIgnore(templatePath)) {
|
|
61
60
|
const ruleResults = rule.check(root, templateResults.data);
|
|
62
|
-
|
|
61
|
+
fixTemplateOrReportIssues(config, ruleResults, templatePath, templateResults, rule);
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -130,7 +129,7 @@ const checkFileName = (filename, templateContent) => {
|
|
|
130
129
|
return templateResults;
|
|
131
130
|
};
|
|
132
131
|
|
|
133
|
-
const
|
|
132
|
+
const checkAndPossiblyFixTreeRules = (templatePath, templateContent, config) => {
|
|
134
133
|
if (!config.disableTreeParse) {
|
|
135
134
|
const tree = TreeBuilder.build(templatePath, templateContent);
|
|
136
135
|
|
|
@@ -140,7 +139,7 @@ const checkTreeRules = (templatePath, templateContent, config) => {
|
|
|
140
139
|
|
|
141
140
|
const ruleArray = getEnabledTreeRules();
|
|
142
141
|
|
|
143
|
-
return
|
|
142
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
144
143
|
ruleArray,
|
|
145
144
|
templatePath,
|
|
146
145
|
tree.rootNode,
|
|
@@ -148,10 +147,10 @@ const checkTreeRules = (templatePath, templateContent, config) => {
|
|
|
148
147
|
}
|
|
149
148
|
};
|
|
150
149
|
|
|
151
|
-
const
|
|
150
|
+
const checkAndPossiblyFixLineByLineRules = (templatePath, templateContent, config) => {
|
|
152
151
|
const ruleArray = getEnabledLineRules();
|
|
153
152
|
|
|
154
|
-
return
|
|
153
|
+
return fixTemplateOrReportIssuesForRuleList(
|
|
155
154
|
ruleArray,
|
|
156
155
|
templatePath,
|
|
157
156
|
templateContent,
|
|
@@ -176,11 +175,11 @@ const checkCustomModules = () => {
|
|
|
176
175
|
return moduleResults;
|
|
177
176
|
};
|
|
178
177
|
|
|
179
|
-
const
|
|
178
|
+
const parseAndPossiblyFixTemplate = (templatePath, content, templateName) => {
|
|
180
179
|
const config = ConfigUtils.load();
|
|
181
180
|
const templateContent = content || fs.readFileSync(templatePath, 'utf-8');
|
|
182
|
-
const lineResults =
|
|
183
|
-
const treeResults =
|
|
181
|
+
const lineResults = checkAndPossiblyFixLineByLineRules(templatePath, templateContent, config);
|
|
182
|
+
const treeResults = checkAndPossiblyFixTreeRules(templatePath, templateContent, config) || { errors : [] };
|
|
184
183
|
const filenameResults = checkFileName(templateName, templateContent);
|
|
185
184
|
|
|
186
185
|
return {
|
|
@@ -227,6 +226,6 @@ const getEnabledTreeRules = () => {
|
|
|
227
226
|
module.exports.getAllLineRules = () => lineByLineRules;
|
|
228
227
|
module.exports.findNodeOfType = findNodeOfType;
|
|
229
228
|
module.exports.isTypeAmongTheFirstElements = isTypeAmongTheFirstElements;
|
|
230
|
-
module.exports.
|
|
229
|
+
module.exports.parseAndPossiblyFixTemplate = parseAndPossiblyFixTemplate;
|
|
231
230
|
module.exports.checkCustomModules = checkCustomModules;
|
|
232
231
|
module.exports.getAvailableRulesQty = getAvailableRulesQty;
|