@solutiondesk/help 1.0.0-85cf20e → 1.0.0-a316e3a
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 +4 -4
- package/dist/fumadocs.d.ts +0 -11
- package/dist/fumadocs.js +29 -42
- package/dist/index.d.cts +0 -7
- package/dist/index.d.ts +0 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ const { page } = await help.page("guides/login"); // one page with its text
|
|
|
29
29
|
|
|
30
30
|
| Method | API | Returns |
|
|
31
31
|
| --- | --- | --- |
|
|
32
|
-
| `site({ lang })` | `GET …/site` | The site (`name`, `languages`, `websiteUrl`, its own building `blocks`) and its navigation tree: pages, folders (with index page, `
|
|
32
|
+
| `site({ lang })` | `GET …/site` | The site (`name`, `languages`, `websiteUrl`, its own building `blocks`) and its navigation tree: pages, folders (with index page, `root` tab, `group`, `defaultOpen`, `collapsible`), separators and links. Empty folders are left out. |
|
|
33
33
|
| `pages({ lang })` | `GET …/pages` | Every visible page without its text, in reading order (for builds and sitemaps). |
|
|
34
34
|
| `page(path, { lang, redirect })` | `GET …/page?path=` | One page: `markdown`, `html`, `headings`, `blocks`, `customBlocks`, `breadcrumbs`, `previous`/`next`. The home page has the path `""`. |
|
|
35
35
|
| `pageMarkdown(path, { lang })` | `GET …/page.md?path=` | One page as plain Markdown. |
|
|
@@ -37,7 +37,7 @@ const { page } = await help.page("guides/login"); // one page with its text
|
|
|
37
37
|
| `preview(token, { lang })` | `GET …/preview?token=` | A page in any state (drafts too) for your preview route. |
|
|
38
38
|
| `llmsTxt({ lang })` / `llmsFullTxt({ lang })` | `GET …/llms.txt`, `…/llms-full.txt` | The site for language models: the index, or every page as Markdown. |
|
|
39
39
|
|
|
40
|
-
`html` is safe to insert as it is: raw HTML in the Markdown is shown as text, links only go to web addresses, `mailto:`, paths and anchors, images only come from your help center. Headings carry the `id`s listed in `headings
|
|
40
|
+
`html` is safe to insert as it is: raw HTML in the Markdown is shown as text, links only go to web addresses, `mailto:`, paths and anchors, images only come from your help center. Headings carry the `id`s listed in `headings`.
|
|
41
41
|
|
|
42
42
|
### Moved pages
|
|
43
43
|
|
|
@@ -104,7 +104,7 @@ The navigation becomes the files Fumadocs knows from a content folder:
|
|
|
104
104
|
| --- | --- |
|
|
105
105
|
| page `guides/login` | `guides/login.mdx` (`slugs: ["guides", "login"]`) |
|
|
106
106
|
| home page | `index.mdx` at the top, or `(core)/index.mdx` when it is a top-level group's own page |
|
|
107
|
-
| folder `guides` | `guides/meta.json` with `title`, `
|
|
107
|
+
| folder `guides` | `guides/meta.json` with `title`, `icon`, `root`, `defaultOpen`, `collapsible`, `pages` |
|
|
108
108
|
| group folder `core` (adds no address part) | `(core)/` — a Fumadocs folder group, so `(core)/sign-up/index.mdx` is still `sign-up` |
|
|
109
109
|
| folder's own page | `guides/index.mdx` (`pagesIndex: "index"`, so it also works for `root` tabs) |
|
|
110
110
|
| any other page with the slug `index` | `guides/index_.mdx` (`slugs: ["guides", "index"]`), so it never collides with the folder's own page |
|
|
@@ -286,7 +286,7 @@ document.querySelector("article")!.innerHTML = page.html;
|
|
|
286
286
|
| Block | HTML |
|
|
287
287
|
| --- | --- |
|
|
288
288
|
| callout | `<div class="sd-callout" data-type="info\|warn\|error\|success\|idea" role="note">` with `<p class="sd-callout-title">` and `<div class="sd-callout-body">` |
|
|
289
|
-
| steps | `<ol class="sd-steps">` of `<li class="sd-step">` with `<
|
|
289
|
+
| steps | `<ol class="sd-steps">` of `<li class="sd-step">` with `<p class="sd-step-title">` and `<div class="sd-step-body">` |
|
|
290
290
|
| tabs | `<div class="sd-tabs">` of `<section class="sd-tab" data-title="…">` (build the tab buttons from `data-title`; `page.blocks` says when a page has tabs) |
|
|
291
291
|
| cards | `<div class="sd-cards">` of `<a class="sd-card" href="…" data-icon="Rocket">` (or `<div class="sd-card">`) with `<p class="sd-card-title">` and `<div class="sd-card-body">` |
|
|
292
292
|
| titled code | `<figure class="sd-code"><figcaption>client.ts</figcaption><pre><code class="language-ts">` |
|
package/dist/fumadocs.d.ts
CHANGED
|
@@ -81,8 +81,6 @@ interface HelpPublicTreeFolder {
|
|
|
81
81
|
/** The folder's path (its index page, if any, lives here; a group's is its parent's). */
|
|
82
82
|
path: string;
|
|
83
83
|
title: string;
|
|
84
|
-
/** A short line under a tab's name in the tab menu (Fumadocs `description`); null without one. */
|
|
85
|
-
description: string | null;
|
|
86
84
|
icon: string | null;
|
|
87
85
|
/** A tab (top level only; Fumadocs `root`). */
|
|
88
86
|
root: boolean;
|
|
@@ -95,11 +93,6 @@ interface HelpPublicTreeFolder {
|
|
|
95
93
|
collapsible: boolean;
|
|
96
94
|
/** The folder's own page, shown at the folder's path; null without one. */
|
|
97
95
|
index: HelpPublicTreePage | null;
|
|
98
|
-
/**
|
|
99
|
-
* List `index` as the folder's first entry (after a section title it starts
|
|
100
|
-
* with); the folder's name then only opens it (Fumadocs: `index` in `pages`).
|
|
101
|
-
*/
|
|
102
|
-
listIndex: boolean;
|
|
103
96
|
children: HelpPublicTreeNode[];
|
|
104
97
|
}
|
|
105
98
|
/** A labelled divider between entries (Fumadocs `---Title---`). */
|
|
@@ -325,8 +318,6 @@ interface HelpStepsProps {
|
|
|
325
318
|
}
|
|
326
319
|
interface HelpStepProps {
|
|
327
320
|
title?: string;
|
|
328
|
-
/** The title's anchor id (a step's title is a heading of the page, level 3). */
|
|
329
|
-
id?: string;
|
|
330
321
|
children: ReactNode;
|
|
331
322
|
}
|
|
332
323
|
interface HelpTabsProps {
|
|
@@ -673,8 +664,6 @@ interface HelpPageData extends PageData {
|
|
|
673
664
|
/** What every folder's `meta.json` of a help source carries. */
|
|
674
665
|
interface HelpMetaData extends MetaData {
|
|
675
666
|
title?: string;
|
|
676
|
-
/** Shown under a tab's name in Fumadocs' tab menu. */
|
|
677
|
-
description?: string;
|
|
678
667
|
icon?: string;
|
|
679
668
|
root?: boolean;
|
|
680
669
|
defaultOpen?: boolean;
|
package/dist/fumadocs.js
CHANGED
|
@@ -112,25 +112,28 @@ function codeInfo(lang, meta) {
|
|
|
112
112
|
const title = (match ? match[1] ?? match[2] ?? match[3] : void 0)?.trim() || void 0;
|
|
113
113
|
return { language, title };
|
|
114
114
|
}
|
|
115
|
-
var
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
115
|
+
var TRANSLITERATIONS = {
|
|
116
|
+
\u00E4: "ae",
|
|
117
|
+
\u00F6: "oe",
|
|
118
|
+
\u00FC: "ue",
|
|
119
|
+
\u00DF: "ss",
|
|
120
|
+
\u00E6: "ae",
|
|
121
|
+
\u0153: "oe",
|
|
122
|
+
\u00F8: "o",
|
|
123
|
+
\u00E5: "a",
|
|
124
|
+
\u0111: "d",
|
|
125
|
+
\u00F0: "d",
|
|
126
|
+
\u00FE: "th",
|
|
127
|
+
\u0142: "l",
|
|
128
|
+
\u0131: "i"
|
|
129
|
+
};
|
|
130
|
+
function headingSlug(text) {
|
|
131
|
+
return text.normalize("NFC").toLowerCase().replace(/[äöüßæœøåđðþłı]/g, (ch) => TRANSLITERATIONS[ch] ?? ch).normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 96).replace(/-+$/, "");
|
|
129
132
|
}
|
|
130
133
|
function collectHeadings(root) {
|
|
131
134
|
const out = [];
|
|
132
135
|
const walk = (node) => {
|
|
133
|
-
if (node.type === "heading"
|
|
136
|
+
if (node.type === "heading") out.push(node);
|
|
134
137
|
if ("children" in node) for (const child of node.children) walk(child);
|
|
135
138
|
};
|
|
136
139
|
walk(root);
|
|
@@ -146,14 +149,12 @@ function headingIds(root, known, override) {
|
|
|
146
149
|
return ids;
|
|
147
150
|
}
|
|
148
151
|
const used = /* @__PURE__ */ new Map();
|
|
149
|
-
const withoutBlocks = override ? (node) => {
|
|
150
|
-
if (override(node) === void 0) return void 0;
|
|
151
|
-
if (node.type !== "textDirective") return "";
|
|
152
|
-
return node.children.map((child) => plainText(child)).join("").trim();
|
|
153
|
-
} : void 0;
|
|
154
152
|
for (const heading of headings) {
|
|
155
|
-
const text =
|
|
156
|
-
|
|
153
|
+
const text = plainText(heading, override).replace(/\s+/g, " ").trim();
|
|
154
|
+
const base = headingSlug(text) || "section";
|
|
155
|
+
const seen = used.get(base) ?? 0;
|
|
156
|
+
used.set(base, seen + 1);
|
|
157
|
+
ids.set(heading, seen === 0 ? base : `${base}-${seen + 1}`);
|
|
157
158
|
}
|
|
158
159
|
return ids;
|
|
159
160
|
}
|
|
@@ -378,8 +379,8 @@ var PLAIN_CODE_COLORS = {
|
|
|
378
379
|
var helpBodyComponents = {
|
|
379
380
|
Callout: ({ type, title, children }) => /* @__PURE__ */ jsx(Callout, { type, title, children }),
|
|
380
381
|
Steps: ({ children }) => /* @__PURE__ */ jsx(Steps, { children }),
|
|
381
|
-
Step: ({ title,
|
|
382
|
-
title ? /* @__PURE__ */ jsx(
|
|
382
|
+
Step: ({ title, children }) => /* @__PURE__ */ jsxs(Step, { children: [
|
|
383
|
+
title ? /* @__PURE__ */ jsx("h3", { children: title }) : null,
|
|
383
384
|
children
|
|
384
385
|
] }),
|
|
385
386
|
Tabs: ({ items, children }) => /* @__PURE__ */ jsx(Tabs, { items, children }),
|
|
@@ -554,7 +555,7 @@ function renderDirective(node, ctx) {
|
|
|
554
555
|
return /* @__PURE__ */ jsx(c.Steps, { children: content.map(
|
|
555
556
|
(child, i) => isDirective(child, "step") ? (
|
|
556
557
|
// biome-ignore lint/suspicious/noArrayIndexKey: static content, never reordered.
|
|
557
|
-
/* @__PURE__ */ jsx(c.Step, { title: directiveTitle(child),
|
|
558
|
+
/* @__PURE__ */ jsx(c.Step, { title: directiveTitle(child), children: renderAll(contentOf(child), ctx) }, i)
|
|
558
559
|
) : (
|
|
559
560
|
// A loose block between steps becomes a step of its own.
|
|
560
561
|
// biome-ignore lint/suspicious/noArrayIndexKey: static content, never reordered.
|
|
@@ -562,7 +563,7 @@ function renderDirective(node, ctx) {
|
|
|
562
563
|
)
|
|
563
564
|
) });
|
|
564
565
|
case "step":
|
|
565
|
-
return /* @__PURE__ */ jsx(c.Steps, { children: /* @__PURE__ */ jsx(c.Step, { title,
|
|
566
|
+
return /* @__PURE__ */ jsx(c.Steps, { children: /* @__PURE__ */ jsx(c.Step, { title, children: renderAll(content, ctx) }) });
|
|
566
567
|
case "tabs":
|
|
567
568
|
return renderTabs(content, ctx);
|
|
568
569
|
case "tab":
|
|
@@ -791,13 +792,6 @@ function helpStructuredData(markdown, headings, blocks) {
|
|
|
791
792
|
if (current && content) out.headings.push({ id: current, content });
|
|
792
793
|
return;
|
|
793
794
|
}
|
|
794
|
-
if (isTitledStep(node)) {
|
|
795
|
-
current = ids.get(node);
|
|
796
|
-
const content = directiveTitle(node) ?? "";
|
|
797
|
-
if (current) out.headings.push({ id: current, content });
|
|
798
|
-
for (const child of contentOf(node)) walk(child);
|
|
799
|
-
return;
|
|
800
|
-
}
|
|
801
795
|
const use = matcher.use(node);
|
|
802
796
|
if (use) {
|
|
803
797
|
add(use.text);
|
|
@@ -870,23 +864,16 @@ function helpTreeToFiles(payload, options) {
|
|
|
870
864
|
};
|
|
871
865
|
files.push({ type: "page", path: file, slugs: slugsOf(page.path), data });
|
|
872
866
|
};
|
|
873
|
-
const folderPages = (folder) => {
|
|
874
|
-
const pages = folder.children.map(helpMetaEntry);
|
|
875
|
-
if (!folder.index || !folder.listIndex) return pages;
|
|
876
|
-
const at = folder.children[0]?.type === "separator" ? 1 : 0;
|
|
877
|
-
return [...pages.slice(0, at), "index", ...pages.slice(at)];
|
|
878
|
-
};
|
|
879
867
|
const addFolder = (folder, dir) => {
|
|
880
868
|
if (folder.index) addPage(folder.index, join(dir, ext("index", "mdx")));
|
|
881
869
|
const data = {
|
|
882
870
|
title: folder.title,
|
|
883
|
-
...folder.description ? { description: folder.description } : {},
|
|
884
871
|
...folder.icon ? { icon: folder.icon } : {},
|
|
885
872
|
...folder.root ? { root: true } : {},
|
|
886
873
|
defaultOpen: folder.defaultOpen,
|
|
887
874
|
collapsible: folder.collapsible,
|
|
888
|
-
...folder.index
|
|
889
|
-
pages:
|
|
875
|
+
...folder.index ? { pagesIndex: "index" } : {},
|
|
876
|
+
pages: folder.children.map(helpMetaEntry)
|
|
890
877
|
};
|
|
891
878
|
files.push({ type: "meta", path: join(dir, ext("meta", "json")), data });
|
|
892
879
|
addChildren(folder.children, dir);
|
package/dist/index.d.cts
CHANGED
|
@@ -208,8 +208,6 @@ interface HelpPublicTreeFolder {
|
|
|
208
208
|
/** The folder's path (its index page, if any, lives here; a group's is its parent's). */
|
|
209
209
|
path: string;
|
|
210
210
|
title: string;
|
|
211
|
-
/** A short line under a tab's name in the tab menu (Fumadocs `description`); null without one. */
|
|
212
|
-
description: string | null;
|
|
213
211
|
icon: string | null;
|
|
214
212
|
/** A tab (top level only; Fumadocs `root`). */
|
|
215
213
|
root: boolean;
|
|
@@ -222,11 +220,6 @@ interface HelpPublicTreeFolder {
|
|
|
222
220
|
collapsible: boolean;
|
|
223
221
|
/** The folder's own page, shown at the folder's path; null without one. */
|
|
224
222
|
index: HelpPublicTreePage | null;
|
|
225
|
-
/**
|
|
226
|
-
* List `index` as the folder's first entry (after a section title it starts
|
|
227
|
-
* with); the folder's name then only opens it (Fumadocs: `index` in `pages`).
|
|
228
|
-
*/
|
|
229
|
-
listIndex: boolean;
|
|
230
223
|
children: HelpPublicTreeNode[];
|
|
231
224
|
}
|
|
232
225
|
/** A labelled divider between entries (Fumadocs `---Title---`). */
|
package/dist/index.d.ts
CHANGED
|
@@ -208,8 +208,6 @@ interface HelpPublicTreeFolder {
|
|
|
208
208
|
/** The folder's path (its index page, if any, lives here; a group's is its parent's). */
|
|
209
209
|
path: string;
|
|
210
210
|
title: string;
|
|
211
|
-
/** A short line under a tab's name in the tab menu (Fumadocs `description`); null without one. */
|
|
212
|
-
description: string | null;
|
|
213
211
|
icon: string | null;
|
|
214
212
|
/** A tab (top level only; Fumadocs `root`). */
|
|
215
213
|
root: boolean;
|
|
@@ -222,11 +220,6 @@ interface HelpPublicTreeFolder {
|
|
|
222
220
|
collapsible: boolean;
|
|
223
221
|
/** The folder's own page, shown at the folder's path; null without one. */
|
|
224
222
|
index: HelpPublicTreePage | null;
|
|
225
|
-
/**
|
|
226
|
-
* List `index` as the folder's first entry (after a section title it starts
|
|
227
|
-
* with); the folder's name then only opens it (Fumadocs: `index` in `pages`).
|
|
228
|
-
*/
|
|
229
|
-
listIndex: boolean;
|
|
230
223
|
children: HelpPublicTreeNode[];
|
|
231
224
|
}
|
|
232
225
|
/** A labelled divider between entries (Fumadocs `---Title---`). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solutiondesk/help",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-a316e3a",
|
|
4
4
|
"description": "Typed, zero-dependency client for the SolutionDesk public help center API, plus a Fumadocs adapter: navigation, pages, search, previews, llms.txt and webhook verification.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"solutiondesk",
|