@fro.bot/wiki-write-core 0.2.0 → 0.3.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/README.md CHANGED
@@ -59,6 +59,8 @@ A page that opens a frontmatter block and never closes it is reported as `invali
59
59
 
60
60
  The package's own readers (`parseFrontmatterDocument`, `splitFrontmatter`, the ingest's page parser and the repo-page move) all use it. Each keeps its error texts and its body handling. An empty block is an empty mapping for the document reader and the ingest parser; a block that parses to `null` (whitespace, comments, `null`, `...`) is not a mapping and gets each reader's rule for a non-mapping. The wiki page reader reports an unclosed block as `Invalid frontmatter: missing closing --- delimiter`.
61
61
 
62
+ The wiki page reader also says why a page could not be read, apart from the text. `splitFrontmatter` returns `errorKind` next to `error`, and `parseWikiPage` and `collectWikiPages` return `frontmatterErrorKind` next to `frontmatterError` (type `WikiFrontmatterErrorKind` from `@fro.bot/wiki-write-core/wiki-utils`). The kind is `'unclosed'` for a block that opens and never closes (the text above) and `'invalid'` for a block the YAML parser rejects (`Invalid YAML frontmatter: <parser message>`). The kind is present exactly when the text is, and the text is unchanged. A block that parses to something other than a mapping is read as empty frontmatter with no error, so it has no kind. Switch on the kind; do not match the wording of the text.
63
+
62
64
  ## Target page sources
63
65
 
64
66
  When the ingest writes the page of the `repo:` target and that page lists no sources (no `sources` key, or an empty list), the page lists `{url, accessed}` with the target's `https://github.com/<owner>/<name>` URL and the date of the ingest's timestamp. When the page on the branch already has an entry for the target, its whole `sources` list is carried over as it is, so a repeat write changes nothing, a repeat after a migration included. The stamp applies only when the owner and name are plain GitHub names (ASCII letters, digits, `.`, `_` and `-`, not `.` or `..`); for any other target the page is written without one. A page that lists any source is never changed, and neither is a `sources` value that is not a list. When the ingest migrates a page to the target's slug by a trusted node ID, the merged page also gains the target's URL if no entry matches it, and keeps its other entries. No other repo page in the write is stamped, and a write whose target is a page path (the dashboard's case) is never stamped. Whether an entry matches the target uses the privacy gate's URL rule: `https`, host `github.com`, no port, owner and name equal without case, any path after them.
@@ -1,4 +1,4 @@
1
1
  // Bump deliberately when an intentional consumer-visible gate contract break ships.
2
2
  export const GATE_CONTRACT_VERSION = 1;
3
3
  // Replaced with the deterministic source-tree hash by the package build.
4
- export const GATE_SOURCE_TREE_HASH = '637b237dc25880625d73dde771514ff4ff64fd845cb6dd1a07c61184570de419';
4
+ export const GATE_SOURCE_TREE_HASH = 'bc3fa911b668e723571bcdb57e15a619e6998ac71675b03330719ad662d54d1b';
@@ -1 +1 @@
1
- {"version":1,"sourceTreeHash":"637b237dc25880625d73dde771514ff4ff64fd845cb6dd1a07c61184570de419"}
1
+ {"version":1,"sourceTreeHash":"bc3fa911b668e723571bcdb57e15a619e6998ac71675b03330719ad662d54d1b"}
@@ -1,6 +1,13 @@
1
1
  /** Canonical root directory for wiki page content. Shared by every wiki script. */
2
2
  export declare const WIKI_ROOT = "knowledge/wiki";
3
3
  export type WikiPageType = 'repo' | 'topic' | 'entity' | 'comparison';
4
+ /**
5
+ * Why a page's frontmatter could not be read, as a closed vocabulary a caller can switch on without matching the
6
+ * wording of the error text. `unclosed` is a block that opens with `---` and never closes; `invalid` is a block the
7
+ * YAML parser rejects. A block that parses to something other than a mapping is read as empty frontmatter and is
8
+ * not an error, so it has no kind.
9
+ */
10
+ export type WikiFrontmatterErrorKind = 'unclosed' | 'invalid';
4
11
  export interface WikiPage {
5
12
  readonly path: string;
6
13
  readonly slug: string;
@@ -11,11 +18,15 @@ export interface WikiPage {
11
18
  readonly body: string;
12
19
  readonly frontmatter: Record<string, unknown>;
13
20
  readonly frontmatterError?: string;
21
+ /** Set exactly when `frontmatterError` is. */
22
+ readonly frontmatterErrorKind?: WikiFrontmatterErrorKind;
14
23
  }
15
24
  export interface SplitFrontmatterResult {
16
25
  readonly frontmatter: Record<string, unknown>;
17
26
  readonly body: string;
18
27
  readonly error?: string;
28
+ /** Set exactly when `error` is. */
29
+ readonly errorKind?: WikiFrontmatterErrorKind;
19
30
  }
20
31
  /**
21
32
  * Split raw wiki page content into frontmatter and body.
@@ -17,7 +17,12 @@ export function splitFrontmatter(content) {
17
17
  return { frontmatter: {}, body: content.trim() };
18
18
  }
19
19
  if (split.kind === 'malformed') {
20
- return { frontmatter: {}, body: content.trim(), error: 'Invalid frontmatter: missing closing --- delimiter' };
20
+ return {
21
+ frontmatter: {},
22
+ body: content.trim(),
23
+ error: 'Invalid frontmatter: missing closing --- delimiter',
24
+ errorKind: 'unclosed',
25
+ };
21
26
  }
22
27
  let parsed;
23
28
  try {
@@ -29,6 +34,7 @@ export function splitFrontmatter(content) {
29
34
  frontmatter: {},
30
35
  body: split.body.trim(),
31
36
  error: `Invalid YAML frontmatter: ${message}`,
37
+ errorKind: 'invalid',
32
38
  };
33
39
  }
34
40
  return {
@@ -100,7 +106,7 @@ export function findWikilinkSpans(content) {
100
106
  }
101
107
  /** Parse a single wiki page's content (relative path + raw content) into a page record. */
102
108
  export function parseWikiPage(path, content) {
103
- const { frontmatter, body, error } = splitFrontmatter(content);
109
+ const { frontmatter, body, error, errorKind } = splitFrontmatter(content);
104
110
  const slug = basename(path, '.md');
105
111
  return {
106
112
  path,
@@ -114,6 +120,7 @@ export function parseWikiPage(path, content) {
114
120
  body,
115
121
  frontmatter,
116
122
  frontmatterError: error,
123
+ frontmatterErrorKind: errorKind,
117
124
  };
118
125
  }
119
126
  /** Collect all `knowledge/wiki/**.md` pages from a path→content file map. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/wiki-write-core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Shared validation and commit primitives for Fro Bot wiki writes",
5
5
  "homepage": "https://github.com/fro-bot/.github/tree/main/packages/wiki-write-core#readme",
6
6
  "bugs": {