@heroiclands/package-build 20.3.1 → 20.5.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 (195) hide show
  1. package/CHANGELOG.md +351 -0
  2. package/CONTENT.md +322 -110
  3. package/README.md +21 -10
  4. package/bin/content-build.mjs +204 -92
  5. package/bin/package-build.mjs +48 -15
  6. package/config.mjs +6 -8
  7. package/content-config.mjs +518 -151
  8. package/docs/api.md +1352 -0
  9. package/docs/commands.md +1609 -0
  10. package/docs/configuration.md +1432 -0
  11. package/docs/content-format.md +73 -74
  12. package/docs/diagnostics.md +356 -0
  13. package/docs/getting-started.md +813 -0
  14. package/docs/project-setup.md +469 -0
  15. package/e2e.mjs +4 -4
  16. package/engine/actor-compiler.mjs +64 -61
  17. package/engine/address-charset.mjs +6 -6
  18. package/engine/address-diff.mjs +57 -52
  19. package/engine/anchored-sections.mjs +1 -1
  20. package/engine/anchors.mjs +1 -1
  21. package/engine/base-compiler.mjs +42 -38
  22. package/engine/bundle-notes.mjs +4 -4
  23. package/engine/bundles.mjs +17 -8
  24. package/engine/code-fences.mjs +3 -3
  25. package/engine/compendiums.mjs +8 -8
  26. package/engine/compile-corpus.mjs +4 -5
  27. package/engine/content-address.mjs +24 -24
  28. package/engine/content-charset.mjs +1 -1
  29. package/engine/content-format-check.mjs +24 -25
  30. package/engine/content-format.mjs +8 -8
  31. package/engine/content-html.mjs +202 -0
  32. package/engine/content-icons.mjs +196 -165
  33. package/engine/content-index.mjs +61 -40
  34. package/engine/content-links.mjs +74 -41
  35. package/engine/content-lint.mjs +64 -34
  36. package/engine/content-package.mjs +7 -9
  37. package/engine/content-slug.mjs +2 -2
  38. package/engine/content-tables.mjs +38 -34
  39. package/engine/content-tree.mjs +1 -1
  40. package/engine/derived-fields.mjs +174 -0
  41. package/engine/diagnostics.mjs +3 -4
  42. package/engine/document-subtypes.mjs +6 -7
  43. package/engine/field-reference.mjs +8 -8
  44. package/engine/field-spec.mjs +29 -30
  45. package/engine/folder-notes.mjs +18 -16
  46. package/engine/foreign-catalog.mjs +8 -9
  47. package/engine/foundry-entries.mjs +19 -20
  48. package/engine/frontmatter-lint.mjs +95 -103
  49. package/engine/frontmatter.mjs +11 -11
  50. package/engine/generate.mjs +44 -39
  51. package/engine/helpers.mjs +147 -84
  52. package/engine/homepage.mjs +20 -22
  53. package/engine/ids.mjs +15 -15
  54. package/engine/index-records.mjs +4 -4
  55. package/engine/index.mjs +26 -10
  56. package/engine/item-compiler.mjs +54 -29
  57. package/engine/item-docs.mjs +11 -13
  58. package/engine/item-registry.mjs +13 -13
  59. package/engine/journals.mjs +24 -15
  60. package/engine/macros.mjs +3 -3
  61. package/engine/map-notes.mjs +6 -6
  62. package/engine/metadata-index.mjs +5 -5
  63. package/engine/note-claims.mjs +51 -41
  64. package/engine/note-ids.mjs +5 -5
  65. package/engine/note-package.mjs +4 -4
  66. package/engine/note-renames.mjs +3 -3
  67. package/engine/note-schemas.mjs +3 -8
  68. package/engine/note-vocabulary.mjs +56 -54
  69. package/engine/pack-config.mjs +39 -25
  70. package/engine/pack-router.mjs +0 -0
  71. package/engine/pdf-build.mjs +464 -0
  72. package/engine/pdf-fonts.mjs +420 -0
  73. package/engine/pdf-render.mjs +798 -0
  74. package/engine/pdf-toc.mjs +525 -0
  75. package/engine/prose-config.mjs +9 -9
  76. package/engine/prose-lint.mjs +12 -13
  77. package/engine/region-events.mjs +2 -2
  78. package/engine/retired-fields.mjs +24 -22
  79. package/engine/runtime-only-fields.mjs +1 -1
  80. package/engine/scene-levels.mjs +1 -1
  81. package/engine/scenes.mjs +33 -25
  82. package/engine/schema-check.mjs +21 -21
  83. package/engine/schema-extract.mjs +1 -1
  84. package/engine/site-build.mjs +66 -50
  85. package/engine/site-index.mjs +17 -18
  86. package/engine/sql-tables.mjs +21 -13
  87. package/engine/subtype-registry.mjs +5 -4
  88. package/engine/system-block.mjs +18 -19
  89. package/engine/systems.mjs +2 -2
  90. package/engine/web-wikilinks.mjs +41 -38
  91. package/engine/wikilink-syntax.mjs +16 -16
  92. package/engine/wikilinks.mjs +40 -42
  93. package/hm3/actors.mjs +30 -22
  94. package/hm3/document-subtypes.mjs +5 -5
  95. package/hm3/index.mjs +2 -2
  96. package/hm3/item-builders.mjs +1 -1
  97. package/hm3/item-fields.mjs +3 -3
  98. package/hm3/items.mjs +28 -8
  99. package/hm3/template-priority.mjs +2 -2
  100. package/lang.mjs +3 -3
  101. package/manifest.mjs +17 -20
  102. package/package.json +1 -2
  103. package/release.mjs +66 -6
  104. package/sohl/actors.mjs +36 -28
  105. package/sohl/affiliation-standings.mjs +2 -2
  106. package/sohl/being-info.mjs +5 -5
  107. package/sohl/default-item-art.mjs +5 -5
  108. package/sohl/document-subtypes.mjs +5 -5
  109. package/sohl/index.mjs +3 -3
  110. package/sohl/item-builders.mjs +7 -7
  111. package/sohl/item-fields.mjs +8 -9
  112. package/sohl/items.mjs +28 -6
  113. package/sohl/kb-passes.mjs +5 -5
  114. package/sohl/note-schemas.mjs +12 -12
  115. package/sohl/skill-base.mjs +1 -1
  116. package/types/content-config.d.mts +91 -39
  117. package/types/e2e.d.mts +3 -3
  118. package/types/engine/actor-compiler.d.mts +45 -40
  119. package/types/engine/address-charset.d.mts +6 -6
  120. package/types/engine/address-diff.d.mts +60 -6
  121. package/types/engine/base-compiler.d.mts +27 -21
  122. package/types/engine/bundle-notes.d.mts +3 -3
  123. package/types/engine/bundles.d.mts +10 -1
  124. package/types/engine/code-fences.d.mts +3 -3
  125. package/types/engine/compendiums.d.mts +3 -3
  126. package/types/engine/compile-corpus.d.mts +1 -1
  127. package/types/engine/content-address.d.mts +20 -20
  128. package/types/engine/content-format-check.d.mts +6 -6
  129. package/types/engine/content-format.d.mts +2 -2
  130. package/types/engine/content-html.d.mts +78 -0
  131. package/types/engine/content-icons.d.mts +139 -92
  132. package/types/engine/content-index.d.mts +59 -15
  133. package/types/engine/content-links.d.mts +8 -8
  134. package/types/engine/content-lint.d.mts +8 -6
  135. package/types/engine/content-package.d.mts +6 -8
  136. package/types/engine/content-tables.d.mts +49 -18
  137. package/types/engine/derived-fields.d.mts +101 -0
  138. package/types/engine/diagnostics.d.mts +2 -2
  139. package/types/engine/document-subtypes.d.mts +3 -3
  140. package/types/engine/field-spec.d.mts +37 -39
  141. package/types/engine/folder-notes.d.mts +4 -5
  142. package/types/engine/foreign-catalog.d.mts +3 -3
  143. package/types/engine/foundry-entries.d.mts +6 -7
  144. package/types/engine/frontmatter-lint.d.mts +10 -9
  145. package/types/engine/frontmatter.d.mts +7 -7
  146. package/types/engine/generate.d.mts +7 -7
  147. package/types/engine/helpers.d.mts +128 -56
  148. package/types/engine/homepage.d.mts +16 -18
  149. package/types/engine/ids.d.mts +13 -13
  150. package/types/engine/index-records.d.mts +3 -3
  151. package/types/engine/index.d.mts +6 -0
  152. package/types/engine/item-compiler.d.mts +21 -5
  153. package/types/engine/item-docs.d.mts +2 -2
  154. package/types/engine/item-registry.d.mts +6 -6
  155. package/types/engine/journals.d.mts +12 -3
  156. package/types/engine/map-notes.d.mts +2 -2
  157. package/types/engine/metadata-index.d.mts +4 -4
  158. package/types/engine/note-claims.d.mts +30 -22
  159. package/types/engine/note-ids.d.mts +4 -4
  160. package/types/engine/note-package.d.mts +1 -1
  161. package/types/engine/note-renames.d.mts +3 -3
  162. package/types/engine/note-vocabulary.d.mts +31 -203
  163. package/types/engine/pack-config.d.mts +7 -7
  164. package/types/engine/pack-router.d.mts +1 -1
  165. package/types/engine/pdf-build.d.mts +42 -0
  166. package/types/engine/pdf-fonts.d.mts +30 -0
  167. package/types/engine/pdf-render.d.mts +144 -0
  168. package/types/engine/pdf-toc.d.mts +114 -0
  169. package/types/engine/prose-config.d.mts +9 -9
  170. package/types/engine/prose-lint.d.mts +3 -4
  171. package/types/engine/region-events.d.mts +2 -2
  172. package/types/engine/retired-fields.d.mts +10 -9
  173. package/types/engine/scenes.d.mts +10 -1
  174. package/types/engine/schema-check.d.mts +13 -13
  175. package/types/engine/site-build.d.mts +52 -25
  176. package/types/engine/site-index.d.mts +3 -4
  177. package/types/engine/sql-tables.d.mts +11 -5
  178. package/types/engine/subtype-registry.d.mts +3 -3
  179. package/types/engine/system-block.d.mts +3 -3
  180. package/types/engine/web-wikilinks.d.mts +7 -7
  181. package/types/engine/wikilink-syntax.d.mts +17 -17
  182. package/types/engine/wikilinks.d.mts +14 -14
  183. package/types/hm3/actors.d.mts +9 -1
  184. package/types/hm3/document-subtypes.d.mts +1 -1
  185. package/types/hm3/items.d.mts +9 -2
  186. package/types/hm3/template-priority.d.mts +1 -1
  187. package/types/manifest.d.mts +8 -8
  188. package/types/release.d.mts +15 -4
  189. package/types/sohl/actors.d.mts +12 -4
  190. package/types/sohl/affiliation-standings.d.mts +2 -2
  191. package/types/sohl/being-info.d.mts +2 -2
  192. package/types/sohl/document-subtypes.d.mts +1 -1
  193. package/types/sohl/items.d.mts +9 -2
  194. package/types/sohl/note-schemas.d.mts +1 -1
  195. package/MIGRATING.md +0 -608
@@ -78,6 +78,7 @@ import yargs from "yargs";
78
78
  import { hideBin } from "yargs/helpers";
79
79
 
80
80
  import { loadPackageBuildConfig } from "../config.mjs";
81
+ import { compilesFoundryDocuments } from "../content-config.mjs";
81
82
  import { loadPackConfig, packConfigPath } from "../engine/pack-config.mjs";
82
83
  import { cleanBuildArtifacts, stageAssets } from "../stage.mjs";
83
84
  import { buildSchemaArtifact } from "../engine/schema-extract.mjs";
@@ -133,7 +134,7 @@ function die(err) {
133
134
  const message = err instanceof Error ? err.message : String(err);
134
135
  // A located diagnostic already starts with `file:line:column:`, which is
135
136
  // exactly the position a parser reads the path from — prefixing it would
136
- // yield a filename no editor can open (#95).
137
+ // yield a filename no editor can open.
137
138
  console.error(
138
139
  /** @type {{located?: boolean}} */ (err)?.located ? message : `package-build: ${message}`,
139
140
  );
@@ -325,7 +326,7 @@ async function formatGenerated(text, filepath) {
325
326
  *
326
327
  * The producing half of the check `content-build lint` runs: Foundry discards
327
328
  * an unknown `system` key at construction and says nothing, so a content build
328
- * needs to know what a document will actually receive (#60). It cannot ask a
329
+ * needs to know what a document will actually receive. It cannot ask a
329
330
  * running Foundry, and it cannot read `defineSchema()` from a sibling checkout,
330
331
  * so the system publishes the field sets as data — the same shape the link
331
332
  * manifest already uses for addresses.
@@ -413,6 +414,18 @@ function manifestCommand() {
413
414
  handler: handler(async () => {
414
415
  const config = loadPackageBuildConfig();
415
416
  const shared = loadPackConfig();
417
+ // Refused rather than written: a manifest is the file Foundry reads
418
+ // to install a package, and a documentation package is not one. An
419
+ // emitted `module.json` would advertise an installable package with
420
+ // no packs, no compatibility range and no id — the plausible lie
421
+ // this toolchain refuses everywhere else.
422
+ if (!compilesFoundryDocuments(shared)) {
423
+ die(
424
+ `\`packageKind: ${shared.packageKind}\` ships no Foundry ` +
425
+ `package, so there is no manifest to generate. The site ` +
426
+ `and the book are built by \`content-build\`.`,
427
+ );
428
+ }
416
429
  const packageJson = readPackageJson(config);
417
430
 
418
431
  let flags;
@@ -704,16 +717,6 @@ function langHardcoded(config) {
704
717
  );
705
718
  }
706
719
 
707
- /**
708
- * `lang <action>` — the three localization guards.
709
- *
710
- * They are three questions about one subject, and each is blind to what the
711
- * others see: `check` asks whether the file will load at all, `coverage`
712
- * whether the keys and the code agree, `hardcoded` whether the markup ever
713
- * asks for a key in the first place.
714
- *
715
- * @returns {object} The yargs command module.
716
- */
717
720
  /**
718
721
  * `package-build yaml` — lint note frontmatter and every YAML file.
719
722
  *
@@ -826,6 +829,16 @@ function labelsCheck(args) {
826
829
  console.log(`package-build: registry and §3 agree (${count} labels).`);
827
830
  }
828
831
 
832
+ /**
833
+ * `lang <action>` — the three localization guards.
834
+ *
835
+ * They are three questions about one subject, and each is blind to what the
836
+ * others see: `check` asks whether the file will load at all, `coverage`
837
+ * whether the keys and the code agree, `hardcoded` whether the markup ever
838
+ * asks for a key in the first place.
839
+ *
840
+ * @returns {object} The yargs command module.
841
+ */
829
842
  function langCommand() {
830
843
  return {
831
844
  command: "lang <action>",
@@ -931,17 +944,37 @@ function releaseCommand() {
931
944
  return {
932
945
  command: "release",
933
946
  describe: "Package the staged build for release",
934
- builder: (y) => y,
935
- handler: handler(async () => {
947
+ builder: (y) =>
948
+ y.option("no-pdf", {
949
+ describe:
950
+ "Skip the content-tree book. A package that publishes no content " +
951
+ "already builds none; this is for a release that has a tree and " +
952
+ "does not want the book.",
953
+ type: "boolean",
954
+ }),
955
+ handler: handler(async (argv) => {
936
956
  const config = loadPackageBuildConfig();
937
- const { zip, version, bytes } = await packRelease({
957
+ const result = await packRelease({
938
958
  artifact: config.artifact,
959
+ pdf: argv.pdf !== false,
939
960
  });
961
+ const { zip, version, bytes } = result;
940
962
  console.log(
941
963
  `✅ Packaged ${version} for release: ` +
942
964
  `${path.relative(config.rootDir, zip)} ` +
943
965
  `(${(bytes / 1024 / 1024).toFixed(1)} MB)`,
944
966
  );
967
+ // Reported, never fatal: the archive above is the release, and a
968
+ // book that would not set is a problem to fix rather than a reason
969
+ // to have published nothing.
970
+ for (const finding of result.pdfFindings ?? []) {
971
+ console.error(`${finding.file ?? "book"}: ${finding.severity}: ${finding.message}`);
972
+ }
973
+ if (result.pdf) {
974
+ console.log(`📕 Book: ${path.relative(config.rootDir, result.pdf)}`);
975
+ } else if (result.pdfSkipped) {
976
+ console.log(` No book: ${result.pdfSkipped}`);
977
+ }
945
978
  }),
946
979
  };
947
980
  }
package/config.mjs CHANGED
@@ -29,10 +29,8 @@
29
29
  * loader checks that the section is a mapping and hands it back frozen;
30
30
  * everything inside it is validated here.
31
31
  *
32
- * **That section used to be a reservation.** Until 3.0.0 these were two
33
- * packages, and `packageBuild:` was a block `@heroiclands/content-build`
34
- * carried on behalf of a toolchain it knew nothing about. One package now owns
35
- * the whole file, so it is an ordinary section — but the validation split is
32
+ * **That section is not a reservation.** One package owns the whole file, so
33
+ * `packageBuild:` is an ordinary section — but the validation split is
36
34
  * kept, because it is what stops a key being checked twice against two
37
35
  * disagreeing ideas of what it means.
38
36
  *
@@ -150,7 +148,7 @@ const ARTIFACT_OF_KIND = Object.freeze({
150
148
  *
151
149
  * The dotted path rides on the error as `field` as well as appearing in the
152
150
  * message, so {@link loadPackageBuildConfig} — the half that knows which file
153
- * was read — can resolve it to a line and column (#95). This half stays pure.
151
+ * was read — can resolve it to a line and column. This half stays pure.
154
152
  *
155
153
  * @param {string} where - Dotted path of the offending key.
156
154
  * @param {string} problem - What is wrong with it.
@@ -802,8 +800,8 @@ export function resolvePackageBuildConfig(shared) {
802
800
  e2eSuite: normalizeE2ESuite(e2eInput.suite),
803
801
  // Declaring nothing keeps the old contract — the suite's exit status is
804
802
  // taken at its word. Declaring where results land is what lets the
805
- // harness tell "the suite ran and passed" from "the suite did not run"
806
- // (#153); a repository that wants that distinction has to say where to
803
+ // harness tell "the suite ran and passed" from "the suite did not run";
804
+ // a repository that wants that distinction has to say where to
807
805
  // look for it, because the harness does not know what the suite is.
808
806
  e2eResults: normalizeGlobs(e2eInput.results, [], "packageBuild.e2e.results"),
809
807
  e2eBuild,
@@ -831,7 +829,7 @@ export function loadPackageBuildConfig() {
831
829
  } catch (err) {
832
830
  // The pure half names the offending key and nothing else; this half
833
831
  // knows the file it was read from, so the position is attached here
834
- // (#95) — the same boundary `configFromData` is for the rest of the
832
+ // — the same boundary `configFromData` is for the rest of the
835
833
  // configuration.
836
834
  throw locateConfigError(err, packConfigPath());
837
835
  }