@heroiclands/package-build 23.9.0 → 23.11.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 +33 -0
- package/README.md +2 -0
- package/bin/content-commands.mjs +197 -68
- package/docs/api.md +365 -70
- package/docs/authoring/first-note.md +10 -0
- package/docs/authoring/frontmatter.md +1 -1
- package/docs/authoring/links-and-markup.md +186 -49
- package/docs/commands.md +92 -3
- package/docs/content-format.md +10 -3
- package/docs/design.md +18 -0
- package/docs/guides/book.md +7 -0
- package/docs/guides/site.md +7 -0
- package/docs/reference/format-details.md +186 -15
- package/docs/reference/note-types.md +4 -4
- package/engine/anchors.mjs +43 -9
- package/engine/base-compiler.mjs +6 -4
- package/engine/changelog-group.mjs +58 -34
- package/engine/changelog-lint.mjs +6 -2
- package/engine/compendiums.mjs +15 -1
- package/engine/compile-corpus.mjs +14 -1
- package/engine/content-charset.mjs +13 -1
- package/engine/content-html.mjs +18 -4
- package/engine/content-icons.mjs +15 -1
- package/engine/content-images.mjs +28 -9
- package/engine/content-index.mjs +102 -23
- package/engine/content-links.mjs +68 -30
- package/engine/content-session.mjs +247 -0
- package/engine/content-sources.mjs +110 -0
- package/engine/content-spans.mjs +118 -14
- package/engine/content-tables.mjs +1 -0
- package/engine/content-tasklists.mjs +20 -4
- package/engine/diagnostics.mjs +17 -6
- package/engine/extension-attributes.mjs +28 -5
- package/engine/first-use.mjs +371 -0
- package/engine/foundry-entries.mjs +12 -9
- package/engine/generate.mjs +13 -4
- package/engine/helpers.mjs +47 -16
- package/engine/index-records.mjs +1 -0
- package/engine/index.mjs +3 -0
- package/engine/journals.mjs +9 -5
- package/engine/language-data.mjs +2 -2
- package/engine/language-rows.mjs +4 -4
- package/engine/language-terms.mjs +4 -4
- package/engine/lexical-sections.mjs +5 -5
- package/engine/markup-validation.mjs +7 -2
- package/engine/metadata-index.mjs +1 -0
- package/engine/name-markup.mjs +114 -0
- package/engine/name-rows.mjs +70 -0
- package/engine/names.mjs +460 -0
- package/engine/note-addresses.mjs +25 -4
- package/engine/path-charset.mjs +24 -1
- package/engine/pdf-render.mjs +15 -1
- package/engine/site-index.mjs +25 -2
- package/engine/sql-tables.mjs +76 -15
- package/engine/stub-lint.mjs +4 -3
- package/engine/web-wikilinks.mjs +33 -12
- package/engine/wikilink-syntax.mjs +65 -8
- package/engine/wikilinks.mjs +29 -11
- package/engine/yaml-lint.mjs +3 -5
- package/hugo-theme/layouts/partials/footer.html +2 -0
- package/hugo-theme/static/css/style.css +20 -0
- package/hugo-theme/static/js/inline-spoilers.js +23 -0
- package/package.json +1 -1
- package/types/engine/anchors.d.mts +6 -3
- package/types/engine/compendiums.d.mts +5 -1
- package/types/engine/compile-corpus.d.mts +5 -2
- package/types/engine/content-charset.d.mts +5 -1
- package/types/engine/content-html.d.mts +5 -1
- package/types/engine/content-icons.d.mts +5 -1
- package/types/engine/content-images.d.mts +5 -1
- package/types/engine/content-index.d.mts +39 -19
- package/types/engine/content-links.d.mts +22 -8
- package/types/engine/content-session.d.mts +108 -0
- package/types/engine/content-sources.d.mts +32 -0
- package/types/engine/content-spans.d.mts +8 -6
- package/types/engine/content-tasklists.d.mts +5 -1
- package/types/engine/diagnostics.d.mts +10 -0
- package/types/engine/extension-attributes.d.mts +16 -2
- package/types/engine/first-use.d.mts +31 -0
- package/types/engine/foundry-entries.d.mts +11 -4
- package/types/engine/generate.d.mts +5 -1
- package/types/engine/helpers.d.mts +30 -7
- package/types/engine/index.d.mts +1 -0
- package/types/engine/journals.d.mts +5 -2
- package/types/engine/lexical-sections.d.mts +3 -2
- package/types/engine/markup-validation.d.mts +2 -1
- package/types/engine/name-markup.d.mts +176 -0
- package/types/engine/name-rows.d.mts +35 -0
- package/types/engine/names.d.mts +356 -0
- package/types/engine/note-addresses.d.mts +3 -3
- package/types/engine/path-charset.d.mts +16 -1
- package/types/engine/site-build.d.mts +2 -2
- package/types/engine/site-index.d.mts +3 -1
- package/types/engine/sql-tables.d.mts +7 -2
- package/types/engine/stub-lint.d.mts +3 -1
- package/types/engine/wikilink-syntax.d.mts +40 -3
|
@@ -12,22 +12,25 @@
|
|
|
12
12
|
* picture's address to the role its asset declares, so a figure anchor's
|
|
13
13
|
* `name` reads `Map 1` rather than `Figure 1` where it is due — see
|
|
14
14
|
* {@link module:engine/content-figures.scanFigures}.
|
|
15
|
+
* @param {import("./content-session.mjs").ContentSyntax} [syntax] - Exact-text scanner projections.
|
|
15
16
|
* @returns {Array<{slug: string, name: string, level: number, line: number,
|
|
16
|
-
* kind: string}>} In document order.
|
|
17
|
+
* kind: string, secret?: boolean}>} In document order.
|
|
17
18
|
*/
|
|
18
|
-
export function collectAnchors(body: string, bodyLine?: number, resolveRole?: (address: string) => string | undefined): Array<{
|
|
19
|
+
export function collectAnchors(body: string, bodyLine?: number, resolveRole?: (address: string) => string | undefined, syntax?: import("./content-session.mjs").ContentSyntax): Array<{
|
|
19
20
|
slug: string;
|
|
20
21
|
name: string;
|
|
21
22
|
level: number;
|
|
22
23
|
line: number;
|
|
23
24
|
kind: string;
|
|
25
|
+
secret?: boolean;
|
|
24
26
|
}>;
|
|
25
27
|
/** Collisions involving a div, verse or inline-span anchor.
|
|
26
28
|
* Heading and caption collisions are diagnosed by their existing scanners.
|
|
27
29
|
* @param {string} body - Authored Markdown.
|
|
30
|
+
* @param {import("./content-session.mjs").ContentSyntax} [syntax] - Exact-text scanner projections.
|
|
28
31
|
* @returns {Array<{line: number, column: number, message: string}>} Located collisions.
|
|
29
32
|
*/
|
|
30
|
-
export function markupAnchorFindings(body: string): Array<{
|
|
33
|
+
export function markupAnchorFindings(body: string, syntax?: import("./content-session.mjs").ContentSyntax): Array<{
|
|
31
34
|
line: number;
|
|
32
35
|
column: number;
|
|
33
36
|
message: string;
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* @param {string} [opts.stageDest] Directory the LevelDB packs are built
|
|
13
13
|
* into, one subdirectory per pack. Defaults to the configured stage.
|
|
14
14
|
* @param {string} [opts.packName] Restrict the run to a single pack.
|
|
15
|
+
* @param {import("./content-session.mjs").ContentSession} [opts.session] - Captured context shared with other operations.
|
|
16
|
+
* @param {boolean} [opts.reportPreparation=true] - Emit shared preparation findings unless the caller already reported them.
|
|
15
17
|
* @throws {Error} If pack JSON generation reported any error. Packs compiled
|
|
16
18
|
* from incomplete or empty JSON ship blank or short compendiums, and the
|
|
17
19
|
* omission is invisible until a player looks for content that is not there
|
|
@@ -23,11 +25,13 @@
|
|
|
23
25
|
* map image is gone before anyone notices it was ever at risk. See
|
|
24
26
|
* {@link verifyPackSceneLevels}.
|
|
25
27
|
*/
|
|
26
|
-
export function compilePacks({ config, sourcePacks, stageDest, packName, }?: {
|
|
28
|
+
export function compilePacks({ config, sourcePacks, stageDest, packName, session, reportPreparation, }?: {
|
|
27
29
|
config?: object | undefined;
|
|
28
30
|
sourcePacks?: string[] | undefined;
|
|
29
31
|
stageDest?: string | undefined;
|
|
30
32
|
packName?: string | undefined;
|
|
33
|
+
session?: import("./content-session.mjs").ContentSession | undefined;
|
|
34
|
+
reportPreparation?: boolean | undefined;
|
|
31
35
|
}): Promise<void>;
|
|
32
36
|
/**
|
|
33
37
|
* Cleans and formats source JSON files, removing unnecessary permissions and flags and adding the proper spacing.
|
|
@@ -15,20 +15,23 @@
|
|
|
15
15
|
* created when none is passed, and returned on the corpus either way — a note
|
|
16
16
|
* the index refuses is a note the compile must still *report*, exactly as the
|
|
17
17
|
* compile loop reported it when the loop was the first to see it.
|
|
18
|
-
* @
|
|
18
|
+
* @param {import("./content-session.mjs").ContentSession} [opts.session] - Captured context shared with other operations.
|
|
19
|
+
* @returns {Promise<{records: object[], parsed: Map<string, object>, linkIndex: object, sqlTables: Map<string, object[]>|undefined, problems: object[], syntax?: import("./content-session.mjs").ContentSyntax}>} The corpus,
|
|
19
20
|
* its indexes, and the notes it could not record.
|
|
20
21
|
*/
|
|
21
|
-
export function buildCompileCorpus({ contentBase, assetsBase, skipDirectories, router, config, problems, }: {
|
|
22
|
+
export function buildCompileCorpus({ contentBase, assetsBase, skipDirectories, router, config, problems, session, }: {
|
|
22
23
|
contentBase: string;
|
|
23
24
|
assetsBase?: string | undefined;
|
|
24
25
|
skipDirectories: readonly string[];
|
|
25
26
|
router: object;
|
|
26
27
|
config?: object | undefined;
|
|
27
28
|
problems?: object[] | undefined;
|
|
29
|
+
session?: import("./content-session.mjs").ContentSession | undefined;
|
|
28
30
|
}): Promise<{
|
|
29
31
|
records: object[];
|
|
30
32
|
parsed: Map<string, object>;
|
|
31
33
|
linkIndex: object;
|
|
32
34
|
sqlTables: Map<string, object[]> | undefined;
|
|
33
35
|
problems: object[];
|
|
36
|
+
syntax?: import("./content-session.mjs").ContentSyntax;
|
|
34
37
|
}>;
|
|
@@ -87,13 +87,17 @@ export function checkText(text: string, file: string): Array<{
|
|
|
87
87
|
* @param {readonly string[]} [opts.skipDirectories] - Directory names to ignore
|
|
88
88
|
* in addition to the dot-directories always skipped.
|
|
89
89
|
* @param {readonly string[]} [opts.extensions] - File extensions to read.
|
|
90
|
+
* @param {Map<string, {raw: string}>} [opts.sources] - Exact captured source strings; omitted, walks and reads the tree.
|
|
90
91
|
* @returns {{findings: Array<{file: string, line: number, column: number,
|
|
91
92
|
* severity: "warning", message: string}>, files: number}} The findings, and how
|
|
92
93
|
* many files produced them.
|
|
93
94
|
*/
|
|
94
|
-
export function lintContentCharset(contentBase: string, { skipDirectories, extensions }?: {
|
|
95
|
+
export function lintContentCharset(contentBase: string, { skipDirectories, extensions, sources }?: {
|
|
95
96
|
skipDirectories?: readonly string[] | undefined;
|
|
96
97
|
extensions?: readonly string[] | undefined;
|
|
98
|
+
sources?: Map<string, {
|
|
99
|
+
raw: string;
|
|
100
|
+
}> | undefined;
|
|
97
101
|
}): {
|
|
98
102
|
findings: Array<{
|
|
99
103
|
file: string;
|
|
@@ -47,12 +47,16 @@ export function checkHtml(body: string, file: string, { bodyLine, bodyColumn }?:
|
|
|
47
47
|
* @param {object} [opts]
|
|
48
48
|
* @param {readonly string[]} [opts.skipDirectories] - Directory names to ignore
|
|
49
49
|
* in addition to the dot-directories always skipped.
|
|
50
|
+
* @param {Map<string, {raw: string}>} [opts.sources] - Exact captured source strings; omitted, walks and reads the tree.
|
|
50
51
|
* @returns {{findings: Array<{file: string, line: number, column: number,
|
|
51
52
|
* severity: "warning", message: string}>, files: number}} The findings, and
|
|
52
53
|
* how many files were read.
|
|
53
54
|
*/
|
|
54
|
-
export function lintContentHtml(contentBase: string, { skipDirectories }?: {
|
|
55
|
+
export function lintContentHtml(contentBase: string, { skipDirectories, sources }?: {
|
|
55
56
|
skipDirectories?: readonly string[] | undefined;
|
|
57
|
+
sources?: Map<string, {
|
|
58
|
+
raw: string;
|
|
59
|
+
}> | undefined;
|
|
56
60
|
}): {
|
|
57
61
|
findings: Array<{
|
|
58
62
|
file: string;
|
|
@@ -119,12 +119,16 @@ export function checkIconRegistry(registry: {
|
|
|
119
119
|
* @param {object} [opts]
|
|
120
120
|
* @param {readonly string[]} [opts.skipDirectories] - Directory names to ignore.
|
|
121
121
|
* @param {IconRegistry} [opts.registry] - The package's registry.
|
|
122
|
+
* @param {Map<string, {raw: string}>} [opts.sources] - Exact captured source strings; omitted, walks and reads the tree.
|
|
122
123
|
* @returns {{findings: Array<{file: string, line: number, column: number,
|
|
123
124
|
* severity: "warning", message: string}>, files: number}} What it found.
|
|
124
125
|
*/
|
|
125
|
-
export function lintContentIcons(contentBase: string, { skipDirectories, registry }?: {
|
|
126
|
+
export function lintContentIcons(contentBase: string, { skipDirectories, registry, sources }?: {
|
|
126
127
|
skipDirectories?: readonly string[] | undefined;
|
|
127
128
|
registry?: IconRegistry | undefined;
|
|
129
|
+
sources?: Map<string, {
|
|
130
|
+
raw: string;
|
|
131
|
+
}> | undefined;
|
|
128
132
|
}): {
|
|
129
133
|
findings: Array<{
|
|
130
134
|
file: string;
|
|
@@ -215,13 +215,17 @@ export function checkImages(body: string, file: string, { bodyLine, bodyColumn,
|
|
|
215
215
|
* in addition to the dot-directories always skipped.
|
|
216
216
|
* @param {object} [opts.config] - The resolved build configuration, passed to
|
|
217
217
|
* {@link checkImages} so an address is held to the Foundry surface too.
|
|
218
|
+
* @param {Map<string, {raw: string}>} [opts.sources] - Exact captured source strings; omitted, walks and reads the tree.
|
|
218
219
|
* @returns {{findings: Array<{file: string, line: number, column: number|undefined,
|
|
219
220
|
* severity: "error", message: string}>, files: number}} The findings, and how
|
|
220
221
|
* many files were read.
|
|
221
222
|
*/
|
|
222
|
-
export function lintContentImages(contentBase: string, { skipDirectories, config }?: {
|
|
223
|
+
export function lintContentImages(contentBase: string, { skipDirectories, config, sources }?: {
|
|
223
224
|
skipDirectories?: readonly string[] | undefined;
|
|
224
225
|
config?: object | undefined;
|
|
226
|
+
sources?: Map<string, {
|
|
227
|
+
raw: string;
|
|
228
|
+
}> | undefined;
|
|
225
229
|
}): {
|
|
226
230
|
findings: Array<{
|
|
227
231
|
file: string;
|
|
@@ -100,6 +100,8 @@ export function asciiAliases(aliases: unknown): Array<string>;
|
|
|
100
100
|
* and for the one question that decides whether the note publishes a page. A
|
|
101
101
|
* caller that states no body is stating an empty one, and the note is a stub.
|
|
102
102
|
* @param {number} [options.bodyLine] - The 1-based file line the body starts on.
|
|
103
|
+
* @param {number} [options.bodyColumn] - The 1-based UTF-16 column of its first character.
|
|
104
|
+
* @param {Iterable<string>} [options.nameTypes] - Additional bare name kinds from configured type declarations.
|
|
103
105
|
* @param {object} [options.manifest] - The package manifest, which the Foundry
|
|
104
106
|
* entries are derived against.
|
|
105
107
|
* @param {object} [options.addressContext] - Address resolution context.
|
|
@@ -108,6 +110,7 @@ export function asciiAliases(aliases: unknown): Array<string>;
|
|
|
108
110
|
* a picture's address to the role its asset declares, so a figure anchor's
|
|
109
111
|
* `name` reads `Map 1` rather than `Figure 1` where it is due — see
|
|
110
112
|
* {@link module:engine/content-figures.scanFigures}.
|
|
113
|
+
* @param {import("./content-session.mjs").ContentSyntax} [options.syntax] - Session scanner projections.
|
|
111
114
|
* @returns {Record<string, any>} The record, keys sorted at every depth. A
|
|
112
115
|
* **stub** — a note with an empty body, on a type an empty body suppresses —
|
|
113
116
|
* carries `address` and `anchors` as `null`: it publishes no page, so it
|
|
@@ -119,7 +122,7 @@ export function asciiAliases(aliases: unknown): Array<string>;
|
|
|
119
122
|
* otherwise be overwritten without a word. `file` and, where the file was
|
|
120
123
|
* read, `position` ride on the error.
|
|
121
124
|
*/
|
|
122
|
-
export function buildIndexRecord({ frontmatter, relPath, absPath, raw, contentPackage, body, bodyLine, manifest, addressContext, dateContext, resolveRole, }: {
|
|
125
|
+
export function buildIndexRecord({ frontmatter, relPath, absPath, raw, contentPackage, body, bodyLine, bodyColumn, nameTypes, manifest, addressContext, dateContext, resolveRole, syntax, }: {
|
|
123
126
|
frontmatter: Record<string, any>;
|
|
124
127
|
relPath: string;
|
|
125
128
|
absPath?: string | undefined;
|
|
@@ -127,25 +130,19 @@ export function buildIndexRecord({ frontmatter, relPath, absPath, raw, contentPa
|
|
|
127
130
|
contentPackage: string;
|
|
128
131
|
body?: string | undefined;
|
|
129
132
|
bodyLine?: number | undefined;
|
|
133
|
+
bodyColumn?: number | undefined;
|
|
134
|
+
nameTypes?: Iterable<string> | undefined;
|
|
130
135
|
manifest?: object | undefined;
|
|
131
136
|
addressContext?: object | undefined;
|
|
132
137
|
dateContext?: object | undefined;
|
|
133
138
|
resolveRole?: ((address: string) => string | undefined) | undefined;
|
|
139
|
+
syntax?: import("./content-session.mjs").ContentSyntax | undefined;
|
|
134
140
|
}): Record<string, any>;
|
|
135
|
-
/**
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
relPath: any;
|
|
141
|
-
absPath: any;
|
|
142
|
-
raw: any;
|
|
143
|
-
contentPackage: any;
|
|
144
|
-
manifest: any;
|
|
145
|
-
addressContext: any;
|
|
146
|
-
dateContext: any;
|
|
147
|
-
resolveRole: any;
|
|
148
|
-
}): object[];
|
|
141
|
+
/**
|
|
142
|
+
* Derive every index record belonging to one parsed note.
|
|
143
|
+
* @param {Parameters<typeof buildIndexRecord>[0]} options - Authored note and its context.
|
|
144
|
+
*/
|
|
145
|
+
export function indexRecordsForNote({ frontmatter, body, bodyLine, bodyColumn, nameTypes, relPath, absPath, raw, contentPackage, manifest, addressContext, dateContext, resolveRole, syntax, }: Parameters<typeof buildIndexRecord>[0]): object[];
|
|
149
146
|
/**
|
|
150
147
|
* Write each note's resolved culture into its record, as `data.culture`.
|
|
151
148
|
*
|
|
@@ -243,10 +240,13 @@ export function resolveCultures(records: Array<Record<string, any>>, { contentPa
|
|
|
243
240
|
* @param {Map<string, {body: string, frontmatter: object|null, raw: string, bodyLine?: number, bodyColumn?: number}>} [options.parsed] -
|
|
244
241
|
* Filled with each note's source text, body coordinates and frontmatter as
|
|
245
242
|
* authored, keyed by file, for reuse throughout the command.
|
|
243
|
+
* @param {Map<string, {raw: string}>} [options.sources] - Selected captured source strings.
|
|
244
|
+
* @param {import("./content-session.mjs").ContentSyntax} [options.syntax] - Session scanner projections.
|
|
245
|
+
* @param {Iterable<string>} [options.nameTypes] - Additional bare name kinds from configured type declarations.
|
|
246
246
|
* @returns {Array<Record<string, any>>} The records, in a total order that does
|
|
247
247
|
* not depend on directory-read order.
|
|
248
248
|
*/
|
|
249
|
-
export function collectContentIndex(contentBase: string, { contentPackage, skipDirectories, assetsBase, manifest, problems, addressContext, foreignRecord, parsed, }: {
|
|
249
|
+
export function collectContentIndex(contentBase: string, { contentPackage, skipDirectories, assetsBase, manifest, problems, addressContext, foreignRecord, parsed, sources, syntax, nameTypes, }: {
|
|
250
250
|
contentPackage: string;
|
|
251
251
|
skipDirectories: readonly string[];
|
|
252
252
|
assetsBase?: string | undefined;
|
|
@@ -263,6 +263,11 @@ export function collectContentIndex(contentBase: string, { contentPackage, skipD
|
|
|
263
263
|
bodyLine?: number;
|
|
264
264
|
bodyColumn?: number;
|
|
265
265
|
}> | undefined;
|
|
266
|
+
sources?: Map<string, {
|
|
267
|
+
raw: string;
|
|
268
|
+
}> | undefined;
|
|
269
|
+
syntax?: import("./content-session.mjs").ContentSyntax | undefined;
|
|
270
|
+
nameTypes?: Iterable<string> | undefined;
|
|
266
271
|
}): Array<Record<string, any>>;
|
|
267
272
|
/**
|
|
268
273
|
* Serialize records as JSON Lines.
|
|
@@ -303,9 +308,13 @@ export function serializeContentIndex(records: Array<Record<string, any>>): stri
|
|
|
303
308
|
* Filled with each note's body and authored frontmatter, keyed by the note's
|
|
304
309
|
* file. Handed to {@link module:engine/sql-tables.prepareTreeSqlTables}, it
|
|
305
310
|
* spares that pass reading and parsing every note again.
|
|
311
|
+
* @param {Map<string, {raw: string}>} [opts.sources] - Selected source strings, in index walk order.
|
|
312
|
+
* @param {import("./content-session.mjs").ContentSyntax} [opts.syntax] - Session scanner projections.
|
|
313
|
+
* @param {Iterable<string>} [opts.nameTypes] - Bare name kinds, defaulting to configured item types.
|
|
314
|
+
* @param {Map<string, object>} [opts.foreignIndex] - Captured dependency address view.
|
|
306
315
|
* @returns {object[]} One record per note, plus one per documentation entry.
|
|
307
316
|
*/
|
|
308
|
-
export function indexRecordsFor({ contentBase, assetsBase, config, skipDirectories, problems, parsed, }?: {
|
|
317
|
+
export function indexRecordsFor({ contentBase, assetsBase, config, skipDirectories, problems, parsed, sources, syntax, nameTypes, foreignIndex, }?: {
|
|
309
318
|
contentBase?: string | undefined;
|
|
310
319
|
assetsBase?: string | undefined;
|
|
311
320
|
config?: object | undefined;
|
|
@@ -318,6 +327,12 @@ export function indexRecordsFor({ contentBase, assetsBase, config, skipDirectori
|
|
|
318
327
|
bodyLine?: number;
|
|
319
328
|
bodyColumn?: number;
|
|
320
329
|
}> | undefined;
|
|
330
|
+
sources?: Map<string, {
|
|
331
|
+
raw: string;
|
|
332
|
+
}> | undefined;
|
|
333
|
+
syntax?: import("./content-session.mjs").ContentSyntax | undefined;
|
|
334
|
+
nameTypes?: Iterable<string> | undefined;
|
|
335
|
+
foreignIndex?: Map<string, object> | undefined;
|
|
321
336
|
}): object[];
|
|
322
337
|
/**
|
|
323
338
|
* Prepare the complete bodies a content-index publication describes.
|
|
@@ -325,12 +340,13 @@ export function indexRecordsFor({ contentBase, assetsBase, config, skipDirectori
|
|
|
325
340
|
* corpus, with target maps limited to that source's declared prose slugs.
|
|
326
341
|
* No output files are written, and the returned inputs are read-only to the emitter.
|
|
327
342
|
*
|
|
328
|
-
* @param {{contentBase?: string, config?: object}} [options]
|
|
343
|
+
* @param {{contentBase?: string, config?: object, session?: import("./content-session.mjs").ContentSession}} [options]
|
|
329
344
|
* @returns {Promise<PreparedContentIndex>}
|
|
330
345
|
*/
|
|
331
|
-
export function prepareContentIndex({ contentBase, config }?: {
|
|
346
|
+
export function prepareContentIndex({ contentBase, config, session }?: {
|
|
332
347
|
contentBase?: string;
|
|
333
348
|
config?: object;
|
|
349
|
+
session?: import("./content-session.mjs").ContentSession;
|
|
334
350
|
}): Promise<PreparedContentIndex>;
|
|
335
351
|
/**
|
|
336
352
|
* Emit this package's content index.
|
|
@@ -426,6 +442,10 @@ export type PreparedContentIndex = {
|
|
|
426
442
|
}>;
|
|
427
443
|
generatedFrom?: number;
|
|
428
444
|
}>;
|
|
445
|
+
/**
|
|
446
|
+
* - Session-local exact-text scanner projections.
|
|
447
|
+
*/
|
|
448
|
+
syntax?: import("./content-session.mjs").ContentSyntax | undefined;
|
|
429
449
|
};
|
|
430
450
|
import { collectAnchors } from "./anchors.mjs";
|
|
431
451
|
import { authoredFrontmatter } from "./index-records.mjs";
|
|
@@ -31,13 +31,11 @@ export function anchorsOf(body: string): Set<string>;
|
|
|
31
31
|
* not hypothetical: this module carried its own anchor reader until the anchor
|
|
32
32
|
* anchor half, and the two disagreed about which anchors existed.
|
|
33
33
|
*
|
|
34
|
-
* **
|
|
35
|
-
* carries no note
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* before, since the walk read the file and it then read it again for the raw
|
|
40
|
-
* text.
|
|
34
|
+
* **Raw sources can come from the caller's capture.** The published index
|
|
35
|
+
* carries no note body, while a link lives in the prose. A caller that already
|
|
36
|
+
* captured the sources supplies `parsed`, so this pass uses those exact raw
|
|
37
|
+
* strings. Without a captured string, it opens the file for its bytes.
|
|
38
|
+
* Frontmatter, addresses and anchors still come from the records.
|
|
41
39
|
*
|
|
42
40
|
* The index holds each compiled document under its complete Address. Readable
|
|
43
41
|
* content uses `note`, and system documents use their declared system.
|
|
@@ -55,17 +53,33 @@ export function anchorsOf(body: string): Set<string>;
|
|
|
55
53
|
* @param {object[]} [opts.records] - Index records the caller already derived,
|
|
56
54
|
* so a command that also needs them — every one of them does, to answer its
|
|
57
55
|
* `sql` tables — enumerates the corpus once rather than twice.
|
|
56
|
+
* @param {Map<string, {raw: string}>} [opts.parsed] - Sources captured alongside
|
|
57
|
+
* `records` in this invocation, keyed by absolute note path. A raw string is
|
|
58
|
+
* used verbatim; a missing string falls back to reading the file. The caller
|
|
59
|
+
* owns the map, which this function only reads.
|
|
58
60
|
* @param {object[]} [opts.problems] - Collects the notes the index cannot
|
|
59
61
|
* record, as diagnostics, instead of letting one of them abort the check
|
|
60
62
|
* before it has reported anything else.
|
|
63
|
+
* @param {ReturnType<import("./metadata-index.mjs").loadForeignIndexes>} [opts.foreign] - Captured dependency address and reference views.
|
|
61
64
|
* @returns {object} The notes, the index, and the resolvers built over it.
|
|
62
65
|
*/
|
|
63
|
-
export function buildLinkIndex(contentBase: string, { config, skipDirectories, sqlTables, records, problems }?: {
|
|
66
|
+
export function buildLinkIndex(contentBase: string, { config, skipDirectories, sqlTables, records, parsed, problems, foreign: capturedForeign, }?: {
|
|
64
67
|
config?: object | undefined;
|
|
65
68
|
skipDirectories?: readonly string[] | undefined;
|
|
66
69
|
sqlTables?: Map<string, object[]> | undefined;
|
|
67
70
|
records?: object[] | undefined;
|
|
71
|
+
parsed?: Map<string, {
|
|
72
|
+
raw: string;
|
|
73
|
+
}> | undefined;
|
|
68
74
|
problems?: object[] | undefined;
|
|
75
|
+
foreign?: {
|
|
76
|
+
index: Map<string, object>;
|
|
77
|
+
packages: Set<string>;
|
|
78
|
+
stale: Array<{
|
|
79
|
+
package: string;
|
|
80
|
+
reason: string;
|
|
81
|
+
}>;
|
|
82
|
+
} | undefined;
|
|
69
83
|
}): object;
|
|
70
84
|
/**
|
|
71
85
|
* Every defect in the addresses a package homepage carries.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture one source tree for index, lint, links and compilation.
|
|
3
|
+
* No source or parser state is persisted or reused by another invocation.
|
|
4
|
+
* Prepared SQL databases close within their existing preparation functions.
|
|
5
|
+
* @param {object} [options]
|
|
6
|
+
* @param {import("../content-config.mjs").ContentBuildConfig} [options.config] - Exact resolved configuration.
|
|
7
|
+
* @param {string} [options.contentBase] - Content root, defaulting to configuration.
|
|
8
|
+
* @param {string} [options.assetsBase] - Assets root, defaulting to configuration.
|
|
9
|
+
* @param {readonly string[]} [options.skipDirectories] - Resolved content scope.
|
|
10
|
+
* @param {ReturnType<typeof routerFor>} [options.router] - One router shared by this session's compile.
|
|
11
|
+
* @returns {Promise<ContentSession>} Captured sources and lazy prepared views; dispose after use.
|
|
12
|
+
*/
|
|
13
|
+
export function createContentSession({ config, contentBase, assetsBase, skipDirectories, router, }?: {
|
|
14
|
+
config?: import("../content-config.mjs").ContentBuildConfig | undefined;
|
|
15
|
+
contentBase?: string | undefined;
|
|
16
|
+
assetsBase?: string | undefined;
|
|
17
|
+
skipDirectories?: readonly string[] | undefined;
|
|
18
|
+
router?: {
|
|
19
|
+
resolve: (fm: object, docType: string, system?: string) => string | undefined;
|
|
20
|
+
resolveOrNull: (fm: object, docType: string, system?: string) => string | undefined;
|
|
21
|
+
packsOfType: (docType: string) => string[];
|
|
22
|
+
defaultOf: (docType: string) => string | undefined;
|
|
23
|
+
} | undefined;
|
|
24
|
+
}): Promise<ContentSession>;
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {"index"|"lint"|"links"|"compile"} ContentTarget
|
|
27
|
+
* @typedef {(source: string) => {blocks: ReturnType<typeof blocks.scanBlocks>, alerts: ReturnType<typeof alerts.scanAlerts>, spans: ReturnType<typeof spans.scanSpans>}} ContentSyntax
|
|
28
|
+
* @typedef {{config?: import("../content-config.mjs").ContentBuildConfig, contentBase?: string, assetsBase?: string, skipDirectories?: readonly string[], router?: ReturnType<typeof routerFor>}} ContentSessionContext
|
|
29
|
+
* @typedef {{frontmatter: object|null, body: string, raw: string, bodyLine?: number, bodyColumn?: number}} ContentNoteSource
|
|
30
|
+
* @typedef {object} ContentSession
|
|
31
|
+
* @property {import("../content-config.mjs").ContentBuildConfig} config
|
|
32
|
+
* @property {string} contentBase
|
|
33
|
+
* @property {string} assetsBase
|
|
34
|
+
* @property {readonly string[]} skipDirectories
|
|
35
|
+
* @property {ReturnType<typeof routerFor>} router
|
|
36
|
+
* @property {ReturnType<typeof captureContentSources>} inventory
|
|
37
|
+
* @property {Map<string, {raw: string}>} sources
|
|
38
|
+
* @property {object[]} records
|
|
39
|
+
* @property {Map<string, ContentNoteSource>} parsed
|
|
40
|
+
* @property {object[]} problems
|
|
41
|
+
* @property {ReturnType<typeof loadForeignIndexes>} foreign
|
|
42
|
+
* @property {ContentSyntax} syntax
|
|
43
|
+
* @property {(options?: ContentSessionContext) => void} assertContext
|
|
44
|
+
* @property {(audience?: "all"|"public") => ReturnType<typeof sql.prepareTreeSqlTables>} sqlTables
|
|
45
|
+
* @property {() => ReturnType<typeof sql.prepareLinkSqlTables>} linkTables
|
|
46
|
+
* @property {(kind?: "lint"|"links") => Promise<ReturnType<typeof buildLinkIndex>>} audit
|
|
47
|
+
* @property {() => Promise<import("./content-index.mjs").PreparedContentIndex>} publication
|
|
48
|
+
* @property {() => ReturnType<import("./compile-corpus.mjs").buildCompileCorpus>} compileCorpus
|
|
49
|
+
* @property {(targets: readonly ContentTarget[]) => Promise<ContentSession>} prepare
|
|
50
|
+
* @property {() => void} dispose
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* The explicit runner's target vocabulary and execution order.
|
|
54
|
+
* @type {readonly ContentTarget[]}
|
|
55
|
+
*/
|
|
56
|
+
export const CONTENT_TARGETS: readonly ContentTarget[];
|
|
57
|
+
export type ContentTarget = "index" | "lint" | "links" | "compile";
|
|
58
|
+
export type ContentSyntax = (source: string) => {
|
|
59
|
+
blocks: ReturnType<typeof blocks.scanBlocks>;
|
|
60
|
+
alerts: ReturnType<typeof alerts.scanAlerts>;
|
|
61
|
+
spans: ReturnType<typeof spans.scanSpans>;
|
|
62
|
+
};
|
|
63
|
+
export type ContentSessionContext = {
|
|
64
|
+
config?: import("../content-config.mjs").ContentBuildConfig;
|
|
65
|
+
contentBase?: string;
|
|
66
|
+
assetsBase?: string;
|
|
67
|
+
skipDirectories?: readonly string[];
|
|
68
|
+
router?: ReturnType<typeof routerFor>;
|
|
69
|
+
};
|
|
70
|
+
export type ContentNoteSource = {
|
|
71
|
+
frontmatter: object | null;
|
|
72
|
+
body: string;
|
|
73
|
+
raw: string;
|
|
74
|
+
bodyLine?: number;
|
|
75
|
+
bodyColumn?: number;
|
|
76
|
+
};
|
|
77
|
+
export type ContentSession = {
|
|
78
|
+
config: import("../content-config.mjs").ContentBuildConfig;
|
|
79
|
+
contentBase: string;
|
|
80
|
+
assetsBase: string;
|
|
81
|
+
skipDirectories: readonly string[];
|
|
82
|
+
router: ReturnType<typeof routerFor>;
|
|
83
|
+
inventory: ReturnType<typeof captureContentSources>;
|
|
84
|
+
sources: Map<string, {
|
|
85
|
+
raw: string;
|
|
86
|
+
}>;
|
|
87
|
+
records: object[];
|
|
88
|
+
parsed: Map<string, ContentNoteSource>;
|
|
89
|
+
problems: object[];
|
|
90
|
+
foreign: ReturnType<typeof loadForeignIndexes>;
|
|
91
|
+
syntax: ContentSyntax;
|
|
92
|
+
assertContext: (options?: ContentSessionContext) => void;
|
|
93
|
+
sqlTables: (audience?: "all" | "public") => ReturnType<typeof sql.prepareTreeSqlTables>;
|
|
94
|
+
linkTables: () => ReturnType<typeof sql.prepareLinkSqlTables>;
|
|
95
|
+
audit: (kind?: "lint" | "links") => Promise<ReturnType<typeof buildLinkIndex>>;
|
|
96
|
+
publication: () => Promise<import("./content-index.mjs").PreparedContentIndex>;
|
|
97
|
+
compileCorpus: () => ReturnType<typeof import("./compile-corpus.mjs").buildCompileCorpus>;
|
|
98
|
+
prepare: (targets: readonly ContentTarget[]) => Promise<ContentSession>;
|
|
99
|
+
dispose: () => void;
|
|
100
|
+
};
|
|
101
|
+
import * as blocks from "./content-blocks.mjs";
|
|
102
|
+
import * as alerts from "./content-alerts.mjs";
|
|
103
|
+
import * as spans from "./content-spans.mjs";
|
|
104
|
+
import { routerFor } from "./pack-router.mjs";
|
|
105
|
+
import { captureContentSources } from "./content-sources.mjs";
|
|
106
|
+
import { loadForeignIndexes } from "./metadata-index.mjs";
|
|
107
|
+
import * as sql from "./sql-tables.mjs";
|
|
108
|
+
import { buildLinkIndex } from "./content-links.mjs";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture exact text once and retain directory entries for physical checks.
|
|
3
|
+
* The index walk and raw check walks retain their established traversal orders.
|
|
4
|
+
* @param {string} contentBase - Absolute content root.
|
|
5
|
+
* @param {string} assetsBase - Absolute assets root.
|
|
6
|
+
* @param {readonly string[]} skipDirectories - Resolved directory scope.
|
|
7
|
+
* @returns {{sources: Map<string, {raw: string}>, indexSources: Map<string, {raw: string}>, paths: Array<{root: string, file: string, name: string, directory: boolean}>}} Captured input and physical walk order.
|
|
8
|
+
*/
|
|
9
|
+
export function captureContentSources(contentBase: string, assetsBase: string, skipDirectories: readonly string[]): {
|
|
10
|
+
sources: Map<string, {
|
|
11
|
+
raw: string;
|
|
12
|
+
}>;
|
|
13
|
+
indexSources: Map<string, {
|
|
14
|
+
raw: string;
|
|
15
|
+
}>;
|
|
16
|
+
paths: Array<{
|
|
17
|
+
root: string;
|
|
18
|
+
file: string;
|
|
19
|
+
name: string;
|
|
20
|
+
directory: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Select the exact physical scope of a raw checker from a captured map.
|
|
25
|
+
* @param {string} contentBase - Content root.
|
|
26
|
+
* @param {Map<string, {raw: string}>} sources - Captured physical sources.
|
|
27
|
+
* @param {readonly string[]} skipDirectories - Directory names to ignore.
|
|
28
|
+
* @param {Set<string>} extensions - Lowercase extensions accepted by the caller.
|
|
29
|
+
*/
|
|
30
|
+
export function capturedSources(contentBase: string, sources: Map<string, {
|
|
31
|
+
raw: string;
|
|
32
|
+
}>, skipDirectories: readonly string[], extensions: Set<string>): Generator<string[], void, unknown>;
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
/** Add bracket spans after recognized Markdown links and footnotes.
|
|
2
2
|
* @param {import("markdown-it")} md - Markdown parser to extend.
|
|
3
|
+
* @param {object} [options] - Surface presentation.
|
|
4
|
+
* @param {boolean} [options.spoilers] - Add visible static Secret labels (Foundry).
|
|
3
5
|
*/
|
|
4
|
-
export function spanMarkdownPlugin(md: typeof import("markdown-it")
|
|
6
|
+
export function spanMarkdownPlugin(md: typeof import("markdown-it"), { spoilers }?: {
|
|
7
|
+
spoilers?: boolean | undefined;
|
|
8
|
+
}): void;
|
|
5
9
|
/** Read span anchors and located attribute diagnostics outside literal code.
|
|
6
10
|
* @param {string} source - Authored Markdown.
|
|
11
|
+
* @returns {import("./name-markup.mjs").SpanScan} Actual spans, explicit names and located diagnostics.
|
|
7
12
|
*/
|
|
8
|
-
export function scanSpans(source: string):
|
|
9
|
-
spans: any[];
|
|
10
|
-
errors: any[];
|
|
11
|
-
};
|
|
13
|
+
export function scanSpans(source: string): import("./name-markup.mjs").SpanScan;
|
|
12
14
|
/** Emit span tags while leaving their inline content as Markdown for Hugo.
|
|
13
15
|
* @param {string} source - Authored Markdown.
|
|
14
16
|
*/
|
|
15
17
|
export function renderSpans(source: string): {
|
|
16
18
|
markdown: string;
|
|
17
|
-
errors:
|
|
19
|
+
errors: import("./name-markup.mjs").SpanFinding[];
|
|
18
20
|
};
|
|
@@ -43,12 +43,16 @@ export function checkTaskLists(body: string, file: string, { bodyLine, bodyColum
|
|
|
43
43
|
* @param {object} [opts]
|
|
44
44
|
* @param {readonly string[]} [opts.skipDirectories] - Directory names to ignore
|
|
45
45
|
* in addition to the dot-directories always skipped.
|
|
46
|
+
* @param {Map<string, {raw: string}>} [opts.sources] - Exact captured source strings; omitted, walks and reads the tree.
|
|
46
47
|
* @returns {{findings: Array<{file: string, line: number, column: number,
|
|
47
48
|
* severity: "warning", message: string}>, files: number}} The findings, and
|
|
48
49
|
* how many files were read.
|
|
49
50
|
*/
|
|
50
|
-
export function lintContentTaskLists(contentBase: string, { skipDirectories }?: {
|
|
51
|
+
export function lintContentTaskLists(contentBase: string, { skipDirectories, sources }?: {
|
|
51
52
|
skipDirectories?: readonly string[] | undefined;
|
|
53
|
+
sources?: Map<string, {
|
|
54
|
+
raw: string;
|
|
55
|
+
}> | undefined;
|
|
52
56
|
}): {
|
|
53
57
|
findings: Array<{
|
|
54
58
|
file: string;
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split opening YAML frontmatter from its untrimmed body without parsing it.
|
|
3
|
+
* LF and CRLF delimiters retain the exact source strings and their offsets.
|
|
4
|
+
* @param {string} raw - Complete Markdown source.
|
|
5
|
+
* @returns {{yaml: string, body: string}|null} Source slices, or no fence.
|
|
6
|
+
*/
|
|
7
|
+
export function splitFrontmatter(raw: string): {
|
|
8
|
+
yaml: string;
|
|
9
|
+
body: string;
|
|
10
|
+
} | null;
|
|
1
11
|
/**
|
|
2
12
|
* The `file:line:column` locator, with whatever is known.
|
|
3
13
|
*
|
|
@@ -6,15 +6,29 @@
|
|
|
6
6
|
* @param {RegExp} [options.idPattern=NAME] - What an `#id` may be named. A
|
|
7
7
|
* construct whose id is published as an HTML `id` admits a digit first and
|
|
8
8
|
* passes a looser pattern; the default is the pattern every other name takes.
|
|
9
|
-
* @
|
|
9
|
+
* @param {boolean} [options.positions=false] - Retain the first supplied
|
|
10
|
+
* attribute's key/value ranges as UTF-16 offsets within this input.
|
|
11
|
+
* @returns {{id: string, classes: string[], values: Record<string, string>, problems: string[],
|
|
12
|
+
* positions?: Record<string, {key: {start: number, end: number}, value: {start: number, end: number}}>}}
|
|
10
13
|
*/
|
|
11
|
-
export function parseExtensionAttributes(source: string, { idPattern }?: {
|
|
14
|
+
export function parseExtensionAttributes(source: string, { idPattern, positions }?: {
|
|
12
15
|
idPattern?: RegExp | undefined;
|
|
16
|
+
positions?: boolean | undefined;
|
|
13
17
|
}): {
|
|
14
18
|
id: string;
|
|
15
19
|
classes: string[];
|
|
16
20
|
values: Record<string, string>;
|
|
17
21
|
problems: string[];
|
|
22
|
+
positions?: Record<string, {
|
|
23
|
+
key: {
|
|
24
|
+
start: number;
|
|
25
|
+
end: number;
|
|
26
|
+
};
|
|
27
|
+
value: {
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
};
|
|
31
|
+
}>;
|
|
18
32
|
};
|
|
19
33
|
/** A Boolean attribute is spelled exactly `true` or `false`. */
|
|
20
34
|
export function booleanAttribute(value: any, key: any): boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepare indexed names once, then check only explicit occurrences without reading files.
|
|
3
|
+
* @param {{records: readonly object[], index: object,
|
|
4
|
+
* catalog?: import("./names.mjs").NameCatalog,
|
|
5
|
+
* parsed?: Map<string, {raw: string, body: string, bodyLine?: number, bodyColumn?: number}>,
|
|
6
|
+
* syntax?: import("./content-session.mjs").ContentSyntax}} options - Lint's
|
|
7
|
+
* records/resolver and optional captured authored-body projections.
|
|
8
|
+
* @returns {(note: {file: string, raw: string}) => Array<{file: string, line: number, column: number, severity: "warning", rules: string[], message: string}>} Located warning diagnostics.
|
|
9
|
+
*/
|
|
10
|
+
export function createFirstUseChecker({ records, index, parsed, syntax, catalog, }: {
|
|
11
|
+
records: readonly object[];
|
|
12
|
+
index: object;
|
|
13
|
+
catalog?: import("./names.mjs").NameCatalog;
|
|
14
|
+
parsed?: Map<string, {
|
|
15
|
+
raw: string;
|
|
16
|
+
body: string;
|
|
17
|
+
bodyLine?: number;
|
|
18
|
+
bodyColumn?: number;
|
|
19
|
+
}>;
|
|
20
|
+
syntax?: import("./content-session.mjs").ContentSyntax;
|
|
21
|
+
}): (note: {
|
|
22
|
+
file: string;
|
|
23
|
+
raw: string;
|
|
24
|
+
}) => Array<{
|
|
25
|
+
file: string;
|
|
26
|
+
line: number;
|
|
27
|
+
column: number;
|
|
28
|
+
severity: "warning";
|
|
29
|
+
rules: string[];
|
|
30
|
+
message: string;
|
|
31
|
+
}>;
|