@heroiclands/package-build 22.15.0 → 22.16.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.
Files changed (223) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/README.md +39 -678
  3. package/bin/{content-build.mjs → content-commands.mjs} +197 -118
  4. package/bin/package-build.mjs +303 -42
  5. package/bin/report.mjs +1 -1
  6. package/ci/ci-docker.mjs +6 -3
  7. package/ci/ci-steps.mjs +6 -4
  8. package/ci/content-format-reference.mjs +106 -0
  9. package/config.mjs +22 -2
  10. package/content-config.mjs +74 -134
  11. package/docs/api.md +294 -234
  12. package/docs/authoring/assets.md +31 -0
  13. package/docs/authoring/dates-and-calendars.md +33 -0
  14. package/docs/authoring/first-note.md +48 -0
  15. package/docs/authoring/frontmatter.md +40 -0
  16. package/docs/authoring/links-and-markup.md +137 -0
  17. package/docs/commands.md +631 -162
  18. package/docs/configuration.md +176 -140
  19. package/docs/content-format.md +50 -4229
  20. package/docs/design.md +32 -0
  21. package/docs/diagnostics.md +29 -22
  22. package/docs/getting-started.md +21 -877
  23. package/docs/guides/book.md +153 -0
  24. package/docs/guides/e2e.md +143 -0
  25. package/docs/guides/icons.md +126 -0
  26. package/docs/guides/localization.md +120 -0
  27. package/docs/guides/module-project.md +915 -0
  28. package/docs/guides/packs.md +167 -0
  29. package/docs/guides/reference-pages.md +148 -0
  30. package/docs/guides/release-and-deploy.md +114 -0
  31. package/docs/guides/site.md +152 -0
  32. package/docs/guides/system-project.md +45 -0
  33. package/docs/index.md +16 -0
  34. package/docs/project-setup.md +54 -35
  35. package/docs/reference/format-details.md +4420 -0
  36. package/docs/reference/note-types.md +531 -0
  37. package/engine/address-render.mjs +26 -0
  38. package/engine/address.mjs +3 -20
  39. package/engine/anchors.mjs +15 -6
  40. package/engine/asset-bindings.mjs +6 -2
  41. package/engine/base-compiler.mjs +47 -11
  42. package/engine/being-measurements.mjs +70 -0
  43. package/engine/calendar-artifacts.mjs +1 -1
  44. package/engine/calendar-choice.mjs +32 -0
  45. package/engine/calendar-human.mjs +71 -0
  46. package/engine/calendar-notes.mjs +41 -3
  47. package/engine/calendars.mjs +8 -1
  48. package/engine/changelog-lint.mjs +2 -2
  49. package/engine/code-fences.mjs +23 -97
  50. package/engine/compile-corpus.mjs +6 -7
  51. package/engine/content-admonitions.mjs +114 -0
  52. package/engine/content-captions.mjs +181 -0
  53. package/engine/content-embeds.mjs +2 -2
  54. package/engine/content-footnotes.mjs +34 -0
  55. package/engine/content-format-check.mjs +2 -2
  56. package/engine/content-format.mjs +127 -73
  57. package/engine/content-format.yaml +745 -0
  58. package/engine/content-html.mjs +1 -1
  59. package/engine/content-icons.mjs +45 -92
  60. package/engine/content-images.mjs +22 -74
  61. package/engine/content-index.mjs +12 -3
  62. package/engine/content-links.mjs +21 -26
  63. package/engine/content-lint.mjs +1 -5
  64. package/engine/content-secrets.mjs +3 -1
  65. package/engine/content-tables.mjs +47 -1257
  66. package/engine/culture-choice.mjs +32 -0
  67. package/engine/date-conversion.mjs +47 -0
  68. package/engine/declaration-check.mjs +87 -0
  69. package/engine/docs-checks.mjs +140 -0
  70. package/engine/documentation-links.mjs +31 -0
  71. package/engine/exported-scene.mjs +1 -1
  72. package/engine/extension-attributes.mjs +74 -0
  73. package/engine/field-reference.mjs +1 -1
  74. package/engine/field-spec.mjs +4 -0
  75. package/engine/foreign-catalog.mjs +5 -5
  76. package/engine/format-generated.mjs +15 -0
  77. package/engine/foundry-entries.mjs +3 -1
  78. package/engine/frontmatter-lint.mjs +5 -1
  79. package/engine/frontmatter.mjs +10 -0
  80. package/engine/generate.mjs +2 -2
  81. package/engine/helpers.mjs +71 -117
  82. package/engine/homepage.mjs +2 -3
  83. package/engine/index-records.mjs +1 -0
  84. package/engine/index.mjs +18 -3
  85. package/engine/infobox-registry.mjs +3 -1
  86. package/engine/infobox.mjs +38 -20
  87. package/engine/item-compiler.mjs +10 -8
  88. package/engine/item-docs.mjs +7 -6
  89. package/engine/itinerary-scenes.mjs +4 -2
  90. package/engine/journals.mjs +51 -10
  91. package/engine/macros.mjs +1 -1
  92. package/engine/map-build.mjs +1 -1
  93. package/engine/map-dot.mjs +1 -1
  94. package/engine/map-raster.mjs +4 -2
  95. package/engine/markdown-expressions.mjs +117 -0
  96. package/engine/metadata-index.mjs +7 -3
  97. package/engine/note-addresses.mjs +1 -0
  98. package/engine/note-dates.mjs +283 -61
  99. package/engine/note-package.mjs +5 -25
  100. package/engine/note-state.mjs +6 -2
  101. package/engine/note-vocabulary.mjs +74 -19
  102. package/engine/number-words.mjs +75 -0
  103. package/engine/office-holders.mjs +188 -0
  104. package/engine/pack-config.mjs +2 -15
  105. package/engine/pack-router.mjs +24 -5
  106. package/engine/packages.mjs +3 -2
  107. package/engine/pathnames.mjs +21 -24
  108. package/engine/pdf-build.mjs +217 -55
  109. package/engine/pdf-fonts.mjs +2 -2
  110. package/engine/pdf-images.mjs +82 -0
  111. package/engine/pdf-render.mjs +174 -22
  112. package/engine/populations.mjs +3 -2
  113. package/engine/project-init.mjs +499 -0
  114. package/engine/prose-config.mjs +1 -1
  115. package/engine/prose-lint.mjs +7 -6
  116. package/engine/readability-lint.mjs +86 -0
  117. package/engine/reckoning-markers.mjs +205 -93
  118. package/engine/scenes.mjs +5 -2
  119. package/engine/schema-check.mjs +3 -3
  120. package/engine/site-build.mjs +87 -37
  121. package/engine/site-config.mjs +8 -8
  122. package/engine/site-index.mjs +4 -0
  123. package/engine/site-maps.mjs +1 -1
  124. package/engine/site-preview.mjs +19 -8
  125. package/engine/social-ties.mjs +5 -1
  126. package/engine/sql-tables.mjs +92 -22
  127. package/engine/web-wikilinks.mjs +15 -31
  128. package/engine/wikilink-syntax.mjs +4 -1
  129. package/engine/wikilinks.mjs +12 -14
  130. package/hm3/item-fields.mjs +1 -1
  131. package/hm3/items.mjs +12 -45
  132. package/index.mjs +2 -14
  133. package/manifest.mjs +31 -4
  134. package/markdownlint-config.mjs +1 -1
  135. package/package.json +32 -11
  136. package/prettier-config.mjs +1 -1
  137. package/sohl/being-info.mjs +3 -145
  138. package/sohl/index.mjs +1 -1
  139. package/sohl/infobox.mjs +2 -1
  140. package/sohl/item-builders.mjs +3 -27
  141. package/sohl/item-fields.mjs +61 -22
  142. package/sohl/kb-passes.mjs +2 -2
  143. package/sohl/note-schemas.mjs +0 -8
  144. package/stage.mjs +19 -0
  145. package/types/config.d.mts +12 -3
  146. package/types/content-config.d.mts +15 -81
  147. package/types/engine/address-render.d.mts +13 -0
  148. package/types/engine/address.d.mts +2 -11
  149. package/types/engine/anchors.d.mts +3 -4
  150. package/types/engine/asset-bindings.d.mts +9 -2
  151. package/types/engine/base-compiler.d.mts +1 -2
  152. package/types/engine/being-measurements.d.mts +16 -0
  153. package/types/engine/calendar-choice.d.mts +14 -0
  154. package/types/engine/calendar-human.d.mts +4 -0
  155. package/types/engine/calendar-notes.d.mts +2 -0
  156. package/types/engine/calendars.d.mts +5 -3
  157. package/types/engine/code-fences.d.mts +6 -72
  158. package/types/engine/compile-corpus.d.mts +1 -3
  159. package/types/engine/content-admonitions.d.mts +24 -0
  160. package/types/engine/content-captions.d.mts +45 -0
  161. package/types/engine/content-footnotes.d.mts +10 -0
  162. package/types/engine/content-format-check.d.mts +17 -4
  163. package/types/engine/content-format.d.mts +24 -11
  164. package/types/engine/content-icons.d.mts +14 -23
  165. package/types/engine/content-images.d.mts +2 -2
  166. package/types/engine/content-index.d.mts +9 -2
  167. package/types/engine/content-links.d.mts +3 -5
  168. package/types/engine/content-tables.d.mts +11 -140
  169. package/types/engine/culture-choice.d.mts +14 -0
  170. package/types/engine/date-conversion.d.mts +4 -0
  171. package/types/engine/declaration-check.d.mts +24 -0
  172. package/types/engine/docs-checks.d.mts +28 -0
  173. package/types/engine/documentation-links.d.mts +7 -0
  174. package/types/engine/exported-scene.d.mts +6 -2
  175. package/types/engine/extension-attributes.d.mts +14 -0
  176. package/types/engine/field-spec.d.mts +9 -0
  177. package/types/engine/format-generated.d.mts +7 -0
  178. package/types/engine/frontmatter.d.mts +14 -4
  179. package/types/engine/generate.d.mts +1 -1
  180. package/types/engine/helpers.d.mts +37 -92
  181. package/types/engine/homepage.d.mts +2 -3
  182. package/types/engine/index.d.mts +5 -0
  183. package/types/engine/infobox-registry.d.mts +3 -1
  184. package/types/engine/infobox.d.mts +17 -6
  185. package/types/engine/item-compiler.d.mts +4 -4
  186. package/types/engine/item-docs.d.mts +4 -3
  187. package/types/engine/journals.d.mts +10 -7
  188. package/types/engine/map-graphviz.d.mts +1 -1
  189. package/types/engine/markdown-expressions.d.mts +17 -0
  190. package/types/engine/note-dates.d.mts +47 -1
  191. package/types/engine/note-package.d.mts +3 -19
  192. package/types/engine/note-state.d.mts +2 -1
  193. package/types/engine/note-vocabulary.d.mts +9 -0
  194. package/types/engine/number-words.d.mts +4 -0
  195. package/types/engine/office-holders.d.mts +14 -0
  196. package/types/engine/pack-config.d.mts +1 -1
  197. package/types/engine/packages.d.mts +3 -2
  198. package/types/engine/pdf-images.d.mts +38 -0
  199. package/types/engine/populations.d.mts +2 -2
  200. package/types/engine/project-init.d.mts +17 -0
  201. package/types/engine/prose-config.d.mts +1 -1
  202. package/types/engine/prose-lint.d.mts +3 -2
  203. package/types/engine/readability-lint.d.mts +22 -0
  204. package/types/engine/reckoning-markers.d.mts +4 -2
  205. package/types/engine/schema-check.d.mts +3 -3
  206. package/types/engine/site-build.d.mts +38 -28
  207. package/types/engine/site-config.d.mts +2 -2
  208. package/types/engine/site-index.d.mts +4 -0
  209. package/types/engine/site-preview.d.mts +1 -1
  210. package/types/engine/social-ties.d.mts +8 -2
  211. package/types/engine/sql-tables.d.mts +13 -2
  212. package/types/engine/web-wikilinks.d.mts +2 -1
  213. package/types/engine/wikilinks.d.mts +7 -1
  214. package/types/hm3/items.d.mts +5 -6
  215. package/types/labels.d.mts +40 -0
  216. package/types/manifest.d.mts +3 -3
  217. package/types/sohl/actors.d.mts +2 -2
  218. package/types/sohl/being-info.d.mts +3 -43
  219. package/types/sohl/index.d.mts +1 -1
  220. package/types/sohl/infobox.d.mts +5 -2
  221. package/types/sohl/item-fields.d.mts +4 -13
  222. package/types/stage.d.mts +9 -0
  223. package/CONTENT.md +0 -3239
@@ -27,7 +27,7 @@ export function parseIconAttributes(raw?: string): {
27
27
  /**
28
28
  * Look one name up.
29
29
  *
30
- * @param {string} name - The name written between the colons, without `icon-`.
30
+ * @param {string} name - The name written between the colons, without `icon `.
31
31
  * @param {IconRegistry} [registry] - The package's registry.
32
32
  * @returns {object|null} The entry, or `null` when the registry does not
33
33
  * declare it.
@@ -63,20 +63,20 @@ export function iconsIn(text: string): Array<{
63
63
  * Report every icon a tree names that its registry does not declare.
64
64
  *
65
65
  * The whole point of a registry is that a typo is answerable, so this is the
66
- * half that makes `:icon-stra:` a finding rather than three words of literal
66
+ * half that makes `:icon stra:` a finding rather than three words of literal
67
67
  * text nobody notices in a rendered page.
68
68
  *
69
69
  * @param {string} text - The file's contents.
70
70
  * @param {string} file - Path to report.
71
71
  * @param {IconRegistry} [registry] - The package's registry.
72
72
  * @returns {Array<{file: string, line: number, column: number,
73
- * severity: "warning", message: string}>} The unknown names.
73
+ * severity: "warning"|"error", message: string}>} The findings.
74
74
  */
75
75
  export function lintIcons(text: string, file: string, registry?: IconRegistry): Array<{
76
76
  file: string;
77
77
  line: number;
78
78
  column: number;
79
- severity: "warning";
79
+ severity: "warning" | "error";
80
80
  message: string;
81
81
  }>;
82
82
  /**
@@ -136,11 +136,11 @@ export function lintContentIcons(contentBase: string, { skipDirectories, registr
136
136
  files: number;
137
137
  };
138
138
  /**
139
- * A markdown-it plugin rendering `:icon-name:` inline.
139
+ * A markdown-it plugin rendering `:icon name:` inline.
140
140
  *
141
141
  * An unknown name is left **exactly as written** rather than dropped. The name
142
142
  * is reported by {@link lintIcons}, and a rendered page that still shows
143
- * `:icon-stra:` is how the author finds it without reading a log.
143
+ * `:icon stra:` is how the author finds it without reading a log.
144
144
  *
145
145
  * **A function is accepted as well as a table**, and resolved per render. The
146
146
  * shared markdown-it instance is a module-level constant, so it is built before
@@ -199,7 +199,7 @@ export function iconPlugin(registry?: Record<string, object> | (() => Record<str
199
199
  *
200
200
  * Empty rather than a starter set, because a starter set is a promise about
201
201
  * fonts this package does not ship. A tree with no `icons:` configured names no
202
- * icons, and `:icon-star:` in one of its notes renders as its own literal text
202
+ * icons, and `:icon star:` in one of its notes renders as its own literal text
203
203
  * and is reported — which is the visible failure, not a silent one.
204
204
  *
205
205
  * @type {IconRegistry}
@@ -243,25 +243,16 @@ export const ICON_ATTRIBUTES: Readonly<Record<string, {
243
243
  /**
244
244
  * The shape a note writes, and the one this module claims.
245
245
  *
246
- * The `icon-` prefix is what keeps it out of the way of an emoji shortcode: a
247
- * surface that also renders `:smile:` can tell the two apart without a lookup,
248
- * and a reader can tell what `:icon-star:` is without knowing this module
249
- * exists. Names are lowercase, digits and hyphens — the charset an address
250
- * segment already uses, so nothing new has to be explained.
251
- *
252
- * Not `:name[content]`. That is remark-directive syntax, and this toolchain
253
- * parses with markdown-it; a directive would render as its own literal text.
246
+ * The `icon` keyword distinguishes inline glyphs from asset Addresses and
247
+ * other colon-based shorthand. Names use lowercase letters, digits and
248
+ * hyphens, and each name resolves in the package's declared icon registry.
254
249
  *
255
- * An optional trailing brace carries **attributes**:
250
+ * An optional brace carries attributes, for example:
256
251
  *
257
- * :icon-affiliation:{size: 2x}
252
+ * :icon affiliation:{size=2x}
258
253
  *
259
- * `key: value` pairs, comma-separated, in the shape `markdown-it-attrs` and
260
- * remark-directive already use — so it is a convention a reader may recognise
261
- * rather than one this module invented. Attributes rather than a bare value
262
- * because `size` is merely the first one anybody needed: a fixed-width flag, a
263
- * rotation, a title override are the same shape of thing, and a syntax that
264
- * could only ever express size would have to be replaced to gain any of them.
254
+ * Attributes are whitespace-separated `key=value` pairs. The closed `size`
255
+ * values are declared in {@link ICON_SIZES}.
265
256
  *
266
257
  * One inline rule consumes the token **and** its brace, so there is no state in
267
258
  * which the icon resolves and the brace is left stranded on the page. An
@@ -208,7 +208,7 @@ export function renderImageFigures(body: string, resolveSrc?: (src: string) => s
208
208
  * A markdown-it plugin that reads an image's directive and renders its figure.
209
209
  *
210
210
  * **A core rule, not an inline one.** markdown-it's own `image` rule consumes
211
- * `![alt](src)` and leaves `{float: top-left}` behind as text, and a rule
211
+ * `![alt](src)` and leaves `{float=top-left}` behind as text, and a rule
212
212
  * running before it would have to re-implement link parsing to find the brace.
213
213
  * Reading the token stream afterwards costs one pass and re-implements nothing.
214
214
  *
@@ -255,7 +255,7 @@ export const IMAGE_CLASSES: Readonly<Record<string, {
255
255
  /** The named sizes an image directive accepts. */
256
256
  export const IMAGE_SIZES: readonly string[];
257
257
  /**
258
- * The `float:` positions an image may take, and where each puts it.
258
+ * The `float` positions an image may take, and where each puts it.
259
259
  *
260
260
  * `align` is the Typst alignment the float is placed at. **Print cannot wrap
261
261
  * text around an arbitrary shape**: a Typst float occupies the column measure,
@@ -101,6 +101,8 @@ export function asciiAliases(aliases: unknown): Array<string>;
101
101
  * @param {number} [options.bodyLine] - The 1-based file line the body starts on.
102
102
  * @param {object} [options.manifest] - The package manifest, which the Foundry
103
103
  * entries are derived against.
104
+ * @param {object} [options.addressContext] - Address resolution context.
105
+ * @param {object} [options.dateContext] - Calendar conversion context.
104
106
  * @returns {Record<string, any>} The record, keys sorted at every depth. A
105
107
  * **stub** — a note with an empty body, on a type an empty body suppresses —
106
108
  * carries `address` and `anchors` as `null`: it publishes no page, so it
@@ -112,7 +114,7 @@ export function asciiAliases(aliases: unknown): Array<string>;
112
114
  * otherwise be overwritten without a word. `file` and, where the file was
113
115
  * read, `position` ride on the error.
114
116
  */
115
- export function buildIndexRecord({ frontmatter, relPath, absPath, contentPackage, body, bodyLine, manifest, addressContext, }: {
117
+ export function buildIndexRecord({ frontmatter, relPath, absPath, contentPackage, body, bodyLine, manifest, addressContext, dateContext, }: {
116
118
  frontmatter: Record<string, any>;
117
119
  relPath: string;
118
120
  absPath?: string | undefined;
@@ -120,9 +122,11 @@ export function buildIndexRecord({ frontmatter, relPath, absPath, contentPackage
120
122
  body?: string | undefined;
121
123
  bodyLine?: number | undefined;
122
124
  manifest?: object | undefined;
125
+ addressContext?: object | undefined;
126
+ dateContext?: object | undefined;
123
127
  }): Record<string, any>;
124
128
  /** Derive every index record belonging to one parsed note. */
125
- export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absPath, contentPackage, manifest, addressContext, }: {
129
+ export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absPath, contentPackage, manifest, addressContext, dateContext, }: {
126
130
  frontmatter: any;
127
131
  body: any;
128
132
  bodyLine: any;
@@ -131,6 +135,7 @@ export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absP
131
135
  contentPackage: any;
132
136
  manifest: any;
133
137
  addressContext: any;
138
+ dateContext: any;
134
139
  }): object[];
135
140
  /**
136
141
  * Read a content tree into index records, in the order they will be written.
@@ -156,6 +161,7 @@ export function indexRecordsForNote({ frontmatter, body, bodyLine, relPath, absP
156
161
  * anyway.
157
162
  * @param {object} [options.manifest] - The package manifest, which the Foundry
158
163
  * entries are derived against.
164
+ * @param {object} [options.addressContext] - Address resolution context.
159
165
  * @param {object[]} [options.problems] - Supplied by a **reader**: a note that
160
166
  * cannot be recorded is pushed here as a diagnostic and skipped. Omitted, the
161
167
  * note throws — the contract the emitter needs, since an index missing a note
@@ -168,6 +174,7 @@ export function collectContentIndex(contentBase: string, { contentPackage, skipD
168
174
  skipDirectories: readonly string[];
169
175
  assetsBase?: string | undefined;
170
176
  manifest?: object | undefined;
177
+ addressContext?: object | undefined;
171
178
  problems?: object[] | undefined;
172
179
  }): Array<Record<string, any>>;
173
180
  /**
@@ -72,9 +72,8 @@ export function buildLinkIndex(contentBase: string, { config, skipDirectories, s
72
72
  *
73
73
  * **Why the homepage needs its own audit at all.** Every other note addresses
74
74
  * the corpus with wikilinks, which {@link auditLinks} resolves. A homepage does
75
- * not and cannot: it is published *verbatim* by every publishing mode, including
76
- * the homepage-only mode two fan-licensed packages ship under, where the content
77
- * tree is never walked and there is no index for a wikilink to resolve against.
75
+ * not and cannot: it is published *verbatim* even when the tree contains other
76
+ * notes. Its body never runs through the wikilink resolver.
78
77
  * So a homepage addresses the web the way the web does — markdown links in its
79
78
  * body — and this is what looks at those. A dead link on the page a reader
80
79
  * arrives at is the one nothing else would report.
@@ -89,8 +88,7 @@ export function buildLinkIndex(contentBase: string, { config, skipDirectories, s
89
88
  * is why every one is reported — including a bare `/<package>/`, which names
90
89
  * another package's front page. A front page's address *is* its package
91
90
  * prefix, so `/<package>/` is the absolute URL with the host struck off —
92
- * host-free, emitted verbatim, and needing no index, which is what lets it
93
- * hold in homepage-only mode where the tree is never walked.
91
+ * host-free, emitted verbatim, and needing no index.
94
92
  * - A **wikilink**, which nothing on this page will ever resolve.
95
93
  *
96
94
  * **What is not checkable, and is not attempted.** Whether an external URL
@@ -1,145 +1,16 @@
1
1
  /**
2
- * Parse one `dataview` block's query.
3
- *
4
- * @param {string} source - The query text (fences already stripped).
5
- * @returns {{columns: Array<{header: string, expr: object}>, from: object|null,
6
- * where: object|null, sort: Array<{expr: object, descending: boolean}>,
7
- * limit: number|null}}
8
- * @throws {Error} When the query is not a supported `TABLE` query — the message
9
- * names the offending clause, column, or token.
2
+ * Replace prepared SQL fences with Markdown tables while retaining source lines.
3
+ * Query execution happens in the asynchronous SQL preparation pass.
4
+ * @param {string} markdown - The authored body.
5
+ * @param {{source?: string, sqlTables?: object[]}} [context] - Prepared results.
6
+ * @returns {{markdown: string, errors: object[], warnings: object[], lineMap: object[]}}
10
7
  */
11
- export function parseDataviewQuery(source: string): {
12
- columns: Array<{
13
- header: string;
14
- expr: object;
15
- }>;
16
- from: object | null;
17
- where: object | null;
18
- sort: Array<{
19
- expr: object;
20
- descending: boolean;
21
- }>;
22
- limit: number | null;
23
- };
24
- /**
25
- * Resolve a dotted path against a content note. `file.*` names the note's place
26
- * in the tree; everything else reads frontmatter, preferring a literal dotted
27
- * key before walking the segments (the same precedence the pack compilers'
28
- * `getFrontmatter` uses) — so **any** frontmatter property is addressable,
29
- * however deeply nested.
30
- *
31
- * @param {ContentTableDoc} doc
32
- * @param {string} path
33
- * @returns {unknown} `null` when the note has no such field.
34
- * @throws {Error} On an unknown `file.*` field, which would otherwise read as a
35
- * table that silently matches nothing.
36
- */
37
- export function resolveField(doc: ContentTableDoc, path: string): unknown;
38
- /**
39
- * Evaluate one parsed expression against a note.
40
- *
41
- * @param {object} node - From {@link parseDataviewQuery}.
42
- * @param {ContentTableDoc} doc - The row being rendered.
43
- * @param {ContentTableDoc} [self] - The note *containing* the query, which is
44
- * what `this` reads; absent means every `this.…` resolves to nothing.
45
- * @returns {unknown}
46
- */
47
- export function evaluate(node: object, doc: ContentTableDoc, self?: ContentTableDoc): unknown;
48
- /**
49
- * The notes a query selects, in the order its `SORT` keys give. With no `SORT`
50
- * the notes keep content-path order, and the note path (then its id) breaks any
51
- * remaining tie, so the emitted table is byte-stable across builds regardless
52
- * of directory-walk order.
53
- *
54
- * @param {object} spec - From {@link parseDataviewQuery}.
55
- * @param {Array<ContentTableDoc>} docs
56
- * @param {ContentTableDoc} [self] - The note containing the query (`this`).
57
- * @returns {Array<ContentTableDoc>} The matching notes, sorted and limited.
58
- */
59
- export function selectRows(spec: object, docs: Array<ContentTableDoc>, self?: ContentTableDoc): Array<ContentTableDoc>;
60
- /**
61
- * Build the markdown table for one query.
62
- *
63
- * A `link(…)` cell — and the implicit `File` column — is emitted as a wikilink
64
- * to the row's own note, which the caller's wikilink pass resolves; a note the
65
- * caller reports as unlinkable (no shortcode, or a content directory that
66
- * compiles into no pack) degrades to plain text. A column is right-aligned when
67
- * every value it shows is numeric.
68
- *
69
- * @param {object} spec - From {@link parseDataviewQuery}.
70
- * @param {Array<ContentTableDoc>} rows - From {@link selectRows}.
71
- * @param {(doc: ContentTableDoc) => boolean} linkable - Can this note be linked to?
72
- * @param {ContentTableDoc} [self] - The note containing the query (`this`).
73
- * @returns {string} The markdown table (no trailing newline).
74
- */
75
- export function renderContentTable(spec: object, rows: Array<ContentTableDoc>, linkable: (doc: ContentTableDoc) => boolean, self?: ContentTableDoc): string;
76
- /**
77
- * Expand every fenced `dataview` and `sql` block in a markdown body.
78
- *
79
- * A block that cannot be honoured — malformed or unsupported — is left in the
80
- * body verbatim and reported in `errors`, so the failure is visible in the
81
- * output as well as on the console. Every other code fence, and every code
82
- * span, is left alone (that is how the syntax is documented).
83
- *
84
- * A query that selects **no** note is an error unless the fence says
85
- * `allow-empty`, which states that an empty table is the intended result.
86
- *
87
- * @param {string} markdown - The note body, frontmatter already stripped.
88
- * @param {object} ctx
89
- * @param {Array<ContentTableDoc>} ctx.docs - The searchable universe: every
90
- * content note the caller considers in scope.
91
- * @param {(doc: ContentTableDoc) => boolean} [ctx.linkable] - Whether a note can
92
- * be linked to from a cell; defaults to never.
93
- * @param {string} [ctx.source] - The note being expanded, for error reports.
94
- * @param {ContentTableDoc} [ctx.self] - The note being expanded, as a searchable
95
- * doc: what a query's `this` reads.
96
- * @param {object[]} [ctx.sqlTables] - This note's prepared `sql` results, in
97
- * document order, from
98
- * {@link module:engine/sql-tables.prepareSqlTables}. An `sql` directive with
99
- * no prepared result is an error: nothing here runs a query.
100
- * @returns {{markdown: string, errors: Array<{source: string, directive: string,
101
- * reason: string, line: number, column?: number}>,
102
- * warnings: Array<{source: string, line: number, column: number,
103
- * reason: string}>, lineMap: Array<{line: number, generated: boolean}>}}
104
- * `lineMap` is parallel to the emitted lines and says which authored line
105
- * each came from, so a diagnostic about the expanded body can name an
106
- * authored position. An `errors` entry carries the 0-based line of the
107
- * directive that failed, for the same reason. `warnings` holds one entry per
108
- * `dataview` directive the body still authors, and one per `sql` directive
109
- * that leaves out stubs it would otherwise list.
110
- */
111
- export function expandContentTables(markdown: string, { docs, linkable, source, self, sqlTables, }?: {
112
- docs: Array<ContentTableDoc>;
113
- linkable?: ((doc: ContentTableDoc) => boolean) | undefined;
114
- source?: string | undefined;
115
- self?: ContentTableDoc | undefined;
116
- sqlTables?: object[] | undefined;
8
+ export function expandContentTables(markdown: string, { source, sqlTables }?: {
9
+ source?: string;
10
+ sqlTables?: object[];
117
11
  }): {
118
12
  markdown: string;
119
- errors: Array<{
120
- source: string;
121
- directive: string;
122
- reason: string;
123
- line: number;
124
- column?: number;
125
- }>;
126
- warnings: Array<{
127
- source: string;
128
- line: number;
129
- column: number;
130
- reason: string;
131
- }>;
132
- lineMap: Array<{
133
- line: number;
134
- generated: boolean;
135
- }>;
136
- };
137
- /**
138
- * One content note as a content build hands it to the expander: its parsed
139
- * frontmatter plus its path below the content root, which backs the `file.*`
140
- * fields.
141
- */
142
- export type ContentTableDoc = {
143
- fm: Record<string, any>;
144
- path?: string;
13
+ errors: object[];
14
+ warnings: object[];
15
+ lineMap: object[];
145
16
  };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Require a being's primary culture to address a culture lore note.
3
+ * @param {object} note
4
+ * @param {{index?: object}} [options]
5
+ */
6
+ export function checkCultureChoice(note: object, { index }?: {
7
+ index?: object;
8
+ }): {
9
+ severity: string;
10
+ message: string;
11
+ line?: number;
12
+ column?: number;
13
+ file: any;
14
+ }[];
@@ -0,0 +1,4 @@
1
+ /** Convert a day in an addressed calendar to its canonical spelling. */
2
+ export function dateFromCalendar(reference: any, value: any, context: any): string;
3
+ /** Convert a canonical day to the date in the covering era of a calendar. */
4
+ export function dateToCalendar(reference: any, value: any, context: any): any;
@@ -0,0 +1,24 @@
1
+ /** All declaration entry points advertised by a package's exports map. */
2
+ export function exportedDeclarationFiles(root: any): {
3
+ files: any[];
4
+ findings: {
5
+ file: string;
6
+ severity: string;
7
+ message: string;
8
+ }[];
9
+ };
10
+ /**
11
+ * Type-check project declarations with library checking enabled.
12
+ * @param {string} project - TypeScript project file.
13
+ * @param {{exports?: boolean}} [options]
14
+ * @returns {Array<{file: string, line?: number, column?: number, severity: "error", message: string}>}
15
+ */
16
+ export function checkDeclarations(project: string, options?: {
17
+ exports?: boolean;
18
+ }): Array<{
19
+ file: string;
20
+ line?: number;
21
+ column?: number;
22
+ severity: "error";
23
+ message: string;
24
+ }>;
@@ -0,0 +1,28 @@
1
+ /** Preserve offsets while excluding literal examples from link scanning. */
2
+ export function maskMarkdownCode(source: any, spans?: boolean): any;
3
+ /** GitHub heading slug, retaining separate spaces after punctuation removal. */
4
+ export function docHeadingSlug(value: any): any;
5
+ /** @param {string} source */
6
+ export function docAnchors(source: string): Set<any>;
7
+ /**
8
+ * Check relative Markdown links beneath a documentation root.
9
+ * @param {string} root
10
+ * @returns {Array<{file: string, line: number, column: number, severity: "error", message: string}>}
11
+ */
12
+ export function checkDocLinks(root: string): Array<{
13
+ file: string;
14
+ line: number;
15
+ column: number;
16
+ severity: "error";
17
+ message: string;
18
+ }>;
19
+ /**
20
+ * Check each direct Markdown page in each section against the root README.
21
+ * @param {string} root
22
+ * @returns {Array<{file: string, severity: "error", message: string}>}
23
+ */
24
+ export function checkDocIndex(root: string): Array<{
25
+ file: string;
26
+ severity: "error";
27
+ message: string;
28
+ }>;
@@ -0,0 +1,7 @@
1
+ /** Keep repository-relative documentation links usable on addressed pages. */
2
+ export function documentationLinksPass({ config, book }: {
3
+ config: any;
4
+ book?: boolean | undefined;
5
+ }): {
6
+ beforeLinks(text: any, page: any): any;
7
+ };
@@ -6,7 +6,11 @@
6
6
  *
7
7
  * @param {object} fm - The map note's frontmatter.
8
8
  * @param {string} markdown - Its converted Markdown body.
9
- * @param {object} [opts] - Pack metadata, derived JournalEntry ID, and asset resolver.
9
+ * @param {{journalEntryId?: string, stats?: object, resolveAddress?: Function}} [opts] - Pack metadata, derived JournalEntry ID, and asset resolver.
10
10
  * @returns {object} The keyed Scene document.
11
11
  */
12
- export function buildExportedScene(fm: object, markdown: string, { journalEntryId, stats, resolveAddress }?: object): object;
12
+ export function buildExportedScene(fm: object, markdown: string, { journalEntryId, stats, resolveAddress }?: {
13
+ journalEntryId?: string;
14
+ stats?: object;
15
+ resolveAddress?: Function;
16
+ }): object;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Read the shared braced attribute grammar used by body extensions.
3
+ * Callers validate which names and classes their extension understands.
4
+ * @param {string} source - Text inside the braces.
5
+ * @returns {{id: string, classes: string[], values: Record<string, string>, problems: string[]}}
6
+ */
7
+ export function parseExtensionAttributes(source: string): {
8
+ id: string;
9
+ classes: string[];
10
+ values: Record<string, string>;
11
+ problems: string[];
12
+ };
13
+ /** A Boolean attribute is spelled exactly `true` or `false`. */
14
+ export function booleanAttribute(value: any, key: any): boolean;
@@ -290,6 +290,9 @@ export function runtimeOnlyFields(fields: readonly FieldSpec[]): FieldSpec[];
290
290
  * which is a Shortcode at both ends and resolves nothing.
291
291
  * @property {any|((fm: object) => any)} [value] - For a field with no `name`:
292
292
  * the constant, or a function deriving it from the frontmatter.
293
+ * @property {(fm: object, out: object) => boolean} [when] - Emit this field
294
+ * only when the note and fields already built meet the condition. The path
295
+ * remains declared for schema checks and authoring validation.
293
296
  * @property {boolean} [omitWhenAbsent] - **The key is left out entirely when
294
297
  * the note does not carry the field**, rather than written from a
295
298
  * declared default.
@@ -572,6 +575,12 @@ export type FieldSpec = {
572
575
  * the constant, or a function deriving it from the frontmatter.
573
576
  */
574
577
  value?: any | ((fm: object) => any);
578
+ /**
579
+ * - Emit this field
580
+ * only when the note and fields already built meet the condition. The path
581
+ * remains declared for schema checks and authoring validation.
582
+ */
583
+ when?: ((fm: object, out: object) => boolean) | undefined;
575
584
  /**
576
585
  * - **The key is left out entirely when
577
586
  * the note does not carry the field**, rather than written from a
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Format generated text using the destination file's Prettier configuration.
3
+ * @param {string} text
4
+ * @param {string} filepath
5
+ * @returns {Promise<string>}
6
+ */
7
+ export function formatGenerated(text: string, filepath: string): Promise<string>;
@@ -1,14 +1,22 @@
1
1
  /**
2
2
  * Resolves a dotted frontmatter key (e.g., "name.full") into the nested
3
3
  * value. Returns `defaultValue` if any path segment is missing.
4
+ * @param {object|null|undefined} fm - Parsed frontmatter.
5
+ * @param {string} key - A top-level or dotted property path.
6
+ * @param {unknown} [defaultValue] - Value for a missing property.
7
+ * @returns {unknown} The property value or default.
4
8
  */
5
- export function getFrontmatter(fm: any, key: any, defaultValue?: undefined): any;
9
+ export function getFrontmatter(fm: object | null | undefined, key: string, defaultValue?: unknown): unknown;
6
10
  /**
7
11
  * Reads a key from `fm.sohl` (the vault's nested system-fields block).
8
12
  * Supports dotted notation, e.g. sohlField(fm, "charges.value", 0).
9
13
  * Falls back to top-level `fm[key]` if `sohl` doesn't carry the key.
14
+ * @param {object|null|undefined} fm - Parsed frontmatter.
15
+ * @param {string} key - A top-level or dotted property path.
16
+ * @param {unknown} [defaultValue] - Value for a missing property.
17
+ * @returns {unknown} The system value, top-level value, or default.
10
18
  */
11
- export function sohlField(fm: any, key: any, defaultValue?: undefined): any;
19
+ export function sohlField(fm: object | null | undefined, key: string, defaultValue?: unknown): unknown;
12
20
  /**
13
21
  * Read a `sohl:` field, seeing the **destination** position as well.
14
22
  *
@@ -139,11 +147,13 @@ export function requireSubType(fm: object, ctx?: string): string;
139
147
  * - Array of "Label:MaxValue" strings, e.g. ["Ugly:4", "Plain:12"]
140
148
  * - Array of objects, e.g. [{ label, maxValue }]
141
149
  * Returns a normalized array of `{ label, maxValue: number }`.
150
+ * @param {unknown} raw - An authored threshold array.
151
+ * @returns {Array<{label: string, maxValue: number}>} Normalized thresholds.
142
152
  */
143
- export function parseValueDesc(raw: any): {
153
+ export function parseValueDesc(raw: unknown): Array<{
144
154
  label: string;
145
155
  maxValue: number;
146
- }[];
156
+ }>;
147
157
  /**
148
158
  * The compendium folder a note names.
149
159
  *
@@ -161,7 +161,7 @@ export function orderPassesByDependency(packs: readonly object[]): object[];
161
161
  * would produce them is not in it.
162
162
  *
163
163
  * Ordering answers the whole-package build; a run restricted to one pack
164
- * (`content-build package compile <name>`) cannot conjure the passes it left
164
+ * (`package-build package compile <name>`) cannot conjure the passes it left
165
165
  * out. Where their output is already on disk from an earlier run that is fine
166
166
  * — it is how compiling one pack at a time is meant to work — so this reports
167
167
  * only what is genuinely absent, and names the pack that would write it rather