@dogsbay/format-gitbook 0.2.0-beta.132 → 0.2.0-beta.134

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/dist/corpus.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** The corpus an importer reads: `@dogsbay/corpus`, shared by every format's browser import. */
2
- export { corpusFromMap, type Corpus, type CorpusFiles } from "@dogsbay/corpus";
2
+ export { corpusFromMap, type Corpus, type CorpusFiles, type Unfetched, unfetchedMessage, pendingCopies, withPages } from "@dogsbay/corpus";
package/dist/corpus.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** The corpus an importer reads: `@dogsbay/corpus`, shared by every format's browser import. */
2
- export { corpusFromMap } from "@dogsbay/corpus";
2
+ export { corpusFromMap, unfetchedMessage, pendingCopies, withPages } from "@dogsbay/corpus";
package/dist/import.d.ts CHANGED
@@ -23,5 +23,7 @@ export interface GitbookImportResult {
23
23
  /** Docs roots to mirror non-`.md` assets from (corpus-relative folder + slug prefix). */
24
24
  assetRoots: GitbookAssetRoot[];
25
25
  ledger: ImportLedgerEntry[];
26
+ /** The corpus file each page was converted from: `sources[i]` is `pages[i]`'s. */
27
+ sources: string[];
26
28
  }
27
29
  export declare function importGitbookCorpus(corpus: Corpus, opts?: GitbookImportOptions): GitbookImportResult;
package/dist/import.js CHANGED
@@ -6,6 +6,7 @@ export function importGitbookCorpus(corpus, opts = {}) {
6
6
  const { pages: sources, nav, redirects, spaces, assetRoots } = loadGitbookCorpus(corpus, opts);
7
7
  const pages = [];
8
8
  const ledger = [];
9
+ const pageFiles = [];
9
10
  // A page written under another file name (README.md → index.md, a landing page → index.md):
10
11
  // links to it follow the rename.
11
12
  const renames = new Map();
@@ -37,6 +38,7 @@ export function importGitbookCorpus(corpus, opts = {}) {
37
38
  // to the H1 / slug (review #6).
38
39
  const fmTitle = typeof frontmatter.title === "string" && frontmatter.title.trim() ? frontmatter.title : undefined;
39
40
  const title = fmTitle || h1?.text || prettify(ps.slug.slice(ps.slug.lastIndexOf("/") + 1));
41
+ pageFiles.push(ps.path);
40
42
  pages.push({
41
43
  slug: ps.slug,
42
44
  title,
@@ -58,5 +60,5 @@ export function importGitbookCorpus(corpus, opts = {}) {
58
60
  });
59
61
  }
60
62
  }
61
- return { pages, nav, redirects, spaces, assetRoots, ledger };
63
+ return { pages, nav, redirects, spaces, assetRoots, ledger, sources: pageFiles };
62
64
  }
package/dist/migrate.d.ts CHANGED
@@ -5,11 +5,17 @@
5
5
  * no console, clock or network. Find the corpus with `@dogsbay/detect` first.
6
6
  */
7
7
  import type { ImportLedgerEntry } from "@dogsbay/types";
8
- import { type CorpusFiles } from "./corpus.js";
9
- export type { CorpusFiles } from "./corpus.js";
8
+ import { type CorpusFiles, type Unfetched } from "./corpus.js";
9
+ export type { CorpusFiles, Unfetched } from "./corpus.js";
10
10
  export interface MigrateInput {
11
11
  /** The corpus: paths relative to its root (a detection's `root`), text or bytes. */
12
12
  files: CorpusFiles;
13
+ /**
14
+ * Every path of the project (relative to the same root as `files`), when the host lists more
15
+ * than it fetched (a GitHub tree). The import then sees the repo as it is, and `unfetched`
16
+ * says what it needed from those not given: fetch them and call `migrate` again.
17
+ */
18
+ paths?: Iterable<string>;
13
19
  /** One space of a multi-space repo (a detection's `choices.spaces`); all when omitted. */
14
20
  choose?: {
15
21
  space?: string;
@@ -28,5 +34,14 @@ export interface MigrateResult {
28
34
  from: string;
29
35
  to: string;
30
36
  }[];
37
+ /**
38
+ * The listed `paths` the conversion needed but `files` did not hold. `read`: it read them,
39
+ * so fetch them and convert again (each round can find one more level of an include or
40
+ * `require` chain: cap the rounds). While `read` is not empty the result is not a
41
+ * conversion; when the import could not go on, `files` is empty and the ledger says where
42
+ * it stopped. `copy`: assets the output copies; fetch them for the finished files, no
43
+ * rerun. Both empty: the result is complete.
44
+ */
45
+ unfetched: Unfetched;
31
46
  }
32
47
  export declare function migrate(input: MigrateInput): Promise<MigrateResult>;
package/dist/migrate.js CHANGED
@@ -1,19 +1,38 @@
1
- import { corpusFromMap } from "./corpus.js";
1
+ import { corpusFromMap, pendingCopies, unfetchedMessage } from "./corpus.js";
2
2
  import { importGitbookCorpus } from "./import.js";
3
3
  import { gitbookProject } from "./project.js";
4
+ /** The ledger line for a conversion that still needs files, or nothing. */
5
+ function unfetchedLedger(read, stoppedOn) {
6
+ const message = unfetchedMessage(read, stoppedOn);
7
+ return message ? [{ severity: "warning", code: "unfetched", message }] : [];
8
+ }
4
9
  export async function migrate(input) {
5
- const corpus = corpusFromMap(input.files);
6
- const imported = importGitbookCorpus(corpus, { space: input.choose?.space });
7
- const project = gitbookProject(imported, corpus, {
8
- siteName: input.siteName?.trim() || "Docs",
9
- siteUrl: input.siteUrl,
10
- sourceLabel: input.sourceLabel ?? "GitBook corpus",
11
- });
10
+ const corpus = corpusFromMap(input.files, { paths: input.paths });
11
+ let project;
12
+ try {
13
+ const imported = importGitbookCorpus(corpus, { space: input.choose?.space });
14
+ project = gitbookProject(imported, corpus, {
15
+ siteName: input.siteName?.trim() || "Docs",
16
+ siteUrl: input.siteUrl,
17
+ sourceLabel: input.sourceLabel ?? "GitBook corpus",
18
+ });
19
+ }
20
+ catch (e) {
21
+ // A file it needed was not given: that, not the error, is the answer
22
+ const read = corpus.missing();
23
+ if (read.length)
24
+ return { files: new Map(), ledger: unfetchedLedger(read, e), redirects: [], unfetched: { read, copy: [], copyTo: [] } };
25
+ throw e;
26
+ }
12
27
  const files = new Map(project.files);
28
+ const copy = [];
13
29
  for (const { from, to } of project.assets) {
14
30
  const bytes = input.files.get(from);
15
31
  if (bytes !== undefined)
16
32
  files.set(to, bytes);
33
+ else
34
+ copy.push({ from, to });
17
35
  }
18
- return { files, ledger: project.ledger, redirects: project.redirects };
36
+ const read = corpus.missing();
37
+ return { files, ledger: [...unfetchedLedger(read), ...project.ledger], redirects: project.redirects, unfetched: { read, ...pendingCopies(copy) } };
19
38
  }
package/dist/project.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ImportLedgerEntry } from "@dogsbay/types";
2
- import type { Corpus } from "./corpus.js";
2
+ import { type Corpus } from "./corpus.js";
3
3
  import type { GitbookImportResult } from "./import.js";
4
4
  export interface GitbookProjectOptions {
5
5
  siteName: string;
package/dist/project.js CHANGED
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import * as yaml from "js-yaml";
9
9
  import { gitbookVisible, within } from "@dogsbay/detect";
10
+ import { withPages } from "./corpus.js";
10
11
  function yamlQuote(s) {
11
12
  return /[:#&*!|>%@`,'"[\]{}]|^\s|\s$/.test(s) ? JSON.stringify(s) : s;
12
13
  }
@@ -95,7 +96,9 @@ export function gitbookProject(result, corpus, opts) {
95
96
  const taken = new Set();
96
97
  let fragments = 0;
97
98
  let collisions = 0;
98
- for (const page of result.pages) {
99
+ // Each written page's source file → the page, for the notes about that file
100
+ const pageOf = new Map();
101
+ for (const [i, page] of result.pages.entries()) {
99
102
  const dst = `content/${page.slug}.md`;
100
103
  if (taken.has(dst.toLowerCase())) {
101
104
  collisions += 1;
@@ -103,6 +106,8 @@ export function gitbookProject(result, corpus, opts) {
103
106
  continue;
104
107
  }
105
108
  taken.add(dst.toLowerCase());
109
+ if (result.sources?.[i] !== undefined)
110
+ pageOf.set(result.sources[i], dst);
106
111
  const body = page.bodyMarkdown ?? "";
107
112
  const text = body.endsWith("\n") ? body : body + "\n";
108
113
  if (page.fragment) {
@@ -170,6 +175,8 @@ export function gitbookProject(result, corpus, opts) {
170
175
  redirects.push(r);
171
176
  }
172
177
  const pages = result.pages.filter((p) => !p.fragment).length;
173
- files.set("MIGRATION.md", migrationNotes({ ...opts, pages, fragments, spaces: result.spaces, redirects: redirects.length, ledger }));
174
- return { files, assets: copies, redirects, ledger, stats: { pages, fragments, collisions, spaces: result.spaces } };
178
+ // Each note about a written page's file names that page
179
+ const placed = withPages(ledger, pageOf);
180
+ files.set("MIGRATION.md", migrationNotes({ ...opts, pages, fragments, spaces: result.spaces, redirects: redirects.length, ledger: placed }));
181
+ return { files, assets: copies, redirects, ledger: placed, stats: { pages, fragments, collisions, spaces: result.spaces } };
175
182
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dogsbay/format-gitbook",
3
- "version": "0.2.0-beta.132",
3
+ "version": "0.2.0-beta.134",
4
4
  "description": "GitBook format plugin for Dogsbay — imports GitBook Git Sync (and legacy gitbook-cli) corpora by translating the Git Sync markdown dialect to Dogsbay-MD. ./migrate converts a corpus given as a map of files in the browser (no Node), the same import the CLI runs.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,10 +25,10 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "js-yaml": "^5.2.1",
28
- "@dogsbay/corpus": "0.2.0-beta.132",
29
- "@dogsbay/format-dogsbay-md": "0.2.0-beta.132",
30
- "@dogsbay/types": "0.2.0-beta.132",
31
- "@dogsbay/detect": "0.2.0-beta.132"
28
+ "@dogsbay/corpus": "0.2.0-beta.134",
29
+ "@dogsbay/format-dogsbay-md": "0.2.0-beta.134",
30
+ "@dogsbay/detect": "0.2.0-beta.134",
31
+ "@dogsbay/types": "0.2.0-beta.134"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/js-yaml": "^4.0.9",