@brainfish-ai/devdoc 0.1.21
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/LICENSE +33 -0
- package/README.md +415 -0
- package/bin/devdoc.js +13 -0
- package/dist/cli/commands/build.d.ts +5 -0
- package/dist/cli/commands/build.js +87 -0
- package/dist/cli/commands/check.d.ts +1 -0
- package/dist/cli/commands/check.js +143 -0
- package/dist/cli/commands/create.d.ts +24 -0
- package/dist/cli/commands/create.js +387 -0
- package/dist/cli/commands/deploy.d.ts +9 -0
- package/dist/cli/commands/deploy.js +433 -0
- package/dist/cli/commands/dev.d.ts +6 -0
- package/dist/cli/commands/dev.js +139 -0
- package/dist/cli/commands/init.d.ts +11 -0
- package/dist/cli/commands/init.js +238 -0
- package/dist/cli/commands/keys.d.ts +12 -0
- package/dist/cli/commands/keys.js +165 -0
- package/dist/cli/commands/start.d.ts +5 -0
- package/dist/cli/commands/start.js +56 -0
- package/dist/cli/commands/upload.d.ts +13 -0
- package/dist/cli/commands/upload.js +238 -0
- package/dist/cli/commands/whoami.d.ts +8 -0
- package/dist/cli/commands/whoami.js +91 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +106 -0
- package/dist/config/index.d.ts +80 -0
- package/dist/config/index.js +133 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.js +13 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +12 -0
- package/dist/utils/logger.d.ts +16 -0
- package/dist/utils/logger.js +61 -0
- package/dist/utils/paths.d.ts +16 -0
- package/dist/utils/paths.js +50 -0
- package/package.json +51 -0
- package/renderer/app/api/assets/[...path]/route.ts +123 -0
- package/renderer/app/api/assets/route.ts +124 -0
- package/renderer/app/api/assets/upload/route.ts +177 -0
- package/renderer/app/api/auth-schemes/route.ts +77 -0
- package/renderer/app/api/chat/route.ts +858 -0
- package/renderer/app/api/codegen/route.ts +72 -0
- package/renderer/app/api/collections/route.ts +1016 -0
- package/renderer/app/api/debug/route.ts +53 -0
- package/renderer/app/api/deploy/route.ts +234 -0
- package/renderer/app/api/device/route.ts +42 -0
- package/renderer/app/api/docs/route.ts +187 -0
- package/renderer/app/api/keys/regenerate/route.ts +80 -0
- package/renderer/app/api/openapi-spec/route.ts +151 -0
- package/renderer/app/api/projects/[slug]/route.ts +153 -0
- package/renderer/app/api/projects/[slug]/stats/route.ts +96 -0
- package/renderer/app/api/projects/register/route.ts +152 -0
- package/renderer/app/api/proxy/route.ts +149 -0
- package/renderer/app/api/proxy-stream/route.ts +168 -0
- package/renderer/app/api/redirects/route.ts +47 -0
- package/renderer/app/api/schema/route.ts +65 -0
- package/renderer/app/api/subdomains/check/route.ts +172 -0
- package/renderer/app/api/suggestions/route.ts +144 -0
- package/renderer/app/favicon.ico +0 -0
- package/renderer/app/globals.css +1103 -0
- package/renderer/app/layout.tsx +47 -0
- package/renderer/app/llms-full.txt/route.ts +346 -0
- package/renderer/app/llms.txt/route.ts +279 -0
- package/renderer/app/page.tsx +14 -0
- package/renderer/app/robots.txt/route.ts +84 -0
- package/renderer/app/sitemap.xml/route.ts +199 -0
- package/renderer/components/docs/index.ts +12 -0
- package/renderer/components/docs/mdx/accordion.tsx +169 -0
- package/renderer/components/docs/mdx/badge.tsx +132 -0
- package/renderer/components/docs/mdx/callouts.tsx +154 -0
- package/renderer/components/docs/mdx/cards.tsx +213 -0
- package/renderer/components/docs/mdx/changelog.tsx +120 -0
- package/renderer/components/docs/mdx/code-block.tsx +186 -0
- package/renderer/components/docs/mdx/code-group.tsx +421 -0
- package/renderer/components/docs/mdx/file-embeds.tsx +105 -0
- package/renderer/components/docs/mdx/frame.tsx +112 -0
- package/renderer/components/docs/mdx/highlight.tsx +151 -0
- package/renderer/components/docs/mdx/iframe.tsx +134 -0
- package/renderer/components/docs/mdx/image.tsx +235 -0
- package/renderer/components/docs/mdx/index.ts +204 -0
- package/renderer/components/docs/mdx/mermaid.tsx +240 -0
- package/renderer/components/docs/mdx/param-field.tsx +200 -0
- package/renderer/components/docs/mdx/steps.tsx +113 -0
- package/renderer/components/docs/mdx/tabs.tsx +86 -0
- package/renderer/components/docs/mdx-renderer.tsx +100 -0
- package/renderer/components/docs/navigation/breadcrumbs.tsx +76 -0
- package/renderer/components/docs/navigation/index.ts +8 -0
- package/renderer/components/docs/navigation/page-nav.tsx +64 -0
- package/renderer/components/docs/navigation/sidebar.tsx +515 -0
- package/renderer/components/docs/navigation/toc.tsx +113 -0
- package/renderer/components/docs/notice.tsx +105 -0
- package/renderer/components/docs-header.tsx +274 -0
- package/renderer/components/docs-viewer/agent/agent-chat.tsx +2076 -0
- package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +90 -0
- package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +49 -0
- package/renderer/components/docs-viewer/agent/cards/index.tsx +50 -0
- package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +212 -0
- package/renderer/components/docs-viewer/agent/cards/types.ts +84 -0
- package/renderer/components/docs-viewer/agent/chat-message.tsx +17 -0
- package/renderer/components/docs-viewer/agent/index.tsx +6 -0
- package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +119 -0
- package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +46 -0
- package/renderer/components/docs-viewer/agent/messages/index.ts +17 -0
- package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +721 -0
- package/renderer/components/docs-viewer/agent/messages/types.ts +61 -0
- package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +24 -0
- package/renderer/components/docs-viewer/agent/messages/user-message.tsx +51 -0
- package/renderer/components/docs-viewer/code-editor/index.tsx +2 -0
- package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +1283 -0
- package/renderer/components/docs-viewer/content/changelog-page.tsx +331 -0
- package/renderer/components/docs-viewer/content/doc-page.tsx +285 -0
- package/renderer/components/docs-viewer/content/documentation-viewer.tsx +17 -0
- package/renderer/components/docs-viewer/content/index.tsx +29 -0
- package/renderer/components/docs-viewer/content/introduction.tsx +21 -0
- package/renderer/components/docs-viewer/content/request-details.tsx +330 -0
- package/renderer/components/docs-viewer/content/sections/auth.tsx +69 -0
- package/renderer/components/docs-viewer/content/sections/body.tsx +66 -0
- package/renderer/components/docs-viewer/content/sections/headers.tsx +43 -0
- package/renderer/components/docs-viewer/content/sections/overview.tsx +40 -0
- package/renderer/components/docs-viewer/content/sections/parameters.tsx +43 -0
- package/renderer/components/docs-viewer/content/sections/responses.tsx +87 -0
- package/renderer/components/docs-viewer/global-auth-modal.tsx +352 -0
- package/renderer/components/docs-viewer/index.tsx +1466 -0
- package/renderer/components/docs-viewer/playground/auth-editor.tsx +280 -0
- package/renderer/components/docs-viewer/playground/body-editor.tsx +221 -0
- package/renderer/components/docs-viewer/playground/code-editor.tsx +224 -0
- package/renderer/components/docs-viewer/playground/code-snippet.tsx +387 -0
- package/renderer/components/docs-viewer/playground/graphql-playground.tsx +745 -0
- package/renderer/components/docs-viewer/playground/index.tsx +671 -0
- package/renderer/components/docs-viewer/playground/key-value-editor.tsx +261 -0
- package/renderer/components/docs-viewer/playground/method-selector.tsx +60 -0
- package/renderer/components/docs-viewer/playground/request-builder.tsx +179 -0
- package/renderer/components/docs-viewer/playground/request-tabs.tsx +237 -0
- package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +21 -0
- package/renderer/components/docs-viewer/playground/response-cards/index.tsx +93 -0
- package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +16 -0
- package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +23 -0
- package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +268 -0
- package/renderer/components/docs-viewer/playground/response-cards/types.ts +82 -0
- package/renderer/components/docs-viewer/playground/response-viewer.tsx +43 -0
- package/renderer/components/docs-viewer/search/index.ts +2 -0
- package/renderer/components/docs-viewer/search/search-dialog.tsx +331 -0
- package/renderer/components/docs-viewer/search/use-search.ts +117 -0
- package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +431 -0
- package/renderer/components/docs-viewer/shared/method-badge.tsx +41 -0
- package/renderer/components/docs-viewer/shared/schema-viewer.tsx +349 -0
- package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +239 -0
- package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +316 -0
- package/renderer/components/docs-viewer/sidebar/index.tsx +343 -0
- package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +202 -0
- package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +118 -0
- package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +226 -0
- package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +52 -0
- package/renderer/components/theme-provider.tsx +11 -0
- package/renderer/components/theme-toggle.tsx +76 -0
- package/renderer/components/ui/badge.tsx +46 -0
- package/renderer/components/ui/button.tsx +59 -0
- package/renderer/components/ui/dialog.tsx +118 -0
- package/renderer/components/ui/dropdown-menu.tsx +257 -0
- package/renderer/components/ui/input.tsx +21 -0
- package/renderer/components/ui/label.tsx +24 -0
- package/renderer/components/ui/navigation-menu.tsx +168 -0
- package/renderer/components/ui/select.tsx +190 -0
- package/renderer/components/ui/spinner.tsx +114 -0
- package/renderer/components/ui/tabs.tsx +66 -0
- package/renderer/components/ui/tooltip.tsx +61 -0
- package/renderer/hooks/use-code-copy.ts +88 -0
- package/renderer/hooks/use-openapi-title.ts +44 -0
- package/renderer/lib/api-docs/agent/index.ts +6 -0
- package/renderer/lib/api-docs/agent/indexer.ts +323 -0
- package/renderer/lib/api-docs/agent/spec-summary.ts +335 -0
- package/renderer/lib/api-docs/agent/types.ts +116 -0
- package/renderer/lib/api-docs/auth/auth-context.tsx +225 -0
- package/renderer/lib/api-docs/auth/auth-storage.ts +87 -0
- package/renderer/lib/api-docs/auth/crypto.ts +89 -0
- package/renderer/lib/api-docs/auth/index.ts +4 -0
- package/renderer/lib/api-docs/code-editor/db.ts +164 -0
- package/renderer/lib/api-docs/code-editor/hooks.ts +266 -0
- package/renderer/lib/api-docs/code-editor/index.ts +6 -0
- package/renderer/lib/api-docs/code-editor/mode-context.tsx +207 -0
- package/renderer/lib/api-docs/code-editor/types.ts +105 -0
- package/renderer/lib/api-docs/codegen/definitions.ts +297 -0
- package/renderer/lib/api-docs/codegen/har.ts +251 -0
- package/renderer/lib/api-docs/codegen/index.ts +159 -0
- package/renderer/lib/api-docs/factories.ts +151 -0
- package/renderer/lib/api-docs/index.ts +17 -0
- package/renderer/lib/api-docs/mobile-context.tsx +112 -0
- package/renderer/lib/api-docs/navigation-context.tsx +88 -0
- package/renderer/lib/api-docs/parsers/graphql/README.md +129 -0
- package/renderer/lib/api-docs/parsers/graphql/index.ts +91 -0
- package/renderer/lib/api-docs/parsers/graphql/parser.ts +491 -0
- package/renderer/lib/api-docs/parsers/graphql/transformer.ts +246 -0
- package/renderer/lib/api-docs/parsers/graphql/types.ts +283 -0
- package/renderer/lib/api-docs/parsers/openapi/README.md +32 -0
- package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +60 -0
- package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +574 -0
- package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +403 -0
- package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +232 -0
- package/renderer/lib/api-docs/parsers/openapi/index.ts +171 -0
- package/renderer/lib/api-docs/parsers/openapi/transformer.ts +277 -0
- package/renderer/lib/api-docs/parsers/openapi/validator.ts +31 -0
- package/renderer/lib/api-docs/playground/context.tsx +107 -0
- package/renderer/lib/api-docs/playground/navigation-context.tsx +124 -0
- package/renderer/lib/api-docs/playground/request-builder.ts +223 -0
- package/renderer/lib/api-docs/playground/request-runner.ts +282 -0
- package/renderer/lib/api-docs/playground/types.ts +35 -0
- package/renderer/lib/api-docs/types.ts +269 -0
- package/renderer/lib/api-docs/utils.ts +311 -0
- package/renderer/lib/cache.ts +193 -0
- package/renderer/lib/docs/config/index.ts +29 -0
- package/renderer/lib/docs/config/loader.ts +142 -0
- package/renderer/lib/docs/config/schema.ts +298 -0
- package/renderer/lib/docs/index.ts +12 -0
- package/renderer/lib/docs/mdx/compiler.ts +176 -0
- package/renderer/lib/docs/mdx/frontmatter.ts +80 -0
- package/renderer/lib/docs/mdx/index.ts +26 -0
- package/renderer/lib/docs/navigation/generator.ts +348 -0
- package/renderer/lib/docs/navigation/index.ts +12 -0
- package/renderer/lib/docs/navigation/types.ts +123 -0
- package/renderer/lib/docs-navigation-context.tsx +80 -0
- package/renderer/lib/multi-tenant/context.ts +105 -0
- package/renderer/lib/storage/blob.ts +845 -0
- package/renderer/lib/utils.ts +6 -0
- package/renderer/next.config.ts +76 -0
- package/renderer/package.json +66 -0
- package/renderer/postcss.config.mjs +5 -0
- package/renderer/public/assets/images/screenshot.png +0 -0
- package/renderer/public/assets/logo/dark.svg +9 -0
- package/renderer/public/assets/logo/light.svg +9 -0
- package/renderer/public/assets/logo.svg +9 -0
- package/renderer/public/file.svg +1 -0
- package/renderer/public/globe.svg +1 -0
- package/renderer/public/icon.png +0 -0
- package/renderer/public/logo.svg +9 -0
- package/renderer/public/window.svg +1 -0
- package/renderer/tsconfig.json +28 -0
- package/templates/basic/README.md +139 -0
- package/templates/basic/assets/favicon.svg +4 -0
- package/templates/basic/assets/logo.svg +9 -0
- package/templates/basic/docs.json +47 -0
- package/templates/basic/guides/configuration.mdx +149 -0
- package/templates/basic/guides/overview.mdx +96 -0
- package/templates/basic/index.mdx +39 -0
- package/templates/basic/package.json +14 -0
- package/templates/basic/quickstart.mdx +92 -0
- package/templates/basic/vercel.json +6 -0
- package/templates/graphql/README.md +139 -0
- package/templates/graphql/api-reference/schema.graphql +305 -0
- package/templates/graphql/assets/favicon.svg +4 -0
- package/templates/graphql/assets/logo.svg +9 -0
- package/templates/graphql/docs.json +54 -0
- package/templates/graphql/guides/configuration.mdx +149 -0
- package/templates/graphql/guides/overview.mdx +96 -0
- package/templates/graphql/index.mdx +39 -0
- package/templates/graphql/package.json +14 -0
- package/templates/graphql/quickstart.mdx +92 -0
- package/templates/graphql/vercel.json +6 -0
- package/templates/openapi/README.md +139 -0
- package/templates/openapi/api-reference/openapi.json +419 -0
- package/templates/openapi/assets/favicon.svg +4 -0
- package/templates/openapi/assets/logo.svg +9 -0
- package/templates/openapi/docs.json +61 -0
- package/templates/openapi/guides/configuration.mdx +149 -0
- package/templates/openapi/guides/overview.mdx +96 -0
- package/templates/openapi/index.mdx +39 -0
- package/templates/openapi/package.json +14 -0
- package/templates/openapi/quickstart.mdx +92 -0
- package/templates/openapi/vercel.json +6 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brainfish API Documentation Types
|
|
3
|
+
*
|
|
4
|
+
* These types are inspired by Hoppscotch's data structures but adapted for Brainfish.
|
|
5
|
+
* Ported from Hoppscotch's HoppCollection and HoppRESTRequest types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Core Request Types
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export type HTTPMethod =
|
|
13
|
+
| 'GET'
|
|
14
|
+
| 'POST'
|
|
15
|
+
| 'PUT'
|
|
16
|
+
| 'DELETE'
|
|
17
|
+
| 'PATCH'
|
|
18
|
+
| 'HEAD'
|
|
19
|
+
| 'OPTIONS'
|
|
20
|
+
|
|
21
|
+
export type ContentType =
|
|
22
|
+
| 'application/json'
|
|
23
|
+
| 'application/xml'
|
|
24
|
+
| 'text/plain'
|
|
25
|
+
| 'text/html'
|
|
26
|
+
| 'application/x-www-form-urlencoded'
|
|
27
|
+
| 'multipart/form-data'
|
|
28
|
+
| 'application/octet-stream'
|
|
29
|
+
| null
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Request Parameter Types
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
export interface BrainfishRESTParam {
|
|
36
|
+
key: string
|
|
37
|
+
value: string
|
|
38
|
+
active: boolean
|
|
39
|
+
description: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface BrainfishRESTHeader {
|
|
43
|
+
key: string
|
|
44
|
+
value: string
|
|
45
|
+
active: boolean
|
|
46
|
+
description: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface BrainfishRESTRequestVariable {
|
|
50
|
+
key: string
|
|
51
|
+
value: string
|
|
52
|
+
active: boolean
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface FormDataKeyValue {
|
|
56
|
+
key: string
|
|
57
|
+
value: string | File | Blob
|
|
58
|
+
isFile: boolean
|
|
59
|
+
active: boolean
|
|
60
|
+
contentType?: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// Request Body Types
|
|
65
|
+
// ============================================================================
|
|
66
|
+
|
|
67
|
+
export interface BrainfishRESTReqBody {
|
|
68
|
+
contentType: ContentType
|
|
69
|
+
body: string | FormDataKeyValue[] | null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Authentication Types
|
|
74
|
+
// ============================================================================
|
|
75
|
+
|
|
76
|
+
export interface BrainfishRESTAuthNone {
|
|
77
|
+
authType: 'none'
|
|
78
|
+
authActive: boolean
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface BrainfishRESTAuthInherit {
|
|
82
|
+
authType: 'inherit'
|
|
83
|
+
authActive: boolean
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface BrainfishRESTAuthBasic {
|
|
87
|
+
authType: 'basic'
|
|
88
|
+
authActive: boolean
|
|
89
|
+
username: string
|
|
90
|
+
password: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface BrainfishRESTAuthBearer {
|
|
94
|
+
authType: 'bearer'
|
|
95
|
+
authActive: boolean
|
|
96
|
+
token: string
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface BrainfishRESTAuthAPIKey {
|
|
100
|
+
authType: 'api-key'
|
|
101
|
+
authActive: boolean
|
|
102
|
+
addTo: 'HEADERS' | 'QUERY_PARAMS'
|
|
103
|
+
key: string
|
|
104
|
+
value: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface BrainfishRESTAuthOAuth2 {
|
|
108
|
+
authType: 'oauth-2'
|
|
109
|
+
authActive: boolean
|
|
110
|
+
grantTypeInfo: {
|
|
111
|
+
grantType:
|
|
112
|
+
| 'AUTHORIZATION_CODE'
|
|
113
|
+
| 'IMPLICIT'
|
|
114
|
+
| 'PASSWORD'
|
|
115
|
+
| 'CLIENT_CREDENTIALS'
|
|
116
|
+
authEndpoint?: string
|
|
117
|
+
tokenEndpoint?: string
|
|
118
|
+
clientID: string
|
|
119
|
+
clientSecret?: string
|
|
120
|
+
username?: string
|
|
121
|
+
password?: string
|
|
122
|
+
token: string
|
|
123
|
+
scopes: string
|
|
124
|
+
isPKCE?: boolean
|
|
125
|
+
clientAuthentication?: 'IN_BODY' | 'IN_HEADER'
|
|
126
|
+
authRequestParams?: Array<{ key: string; value: string }>
|
|
127
|
+
refreshRequestParams?: Array<{ key: string; value: string }>
|
|
128
|
+
tokenRequestParams?: Array<{ key: string; value: string }>
|
|
129
|
+
}
|
|
130
|
+
addTo: 'HEADERS' | 'QUERY_PARAMS'
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export type BrainfishRESTAuth =
|
|
134
|
+
| BrainfishRESTAuthNone
|
|
135
|
+
| BrainfishRESTAuthInherit
|
|
136
|
+
| BrainfishRESTAuthBasic
|
|
137
|
+
| BrainfishRESTAuthBearer
|
|
138
|
+
| BrainfishRESTAuthAPIKey
|
|
139
|
+
| BrainfishRESTAuthOAuth2
|
|
140
|
+
|
|
141
|
+
// ============================================================================
|
|
142
|
+
// Response Types
|
|
143
|
+
// ============================================================================
|
|
144
|
+
|
|
145
|
+
export interface BrainfishRESTResponseOriginalRequest {
|
|
146
|
+
name: string
|
|
147
|
+
method: HTTPMethod
|
|
148
|
+
endpoint: string
|
|
149
|
+
params: BrainfishRESTParam[]
|
|
150
|
+
headers: BrainfishRESTHeader[]
|
|
151
|
+
body: BrainfishRESTReqBody
|
|
152
|
+
auth: BrainfishRESTAuth
|
|
153
|
+
requestVariables: BrainfishRESTRequestVariable[]
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface BrainfishRESTRequestResponse {
|
|
157
|
+
name: string
|
|
158
|
+
status: string
|
|
159
|
+
code: number
|
|
160
|
+
headers: BrainfishRESTHeader[]
|
|
161
|
+
body: string
|
|
162
|
+
originalRequest: BrainfishRESTResponseOriginalRequest
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface BrainfishRESTRequestResponses {
|
|
166
|
+
[name: string]: BrainfishRESTRequestResponse
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ============================================================================
|
|
170
|
+
// Request Type
|
|
171
|
+
// ============================================================================
|
|
172
|
+
|
|
173
|
+
export interface BrainfishRESTRequest {
|
|
174
|
+
id: string
|
|
175
|
+
name: string
|
|
176
|
+
description: string | null
|
|
177
|
+
method: HTTPMethod
|
|
178
|
+
endpoint: string
|
|
179
|
+
params: BrainfishRESTParam[]
|
|
180
|
+
headers: BrainfishRESTHeader[]
|
|
181
|
+
auth: BrainfishRESTAuth
|
|
182
|
+
body: BrainfishRESTReqBody
|
|
183
|
+
requestVariables: BrainfishRESTRequestVariable[]
|
|
184
|
+
responses: BrainfishRESTRequestResponses
|
|
185
|
+
tags: string[]
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ============================================================================
|
|
189
|
+
// Documentation Page Types (MDX pages from starter template)
|
|
190
|
+
// ============================================================================
|
|
191
|
+
|
|
192
|
+
export interface BrainfishDocPage {
|
|
193
|
+
id: string
|
|
194
|
+
slug: string
|
|
195
|
+
title: string
|
|
196
|
+
description?: string
|
|
197
|
+
icon?: string
|
|
198
|
+
filePath: string
|
|
199
|
+
group?: string
|
|
200
|
+
order?: number
|
|
201
|
+
/** Nested pages for collapsible groups */
|
|
202
|
+
children?: BrainfishDocPage[]
|
|
203
|
+
/** Whether this is a collapsible group header */
|
|
204
|
+
isGroup?: boolean
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface BrainfishDocGroup {
|
|
208
|
+
id: string
|
|
209
|
+
title: string
|
|
210
|
+
pages: BrainfishDocPage[]
|
|
211
|
+
order?: number
|
|
212
|
+
/** Phosphor icon name for the group header (e.g., "rocket", "book-open", "sliders") */
|
|
213
|
+
icon?: string
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ============================================================================
|
|
217
|
+
// Collection Variable Types
|
|
218
|
+
// ============================================================================
|
|
219
|
+
|
|
220
|
+
export interface BrainfishCollectionVariable {
|
|
221
|
+
key: string
|
|
222
|
+
value: string
|
|
223
|
+
active: boolean
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ============================================================================
|
|
227
|
+
// Collection Type
|
|
228
|
+
// ============================================================================
|
|
229
|
+
|
|
230
|
+
export interface BrainfishCollection {
|
|
231
|
+
id: string
|
|
232
|
+
name: string
|
|
233
|
+
description: string | null
|
|
234
|
+
folders: BrainfishCollection[] // Nested folders (tags)
|
|
235
|
+
requests: BrainfishRESTRequest[]
|
|
236
|
+
variables: BrainfishCollectionVariable[]
|
|
237
|
+
auth: BrainfishRESTAuth
|
|
238
|
+
headers: BrainfishRESTHeader[]
|
|
239
|
+
// Documentation pages from starter template
|
|
240
|
+
docGroups?: BrainfishDocGroup[]
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ============================================================================
|
|
244
|
+
// Helper Type Guards
|
|
245
|
+
// ============================================================================
|
|
246
|
+
|
|
247
|
+
export function isBrainfishRESTAuthBasic(
|
|
248
|
+
auth: BrainfishRESTAuth
|
|
249
|
+
): auth is BrainfishRESTAuthBasic {
|
|
250
|
+
return auth.authType === 'basic'
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export function isBrainfishRESTAuthBearer(
|
|
254
|
+
auth: BrainfishRESTAuth
|
|
255
|
+
): auth is BrainfishRESTAuthBearer {
|
|
256
|
+
return auth.authType === 'bearer'
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function isBrainfishRESTAuthAPIKey(
|
|
260
|
+
auth: BrainfishRESTAuth
|
|
261
|
+
): auth is BrainfishRESTAuthAPIKey {
|
|
262
|
+
return auth.authType === 'api-key'
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function isBrainfishRESTAuthOAuth2(
|
|
266
|
+
auth: BrainfishRESTAuth
|
|
267
|
+
): auth is BrainfishRESTAuthOAuth2 {
|
|
268
|
+
return auth.authType === 'oauth-2'
|
|
269
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility Functions for Brainfish API Documentation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { BrainfishRESTRequest } from './types'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Checks if a value is a valid HTTP method
|
|
9
|
+
*/
|
|
10
|
+
export function isValidHTTPMethod(value: string): value is BrainfishRESTRequest['method'] {
|
|
11
|
+
const validMethods: BrainfishRESTRequest['method'][] = [
|
|
12
|
+
'GET',
|
|
13
|
+
'POST',
|
|
14
|
+
'PUT',
|
|
15
|
+
'DELETE',
|
|
16
|
+
'PATCH',
|
|
17
|
+
'HEAD',
|
|
18
|
+
'OPTIONS',
|
|
19
|
+
]
|
|
20
|
+
return validMethods.includes(value as BrainfishRESTRequest['method'])
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Checks if a number is numeric
|
|
25
|
+
*/
|
|
26
|
+
export function isNumeric(value: unknown): boolean {
|
|
27
|
+
if (typeof value === 'number') return !isNaN(value)
|
|
28
|
+
if (typeof value === 'string') {
|
|
29
|
+
const num = Number(value)
|
|
30
|
+
return !isNaN(num) && isFinite(num)
|
|
31
|
+
}
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Gets status code reason phrase
|
|
37
|
+
*/
|
|
38
|
+
export function getStatusCodeReasonPhrase(
|
|
39
|
+
code: number,
|
|
40
|
+
defaultPhrase?: string
|
|
41
|
+
): string {
|
|
42
|
+
const statusCodes: Record<number, string> = {
|
|
43
|
+
200: 'OK',
|
|
44
|
+
201: 'Created',
|
|
45
|
+
202: 'Accepted',
|
|
46
|
+
204: 'No Content',
|
|
47
|
+
400: 'Bad Request',
|
|
48
|
+
401: 'Unauthorized',
|
|
49
|
+
403: 'Forbidden',
|
|
50
|
+
404: 'Not Found',
|
|
51
|
+
500: 'Internal Server Error',
|
|
52
|
+
502: 'Bad Gateway',
|
|
53
|
+
503: 'Service Unavailable',
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return statusCodes[code] || defaultPhrase || 'Unknown'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Checks if an object has a specific property
|
|
61
|
+
*/
|
|
62
|
+
export function objectHasProperty<T extends string>(
|
|
63
|
+
obj: unknown,
|
|
64
|
+
propName: T
|
|
65
|
+
): obj is { [K in T]: unknown } {
|
|
66
|
+
return (
|
|
67
|
+
!!obj &&
|
|
68
|
+
typeof obj === 'object' &&
|
|
69
|
+
Object.prototype.hasOwnProperty.call(obj, propName)
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Deep clone an object
|
|
75
|
+
*/
|
|
76
|
+
export function cloneDeep<T>(obj: T): T {
|
|
77
|
+
if (obj === null || typeof obj !== 'object') {
|
|
78
|
+
return obj
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (obj instanceof Date) {
|
|
82
|
+
return new Date(obj.getTime()) as unknown as T
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (Array.isArray(obj)) {
|
|
86
|
+
return obj.map(item => cloneDeep(item)) as unknown as T
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const cloned = {} as T
|
|
90
|
+
for (const key in obj) {
|
|
91
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
92
|
+
cloned[key] = cloneDeep(obj[key])
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return cloned
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Strips markdown syntax from text and returns plain text
|
|
101
|
+
* Useful for displaying markdown content in compact UI areas like sidebars
|
|
102
|
+
*/
|
|
103
|
+
export function stripMarkdown(markdown: string | null | undefined): string {
|
|
104
|
+
if (!markdown) return ''
|
|
105
|
+
|
|
106
|
+
let text = markdown
|
|
107
|
+
|
|
108
|
+
// Remove code blocks (```...```)
|
|
109
|
+
text = text.replace(/```[\s\S]*?```/g, '')
|
|
110
|
+
|
|
111
|
+
// Remove inline code (`...`)
|
|
112
|
+
text = text.replace(/`([^`]+)`/g, '$1')
|
|
113
|
+
|
|
114
|
+
// Remove headers (# ## ###)
|
|
115
|
+
text = text.replace(/^#{1,6}\s+(.+)$/gm, '$1')
|
|
116
|
+
|
|
117
|
+
// Remove bold (**text** or __text__)
|
|
118
|
+
text = text.replace(/\*\*([^*]+)\*\*/g, '$1')
|
|
119
|
+
text = text.replace(/__([^_]+)__/g, '$1')
|
|
120
|
+
|
|
121
|
+
// Remove italic (*text* or _text_)
|
|
122
|
+
text = text.replace(/\*([^*]+)\*/g, '$1')
|
|
123
|
+
text = text.replace(/_([^_]+)_/g, '$1')
|
|
124
|
+
|
|
125
|
+
// Remove links [text](url)
|
|
126
|
+
text = text.replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')
|
|
127
|
+
|
|
128
|
+
// Remove images 
|
|
129
|
+
text = text.replace(/!\[([^\]]*)\]\([^\)]+\)/g, '$1')
|
|
130
|
+
|
|
131
|
+
// Remove horizontal rules (--- or ***)
|
|
132
|
+
text = text.replace(/^[-*]{3,}$/gm, '')
|
|
133
|
+
|
|
134
|
+
// Remove list markers (-, *, +, 1.)
|
|
135
|
+
text = text.replace(/^[\s]*[-*+]\s+/gm, '')
|
|
136
|
+
text = text.replace(/^[\s]*\d+\.\s+/gm, '')
|
|
137
|
+
|
|
138
|
+
// Remove blockquotes (>)
|
|
139
|
+
text = text.replace(/^>\s+/gm, '')
|
|
140
|
+
|
|
141
|
+
// Clean up multiple newlines
|
|
142
|
+
text = text.replace(/\n{3,}/g, '\n\n')
|
|
143
|
+
|
|
144
|
+
// Trim whitespace
|
|
145
|
+
text = text.trim()
|
|
146
|
+
|
|
147
|
+
return text
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Gets a preview of text (strips markdown and truncates)
|
|
152
|
+
*/
|
|
153
|
+
export function getTextPreview(
|
|
154
|
+
text: string | null | undefined,
|
|
155
|
+
maxLength: number = 150
|
|
156
|
+
): string {
|
|
157
|
+
if (!text) return ''
|
|
158
|
+
|
|
159
|
+
const stripped = stripMarkdown(text)
|
|
160
|
+
|
|
161
|
+
if (stripped.length <= maxLength) {
|
|
162
|
+
return stripped
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Truncate at word boundary
|
|
166
|
+
const truncated = stripped.substring(0, maxLength)
|
|
167
|
+
const lastSpace = truncated.lastIndexOf(' ')
|
|
168
|
+
|
|
169
|
+
if (lastSpace > maxLength * 0.7) {
|
|
170
|
+
return truncated.substring(0, lastSpace) + '...'
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return truncated + '...'
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Extracts markdown headings from text
|
|
178
|
+
* Returns an array of { level, text, id, children? } objects
|
|
179
|
+
*
|
|
180
|
+
* Following Scalar's approach:
|
|
181
|
+
* - Only includes the two lowest heading levels (e.g., h2 and h3 if h2 is lowest)
|
|
182
|
+
* - Creates hierarchical structure with children
|
|
183
|
+
* - Adds "Introduction" if content doesn't start with a heading
|
|
184
|
+
*/
|
|
185
|
+
export interface MarkdownHeading {
|
|
186
|
+
level: number
|
|
187
|
+
text: string
|
|
188
|
+
id: string
|
|
189
|
+
children?: MarkdownHeading[]
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get all headings from markdown text
|
|
194
|
+
* Properly handles code blocks to avoid extracting code as headings
|
|
195
|
+
*/
|
|
196
|
+
function getAllHeadings(markdown: string): Array<{ level: number; text: string }> {
|
|
197
|
+
const headings: Array<{ level: number; text: string }> = []
|
|
198
|
+
const lines = markdown.split('\n')
|
|
199
|
+
|
|
200
|
+
let inCodeBlock = false
|
|
201
|
+
|
|
202
|
+
for (const line of lines) {
|
|
203
|
+
// Check for code block delimiters (``` or ~~~)
|
|
204
|
+
if (line.trim().startsWith('```') || line.trim().startsWith('~~~')) {
|
|
205
|
+
inCodeBlock = !inCodeBlock
|
|
206
|
+
continue
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Skip lines inside code blocks
|
|
210
|
+
if (inCodeBlock) {
|
|
211
|
+
continue
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Match markdown headings (# ## ### etc.)
|
|
215
|
+
// Must start with # followed by space, then have actual text content
|
|
216
|
+
const match = line.match(/^(#{1,6})\s+(.+)$/)
|
|
217
|
+
if (match) {
|
|
218
|
+
const text = match[2].trim()
|
|
219
|
+
|
|
220
|
+
// Skip if text looks like JSON or code (starts with special chars)
|
|
221
|
+
if (text.startsWith('{') || text.startsWith('"') || text.startsWith('[') ||
|
|
222
|
+
text.startsWith('}') || text.startsWith(']') || text === '{' || text === '}') {
|
|
223
|
+
continue
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
headings.push({
|
|
227
|
+
level: match[1].length,
|
|
228
|
+
text: text
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return headings
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Get the lowest heading level in the document
|
|
238
|
+
*/
|
|
239
|
+
function getLowestHeadingLevel(headings: Array<{ level: number }>): number {
|
|
240
|
+
if (headings.length === 0) return 1
|
|
241
|
+
return Math.min(...headings.map(h => h.level))
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Generate a URL-friendly slug from text
|
|
246
|
+
*/
|
|
247
|
+
function generateSlug(text: string, idCounts: Record<string, number>): string {
|
|
248
|
+
let baseId = text
|
|
249
|
+
.toLowerCase()
|
|
250
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
251
|
+
.replace(/^-+|-+$/g, '')
|
|
252
|
+
|
|
253
|
+
// Ensure uniqueness by appending a counter if needed
|
|
254
|
+
if (idCounts[baseId] !== undefined) {
|
|
255
|
+
idCounts[baseId]++
|
|
256
|
+
baseId = `${baseId}-${idCounts[baseId]}`
|
|
257
|
+
} else {
|
|
258
|
+
idCounts[baseId] = 0
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return baseId
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function extractMarkdownHeadings(
|
|
265
|
+
markdown: string | null | undefined
|
|
266
|
+
): MarkdownHeading[] {
|
|
267
|
+
if (!markdown?.trim()) return []
|
|
268
|
+
|
|
269
|
+
const allHeadings = getAllHeadings(markdown)
|
|
270
|
+
const lowestLevel = getLowestHeadingLevel(allHeadings)
|
|
271
|
+
const idCounts: Record<string, number> = {}
|
|
272
|
+
|
|
273
|
+
const entries: MarkdownHeading[] = []
|
|
274
|
+
let currentParent: MarkdownHeading | null = null
|
|
275
|
+
|
|
276
|
+
// Add "Introduction" if description doesn't start with a heading
|
|
277
|
+
if (!markdown.trim().startsWith('#')) {
|
|
278
|
+
entries.push({
|
|
279
|
+
level: lowestLevel,
|
|
280
|
+
text: 'Introduction',
|
|
281
|
+
id: generateSlug('Introduction', idCounts),
|
|
282
|
+
children: []
|
|
283
|
+
})
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Process headings - only include lowest level and one level deeper
|
|
287
|
+
for (const heading of allHeadings) {
|
|
288
|
+
// Skip headings that are not at the lowest two levels
|
|
289
|
+
if (heading.level !== lowestLevel && heading.level !== lowestLevel + 1) {
|
|
290
|
+
continue
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const entry: MarkdownHeading = {
|
|
294
|
+
level: heading.level,
|
|
295
|
+
text: heading.text,
|
|
296
|
+
id: generateSlug(heading.text, idCounts)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (heading.level === lowestLevel) {
|
|
300
|
+
// This is a top-level heading
|
|
301
|
+
entry.children = []
|
|
302
|
+
entries.push(entry)
|
|
303
|
+
currentParent = entry
|
|
304
|
+
} else if (currentParent && currentParent.children) {
|
|
305
|
+
// This is a child heading
|
|
306
|
+
currentParent.children.push(entry)
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return entries
|
|
311
|
+
}
|