@pezkuwi/dev 0.86.3 → 0.86.4
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/cjs/packageInfo.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.packageInfo = void 0;
|
|
4
|
-
exports.packageInfo = { name: '@pezkuwi/dev', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '0.86.
|
|
4
|
+
exports.packageInfo = { name: '@pezkuwi/dev', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '0.86.4' };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Copyright 2017-2026 @pezkuwi/dev authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/** @type {Map<string, string>} */
|
|
5
|
+
const sources = new Map();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Widens the fix eslint core gives an unused disable directive.
|
|
9
|
+
*
|
|
10
|
+
* Core removes only the comment and puts a single space in its place
|
|
11
|
+
* (lib/linter/apply-disable-directives.js), so --fix turns
|
|
12
|
+
*
|
|
13
|
+
* const a = 1;
|
|
14
|
+
* // eslint-disable-next-line no-console
|
|
15
|
+
* const b = 2;
|
|
16
|
+
*
|
|
17
|
+
* into a whitespace-only line between the two statements, which the layout
|
|
18
|
+
* rules then leave behind as a blank line. Measured on the consumers after the
|
|
19
|
+
* eslint 10 move: 23 such lines in api alone, each removed by hand.
|
|
20
|
+
*
|
|
21
|
+
* Only a fix that removes a whole directive comment is changed: alone on its
|
|
22
|
+
* line, the line goes; after code, the space before it goes; before code, the
|
|
23
|
+
* space after it goes. Removing one rule name out of several is left as core
|
|
24
|
+
* makes it, as is every message with a rule id.
|
|
25
|
+
*
|
|
26
|
+
* @param {import('eslint').Linter.LintMessage} message
|
|
27
|
+
* @param {string} text the source the message was produced from
|
|
28
|
+
* @returns {import('eslint').Linter.LintMessage}
|
|
29
|
+
*/
|
|
30
|
+
function widenDirectiveFix (message, text) {
|
|
31
|
+
if (message.ruleId !== null || message.fix?.text.trim() !== '') {
|
|
32
|
+
return message;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let [start, end] = message.fix.range;
|
|
36
|
+
|
|
37
|
+
if (!/^\/[/*]/.test(text.slice(start, end))) {
|
|
38
|
+
return message;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const lineStart = text.lastIndexOf('\n', start - 1) + 1;
|
|
42
|
+
const newline = text.indexOf('\n', end);
|
|
43
|
+
const lineEnd = newline === -1 ? text.length : newline;
|
|
44
|
+
const aloneBefore = text.slice(lineStart, start).trim() === '';
|
|
45
|
+
const aloneAfter = text.slice(end, lineEnd).trim() === '';
|
|
46
|
+
|
|
47
|
+
if (aloneBefore && aloneAfter) {
|
|
48
|
+
return { ...message, fix: { range: [lineStart, newline === -1 ? text.length : newline + 1], text: '' } };
|
|
49
|
+
} else if (aloneBefore) {
|
|
50
|
+
while (end < lineEnd && /[ \t]/.test(text[end] ?? '')) {
|
|
51
|
+
end++;
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
while (start > lineStart && /[ \t]/.test(text[start - 1] ?? '')) {
|
|
55
|
+
start--;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { ...message, fix: { range: [start, end], text: '' } };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** @type {import('eslint').Linter.Processor} */
|
|
63
|
+
export const directiveLines = {
|
|
64
|
+
meta: { name: '@pezkuwi/dev/directive-lines' },
|
|
65
|
+
postprocess (lists, filename) {
|
|
66
|
+
const text = sources.get(filename) ?? '';
|
|
67
|
+
|
|
68
|
+
sources.delete(filename);
|
|
69
|
+
|
|
70
|
+
return lists.flat().map((m) => widenDirectiveFix(m, text));
|
|
71
|
+
},
|
|
72
|
+
preprocess (text, filename) {
|
|
73
|
+
sources.set(filename, text);
|
|
74
|
+
|
|
75
|
+
return [text];
|
|
76
|
+
},
|
|
77
|
+
supportsAutofix: true
|
|
78
|
+
};
|
package/config/eslint.js
CHANGED
|
@@ -22,9 +22,11 @@ import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
|
|
|
22
22
|
import sortDestructureKeysPlugin from 'eslint-plugin-sort-destructure-keys';
|
|
23
23
|
import globals from 'globals';
|
|
24
24
|
|
|
25
|
+
import { directiveLines } from './eslint.directives.js';
|
|
25
26
|
import { overrideAll, overrideJs, overrideJsx, overrideSpec } from './eslint.rules.js';
|
|
26
27
|
import { standardRules } from './eslint.standard.js';
|
|
27
28
|
import { withoutContextualAssertions } from './eslint.typeAssertion.js';
|
|
29
|
+
import { withoutExportAllFix } from './eslint.typeExports.js';
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* eslint-plugin-header declares no options schema, and eslint 9+ rejects
|
|
@@ -94,8 +96,8 @@ export default [
|
|
|
94
96
|
},
|
|
95
97
|
plugins: {
|
|
96
98
|
'@stylistic': stylisticPlugin,
|
|
97
|
-
// see eslint.typeAssertion.js
|
|
98
|
-
'@typescript-eslint': withoutContextualAssertions(tsPlugin),
|
|
99
|
+
// see eslint.typeAssertion.js and eslint.typeExports.js
|
|
100
|
+
'@typescript-eslint': withoutExportAllFix(withoutContextualAssertions(tsPlugin)),
|
|
99
101
|
// eslint-plugin-header reports at the first token after the leading
|
|
100
102
|
// comments, so a generated file's /* eslint-disable */ covers it; the
|
|
101
103
|
// maintained fork reports at line 1 instead. The compat layer supplies the
|
|
@@ -126,6 +128,8 @@ export default [
|
|
|
126
128
|
},
|
|
127
129
|
{
|
|
128
130
|
files: extsToGlobs(EXT_ALL),
|
|
131
|
+
// see eslint.directives.js
|
|
132
|
+
processor: directiveLines,
|
|
129
133
|
rules: {
|
|
130
134
|
...eslintJs.configs.recommended.rules,
|
|
131
135
|
...standardRules,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright 2017-2026 @pezkuwi/dev authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
const RULE = 'consistent-type-exports';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* consistent-type-exports reports an `export * from './x'` whose module only
|
|
8
|
+
* exports types, and its autofix turns it into `export type * from './x'`.
|
|
9
|
+
* That changes what runs: `export *` loads the module, `export type *` is
|
|
10
|
+
* erased, so a module that only exports types but registers something when it
|
|
11
|
+
* loads (a Handlebars partial, an interface augmentation) silently stops being
|
|
12
|
+
* loaded. Measured on the consumers: the api typegen lost its `docs` partial
|
|
13
|
+
* this way and the build failed only at template time.
|
|
14
|
+
*
|
|
15
|
+
* Named re-exports do not have this problem: under verbatimModuleSyntax a
|
|
16
|
+
* type re-exported without `type` is already a compile error (TS1205).
|
|
17
|
+
*
|
|
18
|
+
* This keeps the report as it is and moves the `export *` fix into a
|
|
19
|
+
* suggestion, so --fix no longer applies it and an editor still offers it.
|
|
20
|
+
* Whoever accepts it decides whether the module needs a side-effect import.
|
|
21
|
+
*
|
|
22
|
+
* @template {object} P
|
|
23
|
+
* @param {P} plugin the @typescript-eslint plugin
|
|
24
|
+
* @returns {P}
|
|
25
|
+
*/
|
|
26
|
+
export function withoutExportAllFix (plugin) {
|
|
27
|
+
const rules = /** @type {Record<string, import('eslint').Rule.RuleModule>} */ (/** @type {{ rules: unknown }} */ (plugin).rules);
|
|
28
|
+
const rule = rules[RULE];
|
|
29
|
+
|
|
30
|
+
return /** @type {P} */ ({
|
|
31
|
+
...plugin,
|
|
32
|
+
rules: {
|
|
33
|
+
...rules,
|
|
34
|
+
[RULE]: {
|
|
35
|
+
...rule,
|
|
36
|
+
/** @param {import('eslint').Rule.RuleContext} context */
|
|
37
|
+
create (context) {
|
|
38
|
+
const filtered = Object.create(context, {
|
|
39
|
+
report: {
|
|
40
|
+
value: (/** @type {import('eslint').Rule.ReportDescriptor} */ descriptor) => {
|
|
41
|
+
if ('node' in descriptor && descriptor.node.type === 'ExportAllDeclaration' && descriptor.fix) {
|
|
42
|
+
const { fix, ...rest } = descriptor;
|
|
43
|
+
|
|
44
|
+
context.report({
|
|
45
|
+
...rest,
|
|
46
|
+
suggest: [{ desc: 'Use `export type *` (the module is no longer loaded: add a side-effect import if it registers anything)', fix }]
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
context.report(descriptor);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return rule.create(filtered);
|
|
58
|
+
},
|
|
59
|
+
meta: { ...rule.meta, hasSuggestions: true }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"sideEffects": false,
|
|
17
17
|
"type": "module",
|
|
18
|
-
"version": "0.86.
|
|
18
|
+
"version": "0.86.4",
|
|
19
19
|
"bin": {
|
|
20
20
|
"pezkuwi-ci-ghact-build": "./scripts/pezkuwi-ci-ghact-build.mjs",
|
|
21
21
|
"pezkuwi-ci-ghact-docs": "./scripts/pezkuwi-ci-ghact-docs.mjs",
|
|
@@ -63,9 +63,11 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"./config/eslint": "./config/eslint.js",
|
|
66
|
+
"./config/eslint.directives": "./config/eslint.directives.js",
|
|
66
67
|
"./config/eslint.rules": "./config/eslint.rules.js",
|
|
67
68
|
"./config/eslint.standard": "./config/eslint.standard.js",
|
|
68
69
|
"./config/eslint.typeAssertion": "./config/eslint.typeAssertion.js",
|
|
70
|
+
"./config/eslint.typeExports": "./config/eslint.typeExports.js",
|
|
69
71
|
"./config/prettier.cjs": "./config/prettier.cjs",
|
|
70
72
|
"./config/prettier": "./config/prettier.cjs",
|
|
71
73
|
"./config/rollup": "./config/rollup.js",
|
|
@@ -289,8 +291,8 @@
|
|
|
289
291
|
"dependencies": {
|
|
290
292
|
"@eslint/compat": "^2.1.1",
|
|
291
293
|
"@eslint/js": "^10.0.1",
|
|
292
|
-
"@pezkuwi/dev-test": "^0.86.
|
|
293
|
-
"@pezkuwi/dev-ts": "^0.86.
|
|
294
|
+
"@pezkuwi/dev-test": "^0.86.4",
|
|
295
|
+
"@pezkuwi/dev-ts": "^0.86.4",
|
|
294
296
|
"@rollup/plugin-alias": "^5.1.1",
|
|
295
297
|
"@rollup/plugin-commonjs": "^29.0.3",
|
|
296
298
|
"@rollup/plugin-dynamic-import-vars": "^2.1.5",
|
package/packageInfo.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const packageInfo = { name: '@pezkuwi/dev', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '0.86.
|
|
1
|
+
export const packageInfo = { name: '@pezkuwi/dev', path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '0.86.4' };
|
|
@@ -7,8 +7,6 @@ import yargs from 'yargs';
|
|
|
7
7
|
|
|
8
8
|
import { __dirname, execPm, GITHUB_REPO, logBin } from './util.mjs';
|
|
9
9
|
|
|
10
|
-
const TS_CONFIG_BUILD = true;
|
|
11
|
-
|
|
12
10
|
logBin('pezkuwi-dev-run-lint');
|
|
13
11
|
|
|
14
12
|
// Since yargs can also be a promise, we just relax the type here completely
|
|
@@ -36,5 +34,11 @@ if (!argv['skip-eslint']) {
|
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
if (!argv['skip-tsc']) {
|
|
39
|
-
|
|
37
|
+
// The root tsconfig.build.json has `files: []` and only references the
|
|
38
|
+
// packages, so `tsc --project` on it checks no file at all. --build follows
|
|
39
|
+
// the references; it cannot be combined with --noEmit, so it writes the
|
|
40
|
+
// declarations the build would. Previous build output is removed first, since
|
|
41
|
+
// package configs without an `include` would otherwise pick it up as source.
|
|
42
|
+
execPm('pezkuwi-dev-clean-build');
|
|
43
|
+
execPm('pezkuwi-exec-tsc --build tsconfig.build.json --pretty');
|
|
40
44
|
}
|