@brainfish-ai/devdoc 0.1.42 → 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.
Files changed (388) hide show
  1. package/dist/cli/commands/dev.js +19 -10
  2. package/package.json +3 -2
  3. package/renderer/app/api/assets/[...path]/route.js +108 -0
  4. package/renderer/app/api/assets/route.js +114 -0
  5. package/renderer/app/api/assets/upload/route.js +163 -0
  6. package/renderer/app/api/auth-schemes/route.js +58 -0
  7. package/renderer/app/api/chat/route.js +759 -0
  8. package/renderer/app/api/codegen/route.js +52 -0
  9. package/renderer/app/api/collections/route.js +675 -0
  10. package/renderer/app/api/debug/route.js +47 -0
  11. package/renderer/app/api/deploy/route.js +199 -0
  12. package/renderer/app/api/device/route.js +36 -0
  13. package/renderer/app/api/docs/route.js +205 -0
  14. package/renderer/app/api/domains/add/route.js +121 -0
  15. package/renderer/app/api/domains/lookup/route.js +43 -0
  16. package/renderer/app/api/domains/remove/route.js +89 -0
  17. package/renderer/app/api/domains/status/route.js +140 -0
  18. package/renderer/app/api/domains/verify/route.js +168 -0
  19. package/renderer/app/api/keys/regenerate/route.js +71 -0
  20. package/renderer/app/api/local-assets/[...path]/route.js +108 -0
  21. package/renderer/app/api/openapi-spec/route.js +73 -0
  22. package/renderer/app/api/projects/[slug]/route.js +129 -0
  23. package/renderer/app/api/projects/[slug]/stats/route.js +80 -0
  24. package/renderer/app/api/projects/register/route.js +176 -0
  25. package/renderer/app/api/proxy/route.js +139 -0
  26. package/renderer/app/api/proxy-stream/route.js +156 -0
  27. package/renderer/app/api/redirects/route.js +35 -0
  28. package/renderer/app/api/schema/route.js +85 -0
  29. package/renderer/app/api/subdomains/check/route.js +158 -0
  30. package/renderer/app/api/suggestions/route.js +175 -0
  31. package/renderer/app/layout.js +47 -0
  32. package/renderer/app/llms-full.txt/route.js +257 -0
  33. package/renderer/app/llms.txt/route.js +219 -0
  34. package/renderer/app/page.js +12 -0
  35. package/renderer/app/robots.txt/route.js +66 -0
  36. package/renderer/app/sitemap.xml/route.js +145 -0
  37. package/renderer/components/docs/index.js +8 -0
  38. package/renderer/components/docs/mdx/accordion.js +113 -0
  39. package/renderer/components/docs/mdx/badge.js +72 -0
  40. package/renderer/components/docs/mdx/callouts.js +137 -0
  41. package/renderer/components/docs/mdx/cards.js +175 -0
  42. package/renderer/components/docs/mdx/changelog.js +100 -0
  43. package/renderer/components/docs/mdx/code-block.js +147 -0
  44. package/renderer/components/docs/mdx/code-group.js +287 -0
  45. package/renderer/components/docs/mdx/file-embeds.js +82 -0
  46. package/renderer/components/docs/mdx/frame.js +59 -0
  47. package/renderer/components/docs/mdx/highlight.js +90 -0
  48. package/renderer/components/docs/mdx/iframe.js +69 -0
  49. package/renderer/components/docs/mdx/image.js +135 -0
  50. package/renderer/components/docs/mdx/index.js +134 -0
  51. package/renderer/components/docs/mdx/landing.js +315 -0
  52. package/renderer/components/docs/mdx/mermaid.js +212 -0
  53. package/renderer/components/docs/mdx/param-field.js +112 -0
  54. package/renderer/components/docs/mdx/steps.js +74 -0
  55. package/renderer/components/docs/mdx/tabs.js +50 -0
  56. package/renderer/components/docs/mdx-renderer.js +77 -0
  57. package/renderer/components/docs/navigation/breadcrumbs.js +64 -0
  58. package/renderer/components/docs/navigation/index.js +6 -0
  59. package/renderer/components/docs/navigation/page-nav.js +57 -0
  60. package/renderer/components/docs/navigation/sidebar.js +375 -0
  61. package/renderer/components/docs/navigation/toc.js +89 -0
  62. package/renderer/components/docs/notice.js +77 -0
  63. package/renderer/components/docs-header.js +202 -0
  64. package/renderer/components/docs-viewer/agent/agent-chat.js +1930 -0
  65. package/renderer/components/docs-viewer/agent/cards/debug-context-card.js +107 -0
  66. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.js +57 -0
  67. package/renderer/components/docs-viewer/agent/cards/index.js +45 -0
  68. package/renderer/components/docs-viewer/agent/cards/response-options-card.js +154 -0
  69. package/renderer/components/docs-viewer/agent/cards/types.js +22 -0
  70. package/renderer/components/docs-viewer/agent/chat-message.js +2 -0
  71. package/renderer/components/docs-viewer/agent/index.js +4 -0
  72. package/renderer/components/docs-viewer/agent/messages/assistant-message.js +108 -0
  73. package/renderer/components/docs-viewer/agent/messages/chat-message.js +34 -0
  74. package/renderer/components/docs-viewer/agent/messages/index.js +6 -0
  75. package/renderer/components/docs-viewer/agent/messages/tool-call-display.js +1065 -0
  76. package/renderer/components/docs-viewer/agent/messages/types.js +2 -0
  77. package/renderer/components/docs-viewer/agent/messages/typing-indicator.js +26 -0
  78. package/renderer/components/docs-viewer/agent/messages/user-message.js +37 -0
  79. package/renderer/components/docs-viewer/code-editor/{index.tsx → index.js} +1 -1
  80. package/renderer/components/docs-viewer/code-editor/notes-mode.js +1338 -0
  81. package/renderer/components/docs-viewer/content/changelog-page.js +297 -0
  82. package/renderer/components/docs-viewer/content/doc-page.js +264 -0
  83. package/renderer/components/docs-viewer/content/documentation-viewer.js +14 -0
  84. package/renderer/components/docs-viewer/content/index.js +29 -0
  85. package/renderer/components/docs-viewer/content/not-found-page.js +300 -0
  86. package/renderer/components/docs-viewer/content/request-details.js +528 -0
  87. package/renderer/components/docs-viewer/content/sections/auth.js +108 -0
  88. package/renderer/components/docs-viewer/content/sections/body.js +80 -0
  89. package/renderer/components/docs-viewer/content/sections/headers.js +64 -0
  90. package/renderer/components/docs-viewer/content/sections/overview.js +56 -0
  91. package/renderer/components/docs-viewer/content/sections/parameters.js +64 -0
  92. package/renderer/components/docs-viewer/content/sections/responses.js +91 -0
  93. package/renderer/components/docs-viewer/global-auth-modal.js +427 -0
  94. package/renderer/components/docs-viewer/index.js +1552 -0
  95. package/renderer/components/docs-viewer/playground/auth-editor.js +418 -0
  96. package/renderer/components/docs-viewer/playground/body-editor.js +240 -0
  97. package/renderer/components/docs-viewer/playground/code-editor.js +135 -0
  98. package/renderer/components/docs-viewer/playground/code-snippet.js +393 -0
  99. package/renderer/components/docs-viewer/playground/graphql-playground.js +734 -0
  100. package/renderer/components/docs-viewer/playground/index.js +682 -0
  101. package/renderer/components/docs-viewer/playground/key-value-editor.js +317 -0
  102. package/renderer/components/docs-viewer/playground/method-selector.js +65 -0
  103. package/renderer/components/docs-viewer/playground/request-builder.js +181 -0
  104. package/renderer/components/docs-viewer/playground/request-tabs.js +240 -0
  105. package/renderer/components/docs-viewer/playground/response-cards/idle-card.js +42 -0
  106. package/renderer/components/docs-viewer/playground/response-cards/index.js +72 -0
  107. package/renderer/components/docs-viewer/playground/response-cards/loading-card.js +24 -0
  108. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.js +28 -0
  109. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.js +308 -0
  110. package/renderer/components/docs-viewer/playground/response-cards/types.js +9 -0
  111. package/renderer/components/docs-viewer/playground/response-viewer.js +18 -0
  112. package/renderer/components/docs-viewer/search/index.js +2 -0
  113. package/renderer/components/docs-viewer/search/search-dialog.js +367 -0
  114. package/renderer/components/docs-viewer/search/use-search.js +89 -0
  115. package/renderer/components/docs-viewer/shared/markdown-renderer.js +423 -0
  116. package/renderer/components/docs-viewer/shared/method-badge.js +23 -0
  117. package/renderer/components/docs-viewer/shared/schema-viewer.js +321 -0
  118. package/renderer/components/docs-viewer/sidebar/collection-tree.js +222 -0
  119. package/renderer/components/docs-viewer/sidebar/endpoint-options.js +512 -0
  120. package/renderer/components/docs-viewer/sidebar/index.js +196 -0
  121. package/renderer/components/docs-viewer/sidebar/right-sidebar.js +163 -0
  122. package/renderer/components/docs-viewer/sidebar/sidebar-group.js +87 -0
  123. package/renderer/components/docs-viewer/sidebar/sidebar-item.js +172 -0
  124. package/renderer/components/docs-viewer/sidebar/sidebar-section.js +31 -0
  125. package/renderer/components/theme-provider.js +10 -0
  126. package/renderer/components/theme-toggle.js +106 -0
  127. package/renderer/components/ui/badge.js +29 -0
  128. package/renderer/components/ui/button.js +40 -0
  129. package/renderer/components/ui/dialog.js +50 -0
  130. package/renderer/components/ui/dropdown-menu.js +143 -0
  131. package/renderer/components/ui/input.js +12 -0
  132. package/renderer/components/ui/label.js +13 -0
  133. package/renderer/components/ui/navigation-menu.js +83 -0
  134. package/renderer/components/ui/select.js +116 -0
  135. package/renderer/components/ui/spinner.js +92 -0
  136. package/renderer/components/ui/tabs.js +34 -0
  137. package/renderer/components/ui/tooltip.js +43 -0
  138. package/renderer/hooks/use-code-copy.js +76 -0
  139. package/renderer/hooks/use-openapi-title.js +33 -0
  140. package/renderer/lib/api-docs/agent/index.js +4 -0
  141. package/renderer/lib/api-docs/agent/indexer.js +254 -0
  142. package/renderer/lib/api-docs/agent/spec-summary.js +227 -0
  143. package/renderer/lib/api-docs/agent/types.js +5 -0
  144. package/renderer/lib/api-docs/auth/auth-context.js +157 -0
  145. package/renderer/lib/api-docs/auth/auth-storage.js +66 -0
  146. package/renderer/lib/api-docs/auth/crypto.js +64 -0
  147. package/renderer/lib/api-docs/auth/index.js +3 -0
  148. package/renderer/lib/api-docs/code-editor/db.js +145 -0
  149. package/renderer/lib/api-docs/code-editor/hooks.js +254 -0
  150. package/renderer/lib/api-docs/code-editor/{index.ts → index.js} +3 -4
  151. package/renderer/lib/api-docs/code-editor/mode-context.js +154 -0
  152. package/renderer/lib/api-docs/code-editor/types.js +53 -0
  153. package/renderer/lib/api-docs/codegen/definitions.js +258 -0
  154. package/renderer/lib/api-docs/codegen/har.js +171 -0
  155. package/renderer/lib/api-docs/codegen/index.js +118 -0
  156. package/renderer/lib/api-docs/factories.js +136 -0
  157. package/renderer/lib/api-docs/{index.ts → index.js} +5 -10
  158. package/renderer/lib/api-docs/mobile-context.js +79 -0
  159. package/renderer/lib/api-docs/navigation-context.js +62 -0
  160. package/renderer/lib/api-docs/parsers/graphql/index.js +50 -0
  161. package/renderer/lib/api-docs/parsers/graphql/parser.js +350 -0
  162. package/renderer/lib/api-docs/parsers/graphql/transformer.js +215 -0
  163. package/renderer/lib/api-docs/parsers/graphql/types.js +46 -0
  164. package/renderer/lib/api-docs/parsers/openapi/dereferencer.js +43 -0
  165. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.js +486 -0
  166. package/renderer/lib/api-docs/parsers/openapi/extractors/body.js +295 -0
  167. package/renderer/lib/api-docs/parsers/openapi/extractors/index.js +132 -0
  168. package/renderer/lib/api-docs/parsers/openapi/index.js +127 -0
  169. package/renderer/lib/api-docs/parsers/openapi/transformer.js +192 -0
  170. package/renderer/lib/api-docs/parsers/openapi/validator.js +24 -0
  171. package/renderer/lib/api-docs/playground/context.js +65 -0
  172. package/renderer/lib/api-docs/playground/navigation-context.js +74 -0
  173. package/renderer/lib/api-docs/playground/request-builder.js +163 -0
  174. package/renderer/lib/api-docs/playground/request-runner.js +224 -0
  175. package/renderer/lib/api-docs/playground/types.js +5 -0
  176. package/renderer/lib/api-docs/types.js +23 -0
  177. package/renderer/lib/api-docs/utils.js +212 -0
  178. package/renderer/lib/cache.js +157 -0
  179. package/renderer/lib/docs/config/domain-schema.js +161 -0
  180. package/renderer/lib/docs/config/index.js +5 -0
  181. package/renderer/lib/docs/config/loader.js +113 -0
  182. package/renderer/lib/docs/config/schema.js +269 -0
  183. package/renderer/lib/docs/index.js +8 -0
  184. package/renderer/lib/docs/mdx/compiler.js +128 -0
  185. package/renderer/lib/docs/mdx/frontmatter.js +73 -0
  186. package/renderer/lib/docs/mdx/index.js +8 -0
  187. package/renderer/lib/docs/navigation/generator.js +269 -0
  188. package/renderer/lib/docs/navigation/index.js +4 -0
  189. package/renderer/lib/docs/navigation/types.js +9 -0
  190. package/renderer/lib/docs-navigation-context.js +40 -0
  191. package/renderer/lib/multi-tenant/context.js +80 -0
  192. package/renderer/lib/storage/blob.js +767 -0
  193. package/renderer/lib/utils/icons.js +30 -0
  194. package/renderer/lib/utils.js +5 -0
  195. package/renderer/next.config.js +62 -0
  196. package/renderer/tsconfig.json +23 -5
  197. package/renderer/app/api/assets/[...path]/route.ts +0 -123
  198. package/renderer/app/api/assets/route.ts +0 -124
  199. package/renderer/app/api/assets/upload/route.ts +0 -177
  200. package/renderer/app/api/auth-schemes/route.ts +0 -77
  201. package/renderer/app/api/chat/route.ts +0 -858
  202. package/renderer/app/api/codegen/route.ts +0 -72
  203. package/renderer/app/api/collections/route.ts +0 -1002
  204. package/renderer/app/api/debug/route.ts +0 -53
  205. package/renderer/app/api/deploy/route.ts +0 -234
  206. package/renderer/app/api/device/route.ts +0 -42
  207. package/renderer/app/api/docs/route.ts +0 -201
  208. package/renderer/app/api/domains/add/route.ts +0 -132
  209. package/renderer/app/api/domains/lookup/route.ts +0 -43
  210. package/renderer/app/api/domains/remove/route.ts +0 -100
  211. package/renderer/app/api/domains/status/route.ts +0 -158
  212. package/renderer/app/api/domains/verify/route.ts +0 -181
  213. package/renderer/app/api/keys/regenerate/route.ts +0 -80
  214. package/renderer/app/api/local-assets/[...path]/route.ts +0 -122
  215. package/renderer/app/api/openapi-spec/route.ts +0 -151
  216. package/renderer/app/api/projects/[slug]/route.ts +0 -153
  217. package/renderer/app/api/projects/[slug]/stats/route.ts +0 -96
  218. package/renderer/app/api/projects/register/route.ts +0 -152
  219. package/renderer/app/api/proxy/route.ts +0 -149
  220. package/renderer/app/api/proxy-stream/route.ts +0 -168
  221. package/renderer/app/api/redirects/route.ts +0 -47
  222. package/renderer/app/api/schema/route.ts +0 -73
  223. package/renderer/app/api/subdomains/check/route.ts +0 -172
  224. package/renderer/app/api/suggestions/route.ts +0 -144
  225. package/renderer/app/layout.tsx +0 -54
  226. package/renderer/app/llms-full.txt/route.ts +0 -346
  227. package/renderer/app/llms.txt/route.ts +0 -279
  228. package/renderer/app/page.tsx +0 -14
  229. package/renderer/app/robots.txt/route.ts +0 -84
  230. package/renderer/app/sitemap.xml/route.ts +0 -199
  231. package/renderer/components/docs/index.ts +0 -12
  232. package/renderer/components/docs/mdx/accordion.tsx +0 -169
  233. package/renderer/components/docs/mdx/badge.tsx +0 -132
  234. package/renderer/components/docs/mdx/callouts.tsx +0 -154
  235. package/renderer/components/docs/mdx/cards.tsx +0 -241
  236. package/renderer/components/docs/mdx/changelog.tsx +0 -120
  237. package/renderer/components/docs/mdx/code-block.tsx +0 -186
  238. package/renderer/components/docs/mdx/code-group.tsx +0 -421
  239. package/renderer/components/docs/mdx/file-embeds.tsx +0 -105
  240. package/renderer/components/docs/mdx/frame.tsx +0 -112
  241. package/renderer/components/docs/mdx/highlight.tsx +0 -151
  242. package/renderer/components/docs/mdx/iframe.tsx +0 -134
  243. package/renderer/components/docs/mdx/image.tsx +0 -235
  244. package/renderer/components/docs/mdx/index.ts +0 -237
  245. package/renderer/components/docs/mdx/landing.tsx +0 -684
  246. package/renderer/components/docs/mdx/mermaid.tsx +0 -240
  247. package/renderer/components/docs/mdx/param-field.tsx +0 -200
  248. package/renderer/components/docs/mdx/steps.tsx +0 -113
  249. package/renderer/components/docs/mdx/tabs.tsx +0 -86
  250. package/renderer/components/docs/mdx-renderer.tsx +0 -100
  251. package/renderer/components/docs/navigation/breadcrumbs.tsx +0 -76
  252. package/renderer/components/docs/navigation/index.ts +0 -8
  253. package/renderer/components/docs/navigation/page-nav.tsx +0 -64
  254. package/renderer/components/docs/navigation/sidebar.tsx +0 -515
  255. package/renderer/components/docs/navigation/toc.tsx +0 -113
  256. package/renderer/components/docs/notice.tsx +0 -105
  257. package/renderer/components/docs-header.tsx +0 -278
  258. package/renderer/components/docs-viewer/agent/agent-chat.tsx +0 -2076
  259. package/renderer/components/docs-viewer/agent/cards/debug-context-card.tsx +0 -90
  260. package/renderer/components/docs-viewer/agent/cards/endpoint-context-card.tsx +0 -49
  261. package/renderer/components/docs-viewer/agent/cards/index.tsx +0 -50
  262. package/renderer/components/docs-viewer/agent/cards/response-options-card.tsx +0 -212
  263. package/renderer/components/docs-viewer/agent/cards/types.ts +0 -84
  264. package/renderer/components/docs-viewer/agent/chat-message.tsx +0 -17
  265. package/renderer/components/docs-viewer/agent/index.tsx +0 -6
  266. package/renderer/components/docs-viewer/agent/messages/assistant-message.tsx +0 -119
  267. package/renderer/components/docs-viewer/agent/messages/chat-message.tsx +0 -46
  268. package/renderer/components/docs-viewer/agent/messages/index.ts +0 -17
  269. package/renderer/components/docs-viewer/agent/messages/tool-call-display.tsx +0 -721
  270. package/renderer/components/docs-viewer/agent/messages/types.ts +0 -61
  271. package/renderer/components/docs-viewer/agent/messages/typing-indicator.tsx +0 -24
  272. package/renderer/components/docs-viewer/agent/messages/user-message.tsx +0 -51
  273. package/renderer/components/docs-viewer/code-editor/notes-mode.tsx +0 -1283
  274. package/renderer/components/docs-viewer/content/changelog-page.tsx +0 -331
  275. package/renderer/components/docs-viewer/content/doc-page.tsx +0 -367
  276. package/renderer/components/docs-viewer/content/documentation-viewer.tsx +0 -17
  277. package/renderer/components/docs-viewer/content/index.tsx +0 -29
  278. package/renderer/components/docs-viewer/content/not-found-page.tsx +0 -330
  279. package/renderer/components/docs-viewer/content/request-details.tsx +0 -330
  280. package/renderer/components/docs-viewer/content/sections/auth.tsx +0 -69
  281. package/renderer/components/docs-viewer/content/sections/body.tsx +0 -66
  282. package/renderer/components/docs-viewer/content/sections/headers.tsx +0 -43
  283. package/renderer/components/docs-viewer/content/sections/overview.tsx +0 -40
  284. package/renderer/components/docs-viewer/content/sections/parameters.tsx +0 -43
  285. package/renderer/components/docs-viewer/content/sections/responses.tsx +0 -87
  286. package/renderer/components/docs-viewer/global-auth-modal.tsx +0 -352
  287. package/renderer/components/docs-viewer/index.tsx +0 -1670
  288. package/renderer/components/docs-viewer/playground/auth-editor.tsx +0 -280
  289. package/renderer/components/docs-viewer/playground/body-editor.tsx +0 -221
  290. package/renderer/components/docs-viewer/playground/code-editor.tsx +0 -224
  291. package/renderer/components/docs-viewer/playground/code-snippet.tsx +0 -387
  292. package/renderer/components/docs-viewer/playground/graphql-playground.tsx +0 -745
  293. package/renderer/components/docs-viewer/playground/index.tsx +0 -671
  294. package/renderer/components/docs-viewer/playground/key-value-editor.tsx +0 -261
  295. package/renderer/components/docs-viewer/playground/method-selector.tsx +0 -60
  296. package/renderer/components/docs-viewer/playground/request-builder.tsx +0 -179
  297. package/renderer/components/docs-viewer/playground/request-tabs.tsx +0 -237
  298. package/renderer/components/docs-viewer/playground/response-cards/idle-card.tsx +0 -21
  299. package/renderer/components/docs-viewer/playground/response-cards/index.tsx +0 -93
  300. package/renderer/components/docs-viewer/playground/response-cards/loading-card.tsx +0 -16
  301. package/renderer/components/docs-viewer/playground/response-cards/network-error-card.tsx +0 -23
  302. package/renderer/components/docs-viewer/playground/response-cards/response-body-card.tsx +0 -268
  303. package/renderer/components/docs-viewer/playground/response-cards/types.ts +0 -82
  304. package/renderer/components/docs-viewer/playground/response-viewer.tsx +0 -43
  305. package/renderer/components/docs-viewer/search/index.ts +0 -2
  306. package/renderer/components/docs-viewer/search/search-dialog.tsx +0 -331
  307. package/renderer/components/docs-viewer/search/use-search.ts +0 -117
  308. package/renderer/components/docs-viewer/shared/markdown-renderer.tsx +0 -431
  309. package/renderer/components/docs-viewer/shared/method-badge.tsx +0 -41
  310. package/renderer/components/docs-viewer/shared/schema-viewer.tsx +0 -349
  311. package/renderer/components/docs-viewer/sidebar/collection-tree.tsx +0 -259
  312. package/renderer/components/docs-viewer/sidebar/endpoint-options.tsx +0 -316
  313. package/renderer/components/docs-viewer/sidebar/index.tsx +0 -282
  314. package/renderer/components/docs-viewer/sidebar/right-sidebar.tsx +0 -202
  315. package/renderer/components/docs-viewer/sidebar/sidebar-group.tsx +0 -118
  316. package/renderer/components/docs-viewer/sidebar/sidebar-item.tsx +0 -212
  317. package/renderer/components/docs-viewer/sidebar/sidebar-section.tsx +0 -38
  318. package/renderer/components/theme-provider.tsx +0 -11
  319. package/renderer/components/theme-toggle.tsx +0 -76
  320. package/renderer/components/ui/badge.tsx +0 -46
  321. package/renderer/components/ui/button.tsx +0 -59
  322. package/renderer/components/ui/dialog.tsx +0 -118
  323. package/renderer/components/ui/dropdown-menu.tsx +0 -257
  324. package/renderer/components/ui/input.tsx +0 -21
  325. package/renderer/components/ui/label.tsx +0 -24
  326. package/renderer/components/ui/navigation-menu.tsx +0 -168
  327. package/renderer/components/ui/select.tsx +0 -190
  328. package/renderer/components/ui/spinner.tsx +0 -114
  329. package/renderer/components/ui/tabs.tsx +0 -66
  330. package/renderer/components/ui/tooltip.tsx +0 -61
  331. package/renderer/hooks/use-code-copy.ts +0 -88
  332. package/renderer/hooks/use-openapi-title.ts +0 -44
  333. package/renderer/lib/api-docs/agent/index.ts +0 -6
  334. package/renderer/lib/api-docs/agent/indexer.ts +0 -323
  335. package/renderer/lib/api-docs/agent/spec-summary.ts +0 -335
  336. package/renderer/lib/api-docs/agent/types.ts +0 -116
  337. package/renderer/lib/api-docs/auth/auth-context.tsx +0 -225
  338. package/renderer/lib/api-docs/auth/auth-storage.ts +0 -87
  339. package/renderer/lib/api-docs/auth/crypto.ts +0 -89
  340. package/renderer/lib/api-docs/auth/index.ts +0 -4
  341. package/renderer/lib/api-docs/code-editor/db.ts +0 -164
  342. package/renderer/lib/api-docs/code-editor/hooks.ts +0 -266
  343. package/renderer/lib/api-docs/code-editor/mode-context.tsx +0 -207
  344. package/renderer/lib/api-docs/code-editor/types.ts +0 -105
  345. package/renderer/lib/api-docs/codegen/definitions.ts +0 -297
  346. package/renderer/lib/api-docs/codegen/har.ts +0 -251
  347. package/renderer/lib/api-docs/codegen/index.ts +0 -159
  348. package/renderer/lib/api-docs/factories.ts +0 -170
  349. package/renderer/lib/api-docs/mobile-context.tsx +0 -112
  350. package/renderer/lib/api-docs/navigation-context.tsx +0 -88
  351. package/renderer/lib/api-docs/parsers/graphql/README.md +0 -129
  352. package/renderer/lib/api-docs/parsers/graphql/index.ts +0 -91
  353. package/renderer/lib/api-docs/parsers/graphql/parser.ts +0 -491
  354. package/renderer/lib/api-docs/parsers/graphql/transformer.ts +0 -246
  355. package/renderer/lib/api-docs/parsers/graphql/types.ts +0 -283
  356. package/renderer/lib/api-docs/parsers/openapi/README.md +0 -32
  357. package/renderer/lib/api-docs/parsers/openapi/dereferencer.ts +0 -60
  358. package/renderer/lib/api-docs/parsers/openapi/extractors/auth.ts +0 -574
  359. package/renderer/lib/api-docs/parsers/openapi/extractors/body.ts +0 -403
  360. package/renderer/lib/api-docs/parsers/openapi/extractors/index.ts +0 -232
  361. package/renderer/lib/api-docs/parsers/openapi/index.ts +0 -171
  362. package/renderer/lib/api-docs/parsers/openapi/transformer.ts +0 -278
  363. package/renderer/lib/api-docs/parsers/openapi/validator.ts +0 -31
  364. package/renderer/lib/api-docs/playground/context.tsx +0 -107
  365. package/renderer/lib/api-docs/playground/navigation-context.tsx +0 -124
  366. package/renderer/lib/api-docs/playground/request-builder.ts +0 -223
  367. package/renderer/lib/api-docs/playground/request-runner.ts +0 -282
  368. package/renderer/lib/api-docs/playground/types.ts +0 -35
  369. package/renderer/lib/api-docs/types.ts +0 -269
  370. package/renderer/lib/api-docs/utils.ts +0 -311
  371. package/renderer/lib/cache.ts +0 -193
  372. package/renderer/lib/docs/config/domain-schema.ts +0 -260
  373. package/renderer/lib/docs/config/index.ts +0 -43
  374. package/renderer/lib/docs/config/loader.ts +0 -142
  375. package/renderer/lib/docs/config/schema.ts +0 -308
  376. package/renderer/lib/docs/index.ts +0 -12
  377. package/renderer/lib/docs/mdx/compiler.ts +0 -176
  378. package/renderer/lib/docs/mdx/frontmatter.ts +0 -91
  379. package/renderer/lib/docs/mdx/index.ts +0 -26
  380. package/renderer/lib/docs/navigation/generator.ts +0 -348
  381. package/renderer/lib/docs/navigation/index.ts +0 -12
  382. package/renderer/lib/docs/navigation/types.ts +0 -123
  383. package/renderer/lib/docs-navigation-context.tsx +0 -80
  384. package/renderer/lib/multi-tenant/context.ts +0 -105
  385. package/renderer/lib/storage/blob.ts +0 -1083
  386. package/renderer/lib/utils/icons.ts +0 -48
  387. package/renderer/lib/utils.ts +0 -6
  388. package/renderer/next.config.ts +0 -76
@@ -89,12 +89,23 @@ async function installWithProgress(cwd) {
89
89
  let packagesAdded = 0;
90
90
  let spinnerIndex = 0;
91
91
  let lastOutput = '';
92
- // Animated spinner
92
+ // Helper to safely clear line (may not be available in non-TTY)
93
+ const clearLine = () => {
94
+ if (process.stdout.clearLine) {
95
+ process.stdout.clearLine(0);
96
+ }
97
+ if (process.stdout.cursorTo) {
98
+ process.stdout.cursorTo(0);
99
+ }
100
+ };
101
+ // Animated spinner (only if TTY)
102
+ const isTTY = process.stdout.isTTY;
93
103
  const spinnerInterval = setInterval(() => {
94
- process.stdout.clearLine(0);
95
- process.stdout.cursorTo(0);
96
- const spinner = SPINNER_FRAMES[spinnerIndex % SPINNER_FRAMES.length];
97
- process.stdout.write(` ${logger_1.logger.cyan(spinner)} ${currentStep}`);
104
+ if (isTTY) {
105
+ clearLine();
106
+ const spinner = SPINNER_FRAMES[spinnerIndex % SPINNER_FRAMES.length];
107
+ process.stdout.write(` ${logger_1.logger.cyan(spinner)} ${currentStep}`);
108
+ }
98
109
  spinnerIndex++;
99
110
  }, 80);
100
111
  const updateStep = (line) => {
@@ -134,8 +145,7 @@ async function installWithProgress(cwd) {
134
145
  });
135
146
  installChild.on('exit', (code) => {
136
147
  clearInterval(spinnerInterval);
137
- process.stdout.clearLine(0);
138
- process.stdout.cursorTo(0);
148
+ clearLine();
139
149
  if (code === 0) {
140
150
  if (packagesAdded > 0) {
141
151
  console.log(` ${logger_1.logger.green('✓')} Installed ${packagesAdded} packages`);
@@ -155,8 +165,7 @@ async function installWithProgress(cwd) {
155
165
  });
156
166
  installChild.on('error', (error) => {
157
167
  clearInterval(spinnerInterval);
158
- process.stdout.clearLine(0);
159
- process.stdout.cursorTo(0);
168
+ clearLine();
160
169
  reject(error);
161
170
  });
162
171
  });
@@ -257,4 +266,4 @@ async function dev(options) {
257
266
  child.kill('SIGTERM');
258
267
  });
259
268
  }
260
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy9kZXYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFnTEEsa0JBc0hDO0FBdFNELGlEQUFzQztBQUN0QyxnREFBd0I7QUFDeEIsd0RBQTBCO0FBQzFCLDhDQUFzQjtBQUN0Qix5Q0FBMEQ7QUFDMUQsK0NBQTRDO0FBQzVDLDZDQUFtRDtBQVFuRDs7R0FFRztBQUNILEtBQUssVUFBVSxXQUFXLENBQUMsR0FBVztJQUNwQyxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRTdCLElBQUksQ0FBQztRQUNILElBQUksT0FBZSxDQUFDO1FBQ3BCLElBQUksSUFBYyxDQUFDO1FBRW5CLFFBQVEsUUFBUSxFQUFFLENBQUM7WUFDakIsS0FBSyxRQUFRLEVBQUUsUUFBUTtnQkFDckIsT0FBTyxHQUFHLE1BQU0sQ0FBQztnQkFDakIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2IsTUFBTTtZQUNSLEtBQUssT0FBTyxFQUFFLFVBQVU7Z0JBQ3RCLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0JBQ2hCLElBQUksR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUNoQyxNQUFNO1lBQ1IsU0FBUyxtQkFBbUI7Z0JBQzFCLE9BQU8sR0FBRyxVQUFVLENBQUM7Z0JBQ3JCLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNiLE1BQU07UUFDVixDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBQSxxQkFBSyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUU7WUFDakMsS0FBSyxFQUFFLFFBQVE7WUFDZixRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsMkNB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Q0FBQztRQUMvQixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyx3Q0FBd0M7SUFDcEQsQ0FBQztJQUVELEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDMUIsZUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDekQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztJQUVILEtBQUssQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFDeEIsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDMUIsQ0FBQyxDQUFDLENBQUM7SUFFSCxxQkFBcUI7SUFDckIsT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFO1FBQ3hCLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkIsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDekIsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN4QixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzcGF3biB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IG5ldCBmcm9tICduZXQnO1xuaW1wb3J0IHsgbG9hZENvbmZpZywgdmFsaWRhdGVDb25maWcgfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vLi4vdXRpbHMvbG9nZ2VyJztcbmltcG9ydCB7IGdldFJlbmRlcmVyRGlyIH0gZnJvbSAnLi4vLi4vdXRpbHMvcGF0aHMnO1xuXG5pbnRlcmZhY2UgRGV2T3B0aW9ucyB7XG4gIHBvcnQ6IHN0cmluZztcbiAgaG9zdDogc3RyaW5nO1xuICBvcGVuOiBib29sZWFuO1xufVxuXG4vKipcbiAqIE9wZW4gVVJMIGluIHRoZSBkZWZhdWx0IGJyb3dzZXIgKGNyb3NzLXBsYXRmb3JtKVxuICovXG5hc3luYyBmdW5jdGlvbiBvcGVuQnJvd3Nlcih1cmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IHBsYXRmb3JtIH0gPSBwcm9jZXNzO1xuICBcbiAgdHJ5IHtcbiAgICBsZXQgY29tbWFuZDogc3RyaW5nO1xuICAgIGxldCBhcmdzOiBzdHJpbmdbXTtcbiAgICBcbiAgICBzd2l0Y2ggKHBsYXRmb3JtKSB7XG4gICAgICBjYXNlICdkYXJ3aW4nOiAvLyBtYWNPU1xuICAgICAgICBjb21tYW5kID0gJ29wZW4nO1xuICAgICAgICBhcmdzID0gW3VybF07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnd2luMzInOiAvLyBXaW5kb3dzXG4gICAgICAgIGNvbW1hbmQgPSAnY21kJztcbiAgICAgICAgYXJncyA9IFsnL2MnLCAnc3RhcnQnLCAnJywgdXJsXTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OiAvLyBMaW51eCBhbmQgb3RoZXJzXG4gICAgICAgIGNvbW1hbmQgPSAneGRnLW9wZW4nO1xuICAgICAgICBhcmdzID0gW3VybF07XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBjaGlsZCA9IHNwYXduKGNvbW1hbmQsIGFyZ3MsIHtcbiAgICAgIHN0ZGlvOiAnaWdub3JlJyxcbiAgICAgIGRldGFjaGVkOiB0cnVlLFxuICAgIH0pO1xuICAgIFxuICAgIGNoaWxkLnVucmVmKCk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIFNpbGVudGx5IGZhaWwgaWYgYnJvd3NlciBjYW4ndCBiZSBvcGVuZWRcbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgcG9ydCBpcyBhdmFpbGFibGVcbiAqL1xuYXN5bmMgZnVuY3Rpb24gaXNQb3J0QXZhaWxhYmxlKHBvcnQ6IG51bWJlciwgaG9zdDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGNvbnN0IHNlcnZlciA9IG5ldC5jcmVhdGVTZXJ2ZXIoKTtcbiAgICBzZXJ2ZXIub25jZSgnZXJyb3InLCAoKSA9PiByZXNvbHZlKGZhbHNlKSk7XG4gICAgc2VydmVyLm9uY2UoJ2xpc3RlbmluZycsICgpID0+IHtcbiAgICAgIHNlcnZlci5jbG9zZSgpO1xuICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICB9KTtcbiAgICBzZXJ2ZXIubGlzdGVuKHBvcnQsIGhvc3QpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGaW5kIGFuIGF2YWlsYWJsZSBwb3J0IHN0YXJ0aW5nIGZyb20gdGhlIGdpdmVuIHBvcnRcbiAqL1xuYXN5bmMgZnVuY3Rpb24gZmluZEF2YWlsYWJsZVBvcnQoc3RhcnRQb3J0OiBudW1iZXIsIGhvc3Q6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gIGxldCBwb3J0ID0gc3RhcnRQb3J0O1xuICBjb25zdCBtYXhBdHRlbXB0cyA9IDEwO1xuICBcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXhBdHRlbXB0czsgaSsrKSB7XG4gICAgaWYgKGF3YWl0IGlzUG9ydEF2YWlsYWJsZShwb3J0LCBob3N0KSkge1xuICAgICAgcmV0dXJuIHBvcnQ7XG4gICAgfVxuICAgIHBvcnQrKztcbiAgfVxuICBcbiAgdGhyb3cgbmV3IEVycm9yKGBObyBhdmFpbGFibGUgcG9ydCBmb3VuZCBiZXR3ZWVuICR7c3RhcnRQb3J0fSBhbmQgJHtzdGFydFBvcnQgKyBtYXhBdHRlbXB0cyAtIDF9YCk7XG59XG5cbi8qKlxuICogU3Bpbm5lciBmcmFtZXMgZm9yIGFuaW1hdGVkIHByb2dyZXNzXG4gKi9cbmNvbnN0IFNQSU5ORVJfRlJBTUVTID0gWyfioIsnLCAn4qCZJywgJ+KguScsICfioLgnLCAn4qC8JywgJ+KgtCcsICfioKYnLCAn4qCnJywgJ+KghycsICfioI8nXTtcblxuLyoqXG4gKiBJbnN0YWxsIGRlcGVuZGVuY2llcyB3aXRoIGFuaW1hdGVkIHByb2dyZXNzIGRpc3BsYXlcbiAqL1xuYXN5bmMgZnVuY3Rpb24gaW5zdGFsbFdpdGhQcm9ncmVzcyhjd2Q6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGluc3RhbGxDaGlsZCA9IHNwYXduKCducG0nLCBbJ2luc3RhbGwnXSwge1xuICAgICAgY3dkLFxuICAgICAgc3RkaW86IFsncGlwZScsICdwaXBlJywgJ3BpcGUnXSxcbiAgICAgIHNoZWxsOiB0cnVlLFxuICAgIH0pO1xuICAgIFxuICAgIGxldCBjdXJyZW50U3RlcCA9ICdSZXNvbHZpbmcgZGVwZW5kZW5jaWVzLi4uJztcbiAgICBsZXQgcGFja2FnZXNBZGRlZCA9IDA7XG4gICAgbGV0IHNwaW5uZXJJbmRleCA9IDA7XG4gICAgbGV0IGxhc3RPdXRwdXQgPSAnJztcbiAgICBcbiAgICAvLyBBbmltYXRlZCBzcGlubmVyXG4gICAgY29uc3Qgc3Bpbm5lckludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgcHJvY2Vzcy5zdGRvdXQuY2xlYXJMaW5lKDApO1xuICAgICAgcHJvY2Vzcy5zdGRvdXQuY3Vyc29yVG8oMCk7XG4gICAgICBjb25zdCBzcGlubmVyID0gU1BJTk5FUl9GUkFNRVNbc3Bpbm5lckluZGV4ICUgU1BJTk5FUl9GUkFNRVMubGVuZ3RoXTtcbiAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGAgICR7bG9nZ2VyLmN5YW4oc3Bpbm5lcil9ICR7Y3VycmVudFN0ZXB9YCk7XG4gICAgICBzcGlubmVySW5kZXgrKztcbiAgICB9LCA4MCk7XG4gICAgXG4gICAgY29uc3QgdXBkYXRlU3RlcCA9IChsaW5lOiBzdHJpbmcpID0+IHtcbiAgICAgIC8vIERldGVjdCBwaGFzZXMgZnJvbSBucG0gb3V0cHV0XG4gICAgICBpZiAobGluZS5pbmNsdWRlcygnaWRlYWxUcmVlJykgfHwgbGluZS5pbmNsdWRlcygncmVzb2x2aW5nJykpIHtcbiAgICAgICAgY3VycmVudFN0ZXAgPSAnUmVzb2x2aW5nIGRlcGVuZGVuY2llcy4uLic7XG4gICAgICB9IGVsc2UgaWYgKGxpbmUuaW5jbHVkZXMoJ3JlaWZ5JykgfHwgbGluZS5pbmNsdWRlcygnZXh0cmFjdCcpKSB7XG4gICAgICAgIGN1cnJlbnRTdGVwID0gJ0luc3RhbGxpbmcgcGFja2FnZXMuLi4nO1xuICAgICAgfSBlbHNlIGlmIChsaW5lLmluY2x1ZGVzKCdhdWRpdCcpKSB7XG4gICAgICAgIGN1cnJlbnRTdGVwID0gJ1J1bm5pbmcgc2VjdXJpdHkgYXVkaXQuLi4nO1xuICAgICAgfSBlbHNlIGlmIChsaW5lLmluY2x1ZGVzKCdhZGRlZCcpKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gbGluZS5tYXRjaCgvYWRkZWQgKFxcZCspIHBhY2thZ2VzPy9pKTtcbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgcGFja2FnZXNBZGRlZCA9IHBhcnNlSW50KG1hdGNoWzFdLCAxMCk7XG4gICAgICAgICAgY3VycmVudFN0ZXAgPSBgSW5zdGFsbGVkICR7cGFja2FnZXNBZGRlZH0gcGFja2FnZXNgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBsYXN0T3V0cHV0ID0gbGluZTtcbiAgICB9O1xuICAgIFxuICAgIC8vIFByb2Nlc3Mgc3Rkb3V0XG4gICAgaW5zdGFsbENoaWxkLnN0ZG91dD8ub24oJ2RhdGEnLCAoZGF0YTogQnVmZmVyKSA9PiB7XG4gICAgICBkYXRhLnRvU3RyaW5nKCkuc3BsaXQoJ1xcbicpLmZvckVhY2gobGluZSA9PiB7XG4gICAgICAgIGlmIChsaW5lLnRyaW0oKSkgdXBkYXRlU3RlcChsaW5lKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIC8vIFByb2Nlc3Mgc3RkZXJyIChucG0gb3V0cHV0cyBwcm9ncmVzcyB0byBzdGRlcnIpXG4gICAgaW5zdGFsbENoaWxkLnN0ZGVycj8ub24oJ2RhdGEnLCAoZGF0YTogQnVmZmVyKSA9PiB7XG4gICAgICBkYXRhLnRvU3RyaW5nKCkuc3BsaXQoJ1xcbicpLmZvckVhY2gobGluZSA9PiB7XG4gICAgICAgIGlmIChsaW5lLnRyaW0oKSAmJiAhbGluZS5pbmNsdWRlcygnV0FSTicpICYmICFsaW5lLmluY2x1ZGVzKCducG0gd2FybicpKSB7XG4gICAgICAgICAgdXBkYXRlU3RlcChsaW5lKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgXG4gICAgaW5zdGFsbENoaWxkLm9uKCdleGl0JywgKGNvZGUpID0+IHtcbiAgICAgIGNsZWFySW50ZXJ2YWwoc3Bpbm5lckludGVydmFsKTtcbiAgICAgIHByb2Nlc3Muc3Rkb3V0LmNsZWFyTGluZSgwKTtcbiAgICAgIHByb2Nlc3Muc3Rkb3V0LmN1cnNvclRvKDApO1xuICAgICAgXG4gICAgICBpZiAoY29kZSA9PT0gMCkge1xuICAgICAgICBpZiAocGFja2FnZXNBZGRlZCA+IDApIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICAke2xvZ2dlci5ncmVlbign4pyTJyl9IEluc3RhbGxlZCAke3BhY2thZ2VzQWRkZWR9IHBhY2thZ2VzYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYCAgJHtsb2dnZXIuZ3JlZW4oJ+KckycpfSBEZXBlbmRlbmNpZXMgaW5zdGFsbGVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coYCAgJHtsb2dnZXIucmVkKCfinJcnKX0gSW5zdGFsbGF0aW9uIGZhaWxlZGApO1xuICAgICAgICBpZiAobGFzdE91dHB1dCAmJiAhbGFzdE91dHB1dC5pbmNsdWRlcygnbnBtIHdhcm4nKSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICAgJHtsYXN0T3V0cHV0fWApO1xuICAgICAgICB9XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYG5wbSBpbnN0YWxsIGZhaWxlZCB3aXRoIGNvZGUgJHtjb2RlfWApKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICBpbnN0YWxsQ2hpbGQub24oJ2Vycm9yJywgKGVycm9yKSA9PiB7XG4gICAgICBjbGVhckludGVydmFsKHNwaW5uZXJJbnRlcnZhbCk7XG4gICAgICBwcm9jZXNzLnN0ZG91dC5jbGVhckxpbmUoMCk7XG4gICAgICBwcm9jZXNzLnN0ZG91dC5jdXJzb3JUbygwKTtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGV2KG9wdGlvbnM6IERldk9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvamVjdFJvb3QgPSBwcm9jZXNzLmN3ZCgpO1xuICBcbiAgbG9nZ2VyLmluZm8oJ1N0YXJ0aW5nIERldkRvYyBkZXZlbG9wbWVudCBzZXJ2ZXIuLi4nKTtcbiAgXG4gIC8vIENoZWNrIGZvciBkb2NzLmpzb25cbiAgY29uc3QgY29uZmlnUGF0aCA9IHBhdGguam9pbihwcm9qZWN0Um9vdCwgJ2RvY3MuanNvbicpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMoY29uZmlnUGF0aCkpIHtcbiAgICBsb2dnZXIuZXJyb3IoJ2RvY3MuanNvbiBub3QgZm91bmQgaW4gY3VycmVudCBkaXJlY3RvcnknKTtcbiAgICBsb2dnZXIuaW5mbygnUnVuIFwiZGV2ZG9jIGluaXRcIiB0byBjcmVhdGUgYSBuZXcgZG9jdW1lbnRhdGlvbiBwcm9qZWN0Jyk7XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG4gIFxuICAvLyBMb2FkIGFuZCB2YWxpZGF0ZSBjb25maWdcbiAgdHJ5IHtcbiAgICBjb25zdCBjb25maWcgPSBhd2FpdCBsb2FkQ29uZmlnKHByb2plY3RSb290KTtcbiAgICBjb25zdCB2YWxpZGF0aW9uID0gdmFsaWRhdGVDb25maWcoY29uZmlnKTtcbiAgICBcbiAgICBpZiAoIXZhbGlkYXRpb24udmFsaWQpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignSW52YWxpZCBkb2NzLmpzb24gY29uZmlndXJhdGlvbjonKTtcbiAgICAgIHZhbGlkYXRpb24uZXJyb3JzLmZvckVhY2goZXJyID0+IGxvZ2dlci5lcnJvcihgICAtICR7ZXJyfWApKTtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gICAgXG4gICAgbG9nZ2VyLnN1Y2Nlc3MoYExvYWRlZCBjb25maWd1cmF0aW9uOiAke2NvbmZpZy5uYW1lIHx8ICdVbnRpdGxlZCd9YCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBsb2FkIGRvY3MuanNvbjogJHttZXNzYWdlfWApO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuICBcbiAgLy8gR2V0IHRoZSByZW5kZXJlciBkaXJlY3RvcnkgKGJ1bmRsZWQgd2l0aCB0aGlzIHBhY2thZ2UpXG4gIGNvbnN0IHJlbmRlcmVyRGlyID0gZ2V0UmVuZGVyZXJEaXIoKTtcbiAgXG4gIGlmICghcmVuZGVyZXJEaXIgfHwgIWZzLmV4aXN0c1N5bmMocmVuZGVyZXJEaXIpKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdSZW5kZXJlciBub3QgZm91bmQuIFBhY2thZ2UgbWF5IGJlIGNvcnJ1cHRlZC4nKTtcbiAgICBsb2dnZXIuZGVidWcoYExvb2tlZCBmb3IgcmVuZGVyZXIgYXQ6ICR7cmVuZGVyZXJEaXJ9YCk7XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG4gIFxuICAvLyBDaGVjayBpZiByZW5kZXJlciBoYXMgbm9kZV9tb2R1bGVzXG4gIGNvbnN0IG5vZGVNb2R1bGVzUGF0aCA9IHBhdGguam9pbihyZW5kZXJlckRpciwgJ25vZGVfbW9kdWxlcycpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMobm9kZU1vZHVsZXNQYXRoKSkge1xuICAgIGxvZ2dlci5pbmZvKCdJbnN0YWxsaW5nIHJlbmRlcmVyIGRlcGVuZGVuY2llcyAoZmlyc3QgcnVuKS4uLicpO1xuICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICBcbiAgICBhd2FpdCBpbnN0YWxsV2l0aFByb2dyZXNzKHJlbmRlcmVyRGlyKTtcbiAgICBcbiAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgbG9nZ2VyLnN1Y2Nlc3MoJ0RlcGVuZGVuY2llcyBpbnN0YWxsZWQnKTtcbiAgfVxuICBcbiAgLy8gRmluZCBhdmFpbGFibGUgcG9ydFxuICBjb25zdCByZXF1ZXN0ZWRQb3J0ID0gcGFyc2VJbnQob3B0aW9ucy5wb3J0LCAxMCk7XG4gIGxldCBhY3R1YWxQb3J0OiBudW1iZXI7XG4gIFxuICB0cnkge1xuICAgIGFjdHVhbFBvcnQgPSBhd2FpdCBmaW5kQXZhaWxhYmxlUG9ydChyZXF1ZXN0ZWRQb3J0LCBvcHRpb25zLmhvc3QpO1xuICAgIGlmIChhY3R1YWxQb3J0ICE9PSByZXF1ZXN0ZWRQb3J0KSB7XG4gICAgICBsb2dnZXIud2FybihgUG9ydCAke3JlcXVlc3RlZFBvcnR9IGlzIGluIHVzZSwgdXNpbmcgJHthY3R1YWxQb3J0fSBpbnN0ZWFkYCk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgbG9nZ2VyLmVycm9yKG1lc3NhZ2UpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuICBcbiAgLy8gU2V0IGVudmlyb25tZW50IHZhcmlhYmxlcyAtIHVzZSBTVEFSVEVSX1BBVEggd2l0aCBhYnNvbHV0ZSBwYXRoXG4gIGNvbnN0IGVudiA9IHtcbiAgICAuLi5wcm9jZXNzLmVudixcbiAgICBTVEFSVEVSX1BBVEg6IHByb2plY3RSb290LCAvLyBBYnNvbHV0ZSBwYXRoIHRvIHVzZXIncyBwcm9qZWN0XG4gICAgUE9SVDogU3RyaW5nKGFjdHVhbFBvcnQpLFxuICAgIEhPU1ROQU1FOiBvcHRpb25zLmhvc3QsXG4gIH07XG4gIFxuICBjb25zdCBzZXJ2ZXJVcmwgPSBgaHR0cDovLyR7b3B0aW9ucy5ob3N0fToke2FjdHVhbFBvcnR9YDtcbiAgXG4gIGxvZ2dlci5pbmZvKGBDb250ZW50IGRpcmVjdG9yeTogJHtwcm9qZWN0Um9vdH1gKTtcbiAgbG9nZ2VyLmluZm8oYFN0YXJ0aW5nIHNlcnZlciBhdCAke3NlcnZlclVybH1gKTtcbiAgbG9nZ2VyLmluZm8oJ1ByZXNzIEN0cmwrQyB0byBzdG9wXFxuJyk7XG4gIFxuICAvLyBTdGFydCBOZXh0LmpzIGRldiBzZXJ2ZXIgd2l0aCBUdXJib3BhY2sgZm9yIGJldHRlciBwYXRoIGFsaWFzIHN1cHBvcnRcbiAgY29uc3QgY2hpbGQgPSBzcGF3bihcbiAgICAnbnB4JyxcbiAgICBbJ25leHQnLCAnZGV2JywgJy0tdHVyYm8nLCAnLXAnLCBTdHJpbmcoYWN0dWFsUG9ydCksICctSCcsIG9wdGlvbnMuaG9zdF0sXG4gICAge1xuICAgICAgY3dkOiByZW5kZXJlckRpcixcbiAgICAgIGVudixcbiAgICAgIHN0ZGlvOiAnaW5oZXJpdCcsXG4gICAgICBzaGVsbDogdHJ1ZSxcbiAgICB9XG4gICk7XG4gIFxuICAvLyBPcGVuIGJyb3dzZXIgYWZ0ZXIgYSBzaG9ydCBkZWxheSB0byBsZXQgdGhlIHNlcnZlciBzdGFydFxuICBpZiAob3B0aW9ucy5vcGVuKSB7XG4gICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgT3BlbmluZyAke3NlcnZlclVybH0gaW4geW91ciBicm93c2VyLi4uYCk7XG4gICAgICBhd2FpdCBvcGVuQnJvd3NlcihzZXJ2ZXJVcmwpO1xuICAgIH0sIDMwMDApOyAvLyBXYWl0IDMgc2Vjb25kcyBmb3Igc2VydmVyIHRvIGJlIHJlYWR5XG4gIH1cbiAgXG4gIGNoaWxkLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfSk7XG4gIFxuICBjaGlsZC5vbignZXhpdCcsIChjb2RlKSA9PiB7XG4gICAgcHJvY2Vzcy5leGl0KGNvZGUgfHwgMCk7XG4gIH0pO1xuICBcbiAgLy8gSGFuZGxlIHRlcm1pbmF0aW9uXG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsICgpID0+IHtcbiAgICBjaGlsZC5raWxsKCdTSUdJTlQnKTtcbiAgfSk7XG4gIFxuICBwcm9jZXNzLm9uKCdTSUdURVJNJywgKCkgPT4ge1xuICAgIGNoaWxkLmtpbGwoJ1NJR1RFUk0nKTtcbiAgfSk7XG59XG4iXX0=
269
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy9kZXYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUEwTEEsa0JBc0hDO0FBaFRELGlEQUFzQztBQUN0QyxnREFBd0I7QUFDeEIsd0RBQTBCO0FBQzFCLDhDQUFzQjtBQUN0Qix5Q0FBMEQ7QUFDMUQsK0NBQTRDO0FBQzVDLDZDQUFtRDtBQVFuRDs7R0FFRztBQUNILEtBQUssVUFBVSxXQUFXLENBQUMsR0FBVztJQUNwQyxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsT0FBTyxDQUFDO0lBRTdCLElBQUksQ0FBQztRQUNILElBQUksT0FBZSxDQUFDO1FBQ3BCLElBQUksSUFBYyxDQUFDO1FBRW5CLFFBQVEsUUFBUSxFQUFFLENBQUM7WUFDakIsS0FBSyxRQUFRLEVBQUUsUUFBUTtnQkFDckIsT0FBTyxHQUFHLE1BQU0sQ0FBQztnQkFDakIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2IsTUFBTTtZQUNSLEtBQUssT0FBTyxFQUFFLFVBQVU7Z0JBQ3RCLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0JBQ2hCLElBQUksR0FBRyxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUNoQyxNQUFNO1lBQ1IsU0FBUyxtQkFBbUI7Z0JBQzFCLE9BQU8sR0FBRyxVQUFVLENBQUM7Z0JBQ3JCLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNiLE1BQU07UUFDVixDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBQSxxQkFBSyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUU7WUFDakMsS0FBSyxFQUFFLFFBQVE7WUFDZixRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsMkNB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QUM7UUFDakIsVUFBVSxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ3BCLGVBQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxTQUFTLHFCQUFxQixDQUFDLENBQUM7WUFDdkQsTUFBTSxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0lBQ3BELENBQUM7SUFFRCxLQUFLLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQzFCLGVBQU0sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ3hCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFCLENBQUMsQ0FBQyxDQUFDO0lBRUgscUJBQXFCO0lBQ3JCLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRTtRQUN4QixLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFO1FBQ3pCLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJztcbmltcG9ydCBuZXQgZnJvbSAnbmV0JztcbmltcG9ydCB7IGxvYWRDb25maWcsIHZhbGlkYXRlQ29uZmlnIH0gZnJvbSAnLi4vLi4vY29uZmlnJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZ2dlcic7XG5pbXBvcnQgeyBnZXRSZW5kZXJlckRpciB9IGZyb20gJy4uLy4uL3V0aWxzL3BhdGhzJztcblxuaW50ZXJmYWNlIERldk9wdGlvbnMge1xuICBwb3J0OiBzdHJpbmc7XG4gIGhvc3Q6IHN0cmluZztcbiAgb3BlbjogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBPcGVuIFVSTCBpbiB0aGUgZGVmYXVsdCBicm93c2VyIChjcm9zcy1wbGF0Zm9ybSlcbiAqL1xuYXN5bmMgZnVuY3Rpb24gb3BlbkJyb3dzZXIodXJsOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBwbGF0Zm9ybSB9ID0gcHJvY2VzcztcbiAgXG4gIHRyeSB7XG4gICAgbGV0IGNvbW1hbmQ6IHN0cmluZztcbiAgICBsZXQgYXJnczogc3RyaW5nW107XG4gICAgXG4gICAgc3dpdGNoIChwbGF0Zm9ybSkge1xuICAgICAgY2FzZSAnZGFyd2luJzogLy8gbWFjT1NcbiAgICAgICAgY29tbWFuZCA9ICdvcGVuJztcbiAgICAgICAgYXJncyA9IFt1cmxdO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3dpbjMyJzogLy8gV2luZG93c1xuICAgICAgICBjb21tYW5kID0gJ2NtZCc7XG4gICAgICAgIGFyZ3MgPSBbJy9jJywgJ3N0YXJ0JywgJycsIHVybF07XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDogLy8gTGludXggYW5kIG90aGVyc1xuICAgICAgICBjb21tYW5kID0gJ3hkZy1vcGVuJztcbiAgICAgICAgYXJncyA9IFt1cmxdO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgXG4gICAgY29uc3QgY2hpbGQgPSBzcGF3bihjb21tYW5kLCBhcmdzLCB7XG4gICAgICBzdGRpbzogJ2lnbm9yZScsXG4gICAgICBkZXRhY2hlZDogdHJ1ZSxcbiAgICB9KTtcbiAgICBcbiAgICBjaGlsZC51bnJlZigpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBTaWxlbnRseSBmYWlsIGlmIGJyb3dzZXIgY2FuJ3QgYmUgb3BlbmVkXG4gIH1cbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIHBvcnQgaXMgYXZhaWxhYmxlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGlzUG9ydEF2YWlsYWJsZShwb3J0OiBudW1iZXIsIGhvc3Q6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXQuY3JlYXRlU2VydmVyKCk7XG4gICAgc2VydmVyLm9uY2UoJ2Vycm9yJywgKCkgPT4gcmVzb2x2ZShmYWxzZSkpO1xuICAgIHNlcnZlci5vbmNlKCdsaXN0ZW5pbmcnLCAoKSA9PiB7XG4gICAgICBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgfSk7XG4gICAgc2VydmVyLmxpc3Rlbihwb3J0LCBob3N0KTtcbiAgfSk7XG59XG5cbi8qKlxuICogRmluZCBhbiBhdmFpbGFibGUgcG9ydCBzdGFydGluZyBmcm9tIHRoZSBnaXZlbiBwb3J0XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZpbmRBdmFpbGFibGVQb3J0KHN0YXJ0UG9ydDogbnVtYmVyLCBob3N0OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4ge1xuICBsZXQgcG9ydCA9IHN0YXJ0UG9ydDtcbiAgY29uc3QgbWF4QXR0ZW1wdHMgPSAxMDtcbiAgXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4QXR0ZW1wdHM7IGkrKykge1xuICAgIGlmIChhd2FpdCBpc1BvcnRBdmFpbGFibGUocG9ydCwgaG9zdCkpIHtcbiAgICAgIHJldHVybiBwb3J0O1xuICAgIH1cbiAgICBwb3J0Kys7XG4gIH1cbiAgXG4gIHRocm93IG5ldyBFcnJvcihgTm8gYXZhaWxhYmxlIHBvcnQgZm91bmQgYmV0d2VlbiAke3N0YXJ0UG9ydH0gYW5kICR7c3RhcnRQb3J0ICsgbWF4QXR0ZW1wdHMgLSAxfWApO1xufVxuXG4vKipcbiAqIFNwaW5uZXIgZnJhbWVzIGZvciBhbmltYXRlZCBwcm9ncmVzc1xuICovXG5jb25zdCBTUElOTkVSX0ZSQU1FUyA9IFsn4qCLJywgJ+KgmScsICfioLknLCAn4qC4JywgJ+KgvCcsICfioLQnLCAn4qCmJywgJ+KgpycsICfioIcnLCAn4qCPJ107XG5cbi8qKlxuICogSW5zdGFsbCBkZXBlbmRlbmNpZXMgd2l0aCBhbmltYXRlZCBwcm9ncmVzcyBkaXNwbGF5XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluc3RhbGxXaXRoUHJvZ3Jlc3MoY3dkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBpbnN0YWxsQ2hpbGQgPSBzcGF3bignbnBtJywgWydpbnN0YWxsJ10sIHtcbiAgICAgIGN3ZCxcbiAgICAgIHN0ZGlvOiBbJ3BpcGUnLCAncGlwZScsICdwaXBlJ10sXG4gICAgICBzaGVsbDogdHJ1ZSxcbiAgICB9KTtcbiAgICBcbiAgICBsZXQgY3VycmVudFN0ZXAgPSAnUmVzb2x2aW5nIGRlcGVuZGVuY2llcy4uLic7XG4gICAgbGV0IHBhY2thZ2VzQWRkZWQgPSAwO1xuICAgIGxldCBzcGlubmVySW5kZXggPSAwO1xuICAgIGxldCBsYXN0T3V0cHV0ID0gJyc7XG4gICAgXG4gICAgLy8gSGVscGVyIHRvIHNhZmVseSBjbGVhciBsaW5lIChtYXkgbm90IGJlIGF2YWlsYWJsZSBpbiBub24tVFRZKVxuICAgIGNvbnN0IGNsZWFyTGluZSA9ICgpID0+IHtcbiAgICAgIGlmIChwcm9jZXNzLnN0ZG91dC5jbGVhckxpbmUpIHtcbiAgICAgICAgcHJvY2Vzcy5zdGRvdXQuY2xlYXJMaW5lKDApO1xuICAgICAgfVxuICAgICAgaWYgKHByb2Nlc3Muc3Rkb3V0LmN1cnNvclRvKSB7XG4gICAgICAgIHByb2Nlc3Muc3Rkb3V0LmN1cnNvclRvKDApO1xuICAgICAgfVxuICAgIH07XG4gICAgXG4gICAgLy8gQW5pbWF0ZWQgc3Bpbm5lciAob25seSBpZiBUVFkpXG4gICAgY29uc3QgaXNUVFkgPSBwcm9jZXNzLnN0ZG91dC5pc1RUWTtcbiAgICBjb25zdCBzcGlubmVySW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAoaXNUVFkpIHtcbiAgICAgICAgY2xlYXJMaW5lKCk7XG4gICAgICAgIGNvbnN0IHNwaW5uZXIgPSBTUElOTkVSX0ZSQU1FU1tzcGlubmVySW5kZXggJSBTUElOTkVSX0ZSQU1FUy5sZW5ndGhdO1xuICAgICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShgICAke2xvZ2dlci5jeWFuKHNwaW5uZXIpfSAke2N1cnJlbnRTdGVwfWApO1xuICAgICAgfVxuICAgICAgc3Bpbm5lckluZGV4Kys7XG4gICAgfSwgODApO1xuICAgIFxuICAgIGNvbnN0IHVwZGF0ZVN0ZXAgPSAobGluZTogc3RyaW5nKSA9PiB7XG4gICAgICAvLyBEZXRlY3QgcGhhc2VzIGZyb20gbnBtIG91dHB1dFxuICAgICAgaWYgKGxpbmUuaW5jbHVkZXMoJ2lkZWFsVHJlZScpIHx8IGxpbmUuaW5jbHVkZXMoJ3Jlc29sdmluZycpKSB7XG4gICAgICAgIGN1cnJlbnRTdGVwID0gJ1Jlc29sdmluZyBkZXBlbmRlbmNpZXMuLi4nO1xuICAgICAgfSBlbHNlIGlmIChsaW5lLmluY2x1ZGVzKCdyZWlmeScpIHx8IGxpbmUuaW5jbHVkZXMoJ2V4dHJhY3QnKSkge1xuICAgICAgICBjdXJyZW50U3RlcCA9ICdJbnN0YWxsaW5nIHBhY2thZ2VzLi4uJztcbiAgICAgIH0gZWxzZSBpZiAobGluZS5pbmNsdWRlcygnYXVkaXQnKSkge1xuICAgICAgICBjdXJyZW50U3RlcCA9ICdSdW5uaW5nIHNlY3VyaXR5IGF1ZGl0Li4uJztcbiAgICAgIH0gZWxzZSBpZiAobGluZS5pbmNsdWRlcygnYWRkZWQnKSkge1xuICAgICAgICBjb25zdCBtYXRjaCA9IGxpbmUubWF0Y2goL2FkZGVkIChcXGQrKSBwYWNrYWdlcz8vaSk7XG4gICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgIHBhY2thZ2VzQWRkZWQgPSBwYXJzZUludChtYXRjaFsxXSwgMTApO1xuICAgICAgICAgIGN1cnJlbnRTdGVwID0gYEluc3RhbGxlZCAke3BhY2thZ2VzQWRkZWR9IHBhY2thZ2VzYDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGFzdE91dHB1dCA9IGxpbmU7XG4gICAgfTtcbiAgICBcbiAgICAvLyBQcm9jZXNzIHN0ZG91dFxuICAgIGluc3RhbGxDaGlsZC5zdGRvdXQ/Lm9uKCdkYXRhJywgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgZGF0YS50b1N0cmluZygpLnNwbGl0KCdcXG4nKS5mb3JFYWNoKGxpbmUgPT4ge1xuICAgICAgICBpZiAobGluZS50cmltKCkpIHVwZGF0ZVN0ZXAobGluZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBcbiAgICAvLyBQcm9jZXNzIHN0ZGVyciAobnBtIG91dHB1dHMgcHJvZ3Jlc3MgdG8gc3RkZXJyKVxuICAgIGluc3RhbGxDaGlsZC5zdGRlcnI/Lm9uKCdkYXRhJywgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgZGF0YS50b1N0cmluZygpLnNwbGl0KCdcXG4nKS5mb3JFYWNoKGxpbmUgPT4ge1xuICAgICAgICBpZiAobGluZS50cmltKCkgJiYgIWxpbmUuaW5jbHVkZXMoJ1dBUk4nKSAmJiAhbGluZS5pbmNsdWRlcygnbnBtIHdhcm4nKSkge1xuICAgICAgICAgIHVwZGF0ZVN0ZXAobGluZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIFxuICAgIGluc3RhbGxDaGlsZC5vbignZXhpdCcsIChjb2RlKSA9PiB7XG4gICAgICBjbGVhckludGVydmFsKHNwaW5uZXJJbnRlcnZhbCk7XG4gICAgICBjbGVhckxpbmUoKTtcbiAgICAgIFxuICAgICAgaWYgKGNvZGUgPT09IDApIHtcbiAgICAgICAgaWYgKHBhY2thZ2VzQWRkZWQgPiAwKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYCAgJHtsb2dnZXIuZ3JlZW4oJ+KckycpfSBJbnN0YWxsZWQgJHtwYWNrYWdlc0FkZGVkfSBwYWNrYWdlc2ApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLmdyZWVuKCfinJMnKX0gRGVwZW5kZW5jaWVzIGluc3RhbGxlZGApO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAgICR7bG9nZ2VyLnJlZCgn4pyXJyl9IEluc3RhbGxhdGlvbiBmYWlsZWRgKTtcbiAgICAgICAgaWYgKGxhc3RPdXRwdXQgJiYgIWxhc3RPdXRwdXQuaW5jbHVkZXMoJ25wbSB3YXJuJykpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgICAgICR7bGFzdE91dHB1dH1gKTtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QobmV3IEVycm9yKGBucG0gaW5zdGFsbCBmYWlsZWQgd2l0aCBjb2RlICR7Y29kZX1gKSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgaW5zdGFsbENoaWxkLm9uKCdlcnJvcicsIChlcnJvcikgPT4ge1xuICAgICAgY2xlYXJJbnRlcnZhbChzcGlubmVySW50ZXJ2YWwpO1xuICAgICAgY2xlYXJMaW5lKCk7XG4gICAgICByZWplY3QoZXJyb3IpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRldihvcHRpb25zOiBEZXZPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5jd2QoKTtcbiAgXG4gIGxvZ2dlci5pbmZvKCdTdGFydGluZyBEZXZEb2MgZGV2ZWxvcG1lbnQgc2VydmVyLi4uJyk7XG4gIFxuICAvLyBDaGVjayBmb3IgZG9jcy5qc29uXG4gIGNvbnN0IGNvbmZpZ1BhdGggPSBwYXRoLmpvaW4ocHJvamVjdFJvb3QsICdkb2NzLmpzb24nKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGNvbmZpZ1BhdGgpKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdkb2NzLmpzb24gbm90IGZvdW5kIGluIGN1cnJlbnQgZGlyZWN0b3J5Jyk7XG4gICAgbG9nZ2VyLmluZm8oJ1J1biBcImRldmRvYyBpbml0XCIgdG8gY3JlYXRlIGEgbmV3IGRvY3VtZW50YXRpb24gcHJvamVjdCcpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuICBcbiAgLy8gTG9hZCBhbmQgdmFsaWRhdGUgY29uZmlnXG4gIHRyeSB7XG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgbG9hZENvbmZpZyhwcm9qZWN0Um9vdCk7XG4gICAgY29uc3QgdmFsaWRhdGlvbiA9IHZhbGlkYXRlQ29uZmlnKGNvbmZpZyk7XG4gICAgXG4gICAgaWYgKCF2YWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0ludmFsaWQgZG9jcy5qc29uIGNvbmZpZ3VyYXRpb246Jyk7XG4gICAgICB2YWxpZGF0aW9uLmVycm9ycy5mb3JFYWNoKGVyciA9PiBsb2dnZXIuZXJyb3IoYCAgLSAke2Vycn1gKSk7XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuICAgIFxuICAgIGxvZ2dlci5zdWNjZXNzKGBMb2FkZWQgY29uZmlndXJhdGlvbjogJHtjb25maWcubmFtZSB8fCAnVW50aXRsZWQnfWApO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gbG9hZCBkb2NzLmpzb246ICR7bWVzc2FnZX1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbiAgXG4gIC8vIEdldCB0aGUgcmVuZGVyZXIgZGlyZWN0b3J5IChidW5kbGVkIHdpdGggdGhpcyBwYWNrYWdlKVxuICBjb25zdCByZW5kZXJlckRpciA9IGdldFJlbmRlcmVyRGlyKCk7XG4gIFxuICBpZiAoIXJlbmRlcmVyRGlyIHx8ICFmcy5leGlzdHNTeW5jKHJlbmRlcmVyRGlyKSkge1xuICAgIGxvZ2dlci5lcnJvcignUmVuZGVyZXIgbm90IGZvdW5kLiBQYWNrYWdlIG1heSBiZSBjb3JydXB0ZWQuJyk7XG4gICAgbG9nZ2VyLmRlYnVnKGBMb29rZWQgZm9yIHJlbmRlcmVyIGF0OiAke3JlbmRlcmVyRGlyfWApO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuICBcbiAgLy8gQ2hlY2sgaWYgcmVuZGVyZXIgaGFzIG5vZGVfbW9kdWxlc1xuICBjb25zdCBub2RlTW9kdWxlc1BhdGggPSBwYXRoLmpvaW4ocmVuZGVyZXJEaXIsICdub2RlX21vZHVsZXMnKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKG5vZGVNb2R1bGVzUGF0aCkpIHtcbiAgICBsb2dnZXIuaW5mbygnSW5zdGFsbGluZyByZW5kZXJlciBkZXBlbmRlbmNpZXMgKGZpcnN0IHJ1bikuLi4nKTtcbiAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgXG4gICAgYXdhaXQgaW5zdGFsbFdpdGhQcm9ncmVzcyhyZW5kZXJlckRpcik7XG4gICAgXG4gICAgY29uc29sZS5sb2coJycpO1xuICAgIGxvZ2dlci5zdWNjZXNzKCdEZXBlbmRlbmNpZXMgaW5zdGFsbGVkJyk7XG4gIH1cbiAgXG4gIC8vIEZpbmQgYXZhaWxhYmxlIHBvcnRcbiAgY29uc3QgcmVxdWVzdGVkUG9ydCA9IHBhcnNlSW50KG9wdGlvbnMucG9ydCwgMTApO1xuICBsZXQgYWN0dWFsUG9ydDogbnVtYmVyO1xuICBcbiAgdHJ5IHtcbiAgICBhY3R1YWxQb3J0ID0gYXdhaXQgZmluZEF2YWlsYWJsZVBvcnQocmVxdWVzdGVkUG9ydCwgb3B0aW9ucy5ob3N0KTtcbiAgICBpZiAoYWN0dWFsUG9ydCAhPT0gcmVxdWVzdGVkUG9ydCkge1xuICAgICAgbG9nZ2VyLndhcm4oYFBvcnQgJHtyZXF1ZXN0ZWRQb3J0fSBpcyBpbiB1c2UsIHVzaW5nICR7YWN0dWFsUG9ydH0gaW5zdGVhZGApO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgIGxvZ2dlci5lcnJvcihtZXNzYWdlKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbiAgXG4gIC8vIFNldCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgLSB1c2UgU1RBUlRFUl9QQVRIIHdpdGggYWJzb2x1dGUgcGF0aFxuICBjb25zdCBlbnYgPSB7XG4gICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgU1RBUlRFUl9QQVRIOiBwcm9qZWN0Um9vdCwgLy8gQWJzb2x1dGUgcGF0aCB0byB1c2VyJ3MgcHJvamVjdFxuICAgIFBPUlQ6IFN0cmluZyhhY3R1YWxQb3J0KSxcbiAgICBIT1NUTkFNRTogb3B0aW9ucy5ob3N0LFxuICB9O1xuICBcbiAgY29uc3Qgc2VydmVyVXJsID0gYGh0dHA6Ly8ke29wdGlvbnMuaG9zdH06JHthY3R1YWxQb3J0fWA7XG4gIFxuICBsb2dnZXIuaW5mbyhgQ29udGVudCBkaXJlY3Rvcnk6ICR7cHJvamVjdFJvb3R9YCk7XG4gIGxvZ2dlci5pbmZvKGBTdGFydGluZyBzZXJ2ZXIgYXQgJHtzZXJ2ZXJVcmx9YCk7XG4gIGxvZ2dlci5pbmZvKCdQcmVzcyBDdHJsK0MgdG8gc3RvcFxcbicpO1xuICBcbiAgLy8gU3RhcnQgTmV4dC5qcyBkZXYgc2VydmVyIHdpdGggVHVyYm9wYWNrIGZvciBiZXR0ZXIgcGF0aCBhbGlhcyBzdXBwb3J0XG4gIGNvbnN0IGNoaWxkID0gc3Bhd24oXG4gICAgJ25weCcsXG4gICAgWyduZXh0JywgJ2RldicsICctLXR1cmJvJywgJy1wJywgU3RyaW5nKGFjdHVhbFBvcnQpLCAnLUgnLCBvcHRpb25zLmhvc3RdLFxuICAgIHtcbiAgICAgIGN3ZDogcmVuZGVyZXJEaXIsXG4gICAgICBlbnYsXG4gICAgICBzdGRpbzogJ2luaGVyaXQnLFxuICAgICAgc2hlbGw6IHRydWUsXG4gICAgfVxuICApO1xuICBcbiAgLy8gT3BlbiBicm93c2VyIGFmdGVyIGEgc2hvcnQgZGVsYXkgdG8gbGV0IHRoZSBzZXJ2ZXIgc3RhcnRcbiAgaWYgKG9wdGlvbnMub3Blbikge1xuICAgIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oYE9wZW5pbmcgJHtzZXJ2ZXJVcmx9IGluIHlvdXIgYnJvd3Nlci4uLmApO1xuICAgICAgYXdhaXQgb3BlbkJyb3dzZXIoc2VydmVyVXJsKTtcbiAgICB9LCAzMDAwKTsgLy8gV2FpdCAzIHNlY29uZHMgZm9yIHNlcnZlciB0byBiZSByZWFkeVxuICB9XG4gIFxuICBjaGlsZC5vbignZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBzdGFydCBzZXJ2ZXI6ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH0pO1xuICBcbiAgY2hpbGQub24oJ2V4aXQnLCAoY29kZSkgPT4ge1xuICAgIHByb2Nlc3MuZXhpdChjb2RlIHx8IDApO1xuICB9KTtcbiAgXG4gIC8vIEhhbmRsZSB0ZXJtaW5hdGlvblxuICBwcm9jZXNzLm9uKCdTSUdJTlQnLCAoKSA9PiB7XG4gICAgY2hpbGQua2lsbCgnU0lHSU5UJyk7XG4gIH0pO1xuICBcbiAgcHJvY2Vzcy5vbignU0lHVEVSTScsICgpID0+IHtcbiAgICBjaGlsZC5raWxsKCdTSUdURVJNJyk7XG4gIH0pO1xufVxuIl19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainfish-ai/devdoc",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "description": "Documentation framework for developers. Write docs in MDX, preview locally, deploy to Brainfish.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -35,8 +35,9 @@
35
35
  "giget": "^1.2.3"
36
36
  },
37
37
  "devDependencies": {
38
- "@types/node": "^20.0.0",
38
+ "@swc/core": "^1.3.100",
39
39
  "@types/fs-extra": "^11.0.4",
40
+ "@types/node": "^20.0.0",
40
41
  "typescript": "^5.0.0"
41
42
  },
42
43
  "files": [
@@ -0,0 +1,108 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { head } from '@vercel/blob';
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ // Check if we're in local development mode
6
+ const IS_LOCAL_DEV = !process.env.BLOB_READ_WRITE_TOKEN;
7
+ const LOCAL_STORAGE_DIR = path.join(process.cwd(), '.devdoc-storage');
8
+ /**
9
+ * Asset proxy - serves uploaded assets for multi-tenant docs
10
+ *
11
+ * GET /api/assets/[slug]/[...path]
12
+ *
13
+ * This allows MDX files to reference assets as:
14
+ * ![logo](/api/assets/my-project/logo.png)
15
+ *
16
+ * Or with the middleware rewrite, simply:
17
+ * ![logo](/logo.png) -> rewrites to /api/assets/[slug]/logo.png
18
+ */ export async function GET(request, { params }) {
19
+ try {
20
+ const { path: pathSegments } = await params;
21
+ if (!pathSegments || pathSegments.length < 2) {
22
+ return NextResponse.json({
23
+ error: 'Invalid asset path'
24
+ }, {
25
+ status: 400
26
+ });
27
+ }
28
+ // First segment is the project slug, rest is the asset path
29
+ const [slug, ...assetPath] = pathSegments;
30
+ const fileName = assetPath.join('/');
31
+ if (!slug || !fileName) {
32
+ return NextResponse.json({
33
+ error: 'Missing slug or file path'
34
+ }, {
35
+ status: 400
36
+ });
37
+ }
38
+ // Build blob path
39
+ const blobPath = `projects/${slug}/assets/${fileName}`;
40
+ if (IS_LOCAL_DEV) {
41
+ // Local development - serve from filesystem
42
+ const filePath = path.join(LOCAL_STORAGE_DIR, 'projects', slug, 'assets', fileName);
43
+ if (!fs.existsSync(filePath)) {
44
+ return NextResponse.json({
45
+ error: 'Asset not found'
46
+ }, {
47
+ status: 404
48
+ });
49
+ }
50
+ const fileBuffer = fs.readFileSync(filePath);
51
+ const contentType = getContentType(fileName);
52
+ return new NextResponse(fileBuffer, {
53
+ status: 200,
54
+ headers: {
55
+ 'Content-Type': contentType,
56
+ 'Cache-Control': 'public, max-age=31536000, immutable'
57
+ }
58
+ });
59
+ }
60
+ // Production - fetch from Vercel Blob
61
+ const blobInfo = await head(blobPath).catch(()=>null);
62
+ if (!blobInfo) {
63
+ return NextResponse.json({
64
+ error: 'Asset not found'
65
+ }, {
66
+ status: 404
67
+ });
68
+ }
69
+ // Redirect to the blob URL (more efficient than proxying)
70
+ return NextResponse.redirect(blobInfo.url, {
71
+ status: 302,
72
+ headers: {
73
+ 'Cache-Control': 'public, max-age=31536000, immutable'
74
+ }
75
+ });
76
+ } catch (error) {
77
+ console.error('[Asset Proxy] Error:', error);
78
+ return NextResponse.json({
79
+ error: 'Failed to serve asset'
80
+ }, {
81
+ status: 500
82
+ });
83
+ }
84
+ }
85
+ /**
86
+ * Get content type from file extension
87
+ */ function getContentType(fileName) {
88
+ const ext = fileName.split('.').pop()?.toLowerCase();
89
+ const types = {
90
+ 'jpg': 'image/jpeg',
91
+ 'jpeg': 'image/jpeg',
92
+ 'png': 'image/png',
93
+ 'gif': 'image/gif',
94
+ 'webp': 'image/webp',
95
+ 'svg': 'image/svg+xml',
96
+ 'ico': 'image/x-icon',
97
+ 'pdf': 'application/pdf',
98
+ 'mp4': 'video/mp4',
99
+ 'webm': 'video/webm',
100
+ 'mp3': 'audio/mpeg',
101
+ 'wav': 'audio/wav',
102
+ 'woff': 'font/woff',
103
+ 'woff2': 'font/woff2',
104
+ 'ttf': 'font/ttf',
105
+ 'otf': 'font/otf'
106
+ };
107
+ return types[ext || ''] || 'application/octet-stream';
108
+ }
@@ -0,0 +1,114 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { validateApiKey, listProjectAssets, deleteProjectAsset } from '@/lib/storage/blob';
3
+ /**
4
+ * List assets API
5
+ *
6
+ * GET /api/assets?slug=<project-slug>
7
+ * Headers:
8
+ * Authorization: Bearer <api_key>
9
+ */ export async function GET(request) {
10
+ try {
11
+ const { searchParams } = new URL(request.url);
12
+ const slug = searchParams.get('slug');
13
+ if (!slug) {
14
+ return NextResponse.json({
15
+ error: 'Missing slug parameter'
16
+ }, {
17
+ status: 400
18
+ });
19
+ }
20
+ // Validate API key
21
+ const authHeader = request.headers.get('Authorization');
22
+ const apiKey = authHeader?.replace('Bearer ', '');
23
+ if (!apiKey) {
24
+ return NextResponse.json({
25
+ error: 'API key required'
26
+ }, {
27
+ status: 401
28
+ });
29
+ }
30
+ const validatedSlug = await validateApiKey(apiKey);
31
+ if (validatedSlug !== slug) {
32
+ return NextResponse.json({
33
+ error: 'Invalid API key for this project'
34
+ }, {
35
+ status: 403
36
+ });
37
+ }
38
+ const assets = await listProjectAssets(slug);
39
+ return NextResponse.json({
40
+ success: true,
41
+ slug,
42
+ assets,
43
+ count: assets.length
44
+ });
45
+ } catch (error) {
46
+ console.error('[Assets API] Error:', error);
47
+ const message = error instanceof Error ? error.message : String(error);
48
+ return NextResponse.json({
49
+ error: 'Failed to list assets',
50
+ details: message
51
+ }, {
52
+ status: 500
53
+ });
54
+ }
55
+ }
56
+ /**
57
+ * Delete asset API
58
+ *
59
+ * DELETE /api/assets?slug=<project-slug>&fileName=<file-name>
60
+ * Headers:
61
+ * Authorization: Bearer <api_key>
62
+ */ export async function DELETE(request) {
63
+ try {
64
+ const { searchParams } = new URL(request.url);
65
+ const slug = searchParams.get('slug');
66
+ const fileName = searchParams.get('fileName');
67
+ if (!slug || !fileName) {
68
+ return NextResponse.json({
69
+ error: 'Missing slug or fileName parameter'
70
+ }, {
71
+ status: 400
72
+ });
73
+ }
74
+ // Validate API key
75
+ const authHeader = request.headers.get('Authorization');
76
+ const apiKey = authHeader?.replace('Bearer ', '');
77
+ if (!apiKey) {
78
+ return NextResponse.json({
79
+ error: 'API key required'
80
+ }, {
81
+ status: 401
82
+ });
83
+ }
84
+ const validatedSlug = await validateApiKey(apiKey);
85
+ if (validatedSlug !== slug) {
86
+ return NextResponse.json({
87
+ error: 'Invalid API key for this project'
88
+ }, {
89
+ status: 403
90
+ });
91
+ }
92
+ const deleted = await deleteProjectAsset(slug, fileName);
93
+ if (!deleted) {
94
+ return NextResponse.json({
95
+ error: 'Asset not found'
96
+ }, {
97
+ status: 404
98
+ });
99
+ }
100
+ return NextResponse.json({
101
+ success: true,
102
+ message: `Asset ${fileName} deleted`
103
+ });
104
+ } catch (error) {
105
+ console.error('[Assets API] Error:', error);
106
+ const message = error instanceof Error ? error.message : String(error);
107
+ return NextResponse.json({
108
+ error: 'Failed to delete asset',
109
+ details: message
110
+ }, {
111
+ status: 500
112
+ });
113
+ }
114
+ }
@@ -0,0 +1,163 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { put } from '@vercel/blob';
3
+ import { validateApiKey } from '@/lib/storage/blob';
4
+ import path from 'path';
5
+ import fs from 'fs';
6
+ // Max file size: 25MB
7
+ const MAX_FILE_SIZE = 25 * 1024 * 1024;
8
+ // Allowed file types for assets
9
+ const ALLOWED_TYPES = [
10
+ 'image/jpeg',
11
+ 'image/png',
12
+ 'image/gif',
13
+ 'image/webp',
14
+ 'image/svg+xml',
15
+ 'image/x-icon',
16
+ 'image/vnd.microsoft.icon',
17
+ 'application/pdf',
18
+ 'video/mp4',
19
+ 'video/webm',
20
+ 'audio/mpeg',
21
+ 'audio/wav',
22
+ 'font/woff',
23
+ 'font/woff2',
24
+ 'font/ttf',
25
+ 'font/otf',
26
+ 'application/font-woff',
27
+ 'application/font-woff2'
28
+ ];
29
+ // Check if we're in local development mode
30
+ const IS_LOCAL_DEV = !process.env.BLOB_READ_WRITE_TOKEN;
31
+ const LOCAL_STORAGE_DIR = path.join(process.cwd(), '.devdoc-storage');
32
+ /**
33
+ * Upload asset API - receives files from CLI and stores in Vercel Blob
34
+ *
35
+ * POST /api/assets/upload
36
+ * Headers:
37
+ * Authorization: Bearer <api_key>
38
+ * Content-Type: multipart/form-data
39
+ * Body: FormData with:
40
+ * - file: File to upload
41
+ * - slug: Project slug
42
+ * - path: Optional path/filename for the asset
43
+ */ export async function POST(request) {
44
+ try {
45
+ // Validate API key
46
+ const authHeader = request.headers.get('Authorization');
47
+ const apiKey = authHeader?.replace('Bearer ', '');
48
+ if (!apiKey) {
49
+ return NextResponse.json({
50
+ error: 'API key required. Provide via Authorization header.'
51
+ }, {
52
+ status: 401
53
+ });
54
+ }
55
+ const validatedSlug = await validateApiKey(apiKey);
56
+ if (!validatedSlug) {
57
+ return NextResponse.json({
58
+ error: 'Invalid API key'
59
+ }, {
60
+ status: 403
61
+ });
62
+ }
63
+ // Parse multipart form data
64
+ const formData = await request.formData();
65
+ const file = formData.get('file');
66
+ const slug = formData.get('slug');
67
+ const assetPath = formData.get('path');
68
+ if (!file) {
69
+ return NextResponse.json({
70
+ error: 'No file provided'
71
+ }, {
72
+ status: 400
73
+ });
74
+ }
75
+ if (!slug) {
76
+ return NextResponse.json({
77
+ error: 'Project slug is required'
78
+ }, {
79
+ status: 400
80
+ });
81
+ }
82
+ // Verify the API key matches the project
83
+ if (validatedSlug !== slug) {
84
+ return NextResponse.json({
85
+ error: 'API key does not match project'
86
+ }, {
87
+ status: 403
88
+ });
89
+ }
90
+ // Validate file size
91
+ if (file.size > MAX_FILE_SIZE) {
92
+ return NextResponse.json({
93
+ error: `File size exceeds maximum allowed size of 25MB. Current size: ${(file.size / (1024 * 1024)).toFixed(2)}MB`
94
+ }, {
95
+ status: 400
96
+ });
97
+ }
98
+ // Validate file type
99
+ const contentType = file.type;
100
+ if (!ALLOWED_TYPES.includes(contentType) && !contentType.startsWith('image/')) {
101
+ return NextResponse.json({
102
+ error: `File type "${contentType}" is not allowed. Allowed types: images, PDFs, videos, audio, and fonts.`
103
+ }, {
104
+ status: 400
105
+ });
106
+ }
107
+ // Generate asset path
108
+ const fileName = assetPath || file.name;
109
+ const sanitizedFileName = fileName.replace(/[^a-zA-Z0-9._-]/g, '_');
110
+ const blobPath = `projects/${slug}/assets/${sanitizedFileName}`;
111
+ // Get file buffer
112
+ const buffer = Buffer.from(await file.arrayBuffer());
113
+ // Store in local filesystem or Vercel Blob
114
+ let url;
115
+ if (IS_LOCAL_DEV) {
116
+ // Local development - store in filesystem
117
+ const assetDir = path.join(LOCAL_STORAGE_DIR, 'projects', slug, 'assets');
118
+ fs.mkdirSync(assetDir, {
119
+ recursive: true
120
+ });
121
+ const filePath = path.join(assetDir, sanitizedFileName);
122
+ fs.writeFileSync(filePath, buffer);
123
+ url = `file://${filePath}`;
124
+ } else {
125
+ // Production - store in Vercel Blob
126
+ const blob = await put(blobPath, buffer, {
127
+ access: 'public',
128
+ contentType,
129
+ allowOverwrite: true
130
+ });
131
+ url = blob.url;
132
+ }
133
+ return NextResponse.json({
134
+ success: true,
135
+ url,
136
+ path: blobPath,
137
+ fileName: sanitizedFileName,
138
+ size: file.size,
139
+ contentType
140
+ });
141
+ } catch (error) {
142
+ console.error('[Asset Upload API] Error:', error);
143
+ const message = error instanceof Error ? error.message : String(error);
144
+ return NextResponse.json({
145
+ error: 'Upload failed',
146
+ details: message
147
+ }, {
148
+ status: 500
149
+ });
150
+ }
151
+ }
152
+ /**
153
+ * OPTIONS for CORS preflight
154
+ */ export async function OPTIONS() {
155
+ return new NextResponse(null, {
156
+ status: 200,
157
+ headers: {
158
+ 'Access-Control-Allow-Origin': '*',
159
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
160
+ 'Access-Control-Allow-Headers': 'Content-Type, Authorization'
161
+ }
162
+ });
163
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Auth Schemes API Route
3
+ *
4
+ * Returns the security schemes defined in the OpenAPI spec
5
+ * so the frontend can suggest the correct auth type
6
+ */ import { NextResponse } from 'next/server';
7
+ import { readFileSync, existsSync } from 'fs';
8
+ import { join, isAbsolute } from 'path';
9
+ import { extractSecuritySchemes, getDefaultAuth } from '@/lib/api-docs/parsers/openapi/extractors/auth';
10
+ const STARTER_PATH = process.env.STARTER_PATH || 'devdoc-docs';
11
+ const LOCAL_SPEC_PATH = process.env.LOCAL_SPEC_PATH || `${STARTER_PATH}/api-reference/openapi.json`;
12
+ // Helper to resolve paths
13
+ function resolvePath(...paths) {
14
+ if (isAbsolute(STARTER_PATH)) {
15
+ return join(STARTER_PATH, ...paths);
16
+ }
17
+ return join(process.cwd(), STARTER_PATH, ...paths);
18
+ }
19
+ // Load OpenAPI spec from local file
20
+ function loadLocalSpec() {
21
+ try {
22
+ const relativePath = LOCAL_SPEC_PATH;
23
+ const fullPath = relativePath.startsWith(STARTER_PATH) || isAbsolute(relativePath) ? isAbsolute(relativePath) ? relativePath : resolvePath(relativePath.replace(STARTER_PATH + '/', '')) : resolvePath(relativePath);
24
+ if (!existsSync(fullPath)) {
25
+ return null;
26
+ }
27
+ const content = readFileSync(fullPath, 'utf-8');
28
+ return JSON.parse(content);
29
+ } catch (error) {
30
+ console.error('[Auth Schemes] Error loading local spec:', error);
31
+ return null;
32
+ }
33
+ }
34
+ export async function GET() {
35
+ try {
36
+ const spec = loadLocalSpec();
37
+ if (!spec) {
38
+ return NextResponse.json({
39
+ schemes: [],
40
+ defaultAuth: null
41
+ });
42
+ }
43
+ const schemes = extractSecuritySchemes(spec);
44
+ const defaultAuth = getDefaultAuth(spec);
45
+ return NextResponse.json({
46
+ schemes,
47
+ defaultAuth
48
+ });
49
+ } catch (error) {
50
+ return NextResponse.json({
51
+ schemes: [],
52
+ defaultAuth: null,
53
+ error: error instanceof Error ? error.message : 'Unknown error'
54
+ }, {
55
+ status: 500
56
+ });
57
+ }
58
+ }