@heroiclands/package-build 8.0.0 → 9.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 (75) hide show
  1. package/CHANGELOG.md +173 -0
  2. package/bin/content-build.mjs +44 -118
  3. package/bin/package-build.mjs +27 -69
  4. package/bin/report.mjs +1 -2
  5. package/bundle.mjs +2 -10
  6. package/config.mjs +31 -106
  7. package/container.mjs +13 -57
  8. package/content-config.mjs +45 -164
  9. package/coverage.mjs +14 -55
  10. package/deploy.mjs +4 -13
  11. package/e2e.mjs +16 -55
  12. package/engine/address-diff.mjs +1 -4
  13. package/engine/base-compiler.mjs +10 -28
  14. package/engine/code-fences.mjs +4 -13
  15. package/engine/compendiums.mjs +13 -37
  16. package/engine/content-address.mjs +2 -6
  17. package/engine/content-links.mjs +13 -44
  18. package/engine/content-lint.mjs +4 -15
  19. package/engine/content-slug.mjs +2 -6
  20. package/engine/content-tables.mjs +26 -79
  21. package/engine/diagnostics.mjs +4 -15
  22. package/engine/field-reference.mjs +6 -20
  23. package/engine/field-spec.mjs +1 -3
  24. package/engine/foreign-catalog.mjs +7 -22
  25. package/engine/foreign-manifests.mjs +1 -4
  26. package/engine/frontmatter-lint.mjs +6 -18
  27. package/engine/frontmatter.mjs +3 -8
  28. package/engine/generate.mjs +4 -16
  29. package/engine/helpers.mjs +13 -52
  30. package/engine/homepage.mjs +4 -15
  31. package/engine/ids.mjs +3 -12
  32. package/engine/item-registry.mjs +2 -6
  33. package/engine/journals.mjs +4 -14
  34. package/engine/kb-manifest.mjs +5 -17
  35. package/engine/macros.mjs +2 -10
  36. package/engine/manifest-emit.mjs +6 -17
  37. package/engine/map-notes.mjs +19 -69
  38. package/engine/note-package.mjs +1 -4
  39. package/engine/pack-config.mjs +17 -38
  40. package/engine/pack-router.mjs +1 -2
  41. package/engine/prose-config.mjs +20 -4
  42. package/engine/prose-lint.mjs +6 -14
  43. package/engine/region-events.mjs +1 -3
  44. package/engine/scene-levels.mjs +8 -22
  45. package/engine/scenes.mjs +13 -47
  46. package/engine/schema-check.mjs +1 -4
  47. package/engine/schema-extract.mjs +70 -45
  48. package/engine/site-build.mjs +12 -37
  49. package/engine/site-index.mjs +3 -15
  50. package/engine/web-wikilinks.mjs +4 -13
  51. package/engine/wikilinks.mjs +115 -167
  52. package/index.mjs +1 -5
  53. package/lang.mjs +1 -3
  54. package/manifest.mjs +10 -37
  55. package/markdownlint-config.mjs +1 -5
  56. package/package.json +1 -1
  57. package/sohl/actors.mjs +10 -40
  58. package/sohl/being-info.mjs +3 -6
  59. package/sohl/index.mjs +1 -6
  60. package/sohl/item-builders.mjs +1 -3
  61. package/sohl/item-fields.mjs +16 -34
  62. package/sohl/items.mjs +1 -3
  63. package/sohl/kb-passes.mjs +29 -39
  64. package/sohl/skill-base.mjs +7 -23
  65. package/stage.mjs +3 -13
  66. package/templates.mjs +4 -15
  67. package/types/bundle.d.mts +1 -1
  68. package/types/container.d.mts +2 -2
  69. package/types/coverage.d.mts +1 -1
  70. package/types/e2e.d.mts +4 -4
  71. package/types/engine/generate.d.mts +1 -1
  72. package/types/engine/helpers.d.mts +1 -1
  73. package/types/engine/schema-extract.d.mts +1 -1
  74. package/types/engine/site-index.d.mts +1 -1
  75. package/types/manifest.d.mts +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,178 @@
1
1
  # @heroiclands/package-build
2
2
 
3
+ ## 9.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 8e48f7e: Raise the shared `printWidth` from 80 to 100.
8
+
9
+ **Breaking for every consumer**, in the one way this configuration always is: a
10
+ repository that updates and runs `lint:format` will find every file reported
11
+ until it reformats. Nothing about a built package, an emitted document or a
12
+ manifest changes — this is hygiene, and it reaches users not at all.
13
+
14
+ **80 was inherited, not chosen.** The usual argument for it is reading measure,
15
+ and that argument does not apply here: `proseWrap` is left at Prettier's default
16
+ of `preserve`, so authored prose is **never reflowed**. Measured across the
17
+ content trees, prose lines run to a p90 of 378 characters and a maximum of
18
+ 5,531, entirely untouched by this number. What `printWidth` actually governs is
19
+ TypeScript and the YAML of a note's frontmatter.
20
+
21
+ **Both were measurably cramped.** Reformatting a third of the SoHL source at
22
+ each width:
23
+
24
+ | width | total lines | vs 80 | lines still over width |
25
+ | ----- | ----------- | ----- | ---------------------- |
26
+ | 80 | 31,198 | — | **1,399** |
27
+ | 90 | 30,328 | −2.8% | 193 |
28
+ | 100 | 29,672 | −4.9% | 75 |
29
+ | 120 | 28,850 | −7.5% | 25 |
30
+
31
+ The last column is the argument. At 80, Prettier _cannot_ honour the limit on
32
+ 1,399 lines — long string literals, `@src/…` specifiers, generic signatures — so
33
+ those lines are over-width regardless and their surroundings were broken up for
34
+ nothing. At 100 that falls to 75.
35
+
36
+ The same knee appears in content. An item entry written in flow style —
37
+ `{ shortcode: X, type: skill, name: …, system: { … } }` — typically lands in the
38
+ low 90s, so of 318,030 entries across the two largest trees, 90.8% fit on one
39
+ line at 80 and **95.3% at 100**, with almost nothing gained in between. 120 buys
40
+ another 0.8 points and is not worth a second reformat.
41
+
42
+ **This package's own config stops restating the values.** `prettier.config.js`
43
+ carried its own copy of all twelve options with a comment saying they were
44
+ "matched to" the SoHL repository — already the wrong authority once
45
+ `PRETTIER_BASE` existed here, and a copy is a copy: raising the width would have
46
+ left the package that _defines_ the shared style as the one repository not
47
+ written in it. It now re-exports `PRETTIER_CONFIG`, so there is nothing left to
48
+ drift.
49
+
50
+ This release reformats this repository: 147 files, 2,677 lines shorter.
51
+
52
+ **Bump**
53
+
54
+ _Major._ Consumers' `lint:format` fails until they reformat, which is the whole
55
+ of the breakage and is a one-command fix.
56
+
57
+ ## 8.1.0
58
+
59
+ ### Minor Changes
60
+
61
+ - 333c340: Follow a spread of an imported schema function, and refuse a computed field name.
62
+
63
+ Two defects in `package-build schema`, both found by running it against real
64
+ content rather than by reading it.
65
+
66
+ **A shared base schema spread from another file was dropped, in silence.** A
67
+ concrete DataModel spreads a shared builder by name — `...defineSohlDataSchema()`
68
+ — and the resolver looked for that function only in the file doing the
69
+ spreading. When it was imported, the lookup found nothing and the spread
70
+ contributed nothing, with no error: a spread of a missing function read exactly
71
+ like a spread of an empty one.
72
+
73
+ The effect was not small. Every SoHL Item and Actor subtype lost `shortcode`,
74
+ `actionDefs`, `lastRun` and `scheduledActions` from the published schema. So
75
+ content correctly authoring `system.shortcode` — which SoHL requires to be
76
+ unique per `(type, shortcode)` on an actor, and which content therefore sets
77
+ deliberately — was reported as emitting a field no DataModel declares. The check
78
+ was accusing the content of the reader's own blind spot, which is worse than not
79
+ checking: it is a false accusation delivered with the same confidence as a true
80
+ one.
81
+
82
+ An imported spread is now resolved through the import, with a same-file
83
+ definition still taking precedence.
84
+
85
+ **A computed field name is now refused rather than published as source text.**
86
+ `[`${name}Date`]: worldTimeDateField()` takes its real name from an argument
87
+ this reader does not evaluate, and the previous behaviour handed back the source
88
+ text — putting a field called ``[`${name}Date`]`` into the schema. That field
89
+ matches nothing any builder could emit: absent for checking purposes while
90
+ looking present, and permanently reported as unemitted.
91
+
92
+ It now stops, naming the file and the key:
93
+
94
+ ```text
95
+ temporal-fields.ts declares a schema field with a computed name,
96
+ `[`${name}DurationFormula`]`, whose value depends on an argument this reader
97
+ does not evaluate. Write the keys out so the published schema can name them.
98
+ ```
99
+
100
+ Stopping is the same stance `compareFields` already takes on an artifact of the
101
+ wrong version: the schema is a contract other repositories read, so a contract
102
+ this cannot state is worth failing for rather than approximating. The fix
103
+ belongs at the source, where the names are actually decided.
104
+
105
+ **Bump**
106
+
107
+ _Minor._ Repositories whose schemas spread an imported builder will publish more
108
+ fields than before — which is the correction. A repository using computed field
109
+ names now fails where it previously produced a wrong artifact; none does today
110
+ except the one this was found on, and that is being fixed at the source.
111
+
112
+ ### Patch Changes
113
+
114
+ - 2319a56: Bump `markdown-it` from 15.0.0 to 15.0.1 (#121).
115
+
116
+ The surface is unchanged from the 15.0.0 adoption: one constructor,
117
+ `markdownit({ html: true })` in `engine/helpers.mjs`, and three `md.render()`
118
+ call sites — `engine/helpers.mjs`, `engine/journals.mjs` and `sohl/actors.mjs`.
119
+ No plugin is installed, no renderer rule is overridden, and `linkify` is left at
120
+ its default `false`. That last fact decides most of this release.
121
+
122
+ **Two of the five changes cannot reach a build that never linkifies.**
123
+
124
+ | Release note | Reaches here? |
125
+ | --------------------------------------------------------- | ---------------------------------------------------------------- |
126
+ | _Security:_ quadratic complexity replacing fuzzy links | No — `linkify` is `false`, so the fuzzy-link replacer never runs |
127
+ | _Security:_ quadratic complexity in scheme backscan | No — same; the rule is the inline **linkify** rule |
128
+ | Preserve brackets around IPv6 literals in `normalizeLink` | Yes, in principle — no content in any consumer writes one |
129
+ | Preserve spaces in all-space code spans (#1180) | Yes, for runs of three or more spaces only |
130
+ | Code spans after unclosed link/image labels (#1201) | Yes, for an unclosed `[` followed by an odd-length backtick run |
131
+
132
+ Calling the first two "security" fixes is upstream's framing and the honest
133
+ reading of it here is that this package was never exposed: both are complexity
134
+ bounds on `linkify-it` code paths that are unreachable with the linkifier off.
135
+ Taking the bump is hygiene, not remediation.
136
+
137
+ **The three real fixes were measured, not assumed.** Both versions were rendered
138
+ through `markdownit({ html: true })` — this package's exact configuration — and
139
+ compared:
140
+
141
+ ```text
142
+ a ` ` b 15.0.0 → <p>a <code> </code> b</p> 15.0.1 → <p>a <code> </code> b</p>
143
+ [`a`b` 15.0.0 → <p>[`a`b`</p> 15.0.1 → <p>[<code>a</code>b`</p>
144
+ [x](http://[::1]/)
145
+ 15.0.0 → href="http://%5B::1%5D/" 15.0.1 → href="http://[::1]/"
146
+ ```
147
+
148
+ Each has a narrow trigger. The code-span fix moves output only at three spaces
149
+ or more — 15.0.0 stripped one space from each end of an all-space span, so one-
150
+ and two-space spans were already correct and stay byte-identical. The unclosed-
151
+ label fix needs the backtick run to be **odd**: `[Sword `hp`and`ac`` renders
152
+ the same on both, because its four backticks close. And the IPv6 fix only fires
153
+ on a bracketed address literal in a link, image or autolink destination, which
154
+ 15.0.0 percent-encoded into a host no browser resolves.
155
+
156
+ **Verified against every consumer, and against a search rather than a guess.**
157
+ All 14,995 `.md` files across the six HeroicLands content repositories — `sohl`,
158
+ `hm3`, `thalorna`, `kethira`, `harnensemble` and `harnadventures` — were parsed
159
+ the way `parseMarkdownFile` parses them and rendered through both versions.
160
+ Every one is byte-identical. Scanning the same corpus explains why rather than
161
+ leaving it to luck: zero files contain an IPv6 URL, zero contain an all-space
162
+ code span of three or more spaces, and the 109 files that do use `` ` ` `` use
163
+ the one-space form the fix does not touch. Beyond the corpus, an exhaustive
164
+ render of all 488,280 strings up to eight characters over `[`, `]`, `` ` ``,
165
+ `x` and `!` — the alphabet the label-and-backtick fix is about — found the
166
+ divergence set to be exactly the shapes above and nothing else. The repository's
167
+ 1,713 tests pass unchanged.
168
+
169
+ **Bump**
170
+
171
+ _Patch, not minor._ No export, option, or emitted document changes shape. The
172
+ only behaviour that moves is markdown that was rendered wrongly before, on
173
+ constructs no consumer writes, and the two changes advertised as security fixes
174
+ are unreachable from this configuration.
175
+
3
176
  ## 8.0.0
4
177
 
5
178
  ### Major Changes
@@ -59,11 +59,7 @@ import log from "loglevel";
59
59
  import prefix from "loglevel-plugin-prefix";
60
60
  import yargs from "yargs";
61
61
  import { hideBin } from "yargs/helpers";
62
- import {
63
- compilePacks,
64
- cleanPacks,
65
- unpackPacks,
66
- } from "../engine/compendiums.mjs";
62
+ import { compilePacks, cleanPacks, unpackPacks } from "../engine/compendiums.mjs";
67
63
  import { loadPackConfig } from "../engine/pack-config.mjs";
68
64
  import {
69
65
  fetchAllCatalogs,
@@ -93,11 +89,7 @@ import {
93
89
  gatesFailed,
94
90
  formatUnaddressableFinding as formatUnaddressable,
95
91
  } from "../engine/site-build.mjs";
96
- import {
97
- auditLinks,
98
- buildLinkIndex,
99
- walkReachability,
100
- } from "../engine/content-links.mjs";
92
+ import { auditLinks, buildLinkIndex, walkReachability } from "../engine/content-links.mjs";
101
93
  import { emitDiagnostic, positionOfLiteral } from "../engine/diagnostics.mjs";
102
94
  import {
103
95
  readItemAddresses,
@@ -143,9 +135,7 @@ function configuredPacks() {
143
135
  * @returns {string} The `version` field of this package's manifest.
144
136
  */
145
137
  function ownVersion() {
146
- return JSON.parse(
147
- fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
148
- ).version;
138
+ return JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
149
139
  }
150
140
 
151
141
  // Configure loglevel
@@ -176,8 +166,7 @@ prefix.apply(log, {
176
166
  */
177
167
  function reportFailure(err) {
178
168
  const message = err instanceof Error ? err.message : String(err);
179
- if (/** @type {{located?: boolean}} */ (err)?.located)
180
- console.error(message);
169
+ if (/** @type {{located?: boolean}} */ (err)?.located) console.error(message);
181
170
  else log.error(message);
182
171
  }
183
172
 
@@ -245,13 +234,11 @@ function docsCommand() {
245
234
  choices: ["item-fields"],
246
235
  });
247
236
  yargs.option("out", {
248
- describe:
249
- "Write to this file instead of the configured location.",
237
+ describe: "Write to this file instead of the configured location.",
250
238
  type: "string",
251
239
  });
252
240
  yargs.option("check", {
253
- describe:
254
- "Compare against the file already there; write nothing.",
241
+ describe: "Compare against the file already there; write nothing.",
255
242
  type: "boolean",
256
243
  default: false,
257
244
  });
@@ -274,13 +261,10 @@ function docsCommand() {
274
261
  const config = loadPackConfig();
275
262
  const spec = config.docs?.itemFields ?? {};
276
263
  const destination =
277
- argv.out ??
278
- (spec.out ? path.resolve(config.rootDir, spec.out) : null);
264
+ argv.out ?? (spec.out ? path.resolve(config.rootDir, spec.out) : null);
279
265
 
280
266
  const page = `${renderItemFieldReference({
281
- ...((title ?? spec.title) ?
282
- { title: title ?? spec.title }
283
- : {}),
267
+ ...((title ?? spec.title) ? { title: title ?? spec.title } : {}),
284
268
  ...(spec.preamble ? { preamble: spec.preamble } : {}),
285
269
  generatedBy: "`content-build docs item-fields`",
286
270
  config,
@@ -296,9 +280,7 @@ function docsCommand() {
296
280
  }
297
281
  const relative = path.relative(config.rootDir, destination);
298
282
  const current =
299
- fs.existsSync(destination) ?
300
- fs.readFileSync(destination, "utf8")
301
- : "";
283
+ fs.existsSync(destination) ? fs.readFileSync(destination, "utf8") : "";
302
284
  if (current !== page) {
303
285
  // Staleness belongs to the whole file, so no line is
304
286
  // named — the diagnostics contract drops a field it
@@ -321,9 +303,7 @@ function docsCommand() {
321
303
  recursive: true,
322
304
  });
323
305
  fs.writeFileSync(destination, page);
324
- log.info(
325
- `Wrote ${path.relative(config.rootDir, destination)}`,
326
- );
306
+ log.info(`Wrote ${path.relative(config.rootDir, destination)}`);
327
307
  } else {
328
308
  process.stdout.write(page);
329
309
  }
@@ -353,8 +333,7 @@ function lintCommand() {
353
333
  describe: "Check a content tree's addresses and frontmatter",
354
334
  builder: (yargs) => {
355
335
  yargs.positional("root", {
356
- describe:
357
- "Content tree to lint. Defaults to the configured contentBase.",
336
+ describe: "Content tree to lint. Defaults to the configured contentBase.",
358
337
  type: "string",
359
338
  });
360
339
  yargs.option("references", {
@@ -468,9 +447,7 @@ function lintCommand() {
468
447
  ];
469
448
  for (const finding of findings) emitDiagnostic(finding);
470
449
  if (findings.length) {
471
- log.error(
472
- `${findings.length} finding(s) across ${addresses.notes} note(s).`,
473
- );
450
+ log.error(`${findings.length} finding(s) across ${addresses.notes} note(s).`);
474
451
  process.exitCode = 1;
475
452
  } else {
476
453
  log.info(
@@ -510,19 +487,16 @@ function formatCommand() {
510
487
  describe: "Check formatting with the shared Prettier configuration",
511
488
  builder: (yargs) => {
512
489
  yargs.positional("paths", {
513
- describe:
514
- "Files or directories to check. Defaults to the whole repository.",
490
+ describe: "Files or directories to check. Defaults to the whole repository.",
515
491
  type: "string",
516
492
  });
517
493
  yargs.option("write", {
518
- describe:
519
- "Rewrite unformatted files in place instead of reporting them.",
494
+ describe: "Rewrite unformatted files in place instead of reporting them.",
520
495
  type: "boolean",
521
496
  default: false,
522
497
  });
523
498
  yargs.option("check", {
524
- describe:
525
- "Report unformatted files without rewriting them (the default).",
499
+ describe: "Report unformatted files without rewriting them (the default).",
526
500
  type: "boolean",
527
501
  });
528
502
  },
@@ -532,17 +506,15 @@ function formatCommand() {
532
506
  // it contradicts `--write`; naming both is a mistake worth
533
507
  // saying out loud rather than silently resolving.
534
508
  if (argv.check === true && argv.write) {
535
- log.error(
536
- "--check and --write ask for opposite things; name one.",
537
- );
509
+ log.error("--check and --write ask for opposite things; name one.");
538
510
  process.exitCode = 1;
539
511
  return;
540
512
  }
541
513
  const root = process.cwd();
542
- const { findings, checked, written } = await checkFormatting(
543
- root,
544
- { paths: argv.paths, write: argv.write },
545
- );
514
+ const { findings, checked, written } = await checkFormatting(root, {
515
+ paths: argv.paths,
516
+ write: argv.write,
517
+ });
546
518
  if (argv.write) {
547
519
  log.info(
548
520
  written.length ?
@@ -553,9 +525,7 @@ function formatCommand() {
553
525
  }
554
526
  for (const finding of findings) emitDiagnostic(finding);
555
527
  if (findings.length) {
556
- log.error(
557
- `${findings.length} of ${checked} file(s) are not formatted.`,
558
- );
528
+ log.error(`${findings.length} of ${checked} file(s) are not formatted.`);
559
529
  process.exitCode = 1;
560
530
  } else {
561
531
  log.info(`Formatting is clean (${checked} file(s)).`);
@@ -586,8 +556,7 @@ function markdownCommand() {
586
556
  describe: "Lint markdown with the shared markdownlint rule set",
587
557
  builder: (yargs) => {
588
558
  yargs.positional("paths", {
589
- describe:
590
- "Globs to lint. Defaults to every markdown file in the repository.",
559
+ describe: "Globs to lint. Defaults to every markdown file in the repository.",
591
560
  type: "string",
592
561
  });
593
562
  yargs.option("fix", {
@@ -635,8 +604,7 @@ function linksCommand() {
635
604
  describe: "Check that every link in a content tree lands somewhere",
636
605
  builder: (yargs) => {
637
606
  yargs.positional("root", {
638
- describe:
639
- "Content tree to check. Defaults to the configured contentBase.",
607
+ describe: "Content tree to check. Defaults to the configured contentBase.",
640
608
  type: "string",
641
609
  });
642
610
  yargs.option("manifests", {
@@ -665,9 +633,7 @@ function linksCommand() {
665
633
  message: `unusable link manifest: ${s.reason}`,
666
634
  });
667
635
  }
668
- log.error(
669
- "Refresh the vendored copy from that package's own build.",
670
- );
636
+ log.error("Refresh the vendored copy from that package's own build.");
671
637
  process.exitCode = 1;
672
638
  return;
673
639
  }
@@ -675,14 +641,10 @@ function linksCommand() {
675
641
  // Readable is not the same as addressable: a key shape the
676
642
  // lookup cannot parse makes every cross-package link miss, and
677
643
  // the audit then blames the *notes*.
678
- const drifted = unaddressableForeignPackages(
679
- index.foreign.index,
680
- );
644
+ const drifted = unaddressableForeignPackages(index.foreign.index);
681
645
  if (drifted.length) {
682
646
  for (const f of drifted) {
683
- console.error(
684
- formatUnaddressableFinding(f, manifestDir),
685
- );
647
+ console.error(formatUnaddressableFinding(f, manifestDir));
686
648
  }
687
649
  process.exitCode = 1;
688
650
  return;
@@ -744,9 +706,7 @@ function linksCommand() {
744
706
  frontmatterLinks.length +
745
707
  homepageLinks.length;
746
708
  if (failures) {
747
- log.error(
748
- `${failures} link problem(s) across ${index.notes.length} note(s).`,
749
- );
709
+ log.error(`${failures} link problem(s) across ${index.notes.length} note(s).`);
750
710
  process.exitCode = 1;
751
711
  } else {
752
712
  log.info(
@@ -789,14 +749,12 @@ function manifestCommand() {
789
749
  describe: "Emit this package's cross-package link manifest",
790
750
  builder: (yargs) => {
791
751
  yargs.positional("root", {
792
- describe:
793
- "Content tree to read. Defaults to the configured contentBase.",
752
+ describe: "Content tree to read. Defaults to the configured contentBase.",
794
753
  type: "string",
795
754
  });
796
755
  yargs.option("out", {
797
756
  describe:
798
- "Directory to write into. Defaults to the configured " +
799
- "`paths.manifestOut`.",
757
+ "Directory to write into. Defaults to the configured " + "`paths.manifestOut`.",
800
758
  type: "string",
801
759
  });
802
760
  },
@@ -825,10 +783,7 @@ function manifestCommand() {
825
783
  // lost its address becomes a dead link in every consumer.
826
784
  for (const s of skipped) {
827
785
  emitDiagnostic({
828
- file: path.join(
829
- argv.root ?? config.paths.content,
830
- s.file,
831
- ),
786
+ file: path.join(argv.root ?? config.paths.content, s.file),
832
787
  severity: "warning",
833
788
  message: `no address, so it is absent from the manifest: ${s.reason}`,
834
789
  });
@@ -864,8 +819,7 @@ function siteCommand() {
864
819
  describe: "Build a Hugo content tree from the content tree",
865
820
  builder: (yargs) => {
866
821
  yargs.option("out", {
867
- describe:
868
- "Write the mount here instead of the configured `site.out`.",
822
+ describe: "Write the mount here instead of the configured `site.out`.",
869
823
  type: "string",
870
824
  });
871
825
  },
@@ -903,26 +857,16 @@ function siteCommand() {
903
857
  }
904
858
  for (const s of gates.staleManifests) {
905
859
  emitDiagnostic({
906
- file: path.join(
907
- loadPackConfig().paths.manifests,
908
- `${s.package}.json`,
909
- ),
860
+ file: path.join(loadPackConfig().paths.manifests, `${s.package}.json`),
910
861
  severity: "error",
911
862
  message: `unusable link manifest: ${s.reason}`,
912
863
  });
913
864
  }
914
865
  for (const f of gates.unaddressable) {
915
- console.error(
916
- formatUnaddressable(
917
- f,
918
- loadPackConfig().paths.manifests,
919
- ),
920
- );
866
+ console.error(formatUnaddressable(f, loadPackConfig().paths.manifests));
921
867
  }
922
868
  for (const c of gates.conflicts) {
923
- log.error(
924
- `address ${c.key} is also published by ${c.package}`,
925
- );
869
+ log.error(`address ${c.key} is also published by ${c.package}`);
926
870
  }
927
871
  if (gatesFailed(gates)) {
928
872
  process.exitCode = 1;
@@ -937,9 +881,7 @@ function siteCommand() {
937
881
  log.error(`bad content table: ${e.reason} (${e.source})`);
938
882
  }
939
883
  for (const e of result.wikiErrors) {
940
- log.error(
941
- `bad wikilink [[${e.target}]]: ${e.reason} (${e.file})`,
942
- );
884
+ log.error(`bad wikilink [[${e.target}]]: ${e.reason} (${e.file})`);
943
885
  }
944
886
  if (result.tableErrors.length || result.wikiErrors.length) {
945
887
  process.exitCode = 1;
@@ -989,8 +931,7 @@ function reachabilityCommand() {
989
931
  describe: "Check that every document in a corpus is reachable",
990
932
  builder: (yargs) => {
991
933
  yargs.positional("dir", {
992
- describe:
993
- "The corpus directory, relative to the content tree root.",
934
+ describe: "The corpus directory, relative to the content tree root.",
994
935
  type: "string",
995
936
  });
996
937
  yargs.positional("file", {
@@ -1008,8 +949,7 @@ function reachabilityCommand() {
1008
949
  default: [],
1009
950
  });
1010
951
  yargs.option("root", {
1011
- describe:
1012
- "Content tree to read. Defaults to the configured contentBase.",
952
+ describe: "Content tree to read. Defaults to the configured contentBase.",
1013
953
  type: "string",
1014
954
  });
1015
955
  },
@@ -1026,9 +966,7 @@ function reachabilityCommand() {
1026
966
  stopAt: (n) => indexes.has(String(n.fm.shortcode)),
1027
967
  });
1028
968
 
1029
- const total = index.notes.filter((n) =>
1030
- n.rel.startsWith(`${dir}/`),
1031
- ).length;
969
+ const total = index.notes.filter((n) => n.rel.startsWith(`${dir}/`)).length;
1032
970
 
1033
971
  for (const o of orphans) {
1034
972
  // Unreachability is a property of the whole document, so
@@ -1052,8 +990,7 @@ function reachabilityCommand() {
1052
990
  process.exitCode = 1;
1053
991
  } else {
1054
992
  log.info(
1055
- `All ${total} document(s) in ${dir} are reachable ` +
1056
- `from ${argv.file}.`,
993
+ `All ${total} document(s) in ${dir} are reachable ` + `from ${argv.file}.`,
1057
994
  );
1058
995
  }
1059
996
  } catch (err) {
@@ -1144,8 +1081,7 @@ function depsCommand() {
1144
1081
  return;
1145
1082
  }
1146
1083
  const count = await fetchAllCatalogs(config);
1147
- if (count)
1148
- log.info(`Fetched ${count} dependency catalogue(s).`);
1084
+ if (count) log.info(`Fetched ${count} dependency catalogue(s).`);
1149
1085
  } catch (err) {
1150
1086
  reportFailure(err);
1151
1087
  process.exitCode = 1;
@@ -1192,24 +1128,15 @@ async function diffAddresses(config, argv) {
1192
1128
  ...config,
1193
1129
  paths: {
1194
1130
  ...config.paths,
1195
- foreignCache: path.join(
1196
- path.dirname(config.paths.foreignCache),
1197
- "baseline",
1198
- ),
1131
+ foreignCache: path.join(path.dirname(config.paths.foreignCache), "baseline"),
1199
1132
  },
1200
1133
  };
1201
- const dir = await fetchCatalogFromPath(
1202
- cacheConfig,
1203
- { id: config.foundryPackage },
1204
- argv.from,
1205
- );
1134
+ const dir = await fetchCatalogFromPath(cacheConfig, { id: config.foundryPackage }, argv.from);
1206
1135
  // `<id>@<version>`, which is what the diagnostics name the baseline by.
1207
1136
  const label = path.basename(dir);
1208
1137
 
1209
1138
  const itemsRoot = path.join(dir, "items");
1210
- const baselineDirs = fs
1211
- .readdirSync(itemsRoot)
1212
- .map((name) => path.join(itemsRoot, name));
1139
+ const baselineDirs = fs.readdirSync(itemsRoot).map((name) => path.join(itemsRoot, name));
1213
1140
  const currentDirs = itemPackJsonDirs(config);
1214
1141
  if (!currentDirs.length) {
1215
1142
  throw new Error(
@@ -1254,8 +1181,7 @@ async function diffAddresses(config, argv) {
1254
1181
  function addressesCommand() {
1255
1182
  return {
1256
1183
  command: "addresses <action>",
1257
- describe:
1258
- "Compare the addresses this build publishes against a release's",
1184
+ describe: "Compare the addresses this build publishes against a release's",
1259
1185
  builder: (yargs) => {
1260
1186
  // Required, for the reason every other action is (#57): an
1261
1187
  // optional one exits 0 having compared nothing.