@brainfish-ai/devdoc 0.1.42 → 0.1.44
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/commands/create.js +2 -2
- package/dist/cli/commands/dev.js +19 -10
- package/package.json +3 -2
- package/renderer/app/api/assets/[...path]/route.js +108 -0
- package/renderer/app/api/assets/route.js +114 -0
- package/renderer/app/api/assets/upload/route.js +163 -0
- package/renderer/app/api/auth-schemes/route.js +58 -0
- package/renderer/app/api/chat/route.js +759 -0
- package/renderer/app/api/codegen/route.js +52 -0
- package/renderer/app/api/collections/route.js +706 -0
- package/renderer/app/api/debug/route.js +47 -0
- package/renderer/app/api/deploy/route.js +199 -0
- package/renderer/app/api/device/route.js +36 -0
- package/renderer/app/api/docs/route.js +205 -0
- package/renderer/app/api/domains/add/route.js +121 -0
- package/renderer/app/api/domains/lookup/route.js +43 -0
- package/renderer/app/api/domains/remove/route.js +89 -0
- package/renderer/app/api/domains/status/route.js +140 -0
- package/renderer/app/api/domains/verify/route.js +168 -0
- package/renderer/app/api/keys/regenerate/route.js +71 -0
- package/renderer/app/api/local-assets/[...path]/route.js +108 -0
- package/renderer/app/api/openapi-spec/route.js +73 -0
- package/renderer/app/api/projects/[slug]/route.js +129 -0
- package/renderer/app/api/projects/[slug]/stats/route.js +80 -0
- package/renderer/app/api/projects/register/route.js +176 -0
- package/renderer/app/api/proxy/route.js +139 -0
- package/renderer/app/api/proxy-stream/route.js +156 -0
- package/renderer/app/api/redirects/route.js +35 -0
- package/renderer/app/api/schema/route.js +85 -0
- package/renderer/app/api/subdomains/check/route.js +158 -0
- package/renderer/app/api/suggestions/route.js +195 -0
- package/renderer/app/globals.css +69 -0
- package/renderer/app/layout.js +47 -0
- package/renderer/app/llms-full.txt/route.js +266 -0
- package/renderer/app/llms.txt/route.js +228 -0
- package/renderer/app/page.js +12 -0
- package/renderer/app/robots.txt/route.js +66 -0
- package/renderer/app/sitemap.xml/route.js +155 -0
- package/renderer/components/docs/index.js +8 -0
- package/renderer/components/docs/mdx/accordion.js +113 -0
- package/renderer/components/docs/mdx/badge.js +72 -0
- package/renderer/components/docs/mdx/callouts.js +137 -0
- package/renderer/components/docs/mdx/cards.js +175 -0
- package/renderer/components/docs/mdx/changelog.js +100 -0
- package/renderer/components/docs/mdx/code-block.js +147 -0
- package/renderer/components/docs/mdx/code-group.js +287 -0
- package/renderer/components/docs/mdx/file-embeds.js +82 -0
- package/renderer/components/docs/mdx/frame.js +59 -0
- package/renderer/components/docs/mdx/highlight.js +90 -0
- package/renderer/components/docs/mdx/iframe.js +69 -0
- package/renderer/components/docs/mdx/image.js +135 -0
- package/renderer/components/docs/mdx/index.js +134 -0
- package/renderer/components/docs/mdx/landing.js +317 -0
- package/renderer/components/docs/mdx/mermaid.js +212 -0
- package/renderer/components/docs/mdx/param-field.js +112 -0
- package/renderer/components/docs/mdx/steps.js +74 -0
- package/renderer/components/docs/mdx/tabs.js +50 -0
- package/renderer/components/docs/mdx-renderer.js +77 -0
- package/renderer/components/docs/navigation/breadcrumbs.js +64 -0
- package/renderer/components/docs/navigation/index.js +6 -0
- package/renderer/components/docs/navigation/page-nav.js +57 -0
- package/renderer/components/docs/navigation/sidebar.js +375 -0
- package/renderer/components/docs/navigation/toc.js +89 -0
- package/renderer/components/docs/notice.js +77 -0
- package/renderer/components/docs-header.js +202 -0
- package/renderer/components/docs-viewer/agent/agent-chat.js +1831 -0
- package/renderer/components/docs-viewer/agent/agent-popup-button.js +99 -0
- package/renderer/components/docs-viewer/agent/cards/debug-context-card.js +107 -0
- package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.js +57 -0
- package/renderer/components/docs-viewer/agent/cards/index.js +45 -0
- package/renderer/components/docs-viewer/agent/cards/response-options-card.js +154 -0
- package/renderer/components/docs-viewer/agent/cards/types.js +22 -0
- package/renderer/components/docs-viewer/agent/chat-message.js +2 -0
- package/renderer/components/docs-viewer/agent/index.js +7 -0
- package/renderer/components/docs-viewer/agent/messages/assistant-message.js +108 -0
- package/renderer/components/docs-viewer/agent/messages/chat-message.js +34 -0
- package/renderer/components/docs-viewer/agent/messages/index.js +6 -0
- package/renderer/components/docs-viewer/agent/messages/tool-call-display.js +1065 -0
- package/renderer/components/docs-viewer/agent/messages/types.js +2 -0
- package/renderer/components/docs-viewer/agent/messages/typing-indicator.js +26 -0
- package/renderer/components/docs-viewer/agent/messages/user-message.js +37 -0
- package/renderer/components/docs-viewer/code-editor/{index.tsx → index.js} +1 -1
- package/renderer/components/docs-viewer/code-editor/notes-mode.js +1338 -0
- package/renderer/components/docs-viewer/content/changelog-page.js +297 -0
- package/renderer/components/docs-viewer/content/content-router.js +182 -0
- package/renderer/components/docs-viewer/content/doc-page.js +290 -0
- package/renderer/components/docs-viewer/content/documentation-viewer.js +14 -0
- package/renderer/components/docs-viewer/content/index.js +31 -0
- package/renderer/components/docs-viewer/content/not-found-page.js +300 -0
- package/renderer/components/docs-viewer/content/request-details.js +528 -0
- package/renderer/components/docs-viewer/content/sections/auth.js +108 -0
- package/renderer/components/docs-viewer/content/sections/body.js +80 -0
- package/renderer/components/docs-viewer/content/sections/headers.js +64 -0
- package/renderer/components/docs-viewer/content/sections/overview.js +56 -0
- package/renderer/components/docs-viewer/content/sections/parameters.js +64 -0
- package/renderer/components/docs-viewer/content/sections/responses.js +91 -0
- package/renderer/components/docs-viewer/global-auth-modal.js +427 -0
- package/renderer/components/docs-viewer/index.js +1448 -0
- package/renderer/components/docs-viewer/playground/auth-editor.js +418 -0
- package/renderer/components/docs-viewer/playground/body-editor.js +240 -0
- package/renderer/components/docs-viewer/playground/code-editor.js +135 -0
- package/renderer/components/docs-viewer/playground/code-snippet.js +393 -0
- package/renderer/components/docs-viewer/playground/graphql-playground.js +936 -0
- package/renderer/components/docs-viewer/playground/index.js +682 -0
- package/renderer/components/docs-viewer/playground/key-value-editor.js +317 -0
- package/renderer/components/docs-viewer/playground/method-selector.js +65 -0
- package/renderer/components/docs-viewer/playground/request-builder.js +181 -0
- package/renderer/components/docs-viewer/playground/request-tabs.js +240 -0
- package/renderer/components/docs-viewer/playground/response-cards/idle-card.js +42 -0
- package/renderer/components/docs-viewer/playground/response-cards/index.js +72 -0
- package/renderer/components/docs-viewer/playground/response-cards/loading-card.js +24 -0
- package/renderer/components/docs-viewer/playground/response-cards/network-error-card.js +28 -0
- package/renderer/components/docs-viewer/playground/response-cards/response-body-card.js +308 -0
- package/renderer/components/docs-viewer/playground/response-cards/types.js +9 -0
- package/renderer/components/docs-viewer/playground/response-viewer.js +18 -0
- package/renderer/components/docs-viewer/search/index.js +2 -0
- package/renderer/components/docs-viewer/search/search-dialog.js +367 -0
- package/renderer/components/docs-viewer/search/use-search.js +89 -0
- package/renderer/components/docs-viewer/shared/markdown-renderer.js +423 -0
- package/renderer/components/docs-viewer/shared/method-badge.js +23 -0
- package/renderer/components/docs-viewer/shared/schema-viewer.js +321 -0
- package/renderer/components/docs-viewer/sidebar/collection-tree.js +222 -0
- package/renderer/components/docs-viewer/sidebar/endpoint-options.js +512 -0
- package/renderer/components/docs-viewer/sidebar/index.js +196 -0
- package/renderer/components/docs-viewer/sidebar/right-sidebar.js +159 -0
- package/renderer/components/docs-viewer/sidebar/sidebar-group.js +87 -0
- package/renderer/components/docs-viewer/sidebar/sidebar-item.js +172 -0
- package/renderer/components/docs-viewer/sidebar/sidebar-section.js +31 -0
- package/renderer/components/theme-provider.js +10 -0
- package/renderer/components/theme-toggle.js +86 -0
- package/renderer/components/ui/badge.js +29 -0
- package/renderer/components/ui/button.js +40 -0
- package/renderer/components/ui/dialog.js +50 -0
- package/renderer/components/ui/dropdown-menu.js +143 -0
- package/renderer/components/ui/input.js +12 -0
- package/renderer/components/ui/label.js +13 -0
- package/renderer/components/ui/navigation-menu.js +83 -0
- package/renderer/components/ui/select.js +116 -0
- package/renderer/components/ui/spinner.js +92 -0
- package/renderer/components/ui/tabs.js +34 -0
- package/renderer/components/ui/tooltip.js +43 -0
- package/renderer/hooks/use-code-copy.js +76 -0
- package/renderer/hooks/use-openapi-title.js +33 -0
- package/renderer/hooks/use-route-state.js +159 -0
- package/renderer/lib/api-docs/agent/index.js +4 -0
- package/renderer/lib/api-docs/agent/indexer.js +254 -0
- package/renderer/lib/api-docs/agent/spec-summary.js +227 -0
- package/renderer/lib/api-docs/agent/types.js +5 -0
- package/renderer/lib/api-docs/agent/use-suggestions.js +97 -0
- package/renderer/lib/api-docs/auth/auth-context.js +157 -0
- package/renderer/lib/api-docs/auth/auth-storage.js +66 -0
- package/renderer/lib/api-docs/auth/crypto.js +64 -0
- package/renderer/lib/api-docs/auth/index.js +3 -0
- package/renderer/lib/api-docs/code-editor/db.js +145 -0
- package/renderer/lib/api-docs/code-editor/hooks.js +254 -0
- package/renderer/lib/api-docs/code-editor/{index.ts → index.js} +3 -4
- package/renderer/lib/api-docs/code-editor/mode-context.js +126 -0
- package/renderer/lib/api-docs/code-editor/types.js +53 -0
- package/renderer/lib/api-docs/codegen/definitions.js +258 -0
- package/renderer/lib/api-docs/codegen/har.js +171 -0
- package/renderer/lib/api-docs/codegen/index.js +118 -0
- package/renderer/lib/api-docs/factories.js +136 -0
- package/renderer/lib/api-docs/{index.ts → index.js} +5 -10
- package/renderer/lib/api-docs/mobile-context.js +116 -0
- package/renderer/lib/api-docs/navigation-context.js +62 -0
- package/renderer/lib/api-docs/parsers/graphql/index.js +50 -0
- package/renderer/lib/api-docs/parsers/graphql/parser.js +350 -0
- package/renderer/lib/api-docs/parsers/graphql/transformer.js +215 -0
- package/renderer/lib/api-docs/parsers/graphql/types.js +46 -0
- package/renderer/lib/api-docs/parsers/openapi/dereferencer.js +43 -0
- package/renderer/lib/api-docs/parsers/openapi/extractors/auth.js +486 -0
- package/renderer/lib/api-docs/parsers/openapi/extractors/body.js +295 -0
- package/renderer/lib/api-docs/parsers/openapi/extractors/index.js +132 -0
- package/renderer/lib/api-docs/parsers/openapi/index.js +127 -0
- package/renderer/lib/api-docs/parsers/openapi/transformer.js +192 -0
- package/renderer/lib/api-docs/parsers/openapi/validator.js +24 -0
- package/renderer/lib/api-docs/playground/context.js +65 -0
- package/renderer/lib/api-docs/playground/navigation-context.js +74 -0
- package/renderer/lib/api-docs/playground/request-builder.js +163 -0
- package/renderer/lib/api-docs/playground/request-runner.js +224 -0
- package/renderer/lib/api-docs/playground/types.js +5 -0
- package/renderer/lib/api-docs/types.js +23 -0
- package/renderer/lib/api-docs/utils.js +212 -0
- package/renderer/lib/cache.js +157 -0
- package/renderer/lib/docs/config/domain-schema.js +161 -0
- package/renderer/lib/docs/config/environment.js +38 -0
- package/renderer/lib/docs/config/index.js +6 -0
- package/renderer/lib/docs/config/loader.js +113 -0
- package/renderer/lib/docs/config/schema.js +281 -0
- package/renderer/lib/docs/index.js +8 -0
- package/renderer/lib/docs/mdx/compiler.js +131 -0
- package/renderer/lib/docs/mdx/frontmatter.js +73 -0
- package/renderer/lib/docs/mdx/index.js +10 -0
- package/renderer/lib/docs/mdx/remark-mermaid.js +63 -0
- package/renderer/lib/docs/navigation/generator.js +269 -0
- package/renderer/lib/docs/navigation/index.js +3 -0
- package/renderer/lib/docs/navigation/types.js +11 -0
- package/renderer/lib/docs-navigation-context.js +40 -0
- package/renderer/lib/docs-navigation.js +140 -0
- package/renderer/lib/multi-tenant/context.js +80 -0
- package/renderer/lib/storage/blob.js +767 -0
- package/renderer/lib/utils/icons.js +30 -0
- package/renderer/lib/utils.js +5 -0
- package/renderer/next.config.js +62 -0
- package/renderer/package.json +1 -0
- package/renderer/tsconfig.json +23 -5
- package/renderer/app/api/assets/[...path]/route.ts +0 -123
- package/renderer/app/api/assets/route.ts +0 -124
- package/renderer/app/api/assets/upload/route.ts +0 -177
- package/renderer/app/api/auth-schemes/route.ts +0 -77
- package/renderer/app/api/chat/route.ts +0 -858
- package/renderer/app/api/codegen/route.ts +0 -72
- package/renderer/app/api/collections/route.ts +0 -1002
- package/renderer/app/api/debug/route.ts +0 -53
- package/renderer/app/api/deploy/route.ts +0 -234
- package/renderer/app/api/device/route.ts +0 -42
- package/renderer/app/api/docs/route.ts +0 -201
- package/renderer/app/api/domains/add/route.ts +0 -132
- package/renderer/app/api/domains/lookup/route.ts +0 -43
- package/renderer/app/api/domains/remove/route.ts +0 -100
- package/renderer/app/api/domains/status/route.ts +0 -158
- package/renderer/app/api/domains/verify/route.ts +0 -181
- package/renderer/app/api/keys/regenerate/route.ts +0 -80
- package/renderer/app/api/local-assets/[...path]/route.ts +0 -122
- package/renderer/app/api/openapi-spec/route.ts +0 -151
- package/renderer/app/api/projects/[slug]/route.ts +0 -153
- package/renderer/app/api/projects/[slug]/stats/route.ts +0 -96
- package/renderer/app/api/projects/register/route.ts +0 -152
- package/renderer/app/api/proxy/route.ts +0 -149
- package/renderer/app/api/proxy-stream/route.ts +0 -168
- package/renderer/app/api/redirects/route.ts +0 -47
- package/renderer/app/api/schema/route.ts +0 -73
- package/renderer/app/api/subdomains/check/route.ts +0 -172
- package/renderer/app/api/suggestions/route.ts +0 -144
- package/renderer/app/layout.tsx +0 -54
- package/renderer/app/llms-full.txt/route.ts +0 -346
- package/renderer/app/llms.txt/route.ts +0 -279
- package/renderer/app/page.tsx +0 -14
- package/renderer/app/robots.txt/route.ts +0 -84
- package/renderer/app/sitemap.xml/route.ts +0 -199
- package/renderer/components/docs/index.ts +0 -12
- package/renderer/components/docs/mdx/accordion.tsx +0 -169
- package/renderer/components/docs/mdx/badge.tsx +0 -132
- package/renderer/components/docs/mdx/callouts.tsx +0 -154
- package/renderer/components/docs/mdx/cards.tsx +0 -241
- package/renderer/components/docs/mdx/changelog.tsx +0 -120
- package/renderer/components/docs/mdx/code-block.tsx +0 -186
- package/renderer/components/docs/mdx/code-group.tsx +0 -421
- package/renderer/components/docs/mdx/file-embeds.tsx +0 -105
- package/renderer/components/docs/mdx/frame.tsx +0 -112
- package/renderer/components/docs/mdx/highlight.tsx +0 -151
- package/renderer/components/docs/mdx/iframe.tsx +0 -134
- package/renderer/components/docs/mdx/image.tsx +0 -235
- package/renderer/components/docs/mdx/index.ts +0 -237
- package/renderer/components/docs/mdx/landing.tsx +0 -684
- package/renderer/components/docs/mdx/mermaid.tsx +0 -240
- package/renderer/components/docs/mdx/param-field.tsx +0 -200
- package/renderer/components/docs/mdx/steps.tsx +0 -113
- package/renderer/components/docs/mdx/tabs.tsx +0 -86
- package/renderer/components/docs/mdx-renderer.tsx +0 -100
- package/renderer/components/docs/navigation/breadcrumbs.tsx +0 -76
- package/renderer/components/docs/navigation/index.ts +0 -8
- package/renderer/components/docs/navigation/page-nav.tsx +0 -64
- package/renderer/components/docs/navigation/sidebar.tsx +0 -515
- package/renderer/components/docs/navigation/toc.tsx +0 -113
- package/renderer/components/docs/notice.tsx +0 -105
- package/renderer/components/docs-header.tsx +0 -278
- package/renderer/components/docs-viewer/agent/agent-chat.tsx +0 -2076
- package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +0 -90
- package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +0 -49
- package/renderer/components/docs-viewer/agent/cards/index.tsx +0 -50
- package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +0 -212
- package/renderer/components/docs-viewer/agent/cards/types.ts +0 -84
- package/renderer/components/docs-viewer/agent/chat-message.tsx +0 -17
- package/renderer/components/docs-viewer/agent/index.tsx +0 -6
- package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +0 -119
- package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +0 -46
- package/renderer/components/docs-viewer/agent/messages/index.ts +0 -17
- package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +0 -721
- package/renderer/components/docs-viewer/agent/messages/types.ts +0 -61
- package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +0 -24
- package/renderer/components/docs-viewer/agent/messages/user-message.tsx +0 -51
- package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +0 -1283
- package/renderer/components/docs-viewer/content/changelog-page.tsx +0 -331
- package/renderer/components/docs-viewer/content/doc-page.tsx +0 -367
- package/renderer/components/docs-viewer/content/documentation-viewer.tsx +0 -17
- package/renderer/components/docs-viewer/content/index.tsx +0 -29
- package/renderer/components/docs-viewer/content/not-found-page.tsx +0 -330
- package/renderer/components/docs-viewer/content/request-details.tsx +0 -330
- package/renderer/components/docs-viewer/content/sections/auth.tsx +0 -69
- package/renderer/components/docs-viewer/content/sections/body.tsx +0 -66
- package/renderer/components/docs-viewer/content/sections/headers.tsx +0 -43
- package/renderer/components/docs-viewer/content/sections/overview.tsx +0 -40
- package/renderer/components/docs-viewer/content/sections/parameters.tsx +0 -43
- package/renderer/components/docs-viewer/content/sections/responses.tsx +0 -87
- package/renderer/components/docs-viewer/global-auth-modal.tsx +0 -352
- package/renderer/components/docs-viewer/index.tsx +0 -1670
- package/renderer/components/docs-viewer/playground/auth-editor.tsx +0 -280
- package/renderer/components/docs-viewer/playground/body-editor.tsx +0 -221
- package/renderer/components/docs-viewer/playground/code-editor.tsx +0 -224
- package/renderer/components/docs-viewer/playground/code-snippet.tsx +0 -387
- package/renderer/components/docs-viewer/playground/graphql-playground.tsx +0 -745
- package/renderer/components/docs-viewer/playground/index.tsx +0 -671
- package/renderer/components/docs-viewer/playground/key-value-editor.tsx +0 -261
- package/renderer/components/docs-viewer/playground/method-selector.tsx +0 -60
- package/renderer/components/docs-viewer/playground/request-builder.tsx +0 -179
- package/renderer/components/docs-viewer/playground/request-tabs.tsx +0 -237
- package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +0 -21
- package/renderer/components/docs-viewer/playground/response-cards/index.tsx +0 -93
- package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +0 -16
- package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +0 -23
- package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +0 -268
- package/renderer/components/docs-viewer/playground/response-cards/types.ts +0 -82
- package/renderer/components/docs-viewer/playground/response-viewer.tsx +0 -43
- package/renderer/components/docs-viewer/search/index.ts +0 -2
- package/renderer/components/docs-viewer/search/search-dialog.tsx +0 -331
- package/renderer/components/docs-viewer/search/use-search.ts +0 -117
- package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +0 -431
- package/renderer/components/docs-viewer/shared/method-badge.tsx +0 -41
- package/renderer/components/docs-viewer/shared/schema-viewer.tsx +0 -349
- package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +0 -259
- package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +0 -316
- package/renderer/components/docs-viewer/sidebar/index.tsx +0 -282
- package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +0 -202
- package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +0 -118
- package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +0 -212
- package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +0 -38
- package/renderer/components/theme-provider.tsx +0 -11
- package/renderer/components/theme-toggle.tsx +0 -76
- package/renderer/components/ui/badge.tsx +0 -46
- package/renderer/components/ui/button.tsx +0 -59
- package/renderer/components/ui/dialog.tsx +0 -118
- package/renderer/components/ui/dropdown-menu.tsx +0 -257
- package/renderer/components/ui/input.tsx +0 -21
- package/renderer/components/ui/label.tsx +0 -24
- package/renderer/components/ui/navigation-menu.tsx +0 -168
- package/renderer/components/ui/select.tsx +0 -190
- package/renderer/components/ui/spinner.tsx +0 -114
- package/renderer/components/ui/tabs.tsx +0 -66
- package/renderer/components/ui/tooltip.tsx +0 -61
- package/renderer/hooks/use-code-copy.ts +0 -88
- package/renderer/hooks/use-openapi-title.ts +0 -44
- package/renderer/lib/api-docs/agent/index.ts +0 -6
- package/renderer/lib/api-docs/agent/indexer.ts +0 -323
- package/renderer/lib/api-docs/agent/spec-summary.ts +0 -335
- package/renderer/lib/api-docs/agent/types.ts +0 -116
- package/renderer/lib/api-docs/auth/auth-context.tsx +0 -225
- package/renderer/lib/api-docs/auth/auth-storage.ts +0 -87
- package/renderer/lib/api-docs/auth/crypto.ts +0 -89
- package/renderer/lib/api-docs/auth/index.ts +0 -4
- package/renderer/lib/api-docs/code-editor/db.ts +0 -164
- package/renderer/lib/api-docs/code-editor/hooks.ts +0 -266
- package/renderer/lib/api-docs/code-editor/mode-context.tsx +0 -207
- package/renderer/lib/api-docs/code-editor/types.ts +0 -105
- package/renderer/lib/api-docs/codegen/definitions.ts +0 -297
- package/renderer/lib/api-docs/codegen/har.ts +0 -251
- package/renderer/lib/api-docs/codegen/index.ts +0 -159
- package/renderer/lib/api-docs/factories.ts +0 -170
- package/renderer/lib/api-docs/mobile-context.tsx +0 -112
- package/renderer/lib/api-docs/navigation-context.tsx +0 -88
- package/renderer/lib/api-docs/parsers/graphql/README.md +0 -129
- package/renderer/lib/api-docs/parsers/graphql/index.ts +0 -91
- package/renderer/lib/api-docs/parsers/graphql/parser.ts +0 -491
- package/renderer/lib/api-docs/parsers/graphql/transformer.ts +0 -246
- package/renderer/lib/api-docs/parsers/graphql/types.ts +0 -283
- package/renderer/lib/api-docs/parsers/openapi/README.md +0 -32
- package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +0 -60
- package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +0 -574
- package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +0 -403
- package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +0 -232
- package/renderer/lib/api-docs/parsers/openapi/index.ts +0 -171
- package/renderer/lib/api-docs/parsers/openapi/transformer.ts +0 -278
- package/renderer/lib/api-docs/parsers/openapi/validator.ts +0 -31
- package/renderer/lib/api-docs/playground/context.tsx +0 -107
- package/renderer/lib/api-docs/playground/navigation-context.tsx +0 -124
- package/renderer/lib/api-docs/playground/request-builder.ts +0 -223
- package/renderer/lib/api-docs/playground/request-runner.ts +0 -282
- package/renderer/lib/api-docs/playground/types.ts +0 -35
- package/renderer/lib/api-docs/types.ts +0 -269
- package/renderer/lib/api-docs/utils.ts +0 -311
- package/renderer/lib/cache.ts +0 -193
- package/renderer/lib/docs/config/domain-schema.ts +0 -260
- package/renderer/lib/docs/config/index.ts +0 -43
- package/renderer/lib/docs/config/loader.ts +0 -142
- package/renderer/lib/docs/config/schema.ts +0 -308
- package/renderer/lib/docs/index.ts +0 -12
- package/renderer/lib/docs/mdx/compiler.ts +0 -176
- package/renderer/lib/docs/mdx/frontmatter.ts +0 -91
- package/renderer/lib/docs/mdx/index.ts +0 -26
- package/renderer/lib/docs/navigation/generator.ts +0 -348
- package/renderer/lib/docs/navigation/index.ts +0 -12
- package/renderer/lib/docs/navigation/types.ts +0 -123
- package/renderer/lib/docs-navigation-context.tsx +0 -80
- package/renderer/lib/multi-tenant/context.ts +0 -105
- package/renderer/lib/storage/blob.ts +0 -1083
- package/renderer/lib/utils/icons.ts +0 -48
- package/renderer/lib/utils.ts +0 -6
- package/renderer/next.config.ts +0 -76
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
import { NextResponse } from 'next/server';
|
|
2
|
+
import { readFileSync, existsSync, readdirSync } from 'fs';
|
|
3
|
+
import { join, basename, isAbsolute } from 'path';
|
|
4
|
+
import matter from 'gray-matter';
|
|
5
|
+
import { CacheUtils } from '@/lib/cache';
|
|
6
|
+
import { importOpenAPISpec } from '@/lib/api-docs/parsers/openapi';
|
|
7
|
+
import { generateAPISummary, formatAPISummaryForPrompt } from '@/lib/api-docs/agent/spec-summary';
|
|
8
|
+
import { getProjectContent } from '@/lib/storage/blob';
|
|
9
|
+
import { isDevMode, shouldShowItem } from '@/lib/docs/config/environment';
|
|
10
|
+
// Configuration
|
|
11
|
+
const STARTER_PATH = process.env.STARTER_PATH || 'devdoc-docs';
|
|
12
|
+
const LOCAL_SPEC_PATH = process.env.LOCAL_SPEC_PATH || `${STARTER_PATH}/api-reference/openapi.json`;
|
|
13
|
+
// Helper to resolve paths - supports both relative and absolute STARTER_PATH
|
|
14
|
+
function resolvePath(...paths) {
|
|
15
|
+
if (isAbsolute(STARTER_PATH)) {
|
|
16
|
+
return join(STARTER_PATH, ...paths);
|
|
17
|
+
}
|
|
18
|
+
return join(process.cwd(), STARTER_PATH, ...paths);
|
|
19
|
+
}
|
|
20
|
+
// Get the content root directory
|
|
21
|
+
function getContentRoot() {
|
|
22
|
+
if (isAbsolute(STARTER_PATH)) {
|
|
23
|
+
return STARTER_PATH;
|
|
24
|
+
}
|
|
25
|
+
return join(process.cwd(), STARTER_PATH);
|
|
26
|
+
}
|
|
27
|
+
// Debug logging - only in verbose mode
|
|
28
|
+
if (process.env.DEVDOC_VERBOSE === 'true') {
|
|
29
|
+
console.log('[Collections] Config:', {
|
|
30
|
+
starterPath: STARTER_PATH,
|
|
31
|
+
localSpecPath: LOCAL_SPEC_PATH
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// Cache configuration
|
|
35
|
+
const CACHE_KEY = 'collections-local';
|
|
36
|
+
const CACHE_TTL = 60 * 5 // 5 minutes
|
|
37
|
+
;
|
|
38
|
+
const FALLBACK_CACHE_KEY = `${CACHE_KEY}-fallback`;
|
|
39
|
+
const SUMMARY_CACHE_KEY = 'api-summary-local';
|
|
40
|
+
const SUMMARY_CACHE_TTL = 60 * 60 * 24 // 1 day
|
|
41
|
+
;
|
|
42
|
+
// Load GraphQL schema from local file
|
|
43
|
+
function loadGraphQLSchema(schemaPath) {
|
|
44
|
+
try {
|
|
45
|
+
// Resolve the path similar to OpenAPI spec
|
|
46
|
+
const relativePath = schemaPath;
|
|
47
|
+
const fullPath = relativePath.startsWith(STARTER_PATH) || isAbsolute(relativePath) ? isAbsolute(relativePath) ? relativePath : resolvePath(relativePath.replace(STARTER_PATH + '/', '')) : resolvePath(relativePath);
|
|
48
|
+
if (!existsSync(fullPath)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
52
|
+
return content;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('[Collections] Error loading GraphQL schema:', error);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Load OpenAPI spec from local file
|
|
59
|
+
function loadLocalSpec(specPath) {
|
|
60
|
+
try {
|
|
61
|
+
// Use provided path or default
|
|
62
|
+
const relativePath = specPath || LOCAL_SPEC_PATH;
|
|
63
|
+
// If the path already includes STARTER_PATH prefix, use it; otherwise prepend
|
|
64
|
+
const fullPath = relativePath.startsWith(STARTER_PATH) || isAbsolute(relativePath) ? isAbsolute(relativePath) ? relativePath : resolvePath(relativePath.replace(STARTER_PATH + '/', '')) : resolvePath(relativePath);
|
|
65
|
+
if (!existsSync(fullPath)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
69
|
+
const spec = JSON.parse(content);
|
|
70
|
+
return spec;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error('[Collections] Error loading local spec:', error);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Load docs.json configuration
|
|
77
|
+
function loadDocsConfig() {
|
|
78
|
+
try {
|
|
79
|
+
const configPath = resolvePath('docs.json');
|
|
80
|
+
if (!existsSync(configPath)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
84
|
+
return JSON.parse(content);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error('[Collections] Error loading docs.json:', error);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Load theme.json configuration
|
|
91
|
+
function loadThemeConfig() {
|
|
92
|
+
try {
|
|
93
|
+
const configPath = resolvePath('theme.json');
|
|
94
|
+
if (!existsSync(configPath)) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
98
|
+
return JSON.parse(content);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('[Collections] Error loading theme.json:', error);
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Load custom CSS content
|
|
105
|
+
function loadCustomCss(cssPath) {
|
|
106
|
+
if (!cssPath) return null;
|
|
107
|
+
try {
|
|
108
|
+
const fullPath = resolvePath(cssPath);
|
|
109
|
+
if (!existsSync(fullPath)) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return readFileSync(fullPath, 'utf-8');
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error('[Collections] Error loading custom CSS:', error);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Load MDX page metadata
|
|
119
|
+
function loadPageMeta(pagePath) {
|
|
120
|
+
try {
|
|
121
|
+
const contentRoot = getContentRoot();
|
|
122
|
+
// Try .mdx then .md
|
|
123
|
+
let fullPath = join(contentRoot, `${pagePath}.mdx`);
|
|
124
|
+
if (!existsSync(fullPath)) {
|
|
125
|
+
fullPath = join(contentRoot, `${pagePath}.md`);
|
|
126
|
+
}
|
|
127
|
+
if (!existsSync(fullPath)) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
131
|
+
const { data } = matter(content);
|
|
132
|
+
return {
|
|
133
|
+
title: data.title || basename(pagePath),
|
|
134
|
+
description: data.description,
|
|
135
|
+
icon: data.icon
|
|
136
|
+
};
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error('[Collections] Error loading page meta:', pagePath, error);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Extract navigation tabs from docs.json in order
|
|
143
|
+
// Filters out private tabs when in production mode
|
|
144
|
+
function buildNavigationTabs(config, devMode) {
|
|
145
|
+
const tabs = [];
|
|
146
|
+
const isDev = devMode ?? isDevMode();
|
|
147
|
+
if (!config.navigation?.tabs) {
|
|
148
|
+
return tabs;
|
|
149
|
+
}
|
|
150
|
+
config.navigation.tabs.forEach((tab, index)=>{
|
|
151
|
+
// Skip private tabs in production mode
|
|
152
|
+
if (!shouldShowItem(tab.visibility, isDev)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Convert tab name to id (e.g., "API Reference" -> "api-reference")
|
|
156
|
+
const id = tab.tab.toLowerCase().replace(/\s+/g, '-');
|
|
157
|
+
// Determine the type (default to 'docs' if not specified)
|
|
158
|
+
const type = tab.type || 'docs';
|
|
159
|
+
// Build versions array for openapi tabs
|
|
160
|
+
let versions;
|
|
161
|
+
if (tab.type === 'openapi' && tab.versions && tab.versions.length > 0) {
|
|
162
|
+
versions = tab.versions.map((v)=>({
|
|
163
|
+
version: v.version,
|
|
164
|
+
spec: v.spec,
|
|
165
|
+
default: v.default || false
|
|
166
|
+
}));
|
|
167
|
+
// Ensure at least one default
|
|
168
|
+
if (!versions.some((v)=>v.default)) {
|
|
169
|
+
versions[0].default = true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Build graphql schemas array for graphql tabs
|
|
173
|
+
let graphqlSchemas;
|
|
174
|
+
if (tab.type === 'graphql') {
|
|
175
|
+
if (tab.schemas && tab.schemas.length > 0) {
|
|
176
|
+
// Multiple schemas
|
|
177
|
+
graphqlSchemas = tab.schemas.map((s)=>({
|
|
178
|
+
name: s.name || 'GraphQL API',
|
|
179
|
+
schema: s.schema,
|
|
180
|
+
endpoint: s.endpoint,
|
|
181
|
+
default: s.default || false
|
|
182
|
+
}));
|
|
183
|
+
// Ensure at least one default
|
|
184
|
+
if (!graphqlSchemas.some((s)=>s.default)) {
|
|
185
|
+
graphqlSchemas[0].default = true;
|
|
186
|
+
}
|
|
187
|
+
} else if (tab.schema && tab.endpoint) {
|
|
188
|
+
// Single schema
|
|
189
|
+
graphqlSchemas = [
|
|
190
|
+
{
|
|
191
|
+
name: tab.tab,
|
|
192
|
+
schema: tab.schema,
|
|
193
|
+
endpoint: tab.endpoint,
|
|
194
|
+
default: true
|
|
195
|
+
}
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
tabs.push({
|
|
200
|
+
id,
|
|
201
|
+
tab: tab.tab,
|
|
202
|
+
type,
|
|
203
|
+
path: tab.path,
|
|
204
|
+
order: index,
|
|
205
|
+
versions,
|
|
206
|
+
graphqlSchemas,
|
|
207
|
+
visibility: tab.visibility
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
return tabs;
|
|
211
|
+
}
|
|
212
|
+
// Build documentation groups from docs.json
|
|
213
|
+
// Filters out private tabs and groups when in production mode
|
|
214
|
+
function buildDocGroups(config, devMode) {
|
|
215
|
+
const groups = [];
|
|
216
|
+
const isDev = devMode ?? isDevMode();
|
|
217
|
+
if (!config.navigation?.tabs) {
|
|
218
|
+
return groups;
|
|
219
|
+
}
|
|
220
|
+
// Helper to process a page item (string or nested group)
|
|
221
|
+
const processPageItem = (pageItem, index, parentGroup)=>{
|
|
222
|
+
// Handle nested group
|
|
223
|
+
if (typeof pageItem === 'object' && 'group' in pageItem) {
|
|
224
|
+
const nestedGroup = pageItem;
|
|
225
|
+
const children = [];
|
|
226
|
+
for(let j = 0; j < nestedGroup.pages.length; j++){
|
|
227
|
+
const childPath = nestedGroup.pages[j];
|
|
228
|
+
if (typeof childPath === 'string') {
|
|
229
|
+
const childMeta = loadPageMeta(childPath);
|
|
230
|
+
if (childMeta) {
|
|
231
|
+
children.push({
|
|
232
|
+
id: `doc-${childPath.replace(/\//g, '-')}`,
|
|
233
|
+
slug: childPath,
|
|
234
|
+
title: childMeta.title,
|
|
235
|
+
description: childMeta.description,
|
|
236
|
+
icon: childMeta.icon,
|
|
237
|
+
filePath: childPath,
|
|
238
|
+
group: nestedGroup.group,
|
|
239
|
+
order: j
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (children.length > 0) {
|
|
245
|
+
// Return a group item with children
|
|
246
|
+
return {
|
|
247
|
+
id: `group-${nestedGroup.group}`.toLowerCase().replace(/\s+/g, '-'),
|
|
248
|
+
slug: '',
|
|
249
|
+
title: nestedGroup.group,
|
|
250
|
+
filePath: '',
|
|
251
|
+
group: parentGroup,
|
|
252
|
+
order: index,
|
|
253
|
+
isGroup: true,
|
|
254
|
+
children
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
// Handle string page path
|
|
260
|
+
const pagePath = pageItem;
|
|
261
|
+
const meta = loadPageMeta(pagePath);
|
|
262
|
+
if (meta) {
|
|
263
|
+
return {
|
|
264
|
+
id: `doc-${pagePath.replace(/\//g, '-')}`,
|
|
265
|
+
slug: pagePath,
|
|
266
|
+
title: meta.title,
|
|
267
|
+
description: meta.description,
|
|
268
|
+
icon: meta.icon,
|
|
269
|
+
filePath: pagePath,
|
|
270
|
+
group: parentGroup,
|
|
271
|
+
order: index
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return null;
|
|
275
|
+
};
|
|
276
|
+
// Iterate through all tabs and their groups
|
|
277
|
+
for (const tab of config.navigation.tabs){
|
|
278
|
+
// Skip private tabs in production mode
|
|
279
|
+
if (!shouldShowItem(tab.visibility, isDev)) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
// Skip tabs without groups (like API Reference with just href)
|
|
283
|
+
if (!tab.groups) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
for (const group of tab.groups){
|
|
287
|
+
// Skip private groups in production mode
|
|
288
|
+
if (!shouldShowItem(group.visibility, isDev)) {
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
const pages = [];
|
|
292
|
+
for(let i = 0; i < group.pages.length; i++){
|
|
293
|
+
const pageItem = group.pages[i];
|
|
294
|
+
const page = processPageItem(pageItem, i, group.group);
|
|
295
|
+
if (page) {
|
|
296
|
+
pages.push(page);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
if (pages.length > 0) {
|
|
300
|
+
groups.push({
|
|
301
|
+
id: `group-${tab.tab}-${group.group}`.toLowerCase().replace(/\s+/g, '-'),
|
|
302
|
+
title: group.group,
|
|
303
|
+
pages,
|
|
304
|
+
order: groups.length,
|
|
305
|
+
icon: group.icon
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return groups;
|
|
311
|
+
}
|
|
312
|
+
// Scan changelog directory for release files
|
|
313
|
+
function scanChangelogReleases() {
|
|
314
|
+
const releases = [];
|
|
315
|
+
const changelogDir = resolvePath('changelog');
|
|
316
|
+
if (!existsSync(changelogDir)) {
|
|
317
|
+
return releases;
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
const files = readdirSync(changelogDir);
|
|
321
|
+
for (const file of files){
|
|
322
|
+
// Only process versioned files (v1.0.0.mdx, etc.), skip latest.mdx and index files
|
|
323
|
+
if (!file.match(/^v[\d.]+\.mdx?$/)) {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const filePath = join(changelogDir, file);
|
|
327
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
328
|
+
const { data } = matter(content);
|
|
329
|
+
const version = data.version || file.replace(/\.mdx?$/, '');
|
|
330
|
+
releases.push({
|
|
331
|
+
version,
|
|
332
|
+
date: data.date || '',
|
|
333
|
+
title: data.title || version,
|
|
334
|
+
slug: `changelog/${file.replace(/\.mdx?$/, '')}`
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
// Sort by version (newest first)
|
|
338
|
+
releases.sort((a, b)=>{
|
|
339
|
+
const versionA = a.version.replace(/^v/, '').split('.').map(Number);
|
|
340
|
+
const versionB = b.version.replace(/^v/, '').split('.').map(Number);
|
|
341
|
+
for(let i = 0; i < Math.max(versionA.length, versionB.length); i++){
|
|
342
|
+
const numA = versionA[i] || 0;
|
|
343
|
+
const numB = versionB[i] || 0;
|
|
344
|
+
if (numA !== numB) return numB - numA;
|
|
345
|
+
}
|
|
346
|
+
return 0;
|
|
347
|
+
});
|
|
348
|
+
} catch (error) {
|
|
349
|
+
console.error('[Collections] Error scanning changelog:', error);
|
|
350
|
+
}
|
|
351
|
+
return releases;
|
|
352
|
+
}
|
|
353
|
+
// Get OpenAPI spec from local file
|
|
354
|
+
function getOpenApiSpec(specPath) {
|
|
355
|
+
return loadLocalSpec(specPath);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Handle multi-tenant request - fetch content from Blob Storage
|
|
359
|
+
*/ async function handleMultiTenantRequest(projectSlug, request) {
|
|
360
|
+
try {
|
|
361
|
+
const projectContent = await getProjectContent(projectSlug);
|
|
362
|
+
if (!projectContent) {
|
|
363
|
+
return NextResponse.json({
|
|
364
|
+
error: 'Project not found'
|
|
365
|
+
}, {
|
|
366
|
+
status: 404
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
// Parse docs.json from project content
|
|
370
|
+
const docsConfig = JSON.parse(projectContent.docsJson);
|
|
371
|
+
// Build navigation tabs and doc groups from config
|
|
372
|
+
// Multi-tenant projects are always in production mode (deployed), so devMode=false
|
|
373
|
+
const navigationTabs = buildNavigationTabs(docsConfig, false);
|
|
374
|
+
const docGroups = buildDocGroupsFromBlob(docsConfig, projectContent);
|
|
375
|
+
// For now, return docs-only response (no OpenAPI spec from blob)
|
|
376
|
+
return NextResponse.json({
|
|
377
|
+
id: projectSlug,
|
|
378
|
+
name: docsConfig.name || 'Documentation',
|
|
379
|
+
description: 'Documentation',
|
|
380
|
+
folders: [],
|
|
381
|
+
requests: [],
|
|
382
|
+
auth: {
|
|
383
|
+
authType: 'none',
|
|
384
|
+
authActive: true
|
|
385
|
+
},
|
|
386
|
+
headers: [],
|
|
387
|
+
variables: [],
|
|
388
|
+
apiSummary: null,
|
|
389
|
+
docGroups,
|
|
390
|
+
navigationTabs,
|
|
391
|
+
changelogReleases: [],
|
|
392
|
+
docsName: docsConfig.name || null,
|
|
393
|
+
docsFavicon: docsConfig.favicon || null,
|
|
394
|
+
docsLogo: null,
|
|
395
|
+
docsHeader: null,
|
|
396
|
+
docsNavbar: null,
|
|
397
|
+
docsColors: null,
|
|
398
|
+
defaultTheme: null,
|
|
399
|
+
customCss: null,
|
|
400
|
+
apiVersions: [],
|
|
401
|
+
selectedApiVersion: null,
|
|
402
|
+
notice: docsConfig.notice || null,
|
|
403
|
+
isMultiTenant: true,
|
|
404
|
+
projectSlug
|
|
405
|
+
}, {
|
|
406
|
+
headers: {
|
|
407
|
+
'Content-Type': 'application/json',
|
|
408
|
+
'Cache-Control': 'public, max-age=60'
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
} catch (error) {
|
|
412
|
+
console.error('[Collections] Multi-tenant error:', error);
|
|
413
|
+
return NextResponse.json({
|
|
414
|
+
error: 'Failed to load project'
|
|
415
|
+
}, {
|
|
416
|
+
status: 500
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Build doc groups from Blob storage content
|
|
422
|
+
* Note: Multi-tenant (deployed) projects are always in production mode,
|
|
423
|
+
* so private tabs and groups are always filtered out
|
|
424
|
+
*/ function buildDocGroupsFromBlob(config, content) {
|
|
425
|
+
const groups = [];
|
|
426
|
+
// Multi-tenant projects are always in production mode (deployed)
|
|
427
|
+
const isDev = false;
|
|
428
|
+
if (!config.navigation?.tabs) {
|
|
429
|
+
return groups;
|
|
430
|
+
}
|
|
431
|
+
// Helper to find file content
|
|
432
|
+
const findFileContent = (pagePath)=>{
|
|
433
|
+
const mdxPath = `${pagePath}.mdx`;
|
|
434
|
+
const mdPath = `${pagePath}.md`;
|
|
435
|
+
const file = content.files.find((f)=>f.path === mdxPath || f.path === mdPath);
|
|
436
|
+
if (!file) return null;
|
|
437
|
+
try {
|
|
438
|
+
const { data } = matter(file.content);
|
|
439
|
+
return {
|
|
440
|
+
title: data.title || basename(pagePath),
|
|
441
|
+
description: data.description,
|
|
442
|
+
icon: data.icon
|
|
443
|
+
};
|
|
444
|
+
} catch {
|
|
445
|
+
return {
|
|
446
|
+
title: basename(pagePath)
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
// Process tabs and groups
|
|
451
|
+
for (const tab of config.navigation.tabs){
|
|
452
|
+
// Skip private tabs (multi-tenant is always production)
|
|
453
|
+
if (!shouldShowItem(tab.visibility, isDev)) {
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
if (!tab.groups) continue;
|
|
457
|
+
for (const group of tab.groups){
|
|
458
|
+
// Skip private groups (multi-tenant is always production)
|
|
459
|
+
if (!shouldShowItem(group.visibility, isDev)) {
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
const pages = [];
|
|
463
|
+
for(let i = 0; i < group.pages.length; i++){
|
|
464
|
+
const pageItem = group.pages[i];
|
|
465
|
+
if (typeof pageItem === 'string') {
|
|
466
|
+
const meta = findFileContent(pageItem);
|
|
467
|
+
if (meta) {
|
|
468
|
+
pages.push({
|
|
469
|
+
id: `doc-${pageItem.replace(/\//g, '-')}`,
|
|
470
|
+
slug: pageItem,
|
|
471
|
+
title: meta.title,
|
|
472
|
+
description: meta.description,
|
|
473
|
+
icon: meta.icon,
|
|
474
|
+
filePath: pageItem,
|
|
475
|
+
group: group.group,
|
|
476
|
+
order: i
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
} else if ('group' in pageItem) {
|
|
480
|
+
// Nested group
|
|
481
|
+
const children = [];
|
|
482
|
+
for(let j = 0; j < pageItem.pages.length; j++){
|
|
483
|
+
const childPath = pageItem.pages[j];
|
|
484
|
+
if (typeof childPath === 'string') {
|
|
485
|
+
const childMeta = findFileContent(childPath);
|
|
486
|
+
if (childMeta) {
|
|
487
|
+
children.push({
|
|
488
|
+
id: `doc-${childPath.replace(/\//g, '-')}`,
|
|
489
|
+
slug: childPath,
|
|
490
|
+
title: childMeta.title,
|
|
491
|
+
description: childMeta.description,
|
|
492
|
+
icon: childMeta.icon,
|
|
493
|
+
filePath: childPath,
|
|
494
|
+
group: pageItem.group,
|
|
495
|
+
order: j
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
if (children.length > 0) {
|
|
501
|
+
pages.push({
|
|
502
|
+
id: `group-${pageItem.group}`.toLowerCase().replace(/\s+/g, '-'),
|
|
503
|
+
slug: '',
|
|
504
|
+
title: pageItem.group,
|
|
505
|
+
filePath: '',
|
|
506
|
+
group: group.group,
|
|
507
|
+
order: i,
|
|
508
|
+
isGroup: true,
|
|
509
|
+
children
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (pages.length > 0) {
|
|
515
|
+
groups.push({
|
|
516
|
+
id: `group-${tab.tab}-${group.group}`.toLowerCase().replace(/\s+/g, '-'),
|
|
517
|
+
title: group.group,
|
|
518
|
+
pages,
|
|
519
|
+
order: groups.length,
|
|
520
|
+
icon: group.icon
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return groups;
|
|
526
|
+
}
|
|
527
|
+
// Helper to generate or get cached summary
|
|
528
|
+
async function getOrGenerateSummary(collection, specVersion) {
|
|
529
|
+
const versionedCacheKey = `${SUMMARY_CACHE_KEY}-v${specVersion}`;
|
|
530
|
+
const cachedSummary = await CacheUtils.get(versionedCacheKey);
|
|
531
|
+
if (cachedSummary) {
|
|
532
|
+
return cachedSummary;
|
|
533
|
+
}
|
|
534
|
+
const summary = generateAPISummary(collection);
|
|
535
|
+
const formattedSummary = formatAPISummaryForPrompt(summary);
|
|
536
|
+
await CacheUtils.set(versionedCacheKey, formattedSummary, SUMMARY_CACHE_TTL);
|
|
537
|
+
return formattedSummary;
|
|
538
|
+
}
|
|
539
|
+
export async function GET(request) {
|
|
540
|
+
try {
|
|
541
|
+
// Check for multi-tenant mode (project slug from middleware)
|
|
542
|
+
const projectSlug = request.headers.get('x-devdoc-project');
|
|
543
|
+
// If multi-tenant, fetch from Blob Storage
|
|
544
|
+
if (projectSlug && !projectSlug.startsWith('custom:')) {
|
|
545
|
+
return handleMultiTenantRequest(projectSlug, request);
|
|
546
|
+
}
|
|
547
|
+
// Parse query params
|
|
548
|
+
const { searchParams } = new URL(request.url);
|
|
549
|
+
const requestedVersion = searchParams.get('version');
|
|
550
|
+
// Load docs and theme configuration
|
|
551
|
+
const docsConfig = loadDocsConfig();
|
|
552
|
+
const themeConfig = loadThemeConfig();
|
|
553
|
+
const customCss = loadCustomCss(themeConfig?.customCss);
|
|
554
|
+
const docGroups = docsConfig ? buildDocGroups(docsConfig) : [];
|
|
555
|
+
const navigationTabs = docsConfig ? buildNavigationTabs(docsConfig) : [];
|
|
556
|
+
const changelogReleases = scanChangelogReleases();
|
|
557
|
+
// Find the OpenAPI tab and its versions
|
|
558
|
+
const openapiTab = navigationTabs.find((t)=>t.type === 'openapi');
|
|
559
|
+
const apiVersions = openapiTab?.versions || [];
|
|
560
|
+
// Determine which spec to load
|
|
561
|
+
let specPath;
|
|
562
|
+
let selectedVersion;
|
|
563
|
+
if (apiVersions.length > 0) {
|
|
564
|
+
// Find requested version or default
|
|
565
|
+
const versionConfig = requestedVersion ? apiVersions.find((v)=>v.version === requestedVersion) : apiVersions.find((v)=>v.default) || apiVersions[0];
|
|
566
|
+
if (versionConfig) {
|
|
567
|
+
specPath = versionConfig.spec;
|
|
568
|
+
selectedVersion = versionConfig.version;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
// Get OpenAPI spec (with optional path for versioned specs)
|
|
572
|
+
const spec = await getOpenApiSpec(specPath);
|
|
573
|
+
// Handle no spec available
|
|
574
|
+
if (!spec) {
|
|
575
|
+
return NextResponse.json({
|
|
576
|
+
id: 'empty',
|
|
577
|
+
name: docsConfig?.name || 'Documentation',
|
|
578
|
+
description: 'Welcome to the documentation.',
|
|
579
|
+
folders: [],
|
|
580
|
+
requests: [],
|
|
581
|
+
auth: {
|
|
582
|
+
authType: 'none',
|
|
583
|
+
authActive: true
|
|
584
|
+
},
|
|
585
|
+
headers: [],
|
|
586
|
+
variables: [],
|
|
587
|
+
apiSummary: null,
|
|
588
|
+
docGroups,
|
|
589
|
+
navigationTabs,
|
|
590
|
+
changelogReleases,
|
|
591
|
+
docsName: docsConfig?.name || null,
|
|
592
|
+
docsFavicon: docsConfig?.favicon || null,
|
|
593
|
+
docsLogo: themeConfig?.logo || null,
|
|
594
|
+
docsHeader: themeConfig?.header || null,
|
|
595
|
+
docsNavbar: themeConfig?.navbar || null,
|
|
596
|
+
docsColors: themeConfig?.colors || null,
|
|
597
|
+
defaultTheme: themeConfig?.defaultTheme || null,
|
|
598
|
+
customCss: customCss || null,
|
|
599
|
+
apiVersions,
|
|
600
|
+
selectedApiVersion: selectedVersion,
|
|
601
|
+
notice: docsConfig?.notice || null
|
|
602
|
+
}, {
|
|
603
|
+
headers: {
|
|
604
|
+
'Content-Type': 'application/json',
|
|
605
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
// Check if spec has paths
|
|
610
|
+
if (!spec.paths || Object.keys(spec.paths).length === 0) {
|
|
611
|
+
return NextResponse.json({
|
|
612
|
+
id: 'empty',
|
|
613
|
+
name: spec.info?.title || docsConfig?.name || 'Documentation',
|
|
614
|
+
description: spec.info?.description || 'No endpoints defined.',
|
|
615
|
+
folders: [],
|
|
616
|
+
requests: [],
|
|
617
|
+
auth: {
|
|
618
|
+
authType: 'none',
|
|
619
|
+
authActive: true
|
|
620
|
+
},
|
|
621
|
+
headers: [],
|
|
622
|
+
variables: [],
|
|
623
|
+
apiSummary: null,
|
|
624
|
+
docGroups,
|
|
625
|
+
navigationTabs,
|
|
626
|
+
changelogReleases,
|
|
627
|
+
docsName: docsConfig?.name || null,
|
|
628
|
+
docsFavicon: docsConfig?.favicon || null,
|
|
629
|
+
docsLogo: themeConfig?.logo || null,
|
|
630
|
+
docsHeader: themeConfig?.header || null,
|
|
631
|
+
docsNavbar: themeConfig?.navbar || null,
|
|
632
|
+
docsColors: themeConfig?.colors || null,
|
|
633
|
+
defaultTheme: themeConfig?.defaultTheme || null,
|
|
634
|
+
customCss: customCss || null,
|
|
635
|
+
apiVersions,
|
|
636
|
+
selectedApiVersion: selectedVersion,
|
|
637
|
+
notice: docsConfig?.notice || null
|
|
638
|
+
}, {
|
|
639
|
+
headers: {
|
|
640
|
+
'Content-Type': 'application/json',
|
|
641
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
642
|
+
}
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
// Convert to BrainfishCollection using our parser
|
|
646
|
+
const collections = await importOpenAPISpec(spec);
|
|
647
|
+
const collection = collections[0];
|
|
648
|
+
if (!collection) {
|
|
649
|
+
return NextResponse.json(null, {
|
|
650
|
+
headers: {
|
|
651
|
+
'Content-Type': 'application/json',
|
|
652
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
// Generate or get cached API summary
|
|
657
|
+
const specVersion = spec.info?.version || 'unknown';
|
|
658
|
+
const apiSummary = await getOrGenerateSummary(collection, specVersion);
|
|
659
|
+
// Return collection with summary and doc groups
|
|
660
|
+
return NextResponse.json({
|
|
661
|
+
...collection,
|
|
662
|
+
apiSummary,
|
|
663
|
+
specVersion,
|
|
664
|
+
docGroups,
|
|
665
|
+
navigationTabs,
|
|
666
|
+
changelogReleases,
|
|
667
|
+
docsName: docsConfig?.name || null,
|
|
668
|
+
docsFavicon: docsConfig?.favicon || null,
|
|
669
|
+
docsLogo: themeConfig?.logo || null,
|
|
670
|
+
docsHeader: themeConfig?.header || null,
|
|
671
|
+
docsNavbar: themeConfig?.navbar || null,
|
|
672
|
+
docsColors: themeConfig?.colors || null,
|
|
673
|
+
defaultTheme: themeConfig?.defaultTheme || null,
|
|
674
|
+
customCss: customCss || null,
|
|
675
|
+
apiVersions,
|
|
676
|
+
selectedApiVersion: selectedVersion,
|
|
677
|
+
notice: docsConfig?.notice || null
|
|
678
|
+
}, {
|
|
679
|
+
headers: {
|
|
680
|
+
'Content-Type': 'application/json',
|
|
681
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
} catch (error) {
|
|
685
|
+
console.error('[Collections] Unexpected error:', error);
|
|
686
|
+
return NextResponse.json({
|
|
687
|
+
id: 'error',
|
|
688
|
+
name: 'Documentation',
|
|
689
|
+
description: 'Failed to load documentation.',
|
|
690
|
+
folders: [],
|
|
691
|
+
requests: [],
|
|
692
|
+
auth: {
|
|
693
|
+
authType: 'none',
|
|
694
|
+
authActive: true
|
|
695
|
+
},
|
|
696
|
+
headers: [],
|
|
697
|
+
variables: [],
|
|
698
|
+
docGroups: []
|
|
699
|
+
}, {
|
|
700
|
+
headers: {
|
|
701
|
+
'Content-Type': 'application/json',
|
|
702
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate'
|
|
703
|
+
}
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
}
|