@markuplint/file-resolver 5.0.0-rc.5 → 5.0.0-rc.7

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 CHANGED
@@ -3,6 +3,29 @@
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.0.0-rc.7](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.6...v5.0.0-rc.7) (2026-08-31)
7
+
8
+ ### Features
9
+
10
+ - **file-resolver:** record which overrides globs matched a target file ([c4cba6d](https://github.com/markuplint/markuplint/commit/c4cba6d9444ecb19752204a1655caad0d27f3ff8)), closes [#4023](https://github.com/markuplint/markuplint/issues/4023)
11
+
12
+ # [5.0.0-rc.6](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.5...v5.0.0-rc.6) (2026-08-30)
13
+
14
+ ### Bug Fixes
15
+
16
+ - resolveConfig(false) crashes with inline config (not a file path) ([#4018](https://github.com/markuplint/markuplint/issues/4018)) ([7e38b64](https://github.com/markuplint/markuplint/commit/7e38b64caa8cca69009ee765e4aada37fc48c559)), closes [#4015](https://github.com/markuplint/markuplint/issues/4015) [#4015](https://github.com/markuplint/markuplint/issues/4015)
17
+
18
+ ### Performance Improvements
19
+
20
+ - share ConfigProvider across a run's files, fix latent overrides caching bug ([#4016](https://github.com/markuplint/markuplint/issues/4016)) ([fcc1875](https://github.com/markuplint/markuplint/commit/fcc1875b1a984a5ef1bb36aa04e7b3522fefc58e)), closes [#3997](https://github.com/markuplint/markuplint/issues/3997) [#3997](https://github.com/markuplint/markuplint/issues/3997)
21
+
22
+ ### BREAKING CHANGES
23
+
24
+ - `ConfigProvider#resolve(targetFile, names, false)` no longer
25
+ clears the provider's store/cache/plugin-resolution caches by itself. Callers
26
+ that relied on `cache: false` alone to force a fresh re-read must now call
27
+ the new `ConfigProvider#invalidate()` first.
28
+
6
29
  # [5.0.0-rc.5](https://github.com/markuplint/markuplint/compare/v5.0.0-rc.4...v5.0.0-rc.5) (2026-08-28)
7
30
 
8
31
  ### Bug Fixes
@@ -7,9 +7,52 @@ import type { Nullable } from '@markuplint/shared';
7
7
  *
8
8
  * Handles `extends` chains, plugins, presets, overrides, and circular reference detection.
9
9
  * Configuration files are searched via cosmiconfig and cached by file path.
10
+ *
11
+ * Designed to be shared across every target file in a run (see
12
+ * `MLEngineOptions.configProvider` in `packages/markuplint/src/api/ml-engine.ts`):
13
+ * {@link resolve}'s cache is keyed by the resolved config's `names`, not by
14
+ * target file, so one instance reused across many files avoids redoing
15
+ * merge/validate/plugin-resolution once per file that shares the same
16
+ * config — see #3997.
10
17
  */
11
18
  export declare class ConfigProvider {
12
19
  #private;
20
+ /**
21
+ * Clears every cached and stored config entry: the base-config cache
22
+ * (`#cache`), the loaded/registered config store (`#store`), `set()`'s
23
+ * identity→key stabilization (`#autoKeys`), `resolve-plugins.ts`'s own
24
+ * module-level plugin-resolution cache, and the shared `cosmiconfig`
25
+ * explorer's own search/load caches (so {@link search}, called right
26
+ * after this, re-reads the current file content instead of a stale
27
+ * cosmiconfig-level cache).
28
+ *
29
+ * The `cosmiconfig` explorer and the `resolve-plugins.ts` cache are
30
+ * module-level singletons shared by every `ConfigProvider` instance in
31
+ * the process — clearing them here affects other instances too, not just
32
+ * this one. Harmless (they just re-search/re-load), but worth knowing
33
+ * when reasoning about a cache-busting re-resolve's blast radius.
34
+ *
35
+ * Callers doing a cache-busting re-resolve (e.g. watch mode after a file
36
+ * change) must call this **before** registering any inline config via
37
+ * {@link set}, and before {@link search}, for that same resolve —
38
+ * `resolve()` itself no longer clears anything, so a `set()`/`search()`
39
+ * call made after `invalidate()` survives through to `resolve()`. Wrap
40
+ * the whole `invalidate()` → `set()`/`search()` → `resolve()` sequence in
41
+ * {@link runExclusive} so an overlapping call on the same instance can't
42
+ * interleave its own `invalidate()` in the middle of it. See #4015.
43
+ */
44
+ invalidate(): void;
45
+ /**
46
+ * Runs `fn` exclusively with respect to every other `runExclusive` call on
47
+ * this instance: queued calls wait for earlier ones to settle before
48
+ * starting, so two overlapping cache-busting re-resolves (e.g. two
49
+ * watch-triggered `MLEngine#resolveConfig(false)` calls close together,
50
+ * whether from one engine's own provider or several engines sharing one)
51
+ * can't interleave — one call's {@link invalidate} can no longer wipe the
52
+ * `set()`/`search()` entries another call registered a moment earlier but
53
+ * hasn't yet consumed. See #4015.
54
+ */
55
+ runExclusive<T>(fn: () => Promise<T>): Promise<T>;
13
56
  /**
14
57
  * Recursively loads a configuration and all its `extends` dependencies.
15
58
  *
@@ -27,9 +70,27 @@ export declare class ConfigProvider {
27
70
  * Resolves the full configuration for a target file by merging all named configs,
28
71
  * resolving plugins, and applying file-specific overrides.
29
72
  *
73
+ * Split into a cacheable "base" phase (`#resolveBase`: merge/validate/plugin
74
+ * resolution/plugin-provided `extends`) and a per-call `overrides` phase, because
75
+ * `overrides` matching depends on `targetFile` while everything else in `names`
76
+ * resolution does not. Only the base result is cached (keyed on `names`, not on
77
+ * `targetFile`) — callers sharing one `ConfigProvider` across many target files
78
+ * (see #3997) get that work done once, while `overrides` are always re-evaluated
79
+ * per call so a `.vue`-only override never leaks into a `.html` file's result (or
80
+ * vice versa) just because they resolve the same `names`.
81
+ *
82
+ * Does NOT clear the provider's store/cache itself — call {@link invalidate}
83
+ * first if a fresh re-read is needed (e.g. a watch-triggered re-resolve).
84
+ * `cache` only controls whether an already-loaded `names` entry (this call's
85
+ * base-config cache, and — deeper still — cosmiconfig's own per-file cache in
86
+ * `#load`) is reused; it used to also wipe the store/cache up front, which
87
+ * discarded any `set()` call the caller had just made for this same resolve
88
+ * (e.g. `MLEngine#resolveConfig()` registering inline `config`/`defaultConfig`
89
+ * right before calling this) — see #4015.
90
+ *
30
91
  * @param targetFile - The file being linted
31
92
  * @param names - Config file paths or module names to merge
32
- * @param cache - Whether to use cached results
93
+ * @param cache - Whether to reuse already-loaded/cached entries
33
94
  * @returns The fully resolved configuration set including plugins and errors
34
95
  */
35
96
  resolve(targetFile: Readonly<MLFile>, names: readonly Nullable<string>[], cache?: boolean): Promise<ConfigSet>;
@@ -45,7 +106,22 @@ export declare class ConfigProvider {
45
106
  *
46
107
  * @param config - The optimized configuration to store
47
108
  * @param key - An optional key to store the config under; auto-generated if omitted
109
+ * @param identity - Object identity to auto-key on when `key` is omitted (e.g. the
110
+ * caller's original, pre-merge config object). Repeated calls with the same
111
+ * `identity` reuse the same generated key instead of minting a fresh UUID each
112
+ * time, so `resolve()`'s base cache can hit for inline (non-file-path) config
113
+ * shared across multiple target files — see #3997. Falls back to `config` itself
114
+ * (which is rebuilt fresh by every caller today, so this is a no-op unless a
115
+ * caller passes a stable `identity`).
116
+ *
117
+ * **Invariant**: an `identity` must correspond to `config` content that is
118
+ * effectively immutable for as long as that identity is reused — a second
119
+ * call with the same `identity` but *different* `config` content returns
120
+ * the *first* call's key/content, silently discarding the new content. Not
121
+ * reachable via `MLEngine`'s call sites today (they hold `options.config`/
122
+ * `defaultConfig` as one unchanged reference per run); a future caller
123
+ * passing a reused identity for genuinely different content would hit this.
48
124
  * @returns The key under which the config was stored
49
125
  */
50
- set(config: OptimizedConfig, key?: string): string;
126
+ set(config: OptimizedConfig, key?: string, identity?: object): string;
51
127
  }
@@ -3,7 +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 { load as loadConfig, search } from './cosmiconfig.js';
6
+ import { load as loadConfig, search, clearExplorerCache } from './cosmiconfig.js';
7
7
  import { log } from './debug.js';
8
8
  import { generalImport } from './general-import.js';
9
9
  import { getPreset } from './get-preset.js';
@@ -20,12 +20,89 @@ const KEY_SEPARATOR = '__ML_CONFIG_MERGE__';
20
20
  *
21
21
  * Handles `extends` chains, plugins, presets, overrides, and circular reference detection.
22
22
  * Configuration files are searched via cosmiconfig and cached by file path.
23
+ *
24
+ * Designed to be shared across every target file in a run (see
25
+ * `MLEngineOptions.configProvider` in `packages/markuplint/src/api/ml-engine.ts`):
26
+ * {@link resolve}'s cache is keyed by the resolved config's `names`, not by
27
+ * target file, so one instance reused across many files avoids redoing
28
+ * merge/validate/plugin-resolution once per file that shares the same
29
+ * config — see #3997.
23
30
  */
24
31
  export class ConfigProvider {
25
32
  #cache = new Map();
26
33
  #held = new Set();
27
34
  #recursiveLoadKeyAndDepth = new Map();
28
35
  #store = new Map();
36
+ /**
37
+ * Stabilizes {@link set}'s auto-generated key for an inline config object
38
+ * across repeated calls with the *same* object reference (e.g. one caller
39
+ * sharing one `ConfigProvider` — and one `options.config`/`defaultConfig`
40
+ * object — across many target files). Without this, `set()` would mint a
41
+ * fresh UUID per call even for identical content, so `resolve()`'s cache
42
+ * (keyed on that UUID) would never hit for inline (non-file-path) config.
43
+ * Keyed on object identity, not content, so it costs nothing to check and
44
+ * needs no hashing of arbitrary config shapes.
45
+ */
46
+ #autoKeys = new WeakMap();
47
+ /**
48
+ * Serializes {@link runExclusive} calls on this instance.
49
+ */
50
+ #queue = Promise.resolve();
51
+ /**
52
+ * Clears every cached and stored config entry: the base-config cache
53
+ * (`#cache`), the loaded/registered config store (`#store`), `set()`'s
54
+ * identity→key stabilization (`#autoKeys`), `resolve-plugins.ts`'s own
55
+ * module-level plugin-resolution cache, and the shared `cosmiconfig`
56
+ * explorer's own search/load caches (so {@link search}, called right
57
+ * after this, re-reads the current file content instead of a stale
58
+ * cosmiconfig-level cache).
59
+ *
60
+ * The `cosmiconfig` explorer and the `resolve-plugins.ts` cache are
61
+ * module-level singletons shared by every `ConfigProvider` instance in
62
+ * the process — clearing them here affects other instances too, not just
63
+ * this one. Harmless (they just re-search/re-load), but worth knowing
64
+ * when reasoning about a cache-busting re-resolve's blast radius.
65
+ *
66
+ * Callers doing a cache-busting re-resolve (e.g. watch mode after a file
67
+ * change) must call this **before** registering any inline config via
68
+ * {@link set}, and before {@link search}, for that same resolve —
69
+ * `resolve()` itself no longer clears anything, so a `set()`/`search()`
70
+ * call made after `invalidate()` survives through to `resolve()`. Wrap
71
+ * the whole `invalidate()` → `set()`/`search()` → `resolve()` sequence in
72
+ * {@link runExclusive} so an overlapping call on the same instance can't
73
+ * interleave its own `invalidate()` in the middle of it. See #4015.
74
+ */
75
+ invalidate() {
76
+ this.#store.clear();
77
+ this.#cache.clear();
78
+ this.#autoKeys = new WeakMap();
79
+ cacheClear();
80
+ clearExplorerCache();
81
+ }
82
+ /**
83
+ * Runs `fn` exclusively with respect to every other `runExclusive` call on
84
+ * this instance: queued calls wait for earlier ones to settle before
85
+ * starting, so two overlapping cache-busting re-resolves (e.g. two
86
+ * watch-triggered `MLEngine#resolveConfig(false)` calls close together,
87
+ * whether from one engine's own provider or several engines sharing one)
88
+ * can't interleave — one call's {@link invalidate} can no longer wipe the
89
+ * `set()`/`search()` entries another call registered a moment earlier but
90
+ * hasn't yet consumed. See #4015.
91
+ */
92
+ async runExclusive(fn) {
93
+ const previous = this.#queue;
94
+ let release;
95
+ this.#queue = new Promise(resolve => {
96
+ release = resolve;
97
+ });
98
+ await previous;
99
+ try {
100
+ return await fn();
101
+ }
102
+ finally {
103
+ release();
104
+ }
105
+ }
29
106
  /**
30
107
  * Recursively loads a configuration and all its `extends` dependencies.
31
108
  *
@@ -77,28 +154,50 @@ export class ConfigProvider {
77
154
  * Resolves the full configuration for a target file by merging all named configs,
78
155
  * resolving plugins, and applying file-specific overrides.
79
156
  *
157
+ * Split into a cacheable "base" phase (`#resolveBase`: merge/validate/plugin
158
+ * resolution/plugin-provided `extends`) and a per-call `overrides` phase, because
159
+ * `overrides` matching depends on `targetFile` while everything else in `names`
160
+ * resolution does not. Only the base result is cached (keyed on `names`, not on
161
+ * `targetFile`) — callers sharing one `ConfigProvider` across many target files
162
+ * (see #3997) get that work done once, while `overrides` are always re-evaluated
163
+ * per call so a `.vue`-only override never leaks into a `.html` file's result (or
164
+ * vice versa) just because they resolve the same `names`.
165
+ *
166
+ * Does NOT clear the provider's store/cache itself — call {@link invalidate}
167
+ * first if a fresh re-read is needed (e.g. a watch-triggered re-resolve).
168
+ * `cache` only controls whether an already-loaded `names` entry (this call's
169
+ * base-config cache, and — deeper still — cosmiconfig's own per-file cache in
170
+ * `#load`) is reused; it used to also wipe the store/cache up front, which
171
+ * discarded any `set()` call the caller had just made for this same resolve
172
+ * (e.g. `MLEngine#resolveConfig()` registering inline `config`/`defaultConfig`
173
+ * right before calling this) — see #4015.
174
+ *
80
175
  * @param targetFile - The file being linted
81
176
  * @param names - Config file paths or module names to merge
82
- * @param cache - Whether to use cached results
177
+ * @param cache - Whether to reuse already-loaded/cached entries
83
178
  * @returns The fully resolved configuration set including plugins and errors
84
179
  */
85
180
  async resolve(targetFile, names, cache = true) {
86
- if (!cache) {
87
- this.#store.clear();
88
- this.#cache.clear();
89
- cacheClear();
90
- }
91
181
  const keys = names.filter(nonNullableFilter);
92
182
  const key = keys.join(KEY_SEPARATOR);
93
- const currentConfig = this.#cache.get(key);
94
- if (currentConfig) {
95
- return currentConfig;
183
+ let baseConfigSet = this.#cache.get(key);
184
+ if (!baseConfigSet) {
185
+ baseConfigSet = await this.#resolveBase(keys, cache, targetFile.path);
186
+ this.#cache.set(key, baseConfigSet);
96
187
  }
97
- let configSet = await this.#mergeConfigs(keys, cache, targetFile.path);
188
+ return this.#applyOverrides(baseConfigSet, targetFile);
189
+ }
190
+ /**
191
+ * The `names`-dependent, `targetFile`-independent part of {@link resolve}:
192
+ * merges all named configs, validates, resolves plugins, and expands
193
+ * plugin-provided `extends`. Safe to cache under a `names`-only key.
194
+ */
195
+ async #resolveBase(keys, cache, referrer) {
196
+ let configSet = await this.#mergeConfigs(keys, cache, referrer);
98
197
  const filePath = [...configSet.files].toReversed()[0];
99
198
  if (!filePath) {
100
199
  throw new ConfigParserError('Config file not found', {
101
- filePath: targetFile.path,
200
+ filePath: referrer,
102
201
  });
103
202
  }
104
203
  const errors = this.#validateConfig(configSet.config, filePath);
@@ -120,36 +219,43 @@ export class ConfigProvider {
120
219
  }
121
220
  }
122
221
  }
123
- configSet = await this.#mergeConfigs([...keys, ...extendHelds], cache, targetFile.path);
222
+ configSet = await this.#mergeConfigs([...keys, ...extendHelds], cache, referrer);
124
223
  this.#held.clear();
125
224
  }
126
- // Resolves `overrides`
127
- if (configSet.config.overrides) {
128
- const overrides = configSet.config.overrides;
129
- const globs = Object.keys(overrides);
130
- for (const glob of globs) {
131
- const isMatched = targetFile.matches(glob);
132
- const config = overrides[glob];
133
- if (isMatched && config) {
134
- switch (configSet.config.overrideMode) {
135
- case 'merge': {
136
- configSet.config = mergeConfig(configSet.config, config);
137
- break;
138
- }
139
- default: /* or "reset" */ {
140
- configSet.config = config;
141
- break;
142
- }
143
- }
144
- }
145
- }
146
- }
147
- const result = {
225
+ return {
148
226
  ...configSet,
149
227
  plugins,
150
228
  };
151
- this.#cache.set(key, result);
152
- return result;
229
+ }
230
+ /**
231
+ * The `targetFile`-dependent part of {@link resolve}: matches `config.overrides`
232
+ * globs against `targetFile` and applies whichever match, per `overrideMode`.
233
+ * Never mutates `baseConfigSet` — returns it unchanged (same reference) when no
234
+ * override matches, or a shallow copy with a freshly computed `config` otherwise,
235
+ * so the cached base entry stays valid for the next target file.
236
+ *
237
+ * Matches are applied in `Object.keys(overrides)` order (config-key insertion
238
+ * order), each round re-assigning `config` rather than accumulating — so under
239
+ * the default `overrideMode: 'reset'`, the last-matching glob's config entirely
240
+ * replaces every earlier match, not just the base config. `appliedOverrides`
241
+ * records that match order for `--show-config=details` to surface, since this
242
+ * "last match wins outright" behavior is easy to mistake for a bug (see #4023).
243
+ */
244
+ #applyOverrides(baseConfigSet, targetFile) {
245
+ let config = baseConfigSet.config;
246
+ const appliedOverrides = [];
247
+ if (config.overrides) {
248
+ const overrides = config.overrides;
249
+ for (const glob of Object.keys(overrides)) {
250
+ const overrideConfig = overrides[glob];
251
+ if (targetFile.matches(glob) && overrideConfig) {
252
+ config = config.overrideMode === 'merge' ? mergeConfig(config, overrideConfig) : overrideConfig;
253
+ appliedOverrides.push(glob);
254
+ }
255
+ }
256
+ return config === baseConfigSet.config ? baseConfigSet : { ...baseConfigSet, config, appliedOverrides };
257
+ }
258
+ return baseConfigSet;
153
259
  }
154
260
  /**
155
261
  * Searches for a markuplint configuration file starting from the target file's directory.
@@ -180,12 +286,37 @@ export class ConfigProvider {
180
286
  *
181
287
  * @param config - The optimized configuration to store
182
288
  * @param key - An optional key to store the config under; auto-generated if omitted
289
+ * @param identity - Object identity to auto-key on when `key` is omitted (e.g. the
290
+ * caller's original, pre-merge config object). Repeated calls with the same
291
+ * `identity` reuse the same generated key instead of minting a fresh UUID each
292
+ * time, so `resolve()`'s base cache can hit for inline (non-file-path) config
293
+ * shared across multiple target files — see #3997. Falls back to `config` itself
294
+ * (which is rebuilt fresh by every caller today, so this is a no-op unless a
295
+ * caller passes a stable `identity`).
296
+ *
297
+ * **Invariant**: an `identity` must correspond to `config` content that is
298
+ * effectively immutable for as long as that identity is reused — a second
299
+ * call with the same `identity` but *different* `config` content returns
300
+ * the *first* call's key/content, silently discarding the new content. Not
301
+ * reachable via `MLEngine`'s call sites today (they hold `options.config`/
302
+ * `defaultConfig` as one unchanged reference per run); a future caller
303
+ * passing a reused identity for genuinely different content would hit this.
183
304
  * @returns The key under which the config was stored
184
305
  */
185
- set(config, key) {
186
- key = key ?? uuid();
187
- this.#store.set(key, config);
188
- return key;
306
+ set(config, key, identity) {
307
+ if (key != null) {
308
+ this.#store.set(key, config);
309
+ return key;
310
+ }
311
+ const identityKey = identity ?? config;
312
+ const existingKey = this.#autoKeys.get(identityKey);
313
+ if (existingKey != null) {
314
+ return existingKey;
315
+ }
316
+ const newKey = uuid();
317
+ this.#store.set(newKey, config);
318
+ this.#autoKeys.set(identityKey, newKey);
319
+ return newKey;
189
320
  }
190
321
  async #load(filePath, cache, referrer) {
191
322
  const entity = this.#store.get(filePath);
@@ -1,6 +1,15 @@
1
1
  import type { LoaderSync } from 'cosmiconfig';
2
2
  import { ConfigLoadError } from '@markuplint/shared';
3
3
  type CosmiConfig = ReturnType<LoaderSync>;
4
+ /**
5
+ * Clears the shared `cosmiconfig` explorer's own internal search/load caches.
6
+ * Distinct from this module's `cacheClear` parameters (which clear the same
7
+ * caches but only as a side effect of one `search`/`load` call) — this lets a
8
+ * caller (see `ConfigProvider#invalidate`) clear them up front, before any
9
+ * `search`/`load` call, so a subsequent `search` reads the current file
10
+ * content instead of the explorer's stale cache. See #4015.
11
+ */
12
+ export declare function clearExplorerCache(): void;
4
13
  export declare function search<T = CosmiConfig>(filePath: string, cacheClear: boolean): Promise<{
5
14
  filePath: string;
6
15
  config: T;
@@ -40,6 +40,17 @@ const explorer = cosmiconfig('markuplint', {
40
40
  },
41
41
  searchStrategy: 'project',
42
42
  });
43
+ /**
44
+ * Clears the shared `cosmiconfig` explorer's own internal search/load caches.
45
+ * Distinct from this module's `cacheClear` parameters (which clear the same
46
+ * caches but only as a side effect of one `search`/`load` call) — this lets a
47
+ * caller (see `ConfigProvider#invalidate`) clear them up front, before any
48
+ * `search`/`load` call, so a subsequent `search` reads the current file
49
+ * content instead of the explorer's stale cache. See #4015.
50
+ */
51
+ export function clearExplorerCache() {
52
+ explorer.clearCaches();
53
+ }
43
54
  export async function search(filePath, cacheClear) {
44
55
  if (cacheClear) {
45
56
  explorer.clearCaches();
package/lib/types.d.ts CHANGED
@@ -13,6 +13,15 @@ export interface ConfigSet {
13
13
  readonly files: ReadonlySet<string>;
14
14
  /** Errors encountered during config loading or resolution */
15
15
  readonly errs: readonly Readonly<Error>[];
16
+ /**
17
+ * `overrides` keys (resolved to absolute globs by `OptimizedConfig`) that
18
+ * matched the target file, in the order they were applied — config-key
19
+ * order, so later entries win under `overrideMode: 'reset'`, the default.
20
+ * Absent — never an empty array — when no override matched this target
21
+ * file, whether because the config has no `overrides` at all or none of
22
+ * its globs matched.
23
+ */
24
+ readonly appliedOverrides?: readonly string[];
16
25
  }
17
26
  /**
18
27
  * A lint target: either a file path/glob string, or an inline source code object.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/file-resolver",
3
- "version": "5.0.0-rc.5",
3
+ "version": "5.0.0-rc.7",
4
4
  "description": "The file resolver of markuplint",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,15 +34,15 @@
34
34
  "@types/node": "24.13.3"
35
35
  },
36
36
  "dependencies": {
37
- "@markuplint/html-parser": "5.0.0-rc.5",
38
- "@markuplint/ml-ast": "5.0.0-rc.5",
39
- "@markuplint/ml-config": "5.0.0-rc.5",
40
- "@markuplint/ml-core": "5.0.0-rc.5",
41
- "@markuplint/ml-spec": "5.0.0-rc.5",
42
- "@markuplint/parser-utils": "5.0.0-rc.5",
43
- "@markuplint/pretenders": "5.0.0-rc.5",
44
- "@markuplint/selector": "5.0.0-rc.5",
45
- "@markuplint/shared": "5.0.0-rc.5",
37
+ "@markuplint/html-parser": "5.0.0-rc.7",
38
+ "@markuplint/ml-ast": "5.0.0-rc.7",
39
+ "@markuplint/ml-config": "5.0.0-rc.7",
40
+ "@markuplint/ml-core": "5.0.0-rc.7",
41
+ "@markuplint/ml-spec": "5.0.0-rc.7",
42
+ "@markuplint/parser-utils": "5.0.0-rc.7",
43
+ "@markuplint/pretenders": "5.0.0-rc.7",
44
+ "@markuplint/selector": "5.0.0-rc.7",
45
+ "@markuplint/shared": "5.0.0-rc.7",
46
46
  "cosmiconfig": "9.0.1",
47
47
  "debug": "4.4.3",
48
48
  "glob": "13.0.6",
@@ -51,5 +51,5 @@
51
51
  "jsonc": "2.0.0",
52
52
  "minimatch": "10.2.5"
53
53
  },
54
- "gitHead": "8d87463af2ff3f1b83fb28da20f1819362cf3555"
54
+ "gitHead": "8d7a3b801e0f5f88438c003e7eee2bd45e6aedd0"
55
55
  }