@riebeckite/core 0.0.16 → 0.0.18
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/README.md +6 -6
- package/README_ja.md +6 -6
- package/dist/index.d.ts +6 -2
- package/dist/index.js +590 -440
- package/dist/src/config.d.ts +3 -1
- package/dist/src/content/content_build_coordinator.d.ts +2 -1
- package/dist/src/content/content_build_state.d.ts +1 -1
- package/dist/src/content/content_dependency_tracker.d.ts +2 -0
- package/dist/src/content/content_index_builder.d.ts +6 -2
- package/dist/src/content/content_language.d.ts +3 -0
- package/dist/src/content/content_manager.d.ts +2 -0
- package/dist/src/content/content_stable_id.d.ts +1 -4
- package/dist/src/content/file_system_content_source.d.ts +10 -1
- package/dist/src/content/folder_entry.d.ts +1 -1
- package/dist/src/content/manifest_builder.d.ts +1 -1
- package/dist/src/pipeline.d.ts +1 -0
- package/dist/src/plugin/plugin_lifecycle.d.ts +7 -4
- package/dist/src/plugin/plugin_runtime.d.ts +5 -2
- package/dist/src/project/project_layout.d.ts +11 -0
- package/dist/src/types/content_manifest.d.ts +15 -4
- package/dist/src/types/plugin.d.ts +0 -2
- package/dist/src/types/plugin_page.d.ts +2 -0
- package/dist/src/types/plugin_seo.d.ts +3 -2
- package/dist/src/types/post_content.d.ts +0 -2
- package/dist/src/types/resolved_riebeckite_config.d.ts +12 -8
- package/dist/src/types/riebeckite_config.d.ts +0 -7
- package/dist/src/utils/error.d.ts +1 -0
- package/package.json +2 -2
- package/dist/src/types/navigation_config.d.ts +0 -10
package/dist/index.js
CHANGED
|
@@ -18,55 +18,12 @@ function validateConfigIssues(config) {
|
|
|
18
18
|
return [{ path: "config", message: "Expected an object." }];
|
|
19
19
|
}
|
|
20
20
|
validateSite(value.site, issues);
|
|
21
|
-
validateNavigation(value.navigation, issues);
|
|
22
21
|
validateContent(value.content, issues);
|
|
22
|
+
validateCache(value.cache, issues);
|
|
23
23
|
validateTheme(value.theme, issues);
|
|
24
24
|
validatePlugins(value.plugins, issues);
|
|
25
25
|
return issues;
|
|
26
26
|
}
|
|
27
|
-
function validateNavigation(value, issues) {
|
|
28
|
-
if (value === void 0) return;
|
|
29
|
-
if (!isRecord(value)) {
|
|
30
|
-
issues.push({ path: "navigation", message: "Expected an object." });
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
validateNavigationItems(value.header, "navigation.header", issues, /* @__PURE__ */ new Set());
|
|
34
|
-
validateNavigationItems(value.footer, "navigation.footer", issues, /* @__PURE__ */ new Set());
|
|
35
|
-
}
|
|
36
|
-
function validateNavigationItems(value, path5, issues, ancestors) {
|
|
37
|
-
if (value === void 0) return;
|
|
38
|
-
if (!Array.isArray(value)) {
|
|
39
|
-
issues.push({ path: path5, message: "Expected an array." });
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
for (const [index, item] of value.entries()) {
|
|
43
|
-
const itemPath = `${path5}[${index}]`;
|
|
44
|
-
if (!isRecord(item)) {
|
|
45
|
-
issues.push({ path: itemPath, message: "Expected an object." });
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
if (ancestors.has(item)) {
|
|
49
|
-
issues.push({
|
|
50
|
-
path: itemPath,
|
|
51
|
-
message: "Navigation children must not be recursive."
|
|
52
|
-
});
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
validateRequiredString(item.label, `${itemPath}.label`, issues);
|
|
56
|
-
validateRequiredString(item.href, `${itemPath}.href`, issues);
|
|
57
|
-
validateOptionalBoolean(item.external, `${itemPath}.external`, issues);
|
|
58
|
-
if (item.children !== void 0) {
|
|
59
|
-
const nextAncestors = new Set(ancestors);
|
|
60
|
-
nextAncestors.add(item);
|
|
61
|
-
validateNavigationItems(
|
|
62
|
-
item.children,
|
|
63
|
-
`${itemPath}.children`,
|
|
64
|
-
issues,
|
|
65
|
-
nextAncestors
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
27
|
function validateSite(value, issues) {
|
|
71
28
|
if (!isRecord(value)) {
|
|
72
29
|
issues.push({ path: "site", message: "Expected an object." });
|
|
@@ -137,6 +94,15 @@ function validatePublishStrategy(value, issues) {
|
|
|
137
94
|
});
|
|
138
95
|
}
|
|
139
96
|
}
|
|
97
|
+
function validateCache(value, issues) {
|
|
98
|
+
if (value === void 0) return;
|
|
99
|
+
if (!isRecord(value)) {
|
|
100
|
+
issues.push({ path: "cache", message: "Expected an object." });
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
validateOptionalBoolean(value.enabled, "cache.enabled", issues);
|
|
104
|
+
validateOptionalString(value.directory, "cache.directory", issues);
|
|
105
|
+
}
|
|
140
106
|
function validateTheme(value, issues) {
|
|
141
107
|
if (value === void 0) return;
|
|
142
108
|
if (!isRecord(value)) {
|
|
@@ -153,41 +119,41 @@ function validateTheme(value, issues) {
|
|
|
153
119
|
}
|
|
154
120
|
}
|
|
155
121
|
}
|
|
156
|
-
function validateThemeConfig(value,
|
|
157
|
-
validateOptionalString(value.name, `${
|
|
122
|
+
function validateThemeConfig(value, path6, issues) {
|
|
123
|
+
validateOptionalString(value.name, `${path6}.name`, issues);
|
|
158
124
|
validateOneOf(
|
|
159
125
|
value.colorMode,
|
|
160
|
-
`${
|
|
126
|
+
`${path6}.colorMode`,
|
|
161
127
|
["light", "dark", "system"],
|
|
162
128
|
issues
|
|
163
129
|
);
|
|
164
130
|
validateOneOf(
|
|
165
131
|
value.typography,
|
|
166
|
-
`${
|
|
132
|
+
`${path6}.typography`,
|
|
167
133
|
["system", "serif", "sans"],
|
|
168
134
|
issues
|
|
169
135
|
);
|
|
170
136
|
validateOneOf(
|
|
171
137
|
value.articleLayout,
|
|
172
|
-
`${
|
|
138
|
+
`${path6}.articleLayout`,
|
|
173
139
|
["article", "sidebar", "full-width"],
|
|
174
140
|
issues
|
|
175
141
|
);
|
|
176
|
-
validateStringArray(value.userCss, `${
|
|
142
|
+
validateStringArray(value.userCss, `${path6}.userCss`, issues);
|
|
177
143
|
if (value.attributes !== void 0 && !isRecord(value.attributes)) {
|
|
178
|
-
issues.push({ path: `${
|
|
144
|
+
issues.push({ path: `${path6}.attributes`, message: "Expected an object." });
|
|
179
145
|
}
|
|
180
146
|
}
|
|
181
|
-
function validateThemeStyles(value,
|
|
147
|
+
function validateThemeStyles(value, path6, issues) {
|
|
182
148
|
if (value === void 0) return;
|
|
183
149
|
if (!Array.isArray(value)) {
|
|
184
|
-
issues.push({ path:
|
|
150
|
+
issues.push({ path: path6, message: "Expected an array." });
|
|
185
151
|
return;
|
|
186
152
|
}
|
|
187
153
|
for (const [index, style] of value.entries()) {
|
|
188
154
|
if (!isRecord(style) || !isNonEmptyString(style.moduleSpecifier)) {
|
|
189
155
|
issues.push({
|
|
190
|
-
path: `${
|
|
156
|
+
path: `${path6}[${index}].moduleSpecifier`,
|
|
191
157
|
message: "Expected a non-empty string."
|
|
192
158
|
});
|
|
193
159
|
}
|
|
@@ -207,69 +173,69 @@ function validatePlugins(value, issues) {
|
|
|
207
173
|
continue;
|
|
208
174
|
}
|
|
209
175
|
const plugin = input;
|
|
210
|
-
const
|
|
176
|
+
const path6 = `plugins[${index}]`;
|
|
211
177
|
if (!isNonEmptyString(plugin.name)) {
|
|
212
178
|
issues.push({
|
|
213
|
-
path: `${
|
|
179
|
+
path: `${path6}.name`,
|
|
214
180
|
message: "Expected a non-empty string."
|
|
215
181
|
});
|
|
216
182
|
} else if (plugin.enabled !== false) {
|
|
217
183
|
const duplicateIndex = names.get(plugin.name);
|
|
218
184
|
if (duplicateIndex !== void 0) {
|
|
219
185
|
issues.push({
|
|
220
|
-
path: `${
|
|
186
|
+
path: `${path6}.name`,
|
|
221
187
|
message: `Duplicate plugin name "${plugin.name}" (also plugins[${duplicateIndex}]).`
|
|
222
188
|
});
|
|
223
189
|
} else {
|
|
224
190
|
names.set(plugin.name, index);
|
|
225
191
|
}
|
|
226
192
|
}
|
|
227
|
-
validateOptionalBoolean(plugin.enabled, `${
|
|
228
|
-
validateCapabilityMetadata(plugin,
|
|
229
|
-
if (plugin.enabled !== false) validatePluginOptions(plugin,
|
|
193
|
+
validateOptionalBoolean(plugin.enabled, `${path6}.enabled`, issues);
|
|
194
|
+
validateCapabilityMetadata(plugin, path6, issues);
|
|
195
|
+
if (plugin.enabled !== false) validatePluginOptions(plugin, path6, issues);
|
|
230
196
|
}
|
|
231
197
|
}
|
|
232
|
-
function validateCapabilityMetadata(plugin,
|
|
233
|
-
validateStringArray(plugin.provides, `${
|
|
234
|
-
validateStringArray(plugin.requires, `${
|
|
235
|
-
validateStringArray(plugin.optional, `${
|
|
198
|
+
function validateCapabilityMetadata(plugin, path6, issues) {
|
|
199
|
+
validateStringArray(plugin.provides, `${path6}.provides`, issues, true);
|
|
200
|
+
validateStringArray(plugin.requires, `${path6}.requires`, issues, true);
|
|
201
|
+
validateStringArray(plugin.optional, `${path6}.optional`, issues, true);
|
|
236
202
|
}
|
|
237
|
-
function validatePluginOptions(plugin,
|
|
203
|
+
function validatePluginOptions(plugin, path6, issues) {
|
|
238
204
|
if (!plugin.validateOptions) return;
|
|
239
205
|
try {
|
|
240
206
|
const optionIssues = plugin.validateOptions(plugin.options) ?? [];
|
|
241
207
|
for (const issue of optionIssues) {
|
|
242
208
|
issues.push({
|
|
243
|
-
path: issue.path ? `${
|
|
209
|
+
path: issue.path ? `${path6}.options.${issue.path}` : `${path6}.options`,
|
|
244
210
|
message: issue.message
|
|
245
211
|
});
|
|
246
212
|
}
|
|
247
213
|
} catch (error) {
|
|
248
214
|
issues.push({
|
|
249
|
-
path: `${
|
|
215
|
+
path: `${path6}.options`,
|
|
250
216
|
message: `Validator failed: ${toErrorMessage(error)}`
|
|
251
217
|
});
|
|
252
218
|
}
|
|
253
219
|
}
|
|
254
|
-
function validateRequiredString(value,
|
|
220
|
+
function validateRequiredString(value, path6, issues) {
|
|
255
221
|
if (!isNonEmptyString(value)) {
|
|
256
|
-
issues.push({ path:
|
|
222
|
+
issues.push({ path: path6, message: "Expected a non-empty string." });
|
|
257
223
|
}
|
|
258
224
|
}
|
|
259
|
-
function validateOptionalString(value,
|
|
225
|
+
function validateOptionalString(value, path6, issues) {
|
|
260
226
|
if (value !== void 0 && typeof value !== "string") {
|
|
261
|
-
issues.push({ path:
|
|
227
|
+
issues.push({ path: path6, message: "Expected a string." });
|
|
262
228
|
}
|
|
263
229
|
}
|
|
264
|
-
function validateOptionalBoolean(value,
|
|
230
|
+
function validateOptionalBoolean(value, path6, issues) {
|
|
265
231
|
if (value !== void 0 && typeof value !== "boolean") {
|
|
266
|
-
issues.push({ path:
|
|
232
|
+
issues.push({ path: path6, message: "Expected a boolean." });
|
|
267
233
|
}
|
|
268
234
|
}
|
|
269
|
-
function validateAbsoluteUrl(value,
|
|
235
|
+
function validateAbsoluteUrl(value, path6, issues) {
|
|
270
236
|
if (value === void 0 || value === "") return;
|
|
271
237
|
if (typeof value !== "string") {
|
|
272
|
-
issues.push({ path:
|
|
238
|
+
issues.push({ path: path6, message: "Expected an absolute URL." });
|
|
273
239
|
return;
|
|
274
240
|
}
|
|
275
241
|
try {
|
|
@@ -277,27 +243,27 @@ function validateAbsoluteUrl(value, path5, issues) {
|
|
|
277
243
|
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
278
244
|
throw new Error();
|
|
279
245
|
} catch {
|
|
280
|
-
issues.push({ path:
|
|
246
|
+
issues.push({ path: path6, message: "Expected an absolute HTTP(S) URL." });
|
|
281
247
|
}
|
|
282
248
|
}
|
|
283
|
-
function validateStringArray(value,
|
|
249
|
+
function validateStringArray(value, path6, issues, nonEmpty = false) {
|
|
284
250
|
if (value === void 0) return;
|
|
285
251
|
if (!Array.isArray(value)) {
|
|
286
|
-
issues.push({ path:
|
|
252
|
+
issues.push({ path: path6, message: "Expected an array." });
|
|
287
253
|
return;
|
|
288
254
|
}
|
|
289
255
|
for (const [index, item] of value.entries()) {
|
|
290
256
|
if (typeof item !== "string" || nonEmpty && !item.trim()) {
|
|
291
257
|
issues.push({
|
|
292
|
-
path: `${
|
|
258
|
+
path: `${path6}[${index}]`,
|
|
293
259
|
message: nonEmpty ? "Expected a non-empty string." : "Expected a string."
|
|
294
260
|
});
|
|
295
261
|
}
|
|
296
262
|
}
|
|
297
263
|
}
|
|
298
|
-
function validateOneOf(value,
|
|
264
|
+
function validateOneOf(value, path6, choices, issues) {
|
|
299
265
|
if (value !== void 0 && (typeof value !== "string" || !choices.includes(value))) {
|
|
300
|
-
issues.push({ path:
|
|
266
|
+
issues.push({ path: path6, message: `Expected one of: ${choices.join(", ")}.` });
|
|
301
267
|
}
|
|
302
268
|
}
|
|
303
269
|
function formatValidationIssues(issues) {
|
|
@@ -318,6 +284,74 @@ function toErrorMessage(error) {
|
|
|
318
284
|
return error instanceof Error ? error.message : String(error);
|
|
319
285
|
}
|
|
320
286
|
|
|
287
|
+
// src/types/publish_strategy.ts
|
|
288
|
+
function isPublishable(strategy, frontmatter) {
|
|
289
|
+
if (strategy === "explicit") {
|
|
290
|
+
return frontmatter?.publish === true;
|
|
291
|
+
}
|
|
292
|
+
return !(frontmatter?.private === true || frontmatter?.draft === true);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// src/content/publishing.ts
|
|
296
|
+
function resolvePublishingState(frontmatter, options) {
|
|
297
|
+
const explicitVisibility = resolveExplicitVisibility(frontmatter?.visibility);
|
|
298
|
+
const publishAt = resolvePublishAt(frontmatter?.publishAt);
|
|
299
|
+
if (explicitVisibility === "draft")
|
|
300
|
+
return state("draft", false, false, publishAt);
|
|
301
|
+
if (publishAt && publishAt.getTime() > options.buildTime.getTime()) {
|
|
302
|
+
return state("scheduled", false, false, publishAt);
|
|
303
|
+
}
|
|
304
|
+
if (explicitVisibility === "unlisted") {
|
|
305
|
+
return state("unlisted", true, false, publishAt);
|
|
306
|
+
}
|
|
307
|
+
if (explicitVisibility === "public" || publishAt) {
|
|
308
|
+
return state("public", true, true, publishAt);
|
|
309
|
+
}
|
|
310
|
+
const routable = isPublishable(options.strategy, frontmatter);
|
|
311
|
+
return state(routable ? "public" : "draft", routable, routable, publishAt);
|
|
312
|
+
}
|
|
313
|
+
function resolvePublishingBuildTime(input) {
|
|
314
|
+
if (input === void 0) return /* @__PURE__ */ new Date();
|
|
315
|
+
if (input instanceof Date) {
|
|
316
|
+
if (Number.isNaN(input.getTime()))
|
|
317
|
+
throw new Error("Invalid publishing build time.");
|
|
318
|
+
return new Date(input.getTime());
|
|
319
|
+
}
|
|
320
|
+
const parsed = new Date(input);
|
|
321
|
+
if (Number.isNaN(parsed.getTime()))
|
|
322
|
+
throw new Error("Invalid publishing build time.");
|
|
323
|
+
return parsed;
|
|
324
|
+
}
|
|
325
|
+
function resolveExplicitVisibility(value) {
|
|
326
|
+
if (value === void 0) return void 0;
|
|
327
|
+
if (value === "public" || value === "unlisted" || value === "draft")
|
|
328
|
+
return value;
|
|
329
|
+
throw new Error(
|
|
330
|
+
`Invalid content visibility "${String(value)}". Expected public, unlisted, or draft.`
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
function resolvePublishAt(value) {
|
|
334
|
+
if (value === void 0) return void 0;
|
|
335
|
+
if (!(typeof value === "string" || value instanceof Date)) {
|
|
336
|
+
throw new Error("Invalid publishAt. Expected an ISO 8601 date string.");
|
|
337
|
+
}
|
|
338
|
+
const parsed = value instanceof Date ? value : new Date(value);
|
|
339
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
340
|
+
throw new Error(
|
|
341
|
+
`Invalid publishAt "${String(value)}". Expected an ISO 8601 date string.`
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
return new Date(parsed.getTime());
|
|
345
|
+
}
|
|
346
|
+
function state(visibility, routable, discoverable, publishAt) {
|
|
347
|
+
return {
|
|
348
|
+
visibility,
|
|
349
|
+
routable,
|
|
350
|
+
discoverable,
|
|
351
|
+
...publishAt ? { publishAt } : {}
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
321
355
|
// src/plugin/plugin_dependency_error.ts
|
|
322
356
|
var PluginDependencyError = class extends Error {
|
|
323
357
|
kind;
|
|
@@ -607,14 +641,6 @@ function getResolvedPluginMetadata(plugins) {
|
|
|
607
641
|
}));
|
|
608
642
|
}
|
|
609
643
|
|
|
610
|
-
// src/types/publish_strategy.ts
|
|
611
|
-
function isPublishable(strategy, frontmatter) {
|
|
612
|
-
if (strategy === "explicit") {
|
|
613
|
-
return frontmatter?.publish === true;
|
|
614
|
-
}
|
|
615
|
-
return !(frontmatter?.private === true || frontmatter?.draft === true);
|
|
616
|
-
}
|
|
617
|
-
|
|
618
644
|
// src/types/theme_config.ts
|
|
619
645
|
function defineTheme(theme) {
|
|
620
646
|
return theme;
|
|
@@ -669,23 +695,14 @@ function resolveConfig(config) {
|
|
|
669
695
|
language: config.site?.feed?.language ?? config.site?.locale ?? "en"
|
|
670
696
|
}
|
|
671
697
|
},
|
|
672
|
-
navigation: {
|
|
673
|
-
header: config.navigation?.header ?? [],
|
|
674
|
-
footer: config.navigation?.footer ?? []
|
|
675
|
-
},
|
|
676
698
|
content: {
|
|
677
|
-
directory: config.content?.directory ?? "
|
|
699
|
+
directory: config.content?.directory ?? "content",
|
|
678
700
|
source: config.content?.source,
|
|
679
701
|
exclude: config.content?.exclude ?? [],
|
|
680
702
|
filters: {
|
|
681
703
|
publishStrategy: config.content?.filters?.publishStrategy ?? "explicit"
|
|
682
704
|
}
|
|
683
705
|
},
|
|
684
|
-
markdown: {
|
|
685
|
-
syntaxHighlight: {
|
|
686
|
-
theme: config.markdown?.syntaxHighlight?.theme ?? ""
|
|
687
|
-
}
|
|
688
|
-
},
|
|
689
706
|
theme,
|
|
690
707
|
plugins: resolvePlugins(config.plugins),
|
|
691
708
|
cache: {
|
|
@@ -723,10 +740,11 @@ function sanitizeThemeAttributes(attributes) {
|
|
|
723
740
|
).filter(([name]) => !reservedAttributes.has(name))
|
|
724
741
|
);
|
|
725
742
|
}
|
|
726
|
-
function isPublished(config, frontmatter) {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
743
|
+
function isPublished(config, frontmatter, options = {}) {
|
|
744
|
+
return resolvePublishingState(frontmatter, {
|
|
745
|
+
strategy: config.content.filters.publishStrategy,
|
|
746
|
+
buildTime: resolvePublishingBuildTime(options.buildTime)
|
|
747
|
+
}).routable;
|
|
730
748
|
}
|
|
731
749
|
function isExcluded(patterns, relativePath) {
|
|
732
750
|
const normalized = relativePath.replace(/\\/g, "/");
|
|
@@ -788,9 +806,9 @@ var configDeprecations = [];
|
|
|
788
806
|
function collectConfigDeprecationDiagnostics(config, notices = configDeprecations) {
|
|
789
807
|
return notices.filter((notice) => hasConfigPath(config, notice.path)).map(createDeprecationDiagnostic);
|
|
790
808
|
}
|
|
791
|
-
function hasConfigPath(config,
|
|
809
|
+
function hasConfigPath(config, path6) {
|
|
792
810
|
let value = config;
|
|
793
|
-
for (const segment of
|
|
811
|
+
for (const segment of path6.split(".")) {
|
|
794
812
|
if (!isRecord2(value) || !(segment in value)) return false;
|
|
795
813
|
value = value[segment];
|
|
796
814
|
}
|
|
@@ -853,7 +871,7 @@ import fs from "node:fs/promises";
|
|
|
853
871
|
import path from "node:path";
|
|
854
872
|
|
|
855
873
|
// src/content/content_build_state.ts
|
|
856
|
-
var CONTENT_BUILD_STATE_VERSION =
|
|
874
|
+
var CONTENT_BUILD_STATE_VERSION = 8;
|
|
857
875
|
var CONTENT_BUILD_STATE_DIRECTORY = ".riebeckite";
|
|
858
876
|
var CONTENT_BUILD_STATE_EXCLUDE = `${CONTENT_BUILD_STATE_DIRECTORY}/**`;
|
|
859
877
|
|
|
@@ -1258,9 +1276,9 @@ function buildContentCollections(entries, definitions) {
|
|
|
1258
1276
|
function normalizePageSize(value) {
|
|
1259
1277
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
1260
1278
|
}
|
|
1261
|
-
function withPage(
|
|
1262
|
-
if (index === 0) return
|
|
1263
|
-
const base =
|
|
1279
|
+
function withPage(path6, index) {
|
|
1280
|
+
if (index === 0) return path6;
|
|
1281
|
+
const base = path6 === "/" ? "" : path6;
|
|
1264
1282
|
return normalizePath(`${base}/page/${index + 1}`);
|
|
1265
1283
|
}
|
|
1266
1284
|
function defaultPath(context) {
|
|
@@ -1370,6 +1388,23 @@ function isResolvedNoteLink(link) {
|
|
|
1370
1388
|
return link.kind === "note" && link.slug !== null;
|
|
1371
1389
|
}
|
|
1372
1390
|
|
|
1391
|
+
// src/content/content_language.ts
|
|
1392
|
+
function getEntryLanguage(entry) {
|
|
1393
|
+
return entry.publicLocation.language;
|
|
1394
|
+
}
|
|
1395
|
+
function selectEntriesByLanguage(entries, language) {
|
|
1396
|
+
if (!language) {
|
|
1397
|
+
return entries;
|
|
1398
|
+
}
|
|
1399
|
+
const localized = entries.filter(
|
|
1400
|
+
(entry) => getEntryLanguage(entry) !== void 0
|
|
1401
|
+
);
|
|
1402
|
+
if (localized.length === 0) {
|
|
1403
|
+
return entries;
|
|
1404
|
+
}
|
|
1405
|
+
return localized.filter((entry) => getEntryLanguage(entry) === language);
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1373
1408
|
// src/content/content_location.ts
|
|
1374
1409
|
function resolveDefaultContentLocation(content) {
|
|
1375
1410
|
return {
|
|
@@ -1527,6 +1562,8 @@ import { matter as matter2 } from "vfile-matter";
|
|
|
1527
1562
|
|
|
1528
1563
|
// src/content/content_dependency_tracker.ts
|
|
1529
1564
|
import { createHash as createHash2 } from "node:crypto";
|
|
1565
|
+
var LINK_INDEX_PREFIX = "index:";
|
|
1566
|
+
var LINK_LOCATION_PREFIX = "location:";
|
|
1530
1567
|
function createContentDependencyTracker(source) {
|
|
1531
1568
|
const dependencies = /* @__PURE__ */ new Map();
|
|
1532
1569
|
const record = (identity, content) => {
|
|
@@ -1572,6 +1609,30 @@ function dependencyKey(dependency) {
|
|
|
1572
1609
|
return `${normalized.kind}:${normalized.id}`;
|
|
1573
1610
|
}
|
|
1574
1611
|
|
|
1612
|
+
// src/content/content_links.ts
|
|
1613
|
+
var WIKILINK_PATTERN = /(!)?\[\[([^\]|#^]+)(?:[#^][^\]|]+)?(?:\|[^\]]+)?\]\]/g;
|
|
1614
|
+
function extractContentLinks(markdown, contentIndex) {
|
|
1615
|
+
WIKILINK_PATTERN.lastIndex = 0;
|
|
1616
|
+
const links = [];
|
|
1617
|
+
for (let match = WIKILINK_PATTERN.exec(markdown); match !== null; match = WIKILINK_PATTERN.exec(markdown)) {
|
|
1618
|
+
const rawTarget = match[2]?.trim();
|
|
1619
|
+
if (!rawTarget) continue;
|
|
1620
|
+
const resolved = contentIndex.get(rawTarget.toLowerCase()) ?? null;
|
|
1621
|
+
links.push({
|
|
1622
|
+
raw: rawTarget,
|
|
1623
|
+
slug: resolved,
|
|
1624
|
+
kind: resolved ? linkKind(resolved) : "unresolved",
|
|
1625
|
+
embed: match[1] === "!"
|
|
1626
|
+
});
|
|
1627
|
+
}
|
|
1628
|
+
return links;
|
|
1629
|
+
}
|
|
1630
|
+
function linkKind(value) {
|
|
1631
|
+
if (isImagePath(value)) return "image";
|
|
1632
|
+
if (isAttachmentPath(value)) return "attachment";
|
|
1633
|
+
return "note";
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1575
1636
|
// src/content/content_persistent_cache.ts
|
|
1576
1637
|
import { createHash as createHash4 } from "node:crypto";
|
|
1577
1638
|
import fs2 from "node:fs/promises";
|
|
@@ -1768,7 +1829,6 @@ function computePipelineFingerprint(config) {
|
|
|
1768
1829
|
const fingerprintData = {
|
|
1769
1830
|
compatibilityVersion: CONTENT_CACHE_COMPATIBILITY_VERSION,
|
|
1770
1831
|
plugins: plugins.map((p) => pluginFingerprint(p)),
|
|
1771
|
-
markdown: config.markdown,
|
|
1772
1832
|
content: {
|
|
1773
1833
|
filters: config.content.filters
|
|
1774
1834
|
}
|
|
@@ -1933,6 +1993,7 @@ async function writeAtomically2(targetPath, versionDirectory2, serialized) {
|
|
|
1933
1993
|
}
|
|
1934
1994
|
function resolvePluginCacheDirectory(config) {
|
|
1935
1995
|
if (!config) return path3.resolve(process.cwd(), ".riebeckite", "cache");
|
|
1996
|
+
if (config.cache?.directory) return config.cache.directory;
|
|
1936
1997
|
if (config.buildDirectory) return path3.join(config.buildDirectory, "cache");
|
|
1937
1998
|
return path3.resolve(config.content.directory, "..", ".riebeckite", "cache");
|
|
1938
1999
|
}
|
|
@@ -2201,6 +2262,9 @@ var Pipeline = class {
|
|
|
2201
2262
|
frontmatter: file.data.matter || {},
|
|
2202
2263
|
html: String(file.value)
|
|
2203
2264
|
};
|
|
2265
|
+
if (embedDepth === 0 && sourceSlug && dependencyTracker) {
|
|
2266
|
+
this.recordNoteLinkDependencies(markDownContent, dependencyTracker);
|
|
2267
|
+
}
|
|
2204
2268
|
if (sourceSlug && dependencyTracker) {
|
|
2205
2269
|
this.reportContentDependencies(
|
|
2206
2270
|
sourceSlug,
|
|
@@ -2250,6 +2314,25 @@ var Pipeline = class {
|
|
|
2250
2314
|
this.options.isRoutable
|
|
2251
2315
|
);
|
|
2252
2316
|
}
|
|
2317
|
+
recordNoteLinkDependencies(markdown, dependencyTracker) {
|
|
2318
|
+
for (const link of extractContentLinks(markdown, this.contentIndex)) {
|
|
2319
|
+
if (link.slug !== null && link.kind === "note") {
|
|
2320
|
+
const id = `${LINK_LOCATION_PREFIX}${link.slug}`;
|
|
2321
|
+
dependencyTracker.recordLinkResolution(
|
|
2322
|
+
id,
|
|
2323
|
+
this.resolveLinkDependency(id)
|
|
2324
|
+
);
|
|
2325
|
+
continue;
|
|
2326
|
+
}
|
|
2327
|
+
if (link.kind === "unresolved") {
|
|
2328
|
+
const id = `${LINK_INDEX_PREFIX}${link.raw.toLowerCase()}`;
|
|
2329
|
+
dependencyTracker.recordLinkResolution(
|
|
2330
|
+
id,
|
|
2331
|
+
this.resolveLinkDependency(id)
|
|
2332
|
+
);
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2253
2336
|
use(processor, plugin, options) {
|
|
2254
2337
|
const register = processor.use.bind(processor);
|
|
2255
2338
|
if (options === void 0) {
|
|
@@ -2353,8 +2436,6 @@ function normalizeMarkdownLinks(context) {
|
|
|
2353
2436
|
});
|
|
2354
2437
|
};
|
|
2355
2438
|
}
|
|
2356
|
-
var LINK_INDEX_PREFIX = "index:";
|
|
2357
|
-
var LINK_LOCATION_PREFIX = "location:";
|
|
2358
2439
|
function resolveLinkDependencyValue(id, contentIndex, lookupPermalink, isRoutable) {
|
|
2359
2440
|
if (id.startsWith(LINK_INDEX_PREFIX)) {
|
|
2360
2441
|
return contentIndex.get(id.slice(LINK_INDEX_PREFIX.length)) ?? "";
|
|
@@ -2443,9 +2524,9 @@ function resolveRelativeMarkdownSlug(sourceSlug, targetPath) {
|
|
|
2443
2524
|
}
|
|
2444
2525
|
return normalizedParts.join("/").replace(/\.md$/i, "");
|
|
2445
2526
|
}
|
|
2446
|
-
function decodeUriPath(
|
|
2527
|
+
function decodeUriPath(path6) {
|
|
2447
2528
|
try {
|
|
2448
|
-
return decodeURI(
|
|
2529
|
+
return decodeURI(path6);
|
|
2449
2530
|
} catch {
|
|
2450
2531
|
return null;
|
|
2451
2532
|
}
|
|
@@ -2533,16 +2614,16 @@ var GeneratedOutputRegistry = class {
|
|
|
2533
2614
|
outputs = [];
|
|
2534
2615
|
owners = /* @__PURE__ */ new Map();
|
|
2535
2616
|
sinkFor(pluginName) {
|
|
2536
|
-
const register = (
|
|
2537
|
-
const owner = this.owners.get(
|
|
2617
|
+
const register = (path6, output) => {
|
|
2618
|
+
const owner = this.owners.get(path6);
|
|
2538
2619
|
if (owner) {
|
|
2539
2620
|
throw new Error(
|
|
2540
|
-
`Duplicate generated output path "${
|
|
2621
|
+
`Duplicate generated output path "${path6}" declared by "${owner}" and "${pluginName}".`
|
|
2541
2622
|
);
|
|
2542
2623
|
}
|
|
2543
|
-
this.owners.set(
|
|
2624
|
+
this.owners.set(path6, pluginName);
|
|
2544
2625
|
this.outputs.push({
|
|
2545
|
-
path:
|
|
2626
|
+
path: path6,
|
|
2546
2627
|
content: output.content,
|
|
2547
2628
|
dependencies: output.dependencies,
|
|
2548
2629
|
owner: pluginName
|
|
@@ -2565,12 +2646,29 @@ var GeneratedOutputRegistry = class {
|
|
|
2565
2646
|
};
|
|
2566
2647
|
|
|
2567
2648
|
// src/plugin/plugin_lifecycle.ts
|
|
2568
|
-
var
|
|
2649
|
+
var PluginHookError = class extends Error {
|
|
2650
|
+
path;
|
|
2569
2651
|
constructor(pluginName, hookName, cause) {
|
|
2570
2652
|
super(`Plugin "${pluginName}" failed during "${hookName}"`, { cause });
|
|
2571
|
-
this.name = "
|
|
2653
|
+
this.name = "PluginHookError";
|
|
2654
|
+
const path6 = cause?.path;
|
|
2655
|
+
if (typeof path6 === "string") this.path = path6;
|
|
2572
2656
|
}
|
|
2573
2657
|
};
|
|
2658
|
+
async function runPluginHook(plugin, hookName, context, hook) {
|
|
2659
|
+
try {
|
|
2660
|
+
return await context.tracer.span(
|
|
2661
|
+
`plugin.${hookName}`,
|
|
2662
|
+
{
|
|
2663
|
+
plugin: plugin.name,
|
|
2664
|
+
hook: hookName
|
|
2665
|
+
},
|
|
2666
|
+
() => hook(context)
|
|
2667
|
+
);
|
|
2668
|
+
} catch (error) {
|
|
2669
|
+
throw new PluginHookError(plugin.name, hookName, error);
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2574
2672
|
async function runSetup(plugins, createContext) {
|
|
2575
2673
|
await runLifecycleHook(
|
|
2576
2674
|
plugins,
|
|
@@ -2607,19 +2705,7 @@ async function runLifecycleHook(plugins, hookName, getHook, createContext) {
|
|
|
2607
2705
|
for (const plugin of plugins) {
|
|
2608
2706
|
const hook = getHook(plugin);
|
|
2609
2707
|
if (!hook) continue;
|
|
2610
|
-
|
|
2611
|
-
const context = createContext(plugin);
|
|
2612
|
-
await context.tracer.span(
|
|
2613
|
-
`plugin.${hookName}`,
|
|
2614
|
-
{
|
|
2615
|
-
plugin: plugin.name,
|
|
2616
|
-
hook: hookName
|
|
2617
|
-
},
|
|
2618
|
-
() => hook(context)
|
|
2619
|
-
);
|
|
2620
|
-
} catch (error) {
|
|
2621
|
-
throw new PluginLifecycleError(plugin.name, hookName, error);
|
|
2622
|
-
}
|
|
2708
|
+
await runPluginHook(plugin, hookName, createContext(plugin), hook);
|
|
2623
2709
|
}
|
|
2624
2710
|
}
|
|
2625
2711
|
|
|
@@ -2637,6 +2723,7 @@ var PluginRuntime = class {
|
|
|
2637
2723
|
generatedOutputs = new GeneratedOutputRegistry();
|
|
2638
2724
|
isBuildTime = false;
|
|
2639
2725
|
resolvedPlugins = null;
|
|
2726
|
+
pageDeclarations = /* @__PURE__ */ new WeakMap();
|
|
2640
2727
|
getDiagnostics() {
|
|
2641
2728
|
return this.diagnostics;
|
|
2642
2729
|
}
|
|
@@ -2647,7 +2734,7 @@ var PluginRuntime = class {
|
|
|
2647
2734
|
* Starts the plugin build lifecycle exactly once, regardless of which public
|
|
2648
2735
|
* entry point (content processing or location resolution) reaches it first.
|
|
2649
2736
|
* Concurrent callers await the same run, so the ordered hooks
|
|
2650
|
-
* (`setup` → `buildStart` → `
|
|
2737
|
+
* (`setup` → `buildStart` → `onConfigResolved`) are never
|
|
2651
2738
|
* duplicated and no caller proceeds before the lifecycle completes.
|
|
2652
2739
|
*/
|
|
2653
2740
|
startBuild(contentIndex) {
|
|
@@ -2655,7 +2742,7 @@ var PluginRuntime = class {
|
|
|
2655
2742
|
return this.buildLifecycle;
|
|
2656
2743
|
}
|
|
2657
2744
|
async runContentLoaded(slug, markdown, contentIndex) {
|
|
2658
|
-
await this.runHook((plugin) => plugin.onContentLoaded, {
|
|
2745
|
+
await this.runHook("onContentLoaded", (plugin) => plugin.onContentLoaded, {
|
|
2659
2746
|
...this.createContext(contentIndex),
|
|
2660
2747
|
slug,
|
|
2661
2748
|
markdown
|
|
@@ -2667,22 +2754,30 @@ var PluginRuntime = class {
|
|
|
2667
2754
|
for (const plugin of this.plugins()) {
|
|
2668
2755
|
const resolver = plugin.resolveContentLocations;
|
|
2669
2756
|
if (!resolver) continue;
|
|
2670
|
-
const
|
|
2671
|
-
|
|
2757
|
+
const pluginContext = this.createPluginContext(plugin, context);
|
|
2758
|
+
const resolved = await runPluginHook(
|
|
2759
|
+
plugin,
|
|
2760
|
+
"resolveContentLocations",
|
|
2761
|
+
pluginContext,
|
|
2762
|
+
resolver
|
|
2672
2763
|
);
|
|
2673
2764
|
locations.push(...resolved);
|
|
2674
2765
|
}
|
|
2675
2766
|
return locations;
|
|
2676
2767
|
}
|
|
2677
2768
|
async extendContentLocations(entries, locations, contentIndex) {
|
|
2678
|
-
await this.runHook(
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2769
|
+
await this.runHook(
|
|
2770
|
+
"extendContentLocations",
|
|
2771
|
+
(plugin) => plugin.extendContentLocations,
|
|
2772
|
+
{
|
|
2773
|
+
...this.createContext(contentIndex),
|
|
2774
|
+
entries,
|
|
2775
|
+
locations
|
|
2776
|
+
}
|
|
2777
|
+
);
|
|
2683
2778
|
}
|
|
2684
2779
|
async runPostHook(hookName, slug, markdown, content, contentIndex) {
|
|
2685
|
-
await this.runHook((plugin) => plugin[hookName], {
|
|
2780
|
+
await this.runHook(hookName, (plugin) => plugin[hookName], {
|
|
2686
2781
|
...this.createContext(contentIndex),
|
|
2687
2782
|
slug,
|
|
2688
2783
|
markdown,
|
|
@@ -2690,16 +2785,24 @@ var PluginRuntime = class {
|
|
|
2690
2785
|
});
|
|
2691
2786
|
}
|
|
2692
2787
|
async runGraphHook(entries, contentIndex) {
|
|
2693
|
-
await this.runHook(
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2788
|
+
await this.runHook(
|
|
2789
|
+
"extendContentGraph",
|
|
2790
|
+
(plugin) => plugin.extendContentGraph,
|
|
2791
|
+
{
|
|
2792
|
+
...this.createContext(contentIndex),
|
|
2793
|
+
entries
|
|
2794
|
+
}
|
|
2795
|
+
);
|
|
2697
2796
|
}
|
|
2698
2797
|
async runManifestCreated(manifest, contentIndex) {
|
|
2699
|
-
await this.runHook(
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2798
|
+
await this.runHook(
|
|
2799
|
+
"onManifestCreated",
|
|
2800
|
+
(plugin) => plugin.onManifestCreated,
|
|
2801
|
+
{
|
|
2802
|
+
...this.createContext(contentIndex),
|
|
2803
|
+
manifest
|
|
2804
|
+
}
|
|
2805
|
+
);
|
|
2703
2806
|
}
|
|
2704
2807
|
async runBuildEnd(manifest, contentIndex) {
|
|
2705
2808
|
const context = {
|
|
@@ -2710,10 +2813,6 @@ var PluginRuntime = class {
|
|
|
2710
2813
|
this.plugins(),
|
|
2711
2814
|
(plugin) => this.createPluginContext(plugin, context)
|
|
2712
2815
|
);
|
|
2713
|
-
await this.runHook((plugin) => plugin.onBuildEnd, {
|
|
2714
|
-
...this.createContext(contentIndex),
|
|
2715
|
-
manifest
|
|
2716
|
-
});
|
|
2717
2816
|
}
|
|
2718
2817
|
enableBuildTime() {
|
|
2719
2818
|
this.isBuildTime = true;
|
|
@@ -2795,63 +2894,74 @@ var PluginRuntime = class {
|
|
|
2795
2894
|
return highest[0].page;
|
|
2796
2895
|
}
|
|
2797
2896
|
async getPagePaths(manifest, contentIndex) {
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
for (const rawPath of resolved) {
|
|
2806
|
-
paths.push(normalizePageTypePath(rawPath, pageType));
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
}
|
|
2810
|
-
return [...new Set(paths)];
|
|
2897
|
+
return [
|
|
2898
|
+
...new Set(
|
|
2899
|
+
(await this.getPageDeclarations(manifest, contentIndex)).map(
|
|
2900
|
+
(declaration) => declaration.pathname
|
|
2901
|
+
)
|
|
2902
|
+
)
|
|
2903
|
+
];
|
|
2811
2904
|
}
|
|
2812
2905
|
async getPageRoutes(manifest, contentIndex) {
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
for (const pathname of paths) {
|
|
2821
|
-
routes.push({
|
|
2822
|
-
pathname: normalizePageTypePath(pathname, pageType),
|
|
2823
|
-
pluginName: plugin.name,
|
|
2824
|
-
pageType: pageType.id
|
|
2825
|
-
});
|
|
2826
|
-
}
|
|
2827
|
-
}
|
|
2828
|
-
}
|
|
2829
|
-
return routes;
|
|
2906
|
+
return (await this.getPageDeclarations(manifest, contentIndex)).map(
|
|
2907
|
+
({ pathname, plugin, pageType }) => ({
|
|
2908
|
+
pathname,
|
|
2909
|
+
pluginName: plugin.name,
|
|
2910
|
+
pageType: pageType.id
|
|
2911
|
+
})
|
|
2912
|
+
);
|
|
2830
2913
|
}
|
|
2831
2914
|
async getPageOutputs(manifest, contentIndex) {
|
|
2832
|
-
const outputs =
|
|
2915
|
+
const outputs = await Promise.all(
|
|
2916
|
+
(await this.getPageDeclarations(manifest, contentIndex)).map(
|
|
2917
|
+
async ({ pathname, plugin, pageType }) => {
|
|
2918
|
+
const context = {
|
|
2919
|
+
...this.createContext(contentIndex),
|
|
2920
|
+
manifest,
|
|
2921
|
+
pathname
|
|
2922
|
+
};
|
|
2923
|
+
const dependencies = pageType.outputDependencies ? typeof pageType.outputDependencies === "function" ? await pageType.outputDependencies(
|
|
2924
|
+
this.createPluginContext(plugin, context)
|
|
2925
|
+
) : pageType.outputDependencies : [{ type: "unknown" }];
|
|
2926
|
+
return {
|
|
2927
|
+
output: {
|
|
2928
|
+
kind: "plugin-page",
|
|
2929
|
+
path: pathname,
|
|
2930
|
+
producer: `plugin:${plugin.name}:page:${pageType.id}`,
|
|
2931
|
+
dependencies
|
|
2932
|
+
},
|
|
2933
|
+
priority: pageType.priority ?? 0
|
|
2934
|
+
};
|
|
2935
|
+
}
|
|
2936
|
+
)
|
|
2937
|
+
);
|
|
2938
|
+
return uniqueOutputs(outputs);
|
|
2939
|
+
}
|
|
2940
|
+
async getPageDeclarations(manifest, contentIndex) {
|
|
2941
|
+
const existing = this.pageDeclarations.get(manifest);
|
|
2942
|
+
if (existing) return await existing;
|
|
2943
|
+
const declarations = this.resolvePageDeclarations(manifest, contentIndex);
|
|
2944
|
+
this.pageDeclarations.set(manifest, declarations);
|
|
2945
|
+
return await declarations;
|
|
2946
|
+
}
|
|
2947
|
+
async resolvePageDeclarations(manifest, contentIndex) {
|
|
2948
|
+
const declarations = [];
|
|
2833
2949
|
const context = { ...this.createContext(contentIndex), manifest };
|
|
2834
2950
|
for (const plugin of this.plugins()) {
|
|
2835
2951
|
for (const pageType of plugin.pageTypes ?? []) {
|
|
2836
|
-
const
|
|
2837
|
-
if (!
|
|
2838
|
-
const
|
|
2839
|
-
for (const
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
) : pageType.outputDependencies : [{ type: "unknown" }];
|
|
2845
|
-
outputs.push({
|
|
2846
|
-
kind: "plugin-page",
|
|
2847
|
-
path: pathname,
|
|
2848
|
-
producer: `plugin:${plugin.name}:page:${pageType.id}`,
|
|
2849
|
-
dependencies
|
|
2952
|
+
const paths = pageType.paths;
|
|
2953
|
+
if (!paths) continue;
|
|
2954
|
+
const resolved = typeof paths === "function" ? await paths(this.createPluginContext(plugin, context)) : paths;
|
|
2955
|
+
for (const pathname of resolved) {
|
|
2956
|
+
declarations.push({
|
|
2957
|
+
pathname: normalizePageTypePath(pathname, pageType),
|
|
2958
|
+
plugin,
|
|
2959
|
+
pageType
|
|
2850
2960
|
});
|
|
2851
2961
|
}
|
|
2852
2962
|
}
|
|
2853
2963
|
}
|
|
2854
|
-
return
|
|
2964
|
+
return declarations;
|
|
2855
2965
|
}
|
|
2856
2966
|
getContentOutputDependencies() {
|
|
2857
2967
|
return this.plugins().flatMap((plugin) => plugin.outputDependencies ?? []);
|
|
@@ -2862,9 +2972,13 @@ var PluginRuntime = class {
|
|
|
2862
2972
|
const results = [];
|
|
2863
2973
|
const context = this.createContext(contentIndex);
|
|
2864
2974
|
for (const plugin of this.plugins()) {
|
|
2865
|
-
const
|
|
2866
|
-
|
|
2867
|
-
|
|
2975
|
+
const hook = plugin.addDiagnostics;
|
|
2976
|
+
const diagnostics = hook ? await runPluginHook(
|
|
2977
|
+
plugin,
|
|
2978
|
+
"addDiagnostics",
|
|
2979
|
+
this.createPluginContext(plugin, context),
|
|
2980
|
+
hook
|
|
2981
|
+
) : void 0;
|
|
2868
2982
|
for (const diagnostic of diagnostics ?? []) {
|
|
2869
2983
|
results.push({
|
|
2870
2984
|
...diagnostic,
|
|
@@ -2893,13 +3007,13 @@ var PluginRuntime = class {
|
|
|
2893
3007
|
stage: "buildStart",
|
|
2894
3008
|
run: () => runBuildStart(this.plugins(), createPluginContext)
|
|
2895
3009
|
},
|
|
2896
|
-
{
|
|
2897
|
-
stage: "onBuildStart",
|
|
2898
|
-
run: () => this.runHook((plugin) => plugin.onBuildStart, context)
|
|
2899
|
-
},
|
|
2900
3010
|
{
|
|
2901
3011
|
stage: "onConfigResolved",
|
|
2902
|
-
run: () => this.runHook(
|
|
3012
|
+
run: () => this.runHook(
|
|
3013
|
+
"onConfigResolved",
|
|
3014
|
+
(plugin) => plugin.onConfigResolved,
|
|
3015
|
+
context
|
|
3016
|
+
)
|
|
2903
3017
|
}
|
|
2904
3018
|
];
|
|
2905
3019
|
for (const { stage, run } of stages) {
|
|
@@ -2944,18 +3058,12 @@ var PluginRuntime = class {
|
|
|
2944
3058
|
this.pluginCaches.set(plugin.name, cache);
|
|
2945
3059
|
return cache;
|
|
2946
3060
|
}
|
|
2947
|
-
async runHook(hook, context) {
|
|
3061
|
+
async runHook(hookName, hook, context) {
|
|
2948
3062
|
for (const plugin of this.plugins()) {
|
|
2949
3063
|
const pluginHook = hook(plugin);
|
|
2950
3064
|
if (!pluginHook) continue;
|
|
2951
3065
|
const pluginContext = this.createPluginContext(plugin, context);
|
|
2952
|
-
await pluginContext
|
|
2953
|
-
"plugin.hook",
|
|
2954
|
-
{
|
|
2955
|
-
plugin: plugin.name
|
|
2956
|
-
},
|
|
2957
|
-
() => pluginHook(pluginContext)
|
|
2958
|
-
);
|
|
3066
|
+
await runPluginHook(plugin, hookName, pluginContext, pluginHook);
|
|
2959
3067
|
}
|
|
2960
3068
|
}
|
|
2961
3069
|
observability() {
|
|
@@ -3029,22 +3137,40 @@ function normalizePageTypePath(pathname, pageType) {
|
|
|
3029
3137
|
return pageType.directoryIndex ? normalizeDirectoryPagePath(pathname) : normalizePagePath(pathname);
|
|
3030
3138
|
}
|
|
3031
3139
|
function normalizeDirectoryPagePath(pathname) {
|
|
3032
|
-
const
|
|
3033
|
-
return
|
|
3140
|
+
const path6 = normalizePagePath(pathname);
|
|
3141
|
+
return path6 === "/" ? path6 : `${path6}/`;
|
|
3034
3142
|
}
|
|
3035
3143
|
function normalizePagePath(pathname) {
|
|
3036
|
-
const
|
|
3037
|
-
return
|
|
3144
|
+
const path6 = `/${pathname.split("/").filter(Boolean).join("/")}`;
|
|
3145
|
+
return path6 === "/" ? path6 : path6.replace(/\/$/, "");
|
|
3038
3146
|
}
|
|
3039
3147
|
function countSeverity(diagnostics, severity) {
|
|
3040
3148
|
return diagnostics.filter((diagnostic) => diagnostic.severity === severity).length;
|
|
3041
3149
|
}
|
|
3042
3150
|
function uniqueOutputs(outputs) {
|
|
3043
3151
|
const byPath = /* @__PURE__ */ new Map();
|
|
3044
|
-
for (const output of outputs)
|
|
3045
|
-
|
|
3046
|
-
(
|
|
3047
|
-
|
|
3152
|
+
for (const output of outputs) {
|
|
3153
|
+
const previous = byPath.get(output.output.path);
|
|
3154
|
+
if (!previous || output.priority > previous.priority) {
|
|
3155
|
+
byPath.set(output.output.path, output);
|
|
3156
|
+
continue;
|
|
3157
|
+
}
|
|
3158
|
+
if (output.output.producer === previous.output.producer) continue;
|
|
3159
|
+
if (output.priority === previous.priority) {
|
|
3160
|
+
throw new Error(
|
|
3161
|
+
`Multiple plugin page types declare ${output.output.path} at priority ${output.priority}: ${previous.output.producer}, ${output.output.producer}`
|
|
3162
|
+
);
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
return [...byPath.values()].map(({ output }) => output).sort((left, right) => left.path.localeCompare(right.path));
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
// src/utils/error.ts
|
|
3169
|
+
function attachErrorPath(error, path6) {
|
|
3170
|
+
if (error instanceof Error && error.path === void 0) {
|
|
3171
|
+
error.path = path6;
|
|
3172
|
+
}
|
|
3173
|
+
return error;
|
|
3048
3174
|
}
|
|
3049
3175
|
|
|
3050
3176
|
// src/content/affected_content.ts
|
|
@@ -3067,9 +3193,9 @@ function determineAffectedContent(changeSet, previousState, currentPaths, curren
|
|
|
3067
3193
|
previousState.contentIndex,
|
|
3068
3194
|
currentContentIndex
|
|
3069
3195
|
);
|
|
3070
|
-
for (const [
|
|
3071
|
-
if (!isMarkdownPath2(
|
|
3072
|
-
const slug = toDependencyId(
|
|
3196
|
+
for (const [path6, entry] of Object.entries(previousState.entries)) {
|
|
3197
|
+
if (!isMarkdownPath2(path6)) continue;
|
|
3198
|
+
const slug = toDependencyId(path6);
|
|
3073
3199
|
if (direct.has(slug) || dependent.has(slug)) continue;
|
|
3074
3200
|
if (!entry.linkTargets?.some((target) => changedIndexKeys.has(target))) {
|
|
3075
3201
|
continue;
|
|
@@ -3106,27 +3232,27 @@ function findChangedIndexKeys(previousIndex, currentIndex) {
|
|
|
3106
3232
|
return changed;
|
|
3107
3233
|
}
|
|
3108
3234
|
function addAllNotes(target, currentPaths, exclude) {
|
|
3109
|
-
for (const
|
|
3110
|
-
if (!isMarkdownPath2(
|
|
3111
|
-
const slug = toDependencyId(
|
|
3235
|
+
for (const path6 of currentPaths) {
|
|
3236
|
+
if (!isMarkdownPath2(path6)) continue;
|
|
3237
|
+
const slug = toDependencyId(path6);
|
|
3112
3238
|
if (exclude?.has(slug)) continue;
|
|
3113
3239
|
target.add(slug);
|
|
3114
3240
|
}
|
|
3115
3241
|
}
|
|
3116
|
-
function isMarkdownPath2(
|
|
3117
|
-
return
|
|
3242
|
+
function isMarkdownPath2(path6) {
|
|
3243
|
+
return path6.endsWith(".md");
|
|
3118
3244
|
}
|
|
3119
|
-
function toDependencyId(
|
|
3120
|
-
return
|
|
3245
|
+
function toDependencyId(path6) {
|
|
3246
|
+
return path6.replace(/\.md$/, "");
|
|
3121
3247
|
}
|
|
3122
|
-
function toDependency(
|
|
3123
|
-
return isMarkdownPath2(
|
|
3248
|
+
function toDependency(path6) {
|
|
3249
|
+
return isMarkdownPath2(path6) ? { kind: "content", id: toDependencyId(path6) } : { kind: "file", id: path6.replace(/\\/g, "/") };
|
|
3124
3250
|
}
|
|
3125
3251
|
function buildDependentsByDependency(state2) {
|
|
3126
3252
|
const dependents = /* @__PURE__ */ new Map();
|
|
3127
|
-
for (const [
|
|
3128
|
-
if (!isMarkdownPath2(
|
|
3129
|
-
const slug = toDependencyId(
|
|
3253
|
+
for (const [path6, entry] of Object.entries(state2.entries)) {
|
|
3254
|
+
if (!isMarkdownPath2(path6)) continue;
|
|
3255
|
+
const slug = toDependencyId(path6);
|
|
3130
3256
|
for (const dependency of entry.dependencies) {
|
|
3131
3257
|
const key = dependencyKey2(dependency);
|
|
3132
3258
|
const values = dependents.get(key) ?? /* @__PURE__ */ new Set();
|
|
@@ -3148,18 +3274,18 @@ function diffContentEntries(previous, current) {
|
|
|
3148
3274
|
const added = [];
|
|
3149
3275
|
const changed = [];
|
|
3150
3276
|
const unchanged = [];
|
|
3151
|
-
for (const [
|
|
3152
|
-
const previousEntry = previous.entries[
|
|
3277
|
+
for (const [path6, fingerprint] of currentFingerprints) {
|
|
3278
|
+
const previousEntry = previous.entries[path6];
|
|
3153
3279
|
if (!previousEntry) {
|
|
3154
|
-
added.push(
|
|
3280
|
+
added.push(path6);
|
|
3155
3281
|
} else if (previousEntry.fingerprint !== fingerprint) {
|
|
3156
|
-
changed.push(
|
|
3282
|
+
changed.push(path6);
|
|
3157
3283
|
} else {
|
|
3158
|
-
unchanged.push(
|
|
3284
|
+
unchanged.push(path6);
|
|
3159
3285
|
}
|
|
3160
3286
|
}
|
|
3161
3287
|
const removed = Object.keys(previous.entries).filter(
|
|
3162
|
-
(
|
|
3288
|
+
(path6) => !currentFingerprints.has(path6)
|
|
3163
3289
|
);
|
|
3164
3290
|
return sortChangeSet({ added, changed, removed, unchanged });
|
|
3165
3291
|
}
|
|
@@ -3171,9 +3297,6 @@ function allContentChanged(entries) {
|
|
|
3171
3297
|
unchanged: []
|
|
3172
3298
|
});
|
|
3173
3299
|
}
|
|
3174
|
-
function hasContentChanges(changeSet) {
|
|
3175
|
-
return changeSet.added.length > 0 || changeSet.changed.length > 0 || changeSet.removed.length > 0;
|
|
3176
|
-
}
|
|
3177
3300
|
function sortChangeSet(changeSet) {
|
|
3178
3301
|
return {
|
|
3179
3302
|
added: [...changeSet.added].sort(),
|
|
@@ -3249,54 +3372,73 @@ var ContentIndexBuilder = class _ContentIndexBuilder {
|
|
|
3249
3372
|
}
|
|
3250
3373
|
source;
|
|
3251
3374
|
async build(contentEntries, read = (entry) => this.source.read(entry)) {
|
|
3252
|
-
const
|
|
3375
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
3253
3376
|
for (const contentEntry of contentEntries) {
|
|
3254
|
-
await this.indexContentEntry(
|
|
3377
|
+
await this.indexContentEntry(candidates, contentEntry, read);
|
|
3255
3378
|
}
|
|
3256
|
-
return
|
|
3379
|
+
return resolveContentIndex(candidates);
|
|
3257
3380
|
}
|
|
3258
3381
|
static buildFromAliases(contentEntries, aliasesByPath) {
|
|
3259
|
-
const
|
|
3382
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
3260
3383
|
for (const contentEntry of contentEntries) {
|
|
3261
3384
|
_ContentIndexBuilder.indexContentEntryFromAliases(
|
|
3262
|
-
|
|
3385
|
+
candidates,
|
|
3263
3386
|
contentEntry,
|
|
3264
3387
|
aliasesByPath.get(contentEntry.path) ?? []
|
|
3265
3388
|
);
|
|
3266
3389
|
}
|
|
3267
|
-
return
|
|
3390
|
+
return resolveContentIndex(candidates);
|
|
3268
3391
|
}
|
|
3269
|
-
async indexContentEntry(
|
|
3392
|
+
async indexContentEntry(candidates, contentEntry, read) {
|
|
3270
3393
|
const aliases = contentEntry.path.toLowerCase().endsWith(".md") ? extractFrontmatterAliases(readText(await read(contentEntry))) : [];
|
|
3271
3394
|
_ContentIndexBuilder.indexContentEntryFromAliases(
|
|
3272
|
-
|
|
3395
|
+
candidates,
|
|
3273
3396
|
contentEntry,
|
|
3274
3397
|
aliases
|
|
3275
3398
|
);
|
|
3276
3399
|
}
|
|
3277
|
-
static indexContentEntryFromAliases(
|
|
3400
|
+
static indexContentEntryFromAliases(candidates, contentEntry, aliases) {
|
|
3278
3401
|
const contentPath = contentEntry.path;
|
|
3279
3402
|
const ext = contentPath.split(".").pop()?.toLowerCase() ?? "";
|
|
3280
3403
|
const value = ext === "md" ? contentPath.replace(/\.md$/, "") : contentPath;
|
|
3281
3404
|
const parts = value.split("/");
|
|
3282
3405
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
3283
3406
|
const rawSuffix = parts.slice(i).join("/");
|
|
3284
|
-
|
|
3407
|
+
addCandidate(candidates, rawSuffix, value);
|
|
3285
3408
|
if (ext !== "md") {
|
|
3286
|
-
|
|
3409
|
+
addCandidate(candidates, rawSuffix.replace(/\.[^/.]+$/, ""), value);
|
|
3287
3410
|
}
|
|
3288
3411
|
}
|
|
3289
3412
|
if (ext === "md") {
|
|
3290
|
-
for (const alias of aliases)
|
|
3413
|
+
for (const alias of aliases) addCandidate(candidates, alias, value);
|
|
3291
3414
|
}
|
|
3292
3415
|
}
|
|
3293
3416
|
};
|
|
3417
|
+
function resolveContentIndex(candidates) {
|
|
3418
|
+
const index = /* @__PURE__ */ new Map();
|
|
3419
|
+
const ambiguities = /* @__PURE__ */ new Map();
|
|
3420
|
+
for (const [key, values] of candidates) {
|
|
3421
|
+
const list = [...values].sort(compareCandidates);
|
|
3422
|
+
const [only] = list;
|
|
3423
|
+
if (list.length === 1 && only !== void 0) {
|
|
3424
|
+
index.set(key, only);
|
|
3425
|
+
continue;
|
|
3426
|
+
}
|
|
3427
|
+
ambiguities.set(key, list);
|
|
3428
|
+
}
|
|
3429
|
+
return { index, ambiguities };
|
|
3430
|
+
}
|
|
3431
|
+
function compareCandidates(left, right) {
|
|
3432
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
3433
|
+
}
|
|
3294
3434
|
function readText(content) {
|
|
3295
3435
|
return typeof content === "string" ? content : new TextDecoder().decode(content);
|
|
3296
3436
|
}
|
|
3297
|
-
function
|
|
3437
|
+
function addCandidate(candidates, key, value) {
|
|
3298
3438
|
const normalizedKey = key.toLowerCase();
|
|
3299
|
-
|
|
3439
|
+
const values = candidates.get(normalizedKey) ?? /* @__PURE__ */ new Set();
|
|
3440
|
+
values.add(value);
|
|
3441
|
+
candidates.set(normalizedKey, values);
|
|
3300
3442
|
}
|
|
3301
3443
|
|
|
3302
3444
|
// src/content/content_build_coordinator.ts
|
|
@@ -3379,7 +3521,10 @@ var ContentBuildCoordinator = class {
|
|
|
3379
3521
|
previousState,
|
|
3380
3522
|
changeSet
|
|
3381
3523
|
);
|
|
3382
|
-
const
|
|
3524
|
+
const {
|
|
3525
|
+
index: currentContentIndex,
|
|
3526
|
+
ambiguities: currentContentIndexAmbiguities
|
|
3527
|
+
} = await this.dependencies.observability.tracer.span(
|
|
3383
3528
|
"content.index",
|
|
3384
3529
|
{},
|
|
3385
3530
|
() => ContentIndexBuilder.buildFromAliases(
|
|
@@ -3417,6 +3562,7 @@ var ContentBuildCoordinator = class {
|
|
|
3417
3562
|
currentEntries,
|
|
3418
3563
|
currentContentAliases,
|
|
3419
3564
|
currentContentIndex,
|
|
3565
|
+
currentContentIndexAmbiguities,
|
|
3420
3566
|
changeSet,
|
|
3421
3567
|
affectedContent: affected
|
|
3422
3568
|
};
|
|
@@ -3444,8 +3590,8 @@ var ContentBuildCoordinator = class {
|
|
|
3444
3590
|
function readText2(content) {
|
|
3445
3591
|
return typeof content === "string" ? content : new TextDecoder().decode(content);
|
|
3446
3592
|
}
|
|
3447
|
-
function toSlug(
|
|
3448
|
-
return
|
|
3593
|
+
function toSlug(path6) {
|
|
3594
|
+
return path6.replace(/\.md$/, "");
|
|
3449
3595
|
}
|
|
3450
3596
|
function collectDependencies2(manifestEntry, trackedDependencies) {
|
|
3451
3597
|
if (!manifestEntry) return [];
|
|
@@ -3459,8 +3605,8 @@ function collectDependencies2(manifestEntry, trackedDependencies) {
|
|
|
3459
3605
|
kind: "file",
|
|
3460
3606
|
id: asset.path.replace(/\\/g, "/")
|
|
3461
3607
|
})),
|
|
3462
|
-
...trackedDependencies.filter(
|
|
3463
|
-
(dependency) => dependency
|
|
3608
|
+
...trackedDependencies.map(toBuildDependency).filter(
|
|
3609
|
+
(dependency) => dependency !== null
|
|
3464
3610
|
).map((dependency) => ({
|
|
3465
3611
|
kind: dependency.kind,
|
|
3466
3612
|
id: dependency.id.replace(/\\/g, "/")
|
|
@@ -3474,6 +3620,18 @@ function collectDependencies2(manifestEntry, trackedDependencies) {
|
|
|
3474
3620
|
(left, right) => `${left.kind}:${left.id}`.localeCompare(`${right.kind}:${right.id}`)
|
|
3475
3621
|
);
|
|
3476
3622
|
}
|
|
3623
|
+
function toBuildDependency(dependency) {
|
|
3624
|
+
if (dependency.kind === "content" || dependency.kind === "file") {
|
|
3625
|
+
return { kind: dependency.kind, id: dependency.id };
|
|
3626
|
+
}
|
|
3627
|
+
if (dependency.id.startsWith(LINK_LOCATION_PREFIX)) {
|
|
3628
|
+
return {
|
|
3629
|
+
kind: "content",
|
|
3630
|
+
id: dependency.id.slice(LINK_LOCATION_PREFIX.length)
|
|
3631
|
+
};
|
|
3632
|
+
}
|
|
3633
|
+
return null;
|
|
3634
|
+
}
|
|
3477
3635
|
function collectLinkTargets(manifestEntry) {
|
|
3478
3636
|
if (!manifestEntry) return [];
|
|
3479
3637
|
return [
|
|
@@ -3616,8 +3774,8 @@ var ContentLocationResolver = class {
|
|
|
3616
3774
|
}
|
|
3617
3775
|
}
|
|
3618
3776
|
};
|
|
3619
|
-
function toSlug2(
|
|
3620
|
-
return
|
|
3777
|
+
function toSlug2(path6) {
|
|
3778
|
+
return path6.replace(/\.md$/, "");
|
|
3621
3779
|
}
|
|
3622
3780
|
async function mapConcurrent2(values, concurrency, map) {
|
|
3623
3781
|
const results = new Array(values.length);
|
|
@@ -3663,8 +3821,17 @@ var FileSystemContentSource = class {
|
|
|
3663
3821
|
contentDirectory;
|
|
3664
3822
|
exclude;
|
|
3665
3823
|
async scan() {
|
|
3824
|
+
return (await this.scanWithExclusions()).entries;
|
|
3825
|
+
}
|
|
3826
|
+
async scanWithExclusions() {
|
|
3827
|
+
const exclusions = [];
|
|
3666
3828
|
try {
|
|
3667
|
-
|
|
3829
|
+
const entries = await this.scanDirectory(
|
|
3830
|
+
this.contentDirectory,
|
|
3831
|
+
"",
|
|
3832
|
+
exclusions
|
|
3833
|
+
);
|
|
3834
|
+
return { entries, exclusions };
|
|
3668
3835
|
} catch (error) {
|
|
3669
3836
|
if (isMissingDirectoryError(error, this.contentDirectory)) {
|
|
3670
3837
|
throw missingContentDirectoryError(this.contentDirectory);
|
|
@@ -3680,7 +3847,7 @@ var FileSystemContentSource = class {
|
|
|
3680
3847
|
}
|
|
3681
3848
|
return await fs4.readFile(filePath);
|
|
3682
3849
|
}
|
|
3683
|
-
async scanDirectory(directory, parentPath2) {
|
|
3850
|
+
async scanDirectory(directory, parentPath2, exclusions) {
|
|
3684
3851
|
const directoryEntries = await fs4.readdir(directory, {
|
|
3685
3852
|
withFileTypes: true
|
|
3686
3853
|
});
|
|
@@ -3691,9 +3858,16 @@ var FileSystemContentSource = class {
|
|
|
3691
3858
|
parentPath2 ? `${parentPath2}/${directoryEntry.name}` : directoryEntry.name
|
|
3692
3859
|
);
|
|
3693
3860
|
const filePath = path4.join(directory, directoryEntry.name);
|
|
3694
|
-
if (
|
|
3861
|
+
if (isExcluded(INTERNAL_CONTENT_IGNORE_PATTERNS, logicalPath)) continue;
|
|
3862
|
+
const pattern = matchContentExcludePattern(logicalPath, this.exclude);
|
|
3863
|
+
if (pattern !== void 0) {
|
|
3864
|
+
exclusions.push({ path: logicalPath, pattern });
|
|
3865
|
+
continue;
|
|
3866
|
+
}
|
|
3695
3867
|
if (directoryEntry.isDirectory()) {
|
|
3696
|
-
entries.push(
|
|
3868
|
+
entries.push(
|
|
3869
|
+
...await this.scanDirectory(filePath, logicalPath, exclusions)
|
|
3870
|
+
);
|
|
3697
3871
|
continue;
|
|
3698
3872
|
}
|
|
3699
3873
|
if (!directoryEntry.isFile()) continue;
|
|
@@ -3708,9 +3882,6 @@ var FileSystemContentSource = class {
|
|
|
3708
3882
|
}
|
|
3709
3883
|
return entries;
|
|
3710
3884
|
}
|
|
3711
|
-
isExcluded(logicalPath) {
|
|
3712
|
-
return isIgnoredContentPath(logicalPath, this.exclude);
|
|
3713
|
-
}
|
|
3714
3885
|
resolveFilePath(logicalPath) {
|
|
3715
3886
|
const normalizedPath = normalizeLogicalPath(logicalPath);
|
|
3716
3887
|
const filePath = path4.resolve(this.contentDirectory, normalizedPath);
|
|
@@ -3723,8 +3894,14 @@ var FileSystemContentSource = class {
|
|
|
3723
3894
|
};
|
|
3724
3895
|
function isIgnoredContentPath(logicalPath, exclude = []) {
|
|
3725
3896
|
if (isExcluded(INTERNAL_CONTENT_IGNORE_PATTERNS, logicalPath)) return true;
|
|
3726
|
-
|
|
3727
|
-
|
|
3897
|
+
return matchContentExcludePattern(logicalPath, exclude) !== void 0;
|
|
3898
|
+
}
|
|
3899
|
+
function matchContentExcludePattern(logicalPath, exclude = []) {
|
|
3900
|
+
const direct = exclude.find((pattern) => isExcluded([pattern], logicalPath));
|
|
3901
|
+
if (direct !== void 0) return direct;
|
|
3902
|
+
if (!logicalPath.endsWith(".md")) return void 0;
|
|
3903
|
+
const withoutExtension = logicalPath.slice(0, -3);
|
|
3904
|
+
return exclude.find((pattern) => isExcluded([pattern], withoutExtension));
|
|
3728
3905
|
}
|
|
3729
3906
|
function normalizeLogicalPath(logicalPath) {
|
|
3730
3907
|
const normalizedPath = normalizeContentPath(logicalPath);
|
|
@@ -3748,53 +3925,22 @@ function missingContentDirectoryError(directory) {
|
|
|
3748
3925
|
return error;
|
|
3749
3926
|
}
|
|
3750
3927
|
|
|
3751
|
-
// src/content/content_links.ts
|
|
3752
|
-
var WIKILINK_PATTERN = /(!)?\[\[([^\]|#^]+)(?:[#^][^\]|]+)?(?:\|[^\]]+)?\]\]/g;
|
|
3753
|
-
function extractContentLinks(markdown, contentIndex) {
|
|
3754
|
-
WIKILINK_PATTERN.lastIndex = 0;
|
|
3755
|
-
const links = [];
|
|
3756
|
-
for (let match = WIKILINK_PATTERN.exec(markdown); match !== null; match = WIKILINK_PATTERN.exec(markdown)) {
|
|
3757
|
-
const rawTarget = match[2]?.trim();
|
|
3758
|
-
if (!rawTarget) continue;
|
|
3759
|
-
const resolved = contentIndex.get(rawTarget.toLowerCase()) ?? null;
|
|
3760
|
-
links.push({
|
|
3761
|
-
raw: rawTarget,
|
|
3762
|
-
slug: resolved,
|
|
3763
|
-
kind: resolved ? linkKind(resolved) : "unresolved",
|
|
3764
|
-
embed: match[1] === "!"
|
|
3765
|
-
});
|
|
3766
|
-
}
|
|
3767
|
-
return links;
|
|
3768
|
-
}
|
|
3769
|
-
function linkKind(value) {
|
|
3770
|
-
if (isImagePath(value)) return "image";
|
|
3771
|
-
if (isAttachmentPath(value)) return "attachment";
|
|
3772
|
-
return "note";
|
|
3773
|
-
}
|
|
3774
|
-
|
|
3775
3928
|
// src/content/content_stable_id.ts
|
|
3776
3929
|
var MAX_STABLE_CONTENT_ID_LENGTH = 160;
|
|
3777
3930
|
function resolveContentStableId(frontmatter) {
|
|
3778
|
-
|
|
3779
|
-
const uid = readOptionalStableId(frontmatter.uid, "uid");
|
|
3780
|
-
if (id !== void 0 && uid !== void 0 && id !== uid) {
|
|
3781
|
-
throw new Error(
|
|
3782
|
-
'Content frontmatter fields "id" and "uid" must have the same value.'
|
|
3783
|
-
);
|
|
3784
|
-
}
|
|
3785
|
-
return id ?? uid;
|
|
3931
|
+
return readOptionalStableId(frontmatter.id);
|
|
3786
3932
|
}
|
|
3787
|
-
function readOptionalStableId(value
|
|
3933
|
+
function readOptionalStableId(value) {
|
|
3788
3934
|
if (value === void 0) return void 0;
|
|
3789
3935
|
if (typeof value !== "string") {
|
|
3790
|
-
throw new Error(`Content frontmatter field "
|
|
3936
|
+
throw new Error(`Content frontmatter field "id" must be a string.`);
|
|
3791
3937
|
}
|
|
3792
3938
|
if (value.length === 0 || value.length > MAX_STABLE_CONTENT_ID_LENGTH || value.trim() !== value || [...value].some((character) => {
|
|
3793
3939
|
const code = character.codePointAt(0) ?? 0;
|
|
3794
3940
|
return code <= 31 || code === 127;
|
|
3795
3941
|
})) {
|
|
3796
3942
|
throw new Error(
|
|
3797
|
-
`Content frontmatter field "
|
|
3943
|
+
`Content frontmatter field "id" must be a non-empty, trimmed string of at most ${MAX_STABLE_CONTENT_ID_LENGTH} characters without control characters.`
|
|
3798
3944
|
);
|
|
3799
3945
|
}
|
|
3800
3946
|
return value;
|
|
@@ -3827,7 +3973,7 @@ var ManifestBuilder = class {
|
|
|
3827
3973
|
assets: uniqueAssets(assets)
|
|
3828
3974
|
};
|
|
3829
3975
|
}
|
|
3830
|
-
build(entries, contentIndex) {
|
|
3976
|
+
build(entries, contentIndex, contentIndexAmbiguities = /* @__PURE__ */ new Map()) {
|
|
3831
3977
|
const bySlug = new Map(entries.map((entry) => [entry.slug, entry]));
|
|
3832
3978
|
const byContentId = createContentIdIndex(entries);
|
|
3833
3979
|
const byAlias = createAliasIndex(entries);
|
|
@@ -3868,6 +4014,7 @@ var ManifestBuilder = class {
|
|
|
3868
4014
|
outgoingLinks,
|
|
3869
4015
|
incomingLinks,
|
|
3870
4016
|
contentIndex,
|
|
4017
|
+
contentIndexAmbiguities,
|
|
3871
4018
|
assets: [],
|
|
3872
4019
|
clientEntries: [],
|
|
3873
4020
|
diagnostics: [],
|
|
@@ -3984,10 +4131,10 @@ function buildOutputInventory(manifest, pluginPageOutputs = [], contentOutputDep
|
|
|
3984
4131
|
for (const entry of manifest.publicEntries) {
|
|
3985
4132
|
addOutput(outputs, contentOutput(entry, contentOutputDependencies));
|
|
3986
4133
|
}
|
|
3987
|
-
for (const [
|
|
4134
|
+
for (const [path6, redirect] of manifest.publicRedirects) {
|
|
3988
4135
|
addOutput(outputs, {
|
|
3989
4136
|
kind: "redirect",
|
|
3990
|
-
path: htmlOutputPath(
|
|
4137
|
+
path: htmlOutputPath(path6),
|
|
3991
4138
|
producer: `content:${redirect.slug}:redirect`,
|
|
3992
4139
|
dependencies: [{ type: "content", slug: redirect.slug }]
|
|
3993
4140
|
});
|
|
@@ -4101,90 +4248,47 @@ function linkTargets(entry) {
|
|
|
4101
4248
|
).map((link) => link.slug);
|
|
4102
4249
|
}
|
|
4103
4250
|
function addOutput(outputs, output) {
|
|
4251
|
+
const existing = outputs.get(output.path);
|
|
4252
|
+
if (existing) {
|
|
4253
|
+
assertNoGeneratedOutputCollision(existing, output);
|
|
4254
|
+
}
|
|
4104
4255
|
outputs.set(output.path, output);
|
|
4105
4256
|
}
|
|
4257
|
+
function assertNoGeneratedOutputCollision(existing, incoming) {
|
|
4258
|
+
if (existing.kind !== "generated" && incoming.kind !== "generated") return;
|
|
4259
|
+
if (existing.kind === incoming.kind && existing.producer === incoming.producer)
|
|
4260
|
+
return;
|
|
4261
|
+
throw new Error(
|
|
4262
|
+
`Generated output path "${incoming.path}" collides with ${existing.kind} output owned by "${existing.producer}" and ${incoming.kind} output owned by "${incoming.producer}".`
|
|
4263
|
+
);
|
|
4264
|
+
}
|
|
4106
4265
|
function normalizePublicPath(pathname) {
|
|
4107
|
-
const
|
|
4108
|
-
return
|
|
4266
|
+
const path6 = `/${pathname.split("/").filter(Boolean).join("/")}`;
|
|
4267
|
+
return path6 === "/" ? path6 : path6.replace(/\/$/, "");
|
|
4109
4268
|
}
|
|
4110
|
-
function isMarkdownPath3(
|
|
4111
|
-
return
|
|
4269
|
+
function isMarkdownPath3(path6) {
|
|
4270
|
+
return path6.endsWith(".md");
|
|
4112
4271
|
}
|
|
4113
|
-
function toSlug3(
|
|
4114
|
-
return
|
|
4272
|
+
function toSlug3(path6) {
|
|
4273
|
+
return path6.replace(/\.md$/, "");
|
|
4115
4274
|
}
|
|
4116
4275
|
function compareOutput(left, right) {
|
|
4117
4276
|
return left.path.localeCompare(right.path) || left.kind.localeCompare(right.kind);
|
|
4118
4277
|
}
|
|
4119
4278
|
|
|
4120
|
-
// src/content/publishing.ts
|
|
4121
|
-
function resolvePublishingState(frontmatter, options) {
|
|
4122
|
-
const explicitVisibility = resolveExplicitVisibility(frontmatter?.visibility);
|
|
4123
|
-
const publishAt = resolvePublishAt(frontmatter?.publishAt);
|
|
4124
|
-
if (explicitVisibility === "draft")
|
|
4125
|
-
return state("draft", false, false, publishAt);
|
|
4126
|
-
if (publishAt && publishAt.getTime() > options.buildTime.getTime()) {
|
|
4127
|
-
return state("scheduled", false, false, publishAt);
|
|
4128
|
-
}
|
|
4129
|
-
if (explicitVisibility === "unlisted") {
|
|
4130
|
-
return state("unlisted", true, false, publishAt);
|
|
4131
|
-
}
|
|
4132
|
-
if (explicitVisibility === "public" || publishAt) {
|
|
4133
|
-
return state("public", true, true, publishAt);
|
|
4134
|
-
}
|
|
4135
|
-
const routable = isPublishable(options.strategy, frontmatter);
|
|
4136
|
-
return state(routable ? "public" : "draft", routable, routable, publishAt);
|
|
4137
|
-
}
|
|
4138
|
-
function resolvePublishingBuildTime(input) {
|
|
4139
|
-
if (input === void 0) return /* @__PURE__ */ new Date();
|
|
4140
|
-
if (input instanceof Date) {
|
|
4141
|
-
if (Number.isNaN(input.getTime()))
|
|
4142
|
-
throw new Error("Invalid publishing build time.");
|
|
4143
|
-
return new Date(input.getTime());
|
|
4144
|
-
}
|
|
4145
|
-
const parsed = new Date(input);
|
|
4146
|
-
if (Number.isNaN(parsed.getTime()))
|
|
4147
|
-
throw new Error("Invalid publishing build time.");
|
|
4148
|
-
return parsed;
|
|
4149
|
-
}
|
|
4150
|
-
function resolveExplicitVisibility(value) {
|
|
4151
|
-
if (value === void 0) return void 0;
|
|
4152
|
-
if (value === "public" || value === "unlisted" || value === "draft")
|
|
4153
|
-
return value;
|
|
4154
|
-
throw new Error(
|
|
4155
|
-
`Invalid content visibility "${String(value)}". Expected public, unlisted, or draft.`
|
|
4156
|
-
);
|
|
4157
|
-
}
|
|
4158
|
-
function resolvePublishAt(value) {
|
|
4159
|
-
if (value === void 0) return void 0;
|
|
4160
|
-
if (!(typeof value === "string" || value instanceof Date)) {
|
|
4161
|
-
throw new Error("Invalid publishAt. Expected an ISO 8601 date string.");
|
|
4162
|
-
}
|
|
4163
|
-
const parsed = value instanceof Date ? value : new Date(value);
|
|
4164
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
4165
|
-
throw new Error(
|
|
4166
|
-
`Invalid publishAt "${String(value)}". Expected an ISO 8601 date string.`
|
|
4167
|
-
);
|
|
4168
|
-
}
|
|
4169
|
-
return new Date(parsed.getTime());
|
|
4170
|
-
}
|
|
4171
|
-
function state(visibility, routable, discoverable, publishAt) {
|
|
4172
|
-
return {
|
|
4173
|
-
visibility,
|
|
4174
|
-
routable,
|
|
4175
|
-
discoverable,
|
|
4176
|
-
...publishAt ? { publishAt } : {}
|
|
4177
|
-
};
|
|
4178
|
-
}
|
|
4179
|
-
|
|
4180
4279
|
// src/content/content_manager.ts
|
|
4181
4280
|
var CONTENT_PROCESSING_CONCURRENCY = 16;
|
|
4182
4281
|
var ContentManager = class {
|
|
4183
4282
|
constructor(content, exclude = [], pipelineOptions = {}) {
|
|
4184
4283
|
this.pipelineOptions = pipelineOptions;
|
|
4284
|
+
const config = pipelineOptions.config ? {
|
|
4285
|
+
...pipelineOptions.config,
|
|
4286
|
+
plugins: pipelineOptions.plugins ?? pipelineOptions.config.plugins
|
|
4287
|
+
} : void 0;
|
|
4185
4288
|
this.pipelineOptions = {
|
|
4186
4289
|
...pipelineOptions,
|
|
4187
|
-
|
|
4290
|
+
config,
|
|
4291
|
+
plugins: pipelineOptions.plugins ?? config?.plugins,
|
|
4188
4292
|
isRoutable: (slug) => this.isRoutable(slug)
|
|
4189
4293
|
};
|
|
4190
4294
|
this.publishingBuildTime = resolvePublishingBuildTime(
|
|
@@ -4229,6 +4333,7 @@ var ContentManager = class {
|
|
|
4229
4333
|
manifestBuilder = new ManifestBuilder();
|
|
4230
4334
|
pluginRuntime;
|
|
4231
4335
|
contentIndex = null;
|
|
4336
|
+
contentIndexAmbiguities = /* @__PURE__ */ new Map();
|
|
4232
4337
|
contentIndexPromise = null;
|
|
4233
4338
|
contentCache = /* @__PURE__ */ new Map();
|
|
4234
4339
|
manifest = null;
|
|
@@ -4257,15 +4362,10 @@ var ContentManager = class {
|
|
|
4257
4362
|
async getContentIndex(preparation) {
|
|
4258
4363
|
if (this.contentIndex) return this.contentIndex;
|
|
4259
4364
|
if (!preparation && this.contentIndexPromise)
|
|
4260
|
-
return await this.contentIndexPromise;
|
|
4261
|
-
if (preparation?.previousState && !hasContentChanges(preparation.changeSet)) {
|
|
4262
|
-
this.contentIndex = new Map(
|
|
4263
|
-
Object.entries(preparation.previousState.contentIndex)
|
|
4264
|
-
);
|
|
4265
|
-
return this.contentIndex;
|
|
4266
|
-
}
|
|
4365
|
+
return (await this.contentIndexPromise).index;
|
|
4267
4366
|
if (preparation) {
|
|
4268
4367
|
this.contentIndex = preparation.currentContentIndex;
|
|
4368
|
+
this.contentIndexAmbiguities = preparation.currentContentIndexAmbiguities;
|
|
4269
4369
|
return this.contentIndex;
|
|
4270
4370
|
}
|
|
4271
4371
|
const promise = this.observability().tracer.span(
|
|
@@ -4278,7 +4378,9 @@ var ContentManager = class {
|
|
|
4278
4378
|
);
|
|
4279
4379
|
if (!preparation) this.contentIndexPromise = promise;
|
|
4280
4380
|
try {
|
|
4281
|
-
|
|
4381
|
+
const built = await promise;
|
|
4382
|
+
this.contentIndex = built.index;
|
|
4383
|
+
this.contentIndexAmbiguities = built.ambiguities;
|
|
4282
4384
|
return this.contentIndex;
|
|
4283
4385
|
} finally {
|
|
4284
4386
|
if (!preparation) this.contentIndexPromise = null;
|
|
@@ -4293,48 +4395,55 @@ var ContentManager = class {
|
|
|
4293
4395
|
contentPath: `${slug}.md`
|
|
4294
4396
|
},
|
|
4295
4397
|
async () => {
|
|
4296
|
-
|
|
4297
|
-
this.
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
await this.pluginRuntime.startBuild(contentIndex);
|
|
4301
|
-
await this.pluginRuntime.runContentLoaded(slug, rawPost, contentIndex);
|
|
4302
|
-
await this.ensureRoutableSlugs();
|
|
4303
|
-
this.pipeline ??= new Pipeline(
|
|
4304
|
-
contentIndex,
|
|
4305
|
-
await this.locationResolver.getPermalinks(),
|
|
4306
|
-
(postSlug) => this.getPost(postSlug),
|
|
4307
|
-
this.pipelineOptions,
|
|
4308
|
-
this.isBuildTime
|
|
4309
|
-
);
|
|
4310
|
-
const content = await this.pipeline.execute(rawPost, {
|
|
4311
|
-
sourceSlug: slug
|
|
4312
|
-
});
|
|
4313
|
-
this.processedContentCount += 1;
|
|
4314
|
-
if (this.processedContentCount % 100 === 0) {
|
|
4315
|
-
this.observability().tracer.event("content.process.sample", {
|
|
4316
|
-
processed: this.processedContentCount
|
|
4317
|
-
});
|
|
4398
|
+
try {
|
|
4399
|
+
return await this.processContent(slug);
|
|
4400
|
+
} catch (error) {
|
|
4401
|
+
throw attachErrorPath(error, `${slug}.md`);
|
|
4318
4402
|
}
|
|
4319
|
-
await this.pluginRuntime.runPostHook(
|
|
4320
|
-
"onPostParsed",
|
|
4321
|
-
slug,
|
|
4322
|
-
rawPost,
|
|
4323
|
-
content,
|
|
4324
|
-
contentIndex
|
|
4325
|
-
);
|
|
4326
|
-
await this.pluginRuntime.runPostHook(
|
|
4327
|
-
"onPostProcessed",
|
|
4328
|
-
slug,
|
|
4329
|
-
rawPost,
|
|
4330
|
-
content,
|
|
4331
|
-
contentIndex
|
|
4332
|
-
);
|
|
4333
|
-
this.contentCache.set(slug, content);
|
|
4334
|
-
return content;
|
|
4335
4403
|
}
|
|
4336
4404
|
);
|
|
4337
4405
|
}
|
|
4406
|
+
async processContent(slug) {
|
|
4407
|
+
const [contentIndex, rawPost] = await Promise.all([
|
|
4408
|
+
this.getContentIndex(),
|
|
4409
|
+
this.getPost(slug)
|
|
4410
|
+
]);
|
|
4411
|
+
await this.pluginRuntime.startBuild(contentIndex);
|
|
4412
|
+
await this.pluginRuntime.runContentLoaded(slug, rawPost, contentIndex);
|
|
4413
|
+
await this.ensureRoutableSlugs();
|
|
4414
|
+
this.pipeline ??= new Pipeline(
|
|
4415
|
+
contentIndex,
|
|
4416
|
+
await this.locationResolver.getPermalinks(),
|
|
4417
|
+
(postSlug) => this.getPost(postSlug),
|
|
4418
|
+
this.pipelineOptions,
|
|
4419
|
+
this.isBuildTime
|
|
4420
|
+
);
|
|
4421
|
+
const content = await this.pipeline.execute(rawPost, {
|
|
4422
|
+
sourceSlug: slug
|
|
4423
|
+
});
|
|
4424
|
+
this.processedContentCount += 1;
|
|
4425
|
+
if (this.processedContentCount % 100 === 0) {
|
|
4426
|
+
this.observability().tracer.event("content.process.sample", {
|
|
4427
|
+
processed: this.processedContentCount
|
|
4428
|
+
});
|
|
4429
|
+
}
|
|
4430
|
+
await this.pluginRuntime.runPostHook(
|
|
4431
|
+
"onPostParsed",
|
|
4432
|
+
slug,
|
|
4433
|
+
rawPost,
|
|
4434
|
+
content,
|
|
4435
|
+
contentIndex
|
|
4436
|
+
);
|
|
4437
|
+
await this.pluginRuntime.runPostHook(
|
|
4438
|
+
"onPostProcessed",
|
|
4439
|
+
slug,
|
|
4440
|
+
rawPost,
|
|
4441
|
+
content,
|
|
4442
|
+
contentIndex
|
|
4443
|
+
);
|
|
4444
|
+
this.contentCache.set(slug, content);
|
|
4445
|
+
return content;
|
|
4446
|
+
}
|
|
4338
4447
|
async getManifest(options) {
|
|
4339
4448
|
if (this.manifest) return this.manifest;
|
|
4340
4449
|
if (this.manifestPromise) return await this.manifestPromise;
|
|
@@ -4400,7 +4509,11 @@ var ContentManager = class {
|
|
|
4400
4509
|
const manifest = await this.observability().tracer.span(
|
|
4401
4510
|
"content.graph",
|
|
4402
4511
|
{},
|
|
4403
|
-
() => this.manifestBuilder.build(
|
|
4512
|
+
() => this.manifestBuilder.build(
|
|
4513
|
+
entries,
|
|
4514
|
+
contentIndex,
|
|
4515
|
+
this.contentIndexAmbiguities
|
|
4516
|
+
)
|
|
4404
4517
|
);
|
|
4405
4518
|
const cacheManifestEntries = structuredClone(manifest.entries);
|
|
4406
4519
|
this.locationResolver.populateRedirects(manifest, locations);
|
|
@@ -4636,7 +4749,13 @@ var ContentManager = class {
|
|
|
4636
4749
|
const routableSlugs = /* @__PURE__ */ new Set();
|
|
4637
4750
|
await mapConcurrent3(posts, CONTENT_PROCESSING_CONCURRENCY, async (post) => {
|
|
4638
4751
|
const markdown = await this.getPost(post.slug);
|
|
4639
|
-
|
|
4752
|
+
let frontmatter;
|
|
4753
|
+
try {
|
|
4754
|
+
frontmatter = readFrontmatter(markdown);
|
|
4755
|
+
} catch (error) {
|
|
4756
|
+
throw attachErrorPath(error, `${post.slug}.md`);
|
|
4757
|
+
}
|
|
4758
|
+
const publishing = resolvePublishingState(frontmatter, {
|
|
4640
4759
|
strategy,
|
|
4641
4760
|
buildTime: this.publishingBuildTime
|
|
4642
4761
|
});
|
|
@@ -4726,7 +4845,12 @@ function resolveFolderLocation(manifest, folder) {
|
|
|
4726
4845
|
if (candidate) return { type: "content", entry: candidate.entry };
|
|
4727
4846
|
}
|
|
4728
4847
|
if (candidates.length > 1) return { type: "ambiguous", candidates };
|
|
4729
|
-
const
|
|
4848
|
+
const normalizedFolder = normalizeFolder2(folder);
|
|
4849
|
+
const direct = manifest.folderLocations.get(normalizedFolder);
|
|
4850
|
+
if (direct) return { type: "generated", pathname: direct.pathname };
|
|
4851
|
+
const location = [...manifest.folderLocations.values()].find(
|
|
4852
|
+
(candidate) => candidate.folder === normalizedFolder
|
|
4853
|
+
);
|
|
4730
4854
|
return location ? { type: "generated", pathname: location.pathname } : { type: "none" };
|
|
4731
4855
|
}
|
|
4732
4856
|
function resolvePublicFolderLocation(manifest, pathname) {
|
|
@@ -4740,12 +4864,15 @@ function resolvePublicFolderLocation(manifest, pathname) {
|
|
|
4740
4864
|
);
|
|
4741
4865
|
return location ? { type: "generated", pathname: location.pathname } : { type: "none" };
|
|
4742
4866
|
}
|
|
4743
|
-
function resolveGeneratedFolderLocation(manifest, folder) {
|
|
4867
|
+
function resolveGeneratedFolderLocation(manifest, folder, language) {
|
|
4744
4868
|
const normalizedFolder = normalizeFolder2(folder);
|
|
4745
4869
|
if (!normalizedFolder) return null;
|
|
4746
4870
|
const candidates = /* @__PURE__ */ new Set();
|
|
4747
4871
|
const prefix = `${normalizedFolder}/`;
|
|
4748
4872
|
for (const entry of manifest.publicEntries) {
|
|
4873
|
+
if (language !== void 0 && entry.publicLocation.language !== language) {
|
|
4874
|
+
continue;
|
|
4875
|
+
}
|
|
4749
4876
|
if (!entry.slug.startsWith(prefix)) continue;
|
|
4750
4877
|
const remainder = entry.slug.slice(prefix.length).split("/").filter(Boolean);
|
|
4751
4878
|
const pathname = parentPath(
|
|
@@ -4960,7 +5087,7 @@ function clampFinite(value, min, max) {
|
|
|
4960
5087
|
// src/content/read_only_content_graph.ts
|
|
4961
5088
|
async function readOnlyContentGraph(source, locations) {
|
|
4962
5089
|
const entries = await source.scan();
|
|
4963
|
-
const contentIndex = await new ContentIndexBuilder(source).build(entries);
|
|
5090
|
+
const { index: contentIndex, ambiguities: contentIndexAmbiguities } = await new ContentIndexBuilder(source).build(entries);
|
|
4964
5091
|
const markdownEntries = entries.filter((entry) => entry.path.endsWith(".md")).toSorted((left, right) => left.path.localeCompare(right.path));
|
|
4965
5092
|
const markdownContents = await Promise.all(
|
|
4966
5093
|
markdownEntries.map(async (entry) => ({
|
|
@@ -4971,7 +5098,11 @@ async function readOnlyContentGraph(source, locations) {
|
|
|
4971
5098
|
const graphEntries = markdownContents.map(
|
|
4972
5099
|
({ entry, markdown }) => createGraphEntry(entry, markdown, contentIndex, locations)
|
|
4973
5100
|
);
|
|
4974
|
-
return new ManifestBuilder().build(
|
|
5101
|
+
return new ManifestBuilder().build(
|
|
5102
|
+
graphEntries,
|
|
5103
|
+
contentIndex,
|
|
5104
|
+
contentIndexAmbiguities
|
|
5105
|
+
).graph;
|
|
4975
5106
|
}
|
|
4976
5107
|
function createGraphEntry(entry, markdown, contentIndex, locations) {
|
|
4977
5108
|
const slug = entry.path.replace(/\.md$/, "");
|
|
@@ -5005,6 +5136,17 @@ async function readText3(source, entry) {
|
|
|
5005
5136
|
return typeof content === "string" ? content : new TextDecoder().decode(content);
|
|
5006
5137
|
}
|
|
5007
5138
|
|
|
5139
|
+
// src/project/project_layout.ts
|
|
5140
|
+
import path5 from "node:path";
|
|
5141
|
+
function resolveManagedStateRoot(config) {
|
|
5142
|
+
const directory = config?.buildDirectory;
|
|
5143
|
+
return directory ? path5.resolve(directory) : void 0;
|
|
5144
|
+
}
|
|
5145
|
+
function resolveBuildOutputDirectory(config) {
|
|
5146
|
+
const directory = config?.outputDirectory;
|
|
5147
|
+
return directory ? path5.resolve(directory) : void 0;
|
|
5148
|
+
}
|
|
5149
|
+
|
|
5008
5150
|
// src/types/content_manifest.ts
|
|
5009
5151
|
function appendContentBodySlot(entry, slot, html) {
|
|
5010
5152
|
if (!html.trim()) return;
|
|
@@ -5017,12 +5159,12 @@ ${html}` : html
|
|
|
5017
5159
|
}
|
|
5018
5160
|
|
|
5019
5161
|
// src/types/plugin_endpoint.ts
|
|
5020
|
-
function defineEndpoint(
|
|
5162
|
+
function defineEndpoint(path6, handler, options = {}) {
|
|
5021
5163
|
if (options.cacheControl === void 0) {
|
|
5022
|
-
return { path:
|
|
5164
|
+
return { path: path6, handler };
|
|
5023
5165
|
}
|
|
5024
5166
|
return {
|
|
5025
|
-
path:
|
|
5167
|
+
path: path6,
|
|
5026
5168
|
handler: async (context) => {
|
|
5027
5169
|
const response = await handler(context);
|
|
5028
5170
|
const headers = { ...response.headers };
|
|
@@ -5071,12 +5213,14 @@ export {
|
|
|
5071
5213
|
PluginDependencyError,
|
|
5072
5214
|
SinkTracer,
|
|
5073
5215
|
appendContentBodySlot,
|
|
5216
|
+
attachErrorPath,
|
|
5074
5217
|
attachmentUrl,
|
|
5075
5218
|
buildContentCollections,
|
|
5076
5219
|
buildGraphEdges,
|
|
5077
5220
|
buildOutputInventory,
|
|
5078
5221
|
calculateReadingTime,
|
|
5079
5222
|
collectConfigDeprecationDiagnostics,
|
|
5223
|
+
computePipelineFingerprint,
|
|
5080
5224
|
createClientEntry,
|
|
5081
5225
|
createContentGraph,
|
|
5082
5226
|
createDeprecationDiagnostic,
|
|
@@ -5095,6 +5239,7 @@ export {
|
|
|
5095
5239
|
fingerprintContentEntries,
|
|
5096
5240
|
formatDeprecationMessage,
|
|
5097
5241
|
getContentSourceEntry,
|
|
5242
|
+
getEntryLanguage,
|
|
5098
5243
|
getExtension,
|
|
5099
5244
|
getResolvedPluginMetadata,
|
|
5100
5245
|
groupContentEntries,
|
|
@@ -5104,11 +5249,13 @@ export {
|
|
|
5104
5249
|
isIgnoredContentPath,
|
|
5105
5250
|
isImagePath,
|
|
5106
5251
|
isMarkdownPath,
|
|
5252
|
+
isPersistentlyCacheable,
|
|
5107
5253
|
isPublishable,
|
|
5108
5254
|
isPublished,
|
|
5109
5255
|
layoutForceGraph,
|
|
5110
5256
|
layoutRadialGraph,
|
|
5111
5257
|
loadContentBuildState,
|
|
5258
|
+
matchContentExcludePattern,
|
|
5112
5259
|
normalizeContentAssetOutputPath,
|
|
5113
5260
|
normalizeContentPath,
|
|
5114
5261
|
normalizeGeneratedOutputPath,
|
|
@@ -5118,6 +5265,7 @@ export {
|
|
|
5118
5265
|
readContentBuildStateStatus,
|
|
5119
5266
|
readContentSourceEntry,
|
|
5120
5267
|
readOnlyContentGraph,
|
|
5268
|
+
resolveBuildOutputDirectory,
|
|
5121
5269
|
resolveConfig,
|
|
5122
5270
|
resolveConfigModule,
|
|
5123
5271
|
resolveContentBuildStatePath,
|
|
@@ -5127,10 +5275,12 @@ export {
|
|
|
5127
5275
|
resolveFolderEntry,
|
|
5128
5276
|
resolveFolderLocation,
|
|
5129
5277
|
resolveGeneratedFolderLocation,
|
|
5278
|
+
resolveManagedStateRoot,
|
|
5130
5279
|
resolvePlugins,
|
|
5131
5280
|
resolvePublicFolderLocation,
|
|
5132
5281
|
resolvePublishingBuildTime,
|
|
5133
5282
|
resolvePublishingState,
|
|
5283
|
+
selectEntriesByLanguage,
|
|
5134
5284
|
serializePublicClientConfig,
|
|
5135
5285
|
stableStringify,
|
|
5136
5286
|
stripHtml,
|