@heroiclands/package-build 8.1.0 → 10.0.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/CHANGELOG.md +748 -0
- package/CONTENT.md +273 -13
- package/bin/content-build.mjs +479 -123
- package/bin/package-build.mjs +27 -69
- package/bin/report.mjs +1 -2
- package/bundle.mjs +2 -10
- package/config.mjs +31 -106
- package/container.mjs +13 -57
- package/content-config.mjs +300 -188
- package/coverage.mjs +14 -55
- package/deploy.mjs +4 -13
- package/docs/content-format.md +1418 -0
- package/e2e.mjs +16 -55
- package/engine/address-charset.mjs +62 -0
- package/engine/address-diff.mjs +1 -4
- package/engine/alias-index.mjs +153 -0
- package/engine/base-compiler.mjs +203 -31
- package/engine/code-fences.mjs +4 -13
- package/engine/compendiums.mjs +13 -37
- package/engine/content-address.mjs +6 -10
- package/engine/content-format-check.mjs +570 -0
- package/engine/content-format.mjs +253 -0
- package/engine/content-links.mjs +144 -99
- package/engine/content-lint.mjs +12 -16
- package/engine/content-slug.mjs +2 -6
- package/engine/content-tables.mjs +26 -79
- package/engine/diagnostics.mjs +37 -15
- package/engine/document-subtypes.mjs +440 -0
- package/engine/field-reference.mjs +6 -20
- package/engine/field-spec.mjs +49 -45
- package/engine/foreign-catalog.mjs +7 -22
- package/engine/foreign-manifests.mjs +1 -4
- package/engine/frontmatter-lint.mjs +347 -43
- package/engine/frontmatter.mjs +3 -8
- package/engine/generate.mjs +36 -20
- package/engine/helpers.mjs +54 -81
- package/engine/homepage.mjs +4 -15
- package/engine/ids.mjs +21 -12
- package/engine/index.mjs +15 -0
- package/engine/item-registry.mjs +72 -9
- package/engine/journals.mjs +4 -14
- package/engine/kb-manifest.mjs +41 -24
- package/engine/macros.mjs +2 -10
- package/engine/manifest-emit.mjs +6 -17
- package/engine/map-notes.mjs +53 -87
- package/engine/note-claims.mjs +383 -0
- package/engine/note-package.mjs +1 -4
- package/engine/note-vocabulary.mjs +678 -0
- package/engine/pack-config.mjs +56 -60
- package/engine/pack-router.mjs +18 -8
- package/engine/prose-config.mjs +20 -4
- package/engine/prose-lint.mjs +61 -17
- package/engine/region-events.mjs +1 -3
- package/engine/retired-fields.mjs +117 -3
- package/engine/scene-levels.mjs +8 -22
- package/engine/scenes.mjs +31 -47
- package/engine/schema-check.mjs +348 -7
- package/engine/schema-extract.mjs +11 -39
- package/engine/site-build.mjs +13 -38
- package/engine/site-index.mjs +40 -35
- package/engine/system-block.mjs +513 -0
- package/engine/web-wikilinks.mjs +115 -92
- package/engine/wikilink-syntax.mjs +30 -0
- package/engine/wikilinks.mjs +147 -183
- package/index.mjs +1 -5
- package/lang.mjs +1 -3
- package/manifest.mjs +10 -37
- package/markdownlint-config.mjs +1 -5
- package/package.json +6 -2
- package/sohl/actors.mjs +251 -68
- package/sohl/being-info.mjs +3 -6
- package/sohl/document-subtypes.mjs +82 -0
- package/sohl/index.mjs +4 -6
- package/sohl/item-builders.mjs +1 -3
- package/sohl/item-fields.mjs +16 -34
- package/sohl/items.mjs +111 -17
- package/sohl/kb-passes.mjs +29 -39
- package/sohl/note-schemas.mjs +11 -7
- package/sohl/skill-base.mjs +7 -23
- package/stage.mjs +3 -13
- package/templates.mjs +4 -15
- package/types/bundle.d.mts +1 -1
- package/types/container.d.mts +2 -2
- package/types/content-config.d.mts +48 -4
- package/types/coverage.d.mts +1 -1
- package/types/e2e.d.mts +4 -4
- package/types/engine/address-charset.d.mts +45 -0
- package/types/engine/alias-index.d.mts +122 -0
- package/types/engine/base-compiler.d.mts +132 -4
- package/types/engine/content-address.d.mts +2 -2
- package/types/engine/content-format-check.d.mts +163 -0
- package/types/engine/content-format.d.mts +101 -0
- package/types/engine/content-links.d.mts +16 -1
- package/types/engine/content-lint.d.mts +6 -0
- package/types/engine/diagnostics.d.mts +29 -0
- package/types/engine/document-subtypes.d.mts +233 -0
- package/types/engine/field-spec.d.mts +76 -23
- package/types/engine/frontmatter-lint.d.mts +47 -2
- package/types/engine/generate.d.mts +15 -2
- package/types/engine/helpers.d.mts +22 -14
- package/types/engine/ids.d.mts +10 -0
- package/types/engine/index.d.mts +5 -0
- package/types/engine/item-registry.d.mts +21 -2
- package/types/engine/kb-manifest.d.mts +35 -8
- package/types/engine/map-notes.d.mts +21 -11
- package/types/engine/note-claims.d.mts +113 -0
- package/types/engine/note-vocabulary.d.mts +251 -0
- package/types/engine/pack-config.d.mts +4 -3
- package/types/engine/pack-router.d.mts +4 -4
- package/types/engine/prose-lint.d.mts +6 -2
- package/types/engine/retired-fields.d.mts +73 -2
- package/types/engine/schema-check.d.mts +182 -0
- package/types/engine/schema-extract.d.mts +1 -1
- package/types/engine/site-index.d.mts +1 -1
- package/types/engine/system-block.d.mts +281 -0
- package/types/engine/web-wikilinks.d.mts +23 -12
- package/types/engine/wikilink-syntax.d.mts +29 -0
- package/types/manifest.d.mts +1 -1
- package/types/sohl/actors.d.mts +62 -6
- package/types/sohl/document-subtypes.d.mts +14 -0
- package/types/sohl/index.d.mts +1 -0
- package/types/sohl/items.d.mts +21 -0
|
@@ -150,10 +150,7 @@ export function registryOf(src, name) {
|
|
|
150
150
|
}
|
|
151
151
|
if (ts.isObjectLiteralExpression(init)) {
|
|
152
152
|
for (const p of init.properties) {
|
|
153
|
-
if (
|
|
154
|
-
ts.isPropertyAssignment(p) &&
|
|
155
|
-
ts.isIdentifier(p.initializer)
|
|
156
|
-
) {
|
|
153
|
+
if (ts.isPropertyAssignment(p) && ts.isIdentifier(p.initializer)) {
|
|
157
154
|
out.set(propName(p.name), p.initializer.text);
|
|
158
155
|
}
|
|
159
156
|
}
|
|
@@ -216,10 +213,7 @@ function resolveSpecifier(fromDir, spec, aliases) {
|
|
|
216
213
|
}
|
|
217
214
|
if (!base) return null;
|
|
218
215
|
for (const ext of EXTENSIONS) {
|
|
219
|
-
for (const candidate of [
|
|
220
|
-
`${base}${ext}`,
|
|
221
|
-
path.join(base, `index${ext}`),
|
|
222
|
-
]) {
|
|
216
|
+
for (const candidate of [`${base}${ext}`, path.join(base, `index${ext}`)]) {
|
|
223
217
|
if (fs.existsSync(candidate)) return candidate;
|
|
224
218
|
}
|
|
225
219
|
}
|
|
@@ -243,11 +237,7 @@ function importSourceOf(src, name, aliases) {
|
|
|
243
237
|
if (!bindings.elements.some((e) => e.name.text === name)) return;
|
|
244
238
|
const spec = node.moduleSpecifier;
|
|
245
239
|
if (!ts.isStringLiteral(spec)) return;
|
|
246
|
-
found = resolveSpecifier(
|
|
247
|
-
path.dirname(src.fileName),
|
|
248
|
-
spec.text,
|
|
249
|
-
aliases,
|
|
250
|
-
);
|
|
240
|
+
found = resolveSpecifier(path.dirname(src.fileName), spec.text, aliases);
|
|
251
241
|
});
|
|
252
242
|
return found;
|
|
253
243
|
}
|
|
@@ -286,9 +276,7 @@ function locateClass(fromFile, className, aliases, cache) {
|
|
|
286
276
|
if (!imported) return null;
|
|
287
277
|
const importedSrc = parse(imported, cache);
|
|
288
278
|
const importedDecl = classDeclIn(importedSrc, className);
|
|
289
|
-
return importedDecl ?
|
|
290
|
-
{ file: imported, src: importedSrc, decl: importedDecl }
|
|
291
|
-
: null;
|
|
279
|
+
return importedDecl ? { file: imported, src: importedSrc, decl: importedDecl } : null;
|
|
292
280
|
}
|
|
293
281
|
|
|
294
282
|
/**
|
|
@@ -303,8 +291,7 @@ function superClassOf(decl) {
|
|
|
303
291
|
for (const clause of decl.heritageClauses ?? []) {
|
|
304
292
|
if (clause.token !== ts.SyntaxKind.ExtendsKeyword) continue;
|
|
305
293
|
const [type] = clause.types;
|
|
306
|
-
if (type && ts.isIdentifier(type.expression))
|
|
307
|
-
return type.expression.text;
|
|
294
|
+
if (type && ts.isIdentifier(type.expression)) return type.expression.text;
|
|
308
295
|
}
|
|
309
296
|
return null;
|
|
310
297
|
}
|
|
@@ -350,9 +337,8 @@ function literalReturnedBy(src, fnName) {
|
|
|
350
337
|
if (isTarget) {
|
|
351
338
|
const body =
|
|
352
339
|
ts.isFunctionDeclaration(node) ? node.body
|
|
353
|
-
: node.initializer && ts.isArrowFunction(node.initializer) ?
|
|
354
|
-
|
|
355
|
-
: null;
|
|
340
|
+
: node.initializer && ts.isArrowFunction(node.initializer) ? node.initializer.body
|
|
341
|
+
: null;
|
|
356
342
|
if (body) literal = returnedLiteral(body);
|
|
357
343
|
}
|
|
358
344
|
ts.forEachChild(node, visit);
|
|
@@ -404,14 +390,10 @@ function isObjectAssign(expr) {
|
|
|
404
390
|
*/
|
|
405
391
|
function schemaContributions(src, decl) {
|
|
406
392
|
const method = decl.members.find(
|
|
407
|
-
(m) =>
|
|
408
|
-
ts.isMethodDeclaration(m) &&
|
|
409
|
-
propName(m.name) === "defineSchema" &&
|
|
410
|
-
m.body,
|
|
393
|
+
(m) => ts.isMethodDeclaration(m) && propName(m.name) === "defineSchema" && m.body,
|
|
411
394
|
);
|
|
412
395
|
// No `defineSchema()` — the whole schema is the parent's.
|
|
413
|
-
if (!method)
|
|
414
|
-
return { literals: [], edges: [{ kind: "super", name: null }] };
|
|
396
|
+
if (!method) return { literals: [], edges: [{ kind: "super", name: null }] };
|
|
415
397
|
|
|
416
398
|
const direct = returnedLiteral(method.body);
|
|
417
399
|
if (direct) return { literals: [direct], edges: [] };
|
|
@@ -568,12 +550,7 @@ export function fieldsForClass({ file, className, aliases, cache, rootDir }) {
|
|
|
568
550
|
const importedSrc = parse(from, cache);
|
|
569
551
|
const importedLit = literalReturnedBy(importedSrc, edge.name);
|
|
570
552
|
if (importedLit) {
|
|
571
|
-
walkLiteral(
|
|
572
|
-
{ file: from, src: importedSrc },
|
|
573
|
-
importedLit,
|
|
574
|
-
inherited,
|
|
575
|
-
superName,
|
|
576
|
-
);
|
|
553
|
+
walkLiteral({ file: from, src: importedSrc }, importedLit, inherited, superName);
|
|
577
554
|
}
|
|
578
555
|
return;
|
|
579
556
|
}
|
|
@@ -616,12 +593,7 @@ export function fieldsForClass({ file, className, aliases, cache, rootDir }) {
|
|
|
616
593
|
* @param {string} opts.version - The package version.
|
|
617
594
|
* @returns {object} The artifact `schema-check.mjs` reads.
|
|
618
595
|
*/
|
|
619
|
-
export function buildSchemaArtifact({
|
|
620
|
-
rootDir,
|
|
621
|
-
registries,
|
|
622
|
-
packageId,
|
|
623
|
-
version,
|
|
624
|
-
}) {
|
|
596
|
+
export function buildSchemaArtifact({ rootDir, registries, packageId, version }) {
|
|
625
597
|
const aliases = pathAliases(rootDir);
|
|
626
598
|
const cache = new Map();
|
|
627
599
|
const documents = {};
|
package/engine/site-build.mjs
CHANGED
|
@@ -56,10 +56,7 @@ import { expandContentTables } from "./content-tables.mjs";
|
|
|
56
56
|
import { buildSiteIndex, wikiContext } from "./site-index.mjs";
|
|
57
57
|
import { frontmatterWikilinks, resolveWebWikilinks } from "./web-wikilinks.mjs";
|
|
58
58
|
import { loadForeignManifests, manifestsComplete } from "./kb-manifest.mjs";
|
|
59
|
-
import {
|
|
60
|
-
formatUnaddressableFinding,
|
|
61
|
-
unaddressableForeignPackages,
|
|
62
|
-
} from "./foreign-manifests.mjs";
|
|
59
|
+
import { formatUnaddressableFinding, unaddressableForeignPackages } from "./foreign-manifests.mjs";
|
|
63
60
|
import { deriveBeingInfo, isBeing } from "../sohl/being-info.mjs";
|
|
64
61
|
import { loadPackConfig } from "./pack-config.mjs";
|
|
65
62
|
import { searchableFrontmatter } from "./note-package.mjs";
|
|
@@ -192,10 +189,7 @@ export function collectContentPages(contentBase, ctx) {
|
|
|
192
189
|
// authoring folder, for grouped landings.
|
|
193
190
|
folder: path.basename(path.dirname(file)),
|
|
194
191
|
sec,
|
|
195
|
-
url:
|
|
196
|
-
isReadme ?
|
|
197
|
-
`${ctx.mount}${sec}/`
|
|
198
|
-
: `${ctx.mount}${sec}/${slug}/`,
|
|
192
|
+
url: isReadme ? `${ctx.mount}${sec}/` : `${ctx.mount}${sec}/${slug}/`,
|
|
199
193
|
isReadme,
|
|
200
194
|
});
|
|
201
195
|
}
|
|
@@ -229,12 +223,10 @@ export function collectTreePages(tree, ctx) {
|
|
|
229
223
|
const rel = path.relative(tree.from, file).replace(/\\/g, "/");
|
|
230
224
|
const base = path.basename(rel);
|
|
231
225
|
const isReadme = base.toLowerCase() === "readme.md";
|
|
232
|
-
const sec = fm.
|
|
226
|
+
const sec = fm.subType ?? tree.section;
|
|
233
227
|
const h1 = /^#\s+(.+?)\s*$/m.exec(body);
|
|
234
|
-
const h1Title =
|
|
235
|
-
|
|
236
|
-
const name =
|
|
237
|
-
fm.name?.full ?? fm.title ?? h1Title ?? path.basename(base, ".md");
|
|
228
|
+
const h1Title = h1 ? h1[1].replace(/\{@link\s+[^}]*\}/g, "").trim() : null;
|
|
229
|
+
const name = fm.name?.full ?? fm.title ?? h1Title ?? path.basename(base, ".md");
|
|
238
230
|
const slug = fm.slug ?? slugify(path.basename(base, ".md"));
|
|
239
231
|
const relNoExt = rel.slice(0, -3).toLowerCase();
|
|
240
232
|
const dir = path.posix.dirname(relNoExt);
|
|
@@ -562,9 +554,7 @@ export function pageDestination(page) {
|
|
|
562
554
|
: path.join(page.sec, `${page.slug}.md`);
|
|
563
555
|
}
|
|
564
556
|
const rel =
|
|
565
|
-
page.isReadme ?
|
|
566
|
-
path.posix.join(path.posix.dirname(page.rel), "_index.md")
|
|
567
|
-
: page.rel;
|
|
557
|
+
page.isReadme ? path.posix.join(path.posix.dirname(page.rel), "_index.md") : page.rel;
|
|
568
558
|
return path.join(page.sec, rel);
|
|
569
559
|
}
|
|
570
560
|
|
|
@@ -640,10 +630,7 @@ export function renderPages(pages, options) {
|
|
|
640
630
|
const data = pageFrontmatter(page, { readmeSections, decorate });
|
|
641
631
|
const dest = path.join(outRoot, pageDestination(page));
|
|
642
632
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
643
|
-
fs.writeFileSync(
|
|
644
|
-
dest,
|
|
645
|
-
matter.stringify(protectCode(body, resolve), data),
|
|
646
|
-
);
|
|
633
|
+
fs.writeFileSync(dest, matter.stringify(protectCode(body, resolve), data));
|
|
647
634
|
byKind[page.kind] = (byKind[page.kind] ?? 0) + 1;
|
|
648
635
|
}
|
|
649
636
|
|
|
@@ -676,10 +663,7 @@ export function renderPages(pages, options) {
|
|
|
676
663
|
* @param {object} options - `{ sections, landing, sectionTitle }`.
|
|
677
664
|
* @returns {number} How many landings were written.
|
|
678
665
|
*/
|
|
679
|
-
export function writeSectionLandings(
|
|
680
|
-
outRoot,
|
|
681
|
-
{ sections = {}, landing, sectionTitle },
|
|
682
|
-
) {
|
|
666
|
+
export function writeSectionLandings(outRoot, { sections = {}, landing, sectionTitle }) {
|
|
683
667
|
let written = 0;
|
|
684
668
|
|
|
685
669
|
// The mount's own landing carries a `type` of its own. Hugo's template
|
|
@@ -689,10 +673,7 @@ export function writeSectionLandings(
|
|
|
689
673
|
// template out of the path where it could be inherited.
|
|
690
674
|
if (landing) {
|
|
691
675
|
fs.mkdirSync(outRoot, { recursive: true });
|
|
692
|
-
fs.writeFileSync(
|
|
693
|
-
path.join(outRoot, "_index.md"),
|
|
694
|
-
matter.stringify("", landing),
|
|
695
|
-
);
|
|
676
|
+
fs.writeFileSync(path.join(outRoot, "_index.md"), matter.stringify("", landing));
|
|
696
677
|
written += 1;
|
|
697
678
|
}
|
|
698
679
|
|
|
@@ -713,10 +694,7 @@ export function writeSectionLandings(
|
|
|
713
694
|
if (!entry.isDirectory()) continue;
|
|
714
695
|
const index = path.join(outRoot, entry.name, "_index.md");
|
|
715
696
|
if (fs.existsSync(index)) continue;
|
|
716
|
-
fs.writeFileSync(
|
|
717
|
-
index,
|
|
718
|
-
matter.stringify("", { title: sectionTitle(entry.name) }),
|
|
719
|
-
);
|
|
697
|
+
fs.writeFileSync(index, matter.stringify("", { title: sectionTitle(entry.name) }));
|
|
720
698
|
written += 1;
|
|
721
699
|
}
|
|
722
700
|
return written;
|
|
@@ -859,19 +837,16 @@ export function buildSite({ config, outRoot } = {}) {
|
|
|
859
837
|
const outBase = resolveOutputRoot(resolved.rootDir, site.out);
|
|
860
838
|
const out =
|
|
861
839
|
outRoot ? path.resolve(outRoot)
|
|
862
|
-
: publishesContent ?
|
|
863
|
-
path.join(outBase, scheme.prefix.replace(/\/$/, ""))
|
|
840
|
+
: publishesContent ? path.join(outBase, scheme.prefix.replace(/\/$/, ""))
|
|
864
841
|
// Homepage-only has no content mount, so the package's root *is*
|
|
865
842
|
// the output root and `--out` redirects the whole of it.
|
|
866
|
-
:
|
|
843
|
+
: outBase;
|
|
867
844
|
// The homepage publishes at `/<contentPackage>/`, which is the package's
|
|
868
845
|
// own root — one level above the content mount, and the same directory in
|
|
869
846
|
// homepage-only mode.
|
|
870
847
|
const homeRoot = publishesContent ? outBase : out;
|
|
871
848
|
|
|
872
|
-
const packages = new Set(
|
|
873
|
-
site.packages.length ? site.packages : [resolved.contentPackage],
|
|
874
|
-
);
|
|
849
|
+
const packages = new Set(site.packages.length ? site.packages : [resolved.contentPackage]);
|
|
875
850
|
|
|
876
851
|
const ctx = {
|
|
877
852
|
packages,
|
package/engine/site-index.mjs
CHANGED
|
@@ -54,6 +54,9 @@ import path from "node:path";
|
|
|
54
54
|
import { canonicalKey, readCanonicalKey } from "./kb-manifest.mjs";
|
|
55
55
|
import { hasDocEntry } from "./item-docs.mjs";
|
|
56
56
|
import { contentPackage } from "./content-package.mjs";
|
|
57
|
+
// The alias namespace: what a page may be called, and what happens when two
|
|
58
|
+
// pages of one type claim one name (#131).
|
|
59
|
+
import { aliasesOf, indexAliases } from "./alias-index.mjs";
|
|
57
60
|
|
|
58
61
|
/**
|
|
59
62
|
* One page the site will publish, as the index needs to see it.
|
|
@@ -152,10 +155,7 @@ function mergeForeign(index, foreignIndex) {
|
|
|
152
155
|
const parts = readCanonicalKey(key);
|
|
153
156
|
if (!parts) continue;
|
|
154
157
|
const shortKey = `${parts.type}/${parts.shortcode}`;
|
|
155
|
-
if (
|
|
156
|
-
short.has(shortKey) &&
|
|
157
|
-
short.get(shortKey).package !== value.package
|
|
158
|
-
) {
|
|
158
|
+
if (short.has(shortKey) && short.get(shortKey).package !== value.package) {
|
|
159
159
|
ambiguous.add(shortKey);
|
|
160
160
|
} else {
|
|
161
161
|
short.set(shortKey, value);
|
|
@@ -183,11 +183,17 @@ function mergeForeign(index, foreignIndex) {
|
|
|
183
183
|
export function buildSiteIndex(entries, { foreignIndex = new Map() } = {}) {
|
|
184
184
|
const index = new Map();
|
|
185
185
|
const ambiguous = new Set();
|
|
186
|
-
|
|
187
|
-
const
|
|
186
|
+
/** One entry per page, fed to {@link indexAliases} in a pass of its own. */
|
|
187
|
+
const aliasEntries = [];
|
|
188
188
|
const contentTypes = new Set();
|
|
189
189
|
const sections = new Set();
|
|
190
190
|
const refIndex = new Map();
|
|
191
|
+
// Every package an address may name: this build's own, plus every one a
|
|
192
|
+
// vendored manifest speaks for. Without it `readQualifier` cannot see the
|
|
193
|
+
// leading package segment of a canonical address, and `kethira-place-x`
|
|
194
|
+
// reads as the unknown type `kethira` (#131).
|
|
195
|
+
const ownPackage = contentPackage();
|
|
196
|
+
const packages = new Set(ownPackage ? [ownPackage] : []);
|
|
191
197
|
|
|
192
198
|
// `section/slug` is unique by construction; the rest are fallbacks.
|
|
193
199
|
for (const e of entries) {
|
|
@@ -206,6 +212,7 @@ export function buildSiteIndex(entries, { foreignIndex = new Map() } = {}) {
|
|
|
206
212
|
// without it the link reads as prose and silently loses its href.
|
|
207
213
|
for (const value of foreignIndex.values()) {
|
|
208
214
|
if (value.type) contentTypes.add(value.type);
|
|
215
|
+
if (value.package) packages.add(value.package);
|
|
209
216
|
}
|
|
210
217
|
|
|
211
218
|
// Merged *before* the local type-scoped pass below, so a local page always
|
|
@@ -242,10 +249,8 @@ export function buildSiteIndex(entries, { foreignIndex = new Map() } = {}) {
|
|
|
242
249
|
// The page's package is the configured one — the site collection
|
|
243
250
|
// resolves it and records it as `pkg`. Never read out of
|
|
244
251
|
// frontmatter: `package:` is retired (#56).
|
|
245
|
-
index.set(
|
|
246
|
-
|
|
247
|
-
value,
|
|
248
|
-
);
|
|
252
|
+
index.set(canonicalKey(e.pkg ?? ownPackage, type, shortcode), value);
|
|
253
|
+
if (e.pkg) packages.add(e.pkg);
|
|
249
254
|
// In Foundry an item and its documentation are two documents, so
|
|
250
255
|
// `skill/wpnc` and `docskill/wpnc` are two UUIDs (#1362). Here the
|
|
251
256
|
// item note renders as one page which *is* its documentation, so
|
|
@@ -259,33 +264,38 @@ export function buildSiteIndex(entries, { foreignIndex = new Map() } = {}) {
|
|
|
259
264
|
}
|
|
260
265
|
}
|
|
261
266
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (typeCollide.has(key)) continue;
|
|
272
|
-
const cur = typeAlias.get(key);
|
|
273
|
-
if (cur && cur.url !== value.url) {
|
|
274
|
-
typeAlias.delete(key);
|
|
275
|
-
typeCollide.add(key);
|
|
276
|
-
} else if (!cur) {
|
|
277
|
-
typeAlias.set(key, value);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
267
|
+
// The alias sources are the shared ones — `aliases`, `name.aliases`
|
|
268
|
+
// and `name.full`, and deliberately **not** the filename (#131) — plus
|
|
269
|
+
// this page's display name, which is what `name.full` becomes on the
|
|
270
|
+
// site and is carried here already resolved.
|
|
271
|
+
aliasEntries.push({
|
|
272
|
+
type,
|
|
273
|
+
aliases: [...aliasesOf(e.fm), e.name],
|
|
274
|
+
value,
|
|
275
|
+
});
|
|
280
276
|
}
|
|
281
277
|
|
|
278
|
+
// Built in one pass at the end, by the shared rule, so a collision is a
|
|
279
|
+
// reportable fact rather than a silently deleted key. Two pages of one
|
|
280
|
+
// type sharing an alias resolve to neither, and `aliasCollisions` names
|
|
281
|
+
// every claimant — the citing page is innocent (#13, #131).
|
|
282
|
+
const {
|
|
283
|
+
byKey: typeAlias,
|
|
284
|
+
collisions: aliasCollisions,
|
|
285
|
+
claims: aliasClaims,
|
|
286
|
+
} = indexAliases(aliasEntries, { same: (a, b) => a.url === b.url });
|
|
287
|
+
const typeCollide = new Set(aliasCollisions.map((c) => c.key));
|
|
288
|
+
|
|
282
289
|
return {
|
|
283
290
|
index,
|
|
284
291
|
ambiguous,
|
|
285
292
|
typeAlias,
|
|
286
293
|
typeCollide,
|
|
294
|
+
aliasCollisions,
|
|
295
|
+
aliasClaims,
|
|
287
296
|
contentTypes,
|
|
288
297
|
sections,
|
|
298
|
+
packages,
|
|
289
299
|
refIndex,
|
|
290
300
|
conflicts,
|
|
291
301
|
};
|
|
@@ -315,13 +325,7 @@ export function buildSiteIndex(entries, { foreignIndex = new Map() } = {}) {
|
|
|
315
325
|
*/
|
|
316
326
|
export function wikiContext(
|
|
317
327
|
built,
|
|
318
|
-
{
|
|
319
|
-
src,
|
|
320
|
-
type = null,
|
|
321
|
-
errors,
|
|
322
|
-
foreignIndex = new Map(),
|
|
323
|
-
manifestsComplete = true,
|
|
324
|
-
},
|
|
328
|
+
{ src, type = null, errors, foreignIndex = new Map(), manifestsComplete = true },
|
|
325
329
|
) {
|
|
326
330
|
return {
|
|
327
331
|
index: built.index,
|
|
@@ -332,6 +336,7 @@ export function wikiContext(
|
|
|
332
336
|
typeAlias: built.typeAlias,
|
|
333
337
|
typeCollide: built.typeCollide,
|
|
334
338
|
contentTypes: built.contentTypes,
|
|
339
|
+
packages: built.packages,
|
|
335
340
|
type,
|
|
336
341
|
errors,
|
|
337
342
|
src,
|