@heroiclands/package-build 23.9.0 → 23.10.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 +26 -0
- package/README.md +2 -0
- package/bin/content-commands.mjs +197 -68
- package/docs/api.md +336 -68
- package/docs/authoring/links-and-markup.md +114 -47
- package/docs/commands.md +92 -3
- package/docs/content-format.md +6 -1
- package/docs/reference/format-details.md +129 -14
- package/docs/reference/note-types.md +4 -4
- package/engine/anchors.mjs +8 -6
- package/engine/base-compiler.mjs +6 -4
- package/engine/changelog-group.mjs +58 -34
- package/engine/changelog-lint.mjs +6 -2
- package/engine/compendiums.mjs +15 -1
- package/engine/compile-corpus.mjs +14 -1
- package/engine/content-charset.mjs +13 -1
- package/engine/content-html.mjs +18 -4
- package/engine/content-icons.mjs +15 -1
- package/engine/content-images.mjs +28 -9
- package/engine/content-index.mjs +102 -23
- package/engine/content-links.mjs +27 -12
- package/engine/content-session.mjs +247 -0
- package/engine/content-sources.mjs +110 -0
- package/engine/content-spans.mjs +87 -8
- package/engine/content-tables.mjs +1 -0
- package/engine/content-tasklists.mjs +20 -4
- package/engine/diagnostics.mjs +17 -6
- package/engine/extension-attributes.mjs +28 -5
- package/engine/first-use.mjs +371 -0
- package/engine/foundry-entries.mjs +12 -9
- package/engine/generate.mjs +13 -4
- package/engine/helpers.mjs +43 -14
- package/engine/index-records.mjs +1 -0
- package/engine/index.mjs +3 -0
- package/engine/journals.mjs +9 -5
- package/engine/language-data.mjs +2 -2
- package/engine/language-rows.mjs +4 -4
- package/engine/language-terms.mjs +4 -4
- package/engine/lexical-sections.mjs +5 -5
- package/engine/markup-validation.mjs +7 -2
- package/engine/metadata-index.mjs +1 -0
- package/engine/name-markup.mjs +114 -0
- package/engine/name-rows.mjs +70 -0
- package/engine/names.mjs +460 -0
- package/engine/note-addresses.mjs +25 -4
- package/engine/path-charset.mjs +24 -1
- package/engine/pdf-render.mjs +15 -1
- package/engine/site-index.mjs +5 -1
- package/engine/sql-tables.mjs +76 -15
- package/engine/stub-lint.mjs +4 -3
- package/engine/yaml-lint.mjs +3 -5
- package/hugo-theme/static/css/style.css +4 -0
- package/package.json +1 -1
- package/types/engine/anchors.d.mts +4 -2
- package/types/engine/compendiums.d.mts +5 -1
- package/types/engine/compile-corpus.d.mts +5 -2
- package/types/engine/content-charset.d.mts +5 -1
- package/types/engine/content-html.d.mts +5 -1
- package/types/engine/content-icons.d.mts +5 -1
- package/types/engine/content-images.d.mts +5 -1
- package/types/engine/content-index.d.mts +39 -19
- package/types/engine/content-links.d.mts +22 -8
- package/types/engine/content-session.d.mts +108 -0
- package/types/engine/content-sources.d.mts +32 -0
- package/types/engine/content-spans.d.mts +3 -5
- package/types/engine/content-tasklists.d.mts +5 -1
- package/types/engine/diagnostics.d.mts +10 -0
- package/types/engine/extension-attributes.d.mts +16 -2
- package/types/engine/first-use.d.mts +31 -0
- package/types/engine/foundry-entries.d.mts +11 -4
- package/types/engine/generate.d.mts +5 -1
- package/types/engine/helpers.d.mts +30 -7
- package/types/engine/index.d.mts +1 -0
- package/types/engine/journals.d.mts +5 -2
- package/types/engine/lexical-sections.d.mts +3 -2
- package/types/engine/markup-validation.d.mts +2 -1
- package/types/engine/name-markup.d.mts +176 -0
- package/types/engine/name-rows.d.mts +35 -0
- package/types/engine/names.d.mts +356 -0
- package/types/engine/note-addresses.d.mts +3 -3
- package/types/engine/path-charset.d.mts +16 -1
- package/types/engine/site-build.d.mts +2 -2
- package/types/engine/site-index.d.mts +3 -1
- package/types/engine/sql-tables.d.mts +7 -2
- package/types/engine/stub-lint.d.mts +3 -1
package/docs/api.md
CHANGED
|
@@ -467,10 +467,10 @@ What a draft note says about itself, in one sentence, on every surface it reache
|
|
|
467
467
|
|
|
468
468
|
Nonempty `data.words` on a `skill`/`language` note, or `data.glossary` on a culture or affiliation, supplies content without an authored body. Absent or empty arrays supply no such exemption. Every other typed note must have a nonempty body: empty and whitespace-only bodies are errors regardless of description or `draft` tag, including `folder` and `homepage`. Nonempty placeholder-only bodies still produce errors, including on lexical notes. Nonempty bodies with fewer than 25 prose words produce warnings unless tagged `draft`. A `folder` note is held only to the nonempty rule: any body, placeholder or short, passes with or without `draft`. Untyped vault scaffolding is excluded. The lint, content-index, package compile, site and PDF commands enforce body errors before publishing.
|
|
469
469
|
|
|
470
|
-
| Export | Signature
|
|
471
|
-
| ------------------ |
|
|
472
|
-
| `SHORT_BODY_WORDS` | `const SHORT_BODY_WORDS`
|
|
473
|
-
| `lintNoteStates` | `lintNoteStates(contentBase, { records, contentPackage })` | `{findings, counts, byType, oldestDrafts, summary}` | checking a tree's states and counting the ladder, from the corpus the command already derived |
|
|
470
|
+
| Export | Signature | Returns | Use it when |
|
|
471
|
+
| ------------------ | ------------------------------------------------------------------ | --------------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
472
|
+
| `SHORT_BODY_WORDS` | `const SHORT_BODY_WORDS` | `number` | reading the word count below which an unmarked body is asked whether it is a draft |
|
|
473
|
+
| `lintNoteStates` | `lintNoteStates(contentBase, { records, contentPackage, parsed })` | `{findings, counts, byType, oldestDrafts, summary}` | checking a tree's states and counting the ladder, from the corpus the command already derived |
|
|
474
474
|
|
|
475
475
|
### `engine.placeRelations`
|
|
476
476
|
|
|
@@ -871,7 +871,7 @@ Emitting this package's cross-package link manifest. `engine/content-address.mjs
|
|
|
871
871
|
| Export | Signature | Returns | Use it when |
|
|
872
872
|
| ----------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
873
873
|
| `LEAD_ANCHOR` | `const LEAD_ANCHOR` | — | The reserved anchor name for a journal's **first** page. |
|
|
874
|
-
| `anchorsOf` | `
|
|
874
|
+
| `anchorsOf` | `anchorsOf(entryUuid, entryId, body, name, syntax?)` | {Record<string, string>} The anchors. | Every anchor of a note's journal, as `anchorName → Foundry target`. |
|
|
875
875
|
| `entriesForNote` | `function entriesForNote(fm, name, address, body, ctx)` | {Array<object>} One or two entries, in {@link buildManifest}'s shape. | The manifest entries a single note produces. |
|
|
876
876
|
| `collectFoundryEntries` | `function collectFoundryEntries(contentBase, ctx)` | `{{entries: Array<object>, notes: number, skipped: Array<{file: string, reason: string}>}}` | Every note this package publishes, as manifest entries. |
|
|
877
877
|
| `foundryIdentities` | `function foundryIdentities(config` | `{{contentPackage: string, foundryPackageId: string, packRouter: object, web: boolean, skipDirectories: readonly string[]}}` | The identities an emission runs against, from configuration. |
|
|
@@ -881,24 +881,224 @@ A generated dictionary headword maps to its containing page's UUID followed
|
|
|
881
881
|
by its word fragment. Other authored spans keep their containing-page
|
|
882
882
|
mapping.
|
|
883
883
|
|
|
884
|
+
### `engine.contentSession`
|
|
885
|
+
|
|
886
|
+
One invocation's content capture and lazy prepared views. Import the namespace
|
|
887
|
+
from `@heroiclands/package-build/engine`, or import the functions directly from
|
|
888
|
+
`@heroiclands/package-build/engine/content-session`.
|
|
889
|
+
|
|
890
|
+
| Export | Signature | Returns | Use it when |
|
|
891
|
+
| ---------------------- | ---------------------------------------- | -------------------------- | ---------------------------------------------- |
|
|
892
|
+
| `CONTENT_TARGETS` | `readonly [index, lint, links, compile]` | the closed execution order | Selecting operations in a shared invocation. |
|
|
893
|
+
| `createContentSession` | `createContentSession(options?)` | `Promise<ContentSession>` | Sharing source work across content operations. |
|
|
894
|
+
|
|
895
|
+
Options are the resolved `config`, `contentBase`, `assetsBase`,
|
|
896
|
+
`skipDirectories` and compile `router`. Paths and scope default from that
|
|
897
|
+
configuration. The session binds its exact configuration object, canonical
|
|
898
|
+
roots, directory scope and router. `assertContext(options?)` refuses reuse
|
|
899
|
+
with a different bound value. A new invocation, an input edit, a changed
|
|
900
|
+
dependency cache or a changed configuration needs a fresh session; no state
|
|
901
|
+
is persisted or shared across sessions.
|
|
902
|
+
|
|
903
|
+
The session exposes `config`, `contentBase`, `assetsBase`, `skipDirectories`,
|
|
904
|
+
`router`, physical `inventory`, raw `sources`, derived `records`, authored
|
|
905
|
+
`parsed` notes, preparation `problems` and captured dependency `foreign`
|
|
906
|
+
views. Treat these inputs as read-only. Parsed notes retain exact `raw`
|
|
907
|
+
strings, trimmed `body`, authored `frontmatter` and file coordinates; malformed
|
|
908
|
+
or untyped physical files remain available to raw checks. Derivation and
|
|
909
|
+
publication use their own record projections, including per-system clones.
|
|
910
|
+
|
|
911
|
+
| Method | Result and scope |
|
|
912
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
913
|
+
| `syntax(text)` | Memoized block, alert and span scanner results for that exact string; a different projection has its own positions. |
|
|
914
|
+
| `sqlTables(audience?)` | Prepared SQL and generated sections for `all` (default) or `public`, once per audience in this context. |
|
|
915
|
+
| `linkTables()` | Source-audience results selected for prose-link checking. |
|
|
916
|
+
| `audit(kind?)` | The diagnostic link index for `links` (default) or `lint`; this stays separate from routed native resolution. |
|
|
917
|
+
| `publication()` | The complete `PreparedContentIndex`, including source-audience and native bodies. |
|
|
918
|
+
| `compileCorpus()` | Records, parsed notes, native SQL, scanner projections and the routed compiler link index. |
|
|
919
|
+
| `prepare(targets)` | Prepare selected closed targets in `CONTENT_TARGETS` order before a caller starts a writer; returns the session. |
|
|
920
|
+
| `assertContext(options?)` | Check configuration, roots, scope and router against the captured context. |
|
|
921
|
+
| `dispose()` | Invalidate derived views and methods at the end of the invocation. |
|
|
922
|
+
|
|
923
|
+
SQL query answers remain local to each audience preparation; their databases
|
|
924
|
+
close inside preparation. The session reuses results without sharing a public
|
|
925
|
+
answer with the complete native corpus. Scanner results are also read-only.
|
|
926
|
+
`prepare` refuses writers when shared source preparation or the existing note
|
|
927
|
+
state preflight fails. Ordinary lint findings add no gate to compilation.
|
|
928
|
+
|
|
929
|
+
```js
|
|
930
|
+
import { contentSession, contentIndex, compendiums } from "@heroiclands/package-build/engine";
|
|
931
|
+
|
|
932
|
+
const session = await contentSession.createContentSession({ config });
|
|
933
|
+
try {
|
|
934
|
+
await session.prepare(["index", "compile"]);
|
|
935
|
+
contentIndex.emitContentIndex({ config, publication: await session.publication() });
|
|
936
|
+
await compendiums.compilePacks({ config, session });
|
|
937
|
+
} finally {
|
|
938
|
+
session.dispose();
|
|
939
|
+
}
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
### `engine/content-sources.mjs`
|
|
943
|
+
|
|
944
|
+
Reachable through `@heroiclands/package-build/engine/content-sources`; the
|
|
945
|
+
session uses these physical input adapters without adding a namespace export.
|
|
946
|
+
|
|
947
|
+
| Export | Signature | Returns | Use it when |
|
|
948
|
+
| ----------------------- | -------------------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------ |
|
|
949
|
+
| `captureContentSources` | `captureContentSources(contentBase, assetsBase, skipDirectories)` | `{sources, indexSources, paths}` | Capturing exact text and physical path walks before parsing. |
|
|
950
|
+
| `capturedSources` | `capturedSources(contentBase, sources, skipDirectories, extensions)` | generator of `[file, raw]` | Selecting a raw checker's physical scope from captured text. |
|
|
951
|
+
|
|
952
|
+
`sources` maps absolute text-file paths to `{raw}`. `indexSources` retains the
|
|
953
|
+
index walk's selected Markdown order. `paths` retains `{root, file, name,
|
|
954
|
+
directory}` for each physical walk, including its root identity so overlapping
|
|
955
|
+
content and asset scopes preserve their own filtering and order.
|
|
956
|
+
|
|
957
|
+
### `engine/first-use.mjs`
|
|
958
|
+
|
|
959
|
+
Import from `@heroiclands/package-build/engine/first-use`.
|
|
960
|
+
|
|
961
|
+
| Export | Signature | Returns | Use it when |
|
|
962
|
+
| ----------------------- | ----------------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------ |
|
|
963
|
+
| `createFirstUseChecker` | `createFirstUseChecker({ records, index, catalog?, parsed?, syntax? })` | `checker({ file, raw })` | Checking authored prose against the current corpus's name-marking conventions. |
|
|
964
|
+
|
|
965
|
+
Construct one checker with the session's read-only `records` and
|
|
966
|
+
`await session.audit("lint")`. Call it for each existing link-index note.
|
|
967
|
+
It performs no I/O and returns `{file, line, column, severity: "warning",
|
|
968
|
+
rules, message}` diagnostics. `rules` is a list of applicable rule names, merged
|
|
969
|
+
into one warning for each occurrence; the message names the full name or
|
|
970
|
+
explicit label that needs attention. Only `.name` spans and authored link
|
|
971
|
+
labels enter name tracking; plain text is not searched. Indexed full names and
|
|
972
|
+
declared aliases share an identity, while other labels use their whole text.
|
|
973
|
+
A whole bold indexed name receives an advisory without entering name tracking.
|
|
974
|
+
Local and captured dependency names and aliases share the same corpus
|
|
975
|
+
context. The command's lint target constructs
|
|
976
|
+
the checker once, uses exact authored `raw` strings and keeps these findings
|
|
977
|
+
advisory. See the [authoring conventions](authoring/links-and-markup.md#marking-names-in-prose).
|
|
978
|
+
|
|
979
|
+
Supply the invocation's `catalog` to share its full-name and alias lookup with
|
|
980
|
+
the package names report. Optional `parsed` maps absolute files to captured
|
|
981
|
+
`{raw, body, bodyLine?, bodyColumn?}`; `syntax` is the session's scanner
|
|
982
|
+
projection. When the captured raw text matches, the checker rebases the body's
|
|
983
|
+
existing name inventory into its authored raw source coordinates. Standalone
|
|
984
|
+
calls use their supplied raw text.
|
|
985
|
+
|
|
986
|
+
### `engine/name-markup.mjs`
|
|
987
|
+
|
|
988
|
+
Import from `@heroiclands/package-build/engine/name-markup`.
|
|
989
|
+
|
|
990
|
+
| Export | Signature | Returns | Use it when |
|
|
991
|
+
| ----------------- | --------------------------------------------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
992
|
+
| `inlineText` | `inlineText(tokens)` | `string` | Reading visible name text from actual parsed inline children and their resolved reference context. |
|
|
993
|
+
| `rebaseNameSpans` | `rebaseNameSpans(spans, { raw, bodyLine?, bodyColumn? })` | Copied name spans at original file coordinates | Rebasing a captured body inventory and attribute ranges without parsing it again. |
|
|
994
|
+
|
|
995
|
+
`scanSpans(source)` returns `{spans, names, errors}`. `names` contains the same
|
|
996
|
+
span objects with the exact `name` class, including spans inside links. Each
|
|
997
|
+
span retains `text`, `attrs`, offsets, 1-based line/UTF-16 column and `visible`
|
|
998
|
+
text from actual parsed children. `contentEnd` is the exclusive raw inner-label
|
|
999
|
+
endpoint. `attributePositions` maps each named attribute to `key` and `value`
|
|
1000
|
+
ranges with `{start, end, line, column}`. Offsets are 0-based with exclusive
|
|
1001
|
+
ends. Rebasing copies these values and leaves the captured inventory unchanged.
|
|
1002
|
+
|
|
1003
|
+
The leaf module exports the declaration types `ContentSpan`, `SpanSourceSite`,
|
|
1004
|
+
`SpanAttributePosition`, `SpanFinding` and `SpanScan`. The generic rebasing
|
|
1005
|
+
helper retains additional fields of the captured span subtype.
|
|
1006
|
+
|
|
1007
|
+
`engine/extension-attributes.mjs` exposes the shared attribute grammar:
|
|
1008
|
+
|
|
1009
|
+
| Export | Signature | Returns | Use it when |
|
|
1010
|
+
| -------------------------- | ------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
1011
|
+
| `parseExtensionAttributes` | `parseExtensionAttributes(source, { idPattern?, positions? } = {})` | `{id, classes, values, problems, positions?}` | Parsing identifiers, ordered classes and named values; `positions: true` retains attribute key/value offsets. |
|
|
1012
|
+
|
|
1013
|
+
Attribute-parser positions are ranges within its supplied attribute source;
|
|
1014
|
+
the span scanner maps them to Markdown coordinates. The optional range map
|
|
1015
|
+
does not change the parsed values.
|
|
1016
|
+
|
|
1017
|
+
### `engine/name-rows.mjs`
|
|
1018
|
+
|
|
1019
|
+
Import from `@heroiclands/package-build/engine/name-rows`.
|
|
1020
|
+
|
|
1021
|
+
| Export | Signature | Returns | Use it when |
|
|
1022
|
+
| -------------- | -------------------- | --------------------------- | ---------------------------------------------------------------------- |
|
|
1023
|
+
| `NAME_COLUMNS` | `const NAME_COLUMNS` | Frozen ordered column names | Reading `owner`, `name`, `type`, `subType`, `line`, `column`. |
|
|
1024
|
+
| `namesRows` | `namesRows(records)` | `NameRow[]` | Projecting own-note occurrences into SQL rows without I/O or mutation. |
|
|
1025
|
+
|
|
1026
|
+
Rows preserve record and occurrence order. `owner` is the canonical NOTE page
|
|
1027
|
+
derived from the record's canonical Address, including for native Item
|
|
1028
|
+
sources; an unaddressable record keeps `null`. Assets and documentation mirrors
|
|
1029
|
+
contribute no rows. Each row carries the occurrence's visible `name`, nullable
|
|
1030
|
+
`type`/`subType`, and numeric 1-based `line`/UTF-16 `column`. SQL ingestion fixes
|
|
1031
|
+
text columns as `VARCHAR` and positions as `BIGINT`, including empty,
|
|
1032
|
+
entirely-null and late-supplied classifications.
|
|
1033
|
+
|
|
1034
|
+
### `engine/names.mjs`
|
|
1035
|
+
|
|
1036
|
+
Import from `@heroiclands/package-build/engine/names`.
|
|
1037
|
+
|
|
1038
|
+
| Export | Signature | Returns | Use it when |
|
|
1039
|
+
| ----------------------- | -------------------------------------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
1040
|
+
| `normalizeName` | `normalizeName(text)` | `string` | Normalizing NFC, apostrophes and whitespace while preserving case. |
|
|
1041
|
+
| `nameForms` | `nameForms(text)` | `string[]` | Enumerating supported whole-label possessives and regular plurals. |
|
|
1042
|
+
| `createNameCatalog` | `createNameCatalog({ records, index })` | `NameCatalog` | Sharing indexed full-name, alias and resolved Address matching across checks. |
|
|
1043
|
+
| `collectUnwrittenNames` | `collectUnwrittenNames({ records, catalog })` | `{groups, firstUse}` | Grouping every unresolved captured occurrence by supplied classification. |
|
|
1044
|
+
| `analyzeNameSpans` | `analyzeNameSpans(spans, { file?, vocabulary?, types? } = {})` | `{names, findings}` | Validating supplied `data-type` against actual note declarations at attribute-key positions. |
|
|
1045
|
+
| `createNamesReport` | `createNamesReport({ package, records, catalog })` | `NamesReport` | Preparing deterministic current-package unwritten and conflicting groups without I/O. |
|
|
1046
|
+
| `namesReportFinding` | `namesReportFinding(report, { contentBase? } = {})` | A located warning, or `undefined` | Formatting one human package advisory with every reported use. |
|
|
1047
|
+
|
|
1048
|
+
`NameCatalog` provides `recognize(label, preferred?)` and `resolve(target)`;
|
|
1049
|
+
indexed full names and declared aliases share canonical identity, and ambiguous
|
|
1050
|
+
labels retain every candidate. Dependency names come from the captured link
|
|
1051
|
+
index; folder-note identities are excluded. These pure helpers read the
|
|
1052
|
+
invocation's existing corpus.
|
|
1053
|
+
|
|
1054
|
+
`analyzeNameSpans` accepts actual parsed spans at file coordinates, with
|
|
1055
|
+
`visible`, `attrs`, `line`, `column` and optional `attributePositions`. It
|
|
1056
|
+
returns valid five-field `MarkedName` entries and supplied-value error findings.
|
|
1057
|
+
`vocabulary` defaults to `NOTE_VOCABULARY`; `types` supplies additional bare
|
|
1058
|
+
types from configured declarations. Callers propagate findings through their
|
|
1059
|
+
existing preparation error channel.
|
|
1060
|
+
|
|
1061
|
+
`NamesReport` has `{package, unwritten, conflicts}`. Each unwritten group has
|
|
1062
|
+
`{type, subType, names: [{name, uses}]}`. Each conflict has
|
|
1063
|
+
`{name, kinds: [{type, subType, uses}]}`. A use has
|
|
1064
|
+
`{owner, file, line, column}`, with its file relative to the content root and
|
|
1065
|
+
the same NOTE/null owner convention as `namesRows`. Untyped uses are excluded
|
|
1066
|
+
from conflicts; matching bare-type/subtype refinements are compatible.
|
|
1067
|
+
`namesReportFinding` rebases file paths with `contentBase`, anchors the advisory
|
|
1068
|
+
at the earliest reported actual use, and returns no warning for an empty report.
|
|
1069
|
+
|
|
884
1070
|
### `engine.contentIndex`
|
|
885
1071
|
|
|
886
1072
|
Collecting and publishing this package's content index. Records describe note frontmatter, assets, prose and event anchors, and the document targets those notes produce. Dynamic publication prepares the same generated Markdown and scalar expressions as the rendering surfaces, using each source note's audience.
|
|
887
1073
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
1074
|
+
Own-note records carry derived `names` entries in source order as
|
|
1075
|
+
`{name, type, subType, line, column}`. Missing classifications are explicit
|
|
1076
|
+
`null`; no occurrences gives `[]`. Positions refer to original authored span
|
|
1077
|
+
openings, before generated content. Metadata JSONL transports these entries
|
|
1078
|
+
to dependency SQL without an additional artifact. This field is reserved for
|
|
1079
|
+
derived data, and is not an authored frontmatter key.
|
|
1080
|
+
|
|
1081
|
+
`buildIndexRecord` and `indexRecordsForNote` accept `bodyColumn` alongside
|
|
1082
|
+
`bodyLine` to locate the authored body's first UTF-16 character. Their optional
|
|
1083
|
+
`nameTypes` iterable, also accepted by `collectContentIndex` and
|
|
1084
|
+
`indexRecordsFor`, supplies additional bare kinds from configured type
|
|
1085
|
+
declarations. `indexRecordsFor` defaults that iterable to the resolved
|
|
1086
|
+
configuration's `itemTypes`.
|
|
1087
|
+
|
|
1088
|
+
| Export | Signature | Returns | Use it when |
|
|
1089
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1090
|
+
| `noteAddress` | `function noteAddress(frontmatter, contentPackage)` | {{slug: string, canonical: string}\|null} `slug` is what goes inside `[[…]]` within this package; `canonical` is the fully qualified key the manifest files the note under, carrying the package and the system as well. | The address a wikilink writes to reach a note, or `null` when it has none. |
|
|
1091
|
+
| `sortKeysDeep` | `function sortKeysDeep(value)` | {unknown} The value with every plain object's keys in sorted order. | Recursively sort an object's keys, so serialization is order-independent. |
|
|
1092
|
+
| `asciiName` | `function asciiName(name)` | {string\|null} The ASCII form, or `null` when there is no name, or nothing printable survives. | A note's display name reduced to printable 7-bit ASCII. |
|
|
1093
|
+
| `asciiAliases` | `function asciiAliases(aliases)` | {Array<string>} Possibly empty, never null: a note with no aliases has an empty set of them, which is a fact rather than a missing value, and a consumer iterating it should not have to check first. | A note's `name.aliases` reduced to printable 7-bit ASCII, in order. |
|
|
1094
|
+
| `serializeContentIndex` | `function serializeContentIndex(records)` | {string} One compact JSON object per line, newline-terminated. | Serialize records as JSON Lines. |
|
|
1095
|
+
| `indexRecordsFor` | `indexRecordsFor({ contentBase, config, skipDirectories, problems, parsed, sources, syntax, foreignIndex, nameTypes? })` | {object[]} One record per note, plus one per documentation entry. | The index records for a content tree, without writing anything. |
|
|
1096
|
+
| `indexRecordsForNote` | `indexRecordsForNote({ frontmatter, body, bodyLine, bodyColumn?, nameTypes?, relPath, absPath, raw, contentPackage, manifest, addressContext })` | `object[]` | Derive the note's own record and its documentation record from parsed text. |
|
|
1097
|
+
| `prepareContentIndex` | `async prepareContentIndex({ contentBase, config, session } = {})` | `Promise<PreparedContentIndex>` — the captured source context and complete expanded bodies, described below | Prepare dynamic publication without writing files. |
|
|
1098
|
+
| `emitContentIndex` | `emitContentIndex({ contentBase, outDir, config, publication } = {})` | `{{file: string, notes: number, assets: number, records: number, bytes: number, full: number, draft: number, stub: number, dictionary: {file: string, rows: number}, terms: {file: string, rows: number}}}` | Synchronously publish metadata and the dictionary and terms datafiles; dynamic content requires a complete `publication`. |
|
|
1099
|
+
| `buildIndexRecord` | `buildIndexRecord({ frontmatter, relPath, absPath, raw, contentPackage, body, bodyLine, bodyColumn?, nameTypes?, manifest })` | `Record<string, any>` — the record, with derived fields sorted deep | building one note's content-index record; refuses a note that authors a key the index derives itself (`package` among them) before building anything |
|
|
1100
|
+
| `collectContentIndex` | `collectContentIndex(contentBase, { contentPackage, skipDirectories, assetsBase, manifest, problems, foreignRecord, parsed, sources, syntax, nameTypes? })` | `Array<Record<string, any>>` | reading a whole content tree into index records, in a total order independent of directory-read order; an item note yields two records (its own and its documentation journal's), and each asset root yields one per file; each note carries its resolved culture as `data.culture` |
|
|
1101
|
+
| `resolveCultures` | `resolveCultures(records, { contentPackage, contentBase, foreignRecord, problems })` | `Array<Record<string, any>>` — the same records | writing each note's resolved culture into its record as `data.culture`: its own value, else its parents', else for a polity its seat's and governed places', pooled; parents that disagree give a finding into `problems`, or one thrown Error listing every conflict |
|
|
902
1102
|
|
|
903
1103
|
`prepareContentIndex` resolves `contentBase` from the configured `paths.content`
|
|
904
1104
|
when omitted. Its `PreparedContentIndex` contains:
|
|
@@ -911,6 +1111,7 @@ when omitted. Its `PreparedContentIndex` contains:
|
|
|
911
1111
|
| `parsed` | A `Map` keyed by absolute note file, holding authored `frontmatter`, `body`, `raw`, `bodyLine` and `bodyColumn`. |
|
|
912
1112
|
| `expandedBodies` | A `Map` keyed by absolute note file, holding `markdown`, its body-relative `lineMap` of `{line, generated}` entries, and optional `generatedFrom`. |
|
|
913
1113
|
| `foundryBodies` | A `Map` with the same body shape, prepared against the complete native compendium corpus. |
|
|
1114
|
+
| `syntax` | Optional session-local scanner projection function; read-only and valid for that session's lifetime. |
|
|
914
1115
|
|
|
915
1116
|
Preparation expands SQL tables, page lists, automatic sections and scalar
|
|
916
1117
|
expressions. Prose declarations in `expandedBodies` use each source's audience:
|
|
@@ -950,18 +1151,25 @@ scalar expressions, events or other generated sections require
|
|
|
950
1151
|
`indexRecordsFor` and `collectContentIndex` collect authored records and pure
|
|
951
1152
|
lexical sections; use preparation and emission to publish dynamic body targets.
|
|
952
1153
|
|
|
1154
|
+
On lore and affiliation notes, `data.language` and `data.glossary[].language`
|
|
1155
|
+
require a language NOTE Address. Decoding refuses other recognized system
|
|
1156
|
+
segments at the authored value, naming the complete
|
|
1157
|
+
`<pkg>-note-skill-<shortcode>` to write. A short local form such as
|
|
1158
|
+
`skill-provnzlng` is also accepted. See the [glossary language
|
|
1159
|
+
rules](reference/format-details.md#dictionaries-and-glossaries).
|
|
1160
|
+
|
|
953
1161
|
`engine.contentIndex` also re-exports eight names from neighbouring leaf modules, at this same import path:
|
|
954
1162
|
|
|
955
|
-
| Export | Signature
|
|
956
|
-
| --------------------- |
|
|
957
|
-
| `collectAnchors` | `collectAnchors(body, bodyLine)` | `Array<{slug: string, line: number, kind: string}>` | reading a note body's anchors, each with its kind, shared with the link checker and every build that emits a link |
|
|
958
|
-
| `DERIVED_KEYS` | `const DERIVED_KEYS`
|
|
959
|
-
| `noteFile` | `noteFile(contentBase, record)`
|
|
960
|
-
| `authoredFrontmatter` | `authoredFrontmatter(record)`
|
|
961
|
-
| `isNoteRecord` | `isNoteRecord(record)`
|
|
962
|
-
| `isStub` | `isStub(record)`
|
|
963
|
-
| `isAssetRecord` | `isAssetRecord(record)`
|
|
964
|
-
| `recordPath` | `recordPath(record)`
|
|
1163
|
+
| Export | Signature | Returns | Use it when |
|
|
1164
|
+
| --------------------- | ------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1165
|
+
| `collectAnchors` | `collectAnchors(body, bodyLine, resolveRole?, syntax?)` | `Array<{slug: string, line: number, kind: string}>` | reading a note body's anchors, each with its kind, shared with the link checker and every build that emits a link |
|
|
1166
|
+
| `DERIVED_KEYS` | `const DERIVED_KEYS` | — | reading which keys the content index adds to a record, and which a note therefore may not author itself |
|
|
1167
|
+
| `noteFile` | `noteFile(contentBase, record)` | `string` — the note's absolute path | composing an index record's `file.path` (recorded relative, for a byte-stable artifact) back into an openable absolute path |
|
|
1168
|
+
| `authoredFrontmatter` | `authoredFrontmatter(record)` | `Record<string, any>` — the frontmatter without `DERIVED_KEYS` | reading a note's frontmatter back from its index record, its resolved `data.culture` included, so a pass can lint or compile from the index without reasoning about derived keys as if the author wrote them |
|
|
1169
|
+
| `isNoteRecord` | `isNoteRecord(record)` | `boolean` | telling a note's own record apart from its documentation journal's and from an asset's, when enumerating the corpus |
|
|
1170
|
+
| `isStub` | `isStub(record)` | `boolean` | telling a stub apart from a note that publishes a page; asked of the absent address, which is the whole signal |
|
|
1171
|
+
| `isAssetRecord` | `isAssetRecord(record)` | `boolean` | telling a record that addresses a file apart from one that addresses a note; the `asset` block is what marks it |
|
|
1172
|
+
| `recordPath` | `recordPath(record)` | `string` — the path the record names inside its package | ordering or reporting across both record shapes: a note names the `.md` it was parsed from, an asset the file it is |
|
|
965
1173
|
|
|
966
1174
|
### `engine.assetTypes`
|
|
967
1175
|
|
|
@@ -1242,13 +1450,20 @@ One authored pathname, and the four addresses it resolves to. A note names a fil
|
|
|
1242
1450
|
|
|
1243
1451
|
Resolving every link in a content tree, and reporting the ones that land nowhere. Three link defects survive both content builds silently, so neither the pack compilers nor a site build catches them:
|
|
1244
1452
|
|
|
1245
|
-
| Export | Signature
|
|
1246
|
-
| -------------------- |
|
|
1247
|
-
| `anchorsOf` | `function anchorsOf(body)`
|
|
1248
|
-
| `buildLinkIndex` | `buildLinkIndex(contentBase, { config, skipDirectories, sqlTables, records, problems })` | {object} The notes, the index, and the resolvers built over it. | Read a content tree into the index a link resolves against. |
|
|
1249
|
-
| `auditHomepageLinks` | `function auditHomepageLinks(index)`
|
|
1250
|
-
| `auditLinks` | `function auditLinks(index)`
|
|
1251
|
-
| `walkReachability` | `function walkReachability(index,`
|
|
1453
|
+
| Export | Signature | Returns | Use it when |
|
|
1454
|
+
| -------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
|
|
1455
|
+
| `anchorsOf` | `function anchorsOf(body)` | {Set<string>} The declared anchor slugs. | Every `{#anchor}` a note declares on a heading. |
|
|
1456
|
+
| `buildLinkIndex` | `buildLinkIndex(contentBase, { config, skipDirectories, sqlTables, records, parsed, problems })` | {object} The notes, the index, and the resolvers built over it. | Read a content tree into the index a link resolves against. |
|
|
1457
|
+
| `auditHomepageLinks` | `function auditHomepageLinks(index)` | {Array<{note: object, field: string, url: string, text: string, occurrence: number, message: string}>} One finding per defect, `text` and `occurrence` locating it in the note's raw source. | Every defect in the addresses a package homepage carries. |
|
|
1458
|
+
| `auditLinks` | `function auditLinks(index)` | `{{deadAnchors: object[], deadAddresses: object[], unlabelledLinks: object[], frontmatterLinks: object[], homepageLinks: object[], usedManifest: Set<string>}}` The findings, and which addresses a foreign manifest answered. | Every link in a tree that lands nowhere. |
|
|
1459
|
+
| `walkReachability` | `function walkReachability(index,` | `{{root: object, reached: Set<object>, orphans: object[]}}` The root, everything reached from it, and the corpus members that were not. | Walk a corpus from its root and report what nothing links to. |
|
|
1460
|
+
|
|
1461
|
+
`buildLinkIndex` optionally accepts the `parsed` map captured by `indexRecordsFor`
|
|
1462
|
+
alongside the supplied `records` in the same invocation. It reads each entry's
|
|
1463
|
+
`raw` string by absolute note path and derives the untrimmed body as usual;
|
|
1464
|
+
without a raw string it reads that file. The caller owns this map, and the
|
|
1465
|
+
link index leaves it unchanged. This source capture is separate from published
|
|
1466
|
+
metadata and has no persistent or cross-invocation cache.
|
|
1252
1467
|
|
|
1253
1468
|
### `engine.webWikilinks`
|
|
1254
1469
|
|
|
@@ -1277,7 +1492,7 @@ Shared helpers for the pack compilers in `packages/package-build/`. The HeroicLa
|
|
|
1277
1492
|
| ------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1278
1493
|
| `md` | `const md` | — | The markdown renderer every surface shares. |
|
|
1279
1494
|
| `renderFoundryMarkdown` | `function renderFoundryMarkdown(body)` | `string` — HTML with secret sections for GM passages. | Rendering a note body for a Foundry document. |
|
|
1280
|
-
| `parseMarkdownFile` | `
|
|
1495
|
+
| `parseMarkdownFile` | `parseMarkdownFile(filePath, { addressContext, raw, renderDescription } = {})` | — | Parses a markdown file with YAML frontmatter; returns frontmatter, body, rendered description, raw source, and body coordinates. |
|
|
1281
1496
|
| `assertStatedScope` | `function assertStatedScope(skipDirectories, who)` | {void} | Refuse a corpus read whose scope its caller did not state. |
|
|
1282
1497
|
| `assertSuppliedCorpus` | `function assertSuppliedCorpus(records, who)` | {void} | Refuse a corpus read whose records its caller did not supply. |
|
|
1283
1498
|
| `statedTemplatePriority` | `function statedTemplatePriority(fm, label,` | {number\|null} The priority, or `null` when the note is not a template or states nothing. | The template priority a note states, for a system that treats an unstated one as "not a template" rather than as an authoring error. |
|
|
@@ -1294,13 +1509,41 @@ Shared helpers for the pack compilers in `packages/package-build/`. The HeroicLa
|
|
|
1294
1509
|
| `convertNoteWikilinks` | `convertNoteWikilinks(body, { type, id, pack, docPack, index, name, file, bodyLine, bodyColumn, lineMap })` | `{{markdown: string, unresolved: Array<object>}}` | Converts the wikilinks in one note's markdown, reporting any that have no target in the content tree. |
|
|
1295
1510
|
| `expandNoteTables` | `function expandNoteTables(body,` | `{{markdown: string, lineMap: Array<{line: number, generated: boolean}>}}` The body with every table expanded, and where each emitted line came from — which is what lets a diagnostic about the expanded body name an authored position. | Expand prepared SQL tables in one note's markdown, before wikilinks are resolved — so a generated cell may itself be a wikilink. |
|
|
1296
1511
|
| `folderFilename` | `function folderFilename(name, id)` | — | Builds a compendium-source filename for a folder JSON document: `folder_Name_id.json` with non-alphanumeric runs replaced by underscores. |
|
|
1297
|
-
| `walkMarkdownTree` | `walkMarkdownTree(rootDir, { skipDirectories })`
|
|
1512
|
+
| `walkMarkdownTree` | `walkMarkdownTree(rootDir, { skipDirectories, sources, renderDescription })` | generator yielding `{frontmatter, body, description, raw, bodyLine?, bodyColumn?, file, absPath}` | walking a content tree and reading every markdown file's frontmatter and body; `skipDirectories` is required rather than defaulted, so two callers cannot silently disagree about the corpus's scope |
|
|
1298
1513
|
|
|
1299
|
-
`buildContentLinkIndex` accepts `{ config?, records, sqlTables? }`.
|
|
1514
|
+
`buildContentLinkIndex` accepts `{ config?, records, sqlTables?, foreign? }`.
|
|
1300
1515
|
`records` is the required, supplied content corpus. The optional prepared
|
|
1301
1516
|
`sqlTables` map supplies generated anchors and their Foundry page mappings,
|
|
1302
1517
|
so glossary word links resolve to their dictionary entries.
|
|
1303
1518
|
|
|
1519
|
+
`parseMarkdownFile` reads its supplied exact `raw` string when present. Its
|
|
1520
|
+
`renderDescription` option defaults to true; false leaves `description` empty
|
|
1521
|
+
while retaining authored body and positions. `walkMarkdownTree` accepts a
|
|
1522
|
+
selected `sources` map in walk order and the same rendering option, also true
|
|
1523
|
+
by default. Index collection explicitly omits unused rendered descriptions.
|
|
1524
|
+
`indexRecordsFor` accepts that selected map, a `syntax` projection function
|
|
1525
|
+
and a captured `foreignIndex`. These adapters do not retain state globally.
|
|
1526
|
+
|
|
1527
|
+
The physical wrappers `lintContentCharset`, `lintContentHtml`,
|
|
1528
|
+
`lintContentIcons`, `lintContentImages` and `lintContentTaskLists` accept an
|
|
1529
|
+
optional `sources` map of absolute paths to `{raw}`. Their existing extension,
|
|
1530
|
+
hidden-path and skip filters still apply; without the map they walk and read
|
|
1531
|
+
the tree. `lintPathCharset` accepts optional physical `inventory`, retaining
|
|
1532
|
+
walk roots and order. `lintNoteStates` accepts the authored `parsed` map, with
|
|
1533
|
+
its existing file reader for missing entries.
|
|
1534
|
+
`parseMarkdownFile` accepts LF and CRLF frontmatter delimiters and retains the
|
|
1535
|
+
exact source as `raw`. Its trimmed `body` keeps the authored line endings, with
|
|
1536
|
+
`bodyLine` and `bodyColumn` locating its first character in that original source.
|
|
1537
|
+
|
|
1538
|
+
### `./engine/diagnostics`
|
|
1539
|
+
|
|
1540
|
+
The `@heroiclands/package-build/engine/diagnostics` wildcard module provides
|
|
1541
|
+
source locations and frontmatter source slicing.
|
|
1542
|
+
|
|
1543
|
+
| Export | Signature | Returns | Use it when |
|
|
1544
|
+
| ------------------ | ----------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
1545
|
+
| `splitFrontmatter` | `splitFrontmatter(raw)` | `{yaml: string, body: string} \| null` | Split opening LF or CRLF frontmatter into exact YAML and untrimmed body slices, without parsing or rewriting the source. |
|
|
1546
|
+
|
|
1304
1547
|
### `engine.itemRegistry`
|
|
1305
1548
|
|
|
1306
1549
|
**The resolved item-type registry** — the consuming repository's `itemBuilders` table, and the type whitelist derived from its keys. Both are read from the one resolved configuration, so they are literally the same object's keys and values: a type cannot be whitelisted for compilation without the builder that compiles it, which is the guarantee this exists for. Where a consumer declares **several** registries, one per system, the vocabulary is their union and every lookup below takes the system that is asking — a type both systems declare has two builders, and answering with one of them because it was declared first is the silent-wrong-output failure this package spends its time removing. The Item compiler dispatches through {@link itemBuilder}, so the table a consumer configured is the table its notes compile with — the whitelist and the dispatch would otherwise come from different places, and a consumer supplying its own registry got the types it asked for and the builders it did not.
|
|
@@ -1455,15 +1698,15 @@ The content tree, built into a book. The I/O half of the PDF surface: it reads t
|
|
|
1455
1698
|
|
|
1456
1699
|
Journals pack compiler — produces JSON pack files for the "journals" Foundry compendium from markdown notes in the `assets/content/` tree. The content root (`contentBase`) is walked recursively; any `.md` file whose frontmatter declares either `type: doc` or a **doc-carrying type** ({@link sohl.utils.packs.docEntryTypes} — every item type, plus `macro`) is compiled into one JournalEntry document. Each note's body is split on top-level H1 headings; the optional content before the first H1 becomes a lead page, and each subsequent H1 starts a new page named after its heading text. All page bodies are rendered to HTML.
|
|
1457
1700
|
|
|
1458
|
-
| Export | Signature
|
|
1459
|
-
| --------------------- |
|
|
1460
|
-
| `splitPages` | `
|
|
1461
|
-
| `assertUniquePages` | `function assertUniquePages(rawPages, noteName)`
|
|
1462
|
-
| `assertUniqueAnchors` | `function assertUniqueAnchors(rawPages, noteName)`
|
|
1463
|
-
| `journalPageId` | `function journalPageId(entryId, page)`
|
|
1464
|
-
| `buildPages` | `function buildPages(rawPages, entryId, noteName)`
|
|
1465
|
-
| `buildJournalEntry` | `buildJournalEntry({ id, name, markdown, leadName, folder,
|
|
1466
|
-
| `Journals` | `class Journals extends BasePackCompiler`
|
|
1701
|
+
| Export | Signature | Returns | Use it when |
|
|
1702
|
+
| --------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
1703
|
+
| `splitPages` | `splitPages(body, leadName, resolveRole, syntax?)` | — | Splits a markdown body into pages by top-level H1 headings. |
|
|
1704
|
+
| `assertUniquePages` | `function assertUniquePages(rawPages, noteName)` | — | Two pages in one note that would derive the same id, which the LevelDB packer reports only as an opaque duplicate-key collision. |
|
|
1705
|
+
| `assertUniqueAnchors` | `function assertUniqueAnchors(rawPages, noteName)` | — | The anchor half of {@link assertUniquePages}, under its former name. |
|
|
1706
|
+
| `journalPageId` | `function journalPageId(entryId, page)` | {string} A 16-character Foundry id. | The id of one page within its entry. |
|
|
1707
|
+
| `buildPages` | `function buildPages(rawPages, entryId, noteName)` | {Array<{\_id: string, name: string, type: string, title: {show: boolean, level: number}, text: {format: number, content: string}, \_key: string}>} The page documents, in order. | Compile split pages into JournalEntryPage documents. |
|
|
1708
|
+
| `buildJournalEntry` | `buildJournalEntry({ id, name, markdown, leadName, folder, stats, syntax })` | {object} The JournalEntry document, keyed for the pack. | Assemble one JournalEntry document from a note's converted markdown. |
|
|
1709
|
+
| `Journals` | `class Journals extends BasePackCompiler` | — | not called directly — imported and driven by `engine/generate.mjs` as the "journals" pack compiler |
|
|
1467
1710
|
|
|
1468
1711
|
### `engine.macros`
|
|
1469
1712
|
|
|
@@ -1536,28 +1779,28 @@ Adventure pack compiler — `type: bundle` notes → Foundry `Adventure` documen
|
|
|
1536
1779
|
|
|
1537
1780
|
Pack JSON generation — in-repo Markdown → per-entry JSON (build-only). Reads the authoritative content tree at the configured content root and compiles each pack's entries to per-entry JSON under its build directory (`build/packs-json/<pack>/` in this repository). The JSON is a disposable build intermediate consumed by `build:compiledb` (which turns it into the shipped LevelDB packs) — it is never committed.
|
|
1538
1781
|
|
|
1539
|
-
| Export | Signature
|
|
1540
|
-
| ----------------------------- |
|
|
1541
|
-
| `systemCompilers` | `function systemCompilers(passes)`
|
|
1542
|
-
| `compilerFor` | `function compilerFor(docType, system`
|
|
1543
|
-
| `emittedArtFor` | `function emittedArtFor(type)`
|
|
1544
|
-
| `packJsonDir` | `const packJsonDir`
|
|
1545
|
-
| `itemPackJsonDirs` | `function itemPackJsonDirs(config`
|
|
1546
|
-
| `bundleSourceJsonDirs` | `function bundleSourceJsonDirs(config`
|
|
1547
|
-
| `orderPassesByDependency` | `function orderPassesByDependency(packs)`
|
|
1548
|
-
| `unsatisfiedPassDependencies` | `function unsatisfiedPassDependencies(running, config)`
|
|
1549
|
-
| `emptyPassErrors` | `function emptyPassErrors(passes)`
|
|
1550
|
-
| `generatePacksJson` | `
|
|
1782
|
+
| Export | Signature | Returns | Use it when |
|
|
1783
|
+
| ----------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
1784
|
+
| `systemCompilers` | `function systemCompilers(passes)` | {Readonly<Record<string, Readonly<Record<string, Function>>>>} System id → document class → pass. | The system-specific compilers, derived from the passes themselves. |
|
|
1785
|
+
| `compilerFor` | `function compilerFor(docType, system` | {Function\|undefined} The compiler class, or `undefined` for a document type nothing here compiles — which {@link generatePack} reports rather than defaulting past. | The compiler class a pack of one document type and one system gets. |
|
|
1786
|
+
| `emittedArtFor` | `function emittedArtFor(type)` | {{document: string\|null, art: readonly string[]}\|null} What the type compiles into and the art it carries there, or `null` where no claim can be made. | The art fields a note of one content type reaches its document through, and the document it reaches. |
|
|
1787
|
+
| `packJsonDir` | `const packJsonDir` | {string} The pack's JSON directory. | Root of the build-only JSON tree for one pack. |
|
|
1788
|
+
| `itemPackJsonDirs` | `function itemPackJsonDirs(config` | {string[]} Each Item pack's JSON directory. | The generated JSON of **every** configured Item pack — what the actors pass reads its predefined items from. |
|
|
1789
|
+
| `bundleSourceJsonDirs` | `function bundleSourceJsonDirs(config` | {Record<string, string[]>} Each readable pack's JSON directory, by the Foundry document type it holds. | The compiled JSON a bundle may hold copies of, by document type. |
|
|
1790
|
+
| `orderPassesByDependency` | `function orderPassesByDependency(packs)` | {object[]} A new list, in compile order. | The passes to run, ordered so that each one follows the output it reads. |
|
|
1791
|
+
| `unsatisfiedPassDependencies` | `function unsatisfiedPassDependencies(running, config)` | {string[]} One message per unsatisfiable dependency. | The dependencies this run cannot satisfy by ordering, because the pass that would produce them is not in it. |
|
|
1792
|
+
| `emptyPassErrors` | `function emptyPassErrors(passes)` | {string[]} One message per pass that must not have been empty. | The passes that compiled nothing when they were expected to compile something — a build failure, not a quiet no-op. |
|
|
1793
|
+
| `generatePacksJson` | `generatePacksJson({ only, config, session, reportPreparation })` | {Promise<number>} Total error count across the generated packs. | Generate the build-only JSON for every pack (or one, when `only` is given). |
|
|
1551
1794
|
|
|
1552
1795
|
### `engine.compendiums`
|
|
1553
1796
|
|
|
1554
1797
|
Compendium pack library — compile / unpack / clean LevelDB packs. Wraps `@foundryvtt/foundryvtt-cli` over the packs a consuming repository declares: - {@link compilePacks}: generates each pack's per-entry JSON from the `assets/content/` Markdown into `build/packs-json/<name>/` (via generate.mjs), then builds LevelDB from it; no committed JSON, no vault. - {@link unpackPacks}: extracts a compiled pack back to per-entry JSON, rebuilding folder paths. - {@link cleanPacks}: normalizes/strips extracted JSON.
|
|
1555
1798
|
|
|
1556
|
-
| Export | Signature
|
|
1557
|
-
| -------------- |
|
|
1558
|
-
| `compilePacks` | `
|
|
1559
|
-
| `cleanPacks` | `async cleanPacks({ config, packDest, packName, entryName })`
|
|
1560
|
-
| `unpackPacks` | `async unpackPacks({ packs, config, stageDest, packDest, packName })`
|
|
1799
|
+
| Export | Signature | Returns | Use it when |
|
|
1800
|
+
| -------------- | ---------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1801
|
+
| `compilePacks` | `compilePacks({ config, sourcePacks, stageDest, packName, session, reportPreparation })` | — | Generates each pack's per-entry JSON from `assets/content/` into `build/packs-json/<name>/`, then builds the LevelDB output from it. |
|
|
1802
|
+
| `cleanPacks` | `async cleanPacks({ config, packDest, packName, entryName })` | — | Cleans and formats source JSON files, removing unnecessary permissions and flags and adding the proper spacing. |
|
|
1803
|
+
| `unpackPacks` | `async unpackPacks({ packs, config, stageDest, packDest, packName })` | — | Extracts compiled LevelDB packs back to per-entry JSON, rebuilding the folder hierarchy as directories. |
|
|
1561
1804
|
|
|
1562
1805
|
### `engine.regionEvents`
|
|
1563
1806
|
|
|
@@ -2104,6 +2347,15 @@ The Changesets changelog generator, loaded with `require` — a CommonJS module
|
|
|
2104
2347
|
| `getReleaseLine` | `getReleaseLine(changeset, type, changelogOpts)` | `string` — the summary, verbatim, separated from its neighbours by a blank line | writing one changeset's release line with no commit-hash prefix and no bullet |
|
|
2105
2348
|
| `getDependencyReleaseLine` | `getDependencyReleaseLine(changesets, dependenciesUpdated, changelogOpts)` | `string` — always `""` | satisfying the `ChangelogFunctions` interface; these packages narrate no internal dependency bumps |
|
|
2106
2349
|
|
|
2350
|
+
`engine/changelog-group.mjs` exports `groupChangelogText(text, { labels })`,
|
|
2351
|
+
returning `{ text, findings }`. It groups the newest release's summaries
|
|
2352
|
+
within each bump tier, retaining prose, bullets, wrapped continuations,
|
|
2353
|
+
nested item content and literal code. Merged labels' opening paragraphs
|
|
2354
|
+
combine in source order before their items. Exact duplicate items print
|
|
2355
|
+
once; labels follow the configured order, with unlabelled lead items first.
|
|
2356
|
+
Earlier release sections stay byte-identical, and grouping the result
|
|
2357
|
+
again leaves its text unchanged.
|
|
2358
|
+
|
|
2107
2359
|
## `./package.json`
|
|
2108
2360
|
|
|
2109
2361
|
Not a JavaScript module — this subpath entry exists so tooling (bundlers, `import.meta.resolve`, a script reading the installed version) can resolve the package's own `package.json` through Node's package-exports resolution instead of reaching outside the declared export map.
|
|
@@ -2117,7 +2369,7 @@ The engine wildcard subpath also exposes the body parsers below. Their figure ex
|
|
|
2117
2369
|
| `engine/content-figures.mjs` | `FIGURE_NAMES`, `FIGURE_CLASSES`, `scanFigures`, `numberFigures`, `renderFigureBlocks` | Scan leading captions and their next supported blocks; `numbered` distinguishes `:` and `:@`. `type` may override inference; `example` is supported. `FIGURE_CLASSES` retains built-in styled classes, not a closed author vocabulary. |
|
|
2118
2370
|
| `engine/content-blocks.mjs` | `BLOCK_NAMES`, `BLOCK_CONTAINERS`, `scanBlocks`, `renderBlocks`, `renderWithheldSections` | Read div and secret fences; generic div records have `name: "div"` and no generated title. Scanning includes poetry errors. |
|
|
2119
2371
|
| `engine/content-poetry.mjs` | `verseLines`, `poetryStanzas`, `inlineVerse`, `poetryMarkdown`, `scanPoetry`, `renderPoetry` | Read `poetry` code fences, validate authored metadata and tabs, and preserve relative indent levels and stanzas. |
|
|
2120
|
-
| `engine/content-spans.mjs` | `spanMarkdownPlugin`, `scanSpans`, `renderSpans` | Parse bracket spans after recognized links. The scanner returns spans and located errors;
|
|
2372
|
+
| `engine/content-spans.mjs` | `spanMarkdownPlugin`, `scanSpans`, `renderSpans` | Parse bracket spans after recognized links. The scanner returns spans, the exact `.name` inventory and located errors, retaining visible text and attribute positions; rendering preserves inline Markdown and permitted attributes. |
|
|
2121
2373
|
|
|
2122
2374
|
`scanFigures` retains `line` (1-based caption line), `bodyStart`/`bodyEnd` (0-based, exclusive-end target range), and `close` (last consumed target line), plus caption attributes, kind, label and number. Unnumbered captions have an empty label and consume no number. `collectAnchors` discovers heading, caption, div, poem and span identifiers; `markupAnchorFindings(body)` reports collisions involving non-page identifiers; Foundry maps non-page anchors to the actual containing page UUID. An unnumbered `ref` requires `form="title"` or `form="full"`.
|
|
2123
2375
|
|
|
@@ -2127,7 +2379,7 @@ The engine wildcard subpath also exposes the body parsers below. Their figure ex
|
|
|
2127
2379
|
| ---------------- | ----------------------------------------------------------------------------------- |
|
|
2128
2380
|
| `markupFindings` | Validate complete Markdown source and return diagnostics for the supplied filename. |
|
|
2129
2381
|
|
|
2130
|
-
`markupFindings(source, file)` masks YAML frontmatter without moving source positions and returns block and alert scanner errors as `{file, line, column, severity, message}` diagnostics. Content lint, Markdown checks and formatting preflight share this validation; malformed files are not rewritten by formatting or Markdown fixes.
|
|
2382
|
+
`markupFindings(source, file, syntax?)` masks YAML frontmatter without moving source positions and returns block and alert scanner errors as `{file, line, column, severity, message}` diagnostics. Content lint, Markdown checks and formatting preflight share this validation; malformed files are not rewritten by formatting or Markdown fixes.
|
|
2131
2383
|
|
|
2132
2384
|
`engine/content-alerts.mjs` exposes `ALERT_TYPES`, `scanAlerts(source)` and `renderAlerts(source, target)` and `alertMarkdownPlugin(md)`. The scanner returns `{blocks, errors}`; alert records carry `type`, `id`, `classes`, `attributes`, `title`, `body` and inclusive zero-based `start`/`end` source lines. The renderer produces attributed `aside.alert` wrappers while leaving alert body Markdown in the document's scope. Alert validation and anchor discovery run in site, Foundry and book pipelines.
|
|
2133
2385
|
|
|
@@ -2140,6 +2392,22 @@ that map as `parsed` for its document passes. `unclaimedNoteFindings` accepts it
|
|
|
2140
2392
|
alongside `records`. `locateFrontmatterKey` and `assertNoDeclaredPackage` accept
|
|
2141
2393
|
`raw` in their options to locate findings without opening the note again.
|
|
2142
2394
|
|
|
2395
|
+
`buildCompileCorpus`, `generatePacksJson` and `compilePacks` accept an optional
|
|
2396
|
+
`session` bound to their resolved configuration, roots, scope and router.
|
|
2397
|
+
`prepareContentIndex` also accepts it. Without a session, the existing entry
|
|
2398
|
+
points derive their own inputs. Generation and pack compilation accept
|
|
2399
|
+
`reportPreparation` (default true); a coordinating caller may set it false
|
|
2400
|
+
only after reporting the shared source findings itself.
|
|
2401
|
+
|
|
2402
|
+
`buildLinkIndex` and `buildContentLinkIndex` accept an optional `foreign` view
|
|
2403
|
+
from the same session; their diagnostic and routed resolver contracts remain
|
|
2404
|
+
distinct. `collectAnchors`, `markupAnchorFindings`, `markupFindings`, journal
|
|
2405
|
+
`splitPages`, Foundry `anchorsOf` and `buildJournalEntry` accept the optional
|
|
2406
|
+
`syntax` function described above. `buildSiteIndex` and `prepareTreeSqlTables`
|
|
2407
|
+
accept it in options, and `insertLexicalSections` accepts it in context.
|
|
2408
|
+
Prepared per-note SQL results carry it to `expandContentTables`. No scan result
|
|
2409
|
+
is reused for a different source projection.
|
|
2410
|
+
|
|
2143
2411
|
`prepareSqlTables` accepts sources with an optional `authoredSqlBlocks` count,
|
|
2144
2412
|
set by `joinGeneratedSections`. Subsequent fences are generated event queries
|
|
2145
2413
|
whose stub-inclusive results are identical; only authored fences receive a
|
|
@@ -2156,7 +2424,7 @@ unknown addresses. Only public records contribute rendered sources and links.
|
|
|
2156
2424
|
|
|
2157
2425
|
`engine/sql-tables.mjs` exports `prepareLinkSqlTables(contentBase, options)`.
|
|
2158
2426
|
Its options are `config`, `skipDirectories`, complete `records`, the shared
|
|
2159
|
-
`parsed` map and `
|
|
2427
|
+
`parsed` map, `foreignIndex` and optional `prepareAudience(audience)` callback. The callback supplies the bound session's existing `public` or `all` preparation. It returns prepared tables with `pageLists`
|
|
2160
2428
|
and `inline` maps, or `undefined` when no source needs a directive or automatic
|
|
2161
2429
|
lexical section. Public
|
|
2162
2430
|
sources use public rows; GM sources use all rows. Query results remain local
|