mikser-io 9.88.0 → 9.89.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.
@@ -948,6 +948,15 @@ surfaces that turn silence into a statement:
948
948
  sitemap — and warns under `asset-missing`. Where both can see the
949
949
  same file, the output scan reports it and this one stays quiet.
950
950
 
951
+ A `url()` inside a **custom property** is resolved from the stylesheet that
952
+ substitutes it, for both of these questions and for the climb check below.
953
+ It is substituted where it is *used*, so the page that declared it in a
954
+ style attribute is not its base — a bundle at `styles/` is. Every emitted
955
+ stylesheet is a candidate, since which one substitutes the variable is not
956
+ knowable from the bytes; a clean resolution settles it, one that resolves
957
+ only by climbing is a genuine over-deep against *that* base, and a url that
958
+ resolves from none of them is reported as broken.
959
+
951
960
  A url under the assets folder gets a cause rather than a guess. Whether a
952
961
  preset covers a file is decided by `match` against the entity id, which is
953
962
  not visible from a url, so the assets plugin is asked and the answer is one
@@ -971,7 +980,11 @@ surfaces that turn silence into a statement:
971
980
  - **A link that works only by accident** — a url with one `..` too many
972
981
  still loads, because a browser discards a climb above the origin root
973
982
  rather than failing. Reported under `reference-over-deep`, separately
974
- from the outright failures, and grouped by how far each climbed:
983
+ from the outright failures, and grouped by how far each climbed. A custom
984
+ property is judged against its stylesheet here too: judged against the page
985
+ it produced a climb report for references that are correct, with a reason
986
+ — "a browser discards the extra `..`" — that was false for them, which
987
+ sends the reader to fix a base that is right:
975
988
  - **One url, or several climbing different distances** — each is a
976
989
  latent 404, working today and broken as soon as the same markup
977
990
  renders one level deeper.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikser-io",
3
- "version": "9.88.0",
3
+ "version": "9.89.0",
4
4
  "files": [
5
5
  "app.js",
6
6
  "index.js",
package/src/references.js CHANGED
@@ -198,21 +198,46 @@ export async function checkReferences(outputFolder, { siteRoots = [] } = {}) {
198
198
  const pageDir = path.dirname(file).slice(root.length).replace(/^\/+/, '')
199
199
 
200
200
  for (const { url, customProperty } of extractReferences(source)) {
201
- const { target, overDeep, floored } = resolveUrl(pageDir, url, { root })
201
+ let { target, overDeep, floored } = resolveUrl(pageDir, url, { root })
202
202
  checked++
203
203
 
204
- if (!exists.has(target)) {
205
- exists.set(target, existsSync(path.join(outputFolder, target)))
204
+ const resolves = (candidate) => {
205
+ if (!exists.has(candidate)) {
206
+ exists.set(candidate, existsSync(path.join(outputFolder, candidate)))
207
+ }
208
+ return exists.get(candidate)
206
209
  }
210
+ resolves(target)
207
211
 
208
- // Resolved from a stylesheet instead, and correct there.
209
- if (!exists.get(target) && customProperty && styleBases.some((base) => {
210
- const from = resolveUrl(base.dir, url, { root: base.root }).target
211
- if (!exists.has(from)) {
212
- exists.set(from, existsSync(path.join(outputFolder, from)))
212
+ // A custom property is resolved from the STYLESHEET, for BOTH
213
+ // questions this check asks.
214
+ //
215
+ // The first version of this only replaced the verdict when the
216
+ // page-relative target was missing, which left the climb check
217
+ // answering from a base it had already been told was the wrong
218
+ // one. Where the discarded `..` happened to land on a real file,
219
+ // the reference was reported as climbing above the site root, and
220
+ // the explanation said it loads "because a browser discards the
221
+ // extra `..`" — when it loads because it is correct where it is
222
+ // actually read from. A wrong reason on a correct reference is
223
+ // worse than the original false positive: it sends the reader to
224
+ // fix a base that is right.
225
+ //
226
+ // Clean beats floored beats missing. A stylesheet that resolves it
227
+ // without climbing settles it; one that resolves it only by
228
+ // climbing is a genuine over-deep against THAT base; and if none
229
+ // resolves it the page-relative answer stands and the url is
230
+ // simply broken.
231
+ if (customProperty && styleBases.length) {
232
+ let best = null
233
+ for (const base of styleBases) {
234
+ const from = resolveUrl(base.dir, url, { root: base.root })
235
+ if (!resolves(from.target)) continue
236
+ if (!from.overDeep) { best = from; break }
237
+ best ??= from
213
238
  }
214
- return exists.get(from)
215
- })) continue
239
+ if (best) ({ target, overDeep, floored } = best)
240
+ }
216
241
 
217
242
  // Broken outranks over-deep: a url that resolves nowhere is the
218
243
  // failure, and adding that it is also one level too deep is noise.