podlite 0.0.79 → 0.0.81
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.podlite +34 -0
- package/esm/cli.js +79 -11
- package/esm/cli.js.map +1 -1
- package/esm/lint/config.d.ts +2 -0
- package/esm/lint/config.js +46 -0
- package/esm/lint/config.js.map +1 -1
- package/esm/lint/grammar/lint.js +7 -4
- package/esm/lint/grammar/lint.js.map +1 -1
- package/esm/lint/grammar/scan.d.ts +1 -1
- package/esm/lint/grammar/scan.js +15 -2
- package/esm/lint/grammar/scan.js.map +1 -1
- package/esm/lint/index.d.ts +11 -1
- package/esm/lint/index.js +30 -18
- package/esm/lint/index.js.map +1 -1
- package/esm/lint/parallel.d.ts +4 -0
- package/esm/lint/parallel.js +57 -0
- package/esm/lint/parallel.js.map +1 -0
- package/esm/lint/rules/abbreviated-attrs.d.ts +4 -0
- package/esm/lint/rules/abbreviated-attrs.js +67 -0
- package/esm/lint/rules/abbreviated-attrs.js.map +1 -0
- package/esm/lint/rules/dead-definitions.d.ts +3 -0
- package/esm/lint/rules/dead-definitions.js +80 -0
- package/esm/lint/rules/dead-definitions.js.map +1 -0
- package/esm/lint/rules/index.js +6 -0
- package/esm/lint/rules/index.js.map +1 -1
- package/esm/lint/rules/link-file-resolves.d.ts +3 -0
- package/esm/lint/rules/link-file-resolves.js +58 -0
- package/esm/lint/rules/link-file-resolves.js.map +1 -0
- package/esm/lint/rules/link-not-empty.d.ts +3 -0
- package/esm/lint/rules/link-not-empty.js +15 -0
- package/esm/lint/rules/link-not-empty.js.map +1 -0
- package/esm/lint/rules/link-target-resolves.js +10 -28
- package/esm/lint/rules/link-target-resolves.js.map +1 -1
- package/esm/lint/rules/link-targets.d.ts +11 -0
- package/esm/lint/rules/link-targets.js +42 -0
- package/esm/lint/rules/link-targets.js.map +1 -0
- package/esm/lint/rules/markdown-in-pod.d.ts +4 -0
- package/esm/lint/rules/markdown-in-pod.js +67 -0
- package/esm/lint/rules/markdown-in-pod.js.map +1 -0
- package/esm/lint/rules/table-column-width.js +10 -6
- package/esm/lint/rules/table-column-width.js.map +1 -1
- package/esm/lint/rules/unclosed-markup-code.d.ts +4 -0
- package/esm/lint/rules/unclosed-markup-code.js +105 -0
- package/esm/lint/rules/unclosed-markup-code.js.map +1 -0
- package/esm/lint/types.d.ts +2 -0
- package/esm/lint/types.js +3 -1
- package/esm/lint/types.js.map +1 -1
- package/esm/lint/worker.d.ts +5 -0
- package/esm/lint/worker.js +15 -0
- package/esm/lint/worker.js.map +1 -0
- package/esm/query.js +4 -1
- package/esm/query.js.map +1 -1
- package/esm/resolve-includes.js +56 -7
- package/esm/resolve-includes.js.map +1 -1
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/lib/cli.js +78 -10
- package/lib/cli.js.map +1 -1
- package/lib/lint/config.d.ts +2 -0
- package/lib/lint/config.js +48 -0
- package/lib/lint/config.js.map +1 -1
- package/lib/lint/grammar/lint.js +7 -4
- package/lib/lint/grammar/lint.js.map +1 -1
- package/lib/lint/grammar/scan.d.ts +1 -1
- package/lib/lint/grammar/scan.js +14 -1
- package/lib/lint/grammar/scan.js.map +1 -1
- package/lib/lint/index.d.ts +11 -1
- package/lib/lint/index.js +69 -17
- package/lib/lint/index.js.map +1 -1
- package/lib/lint/parallel.d.ts +4 -0
- package/lib/lint/parallel.js +95 -0
- package/lib/lint/parallel.js.map +1 -0
- package/lib/lint/rules/abbreviated-attrs.d.ts +4 -0
- package/lib/lint/rules/abbreviated-attrs.js +71 -0
- package/lib/lint/rules/abbreviated-attrs.js.map +1 -0
- package/lib/lint/rules/dead-definitions.d.ts +3 -0
- package/lib/lint/rules/dead-definitions.js +83 -0
- package/lib/lint/rules/dead-definitions.js.map +1 -0
- package/lib/lint/rules/index.js +6 -0
- package/lib/lint/rules/index.js.map +1 -1
- package/lib/lint/rules/link-file-resolves.d.ts +3 -0
- package/lib/lint/rules/link-file-resolves.js +61 -0
- package/lib/lint/rules/link-file-resolves.js.map +1 -0
- package/lib/lint/rules/link-not-empty.d.ts +3 -0
- package/lib/lint/rules/link-not-empty.js +18 -0
- package/lib/lint/rules/link-not-empty.js.map +1 -0
- package/lib/lint/rules/link-target-resolves.js +9 -27
- package/lib/lint/rules/link-target-resolves.js.map +1 -1
- package/lib/lint/rules/link-targets.d.ts +11 -0
- package/lib/lint/rules/link-targets.js +47 -0
- package/lib/lint/rules/link-targets.js.map +1 -0
- package/lib/lint/rules/markdown-in-pod.d.ts +4 -0
- package/lib/lint/rules/markdown-in-pod.js +71 -0
- package/lib/lint/rules/markdown-in-pod.js.map +1 -0
- package/lib/lint/rules/table-column-width.js +9 -5
- package/lib/lint/rules/table-column-width.js.map +1 -1
- package/lib/lint/rules/unclosed-markup-code.d.ts +4 -0
- package/lib/lint/rules/unclosed-markup-code.js +109 -0
- package/lib/lint/rules/unclosed-markup-code.js.map +1 -0
- package/lib/lint/types.d.ts +2 -0
- package/lib/lint/types.js +4 -0
- package/lib/lint/types.js.map +1 -1
- package/lib/lint/worker.d.ts +5 -0
- package/lib/lint/worker.js +17 -0
- package/lib/lint/worker.js.map +1 -0
- package/lib/query.js +4 -1
- package/lib/query.js.map +1 -1
- package/lib/resolve-includes.js +55 -6
- package/lib/resolve-includes.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +13 -7
package/lib/lint/index.js
CHANGED
|
@@ -1,7 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
36
|
+
exports.readConfig = exports.findConfig = exports.ConfigError = void 0;
|
|
37
|
+
exports.lintSource = lintSource;
|
|
38
|
+
exports.lintFile = lintFile;
|
|
39
|
+
exports.resolveConfig = resolveConfig;
|
|
40
|
+
exports.reportLint = reportLint;
|
|
4
41
|
exports.runLint = runLint;
|
|
42
|
+
const path = __importStar(require("path"));
|
|
5
43
|
const syntax_valid_1 = require("./rules/syntax-valid");
|
|
6
44
|
const rules_1 = require("./rules");
|
|
7
45
|
const engine_1 = require("./engine");
|
|
@@ -10,15 +48,19 @@ const text_1 = require("./formatters/text");
|
|
|
10
48
|
const json_1 = require("./formatters/json");
|
|
11
49
|
const scan_1 = require("./grammar/scan");
|
|
12
50
|
const config_1 = require("./config");
|
|
51
|
+
const types_1 = require("./types");
|
|
13
52
|
const mute_1 = require("./mute");
|
|
53
|
+
var config_2 = require("./config");
|
|
54
|
+
Object.defineProperty(exports, "ConfigError", { enumerable: true, get: function () { return config_2.ConfigError; } });
|
|
55
|
+
Object.defineProperty(exports, "findConfig", { enumerable: true, get: function () { return config_2.findConfig; } });
|
|
56
|
+
Object.defineProperty(exports, "readConfig", { enumerable: true, get: function () { return config_2.readConfig; } });
|
|
14
57
|
// text handed to the command instead of a path is reported under this name
|
|
15
|
-
exports.STDIN_NAME = '<stdin>';
|
|
16
58
|
function lintSource(content, filePath, config) {
|
|
17
|
-
const violations = [...(0, config_1.applyConfig)((0, scan_1.scanSourceRules)(content), config)];
|
|
18
59
|
const fileType = (0, loader_1.detectFileType)(filePath);
|
|
60
|
+
const violations = [...(0, config_1.applyConfig)((0, scan_1.scanSourceRules)(content, fileType), config)];
|
|
19
61
|
try {
|
|
20
62
|
const ast = (0, loader_1.parseContent)(content, fileType);
|
|
21
|
-
const ctx = { filePath, fileType, config };
|
|
63
|
+
const ctx = { filePath, fileType, config, source: content };
|
|
22
64
|
violations.push(...(0, engine_1.runRules)(ast, rules_1.DEFAULT_RULES, ctx));
|
|
23
65
|
const muted = (0, mute_1.applyMutes)(violations, ast);
|
|
24
66
|
return { filePath, violations: (0, config_1.applyConfig)(muted.kept, config), silenced: muted.silenced };
|
|
@@ -47,10 +89,30 @@ function lintFile(filePath, config) {
|
|
|
47
89
|
}
|
|
48
90
|
return lintSource(content, filePath, config);
|
|
49
91
|
}
|
|
92
|
+
// Thrown out of resolveConfig so a caller can turn it into exit code 2 wherever
|
|
93
|
+
// the run is scheduled from.
|
|
94
|
+
function resolveConfig(files, options) {
|
|
95
|
+
const searchFrom = files.length > 0 ? path.dirname(path.resolve(files[0])) : process.cwd();
|
|
96
|
+
const configPath = options.configPath || (0, config_1.findConfig)(searchFrom);
|
|
97
|
+
return (0, config_1.applyRuleFlags)((0, config_1.readConfig)(configPath), options.enable || [], options.disable || []);
|
|
98
|
+
}
|
|
99
|
+
function reportLint(reports, options) {
|
|
100
|
+
const output = options.format === 'json' ? (0, json_1.formatJson)(reports) : (0, text_1.formatText)(reports, { color: process.stdout.isTTY === true });
|
|
101
|
+
if (output)
|
|
102
|
+
process.stdout.write(output);
|
|
103
|
+
const totals = reports.flatMap(r => r.violations);
|
|
104
|
+
const hasError = totals.some(v => v.severity === 'error');
|
|
105
|
+
const hasWarning = totals.some(v => v.severity === 'warning');
|
|
106
|
+
if (hasError)
|
|
107
|
+
return 1;
|
|
108
|
+
if (options.strict && hasWarning)
|
|
109
|
+
return 1;
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
50
112
|
function runLint(files, options) {
|
|
51
113
|
let config;
|
|
52
114
|
try {
|
|
53
|
-
config = (
|
|
115
|
+
config = resolveConfig(files, options);
|
|
54
116
|
}
|
|
55
117
|
catch (e) {
|
|
56
118
|
if (!(e instanceof config_1.ConfigError))
|
|
@@ -60,18 +122,8 @@ function runLint(files, options) {
|
|
|
60
122
|
}
|
|
61
123
|
const reports = files.map(filePath => lintFile(filePath, config));
|
|
62
124
|
if (options.stdinContent !== undefined) {
|
|
63
|
-
reports.push(lintSource(options.stdinContent,
|
|
125
|
+
reports.push(lintSource(options.stdinContent, types_1.STDIN_NAME, config));
|
|
64
126
|
}
|
|
65
|
-
|
|
66
|
-
if (output)
|
|
67
|
-
process.stdout.write(output);
|
|
68
|
-
const totals = reports.flatMap(r => r.violations);
|
|
69
|
-
const hasError = totals.some(v => v.severity === 'error');
|
|
70
|
-
const hasWarning = totals.some(v => v.severity === 'warning');
|
|
71
|
-
if (hasError)
|
|
72
|
-
return 1;
|
|
73
|
-
if (options.strict && hasWarning)
|
|
74
|
-
return 1;
|
|
75
|
-
return 0;
|
|
127
|
+
return reportLint(reports, options);
|
|
76
128
|
}
|
|
77
129
|
//# sourceMappingURL=index.js.map
|
package/lib/lint/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lint/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.worthThreads = void 0;
|
|
37
|
+
exports.lintFilesInParallel = lintFilesInParallel;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const worker_threads_1 = require("worker_threads");
|
|
42
|
+
const index_1 = require("./index");
|
|
43
|
+
// Measured on a 126-file corpus: reading takes 5 ms and parsing 1032 ms, so the
|
|
44
|
+
// work is bound by the processor and threads are what buys anything. Eight of
|
|
45
|
+
// them start in 80 ms together, which pays for itself only on a longer list.
|
|
46
|
+
const MIN_FILES = 12;
|
|
47
|
+
const threadCount = (files) => Math.max(2, Math.min(os.cpus().length - 2, 8, Math.floor(files / 4)));
|
|
48
|
+
const workerFile = () => {
|
|
49
|
+
const candidate = path.join(__dirname, 'worker.js');
|
|
50
|
+
return fs.existsSync(candidate) ? candidate : undefined;
|
|
51
|
+
};
|
|
52
|
+
const worthThreads = (files) => files.length >= MIN_FILES && workerFile() !== undefined;
|
|
53
|
+
exports.worthThreads = worthThreads;
|
|
54
|
+
// Reports come back in the order the files were given, whichever thread got
|
|
55
|
+
// there first: the report is read by a person and by a snapshot test, and both
|
|
56
|
+
// expect the order they asked for.
|
|
57
|
+
function lintFilesInParallel(files, config) {
|
|
58
|
+
const script = workerFile();
|
|
59
|
+
if (!script)
|
|
60
|
+
return Promise.resolve(files.map(f => (0, index_1.lintFile)(f, config)));
|
|
61
|
+
const threads = threadCount(files.length);
|
|
62
|
+
const jobs = files.map((filePath, index) => ({ index, filePath }));
|
|
63
|
+
const chunks = Array.from({ length: threads }, () => []);
|
|
64
|
+
jobs.forEach(job => chunks[job.index % threads].push(job));
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const collected = new Array(files.length);
|
|
67
|
+
const workers = [];
|
|
68
|
+
let finished = 0;
|
|
69
|
+
let failed = false;
|
|
70
|
+
const stop = () => workers.forEach(w => void w.terminate());
|
|
71
|
+
for (let i = 0; i < threads; i++) {
|
|
72
|
+
const worker = new worker_threads_1.Worker(script);
|
|
73
|
+
workers.push(worker);
|
|
74
|
+
worker.on('message', (message) => {
|
|
75
|
+
if (message === 'ready') {
|
|
76
|
+
worker.postMessage({ config, jobs: chunks[i] });
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
for (const item of message)
|
|
80
|
+
collected[item.index] = item.report;
|
|
81
|
+
void worker.terminate();
|
|
82
|
+
if (++finished === threads && !failed)
|
|
83
|
+
resolve(collected);
|
|
84
|
+
});
|
|
85
|
+
worker.on('error', err => {
|
|
86
|
+
if (failed)
|
|
87
|
+
return;
|
|
88
|
+
failed = true;
|
|
89
|
+
stop();
|
|
90
|
+
reject(err);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=parallel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parallel.js","sourceRoot":"","sources":["../../src/lint/parallel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.abbreviatedAttrsRule = exports.ABBREVIATED_ATTRS_RULE_ID = void 0;
|
|
4
|
+
exports.scanAbbreviatedAttrs = scanAbbreviatedAttrs;
|
|
5
|
+
const schema_1 = require("@podlite/schema");
|
|
6
|
+
exports.ABBREVIATED_ATTRS_RULE_ID = 'abbreviated-attrs';
|
|
7
|
+
exports.abbreviatedAttrsRule = {
|
|
8
|
+
id: exports.ABBREVIATED_ATTRS_RULE_ID,
|
|
9
|
+
severity: 'warning',
|
|
10
|
+
};
|
|
11
|
+
// The specification is plain about it: the rest of an abbreviated block's line
|
|
12
|
+
// is block data, not configuration. What the author wrote as an attribute
|
|
13
|
+
// arrives as text, the markup stays legal, and nothing says the mechanism did
|
|
14
|
+
// not run.
|
|
15
|
+
const ABBREVIATED = /^\s*=([A-Za-z][\w-]*)[ \t]+(\S.*)$/;
|
|
16
|
+
const DELIMITED = /^\s*=(?:begin|end|for)[ \t]+([\w-]+)/;
|
|
17
|
+
// Only a line made of attributes and nothing else is reported. A line where
|
|
18
|
+
// attributes stand next to real text is the author writing prose that happens
|
|
19
|
+
// to hold a colon, and calling that a fault would bury the rule in noise.
|
|
20
|
+
const ONLY_ATTRIBUTES = /^(:[A-Za-z][\w-]*(<[^>]*>|\([^)]*\)|\{[^}]*\}|\[[^\]]*\])?[ \t]*)+$/;
|
|
21
|
+
// An attribute written with nothing inside documents the attribute itself,
|
|
22
|
+
// which is how the registries and the specifications spell one out.
|
|
23
|
+
const EMPTY_VALUE = /^:[A-Za-z][\w-]*<>$/;
|
|
24
|
+
const allEmpty = (rest) => rest
|
|
25
|
+
.trim()
|
|
26
|
+
.split(/[ \t]+/)
|
|
27
|
+
.every(part => EMPTY_VALUE.test(part));
|
|
28
|
+
function scanAbbreviatedAttrs(content) {
|
|
29
|
+
const lines = content.split(/\r?\n/);
|
|
30
|
+
const open = [];
|
|
31
|
+
const violations = [];
|
|
32
|
+
for (let i = 0; i < lines.length; i++) {
|
|
33
|
+
const line = lines[i];
|
|
34
|
+
const delimited = line.match(DELIMITED);
|
|
35
|
+
if (delimited) {
|
|
36
|
+
if (/^\s*=end\b/.test(line))
|
|
37
|
+
open.pop();
|
|
38
|
+
else if (/^\s*=begin\b/.test(line))
|
|
39
|
+
open.push(delimited[1]);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (open.some(schema_1.isVerbatimBlock))
|
|
43
|
+
continue;
|
|
44
|
+
const abbreviated = line.match(ABBREVIATED);
|
|
45
|
+
if (!abbreviated)
|
|
46
|
+
continue;
|
|
47
|
+
const [, name, rest] = abbreviated;
|
|
48
|
+
if ((0, schema_1.isVerbatimBlock)(name))
|
|
49
|
+
continue;
|
|
50
|
+
if (!ONLY_ATTRIBUTES.test(rest.trim()))
|
|
51
|
+
continue;
|
|
52
|
+
if (allEmpty(rest))
|
|
53
|
+
continue;
|
|
54
|
+
// content has to follow, otherwise the line is the whole block and the
|
|
55
|
+
// author wrote no data at all — a different mistake, if it is one
|
|
56
|
+
const next = lines[i + 1];
|
|
57
|
+
if (next === undefined || next.trim() === '' || /^\s*=/.test(next))
|
|
58
|
+
continue;
|
|
59
|
+
violations.push({
|
|
60
|
+
rule: exports.ABBREVIATED_ATTRS_RULE_ID,
|
|
61
|
+
severity: 'warning',
|
|
62
|
+
message: `=${name} takes the rest of its line as data, so ${rest.trim()} arrives as text; write =for ${name} to pass configuration`,
|
|
63
|
+
location: {
|
|
64
|
+
start: { line: i + 1, column: 1, offset: 0 },
|
|
65
|
+
end: { line: i + 1, column: 1, offset: 0 },
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return violations;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=abbreviated-attrs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abbreviated-attrs.js","sourceRoot":"","sources":["../../../src/lint/rules/abbreviated-attrs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deadDefinitionsRule = exports.DEAD_DEFINITIONS_RULE_ID = void 0;
|
|
4
|
+
const schema_1 = require("@podlite/schema");
|
|
5
|
+
exports.DEAD_DEFINITIONS_RULE_ID = 'dead-definitions';
|
|
6
|
+
const attr = (node, name) => {
|
|
7
|
+
const item = (Array.isArray(node.config) ? node.config : []).find(c => c && c.name === name);
|
|
8
|
+
return item && item.value !== undefined && item.value !== null ? String(item.value) : undefined;
|
|
9
|
+
};
|
|
10
|
+
// An alias node carries no location, so the line is read back from the source;
|
|
11
|
+
// a warning that cannot say where is a warning the author cannot act on.
|
|
12
|
+
const aliasLine = (source, name) => {
|
|
13
|
+
const lines = source.split(/\r?\n/);
|
|
14
|
+
const at = lines.findIndex(line => new RegExp(`^\\s*=alias\\s+${name}(\\s|$)`).test(line));
|
|
15
|
+
if (at === -1)
|
|
16
|
+
return undefined;
|
|
17
|
+
return { start: { line: at + 1, column: 1, offset: 0 }, end: { line: at + 1, column: 1, offset: 0 } };
|
|
18
|
+
};
|
|
19
|
+
const definitions = (ast) => {
|
|
20
|
+
const nodes = (0, schema_1.getFromTree)(ast, () => true);
|
|
21
|
+
const found = [];
|
|
22
|
+
for (const node of nodes) {
|
|
23
|
+
if (node.type === 'alias' && node.name) {
|
|
24
|
+
found.push({ kind: 'alias', name: node.name, location: node.location });
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (node.name === 'data') {
|
|
28
|
+
const key = attr(node, 'key');
|
|
29
|
+
if (key)
|
|
30
|
+
found.push({ kind: 'data', name: key, location: node.location });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return found;
|
|
34
|
+
};
|
|
35
|
+
const aliasUses = (ast) => {
|
|
36
|
+
const nodes = (0, schema_1.getFromTree)(ast, () => true);
|
|
37
|
+
const used = new Set();
|
|
38
|
+
for (const node of nodes) {
|
|
39
|
+
if (node.type !== 'fcode' || node.name !== 'A')
|
|
40
|
+
continue;
|
|
41
|
+
const name = (0, schema_1.getTextContentFromNode)(node)
|
|
42
|
+
?.toString()
|
|
43
|
+
.trim();
|
|
44
|
+
if (name)
|
|
45
|
+
used.add(name);
|
|
46
|
+
}
|
|
47
|
+
return used;
|
|
48
|
+
};
|
|
49
|
+
// A data reference is read from the source rather than from the tree: the block
|
|
50
|
+
// that consumes it resolves the reference while the tree is built, so by the
|
|
51
|
+
// time a rule sees the tree the mention is already gone.
|
|
52
|
+
const dataUses = (source) => {
|
|
53
|
+
const used = new Set();
|
|
54
|
+
const reference = /data:([A-Za-z0-9_-]+)/g;
|
|
55
|
+
let match;
|
|
56
|
+
while ((match = reference.exec(source)) !== null)
|
|
57
|
+
used.add(match[1]);
|
|
58
|
+
return used;
|
|
59
|
+
};
|
|
60
|
+
exports.deadDefinitionsRule = {
|
|
61
|
+
id: exports.DEAD_DEFINITIONS_RULE_ID,
|
|
62
|
+
severity: 'warning',
|
|
63
|
+
check: (ast, ctx) => {
|
|
64
|
+
// without the source a data reference cannot be found at all, and reporting
|
|
65
|
+
// every keyed block as dead would be worse than saying nothing
|
|
66
|
+
const declared = definitions(ast).filter(item => item.kind === 'alias' || ctx.source !== undefined);
|
|
67
|
+
if (declared.length === 0)
|
|
68
|
+
return [];
|
|
69
|
+
const aliases = aliasUses(ast);
|
|
70
|
+
const keys = dataUses(ctx.source || '');
|
|
71
|
+
return declared
|
|
72
|
+
.filter(item => !(item.kind === 'alias' ? aliases.has(item.name) : keys.has(item.name)))
|
|
73
|
+
.map(item => ({
|
|
74
|
+
rule: exports.DEAD_DEFINITIONS_RULE_ID,
|
|
75
|
+
severity: 'warning',
|
|
76
|
+
message: item.kind === 'alias'
|
|
77
|
+
? `=alias ${item.name} is never used; A<${item.name}> appears nowhere in the document`
|
|
78
|
+
: `=data :key<${item.name}> is never used; data:${item.name} appears nowhere in the document`,
|
|
79
|
+
location: item.location || (item.kind === 'alias' ? aliasLine(ctx.source || '', item.name) : undefined),
|
|
80
|
+
}));
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=dead-definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-definitions.js","sourceRoot":"","sources":["../../../src/lint/rules/dead-definitions.ts"],"names":[],"mappings":"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"}
|
package/lib/lint/rules/index.js
CHANGED
|
@@ -6,15 +6,21 @@ const heading_hierarchy_1 = require("./heading-hierarchy");
|
|
|
6
6
|
const id_unique_1 = require("./id-unique");
|
|
7
7
|
const media_absolute_file_1 = require("./media-absolute-file");
|
|
8
8
|
const link_target_resolves_1 = require("./link-target-resolves");
|
|
9
|
+
const link_file_resolves_1 = require("./link-file-resolves");
|
|
10
|
+
const link_not_empty_1 = require("./link-not-empty");
|
|
9
11
|
const attr_value_dropped_1 = require("./attr-value-dropped");
|
|
10
12
|
const table_shape_1 = require("./table-shape");
|
|
13
|
+
const dead_definitions_1 = require("./dead-definitions");
|
|
11
14
|
exports.DEFAULT_RULES = [
|
|
12
15
|
syntax_valid_1.syntaxValidRule,
|
|
13
16
|
heading_hierarchy_1.headingHierarchyRule,
|
|
14
17
|
id_unique_1.idUniqueRule,
|
|
15
18
|
media_absolute_file_1.mediaAbsoluteFileRule,
|
|
16
19
|
link_target_resolves_1.linkTargetResolvesRule,
|
|
20
|
+
link_file_resolves_1.linkFileResolvesRule,
|
|
21
|
+
link_not_empty_1.linkNotEmptyRule,
|
|
17
22
|
attr_value_dropped_1.attrValueDroppedRule,
|
|
18
23
|
table_shape_1.tableShapeRule,
|
|
24
|
+
dead_definitions_1.deadDefinitionsRule,
|
|
19
25
|
];
|
|
20
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lint/rules/index.ts"],"names":[],"mappings":";;;AACA,iDAAgD;AAChD,2DAA0D;AAC1D,2CAA0C;AAC1C,+DAA6D;AAC7D,iEAA+D;AAC/D,6DAA2D;AAC3D,+CAA8C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lint/rules/index.ts"],"names":[],"mappings":";;;AACA,iDAAgD;AAChD,2DAA0D;AAC1D,2CAA0C;AAC1C,+DAA6D;AAC7D,iEAA+D;AAC/D,6DAA2D;AAC3D,qDAAmD;AACnD,6DAA2D;AAC3D,+CAA8C;AAC9C,yDAAwD;AAE3C,QAAA,aAAa,GAAW;IACnC,8BAAe;IACf,wCAAoB;IACpB,wBAAY;IACZ,2CAAqB;IACrB,6CAAsB;IACtB,yCAAoB;IACpB,iCAAgB;IAChB,yCAAoB;IACpB,4BAAc;IACd,sCAAmB;CACpB,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.linkFileResolvesRule = exports.LINK_FILE_RESOLVES_RULE_ID = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
const link_targets_1 = require("./link-targets");
|
|
8
|
+
exports.LINK_FILE_RESOLVES_RULE_ID = 'link-file-resolves';
|
|
9
|
+
// Written with `./` or `../`, the author has declared a path as plainly as a
|
|
10
|
+
// scheme would. A bare word declares nothing in a Podlite document, though in a
|
|
11
|
+
// markdown one it is the ordinary way to write a relative link. A leading slash
|
|
12
|
+
// reads as the root of a site far more often than the root of a disk, so it is
|
|
13
|
+
// left to the author to say `file:` when a disk is what was meant.
|
|
14
|
+
const looksLikePath = (path) => path.startsWith('./') || path.startsWith('../');
|
|
15
|
+
// Relative targets are answered from the directory of the document, so a caller
|
|
16
|
+
// that passed a name rather than a path gets no answer at all: resolving it
|
|
17
|
+
// would silently measure whatever sits in the working directory instead.
|
|
18
|
+
const documentDirectory = (filePath) => {
|
|
19
|
+
if (filePath === types_1.STDIN_NAME)
|
|
20
|
+
return null;
|
|
21
|
+
const full = (0, path_1.resolve)(filePath);
|
|
22
|
+
if (!(0, fs_1.existsSync)(full) || !(0, fs_1.statSync)(full).isFile())
|
|
23
|
+
return null;
|
|
24
|
+
return (0, path_1.dirname)(full);
|
|
25
|
+
};
|
|
26
|
+
// A home-relative path answers differently on every machine, so a check of it
|
|
27
|
+
// would make the run depend on who is running it.
|
|
28
|
+
const isHomeRelative = (path) => path === '~' || path.startsWith('~/');
|
|
29
|
+
const candidatePath = (target, fileType) => {
|
|
30
|
+
if (!target || target.startsWith('#'))
|
|
31
|
+
return null;
|
|
32
|
+
const { scheme, path } = (0, link_targets_1.readAddress)(target);
|
|
33
|
+
if (scheme !== null && scheme !== 'file')
|
|
34
|
+
return null;
|
|
35
|
+
if (!path || isHomeRelative(path))
|
|
36
|
+
return null;
|
|
37
|
+
if (scheme === 'file')
|
|
38
|
+
return path;
|
|
39
|
+
if (path.startsWith('/'))
|
|
40
|
+
return null;
|
|
41
|
+
return fileType === 'md' || looksLikePath(path) ? path : null;
|
|
42
|
+
};
|
|
43
|
+
exports.linkFileResolvesRule = {
|
|
44
|
+
id: exports.LINK_FILE_RESOLVES_RULE_ID,
|
|
45
|
+
severity: 'warning',
|
|
46
|
+
check: (ast, ctx) => {
|
|
47
|
+
const base = documentDirectory(ctx.filePath);
|
|
48
|
+
if (base === null)
|
|
49
|
+
return [];
|
|
50
|
+
return (0, link_targets_1.collectLinks)(ast)
|
|
51
|
+
.map(site => ({ site, path: candidatePath(site.target, ctx.fileType) }))
|
|
52
|
+
.filter(({ path }) => path !== null && !(0, fs_1.existsSync)((0, path_1.isAbsolute)(path) ? path : (0, path_1.resolve)(base, path)))
|
|
53
|
+
.map(({ site }) => ({
|
|
54
|
+
rule: exports.LINK_FILE_RESOLVES_RULE_ID,
|
|
55
|
+
severity: 'warning',
|
|
56
|
+
message: `Link target ${site.target} is not there`,
|
|
57
|
+
location: site.at,
|
|
58
|
+
}));
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=link-file-resolves.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-file-resolves.js","sourceRoot":"","sources":["../../../src/lint/rules/link-file-resolves.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.linkNotEmptyRule = exports.LINK_NOT_EMPTY_RULE_ID = void 0;
|
|
4
|
+
const link_targets_1 = require("./link-targets");
|
|
5
|
+
exports.LINK_NOT_EMPTY_RULE_ID = 'link-not-empty';
|
|
6
|
+
exports.linkNotEmptyRule = {
|
|
7
|
+
id: exports.LINK_NOT_EMPTY_RULE_ID,
|
|
8
|
+
severity: 'error',
|
|
9
|
+
check: (ast, _ctx) => (0, link_targets_1.collectLinks)(ast)
|
|
10
|
+
.filter(({ target }) => target === '')
|
|
11
|
+
.map(({ at }) => ({
|
|
12
|
+
rule: exports.LINK_NOT_EMPTY_RULE_ID,
|
|
13
|
+
severity: 'error',
|
|
14
|
+
message: 'Link has no address to go to',
|
|
15
|
+
location: at,
|
|
16
|
+
})),
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=link-not-empty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-not-empty.js","sourceRoot":"","sources":["../../../src/lint/rules/link-not-empty.ts"],"names":[],"mappings":";;;AAEA,iDAA6C;AAEhC,QAAA,sBAAsB,GAAG,gBAAgB,CAAA;AAEzC,QAAA,gBAAgB,GAAS;IACpC,EAAE,EAAE,8BAAsB;IAC1B,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,CAAC,GAAoB,EAAE,IAAiB,EAAe,EAAE,CAC9D,IAAA,2BAAY,EAAC,GAAG,CAAC;SACd,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,KAAK,EAAE,CAAC;SACrC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAChB,IAAI,EAAE,8BAAsB;QAC5B,QAAQ,EAAE,OAAgB;QAC1B,OAAO,EAAE,8BAA8B;QACvC,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;CACR,CAAA"}
|
|
@@ -2,42 +2,24 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.linkTargetResolvesRule = exports.LINK_TARGET_RESOLVES_RULE_ID = void 0;
|
|
4
4
|
const schema_1 = require("@podlite/schema");
|
|
5
|
-
const
|
|
5
|
+
const link_targets_1 = require("./link-targets");
|
|
6
6
|
exports.LINK_TARGET_RESOLVES_RULE_ID = 'link-target-resolves';
|
|
7
|
-
// A link without display text carries the target in its content instead of meta.
|
|
8
|
-
const linkTarget = (node) => {
|
|
9
|
-
if (typeof node.meta === 'string')
|
|
10
|
-
return node.meta.trim();
|
|
11
|
-
const content = Array.isArray(node.content) ? node.content : [];
|
|
12
|
-
const first = content[0];
|
|
13
|
-
return typeof first === 'string' ? first.trim() : '';
|
|
14
|
-
};
|
|
15
|
-
// Inline nodes carry no location, so the nearest enclosing block supplies one.
|
|
16
|
-
const collectAnchors = (node, at) => {
|
|
17
|
-
if (Array.isArray(node))
|
|
18
|
-
return node.flatMap(child => collectAnchors(child, at));
|
|
19
|
-
if (!node || typeof node !== 'object')
|
|
20
|
-
return [];
|
|
21
|
-
const n = node;
|
|
22
|
-
const here = n.location || at;
|
|
23
|
-
const found = n.type === 'fcode' && (n.name === 'L' || n.name === 'W') ? [{ target: linkTarget(n), at: here }] : [];
|
|
24
|
-
return [...found, ...collectAnchors(n.content, here)];
|
|
25
|
-
};
|
|
26
7
|
exports.linkTargetResolvesRule = {
|
|
27
8
|
id: exports.LINK_TARGET_RESOLVES_RULE_ID,
|
|
28
9
|
severity: 'error',
|
|
29
10
|
check: (ast, _ctx) => {
|
|
30
|
-
|
|
11
|
+
// A bare # is left alone by the export — it is not a target and not a mistake —
|
|
12
|
+
// so the rule has nothing to say about it either.
|
|
13
|
+
const anchors = (0, link_targets_1.collectLinks)(ast).filter(({ target }) => target.startsWith('#') && target !== '#');
|
|
31
14
|
if (anchors.length === 0)
|
|
32
15
|
return [];
|
|
33
16
|
// Both ways an anchor can exist: written by the author as :id, or carried by a
|
|
34
17
|
// heading under its own name. Matched the way the exporter matches them.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
18
|
+
// Asked of the same binding the exporters ask, rather than worked out again here.
|
|
19
|
+
// Two answers to one question is how this rule came to call a link sound that the
|
|
20
|
+
// export could not resolve: it shaped both sides itself, and the export did not.
|
|
21
|
+
const index = (0, schema_1.buildBindingIndex)(ast);
|
|
22
|
+
const resolves = (target) => (0, schema_1.bindTarget)(target.slice(1), index).found;
|
|
41
23
|
return anchors
|
|
42
24
|
.filter(({ target }) => !resolves(target))
|
|
43
25
|
.map(({ target, at }) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-target-resolves.js","sourceRoot":"","sources":["../../../src/lint/rules/link-target-resolves.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"link-target-resolves.js","sourceRoot":"","sources":["../../../src/lint/rules/link-target-resolves.ts"],"names":[],"mappings":";;;AAAA,4CAAgF;AAEhF,iDAA6C;AAEhC,QAAA,4BAA4B,GAAG,sBAAsB,CAAA;AAErD,QAAA,sBAAsB,GAAS;IAC1C,EAAE,EAAE,oCAA4B;IAChC,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,CAAC,GAAoB,EAAE,IAAiB,EAAe,EAAE;QAC9D,gFAAgF;QAChF,kDAAkD;QAClD,MAAM,OAAO,GAAG,IAAA,2BAAY,EAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,KAAK,GAAG,CAAC,CAAA;QAClG,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAA;QACnC,+EAA+E;QAC/E,yEAAyE;QACzE,kFAAkF;QAClF,kFAAkF;QAClF,iFAAiF;QACjF,MAAM,KAAK,GAAG,IAAA,0BAAiB,EAAC,GAAG,CAAC,CAAA;QACpC,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAW,EAAE,CAAC,IAAA,mBAAU,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAA;QACtF,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;aACzC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YACxB,IAAI,EAAE,oCAA4B;YAClC,QAAQ,EAAE,OAAgB;YAC1B,OAAO,EAAE,eAAe,MAAM,gCAAgC;YAC9D,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC,CAAA;IACP,CAAC;CACF,CAAA"}
|