@conduction/docusaurus-preset 3.8.0 → 3.9.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/bin/validate-ai-baseline.mjs +73 -0
- package/package.json +1 -1
|
@@ -176,6 +176,79 @@ check('homepage has og:image, og:type, twitter:site, twitter:card', () => {
|
|
|
176
176
|
return {ok: true, msg: 'all four present'};
|
|
177
177
|
});
|
|
178
178
|
|
|
179
|
+
/* TechArticle JSON-LD on docs pages. Preset 3.8.0+ swizzles
|
|
180
|
+
DocItem/Content to prepend TechArticle on every doc page. If the
|
|
181
|
+
swizzle ever regresses (preset downgrade, opt-out via frontmatter
|
|
182
|
+
accidentally site-wide, theme path mis-wired), this check fires.
|
|
183
|
+
Scans the build's docs/ tree and looks for any rendered page that
|
|
184
|
+
carries a TechArticle JSON-LD block. Skips gracefully on sites that
|
|
185
|
+
don't have a docs/ subtree (marketing sites like conduction.nl). */
|
|
186
|
+
function findFirstHtmlIn(dir, depth = 0) {
|
|
187
|
+
if (depth > 4) return null;
|
|
188
|
+
if (!existsSync(dir)) return null;
|
|
189
|
+
let entries;
|
|
190
|
+
try {entries = require('node:fs').readdirSync(dir, {withFileTypes: true});}
|
|
191
|
+
catch {return null;}
|
|
192
|
+
/* Prefer index.html in this dir first. */
|
|
193
|
+
const indexEntry = entries.find(e => e.isFile() && e.name === 'index.html');
|
|
194
|
+
if (indexEntry) return join(dir, 'index.html');
|
|
195
|
+
/* Recurse into directories. */
|
|
196
|
+
for (const e of entries) {
|
|
197
|
+
if (e.isDirectory() && !e.name.startsWith('.')) {
|
|
198
|
+
const found = findFirstHtmlIn(join(dir, e.name), depth + 1);
|
|
199
|
+
if (found) return found;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
check('TechArticle JSON-LD present on docs pages (preset 3.8+)', () => {
|
|
206
|
+
const docsDir = join(buildDir, 'docs');
|
|
207
|
+
if (!existsSync(docsDir)) {
|
|
208
|
+
return {ok: true, msg: 'no docs/ subtree, skipped (marketing site)'};
|
|
209
|
+
}
|
|
210
|
+
/* Walk up to 100 pages looking for any with TechArticle. Most sites
|
|
211
|
+
hit it on the very first sample (the swizzle fires on every page),
|
|
212
|
+
but small sites with /docs/category/X redirects need a few hops. */
|
|
213
|
+
const visited = new Set();
|
|
214
|
+
let firstFound = null;
|
|
215
|
+
let firstChecked = null;
|
|
216
|
+
function scan(dir, depth = 0) {
|
|
217
|
+
if (depth > 4 || firstFound) return;
|
|
218
|
+
let entries;
|
|
219
|
+
try {entries = require('node:fs').readdirSync(dir, {withFileTypes: true});}
|
|
220
|
+
catch {return;}
|
|
221
|
+
for (const e of entries) {
|
|
222
|
+
if (firstFound) return;
|
|
223
|
+
const p = join(dir, e.name);
|
|
224
|
+
if (e.isFile() && e.name === 'index.html') {
|
|
225
|
+
if (visited.has(p)) continue;
|
|
226
|
+
visited.add(p);
|
|
227
|
+
if (!firstChecked) firstChecked = p;
|
|
228
|
+
const html = readFileSync(p, 'utf8');
|
|
229
|
+
if (html.includes('"@type":"TechArticle"')) {
|
|
230
|
+
firstFound = p;
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
} else if (e.isDirectory() && !e.name.startsWith('.')) {
|
|
234
|
+
scan(p, depth + 1);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
scan(docsDir);
|
|
239
|
+
if (firstFound) {
|
|
240
|
+
const rel = firstFound.replace(buildDir + '/', '');
|
|
241
|
+
return {ok: true, msg: `found on ${rel}`};
|
|
242
|
+
}
|
|
243
|
+
if (!firstChecked) {
|
|
244
|
+
return {ok: true, msg: 'docs/ has no index.html files, skipped'};
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
ok: false,
|
|
248
|
+
msg: `0 docs pages emit TechArticle JSON-LD. Checked ${visited.size} pages starting from ${firstChecked.replace(buildDir + '/', '')}. Verify @conduction/docusaurus-preset is at ^3.8.0 and DocItem swizzle is registered.`,
|
|
249
|
+
};
|
|
250
|
+
});
|
|
251
|
+
|
|
179
252
|
check('og:image URL resolves to a file in the build', () => {
|
|
180
253
|
const html = readBuild('index.html');
|
|
181
254
|
const url = metaTag(html, 'og:image');
|