@markuplint/file-resolver 5.1.1 → 5.3.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 +21 -0
- package/lib/auto-load-rules.d.ts +1 -0
- package/lib/auto-load-rules.js +37 -42
- package/lib/config-provider.d.ts +12 -9
- package/lib/config-provider.js +18 -11
- package/lib/debug.d.ts +4 -0
- package/lib/debug.js +4 -0
- package/lib/resolve-pretenders.d.ts +14 -15
- package/lib/resolve-pretenders.js +22 -17
- package/package.json +22 -22
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [5.3.0](https://github.com/markuplint/markuplint/compare/v5.2.0...v5.3.0) (2026-10-21)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **file-resolver:** cache the auto-load promise so a mid-load cache clear is not undone ([1f1b40e](https://github.com/markuplint/markuplint/commit/1f1b40e4020dfe51310f73e7c89bc887a4ad04d4))
|
|
11
|
+
* **file-resolver:** pass the working directory to the lint-time disambiguation ([542cc62](https://github.com/markuplint/markuplint/commit/542cc6272ab8922116bda7d87bb4c9ccb984c3f1)), closes [#4269](https://github.com/markuplint/markuplint/issues/4269)
|
|
12
|
+
* **file-resolver:** resolve a lone scanned component against the file's imports ([c37e922](https://github.com/markuplint/markuplint/commit/c37e922eed92876dd963dd74e9990a4a0da68ccc))
|
|
13
|
+
* make published packages loadable from require() and put types first ([723106f](https://github.com/markuplint/markuplint/commit/723106f51aac4e60dc02db2c1a894617368b0253)), closes [#4198](https://github.com/markuplint/markuplint/issues/4198)
|
|
14
|
+
|
|
15
|
+
### Performance Improvements
|
|
16
|
+
|
|
17
|
+
* **file-resolver:** cache auto-load misses to skip repeated module resolution ([91931ca](https://github.com/markuplint/markuplint/commit/91931caf078c815c0e456dde51f0230b6d782c9d))
|
|
18
|
+
* **file-resolver:** group the config search debug calls under one guard ([0353e02](https://github.com/markuplint/markuplint/commit/0353e029f79471b8b5495a4ae83edea58ab8cfe3))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# [5.2.0](https://github.com/markuplint/markuplint/compare/v5.1.1...v5.2.0) (2026-10-13)
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
- use caret ranges for third-party dependencies of published packages ([5fb5d2e](https://github.com/markuplint/markuplint/commit/5fb5d2ee81eaeea45fe7256a40dd41c95ff0d672))
|
|
26
|
+
|
|
6
27
|
## [5.1.1](https://github.com/markuplint/markuplint/compare/v5.1.0...v5.1.1) (2026-10-09)
|
|
7
28
|
|
|
8
29
|
### Bug Fixes
|
package/lib/auto-load-rules.d.ts
CHANGED
package/lib/auto-load-rules.js
CHANGED
|
@@ -1,58 +1,53 @@
|
|
|
1
1
|
import { MLRule } from '@markuplint/ml-core';
|
|
2
|
+
/**
|
|
3
|
+
* Keyed by rule name, holding the in-flight or settled load. A miss stays
|
|
4
|
+
* cached (`rule: null`, with the errors each probe raised) until
|
|
5
|
+
* {@link clearAutoLoadRulesCache}: this runs once per linted file and built-in
|
|
6
|
+
* rule names never resolve to a package, so re-probing would cost two failing
|
|
7
|
+
* imports per rule per file. Same lifetime policy as `generalImport`'s cache,
|
|
8
|
+
* which never retries a miss either.
|
|
9
|
+
*
|
|
10
|
+
* The entry is set synchronously before the first `await`, so a
|
|
11
|
+
* `clearAutoLoadRulesCache()` that lands mid-load evicts the promise and the
|
|
12
|
+
* eventual result is never written back into the fresh map.
|
|
13
|
+
*/
|
|
2
14
|
const cache = new Map();
|
|
15
|
+
export function clearAutoLoadRulesCache() {
|
|
16
|
+
cache.clear();
|
|
17
|
+
}
|
|
3
18
|
export async function autoLoadRules(ruleset) {
|
|
4
19
|
const rules = [];
|
|
5
20
|
const errors = [];
|
|
6
21
|
for (const ruleName of Object.keys(ruleset.rules)) {
|
|
7
|
-
|
|
8
|
-
if (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
let seed = null;
|
|
13
|
-
try {
|
|
14
|
-
const _module = await import(`@markuplint/rule-${ruleName}`);
|
|
15
|
-
seed = _module.default;
|
|
16
|
-
if (!(seed && 'defaultValue' in seed && 'defaultOptions' in seed && 'verify' in seed)) {
|
|
17
|
-
seed = null;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
errors.push(error);
|
|
22
|
+
let loading = cache.get(ruleName);
|
|
23
|
+
if (!loading) {
|
|
24
|
+
loading = load(ruleName);
|
|
25
|
+
cache.set(ruleName, loading);
|
|
22
26
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
...seed,
|
|
27
|
-
});
|
|
28
|
-
cache.set(ruleName, rule);
|
|
29
|
-
rules.push(rule);
|
|
30
|
-
continue;
|
|
27
|
+
const loaded = await loading;
|
|
28
|
+
if (loaded.rule) {
|
|
29
|
+
rules.push(loaded.rule);
|
|
31
30
|
}
|
|
31
|
+
errors.push(...loaded.errors);
|
|
32
|
+
}
|
|
33
|
+
return { rules, errors };
|
|
34
|
+
}
|
|
35
|
+
async function load(ruleName) {
|
|
36
|
+
const errors = [];
|
|
37
|
+
for (const specifier of [`@markuplint/rule-${ruleName}`, `markuplint-rule-${ruleName}`]) {
|
|
32
38
|
try {
|
|
33
|
-
const
|
|
34
|
-
seed =
|
|
35
|
-
if (
|
|
36
|
-
seed
|
|
39
|
+
const mod = await import(specifier);
|
|
40
|
+
const seed = mod.default;
|
|
41
|
+
if (isRuleSeed(seed)) {
|
|
42
|
+
return { rule: new MLRule({ name: ruleName, ...seed }), errors };
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
45
|
catch (error) {
|
|
40
46
|
errors.push(error);
|
|
41
47
|
}
|
|
42
|
-
if (seed) {
|
|
43
|
-
const rule = new MLRule({
|
|
44
|
-
name: ruleName,
|
|
45
|
-
...seed,
|
|
46
|
-
});
|
|
47
|
-
cache.set(ruleName, rule);
|
|
48
|
-
rules.push(rule);
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
48
|
}
|
|
52
|
-
return {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
errors: [...errors],
|
|
57
|
-
};
|
|
49
|
+
return { rule: null, errors };
|
|
50
|
+
}
|
|
51
|
+
function isRuleSeed(seed) {
|
|
52
|
+
return !!seed && typeof seed === 'object' && 'defaultValue' in seed && 'defaultOptions' in seed && 'verify' in seed;
|
|
58
53
|
}
|
package/lib/config-provider.d.ts
CHANGED
|
@@ -21,16 +21,19 @@ export declare class ConfigProvider {
|
|
|
21
21
|
* Clears every cached and stored config entry: the base-config cache
|
|
22
22
|
* (`#cache`), the loaded/registered config store (`#store`), `set()`'s
|
|
23
23
|
* identity→key stabilization (`#autoKeys`), `resolve-plugins.ts`'s own
|
|
24
|
-
* module-level plugin-resolution cache,
|
|
25
|
-
* explorer's own search/load caches
|
|
26
|
-
* after this, re-reads the current file
|
|
27
|
-
* cosmiconfig-level cache).
|
|
24
|
+
* module-level plugin-resolution cache, `auto-load-rules.ts`'s rule
|
|
25
|
+
* cache, and the shared `cosmiconfig` explorer's own search/load caches
|
|
26
|
+
* (so {@link search}, called right after this, re-reads the current file
|
|
27
|
+
* content instead of a stale cosmiconfig-level cache).
|
|
28
28
|
*
|
|
29
|
-
* The `cosmiconfig` explorer and the `resolve-plugins.ts`
|
|
30
|
-
* module-level singletons shared by every
|
|
31
|
-
* the process — clearing them here affects
|
|
32
|
-
*
|
|
33
|
-
*
|
|
29
|
+
* The `cosmiconfig` explorer and the `resolve-plugins.ts` /
|
|
30
|
+
* `auto-load-rules.ts` caches are module-level singletons shared by every
|
|
31
|
+
* `ConfigProvider` instance in the process — clearing them here affects
|
|
32
|
+
* other instances too, not just this one. Correctness is unaffected (they
|
|
33
|
+
* just re-search/re-load), but the auto-load cache holds a miss for every
|
|
34
|
+
* built-in rule name, so the first lint after a clear repeats two failing
|
|
35
|
+
* imports per rule — worth knowing when reasoning about a cache-busting
|
|
36
|
+
* re-resolve's blast radius.
|
|
34
37
|
*
|
|
35
38
|
* Callers doing a cache-busting re-resolve (e.g. watch mode after a file
|
|
36
39
|
* change) must call this **before** registering any inline config via
|
package/lib/config-provider.js
CHANGED
|
@@ -3,6 +3,7 @@ import { mergeConfig } from '@markuplint/ml-config';
|
|
|
3
3
|
import { ConfigParserError } from '@markuplint/parser-utils';
|
|
4
4
|
import { InvalidSelectorError, createSelector } from '@markuplint/selector';
|
|
5
5
|
import { nonNullableFilter, toNoEmptyStringArrayFromStringOrArray, ConfigLoadError } from '@markuplint/shared';
|
|
6
|
+
import { clearAutoLoadRulesCache } from './auto-load-rules.js';
|
|
6
7
|
import { load as loadConfig, search, clearExplorerCache } from './cosmiconfig.js';
|
|
7
8
|
import { log } from './debug.js';
|
|
8
9
|
import { generalImport } from './general-import.js';
|
|
@@ -52,16 +53,19 @@ export class ConfigProvider {
|
|
|
52
53
|
* Clears every cached and stored config entry: the base-config cache
|
|
53
54
|
* (`#cache`), the loaded/registered config store (`#store`), `set()`'s
|
|
54
55
|
* identity→key stabilization (`#autoKeys`), `resolve-plugins.ts`'s own
|
|
55
|
-
* module-level plugin-resolution cache,
|
|
56
|
-
* explorer's own search/load caches
|
|
57
|
-
* after this, re-reads the current file
|
|
58
|
-
* cosmiconfig-level cache).
|
|
56
|
+
* module-level plugin-resolution cache, `auto-load-rules.ts`'s rule
|
|
57
|
+
* cache, and the shared `cosmiconfig` explorer's own search/load caches
|
|
58
|
+
* (so {@link search}, called right after this, re-reads the current file
|
|
59
|
+
* content instead of a stale cosmiconfig-level cache).
|
|
59
60
|
*
|
|
60
|
-
* The `cosmiconfig` explorer and the `resolve-plugins.ts`
|
|
61
|
-
* module-level singletons shared by every
|
|
62
|
-
* the process — clearing them here affects
|
|
63
|
-
*
|
|
64
|
-
*
|
|
61
|
+
* The `cosmiconfig` explorer and the `resolve-plugins.ts` /
|
|
62
|
+
* `auto-load-rules.ts` caches are module-level singletons shared by every
|
|
63
|
+
* `ConfigProvider` instance in the process — clearing them here affects
|
|
64
|
+
* other instances too, not just this one. Correctness is unaffected (they
|
|
65
|
+
* just re-search/re-load), but the auto-load cache holds a miss for every
|
|
66
|
+
* built-in rule name, so the first lint after a clear repeats two failing
|
|
67
|
+
* imports per rule — worth knowing when reasoning about a cache-busting
|
|
68
|
+
* re-resolve's blast radius.
|
|
65
69
|
*
|
|
66
70
|
* Callers doing a cache-busting re-resolve (e.g. watch mode after a file
|
|
67
71
|
* change) must call this **before** registering any inline config via
|
|
@@ -77,6 +81,7 @@ export class ConfigProvider {
|
|
|
77
81
|
this.#cache.clear();
|
|
78
82
|
this.#autoKeys = new WeakMap();
|
|
79
83
|
cacheClear();
|
|
84
|
+
clearAutoLoadRulesCache();
|
|
80
85
|
clearExplorerCache();
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
@@ -265,8 +270,10 @@ export class ConfigProvider {
|
|
|
265
270
|
*/
|
|
266
271
|
async search(targetFile) {
|
|
267
272
|
const isExists = await targetFile.dirExists();
|
|
268
|
-
cpLog
|
|
269
|
-
|
|
273
|
+
if (cpLog.enabled) {
|
|
274
|
+
cpLog('search: %s', targetFile.path);
|
|
275
|
+
cpLog('isExists: %s', isExists);
|
|
276
|
+
}
|
|
270
277
|
if (!isExists) {
|
|
271
278
|
return null;
|
|
272
279
|
}
|
package/lib/debug.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
2
|
export type Log = debug.Debugger;
|
|
3
|
+
/**
|
|
4
|
+
* Read `.enabled` at call time; never cache it at module load. `debug.enable()` (including via `verbosely()` /
|
|
5
|
+
* `enableDebug()`) can switch a namespace on after import.
|
|
6
|
+
*/
|
|
3
7
|
export declare const log: debug.Debugger;
|
package/lib/debug.js
CHANGED
|
@@ -101,31 +101,30 @@ export declare function createPretenderResolver(config: PretendersConfig): Prete
|
|
|
101
101
|
*/
|
|
102
102
|
export declare function resolvePretenders(config: PretendersConfig, context?: ResolvePretendersContext, options?: ResolvePretendersOptions): Promise<Pretender[]>;
|
|
103
103
|
/**
|
|
104
|
-
* Resolves
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
104
|
+
* Resolves, for the specific file about to be linted, which of the
|
|
105
|
+
* file-backed `pretenders` it actually refers to — a selector shared by
|
|
106
|
+
* several of them, and a name it imports from a package (a lone entry
|
|
107
|
+
* included, as it may be a package's component that shares the name) — by
|
|
108
|
+
* deferring to `@markuplint/pretenders`' `disambiguatePretenders`. Without a
|
|
109
|
+
* file-backed entry there is nothing to resolve, which keeps that common case
|
|
110
|
+
* free of the dynamic import; `disambiguatePretenders` itself skips the
|
|
111
|
+
* file/AST work for a source that names none of them.
|
|
109
112
|
*
|
|
110
113
|
* @param filePath - Absolute path of the file being linted
|
|
111
114
|
* @param sourceCode - Full source text of the file being linted
|
|
112
115
|
* @param pretenders - The flat pretender list {@link resolvePretenders} produced
|
|
113
116
|
* @param options - Where to report the files the result depends on
|
|
114
117
|
* @returns The disambiguated pretender list, or `pretenders` itself (same
|
|
115
|
-
* reference) when there was
|
|
118
|
+
* reference) when there was nothing to resolve
|
|
116
119
|
*/
|
|
117
120
|
export declare function disambiguatePretendersForFile(filePath: string, sourceCode: string, pretenders: readonly Pretender[], options?: ResolvePretendersOptions): Promise<readonly Pretender[]>;
|
|
118
121
|
/**
|
|
119
|
-
*
|
|
120
|
-
* selector name shape
|
|
121
|
-
* actually resolves (plain identifiers only). Duplicating that name-shape
|
|
122
|
-
* check here would let the two independently maintained filters drift out
|
|
123
|
-
* of sync: if the real filter is ever loosened without updating this one,
|
|
124
|
-
* this fast-path gate would keep skipping the dynamic import for cases the
|
|
125
|
-
* real logic would now handle, silently disabling disambiguation for them.
|
|
126
|
-
* Being a strict superset costs at most an unnecessary dynamic import for
|
|
127
|
-
* selectors the real logic ends up not touching — never a missed one.
|
|
122
|
+
* Whether two or more `filePath`-backed entries share a selector, whatever the
|
|
123
|
+
* selector name shape.
|
|
128
124
|
*
|
|
125
|
+
* @deprecated Nothing in markuplint calls it any more, and it has no replacement:
|
|
126
|
+
* {@link disambiguatePretendersForFile} decides by itself whether there is anything
|
|
127
|
+
* to resolve. To be removed in the next major version.
|
|
129
128
|
* @param pretenders - The flat pretender list to check
|
|
130
129
|
* @returns `true` if some `selector` is shared by two or more `filePath`-backed entries
|
|
131
130
|
*/
|
|
@@ -164,37 +164,42 @@ async function appendAutoPretenders(data, context, auto, dependencies) {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
/**
|
|
167
|
-
* Resolves
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
167
|
+
* Resolves, for the specific file about to be linted, which of the
|
|
168
|
+
* file-backed `pretenders` it actually refers to — a selector shared by
|
|
169
|
+
* several of them, and a name it imports from a package (a lone entry
|
|
170
|
+
* included, as it may be a package's component that shares the name) — by
|
|
171
|
+
* deferring to `@markuplint/pretenders`' `disambiguatePretenders`. Without a
|
|
172
|
+
* file-backed entry there is nothing to resolve, which keeps that common case
|
|
173
|
+
* free of the dynamic import; `disambiguatePretenders` itself skips the
|
|
174
|
+
* file/AST work for a source that names none of them.
|
|
172
175
|
*
|
|
173
176
|
* @param filePath - Absolute path of the file being linted
|
|
174
177
|
* @param sourceCode - Full source text of the file being linted
|
|
175
178
|
* @param pretenders - The flat pretender list {@link resolvePretenders} produced
|
|
176
179
|
* @param options - Where to report the files the result depends on
|
|
177
180
|
* @returns The disambiguated pretender list, or `pretenders` itself (same
|
|
178
|
-
* reference) when there was
|
|
181
|
+
* reference) when there was nothing to resolve
|
|
179
182
|
*/
|
|
180
183
|
export async function disambiguatePretendersForFile(filePath, sourceCode, pretenders, options) {
|
|
181
|
-
if (!
|
|
184
|
+
if (!pretenders.some(pretender => pretender.filePath)) {
|
|
182
185
|
return pretenders;
|
|
183
186
|
}
|
|
184
187
|
const { disambiguatePretenders } = await import('@markuplint/pretenders');
|
|
185
|
-
|
|
188
|
+
// The same base the scanned pretenders' paths were made absolute from (see `rebasePretenderFilePaths`).
|
|
189
|
+
return disambiguatePretenders(pretenders, {
|
|
190
|
+
filePath,
|
|
191
|
+
sourceCode,
|
|
192
|
+
dependencies: options?.dependencies,
|
|
193
|
+
cwd: process.cwd(),
|
|
194
|
+
});
|
|
186
195
|
}
|
|
187
196
|
/**
|
|
188
|
-
*
|
|
189
|
-
* selector name shape
|
|
190
|
-
* actually resolves (plain identifiers only). Duplicating that name-shape
|
|
191
|
-
* check here would let the two independently maintained filters drift out
|
|
192
|
-
* of sync: if the real filter is ever loosened without updating this one,
|
|
193
|
-
* this fast-path gate would keep skipping the dynamic import for cases the
|
|
194
|
-
* real logic would now handle, silently disabling disambiguation for them.
|
|
195
|
-
* Being a strict superset costs at most an unnecessary dynamic import for
|
|
196
|
-
* selectors the real logic ends up not touching — never a missed one.
|
|
197
|
+
* Whether two or more `filePath`-backed entries share a selector, whatever the
|
|
198
|
+
* selector name shape.
|
|
197
199
|
*
|
|
200
|
+
* @deprecated Nothing in markuplint calls it any more, and it has no replacement:
|
|
201
|
+
* {@link disambiguatePretendersForFile} decides by itself whether there is anything
|
|
202
|
+
* to resolve. To be removed in the next major version.
|
|
198
203
|
* @param pretenders - The flat pretender list to check
|
|
199
204
|
* @returns `true` if some `selector` is shared by two or more `filePath`-backed entries
|
|
200
205
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/file-resolver",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "The file resolver of markuplint",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
18
|
+
"types": "./lib/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
@@ -31,25 +31,25 @@
|
|
|
31
31
|
"clean": "tsc --build --clean"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/node": "24.
|
|
34
|
+
"@types/node": "24.19.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@markuplint/html-parser": "5.
|
|
38
|
-
"@markuplint/ml-ast": "5.
|
|
39
|
-
"@markuplint/ml-config": "5.
|
|
40
|
-
"@markuplint/ml-core": "5.
|
|
41
|
-
"@markuplint/ml-spec": "5.
|
|
42
|
-
"@markuplint/parser-utils": "5.
|
|
43
|
-
"@markuplint/pretenders": "5.
|
|
44
|
-
"@markuplint/selector": "5.
|
|
45
|
-
"@markuplint/shared": "5.
|
|
46
|
-
"cosmiconfig": "
|
|
47
|
-
"debug": "4.4.3",
|
|
48
|
-
"glob": "13.0.6",
|
|
49
|
-
"ignore": "7.0.
|
|
50
|
-
"import-meta-resolve": "4.2.0",
|
|
51
|
-
"jsonc": "
|
|
52
|
-
"minimatch": "10.2.
|
|
53
|
-
},
|
|
54
|
-
"gitHead": "
|
|
37
|
+
"@markuplint/html-parser": "5.3.0",
|
|
38
|
+
"@markuplint/ml-ast": "5.3.0",
|
|
39
|
+
"@markuplint/ml-config": "5.3.0",
|
|
40
|
+
"@markuplint/ml-core": "5.3.0",
|
|
41
|
+
"@markuplint/ml-spec": "5.3.0",
|
|
42
|
+
"@markuplint/parser-utils": "5.3.0",
|
|
43
|
+
"@markuplint/pretenders": "5.3.0",
|
|
44
|
+
"@markuplint/selector": "5.3.0",
|
|
45
|
+
"@markuplint/shared": "5.3.0",
|
|
46
|
+
"cosmiconfig": "^10.0.1",
|
|
47
|
+
"debug": "^4.4.3",
|
|
48
|
+
"glob": "^13.0.6",
|
|
49
|
+
"ignore": "^7.0.12",
|
|
50
|
+
"import-meta-resolve": "^4.2.0",
|
|
51
|
+
"jsonc": "^3.0.0",
|
|
52
|
+
"minimatch": "^10.2.6"
|
|
53
|
+
},
|
|
54
|
+
"gitHead": "f587cf0206c8426e57369a48d6d5fb22306eafde"
|
|
55
55
|
}
|