isml-linter 5.40.4 → 5.41.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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.41.0] - 2023-01-21
4
+
5
+ ### Added
6
+ - Exposed "fix" method in [ISML Linter API][api-docs];
7
+
8
+ ### Fixed
9
+ - Line-by-line and tree rules issues now are fixed in a single ISML Linter execution, not in two steps anymore;
10
+
11
+ ## [5.40.5] - 2023-01-15
12
+
13
+ ### Fixed
14
+ - Disallow void elements closing tags;
15
+ - Minor output messages improvement;
16
+
3
17
  ## [5.40.4] - 2023-01-15
4
18
 
5
19
  ### Fixed
@@ -1034,6 +1048,8 @@
1034
1048
  ### Added
1035
1049
  - Linter is published;
1036
1050
 
1051
+ [5.41.0]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.5...v5.41.0
1052
+ [5.40.5]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.4...v5.40.5
1037
1053
  [5.40.4]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.3...v5.40.4
1038
1054
  [5.40.3]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.2...v5.40.3
1039
1055
  [5.40.2]: https://github.com/FabiowQuixada/isml-linter/compare/v5.40.1...v5.40.2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isml-linter",
3
- "version": "5.40.4",
3
+ "version": "5.41.0",
4
4
  "author": "Fabiow Quixadá <ftquixada@gmail.com>",
5
5
  "license": "MIT",
6
6
  "main": "src/publicApi.js",
@@ -103,6 +103,9 @@ const checkBalance = (node, templatePath) => {
103
103
  };
104
104
 
105
105
  const parseNextElement = state => {
106
+ const ConfigUtils = require('../util/ConfigUtils');
107
+
108
+ const config = ConfigUtils.load();
106
109
  const newElement = getNewElement(state);
107
110
 
108
111
  const trimmedElement = newElement.value.trim();
@@ -125,7 +128,8 @@ const parseNextElement = state => {
125
128
  parseTextElement(state, newElement);
126
129
  }
127
130
 
128
- newElement.columnNumber = getElementColumnNumber(newElement, state);
131
+ newElement.columnNumber = getElementColumnNumber(newElement, state);
132
+ newElement.isVoidElement = !config.disableHtml5 && Constants.voidElementsArray.indexOf(newElement.tagType) >= 0;
129
133
 
130
134
  if (state.isCrlfLineBreak) {
131
135
  newElement.globalPos += newElement.lineNumber - 1;
@@ -110,7 +110,17 @@ const parseContainerElements = (element, currentParent, newNode, templatePath) =
110
110
 
111
111
  const parseNonContainerElements = (element, currentParent, newNode, templatePath) => {
112
112
  if (element.isSelfClosing) {
113
- currentParent.addChild(newNode);
113
+ if (element.isClosingTag && element.isVoidElement) {
114
+ throw ExceptionUtils.voidElementClosingTag(
115
+ element.tagType,
116
+ element.lineNumber,
117
+ element.globalPos,
118
+ element.value.trim().length,
119
+ templatePath
120
+ );
121
+ } else {
122
+ currentParent.addChild(newNode);
123
+ }
114
124
  } else if (!element.isClosingTag && element.tagType !== 'isif') {
115
125
  currentParent.addChild(newNode);
116
126
 
package/src/publicApi.js CHANGED
@@ -14,8 +14,23 @@ module.exports = {
14
14
  }
15
15
 
16
16
  linterResult = IsmlLinter.run(path, content);
17
+
17
18
  return linterResult;
18
19
  },
20
+ fix : (path, content, config) => {
21
+ let autofixConfig = config;
22
+
23
+ if (config) {
24
+ autofixConfig.autoFix = true;
25
+ IsmlLinter.setConfig(autofixConfig);
26
+ } else {
27
+ autofixConfig = IsmlLinter.getConfig();
28
+ autofixConfig.autoFix = true;
29
+ IsmlLinter.setConfig(autofixConfig);
30
+ }
31
+
32
+ return IsmlLinter.run(path, content, autofixConfig);
33
+ },
19
34
  printResults : () => ConsoleUtils.displayOccurrenceList(linterResult),
20
35
  build : path => Builder.run(path),
21
36
 
@@ -41,7 +41,10 @@ SingleLineRulePrototype.check = function(templateContent, data = { isCrlfLineBre
41
41
  };
42
42
  }
43
43
 
44
- return { occurrenceList };
44
+ return {
45
+ occurrenceList,
46
+ fixedContent : templateContent
47
+ };
45
48
  };
46
49
 
47
50
  module.exports = SingleLineRulePrototype;
@@ -158,7 +158,7 @@ const existEslintConfigFile = () => {
158
158
  FileUtils.fileExists(Constants.eslintConfigFilePathList[2]);
159
159
  };
160
160
 
161
- const isTestEnv = () => process.env.NODE_ENV === Constants.ENV_TEST;
161
+ const isTestEnv = () => process.env.NODE_ENV === Constants.ENV_TEST && !global.isSimulatingProductionEnvironment;
162
162
 
163
163
  const setLocalConfig = configParam => {
164
164
  if (isTestEnv()) {
@@ -7,6 +7,7 @@ const types = {
7
7
  INVALID_TEMPLATE : 'INVALID_TEMPLATE',
8
8
  INVALID_NESTED_ISIF : 'INVALID_NESTED_ISIF',
9
9
  INVALID_CHARACTER : 'INVALID_CHARACTER',
10
+ VOID_ELEMENT_CLOSING_TAG : 'VOID_ELEMENT_CLOSING_TAG',
10
11
  RULE_ERROR : 'RULE_ERROR',
11
12
  NO_CONFIG : 'NO_CONFIG',
12
13
  };
@@ -100,6 +101,18 @@ const invalidCharacterError = (character, lineNumber, globalPos, length, templat
100
101
  };
101
102
  };
102
103
 
104
+ const voidElementClosingTag = (element, lineNumber, globalPos, length, templatePath) => {
105
+ return {
106
+ message : `"<${element}>" is a void element, and as such, should not have a corresponding closing tag`,
107
+ templatePath : templatePath,
108
+ globalPos,
109
+ length,
110
+ lineNumber : lineNumber,
111
+ isCustom : true,
112
+ type : types.VOID_ELEMENT_CLOSING_TAG
113
+ };
114
+ };
115
+
103
116
  const invalidNestedIsifError = (tagType, lineNumber, globalPos, templatePath) => {
104
117
  return {
105
118
  message : `An error occurred while parsing element "<${tagType}>" in line ${lineNumber}. Try moving the closing character ">" of the "<${tagType}>" element to outside of the "<isif>" condition.`,
@@ -135,14 +148,14 @@ const unkownError = (templatePath) => {
135
148
 
136
149
  const noConfigError = () => {
137
150
  return {
138
- message : `No configuration found. Please run the following command: ${Constants.EOL}${Constants.EOL}\t./node_modules/.bin/isml-linter --init${Constants.EOL}${Constants.EOL}`,
151
+ message : `No ISML Linter configuration file found. Please run the following command: ${Constants.EOL}${Constants.EOL}\t./node_modules/.bin/isml-linter --init${Constants.EOL}${Constants.EOL}`,
139
152
  isCustom : true
140
153
  };
141
154
  };
142
155
 
143
156
  const noEslintConfigError = () => {
144
157
  return {
145
- message : 'No eslint configuration found. Please add an ESLint configuration file and try again.',
158
+ message : 'No ESLint configuration file found. Please add an ESLint configuration file and try again.',
146
159
  isCustom : true
147
160
  };
148
161
  };
@@ -160,6 +173,7 @@ module.exports = {
160
173
  unbalancedQuotesError,
161
174
  ruleApplianceError,
162
175
  unkownError,
176
+ voidElementClosingTag,
163
177
  invalidNestedIsifError,
164
178
  unclosedDeprecatedIsmlComment,
165
179
  unbalancedElementError,
@@ -93,6 +93,7 @@ const applyRuleOnTemplate = (ruleArray, templatePath, root, config, data) => {
93
93
  try {
94
94
  ConsoleUtils.displayVerboseMessage(`Applying "${rule.id}" rule`, 1);
95
95
  const ruleResults = rule.check(root, templateResults.data);
96
+ templateResults.finalContent = ruleResults.fixedContent;
96
97
  applyRuleResult(config, ruleResults, templatePath, templateResults, rule);
97
98
 
98
99
  } catch (error) {
@@ -226,7 +227,7 @@ const checkTemplate = (templatePath, data, content = '', templateName = '') => {
226
227
  const config = ConfigUtils.load();
227
228
  const templateContent = GeneralUtils.toLF(content || fs.readFileSync(templatePath, 'utf-8'));
228
229
  const lineResults = checkLineByLineRules(templatePath, templateContent, config, data);
229
- const treeResults = checkTreeRules(templatePath, templateContent, config, data) || { errors : [] };
230
+ const treeResults = checkTreeRules(templatePath, lineResults.finalContent, config, data) || { errors : [] };
230
231
  const filenameResults = checkFileName(templateName, templateContent);
231
232
 
232
233
  return {