ilib-lint 1.0.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.
Files changed (89) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +231 -0
  3. package/docs/AnsiConsoleFormatter.html +467 -0
  4. package/docs/Formatter.html +577 -0
  5. package/docs/Formatter.js.html +135 -0
  6. package/docs/FormatterFactory.html +191 -0
  7. package/docs/FormatterFactory.js.html +109 -0
  8. package/docs/Parser.html +483 -0
  9. package/docs/Parser.js.html +122 -0
  10. package/docs/ParserFactory.js.html +109 -0
  11. package/docs/Plugin.html +847 -0
  12. package/docs/Plugin.js.html +168 -0
  13. package/docs/PluginManager.html +541 -0
  14. package/docs/PluginManager.js.html +125 -0
  15. package/docs/ResourceICUPlurals.html +278 -0
  16. package/docs/ResourceQuoteStyle.html +278 -0
  17. package/docs/ResourceRegExpChecker.html +295 -0
  18. package/docs/ResourceUniqueKeys.html +278 -0
  19. package/docs/Result.html +263 -0
  20. package/docs/Result.js.html +130 -0
  21. package/docs/Rule.html +774 -0
  22. package/docs/Rule.js.html +230 -0
  23. package/docs/RuleSet.html +760 -0
  24. package/docs/RuleSet.js.html +153 -0
  25. package/docs/SourceFile.html +826 -0
  26. package/docs/SourceFile.js.html +232 -0
  27. package/docs/XliffParser.html +396 -0
  28. package/docs/XliffPlugin.html +472 -0
  29. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  30. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  31. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  32. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  33. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  34. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  35. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  36. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  37. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  38. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  39. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  40. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  41. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  42. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  43. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  44. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  45. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  46. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  47. package/docs/formatters_AnsiConsoleFormatter.js.html +147 -0
  48. package/docs/global.html +448 -0
  49. package/docs/ilibLint.md +1013 -0
  50. package/docs/index.html +81 -0
  51. package/docs/plugins_XliffParser.js.html +129 -0
  52. package/docs/plugins_XliffPlugin.js.html +129 -0
  53. package/docs/rules_ResourceICUPlurals.js.html +297 -0
  54. package/docs/rules_ResourceQuoteStyle.js.html +238 -0
  55. package/docs/rules_ResourceRegExpChecker.js.html +248 -0
  56. package/docs/rules_ResourceUniqueKeys.js.html +144 -0
  57. package/docs/scripts/collapse.js +20 -0
  58. package/docs/scripts/linenumber.js +25 -0
  59. package/docs/scripts/nav.js +12 -0
  60. package/docs/scripts/polyfill.js +4 -0
  61. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  62. package/docs/scripts/prettify/lang-css.js +2 -0
  63. package/docs/scripts/prettify/prettify.js +28 -0
  64. package/docs/scripts/search.js +83 -0
  65. package/docs/styles/jsdoc.css +765 -0
  66. package/docs/styles/prettify.css +79 -0
  67. package/docs/walk.js.html +214 -0
  68. package/log4js.json +21 -0
  69. package/package.json +83 -0
  70. package/src/Formatter.js +66 -0
  71. package/src/FormatterFactory.js +41 -0
  72. package/src/Parser.js +53 -0
  73. package/src/ParserFactory.js +41 -0
  74. package/src/Plugin.js +99 -0
  75. package/src/PluginManager.js +56 -0
  76. package/src/Result.js +62 -0
  77. package/src/Rule.js +162 -0
  78. package/src/RuleSet.js +84 -0
  79. package/src/SourceFile.js +163 -0
  80. package/src/formatters/AnsiConsoleFormatter.js +78 -0
  81. package/src/index.js +213 -0
  82. package/src/plugins/XliffParser.js +60 -0
  83. package/src/plugins/XliffPlugin.js +60 -0
  84. package/src/rules/ResourceICUPlurals.js +229 -0
  85. package/src/rules/ResourceQuoteStyle.js +170 -0
  86. package/src/rules/ResourceRegExpChecker.js +179 -0
  87. package/src/rules/ResourceUniqueKeys.js +76 -0
  88. package/src/rules/utils.js +78 -0
  89. package/src/walk.js +146 -0
package/src/Plugin.js ADDED
@@ -0,0 +1,99 @@
1
+ /*
2
+ * Plugin.js - common SPI that all plugins must implement
3
+ *
4
+ * Copyright © 2022 JEDLSoft
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ *
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+
20
+ /**
21
+ * @class common SPI that all plugins must implement
22
+ * @abstract
23
+ */
24
+ class Plugin {
25
+ /**
26
+ * Construct a new plugin.
27
+ */
28
+ constructor(options) {
29
+ }
30
+
31
+ /**
32
+ * Initialize the current plugin,
33
+ * @abstract
34
+ */
35
+ init() {}
36
+
37
+ /**
38
+ * Return the type of this plugin. This can be one of the
39
+ * following:
40
+ *
41
+ * <ul>
42
+ * <li>rule - this plugin implements a new rules
43
+ * <li>parser - this plugin knows how to parse files more deeply
44
+ * than line-by-line
45
+ * <li>formatter - this plugin formats results for a particular
46
+ * type of output
47
+ * </ul>
48
+ *
49
+ * @returns {String} tells what type of plugin this is
50
+ * @abstract
51
+ */
52
+ getType() {
53
+ }
54
+
55
+ /**
56
+ * Return the list of extensions of the files that this parser handles.
57
+ * The extensions are listed without the dot. eg. ["json", "jsn"]
58
+ *
59
+ * @returns {Array.<String>} a list of file name extensions
60
+ */
61
+ getExtensions() {
62
+ return [];
63
+ }
64
+
65
+ /**
66
+ * For a "rule" type of plugin, this returns a list of Rule instances
67
+ * that this plugin implements.
68
+ *
69
+ * @returns {Array.<Rule>} list of Rule instances implemented by this
70
+ * plugin
71
+ */
72
+ getRules() {
73
+ return [];
74
+ }
75
+
76
+ /**
77
+ * For a "parser" type of plugin, this returns a list of Parser classes
78
+ * that this plugin implements.
79
+ *
80
+ * @returns {Array.<Parser>} list of Parser classes implemented by this
81
+ * plugin
82
+ */
83
+ getParsers() {
84
+ return [];
85
+ }
86
+
87
+ /**
88
+ * For a "formatter" type of plugin, this returns a list of Formatter
89
+ * instances that this plugin implements.
90
+ *
91
+ * @returns {Array.<Formatter>} list of Formatter instances implemented by this
92
+ * plugin
93
+ */
94
+ getFormatters() {
95
+ return [];
96
+ }
97
+ };
98
+
99
+ export default Plugin;
@@ -0,0 +1,56 @@
1
+ /*
2
+ * PluginManager.js - Load a list of plugins and maintain them
3
+ *
4
+ * Copyright © 2022 JEDLSoft
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ *
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+
20
+ /**
21
+ * @class Represent a plugin manager, which loads a list of plugins
22
+ * and then maintains references to them
23
+ */
24
+ class PluginManager {
25
+ /**
26
+ * Construct a new plugin manager.
27
+ */
28
+ constructor(options) {
29
+ }
30
+
31
+ /**
32
+ * Load the named plugin.
33
+ *
34
+ * @param {String} name plugin to load
35
+ * @returns {Promise} a promise to load the named plugin.
36
+ * @accept {Plugin} the loaded plugin
37
+ * @reject the plugin could not be found or loaded
38
+ */
39
+ load(name) {
40
+
41
+ }
42
+
43
+ /**
44
+ * Return an array of handlers that handle the given path name based
45
+ * on things like the file name extension.
46
+ *
47
+ * @param {String} pathName path to a file to match
48
+ * @param {String} type the type of plugin being sought
49
+ * @returns {Array.<Plugin>} an array of plugins that claim to handle
50
+ * the given path name
51
+ */
52
+ getHandlers(pathName, type) {
53
+ }
54
+ };
55
+
56
+ export default PluginManager;
package/src/Result.js ADDED
@@ -0,0 +1,62 @@
1
+ /*
2
+ * Result.js - Represent an ilib-lint rule check result
3
+ *
4
+ * Copyright © 2022 JEDLSoft
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ *
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+
20
+ /**
21
+ * @class Represent an ilib-lint rule check result
22
+ * @abstract
23
+ */
24
+ class Result {
25
+ /**
26
+ * Construct an ilib-lint rule check result. Rules should return this
27
+ * type when reporting issues in the source files. The fields can
28
+ * contain any of the following properties:
29
+ *
30
+ * - severity {String}: "warning" or "error" (required)
31
+ * - description {String}: description of the problem in the source file
32
+ * (required)
33
+ * - pathName {String}: name of the file that the issue was found in (required)
34
+ * - rule {Rule}: the rule that generated this issue (required)
35
+ * - id {String}: key of a resource being checked
36
+ * - source {String}: for resource problems, this is the original source string
37
+ * - highlight {String}: highlighted text from the source file indicating
38
+ * where the issue was. For resources, this is either the source or target
39
+ * string, where-ever the problem occurred
40
+ * - lineNumber {Number}: line number in the source fie where the issue
41
+ * was found
42
+ * - locale {String}: locale of associated with this issue
43
+ *
44
+ * Only the severity, description, pathName, and rule are required. All other
45
+ * properties are optional.
46
+ *
47
+ * @param {Object} fields result fields
48
+ */
49
+ constructor(fields) {
50
+ if (!fields || !fields.severity || !fields.description || !fields.pathName || !fields.rule) {
51
+ throw "Missing fields in Result constructor";
52
+ }
53
+ this.severity = (fields.severity === "error" || fields.severity === "warning") ?
54
+ fields.severity :
55
+ "warning";
56
+ ["description", "pathName", "rule", "id", "highlight", "lineNumber", "locale", "source"].forEach(property => {
57
+ if (fields[property]) this[property] = fields[property];
58
+ });
59
+ }
60
+ }
61
+
62
+ export default Result;
package/src/Rule.js ADDED
@@ -0,0 +1,162 @@
1
+ /*
2
+ * Rule.js - Represent an ilib-lint rule
3
+ *
4
+ * Copyright © 2022 JEDLSoft
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ *
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+
20
+ /**
21
+ * @class Represent an ilib-lint rule.
22
+ * @abstract
23
+ */
24
+ class Rule {
25
+ /**
26
+ * Construct an ilib-lint rule. Rules in plugins should implement this
27
+ * abstract class.
28
+ */
29
+ constructor() {
30
+ if (this.constructor === Rule) {
31
+ throw new Error("Cannot instantiate abstract class Rule!");
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Get the name of the rule. This should be a string with a dash-separated
37
+ * set of words (kebab or dash case). Example: "resource-match-whitespace"
38
+ *
39
+ * @returns {String} the name of this rule
40
+ */
41
+ getName() {
42
+ // make sure to define this.name in your implementation
43
+ return this.name;
44
+ }
45
+
46
+ /**
47
+ * Return a general description of the type of problems that this rule is
48
+ * testing for. This description is not related to particular matches, so
49
+ * it cannot be more specific. Examples:
50
+ *
51
+ * "translation should use the appropriate quote style"
52
+ * "parameters to the translation wrapper function must not be concatenated"
53
+ * "translation should match the whitespace of the source string"
54
+ *
55
+ * @returns {String} a general description of the type of problems that this rule is
56
+ * testing for
57
+ */
58
+ getDescription() {
59
+ return this.description;
60
+ }
61
+
62
+ /**
63
+ * Return the type of this rule. Rules can be organized into the following
64
+ * types:
65
+ *
66
+ * - A resource rule. This checks a translated resource with a source string
67
+ * and a translation to a given locale. eg. a rule that checks that
68
+ * substitution parameters that exist in the source string also are
69
+ * given in the target string.
70
+ * - A line rule. This rule checks single lines of a file. eg. a rule to
71
+ * check the parameters to a function call.
72
+ * - A multiline rule. This rule checks multiple lines at once to find
73
+ * problems that may span multiple lines. For example, a rule to enforce
74
+ * a policy that all translatable strings in a source file have an appropriate
75
+ * translator's comment on them.
76
+ * - A multifile rule. This rule checks problems across multiple files. eg.
77
+ * a rule to check that ids for translatable strings are unique across all
78
+ * files.
79
+ *
80
+ * @returns {String} a string with either "resource", "line", "multiline", or
81
+ * "multifile".
82
+ */
83
+ getRuleType() {
84
+ // default rule type. If your rule is different, override this method.
85
+ return "line";
86
+ }
87
+
88
+ getSourceLocale() {
89
+ return this.sourceLocale || "en-US";
90
+ }
91
+
92
+ /**
93
+ * Return whether or not this rule matches the input. The options object can
94
+ * contain any of the following properties:
95
+ *
96
+ * <ul>
97
+ * <li>locale - the locale against which this rule should be checked. Some rules
98
+ * are locale-sensitive, others not.
99
+ * <li>resource - the resource to test this rule against. For resource rules, this
100
+ * is a required property.
101
+ * <li>line - a single line of a file to test this rule against (for line rules)
102
+ * <li>lines - all the lines of a file to test this rule against (for multiline rules
103
+ * and multifile rules)
104
+ * <li>pathName - the name of the current file being matched in multifile rules.
105
+ * <li>parameters - (optional) parameters for this rule from the configuration file
106
+ * </ul>
107
+ *
108
+ * The return value from this method when a rule matches is an object with the
109
+ * following properties:
110
+ *
111
+ * <ul>
112
+ * <li>severity - the severity of this match. This can be one of the following:
113
+ * <ul>
114
+ * <li>suggestion - a suggestion of a better way to do things. The current way is
115
+ * not incorrect, but probably not optimal
116
+ * <li>warning - a problem that should be fixed, but which does not prevent
117
+ * your app from operating internationally. This is more severe than a suggestion.
118
+ * <li>error - a problem that must be fixed. This type of problem will prevent
119
+ * your app from operating properly internationally and could possibly even
120
+ * crash your app in some cases.
121
+ * </ul>
122
+ * <li>description - a description of the problem to display to the user. In order
123
+ * to make the ilib-lint output useful, this description should attempt to make the
124
+ * following things clear:
125
+ * <ul>
126
+ * <li>What part is wrong
127
+ * <li>Why it is wrong
128
+ * <li>Suggestions on how to fix it
129
+ * </ul>
130
+ * <li>lineNumber - the line number where the match occurred in multiline rules
131
+ * <li>highlight - the line where the problem occurred, highlighted with XML syntax
132
+ * (see below)
133
+ * </ul>
134
+ *
135
+ * For the `highlight` property, the line that has a problem is reproduced with
136
+ * XML tags around the problem part, if it is known. The tags are of the form
137
+ * &lt;eX&gt; where X is a digit starting with 0 and progressing to 9 for each
138
+ * subsequent problem. If the file type is XML already, the rest of the line will
139
+ * be XML-escaped first.<p>
140
+ *
141
+ * Example:<p>
142
+ *
143
+ * "const str = rb.getString(<e0>id</e0>);"<p>
144
+ *
145
+ * In this rule, `getString()` must be called with a static string in order for the
146
+ * loctool to be able to extract that string. The line above calls `getString()`
147
+ * with a variable named "id" as a parameter. The variable is highlighted with the
148
+ * e0 tag. Callers can then translate the open and close tags appropriately for
149
+ * the output device, such as ASCII escapes for a regular terminal, or HTML tags
150
+ * for a web-based device.
151
+ *
152
+ * @param {Object} options The options object as per the description above
153
+ * @returns {Object|Array.<Object>|undefined} an object describing the problem if the rule
154
+ * does match for this locale, or an array of such Objects if there are multiple
155
+ * problems with the same input, or undefined if the rule does not match
156
+ */
157
+ match(options) {
158
+ throw new Error("Cannot call Rule.match() directly.");
159
+ }
160
+ }
161
+
162
+ export default Rule;
package/src/RuleSet.js ADDED
@@ -0,0 +1,84 @@
1
+ /*
2
+ * RuleSet.js - Represent a set of ilib-lint rules
3
+ *
4
+ * Copyright © 2022 JEDLSoft
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ *
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+
20
+ import Rule from './Rule.js';
21
+
22
+ /**
23
+ * @class Represent a set of ilib-lint rules.
24
+ */
25
+ class RuleSet {
26
+ /**
27
+ * Construct an ilib-lint rule set.
28
+ */
29
+ constructor(rules) {
30
+ this.rules = {};
31
+ this.byname = {};
32
+ if (rules) {
33
+ rules.forEach(rule => {
34
+ this.addRule(rule);
35
+ });
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @param {Rule} rule
41
+ */
42
+ addRule(rule) {
43
+ if (!rule || !(rule instanceof Rule)) return;
44
+ const name = rule.getName();
45
+ if (this.byname[name]) return; // already added
46
+ this.byname[name] = rule;
47
+ const type = rule.getRuleType();
48
+ if (!this.rules[type]) {
49
+ this.rules[type] = [rule];
50
+ } else {
51
+ this.rules[type].push(rule);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Return the rule with the given name.
57
+ *
58
+ * @param {String} name name to search for
59
+ * @returns {Rule|undefined} the rule with the given name or
60
+ * undefined if the rule is not known
61
+ */
62
+ getRule(name) {
63
+ return this.byname[name];
64
+ }
65
+
66
+ /**
67
+ * Return all the rules of the given type in this set.
68
+ * @param {String} type to search for
69
+ * @returns {Array.<Rule>} the list of rules of the requested type
70
+ */
71
+ getRules(type) {
72
+ return this.rules[type] || [];
73
+ }
74
+
75
+ /**
76
+ * Return the number of rules in this set.
77
+ * @returns {Number} the number of rules in this set
78
+ */
79
+ getSize() {
80
+ return Object.keys(this.byname).length;
81
+ }
82
+ };
83
+
84
+ export default RuleSet;
@@ -0,0 +1,163 @@
1
+ /*
2
+ * SourceFile.js - Represent a source file
3
+ *
4
+ * Copyright © 2022 JEDLSoft
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ *
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+
20
+ import path from 'node:path';
21
+ import fs from 'node:fs';
22
+ import { getLocaleFromPath } from 'ilib-tools-common';
23
+
24
+ import ParserFactory from './ParserFactory.js';
25
+
26
+ /**
27
+ * @class Represent a set of ilib-lint rules.
28
+ */
29
+ class SourceFile {
30
+ /**
31
+ * Construct a source file instance
32
+ * The options parameter can contain any of the following properties:
33
+ *
34
+ * - filePath {String} path to the file
35
+ * - settings {Object} the settings from the ilib-lint config that
36
+ * apply to this file
37
+ */
38
+ constructor(options) {
39
+ if (!options || !options.filePath) {
40
+ throw "Incorrect options given to SourceFile constructor";
41
+ }
42
+ this.filePath = options.filePath;
43
+ this.settings = options.settings;
44
+ }
45
+
46
+ /**
47
+ * Return the file path for this source file.
48
+ *
49
+ * @returns {String} the file path for this source file
50
+ */
51
+ getFilePath() {
52
+ return this.filePath;
53
+ }
54
+
55
+ /**
56
+ * Return the locale gleaned from the file path using the template in
57
+ * the settings, or undefined if no locale could be found.
58
+ *
59
+ * @returns {String} the locale gleaned from the path, or the empty
60
+ * string if no locale could be found.
61
+ */
62
+ getLocaleFromPath() {
63
+ if (this.settings && this.settings.template) {
64
+ return getLocaleFromPath(this.settings.template, this.filePath);
65
+ }
66
+ return "";
67
+ }
68
+
69
+ /**
70
+ * Parse the current source file into a list of resources (in the case of
71
+ * resource files, or lines in the case of other types of files.
72
+ * @returns {Object} the parsed representation of this file
73
+ */
74
+ parse() {
75
+ if (!this.filePath) return;
76
+ let extension = path.extname(this.filePath);
77
+ if (extension) {
78
+ // remove the dot
79
+ extension = extension.substring(1);
80
+ const parserClasses = ParserFactory({extension});
81
+ if (parserClasses && parserClasses.length) {
82
+ const parser = new parserClasses[0]({
83
+ filePath: this.filePath
84
+ });
85
+ parser.parse();
86
+ this.resources = parser.getResources();
87
+ this.type = "resource";
88
+
89
+ return this.resources;
90
+ }
91
+ }
92
+
93
+ const data = fs.readFileSync(this.filePath, "utf-8");
94
+ this.lines = data.split(/\n/g);
95
+ this.type = "line";
96
+
97
+ return this.lines;
98
+ }
99
+
100
+ /**
101
+ * Return the type of this file, resource or line.
102
+ * @returns {String} the type of this file
103
+ */
104
+ getType() {
105
+ return this.type;
106
+ }
107
+
108
+ /**
109
+ * Check the current file and return a list of issues found in this file.
110
+ * This method parses the source file and applies each rule in turn
111
+ * using the given locales.
112
+ *
113
+ * @param {RuleSet} ruleset a set of rules to apply
114
+ * @param {Array.<Locale>} locales a set of locales to apply
115
+ * @returns {Array.<Result>} a list of natch results
116
+ */
117
+ findIssues(ruleset, locales) {
118
+ let issues = [], rules;
119
+ const detectedLocale = this.getLocaleFromPath();
120
+
121
+ if (detectedLocale && locales.indexOf(detectedLocale) < -1) {
122
+ // not one of the locales we need to check
123
+ return issues;
124
+ }
125
+
126
+ switch (this.type) {
127
+ case "line":
128
+ rules = ruleset.getRules("line");
129
+ if (rules && rules.length) {
130
+ for (let i = 0; i < this.lines.length; i++) {
131
+ rules.forEach(rule => {
132
+ const result = rule.match({
133
+ line: this.lines[i],
134
+ locale: detectedLocale,
135
+ file: this.filePath
136
+ });
137
+ if (result) issues = issues.concat(result);
138
+ });
139
+ }
140
+ }
141
+ break;
142
+ case "resource":
143
+ rules = ruleset.getRules("resource");
144
+ if (rules && rules.length) {
145
+ this.resources.forEach(resource => {
146
+ rules.forEach(rule => {
147
+ const result = rule.match({
148
+ locale: resource.getTargetLocale(),
149
+ resource,
150
+ file: this.filePath
151
+ });
152
+ if (result) issues = issues.concat(result);
153
+ });
154
+ });
155
+ }
156
+ break;
157
+ }
158
+
159
+ return issues;
160
+ }
161
+ };
162
+
163
+ export default SourceFile;