@heroiclands/package-build 17.1.0 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +1773 -0
  2. package/CONTENT.md +288 -72
  3. package/README.md +1 -1
  4. package/bin/content-build.mjs +218 -137
  5. package/bin/package-build.mjs +43 -0
  6. package/content-config.mjs +62 -67
  7. package/docs/content-format.md +768 -58
  8. package/engine/actor-compiler.mjs +586 -0
  9. package/engine/address-charset.mjs +11 -8
  10. package/engine/address-diff.mjs +266 -22
  11. package/engine/anchored-sections.mjs +83 -0
  12. package/engine/anchors.mjs +83 -0
  13. package/engine/base-compiler.mjs +148 -18
  14. package/engine/bundle-notes.mjs +276 -0
  15. package/engine/bundles.mjs +307 -0
  16. package/engine/code-fences.mjs +103 -0
  17. package/engine/compile-corpus.mjs +89 -0
  18. package/engine/content-address.mjs +267 -5
  19. package/engine/content-format-check.mjs +54 -11
  20. package/engine/content-format.mjs +37 -5
  21. package/engine/content-index.mjs +394 -111
  22. package/engine/content-links.mjs +185 -77
  23. package/engine/content-lint.mjs +232 -14
  24. package/engine/content-package.mjs +2 -1
  25. package/engine/content-tables.mjs +99 -3
  26. package/engine/document-subtypes.mjs +49 -6
  27. package/engine/field-reference.mjs +1 -1
  28. package/engine/field-spec.mjs +56 -6
  29. package/engine/folder-notes.mjs +470 -0
  30. package/engine/foreign-catalog.mjs +195 -4
  31. package/engine/{manifest-emit.mjs → foundry-entries.mjs} +78 -81
  32. package/engine/frontmatter-lint.mjs +245 -19
  33. package/engine/frontmatter.mjs +88 -8
  34. package/engine/generate.mjs +304 -13
  35. package/engine/helpers.mjs +293 -64
  36. package/engine/ids.mjs +137 -2
  37. package/engine/index-records.mjs +126 -0
  38. package/engine/index.mjs +23 -5
  39. package/engine/item-compiler.mjs +349 -0
  40. package/engine/item-docs.mjs +7 -1
  41. package/engine/item-registry.mjs +6 -0
  42. package/engine/journals.mjs +93 -27
  43. package/engine/macros.mjs +4 -2
  44. package/engine/metadata-index.mjs +495 -0
  45. package/engine/note-claims.mjs +146 -25
  46. package/engine/note-ids.mjs +112 -0
  47. package/engine/note-renames.mjs +134 -0
  48. package/engine/note-schemas.mjs +25 -0
  49. package/engine/note-vocabulary.mjs +110 -27
  50. package/engine/pack-config.mjs +4 -0
  51. package/engine/pack-router.mjs +23 -0
  52. package/engine/retired-fields.mjs +137 -3
  53. package/engine/scenes.mjs +66 -34
  54. package/engine/schema-check.mjs +58 -17
  55. package/engine/site-build.mjs +71 -12
  56. package/engine/site-index.mjs +20 -7
  57. package/engine/sql-tables.mjs +485 -0
  58. package/engine/subtype-registry.mjs +102 -0
  59. package/engine/system-block.mjs +96 -12
  60. package/engine/systems.mjs +201 -0
  61. package/engine/web-wikilinks.mjs +50 -20
  62. package/engine/wikilink-syntax.mjs +17 -8
  63. package/engine/wikilinks.mjs +124 -51
  64. package/engine/yaml-lint.mjs +282 -0
  65. package/hm3/actors.mjs +352 -0
  66. package/hm3/default-item-art.mjs +75 -0
  67. package/hm3/document-subtypes.mjs +134 -0
  68. package/hm3/index.mjs +56 -0
  69. package/hm3/item-builders.mjs +84 -0
  70. package/hm3/item-fields.mjs +180 -0
  71. package/hm3/items.mjs +96 -0
  72. package/hm3/template-priority.mjs +85 -0
  73. package/labels.mjs +191 -0
  74. package/manifest.mjs +43 -2
  75. package/package.json +19 -4
  76. package/release.mjs +62 -7
  77. package/sohl/actors.mjs +33 -487
  78. package/sohl/being-info.mjs +16 -7
  79. package/sohl/default-item-art.mjs +14 -3
  80. package/sohl/document-subtypes.mjs +16 -10
  81. package/sohl/item-builders.mjs +14 -5
  82. package/sohl/item-fields.mjs +68 -7
  83. package/sohl/items.mjs +44 -258
  84. package/sohl/note-schemas.mjs +2 -2
  85. package/types/content-config.d.mts +21 -42
  86. package/types/engine/actor-compiler.d.mts +204 -0
  87. package/types/engine/address-charset.d.mts +11 -8
  88. package/types/engine/address-diff.d.mts +53 -5
  89. package/types/engine/anchored-sections.d.mts +21 -0
  90. package/types/engine/anchors.d.mts +20 -0
  91. package/types/engine/base-compiler.d.mts +17 -17
  92. package/types/engine/bundle-notes.d.mts +173 -0
  93. package/types/engine/bundles.d.mts +60 -0
  94. package/types/engine/code-fences.d.mts +43 -0
  95. package/types/engine/compile-corpus.d.mts +32 -0
  96. package/types/engine/content-address.d.mts +205 -5
  97. package/types/engine/content-format-check.d.mts +6 -2
  98. package/types/engine/content-format.d.mts +57 -1
  99. package/types/engine/content-index.d.mts +64 -80
  100. package/types/engine/content-links.d.mts +52 -7
  101. package/types/engine/content-lint.d.mts +10 -1
  102. package/types/engine/content-package.d.mts +2 -1
  103. package/types/engine/content-tables.d.mts +21 -39
  104. package/types/engine/document-subtypes.d.mts +37 -3
  105. package/types/engine/field-spec.d.mts +76 -5
  106. package/types/engine/folder-notes.d.mts +159 -0
  107. package/types/engine/foreign-catalog.d.mts +53 -0
  108. package/types/engine/{manifest-emit.d.mts → foundry-entries.d.mts} +16 -38
  109. package/types/engine/frontmatter-lint.d.mts +10 -2
  110. package/types/engine/frontmatter.d.mts +64 -0
  111. package/types/engine/generate.d.mts +38 -0
  112. package/types/engine/helpers.d.mts +94 -30
  113. package/types/engine/ids.d.mts +96 -0
  114. package/types/engine/index-records.d.mts +68 -0
  115. package/types/engine/index.d.mts +9 -3
  116. package/types/engine/item-compiler.d.mts +131 -0
  117. package/types/engine/journals.d.mts +47 -9
  118. package/types/engine/metadata-index.d.mts +226 -0
  119. package/types/engine/note-claims.d.mts +57 -11
  120. package/types/engine/note-ids.d.mts +38 -0
  121. package/types/engine/note-renames.d.mts +102 -0
  122. package/types/engine/note-vocabulary.d.mts +44 -8
  123. package/types/engine/retired-fields.d.mts +75 -0
  124. package/types/engine/scenes.d.mts +3 -2
  125. package/types/engine/schema-check.d.mts +25 -4
  126. package/types/engine/site-build.d.mts +4 -4
  127. package/types/engine/site-index.d.mts +1 -1
  128. package/types/engine/sql-tables.d.mts +185 -0
  129. package/types/engine/subtype-registry.d.mts +49 -0
  130. package/types/engine/system-block.d.mts +40 -1
  131. package/types/engine/systems.d.mts +106 -0
  132. package/types/engine/web-wikilinks.d.mts +4 -2
  133. package/types/engine/wikilink-syntax.d.mts +10 -3
  134. package/types/engine/wikilinks.d.mts +41 -13
  135. package/types/engine/yaml-lint.d.mts +107 -0
  136. package/types/hm3/actors.d.mts +48 -0
  137. package/types/hm3/default-item-art.d.mts +42 -0
  138. package/types/hm3/document-subtypes.d.mts +24 -0
  139. package/types/hm3/index.d.mts +7 -0
  140. package/types/hm3/item-builders.d.mts +11 -0
  141. package/types/hm3/item-fields.d.mts +12 -0
  142. package/types/hm3/items.d.mts +23 -0
  143. package/types/hm3/template-priority.d.mts +21 -0
  144. package/types/manifest.d.mts +22 -1
  145. package/types/release.d.mts +9 -4
  146. package/types/sohl/actors.d.mts +7 -74
  147. package/types/sohl/being-info.d.mts +8 -27
  148. package/types/sohl/default-item-art.d.mts +5 -3
  149. package/types/sohl/items.d.mts +17 -32
  150. package/engine/foreign-manifests.mjs +0 -126
  151. package/engine/kb-manifest.mjs +0 -490
  152. package/types/engine/foreign-manifests.d.mts +0 -43
  153. package/types/engine/kb-manifest.d.mts +0 -241
@@ -34,7 +34,6 @@
34
34
  * - { from: assets/icons, to: assets/icons }
35
35
  * publish:
36
36
  * site: content
37
- * manifests: { publish: true, consume: true }
38
37
  * ```
39
38
  *
40
39
  * `defineConfig` is the whole of the contract: it validates the object, fills
@@ -70,6 +69,7 @@ import path from "node:path";
70
69
  // a cycle around a consumer's config file (see `engine/pack-config.mjs`).
71
70
  import { ADDRESS_SEGMENT_PATTERN, isAddressSegment } from "./engine/address-charset.mjs";
72
71
  import { MAP_TYPES, PACK_BY_TYPE } from "./engine/ids.mjs";
72
+ import { NOTE_VOCABULARY } from "./engine/note-vocabulary.mjs";
73
73
 
74
74
  /**
75
75
  * The two kinds of Foundry package a content module can be built into. The
@@ -88,8 +88,6 @@ export const PACKAGE_KINDS = /** @type {const} */ (["systems", "modules"]);
88
88
  */
89
89
  export const DEFAULT_PATHS = /** @type {const} */ ({
90
90
  content: "assets/content",
91
- manifests: "assets/manifests",
92
- manifestOut: "build/manifests",
93
91
  // Where `content-index` writes this package's note index. Under `build/`
94
92
  // because it is derived and disposable — regenerating it costs a
95
93
  // frontmatter parse — and emphatically not under `stage`, which is mirrored
@@ -101,6 +99,13 @@ export const DEFAULT_PATHS = /** @type {const} */ ({
101
99
  // Where a dependency declaring `itemCatalog: true` is unpacked. Under
102
100
  // `build/` because it is derived, disposable, and version-keyed.
103
101
  foreignCache: "build/cache/foreign",
102
+ // Where a dependency's published content index is fetched to (#239). A
103
+ // sibling of the item catalogue rather than a subdirectory of it: the two
104
+ // are fetched for different dependency sets — a catalogue only where
105
+ // `itemCatalog: true` is declared, an index for *every* declared
106
+ // dependency — so nesting one under the other would imply a containment
107
+ // that does not hold.
108
+ metadataCache: "build/cache/metadata",
104
109
  });
105
110
 
106
111
  /**
@@ -161,7 +166,7 @@ export const RETIRED_ADDRESS_KEYS = Object.freeze({
161
166
  * `sohl`, whose knowledgebase is one surface among several, and empty for
162
167
  * `thalorna`, whose site is nothing but its content. It is not the package's
163
168
  * own mount point: where the package itself is served is the consuming build's
164
- * knowledge, held in `PACKAGE_BASE` (`engine/kb-manifest.mjs`) and prefixed at
169
+ * knowledge, held in `PACKAGE_BASE` (`engine/content-address.mjs`) and prefixed at
165
170
  * resolve time, so it is never recorded here (#1465).
166
171
  *
167
172
  * It is the whole scheme: `landing`, the key that named which note addressed a
@@ -183,7 +188,7 @@ export const DEFAULT_ADDRESS_SCHEME = Object.freeze({
183
188
  *
184
189
  * - `homepage` — the authored homepage, and **no other page**. The content tree
185
190
  * is not walked for pages, `site.sections` / `site.trees` / `site.landing`
186
- * emit nothing, and link-manifest entries carry no web `path`.
191
+ * emit nothing, and nothing serves a page for its addresses.
187
192
  * - `content` — the homepage *plus* every page the content tree publishes: the
188
193
  * knowledgebase, the extra trees, the section landings.
189
194
  *
@@ -217,7 +222,7 @@ export const SITE_MODES = /** @type {const} */ (["homepage", "content"]);
217
222
  * Whether this package publishes the pages its content tree compiles to.
218
223
  *
219
224
  * The one question every reader of the mode actually asks — the site build, to
220
- * decide whether to walk the tree at all, and the link-manifest emitter, to
225
+ * decide whether to walk the tree at all, and the content index, to
221
226
  * decide whether an entry carries a web `path`. Written once here so the two
222
227
  * cannot come to disagree about what a mode means.
223
228
  *
@@ -303,13 +308,6 @@ export function publishesContentPages(config) {
303
308
  *
304
309
  * @typedef {object} PathsInput
305
310
  * @property {string} [content] Content tree root.
306
- * @property {string} [manifests] Vendored cross-package link manifests,
307
- * read by `links`. Inbound.
308
- * @property {string} [manifestOut] Where `manifest` writes this package's
309
- * own link manifest. Outbound, and a
310
- * build artifact — the published copy is
311
- * the one a consumer vendors into its
312
- * `manifests` directory.
313
311
  * @property {string} [contentIndex] Where `content-index` writes this
314
312
  * package's note index. Outbound, and a
315
313
  * derived artifact — never a source, and
@@ -317,6 +315,14 @@ export function publishesContentPages(config) {
317
315
  * @property {string} [packJson] Build-only per-entry JSON intermediate.
318
316
  * @property {string} [stage] Compiled LevelDB packs.
319
317
  * @property {string} [unpack] Where `unpack` extracts JSON back to.
318
+ * @property {string} [foreignCache] Where a dependency declaring
319
+ * `itemCatalog: true` is unpacked.
320
+ * Inbound, and fetched rather than
321
+ * committed.
322
+ * @property {string} [metadataCache] Where a dependency's published content
323
+ * index is fetched to (#239). Inbound,
324
+ * for *every* declared dependency, not
325
+ * only those supplying a catalogue.
320
326
  */
321
327
 
322
328
  /**
@@ -324,12 +330,12 @@ export function publishesContentPages(config) {
324
330
  *
325
331
  * @typedef {object} ResolvedPaths
326
332
  * @property {string} content
327
- * @property {string} manifests
328
- * @property {string} manifestOut
329
333
  * @property {string} contentIndex
330
334
  * @property {string} packJson
331
335
  * @property {string} stage
332
336
  * @property {string} unpack
337
+ * @property {string} foreignCache
338
+ * @property {string} metadataCache
333
339
  */
334
340
 
335
341
  /**
@@ -368,27 +374,10 @@ export function publishesContentPages(config) {
368
374
  * @typedef {Record<string, unknown>} PackageBuildSection
369
375
  */
370
376
 
371
- /**
372
- * The two manifest switches. A package may publish a link manifest, consume
373
- * other packages' manifests, both, or neither — the four combinations are all
374
- * real (see #1385/#1446: `kethira` consumes but never publishes).
375
- *
376
- * @typedef {object} ManifestSwitches
377
- * @property {boolean} publish Emit this package's link manifest.
378
- * @property {boolean} consume Resolve cross-package links through vendored manifests.
379
- */
380
-
381
377
  /**
382
378
  * @typedef {object} PublishSwitches
383
379
  * @property {SiteMode} site How much of this package reaches the web.
384
380
  * See {@link SITE_MODES}.
385
- * @property {ManifestSwitches} manifests
386
- */
387
-
388
- /**
389
- * @typedef {object} ManifestSwitchesInput
390
- * @property {boolean} [publish]
391
- * @property {boolean} [consume]
392
381
  */
393
382
 
394
383
  /**
@@ -469,7 +458,6 @@ export function publishesContentPages(config) {
469
458
  /**
470
459
  * @typedef {object} PublishSwitchesInput
471
460
  * @property {SiteMode} [site]
472
- * @property {ManifestSwitchesInput} [manifests]
473
461
  * @property {AddressSchemeInput} [address]
474
462
  */
475
463
 
@@ -694,8 +682,7 @@ const STATS_KEYS = ["lastModifiedBy"];
694
682
  * @type {symbol}
695
683
  */
696
684
  export const DERIVED_SYSTEM_VERSION = Symbol.for("package-build.derivedSystemVersion");
697
- const PUBLISH_KEYS = ["site", "manifests", "address"];
698
- const MANIFEST_KEYS = ["publish", "consume"];
685
+ const PUBLISH_KEYS = ["site", "address"];
699
686
  const ADDRESS_KEYS = ["prefix"];
700
687
 
701
688
  /** @param {unknown} value */
@@ -754,28 +741,37 @@ function requireNonEmptyString(value, field) {
754
741
  * The `contentPackage`, checked against the two rules an address puts on it.
755
742
  *
756
743
  * It is the first segment of every canonical address this repository publishes
757
- * (`sohl-skill-clmb`), and an address is read by counting hyphen-separated
758
- * segments. So the value carries two obligations that the rest of the
759
- * configuration does not, and #59 asks for both to be **enforced rather than
760
- * assumed** — the alternative is a package whose addresses are simply
761
- * unreadable, reported nowhere and discovered as links that resolve to nothing.
744
+ * (`package-system-type-shortcode`, so `sohl-none-doc-gear`), and an address is
745
+ * read by counting hyphen-separated segments. So the value carries two
746
+ * obligations that the rest of the configuration does not, and #59 asks for
747
+ * both to be **enforced rather than assumed** — the alternative is a package
748
+ * whose addresses are simply unreadable, reported nowhere and discovered as
749
+ * links that resolve to nothing.
762
750
  *
763
751
  * 1. _Alphanumeric_, so the hyphen stays purely a separator. `harn-adventures`
764
- * was the one violator, and its keys read as four segments and failed as a
765
- * `null` return from `readCanonicalKey` — a silence, not an error.
766
- * 2. _Not a note type_, because the package and the type are adjacent segments
767
- * drawn from two vocabularies. Keeping them disjoint is what lets a reader
768
- * take a name at face value instead of deciding which slot it is filling.
752
+ * was the one violator, and its keys read as one segment too many and failed
753
+ * as a `null` return from `readCanonicalKey` — a silence, not an error.
754
+ * 2. _Not a note type_, because a written address is a **partial** one: the
755
+ * shorter forms drop segments from the left, so `skill-clmb` and
756
+ * `sohl-skill-clmb` are both addresses and position alone no longer says
757
+ * which vocabulary a leading segment is drawn from. The reader decides that
758
+ * by asking whether the name is a known package, and a name in both
759
+ * vocabularies makes one target readable two ways with no defensible pick.
760
+ * Keeping the two disjoint is what lets a name be taken at face value; that
761
+ * the package and the type are no longer *adjacent* segments (#59 put the
762
+ * system between them) changes nothing, because the hazard was never
763
+ * adjacency — it is that a short form omits the slots in between.
769
764
  * One such collision is structural and cannot be fixed — `sohl` is both a
770
765
  * content package and a system id, because Foundry requires a system
771
- * package's id to *be* its system id which is the reason to prevent the
772
- * ones that are avoidable.
766
+ * package's id to *be* its system id, and `sohl-sohl-skill-clmb` is the
767
+ * honest address that results — which is the reason to prevent the ones that
768
+ * are avoidable.
773
769
  *
774
770
  * @param {unknown} value - The configured `contentPackage`.
775
771
  * @param {ReadonlySet<string>} docEntryTypes - Every type whose prose compiles
776
772
  * to a documentation entry: the item types plus `macro` and the map types.
777
- * With {@link PACK_BY_TYPE} and the `doc`-prefixed forms, this is the whole
778
- * type vocabulary an address may write.
773
+ * With {@link PACK_BY_TYPE}, {@link NOTE_VOCABULARY} and the `doc`-prefixed
774
+ * forms, this is the whole type vocabulary an address may write.
779
775
  * @returns {string} The value, unchanged.
780
776
  */
781
777
  function requireContentPackage(value, docEntryTypes) {
@@ -785,14 +781,25 @@ function requireContentPackage(value, docEntryTypes) {
785
781
  "contentPackage",
786
782
  `is \`${pkg}\`, which is not alphanumeric. It is the first ` +
787
783
  `segment of every address this package publishes ` +
788
- `(\`${pkg}-<type>-<shortcode>\`), and an address is read by ` +
784
+ `(\`${pkg}-<system>-<type>-<shortcode>\`), and an address is read by ` +
789
785
  `counting hyphen-separated segments — so anything outside ` +
790
786
  "`[A-Za-z0-9]` here makes those addresses unreadable rather " +
791
787
  "than merely ugly. `harn-adventures` became `harnadventures`",
792
788
  );
793
789
  }
790
+ // The closed vocabulary is read alongside the configured registries, not
791
+ // instead of them, because neither is a superset of the other. The format's
792
+ // vocabulary holds every type a note may declare *however this repository
793
+ // is configured* — the reasoning `KNOWN_DOCUMENT_SUBTYPE_MAPS` already
794
+ // states — so `skill` and `bundle` are type names in a repository that
795
+ // declares no `itemBuilders`, where `docEntryTypes` alone would have let
796
+ // either through. The registries hold whatever a consumer declares beyond
797
+ // it. The `doc`-prefixed forms follow the registry, since a type that
798
+ // compiles no documentation entry has no `doc`-prefixed address to collide
799
+ // with.
794
800
  const typeNames = new Set([
795
801
  ...Object.keys(PACK_BY_TYPE),
802
+ ...Object.keys(NOTE_VOCABULARY),
796
803
  ...docEntryTypes,
797
804
  ...[...docEntryTypes].map((type) => `doc${type}`),
798
805
  ]);
@@ -800,10 +807,10 @@ function requireContentPackage(value, docEntryTypes) {
800
807
  fail(
801
808
  "contentPackage",
802
809
  `is \`${pkg}\`, which is also a note type — \`${pkg}-<shortcode>\` ` +
803
- "already addresses one. The package and the type are adjacent " +
804
- "segments of an address, and the two vocabularies are kept " +
805
- "disjoint so a reader never has to decide which slot a name " +
806
- "is filling. Rename the package",
810
+ "already addresses one. A written address may omit its leading " +
811
+ `segments, so \`${pkg}-<shortcode>\` reads as a type and a ` +
812
+ "shortcode and nothing but the two vocabularies being disjoint " +
813
+ "says which slot the name is filling. Rename the package",
807
814
  );
808
815
  }
809
816
  return pkg;
@@ -1598,7 +1605,7 @@ function normalizeOneRegistry(value, at) {
1598
1605
  * builder behind it (#1504) — and, with one registry, impossible to accept a
1599
1606
  * type a *second* system declares. A tree feeding two systems has both:
1600
1607
  * `spell`, `invocation` and `psionic` are HM3's, `mysticalability` and
1601
- * `projectilegear` are SoHL's, and `skill` is both systems' under one name and
1608
+ * `projectile` are SoHL's, and `skill` is both systems' under one name and
1602
1609
  * two data models.
1603
1610
  *
1604
1611
  * So `itemBuilders` accepts either form:
@@ -1765,7 +1772,6 @@ function normalizePublish(value) {
1765
1772
  if (value === undefined) {
1766
1773
  return Object.freeze({
1767
1774
  site: "homepage",
1768
- manifests: Object.freeze({ publish: false, consume: false }),
1769
1775
  address: Object.freeze({ ...DEFAULT_ADDRESS_SCHEME }),
1770
1776
  });
1771
1777
  }
@@ -1773,13 +1779,6 @@ function normalizePublish(value) {
1773
1779
  const publish = /** @type {Record<string, unknown>} */ (value);
1774
1780
  rejectUnknownKeys(publish, PUBLISH_KEYS, "publish.");
1775
1781
 
1776
- const manifestsInput = publish.manifests;
1777
- if (manifestsInput !== undefined && !isPlainObject(manifestsInput)) {
1778
- fail("publish.manifests", "must be an object");
1779
- }
1780
- const manifests = /** @type {Record<string, unknown>} */ (manifestsInput ?? {});
1781
- rejectUnknownKeys(manifests, MANIFEST_KEYS, "publish.manifests.");
1782
-
1783
1782
  const addressInput = publish.address;
1784
1783
  if (addressInput !== undefined && !isPlainObject(addressInput)) {
1785
1784
  fail("publish.address", "must be an object");
@@ -1815,10 +1814,6 @@ function normalizePublish(value) {
1815
1814
  return Object.freeze({
1816
1815
  site: normalizeSiteMode(publish.site),
1817
1816
  address: Object.freeze({ prefix }),
1818
- manifests: Object.freeze({
1819
- publish: optionalBoolean(manifests.publish, "publish.manifests.publish", false),
1820
- consume: optionalBoolean(manifests.consume, "publish.manifests.consume", false),
1821
- }),
1822
1817
  });
1823
1818
  }
1824
1819