@terrafirmagreg-team/kit 0.0.0-stage → 1.2.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/package.json +56 -3
- package/src/components/blocks/nav-title.tsx +62 -0
- package/src/components/outline/dropdown.tsx +68 -0
- package/src/components/outline/index.ts +11 -0
- package/src/components/outline/list.tsx +121 -0
- package/src/components/outline/outline.tsx +50 -0
- package/src/components/outline/popover.tsx +77 -0
- package/src/components/page-actions.tsx +202 -0
- package/src/components/relative-link.tsx +19 -0
- package/src/components/toc/base.tsx +66 -0
- package/src/components/toc/block.tsx +112 -0
- package/src/components/toc/clerk.tsx +266 -0
- package/src/components/toc/default.tsx +334 -0
- package/src/components/version-menu.tsx +130 -0
- package/src/components/views/dataset.tsx +72 -0
- package/src/components/views/section.tsx +152 -0
- package/src/components/workspace/content.tsx +54 -0
- package/src/components/workspace/index.ts +13 -0
- package/src/components/workspace/pagination.tsx +74 -0
- package/src/components/workspace/workspace.tsx +149 -0
- package/src/hooks/use-catalog.ts +12 -0
- package/src/hooks/use-current-dataset.ts +24 -0
- package/src/hooks/use-dataset-accent.ts +14 -0
- package/src/hooks/use-nav-options.ts +87 -0
- package/src/hooks/use-section-names.ts +40 -0
- package/src/hooks/use-toc.ts +10 -0
- package/src/hooks/use-version-pref.ts +31 -0
- package/src/hooks/use-versioned-dataset.ts +21 -0
- package/src/lib/breadcrumb.ts +65 -0
- package/src/lib/config.ts +111 -0
- package/src/lib/dataset-links.ts +31 -0
- package/src/lib/datasets.ts +241 -0
- package/src/lib/landing.ts +48 -0
- package/src/lib/layout.ts +16 -0
- package/src/lib/locale/renderer.ts +49 -0
- package/src/lib/order.ts +89 -0
- package/src/lib/page.ts +109 -0
- package/src/lib/pin-tree.ts +38 -0
- package/src/lib/preview/lookup.ts +51 -0
- package/src/lib/section/schema.ts +32 -0
- package/src/lib/section/source.ts +77 -0
- package/src/lib/sources.ts +22 -0
- package/src/lib/tree.ts +61 -0
- package/src/lib/urls.ts +17 -0
- package/src/locales/en_us.json +7 -0
- package/src/locales/ru_ru.json +7 -0
- package/src/locales.ts +6 -0
- package/src/types/embeds.ts +54 -0
- package/src/types/index.ts +87 -0
- package/src/types/outline.ts +30 -0
- package/README.md +0 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
2
|
+
|
|
3
|
+
function pinUrl(url: string, from: string, version: string): string {
|
|
4
|
+
const next = url[from.length];
|
|
5
|
+
if (!url.startsWith(from) ||
|
|
6
|
+
(next !== undefined && next !== '/' && next !== '?' && next !== '#')) return url;
|
|
7
|
+
const [pathQuery, hash] = url.split('#');
|
|
8
|
+
const [path, query] = pathQuery.split('?');
|
|
9
|
+
const params = new URLSearchParams(query);
|
|
10
|
+
params.set('version', version);
|
|
11
|
+
return `${path}?${params}${hash === undefined ? '' : `#${hash}`}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function pinTreeDataset(
|
|
15
|
+
tree: PageTree.Root,
|
|
16
|
+
section: string,
|
|
17
|
+
datasetId: string,
|
|
18
|
+
version: string,
|
|
19
|
+
): PageTree.Root {
|
|
20
|
+
const from = `/${section}/${datasetId}`;
|
|
21
|
+
const pinNode = (node: PageTree.Node): PageTree.Node => {
|
|
22
|
+
if (node.type === 'page') {
|
|
23
|
+
return { ...node, url: pinUrl(node.url, from, version) };
|
|
24
|
+
}
|
|
25
|
+
if (node.type === 'folder') {
|
|
26
|
+
return {
|
|
27
|
+
...node,
|
|
28
|
+
index: node.index
|
|
29
|
+
? { ...node.index, url: pinUrl(node.index.url, from, version) }
|
|
30
|
+
: node.index,
|
|
31
|
+
children: node.children.map(pinNode),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return node;
|
|
35
|
+
};
|
|
36
|
+
return { ...tree, children: tree.children.map(pinNode) };
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import { resolveLang } from '@terrafirmagreg-team/translate/lib/code';
|
|
3
|
+
import { loadLocaleRegistry } from '@terrafirmagreg-team/translate/server';
|
|
4
|
+
import { sectionConfig } from '@terrafirmagreg-team/kit/lib/config';
|
|
5
|
+
import { isSectionKey } from '@terrafirmagreg-team/sites/location';
|
|
6
|
+
import { resolvePage } from '@terrafirmagreg-team/kit/lib/page';
|
|
7
|
+
import { sections } from '@terrafirmagreg-team/kit/lib/sources';
|
|
8
|
+
import type {
|
|
9
|
+
DatasetCatalog,
|
|
10
|
+
SectionKey,
|
|
11
|
+
SectionPage,
|
|
12
|
+
} from '@terrafirmagreg-team/kit/types';
|
|
13
|
+
import type { PagePreviewData } from '@terrafirmagreg-team/ui/types/preview';
|
|
14
|
+
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
15
|
+
|
|
16
|
+
export function lookupPagePreview(
|
|
17
|
+
catalog: DatasetCatalog,
|
|
18
|
+
href: string | undefined,
|
|
19
|
+
lang?: Lang,
|
|
20
|
+
): PagePreviewData | undefined {
|
|
21
|
+
if (!href || /^(https?:|mailto:|\/\/|#)/i.test(href)) return undefined;
|
|
22
|
+
const [withoutHash] = href.split('#');
|
|
23
|
+
const [pathname, qs] = withoutHash.split('?');
|
|
24
|
+
if (!pathname.startsWith('/')) return undefined;
|
|
25
|
+
|
|
26
|
+
const { defaultLanguage } = loadLocaleRegistry();
|
|
27
|
+
const parts = pathname.split('/').filter(Boolean);
|
|
28
|
+
if (!isSectionKey(parts[0])) return undefined;
|
|
29
|
+
|
|
30
|
+
const section = sections[parts[0]];
|
|
31
|
+
if (!section) return undefined;
|
|
32
|
+
const dataset = catalog[parts[0] as SectionKey]?.find(
|
|
33
|
+
(row) => row.id === parts[1],
|
|
34
|
+
);
|
|
35
|
+
const pageLang = resolveLang(
|
|
36
|
+
new URLSearchParams(qs).get('lang') ?? lang,
|
|
37
|
+
dataset?.languages ?? [...sectionConfig().knownLanguages],
|
|
38
|
+
defaultLanguage,
|
|
39
|
+
);
|
|
40
|
+
const source = section.getSourceSync?.();
|
|
41
|
+
if (!source) return undefined;
|
|
42
|
+
const resolved = resolvePage(source, parts.slice(1), pageLang);
|
|
43
|
+
const page = resolved?.page as SectionPage | undefined;
|
|
44
|
+
if (!page) return undefined;
|
|
45
|
+
return {
|
|
46
|
+
title: page.data.title,
|
|
47
|
+
description: page.data.description,
|
|
48
|
+
icon: dataset?.icon ? { type: 'icon', name: dataset.icon } : undefined,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { metaSchema, pageSchema } from 'fumadocs-core/source/schema';
|
|
2
|
+
import { z, type ZodRawShape } from 'zod';
|
|
3
|
+
|
|
4
|
+
export function sectionDocsConfig(schemaFields: ZodRawShape = {}): {
|
|
5
|
+
docs: {
|
|
6
|
+
schema: ReturnType<typeof pageSchema.extend>;
|
|
7
|
+
postprocess: { includeProcessedMarkdown: true };
|
|
8
|
+
};
|
|
9
|
+
meta: { schema: typeof metaSchema };
|
|
10
|
+
} {
|
|
11
|
+
return {
|
|
12
|
+
docs: {
|
|
13
|
+
schema: pageSchema.extend({
|
|
14
|
+
order: z.number().optional(),
|
|
15
|
+
unlisted: z.boolean().optional(),
|
|
16
|
+
comments: z.boolean().optional(),
|
|
17
|
+
redirect: z.string().optional(),
|
|
18
|
+
defaultOpen: z.boolean().optional(),
|
|
19
|
+
collapsible: z.boolean().optional(),
|
|
20
|
+
link: z.boolean().optional(),
|
|
21
|
+
...schemaFields,
|
|
22
|
+
}),
|
|
23
|
+
postprocess: {
|
|
24
|
+
includeProcessedMarkdown: true,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
meta: {
|
|
28
|
+
schema: metaSchema,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dynamicLoader,
|
|
3
|
+
llms,
|
|
4
|
+
type DynamicSource,
|
|
5
|
+
type LoaderConfig,
|
|
6
|
+
type LoaderOutput,
|
|
7
|
+
} from 'fumadocs-core/source';
|
|
8
|
+
import { sectionDatasets } from '@terrafirmagreg-team/kit/lib/datasets';
|
|
9
|
+
import { sectionConfig } from '@terrafirmagreg-team/kit/lib/config';
|
|
10
|
+
import { orderPlugin } from '@terrafirmagreg-team/kit/lib/order';
|
|
11
|
+
import { renderSectionMarkdown } from '@terrafirmagreg-team/mdx/lib/markdown';
|
|
12
|
+
import { localizedDatasetTrees } from '@terrafirmagreg-team/kit/lib/tree';
|
|
13
|
+
import type { SectionTrees } from '@terrafirmagreg-team/kit/types';
|
|
14
|
+
import type { SectionKey } from '@terrafirmagreg-team/sites/location';
|
|
15
|
+
|
|
16
|
+
const LOCALE_SEGMENT = /^[a-z]{2,3}_[a-z]{2,4}$/;
|
|
17
|
+
|
|
18
|
+
export function createSectionSource(options: {
|
|
19
|
+
route: string;
|
|
20
|
+
|
|
21
|
+
section: SectionKey;
|
|
22
|
+
source: DynamicSource;
|
|
23
|
+
|
|
24
|
+
postTrees?: (trees: SectionTrees) => SectionTrees;
|
|
25
|
+
}) {
|
|
26
|
+
const { route, section, source: dynamicSource, postTrees } = options;
|
|
27
|
+
const source: DynamicSource = {
|
|
28
|
+
...dynamicSource,
|
|
29
|
+
files: async () => {
|
|
30
|
+
const known = new Set(sectionConfig().knownLanguages);
|
|
31
|
+
return (await dynamicSource.files()).filter(
|
|
32
|
+
(file) =>
|
|
33
|
+
!file.path
|
|
34
|
+
.split('/')
|
|
35
|
+
.some((seg) => LOCALE_SEGMENT.test(seg) && !known.has(seg)),
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const loader = dynamicLoader(source, {
|
|
40
|
+
baseUrl: route,
|
|
41
|
+
plugins: [orderPlugin()],
|
|
42
|
+
});
|
|
43
|
+
let resolved: LoaderOutput<LoaderConfig> | undefined;
|
|
44
|
+
const getSource = async () => {
|
|
45
|
+
resolved = (await loader.get()) as unknown as LoaderOutput<LoaderConfig>;
|
|
46
|
+
return resolved;
|
|
47
|
+
};
|
|
48
|
+
const getSourceSync = () => resolved;
|
|
49
|
+
const markdown = {
|
|
50
|
+
page: async (page: unknown) =>
|
|
51
|
+
llms((await getSource()) as never, {
|
|
52
|
+
renderPage: renderSectionMarkdown as (
|
|
53
|
+
page: unknown,
|
|
54
|
+
) => Promise<string>,
|
|
55
|
+
}).page(page as never),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
let cached:
|
|
59
|
+
| { source: LoaderOutput<LoaderConfig>; trees: Promise<SectionTrees> }
|
|
60
|
+
| undefined;
|
|
61
|
+
const trees = (): Promise<SectionTrees> =>
|
|
62
|
+
getSource().then((source) => {
|
|
63
|
+
if (cached?.source === source) return cached.trees;
|
|
64
|
+
const built = (async () => {
|
|
65
|
+
const result = localizedDatasetTrees(
|
|
66
|
+
source,
|
|
67
|
+
await sectionDatasets(section),
|
|
68
|
+
);
|
|
69
|
+
return postTrees ? postTrees(result) : result;
|
|
70
|
+
})();
|
|
71
|
+
cached = { source, trees: built };
|
|
72
|
+
return built;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return { route, getSource, getSourceSync, markdown, trees };
|
|
76
|
+
}
|
|
77
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { sectionConfig } from './config';
|
|
2
|
+
import type { SectionKey, SectionSourceEntry } from '@terrafirmagreg-team/kit/types';
|
|
3
|
+
|
|
4
|
+
export const sections: Partial<Record<SectionKey, SectionSourceEntry>> =
|
|
5
|
+
new Proxy(
|
|
6
|
+
{},
|
|
7
|
+
{
|
|
8
|
+
get: (_, key: string) => sectionConfig().sources[key as SectionKey],
|
|
9
|
+
has: (_, key: string) =>
|
|
10
|
+
Object.hasOwn(sectionConfig().sources ?? {}, key as string),
|
|
11
|
+
ownKeys: () => Reflect.ownKeys(sectionConfig().sources ?? {}),
|
|
12
|
+
getOwnPropertyDescriptor: (_, key: string) =>
|
|
13
|
+
Object.hasOwn(sectionConfig().sources, key)
|
|
14
|
+
? {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
value: sectionConfig().sources[key as SectionKey],
|
|
18
|
+
}
|
|
19
|
+
: undefined,
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
|
package/src/lib/tree.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
2
|
+
import { localizePageTree } from '@terrafirmagreg-team/translate/server';
|
|
3
|
+
import { loadLocaleRegistry } from '@terrafirmagreg-team/translate/server';
|
|
4
|
+
import { sectionConfig } from './config';
|
|
5
|
+
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
6
|
+
import type { SectionDataset, SectionTrees } from '@terrafirmagreg-team/kit/types';
|
|
7
|
+
import type { SectionSource } from './page';
|
|
8
|
+
|
|
9
|
+
export function datasetId(node: PageTree.Folder): string | undefined {
|
|
10
|
+
const segment = node.index?.url.split('/').filter(Boolean)[1];
|
|
11
|
+
if (segment) return segment;
|
|
12
|
+
const segments = node.$id?.split('/').filter(Boolean);
|
|
13
|
+
return segments?.[segments.length - 1];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function datasetTree(
|
|
17
|
+
tree: PageTree.Root,
|
|
18
|
+
id: string,
|
|
19
|
+
lang: Lang,
|
|
20
|
+
): PageTree.Root {
|
|
21
|
+
const folder = tree.children.find(
|
|
22
|
+
(node): node is PageTree.Folder =>
|
|
23
|
+
node.type === 'folder' && datasetId(node) === id,
|
|
24
|
+
);
|
|
25
|
+
if (!folder) return { name: id, children: [], $id: `${id}:${lang}` };
|
|
26
|
+
return { name: folder.name, children: folder.children, $id: `${id}:${lang}` };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function localizedDatasetTrees(
|
|
30
|
+
source: SectionSource,
|
|
31
|
+
datasets: readonly SectionDataset[],
|
|
32
|
+
): SectionTrees {
|
|
33
|
+
const { defaultLanguage } = loadLocaleRegistry();
|
|
34
|
+
const tree = source.getPageTree();
|
|
35
|
+
const options = {
|
|
36
|
+
languages: [...sectionConfig().knownLanguages],
|
|
37
|
+
fallbackLanguage: defaultLanguage,
|
|
38
|
+
};
|
|
39
|
+
const localized = new Map<string, PageTree.Root>();
|
|
40
|
+
const localize = (lang: Lang) => {
|
|
41
|
+
let out = localized.get(lang);
|
|
42
|
+
if (!out) {
|
|
43
|
+
out = localizePageTree(tree, lang, options);
|
|
44
|
+
localized.set(lang, out);
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
};
|
|
48
|
+
const trees: SectionTrees = {};
|
|
49
|
+
for (const dataset of datasets) {
|
|
50
|
+
for (const lang of dataset.languages ?? [defaultLanguage]) {
|
|
51
|
+
const code = lang as Lang;
|
|
52
|
+
(trees[code] ??= {})[dataset.id] = datasetTree(
|
|
53
|
+
localize(code),
|
|
54
|
+
dataset.id,
|
|
55
|
+
code,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return trees;
|
|
60
|
+
}
|
|
61
|
+
|
package/src/lib/urls.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createGetUrl } from 'fumadocs-core/source';
|
|
2
|
+
import { sectionConfig } from './config';
|
|
3
|
+
|
|
4
|
+
export function canonicalUrl(pathname: string): string {
|
|
5
|
+
const path = pathname.startsWith('/') ? pathname : `/${pathname}`;
|
|
6
|
+
return new URL(path, sectionConfig().siteUrl).toString();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getDatasetImageUrl(section: string, dataset: string) {
|
|
10
|
+
const segments = [section, dataset, 'image.png'];
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
segments,
|
|
14
|
+
url: createGetUrl(sectionConfig().previewRoute)(segments),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Failed to copy(ui.copy_error)": "Failed to copy",
|
|
3
|
+
"Select dataset(ui.select_dataset)": "Select dataset",
|
|
4
|
+
"Select section(ui.select_section)": "Select section",
|
|
5
|
+
"View as Markdown(ui.view_markdown)": "View as Markdown",
|
|
6
|
+
"latest(ui.version_latest)": "latest"
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Failed to copy(ui.copy_error)": "Не удалось скопировать",
|
|
3
|
+
"Select dataset(ui.select_dataset)": "Выберите набор данных",
|
|
4
|
+
"Select section(ui.select_section)": "Выберите раздел",
|
|
5
|
+
"View as Markdown(ui.view_markdown)": "Просмотр Markdown",
|
|
6
|
+
"latest(ui.version_latest)": "последняя"
|
|
7
|
+
}
|
package/src/locales.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
2
|
+
import type { DatasetRef } from '@terrafirmagreg-team/sites/location';
|
|
3
|
+
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
4
|
+
|
|
5
|
+
export type EmbedRecipe = {
|
|
6
|
+
id: string;
|
|
7
|
+
w?: number | null;
|
|
8
|
+
inputs: { id: string }[];
|
|
9
|
+
outputs: { id: string }[];
|
|
10
|
+
slots?: Record<
|
|
11
|
+
string,
|
|
12
|
+
{ id: string; alternatives?: { id: string }[] }
|
|
13
|
+
>;
|
|
14
|
+
widgets?: {
|
|
15
|
+
type: string;
|
|
16
|
+
id: string;
|
|
17
|
+
alternatives?: string[];
|
|
18
|
+
}[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type EmbedRecipeCardProps = {
|
|
22
|
+
id: string;
|
|
23
|
+
recipe: EmbedRecipe;
|
|
24
|
+
dataset: DatasetRef;
|
|
25
|
+
lang: Lang;
|
|
26
|
+
langMap: Record<string, string>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type EmbedQuestLocation = { filename: string; questId: string };
|
|
30
|
+
|
|
31
|
+
export type SectionEmbeds = {
|
|
32
|
+
quest?: {
|
|
33
|
+
href(
|
|
34
|
+
dataset: DatasetRef,
|
|
35
|
+
lang: Lang | undefined,
|
|
36
|
+
ref: { category: string; id: string },
|
|
37
|
+
): string;
|
|
38
|
+
findLocation(
|
|
39
|
+
dataset: DatasetRef,
|
|
40
|
+
questId: string,
|
|
41
|
+
): Promise<EmbedQuestLocation | undefined>;
|
|
42
|
+
};
|
|
43
|
+
recipe?: {
|
|
44
|
+
href(
|
|
45
|
+
dataset: DatasetRef,
|
|
46
|
+
lang: Lang | undefined,
|
|
47
|
+
ref: { id: string },
|
|
48
|
+
): string;
|
|
49
|
+
cardImageUrl(dataset: DatasetRef, id: string): string | undefined;
|
|
50
|
+
load(dataset: DatasetRef, id: string): Promise<EmbedRecipe | undefined>;
|
|
51
|
+
title(recipe: EmbedRecipe, langMap: Record<string, string>): string;
|
|
52
|
+
Card: ComponentType<EmbedRecipeCardProps>;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { DatasetRef, SectionKey } from '@terrafirmagreg-team/sites/location';
|
|
2
|
+
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
3
|
+
import type { ComponentType } from 'react';
|
|
4
|
+
import type { IconName } from 'lucide-react/dynamic';
|
|
5
|
+
import type { Page } from 'fumadocs-core/source';
|
|
6
|
+
import type { Lang } from '@terrafirmagreg-team/translate/types/locale';
|
|
7
|
+
|
|
8
|
+
export type { SectionKey } from '@terrafirmagreg-team/sites/location';
|
|
9
|
+
|
|
10
|
+
export type SectionUrl = string;
|
|
11
|
+
|
|
12
|
+
export type SectionDataset = {
|
|
13
|
+
id: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
icon?: IconName;
|
|
17
|
+
accent?: string;
|
|
18
|
+
|
|
19
|
+
versions?: string[];
|
|
20
|
+
|
|
21
|
+
languages?: Lang[];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type DatasetCatalog = Record<SectionKey, SectionDataset[]>;
|
|
25
|
+
|
|
26
|
+
export type LeftSidebarScope = {
|
|
27
|
+
section: SectionKey;
|
|
28
|
+
catalog: DatasetCatalog;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type LeftSidebarSlotProps = LeftSidebarScope & {
|
|
32
|
+
|
|
33
|
+
feature?: ComponentType;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type SectionTrees = Record<Lang, Record<string, PageTree.Root>>;
|
|
37
|
+
|
|
38
|
+
export type SectionPage = {
|
|
39
|
+
data: {
|
|
40
|
+
title: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
full?: boolean;
|
|
43
|
+
comments?: boolean;
|
|
44
|
+
redirect?: string;
|
|
45
|
+
authors?: string[];
|
|
46
|
+
gitChangelog?:
|
|
47
|
+
| boolean
|
|
48
|
+
| {
|
|
49
|
+
disableChangelog?: boolean;
|
|
50
|
+
disableContributors?: boolean;
|
|
51
|
+
};
|
|
52
|
+
load?(): Promise<unknown>;
|
|
53
|
+
content?: string;
|
|
54
|
+
structuredData?: unknown;
|
|
55
|
+
frontmatter?: Record<string, unknown>;
|
|
56
|
+
};
|
|
57
|
+
path: string;
|
|
58
|
+
slugs: string[];
|
|
59
|
+
url: string;
|
|
60
|
+
locale?: string;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type SectionSource = {
|
|
64
|
+
getPage(slugs: string[] | undefined, language?: string): unknown;
|
|
65
|
+
getPages(language?: string): Page[];
|
|
66
|
+
getPageTree(locale?: string): PageTree.Root;
|
|
67
|
+
getNodeMeta?(
|
|
68
|
+
node: PageTree.Folder | PageTree.Root,
|
|
69
|
+
language?: string,
|
|
70
|
+
): unknown;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type DatasetLanding = {
|
|
74
|
+
title: string;
|
|
75
|
+
description?: string;
|
|
76
|
+
dataset: DatasetRef;
|
|
77
|
+
datasetTitle?: string;
|
|
78
|
+
lang: Lang;
|
|
79
|
+
versions?: string[];
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type SectionSourceEntry = {
|
|
83
|
+
getSource: () => Promise<SectionSource>;
|
|
84
|
+
getSourceSync?: () => SectionSource | undefined;
|
|
85
|
+
markdown: { page(page: unknown): Promise<string> };
|
|
86
|
+
};
|
|
87
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
+
import type * as OutlineDefault from '@terrafirmagreg-team/kit/components/toc/default';
|
|
3
|
+
import type * as OutlineClerk from '@terrafirmagreg-team/kit/components/toc/clerk';
|
|
4
|
+
import type * as OutlineBlock from '@terrafirmagreg-team/kit/components/toc/block';
|
|
5
|
+
|
|
6
|
+
export type OutlineStyle =
|
|
7
|
+
| { style?: 'block'; list?: OutlineBlock.TOCItemsProps }
|
|
8
|
+
| { style: 'normal'; list?: OutlineDefault.TOCItemsProps }
|
|
9
|
+
| { style: 'clerk'; list?: OutlineClerk.TOCItemsProps };
|
|
10
|
+
|
|
11
|
+
export type OutlineContent = {
|
|
12
|
+
|
|
13
|
+
header?: ReactNode;
|
|
14
|
+
|
|
15
|
+
footer?: ReactNode;
|
|
16
|
+
} & OutlineStyle;
|
|
17
|
+
|
|
18
|
+
export type OutlineProps = OutlineContent & {
|
|
19
|
+
container?: ComponentProps<'div'>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type WorkspaceOutlineDropdownProps = OutlineContent & {
|
|
23
|
+
trigger?: ComponentProps<'button'>;
|
|
24
|
+
content?: ComponentProps<'div'>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type WorkspaceOutlinePopoverProps = WorkspaceOutlineDropdownProps & {
|
|
28
|
+
container?: ComponentProps<'div'>;
|
|
29
|
+
};
|
|
30
|
+
|
package/README.md
DELETED