@heroiclands/package-build 22.1.0 → 22.2.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 +25 -0
- package/CONTENT.md +22 -0
- package/bin/content-build.mjs +29 -3
- package/bin/package-build.mjs +9 -26
- package/config.mjs +7 -2
- package/content-config.mjs +61 -2
- package/docs/api.md +26 -23
- package/docs/commands.md +22 -22
- package/docs/configuration.md +117 -54
- package/engine/content-links.mjs +19 -9
- package/engine/helpers.mjs +2 -1
- package/engine/metadata-index.mjs +32 -0
- package/engine/note-vocabulary.mjs +20 -0
- package/engine/pack-config.mjs +14 -1
- package/engine/schema-check.mjs +6 -6
- package/engine/site-build.mjs +14 -3
- package/engine/site-config.mjs +68 -27
- package/engine/site-index.mjs +10 -1
- package/engine/web-wikilinks.mjs +16 -6
- package/engine/wikilink-syntax.mjs +10 -0
- package/engine/wikilinks.mjs +34 -7
- package/manifest.mjs +16 -10
- package/package.json +1 -1
- package/release.mjs +41 -8
- package/types/config.d.mts +17 -0
- package/types/content-config.d.mts +11 -0
- package/types/engine/content-links.d.mts +3 -2
- package/types/engine/metadata-index.d.mts +22 -0
- package/types/engine/note-vocabulary.d.mts +12 -0
- package/types/engine/schema-check.d.mts +5 -5
- package/types/engine/site-build.d.mts +5 -1
- package/types/engine/site-config.d.mts +23 -12
- package/types/engine/site-index.d.mts +6 -1
- package/types/engine/web-wikilinks.d.mts +9 -5
- package/types/engine/wikilink-syntax.d.mts +3 -0
- package/types/engine/wikilinks.d.mts +16 -5
- package/types/manifest.d.mts +5 -3
- package/types/release.d.mts +7 -6
|
@@ -157,8 +157,8 @@ export function compareEmittedSystem({ system, artifact, documentType, subtype,
|
|
|
157
157
|
* Two places to find it, because a system checks itself against source it owns
|
|
158
158
|
* while a module checks against a dependency it fetched:
|
|
159
159
|
*
|
|
160
|
-
* - **A system**: its own `schema.json`, generated from its `src/`
|
|
161
|
-
*
|
|
160
|
+
* - **A system**: its own `schema.json`, generated from its `src/` into
|
|
161
|
+
* `build/` by `package-build schema`.
|
|
162
162
|
* - **A module**: the copy cached by `content-build deps fetch`, from the
|
|
163
163
|
* archive of the version it pins — which is what makes the comparison happen
|
|
164
164
|
* at `verified` rather than against whatever the system's `main` holds today.
|
|
@@ -282,9 +282,9 @@ export function checkAuthoredSystemData(fm: object, { block, documentType, subTy
|
|
|
282
282
|
* subtype declares.
|
|
283
283
|
*
|
|
284
284
|
* The build-time face of {@link compareEmittedSystem}: it resolves the schema
|
|
285
|
-
* the way every other check here does — the system's own
|
|
286
|
-
* the cached one from the release a module pins — and attaches the message
|
|
287
|
-
* reader sees.
|
|
285
|
+
* the way every other check here does — the system's own published artifact,
|
|
286
|
+
* or the cached one from the release a module pins — and attaches the message
|
|
287
|
+
* a reader sees.
|
|
288
288
|
*
|
|
289
289
|
* **Silent where there is nothing to check against**, exactly as its two
|
|
290
290
|
* siblings are: a module pinning a system version released before the artifact
|
|
@@ -396,7 +396,10 @@ export function resolveSitePass(name: string | undefined, options: object): {
|
|
|
396
396
|
* `sql` directive with none prepared is a table error: nothing here runs a
|
|
397
397
|
* query.
|
|
398
398
|
* @returns {{gates: object, stats: object|null, tableErrors: object[],
|
|
399
|
-
* wikiErrors: object[], imageErrors: object[], manifests: object|null
|
|
399
|
+
* wikiErrors: object[], imageErrors: object[], manifests: object|null,
|
|
400
|
+
* hasTags: boolean}} `hasTags` is whether any note the walk read carries
|
|
401
|
+
* `tags:` — what {@link module:engine/site-config.hugoConfig} reads to
|
|
402
|
+
* decide whether the site emits taxonomy pages.
|
|
400
403
|
*/
|
|
401
404
|
export function buildSite({ config, sqlTables }?: {
|
|
402
405
|
config?: object | undefined;
|
|
@@ -408,6 +411,7 @@ export function buildSite({ config, sqlTables }?: {
|
|
|
408
411
|
wikiErrors: object[];
|
|
409
412
|
imageErrors: object[];
|
|
410
413
|
manifests: object | null;
|
|
414
|
+
hasTags: boolean;
|
|
411
415
|
};
|
|
412
416
|
export { formatUnaddressableFinding };
|
|
413
417
|
import { formatUnaddressableFinding } from "./metadata-index.mjs";
|
|
@@ -89,18 +89,21 @@ export function resolveThemesDir(rootDir: string): string;
|
|
|
89
89
|
*
|
|
90
90
|
* @param {object} options - The sources.
|
|
91
91
|
* @param {object} options.config - The resolved build configuration.
|
|
92
|
-
* @param {string} [options.description] - `package.json`'s `description`.
|
|
93
92
|
* @param {readonly NavigationEntry[]} options.navigation - The navigation.
|
|
94
93
|
* @param {string} options.themesDir - From {@link resolveThemesDir}.
|
|
94
|
+
* @param {boolean} [options.hasTags] - Whether any note the site build walked
|
|
95
|
+
* carries `tags:`, from {@link module:engine/site-build.buildSite}'s
|
|
96
|
+
* `hasTags`. Defaults to `false` — no tagged note, no taxonomy pages.
|
|
95
97
|
* @returns {Record<string, any>} The configuration Hugo reads.
|
|
96
98
|
* @throws {TypeError} When `homepage` fails `checkHomepage`, or the
|
|
97
|
-
* configuration declares no `packageBuild.manifest.title
|
|
99
|
+
* configuration declares no `packageBuild.manifest.title`, no
|
|
100
|
+
* `site.description`, or no `site.assets`.
|
|
98
101
|
*/
|
|
99
|
-
export function hugoConfig({ config,
|
|
102
|
+
export function hugoConfig({ config, navigation, themesDir, hasTags }: {
|
|
100
103
|
config: object;
|
|
101
|
-
description?: string | undefined;
|
|
102
104
|
navigation: readonly NavigationEntry[];
|
|
103
105
|
themesDir: string;
|
|
106
|
+
hasTags?: boolean | undefined;
|
|
104
107
|
}): Record<string, any>;
|
|
105
108
|
/**
|
|
106
109
|
* The configuration as the TOML Hugo reads.
|
|
@@ -112,16 +115,22 @@ export function hugoToml(generated: Record<string, unknown>): string;
|
|
|
112
115
|
/**
|
|
113
116
|
* The Hugo configuration, every source read from the repository.
|
|
114
117
|
*
|
|
115
|
-
* Reads
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* intact.
|
|
118
|
+
* Reads the cached navigation and the installed theme's location, and
|
|
119
|
+
* composes them with {@link hugoConfig}. Nothing is written, so a caller can
|
|
120
|
+
* run this before touching the output tree and fail with it intact.
|
|
119
121
|
*
|
|
120
122
|
* @param {object} config - The resolved build configuration.
|
|
123
|
+
* @param {object} [options] - Options.
|
|
124
|
+
* @param {boolean} [options.hasTags] - Whether any note the site build walked
|
|
125
|
+
* carries `tags:`. Defaults to `false`, so a caller generating the
|
|
126
|
+
* configuration before the walk (to fail fast on a missing source) gets the
|
|
127
|
+
* untagged shape; pass the site build's own `hasTags` once it is known.
|
|
121
128
|
* @returns {Record<string, any>} The configuration Hugo reads.
|
|
122
129
|
* @throws {Error} When any source is missing or wrong.
|
|
123
130
|
*/
|
|
124
|
-
export function generateHugoConfig(config: object
|
|
131
|
+
export function generateHugoConfig(config: object, { hasTags }?: {
|
|
132
|
+
hasTags?: boolean | undefined;
|
|
133
|
+
}): Record<string, any>;
|
|
125
134
|
/**
|
|
126
135
|
* Write `build/hugo/hugo.toml`.
|
|
127
136
|
*
|
|
@@ -162,11 +171,13 @@ export const BRAND: Readonly<{
|
|
|
162
171
|
discordURL: "https://discord.gg/EwMfkNd3az";
|
|
163
172
|
}>;
|
|
164
173
|
/**
|
|
165
|
-
* The kinds
|
|
174
|
+
* The kinds a site with no tagged notes renders.
|
|
166
175
|
*
|
|
167
176
|
* A section exists only where `site.sections` declares one, so a tree holding
|
|
168
|
-
* only the homepage emits nothing beyond it;
|
|
169
|
-
* empty shells
|
|
177
|
+
* only the homepage emits nothing beyond it; a taxonomy nobody's notes fill
|
|
178
|
+
* and a feed would be empty shells. A site whose notes carry `tags:` emits
|
|
179
|
+
* `taxonomy` and `term` after all — see {@link hugoConfig} — but `RSS` is
|
|
180
|
+
* disabled either way: nothing here publishes a feed.
|
|
170
181
|
*/
|
|
171
182
|
export const DISABLE_KINDS: readonly string[];
|
|
172
183
|
/**
|
|
@@ -7,13 +7,18 @@
|
|
|
7
7
|
* @param {Map<string, {package: string, type?: string}>} [options.foreignIndex]
|
|
8
8
|
* The merged index from `loadForeignIndexes`. Omit when the build publishes
|
|
9
9
|
* no cross-package links.
|
|
10
|
+
* @param {Set<string>} [options.noIndexPackages] - Packages declared
|
|
11
|
+
* `contentIndex: false` — a Foundry dependency only, with no fetched index.
|
|
12
|
+
* A link naming one fails naming the key, rather than reading as prose or an
|
|
13
|
+
* ordinary dead address.
|
|
10
14
|
* @returns {SiteIndex} The index, and what could not be addressed unambiguously.
|
|
11
15
|
*/
|
|
12
|
-
export function buildSiteIndex(entries: readonly SiteEntry[], { foreignIndex }?: {
|
|
16
|
+
export function buildSiteIndex(entries: readonly SiteEntry[], { foreignIndex, noIndexPackages }?: {
|
|
13
17
|
foreignIndex?: Map<string, {
|
|
14
18
|
package: string;
|
|
15
19
|
type?: string;
|
|
16
20
|
}> | undefined;
|
|
21
|
+
noIndexPackages?: Set<string> | undefined;
|
|
17
22
|
}): SiteIndex;
|
|
18
23
|
/**
|
|
19
24
|
* The per-page context a wikilink resolver takes.
|
|
@@ -44,9 +44,10 @@ export function frontmatterWikilinks(fm: unknown): Array<{
|
|
|
44
44
|
*
|
|
45
45
|
* **Every target that resolves nowhere fails the build**, and is
|
|
46
46
|
* classified into the vocabulary all three resolvers share — `unlabelled`,
|
|
47
|
-
* `not-an-address`, `unknown-type`, `ambiguous`, `unresolved
|
|
48
|
-
* collected in `ctx.errors`, each carrying
|
|
49
|
-
* `occurrence` so a caller can report the line and
|
|
47
|
+
* `not-an-address`, `unknown-type`, `ambiguous`, `unresolved`,
|
|
48
|
+
* `no-content-index`. Failures are collected in `ctx.errors`, each carrying
|
|
49
|
+
* the authored `link` and its `occurrence` so a caller can report the line and
|
|
50
|
+
* column it sits on.
|
|
50
51
|
*
|
|
51
52
|
* There is deliberately no exception letting a hyphen-form address through while
|
|
52
53
|
* any linkable package had no vendored manifest, since a real cross-package
|
|
@@ -77,9 +78,12 @@ export function frontmatterWikilinks(fm: unknown): Array<{
|
|
|
77
78
|
*
|
|
78
79
|
* @param {string} body - The markdown body.
|
|
79
80
|
* @param {object} ctx - `{ index, assets, collide, sections, contentTypes,
|
|
80
|
-
* packages, foreign, type, errors, src, file }`.
|
|
81
|
+
* packages, noIndexPackages, foreign, type, errors, src, file }`.
|
|
81
82
|
* `packages` is every package an address may name, without which the leading
|
|
82
|
-
* package segment of a canonical address reads as an unknown type;
|
|
83
|
+
* package segment of a canonical address reads as an unknown type;
|
|
84
|
+
* `noIndexPackages` is every package declared `contentIndex: false`, so a
|
|
85
|
+
* qualified address naming one fails with `no-content-index` rather than
|
|
86
|
+
* `not-an-address`; `foreign`
|
|
83
87
|
* is the cross-package manifest index; `assets` is the address space an embed
|
|
84
88
|
* resolves against. `src` is the page's display
|
|
85
89
|
* path and `file` the source file a diagnostic should name — absent, `src`
|
|
@@ -223,6 +223,9 @@ export const WIKILINK: RegExp;
|
|
|
223
223
|
* - `unresolved` — parses as an address, and nothing publishes it.
|
|
224
224
|
* - `ambiguous` — more than one package publishes the short address.
|
|
225
225
|
* - `unknown-anchor` — the address resolved, the `#section` it names did not.
|
|
226
|
+
* - `no-content-index` — the address names a package declared
|
|
227
|
+
* `contentIndex: false`, a Foundry dependency only, so no index was fetched
|
|
228
|
+
* for it to resolve against.
|
|
226
229
|
*
|
|
227
230
|
* @type {ReadonlySet<string>}
|
|
228
231
|
*/
|
|
@@ -81,13 +81,18 @@ export function resolveItemDocType(qualifier: string, types: Set<string>): strin
|
|
|
81
81
|
* @param {Set<string>} types - Every type the content tree contains.
|
|
82
82
|
* @param {Set<string>} [packages] - Every package an address may name. Omitted
|
|
83
83
|
* by callers that resolve within one package, where the form cannot occur.
|
|
84
|
+
* @param {Set<string>} [noIndexPackages] - Packages declared `contentIndex:
|
|
85
|
+
* false` — a Foundry dependency only, with no fetched index. A fully
|
|
86
|
+
* qualified target naming one is refused with `no-content-index` before its
|
|
87
|
+
* type is even considered, since there is no index to resolve it against.
|
|
84
88
|
* @returns {{type: string, shortcode: string, itemDoc: boolean,
|
|
85
89
|
* package?: string, system?: string, reason?: undefined}
|
|
86
|
-
* | {reason: "unknown-type"} | null}
|
|
90
|
+
* | {reason: "unknown-type"|"no-content-index", package?: string} | null}
|
|
87
91
|
* The resolved qualifier; a `reason` when the target is definitely qualified
|
|
88
|
-
* but names no known type; or `null` when it is not an
|
|
92
|
+
* but names no known type or no fetched index; or `null` when it is not an
|
|
93
|
+
* address at all.
|
|
89
94
|
*/
|
|
90
|
-
export function readQualifier(target: string, types: Set<string>, packages?: Set<string>): {
|
|
95
|
+
export function readQualifier(target: string, types: Set<string>, packages?: Set<string>, noIndexPackages?: Set<string>): {
|
|
91
96
|
type: string;
|
|
92
97
|
shortcode: string;
|
|
93
98
|
itemDoc: boolean;
|
|
@@ -95,7 +100,8 @@ export function readQualifier(target: string, types: Set<string>, packages?: Set
|
|
|
95
100
|
system?: string;
|
|
96
101
|
reason?: undefined;
|
|
97
102
|
} | {
|
|
98
|
-
reason: "unknown-type";
|
|
103
|
+
reason: "unknown-type" | "no-content-index";
|
|
104
|
+
package?: string;
|
|
99
105
|
} | null;
|
|
100
106
|
/**
|
|
101
107
|
* The deterministic JournalEntryPage id for one anchor: SHA-256 of
|
|
@@ -132,6 +138,10 @@ export function anchorPageId(noteId: string, anchorSlug: string): string;
|
|
|
132
138
|
* @param {Map<string, object>} [opts.assets] - The files this package ships, by
|
|
133
139
|
* canonical address. They resolve no link — an asset is not a document — and
|
|
134
140
|
* answer only the art fields, which name a file and never a document.
|
|
141
|
+
* @param {Set<string>} [opts.noIndexPackages] - Packages declared
|
|
142
|
+
* `contentIndex: false` — a Foundry dependency only. A link naming one fails
|
|
143
|
+
* with `no-content-index` rather than resolving, ambiguously, as either a
|
|
144
|
+
* typo or an undeclared package.
|
|
135
145
|
* @returns {{byShortcode: Map<string, object>, types: Set<string>}} `types` is
|
|
136
146
|
* every type the tree actually contains, so a qualifier naming no real type
|
|
137
147
|
* can be told apart from a missing target.
|
|
@@ -144,8 +154,9 @@ export function buildWikilinkIndex(docs: Array<{
|
|
|
144
154
|
pack?: string;
|
|
145
155
|
docPack?: string;
|
|
146
156
|
draft?: boolean;
|
|
147
|
-
}>, packageId: string, foreign?: Map<string, object>, contentPackage?: string, { assets }?: {
|
|
157
|
+
}>, packageId: string, foreign?: Map<string, object>, contentPackage?: string, { assets, noIndexPackages }?: {
|
|
148
158
|
assets?: Map<string, object> | undefined;
|
|
159
|
+
noIndexPackages?: Set<string> | undefined;
|
|
149
160
|
}): {
|
|
150
161
|
byShortcode: Map<string, object>;
|
|
151
162
|
types: Set<string>;
|
package/types/manifest.d.mts
CHANGED
|
@@ -187,11 +187,13 @@ export function publishedRelationships(relationships: Record<string, unknown>):
|
|
|
187
187
|
* Three kinds of key end up in the result:
|
|
188
188
|
*
|
|
189
189
|
* - **Declared** — everything in `packageBuild.manifest`, emitted unchanged, so
|
|
190
|
-
* a key Foundry adds later needs no release of this package.
|
|
190
|
+
* a key Foundry adds later needs no release of this package. The one
|
|
191
|
+
* exception is `descriptionHtml`, folded into the description below rather
|
|
192
|
+
* than surviving under its own name.
|
|
191
193
|
* - **Derived** — the identity, the description, the release addresses, the
|
|
192
194
|
* version, the Foundry and system compatibility ranges, and the pack list.
|
|
193
|
-
* These are refused if also declared
|
|
194
|
-
* and the two would disagree with nothing to say so.
|
|
195
|
+
* These are refused if also declared (`description` directly; `descriptionHtml`
|
|
196
|
+
* is how it is authored) and the two would disagree with nothing to say so.
|
|
195
197
|
* - **Computed** — namespaced `flags` a repository works out for itself, merged
|
|
196
198
|
* over any it declared.
|
|
197
199
|
*
|
package/types/release.d.mts
CHANGED
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
* @param {boolean} [opts.pdf] - Whether to build the book that ships beside the
|
|
19
19
|
* archive. `true` by default; `false` skips the build and reports the skip.
|
|
20
20
|
* @returns {Promise<{zip: string, manifest: string, metadata?: string,
|
|
21
|
-
* pdf?: string, pdfFindings: object[], pdfSkipped: string|null,
|
|
21
|
+
* schema?: string, pdf?: string, pdfFindings: object[], pdfSkipped: string|null,
|
|
22
22
|
* bytes: number, version: string}>} The paths written, what the book build
|
|
23
23
|
* found, the archive's size, and the version the manifest declares.
|
|
24
|
-
* `metadata` is absent when the manifest advertises no content index,
|
|
25
|
-
* `
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* `pdfFindings`.
|
|
24
|
+
* `metadata` is absent when the manifest advertises no content index,
|
|
25
|
+
* `schema` is absent when the stage carries no `schema.json`, and `pdf` is
|
|
26
|
+
* absent when no book was written. `pdfSkipped` is `null` when a book was
|
|
27
|
+
* built, and otherwise the reason none was — itself `null` when the book
|
|
28
|
+
* builder could not be loaded, which is reported through `pdfFindings`.
|
|
29
29
|
* @throws {Error} When the stage has no manifest — there is nothing to release,
|
|
30
30
|
* and an archive without one installs as nothing.
|
|
31
31
|
*/
|
|
@@ -39,6 +39,7 @@ export function packRelease({ stageDir, outDir, artifact, metadataDir, pdf, }?:
|
|
|
39
39
|
zip: string;
|
|
40
40
|
manifest: string;
|
|
41
41
|
metadata?: string;
|
|
42
|
+
schema?: string;
|
|
42
43
|
pdf?: string;
|
|
43
44
|
pdfFindings: object[];
|
|
44
45
|
pdfSkipped: string | null;
|