@blaaiz/docs-core 0.5.0 → 0.7.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.
Files changed (46) hide show
  1. package/dist/{chunk-ZKOOKLZ3.js → chunk-6H6OB7YP.js} +17 -2
  2. package/dist/chunk-6H6OB7YP.js.map +1 -0
  3. package/dist/{chunk-ZWDLAW5M.js → chunk-L4PFRXIK.js} +231 -28
  4. package/dist/chunk-L4PFRXIK.js.map +1 -0
  5. package/dist/generator.cjs +161 -18
  6. package/dist/generator.cjs.map +1 -1
  7. package/dist/generator.d.cts +24 -0
  8. package/dist/generator.d.ts +24 -0
  9. package/dist/generator.js +140 -13
  10. package/dist/generator.js.map +1 -1
  11. package/dist/index.cjs +233 -25
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +258 -7
  14. package/dist/index.d.ts +258 -7
  15. package/dist/index.js +1 -1
  16. package/dist/{navigation-CGqFIPlP.d.cts → navigation-DvgyWSZ4.d.cts} +22 -1
  17. package/dist/{navigation-CGqFIPlP.d.ts → navigation-DvgyWSZ4.d.ts} +22 -1
  18. package/dist/ui/api-try-it.cjs +19 -1
  19. package/dist/ui/api-try-it.cjs.map +1 -1
  20. package/dist/ui/api-try-it.d.cts +4 -2
  21. package/dist/ui/api-try-it.d.ts +4 -2
  22. package/dist/ui/api-try-it.js +5 -2
  23. package/dist/ui/api-try-it.js.map +1 -1
  24. package/dist/ui/ask-ai.cjs +26 -6
  25. package/dist/ui/ask-ai.cjs.map +1 -1
  26. package/dist/ui/ask-ai.d.cts +6 -1
  27. package/dist/ui/ask-ai.d.ts +6 -1
  28. package/dist/ui/ask-ai.js +26 -6
  29. package/dist/ui/ask-ai.js.map +1 -1
  30. package/dist/ui/copy-page.cjs +15 -0
  31. package/dist/ui/copy-page.cjs.map +1 -1
  32. package/dist/ui/copy-page.js +1 -1
  33. package/dist/ui.cjs +77 -6
  34. package/dist/ui.cjs.map +1 -1
  35. package/dist/ui.d.cts +99 -8
  36. package/dist/ui.d.ts +99 -8
  37. package/dist/ui.js +62 -8
  38. package/dist/ui.js.map +1 -1
  39. package/package.json +1 -1
  40. package/skills/SKILL.md +68 -27
  41. package/styles/api-reference.css +45 -2
  42. package/styles/ask-ai.css +28 -0
  43. package/styles/docs.css +96 -1
  44. package/styles/home.css +34 -1
  45. package/dist/chunk-ZKOOKLZ3.js.map +0 -1
  46. package/dist/chunk-ZWDLAW5M.js.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AiConfig, T as ThemeConfig, D as DocsConfig, N as Navigation } from './navigation-CGqFIPlP.cjs';
2
- export { a as AI_PROVIDER_MODELS, b as AI_PROVIDER_NAMES, c as AiConfigError, d as AiProviderModels, e as AiProviderName, f as AuthConfig, g as DocPage, h as DocsConfigError, F as FeaturesConfig, G as GoogleProviderConfig, i as NavGroup, j as NavItem, k as NavMethod, l as NavPage, m as NavTab, O as OpenApiPage, P as ProxyConfig, R as ResolvedAiConfig, S as SecretProviderConfig, n as SeoConfig, o as ThemeLogo, p as ThemePalette, W as WorkspaceAuthConfig, q as WorkspaceProviders, r as defineDocsConfig, s as resolveAiConfig, v as validateDocsConfig } from './navigation-CGqFIPlP.cjs';
1
+ import { A as AiConfig, T as ThemeConfig, D as DocsConfig, N as Navigation } from './navigation-DvgyWSZ4.cjs';
2
+ export { a as AI_PROVIDER_MODELS, b as AI_PROVIDER_NAMES, c as AiConfigError, d as AiProviderModels, e as AiProviderName, f as AuthConfig, g as DocPage, h as DocsConfigError, F as FeaturesConfig, G as GoogleProviderConfig, i as NavGroup, j as NavItem, k as NavMethod, l as NavPage, m as NavTab, O as OpenApiPage, P as ProxyConfig, R as ResolvedAiConfig, S as SecretProviderConfig, n as SeoConfig, o as ThemeLogo, p as ThemePalette, W as WorkspaceAuthConfig, q as WorkspaceProviders, r as defineDocsConfig, s as resolveAiConfig, v as validateDocsConfig } from './navigation-DvgyWSZ4.cjs';
3
3
  import { b as OpenApiDocument, O as OpenApiInfo, a as OpenApiServer } from './openapi-types-CJ6p5Cux.cjs';
4
4
  export { c as OpenApiComponents, d as OpenApiOperation, e as OpenApiPathItem, f as OpenApiTag } from './openapi-types-CJ6p5Cux.cjs';
5
5
 
@@ -275,7 +275,9 @@ declare function searchIndex(index: SearchIndex, query: string, limit?: number):
275
275
  * - **Configuration is resolved eagerly.** {@link createAskAiRoute} validates
276
276
  * the `ai` block when the route is built, so a typo in `docs.config.ts` fails
277
277
  * the build. Deferring it to the first request would turn a site's typo into a
278
- * reader's error message.
278
+ * reader's error message. A site with no `ai` block at all is different from
279
+ * a typo: the route mounts dormant and answers `404`, so a scaffold ships the
280
+ * file and enabling Ask AI is a config change, not a code change.
279
281
  * - **The API key is read lazily, per request.** An edge runtime binds its
280
282
  * environment per invocation, not at module load, so the key is looked up when
281
283
  * it is needed. It is never logged; a missing key is reported by env var name.
@@ -301,8 +303,12 @@ type AskAiDocumentsSource = readonly SearchDocument[] | (() => Promise<readonly
301
303
  * @public
302
304
  */
303
305
  interface AskAiRouteOptions {
304
- /** The site's raw `ai` block. Validated when the route is built. */
305
- readonly config: AiConfig;
306
+ /**
307
+ * The site's raw `ai` block. Validated when the route is built. `undefined`
308
+ * (the config declares no `ai` block) mounts the route dormant: every
309
+ * request answers `404`.
310
+ */
311
+ readonly config: AiConfig | undefined;
306
312
  /** Display name used in the system prompt, normally `theme.name`. */
307
313
  readonly siteName: string;
308
314
  /**
@@ -397,6 +403,152 @@ declare function createAskAiRoute(options: AskAiRouteOptions): AskAiRoute;
397
403
  */
398
404
  declare function buildThemeCss(theme: ThemeConfig): string;
399
405
 
406
+ /**
407
+ * Permanent redirects for renamed pages. The generator writes
408
+ * `content/redirects.json` (old page URL to current) whenever an operation's
409
+ * URL changes; the site's middleware serves `308`s from it, so an edited
410
+ * summary is a rename with a forwarding address, never a dead link.
411
+ *
412
+ * @packageDocumentation
413
+ */
414
+ /**
415
+ * The URL a renamed page's request should be redirected to, or `null` when
416
+ * the request matches no entry. The `.md` form of a renamed page redirects to
417
+ * the `.md` form of its new address.
418
+ *
419
+ * @example
420
+ * ```ts
421
+ * const redirected = redirectTarget(request.nextUrl, redirects);
422
+ * if (redirected) {
423
+ * return NextResponse.redirect(redirected, 308);
424
+ * }
425
+ * ```
426
+ *
427
+ * @param url - the request URL
428
+ * @param redirects - the parsed `content/redirects.json`
429
+ * @returns the redirect target, or `null`
430
+ * @public
431
+ */
432
+ declare function redirectTarget(url: URL, redirects: Readonly<Record<string, string>>): URL | null;
433
+
434
+ /**
435
+ * The site's `/llms.txt`: a Markdown index of every page, the entry point
436
+ * agents fetch first. Each entry links the page's `.md` address.
437
+ *
438
+ * @packageDocumentation
439
+ */
440
+ /**
441
+ * One page of the documentation index.
442
+ *
443
+ * @public
444
+ */
445
+ interface LlmsTxtPage {
446
+ readonly title: string;
447
+ /** The page URL (e.g. `/docs/guides/webhooks`); `.md` is appended. */
448
+ readonly url: string;
449
+ readonly description?: string;
450
+ }
451
+ /**
452
+ * Options for {@link buildLlmsTxt}.
453
+ *
454
+ * @public
455
+ */
456
+ interface BuildLlmsTxtOptions {
457
+ /** The site name, the index's `#` heading. */
458
+ readonly name: string;
459
+ /** One sentence on what the site documents. */
460
+ readonly description?: string;
461
+ /** Absolute origin to prefix every link with (e.g. `https://docs.example.com`). */
462
+ readonly origin?: string;
463
+ }
464
+ /**
465
+ * Build the `/llms.txt` document from the site's pages.
466
+ *
467
+ * @example
468
+ * ```ts
469
+ * // app/llms.txt/route.ts
470
+ * export function GET() {
471
+ * const body = buildLlmsTxt(pages, { name: config.theme.name });
472
+ * return new Response(body, { headers: { 'content-type': 'text/plain; charset=utf-8' } });
473
+ * }
474
+ * ```
475
+ *
476
+ * @param pages - the site's pages, in navigation order
477
+ * @param options - the site name, description, and link origin
478
+ * @returns the document text
479
+ * @public
480
+ */
481
+ declare function buildLlmsTxt(pages: readonly LlmsTxtPage[], options: BuildLlmsTxtOptions): string;
482
+
483
+ /**
484
+ * Code-sample generators for the API reference's usage panel.
485
+ *
486
+ * `fumadocs-openapi` renders one sample per registered generator; a site
487
+ * replaces a built-in one by adding a generator under the same id. The shapes
488
+ * here are structural, so this module needs no fumadocs types.
489
+ *
490
+ * @packageDocumentation
491
+ */
492
+ /**
493
+ * One resolved request parameter, as the usage panel passes it.
494
+ *
495
+ * @public
496
+ */
497
+ interface CodeUsageValue {
498
+ /** The parameter's example value. */
499
+ readonly value: string;
500
+ }
501
+ /**
502
+ * The resolved example request a code-sample generator receives.
503
+ *
504
+ * @public
505
+ */
506
+ interface CodeUsageRequest {
507
+ /** The HTTP method. */
508
+ readonly method: string;
509
+ /** The full request URL, path and query resolved. */
510
+ readonly url: string;
511
+ /** Header name to example value. */
512
+ readonly header?: Readonly<Record<string, CodeUsageValue>>;
513
+ /** Cookie name to example value. */
514
+ readonly cookie?: Readonly<Record<string, CodeUsageValue>>;
515
+ /** The example request body, when the operation takes one. */
516
+ readonly body?: unknown;
517
+ /** The body's media type, when the operation takes a body. */
518
+ readonly bodyMediaType?: string;
519
+ }
520
+ /**
521
+ * A code-sample generator, shaped for fumadocs-openapi's code-usage registry.
522
+ *
523
+ * @public
524
+ */
525
+ interface CodeUsageGenerator {
526
+ /** The tab label readers see. */
527
+ readonly label: string;
528
+ /** The sample's syntax-highlighting language. */
529
+ readonly lang: string;
530
+ /** Render the sample for one resolved example request. */
531
+ generate(data: CodeUsageRequest): string;
532
+ }
533
+ /**
534
+ * A cURL sample in long-form flags: `--request`, `--url`, `--header`,
535
+ * `--data`. Register it over the built-in `curl` entry:
536
+ *
537
+ * @example
538
+ * ```ts
539
+ * import { curlCodeUsage } from '@blaaiz/docs-core';
540
+ * import { createCodeUsageGeneratorRegistry } from 'fumadocs-openapi/requests/generators';
541
+ * import { registerDefault } from 'fumadocs-openapi/requests/generators/all';
542
+ *
543
+ * const codeUsages = registerDefault(createCodeUsageGeneratorRegistry());
544
+ * codeUsages.add('curl', curlCodeUsage);
545
+ * createOpenAPI({ input, codeUsages });
546
+ * ```
547
+ *
548
+ * @public
549
+ */
550
+ declare const curlCodeUsage: CodeUsageGenerator;
551
+
400
552
  /**
401
553
  * SEO metadata, derived from {@link DocsConfig}.
402
554
  *
@@ -628,6 +780,8 @@ interface PlannedGroupChild {
628
780
  readonly order: number;
629
781
  /** The child folder's name within the group directory. */
630
782
  readonly folder: string;
783
+ /** The child group's title, for the heading the `headings` style renders. */
784
+ readonly title: string;
631
785
  }
632
786
  /**
633
787
  * A planned API group folder. The generator fills its page order once the
@@ -688,6 +842,17 @@ interface DocsTreePlan {
688
842
  */
689
843
  readonly apiDocLinks: readonly PlannedApiDocLink[];
690
844
  }
845
+ /**
846
+ * How the sidebar presents a tab's top-level groups.
847
+ *
848
+ * - `collapsible`: every group is a collapsible folder (the fumadocs default).
849
+ * - `headings`: a top-level group is a flat, always-open section heading with
850
+ * its pages listed beneath it; only nested groups collapse, and they start
851
+ * closed. The Mintlify presentation.
852
+ *
853
+ * @public
854
+ */
855
+ type SidebarStyle = 'collapsible' | 'headings';
691
856
  /**
692
857
  * Options for {@link planDocsTree}.
693
858
  *
@@ -696,6 +861,8 @@ interface DocsTreePlan {
696
861
  interface PlanDocsTreeOptions {
697
862
  /** Folder for generated API pages when one tab publishes them. Default `api`. */
698
863
  readonly apiDir?: string;
864
+ /** The sidebar's group presentation. Default `collapsible`. */
865
+ readonly sidebar?: SidebarStyle;
699
866
  }
700
867
  /**
701
868
  * Plan the content tree for a navigation.
@@ -710,9 +877,11 @@ interface PlanDocsTreeOptions {
710
877
  * - Root-level doc pages (no `/` in the path) are listed in the root meta.
711
878
  * - Tab folders get `root: true`, so the sidebar scopes to the active tab.
712
879
  * - Sidebar order is declaration order, pages and groups interleaved.
880
+ * - With `sidebar: 'headings'`, a tab-level group renders as a flat heading
881
+ * with its pages extracted beneath it, and nested groups start closed.
713
882
  *
714
883
  * @param navigation - the parsed navigation
715
- * @param options - the API folder name
884
+ * @param options - the API folder name and the sidebar style
716
885
  * @returns the plan the generator executes
717
886
  * @throws when two sibling groups slugify to the same folder
718
887
  * @public
@@ -799,6 +968,38 @@ interface CreateMarkdownRouteOptions {
799
968
  * when the document is expensive to build.
800
969
  */
801
970
  readonly loadOpenApiDocuments?: () => Readonly<Record<string, OpenApiDocument>> | Promise<Readonly<Record<string, OpenApiDocument>>>;
971
+ /**
972
+ * Loads a generated API page's original operation source: the spec file
973
+ * path, the method and route, and the file's raw contents. When it returns
974
+ * one, the page's Markdown is the operation spec in full under an
975
+ * `## OpenAPI` heading, the shape agents get from the major docs platforms;
976
+ * pages it returns `null` for fall through to the MDX conversion. Wire it
977
+ * from the generator's `api-sources.json`.
978
+ */
979
+ readonly loadOperationSource?: (slug: readonly string[] | undefined) => Promise<OperationSource | null>;
980
+ /**
981
+ * The site's documentation index path (`/llms.txt`). When set, every
982
+ * response opens with a blockquote pointing agents at it, on the origin the
983
+ * request came in on — correct on localhost, a preview deploy, and
984
+ * production alike.
985
+ */
986
+ readonly llmsTxtPath?: string;
987
+ }
988
+ /**
989
+ * A generated API page's original operation source, as
990
+ * {@link CreateMarkdownRouteOptions.loadOperationSource} returns it.
991
+ *
992
+ * @public
993
+ */
994
+ interface OperationSource {
995
+ /** The spec file, relative to the content directory. */
996
+ readonly file: string;
997
+ /** The operation's HTTP method. */
998
+ readonly method: string;
999
+ /** The operation's API route. */
1000
+ readonly route: string;
1001
+ /** The spec file's raw contents. */
1002
+ readonly source: string;
802
1003
  }
803
1004
  /**
804
1005
  * Build a drop-in route that serves a page as plain Markdown. It reads the raw
@@ -816,6 +1017,56 @@ interface CreateMarkdownRouteOptions {
816
1017
  * @public
817
1018
  */
818
1019
  declare function createMarkdownRoute(options: CreateMarkdownRouteOptions): MarkdownRoute;
1020
+ /**
1021
+ * Options for {@link markdownRewriteTarget}.
1022
+ *
1023
+ * @public
1024
+ */
1025
+ interface MarkdownRewriteOptions {
1026
+ /** The docs base URL. Default `/docs`. */
1027
+ readonly baseUrl?: string;
1028
+ /** Where the Markdown route is mounted. Default `/md`. */
1029
+ readonly markdownBase?: string;
1030
+ }
1031
+ /**
1032
+ * The internal URL serving a docs page's Markdown, for a request whose path is
1033
+ * the page URL plus `.md` — the convention agents and other tools expect
1034
+ * (`/docs/guides/webhooks.md`). Returns `null` for every other request. A
1035
+ * site's middleware rewrites to the returned URL:
1036
+ *
1037
+ * @example
1038
+ * ```ts
1039
+ * const markdown = markdownRewriteTarget(request.nextUrl);
1040
+ * if (markdown) {
1041
+ * return NextResponse.rewrite(markdown);
1042
+ * }
1043
+ * ```
1044
+ *
1045
+ * @param url - the request URL
1046
+ * @param options - the docs base and the Markdown route's mount point
1047
+ * @returns the rewrite target, or `null` when the request is not a `.md` path
1048
+ * @public
1049
+ */
1050
+ declare function markdownRewriteTarget(url: URL, options?: MarkdownRewriteOptions): URL | null;
1051
+ /**
1052
+ * Whether a request addresses the Markdown route's internal mount directly.
1053
+ * The route exists as the rewrite target for the page-URL-plus-`.md`
1054
+ * convention; a direct request to it gets `404` from the site's middleware,
1055
+ * so every page's Markdown has one public address.
1056
+ *
1057
+ * @example
1058
+ * ```ts
1059
+ * if (isMarkdownRouteRequest(request.nextUrl)) {
1060
+ * return new NextResponse('Not found', { status: 404 });
1061
+ * }
1062
+ * ```
1063
+ *
1064
+ * @param url - the request URL
1065
+ * @param options - the Markdown route's mount point
1066
+ * @returns whether the request must be refused
1067
+ * @public
1068
+ */
1069
+ declare function isMarkdownRouteRequest(url: URL, options?: Pick<MarkdownRewriteOptions, 'markdownBase'>): boolean;
819
1070
 
820
1071
  /**
821
1072
  * Allowed-domain checks.
@@ -1294,4 +1545,4 @@ declare class OpenApiMergeError extends Error {
1294
1545
  */
1295
1546
  declare function mergeOpenApiDocuments(inputs: readonly unknown[], options: MergeOpenApiOptions): OpenApiDocument;
1296
1547
 
1297
- export { AiConfig, type AiMessage, type AskAiDocumentsSource, type AskAiRoute, type AskAiRouteOptions, type AskAiSource, type AuthGateOptions, type BuildSitemapOptions, type CreateMarkdownRouteOptions, type CreateTryItProxyOptions, DocsConfig, type DocsMetadata, type DocsRobots, type DocsSitemapEntry, type DocsTreePlan, type EmailSignInOptions, type FetchLike, type GoogleAuthHandlers, type GoogleAuthOptions, type IndexedDocument, InvalidNavigationError, type MarkdownRoute, type MdxReader, type MdxToMarkdownOptions, type MergeOpenApiOptions, Navigation, OpenApiDocument, OpenApiInfo, OpenApiMergeError, type OpenApiOperationRef, OpenApiServer, type PageSeo, type PlanDocsTreeOptions, type PlannedApiDocLink, type PlannedApiGroup, type PlannedApiPage, type PlannedGroupChild, type PlannedMeta, ProxyTargetError, SESSION_COOKIE, type SearchDocument, type SearchIndex, type SearchResult, type SecretSignInOptions, type SessionPayload, type SignOutOptions, type SiteAuth, type SiteAuthOptions, type SitemapChangeFrequency, type SitemapEntry, ThemeConfig, type TryItEnvelope, type TryItProxyRoute, assertAllowedTarget, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createSiteAuth, createTryItProxy, createTryItProxyRoute, isAllowedEmail, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, searchIndex, signSession, unwrapProxyTarget, verifySession };
1548
+ export { AiConfig, type AiMessage, type AskAiDocumentsSource, type AskAiRoute, type AskAiRouteOptions, type AskAiSource, type AuthGateOptions, type BuildLlmsTxtOptions, type BuildSitemapOptions, type CodeUsageGenerator, type CodeUsageRequest, type CodeUsageValue, type CreateMarkdownRouteOptions, type CreateTryItProxyOptions, DocsConfig, type DocsMetadata, type DocsRobots, type DocsSitemapEntry, type DocsTreePlan, type EmailSignInOptions, type FetchLike, type GoogleAuthHandlers, type GoogleAuthOptions, type IndexedDocument, InvalidNavigationError, type LlmsTxtPage, type MarkdownRewriteOptions, type MarkdownRoute, type MdxReader, type MdxToMarkdownOptions, type MergeOpenApiOptions, Navigation, OpenApiDocument, OpenApiInfo, OpenApiMergeError, type OpenApiOperationRef, OpenApiServer, type OperationSource, type PageSeo, type PlanDocsTreeOptions, type PlannedApiDocLink, type PlannedApiGroup, type PlannedApiPage, type PlannedGroupChild, type PlannedMeta, ProxyTargetError, SESSION_COOKIE, type SearchDocument, type SearchIndex, type SearchResult, type SecretSignInOptions, type SessionPayload, type SignOutOptions, type SiteAuth, type SiteAuthOptions, type SitemapChangeFrequency, type SitemapEntry, ThemeConfig, type TryItEnvelope, type TryItProxyRoute, assertAllowedTarget, buildLlmsTxt, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createSiteAuth, createTryItProxy, createTryItProxyRoute, curlCodeUsage, isAllowedEmail, isMarkdownRouteRequest, markdownRewriteTarget, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, redirectTarget, searchIndex, signSession, unwrapProxyTarget, verifySession };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AiConfig, T as ThemeConfig, D as DocsConfig, N as Navigation } from './navigation-CGqFIPlP.js';
2
- export { a as AI_PROVIDER_MODELS, b as AI_PROVIDER_NAMES, c as AiConfigError, d as AiProviderModels, e as AiProviderName, f as AuthConfig, g as DocPage, h as DocsConfigError, F as FeaturesConfig, G as GoogleProviderConfig, i as NavGroup, j as NavItem, k as NavMethod, l as NavPage, m as NavTab, O as OpenApiPage, P as ProxyConfig, R as ResolvedAiConfig, S as SecretProviderConfig, n as SeoConfig, o as ThemeLogo, p as ThemePalette, W as WorkspaceAuthConfig, q as WorkspaceProviders, r as defineDocsConfig, s as resolveAiConfig, v as validateDocsConfig } from './navigation-CGqFIPlP.js';
1
+ import { A as AiConfig, T as ThemeConfig, D as DocsConfig, N as Navigation } from './navigation-DvgyWSZ4.js';
2
+ export { a as AI_PROVIDER_MODELS, b as AI_PROVIDER_NAMES, c as AiConfigError, d as AiProviderModels, e as AiProviderName, f as AuthConfig, g as DocPage, h as DocsConfigError, F as FeaturesConfig, G as GoogleProviderConfig, i as NavGroup, j as NavItem, k as NavMethod, l as NavPage, m as NavTab, O as OpenApiPage, P as ProxyConfig, R as ResolvedAiConfig, S as SecretProviderConfig, n as SeoConfig, o as ThemeLogo, p as ThemePalette, W as WorkspaceAuthConfig, q as WorkspaceProviders, r as defineDocsConfig, s as resolveAiConfig, v as validateDocsConfig } from './navigation-DvgyWSZ4.js';
3
3
  import { b as OpenApiDocument, O as OpenApiInfo, a as OpenApiServer } from './openapi-types-CJ6p5Cux.js';
4
4
  export { c as OpenApiComponents, d as OpenApiOperation, e as OpenApiPathItem, f as OpenApiTag } from './openapi-types-CJ6p5Cux.js';
5
5
 
@@ -275,7 +275,9 @@ declare function searchIndex(index: SearchIndex, query: string, limit?: number):
275
275
  * - **Configuration is resolved eagerly.** {@link createAskAiRoute} validates
276
276
  * the `ai` block when the route is built, so a typo in `docs.config.ts` fails
277
277
  * the build. Deferring it to the first request would turn a site's typo into a
278
- * reader's error message.
278
+ * reader's error message. A site with no `ai` block at all is different from
279
+ * a typo: the route mounts dormant and answers `404`, so a scaffold ships the
280
+ * file and enabling Ask AI is a config change, not a code change.
279
281
  * - **The API key is read lazily, per request.** An edge runtime binds its
280
282
  * environment per invocation, not at module load, so the key is looked up when
281
283
  * it is needed. It is never logged; a missing key is reported by env var name.
@@ -301,8 +303,12 @@ type AskAiDocumentsSource = readonly SearchDocument[] | (() => Promise<readonly
301
303
  * @public
302
304
  */
303
305
  interface AskAiRouteOptions {
304
- /** The site's raw `ai` block. Validated when the route is built. */
305
- readonly config: AiConfig;
306
+ /**
307
+ * The site's raw `ai` block. Validated when the route is built. `undefined`
308
+ * (the config declares no `ai` block) mounts the route dormant: every
309
+ * request answers `404`.
310
+ */
311
+ readonly config: AiConfig | undefined;
306
312
  /** Display name used in the system prompt, normally `theme.name`. */
307
313
  readonly siteName: string;
308
314
  /**
@@ -397,6 +403,152 @@ declare function createAskAiRoute(options: AskAiRouteOptions): AskAiRoute;
397
403
  */
398
404
  declare function buildThemeCss(theme: ThemeConfig): string;
399
405
 
406
+ /**
407
+ * Permanent redirects for renamed pages. The generator writes
408
+ * `content/redirects.json` (old page URL to current) whenever an operation's
409
+ * URL changes; the site's middleware serves `308`s from it, so an edited
410
+ * summary is a rename with a forwarding address, never a dead link.
411
+ *
412
+ * @packageDocumentation
413
+ */
414
+ /**
415
+ * The URL a renamed page's request should be redirected to, or `null` when
416
+ * the request matches no entry. The `.md` form of a renamed page redirects to
417
+ * the `.md` form of its new address.
418
+ *
419
+ * @example
420
+ * ```ts
421
+ * const redirected = redirectTarget(request.nextUrl, redirects);
422
+ * if (redirected) {
423
+ * return NextResponse.redirect(redirected, 308);
424
+ * }
425
+ * ```
426
+ *
427
+ * @param url - the request URL
428
+ * @param redirects - the parsed `content/redirects.json`
429
+ * @returns the redirect target, or `null`
430
+ * @public
431
+ */
432
+ declare function redirectTarget(url: URL, redirects: Readonly<Record<string, string>>): URL | null;
433
+
434
+ /**
435
+ * The site's `/llms.txt`: a Markdown index of every page, the entry point
436
+ * agents fetch first. Each entry links the page's `.md` address.
437
+ *
438
+ * @packageDocumentation
439
+ */
440
+ /**
441
+ * One page of the documentation index.
442
+ *
443
+ * @public
444
+ */
445
+ interface LlmsTxtPage {
446
+ readonly title: string;
447
+ /** The page URL (e.g. `/docs/guides/webhooks`); `.md` is appended. */
448
+ readonly url: string;
449
+ readonly description?: string;
450
+ }
451
+ /**
452
+ * Options for {@link buildLlmsTxt}.
453
+ *
454
+ * @public
455
+ */
456
+ interface BuildLlmsTxtOptions {
457
+ /** The site name, the index's `#` heading. */
458
+ readonly name: string;
459
+ /** One sentence on what the site documents. */
460
+ readonly description?: string;
461
+ /** Absolute origin to prefix every link with (e.g. `https://docs.example.com`). */
462
+ readonly origin?: string;
463
+ }
464
+ /**
465
+ * Build the `/llms.txt` document from the site's pages.
466
+ *
467
+ * @example
468
+ * ```ts
469
+ * // app/llms.txt/route.ts
470
+ * export function GET() {
471
+ * const body = buildLlmsTxt(pages, { name: config.theme.name });
472
+ * return new Response(body, { headers: { 'content-type': 'text/plain; charset=utf-8' } });
473
+ * }
474
+ * ```
475
+ *
476
+ * @param pages - the site's pages, in navigation order
477
+ * @param options - the site name, description, and link origin
478
+ * @returns the document text
479
+ * @public
480
+ */
481
+ declare function buildLlmsTxt(pages: readonly LlmsTxtPage[], options: BuildLlmsTxtOptions): string;
482
+
483
+ /**
484
+ * Code-sample generators for the API reference's usage panel.
485
+ *
486
+ * `fumadocs-openapi` renders one sample per registered generator; a site
487
+ * replaces a built-in one by adding a generator under the same id. The shapes
488
+ * here are structural, so this module needs no fumadocs types.
489
+ *
490
+ * @packageDocumentation
491
+ */
492
+ /**
493
+ * One resolved request parameter, as the usage panel passes it.
494
+ *
495
+ * @public
496
+ */
497
+ interface CodeUsageValue {
498
+ /** The parameter's example value. */
499
+ readonly value: string;
500
+ }
501
+ /**
502
+ * The resolved example request a code-sample generator receives.
503
+ *
504
+ * @public
505
+ */
506
+ interface CodeUsageRequest {
507
+ /** The HTTP method. */
508
+ readonly method: string;
509
+ /** The full request URL, path and query resolved. */
510
+ readonly url: string;
511
+ /** Header name to example value. */
512
+ readonly header?: Readonly<Record<string, CodeUsageValue>>;
513
+ /** Cookie name to example value. */
514
+ readonly cookie?: Readonly<Record<string, CodeUsageValue>>;
515
+ /** The example request body, when the operation takes one. */
516
+ readonly body?: unknown;
517
+ /** The body's media type, when the operation takes a body. */
518
+ readonly bodyMediaType?: string;
519
+ }
520
+ /**
521
+ * A code-sample generator, shaped for fumadocs-openapi's code-usage registry.
522
+ *
523
+ * @public
524
+ */
525
+ interface CodeUsageGenerator {
526
+ /** The tab label readers see. */
527
+ readonly label: string;
528
+ /** The sample's syntax-highlighting language. */
529
+ readonly lang: string;
530
+ /** Render the sample for one resolved example request. */
531
+ generate(data: CodeUsageRequest): string;
532
+ }
533
+ /**
534
+ * A cURL sample in long-form flags: `--request`, `--url`, `--header`,
535
+ * `--data`. Register it over the built-in `curl` entry:
536
+ *
537
+ * @example
538
+ * ```ts
539
+ * import { curlCodeUsage } from '@blaaiz/docs-core';
540
+ * import { createCodeUsageGeneratorRegistry } from 'fumadocs-openapi/requests/generators';
541
+ * import { registerDefault } from 'fumadocs-openapi/requests/generators/all';
542
+ *
543
+ * const codeUsages = registerDefault(createCodeUsageGeneratorRegistry());
544
+ * codeUsages.add('curl', curlCodeUsage);
545
+ * createOpenAPI({ input, codeUsages });
546
+ * ```
547
+ *
548
+ * @public
549
+ */
550
+ declare const curlCodeUsage: CodeUsageGenerator;
551
+
400
552
  /**
401
553
  * SEO metadata, derived from {@link DocsConfig}.
402
554
  *
@@ -628,6 +780,8 @@ interface PlannedGroupChild {
628
780
  readonly order: number;
629
781
  /** The child folder's name within the group directory. */
630
782
  readonly folder: string;
783
+ /** The child group's title, for the heading the `headings` style renders. */
784
+ readonly title: string;
631
785
  }
632
786
  /**
633
787
  * A planned API group folder. The generator fills its page order once the
@@ -688,6 +842,17 @@ interface DocsTreePlan {
688
842
  */
689
843
  readonly apiDocLinks: readonly PlannedApiDocLink[];
690
844
  }
845
+ /**
846
+ * How the sidebar presents a tab's top-level groups.
847
+ *
848
+ * - `collapsible`: every group is a collapsible folder (the fumadocs default).
849
+ * - `headings`: a top-level group is a flat, always-open section heading with
850
+ * its pages listed beneath it; only nested groups collapse, and they start
851
+ * closed. The Mintlify presentation.
852
+ *
853
+ * @public
854
+ */
855
+ type SidebarStyle = 'collapsible' | 'headings';
691
856
  /**
692
857
  * Options for {@link planDocsTree}.
693
858
  *
@@ -696,6 +861,8 @@ interface DocsTreePlan {
696
861
  interface PlanDocsTreeOptions {
697
862
  /** Folder for generated API pages when one tab publishes them. Default `api`. */
698
863
  readonly apiDir?: string;
864
+ /** The sidebar's group presentation. Default `collapsible`. */
865
+ readonly sidebar?: SidebarStyle;
699
866
  }
700
867
  /**
701
868
  * Plan the content tree for a navigation.
@@ -710,9 +877,11 @@ interface PlanDocsTreeOptions {
710
877
  * - Root-level doc pages (no `/` in the path) are listed in the root meta.
711
878
  * - Tab folders get `root: true`, so the sidebar scopes to the active tab.
712
879
  * - Sidebar order is declaration order, pages and groups interleaved.
880
+ * - With `sidebar: 'headings'`, a tab-level group renders as a flat heading
881
+ * with its pages extracted beneath it, and nested groups start closed.
713
882
  *
714
883
  * @param navigation - the parsed navigation
715
- * @param options - the API folder name
884
+ * @param options - the API folder name and the sidebar style
716
885
  * @returns the plan the generator executes
717
886
  * @throws when two sibling groups slugify to the same folder
718
887
  * @public
@@ -799,6 +968,38 @@ interface CreateMarkdownRouteOptions {
799
968
  * when the document is expensive to build.
800
969
  */
801
970
  readonly loadOpenApiDocuments?: () => Readonly<Record<string, OpenApiDocument>> | Promise<Readonly<Record<string, OpenApiDocument>>>;
971
+ /**
972
+ * Loads a generated API page's original operation source: the spec file
973
+ * path, the method and route, and the file's raw contents. When it returns
974
+ * one, the page's Markdown is the operation spec in full under an
975
+ * `## OpenAPI` heading, the shape agents get from the major docs platforms;
976
+ * pages it returns `null` for fall through to the MDX conversion. Wire it
977
+ * from the generator's `api-sources.json`.
978
+ */
979
+ readonly loadOperationSource?: (slug: readonly string[] | undefined) => Promise<OperationSource | null>;
980
+ /**
981
+ * The site's documentation index path (`/llms.txt`). When set, every
982
+ * response opens with a blockquote pointing agents at it, on the origin the
983
+ * request came in on — correct on localhost, a preview deploy, and
984
+ * production alike.
985
+ */
986
+ readonly llmsTxtPath?: string;
987
+ }
988
+ /**
989
+ * A generated API page's original operation source, as
990
+ * {@link CreateMarkdownRouteOptions.loadOperationSource} returns it.
991
+ *
992
+ * @public
993
+ */
994
+ interface OperationSource {
995
+ /** The spec file, relative to the content directory. */
996
+ readonly file: string;
997
+ /** The operation's HTTP method. */
998
+ readonly method: string;
999
+ /** The operation's API route. */
1000
+ readonly route: string;
1001
+ /** The spec file's raw contents. */
1002
+ readonly source: string;
802
1003
  }
803
1004
  /**
804
1005
  * Build a drop-in route that serves a page as plain Markdown. It reads the raw
@@ -816,6 +1017,56 @@ interface CreateMarkdownRouteOptions {
816
1017
  * @public
817
1018
  */
818
1019
  declare function createMarkdownRoute(options: CreateMarkdownRouteOptions): MarkdownRoute;
1020
+ /**
1021
+ * Options for {@link markdownRewriteTarget}.
1022
+ *
1023
+ * @public
1024
+ */
1025
+ interface MarkdownRewriteOptions {
1026
+ /** The docs base URL. Default `/docs`. */
1027
+ readonly baseUrl?: string;
1028
+ /** Where the Markdown route is mounted. Default `/md`. */
1029
+ readonly markdownBase?: string;
1030
+ }
1031
+ /**
1032
+ * The internal URL serving a docs page's Markdown, for a request whose path is
1033
+ * the page URL plus `.md` — the convention agents and other tools expect
1034
+ * (`/docs/guides/webhooks.md`). Returns `null` for every other request. A
1035
+ * site's middleware rewrites to the returned URL:
1036
+ *
1037
+ * @example
1038
+ * ```ts
1039
+ * const markdown = markdownRewriteTarget(request.nextUrl);
1040
+ * if (markdown) {
1041
+ * return NextResponse.rewrite(markdown);
1042
+ * }
1043
+ * ```
1044
+ *
1045
+ * @param url - the request URL
1046
+ * @param options - the docs base and the Markdown route's mount point
1047
+ * @returns the rewrite target, or `null` when the request is not a `.md` path
1048
+ * @public
1049
+ */
1050
+ declare function markdownRewriteTarget(url: URL, options?: MarkdownRewriteOptions): URL | null;
1051
+ /**
1052
+ * Whether a request addresses the Markdown route's internal mount directly.
1053
+ * The route exists as the rewrite target for the page-URL-plus-`.md`
1054
+ * convention; a direct request to it gets `404` from the site's middleware,
1055
+ * so every page's Markdown has one public address.
1056
+ *
1057
+ * @example
1058
+ * ```ts
1059
+ * if (isMarkdownRouteRequest(request.nextUrl)) {
1060
+ * return new NextResponse('Not found', { status: 404 });
1061
+ * }
1062
+ * ```
1063
+ *
1064
+ * @param url - the request URL
1065
+ * @param options - the Markdown route's mount point
1066
+ * @returns whether the request must be refused
1067
+ * @public
1068
+ */
1069
+ declare function isMarkdownRouteRequest(url: URL, options?: Pick<MarkdownRewriteOptions, 'markdownBase'>): boolean;
819
1070
 
820
1071
  /**
821
1072
  * Allowed-domain checks.
@@ -1294,4 +1545,4 @@ declare class OpenApiMergeError extends Error {
1294
1545
  */
1295
1546
  declare function mergeOpenApiDocuments(inputs: readonly unknown[], options: MergeOpenApiOptions): OpenApiDocument;
1296
1547
 
1297
- export { AiConfig, type AiMessage, type AskAiDocumentsSource, type AskAiRoute, type AskAiRouteOptions, type AskAiSource, type AuthGateOptions, type BuildSitemapOptions, type CreateMarkdownRouteOptions, type CreateTryItProxyOptions, DocsConfig, type DocsMetadata, type DocsRobots, type DocsSitemapEntry, type DocsTreePlan, type EmailSignInOptions, type FetchLike, type GoogleAuthHandlers, type GoogleAuthOptions, type IndexedDocument, InvalidNavigationError, type MarkdownRoute, type MdxReader, type MdxToMarkdownOptions, type MergeOpenApiOptions, Navigation, OpenApiDocument, OpenApiInfo, OpenApiMergeError, type OpenApiOperationRef, OpenApiServer, type PageSeo, type PlanDocsTreeOptions, type PlannedApiDocLink, type PlannedApiGroup, type PlannedApiPage, type PlannedGroupChild, type PlannedMeta, ProxyTargetError, SESSION_COOKIE, type SearchDocument, type SearchIndex, type SearchResult, type SecretSignInOptions, type SessionPayload, type SignOutOptions, type SiteAuth, type SiteAuthOptions, type SitemapChangeFrequency, type SitemapEntry, ThemeConfig, type TryItEnvelope, type TryItProxyRoute, assertAllowedTarget, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createSiteAuth, createTryItProxy, createTryItProxyRoute, isAllowedEmail, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, searchIndex, signSession, unwrapProxyTarget, verifySession };
1548
+ export { AiConfig, type AiMessage, type AskAiDocumentsSource, type AskAiRoute, type AskAiRouteOptions, type AskAiSource, type AuthGateOptions, type BuildLlmsTxtOptions, type BuildSitemapOptions, type CodeUsageGenerator, type CodeUsageRequest, type CodeUsageValue, type CreateMarkdownRouteOptions, type CreateTryItProxyOptions, DocsConfig, type DocsMetadata, type DocsRobots, type DocsSitemapEntry, type DocsTreePlan, type EmailSignInOptions, type FetchLike, type GoogleAuthHandlers, type GoogleAuthOptions, type IndexedDocument, InvalidNavigationError, type LlmsTxtPage, type MarkdownRewriteOptions, type MarkdownRoute, type MdxReader, type MdxToMarkdownOptions, type MergeOpenApiOptions, Navigation, OpenApiDocument, OpenApiInfo, OpenApiMergeError, type OpenApiOperationRef, OpenApiServer, type OperationSource, type PageSeo, type PlanDocsTreeOptions, type PlannedApiDocLink, type PlannedApiGroup, type PlannedApiPage, type PlannedGroupChild, type PlannedMeta, ProxyTargetError, SESSION_COOKIE, type SearchDocument, type SearchIndex, type SearchResult, type SecretSignInOptions, type SessionPayload, type SignOutOptions, type SiteAuth, type SiteAuthOptions, type SitemapChangeFrequency, type SitemapEntry, ThemeConfig, type TryItEnvelope, type TryItProxyRoute, assertAllowedTarget, buildLlmsTxt, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createSiteAuth, createTryItProxy, createTryItProxyRoute, curlCodeUsage, isAllowedEmail, isMarkdownRouteRequest, markdownRewriteTarget, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, redirectTarget, searchIndex, signSession, unwrapProxyTarget, verifySession };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { AI_PROVIDER_MODELS, AI_PROVIDER_NAMES, AiConfigError, DocsConfigError, InvalidNavigationError, OpenApiMergeError, ProxyTargetError, SESSION_COOKIE, assertAllowedTarget, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createSiteAuth, createTryItProxy, createTryItProxyRoute, defineDocsConfig, isAllowedEmail, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, resolveAiConfig, searchIndex, signSession, unwrapProxyTarget, validateDocsConfig, verifySession } from './chunk-ZWDLAW5M.js';
1
+ export { AI_PROVIDER_MODELS, AI_PROVIDER_NAMES, AiConfigError, DocsConfigError, InvalidNavigationError, OpenApiMergeError, ProxyTargetError, SESSION_COOKIE, assertAllowedTarget, buildLlmsTxt, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createSiteAuth, createTryItProxy, createTryItProxyRoute, curlCodeUsage, defineDocsConfig, isAllowedEmail, isMarkdownRouteRequest, markdownRewriteTarget, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, redirectTarget, resolveAiConfig, searchIndex, signSession, unwrapProxyTarget, validateDocsConfig, verifySession } from './chunk-L4PFRXIK.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map