@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.
Files changed (268) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +415 -0
  3. package/bin/devdoc.js +13 -0
  4. package/dist/cli/commands/build.d.ts +5 -0
  5. package/dist/cli/commands/build.js +87 -0
  6. package/dist/cli/commands/check.d.ts +1 -0
  7. package/dist/cli/commands/check.js +143 -0
  8. package/dist/cli/commands/create.d.ts +24 -0
  9. package/dist/cli/commands/create.js +387 -0
  10. package/dist/cli/commands/deploy.d.ts +9 -0
  11. package/dist/cli/commands/deploy.js +433 -0
  12. package/dist/cli/commands/dev.d.ts +6 -0
  13. package/dist/cli/commands/dev.js +139 -0
  14. package/dist/cli/commands/init.d.ts +11 -0
  15. package/dist/cli/commands/init.js +238 -0
  16. package/dist/cli/commands/keys.d.ts +12 -0
  17. package/dist/cli/commands/keys.js +165 -0
  18. package/dist/cli/commands/start.d.ts +5 -0
  19. package/dist/cli/commands/start.js +56 -0
  20. package/dist/cli/commands/upload.d.ts +13 -0
  21. package/dist/cli/commands/upload.js +238 -0
  22. package/dist/cli/commands/whoami.d.ts +8 -0
  23. package/dist/cli/commands/whoami.js +91 -0
  24. package/dist/cli/index.d.ts +1 -0
  25. package/dist/cli/index.js +106 -0
  26. package/dist/config/index.d.ts +80 -0
  27. package/dist/config/index.js +133 -0
  28. package/dist/constants.d.ts +9 -0
  29. package/dist/constants.js +13 -0
  30. package/dist/index.d.ts +7 -0
  31. package/dist/index.js +12 -0
  32. package/dist/utils/logger.d.ts +16 -0
  33. package/dist/utils/logger.js +61 -0
  34. package/dist/utils/paths.d.ts +16 -0
  35. package/dist/utils/paths.js +50 -0
  36. package/package.json +51 -0
  37. package/renderer/app/api/assets/[...path]/route.ts +123 -0
  38. package/renderer/app/api/assets/route.ts +124 -0
  39. package/renderer/app/api/assets/upload/route.ts +177 -0
  40. package/renderer/app/api/auth-schemes/route.ts +77 -0
  41. package/renderer/app/api/chat/route.ts +858 -0
  42. package/renderer/app/api/codegen/route.ts +72 -0
  43. package/renderer/app/api/collections/route.ts +1016 -0
  44. package/renderer/app/api/debug/route.ts +53 -0
  45. package/renderer/app/api/deploy/route.ts +234 -0
  46. package/renderer/app/api/device/route.ts +42 -0
  47. package/renderer/app/api/docs/route.ts +187 -0
  48. package/renderer/app/api/keys/regenerate/route.ts +80 -0
  49. package/renderer/app/api/openapi-spec/route.ts +151 -0
  50. package/renderer/app/api/projects/[slug]/route.ts +153 -0
  51. package/renderer/app/api/projects/[slug]/stats/route.ts +96 -0
  52. package/renderer/app/api/projects/register/route.ts +152 -0
  53. package/renderer/app/api/proxy/route.ts +149 -0
  54. package/renderer/app/api/proxy-stream/route.ts +168 -0
  55. package/renderer/app/api/redirects/route.ts +47 -0
  56. package/renderer/app/api/schema/route.ts +65 -0
  57. package/renderer/app/api/subdomains/check/route.ts +172 -0
  58. package/renderer/app/api/suggestions/route.ts +144 -0
  59. package/renderer/app/favicon.ico +0 -0
  60. package/renderer/app/globals.css +1103 -0
  61. package/renderer/app/layout.tsx +47 -0
  62. package/renderer/app/llms-full.txt/route.ts +346 -0
  63. package/renderer/app/llms.txt/route.ts +279 -0
  64. package/renderer/app/page.tsx +14 -0
  65. package/renderer/app/robots.txt/route.ts +84 -0
  66. package/renderer/app/sitemap.xml/route.ts +199 -0
  67. package/renderer/components/docs/index.ts +12 -0
  68. package/renderer/components/docs/mdx/accordion.tsx +169 -0
  69. package/renderer/components/docs/mdx/badge.tsx +132 -0
  70. package/renderer/components/docs/mdx/callouts.tsx +154 -0
  71. package/renderer/components/docs/mdx/cards.tsx +213 -0
  72. package/renderer/components/docs/mdx/changelog.tsx +120 -0
  73. package/renderer/components/docs/mdx/code-block.tsx +186 -0
  74. package/renderer/components/docs/mdx/code-group.tsx +421 -0
  75. package/renderer/components/docs/mdx/file-embeds.tsx +105 -0
  76. package/renderer/components/docs/mdx/frame.tsx +112 -0
  77. package/renderer/components/docs/mdx/highlight.tsx +151 -0
  78. package/renderer/components/docs/mdx/iframe.tsx +134 -0
  79. package/renderer/components/docs/mdx/image.tsx +235 -0
  80. package/renderer/components/docs/mdx/index.ts +204 -0
  81. package/renderer/components/docs/mdx/mermaid.tsx +240 -0
  82. package/renderer/components/docs/mdx/param-field.tsx +200 -0
  83. package/renderer/components/docs/mdx/steps.tsx +113 -0
  84. package/renderer/components/docs/mdx/tabs.tsx +86 -0
  85. package/renderer/components/docs/mdx-renderer.tsx +100 -0
  86. package/renderer/components/docs/navigation/breadcrumbs.tsx +76 -0
  87. package/renderer/components/docs/navigation/index.ts +8 -0
  88. package/renderer/components/docs/navigation/page-nav.tsx +64 -0
  89. package/renderer/components/docs/navigation/sidebar.tsx +515 -0
  90. package/renderer/components/docs/navigation/toc.tsx +113 -0
  91. package/renderer/components/docs/notice.tsx +105 -0
  92. package/renderer/components/docs-header.tsx +274 -0
  93. package/renderer/components/docs-viewer/agent/agent-chat.tsx +2076 -0
  94. package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +90 -0
  95. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +49 -0
  96. package/renderer/components/docs-viewer/agent/cards/index.tsx +50 -0
  97. package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +212 -0
  98. package/renderer/components/docs-viewer/agent/cards/types.ts +84 -0
  99. package/renderer/components/docs-viewer/agent/chat-message.tsx +17 -0
  100. package/renderer/components/docs-viewer/agent/index.tsx +6 -0
  101. package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +119 -0
  102. package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +46 -0
  103. package/renderer/components/docs-viewer/agent/messages/index.ts +17 -0
  104. package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +721 -0
  105. package/renderer/components/docs-viewer/agent/messages/types.ts +61 -0
  106. package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +24 -0
  107. package/renderer/components/docs-viewer/agent/messages/user-message.tsx +51 -0
  108. package/renderer/components/docs-viewer/code-editor/index.tsx +2 -0
  109. package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +1283 -0
  110. package/renderer/components/docs-viewer/content/changelog-page.tsx +331 -0
  111. package/renderer/components/docs-viewer/content/doc-page.tsx +285 -0
  112. package/renderer/components/docs-viewer/content/documentation-viewer.tsx +17 -0
  113. package/renderer/components/docs-viewer/content/index.tsx +29 -0
  114. package/renderer/components/docs-viewer/content/introduction.tsx +21 -0
  115. package/renderer/components/docs-viewer/content/request-details.tsx +330 -0
  116. package/renderer/components/docs-viewer/content/sections/auth.tsx +69 -0
  117. package/renderer/components/docs-viewer/content/sections/body.tsx +66 -0
  118. package/renderer/components/docs-viewer/content/sections/headers.tsx +43 -0
  119. package/renderer/components/docs-viewer/content/sections/overview.tsx +40 -0
  120. package/renderer/components/docs-viewer/content/sections/parameters.tsx +43 -0
  121. package/renderer/components/docs-viewer/content/sections/responses.tsx +87 -0
  122. package/renderer/components/docs-viewer/global-auth-modal.tsx +352 -0
  123. package/renderer/components/docs-viewer/index.tsx +1466 -0
  124. package/renderer/components/docs-viewer/playground/auth-editor.tsx +280 -0
  125. package/renderer/components/docs-viewer/playground/body-editor.tsx +221 -0
  126. package/renderer/components/docs-viewer/playground/code-editor.tsx +224 -0
  127. package/renderer/components/docs-viewer/playground/code-snippet.tsx +387 -0
  128. package/renderer/components/docs-viewer/playground/graphql-playground.tsx +745 -0
  129. package/renderer/components/docs-viewer/playground/index.tsx +671 -0
  130. package/renderer/components/docs-viewer/playground/key-value-editor.tsx +261 -0
  131. package/renderer/components/docs-viewer/playground/method-selector.tsx +60 -0
  132. package/renderer/components/docs-viewer/playground/request-builder.tsx +179 -0
  133. package/renderer/components/docs-viewer/playground/request-tabs.tsx +237 -0
  134. package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +21 -0
  135. package/renderer/components/docs-viewer/playground/response-cards/index.tsx +93 -0
  136. package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +16 -0
  137. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +23 -0
  138. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +268 -0
  139. package/renderer/components/docs-viewer/playground/response-cards/types.ts +82 -0
  140. package/renderer/components/docs-viewer/playground/response-viewer.tsx +43 -0
  141. package/renderer/components/docs-viewer/search/index.ts +2 -0
  142. package/renderer/components/docs-viewer/search/search-dialog.tsx +331 -0
  143. package/renderer/components/docs-viewer/search/use-search.ts +117 -0
  144. package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +431 -0
  145. package/renderer/components/docs-viewer/shared/method-badge.tsx +41 -0
  146. package/renderer/components/docs-viewer/shared/schema-viewer.tsx +349 -0
  147. package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +239 -0
  148. package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +316 -0
  149. package/renderer/components/docs-viewer/sidebar/index.tsx +343 -0
  150. package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +202 -0
  151. package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +118 -0
  152. package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +226 -0
  153. package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +52 -0
  154. package/renderer/components/theme-provider.tsx +11 -0
  155. package/renderer/components/theme-toggle.tsx +76 -0
  156. package/renderer/components/ui/badge.tsx +46 -0
  157. package/renderer/components/ui/button.tsx +59 -0
  158. package/renderer/components/ui/dialog.tsx +118 -0
  159. package/renderer/components/ui/dropdown-menu.tsx +257 -0
  160. package/renderer/components/ui/input.tsx +21 -0
  161. package/renderer/components/ui/label.tsx +24 -0
  162. package/renderer/components/ui/navigation-menu.tsx +168 -0
  163. package/renderer/components/ui/select.tsx +190 -0
  164. package/renderer/components/ui/spinner.tsx +114 -0
  165. package/renderer/components/ui/tabs.tsx +66 -0
  166. package/renderer/components/ui/tooltip.tsx +61 -0
  167. package/renderer/hooks/use-code-copy.ts +88 -0
  168. package/renderer/hooks/use-openapi-title.ts +44 -0
  169. package/renderer/lib/api-docs/agent/index.ts +6 -0
  170. package/renderer/lib/api-docs/agent/indexer.ts +323 -0
  171. package/renderer/lib/api-docs/agent/spec-summary.ts +335 -0
  172. package/renderer/lib/api-docs/agent/types.ts +116 -0
  173. package/renderer/lib/api-docs/auth/auth-context.tsx +225 -0
  174. package/renderer/lib/api-docs/auth/auth-storage.ts +87 -0
  175. package/renderer/lib/api-docs/auth/crypto.ts +89 -0
  176. package/renderer/lib/api-docs/auth/index.ts +4 -0
  177. package/renderer/lib/api-docs/code-editor/db.ts +164 -0
  178. package/renderer/lib/api-docs/code-editor/hooks.ts +266 -0
  179. package/renderer/lib/api-docs/code-editor/index.ts +6 -0
  180. package/renderer/lib/api-docs/code-editor/mode-context.tsx +207 -0
  181. package/renderer/lib/api-docs/code-editor/types.ts +105 -0
  182. package/renderer/lib/api-docs/codegen/definitions.ts +297 -0
  183. package/renderer/lib/api-docs/codegen/har.ts +251 -0
  184. package/renderer/lib/api-docs/codegen/index.ts +159 -0
  185. package/renderer/lib/api-docs/factories.ts +151 -0
  186. package/renderer/lib/api-docs/index.ts +17 -0
  187. package/renderer/lib/api-docs/mobile-context.tsx +112 -0
  188. package/renderer/lib/api-docs/navigation-context.tsx +88 -0
  189. package/renderer/lib/api-docs/parsers/graphql/README.md +129 -0
  190. package/renderer/lib/api-docs/parsers/graphql/index.ts +91 -0
  191. package/renderer/lib/api-docs/parsers/graphql/parser.ts +491 -0
  192. package/renderer/lib/api-docs/parsers/graphql/transformer.ts +246 -0
  193. package/renderer/lib/api-docs/parsers/graphql/types.ts +283 -0
  194. package/renderer/lib/api-docs/parsers/openapi/README.md +32 -0
  195. package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +60 -0
  196. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +574 -0
  197. package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +403 -0
  198. package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +232 -0
  199. package/renderer/lib/api-docs/parsers/openapi/index.ts +171 -0
  200. package/renderer/lib/api-docs/parsers/openapi/transformer.ts +277 -0
  201. package/renderer/lib/api-docs/parsers/openapi/validator.ts +31 -0
  202. package/renderer/lib/api-docs/playground/context.tsx +107 -0
  203. package/renderer/lib/api-docs/playground/navigation-context.tsx +124 -0
  204. package/renderer/lib/api-docs/playground/request-builder.ts +223 -0
  205. package/renderer/lib/api-docs/playground/request-runner.ts +282 -0
  206. package/renderer/lib/api-docs/playground/types.ts +35 -0
  207. package/renderer/lib/api-docs/types.ts +269 -0
  208. package/renderer/lib/api-docs/utils.ts +311 -0
  209. package/renderer/lib/cache.ts +193 -0
  210. package/renderer/lib/docs/config/index.ts +29 -0
  211. package/renderer/lib/docs/config/loader.ts +142 -0
  212. package/renderer/lib/docs/config/schema.ts +298 -0
  213. package/renderer/lib/docs/index.ts +12 -0
  214. package/renderer/lib/docs/mdx/compiler.ts +176 -0
  215. package/renderer/lib/docs/mdx/frontmatter.ts +80 -0
  216. package/renderer/lib/docs/mdx/index.ts +26 -0
  217. package/renderer/lib/docs/navigation/generator.ts +348 -0
  218. package/renderer/lib/docs/navigation/index.ts +12 -0
  219. package/renderer/lib/docs/navigation/types.ts +123 -0
  220. package/renderer/lib/docs-navigation-context.tsx +80 -0
  221. package/renderer/lib/multi-tenant/context.ts +105 -0
  222. package/renderer/lib/storage/blob.ts +845 -0
  223. package/renderer/lib/utils.ts +6 -0
  224. package/renderer/next.config.ts +76 -0
  225. package/renderer/package.json +66 -0
  226. package/renderer/postcss.config.mjs +5 -0
  227. package/renderer/public/assets/images/screenshot.png +0 -0
  228. package/renderer/public/assets/logo/dark.svg +9 -0
  229. package/renderer/public/assets/logo/light.svg +9 -0
  230. package/renderer/public/assets/logo.svg +9 -0
  231. package/renderer/public/file.svg +1 -0
  232. package/renderer/public/globe.svg +1 -0
  233. package/renderer/public/icon.png +0 -0
  234. package/renderer/public/logo.svg +9 -0
  235. package/renderer/public/window.svg +1 -0
  236. package/renderer/tsconfig.json +28 -0
  237. package/templates/basic/README.md +139 -0
  238. package/templates/basic/assets/favicon.svg +4 -0
  239. package/templates/basic/assets/logo.svg +9 -0
  240. package/templates/basic/docs.json +47 -0
  241. package/templates/basic/guides/configuration.mdx +149 -0
  242. package/templates/basic/guides/overview.mdx +96 -0
  243. package/templates/basic/index.mdx +39 -0
  244. package/templates/basic/package.json +14 -0
  245. package/templates/basic/quickstart.mdx +92 -0
  246. package/templates/basic/vercel.json +6 -0
  247. package/templates/graphql/README.md +139 -0
  248. package/templates/graphql/api-reference/schema.graphql +305 -0
  249. package/templates/graphql/assets/favicon.svg +4 -0
  250. package/templates/graphql/assets/logo.svg +9 -0
  251. package/templates/graphql/docs.json +54 -0
  252. package/templates/graphql/guides/configuration.mdx +149 -0
  253. package/templates/graphql/guides/overview.mdx +96 -0
  254. package/templates/graphql/index.mdx +39 -0
  255. package/templates/graphql/package.json +14 -0
  256. package/templates/graphql/quickstart.mdx +92 -0
  257. package/templates/graphql/vercel.json +6 -0
  258. package/templates/openapi/README.md +139 -0
  259. package/templates/openapi/api-reference/openapi.json +419 -0
  260. package/templates/openapi/assets/favicon.svg +4 -0
  261. package/templates/openapi/assets/logo.svg +9 -0
  262. package/templates/openapi/docs.json +61 -0
  263. package/templates/openapi/guides/configuration.mdx +149 -0
  264. package/templates/openapi/guides/overview.mdx +96 -0
  265. package/templates/openapi/index.mdx +39 -0
  266. package/templates/openapi/package.json +14 -0
  267. package/templates/openapi/quickstart.mdx +92 -0
  268. 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 ![alt](url)
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
+ }