@heroiclands/package-build 23.1.0 → 23.2.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 +71 -0
- package/bin/content-commands.mjs +68 -149
- package/bin/package-build.mjs +56 -10
- package/ci/check-banners.mjs +42 -6
- package/ci/confirm-npm-version.mjs +135 -0
- package/ci/content-format-reference.mjs +14 -5
- package/config.mjs +1 -0
- package/container.mjs +185 -4
- package/content-config.mjs +333 -210
- package/deploy.mjs +116 -10
- package/docs/api.md +238 -246
- package/docs/authoring/assets.md +11 -5
- package/docs/authoring/frontmatter.md +1 -1
- package/docs/authoring/links-and-markup.md +87 -0
- package/docs/commands.md +138 -99
- package/docs/configuration.md +277 -125
- package/docs/content-format.md +2 -0
- package/docs/diagnostics.md +48 -13
- package/docs/guides/book.md +341 -21
- package/docs/guides/e2e.md +13 -2
- package/docs/guides/icons.md +14 -4
- package/docs/guides/module-project.md +18 -8
- package/docs/guides/release-and-deploy.md +54 -6
- package/docs/guides/site.md +5 -2
- package/docs/project-setup.md +30 -10
- package/docs/reference/format-details.md +373 -170
- package/docs/reference/note-types.md +128 -109
- package/docs/reference/theme-pages.md +31 -6
- package/e2e.mjs +140 -28
- package/engine/actor-compiler.mjs +22 -31
- package/engine/address-charset.mjs +4 -17
- package/engine/address-fields.mjs +1 -1
- package/engine/address-render.mjs +12 -1
- package/engine/address-values.mjs +6 -0
- package/engine/address.mjs +46 -33
- package/engine/art-fields.mjs +30 -5
- package/engine/art-slots.mjs +10 -1
- package/engine/asset-bindings.mjs +12 -1
- package/engine/base-compiler.mjs +34 -65
- package/engine/being-age.mjs +2 -7
- package/engine/being-measurements.mjs +12 -1
- package/engine/calendar-artifacts.mjs +6 -0
- package/engine/calendar-choice.mjs +12 -1
- package/engine/calendar-format.mjs +12 -1
- package/engine/calendar-human.mjs +12 -1
- package/engine/compile-corpus.mjs +3 -1
- package/engine/content-address.mjs +9 -12
- package/engine/content-alerts.mjs +13 -1
- package/engine/content-blocks.mjs +14 -3
- package/engine/content-embeds.mjs +11 -3
- package/engine/content-figures.mjs +9 -0
- package/engine/content-footnotes.mjs +12 -1
- package/engine/content-format-check.mjs +11 -262
- package/engine/content-format.yaml +5 -2
- package/engine/content-images.mjs +3 -0
- package/engine/content-index.mjs +443 -20
- package/engine/content-links.mjs +29 -35
- package/engine/content-lint.mjs +2 -3
- package/engine/content-poetry.mjs +12 -1
- package/engine/content-slug.mjs +2 -14
- package/engine/content-spans.mjs +13 -1
- package/engine/content-tables.mjs +12 -1
- package/engine/culture-choice.mjs +210 -13
- package/engine/data-keys.mjs +19 -16
- package/engine/date-conversion.mjs +12 -1
- package/engine/declaration-check.mjs +9 -0
- package/engine/derived-fields.mjs +6 -7
- package/engine/diagnostics.mjs +34 -4
- package/engine/docs-checks.mjs +9 -0
- package/engine/document-subtypes.mjs +47 -34
- package/engine/event-views.mjs +139 -14
- package/engine/exported-scene.mjs +92 -28
- package/engine/extension-attributes.mjs +12 -1
- package/engine/field-spec.mjs +11 -102
- package/engine/folder-notes.mjs +0 -64
- package/engine/foreign-catalog.mjs +2 -1
- package/engine/format-generated.mjs +9 -0
- package/engine/foundry-entries.mjs +10 -28
- package/engine/frontmatter-lint.mjs +83 -392
- package/engine/frontmatter.mjs +20 -70
- package/engine/generate.mjs +10 -15
- package/engine/heading-attributes.mjs +12 -1
- package/engine/helpers.mjs +41 -102
- package/engine/holdings.mjs +1 -1
- package/engine/homepage.mjs +3 -10
- package/engine/ids.mjs +1 -167
- package/engine/index-records.mjs +6 -4
- package/engine/index.mjs +0 -3
- package/engine/infobox-render.mjs +15 -3
- package/engine/infobox.mjs +13 -14
- package/engine/item-compiler.mjs +4 -10
- package/engine/item-docs.mjs +3 -5
- package/engine/item-registry.mjs +2 -10
- package/engine/journals.mjs +1 -5
- package/engine/literature-notes.mjs +4 -12
- package/engine/macros.mjs +1 -2
- package/engine/map-graphviz.mjs +12 -1
- package/engine/markdown-expressions.mjs +12 -1
- package/engine/markdownlint-run.mjs +567 -0
- package/engine/metadata-index.mjs +42 -12
- package/engine/note-addresses.mjs +143 -35
- package/engine/note-claims.mjs +14 -28
- package/engine/note-dates.mjs +3 -3
- package/engine/note-frontmatter.mjs +6 -0
- package/engine/note-ids.mjs +8 -14
- package/engine/note-package.mjs +8 -25
- package/engine/note-state.mjs +1 -3
- package/engine/note-vocabulary.mjs +148 -84
- package/engine/number-words.mjs +12 -1
- package/engine/pack-config.mjs +15 -25
- package/engine/pack-router.mjs +10 -16
- package/engine/pathnames.mjs +8 -22
- package/engine/pdf-build.mjs +773 -121
- package/engine/pdf-coverage.mjs +188 -0
- package/engine/pdf-index.mjs +54 -7
- package/engine/pdf-pages.mjs +247 -0
- package/engine/pdf-render.mjs +114 -4
- package/engine/pdf-toc.mjs +29 -32
- package/engine/project-init.mjs +46 -6
- package/engine/prose-config.mjs +1 -1
- package/engine/prose-lint.mjs +52 -88
- package/engine/readability-lint.mjs +9 -0
- package/engine/reckoning-markers.mjs +12 -1
- package/engine/reference-targets.mjs +7 -0
- package/engine/runtime-only-fields.mjs +5 -8
- package/engine/scene-levels.mjs +2 -2
- package/engine/scenes.mjs +1 -1
- package/engine/shortcode-references.mjs +7 -0
- package/engine/site-build.mjs +30 -16
- package/engine/site-index.mjs +10 -16
- package/engine/site-preview.mjs +6 -0
- package/engine/site-root.mjs +8 -1
- package/engine/social-tie-terms.mjs +12 -1
- package/engine/social-ties.mjs +3 -0
- package/engine/sql-tables.mjs +56 -20
- package/engine/standing-terms.mjs +11 -1
- package/engine/standings.mjs +11 -27
- package/engine/system-block.mjs +39 -141
- package/engine/system-vocabulary.mjs +6 -0
- package/engine/walk-files.mjs +69 -0
- package/engine/web-wikilinks.mjs +23 -3
- package/engine/wikilink-syntax.mjs +32 -21
- package/engine/wikilinks.mjs +27 -16
- package/engine/yaml-lint.mjs +7 -4
- package/githooks/attribution.mjs +8 -0
- package/githooks/commit-message.mjs +9 -0
- package/hm3/actors.mjs +9 -48
- package/hm3/default-item-art.mjs +9 -9
- package/hm3/item-fields.mjs +2 -9
- package/hm3/template-priority.mjs +6 -7
- package/hugo-theme/data/banner-kinds.yaml +78 -0
- package/hugo-theme/data/banners.yaml +2 -3
- package/hugo-theme/layouts/404.html +3 -3
- package/hugo-theme/layouts/partials/banner-url.html +31 -7
- package/hugo-theme/layouts/partials/hero-banner.html +13 -14
- package/hugo-theme/layouts/partials/related.html +1 -1
- package/hugo-theme/layouts/partials/warn-missing-banner.html +1 -1
- package/hugo-theme/static/css/style.css +1 -1
- package/manifest.mjs +11 -4
- package/markdownlint-config.mjs +1 -1
- package/package.json +6 -3
- package/release.mjs +83 -18
- package/sohl/actors.mjs +16 -27
- package/sohl/default-item-art.mjs +3 -3
- package/sohl/document-subtypes.mjs +1 -16
- package/sohl/infobox.mjs +2 -3
- package/sohl/item-builders.mjs +5 -8
- package/sohl/item-fields.mjs +5 -35
- package/sohl/items.mjs +0 -4
- package/sohl/kb-passes.mjs +3 -3
- package/types/container.d.mts +116 -5
- package/types/content-config.d.mts +83 -35
- package/types/deploy.d.mts +42 -6
- package/types/e2e.d.mts +35 -3
- package/types/engine/address-charset.d.mts +4 -17
- package/types/engine/address.d.mts +17 -8
- package/types/engine/art-fields.d.mts +7 -4
- package/types/engine/art-slots.d.mts +6 -0
- package/types/engine/base-compiler.d.mts +15 -17
- package/types/engine/content-address.d.mts +9 -12
- package/types/engine/content-embeds.d.mts +4 -2
- package/types/engine/content-format-check.d.mts +0 -64
- package/types/engine/content-index.d.mts +82 -3
- package/types/engine/content-links.d.mts +2 -4
- package/types/engine/culture-choice.d.mts +51 -8
- package/types/engine/data-keys.d.mts +2 -2
- package/types/engine/derived-fields.d.mts +1 -2
- package/types/engine/diagnostics.d.mts +27 -4
- package/types/engine/document-subtypes.d.mts +12 -31
- package/types/engine/event-views.d.mts +14 -2
- package/types/engine/exported-scene.d.mts +3 -2
- package/types/engine/field-spec.d.mts +13 -122
- package/types/engine/folder-notes.d.mts +0 -39
- package/types/engine/foreign-catalog.d.mts +2 -1
- package/types/engine/foundry-entries.d.mts +4 -5
- package/types/engine/frontmatter-lint.d.mts +2 -2
- package/types/engine/frontmatter.d.mts +19 -45
- package/types/engine/generate.d.mts +1 -1
- package/types/engine/helpers.d.mts +25 -42
- package/types/engine/homepage.d.mts +3 -10
- package/types/engine/ids.d.mts +0 -114
- package/types/engine/index-records.d.mts +6 -4
- package/types/engine/index.d.mts +0 -1
- package/types/engine/infobox-render.d.mts +7 -1
- package/types/engine/infobox.d.mts +3 -2
- package/types/engine/item-docs.d.mts +1 -1
- package/types/engine/item-registry.d.mts +2 -4
- package/types/engine/literature-notes.d.mts +1 -1
- package/types/engine/markdownlint-run.d.mts +40 -0
- package/types/engine/metadata-index.d.mts +9 -1
- package/types/engine/note-addresses.d.mts +27 -2
- package/types/engine/note-claims.d.mts +3 -5
- package/types/engine/note-ids.d.mts +2 -4
- package/types/engine/note-package.d.mts +1 -1
- package/types/engine/note-state.d.mts +1 -3
- package/types/engine/note-vocabulary.d.mts +28 -21
- package/types/engine/pack-config.d.mts +2 -6
- package/types/engine/pack-router.d.mts +4 -4
- package/types/engine/pathnames.d.mts +3 -3
- package/types/engine/pdf-build.d.mts +98 -12
- package/types/engine/pdf-coverage.d.mts +60 -0
- package/types/engine/pdf-index.d.mts +34 -5
- package/types/engine/pdf-pages.d.mts +143 -0
- package/types/engine/pdf-render.d.mts +45 -1
- package/types/engine/pdf-toc.d.mts +12 -14
- package/types/engine/prose-config.d.mts +1 -1
- package/types/engine/prose-lint.d.mts +11 -10
- package/types/engine/runtime-only-fields.d.mts +2 -2
- package/types/engine/site-build.d.mts +9 -5
- package/types/engine/site-index.d.mts +4 -5
- package/types/engine/site-root.d.mts +1 -1
- package/types/engine/sql-tables.d.mts +31 -2
- package/types/engine/standing-terms.d.mts +2 -1
- package/types/engine/standings.d.mts +7 -9
- package/types/engine/system-block.d.mts +10 -44
- package/types/engine/walk-files.d.mts +15 -0
- package/types/engine/wikilink-syntax.d.mts +18 -19
- package/types/engine/yaml-lint.d.mts +5 -4
- package/types/hm3/actors.d.mts +1 -2
- package/types/hm3/item-fields.d.mts +2 -4
- package/types/hm3/template-priority.d.mts +6 -7
- package/types/manifest.d.mts +3 -2
- package/types/release.d.mts +12 -7
- package/types/sohl/actors.d.mts +2 -1
- package/types/sohl/document-subtypes.d.mts +1 -2
- package/types/sohl/item-fields.d.mts +3 -7
- package/engine/retired-fields.mjs +0 -631
- package/types/engine/retired-fields.d.mts +0 -354
|
@@ -298,14 +298,14 @@ export class BasePackCompiler {
|
|
|
298
298
|
* A refusal only this pass can make, because its subject is the note's
|
|
299
299
|
* **type**.
|
|
300
300
|
*
|
|
301
|
-
* The `
|
|
302
|
-
* construction: it runs before `selects`, so that a note declaring
|
|
303
|
-
*
|
|
301
|
+
* The `assertNoDeclaredPackage` check above it in the walk is type-agnostic
|
|
302
|
+
* by construction: it runs before `selects`, so that a note declaring
|
|
303
|
+
* `package:` is answered whichever pass would have claimed it. A rule
|
|
304
304
|
* about what a *`trauma`* may write cannot live there — it needs the type's
|
|
305
305
|
* field declaration, which only the pass that compiles the type can reach.
|
|
306
306
|
*
|
|
307
307
|
* So it is a hook, called once the note is known to be this pass's, and its
|
|
308
|
-
* throw is counted and located exactly as
|
|
308
|
+
* throw is counted and located exactly as that check's is: the note is
|
|
309
309
|
* declined rather than skipped, and the build fails naming the line.
|
|
310
310
|
*
|
|
311
311
|
* The default refuses nothing, which is the honest position for a pass
|
|
@@ -404,12 +404,10 @@ export class BasePackCompiler {
|
|
|
404
404
|
/**
|
|
405
405
|
* The Foundry path one authored art address names, or `null`.
|
|
406
406
|
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
* than restated, which is also what puts an art address and a body image
|
|
412
|
-
* through one ownership rule.
|
|
407
|
+
* `null` and an absent key mean *no art named*, so the caller's own default
|
|
408
|
+
* applies with nullish coalescing. The address goes through
|
|
409
|
+
* {@link module:engine/helpers.resolveImg}, which puts an art address and a
|
|
410
|
+
* body image through one ownership rule.
|
|
413
411
|
*
|
|
414
412
|
* An address nothing answers is reported against the note and treated as
|
|
415
413
|
* unnamed, so the document takes its default rather than shipping a path
|
|
@@ -421,8 +419,8 @@ export class BasePackCompiler {
|
|
|
421
419
|
* @param {string} key - The key it was authored at, for the message.
|
|
422
420
|
* @param {string} type - The asset type a bare value takes.
|
|
423
421
|
* @param {Iterable<string>} [accepts] - The types this slot accepts.
|
|
424
|
-
* @returns {string|null} The Foundry-relative path, `
|
|
425
|
-
*
|
|
422
|
+
* @returns {string|null} The Foundry-relative path, or `null` where the
|
|
423
|
+
* note names none.
|
|
426
424
|
*/
|
|
427
425
|
artPathOf(value: unknown, key: string, type: string, accepts?: Iterable<string>): string | null;
|
|
428
426
|
/**
|
|
@@ -636,8 +634,8 @@ export class BasePackCompiler {
|
|
|
636
634
|
* The tallies one pass accumulates while walking the tree.
|
|
637
635
|
*
|
|
638
636
|
* `declined` and `skippedOther` are deliberately separate numbers. A declined
|
|
639
|
-
* note is one this build **refused** — it declares
|
|
640
|
-
*
|
|
637
|
+
* note is one this build **refused** — it declares `package:` — and it is an
|
|
638
|
+
* error; a skipped one legitimately belongs to another pass, and
|
|
641
639
|
* there are thousands of those. Folding the first into the second is what let a
|
|
642
640
|
* whole tree be filtered out in silence.
|
|
643
641
|
*/
|
|
@@ -655,9 +653,9 @@ export type PassStats = {
|
|
|
655
653
|
*/
|
|
656
654
|
skippedOther: number;
|
|
657
655
|
/**
|
|
658
|
-
* - Notes this pack **refused** — one declaring
|
|
659
|
-
*
|
|
660
|
-
*
|
|
656
|
+
* - Notes this pack **refused** — one declaring
|
|
657
|
+
* `package:`, or one routed to a system pack whose system it says nothing
|
|
658
|
+
* about. Counted as errors, never as skips.
|
|
661
659
|
*/
|
|
662
660
|
declined: number;
|
|
663
661
|
};
|
|
@@ -49,12 +49,10 @@ export function addressSlug(fm: object): string;
|
|
|
49
49
|
* docs, neither of which contains a hyphen or names a type.
|
|
50
50
|
*
|
|
51
51
|
* **It is a pure function of the frontmatter**, and takes no options. Nothing
|
|
52
|
-
* about the file the note was read from reaches it
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* discarded; with that key retired, `prefix` was the only thing left in the
|
|
57
|
-
* scheme and the paragraph above is the reason it never applied.
|
|
52
|
+
* about the file the note was read from reaches it, so every note is addressed
|
|
53
|
+
* alike and there is one rule and no branch. It takes no address scheme:
|
|
54
|
+
* `prefix` is the whole scheme and the paragraph above is the reason it never
|
|
55
|
+
* applies here.
|
|
58
56
|
*
|
|
59
57
|
* @param {object} fm - Parsed frontmatter.
|
|
60
58
|
* @returns {string} The package-relative address, with a trailing slash and no
|
|
@@ -124,13 +122,12 @@ export function resolvePackageUrl(rel: string, base: string): string;
|
|
|
124
122
|
* The Foundry `_id` of the document a note compiles into, derived from its
|
|
125
123
|
* canonical address.
|
|
126
124
|
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
125
|
+
* An authored id would be an opaque string that says nothing its address
|
|
126
|
+
* does not and that no check guarantees. The address is the identity that
|
|
127
|
+
* *is* guaranteed: `content-lint` refuses a
|
|
130
128
|
* duplicate `(type, shortcode)` across every pack of a document type, which is
|
|
131
129
|
* exactly the scope a primary document's id must be unique within. So the
|
|
132
|
-
* derived id inherits
|
|
133
|
-
* none.
|
|
130
|
+
* derived id inherits that guard.
|
|
134
131
|
*
|
|
135
132
|
* **The coupling this creates, stated plainly.** The address carries the
|
|
136
133
|
* shortcode, so renaming a shortcode moves the document's id — where an
|
|
@@ -139,7 +136,7 @@ export function resolvePackageUrl(rel: string, base: string): string;
|
|
|
139
136
|
* note, so it is a breaking change either way; and a note that must keep its
|
|
140
137
|
* identity across a rename pins an `id`, which is what the pin is for. One
|
|
141
138
|
* thing genuinely degrades — `engine/address-diff.mjs` tells a rename from a
|
|
142
|
-
* withdrawal by matching document ids, and
|
|
139
|
+
* withdrawal by matching document ids, and cannot do so for a note that
|
|
143
140
|
* authors none. Its module note records that.
|
|
144
141
|
*
|
|
145
142
|
* @param {string} pkg - The owning **content** package.
|
|
@@ -35,8 +35,8 @@ export function embedsIn(body: string, context: any): ParsedEmbed[];
|
|
|
35
35
|
* @param {object} index - From {@link module:engine/wikilinks.buildWikilinkIndex},
|
|
36
36
|
* or the equivalent the site and the book build.
|
|
37
37
|
* @param {ParsedEmbed} embed - The embed.
|
|
38
|
-
* @returns {{pathname: string}|{reason: string, target: string, type?: string
|
|
39
|
-
* The authored pathname the picture is at, or the finding.
|
|
38
|
+
* @returns {{pathname: string}|{reason: string, target: string, type?: string,
|
|
39
|
+
* shortcode?: string, declared?: string}} The authored pathname the picture is at, or the finding.
|
|
40
40
|
*/
|
|
41
41
|
export function resolveEmbed(index: object, embed: ParsedEmbed): {
|
|
42
42
|
pathname: string;
|
|
@@ -44,6 +44,8 @@ export function resolveEmbed(index: object, embed: ParsedEmbed): {
|
|
|
44
44
|
reason: string;
|
|
45
45
|
target: string;
|
|
46
46
|
type?: string;
|
|
47
|
+
shortcode?: string;
|
|
48
|
+
declared?: string;
|
|
47
49
|
};
|
|
48
50
|
/**
|
|
49
51
|
* The role an address's asset declares, read through the same resolution an
|
|
@@ -56,55 +56,6 @@ export function checkSchemaTargets({ format, schemas }: {
|
|
|
56
56
|
checked: number;
|
|
57
57
|
unchecked: Record<string, number>;
|
|
58
58
|
};
|
|
59
|
-
/**
|
|
60
|
-
* The systems the specification names.
|
|
61
|
-
*
|
|
62
|
-
* Taken from the columns of its mapping tables rather than from a list written
|
|
63
|
-
* here, so a system added to the document is measured with no code change.
|
|
64
|
-
* Cached per parsed document, since the answer is the same for every note.
|
|
65
|
-
*
|
|
66
|
-
* @param {import("./content-format.mjs").ContentFormat} format - The parsed
|
|
67
|
-
* specification.
|
|
68
|
-
* @returns {ReadonlySet<string>} The system ids.
|
|
69
|
-
*/
|
|
70
|
-
export function systemsNamed(format: import("./content-format.mjs").ContentFormat): ReadonlySet<string>;
|
|
71
|
-
/**
|
|
72
|
-
* Measure one note against the vocabulary the format declares for its type.
|
|
73
|
-
*
|
|
74
|
-
* @param {object} note - `{file, raw, fm}` — as the link index hands one over.
|
|
75
|
-
* @param {import("./content-format.mjs").ContentFormat} format - The parsed
|
|
76
|
-
* specification.
|
|
77
|
-
* @param {object} [opts]
|
|
78
|
-
* @param {"warning"|"error"} [opts.severity="warning"] - What the findings are.
|
|
79
|
-
* A report by default; `--strict` raises it.
|
|
80
|
-
* @returns {object[]} Findings, each carrying the `class` it belongs to
|
|
81
|
-
* alongside the fields `emitDiagnostic` reads.
|
|
82
|
-
*/
|
|
83
|
-
export function measureNote(note: object, format: import("./content-format.mjs").ContentFormat, { severity }?: {
|
|
84
|
-
severity?: "error" | "warning" | undefined;
|
|
85
|
-
}): object[];
|
|
86
|
-
/**
|
|
87
|
-
* Measure a corpus, and count what it finds by class.
|
|
88
|
-
*
|
|
89
|
-
* The counts are the point as much as the findings: a class is promoted to
|
|
90
|
-
* fatal when its count reaches zero, so a run that prints them is the
|
|
91
|
-
* migration's progress bar.
|
|
92
|
-
*
|
|
93
|
-
* @param {Iterable<object>} notes - `{file, raw, fm}` for each authored note.
|
|
94
|
-
* @param {import("./content-format.mjs").ContentFormat} format - The parsed
|
|
95
|
-
* specification.
|
|
96
|
-
* @param {object} [opts]
|
|
97
|
-
* @param {boolean} [opts.strict=false] - Report the findings as errors rather
|
|
98
|
-
* than warnings. Turned on one slice at a time.
|
|
99
|
-
* @returns {{findings: object[], notes: number, byClass: Record<string, number>}}
|
|
100
|
-
*/
|
|
101
|
-
export function measureCorpus(notes: Iterable<object>, format: import("./content-format.mjs").ContentFormat, { strict }?: {
|
|
102
|
-
strict?: boolean | undefined;
|
|
103
|
-
}): {
|
|
104
|
-
findings: object[];
|
|
105
|
-
notes: number;
|
|
106
|
-
byClass: Record<string, number>;
|
|
107
|
-
};
|
|
108
59
|
/**
|
|
109
60
|
* What an author is told when the specification and the declaration disagree.
|
|
110
61
|
*
|
|
@@ -177,21 +128,6 @@ export function checkDeclaredFields({ format, itemFields, system, severity }: {
|
|
|
177
128
|
};
|
|
178
129
|
fields: number;
|
|
179
130
|
};
|
|
180
|
-
/**
|
|
181
|
-
* Top-level keys the format names as the note's own, whatever its type.
|
|
182
|
-
*
|
|
183
|
-
* The top-level vocabulary itself, read rather than restated: this set exists
|
|
184
|
-
* to keep a note's own identity fields from being mistaken for a misplaced
|
|
185
|
-
* `data` property where the two share a name, and the keys that are a note's
|
|
186
|
-
* own are exactly the ones the region declares. `type` and `subType` are the
|
|
187
|
-
* pair that matters — several mapping tables name `subType` as a shared source,
|
|
188
|
-
* and it is authored at top level by design. A key the region does *not*
|
|
189
|
-
* declare, such as `id` beside `data.id`, is reported as the misplaced `data`
|
|
190
|
-
* property it is.
|
|
191
|
-
*
|
|
192
|
-
* @type {ReadonlySet<string>}
|
|
193
|
-
*/
|
|
194
|
-
export const NOTE_LEVEL_KEYS: ReadonlySet<string>;
|
|
195
131
|
/**
|
|
196
132
|
* Where one declared field sends one authored value.
|
|
197
133
|
*/
|
|
@@ -143,6 +143,62 @@ export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absP
|
|
|
143
143
|
dateContext: any;
|
|
144
144
|
resolveRole: any;
|
|
145
145
|
}): object[];
|
|
146
|
+
/**
|
|
147
|
+
* Write each note's resolved culture into its record, as `data.culture`.
|
|
148
|
+
*
|
|
149
|
+
* A note's culture is:
|
|
150
|
+
*
|
|
151
|
+
* - its own `data.culture`, when it states one;
|
|
152
|
+
* - for a `lore` note of `subType: culture`, its own canonical Address;
|
|
153
|
+
* - for a `place` or an `affiliation`, else the resolved cultures of its
|
|
154
|
+
* `data.parents`;
|
|
155
|
+
* - for a `polity` affiliation, else the resolved cultures of its places: its
|
|
156
|
+
* `data.seat` pooled with every place whose `data.government` names it, as
|
|
157
|
+
* one set;
|
|
158
|
+
* - else nothing. A `being`, a `doc` and any other `lore` note have their own
|
|
159
|
+
* value only; every other type has none.
|
|
160
|
+
*
|
|
161
|
+
* A parent's culture is its own resolved culture, found recursively; a parent
|
|
162
|
+
* resolving to nothing is ignored, as is one in another package that its index
|
|
163
|
+
* gives none. Sources that agree give that culture. Sources that differ, on a
|
|
164
|
+
* note with no value of its own, give it none and one error finding, at
|
|
165
|
+
* `data.parents`, or for a polity's places at `data.seat`, else at its `data:`
|
|
166
|
+
* line. A note whose parent raised that error treats the parent as resolving to
|
|
167
|
+
* nothing, so a disagreement is reported once, where it is. A cycle resolves to
|
|
168
|
+
* nothing.
|
|
169
|
+
*
|
|
170
|
+
* A parent in another package is read through `foreignRecord`, whose published
|
|
171
|
+
* entry already carries that parent's resolved culture, so a foreign chain is
|
|
172
|
+
* never walked.
|
|
173
|
+
*
|
|
174
|
+
* The record's `data` is replaced by a copy carrying the culture, never
|
|
175
|
+
* assigned into, because the note's parsed frontmatter shares that object. The
|
|
176
|
+
* record then carries the resolved culture to every pass that reads it — lint,
|
|
177
|
+
* compile and site alike. A note resolving to nothing gains no `culture` key.
|
|
178
|
+
*
|
|
179
|
+
* @param {Array<Record<string, any>>} records - Index records, every Address a
|
|
180
|
+
* tuple. Records that are not notes are passed over.
|
|
181
|
+
* @param {object} options - Options.
|
|
182
|
+
* @param {string} options.contentPackage - The package the records belong to.
|
|
183
|
+
* @param {string} [options.contentBase] - The content tree, for opening a
|
|
184
|
+
* conflicting note to locate the finding. Without it a finding names the
|
|
185
|
+
* note's path within the tree and no position.
|
|
186
|
+
* @param {(key: string) => ({culture?: unknown}|undefined)} [options.foreignRecord] -
|
|
187
|
+
* Another package's entry for a canonical address. Asked only for an
|
|
188
|
+
* immediate parent whose package is not this one.
|
|
189
|
+
* @param {object[]} [options.problems] - Receives each conflict as a finding.
|
|
190
|
+
* Omitted, every conflict is collected and one Error lists them all.
|
|
191
|
+
* @returns {Array<Record<string, any>>} The same records.
|
|
192
|
+
* @throws {Error} When `problems` is omitted and any note's sources disagree.
|
|
193
|
+
*/
|
|
194
|
+
export function resolveCultures(records: Array<Record<string, any>>, { contentPackage, contentBase, foreignRecord, problems }: {
|
|
195
|
+
contentPackage: string;
|
|
196
|
+
contentBase?: string | undefined;
|
|
197
|
+
foreignRecord?: ((key: string) => ({
|
|
198
|
+
culture?: unknown;
|
|
199
|
+
} | undefined)) | undefined;
|
|
200
|
+
problems?: object[] | undefined;
|
|
201
|
+
}): Array<Record<string, any>>;
|
|
146
202
|
/**
|
|
147
203
|
* Read a content tree into index records, in the order they will be written.
|
|
148
204
|
*
|
|
@@ -171,17 +227,32 @@ export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absP
|
|
|
171
227
|
* @param {object[]} [options.problems] - Supplied by a **reader**: a note that
|
|
172
228
|
* cannot be recorded is pushed here as a diagnostic and skipped. Omitted, the
|
|
173
229
|
* note throws — the contract the emitter needs, since an index missing a note
|
|
174
|
-
* asserts that it does not exist.
|
|
230
|
+
* asserts that it does not exist. The same holds for a culture conflict: a
|
|
231
|
+
* reader receives each as a finding, and the emitter throws once, listing
|
|
232
|
+
* every one.
|
|
233
|
+
* @param {(key: string) => ({culture?: unknown}|undefined)} [options.foreignRecord] -
|
|
234
|
+
* Another package's entry for a canonical address, read for a parent that
|
|
235
|
+
* package publishes; see {@link resolveCultures}.
|
|
236
|
+
* @param {Map<string, {body: string, frontmatter: object|null}>} [options.parsed] -
|
|
237
|
+
* Filled with each note's body and its frontmatter as authored, keyed by the
|
|
238
|
+
* note's file, so a later pass reads the notes this walk already parsed.
|
|
175
239
|
* @returns {Array<Record<string, any>>} The records, in a total order that does
|
|
176
240
|
* not depend on directory-read order.
|
|
177
241
|
*/
|
|
178
|
-
export function collectContentIndex(contentBase: string, { contentPackage, skipDirectories, assetsBase, manifest, problems, addressContext }: {
|
|
242
|
+
export function collectContentIndex(contentBase: string, { contentPackage, skipDirectories, assetsBase, manifest, problems, addressContext, foreignRecord, parsed, }: {
|
|
179
243
|
contentPackage: string;
|
|
180
244
|
skipDirectories: readonly string[];
|
|
181
245
|
assetsBase?: string | undefined;
|
|
182
246
|
manifest?: object | undefined;
|
|
183
247
|
addressContext?: object | undefined;
|
|
184
248
|
problems?: object[] | undefined;
|
|
249
|
+
foreignRecord?: ((key: string) => ({
|
|
250
|
+
culture?: unknown;
|
|
251
|
+
} | undefined)) | undefined;
|
|
252
|
+
parsed?: Map<string, {
|
|
253
|
+
body: string;
|
|
254
|
+
frontmatter: object | null;
|
|
255
|
+
}> | undefined;
|
|
185
256
|
}): Array<Record<string, any>>;
|
|
186
257
|
/**
|
|
187
258
|
* Serialize records as JSON Lines.
|
|
@@ -218,14 +289,22 @@ export function serializeContentIndex(records: Array<Record<string, any>>): stri
|
|
|
218
289
|
* aborting the derivation. Omitted, the note throws — which is the contract
|
|
219
290
|
* the emitter needs, since an index missing a note asserts that it does not
|
|
220
291
|
* exist.
|
|
292
|
+
* @param {Map<string, {body: string, frontmatter: object|null}>} [opts.parsed] -
|
|
293
|
+
* Filled with each note's body and authored frontmatter, keyed by the note's
|
|
294
|
+
* file. Handed to {@link module:engine/sql-tables.prepareTreeSqlTables}, it
|
|
295
|
+
* spares that pass reading and parsing every note again.
|
|
221
296
|
* @returns {object[]} One record per note, plus one per documentation entry.
|
|
222
297
|
*/
|
|
223
|
-
export function indexRecordsFor({ contentBase, assetsBase, config, skipDirectories, problems, }?: {
|
|
298
|
+
export function indexRecordsFor({ contentBase, assetsBase, config, skipDirectories, problems, parsed, }?: {
|
|
224
299
|
contentBase?: string | undefined;
|
|
225
300
|
assetsBase?: string | undefined;
|
|
226
301
|
config?: object | undefined;
|
|
227
302
|
skipDirectories?: readonly string[] | undefined;
|
|
228
303
|
problems?: object[] | undefined;
|
|
304
|
+
parsed?: Map<string, {
|
|
305
|
+
body: string;
|
|
306
|
+
frontmatter: object | null;
|
|
307
|
+
}> | undefined;
|
|
229
308
|
}): object[];
|
|
230
309
|
/**
|
|
231
310
|
* Emit this package's content index.
|
|
@@ -21,8 +21,8 @@ export function anchorsOf(body: string): Set<string>;
|
|
|
21
21
|
* Read a content tree into the index a link resolves against.
|
|
22
22
|
*
|
|
23
23
|
* **The corpus comes from the content index, not from a walk of this module's
|
|
24
|
-
* own**.
|
|
25
|
-
*
|
|
24
|
+
* own**. Passes do not each answer "which files are the content?" for
|
|
25
|
+
* themselves; this one reads
|
|
26
26
|
* {@link module:engine/content-index.indexRecordsFor}, which is the same
|
|
27
27
|
* derivation the published artifact and the compilers are driven from. So a
|
|
28
28
|
* note the index records is a note the link check sees, and the addresses and
|
|
@@ -81,8 +81,6 @@ export function buildLinkIndex(contentBase: string, { config, skipDirectories, s
|
|
|
81
81
|
* **What is checkable, stated plainly.** Only an address into this site is, and
|
|
82
82
|
* only against facts this build already holds:
|
|
83
83
|
*
|
|
84
|
-
* - A **retired content type** in the path. The engine knows the retired names
|
|
85
|
-
* and what replaced it, so this is a fact rather than a guess.
|
|
86
84
|
* - A **hardcoded absolute URL** into this package's own prefix, or into one a
|
|
87
85
|
* fetched index names. Every one of them has a better form to write, which
|
|
88
86
|
* is why every one is reported — including a bare `/<package>/`, which names
|
|
@@ -1,14 +1,57 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Whether a `data.culture` value names the note that carries it.
|
|
3
|
+
*
|
|
4
|
+
* The comparison is between canonical Addresses, so a culture note's shortcode,
|
|
5
|
+
* any longer form of its Address and a decoded tuple all name it alike. A note
|
|
6
|
+
* with no shortcode has no Address to compare against and names nothing.
|
|
7
|
+
*
|
|
8
|
+
* @param {object} fm - The note's frontmatter.
|
|
9
|
+
* @param {unknown} value - The `data.culture` value, as written or decoded.
|
|
10
|
+
* @param {object} [index] - The package and vocabularies a written value is
|
|
11
|
+
* read against, and the package the note's own Address is in.
|
|
12
|
+
* @returns {boolean} Whether the value is the note's own Address.
|
|
13
|
+
*/
|
|
14
|
+
export function cultureNamesItself(fm: object, value: unknown, index?: object): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Require a note's `data.culture` to address a culture lore note.
|
|
17
|
+
*
|
|
18
|
+
* A value that is not a `lore` Address, or names nothing, is left to the
|
|
19
|
+
* reference check, which reports it in its own terms. A culture note's own
|
|
20
|
+
* value is {@link checkCultureSubType}'s to judge, since it names only the note
|
|
21
|
+
* itself.
|
|
22
|
+
*
|
|
3
23
|
* @param {object} note
|
|
4
24
|
* @param {{index?: object}} [options]
|
|
25
|
+
* @returns {object[]} One error at the value when it names lore of another subType.
|
|
5
26
|
*/
|
|
6
27
|
export function checkCultureChoice(note: object, { index }?: {
|
|
7
28
|
index?: object;
|
|
8
|
-
}):
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
29
|
+
}): object[];
|
|
30
|
+
/**
|
|
31
|
+
* Scope `data.culture` to the subtypes that take it.
|
|
32
|
+
*
|
|
33
|
+
* A `doc` of `subType: settingguide` introduces one culture's setting and must
|
|
34
|
+
* name it; a missing value is an error at the `subType:` line. Every other `doc`
|
|
35
|
+
* subType refuses a written value, as an error at the key.
|
|
36
|
+
*
|
|
37
|
+
* A `lore` note of `subType: culture` is itself the culture. It may omit the
|
|
38
|
+
* field or name itself, in any form the Address parser reads; a value naming any
|
|
39
|
+
* other Address is an error at the value. A note with no shortcode has no
|
|
40
|
+
* Address to compare against, and the shortcode check reports it.
|
|
41
|
+
*
|
|
42
|
+
* @param {object} note - The note, as the link index hands it over.
|
|
43
|
+
* @param {{index?: object}} [options] - The link index, for the package and
|
|
44
|
+
* vocabularies a written value is read against.
|
|
45
|
+
* @returns {object[]} Findings.
|
|
46
|
+
*/
|
|
47
|
+
export function checkCultureSubType(note: object, { index }?: {
|
|
48
|
+
index?: object;
|
|
49
|
+
}): object[];
|
|
50
|
+
/**
|
|
51
|
+
* The `data.culture` field, declared once and spread into each type that takes
|
|
52
|
+
* it. A type gives its own `describe` where the field means something narrower
|
|
53
|
+
* there.
|
|
54
|
+
*
|
|
55
|
+
* @type {Readonly<object>}
|
|
56
|
+
*/
|
|
57
|
+
export const CULTURE_FIELD: Readonly<object>;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @property {string} name - The key as an author writes it.
|
|
6
6
|
* @property {string} [kind] - Its value's shape: `string`, `date`, `number`,
|
|
7
7
|
* `integer`, `boolean`, `address`, `list`, `map`, `scalar-or-map`,
|
|
8
|
-
*
|
|
8
|
+
* or `string-or-list` — see {@link fitsKind}. Absent, the check
|
|
9
9
|
* makes no claim about the value.
|
|
10
10
|
* @property {readonly string[]} [allowed] - The closed set a present value is
|
|
11
11
|
* one of, where the key takes a fixed word.
|
|
@@ -94,7 +94,7 @@ export type InnerKeySpec = {
|
|
|
94
94
|
/**
|
|
95
95
|
* - Its value's shape: `string`, `date`, `number`,
|
|
96
96
|
* `integer`, `boolean`, `address`, `list`, `map`, `scalar-or-map`,
|
|
97
|
-
*
|
|
97
|
+
* or `string-or-list` — see {@link fitsKind}. Absent, the check
|
|
98
98
|
* makes no claim about the value.
|
|
99
99
|
*/
|
|
100
100
|
kind?: string | undefined;
|
|
@@ -20,8 +20,7 @@ export function derivedMessage(key: string, from: string, file?: string): string
|
|
|
20
20
|
/**
|
|
21
21
|
* The derived keys a note actually writes, in declaration order.
|
|
22
22
|
*
|
|
23
|
-
* **Presence is the whole test**, as it is for a
|
|
24
|
-
* field: an authored empty string is as much a claim on the key as prose is,
|
|
23
|
+
* **Presence is the whole test**, as it is for a runtime-only field: an authored empty string is as much a claim on the key as prose is,
|
|
25
24
|
* and it is the same belief the message exists to correct. So the question is
|
|
26
25
|
* whether the path resolves to anything at all, never whether the value is a
|
|
27
26
|
* usable one.
|
|
@@ -114,10 +114,8 @@ export function positionInBody(body: string, offset: number, { bodyLine, bodyCol
|
|
|
114
114
|
* The key match tolerates leading whitespace by default, so a nested key of the
|
|
115
115
|
* same name answers when no top-level one is present — which is usually what a
|
|
116
116
|
* reader wants, the key being unique in nearly every note. Pass `topLevel` where
|
|
117
|
-
* it is not:
|
|
118
|
-
*
|
|
119
|
-
* second, which would tell an author to delete a field they are allowed to
|
|
120
|
-
* write.
|
|
117
|
+
* it is not: a finding about a top-level key must never open on a nested key
|
|
118
|
+
* of the same name.
|
|
121
119
|
*
|
|
122
120
|
* @param {string} raw - The file's full contents, frontmatter included.
|
|
123
121
|
* @param {string} key - The top-level frontmatter key.
|
|
@@ -137,6 +135,31 @@ export function positionInFrontmatter(raw: string, key: string, value?: string,
|
|
|
137
135
|
line?: number;
|
|
138
136
|
column?: number;
|
|
139
137
|
};
|
|
138
|
+
/**
|
|
139
|
+
* A frontmatter key's position in a note's file, or nothing.
|
|
140
|
+
*
|
|
141
|
+
* {@link positionInFrontmatter} answers the same question from the file's
|
|
142
|
+
* *text*; this reads the file to ask it.
|
|
143
|
+
*
|
|
144
|
+
* @param {string|undefined} absPath - The note's file.
|
|
145
|
+
* @param {string} key - The frontmatter key.
|
|
146
|
+
* @param {string} [value] - When given, prefer the occurrence whose line also
|
|
147
|
+
* carries this text — so a finding about one entry of a block opens on that
|
|
148
|
+
* entry rather than on the key that introduces it.
|
|
149
|
+
* @param {object} [options] - Options, forwarded to
|
|
150
|
+
* {@link positionInFrontmatter}.
|
|
151
|
+
* @param {boolean} [options.topLevel=false] - Require the key at column 1, so
|
|
152
|
+
* an identically named nested key cannot answer for it.
|
|
153
|
+
* @returns {{line?: number, column?: number}|undefined} Spreadable position
|
|
154
|
+
* fields, dropped rather than guessed when the file cannot be read or the key
|
|
155
|
+
* cannot be found — as `formatDiagnostic` requires.
|
|
156
|
+
*/
|
|
157
|
+
export function locateFrontmatterKey(absPath: string | undefined, key: string, value?: string, { topLevel }?: {
|
|
158
|
+
topLevel?: boolean | undefined;
|
|
159
|
+
}): {
|
|
160
|
+
line?: number;
|
|
161
|
+
column?: number;
|
|
162
|
+
} | undefined;
|
|
140
163
|
/**
|
|
141
164
|
* Where a literal sits in a text, so a finding about it can be opened.
|
|
142
165
|
*
|
|
@@ -53,12 +53,9 @@ export function defineDocumentSubtypes({ system, block, types }?: {
|
|
|
53
53
|
/**
|
|
54
54
|
* The row a system declares for a note type, or nothing.
|
|
55
55
|
*
|
|
56
|
-
* The **one** place a map is indexed
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* {@link systemOf} all arrive here. A note still spelling `armorgear` finds the
|
|
60
|
-
* `armor` row, compiles into the `armorgear` document it always did, and keeps
|
|
61
|
-
* the address it publishes at; only the *report* tells it to move.
|
|
56
|
+
* The **one** place a map is indexed — {@link documentSubtype},
|
|
57
|
+
* {@link mapsNoteType}, {@link noteTypesFor}'s consumers and {@link systemOf}
|
|
58
|
+
* all arrive here.
|
|
62
59
|
*
|
|
63
60
|
* @param {DocumentSubtypeMap} map - The system's map.
|
|
64
61
|
* @param {string|undefined} noteType - The note's declared `type`.
|
|
@@ -114,18 +111,6 @@ export function documentSubtype(map: DocumentSubtypeMap, noteType: string | unde
|
|
|
114
111
|
file?: string | undefined;
|
|
115
112
|
absPath?: string | undefined;
|
|
116
113
|
}): string | undefined;
|
|
117
|
-
/**
|
|
118
|
-
* The answer {@link referencedSubtype} gives: a subtype, or why there is none.
|
|
119
|
-
*
|
|
120
|
-
* Exactly one of the two fields is set. A `problem` is a sentence a caller
|
|
121
|
-
* prefixes with its own context and emits as a finding — it never throws,
|
|
122
|
-
* because the caller resolving a reference is walking a list and has to report
|
|
123
|
-
* this one and carry on.
|
|
124
|
-
*
|
|
125
|
-
* @typedef {object} ReferencedSubtype
|
|
126
|
-
* @property {string} [subType] - The document subtype the reference addresses.
|
|
127
|
-
* @property {string} [problem] - Why the reference names no document subtype.
|
|
128
|
-
*/
|
|
129
114
|
/**
|
|
130
115
|
* The document subtype a `(type, shortcode)` **reference** addresses.
|
|
131
116
|
*
|
|
@@ -165,26 +150,22 @@ export function documentSubtype(map: DocumentSubtypeMap, noteType: string | unde
|
|
|
165
150
|
* only the row has no block to read a discriminator from, so nothing here
|
|
166
151
|
* can choose, and choosing anyway would be right about half the time.
|
|
167
152
|
*
|
|
168
|
-
* A
|
|
169
|
-
*
|
|
170
|
-
* a document
|
|
171
|
-
* retirement exists to stop.
|
|
172
|
-
*
|
|
173
|
-
* A **renamed** spelling is the opposite case and resolves normally, through
|
|
174
|
-
* the same {@link currentType} every other lookup goes through. It has to
|
|
175
|
-
* be this side as much as the note's own `type:`: the overwhelming majority of
|
|
176
|
-
* the 31,000 occurrences of the old names are `(type, shortcode)` references
|
|
177
|
-
* inside a being's `items:` list, so a window that resolved notes but not
|
|
178
|
-
* references would silently drop 30,000 embedded items rather than compile them
|
|
179
|
-
* unchanged.
|
|
153
|
+
* A type that no row names, that no row produces as a subtype and that the
|
|
154
|
+
* consumer does not declare is refused: stamping the authored spelling on it
|
|
155
|
+
* would address a document that cannot exist.
|
|
180
156
|
*
|
|
181
157
|
* @param {DocumentSubtypeMap} map - The system's map.
|
|
182
158
|
* @param {string|undefined} noteType - The type the reference names.
|
|
183
159
|
* @param {string} document - The Foundry document class the reference must
|
|
184
160
|
* address — `"Item"` for a being's embedded items.
|
|
161
|
+
* @param {object} [options] - Options.
|
|
162
|
+
* @param {ReadonlySet<string>} [options.declared] - The item types the
|
|
163
|
+
* consuming repository declares itself, which the map does not name.
|
|
185
164
|
* @returns {ReferencedSubtype} The subtype, or why there is none.
|
|
186
165
|
*/
|
|
187
|
-
export function referencedSubtype(map: DocumentSubtypeMap, noteType: string | undefined, document: string
|
|
166
|
+
export function referencedSubtype(map: DocumentSubtypeMap, noteType: string | undefined, document: string, { declared }?: {
|
|
167
|
+
declared?: ReadonlySet<string> | undefined;
|
|
168
|
+
}): ReferencedSubtype;
|
|
188
169
|
/**
|
|
189
170
|
* Which system defines the document a note of this type compiles into.
|
|
190
171
|
*
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every form an event may name a note by: its Address in the `note` system,
|
|
3
|
+
* and in its own document's system where that differs.
|
|
4
|
+
*
|
|
5
|
+
* @param {object} record - The note's index record.
|
|
6
|
+
* @returns {string[]} The forms, the `note` one first.
|
|
7
|
+
*/
|
|
8
|
+
export function selfForms(record: object): string[];
|
|
1
9
|
/**
|
|
2
10
|
* The views each note is given, by section.
|
|
3
11
|
*
|
|
@@ -20,11 +28,14 @@ export function eventViewSections(db: object, records: Iterable<object>, fileOf:
|
|
|
20
28
|
* index record, and the `query` it writes for a note — given the note's
|
|
21
29
|
* Address in each form an event may name it by, and the shape of the corpus —
|
|
22
30
|
* or `null` where the corpus states nothing the view could select. A view's
|
|
23
|
-
* `own` query, where it has one, is what decides whether the view has rows
|
|
31
|
+
* `own` query, where it has one, is what decides whether the view has rows;
|
|
32
|
+
* a view with `owners` answers that for many notes in one query, given each
|
|
33
|
+
* note's Address forms.
|
|
24
34
|
*
|
|
25
35
|
* @type {ReadonlyArray<Readonly<{slug: string, heading: string,
|
|
26
36
|
* applies: (record: object) => boolean,
|
|
27
|
-
* query: (self: string[], shape: CorpusShape) => {fence: string, own?: string}|null
|
|
37
|
+
* query: (self: string[], shape: CorpusShape) => {fence: string, own?: string}|null,
|
|
38
|
+
* owners?: (db: object, selves: string[][], shape: CorpusShape) => Promise<Set<string>>}>>}
|
|
28
39
|
*/
|
|
29
40
|
export const EVENT_VIEWS: ReadonlyArray<Readonly<{
|
|
30
41
|
slug: string;
|
|
@@ -34,6 +45,7 @@ export const EVENT_VIEWS: ReadonlyArray<Readonly<{
|
|
|
34
45
|
fence: string;
|
|
35
46
|
own?: string;
|
|
36
47
|
} | null;
|
|
48
|
+
owners?: (db: object, selves: string[][], shape: CorpusShape) => Promise<Set<string>>;
|
|
37
49
|
}>>;
|
|
38
50
|
export type CorpusShape = {
|
|
39
51
|
/**
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Compile a Foundry Scene export into a pack document.
|
|
3
3
|
*
|
|
4
4
|
* The Scene passes through as exported. Only the note-derived Scene ID,
|
|
5
|
-
* compendium metadata, `data.fixup` and
|
|
6
|
-
*
|
|
5
|
+
* compendium metadata, the fixups — `data.fixup` and the map fields that
|
|
6
|
+
* declare a Scene property, such as `data.thumbnail` — and pins marked
|
|
7
|
+
* `#anchor` change; nothing else inside the Scene is read or checked.
|
|
7
8
|
*
|
|
8
9
|
* @param {object} fm - The map note's frontmatter.
|
|
9
10
|
* @param {string} markdown - Its converted Markdown body.
|