@gitpagedocs/cli 1.1.53 → 1.1.55

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
@@ -38,36 +38,36 @@ The AI-CLI implementation lives in `cli/ai/` (relocated from the frontend so the
38
38
 
39
39
  ```
40
40
  cli/
41
- ├── index.mjs # Node entry (bootstraps TS presentation via tsx)
42
- ├── package.json # the published `gitpagedocs` package
43
- ├── ai/ # AI documentation CLI (provider/model/paths → markdown)
44
- ├── contracts/ # Stable contracts for external tooling
45
- │ └── doc-versions.mjs
46
- │
47
- ├── presentation/ # Interface/composition root
48
- │ ├── index.ts
49
- │ ├── options/
50
- │ └── ui/
51
- │
52
- ├── application/ # Use-cases and ports
53
- │ ├── config-only/handler.mjs
54
- │ ├── home/handler.mjs
55
- │ ├── report/config-only-reporter.mjs
56
- │ ├── use-cases/dispatch-mode.ts
57
- │ └── ports/cli-runtime-ports.ts
58
- │
59
- ├── domain/ # Business rules
60
- │ └── services/sanitize-segment.mjs
61
- │
62
- ├── infrastructure/ # Side effects and adapters
63
- │ ├── config-only/runtime.mjs
64
- │ └── home/runtime.mjs
65
- │
66
- ├── builders/ # Pure config builders
67
- ├── data/ # Constants and metadata
68
- ├── content/ # Static docs content
69
- ├── runtime/ # Low-level runtime helpers
70
- └── home/ # Home templates/files
41
+ |-- index.mjs # Node entry (bootstraps TS presentation via tsx)
42
+ |-- package.json # the published `gitpagedocs` package
43
+ |-- ai/ # AI documentation CLI (provider/model/paths → markdown)
44
+ |-- contracts/ # Stable contracts for external tooling
45
+ | `-- doc-versions.mjs
46
+ |
47
+ |-- presentation/ # Interface/composition root
48
+ | |-- index.ts
49
+ | |-- options/
50
+ | `-- ui/
51
+ |
52
+ |-- application/ # Use-cases and ports
53
+ | |-- config-only/handler.mjs
54
+ | |-- home/handler.mjs
55
+ | |-- report/config-only-reporter.mjs
56
+ | |-- use-cases/dispatch-mode.ts
57
+ | `-- ports/cli-runtime-ports.ts
58
+ |
59
+ |-- domain/ # Business rules
60
+ | `-- services/sanitize-segment.mjs
61
+ |
62
+ |-- infrastructure/ # Side effects and adapters
63
+ | |-- config-only/runtime.mjs
64
+ | `-- home/runtime.mjs
65
+ |
66
+ |-- builders/ # Pure config builders
67
+ |-- data/ # Constants and metadata
68
+ |-- content/ # Static docs content
69
+ |-- runtime/ # Low-level runtime helpers
70
+ `-- home/ # Home templates/files
71
71
  ```
72
72
 
73
73
  ## SOLID Principles
@@ -1,68 +1,68 @@
1
- /**
2
- * Parse an AI documentation response into gitpagedocs pages.
3
- *
4
- * The model is instructed (see GITPAGEDOCS_DOC_SYSTEM_PROMPT) to delimit each
5
- * page with a line `=== PAGE: <slug> | <Title> ===`. This splits that response
6
- * into individual pages. If the model ignored the format, the whole response is
7
- * returned as a single "ai-overview" page so content is never lost.
8
- */
9
-
10
- export interface AiDocPage {
11
- /** lowercase-kebab, English, identical across languages (used as the filename) */
12
- slug: string;
13
- title: string;
14
- body: string;
15
- }
16
-
17
- const PAGE_DELIMITER = /^===\s*PAGE:\s*(.+?)\s*\|\s*(.*?)\s*===\s*$/;
18
-
19
- /** Turn an arbitrary heading into a safe lowercase-kebab slug. */
20
- export function slugify(raw: string): string {
21
- const slug = (raw ?? "")
22
- .toLowerCase()
23
- .normalize("NFKD")
24
- .replace(/[^a-z0-9]+/g, "-")
25
- .replace(/^-+|-+$/g, "")
26
- .slice(0, 60);
27
- return slug || "page";
28
- }
29
-
30
- export function parseAiPages(markdown: string): AiDocPage[] {
31
- const text = (markdown ?? "").replace(/\r\n/g, "\n").trim();
32
- if (!text) return [];
33
-
34
- const pages: AiDocPage[] = [];
35
- let current: { slug: string; title: string; body: string[] } | null = null;
36
-
37
- const flush = () => {
38
- if (current) {
39
- pages.push({ slug: current.slug, title: current.title, body: current.body.join("\n").trim() });
40
- }
41
- };
42
-
43
- for (const line of text.split("\n")) {
44
- const match = line.match(PAGE_DELIMITER);
45
- if (match) {
46
- flush();
47
- const rawSlug = match[1].trim();
48
- const title = match[2].trim() || rawSlug;
49
- current = { slug: slugify(rawSlug), title, body: [] };
50
- } else if (current) {
51
- current.body.push(line);
52
- }
53
- }
54
- flush();
55
-
56
- const withBody = pages.filter((page) => page.body.length > 0);
57
- if (withBody.length === 0) {
58
- return [{ slug: "ai-overview", title: "Overview", body: text }];
59
- }
60
-
61
- // De-duplicate slugs within a single response (suffix later collisions).
62
- const seen = new Map<string, number>();
63
- return withBody.map((page) => {
64
- const count = seen.get(page.slug) ?? 0;
65
- seen.set(page.slug, count + 1);
66
- return count === 0 ? page : { ...page, slug: `${page.slug}-${count + 1}` };
67
- });
68
- }
1
+ /**
2
+ * Parse an AI documentation response into gitpagedocs pages.
3
+ *
4
+ * The model is instructed (see GITPAGEDOCS_DOC_SYSTEM_PROMPT) to delimit each
5
+ * page with a line `=== PAGE: <slug> | <Title> ===`. This splits that response
6
+ * into individual pages. If the model ignored the format, the whole response is
7
+ * returned as a single "ai-overview" page so content is never lost.
8
+ */
9
+
10
+ export interface AiDocPage {
11
+ /** lowercase-kebab, English, identical across languages (used as the filename) */
12
+ slug: string;
13
+ title: string;
14
+ body: string;
15
+ }
16
+
17
+ const PAGE_DELIMITER = /^===\s*PAGE:\s*(.+?)\s*\|\s*(.*?)\s*===\s*$/;
18
+
19
+ /** Turn an arbitrary heading into a safe lowercase-kebab slug. */
20
+ export function slugify(raw: string): string {
21
+ const slug = (raw ?? "")
22
+ .toLowerCase()
23
+ .normalize("NFKD")
24
+ .replace(/[^a-z0-9]+/g, "-")
25
+ .replace(/^-+|-+$/g, "")
26
+ .slice(0, 60);
27
+ return slug || "page";
28
+ }
29
+
30
+ export function parseAiPages(markdown: string): AiDocPage[] {
31
+ const text = (markdown ?? "").replace(/\r\n/g, "\n").trim();
32
+ if (!text) return [];
33
+
34
+ const pages: AiDocPage[] = [];
35
+ let current: { slug: string; title: string; body: string[] } | null = null;
36
+
37
+ const flush = () => {
38
+ if (current) {
39
+ pages.push({ slug: current.slug, title: current.title, body: current.body.join("\n").trim() });
40
+ }
41
+ };
42
+
43
+ for (const line of text.split("\n")) {
44
+ const match = line.match(PAGE_DELIMITER);
45
+ if (match) {
46
+ flush();
47
+ const rawSlug = match[1].trim();
48
+ const title = match[2].trim() || rawSlug;
49
+ current = { slug: slugify(rawSlug), title, body: [] };
50
+ } else if (current) {
51
+ current.body.push(line);
52
+ }
53
+ }
54
+ flush();
55
+
56
+ const withBody = pages.filter((page) => page.body.length > 0);
57
+ if (withBody.length === 0) {
58
+ return [{ slug: "ai-overview", title: "Overview", body: text }];
59
+ }
60
+
61
+ // De-duplicate slugs within a single response (suffix later collisions).
62
+ const seen = new Map<string, number>();
63
+ return withBody.map((page) => {
64
+ const count = seen.get(page.slug) ?? 0;
65
+ seen.set(page.slug, count + 1);
66
+ return count === 0 ? page : { ...page, slug: `${page.slug}-${count + 1}` };
67
+ });
68
+ }
@@ -1,143 +1,143 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- // @ts-expect-error .mjs runtime module is type-less in this package.
4
- import { buildMdRoute } from "../../builders/route-builders.mjs";
5
- import type { AiDocPage } from "../application/docs-pattern";
6
-
7
- const CANONICAL_LANGS = ["pt", "en", "es"] as const;
8
- type Lang = (typeof CANONICAL_LANGS)[number];
9
-
10
- /** AI routes/menus use a high, dedicated id range so they never clash with the
11
- * deterministic base routes (ids 1..N) and can be identified for idempotency. */
12
- const AI_ROUTE_ID_BASE = 1000;
13
-
14
- export interface VersionDocsWriteInput {
15
- cwd: string;
16
- versionId: string;
17
- /** Pages generated per language (only the languages the user selected). */
18
- pagesByLang: Partial<Record<Lang, AiDocPage[]>>;
19
- }
20
-
21
- export interface VersionDocsWriteResult {
22
- configPath: string;
23
- slugs: string[];
24
- files: string[];
25
- }
26
-
27
- interface LangContent {
28
- title: string;
29
- body: string;
30
- }
31
-
32
- function indexBySlug(pages: AiDocPage[] | undefined): Map<string, AiDocPage> {
33
- const map = new Map<string, AiDocPage>();
34
- for (const page of pages ?? []) {
35
- if (!map.has(page.slug)) map.set(page.slug, page);
36
- }
37
- return map;
38
- }
39
-
40
- /**
41
- * Write AI-generated pages into the gitpagedocs versioned structure and wire
42
- * them into the version config.json (routes-md + menus-header-md). Pages are
43
- * written for ALL three canonical languages (missing languages reuse an
44
- * available translation) so every route path stays valid. Idempotent: any prior
45
- * `aiGenerated` routes/menus are replaced, never duplicated. The base config and
46
- * its deterministic routes are preserved untouched.
47
- */
48
- export async function writeVersionDocs(input: VersionDocsWriteInput): Promise<VersionDocsWriteResult> {
49
- const { cwd, versionId, pagesByLang } = input;
50
- const base = `gitpagedocs/docs/versions/${versionId}`;
51
-
52
- const perLang: Record<Lang, Map<string, AiDocPage>> = {
53
- pt: indexBySlug(pagesByLang.pt),
54
- en: indexBySlug(pagesByLang.en),
55
- es: indexBySlug(pagesByLang.es),
56
- };
57
-
58
- // Ordered unique slug list (prefer en order, then pt, then es).
59
- const order: string[] = [];
60
- const seen = new Set<string>();
61
- for (const lang of ["en", "pt", "es"] as Lang[]) {
62
- for (const page of pagesByLang[lang] ?? []) {
63
- if (!seen.has(page.slug)) {
64
- seen.add(page.slug);
65
- order.push(page.slug);
66
- }
67
- }
68
- }
69
- if (order.length === 0) {
70
- throw new Error("No AI pages to write.");
71
- }
72
-
73
- const resolve = (slug: string): Record<Lang, LangContent> => {
74
- const fallback = CANONICAL_LANGS.map((lang) => perLang[lang].get(slug)).find(Boolean);
75
- const out = {} as Record<Lang, LangContent>;
76
- for (const lang of CANONICAL_LANGS) {
77
- const page = perLang[lang].get(slug) ?? fallback!;
78
- out[lang] = { title: page.title, body: page.body };
79
- }
80
- return out;
81
- };
82
-
83
- // 1) Write the markdown files (all 3 canonical languages).
84
- const writtenFiles: string[] = [];
85
- for (const slug of order) {
86
- const content = resolve(slug);
87
- for (const lang of CANONICAL_LANGS) {
88
- const rel = `${base}/${lang}/${slug}.md`;
89
- const abs = path.resolve(cwd, rel);
90
- await fs.mkdir(path.dirname(abs), { recursive: true });
91
- await fs.writeFile(abs, `${content[lang].body}\n`, "utf-8");
92
- writtenFiles.push(rel);
93
- }
94
- }
95
-
96
- // 2) Patch the version config.json (raw JSON round-trip, preserve all keys).
97
- const configRel = `${base}/config.json`;
98
- const configAbs = path.resolve(cwd, configRel);
99
- let raw: string;
100
- try {
101
- raw = await fs.readFile(configAbs, "utf-8");
102
- } catch {
103
- throw new Error(
104
- `Version config not found at ${configRel}. Run the base scaffold (\`gitpagedocs\`) first.`,
105
- );
106
- }
107
- const config = JSON.parse(raw) as Record<string, unknown>;
108
-
109
- const routesMd = Array.isArray(config["routes-md"]) ? (config["routes-md"] as Array<Record<string, unknown>>) : [];
110
- const menusMd = Array.isArray(config["menus-header-md"]) ? (config["menus-header-md"] as Array<Record<string, unknown>>) : [];
111
- const keptRoutes = routesMd.filter((route) => route?.aiGenerated !== true);
112
- const keptMenus = menusMd.filter((menu) => menu?.aiGenerated !== true);
113
-
114
- const newRoutes: Array<Record<string, unknown>> = [];
115
- const newMenus: Array<Record<string, unknown>> = [];
116
- order.forEach((slug, index) => {
117
- const content = resolve(slug);
118
- const id = AI_ROUTE_ID_BASE + index + 1;
119
- const pathByLang = {
120
- pt: `${base}/pt/${slug}.md`,
121
- en: `${base}/en/${slug}.md`,
122
- es: `${base}/es/${slug}.md`,
123
- };
124
- const titles = { pt: content.pt.title, en: content.en.title, es: content.es.title };
125
- const descriptions = { pt: "", en: "", es: "" };
126
- const route = buildMdRoute(versionId, id, pathByLang, titles, descriptions, {}) as Record<string, unknown>;
127
- route.aiGenerated = true;
128
- newRoutes.push(route);
129
- newMenus.push({
130
- id,
131
- aiGenerated: true,
132
- pt: { title: content.pt.title, "path-click": pathByLang.pt },
133
- en: { title: content.en.title, "path-click": pathByLang.en },
134
- es: { title: content.es.title, "path-click": pathByLang.es },
135
- });
136
- });
137
-
138
- config["routes-md"] = [...keptRoutes, ...newRoutes];
139
- config["menus-header-md"] = [...keptMenus, ...newMenus];
140
- await fs.writeFile(configAbs, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
141
-
142
- return { configPath: configRel, slugs: order, files: writtenFiles };
143
- }
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ // @ts-expect-error .mjs runtime module is type-less in this package.
4
+ import { buildMdRoute } from "../../builders/route-builders.mjs";
5
+ import type { AiDocPage } from "../application/docs-pattern";
6
+
7
+ const CANONICAL_LANGS = ["pt", "en", "es"] as const;
8
+ type Lang = (typeof CANONICAL_LANGS)[number];
9
+
10
+ /** AI routes/menus use a high, dedicated id range so they never clash with the
11
+ * deterministic base routes (ids 1..N) and can be identified for idempotency. */
12
+ const AI_ROUTE_ID_BASE = 1000;
13
+
14
+ export interface VersionDocsWriteInput {
15
+ cwd: string;
16
+ versionId: string;
17
+ /** Pages generated per language (only the languages the user selected). */
18
+ pagesByLang: Partial<Record<Lang, AiDocPage[]>>;
19
+ }
20
+
21
+ export interface VersionDocsWriteResult {
22
+ configPath: string;
23
+ slugs: string[];
24
+ files: string[];
25
+ }
26
+
27
+ interface LangContent {
28
+ title: string;
29
+ body: string;
30
+ }
31
+
32
+ function indexBySlug(pages: AiDocPage[] | undefined): Map<string, AiDocPage> {
33
+ const map = new Map<string, AiDocPage>();
34
+ for (const page of pages ?? []) {
35
+ if (!map.has(page.slug)) map.set(page.slug, page);
36
+ }
37
+ return map;
38
+ }
39
+
40
+ /**
41
+ * Write AI-generated pages into the gitpagedocs versioned structure and wire
42
+ * them into the version config.json (routes-md + menus-header-md). Pages are
43
+ * written for ALL three canonical languages (missing languages reuse an
44
+ * available translation) so every route path stays valid. Idempotent: any prior
45
+ * `aiGenerated` routes/menus are replaced, never duplicated. The base config and
46
+ * its deterministic routes are preserved untouched.
47
+ */
48
+ export async function writeVersionDocs(input: VersionDocsWriteInput): Promise<VersionDocsWriteResult> {
49
+ const { cwd, versionId, pagesByLang } = input;
50
+ const base = `gitpagedocs/docs/versions/${versionId}`;
51
+
52
+ const perLang: Record<Lang, Map<string, AiDocPage>> = {
53
+ pt: indexBySlug(pagesByLang.pt),
54
+ en: indexBySlug(pagesByLang.en),
55
+ es: indexBySlug(pagesByLang.es),
56
+ };
57
+
58
+ // Ordered unique slug list (prefer en order, then pt, then es).
59
+ const order: string[] = [];
60
+ const seen = new Set<string>();
61
+ for (const lang of ["en", "pt", "es"] as Lang[]) {
62
+ for (const page of pagesByLang[lang] ?? []) {
63
+ if (!seen.has(page.slug)) {
64
+ seen.add(page.slug);
65
+ order.push(page.slug);
66
+ }
67
+ }
68
+ }
69
+ if (order.length === 0) {
70
+ throw new Error("No AI pages to write.");
71
+ }
72
+
73
+ const resolve = (slug: string): Record<Lang, LangContent> => {
74
+ const fallback = CANONICAL_LANGS.map((lang) => perLang[lang].get(slug)).find(Boolean);
75
+ const out = {} as Record<Lang, LangContent>;
76
+ for (const lang of CANONICAL_LANGS) {
77
+ const page = perLang[lang].get(slug) ?? fallback!;
78
+ out[lang] = { title: page.title, body: page.body };
79
+ }
80
+ return out;
81
+ };
82
+
83
+ // 1) Write the markdown files (all 3 canonical languages).
84
+ const writtenFiles: string[] = [];
85
+ for (const slug of order) {
86
+ const content = resolve(slug);
87
+ for (const lang of CANONICAL_LANGS) {
88
+ const rel = `${base}/${lang}/${slug}.md`;
89
+ const abs = path.resolve(cwd, rel);
90
+ await fs.mkdir(path.dirname(abs), { recursive: true });
91
+ await fs.writeFile(abs, `${content[lang].body}\n`, "utf-8");
92
+ writtenFiles.push(rel);
93
+ }
94
+ }
95
+
96
+ // 2) Patch the version config.json (raw JSON round-trip, preserve all keys).
97
+ const configRel = `${base}/config.json`;
98
+ const configAbs = path.resolve(cwd, configRel);
99
+ let raw: string;
100
+ try {
101
+ raw = await fs.readFile(configAbs, "utf-8");
102
+ } catch {
103
+ throw new Error(
104
+ `Version config not found at ${configRel}. Run the base scaffold (\`gitpagedocs\`) first.`,
105
+ );
106
+ }
107
+ const config = JSON.parse(raw) as Record<string, unknown>;
108
+
109
+ const routesMd = Array.isArray(config["routes-md"]) ? (config["routes-md"] as Array<Record<string, unknown>>) : [];
110
+ const menusMd = Array.isArray(config["menus-header-md"]) ? (config["menus-header-md"] as Array<Record<string, unknown>>) : [];
111
+ const keptRoutes = routesMd.filter((route) => route?.aiGenerated !== true);
112
+ const keptMenus = menusMd.filter((menu) => menu?.aiGenerated !== true);
113
+
114
+ const newRoutes: Array<Record<string, unknown>> = [];
115
+ const newMenus: Array<Record<string, unknown>> = [];
116
+ order.forEach((slug, index) => {
117
+ const content = resolve(slug);
118
+ const id = AI_ROUTE_ID_BASE + index + 1;
119
+ const pathByLang = {
120
+ pt: `${base}/pt/${slug}.md`,
121
+ en: `${base}/en/${slug}.md`,
122
+ es: `${base}/es/${slug}.md`,
123
+ };
124
+ const titles = { pt: content.pt.title, en: content.en.title, es: content.es.title };
125
+ const descriptions = { pt: "", en: "", es: "" };
126
+ const route = buildMdRoute(versionId, id, pathByLang, titles, descriptions, {}) as Record<string, unknown>;
127
+ route.aiGenerated = true;
128
+ newRoutes.push(route);
129
+ newMenus.push({
130
+ id,
131
+ aiGenerated: true,
132
+ pt: { title: content.pt.title, "path-click": pathByLang.pt },
133
+ en: { title: content.en.title, "path-click": pathByLang.en },
134
+ es: { title: content.es.title, "path-click": pathByLang.es },
135
+ });
136
+ });
137
+
138
+ config["routes-md"] = [...keptRoutes, ...newRoutes];
139
+ config["menus-header-md"] = [...keptMenus, ...newMenus];
140
+ await fs.writeFile(configAbs, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
141
+
142
+ return { configPath: configRel, slugs: order, files: writtenFiles };
143
+ }
@@ -5,7 +5,6 @@ import { DOCS } from "../content/docs.mjs";
5
5
  import { DOC_VERSIONS } from "../data/version-constants.mjs";
6
6
  import { buildRootConfig } from "./root-config-builder.mjs";
7
7
  import { buildVersionConfig } from "./version-config-builder.mjs";
8
- import { generateSourceViewerHtml } from "./source-viewer.mjs";
9
8
 
10
9
  /**
11
10
  * Build all config artifacts (root, layouts, versions, docs).
@@ -19,11 +18,6 @@ export function buildConfigArtifacts(options = {}) {
19
18
  const layoutsConfig = { layouts: LAYOUTS };
20
19
  const fallbackLayoutsConfig = { layouts: FALLBACK_LAYOUTS };
21
20
 
22
- const sourceViewerHtml = generateSourceViewerHtml(root);
23
- const docsHtml = {
24
- sourceViewer: { pt: sourceViewerHtml, en: sourceViewerHtml, es: sourceViewerHtml },
25
- };
26
-
27
21
  const versionConfigs = {};
28
22
  for (const versionId of DOC_VERSIONS) {
29
23
  versionConfigs[versionId] = buildVersionConfig(versionId);
@@ -34,7 +28,7 @@ export function buildConfigArtifacts(options = {}) {
34
28
  layoutsConfig,
35
29
  fallbackLayoutsConfig,
36
30
  docs: DOCS,
37
- docsHtml,
31
+ docsHtml: {},
38
32
  versionConfigs,
39
33
  };
40
34
  }
@@ -11,15 +11,16 @@ export function buildRootConfig(options = {}) {
11
11
  const useOfficialLayouts = !useLocalLayoutConfig;
12
12
  const githubOwner = options.githubOwner;
13
13
  const githubRepo = options.githubRepo;
14
- const repositorySearchHome = false;
14
+ const repositorySearchHome = true;
15
15
  const renderingUrl =
16
16
  githubOwner && githubRepo
17
17
  ? `https://${githubOwner}.github.io/${githubRepo}/`
18
18
  : "https://vidigal-code.github.io/git-page-docs/";
19
- const projectLink =
20
- githubOwner && githubRepo
21
- ? `https://github.com/${githubOwner}/${githubRepo}`
22
- : "https://github.com/Vidigal-code/git-page-docs";
19
+ const projectLink =
20
+ githubOwner && githubRepo
21
+ ? `https://github.com/${githubOwner}/${githubRepo}`
22
+ : "https://github.com/Vidigal-code/git-page-docs";
23
+ const sourceViewerPath = `${projectLink}/tree/main`;
23
24
 
24
25
  const versionEntries = DOC_VERSIONS.map((id) => ({
25
26
  id,
@@ -28,10 +29,12 @@ export function buildRootConfig(options = {}) {
28
29
  PathConfig: `gitpagedocs/docs/versions/${id}/config.json`,
29
30
  PreviewProject: "",
30
31
  UpdateDate: "",
31
- branch: "",
32
- release: "",
33
- commit: "",
34
- }));
32
+ branch: "",
33
+ release: "",
34
+ commit: "",
35
+ "source-viewer": true,
36
+ "source-viewer-path": sourceViewerPath,
37
+ }));
35
38
 
36
39
  const baseSiteConfig = getDefaultSiteConfig(DOCS, projectLink);
37
40
 
@@ -109,3 +109,28 @@ export function buildVideoRoute(versionId, routeId, videoType, pathVideo, titles
109
109
  if (authorization !== undefined) obj.authorization = authorization;
110
110
  return obj;
111
111
  }
112
+
113
+ export function buildAudioRoute(versionId, routeId, audioType, pathAudio, titles, descriptions, options = {}) {
114
+ const base = buildVideoRoute(versionId, routeId, audioType, pathAudio, titles, descriptions, options);
115
+ const audioTypeByLang = typeof audioType === "string" ? { pt: audioType, en: audioType, es: audioType } : audioType;
116
+ const pathAudioByLang = typeof pathAudio === "string" ? { pt: pathAudio, en: pathAudio, es: pathAudio } : pathAudio;
117
+ const { video, ...rest } = base;
118
+ return {
119
+ ...rest,
120
+ audio: { audioType: audioTypeByLang, pathAudio: pathAudioByLang },
121
+ };
122
+ }
123
+
124
+ export function buildSourceViewerRoute(routeId, sourceViewerPath, titles, descriptions, options = {}) {
125
+ const base = buildMdRoute("", routeId, {}, titles, descriptions, {
126
+ ...options,
127
+ fullscreenEnabled: false,
128
+ RouteguideBrand: false,
129
+ });
130
+ delete base.path;
131
+ return {
132
+ ...base,
133
+ "source-viewer": true,
134
+ "source-viewer-path": sourceViewerPath,
135
+ };
136
+ }
@@ -9,7 +9,7 @@ export function createThemeTemplate(layout, themeColors = THEME_COLORS) {
9
9
  id: layout.id,
10
10
  name: layout.name,
11
11
  author: layout.author,
12
- version: "1.0.0",
12
+ version: "1.1.54",
13
13
  mode: layout.mode,
14
14
  supportsLightAndDarkModes: layout.supportsLightAndDarkModes,
15
15
  colors,