@sasjs/lint 5.3.0 → 5.3.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/README.md
CHANGED
|
@@ -59,6 +59,8 @@ Configuration is via a `.sasjslint` file with the following structure (these are
|
|
|
59
59
|
|
|
60
60
|
Two keys do not have a section of their own. `requiredMacroOptions` is documented with [`hasRequiredMacroOptions`](#hasrequiredmacrooptions), the rule it configures. The deprecated alias `noTabIndentation` is accepted in place of `noTabs`, and is therefore not listed above - it is an alternative spelling rather than a setting of its own.
|
|
61
61
|
|
|
62
|
+
The file is read as strict JSON, so it cannot carry comments: a file that does not parse is reported as an error, naming the file, rather than being treated as though no configuration were present. Add `"$schema": "https://cli.sasjs.io/sasjslint-schema.json"` to get completion, hover text and validation for every setting in an editor that understands JSON schemas - `sasjs lint init` and a SASjs Server's seeded drive-root file both write it.
|
|
63
|
+
|
|
62
64
|
## SAS Lint Settings
|
|
63
65
|
|
|
64
66
|
Each setting can have three states:
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ exports.hasMacroParentheses = void 0;
|
|
|
4
4
|
const LintRuleType_1 = require("../../types/LintRuleType");
|
|
5
5
|
const Severity_1 = require("../../types/Severity");
|
|
6
6
|
const getColumnNumber_1 = require("../../utils/getColumnNumber");
|
|
7
|
+
const getIndex_1 = require("../../utils/getIndex");
|
|
7
8
|
const parseMacros_1 = require("../../utils/parseMacros");
|
|
8
9
|
const utils_1 = require("../../utils");
|
|
9
10
|
const getSeverity_1 = require("../../utils/getSeverity");
|
|
@@ -20,19 +21,6 @@ const message = 'Macro definition missing parentheses';
|
|
|
20
21
|
const parameterlessDeclaration = (macroName) => new RegExp(`(%macro\\s+${(0, utils_1.escapeRegExp)(macroName)})((?:\\s*/\\*.*?\\*/)?\\s*;)`, 'i');
|
|
21
22
|
/** The line of the declaration that carries the macro name. */
|
|
22
23
|
const nameLine = (macro) => macro.declarationLines.findIndex((declarationLine) => declarationLine.includes(macro.name));
|
|
23
|
-
/**
|
|
24
|
-
* The offset at which each line of the text starts, measured on the text as it
|
|
25
|
-
* stands. Used to edit one line without re-joining every other one, which would
|
|
26
|
-
* rewrite line endings this rule has no business touching.
|
|
27
|
-
*/
|
|
28
|
-
const lineStarts = (text) => {
|
|
29
|
-
const starts = [0];
|
|
30
|
-
for (let index = 0; index < text.length; index++) {
|
|
31
|
-
if (text[index] === '\n')
|
|
32
|
-
starts.push(index + 1);
|
|
33
|
-
}
|
|
34
|
-
return starts;
|
|
35
|
-
};
|
|
36
24
|
const test = (value, config) => {
|
|
37
25
|
const diagnostics = [];
|
|
38
26
|
const macros = (0, parseMacros_1.parseMacros)(value, config);
|
|
@@ -89,9 +77,11 @@ const fix = (value, config) => {
|
|
|
89
77
|
.filter(({ index }) => index !== -1);
|
|
90
78
|
return declarations.reduce((text, { macro, index }) => {
|
|
91
79
|
const lineNumber = macro.startLineNumbers[index];
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
80
|
+
// The offsets of this line and of the next one, measured on the text as it
|
|
81
|
+
// stands. `getIndex` clamps to the end of the file, so the last line ends
|
|
82
|
+
// there.
|
|
83
|
+
const start = (0, getIndex_1.getIndex)(text, lineNumber, 1);
|
|
84
|
+
const end = (0, getIndex_1.getIndex)(text, lineNumber + 1, 1);
|
|
95
85
|
// The line is taken with its terminator and put back with it, so every byte
|
|
96
86
|
// of the file other than the two this fix inserts is left alone.
|
|
97
87
|
const line = text.slice(start, end);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hasMacroParentheses.js","sourceRoot":"","sources":["../../../src/rules/file/hasMacroParentheses.ts"],"names":[],"mappings":";;;AAEA,2DAAuD;AACvD,mDAA+C;AAC/C,iEAA6D;AAC7D,yDAAqD;AAGrD,uCAA0C;AAC1C,yDAAqD;AAErD,MAAM,IAAI,GAAG,qBAAqB,CAAA;AAClC,MAAM,WAAW,GAAG,4DAA4D,CAAA;AAChF,MAAM,OAAO,GAAG,sCAAsC,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,wBAAwB,GAAG,CAAC,SAAiB,EAAE,EAAE,CACrD,IAAI,MAAM,CACR,cAAc,IAAA,oBAAY,EAAC,SAAS,CAAC,8BAA8B,EACnE,GAAG,CACJ,CAAA;AAEH,+DAA+D;AAC/D,MAAM,QAAQ,GAAG,CAAC,KAAY,EAAU,EAAE,CACxC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,eAAe,EAAE,EAAE,CACnD,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CACrC,CAAA;AAEH
|
|
1
|
+
{"version":3,"file":"hasMacroParentheses.js","sourceRoot":"","sources":["../../../src/rules/file/hasMacroParentheses.ts"],"names":[],"mappings":"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"}
|
package/utils/getLintConfig.d.ts
CHANGED
|
@@ -50,6 +50,18 @@ export declare const DefaultLintConfiguration: {
|
|
|
50
50
|
/**
|
|
51
51
|
* Fetches the config from the .sasjslint file (at project root or home directory) and creates a LintConfig object.
|
|
52
52
|
* Returns the default configuration when a .sasjslint file is unavailable.
|
|
53
|
+
*
|
|
54
|
+
* An absent file means the defaults, but a file that IS there and does not parse
|
|
55
|
+
* is a mistake in the project rather than a missing configuration: reporting it
|
|
56
|
+
* as "no file" applies a different rule set without saying so, which is how a
|
|
57
|
+
* commented-out rule or a stray trailing comma comes to look like it works.
|
|
53
58
|
* @returns {Promise<LintConfig>} resolves with an object representing the current lint configuration.
|
|
54
59
|
*/
|
|
55
60
|
export declare function getLintConfig(): Promise<LintConfig>;
|
|
61
|
+
/**
|
|
62
|
+
* Reads the configuration file, turning a parse failure into a message that
|
|
63
|
+
* names the file and says what to do about it. A raw `JSON.parse` error reads
|
|
64
|
+
* `Unexpected token } in JSON at position 12`, which leaves the reader to work
|
|
65
|
+
* out which file was read and why JSON is involved at all.
|
|
66
|
+
*/
|
|
67
|
+
export declare const parseLintConfig: (configuration: string, filePath: string) => any;
|
package/utils/getLintConfig.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.DefaultLintConfiguration = exports.getDefaultHeader = void 0;
|
|
15
|
+
exports.parseLintConfig = exports.DefaultLintConfiguration = exports.getDefaultHeader = void 0;
|
|
16
16
|
exports.getLintConfig = getLintConfig;
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const os_1 = __importDefault(require("os"));
|
|
@@ -73,16 +73,42 @@ exports.DefaultLintConfiguration = {
|
|
|
73
73
|
/**
|
|
74
74
|
* Fetches the config from the .sasjslint file (at project root or home directory) and creates a LintConfig object.
|
|
75
75
|
* Returns the default configuration when a .sasjslint file is unavailable.
|
|
76
|
+
*
|
|
77
|
+
* An absent file means the defaults, but a file that IS there and does not parse
|
|
78
|
+
* is a mistake in the project rather than a missing configuration: reporting it
|
|
79
|
+
* as "no file" applies a different rule set without saying so, which is how a
|
|
80
|
+
* commented-out rule or a stray trailing comma comes to look like it works.
|
|
76
81
|
* @returns {Promise<LintConfig>} resolves with an object representing the current lint configuration.
|
|
77
82
|
*/
|
|
78
83
|
function getLintConfig() {
|
|
79
84
|
return __awaiter(this, void 0, void 0, function* () {
|
|
80
85
|
const projectRoot = yield (0, getProjectRoot_1.getProjectRoot)();
|
|
81
86
|
const lintFileLocation = projectRoot || os_1.default.homedir();
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
const lintFilePath = path_1.default.join(lintFileLocation, '.sasjslint');
|
|
88
|
+
const configuration = yield (0, file_1.readFile)(lintFilePath).catch((_) => null);
|
|
89
|
+
if (configuration === null) {
|
|
90
|
+
return new LintConfig_1.LintConfig(exports.DefaultLintConfiguration);
|
|
91
|
+
}
|
|
92
|
+
return new LintConfig_1.LintConfig((0, exports.parseLintConfig)(configuration, lintFilePath));
|
|
86
93
|
});
|
|
87
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Reads the configuration file, turning a parse failure into a message that
|
|
97
|
+
* names the file and says what to do about it. A raw `JSON.parse` error reads
|
|
98
|
+
* `Unexpected token } in JSON at position 12`, which leaves the reader to work
|
|
99
|
+
* out which file was read and why JSON is involved at all.
|
|
100
|
+
*/
|
|
101
|
+
const parseLintConfig = (configuration, filePath) => {
|
|
102
|
+
try {
|
|
103
|
+
return JSON.parse(configuration);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
107
|
+
throw new Error(`${filePath} is not valid JSON (${reason}).\n` +
|
|
108
|
+
'The file is read as strict JSON, so it cannot carry comments. ' +
|
|
109
|
+
'Every setting, its type and its default are documented in the schema: ' +
|
|
110
|
+
'https://cli.sasjs.io/sasjslint-schema.json');
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
exports.parseLintConfig = parseLintConfig;
|
|
88
114
|
//# sourceMappingURL=getLintConfig.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLintConfig.js","sourceRoot":"","sources":["../../src/utils/getLintConfig.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"getLintConfig.js","sourceRoot":"","sources":["../../src/utils/getLintConfig.ts"],"names":[],"mappings":"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"}
|