@mui/internal-docs-infra 0.12.1-canary.19 → 0.12.1-canary.20
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/internal-docs-infra",
|
|
3
|
-
"version": "0.12.1-canary.
|
|
3
|
+
"version": "0.12.1-canary.20",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "MUI Infra - internal documentation creation tools.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -804,5 +804,5 @@
|
|
|
804
804
|
"bin": {
|
|
805
805
|
"docs-infra": "./cli/index.mjs"
|
|
806
806
|
},
|
|
807
|
-
"gitSha": "
|
|
807
|
+
"gitSha": "d812bc24a3f4f38926ffe69e171df9c72254f78a"
|
|
808
808
|
}
|
|
@@ -97,6 +97,55 @@ async function savePageIndexCache({
|
|
|
97
97
|
}, markdown, enrichPageIndex(cacheMetadata, indexPath, rootContext));
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Merges the incoming metadata into the source pages (keyed by path, matching
|
|
102
|
+
* mergeMetadataMarkdown's logic) and renders the index markdown exactly as it is
|
|
103
|
+
* persisted. Shared by the writer and the `errorIfOutOfDate` validation path so the two
|
|
104
|
+
* always agree on what the index should contain - otherwise validation could render
|
|
105
|
+
* differently from the writer and flag an up-to-date file (or miss a stale one).
|
|
106
|
+
*/
|
|
107
|
+
async function renderIndexPages(sourceMarkdown, sourcePages, metadataArray, {
|
|
108
|
+
indexTitle,
|
|
109
|
+
indexWrapperComponent,
|
|
110
|
+
preserveExistingTitleAndSlug,
|
|
111
|
+
relativeIndexPath
|
|
112
|
+
}) {
|
|
113
|
+
// Build a map keyed by path (not slug) to match mergeMetadataMarkdown's logic.
|
|
114
|
+
const updatedPagesMap = new Map();
|
|
115
|
+
// First, add all source pages.
|
|
116
|
+
for (const page of sourcePages) {
|
|
117
|
+
updatedPagesMap.set(page.path, page);
|
|
118
|
+
}
|
|
119
|
+
// Then update/add the new metadata items.
|
|
120
|
+
for (const metaItem of metadataArray) {
|
|
121
|
+
updatedPagesMap.set(metaItem.path, metaItem);
|
|
122
|
+
}
|
|
123
|
+
// The COMPLETE list of pages that should exist.
|
|
124
|
+
const allPages = Array.from(updatedPagesMap.values());
|
|
125
|
+
|
|
126
|
+
// mergeMetadataPages preserves the order from sourceMarkdown and returns the normalized
|
|
127
|
+
// metadata that renders to finalMarkdown - reused by the writer to populate the cache
|
|
128
|
+
// without re-parsing what it just wrote.
|
|
129
|
+
const merged = await mergeMetadataPages(sourceMarkdown, {
|
|
130
|
+
title: indexTitle,
|
|
131
|
+
pages: allPages
|
|
132
|
+
}, {
|
|
133
|
+
indexWrapperComponent,
|
|
134
|
+
preserveExistingTitleAndSlug
|
|
135
|
+
});
|
|
136
|
+
const finalMarkdown = await metadataToMarkdown(merged.metadata, {
|
|
137
|
+
editableMarker: merged.editableMarker,
|
|
138
|
+
indexWrapperComponent: merged.indexWrapperComponent,
|
|
139
|
+
// Only include path in the comment when baseDir is set (otherwise it's an absolute path).
|
|
140
|
+
path: relativeIndexPath
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
allPages,
|
|
144
|
+
merged,
|
|
145
|
+
finalMarkdown
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
100
149
|
/**
|
|
101
150
|
* Updates the parent directory's index file with metadata from a page.
|
|
102
151
|
*
|
|
@@ -218,6 +267,21 @@ export async function syncPageIndex(options) {
|
|
|
218
267
|
}
|
|
219
268
|
}
|
|
220
269
|
|
|
270
|
+
// Refresh the page-index cache from the committed markdown for the "nothing to write"
|
|
271
|
+
// exits, so the next cold loadServerPageIndex read stays warm without re-parsing.
|
|
272
|
+
const saveExistingIndexCache = async () => {
|
|
273
|
+
if (cacheDir && existingMetadata) {
|
|
274
|
+
await savePageIndexCache({
|
|
275
|
+
cacheDir,
|
|
276
|
+
indexPath,
|
|
277
|
+
rootContext,
|
|
278
|
+
markdown: existingContent,
|
|
279
|
+
metadata: existingMetadata,
|
|
280
|
+
defaultPageMetadata: false
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
221
285
|
// Step 3: Check if any of our metadata items need updating
|
|
222
286
|
let needsUpdate = false;
|
|
223
287
|
for (const metaItem of metadataArray) {
|
|
@@ -238,25 +302,36 @@ export async function syncPageIndex(options) {
|
|
|
238
302
|
}
|
|
239
303
|
}
|
|
240
304
|
if (!needsUpdate) {
|
|
241
|
-
|
|
242
|
-
await savePageIndexCache({
|
|
243
|
-
cacheDir,
|
|
244
|
-
indexPath,
|
|
245
|
-
rootContext,
|
|
246
|
-
markdown: existingContent,
|
|
247
|
-
metadata: existingMetadata,
|
|
248
|
-
defaultPageMetadata: false
|
|
249
|
-
});
|
|
250
|
-
}
|
|
305
|
+
await saveExistingIndexCache();
|
|
251
306
|
|
|
252
307
|
// All pages are already up-to-date, no need to acquire lock or write the index.
|
|
253
308
|
return;
|
|
254
309
|
}
|
|
255
310
|
|
|
256
|
-
// If errorIfOutOfDate is true,
|
|
311
|
+
// If errorIfOutOfDate is true, the writer would refuse to touch the file. The coarse
|
|
312
|
+
// per-page comparison above compares the raw in-memory metadata, which contains fields
|
|
313
|
+
// that never reach the persisted index (volatile AST node positions, or metadata that
|
|
314
|
+
// mergeMetadataPages fills in from the existing markdown). Those produce false positives.
|
|
315
|
+
// Determine whether the index is genuinely out of date by rendering the exact markdown
|
|
316
|
+
// the writer would produce and comparing it to what is committed on disk. Only fail when
|
|
317
|
+
// the rendered output actually differs. This is validation only - it never writes, so it
|
|
318
|
+
// works from the pre-lock read (existingMarkdown/existingPages) rather than re-reading
|
|
319
|
+
// under a lock like the writer does.
|
|
257
320
|
if (errorIfOutOfDate) {
|
|
258
|
-
const relativeIndexPath = baseDir ? relative(resolve(baseDir), indexPath) :
|
|
259
|
-
|
|
321
|
+
const relativeIndexPath = baseDir ? relative(resolve(baseDir), indexPath) : undefined;
|
|
322
|
+
const {
|
|
323
|
+
finalMarkdown
|
|
324
|
+
} = await renderIndexPages(existingMarkdown, existingPages, metadataArray, {
|
|
325
|
+
indexTitle,
|
|
326
|
+
indexWrapperComponent,
|
|
327
|
+
preserveExistingTitleAndSlug,
|
|
328
|
+
relativeIndexPath
|
|
329
|
+
});
|
|
330
|
+
if (existingContent !== finalMarkdown) {
|
|
331
|
+
throw new Error(`Index file is out of date: ${relativeIndexPath ?? indexPath}\n` + `Please run the validation command (or next build) locally and commit the updated index files.`);
|
|
332
|
+
}
|
|
333
|
+
await saveExistingIndexCache();
|
|
334
|
+
return;
|
|
260
335
|
}
|
|
261
336
|
|
|
262
337
|
// Step 4: Ensure the file exists before locking (proper-lockfile requires an existing file)
|
|
@@ -302,45 +377,24 @@ export async function syncPageIndex(options) {
|
|
|
302
377
|
}
|
|
303
378
|
}
|
|
304
379
|
|
|
305
|
-
//
|
|
306
|
-
//
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
// First, add all current pages
|
|
310
|
-
for (const page of currentPages) {
|
|
311
|
-
updatedPagesMap.set(page.path, page);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Then update/add the new metadata items
|
|
315
|
-
for (const metaItem of metadataArray) {
|
|
316
|
-
updatedPagesMap.set(metaItem.path, metaItem);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Convert back to array - this is the COMPLETE list of pages that should exist
|
|
320
|
-
const allPages = Array.from(updatedPagesMap.values());
|
|
321
|
-
|
|
322
|
-
// Store for parent update
|
|
323
|
-
mergedPages = allPages;
|
|
324
|
-
|
|
325
|
-
// Re-merge with the latest content, passing the COMPLETE list of pages.
|
|
326
|
-
// mergeMetadataPages preserves the order from currentMarkdown and returns the
|
|
327
|
-
// normalized metadata that renders to finalMarkdown - reused below to populate
|
|
328
|
-
// the cache without re-parsing what we just wrote.
|
|
329
|
-
// Only include path in the comment when baseDir is set (otherwise it's an absolute path)
|
|
380
|
+
// Re-merge with the latest content re-read under the lock, passing the COMPLETE list
|
|
381
|
+
// of pages. The returned normalized metadata is reused below to populate the cache
|
|
382
|
+
// without re-parsing what we just wrote.
|
|
330
383
|
const relativeIndexPath = baseDir ? relative(resolve(baseDir), indexPath) : undefined;
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
384
|
+
const {
|
|
385
|
+
allPages,
|
|
386
|
+
merged,
|
|
387
|
+
finalMarkdown
|
|
388
|
+
} = await renderIndexPages(currentMarkdown, currentPages, metadataArray, {
|
|
389
|
+
indexTitle,
|
|
335
390
|
indexWrapperComponent,
|
|
336
|
-
preserveExistingTitleAndSlug
|
|
337
|
-
|
|
338
|
-
const finalMarkdown = await metadataToMarkdown(merged.metadata, {
|
|
339
|
-
editableMarker: merged.editableMarker,
|
|
340
|
-
indexWrapperComponent: merged.indexWrapperComponent,
|
|
341
|
-
path: relativeIndexPath
|
|
391
|
+
preserveExistingTitleAndSlug,
|
|
392
|
+
relativeIndexPath
|
|
342
393
|
});
|
|
343
394
|
|
|
395
|
+
// Store for parent update
|
|
396
|
+
mergedPages = allPages;
|
|
397
|
+
|
|
344
398
|
// Defensive check
|
|
345
399
|
if (!finalMarkdown || !finalMarkdown.trim()) {
|
|
346
400
|
throw new Error(`Cannot write empty content to ${indexPath}`);
|