Skip to content

Commit 2061dac

Browse files
committed
update
1 parent 58c9a1d commit 2061dac

13 files changed

Lines changed: 393 additions & 289 deletions

src/app/not-found.tsx

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,38 +21,18 @@ import {
2121
import { SearchShellLayout } from "@/widgets/search-shell-layout";
2222
import notFoundStyles from "./not-found.module.css";
2323
import { DocsShell } from "@/widgets/docs-shell";
24+
import {
25+
NOT_INSTALLED,
26+
INSTALLED_NOT_PRERENDERED,
27+
SEARCH_PROMPT,
28+
INSTALLED_PROMPT,
29+
RETURN_HOME,
30+
} from "@/shared/config/i18n/not-found-dict";
2431

25-
const NOT_INSTALLED = {
26-
en: "GitPageDocs is not installed.",
27-
pt: "GitPageDocs Não instalado.",
28-
es: "GitPageDocs no está instalado.",
29-
};
30-
31-
const INSTALLED_NOT_PRERENDERED = {
32-
en: "GitPageDocs is installed in this repository.",
33-
pt: "GitPageDocs esta instalado neste repositorio.",
34-
es: "GitPageDocs esta instalado en este repositorio.",
35-
};
36-
37-
const SEARCH_PROMPT = {
38-
en: "Enter owner and repository to open remote documentation.",
39-
pt: "Informe usuário e repositório para abrir a documentação remota.",
40-
es: "Ingresa usuario y repositorio para abrir la documentación remota.",
41-
};
32+
type RepoStatus = "unknown" | "checking" | "installed" | "not_installed";
4233

43-
const INSTALLED_PROMPT = {
44-
en: "This direct URL was not pre-rendered on GitHub Pages. Use the search form below with the same owner and repository.",
45-
pt: "Esta URL direta nao foi pre-renderizada no GitHub Pages. Use o formulario de busca abaixo com o mesmo usuario e repositorio.",
46-
es: "Esta URL directa no fue pre-renderizada en GitHub Pages. Usa el formulario de busqueda abajo con el mismo usuario y repositorio.",
47-
};
4834

49-
const RETURN_HOME = {
50-
en: "Return Home",
51-
pt: "Voltar ao início",
52-
es: "Volver al inicio",
53-
};
5435

55-
type RepoStatus = "unknown" | "checking" | "installed" | "not_installed";
5636
type SupportedLanguage = "en" | "pt" | "es";
5737

5838
const MIN_LOADING_TRANSITION_MS = 700;

src/entities/docs/api/load-remote-docs-data-client.ts

Lines changed: 13 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ import type {
1515
VersionEntry,
1616
} from "@/entities/docs/model/types";
1717
import { dedupeVersionEntriesById } from "../lib/dedupe-version-entries";
18+
import {
19+
DEFAULT_LAYOUTS_PATH,
20+
DEFAULT_TEMPLATES_BASE_PATH,
21+
OFFICIAL_LAYOUTS_CONFIG_URL,
22+
OFFICIAL_LAYOUTS_TEMPLATES_URL,
23+
} from "@/shared/config/remote-urls";
24+
import {
25+
tryFetchText,
26+
fetchRepoText,
27+
fetchUrlText,
28+
fetchRepoJson,
29+
fetchUrlJson,
30+
} from "@/shared/api/fetch-client";
1831

1932
type VersionConfig = {
2033
routes?: RouteConfig[];
@@ -24,13 +37,6 @@ type VersionConfig = {
2437
};
2538
export type SupportedLanguage = "en" | "pt" | "es";
2639

27-
const REQUEST_TIMEOUT_MS = 12000;
28-
const DEFAULT_LAYOUTS_PATH = "gitpagedocs/layouts/layoutsConfig.json";
29-
const DEFAULT_TEMPLATES_BASE_PATH = "gitpagedocs/layouts/";
30-
const OFFICIAL_LAYOUTS_CONFIG_URL =
31-
"https://github.com/Vidigal-code/git-page-docs/blob/main/gitpagedocs/layouts/layoutsConfig.json";
32-
const OFFICIAL_LAYOUTS_TEMPLATES_URL =
33-
"https://github.com/Vidigal-code/git-page-docs/blob/main/gitpagedocs/layouts/templates";
3440
export async function loadStandaloneLayoutsAndThemes(): Promise<{
3541
layoutsConfig: LayoutsConfig;
3642
themes: Record<string, ThemeTemplate>;
@@ -109,61 +115,6 @@ function stripFrontMatter(markdown: string): string {
109115
return markdown.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, "");
110116
}
111117

112-
async function tryFetchText(url: string): Promise<string | null> {
113-
const controller = new AbortController();
114-
const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
115-
try {
116-
const response = await fetch(url, { cache: "no-store", signal: controller.signal });
117-
if (!response.ok) {
118-
return null;
119-
}
120-
return await response.text();
121-
} catch {
122-
return null;
123-
} finally {
124-
clearTimeout(timer);
125-
}
126-
}
127-
128-
async function fetchRepoText(owner: string, repo: string, relativePath: string): Promise<string | null> {
129-
const candidates = buildGithubRawCandidates(owner, repo, relativePath);
130-
for (const candidate of candidates) {
131-
const content = await tryFetchText(candidate);
132-
if (content !== null) {
133-
return content;
134-
}
135-
}
136-
return null;
137-
}
138-
139-
async function fetchUrlText(url: string): Promise<string | null> {
140-
return tryFetchText(toRawGithubUrl(url));
141-
}
142-
143-
async function fetchRepoJson<T>(owner: string, repo: string, relativePath: string): Promise<T | null> {
144-
const text = await fetchRepoText(owner, repo, relativePath);
145-
if (!text) {
146-
return null;
147-
}
148-
try {
149-
return JSON.parse(text) as T;
150-
} catch {
151-
return null;
152-
}
153-
}
154-
155-
async function fetchUrlJson<T>(url: string): Promise<T | null> {
156-
const text = await fetchUrlText(url);
157-
if (!text) {
158-
return null;
159-
}
160-
try {
161-
return JSON.parse(text) as T;
162-
} catch {
163-
return null;
164-
}
165-
}
166-
167118
function getAvailableLanguages(
168119
routes: Array<{ path?: Record<LanguageCode, string> }>,
169120
fallbackLanguage: LanguageCode,

src/entities/docs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export { toBaseThemeCssVars, toDocsShellCssVars, toSearchShellCssVars } from "./
1818
export { getEmbedUrl, isNativeAudio, isNativeVideo } from "./lib/video/embed-url";
1919
export { getBackgroundAudioConfig, type ResolvedBackgroundAudioConfig } from "./lib/audio";
2020
export { buildVersionLinkOptions, type VersionLinkOption } from "./lib/version-links";
21+
export { resolvePageHierarchy } from "./lib/hierarchy/resolve-page-hierarchy";
2122

2223
export type * from "./model/types";
2324
export { type MenuNode, type MenuEntry, type BreadcrumbItem, getBreadcrumbTrail } from "./model/menu";
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type {
2+
LoadedPage,
3+
GitPageDocsConfig,
4+
HierarchyConfig,
5+
ContentType,
6+
} from "../../model/types";
7+
import { CONTENT_TYPES } from "../../model/types/config";
8+
9+
export function resolvePageHierarchy(
10+
currentPage: LoadedPage | undefined,
11+
globalConfig: GitPageDocsConfig,
12+
contentTypeFilter?: ContentType
13+
): ContentType[] {
14+
if (!currentPage) return [];
15+
16+
const localHierarchy =
17+
(currentPage.md?.config as any)?.hierarchyPage ??
18+
(currentPage.html?.config as any)?.hierarchyPage ??
19+
(currentPage.video?.config as any)?.hierarchyPage ??
20+
(currentPage.audio?.config as any)?.hierarchyPage;
21+
22+
const effectiveHierarchy: HierarchyConfig =
23+
localHierarchy ??
24+
globalConfig.hierarchyPage ??
25+
{ md: 0, html: 1, video: 2, audio: 3 };
26+
27+
const availableTypes = CONTENT_TYPES.filter((t) => currentPage[t]);
28+
29+
if (contentTypeFilter) {
30+
if (availableTypes.includes(contentTypeFilter)) {
31+
return [contentTypeFilter];
32+
}
33+
return [];
34+
}
35+
36+
return availableTypes.sort((a, b) => {
37+
const orderA = effectiveHierarchy[a] ?? 999;
38+
const orderB = effectiveHierarchy[b] ?? 999;
39+
return orderA - orderB;
40+
});
41+
}

src/entities/docs/model/types/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { VersionControlConfig } from "./version";
33
import type { SiteConfig, UiTranslationsConfig } from "./site";
44

55
export type ContentType = "md" | "html" | "video" | "audio";
6+
export const CONTENT_TYPES: ContentType[] = ["md", "html", "video", "audio"];
67

78
export type ExternalAuthProviderType = "authjs" | "clerk" | "firebase" | "jwt";
89

@@ -117,6 +118,8 @@ export interface ContentTypeRouteConfig {
117118
audioSlug?: Record<LanguageCode, string>;
118119
/** Route-level authorization rules for access-key, roles and external providers. */
119120
authorization?: RouteAuthorizationConfig;
121+
/** Granular content hierarchy override for this specific route. */
122+
hierarchyPage?: HierarchyConfig;
120123
}
121124

122125
export interface RouteConfig {

src/shared/api/fetch-client.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { REMOTE_FETCH_TIMEOUT_MS } from "../config/remote-urls";
2+
import { toRawGithubUrl, buildGithubRawCandidates } from "@/entities/docs/lib/remote/github-url";
3+
4+
export async function tryFetchText(url: string): Promise<string | null> {
5+
const controller = new AbortController();
6+
const timer = setTimeout(() => controller.abort(), REMOTE_FETCH_TIMEOUT_MS);
7+
try {
8+
const response = await fetch(url, { cache: "no-store", signal: controller.signal });
9+
if (!response.ok) {
10+
return null;
11+
}
12+
return await response.text();
13+
} catch {
14+
return null;
15+
} finally {
16+
clearTimeout(timer);
17+
}
18+
}
19+
20+
export async function fetchRepoText(owner: string, repo: string, relativePath: string): Promise<string | null> {
21+
const candidates = buildGithubRawCandidates(owner, repo, relativePath);
22+
for (const candidate of candidates) {
23+
const content = await tryFetchText(candidate);
24+
if (content !== null) {
25+
return content;
26+
}
27+
}
28+
return null;
29+
}
30+
31+
export async function fetchUrlText(url: string): Promise<string | null> {
32+
return tryFetchText(toRawGithubUrl(url));
33+
}
34+
35+
export async function fetchRepoJson<T>(owner: string, repo: string, relativePath: string): Promise<T | null> {
36+
const text = await fetchRepoText(owner, repo, relativePath);
37+
if (!text) {
38+
return null;
39+
}
40+
try {
41+
return JSON.parse(text) as T;
42+
} catch {
43+
return null;
44+
}
45+
}
46+
47+
export async function fetchUrlJson<T>(url: string): Promise<T | null> {
48+
const text = await fetchUrlText(url);
49+
if (!text) {
50+
return null;
51+
}
52+
try {
53+
return JSON.parse(text) as T;
54+
} catch {
55+
return null;
56+
}
57+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export const NOT_INSTALLED = {
2+
en: "GitPageDocs is not installed.",
3+
pt: "GitPageDocs Não instalado.",
4+
es: "GitPageDocs no está instalado.",
5+
} as const;
6+
7+
export const INSTALLED_NOT_PRERENDERED = {
8+
en: "GitPageDocs is installed in this repository.",
9+
pt: "GitPageDocs esta instalado neste repositorio.",
10+
es: "GitPageDocs esta instalado en este repositorio.",
11+
} as const;
12+
13+
export const SEARCH_PROMPT = {
14+
en: "Enter owner and repository to open remote documentation.",
15+
pt: "Informe usuário e repositório para abrir a documentação remota.",
16+
es: "Ingresa usuario y repositorio para abrir la documentación remota.",
17+
} as const;
18+
19+
export const INSTALLED_PROMPT = {
20+
en: "This direct URL was not pre-rendered on GitHub Pages. Use the search form below with the same owner and repository.",
21+
pt: "Esta URL direta nao foi pre-renderizada no GitHub Pages. Use o formulario de busca abaixo com o mesmo usuario e repositorio.",
22+
es: "Esta URL directa no fue pre-renderizada en GitHub Pages. Usa el formulario de busqueda abajo con el mismo usuario y repositorio.",
23+
} as const;
24+
25+
export const RETURN_HOME = {
26+
en: "Return Home",
27+
pt: "Voltar ao início",
28+
es: "Volver al inicio",
29+
} as const;

src/shared/config/remote-urls.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export const REMOTE_FETCH_TIMEOUT_MS = 12000;
2+
export const DEFAULT_LAYOUTS_PATH = "gitpagedocs/layouts/layoutsConfig.json";
3+
export const DEFAULT_TEMPLATES_BASE_PATH = "gitpagedocs/layouts/";
4+
export const OFFICIAL_LAYOUTS_CONFIG_URL =
5+
"https://github.com/Vidigal-code/git-page-docs/blob/main/gitpagedocs/layouts/layoutsConfig.json";
6+
export const OFFICIAL_LAYOUTS_TEMPLATES_URL =
7+
"https://github.com/Vidigal-code/git-page-docs/blob/main/gitpagedocs/layouts/templates";

0 commit comments

Comments
 (0)