@heyo-sh/create-heyo-docs 1.0.0 → 2.0.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/deployments/cloudflare/astro/package.json +2 -1
- package/deployments/cloudflare/astro/src/env.d.ts +8 -0
- package/deployments/cloudflare/astro/src/pages/heyo-docs-internal/ai-chat.ts +32 -0
- package/deployments/cloudflare/next/app/heyo-docs-internal/ai-chat/route.ts +27 -0
- package/deployments/cloudflare/next/cloudflare-env.d.ts +7 -0
- package/deployments/cloudflare/react-router/app/cloudflare-env.d.ts +7 -0
- package/deployments/cloudflare/react-router/app/lib/cloudflare-context.ts +4 -0
- package/deployments/cloudflare/react-router/app/routes/ai-chat.ts +31 -0
- package/deployments/cloudflare/react-router/package.json +2 -1
- package/deployments/cloudflare/react-router/workers/app.ts +6 -2
- package/deployments/vercel/astro/package.json +1 -0
- package/dist/index.js +37 -16
- package/dist/project-name.d.ts +1 -1
- package/dist/project-name.d.ts.map +1 -1
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +2 -2
- package/templates/astro/content/index.mdx +8 -0
- package/templates/astro/heyo-docs.config.ts +4 -48
- package/templates/astro/src/components/docs-app.tsx +30 -130
- package/templates/astro/src/heyo-docs-icons.tsx +3 -1
- package/templates/astro/src/layouts/docs-layout.astro +20 -504
- package/templates/astro/src/lib/docs.ts +3 -2
- package/templates/astro/src/lib/openapi-request.ts +6 -146
- package/templates/astro/src/pages/[...slug].astro +7 -15
- package/templates/astro/src/pages/[...slug].md.ts +4 -1
- package/templates/astro/src/pages/heyo-docs-internal/ai-chat.ts +10 -3
- package/templates/astro/src/pages/heyo-docs-internal/openapi-request.ts +6 -0
- package/templates/astro/src/pages/index.astro +18 -9
- package/templates/astro/src/pages/llms-full.txt.ts +1 -1
- package/templates/astro/src/pages/llms.txt.ts +1 -1
- package/templates/astro/src/pages/rss.xml.ts +1 -1
- package/templates/astro/src/pages/sitemap.xml.ts +2 -2
- package/templates/astro/src/virtual.d.ts +5 -5
- package/templates/next/app/[[...slug]]/page.tsx +10 -9
- package/templates/next/app/components/docs-app.tsx +28 -120
- package/templates/next/app/heyo-docs-icons.tsx +1 -1
- package/templates/next/app/heyo-docs-internal/ai-chat/route.ts +9 -2
- package/templates/next/app/heyo-docs-internal/markdown/[[...slug]]/route.ts +1 -1
- package/templates/next/app/layout.tsx +25 -444
- package/templates/next/app/lib/docs.ts +3 -3
- package/templates/next/app/lib/openapi-request.ts +4 -136
- package/templates/next/app/llms-full.txt/route.ts +1 -1
- package/templates/next/app/llms.txt/route.ts +1 -1
- package/templates/next/app/rss.xml/route.ts +1 -1
- package/templates/next/app/sitemap.xml/route.ts +1 -1
- package/templates/next/content/index.mdx +8 -0
- package/templates/next/heyo-docs.config.ts +3 -47
- package/templates/next/next.config.ts +7 -1
- package/templates/react-router/app/heyo-docs-icons.tsx +3 -1
- package/templates/react-router/app/root.tsx +28 -465
- package/templates/react-router/app/routes/ai-chat.ts +6 -2
- package/templates/react-router/app/routes/docs.tsx +22 -63
- package/templates/react-router/app/routes/home.tsx +6 -1
- package/templates/react-router/app/routes/llms-full.ts +1 -1
- package/templates/react-router/app/routes/llms.ts +1 -1
- package/templates/react-router/app/routes/markdown.ts +4 -1
- package/templates/react-router/app/routes/openapi-request.ts +11 -144
- package/templates/react-router/app/routes/rss.ts +1 -1
- package/templates/react-router/app/routes/sitemap.ts +5 -8
- package/templates/react-router/app/virtual.d.ts +5 -5
- package/templates/react-router/content/index.mdx +8 -0
- package/templates/react-router/heyo-docs.config.ts +4 -48
- package/templates/astro/content/api-overview.mdx +0 -20
- package/templates/astro/content/assets/local-architecture.svg +0 -22
- package/templates/astro/content/assets/quick-reference.txt +0 -5
- package/templates/astro/content/changelog.mdx +0 -38
- package/templates/astro/content/configuration.mdx +0 -117
- package/templates/astro/content/deploying.mdx +0 -57
- package/templates/astro/content/essentials/callouts.mdx +0 -34
- package/templates/astro/content/essentials/code-blocks.mdx +0 -43
- package/templates/astro/content/essentials/lists.mdx +0 -36
- package/templates/astro/content/essentials/tables.mdx +0 -30
- package/templates/astro/content/essentials/tabs.mdx +0 -40
- package/templates/astro/content/essentials/text-styling.mdx +0 -43
- package/templates/astro/content/getting-started.mdx +0 -16
- package/templates/astro/content/mdx-components.mdx +0 -44
- package/templates/astro/content/openapi-petstore.json +0 -160
- package/templates/astro/content/openapi.json +0 -278
- package/templates/astro/content/quickstart.mdx +0 -60
- package/templates/astro/src/components/theme-provider.tsx +0 -106
- package/templates/astro/src/lib/seo.ts +0 -221
- package/templates/astro/src/lib/theme.ts +0 -74
- package/templates/next/app/components/theme-provider.tsx +0 -93
- package/templates/next/app/lib/seo.ts +0 -189
- package/templates/next/app/lib/theme.ts +0 -61
- package/templates/next/content/api-overview.mdx +0 -20
- package/templates/next/content/assets/local-architecture.svg +0 -22
- package/templates/next/content/assets/quick-reference.txt +0 -5
- package/templates/next/content/changelog.mdx +0 -38
- package/templates/next/content/configuration.mdx +0 -117
- package/templates/next/content/deploying.mdx +0 -57
- package/templates/next/content/essentials/callouts.mdx +0 -34
- package/templates/next/content/essentials/code-blocks.mdx +0 -43
- package/templates/next/content/essentials/lists.mdx +0 -36
- package/templates/next/content/essentials/tables.mdx +0 -30
- package/templates/next/content/essentials/tabs.mdx +0 -40
- package/templates/next/content/essentials/text-styling.mdx +0 -43
- package/templates/next/content/getting-started.mdx +0 -16
- package/templates/next/content/mdx-components.mdx +0 -41
- package/templates/next/content/openapi-petstore.json +0 -160
- package/templates/next/content/openapi.json +0 -278
- package/templates/next/content/quickstart.mdx +0 -60
- package/templates/react-router/app/components/theme-provider.tsx +0 -106
- package/templates/react-router/app/lib/theme.ts +0 -74
- package/templates/react-router/content/api-overview.mdx +0 -20
- package/templates/react-router/content/assets/local-architecture.svg +0 -22
- package/templates/react-router/content/assets/quick-reference.txt +0 -5
- package/templates/react-router/content/changelog.mdx +0 -38
- package/templates/react-router/content/configuration.mdx +0 -117
- package/templates/react-router/content/deploying.mdx +0 -57
- package/templates/react-router/content/essentials/callouts.mdx +0 -34
- package/templates/react-router/content/essentials/code-blocks.mdx +0 -43
- package/templates/react-router/content/essentials/lists.mdx +0 -36
- package/templates/react-router/content/essentials/tables.mdx +0 -30
- package/templates/react-router/content/essentials/tabs.mdx +0 -40
- package/templates/react-router/content/essentials/text-styling.mdx +0 -43
- package/templates/react-router/content/getting-started.mdx +0 -16
- package/templates/react-router/content/mdx-components.mdx +0 -293
- package/templates/react-router/content/openapi-petstore.json +0 -160
- package/templates/react-router/content/openapi.json +0 -278
- package/templates/react-router/content/quickstart.mdx +0 -60
|
@@ -7,10 +7,14 @@ import { pages as markdownPages } from "virtual:heyo-docs-content/server";
|
|
|
7
7
|
export async function action({ request }: ActionFunctionArgs) {
|
|
8
8
|
if (request.method !== "POST")
|
|
9
9
|
return new Response("Method Not Allowed", {
|
|
10
|
-
headers: { Allow: "POST" },
|
|
11
10
|
status: 405,
|
|
11
|
+
headers: { Allow: "POST" },
|
|
12
12
|
});
|
|
13
|
-
|
|
13
|
+
if (!config.ai?.chat)
|
|
14
|
+
return Response.json(
|
|
15
|
+
{ error: "AI chat is not configured." },
|
|
16
|
+
{ status: 404 },
|
|
17
|
+
);
|
|
14
18
|
const { createAiChatResponse } = await import("@heyo-sh/heyo-docs/ai");
|
|
15
19
|
return createAiChatResponse(request, {
|
|
16
20
|
ai: config.ai,
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
import { DocsApp } from "@heyo-sh/heyo-docs";
|
|
1
2
|
import {
|
|
2
3
|
createDocsModel,
|
|
3
|
-
DocsApp,
|
|
4
4
|
findDocsPage,
|
|
5
5
|
findOpenApiEndpoint,
|
|
6
|
+
} from "@heyo-sh/heyo-docs/model";
|
|
7
|
+
import { changelogGroupForPage } from "@heyo-sh/heyo-docs/navigation";
|
|
8
|
+
import {
|
|
6
9
|
openApiEndpointDataPath,
|
|
7
10
|
openApiEndpointDetail,
|
|
8
|
-
|
|
9
|
-
} from "@heyo-sh/heyo-docs";
|
|
11
|
+
} from "@heyo-sh/heyo-docs/openapi";
|
|
12
|
+
import { docsSeoMeta } from "@heyo-sh/heyo-docs/seo/react-router";
|
|
13
|
+
import type { OpenApiEndpoint } from "@heyo-sh/heyo-docs/types";
|
|
14
|
+
import { useDocsTheme } from "@heyo-sh/heyo-docs/theme/provider";
|
|
10
15
|
import {
|
|
11
16
|
Link,
|
|
12
17
|
useLoaderData,
|
|
@@ -15,9 +20,9 @@ import {
|
|
|
15
20
|
type MetaFunction,
|
|
16
21
|
} from "react-router";
|
|
17
22
|
import { forwardRef, type ComponentPropsWithoutRef } from "react";
|
|
23
|
+
import { __HEYO_THEME_IDENTIFIER__ } from "@heyo-sh/heyo-docs/theme/__HEYO_THEME__";
|
|
18
24
|
|
|
19
25
|
import { iconSet } from "../heyo-docs-icons";
|
|
20
|
-
import { useTheme } from "../components/theme-provider";
|
|
21
26
|
import { config } from "virtual:heyo-docs-config";
|
|
22
27
|
import { pages } from "virtual:heyo-docs-content";
|
|
23
28
|
import { openApiDocuments } from "virtual:heyo-docs-openapi";
|
|
@@ -80,59 +85,16 @@ export const meta: MetaFunction = ({ params }) => {
|
|
|
80
85
|
{ title: `Not found | ${config.title}` },
|
|
81
86
|
{ name: "robots", content: "noindex" },
|
|
82
87
|
];
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
page
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{ name: "description", content: description },
|
|
94
|
-
{ name: "robots", content: "index, follow" },
|
|
95
|
-
{ property: "og:type", content: "article" },
|
|
96
|
-
{ property: "og:site_name", content: config.title },
|
|
97
|
-
{ property: "og:title", content: title },
|
|
98
|
-
{ property: "og:description", content: description },
|
|
99
|
-
{ name: "twitter:card", content: "summary" },
|
|
100
|
-
{ name: "twitter:title", content: title },
|
|
101
|
-
{ name: "twitter:description", content: description },
|
|
102
|
-
...(canonical
|
|
103
|
-
? [
|
|
104
|
-
{ property: "og:url", content: canonical },
|
|
105
|
-
{
|
|
106
|
-
tagName: "link" as const,
|
|
107
|
-
rel: "canonical",
|
|
108
|
-
href: canonical,
|
|
109
|
-
},
|
|
110
|
-
]
|
|
111
|
-
: []),
|
|
112
|
-
{
|
|
113
|
-
"script:ld+json": [
|
|
114
|
-
{
|
|
115
|
-
"@context": "https://schema.org",
|
|
116
|
-
"@type": "WebSite",
|
|
117
|
-
name: config.title,
|
|
118
|
-
description: config.description,
|
|
119
|
-
...(config.siteUrl ? { url: config.siteUrl } : {}),
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
"@context": "https://schema.org",
|
|
123
|
-
"@type": "TechArticle",
|
|
124
|
-
headline: page?.title ?? endpoint!.title,
|
|
125
|
-
description,
|
|
126
|
-
...(canonical ? { url: canonical } : {}),
|
|
127
|
-
isPartOf: {
|
|
128
|
-
"@type": "WebSite",
|
|
129
|
-
name: config.title,
|
|
130
|
-
...(config.siteUrl ? { url: config.siteUrl } : {}),
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
},
|
|
135
|
-
];
|
|
88
|
+
return docsSeoMeta({
|
|
89
|
+
config,
|
|
90
|
+
pathname,
|
|
91
|
+
page,
|
|
92
|
+
endpoint,
|
|
93
|
+
navigation: model.navigation,
|
|
94
|
+
changelogGroup: page
|
|
95
|
+
? changelogGroupForPage(config.groups, page, model.pages)
|
|
96
|
+
: undefined,
|
|
97
|
+
});
|
|
136
98
|
};
|
|
137
99
|
|
|
138
100
|
export default function DocsRoute() {
|
|
@@ -152,7 +114,7 @@ function DocsShell({
|
|
|
152
114
|
currentOpenApiEndpoint?: OpenApiEndpoint;
|
|
153
115
|
pathname: string;
|
|
154
116
|
}) {
|
|
155
|
-
const { mounted, resolvedTheme,
|
|
117
|
+
const { mounted, resolvedTheme, toggleTheme } = useDocsTheme();
|
|
156
118
|
|
|
157
119
|
return (
|
|
158
120
|
<DocsApp
|
|
@@ -164,12 +126,9 @@ function DocsShell({
|
|
|
164
126
|
openApiRequestUrl="/heyo-docs-internal/openapi-request"
|
|
165
127
|
pages={pages}
|
|
166
128
|
pathname={pathname}
|
|
129
|
+
theme={__HEYO_THEME_IDENTIFIER__}
|
|
167
130
|
isDark={mounted ? resolvedTheme === "dark" : undefined}
|
|
168
|
-
onThemeToggle={
|
|
169
|
-
mounted
|
|
170
|
-
? () => setTheme(resolvedTheme === "dark" ? "light" : "dark")
|
|
171
|
-
: undefined
|
|
172
|
-
}
|
|
131
|
+
onThemeToggle={mounted ? toggleTheme : undefined}
|
|
173
132
|
/>
|
|
174
133
|
);
|
|
175
134
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createDocsModel
|
|
1
|
+
import { createDocsModel } from "@heyo-sh/heyo-docs/model";
|
|
2
|
+
import { navigationPages } from "@heyo-sh/heyo-docs/navigation";
|
|
2
3
|
import { redirect } from "react-router";
|
|
3
4
|
|
|
4
5
|
import { config } from "virtual:heyo-docs-config";
|
|
@@ -14,6 +15,10 @@ export function loader() {
|
|
|
14
15
|
status: 404,
|
|
15
16
|
});
|
|
16
17
|
|
|
18
|
+
// `content/index.mdx` is a valid minimal starter. Redirecting `/` to `/`
|
|
19
|
+
// creates an infinite prerender redirect on Workers, so render DocsRoute in
|
|
20
|
+
// place when the first document owns the root path.
|
|
21
|
+
if (firstPage.slug === "/") return {};
|
|
17
22
|
return redirect(firstPage.slug);
|
|
18
23
|
}
|
|
19
24
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
markdownForPage,
|
|
3
|
+
pathnameFromMarkdownPath,
|
|
4
|
+
} from "@heyo-sh/heyo-docs/llm";
|
|
2
5
|
import type { LoaderFunctionArgs } from "react-router";
|
|
3
6
|
|
|
4
7
|
import { pages } from "virtual:heyo-docs-content/server";
|
|
@@ -1,159 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
findOpenApiEndpoint,
|
|
4
|
-
type OpenApiEndpoint,
|
|
5
|
-
} from "@heyo-sh/heyo-docs";
|
|
1
|
+
import { createDocsModel } from "@heyo-sh/heyo-docs/model";
|
|
2
|
+
import { handleOpenApiRequest } from "@heyo-sh/heyo-docs/openapi/request";
|
|
6
3
|
import type { ActionFunctionArgs } from "react-router";
|
|
7
4
|
|
|
8
5
|
import config from "../../heyo-docs.config";
|
|
9
6
|
import { pages } from "virtual:heyo-docs-content";
|
|
10
7
|
import { openApiDocuments } from "virtual:heyo-docs-openapi";
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
server: string;
|
|
9
|
+
export function loader() {
|
|
10
|
+
return new Response("Method Not Allowed", {
|
|
11
|
+
status: 405,
|
|
12
|
+
headers: { Allow: "POST" },
|
|
13
|
+
});
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
/**
|
|
21
|
-
* Sends documented API calls from the server, so browsers do not need the API
|
|
22
|
-
* to expose CORS headers. Targets are limited to servers from the OpenAPI file.
|
|
23
|
-
*/
|
|
24
16
|
export async function action({ request }: ActionFunctionArgs) {
|
|
25
17
|
if (request.method !== "POST")
|
|
26
18
|
return new Response("Method Not Allowed", {
|
|
27
|
-
headers: { Allow: "POST" },
|
|
28
19
|
status: 405,
|
|
20
|
+
headers: { Allow: "POST" },
|
|
29
21
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return new Response("Invalid OpenAPI request.", { status: 400 });
|
|
34
|
-
|
|
35
|
-
const model = createDocsModel(config, pages, openApiDocuments);
|
|
36
|
-
const endpoint = findOpenApiEndpoint(model.endpoints, payload.endpointSlug);
|
|
37
|
-
if (!endpoint) return new Response("Endpoint not found.", { status: 404 });
|
|
38
|
-
if (endpoint.servers.length && !endpoint.servers.includes(payload.server))
|
|
39
|
-
return new Response("API server is not declared in the OpenAPI schema.", {
|
|
40
|
-
status: 400,
|
|
41
|
-
});
|
|
42
|
-
if (!endpoint.servers.length && payload.server)
|
|
43
|
-
return new Response("This endpoint does not declare an API server.", {
|
|
44
|
-
status: 400,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const headers = requestHeaders(
|
|
48
|
-
endpoint,
|
|
49
|
-
payload.parameters,
|
|
50
|
-
payload.bearerToken,
|
|
51
|
-
);
|
|
52
|
-
const url = requestUrl(
|
|
53
|
-
endpoint,
|
|
54
|
-
payload.server,
|
|
55
|
-
payload.parameters,
|
|
56
|
-
request.url,
|
|
22
|
+
return handleOpenApiRequest(
|
|
23
|
+
request,
|
|
24
|
+
createDocsModel(config, pages, openApiDocuments).endpoints,
|
|
57
25
|
);
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
const response = await fetch(url, {
|
|
61
|
-
method: endpoint.method.toUpperCase(),
|
|
62
|
-
headers,
|
|
63
|
-
body: payload.body,
|
|
64
|
-
});
|
|
65
|
-
const responseHeaders = new Headers();
|
|
66
|
-
const contentType = response.headers.get("content-type");
|
|
67
|
-
if (contentType) responseHeaders.set("content-type", contentType);
|
|
68
|
-
const body = [204, 205, 304].includes(response.status)
|
|
69
|
-
? null
|
|
70
|
-
: await response.arrayBuffer();
|
|
71
|
-
return new Response(body, {
|
|
72
|
-
headers: responseHeaders,
|
|
73
|
-
status: response.status,
|
|
74
|
-
statusText: response.statusText,
|
|
75
|
-
});
|
|
76
|
-
} catch {
|
|
77
|
-
return new Response("The API server could not be reached.", {
|
|
78
|
-
status: 502,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function requestPayload(
|
|
84
|
-
request: Request,
|
|
85
|
-
): Promise<OpenApiRequestPayload | undefined> {
|
|
86
|
-
try {
|
|
87
|
-
const value: unknown = await request.json();
|
|
88
|
-
if (!isRecord(value)) return undefined;
|
|
89
|
-
const endpointSlug = stringValue(value.endpointSlug);
|
|
90
|
-
const server = stringValue(value.server);
|
|
91
|
-
if (!endpointSlug || server === undefined) return undefined;
|
|
92
|
-
return {
|
|
93
|
-
bearerToken: stringValue(value.bearerToken) ?? "",
|
|
94
|
-
body: stringValue(value.body),
|
|
95
|
-
endpointSlug,
|
|
96
|
-
parameters: stringRecord(value.parameters),
|
|
97
|
-
server,
|
|
98
|
-
};
|
|
99
|
-
} catch {
|
|
100
|
-
return undefined;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function requestUrl(
|
|
105
|
-
endpoint: OpenApiEndpoint,
|
|
106
|
-
server: string,
|
|
107
|
-
parameters: Record<string, string>,
|
|
108
|
-
requestUrl: string,
|
|
109
|
-
) {
|
|
110
|
-
let path = endpoint.path.replace(/\{([^}]+)\}/g, (match, name: string) => {
|
|
111
|
-
const value = parameters[`path:${name}`];
|
|
112
|
-
return value ? encodeURIComponent(value) : match;
|
|
113
|
-
});
|
|
114
|
-
const query = new URLSearchParams();
|
|
115
|
-
for (const parameter of endpoint.parameters) {
|
|
116
|
-
if (parameter.in !== "query") continue;
|
|
117
|
-
const value = parameters[`query:${parameter.name}`];
|
|
118
|
-
if (value) query.set(parameter.name, value);
|
|
119
|
-
}
|
|
120
|
-
const search = query.toString();
|
|
121
|
-
path = `${path}${search ? `?${search}` : ""}`;
|
|
122
|
-
return server
|
|
123
|
-
? `${server.replace(/\/$/, "")}${path}`
|
|
124
|
-
: new URL(path, requestUrl).toString();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function requestHeaders(
|
|
128
|
-
endpoint: OpenApiEndpoint,
|
|
129
|
-
parameters: Record<string, string>,
|
|
130
|
-
bearerToken: string,
|
|
131
|
-
) {
|
|
132
|
-
const headers = new Headers();
|
|
133
|
-
for (const parameter of endpoint.parameters) {
|
|
134
|
-
if (parameter.in !== "header") continue;
|
|
135
|
-
const value = parameters[`header:${parameter.name}`];
|
|
136
|
-
if (value) headers.set(parameter.name, value);
|
|
137
|
-
}
|
|
138
|
-
if (endpoint.requestBody?.contentType)
|
|
139
|
-
headers.set("Content-Type", endpoint.requestBody.contentType);
|
|
140
|
-
if (bearerToken) headers.set("Authorization", `Bearer ${bearerToken}`);
|
|
141
|
-
return headers;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
145
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function stringRecord(value: unknown): Record<string, string> {
|
|
149
|
-
if (!isRecord(value)) return {};
|
|
150
|
-
return Object.fromEntries(
|
|
151
|
-
Object.entries(value).filter(
|
|
152
|
-
(entry): entry is [string, string] => typeof entry[1] === "string",
|
|
153
|
-
),
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function stringValue(value: unknown): string | undefined {
|
|
158
|
-
return typeof value === "string" ? value : undefined;
|
|
159
26
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createDocsModel
|
|
1
|
+
import { createDocsModel } from "@heyo-sh/heyo-docs/model";
|
|
2
|
+
import { sitemapPaths, sitemapXml } from "@heyo-sh/heyo-docs/seo";
|
|
2
3
|
import type { Route } from "./+types/sitemap";
|
|
3
4
|
|
|
4
5
|
import config from "../../heyo-docs.config";
|
|
@@ -8,11 +9,7 @@ import { openApiDocuments } from "virtual:heyo-docs-openapi";
|
|
|
8
9
|
export function loader({ request }: Route.LoaderArgs) {
|
|
9
10
|
const siteUrl = config.siteUrl ?? new URL(request.url).origin;
|
|
10
11
|
const model = createDocsModel(config, pages, openApiDocuments);
|
|
11
|
-
return new Response(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
[...model.pages, ...model.endpoints].map((page) => page.slug),
|
|
15
|
-
),
|
|
16
|
-
{ headers: { "content-type": "application/xml; charset=utf-8" } },
|
|
17
|
-
);
|
|
12
|
+
return new Response(sitemapXml(siteUrl, sitemapPaths(model)), {
|
|
13
|
+
headers: { "content-type": "application/xml; charset=utf-8" },
|
|
14
|
+
});
|
|
18
15
|
}
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
declare module "virtual:heyo-docs-content" {
|
|
2
|
-
import type { DocsPage } from "@heyo-sh/heyo-docs";
|
|
2
|
+
import type { DocsPage } from "@heyo-sh/heyo-docs/types";
|
|
3
3
|
export const pages: DocsPage[];
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
declare module "virtual:heyo-docs-config" {
|
|
7
|
-
import type { HeyoDocsConfig } from "@heyo-sh/heyo-docs";
|
|
7
|
+
import type { HeyoDocsConfig } from "@heyo-sh/heyo-docs/types";
|
|
8
8
|
export const config: HeyoDocsConfig;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
declare module "virtual:heyo-docs-theme.css";
|
|
12
12
|
|
|
13
13
|
declare module "virtual:heyo-docs-content/server" {
|
|
14
|
-
import type { MarkdownPage } from "@heyo-sh/heyo-docs";
|
|
14
|
+
import type { MarkdownPage } from "@heyo-sh/heyo-docs/types";
|
|
15
15
|
export const pages: MarkdownPage[];
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
declare module "virtual:heyo-docs-openapi" {
|
|
19
|
-
import type { OpenApiDocumentSource } from "@heyo-sh/heyo-docs";
|
|
19
|
+
import type { OpenApiDocumentSource } from "@heyo-sh/heyo-docs/types";
|
|
20
20
|
export const openApiDocuments: OpenApiDocumentSource[];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
declare module "virtual:heyo-docs-openapi/index" {
|
|
24
|
-
import type { OpenApiEndpoint } from "@heyo-sh/heyo-docs";
|
|
24
|
+
import type { OpenApiEndpoint } from "@heyo-sh/heyo-docs/types";
|
|
25
25
|
export const openApiEndpoints: OpenApiEndpoint[];
|
|
26
26
|
}
|
|
@@ -1,56 +1,12 @@
|
|
|
1
|
-
import { heyoDocs } from "@heyo-sh/heyo-docs";
|
|
1
|
+
import { heyoDocs } from "@heyo-sh/heyo-docs/config";
|
|
2
2
|
|
|
3
3
|
export default heyoDocs({
|
|
4
4
|
title: "{{PROJECT_NAME}}",
|
|
5
5
|
description: "Developer documentation",
|
|
6
|
-
content: "./content",
|
|
7
6
|
theme: "{{THEME}}",
|
|
8
|
-
mode: "system",
|
|
9
|
-
groups: [
|
|
10
|
-
{
|
|
11
|
-
group: "Documentation",
|
|
12
|
-
icon: "globe",
|
|
13
|
-
sections: [
|
|
14
|
-
{
|
|
15
|
-
section: "Get Started",
|
|
16
|
-
icon: "lightbulb",
|
|
17
|
-
pages: ["quickstart", "configuration", "deploying"],
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
section: "Essentials",
|
|
21
|
-
icon: "book",
|
|
22
|
-
pages: [
|
|
23
|
-
"essentials/text-styling",
|
|
24
|
-
"essentials/code-blocks",
|
|
25
|
-
"essentials/callouts",
|
|
26
|
-
"essentials/tabs",
|
|
27
|
-
"essentials/lists",
|
|
28
|
-
"essentials/tables",
|
|
29
|
-
],
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
group: "OpenAPI",
|
|
35
|
-
icon: "code",
|
|
36
|
-
sections: [
|
|
37
|
-
{
|
|
38
|
-
pages: ["api-overview"],
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
schema: "./openapi.json",
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
group: "Changelog",
|
|
47
|
-
description: "Mock release notes for the Heyo Docs demo.",
|
|
48
|
-
icon: "changelog",
|
|
49
|
-
type: "changelog",
|
|
50
|
-
updates: ["changelog"],
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
7
|
branding: { name: "{{PROJECT_NAME}}", logo: "/logo.svg" },
|
|
54
|
-
// Set this before deploying to publish canonical and
|
|
8
|
+
// Set this before deploying to publish canonical, sitemap, and social URLs.
|
|
55
9
|
// siteUrl: "https://docs.example.com",
|
|
10
|
+
// Add analytics, consent, and support integrations here when you need them.
|
|
11
|
+
// integrations: { analytics: { ga4: { measurementId: "G-..." } } },
|
|
56
12
|
});
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: API overview
|
|
3
|
-
description: Learn how to authenticate and explore the API reference.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# API overview
|
|
7
|
-
|
|
8
|
-
The API reference is generated from `openapi.json`. Use the endpoint pages to
|
|
9
|
-
enter parameters, send a request, and copy a cURL or JavaScript example.
|
|
10
|
-
|
|
11
|
-
## Authentication
|
|
12
|
-
|
|
13
|
-
The example API uses a Bearer token. Enter it once on any protected endpoint;
|
|
14
|
-
Heyo Docs keeps it in this browser while you move between API pages.
|
|
15
|
-
|
|
16
|
-
## Custom pages first
|
|
17
|
-
|
|
18
|
-
This ordinary MDX page belongs to the OpenAPI group. Its section is configured
|
|
19
|
-
before the generated endpoint sections, so it always appears at the top of the
|
|
20
|
-
sidebar.
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="360" viewBox="0 0 960 360" fill="none">
|
|
2
|
-
<rect width="960" height="360" rx="24" fill="#F7F7F8"/>
|
|
3
|
-
<g fill="#FFFFFF" stroke="#D4D4D8" stroke-width="2">
|
|
4
|
-
<rect x="72" y="108" width="220" height="144" rx="18"/>
|
|
5
|
-
<rect x="370" y="108" width="220" height="144" rx="18"/>
|
|
6
|
-
<rect x="668" y="108" width="220" height="144" rx="18"/>
|
|
7
|
-
</g>
|
|
8
|
-
<g fill="#18181B" font-family="Arial, sans-serif" text-anchor="middle">
|
|
9
|
-
<text x="182" y="166" font-size="17" font-weight="700">Content</text>
|
|
10
|
-
<text x="182" y="194" font-size="14" fill="#71717A">MDX and assets</text>
|
|
11
|
-
<text x="480" y="166" font-size="17" font-weight="700">Build</text>
|
|
12
|
-
<text x="480" y="194" font-size="14" fill="#71717A">Vite bundles files</text>
|
|
13
|
-
<text x="778" y="166" font-size="17" font-weight="700">Documentation</text>
|
|
14
|
-
<text x="778" y="194" font-size="14" fill="#71717A">Static output</text>
|
|
15
|
-
</g>
|
|
16
|
-
<g stroke="#71717A" stroke-linecap="round" stroke-width="2">
|
|
17
|
-
<path d="M314 180h34"/>
|
|
18
|
-
<path d="m340 172 8 8-8 8"/>
|
|
19
|
-
<path d="M612 180h34"/>
|
|
20
|
-
<path d="m638 172 8 8-8 8"/>
|
|
21
|
-
</g>
|
|
22
|
-
</svg>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Changelog
|
|
3
|
-
description: Mock release notes for the Heyo Docs example.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Changelog
|
|
7
|
-
|
|
8
|
-
<Update label="April 2026" tags={["New", "Documentation"]}>
|
|
9
|
-
|
|
10
|
-
## Starter documentation
|
|
11
|
-
|
|
12
|
-
New projects and runnable examples now include a structured Quickstart, basic
|
|
13
|
-
configuration guide, deployment overview, and essential writing patterns.
|
|
14
|
-
|
|
15
|
-
## Square API group
|
|
16
|
-
|
|
17
|
-
The example navigation now keeps the pinned Square OpenAPI schema in its own
|
|
18
|
-
group, making large-schema behaviour easy to inspect.
|
|
19
|
-
|
|
20
|
-
</Update>
|
|
21
|
-
|
|
22
|
-
<Update label="March 2026" tags={["Improved", "Developer experience"]}>
|
|
23
|
-
|
|
24
|
-
## Clearer navigation
|
|
25
|
-
|
|
26
|
-
External documentation links can display an icon, and sidebar groups now keep
|
|
27
|
-
onboarding, API reference, and release notes separate.
|
|
28
|
-
|
|
29
|
-
</Update>
|
|
30
|
-
|
|
31
|
-
<Update label="February 2026" tags={["Fixed"]}>
|
|
32
|
-
|
|
33
|
-
## More predictable previews
|
|
34
|
-
|
|
35
|
-
Preview builds now validate configured routes before mock release notes are
|
|
36
|
-
published.
|
|
37
|
-
|
|
38
|
-
</Update>
|