@brainfish-ai/devdoc 0.1.41 → 0.1.43
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/ai-agents/.claude/skills/bootstrap-docs/SKILL.md +710 -79
- package/ai-agents/.claude/skills/check-docs/SKILL.md +83 -8
- package/ai-agents/.claude/skills/create-doc/SKILL.md +267 -55
- package/ai-agents/.claude/skills/update-doc/SKILL.md +162 -63
- package/ai-agents/.cursor/rules/devdoc-bootstrap.mdc +145 -15
- package/ai-agents/.cursor/rules/devdoc-create.mdc +108 -57
- package/ai-agents/.cursor/rules/devdoc-update.mdc +93 -70
- package/ai-agents/.cursor/rules/devdoc.mdc +21 -0
- package/ai-agents/schemas/docs.schema.json +332 -0
- package/ai-agents/schemas/theme.schema.json +243 -0
- package/dist/cli/commands/create.js +4 -9
- package/dist/cli/commands/deploy.js +50 -25
- 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 +675 -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 +175 -0
- package/renderer/app/layout.js +47 -0
- package/renderer/app/llms-full.txt/route.js +257 -0
- package/renderer/app/llms.txt/route.js +219 -0
- package/renderer/app/page.js +12 -0
- package/renderer/app/robots.txt/route.js +66 -0
- package/renderer/app/sitemap.xml/route.js +145 -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 +315 -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 +1930 -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 +4 -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/doc-page.js +264 -0
- package/renderer/components/docs-viewer/content/documentation-viewer.js +14 -0
- package/renderer/components/docs-viewer/content/index.js +29 -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 +1552 -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 +734 -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 +163 -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 +106 -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/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/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 +154 -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 +79 -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/index.js +5 -0
- package/renderer/lib/docs/config/loader.js +113 -0
- package/renderer/lib/docs/config/schema.js +269 -0
- package/renderer/lib/docs/index.js +8 -0
- package/renderer/lib/docs/mdx/compiler.js +128 -0
- package/renderer/lib/docs/mdx/frontmatter.js +73 -0
- package/renderer/lib/docs/mdx/index.js +8 -0
- package/renderer/lib/docs/navigation/generator.js +269 -0
- package/renderer/lib/docs/navigation/index.js +4 -0
- package/renderer/lib/docs/navigation/types.js +9 -0
- package/renderer/lib/docs-navigation-context.js +40 -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/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 -1662
- 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,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI Transformer
|
|
3
|
+
*
|
|
4
|
+
* Ported from Hoppscotch's openapi/index.ts
|
|
5
|
+
* Converts OpenAPI Document to BrainfishCollection
|
|
6
|
+
*/ /* eslint-disable @typescript-eslint/no-explicit-any */ import { makeBrainfishCollection, makeBrainfishRESTRequest, makeBrainfishRESTResponseOriginalRequest } from '../../factories';
|
|
7
|
+
import { objectHasProperty, cloneDeep } from '../../utils';
|
|
8
|
+
import { hasUnresolvedRefs } from './dereferencer';
|
|
9
|
+
import { replaceOpenApiPathTemplating, parseOpenAPIParams, parseOpenAPIHeaders, parseOpenAPIVariables, parseOpenAPIResponses } from './extractors';
|
|
10
|
+
import { parseOpenAPIBody } from './extractors/body';
|
|
11
|
+
import { parseOpenAPIAuth, extractSecurityHeaders, getDefaultAuth } from './extractors/auth';
|
|
12
|
+
/**
|
|
13
|
+
* Formats an operation name for display
|
|
14
|
+
* Converts snake_case/kebab-case operationIds to readable Title Case
|
|
15
|
+
* Prefers summary over operationId if available
|
|
16
|
+
*/ function formatOperationName(info) {
|
|
17
|
+
const summary = info.summary?.trim();
|
|
18
|
+
const operationId = info.operationId?.trim();
|
|
19
|
+
// Prefer summary as it's usually more human-readable
|
|
20
|
+
if (summary) {
|
|
21
|
+
return summary;
|
|
22
|
+
}
|
|
23
|
+
// If only operationId is available, convert to readable format
|
|
24
|
+
if (operationId) {
|
|
25
|
+
return operationId// Replace underscores and hyphens with spaces
|
|
26
|
+
.replace(/[_-]/g, ' ')// Handle camelCase by adding space before capital letters
|
|
27
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')// Capitalize first letter of each word
|
|
28
|
+
.replace(/\b\w/g, (char)=>char.toUpperCase())// Clean up multiple spaces
|
|
29
|
+
.replace(/\s+/g, ' ').trim();
|
|
30
|
+
}
|
|
31
|
+
return 'Untitled Request';
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parses OpenAPI URL from document (v2 or v3)
|
|
35
|
+
*/ function parseOpenAPIUrl(doc) {
|
|
36
|
+
// OpenAPI V2 has host and basePath in document properties
|
|
37
|
+
if (objectHasProperty(doc, 'swagger')) {
|
|
38
|
+
const host = doc.host?.trim() || '<<baseUrl>>';
|
|
39
|
+
const basePath = doc.basePath?.trim() || '';
|
|
40
|
+
return `${host}${basePath}`;
|
|
41
|
+
}
|
|
42
|
+
// OpenAPI V3 has servers array
|
|
43
|
+
if (objectHasProperty(doc, 'servers')) {
|
|
44
|
+
const serverUrl = doc.servers?.[0]?.url;
|
|
45
|
+
return !serverUrl || serverUrl === './' ? '<<baseUrl>>' : serverUrl;
|
|
46
|
+
}
|
|
47
|
+
// Fallback
|
|
48
|
+
return '<<baseUrl>>';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Converts an OpenAPI path to Brainfish requests
|
|
52
|
+
*/ function convertPathToBrainfishReqs(doc, pathName, pathObj) {
|
|
53
|
+
const methods = [
|
|
54
|
+
'get',
|
|
55
|
+
'head',
|
|
56
|
+
'post',
|
|
57
|
+
'put',
|
|
58
|
+
'delete',
|
|
59
|
+
'options',
|
|
60
|
+
'patch'
|
|
61
|
+
];
|
|
62
|
+
return methods.filter((method)=>!!pathObj[method]).map((method)=>{
|
|
63
|
+
const info = pathObj[method];
|
|
64
|
+
const openAPIUrl = parseOpenAPIUrl(doc);
|
|
65
|
+
const openAPIPath = replaceOpenApiPathTemplating(pathName);
|
|
66
|
+
const endpoint = openAPIUrl.endsWith('/') && openAPIPath.startsWith('/') ? openAPIUrl + openAPIPath.slice(1) : openAPIUrl + openAPIPath;
|
|
67
|
+
const params = parseOpenAPIParams(info.parameters ?? []);
|
|
68
|
+
const baseHeaders = parseOpenAPIHeaders(info.parameters ?? []);
|
|
69
|
+
// Get the primary auth key (handled by global auth) to exclude from additional headers
|
|
70
|
+
const defaultAuth = getDefaultAuth(doc);
|
|
71
|
+
const primaryAuthKey = defaultAuth?.authType === 'api-key' ? defaultAuth.key : undefined;
|
|
72
|
+
// Extract additional security headers (e.g., agent-key when access-token is primary)
|
|
73
|
+
const securityHeaders = extractSecurityHeaders(doc, info, primaryAuthKey);
|
|
74
|
+
// Merge headers: base headers + security headers (avoiding duplicates)
|
|
75
|
+
const existingKeys = new Set(baseHeaders.map((h)=>h.key.toLowerCase()));
|
|
76
|
+
const additionalSecurityHeaders = securityHeaders.filter((h)=>!existingKeys.has(h.key.toLowerCase())).map((h)=>({
|
|
77
|
+
key: h.key,
|
|
78
|
+
value: h.value,
|
|
79
|
+
active: h.active,
|
|
80
|
+
description: h.description
|
|
81
|
+
}));
|
|
82
|
+
const headers = [
|
|
83
|
+
...baseHeaders,
|
|
84
|
+
...additionalSecurityHeaders
|
|
85
|
+
];
|
|
86
|
+
const requestVariables = parseOpenAPIVariables(info.parameters ?? []);
|
|
87
|
+
const auth = parseOpenAPIAuth(doc, info);
|
|
88
|
+
const body = parseOpenAPIBody(doc, info);
|
|
89
|
+
const displayName = formatOperationName(info);
|
|
90
|
+
const originalRequest = makeBrainfishRESTResponseOriginalRequest({
|
|
91
|
+
name: displayName,
|
|
92
|
+
method: method.toUpperCase(),
|
|
93
|
+
endpoint,
|
|
94
|
+
params,
|
|
95
|
+
headers,
|
|
96
|
+
body,
|
|
97
|
+
auth,
|
|
98
|
+
requestVariables
|
|
99
|
+
});
|
|
100
|
+
const responses = parseOpenAPIResponses(doc, info, originalRequest);
|
|
101
|
+
const request = makeBrainfishRESTRequest({
|
|
102
|
+
name: displayName,
|
|
103
|
+
description: info.description ?? null,
|
|
104
|
+
method: method.toUpperCase(),
|
|
105
|
+
endpoint,
|
|
106
|
+
params,
|
|
107
|
+
headers,
|
|
108
|
+
auth,
|
|
109
|
+
body,
|
|
110
|
+
requestVariables,
|
|
111
|
+
responses,
|
|
112
|
+
tags: info.tags ?? [],
|
|
113
|
+
operationId: info.operationId ?? undefined
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
request,
|
|
117
|
+
metadata: {
|
|
118
|
+
tags: info.tags ?? []
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Converts OpenAPI documents to BrainfishCollections
|
|
125
|
+
*/ export function convertOpenAPIToCollection(docs) {
|
|
126
|
+
// Check for unresolved references before conversion
|
|
127
|
+
for (const doc of docs){
|
|
128
|
+
if (hasUnresolvedRefs(doc)) {
|
|
129
|
+
console.warn('Document contains unresolved references which may affect import quality');
|
|
130
|
+
// Continue anyway to provide a best-effort import
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const collections = docs.map((doc)=>{
|
|
134
|
+
const name = doc.info.title;
|
|
135
|
+
const description = doc.info.description ?? null;
|
|
136
|
+
// Extract tag descriptions from OpenAPI spec
|
|
137
|
+
const tagDescriptions = {};
|
|
138
|
+
if ('tags' in doc && Array.isArray(doc.tags)) {
|
|
139
|
+
doc.tags.forEach((tag)=>{
|
|
140
|
+
if (tag.name && tag.description) {
|
|
141
|
+
tagDescriptions[tag.name] = tag.description;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// Convert all paths to requests
|
|
146
|
+
const paths = Object.entries(doc.paths ?? {}).map(([pathName, pathObj])=>convertPathToBrainfishReqs(doc, pathName, pathObj)).flat();
|
|
147
|
+
// Organize requests by tags
|
|
148
|
+
const requestsByTags = {};
|
|
149
|
+
const requestsWithoutTags = [];
|
|
150
|
+
paths.forEach(({ metadata, request })=>{
|
|
151
|
+
const tags = metadata.tags;
|
|
152
|
+
if (tags.length === 0) {
|
|
153
|
+
requestsWithoutTags.push(request);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
for (const tag of tags){
|
|
157
|
+
if (!requestsByTags[tag]) {
|
|
158
|
+
requestsByTags[tag] = [];
|
|
159
|
+
}
|
|
160
|
+
// Clone request for each tag (request can belong to multiple tags)
|
|
161
|
+
requestsByTags[tag].push(cloneDeep(request));
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
// Create folders (collections) for each tag
|
|
165
|
+
const folders = Object.entries(requestsByTags).map(([tagName, requests])=>makeBrainfishCollection({
|
|
166
|
+
name: tagName,
|
|
167
|
+
description: tagDescriptions[tagName] ?? null,
|
|
168
|
+
requests,
|
|
169
|
+
folders: [],
|
|
170
|
+
variables: [],
|
|
171
|
+
auth: {
|
|
172
|
+
authType: 'inherit',
|
|
173
|
+
authActive: true
|
|
174
|
+
},
|
|
175
|
+
headers: []
|
|
176
|
+
}));
|
|
177
|
+
// Create main collection
|
|
178
|
+
return makeBrainfishCollection({
|
|
179
|
+
name,
|
|
180
|
+
description,
|
|
181
|
+
folders,
|
|
182
|
+
requests: requestsWithoutTags,
|
|
183
|
+
variables: [],
|
|
184
|
+
auth: {
|
|
185
|
+
authType: 'inherit',
|
|
186
|
+
authActive: true
|
|
187
|
+
},
|
|
188
|
+
headers: []
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
return collections;
|
|
192
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI Validator
|
|
3
|
+
*
|
|
4
|
+
* Ported from Hoppscotch's openapi-import-worker.ts
|
|
5
|
+
* Converts Web Worker pattern to direct function calls for Next.js
|
|
6
|
+
*/ import SwaggerParser from '@apidevtools/swagger-parser';
|
|
7
|
+
/**
|
|
8
|
+
* Validates an OpenAPI document using SwaggerParser
|
|
9
|
+
*
|
|
10
|
+
* @param docs - The OpenAPI document to validate
|
|
11
|
+
* @returns Promise resolving to validated OpenAPI document
|
|
12
|
+
* @throws Error if validation fails
|
|
13
|
+
*/ export async function validateOpenAPISpec(docs) {
|
|
14
|
+
try {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
const validated = await SwaggerParser.validate(docs, {
|
|
17
|
+
// @ts-expect-error - this is a valid option, but types may not be updated
|
|
18
|
+
continueOnError: true
|
|
19
|
+
});
|
|
20
|
+
return validated;
|
|
21
|
+
} catch {
|
|
22
|
+
throw new Error('COULD_NOT_VALIDATE');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useState, useCallback } from 'react';
|
|
4
|
+
const PlaygroundContext = /*#__PURE__*/ createContext(null);
|
|
5
|
+
export function PlaygroundProvider({ children }) {
|
|
6
|
+
const [pendingPrefill, setPendingPrefill] = useState(null);
|
|
7
|
+
const [currentRequestPayload, setCurrentRequestPayloadState] = useState(null);
|
|
8
|
+
const [triggerSend, setTriggerSend] = useState(false);
|
|
9
|
+
const setPrefill = useCallback((data)=>{
|
|
10
|
+
setPendingPrefill(data);
|
|
11
|
+
}, []);
|
|
12
|
+
const clearPrefill = useCallback(()=>{
|
|
13
|
+
setPendingPrefill(null);
|
|
14
|
+
}, []);
|
|
15
|
+
const setCurrentRequestPayload = useCallback((payload)=>{
|
|
16
|
+
setCurrentRequestPayloadState(payload);
|
|
17
|
+
}, []);
|
|
18
|
+
const requestSend = useCallback(()=>{
|
|
19
|
+
setTriggerSend(true);
|
|
20
|
+
}, []);
|
|
21
|
+
const clearSendTrigger = useCallback(()=>{
|
|
22
|
+
setTriggerSend(false);
|
|
23
|
+
}, []);
|
|
24
|
+
return /*#__PURE__*/ _jsx(PlaygroundContext.Provider, {
|
|
25
|
+
value: {
|
|
26
|
+
pendingPrefill,
|
|
27
|
+
setPrefill,
|
|
28
|
+
clearPrefill,
|
|
29
|
+
currentRequestPayload,
|
|
30
|
+
setCurrentRequestPayload,
|
|
31
|
+
triggerSend,
|
|
32
|
+
requestSend,
|
|
33
|
+
clearSendTrigger
|
|
34
|
+
},
|
|
35
|
+
children: children
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export function usePlaygroundPrefill() {
|
|
39
|
+
const context = useContext(PlaygroundContext);
|
|
40
|
+
if (!context) {
|
|
41
|
+
throw new Error('usePlaygroundPrefill must be used within a PlaygroundProvider');
|
|
42
|
+
}
|
|
43
|
+
return context;
|
|
44
|
+
}
|
|
45
|
+
export function useCurrentRequestPayload() {
|
|
46
|
+
const context = useContext(PlaygroundContext);
|
|
47
|
+
if (!context) {
|
|
48
|
+
throw new Error('useCurrentRequestPayload must be used within a PlaygroundProvider');
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
currentRequestPayload: context.currentRequestPayload,
|
|
52
|
+
setCurrentRequestPayload: context.setCurrentRequestPayload
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function useSendTrigger() {
|
|
56
|
+
const context = useContext(PlaygroundContext);
|
|
57
|
+
if (!context) {
|
|
58
|
+
throw new Error('useSendTrigger must be used within a PlaygroundProvider');
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
triggerSend: context.triggerSend,
|
|
62
|
+
requestSend: context.requestSend,
|
|
63
|
+
clearSendTrigger: context.clearSendTrigger
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useState, useCallback } from 'react';
|
|
4
|
+
const PlaygroundNavigationContext = /*#__PURE__*/ createContext(undefined);
|
|
5
|
+
export function PlaygroundNavigationProvider({ children }) {
|
|
6
|
+
const [state, setState] = useState({
|
|
7
|
+
activeTab: null,
|
|
8
|
+
highlightField: null,
|
|
9
|
+
showError: false
|
|
10
|
+
});
|
|
11
|
+
const navigateToTab = useCallback((tab)=>{
|
|
12
|
+
setState((prev)=>({
|
|
13
|
+
...prev,
|
|
14
|
+
activeTab: tab,
|
|
15
|
+
highlightField: null,
|
|
16
|
+
showError: false
|
|
17
|
+
}));
|
|
18
|
+
}, []);
|
|
19
|
+
const navigateAndHighlight = useCallback((tab, field, showError = true)=>{
|
|
20
|
+
setState({
|
|
21
|
+
activeTab: tab,
|
|
22
|
+
highlightField: field || null,
|
|
23
|
+
showError
|
|
24
|
+
});
|
|
25
|
+
// Auto-clear highlight after a delay
|
|
26
|
+
if (field) {
|
|
27
|
+
setTimeout(()=>{
|
|
28
|
+
setState((prev)=>({
|
|
29
|
+
...prev,
|
|
30
|
+
highlightField: null,
|
|
31
|
+
showError: false
|
|
32
|
+
}));
|
|
33
|
+
}, 3000);
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
36
|
+
const clearHighlight = useCallback(()=>{
|
|
37
|
+
setState((prev)=>({
|
|
38
|
+
...prev,
|
|
39
|
+
highlightField: null,
|
|
40
|
+
showError: false
|
|
41
|
+
}));
|
|
42
|
+
}, []);
|
|
43
|
+
const setActiveTab = useCallback((tab)=>{
|
|
44
|
+
setState((prev)=>({
|
|
45
|
+
...prev,
|
|
46
|
+
activeTab: tab
|
|
47
|
+
}));
|
|
48
|
+
}, []);
|
|
49
|
+
const resetNavigation = useCallback(()=>{
|
|
50
|
+
setState({
|
|
51
|
+
activeTab: null,
|
|
52
|
+
highlightField: null,
|
|
53
|
+
showError: false
|
|
54
|
+
});
|
|
55
|
+
}, []);
|
|
56
|
+
return /*#__PURE__*/ _jsx(PlaygroundNavigationContext.Provider, {
|
|
57
|
+
value: {
|
|
58
|
+
state,
|
|
59
|
+
navigateToTab,
|
|
60
|
+
navigateAndHighlight,
|
|
61
|
+
clearHighlight,
|
|
62
|
+
setActiveTab,
|
|
63
|
+
resetNavigation
|
|
64
|
+
},
|
|
65
|
+
children: children
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
export function usePlaygroundNavigation() {
|
|
69
|
+
const context = useContext(PlaygroundNavigationContext);
|
|
70
|
+
if (context === undefined) {
|
|
71
|
+
throw new Error('usePlaygroundNavigation must be used within a PlaygroundNavigationProvider');
|
|
72
|
+
}
|
|
73
|
+
return context;
|
|
74
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds HTTP requests from BrainfishRESTRequest
|
|
5
|
+
* Ported and simplified from Hoppscotch's EffectiveURL and request building logic
|
|
6
|
+
*/ /**
|
|
7
|
+
* Builds auth headers from auth configuration
|
|
8
|
+
*/ function buildAuthHeaders(auth) {
|
|
9
|
+
const headers = {};
|
|
10
|
+
if (auth.authType === 'basic' && auth.authActive) {
|
|
11
|
+
const credentials = btoa(`${auth.username}:${auth.password}`);
|
|
12
|
+
headers['Authorization'] = `Basic ${credentials}`;
|
|
13
|
+
} else if (auth.authType === 'bearer' && auth.authActive) {
|
|
14
|
+
headers['Authorization'] = `Bearer ${auth.token}`;
|
|
15
|
+
} else if (auth.authType === 'api-key' && auth.authActive) {
|
|
16
|
+
if (auth.addTo === 'HEADERS') {
|
|
17
|
+
headers[auth.key] = auth.value;
|
|
18
|
+
}
|
|
19
|
+
} else if (auth.authType === 'oauth-2' && auth.authActive) {
|
|
20
|
+
// For OAuth2, we'll use the token if available
|
|
21
|
+
if (auth.grantTypeInfo.token) {
|
|
22
|
+
headers['Authorization'] = `Bearer ${auth.grantTypeInfo.token}`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return headers;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Builds auth query parameters
|
|
29
|
+
*/ function buildAuthParams(auth) {
|
|
30
|
+
const params = {};
|
|
31
|
+
if (auth.authType === 'api-key' && auth.authActive) {
|
|
32
|
+
if (auth.addTo === 'QUERY_PARAMS') {
|
|
33
|
+
params[auth.key] = auth.value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return params;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Builds request body from body configuration
|
|
40
|
+
*/ function buildRequestBody(body, bodyValue) {
|
|
41
|
+
if (!body.body || body.contentType === null) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
// Use provided bodyValue if available (from playground editor)
|
|
45
|
+
if (bodyValue !== undefined && bodyValue !== null) {
|
|
46
|
+
if (body.contentType === 'application/json') {
|
|
47
|
+
// Return as-is - user might be editing
|
|
48
|
+
return bodyValue;
|
|
49
|
+
} else if (body.contentType === 'application/x-www-form-urlencoded') {
|
|
50
|
+
// Parse as form data
|
|
51
|
+
const params = new URLSearchParams();
|
|
52
|
+
bodyValue.split('\n').forEach((line)=>{
|
|
53
|
+
const [key, ...valueParts] = line.split(':');
|
|
54
|
+
if (key && valueParts.length > 0) {
|
|
55
|
+
params.append(key.trim(), valueParts.join(':').trim());
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return params.toString();
|
|
59
|
+
}
|
|
60
|
+
return bodyValue;
|
|
61
|
+
}
|
|
62
|
+
// Use body from request
|
|
63
|
+
if (Array.isArray(body.body)) {
|
|
64
|
+
// Form data
|
|
65
|
+
if (body.contentType === 'multipart/form-data') {
|
|
66
|
+
const formData = new FormData();
|
|
67
|
+
body.body.forEach((item)=>{
|
|
68
|
+
// Note: In a real implementation, isFile would indicate a file upload
|
|
69
|
+
// For now, we just append the string value
|
|
70
|
+
if (typeof item.value === 'string') {
|
|
71
|
+
formData.append(item.key, item.value);
|
|
72
|
+
} else {
|
|
73
|
+
// File or Blob value
|
|
74
|
+
formData.append(item.key, item.value);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return formData;
|
|
78
|
+
} else if (body.contentType === 'application/x-www-form-urlencoded') {
|
|
79
|
+
// URL encoded form
|
|
80
|
+
const params = new URLSearchParams();
|
|
81
|
+
body.body.forEach((item)=>{
|
|
82
|
+
if (typeof item.value === 'string') {
|
|
83
|
+
params.append(item.key, item.value);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
return params;
|
|
87
|
+
}
|
|
88
|
+
} else if (typeof body.body === 'string') {
|
|
89
|
+
return body.body;
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Builds the final URL with path variables and query parameters
|
|
95
|
+
*/ function buildURL(endpoint, params, variables, authParams) {
|
|
96
|
+
// Replace path variables (<<variable>> or {variable})
|
|
97
|
+
let url = endpoint;
|
|
98
|
+
variables.forEach((variable)=>{
|
|
99
|
+
// Replace <<variable>> pattern
|
|
100
|
+
url = url.replace(new RegExp(`<<${variable.key}>>`, 'g'), variable.value || '');
|
|
101
|
+
// Replace {variable} pattern
|
|
102
|
+
url = url.replace(new RegExp(`\\{${variable.key}\\}`, 'g'), variable.value || '');
|
|
103
|
+
});
|
|
104
|
+
// Build query string
|
|
105
|
+
const queryParams = new URLSearchParams();
|
|
106
|
+
// Add request params
|
|
107
|
+
params.filter((p)=>p.active && p.key).forEach((param)=>{
|
|
108
|
+
queryParams.append(param.key, param.value);
|
|
109
|
+
});
|
|
110
|
+
// Add auth params
|
|
111
|
+
Object.entries(authParams).forEach(([key, value])=>{
|
|
112
|
+
queryParams.append(key, value);
|
|
113
|
+
});
|
|
114
|
+
// Append query string to URL
|
|
115
|
+
const queryString = queryParams.toString();
|
|
116
|
+
if (queryString) {
|
|
117
|
+
const separator = url.includes('?') ? '&' : '?';
|
|
118
|
+
url = `${url}${separator}${queryString}`;
|
|
119
|
+
}
|
|
120
|
+
return url;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Builds a complete HTTP request from BrainfishRESTRequest
|
|
124
|
+
*/ export function buildRequest(request, options) {
|
|
125
|
+
// Use provided values or fall back to request defaults
|
|
126
|
+
const params = options?.params || request.params;
|
|
127
|
+
const headers = options?.headers || request.headers;
|
|
128
|
+
const variables = options?.variables || request.requestVariables;
|
|
129
|
+
const bodyValue = options?.body;
|
|
130
|
+
// Build auth headers and params
|
|
131
|
+
const authHeaders = buildAuthHeaders(request.auth);
|
|
132
|
+
const authParams = buildAuthParams(request.auth);
|
|
133
|
+
// Build URL
|
|
134
|
+
const url = buildURL(request.endpoint, params, variables, authParams);
|
|
135
|
+
// Build body
|
|
136
|
+
const body = buildRequestBody(request.body, bodyValue ?? undefined);
|
|
137
|
+
// Build headers
|
|
138
|
+
const finalHeaders = {
|
|
139
|
+
...authHeaders
|
|
140
|
+
};
|
|
141
|
+
headers.filter((h)=>h.active && h.key).forEach((header)=>{
|
|
142
|
+
finalHeaders[header.key] = header.value;
|
|
143
|
+
});
|
|
144
|
+
// Add content-type if body exists (but don't override if already set)
|
|
145
|
+
if (body && request.body.contentType && !finalHeaders['Content-Type']) {
|
|
146
|
+
finalHeaders['Content-Type'] = request.body.contentType;
|
|
147
|
+
}
|
|
148
|
+
// For POST/PUT/PATCH requests without body, add default Content-Type
|
|
149
|
+
// Some APIs require this header even for empty requests
|
|
150
|
+
if (!finalHeaders['Content-Type'] && [
|
|
151
|
+
'POST',
|
|
152
|
+
'PUT',
|
|
153
|
+
'PATCH'
|
|
154
|
+
].includes(request.method)) {
|
|
155
|
+
finalHeaders['Content-Type'] = 'application/json';
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
url,
|
|
159
|
+
method: request.method,
|
|
160
|
+
headers: finalHeaders,
|
|
161
|
+
body
|
|
162
|
+
};
|
|
163
|
+
}
|