@lukoweb/apitogo 0.2.60 → 0.2.64
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/dist/cli/cli.js +1101 -589
- package/dist/declarations/cli/platform/client/platform-api.d.ts +3 -0
- package/dist/declarations/cli/platform/errors.d.ts +5 -0
- package/docs/cli/commands.md +6 -6
- package/docs/cli/go-live.md +12 -12
- package/docs/cli/overview.md +26 -27
- package/docs/cli/setup.md +38 -46
- package/docs/cli/shape.md +32 -35
- package/docs/cli/walkthrough.md +19 -19
- package/docs/components/slot.mdx +116 -116
- package/docs/configuration/api-reference.md +1 -1
- package/docs/configuration/authentication.md +3 -3
- package/docs/configuration/footer.mdx +89 -89
- package/docs/configuration/gateway.md +8 -8
- package/docs/configuration/make-config.mdx +20 -10
- package/docs/configuration/overview.md +3 -3
- package/docs/configuration/plans.md +5 -5
- package/docs/configuration/portal.md +36 -0
- package/docs/customization/colors-theme.mdx +255 -255
- package/docs/customization/fonts.md +105 -105
- package/docs/customization/landing-page.md +1 -1
- package/docs/deploy/apitogo.md +3 -3
- package/docs/deployment.md +3 -3
- package/docs/guides/custom-pages.md +3 -3
- package/docs/guides/customer-account.md +1 -1
- package/docs/guides/stripe-setup.mdx +9 -9
- package/docs/markdown/frontmatter.md +2 -2
- package/docs/mcp/go-live.md +7 -7
- package/docs/mcp/overview.md +58 -58
- package/docs/mcp/setup.md +20 -15
- package/docs/mcp/shape.md +2 -2
- package/docs/mcp/tools.md +57 -57
- package/docs/quickstart.md +6 -4
- package/docs/writing.mdx +68 -68
- package/package.json +1 -1
- package/src/config/apitogo-config-core.ts +11 -1
- package/src/config/v2/home-redirect.ts +5 -5
- package/src/config/v2/index.ts +5 -1
- package/src/config/v2/portal-profile.ts +17 -0
- package/src/config/v2/resolve.ts +19 -0
- package/src/config/v2/rules.ts +124 -0
- package/src/config/v2/schema.ts +28 -0
- package/src/config/v2/wrapper.ts +76 -13
- package/src/vite/config.ts +278 -273
- package/src/vite/markdown-output-path.ts +48 -0
- package/src/vite/plugin-markdown-export.ts +210 -214
- package/src/vite/prerender/prerender.ts +4 -4
- package/src/vite/watch-ignore.ts +19 -0
package/src/config/v2/wrapper.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./manifest.js";
|
|
25
25
|
import { type PortalProfile, portalProfile } from "./portal-profile.js";
|
|
26
26
|
import { protectedRoutesFor } from "./protected-routes.js";
|
|
27
|
-
import { isLogoUrl, type ResolvedConfigV2 } from "./resolve.js";
|
|
27
|
+
import { isLogoUrl, type ResolvedConfigV2, toGlobPath } from "./resolve.js";
|
|
28
28
|
import { findTsxPages, TSX_PAGE_ELEMENT_PREFIX } from "./tsx-pages.js";
|
|
29
29
|
|
|
30
30
|
export const WRAPPER_FILE = "apitogo.config.tsx";
|
|
@@ -322,6 +322,29 @@ export const REFERENCE_SPEC_FILE = "openapi/gateway.json";
|
|
|
322
322
|
/** Route of the API reference page. */
|
|
323
323
|
export const API_REFERENCE_PATH = "api";
|
|
324
324
|
|
|
325
|
+
const MARKDOWN_PAGE = /\.mdx?$/i;
|
|
326
|
+
|
|
327
|
+
/** Placeholder of a React header page in the site config; the wrapper puts the component in its place. */
|
|
328
|
+
export const HEADER_PAGE_ELEMENT_PREFIX = "apitogo:header-page:";
|
|
329
|
+
|
|
330
|
+
/** The React header pages (`portal.header.links[].page` ending in `.tsx`), each with its wrapper placeholder. */
|
|
331
|
+
export function headerTsxPages(
|
|
332
|
+
resolved: ResolvedConfigV2,
|
|
333
|
+
plan: PortalPlan,
|
|
334
|
+
): { id: string; route: string; label: string; file: string }[] {
|
|
335
|
+
if (!plan.docs) return [];
|
|
336
|
+
return (resolved.portal?.headerLinks ?? [])
|
|
337
|
+
.flatMap((link) =>
|
|
338
|
+
link.page && /\.tsx$/i.test(link.page)
|
|
339
|
+
? [{ route: link.to, label: link.label, file: link.page }]
|
|
340
|
+
: [],
|
|
341
|
+
)
|
|
342
|
+
.map((page, index) => ({
|
|
343
|
+
...page,
|
|
344
|
+
id: `${HEADER_PAGE_ELEMENT_PREFIX}${index}`,
|
|
345
|
+
}));
|
|
346
|
+
}
|
|
347
|
+
|
|
325
348
|
/**
|
|
326
349
|
* The site settings (title, modules, docs globs, theme, sign-in) in the shape the existing build reads from
|
|
327
350
|
* `apitogo.config.json`. It is generated, never edited, and lives in `generated/`.
|
|
@@ -342,9 +365,31 @@ export function buildSiteConfig(
|
|
|
342
365
|
): Record<string, unknown> {
|
|
343
366
|
const portal = resolved.portal;
|
|
344
367
|
const redirects = extras.redirects ?? [];
|
|
368
|
+
// Header pages are pages the sidebar leaves out. A Markdown one is served by the docs plugin from its own file; a React
|
|
369
|
+
// one is a hidden custom page, whose placeholder the wrapper replaces with the component. Both need hosted docs.
|
|
370
|
+
const headerLinks = portal?.headerLinks ?? [];
|
|
371
|
+
const headerPages = plan.docs
|
|
372
|
+
? headerLinks.flatMap((link) =>
|
|
373
|
+
link.page && MARKDOWN_PAGE.test(link.page) ? [link.page] : [],
|
|
374
|
+
)
|
|
375
|
+
: [];
|
|
376
|
+
const shownHeaderLinks = headerLinks
|
|
377
|
+
.filter((link) => !link.page || plan.docs)
|
|
378
|
+
.map((link) => ({
|
|
379
|
+
label: link.label,
|
|
380
|
+
to: link.to,
|
|
381
|
+
...(link.to.startsWith("https://") ? { target: "_blank" } : {}),
|
|
382
|
+
}));
|
|
345
383
|
// One header tab for the docs sidebar, and the API reference as a link next to it.
|
|
346
384
|
const navigation = [
|
|
347
385
|
...(extras.docsNavigation ?? []),
|
|
386
|
+
...headerTsxPages(resolved, plan).map((page) => ({
|
|
387
|
+
type: "custom-page",
|
|
388
|
+
path: page.route,
|
|
389
|
+
label: page.label,
|
|
390
|
+
element: page.id,
|
|
391
|
+
display: "hide",
|
|
392
|
+
})),
|
|
348
393
|
...(plan.apiReference
|
|
349
394
|
? [
|
|
350
395
|
{
|
|
@@ -392,9 +437,10 @@ export function buildSiteConfig(
|
|
|
392
437
|
...(plan.docs
|
|
393
438
|
? {
|
|
394
439
|
docs: {
|
|
395
|
-
files:
|
|
396
|
-
|
|
397
|
-
|
|
440
|
+
files: [
|
|
441
|
+
...(portal?.docs.content ?? []),
|
|
442
|
+
...headerPages.map(toGlobPath),
|
|
443
|
+
].map((glob) => contentGlob(resolved.configDir, glob)),
|
|
398
444
|
},
|
|
399
445
|
}
|
|
400
446
|
: {}),
|
|
@@ -412,15 +458,18 @@ export function buildSiteConfig(
|
|
|
412
458
|
: {}),
|
|
413
459
|
...(navigation.length > 0 ? { navigation } : {}),
|
|
414
460
|
// The sidebar link above is only seen inside the docs; the header is what every page shows. A header navigation
|
|
415
|
-
// replaces the docs tab, so the docs get a header link of their own.
|
|
416
|
-
...(plan.apiReference
|
|
461
|
+
// replaces the docs tab, so the docs get a header link of their own. The tenant's own links (portal.header) follow.
|
|
462
|
+
...(plan.apiReference || shownHeaderLinks.length > 0
|
|
417
463
|
? {
|
|
418
464
|
header: {
|
|
419
465
|
navigation: [
|
|
420
466
|
...(plan.docs && extras.docsPath
|
|
421
467
|
? [{ label: "Documentation", to: extras.docsPath }]
|
|
422
468
|
: []),
|
|
423
|
-
|
|
469
|
+
...(plan.apiReference
|
|
470
|
+
? [{ label: "API Reference", to: `/${API_REFERENCE_PATH}` }]
|
|
471
|
+
: []),
|
|
472
|
+
...shownHeaderLinks,
|
|
424
473
|
],
|
|
425
474
|
},
|
|
426
475
|
}
|
|
@@ -764,13 +813,19 @@ export async function preparePortal(
|
|
|
764
813
|
(page) => !markdownRoutes.includes(page.route),
|
|
765
814
|
)
|
|
766
815
|
: [];
|
|
816
|
+
const importPathOf = (file: string) =>
|
|
817
|
+
`./${CONTENT_LINK}/${path
|
|
818
|
+
.relative(resolved.configDir, file)
|
|
819
|
+
.split(path.sep)
|
|
820
|
+
.join("/")}`;
|
|
767
821
|
const wrapperPages: WrapperPage[] = tsxPages.map((page, index) => ({
|
|
768
822
|
id: `${TSX_PAGE_ELEMENT_PREFIX}${index}`,
|
|
769
|
-
importPath:
|
|
770
|
-
.relative(resolved.configDir, page.file)
|
|
771
|
-
.split(path.sep)
|
|
772
|
-
.join("/")}`,
|
|
823
|
+
importPath: importPathOf(page.file),
|
|
773
824
|
}));
|
|
825
|
+
// React header pages are imported the same way; their placeholders are in the navigation, outside the sidebar.
|
|
826
|
+
const headerWrapperPages: WrapperPage[] = headerTsxPages(resolved, plan).map(
|
|
827
|
+
(page) => ({ id: page.id, importPath: importPathOf(page.file) }),
|
|
828
|
+
);
|
|
774
829
|
const hostedDocRoutes = [
|
|
775
830
|
...new Set([...markdownRoutes, ...tsxPages.map((page) => page.route)]),
|
|
776
831
|
].sort();
|
|
@@ -872,7 +927,15 @@ export async function preparePortal(
|
|
|
872
927
|
protectedRoutes: protectedRoutesFor({
|
|
873
928
|
requireAuth: resolved.portal?.requireAuth,
|
|
874
929
|
hasAuth: !!plan.auth,
|
|
875
|
-
|
|
930
|
+
// A header page is a docs page too, so a portal behind login keeps it behind login.
|
|
931
|
+
docRoutes: plan.docs
|
|
932
|
+
? [
|
|
933
|
+
...hostedDocRoutes,
|
|
934
|
+
...(resolved.portal?.headerLinks ?? []).flatMap((link) =>
|
|
935
|
+
link.page ? [link.to] : [],
|
|
936
|
+
),
|
|
937
|
+
]
|
|
938
|
+
: hostedDocRoutes,
|
|
876
939
|
apiReferencePath: plan.apiReference
|
|
877
940
|
? `/${API_REFERENCE_PATH}`
|
|
878
941
|
: undefined,
|
|
@@ -881,7 +944,7 @@ export async function preparePortal(
|
|
|
881
944
|
);
|
|
882
945
|
const wrapper = renderWrapper(
|
|
883
946
|
plan,
|
|
884
|
-
wrapperPages,
|
|
947
|
+
[...wrapperPages, ...headerWrapperPages],
|
|
885
948
|
resolved.portal?.footer
|
|
886
949
|
? wrapperImport(contentFile(resolved.configDir, resolved.portal.footer))
|
|
887
950
|
: undefined,
|