@kingsleyweb/bun-ui 0.0.0-stage → 3.0.0-rc.2

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 (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -2
  3. package/app/docs/App.tsx +72 -0
  4. package/app/docs/api/client.ts +303 -0
  5. package/app/docs/api/contract.ts +24 -0
  6. package/app/docs/api/docs.ts +38 -0
  7. package/app/docs/api/errors.ts +144 -0
  8. package/app/docs/boot.tsx +58 -0
  9. package/app/docs/components/Badge.tsx +65 -0
  10. package/app/docs/components/Button.tsx +37 -0
  11. package/app/docs/components/Card.tsx +41 -0
  12. package/app/docs/components/ConfirmDialog.tsx +173 -0
  13. package/app/docs/components/CopyButton.tsx +68 -0
  14. package/app/docs/components/Dialog.tsx +230 -0
  15. package/app/docs/components/EmptyState.tsx +34 -0
  16. package/app/docs/components/ErrorView.tsx +70 -0
  17. package/app/docs/components/Field.tsx +93 -0
  18. package/app/docs/components/JsonEditor.tsx +151 -0
  19. package/app/docs/components/JsonView.tsx +338 -0
  20. package/app/docs/components/KeyValue.tsx +63 -0
  21. package/app/docs/components/ProblemBanner.tsx +116 -0
  22. package/app/docs/components/ScreenErrorBoundary.tsx +141 -0
  23. package/app/docs/components/Spinner.tsx +33 -0
  24. package/app/docs/components/Table.tsx +33 -0
  25. package/app/docs/components/Tabs.tsx +226 -0
  26. package/app/docs/components/classNames.ts +4 -0
  27. package/app/docs/components/components.css +691 -0
  28. package/app/docs/components/copy.ts +89 -0
  29. package/app/docs/components/fieldContext.ts +29 -0
  30. package/app/docs/components/inputValues.ts +142 -0
  31. package/app/docs/components/inputs.tsx +387 -0
  32. package/app/docs/components/jsonParse.ts +338 -0
  33. package/app/docs/components/listKeys.ts +30 -0
  34. package/app/docs/config.ts +86 -0
  35. package/app/docs/context.ts +33 -0
  36. package/app/docs/embed.ts +74 -0
  37. package/app/docs/env.d.ts +2 -0
  38. package/app/docs/format.ts +9 -0
  39. package/app/docs/hooks/useUrlTab.ts +16 -0
  40. package/app/docs/main.tsx +11 -0
  41. package/app/docs/queryClient.ts +54 -0
  42. package/app/docs/router.tsx +194 -0
  43. package/app/docs/routing.ts +194 -0
  44. package/app/docs/screens/docs/document.ts +27 -0
  45. package/app/docs/screens/docs/http/OperationView.tsx +407 -0
  46. package/app/docs/screens/docs/http/Sidebar.tsx +190 -0
  47. package/app/docs/screens/docs/http/TryItPanel.tsx +603 -0
  48. package/app/docs/screens/docs/http/http.css +405 -0
  49. package/app/docs/screens/docs/http/index.tsx +395 -0
  50. package/app/docs/screens/docs/http/model.ts +604 -0
  51. package/app/docs/screens/docs/http/tryIt.ts +455 -0
  52. package/app/docs/screens/docs/permissions.ts +6 -0
  53. package/app/docs/screens/docs/schema/Prose.tsx +43 -0
  54. package/app/docs/screens/docs/schema/SchemaTree.tsx +319 -0
  55. package/app/docs/screens/docs/schema/index.ts +30 -0
  56. package/app/docs/screens/docs/schema/resolve.ts +466 -0
  57. package/app/docs/screens/docs/schema/schema.css +137 -0
  58. package/app/docs/screens/docs/schema/skeleton.ts +92 -0
  59. package/app/docs/screens/docs/viewer.tsx +154 -0
  60. package/app/docs/screens/docs/ws/InlineText.tsx +25 -0
  61. package/app/docs/screens/docs/ws/PayloadSchema.tsx +39 -0
  62. package/app/docs/screens/docs/ws/format.ts +82 -0
  63. package/app/docs/screens/docs/ws/index.tsx +286 -0
  64. package/app/docs/screens/docs/ws/items.tsx +786 -0
  65. package/app/docs/screens/docs/ws/model.ts +1178 -0
  66. package/app/docs/screens/docs/ws/panels.tsx +440 -0
  67. package/app/docs/screens/docs/ws/ws.css +231 -0
  68. package/app/docs/shortcuts.ts +94 -0
  69. package/app/docs/styles/base.css +847 -0
  70. package/app/docs/styles/tokens.css +143 -0
  71. package/app/docs/theme.ts +56 -0
  72. package/app/kit/unauthorized.ts +222 -0
  73. package/dist/docs/assets/main-0rchxtv5.js +18 -0
  74. package/dist/docs/assets/main-0rchxtv5.js.map +99 -0
  75. package/dist/docs/assets/main-cqgyvs86.css +1 -0
  76. package/dist/docs/manifest.json +26 -0
  77. package/dist/jobs/assets/AddFlowDialog-h6xkgx9b.js +6 -0
  78. package/dist/jobs/assets/AddFlowDialog-h6xkgx9b.js.map +11 -0
  79. package/dist/jobs/assets/AddFlowDialog-n7gtc84v.css +1 -0
  80. package/dist/jobs/assets/added-cbwsxv3e.js +4 -0
  81. package/dist/jobs/assets/added-cbwsxv3e.js.map +11 -0
  82. package/dist/jobs/assets/bodies-yyw5hmrp.js +6 -0
  83. package/dist/jobs/assets/bodies-yyw5hmrp.js.map +10 -0
  84. package/dist/jobs/assets/channel-tgkvqm8y.js +4 -0
  85. package/dist/jobs/assets/channel-tgkvqm8y.js.map +10 -0
  86. package/dist/jobs/assets/channelChecks-s4yz4yhw.js +4 -0
  87. package/dist/jobs/assets/channelChecks-s4yz4yhw.js.map +10 -0
  88. package/dist/jobs/assets/index-02427smp.css +1 -0
  89. package/dist/jobs/assets/index-09z2cjft.js +4 -0
  90. package/dist/jobs/assets/index-09z2cjft.js.map +16 -0
  91. package/dist/jobs/assets/index-18bn0gvy.css +1 -0
  92. package/dist/jobs/assets/index-47pxmyxn.js +4 -0
  93. package/dist/jobs/assets/index-47pxmyxn.js.map +10 -0
  94. package/dist/jobs/assets/index-4e55z986.js +4 -0
  95. package/dist/jobs/assets/index-4e55z986.js.map +11 -0
  96. package/dist/jobs/assets/index-5c933424.js +4 -0
  97. package/dist/jobs/assets/index-5c933424.js.map +18 -0
  98. package/dist/jobs/assets/index-5kbyqspm.css +1 -0
  99. package/dist/jobs/assets/index-5ng37hk6.css +1 -0
  100. package/dist/jobs/assets/index-5w8w7fvc.css +1 -0
  101. package/dist/jobs/assets/index-71qs5qyx.css +1 -0
  102. package/dist/jobs/assets/index-btpg4r8b.css +1 -0
  103. package/dist/jobs/assets/index-d5r5n0mm.js +4 -0
  104. package/dist/jobs/assets/index-d5r5n0mm.js.map +23 -0
  105. package/dist/jobs/assets/index-e0yy2skq.css +1 -0
  106. package/dist/jobs/assets/index-hs60b25v.js +10 -0
  107. package/dist/jobs/assets/index-hs60b25v.js.map +62 -0
  108. package/dist/jobs/assets/index-k2smrr70.js +4 -0
  109. package/dist/jobs/assets/index-k2smrr70.js.map +9 -0
  110. package/dist/jobs/assets/index-q24jw3w9.js +4 -0
  111. package/dist/jobs/assets/index-q24jw3w9.js.map +32 -0
  112. package/dist/jobs/assets/index-qfb80xen.css +1 -0
  113. package/dist/jobs/assets/index-rtynx6wj.js +4 -0
  114. package/dist/jobs/assets/index-rtynx6wj.js.map +10 -0
  115. package/dist/jobs/assets/live-6k7s6358.js +4 -0
  116. package/dist/jobs/assets/live-6k7s6358.js.map +10 -0
  117. package/dist/jobs/assets/main-0jmeh6mq.js +6 -0
  118. package/dist/jobs/assets/main-0jmeh6mq.js.map +12 -0
  119. package/dist/jobs/assets/main-3yj6bv90.js +5 -0
  120. package/dist/jobs/assets/main-3yj6bv90.js.map +10 -0
  121. package/dist/jobs/assets/main-4g69fn3x.js +5 -0
  122. package/dist/jobs/assets/main-4g69fn3x.js.map +10 -0
  123. package/dist/jobs/assets/main-4gte3eqq.js +5 -0
  124. package/dist/jobs/assets/main-4gte3eqq.js.map +10 -0
  125. package/dist/jobs/assets/main-4j1fcevh.js +5 -0
  126. package/dist/jobs/assets/main-4j1fcevh.js.map +10 -0
  127. package/dist/jobs/assets/main-54qwkz28.css +1 -0
  128. package/dist/jobs/assets/main-5grjvsy7.js +5 -0
  129. package/dist/jobs/assets/main-5grjvsy7.js.map +11 -0
  130. package/dist/jobs/assets/main-5zbx60gq.js +5 -0
  131. package/dist/jobs/assets/main-5zbx60gq.js.map +11 -0
  132. package/dist/jobs/assets/main-9prgjhg4.js +5 -0
  133. package/dist/jobs/assets/main-9prgjhg4.js.map +10 -0
  134. package/dist/jobs/assets/main-a250ffk7.js +17 -0
  135. package/dist/jobs/assets/main-a250ffk7.js.map +115 -0
  136. package/dist/jobs/assets/main-d6ge7w08.js +5 -0
  137. package/dist/jobs/assets/main-d6ge7w08.js.map +10 -0
  138. package/dist/jobs/assets/main-gngzht43.js +5 -0
  139. package/dist/jobs/assets/main-gngzht43.js.map +10 -0
  140. package/dist/jobs/assets/main-hg0hrg8j.js +5 -0
  141. package/dist/jobs/assets/main-hg0hrg8j.js.map +10 -0
  142. package/dist/jobs/assets/main-hm1ng3yg.js +5 -0
  143. package/dist/jobs/assets/main-hm1ng3yg.js.map +12 -0
  144. package/dist/jobs/assets/main-jkvd92z9.js +5 -0
  145. package/dist/jobs/assets/main-jkvd92z9.js.map +10 -0
  146. package/dist/jobs/assets/main-jv5xqd13.js +5 -0
  147. package/dist/jobs/assets/main-jv5xqd13.js.map +21 -0
  148. package/dist/jobs/assets/main-jxre7w93.js +5 -0
  149. package/dist/jobs/assets/main-jxre7w93.js.map +23 -0
  150. package/dist/jobs/assets/main-kwmqkjfx.js +5 -0
  151. package/dist/jobs/assets/main-kwmqkjfx.js.map +11 -0
  152. package/dist/jobs/assets/main-n9cf6bxm.js +5 -0
  153. package/dist/jobs/assets/main-n9cf6bxm.js.map +11 -0
  154. package/dist/jobs/assets/main-pegp0ygb.js +5 -0
  155. package/dist/jobs/assets/main-pegp0ygb.js.map +10 -0
  156. package/dist/jobs/assets/main-qr573853.js +5 -0
  157. package/dist/jobs/assets/main-qr573853.js.map +12 -0
  158. package/dist/jobs/assets/main-rq97rdr4.js +4 -0
  159. package/dist/jobs/assets/main-rq97rdr4.js.map +22 -0
  160. package/dist/jobs/assets/main-szjdmydc.js +5 -0
  161. package/dist/jobs/assets/main-szjdmydc.js.map +13 -0
  162. package/dist/jobs/assets/main-tnbhrm9n.js +7 -0
  163. package/dist/jobs/assets/main-tnbhrm9n.js.map +11 -0
  164. package/dist/jobs/assets/main-ts19j4n0.js +5 -0
  165. package/dist/jobs/assets/main-ts19j4n0.js.map +25 -0
  166. package/dist/jobs/assets/main-w93x1dzs.js +5 -0
  167. package/dist/jobs/assets/main-w93x1dzs.js.map +10 -0
  168. package/dist/jobs/assets/sections-0ksdxs8m.css +1 -0
  169. package/dist/jobs/assets/sections-0y7w4fb4.js +4 -0
  170. package/dist/jobs/assets/sections-0y7w4fb4.js.map +10 -0
  171. package/dist/jobs/assets/sse-mn0t0fh7.js +5 -0
  172. package/dist/jobs/assets/sse-mn0t0fh7.js.map +11 -0
  173. package/dist/jobs/assets/sseChecks-t7tcm7ra.js +4 -0
  174. package/dist/jobs/assets/sseChecks-t7tcm7ra.js.map +10 -0
  175. package/dist/jobs/assets/validation-ysjfy072.js +4 -0
  176. package/dist/jobs/assets/validation-ysjfy072.js.map +9 -0
  177. package/dist/jobs/manifest.json +511 -0
  178. package/dts/docs/assets.d.ts +144 -0
  179. package/dts/docs/assets.d.ts.map +1 -0
  180. package/dts/docs/browser/config.d.ts +61 -0
  181. package/dts/docs/browser/config.d.ts.map +1 -0
  182. package/dts/docs/browser/index.d.ts +12 -0
  183. package/dts/docs/browser/index.d.ts.map +1 -0
  184. package/dts/docs/docsUi.d.ts +42 -0
  185. package/dts/docs/docsUi.d.ts.map +1 -0
  186. package/dts/docs/hosted.d.ts +22 -0
  187. package/dts/docs/hosted.d.ts.map +1 -0
  188. package/dts/docs/index.d.ts +18 -0
  189. package/dts/docs/index.d.ts.map +1 -0
  190. package/dts/docs/shell.d.ts +57 -0
  191. package/dts/docs/shell.d.ts.map +1 -0
  192. package/dts/docs/types.d.ts +137 -0
  193. package/dts/docs/types.d.ts.map +1 -0
  194. package/dts/index.d.ts +21 -0
  195. package/dts/index.d.ts.map +1 -0
  196. package/dts/jobs/assets.d.ts +157 -0
  197. package/dts/jobs/assets.d.ts.map +1 -0
  198. package/dts/jobs/browser/config.d.ts +67 -0
  199. package/dts/jobs/browser/config.d.ts.map +1 -0
  200. package/dts/jobs/browser/index.d.ts +10 -0
  201. package/dts/jobs/browser/index.d.ts.map +1 -0
  202. package/dts/jobs/browser/unauthorized.d.ts +9 -0
  203. package/dts/jobs/browser/unauthorized.d.ts.map +1 -0
  204. package/dts/jobs/index.d.ts +24 -0
  205. package/dts/jobs/index.d.ts.map +1 -0
  206. package/dts/jobs/jobsUi.d.ts +63 -0
  207. package/dts/jobs/jobsUi.d.ts.map +1 -0
  208. package/dts/jobs/shell.d.ts +77 -0
  209. package/dts/jobs/shell.d.ts.map +1 -0
  210. package/dts/jobs/types.d.ts +146 -0
  211. package/dts/jobs/types.d.ts.map +1 -0
  212. package/dts/kit/browser/shared.d.ts +10 -0
  213. package/dts/kit/browser/shared.d.ts.map +1 -0
  214. package/dts/kit/browser/unauthorized.d.ts +74 -0
  215. package/dts/kit/browser/unauthorized.d.ts.map +1 -0
  216. package/dts/kit/unauthorized.d.ts +47 -0
  217. package/dts/kit/unauthorized.d.ts.map +1 -0
  218. package/guides/docs.md +170 -0
  219. package/guides/jobs.md +1120 -0
  220. package/lib/docs/assets.ts +427 -0
  221. package/lib/docs/browser/config.ts +66 -0
  222. package/lib/docs/browser/index.ts +24 -0
  223. package/lib/docs/docsUi.ts +623 -0
  224. package/lib/docs/hosted.ts +31 -0
  225. package/lib/docs/index.ts +37 -0
  226. package/lib/docs/shell.ts +156 -0
  227. package/lib/docs/types.ts +149 -0
  228. package/lib/index.ts +27 -0
  229. package/lib/jobs/assets.ts +448 -0
  230. package/lib/jobs/browser/config.ts +65 -0
  231. package/lib/jobs/browser/index.ts +9 -0
  232. package/lib/jobs/browser/unauthorized.ts +11 -0
  233. package/lib/jobs/index.ts +41 -0
  234. package/lib/jobs/jobsUi.ts +709 -0
  235. package/lib/jobs/shell.ts +205 -0
  236. package/lib/jobs/types.ts +162 -0
  237. package/lib/kit/browser/shared.ts +11 -0
  238. package/lib/kit/browser/unauthorized.ts +114 -0
  239. package/lib/kit/unauthorized.ts +222 -0
  240. package/package.json +198 -4
@@ -0,0 +1,61 @@
1
+ /**
2
+ * The contract between `docsUi()` (server, `lib/docs/`) and the React viewer
3
+ * (`app/docs/`).
4
+ *
5
+ * The server resolves this once per mount and inlines it into the HTML shell
6
+ * as `<script type="application/json" id="bun-api-docs-ui-config" nonce="…">`.
7
+ * The viewer reads it before its first request. It must stay free of runtime
8
+ * imports: both sides import it, and the app side is bundled for the browser.
9
+ */
10
+ import type { UiTheme } from "../../kit/browser/shared.js";
11
+ import type { UiUnauthorized } from "../../kit/browser/unauthorized.js";
12
+ export type { UiTheme };
13
+ /** Id of the `<script type="application/json">` element carrying {@link DocsUiConfig}. */
14
+ export declare const DOCS_UI_CONFIG_ELEMENT_ID = "bun-api-docs-ui-config";
15
+ /**
16
+ * The specification-extension prefixes the viewers read, in priority order:
17
+ * an extension named on an operation, channel or scheme as
18
+ * `<prefix>-<name>` is read from the first prefix that carries it (so
19
+ * `x-bun-common-schema` wins over `x-bun-jobs-schema` when a document has
20
+ * both). An extension under any other prefix is ignored.
21
+ */
22
+ export declare const DEFAULT_EXTENSION_PREFIXES: string[];
23
+ /**
24
+ * Colour scheme the viewer starts in: the package's shared {@link UiTheme}
25
+ * (`"system"` follows `prefers-color-scheme`), under the docs viewer's name.
26
+ */
27
+ export type DocsUiTheme = UiTheme;
28
+ /** Resolved configuration handed to the browser. Never carries secrets. */
29
+ export interface DocsUiConfig {
30
+ /** Shape version of this object, bumped on a breaking change. Currently `1`. */
31
+ version: 1;
32
+ /** Page title. Defaults to `"API docs"`. */
33
+ title: string;
34
+ /** Absolute path the viewer is mounted at, no trailing slash (e.g. `"/docs"`). Client routes live under it. */
35
+ basePath: string;
36
+ /** Path the hashed assets are served from, e.g. `"/docs/assets"`. */
37
+ assetsPath: string;
38
+ /**
39
+ * Where the viewer fetches the one document it shows: `<basePath>/document.json`
40
+ * when `docsUi()` was given a thunk (the router serves it there), else the
41
+ * URL exactly as configured (a same-origin path or an `http(s)` URL).
42
+ */
43
+ documentUrl: string;
44
+ /**
45
+ * Header the try-it panel adds on every mutation (any non-empty value), or
46
+ * `null` when none is configured. Mirrors the documented API's CSRF rule.
47
+ */
48
+ csrfHeader: string | null;
49
+ /** The extension prefixes in effect (see {@link DEFAULT_EXTENSION_PREFIXES}). */
50
+ extensions: readonly string[];
51
+ /** Initial colour scheme. */
52
+ theme: DocsUiTheme;
53
+ /**
54
+ * Where an authorization failure sends the browser (`docsUi()`'s
55
+ * `unauthorized`), or `null` when it is off: the viewer then shows the
56
+ * failure, as before. A host app that embeds the viewer's screens passes
57
+ * `null` and redirects through its own option.
58
+ */
59
+ unauthorized: UiUnauthorized | null;
60
+ }
61
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../lib/docs/browser/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,YAAY,EAAE,OAAO,EAAE,CAAC;AAExB,0FAA0F;AAC1F,eAAO,MAAM,yBAAyB,2BAA2B,CAAC;AAElE;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,UAAiC,CAAC;AAEzE;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC;AAElC,2EAA2E;AAC3E,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,OAAO,EAAE,CAAC,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,+GAA+G;IAC/G,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iFAAiF;IACjF,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,6BAA6B;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB;;;;;OAKG;IACH,YAAY,EAAE,cAAc,GAAG,IAAI,CAAC;CACrC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `@kingsleyweb/bun-ui/docs/browser`: the docs viewer's browser-safe
3
+ * contract, what `docsUi()` inlines into the page and the viewer reads before
4
+ * its first request, and the `unauthorized` option's browser-safe helpers
5
+ * (the redirect URL, the shape check, the defaults). No runtime import beyond
6
+ * constants and pure functions, and no domain package.
7
+ */
8
+ export type { DocsUiConfig, DocsUiTheme, UiTheme } from "./config.js";
9
+ export { DEFAULT_EXTENSION_PREFIXES, DOCS_UI_CONFIG_ELEMENT_ID, } from "./config.js";
10
+ export { DEFAULT_RETURN_PARAM, DEFAULT_UNAUTHORIZED_STATUSES, isUiUnauthorized, relativeReturnPath, unauthorizedRedirectUrl, } from "../../kit/browser/unauthorized.js";
11
+ export type { UiUnauthorized, UiUnauthorizedStatus, UnauthorizedOptions, } from "../../kit/browser/unauthorized.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/docs/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,gCAAgC,CAAC;AACxC,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { DocsUi, DocsUiOptions } from "./types.js";
2
+ import { ASSET_CACHE_CONTROL } from "../kit/browser/shared.js";
3
+ /** The viewer's default mount path. */
4
+ export declare const DEFAULT_BASE_PATH = "/docs";
5
+ /** The default page title. */
6
+ export declare const DEFAULT_TITLE = "API docs";
7
+ /** The path under `basePath` the bundle is served from. */
8
+ export declare const ASSETS_SUBPATH = "/assets";
9
+ /** The path under `basePath` a `document` thunk is served from. */
10
+ export declare const DOCUMENT_SUBPATH = "/document.json";
11
+ export { ASSET_CACHE_CONTROL };
12
+ /** Where the bundle comes from; tests point these at a fixture. */
13
+ export interface DocsUiInternals {
14
+ /** The dist directory read when present. Defaults to the package's `dist/`. */
15
+ distDir?: string;
16
+ /** The entry built in memory without a dist. Defaults to `app/main.tsx`. */
17
+ entry?: string;
18
+ }
19
+ /**
20
+ * Validates and normalises an absolute mount path: absolute, trailing slashes
21
+ * dropped, not `"/"`, and only segments of letters, digits, `_`, `.`, `~` and
22
+ * `-`.
23
+ */
24
+ export declare function normalizeBasePath(value: unknown, what: string): string;
25
+ /**
26
+ * Creates the viewer with an explicit bundle source. {@link docsUi} is this
27
+ * with the package's own `dist/` and `app/main.tsx`; tests point it at a
28
+ * fixture.
29
+ */
30
+ export declare function createDocsUi(options: DocsUiOptions, internals?: DocsUiInternals): DocsUi;
31
+ /**
32
+ * Creates the API-docs viewer: validates the options (throwing `ConfigError`
33
+ * for anything unusable), resolves the configuration the app is given, and
34
+ * builds the router.
35
+ *
36
+ * ```ts
37
+ * const ui = docsUi({ document: () => api.openapi(), basePath: "/docs" });
38
+ * app.use(ui.basePath, ui.router);
39
+ * ```
40
+ */
41
+ export declare function docsUi(options: DocsUiOptions): DocsUi;
42
+ //# sourceMappingURL=docsUi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docsUi.d.ts","sourceRoot":"","sources":["../../lib/docs/docsUi.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,MAAM,EAGN,aAAa,EACd,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAe5D,uCAAuC;AACvC,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,8BAA8B;AAC9B,eAAO,MAAM,aAAa,aAAa,CAAC;AAExC,2DAA2D;AAC3D,eAAO,MAAM,cAAc,YAAY,CAAC;AAExC,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAW/B,mEAAmE;AACnE,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBtE;AA6OD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,aAAa,EACtB,SAAS,GAAE,eAAoB,GAC9B,MAAM,CAiQR;AAED;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAErD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The bundle + shell surface a host router needs to serve the viewer itself
3
+ * (bun-common's `docsRouter` `"self-hosted"` viewer): the package's `dist/`
4
+ * resolution and the shell/CSP builders, re-exported from one module so the
5
+ * host imports one specifier. Everything here is server-side.
6
+ */
7
+ import type { Logger } from "@kingsleyweb/bun-common";
8
+ import type { UiAssets } from "./assets.js";
9
+ export { DEFAULT_DIST_DIR, DEFAULT_ENTRY, resolveAssetSource } from "./assets.js";
10
+ export type { UiAsset, UiAssets, UiManifest, UiManifestFile } from "./assets.js";
11
+ export { ASSET_CACHE_CONTROL } from "./docsUi.js";
12
+ export { createNonce, createShellRenderer, cspHeader } from "./shell.js";
13
+ export type { CspOptions, ShellRenderer } from "./shell.js";
14
+ /**
15
+ * Resolves the viewer's bundle for a host: the prebuilt `dist/` when present
16
+ * (verified against its manifest, SRI computed over the local bytes), else an
17
+ * in-memory `Bun.build` on the first request, once per process. This is the
18
+ * `dev: undefined` rule of `docsUi()` — a host serving the viewer gets the
19
+ * same assets the package would serve.
20
+ */
21
+ export declare function resolveHostedAssets(logger: Logger): () => Promise<UiAssets>;
22
+ //# sourceMappingURL=hosted.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted.d.ts","sourceRoot":"","sources":["../../lib/docs/hosted.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEzD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAO3E"}
@@ -0,0 +1,18 @@
1
+ export { ASSET_CACHE_CONTROL, DEFAULT_BASE_PATH, DEFAULT_TITLE, DOCUMENT_SUBPATH, docsUi, } from "./docsUi.js";
2
+ /**
3
+ * `@kingsleyweb/bun-ui/docs`: a self-hosted viewer for one OpenAPI 3.1 or
4
+ * AsyncAPI 3.0 document, served by a `docsUi()` handler. Needs no peer.
5
+ *
6
+ * ```ts
7
+ * const ui = docsUi({ document: "/jobs-api/openapi.json", basePath: "/docs" });
8
+ * app.use(ui.basePath, ui.router);
9
+ * ```
10
+ *
11
+ * The bundle machinery (`lib/docs/assets.ts`: building, writing and loading
12
+ * `dist/docs/`) is internal: `scripts/build.ts` and the tests import it directly.
13
+ */
14
+ export type { DocsUiConfig, DocsUiTheme } from "./browser/config.js";
15
+ export type { UiUnauthorized, UiUnauthorizedStatus, } from "../kit/browser/unauthorized.js";
16
+ export { DEFAULT_EXTENSION_PREFIXES, DOCS_UI_CONFIG_ELEMENT_ID, } from "./browser/config.js";
17
+ export type { DocsUi, DocsUiAuthorize, DocsUiAuthorizeContext, DocsUiAuthorizeResult, DocsUiDocumentThunk, DocsUiOptions, DocsUiUnauthorizedOptions, } from "./types.js";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/docs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,MAAM,GACP,MAAM,UAAU,CAAC;AAClB;;;;;;;;;;;GAWG;AACH,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClE,YAAY,EACV,cAAc,EACd,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,MAAM,EACN,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,aAAa,EACb,yBAAyB,GAC1B,MAAM,SAAS,CAAC"}
@@ -0,0 +1,57 @@
1
+ import type { UiAssets } from "./assets.js";
2
+ /**
3
+ * The HTML shell: the one page every client route answers with, and the
4
+ * Content-Security-Policy it is served under.
5
+ *
6
+ * Everything in it is fixed per mount except the nonce, which is fresh per
7
+ * request. The configuration travels as a nonce'd
8
+ * `<script type="application/json">`, escaped for a script context, so a title
9
+ * containing `</script>` cannot end the element early.
10
+ */
11
+ import type { DocsUiConfig } from "./browser/config.js";
12
+ /** A fresh CSP nonce: 128 random bits, base64. */
13
+ export declare function createNonce(): string;
14
+ /** Escapes text for an HTML text node or a quoted attribute value. */
15
+ export declare function escapeHtml(value: string): string;
16
+ /**
17
+ * Serialises a value as JSON that is safe inside a `<script>` element: `<`,
18
+ * `>` and `&` become `<`/`>`/`&` (so neither `</script>` nor
19
+ * `<!--` can appear), and U+2028/U+2029 are escaped too. The result is still
20
+ * valid JSON that parses back to the same value.
21
+ */
22
+ export declare function jsonForScript(value: unknown): string;
23
+ /** Inputs to {@link cspHeader}. */
24
+ export interface CspOptions {
25
+ /** This request's nonce. */
26
+ nonce: string;
27
+ /**
28
+ * `connect-src` sources after `'self'` — for a cross-origin document URL,
29
+ * its origin (see {@link documentOriginSource}). A source that is not a
30
+ * single CSP token (whitespace, `;` or `,`) is dropped rather than written
31
+ * into the header. Defaults to none.
32
+ */
33
+ connectSrc?: readonly string[];
34
+ }
35
+ /**
36
+ * The shell's Content-Security-Policy. Scripts only from this origin and
37
+ * carrying the nonce; styles only from files (no inline `<style>`, no `style`
38
+ * attributes in markup — setting `element.style` from script is still fine);
39
+ * connections to `'self'` plus `connectSrc`.
40
+ */
41
+ export declare function cspHeader(options: CspOptions): string;
42
+ /**
43
+ * The origin a cross-origin document URL adds to `connect-src`, or
44
+ * `undefined` for a same-origin one (`/jobs-api/openapi.json`). The viewer
45
+ * fetches the document from the page; a thunk is served same-origin by the
46
+ * router itself. Anything malformed is dropped rather than written into the
47
+ * header.
48
+ */
49
+ export declare function documentOriginSource(documentUrl: string): string | undefined;
50
+ /** A renderer for one mount: fixed parts computed once, the nonce per call. */
51
+ export type ShellRenderer = (nonce: string) => string;
52
+ /**
53
+ * Prepares the shell for a mount and a bundle. The returned function only
54
+ * splices a nonce in.
55
+ */
56
+ export declare function createShellRenderer(config: DocsUiConfig, assets: UiAssets): ShellRenderer;
57
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../lib/docs/shell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,kBAAkB,CAAC;AAIlE,kDAAkD;AAClD,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOpD;AAOD,mCAAmC;AACnC,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAKD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAerD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS5E;AAED,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,QAAQ,GACf,aAAa,CAqCf"}
@@ -0,0 +1,137 @@
1
+ import type { BunRequest, BunRouter, LoggerLike, RouterHandler } from "@kingsleyweb/bun-common";
2
+ import type { DocsUiConfig, DocsUiTheme } from "./browser/config.js";
3
+ import type { UnauthorizedOptions } from "../kit/browser/unauthorized.js";
4
+ /**
5
+ * Where to send the browser when an authorization check fails, instead of
6
+ * leaving it on a viewer that reports the failure. See
7
+ * {@link DocsUiOptions.unauthorized}; the fields are described on
8
+ * `UnauthorizedOptions`.
9
+ */
10
+ export type DocsUiUnauthorizedOptions = UnauthorizedOptions;
11
+ /** What {@link DocsUiOptions.authorize} is told about the request being decided. */
12
+ export interface DocsUiAuthorizeContext {
13
+ /** `true` for a bundle file under `<basePath>/assets/`, `false` for the HTML shell or the document a thunk serves. */
14
+ asset: boolean;
15
+ /** The request's full path, e.g. `"/docs/http/listQueues"` (no query string). */
16
+ path: string;
17
+ }
18
+ /**
19
+ * What `authorize` answers — the same shape as bun-jobs' API and UI take:
20
+ * `true`/`false`, or `{ allow: true }` / `{ allow: false, status?: 401 | 403,
21
+ * reason? }`. A denial is a 401 only when `status` is exactly `401`; any other
22
+ * `status` (a `429`, a `500`, a string) is a 403 — fail closed. Rate limiting
23
+ * belongs in `middleware`, which can answer 429 itself. Anything that is not
24
+ * one of these shapes denies with 403.
25
+ */
26
+ export type DocsUiAuthorizeResult = boolean | {
27
+ allow: boolean;
28
+ status?: 401 | 403;
29
+ reason?: string;
30
+ };
31
+ /**
32
+ * Decides whether a request may load the viewer. May be async; a throw (or a
33
+ * rejection) is a 500. A denial is 401 for `status: 401` and 403 for every
34
+ * other status — see {@link DocsUiAuthorizeResult}.
35
+ */
36
+ export type DocsUiAuthorize = (req: BunRequest, context: DocsUiAuthorizeContext) => DocsUiAuthorizeResult | Promise<DocsUiAuthorizeResult>;
37
+ /**
38
+ * The one document the viewer shows, produced on demand. A thunk is served by
39
+ * the router at `<basePath>/document.json`, so the viewer always fetches
40
+ * same-origin and the strict CSP needs no exception for it.
41
+ */
42
+ export type DocsUiDocumentThunk = () => Record<string, unknown> | Promise<Record<string, unknown>>;
43
+ /** Options for {@link docsUi}. */
44
+ export interface DocsUiOptions {
45
+ /**
46
+ * The document to show: where the viewer fetches it — a same-origin
47
+ * absolute path (`"/jobs-api/openapi.json"`) or an `http(s)://` URL — or a
48
+ * thunk producing it, which the router serves at `<basePath>/document.json`.
49
+ *
50
+ * A URL follows the path rules of `basePath` (checked on the string as
51
+ * written, so `..`, a space or `%2F` is refused rather than normalised
52
+ * away) and may not carry credentials; a URL's origin is added to the CSP's
53
+ * `connect-src`. Whether it is an OpenAPI 3.1 or an AsyncAPI 3.0 document is
54
+ * read from the document itself (`openapi` / `asyncapi`).
55
+ */
56
+ document: string | DocsUiDocumentThunk;
57
+ /**
58
+ * Absolute path the viewer is mounted at: no trailing slash, not `"/"`,
59
+ * segments of letters, digits, `_`, `.`, `~` and `-`. Defaults to `"/docs"`.
60
+ */
61
+ basePath?: string;
62
+ /** Page title. Defaults to `"API docs"`. */
63
+ title?: string;
64
+ /**
65
+ * The specification extensions the viewers read, as their prefixes, first
66
+ * hit winning: a `<prefix>-<name>` extension on an operation, channel or
67
+ * scheme is read from the first prefix carrying it, and one under any other
68
+ * prefix is ignored. Defaults to `["x-bun-common", "x-bun-jobs"]`.
69
+ */
70
+ extensions?: readonly string[];
71
+ /**
72
+ * Header the try-it panel sends on every mutation (any non-empty value), as
73
+ * the documented API's CSRF rule, or `false` for none. Unset: none.
74
+ */
75
+ csrfHeader?: string | false;
76
+ /**
77
+ * Guards the shell, the bundle and a thunk's document. Same result shape as
78
+ * the bun-jobs API's, and fails closed the same way: a denial is 401 only
79
+ * for `status: 401` and 403 for any other status (`429` included), an
80
+ * unrecognised answer is 403 and a throw is 500. Omitted: everyone may load
81
+ * the page.
82
+ */
83
+ authorize?: DocsUiAuthorize;
84
+ /**
85
+ * Sends the browser to a sign-in (or any other) page when the caller is not
86
+ * authorized, instead of showing the failure. Off by default (today's
87
+ * behaviour: the shell answers a problem, the viewer shows the error).
88
+ *
89
+ * With it set, for a status in `statuses` (`[401]` by default):
90
+ *
91
+ * - **The shell:** a browser navigation (`GET`/`HEAD` of a page, not a
92
+ * bundle file and not `document.json`) that `authorize` denies answers
93
+ * `303 See Other` to `redirectTo`. A bundle file, the document, and a
94
+ * request that is not a navigation (a script's `fetch`, an `Accept`
95
+ * without `text/html`) keep the problem answer.
96
+ * - **The viewer:** a document read that fails with such a status sends
97
+ * the browser to `redirectTo` with `location.assign`, once per page
98
+ * load. The try-it panel's calls never do: their 401 is the documented
99
+ * API's answer to the request being tried, not the viewer's.
100
+ *
101
+ * A denial `middleware` answers itself is not redirected: only
102
+ * `authorize`'s. The target is fixed here, never read from the request, so
103
+ * it cannot be an open redirect. `jobsUi()` (`/jobs`) takes the same
104
+ * option.
105
+ */
106
+ unauthorized?: DocsUiUnauthorizedOptions;
107
+ /**
108
+ * Middleware run before every route, on the `GET`/`HEAD` requests the
109
+ * viewer answers (session loading, a rate limiter). Runs before
110
+ * `authorize`. Defaults to none.
111
+ */
112
+ middleware?: readonly RouterHandler[];
113
+ /** Initial colour scheme. Defaults to `"system"` (follows `prefers-color-scheme`). */
114
+ theme?: DocsUiTheme;
115
+ /**
116
+ * Where the bundle comes from. Unset (default): the prebuilt `dist/` when
117
+ * present, else an in-memory `Bun.build` on the first request. `true`:
118
+ * always build in memory. `false`: `dist/` is required — `docsUi()` throws
119
+ * a `ConfigError` without it.
120
+ */
121
+ dev?: boolean;
122
+ /** Logger, or anything `resolveLogger` accepts. Defaults to a console logger. */
123
+ logger?: LoggerLike;
124
+ }
125
+ /** A mountable API-docs viewer. */
126
+ export interface DocsUi {
127
+ /**
128
+ * Serves the shell, the bundle and a thunk's document. Mount with
129
+ * `use(ui.basePath, ui.router)`, on a bun-common or a bun-nest adapter.
130
+ */
131
+ readonly router: BunRouter;
132
+ /** The normalised `basePath`, no trailing slash. */
133
+ readonly basePath: string;
134
+ /** The configuration injected into every page, frozen. */
135
+ readonly config: Readonly<DocsUiConfig>;
136
+ }
137
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/docs/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,aAAa,EACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AAE5D,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACrC,sHAAsH;IACtH,KAAK,EAAE,OAAO,CAAC;IACf,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAC/B,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,sBAAsB,KAC5B,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAE5D;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7D,kCAAkC;AAClC,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;OAUG;IACH,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACtC,sFAAsF;IACtF,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,iFAAiF;IACjF,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,mCAAmC;AACnC,MAAM,WAAW,MAAM;IACrB;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;CACzC"}
package/dts/index.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `@kingsleyweb/bun-ui`: every bun-node browser UI, one subpath each.
3
+ *
4
+ * - `@kingsleyweb/bun-ui/jobs`: `jobsUi()`, the bun-jobs management UI
5
+ * (needs the optional peer `@kingsleyweb/bun-jobs`);
6
+ * `@kingsleyweb/bun-ui/jobs/browser`: its browser-safe config contract.
7
+ * - `@kingsleyweb/bun-ui/docs`: `docsUi()`, the viewer for one OpenAPI or
8
+ * AsyncAPI document; `/docs/browser` its browser-safe contract;
9
+ * `/docs/hosted` what bun-common's `"self-hosted"` viewer loads;
10
+ * `/docs/embed*` the viewer's screens, as source, for a host app to bundle.
11
+ *
12
+ * This root entry holds only what every UI shares and a browser may import:
13
+ * the theme type, the `unauthorized` option's types and defaults, and the
14
+ * assets' `Cache-Control`. It never imports a UI or a domain package, so
15
+ * importing it needs no peer.
16
+ */
17
+ export { ASSET_CACHE_CONTROL } from "./kit/browser/shared.js";
18
+ export type { UiTheme } from "./kit/browser/shared.js";
19
+ export { DEFAULT_RETURN_PARAM, DEFAULT_UNAUTHORIZED_STATUSES, } from "./kit/browser/unauthorized.js";
20
+ export type { UiUnauthorized, UiUnauthorizedStatus, UnauthorizedOptions, } from "./kit/browser/unauthorized.js";
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EACL,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * The app bundle, as the server serves it: every file in memory, keyed by its
3
+ * hashed name, with the content type, SRI integrity and ETag worked out once.
4
+ *
5
+ * Two sources, one shape. A published package ships `dist/` (built on
6
+ * `prepack` by `scripts/build.ts`): `dist/manifest.json` plus the hashed files
7
+ * under `dist/assets/`. Inside the repo `dist/` is usually absent, so the same
8
+ * {@link buildAssets} runs in memory on the first request instead, once per
9
+ * entry, and logs one line saying so.
10
+ */
11
+ import type { Logger } from "@kingsleyweb/bun-common";
12
+ /** The package root (`packages/bun-ui`, or `node_modules/@kingsleyweb/bun-ui`). */
13
+ export declare const PACKAGE_DIR: string;
14
+ /** The React app's entry point, bundled by {@link buildAssets}. */
15
+ export declare const DEFAULT_ENTRY: string;
16
+ /** Where `scripts/build.ts` writes the bundle and where `jobsUi()` looks for it. */
17
+ export declare const DEFAULT_DIST_DIR: string;
18
+ /**
19
+ * Makes the error this module throws for a bad configuration (a missing
20
+ * entry, a corrupt `dist/`, `dev: false` with no build). It imports no domain
21
+ * package: each UI passes its own domain's `ConfigError` (`jobsUi()` passes
22
+ * bun-jobs'), so the bundle code never makes an entry need a peer.
23
+ */
24
+ export type AssetsFail = (message: string, context: Record<string, unknown>) => Error;
25
+ /** The {@link AssetsFail} used when a caller passes none: a plain `Error`. */
26
+ export declare const plainFail: AssetsFail;
27
+ /** The manifest's file name inside a dist directory. */
28
+ export declare const MANIFEST_FILE = "manifest.json";
29
+ /** The sub-directory of a dist directory holding the hashed files. */
30
+ export declare const ASSETS_DIR = "assets";
31
+ /** One file of the bundle, as `dist/manifest.json` records it. */
32
+ export interface UiManifestFile {
33
+ /** The `Content-Type` it is served with, e.g. `"text/javascript; charset=utf-8"`. */
34
+ type: string;
35
+ /** Its size in bytes. */
36
+ size: number;
37
+ /** Its Subresource Integrity digest, `"sha384-<base64>"`. */
38
+ integrity: string;
39
+ }
40
+ /** `dist/manifest.json`: what the build produced, and which files the shell links. */
41
+ export interface UiManifest {
42
+ /** Shape version of the manifest. Currently `1`. */
43
+ version: 1;
44
+ /** The files the HTML shell references directly. */
45
+ entry: {
46
+ /** File name of the entry module (loaded with `<script type="module">`). */
47
+ js: string;
48
+ /** File names of every stylesheet the build emitted, in build order. */
49
+ css: string[];
50
+ };
51
+ /** Every file under `dist/assets/`, by file name. */
52
+ files: Record<string, UiManifestFile>;
53
+ }
54
+ /** One file of the bundle, held in memory. */
55
+ export interface UiAsset extends UiManifestFile {
56
+ /** The hashed file name, e.g. `"main-3kx9a2f1.js"`. It is also the URL segment. */
57
+ name: string;
58
+ /** The bytes served. */
59
+ body: Uint8Array<ArrayBuffer>;
60
+ /** A strong ETag derived from the integrity digest, quoted. */
61
+ etag: string;
62
+ }
63
+ /** The whole bundle, ready to serve. */
64
+ export interface UiAssets {
65
+ /** The files the shell links: the entry module and the stylesheets. */
66
+ entry: UiManifest["entry"];
67
+ /** Every file, by its hashed name. */
68
+ files: ReadonlyMap<string, UiAsset>;
69
+ /** Where the bundle came from: a `dist/` directory or an in-memory build. */
70
+ source: "dist" | "memory";
71
+ }
72
+ /** Options for {@link buildAssets}. */
73
+ export interface BuildAssetsOptions {
74
+ /** The entry point to bundle. Defaults to {@link DEFAULT_ENTRY}, the React app. */
75
+ entry?: string;
76
+ /** Minify the output. Defaults to `true`. */
77
+ minify?: boolean;
78
+ /**
79
+ * Source maps: `"linked"` (default) emits `.map` files the bundle points
80
+ * at, `"external"` emits them unreferenced, `"none"` emits none.
81
+ */
82
+ sourcemap?: "linked" | "external" | "none";
83
+ /**
84
+ * Type-check the entry and everything it imports first, with Bun.build's
85
+ * `check` (Bun ≥ 1.4.3; app/tsconfig.json's options), and fail the build on
86
+ * a type error. Defaults to `false`: `scripts/build.ts` (prepack) turns it
87
+ * on; the in-memory build `jobsUi()` runs on a request never does, which
88
+ * also keeps it off a 1.4.2 runtime. Adds about 175 ms.
89
+ */
90
+ check?: boolean;
91
+ /** Makes the error for a missing entry. Defaults to {@link plainFail}. */
92
+ fail?: AssetsFail;
93
+ }
94
+ /** The `Content-Type` for a file name, falling back to what the bundler reported. */
95
+ export declare function contentTypeFor(name: string, reported?: string): string;
96
+ /** The SRI digest of some bytes, `"sha384-<base64>"`. */
97
+ export declare function integrityOf(bytes: Uint8Array): string;
98
+ /**
99
+ * Bundles the app with `Bun.build`, in memory: browser target, content-hashed
100
+ * names (`[name]-[hash].[ext]`), code splitting, `NODE_ENV=production`.
101
+ * Throws with the bundler's messages when the build fails.
102
+ */
103
+ export declare function buildAssets(options?: BuildAssetsOptions): Promise<UiAssets>;
104
+ /**
105
+ * The stylesheets the shell links. With code splitting, Bun emits the entry's
106
+ * stylesheet holding every rule, lazily imported ones included, plus one per
107
+ * split chunk repeating that chunk's rules, and marks them all "asset". The
108
+ * entry's is the one named after the entry module; linking the others too
109
+ * would download the same rules twice. If none matches (a bundler change),
110
+ * every stylesheet is linked, which is redundant but never unstyled.
111
+ */
112
+ export declare function entryStylesheets(js: string, css: readonly string[]): string[];
113
+ /** The manifest describing a bundle. */
114
+ export declare function manifestOf(assets: UiAssets): UiManifest;
115
+ /**
116
+ * Writes a bundle as a dist directory: the files under `<dir>/assets/` (the
117
+ * directory is emptied first, so stale hashes do not accumulate) and
118
+ * `<dir>/manifest.json`. Returns the manifest written.
119
+ */
120
+ export declare function writeAssets(assets: UiAssets, dir?: string): Promise<UiManifest>;
121
+ /** Whether `dir` holds a built bundle (its manifest exists). */
122
+ export declare function hasDist(dir?: string): boolean;
123
+ /**
124
+ * Reads a dist directory into memory, synchronously. Every file the manifest
125
+ * lists must exist and match its recorded integrity — a half-copied or
126
+ * hand-edited dist fails here, with the file named, rather than as a browser
127
+ * refusing a script over SRI.
128
+ */
129
+ export declare function loadDistAssets(dir?: string, fail?: AssetsFail): UiAssets;
130
+ /**
131
+ * Builds an entry in memory, once per process: concurrent and later callers
132
+ * share the first build. A failed build is forgotten, so the next call tries
133
+ * again. Logs one `info` line when a build starts.
134
+ */
135
+ export declare function buildAssetsOnce(entry: string, logger: Logger): Promise<UiAssets>;
136
+ /** Where `jobsUi()` gets its bundle from, and how. */
137
+ export interface AssetSourceOptions {
138
+ /** `false`: require `distDir`; `true`: always build `entry` in memory; `undefined`: dist when present, else build. */
139
+ dev: boolean | undefined;
140
+ /** The dist directory to read. */
141
+ distDir: string;
142
+ /** The entry to build in memory. */
143
+ entry: string;
144
+ /** Receives the one-line notice of an in-memory build. */
145
+ logger: Logger;
146
+ /** Makes the error for `dev: false` with no build, or a corrupt one: the UI's domain `ConfigError`. */
147
+ fail: AssetsFail;
148
+ }
149
+ /**
150
+ * Resolves the bundle source when `jobsUi()` is called. A dist directory is
151
+ * read synchronously right away, so a missing or corrupt one fails the call,
152
+ * not the first request; an in-memory build is deferred to the first request.
153
+ *
154
+ * @throws `options.fail`'s error with `dev: false` and no dist, or a corrupt dist.
155
+ */
156
+ export declare function resolveAssetSource(options: AssetSourceOptions): () => Promise<UiAssets>;
157
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../lib/jobs/assets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The contract between `jobsUi()` (server, `lib/jobs/`) and the React app (`app/jobs/`).
3
+ *
4
+ * The server resolves this once per mount and inlines it into the HTML shell as
5
+ * `<script type="application/json" id="bun-jobs-ui-config" nonce="…">`. The app
6
+ * reads it before its first request. It must stay free of runtime imports: both
7
+ * sides import it, and the app side is bundled for the browser.
8
+ */
9
+ import type { UiTheme } from "../../kit/browser/shared.js";
10
+ import type { UiUnauthorized } from "./unauthorized.js";
11
+ export type { UiTheme };
12
+ /** Id of the `<script type="application/json">` element carrying {@link JobsUiConfig}. */
13
+ export declare const JOBS_UI_CONFIG_ELEMENT_ID = "bun-jobs-ui-config";
14
+ /** Sections of the app a mount can switch off. */
15
+ export interface JobsUiSections {
16
+ /** Job/queue/runner management screens. Defaults to `true`. */
17
+ manage: boolean;
18
+ /** The OpenAPI and AsyncAPI documentation viewers. Defaults to `true`. */
19
+ docs: boolean;
20
+ }
21
+ /** Resolved configuration handed to the browser. Never carries secrets. */
22
+ export interface JobsUiConfig {
23
+ /** Shape version of this object, bumped on a breaking change. Currently `1`. */
24
+ version: 1;
25
+ /** Page title and brand text. Defaults to `"Jobs"`. */
26
+ title: string;
27
+ /** Absolute path the UI is mounted at, no trailing slash (e.g. `"/jobs"`). Client routes live under it. */
28
+ basePath: string;
29
+ /** Path the hashed assets are served from, e.g. `"/jobs/assets"`. */
30
+ assetsPath: string;
31
+ /**
32
+ * Base URL of the management API with no trailing slash: a same-origin
33
+ * absolute path (`"/jobs-api"`) or, with `apiUrl`, a full origin-qualified URL.
34
+ */
35
+ apiBase: string;
36
+ /**
37
+ * Header every mutation must carry (any non-empty value), or `null` when the
38
+ * API has no CSRF header configured. Mirrors the API's `csrf.header`.
39
+ */
40
+ csrfHeader: string | null;
41
+ /**
42
+ * The API's WebSocket endpoint, when it has one: `path` is the full path
43
+ * (including the API basePath); `port` is set only for a dedicated-port
44
+ * socket. `null` when the API has no socket. `/meta` remains the authority at
45
+ * runtime; this lets the app connect without waiting for it.
46
+ */
47
+ websocket: {
48
+ path: string;
49
+ port: number | null;
50
+ } | null;
51
+ /** Full paths of the API's spec documents, or `null` when docs are off. */
52
+ docs: {
53
+ openapi: string;
54
+ asyncapi: string | null;
55
+ } | null;
56
+ /** Which sections are enabled. */
57
+ sections: JobsUiSections;
58
+ /** Initial colour scheme. */
59
+ theme: UiTheme;
60
+ /**
61
+ * Where an authorization failure sends the browser (`jobsUi()`'s
62
+ * `unauthorized`), or `null` when it is off: the app then shows each
63
+ * screen's own message, as before.
64
+ */
65
+ unauthorized: UiUnauthorized | null;
66
+ }
67
+ //# sourceMappingURL=config.d.ts.map