@heroiclands/package-build 5.0.0 → 6.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.
- package/CHANGELOG.md +319 -0
- package/CONTENT.md +136 -13
- package/MIGRATING.md +41 -0
- package/README.md +30 -0
- package/bin/content-build.mjs +20 -3
- package/bin/package-build.mjs +3 -1
- package/engine/base-compiler.mjs +28 -3
- package/engine/content-links.mjs +221 -2
- package/engine/content-lint.mjs +12 -3
- package/engine/diagnostics.mjs +46 -0
- package/engine/generate.mjs +156 -7
- package/engine/homepage.mjs +109 -0
- package/engine/pack-config.mjs +21 -0
- package/engine/site-build.mjs +10 -4
- package/manifest.mjs +195 -0
- package/package.json +1 -1
- package/sohl/actors.mjs +14 -1
- package/sohl/item-fields.mjs +0 -5
- package/sohl/kb-passes.mjs +81 -14
- package/types/engine/base-compiler.d.mts +22 -0
- package/types/engine/content-links.d.mts +53 -2
- package/types/engine/diagnostics.d.mts +28 -0
- package/types/engine/generate.d.mts +50 -2
- package/types/engine/homepage.d.mts +49 -42
- package/types/engine/pack-config.d.mts +13 -0
- package/types/engine/site-build.d.mts +10 -4
- package/types/manifest.d.mts +67 -1
- package/types/sohl/kb-passes.d.mts +5 -1
|
@@ -26,18 +26,69 @@ export function buildLinkIndex(contentBase: string, { manifestDir, skipDirectori
|
|
|
26
26
|
manifestDir?: string | undefined;
|
|
27
27
|
skipDirectories?: readonly string[] | undefined;
|
|
28
28
|
}): object;
|
|
29
|
+
/**
|
|
30
|
+
* Every defect in the addresses a package homepage carries.
|
|
31
|
+
*
|
|
32
|
+
* **Why the homepage needs its own audit at all.** Every other note addresses
|
|
33
|
+
* the corpus with wikilinks, which {@link auditLinks} resolves. A homepage does
|
|
34
|
+
* not and cannot: it is published *verbatim* by every publishing mode, including
|
|
35
|
+
* the homepage-only mode two fan-licensed packages ship under, where the content
|
|
36
|
+
* tree is never walked and there is no index for a wikilink to resolve against.
|
|
37
|
+
* So a landing addresses the web the way the web does — markdown links and
|
|
38
|
+
* `url:` fields — and nothing was looking at those. SoHL's landing pointed at
|
|
39
|
+
* `kb/creature/` and `kb/character/` from the day those types merged into
|
|
40
|
+
* `being`: two 404s on the package's front page, through every build.
|
|
41
|
+
*
|
|
42
|
+
* **What is checkable, stated plainly.** Only an address into this site is, and
|
|
43
|
+
* only against facts this build already holds:
|
|
44
|
+
*
|
|
45
|
+
* - A **retired content type** in the path. The engine knows what used to exist
|
|
46
|
+
* and what replaced it, so this is a fact rather than a guess — and it is
|
|
47
|
+
* exactly the SoHL defect.
|
|
48
|
+
* - A **hardcoded absolute URL** into this package's own prefix, or into one a
|
|
49
|
+
* vendored manifest names. Both have a better form to write, which is why they
|
|
50
|
+
* are reported; a bare `/<package>/` is left alone, because a package
|
|
51
|
+
* homepage is in no manifest and there is nothing better to write.
|
|
52
|
+
* - A **root-relative `url:`**, which the theme's `relURL` prefixes a second
|
|
53
|
+
* time. `href:` means "already resolved, use verbatim", so the same leading
|
|
54
|
+
* slash is correct there and is not reported.
|
|
55
|
+
* - A **wikilink**, which nothing on this page will ever resolve.
|
|
56
|
+
*
|
|
57
|
+
* **What is not checkable, and is not attempted.** Whether an external URL
|
|
58
|
+
* answers — there is no network at build time, and a build must not fail because
|
|
59
|
+
* a third party is down. And whether a live in-site address names a page that
|
|
60
|
+
* exists: several of the surfaces a landing routes to are produced by other
|
|
61
|
+
* tools entirely (generated API documentation, hand-authored Hugo sections), so
|
|
62
|
+
* this build does not hold the set of published pages and would report a working
|
|
63
|
+
* link as dead.
|
|
64
|
+
*
|
|
65
|
+
* @param {ReturnType<typeof buildLinkIndex>} index - The built index.
|
|
66
|
+
* @returns {Array<{note: object, field: string, url: string, text: string,
|
|
67
|
+
* occurrence: number, message: string}>} One finding per defect, `text` and
|
|
68
|
+
* `occurrence` locating it in the note's raw source.
|
|
69
|
+
*/
|
|
70
|
+
export function auditHomepageLinks(index: ReturnType<typeof buildLinkIndex>): Array<{
|
|
71
|
+
note: object;
|
|
72
|
+
field: string;
|
|
73
|
+
url: string;
|
|
74
|
+
text: string;
|
|
75
|
+
occurrence: number;
|
|
76
|
+
message: string;
|
|
77
|
+
}>;
|
|
29
78
|
/**
|
|
30
79
|
* Every link in a tree that lands nowhere.
|
|
31
80
|
*
|
|
32
81
|
* @param {ReturnType<typeof buildLinkIndex>} index - The built index.
|
|
33
82
|
* @returns {{deadAnchors: object[], deadAddresses: object[],
|
|
34
|
-
* frontmatterLinks: object[],
|
|
35
|
-
* which addresses a foreign
|
|
83
|
+
* frontmatterLinks: object[], homepageLinks: object[],
|
|
84
|
+
* usedManifest: Set<string>}} The findings, and which addresses a foreign
|
|
85
|
+
* manifest answered.
|
|
36
86
|
*/
|
|
37
87
|
export function auditLinks(index: ReturnType<typeof buildLinkIndex>): {
|
|
38
88
|
deadAnchors: object[];
|
|
39
89
|
deadAddresses: object[];
|
|
40
90
|
frontmatterLinks: object[];
|
|
91
|
+
homepageLinks: object[];
|
|
41
92
|
usedManifest: Set<string>;
|
|
42
93
|
};
|
|
43
94
|
/**
|
|
@@ -150,3 +150,31 @@ export function positionOfLiteral(text: string, needle: string, occurrence?: num
|
|
|
150
150
|
line?: number;
|
|
151
151
|
column?: number;
|
|
152
152
|
};
|
|
153
|
+
/**
|
|
154
|
+
* Where a **key or value in a YAML document** sits, addressed by its path.
|
|
155
|
+
*
|
|
156
|
+
* {@link positionOfLiteral} is the plain search, and it is the wrong tool for a
|
|
157
|
+
* configuration file: a pack name like `items` or `actors` appears in the
|
|
158
|
+
* `packs:` block, in a folder's list, in a path, and often in prose, so the
|
|
159
|
+
* first occurrence is routinely not the one the finding is about — which is the
|
|
160
|
+
* one thing the located form exists to prevent.
|
|
161
|
+
*
|
|
162
|
+
* A path resolves the exact node instead. The document is re-parsed here rather
|
|
163
|
+
* than threaded from the loader because the loader returns plain data: `yaml`
|
|
164
|
+
* discards ranges once a document is materialised, and carrying a parallel
|
|
165
|
+
* position tree through configuration resolution would be a second
|
|
166
|
+
* representation of the same file to keep in step.
|
|
167
|
+
*
|
|
168
|
+
* Every failure — unparseable text, an `.mjs` configuration, a path that
|
|
169
|
+
* resolves to nothing — yields `{}`, so a caller spreads the result and the
|
|
170
|
+
* position is dropped rather than guessed.
|
|
171
|
+
*
|
|
172
|
+
* @param {string} text - The document's contents.
|
|
173
|
+
* @param {ReadonlyArray<string|number>} keyPath - Path to the node: map keys as
|
|
174
|
+
* strings, sequence entries as numbers.
|
|
175
|
+
* @returns {{line?: number, column?: number}} Spreadable position fields.
|
|
176
|
+
*/
|
|
177
|
+
export function positionOfYamlPath(text: string, keyPath: ReadonlyArray<string | number>): {
|
|
178
|
+
line?: number;
|
|
179
|
+
column?: number;
|
|
180
|
+
};
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* and an actor's embedded items may be sourced from any of them. Finding one
|
|
7
7
|
* pack and stopping is how embedded-item resolution would silently miss every
|
|
8
8
|
* item that landed in another. Returned in configured order, which is also the
|
|
9
|
-
* order they compile in
|
|
10
|
-
* is written
|
|
9
|
+
* order they compile in — {@link orderPassesByDependency} keeps the declared
|
|
10
|
+
* order among packs of one type — and every one of them is written before the
|
|
11
|
+
* actors pass that reads them.
|
|
11
12
|
*
|
|
12
13
|
* @param {object} [config] - The resolved build configuration. Defaults to this
|
|
13
14
|
* repository's.
|
|
@@ -16,6 +17,53 @@
|
|
|
16
17
|
* caller that needs one, refuses that itself.
|
|
17
18
|
*/
|
|
18
19
|
export function itemPackJsonDirs(config?: object): string[];
|
|
20
|
+
/**
|
|
21
|
+
* The passes to run, ordered so that each one follows the output it reads.
|
|
22
|
+
*
|
|
23
|
+
* **Declaration order is presentation, not compile order (#73).** The same
|
|
24
|
+
* `packs:` list is the manifest's `packs` array, which a consumer orders for a
|
|
25
|
+
* reader browsing compendiums; the actors pass, meanwhile, resolves each
|
|
26
|
+
* being's embedded items against the item passes' *output*. Making one list
|
|
27
|
+
* satisfy both meant an Actor pack declared first compiled only where a
|
|
28
|
+
* previous run had already left `build/packs-json` populated — green on a warm
|
|
29
|
+
* tree, exit 1 on every fresh checkout and every CI runner, and `build/` is
|
|
30
|
+
* gitignored so that is the state CI always starts from.
|
|
31
|
+
*
|
|
32
|
+
* **The reordering is the smallest one that works.** Each step takes the
|
|
33
|
+
* *earliest declared* pass whose dependencies are all already emitted, so a
|
|
34
|
+
* list that was already in a workable order comes back untouched, and one that
|
|
35
|
+
* was not moves exactly the passes that had to move. A dependency is satisfied
|
|
36
|
+
* only when **every** pack of that type has run: a being addresses an item by
|
|
37
|
+
* `(type, shortcode)` without knowing which Item pack ships it, so waiting for
|
|
38
|
+
* one of several would resolve some beings and silently fail others.
|
|
39
|
+
*
|
|
40
|
+
* A dependency on a type this configuration declares no pack of is not waited
|
|
41
|
+
* for. A package may ship an Actor pack and no Item pack; the pass that needs
|
|
42
|
+
* one refuses on its own, with a message about items rather than about order.
|
|
43
|
+
*
|
|
44
|
+
* @param {readonly object[]} packs - The passes to be run, as declared.
|
|
45
|
+
* @returns {object[]} A new list, in compile order. The input is untouched.
|
|
46
|
+
* @throws {Error} If the passes read each other's output in a cycle, which no
|
|
47
|
+
* order can satisfy. Only reachable from a mis-declared compiler, so it names
|
|
48
|
+
* the passes rather than blaming the pack list.
|
|
49
|
+
*/
|
|
50
|
+
export function orderPassesByDependency(packs: readonly object[]): object[];
|
|
51
|
+
/**
|
|
52
|
+
* The dependencies this run cannot satisfy by ordering, because the pass that
|
|
53
|
+
* would produce them is not in it.
|
|
54
|
+
*
|
|
55
|
+
* Ordering answers the whole-package build; a run restricted to one pack
|
|
56
|
+
* (`content-build package compile <name>`) cannot conjure the passes it left
|
|
57
|
+
* out. Where their output is already on disk from an earlier run that is fine
|
|
58
|
+
* — it is how compiling one pack at a time is meant to work — so this reports
|
|
59
|
+
* only what is genuinely absent, and names the pack that would write it rather
|
|
60
|
+
* than the directory that is missing.
|
|
61
|
+
*
|
|
62
|
+
* @param {readonly object[]} running - The passes this run will execute.
|
|
63
|
+
* @param {object} config - The resolved build configuration.
|
|
64
|
+
* @returns {string[]} One message per unsatisfiable dependency.
|
|
65
|
+
*/
|
|
66
|
+
export function unsatisfiedPassDependencies(running: readonly object[], config: object): string[];
|
|
19
67
|
/**
|
|
20
68
|
* The passes that compiled nothing when they were expected to compile
|
|
21
69
|
* something — a build failure, not a quiet no-op.
|
|
@@ -46,49 +46,40 @@ export function homepageFrontmatter(fm: object, { contentPackage, title }: {
|
|
|
46
46
|
title: string;
|
|
47
47
|
}): object;
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* the
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* knowledge from *game-system* knowledge, and a homepage is note format: it
|
|
78
|
-
* carries no `system` block, mirrors no item builder, and would mean the same
|
|
79
|
-
* thing for a game system that is not SoHL. Reachability is the symptom that
|
|
80
|
-
* makes it obvious — `HarnMaster-3-FoundryVTT` declares no `itemBuilders`, so a
|
|
81
|
-
* type living in the SoHL registry would be unavailable to HM3 and to every HM3
|
|
82
|
-
* module, which is most of the packages that need a homepage and nothing else.
|
|
83
|
-
*
|
|
84
|
-
* **Its address is the package's, not the note's.** A homepage publishes at
|
|
85
|
-
* `/<contentPackage>/` because that is where the package is, so `name.full`,
|
|
86
|
-
* `shortcode` and `id` decide nothing on it (#53 refuses them outright; this
|
|
87
|
-
* module simply never reads them). It compiles into no document, so it carries
|
|
88
|
-
* no compendium UUID and appears in no pack and in no link-manifest entry.
|
|
89
|
-
*
|
|
90
|
-
* @module
|
|
49
|
+
* Every address a homepage carries, wherever it is written.
|
|
50
|
+
*
|
|
51
|
+
* **Both halves of the page are in scope, and that is the finding rather than
|
|
52
|
+
* the assumption.** Of the six homepages authored today, four carry every link
|
|
53
|
+
* in the body as ordinary markdown and two carry them in `landing:` — and the
|
|
54
|
+
* one whose dead links prompted the check has an *empty body*, so a body-only
|
|
55
|
+
* reading would have found nothing at all on it. A dead link in a card is
|
|
56
|
+
* exactly as broken as one in a paragraph.
|
|
57
|
+
*
|
|
58
|
+
* Three shapes are gathered, and the caller needs to tell them apart because
|
|
59
|
+
* the rules differ:
|
|
60
|
+
*
|
|
61
|
+
* - **`url`** — package-relative, resolved against the site by the theme.
|
|
62
|
+
* - **`href`** — already resolved, used verbatim.
|
|
63
|
+
* - **prose and body markdown links** — emitted as written and resolved by the
|
|
64
|
+
* browser against the landing's own address, which *is* the package root, so
|
|
65
|
+
* a relative one means the same thing a `url` does.
|
|
66
|
+
*
|
|
67
|
+
* `banner:` is not an address: it is an image path resolved through the CDN
|
|
68
|
+
* base, and `banner: none` is a sentinel rather than a target. Top-level
|
|
69
|
+
* `title` and `description` are not walked either — they are set as text, never
|
|
70
|
+
* rendered as markdown.
|
|
71
|
+
*
|
|
72
|
+
* @param {object|null|undefined} fm - The note's frontmatter.
|
|
73
|
+
* @param {string} [body] - The note's markdown body.
|
|
74
|
+
* @returns {Array<{field: string, url: string, kind: string}>} Every address,
|
|
75
|
+
* frontmatter first and then the body, each with the dotted path it was
|
|
76
|
+
* written at.
|
|
91
77
|
*/
|
|
78
|
+
export function homepageAddresses(fm: object | null | undefined, body?: string): Array<{
|
|
79
|
+
field: string;
|
|
80
|
+
url: string;
|
|
81
|
+
kind: string;
|
|
82
|
+
}>;
|
|
92
83
|
/**
|
|
93
84
|
* The note type that compiles to the package homepage.
|
|
94
85
|
*
|
|
@@ -116,3 +107,19 @@ export const HOMEPAGE_FIELDS: readonly import("./field-spec.mjs").FieldSpec[];
|
|
|
116
107
|
* @type {string}
|
|
117
108
|
*/
|
|
118
109
|
export const HOMEPAGE_DESTINATION: string;
|
|
110
|
+
/**
|
|
111
|
+
* The two frontmatter keys that hold an address, and what each one means.
|
|
112
|
+
*
|
|
113
|
+
* They are **not** interchangeable, and a check that treated them as one would
|
|
114
|
+
* be wrong about both. The theme resolves a `url` against the site with
|
|
115
|
+
* `relURL`, so a package writes `kb/rules/` and is served `/sohl/kb/rules/`
|
|
116
|
+
* without ever naming its own prefix. An `href` is an address that is *already*
|
|
117
|
+
* resolved and is used verbatim — which is what `cards.source: sections` fills
|
|
118
|
+
* in, since a section's permalink already carries the prefix.
|
|
119
|
+
*
|
|
120
|
+
* So a leading `/` is a defect in a `url` (it is prefixed a second time) and
|
|
121
|
+
* correct in an `href`.
|
|
122
|
+
*
|
|
123
|
+
* @type {ReadonlySet<string>}
|
|
124
|
+
*/
|
|
125
|
+
export const HOMEPAGE_ADDRESS_KEYS: ReadonlySet<string>;
|
|
@@ -56,6 +56,19 @@ export function configFromData(data: unknown, configPath: string): import("../co
|
|
|
56
56
|
* compilers know neither what to compile nor where to put it.
|
|
57
57
|
*/
|
|
58
58
|
export function loadPackConfig(): import("../config.mjs").ContentBuildConfig;
|
|
59
|
+
/**
|
|
60
|
+
* The file {@link loadPackConfig} resolved the configuration from.
|
|
61
|
+
*
|
|
62
|
+
* A diagnostic about a *configured* value has to name the file it was declared
|
|
63
|
+
* in, and re-deriving that path at the point of the finding would be a second
|
|
64
|
+
* resolution free to disagree with the first — the `PACKAGE_BUILD_CONFIG`
|
|
65
|
+
* override, the upward walk and the one-file-per-directory rule all have to
|
|
66
|
+
* come out the same way. This reports the path actually read.
|
|
67
|
+
*
|
|
68
|
+
* @returns {string} Its absolute path.
|
|
69
|
+
* @throws {Error} As {@link loadPackConfig}, when there is no configuration.
|
|
70
|
+
*/
|
|
71
|
+
export function packConfigPath(): string;
|
|
59
72
|
/** The stem every consuming repository declares its build under. */
|
|
60
73
|
export const CONFIG_BASENAME: "package-build.config";
|
|
61
74
|
/**
|
|
@@ -65,10 +65,16 @@ export function collectHomepages(contentBase: string, ctx: object): {
|
|
|
65
65
|
* Writes each homepage at the package's own root.
|
|
66
66
|
*
|
|
67
67
|
* Its own writer, deliberately small. A homepage is authored markdown published
|
|
68
|
-
* verbatim — no table expansion, no section landing
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
68
|
+
* verbatim — no table expansion, no section landing and no link resolution — so
|
|
69
|
+
* routing it through {@link renderPages} would buy it a pipeline it has no input
|
|
70
|
+
* for, and would make homepage-only mode depend on the index, the foreign
|
|
71
|
+
* manifests and the table universe that mode exists to not build.
|
|
72
|
+
*
|
|
73
|
+
* **Verbatim is the answer to #54, not a gap left by it.** A landing's links
|
|
74
|
+
* could not be *resolved* here without giving `homepage` mode the index its
|
|
75
|
+
* licensing fence exists to not build, so they are **checked** instead:
|
|
76
|
+
* {@link auditHomepageLinks} reads the `landing:` addresses and the body's
|
|
77
|
+
* markdown links, and reports a wikilink on the page rather than resolving one.
|
|
72
78
|
*
|
|
73
79
|
* @param {string} outRoot - The package's site root — the configured `site.out`,
|
|
74
80
|
* one level above the content mount.
|
package/types/manifest.d.mts
CHANGED
|
@@ -59,6 +59,60 @@ export function releaseUrls({ repoUrl, version, artifact }: {
|
|
|
59
59
|
* @returns {object[]} The manifest's `packs` array.
|
|
60
60
|
*/
|
|
61
61
|
export function manifestPacks(config: object): object[];
|
|
62
|
+
/**
|
|
63
|
+
* What `packFolders` and the derived `packs[]` disagree about.
|
|
64
|
+
*
|
|
65
|
+
* `packFolders` is the one **declared** manifest key that names something the
|
|
66
|
+
* build **derives**: every other declared key states a fact about the package
|
|
67
|
+
* (`title`, `socket`, `grid`) or addresses a staged file (`esmodules`,
|
|
68
|
+
* `styles`, `languages`), and a staged file is a different relation, checked
|
|
69
|
+
* against the stage rather than against configuration. So this is the one place
|
|
70
|
+
* a declaration can go stale against a value the build already computed — and
|
|
71
|
+
* until now nothing compared them (#81).
|
|
72
|
+
*
|
|
73
|
+
* `HarnMaster-3-FoundryVTT` shipped the consequence: its folder named four
|
|
74
|
+
* packs, three of which had not existed since the compendium was consolidated,
|
|
75
|
+
* and omitted `items` — 1,577 of 1,597 documents, loose in Foundry's compendium
|
|
76
|
+
* browser, with the build reporting nothing (HM3#420).
|
|
77
|
+
*
|
|
78
|
+
* **The two findings are not the same finding**, and giving them one severity
|
|
79
|
+
* gets one of them wrong:
|
|
80
|
+
*
|
|
81
|
+
* - _A folder names a pack that does not exist_ is an **error**. Foundry
|
|
82
|
+
* resolves the name against the package's own packs and silently skips what
|
|
83
|
+
* it cannot find, so the declaration does nothing at all; there is no
|
|
84
|
+
* arrangement in which it is intended, and the fix is unambiguous.
|
|
85
|
+
* - _A pack no folder names_ is a **warning**. It is legal and can be
|
|
86
|
+
* deliberate — a package may want one pack at the root — so failing on it
|
|
87
|
+
* would break working packages for a matter of taste. But a package that
|
|
88
|
+
* bothered to declare a folder rarely meant to leave one out, which is
|
|
89
|
+
* exactly how HM3's `items` went unnoticed.
|
|
90
|
+
* - _A package declaring no folders_ says **nothing**. Everything at the root
|
|
91
|
+
* is the majority arrangement, not an omission.
|
|
92
|
+
*
|
|
93
|
+
* Errors come first, in declaration order, then warnings in pack order: the
|
|
94
|
+
* unresolvable names are what a reader fixes, and a folder gaining a name often
|
|
95
|
+
* settles a warning too.
|
|
96
|
+
*
|
|
97
|
+
* @param {object} options
|
|
98
|
+
* @param {unknown} [options.packFolders] - The declared `packFolders`.
|
|
99
|
+
* @param {ReadonlyArray<{name: string}>} [options.packs] - The derived packs,
|
|
100
|
+
* as {@link manifestPacks} returns them.
|
|
101
|
+
* @returns {Array<{severity: "error"|"warning", message: string, pack: string,
|
|
102
|
+
* folder?: string, keyPath: Array<string|number>}>} The findings, ordered.
|
|
103
|
+
*/
|
|
104
|
+
export function packFolderFindings({ packFolders, packs }: {
|
|
105
|
+
packFolders?: unknown;
|
|
106
|
+
packs?: readonly {
|
|
107
|
+
name: string;
|
|
108
|
+
}[] | undefined;
|
|
109
|
+
}): Array<{
|
|
110
|
+
severity: "error" | "warning";
|
|
111
|
+
message: string;
|
|
112
|
+
pack: string;
|
|
113
|
+
folder?: string;
|
|
114
|
+
keyPath: Array<string | number>;
|
|
115
|
+
}>;
|
|
62
116
|
/**
|
|
63
117
|
* The `relationships` block as published — every declared dependency, with the
|
|
64
118
|
* build's own keys dropped.
|
|
@@ -109,20 +163,32 @@ export function buildManifest({ config, packageJson, artifact, flags }: {
|
|
|
109
163
|
/**
|
|
110
164
|
* Write the generated manifest into the staged package.
|
|
111
165
|
*
|
|
166
|
+
* The declared `packFolders` is checked against the derived `packs[]` first,
|
|
167
|
+
* and an unresolvable name **stops the write**: a manifest already known to
|
|
168
|
+
* describe packs the package does not ship should not reach the stage, where
|
|
169
|
+
* the next command would deploy it (#81). See {@link packFolderFindings} for
|
|
170
|
+
* the rule and why its two findings carry different severities.
|
|
171
|
+
*
|
|
112
172
|
* @param {object} options - As {@link buildManifest}, plus where to write.
|
|
113
173
|
* @param {object} options.config - The resolved content configuration.
|
|
114
174
|
* @param {object} options.packageJson - The repository's `package.json`.
|
|
115
175
|
* @param {string} options.artifact - `system` or `module`.
|
|
116
176
|
* @param {string} options.outDir - Directory to write into.
|
|
117
177
|
* @param {Record<string, object>} [options.flags] - Namespaced flags to merge.
|
|
178
|
+
* @param {string} [options.configFile] - Absolute path of the configuration
|
|
179
|
+
* file the manifest was resolved from, so a finding about it can be located.
|
|
180
|
+
* Omitting it costs the position, not the finding.
|
|
118
181
|
* @returns {Promise<{path: string, manifest: object}>} Where it went, and what.
|
|
182
|
+
* @throws {Error} When a `packFolders` entry names a pack the package does not
|
|
183
|
+
* ship. Nothing is written in that case.
|
|
119
184
|
*/
|
|
120
|
-
export function writeManifest({ config, packageJson, artifact, outDir, flags, }: {
|
|
185
|
+
export function writeManifest({ config, packageJson, artifact, outDir, flags, configFile, }: {
|
|
121
186
|
config: object;
|
|
122
187
|
packageJson: object;
|
|
123
188
|
artifact: string;
|
|
124
189
|
outDir: string;
|
|
125
190
|
flags?: Record<string, object> | undefined;
|
|
191
|
+
configFile?: string | undefined;
|
|
126
192
|
}): Promise<{
|
|
127
193
|
path: string;
|
|
128
194
|
manifest: object;
|
|
@@ -54,11 +54,15 @@ export function rewriteRepoLinks(body: string, docRel: string, options: object):
|
|
|
54
54
|
* Both run inside code-fence protection, so neither can rewrite a fenced example.
|
|
55
55
|
*
|
|
56
56
|
* @param {object} options - Resolved from `site.passOptions`.
|
|
57
|
-
* @param {string} [options.symbolMap] - Path to the TypeDoc symbol map
|
|
57
|
+
* @param {string} [options.symbolMap] - Path to the TypeDoc symbol map,
|
|
58
|
+
* relative to `repoRoot`. Absent means no API links; present and unusable is
|
|
59
|
+
* a build failure.
|
|
58
60
|
* @param {string} [options.apiBase] - Where the API documentation is served.
|
|
59
61
|
* @param {string} [options.blob] - GitHub blob base for repository files.
|
|
60
62
|
* @param {string} options.repoRoot - The repository root, for relative paths.
|
|
61
63
|
* @returns {{beforeLinks: Function, afterLinks: Function}} The bundle.
|
|
64
|
+
* @throws {Error} When a configured `symbolMap` cannot be resolved, read,
|
|
65
|
+
* parsed, or is not a name → page object.
|
|
62
66
|
*/
|
|
63
67
|
export function sohlKbPass(options: {
|
|
64
68
|
symbolMap?: string | undefined;
|