mikser-io 9.19.0 → 9.19.1
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/docs/diagnostics.md +10 -3
- package/package.json +1 -1
- package/src/engine.js +8 -1
- package/src/manifest.js +41 -4
package/docs/diagnostics.md
CHANGED
|
@@ -106,9 +106,16 @@ there is no manifest to check against.
|
|
|
106
106
|
npx mikser --verify || echo "output folder has drifted"
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
A destination is resolved against the output folder first and, when that
|
|
110
|
+
finds nothing, treated as a filesystem path — assets carry an absolute
|
|
111
|
+
destination built from `assetsFolder`, which may sit outside the output
|
|
112
|
+
folder entirely.
|
|
113
|
+
|
|
114
|
+
`Orphan` still needs reading with that in mind: only files under the
|
|
115
|
+
output folder are walked, and a file is an orphan when no snapshot claims
|
|
116
|
+
it. That is normal for anything written without a render snapshot (the
|
|
117
|
+
`files` and `data` plugins), and a real signal for a page whose layout
|
|
118
|
+
stopped producing it.
|
|
112
119
|
|
|
113
120
|
### The rest, briefly
|
|
114
121
|
|
package/package.json
CHANGED
package/src/engine.js
CHANGED
|
@@ -265,8 +265,15 @@ export async function setup(options) {
|
|
|
265
265
|
for (const e of unverifiable) logger.warn('No hash: %s (entity %s)', e.destination, e.id)
|
|
266
266
|
for (const e of orphaned) logger.warn('Orphan: %s', e.path)
|
|
267
267
|
|
|
268
|
+
// Level picked from the verdict, because the level IS the marker
|
|
269
|
+
// in pino-pretty's messageFormat: notice renders 🟢, warn 🟡,
|
|
270
|
+
// error 🔴. A fixed `notice` prints a green tick next to the word
|
|
271
|
+
// FAIL, which reads as success at a glance even though the exit
|
|
272
|
+
// code is right.
|
|
268
273
|
const verdict = errors > 0 ? 'FAIL' : (warnings > 0 ? 'WARN' : 'OK')
|
|
269
|
-
logger.
|
|
274
|
+
const report = errors > 0 ? logger.error : (warnings > 0 ? logger.warn : logger.notice)
|
|
275
|
+
report.call(logger,
|
|
276
|
+
'Verify %s: %d snapshots, %d missing, %d mismatched, %d unverifiable, %d orphaned',
|
|
270
277
|
verdict, total, missing.length, mismatched.length, unverifiable.length, orphaned.length)
|
|
271
278
|
process.exit(errors > 0 ? 2 : (warnings > 0 ? 1 : 0))
|
|
272
279
|
}
|
package/src/manifest.js
CHANGED
|
@@ -66,7 +66,10 @@ import { useDatabase, registerSchema } from './database/index.js'
|
|
|
66
66
|
// PK index, no separate id index needed. Parent index is for pagination
|
|
67
67
|
// cleanup (drop all children of X). WITHOUT ROWID keeps the file
|
|
68
68
|
// smaller.
|
|
69
|
-
|
|
69
|
+
// Exported so tests build against the real schema rather than a copy. A
|
|
70
|
+
// copy drifts the moment a column is added, and the failure is a bare
|
|
71
|
+
// SQLITE_ERROR that names nothing.
|
|
72
|
+
export const SNAPSHOTS_SCHEMA = `
|
|
70
73
|
CREATE TABLE IF NOT EXISTS mikser_snapshots (
|
|
71
74
|
id TEXT NOT NULL,
|
|
72
75
|
destination TEXT NOT NULL,
|
|
@@ -78,7 +81,8 @@ registerSchema('mikser_snapshots', `
|
|
|
78
81
|
PRIMARY KEY (id, destination)
|
|
79
82
|
) WITHOUT ROWID;
|
|
80
83
|
CREATE INDEX IF NOT EXISTS idx_mikser_snapshots_parent ON mikser_snapshots(parent) WHERE parent IS NOT NULL;
|
|
81
|
-
`
|
|
84
|
+
`
|
|
85
|
+
registerSchema('mikser_snapshots', SNAPSHOTS_SCHEMA)
|
|
82
86
|
|
|
83
87
|
// Module-level DB handle + prepared statements for the lifecycle
|
|
84
88
|
// integration. Tests build their own via `createManifest(db)` —
|
|
@@ -548,8 +552,41 @@ export function createManifest(db) {
|
|
|
548
552
|
for (const row of stmtSelectAll.iterate()) {
|
|
549
553
|
const snap = rowToSnap(row)
|
|
550
554
|
if (!snap.destination) continue
|
|
551
|
-
|
|
552
|
-
|
|
555
|
+
// `destination` arrives in two shapes and both are legitimate.
|
|
556
|
+
// A page's is output-relative with a leading slash
|
|
557
|
+
// (`/bg/index.html`); an asset's is a real filesystem path,
|
|
558
|
+
// because assets.js builds it from
|
|
559
|
+
// `runtime.options.assetsFolder` — which resolves inside the
|
|
560
|
+
// WORKING folder and may sit outside outputFolder entirely
|
|
561
|
+
// (a `derived/` tree that `shares` symlinks into each language
|
|
562
|
+
// root is the case that proves it).
|
|
563
|
+
//
|
|
564
|
+
// `path.isAbsolute` cannot tell them apart: on POSIX
|
|
565
|
+
// `/bg/index.html` is absolute too. So resolve by EXISTENCE,
|
|
566
|
+
// output-relative first — that is the dominant shape, and a
|
|
567
|
+
// page destination interpreted as a filesystem path would
|
|
568
|
+
// otherwise be looked for at the root of the disk.
|
|
569
|
+
//
|
|
570
|
+
// Only the fallback path is a filesystem path, so it is only
|
|
571
|
+
// tried when the destination is absolute and joining changed
|
|
572
|
+
// nothing that resolves.
|
|
573
|
+
const joined = path.join(outputFolder, snap.destination)
|
|
574
|
+
let filePath = joined
|
|
575
|
+
if (!existsSync(joined)
|
|
576
|
+
&& path.isAbsolute(snap.destination)
|
|
577
|
+
&& existsSync(snap.destination)) {
|
|
578
|
+
filePath = snap.destination
|
|
579
|
+
}
|
|
580
|
+
// Orphan detection compares against a globby walk of
|
|
581
|
+
// outputFolder, so `claimed` has to hold exactly the relative
|
|
582
|
+
// form that walk produces. A destination resolving outside
|
|
583
|
+
// outputFolder can never appear in it and is not claimable;
|
|
584
|
+
// one inside it must be claimed by its relative path, not by
|
|
585
|
+
// the raw string with its leading slashes stripped.
|
|
586
|
+
const relative = path.relative(outputFolder, filePath)
|
|
587
|
+
if (relative && !relative.startsWith('..') && !path.isAbsolute(relative)) {
|
|
588
|
+
claimed.add(relative)
|
|
589
|
+
}
|
|
553
590
|
if (!existsSync(filePath)) {
|
|
554
591
|
missing.push({ id: snap.id, destination: snap.destination })
|
|
555
592
|
continue
|