@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.
- package/LICENSE +21 -0
- package/README.md +80 -2
- package/app/docs/App.tsx +72 -0
- package/app/docs/api/client.ts +303 -0
- package/app/docs/api/contract.ts +24 -0
- package/app/docs/api/docs.ts +38 -0
- package/app/docs/api/errors.ts +144 -0
- package/app/docs/boot.tsx +58 -0
- package/app/docs/components/Badge.tsx +65 -0
- package/app/docs/components/Button.tsx +37 -0
- package/app/docs/components/Card.tsx +41 -0
- package/app/docs/components/ConfirmDialog.tsx +173 -0
- package/app/docs/components/CopyButton.tsx +68 -0
- package/app/docs/components/Dialog.tsx +230 -0
- package/app/docs/components/EmptyState.tsx +34 -0
- package/app/docs/components/ErrorView.tsx +70 -0
- package/app/docs/components/Field.tsx +93 -0
- package/app/docs/components/JsonEditor.tsx +151 -0
- package/app/docs/components/JsonView.tsx +338 -0
- package/app/docs/components/KeyValue.tsx +63 -0
- package/app/docs/components/ProblemBanner.tsx +116 -0
- package/app/docs/components/ScreenErrorBoundary.tsx +141 -0
- package/app/docs/components/Spinner.tsx +33 -0
- package/app/docs/components/Table.tsx +33 -0
- package/app/docs/components/Tabs.tsx +226 -0
- package/app/docs/components/classNames.ts +4 -0
- package/app/docs/components/components.css +691 -0
- package/app/docs/components/copy.ts +89 -0
- package/app/docs/components/fieldContext.ts +29 -0
- package/app/docs/components/inputValues.ts +142 -0
- package/app/docs/components/inputs.tsx +387 -0
- package/app/docs/components/jsonParse.ts +338 -0
- package/app/docs/components/listKeys.ts +30 -0
- package/app/docs/config.ts +86 -0
- package/app/docs/context.ts +33 -0
- package/app/docs/embed.ts +74 -0
- package/app/docs/env.d.ts +2 -0
- package/app/docs/format.ts +9 -0
- package/app/docs/hooks/useUrlTab.ts +16 -0
- package/app/docs/main.tsx +11 -0
- package/app/docs/queryClient.ts +54 -0
- package/app/docs/router.tsx +194 -0
- package/app/docs/routing.ts +194 -0
- package/app/docs/screens/docs/document.ts +27 -0
- package/app/docs/screens/docs/http/OperationView.tsx +407 -0
- package/app/docs/screens/docs/http/Sidebar.tsx +190 -0
- package/app/docs/screens/docs/http/TryItPanel.tsx +603 -0
- package/app/docs/screens/docs/http/http.css +405 -0
- package/app/docs/screens/docs/http/index.tsx +395 -0
- package/app/docs/screens/docs/http/model.ts +604 -0
- package/app/docs/screens/docs/http/tryIt.ts +455 -0
- package/app/docs/screens/docs/permissions.ts +6 -0
- package/app/docs/screens/docs/schema/Prose.tsx +43 -0
- package/app/docs/screens/docs/schema/SchemaTree.tsx +319 -0
- package/app/docs/screens/docs/schema/index.ts +30 -0
- package/app/docs/screens/docs/schema/resolve.ts +466 -0
- package/app/docs/screens/docs/schema/schema.css +137 -0
- package/app/docs/screens/docs/schema/skeleton.ts +92 -0
- package/app/docs/screens/docs/viewer.tsx +154 -0
- package/app/docs/screens/docs/ws/InlineText.tsx +25 -0
- package/app/docs/screens/docs/ws/PayloadSchema.tsx +39 -0
- package/app/docs/screens/docs/ws/format.ts +82 -0
- package/app/docs/screens/docs/ws/index.tsx +286 -0
- package/app/docs/screens/docs/ws/items.tsx +786 -0
- package/app/docs/screens/docs/ws/model.ts +1178 -0
- package/app/docs/screens/docs/ws/panels.tsx +440 -0
- package/app/docs/screens/docs/ws/ws.css +231 -0
- package/app/docs/shortcuts.ts +94 -0
- package/app/docs/styles/base.css +847 -0
- package/app/docs/styles/tokens.css +143 -0
- package/app/docs/theme.ts +56 -0
- package/app/kit/unauthorized.ts +222 -0
- package/dist/docs/assets/main-0rchxtv5.js +18 -0
- package/dist/docs/assets/main-0rchxtv5.js.map +99 -0
- package/dist/docs/assets/main-cqgyvs86.css +1 -0
- package/dist/docs/manifest.json +26 -0
- package/dist/jobs/assets/AddFlowDialog-h6xkgx9b.js +6 -0
- package/dist/jobs/assets/AddFlowDialog-h6xkgx9b.js.map +11 -0
- package/dist/jobs/assets/AddFlowDialog-n7gtc84v.css +1 -0
- package/dist/jobs/assets/added-cbwsxv3e.js +4 -0
- package/dist/jobs/assets/added-cbwsxv3e.js.map +11 -0
- package/dist/jobs/assets/bodies-yyw5hmrp.js +6 -0
- package/dist/jobs/assets/bodies-yyw5hmrp.js.map +10 -0
- package/dist/jobs/assets/channel-tgkvqm8y.js +4 -0
- package/dist/jobs/assets/channel-tgkvqm8y.js.map +10 -0
- package/dist/jobs/assets/channelChecks-s4yz4yhw.js +4 -0
- package/dist/jobs/assets/channelChecks-s4yz4yhw.js.map +10 -0
- package/dist/jobs/assets/index-02427smp.css +1 -0
- package/dist/jobs/assets/index-09z2cjft.js +4 -0
- package/dist/jobs/assets/index-09z2cjft.js.map +16 -0
- package/dist/jobs/assets/index-18bn0gvy.css +1 -0
- package/dist/jobs/assets/index-47pxmyxn.js +4 -0
- package/dist/jobs/assets/index-47pxmyxn.js.map +10 -0
- package/dist/jobs/assets/index-4e55z986.js +4 -0
- package/dist/jobs/assets/index-4e55z986.js.map +11 -0
- package/dist/jobs/assets/index-5c933424.js +4 -0
- package/dist/jobs/assets/index-5c933424.js.map +18 -0
- package/dist/jobs/assets/index-5kbyqspm.css +1 -0
- package/dist/jobs/assets/index-5ng37hk6.css +1 -0
- package/dist/jobs/assets/index-5w8w7fvc.css +1 -0
- package/dist/jobs/assets/index-71qs5qyx.css +1 -0
- package/dist/jobs/assets/index-btpg4r8b.css +1 -0
- package/dist/jobs/assets/index-d5r5n0mm.js +4 -0
- package/dist/jobs/assets/index-d5r5n0mm.js.map +23 -0
- package/dist/jobs/assets/index-e0yy2skq.css +1 -0
- package/dist/jobs/assets/index-hs60b25v.js +10 -0
- package/dist/jobs/assets/index-hs60b25v.js.map +62 -0
- package/dist/jobs/assets/index-k2smrr70.js +4 -0
- package/dist/jobs/assets/index-k2smrr70.js.map +9 -0
- package/dist/jobs/assets/index-q24jw3w9.js +4 -0
- package/dist/jobs/assets/index-q24jw3w9.js.map +32 -0
- package/dist/jobs/assets/index-qfb80xen.css +1 -0
- package/dist/jobs/assets/index-rtynx6wj.js +4 -0
- package/dist/jobs/assets/index-rtynx6wj.js.map +10 -0
- package/dist/jobs/assets/live-6k7s6358.js +4 -0
- package/dist/jobs/assets/live-6k7s6358.js.map +10 -0
- package/dist/jobs/assets/main-0jmeh6mq.js +6 -0
- package/dist/jobs/assets/main-0jmeh6mq.js.map +12 -0
- package/dist/jobs/assets/main-3yj6bv90.js +5 -0
- package/dist/jobs/assets/main-3yj6bv90.js.map +10 -0
- package/dist/jobs/assets/main-4g69fn3x.js +5 -0
- package/dist/jobs/assets/main-4g69fn3x.js.map +10 -0
- package/dist/jobs/assets/main-4gte3eqq.js +5 -0
- package/dist/jobs/assets/main-4gte3eqq.js.map +10 -0
- package/dist/jobs/assets/main-4j1fcevh.js +5 -0
- package/dist/jobs/assets/main-4j1fcevh.js.map +10 -0
- package/dist/jobs/assets/main-54qwkz28.css +1 -0
- package/dist/jobs/assets/main-5grjvsy7.js +5 -0
- package/dist/jobs/assets/main-5grjvsy7.js.map +11 -0
- package/dist/jobs/assets/main-5zbx60gq.js +5 -0
- package/dist/jobs/assets/main-5zbx60gq.js.map +11 -0
- package/dist/jobs/assets/main-9prgjhg4.js +5 -0
- package/dist/jobs/assets/main-9prgjhg4.js.map +10 -0
- package/dist/jobs/assets/main-a250ffk7.js +17 -0
- package/dist/jobs/assets/main-a250ffk7.js.map +115 -0
- package/dist/jobs/assets/main-d6ge7w08.js +5 -0
- package/dist/jobs/assets/main-d6ge7w08.js.map +10 -0
- package/dist/jobs/assets/main-gngzht43.js +5 -0
- package/dist/jobs/assets/main-gngzht43.js.map +10 -0
- package/dist/jobs/assets/main-hg0hrg8j.js +5 -0
- package/dist/jobs/assets/main-hg0hrg8j.js.map +10 -0
- package/dist/jobs/assets/main-hm1ng3yg.js +5 -0
- package/dist/jobs/assets/main-hm1ng3yg.js.map +12 -0
- package/dist/jobs/assets/main-jkvd92z9.js +5 -0
- package/dist/jobs/assets/main-jkvd92z9.js.map +10 -0
- package/dist/jobs/assets/main-jv5xqd13.js +5 -0
- package/dist/jobs/assets/main-jv5xqd13.js.map +21 -0
- package/dist/jobs/assets/main-jxre7w93.js +5 -0
- package/dist/jobs/assets/main-jxre7w93.js.map +23 -0
- package/dist/jobs/assets/main-kwmqkjfx.js +5 -0
- package/dist/jobs/assets/main-kwmqkjfx.js.map +11 -0
- package/dist/jobs/assets/main-n9cf6bxm.js +5 -0
- package/dist/jobs/assets/main-n9cf6bxm.js.map +11 -0
- package/dist/jobs/assets/main-pegp0ygb.js +5 -0
- package/dist/jobs/assets/main-pegp0ygb.js.map +10 -0
- package/dist/jobs/assets/main-qr573853.js +5 -0
- package/dist/jobs/assets/main-qr573853.js.map +12 -0
- package/dist/jobs/assets/main-rq97rdr4.js +4 -0
- package/dist/jobs/assets/main-rq97rdr4.js.map +22 -0
- package/dist/jobs/assets/main-szjdmydc.js +5 -0
- package/dist/jobs/assets/main-szjdmydc.js.map +13 -0
- package/dist/jobs/assets/main-tnbhrm9n.js +7 -0
- package/dist/jobs/assets/main-tnbhrm9n.js.map +11 -0
- package/dist/jobs/assets/main-ts19j4n0.js +5 -0
- package/dist/jobs/assets/main-ts19j4n0.js.map +25 -0
- package/dist/jobs/assets/main-w93x1dzs.js +5 -0
- package/dist/jobs/assets/main-w93x1dzs.js.map +10 -0
- package/dist/jobs/assets/sections-0ksdxs8m.css +1 -0
- package/dist/jobs/assets/sections-0y7w4fb4.js +4 -0
- package/dist/jobs/assets/sections-0y7w4fb4.js.map +10 -0
- package/dist/jobs/assets/sse-mn0t0fh7.js +5 -0
- package/dist/jobs/assets/sse-mn0t0fh7.js.map +11 -0
- package/dist/jobs/assets/sseChecks-t7tcm7ra.js +4 -0
- package/dist/jobs/assets/sseChecks-t7tcm7ra.js.map +10 -0
- package/dist/jobs/assets/validation-ysjfy072.js +4 -0
- package/dist/jobs/assets/validation-ysjfy072.js.map +9 -0
- package/dist/jobs/manifest.json +511 -0
- package/dts/docs/assets.d.ts +144 -0
- package/dts/docs/assets.d.ts.map +1 -0
- package/dts/docs/browser/config.d.ts +61 -0
- package/dts/docs/browser/config.d.ts.map +1 -0
- package/dts/docs/browser/index.d.ts +12 -0
- package/dts/docs/browser/index.d.ts.map +1 -0
- package/dts/docs/docsUi.d.ts +42 -0
- package/dts/docs/docsUi.d.ts.map +1 -0
- package/dts/docs/hosted.d.ts +22 -0
- package/dts/docs/hosted.d.ts.map +1 -0
- package/dts/docs/index.d.ts +18 -0
- package/dts/docs/index.d.ts.map +1 -0
- package/dts/docs/shell.d.ts +57 -0
- package/dts/docs/shell.d.ts.map +1 -0
- package/dts/docs/types.d.ts +137 -0
- package/dts/docs/types.d.ts.map +1 -0
- package/dts/index.d.ts +21 -0
- package/dts/index.d.ts.map +1 -0
- package/dts/jobs/assets.d.ts +157 -0
- package/dts/jobs/assets.d.ts.map +1 -0
- package/dts/jobs/browser/config.d.ts +67 -0
- package/dts/jobs/browser/config.d.ts.map +1 -0
- package/dts/jobs/browser/index.d.ts +10 -0
- package/dts/jobs/browser/index.d.ts.map +1 -0
- package/dts/jobs/browser/unauthorized.d.ts +9 -0
- package/dts/jobs/browser/unauthorized.d.ts.map +1 -0
- package/dts/jobs/index.d.ts +24 -0
- package/dts/jobs/index.d.ts.map +1 -0
- package/dts/jobs/jobsUi.d.ts +63 -0
- package/dts/jobs/jobsUi.d.ts.map +1 -0
- package/dts/jobs/shell.d.ts +77 -0
- package/dts/jobs/shell.d.ts.map +1 -0
- package/dts/jobs/types.d.ts +146 -0
- package/dts/jobs/types.d.ts.map +1 -0
- package/dts/kit/browser/shared.d.ts +10 -0
- package/dts/kit/browser/shared.d.ts.map +1 -0
- package/dts/kit/browser/unauthorized.d.ts +74 -0
- package/dts/kit/browser/unauthorized.d.ts.map +1 -0
- package/dts/kit/unauthorized.d.ts +47 -0
- package/dts/kit/unauthorized.d.ts.map +1 -0
- package/guides/docs.md +170 -0
- package/guides/jobs.md +1120 -0
- package/lib/docs/assets.ts +427 -0
- package/lib/docs/browser/config.ts +66 -0
- package/lib/docs/browser/index.ts +24 -0
- package/lib/docs/docsUi.ts +623 -0
- package/lib/docs/hosted.ts +31 -0
- package/lib/docs/index.ts +37 -0
- package/lib/docs/shell.ts +156 -0
- package/lib/docs/types.ts +149 -0
- package/lib/index.ts +27 -0
- package/lib/jobs/assets.ts +448 -0
- package/lib/jobs/browser/config.ts +65 -0
- package/lib/jobs/browser/index.ts +9 -0
- package/lib/jobs/browser/unauthorized.ts +11 -0
- package/lib/jobs/index.ts +41 -0
- package/lib/jobs/jobsUi.ts +709 -0
- package/lib/jobs/shell.ts +205 -0
- package/lib/jobs/types.ts +162 -0
- package/lib/kit/browser/shared.ts +11 -0
- package/lib/kit/browser/unauthorized.ts +114 -0
- package/lib/kit/unauthorized.ts +222 -0
- package/package.json +198 -4
package/guides/docs.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# The docs viewer: `@kingsleyweb/bun-ui/docs`
|
|
2
|
+
|
|
3
|
+
A self-hosted viewer for one **OpenAPI 3.1** or **AsyncAPI 3.0** document,
|
|
4
|
+
served by a `docsUi()` handler you mount beside your API. The viewer is a
|
|
5
|
+
bundled React app the package builds itself (React 19 and TanStack Query are
|
|
6
|
+
bundled into it — the host installs neither), served with hash-named immutable
|
|
7
|
+
assets, computed Subresource Integrity and a strict self-only
|
|
8
|
+
Content-Security-Policy (`default-src 'self'; script-src 'self' 'nonce-…';
|
|
9
|
+
style-src 'self'`). Nothing comes from a CDN, so it works offline.
|
|
10
|
+
|
|
11
|
+
Requires Bun ≥ 1.4.2 and `bun add @kingsleyweb/bun-ui`. `/docs` needs no peer:
|
|
12
|
+
not `@kingsleyweb/bun-jobs`, which only the package's `/jobs` entry uses. The
|
|
13
|
+
browser-safe half (`DocsUiConfig`, `DOCS_UI_CONFIG_ELEMENT_ID`,
|
|
14
|
+
`DEFAULT_EXTENSION_PREFIXES` and the `unauthorized` helpers) is
|
|
15
|
+
`@kingsleyweb/bun-ui/docs/browser`; what bun-common's `docsRouter`
|
|
16
|
+
`"self-hosted"` viewer loads is `@kingsleyweb/bun-ui/docs/hosted`.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { BunRouter } from "@kingsleyweb/bun-common";
|
|
22
|
+
import { docsUi } from "@kingsleyweb/bun-ui/docs";
|
|
23
|
+
|
|
24
|
+
const app = new BunRouter();
|
|
25
|
+
|
|
26
|
+
// Point at a document your API already serves…
|
|
27
|
+
const ui = docsUi({ document: "/jobs-api/openapi.json", basePath: "/docs" });
|
|
28
|
+
|
|
29
|
+
// …or hand it a thunk, and the router serves the document itself
|
|
30
|
+
// at <basePath>/document.json:
|
|
31
|
+
const ui = docsUi({
|
|
32
|
+
document: () => buildAsyncApiDocument(),
|
|
33
|
+
title: "Events API",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
app.use(ui.basePath, ui.router);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Which reference the viewer shows is read from the document itself: an
|
|
40
|
+
`openapi` field gets the HTTP reference (operations by tag — and, when the
|
|
41
|
+
document declares `x-tagGroups`, the tags nested under those sections, with
|
|
42
|
+
any tag no section names in a trailing `Other` one; schemas as
|
|
43
|
+
expandable trees, a try-it panel per operation), an `asyncapi` field gets the
|
|
44
|
+
WebSocket reference (channels, operations, messages, limits, close codes).
|
|
45
|
+
|
|
46
|
+
The whole page is client-routed under `basePath`, so every URL under it
|
|
47
|
+
(`<basePath>/http/<operationId>`, `<basePath>/ws/<item>`) is a deep link the
|
|
48
|
+
router answers with the shell.
|
|
49
|
+
|
|
50
|
+
## Options
|
|
51
|
+
|
|
52
|
+
| Option | Default | What it does |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| `document` | — (required) | Same-origin path or `http(s)` URL the viewer fetches, or a `() => document` thunk the router serves at `<basePath>/document.json`. |
|
|
55
|
+
| `basePath` | `"/docs"` | Mount path. Not `"/"`, no trailing slash, simple segments only. |
|
|
56
|
+
| `title` | `"API docs"` | Page title. |
|
|
57
|
+
| `theme` | `"system"` | Initial colour scheme: `"system"`, `"light"` or `"dark"`. |
|
|
58
|
+
| `extensions` | `["x-bun-common", "x-bun-jobs"]` | Specification-extension prefixes the viewers read, first hit winning: a `<prefix>-<name>` extension is read from the first prefix carrying it; anything under another prefix is ignored. |
|
|
59
|
+
| `csrfHeader` | none | Header the try-it panel adds on every mutation, or `false`. |
|
|
60
|
+
| `authorize` | none | Guards the shell, the bundle and a thunk's document (not the documented API itself). |
|
|
61
|
+
| `unauthorized` | off | `{ redirectTo, returnParam?, statuses? }`: sends the browser to a sign-in page (or any page) when the caller is not authorized, instead of showing the failure. See [Sending the browser to sign in](#sending-the-browser-to-sign-in). |
|
|
62
|
+
| `middleware` | none | Runs before every route. |
|
|
63
|
+
| `dev` | auto | `true` always builds the bundle in memory; `false` requires the prebuilt `dist/docs/` (a `ConfigError` names the fix without it). |
|
|
64
|
+
| `logger` | console | Anything `resolveLogger` accepts. |
|
|
65
|
+
|
|
66
|
+
### Sending the browser to sign in
|
|
67
|
+
|
|
68
|
+
By default an authorization failure stays where it happens: the shell
|
|
69
|
+
answers a 401 problem, and a refused document read shows "Could not load the
|
|
70
|
+
API document". With `unauthorized`, a failure sends the browser to a page you
|
|
71
|
+
choose. The jobs UI's `jobsUi()` takes the same option, and both run the same
|
|
72
|
+
code (`lib/kit/unauthorized.ts`, `./docs/embed/unauthorized`).
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const ui = docsUi({
|
|
76
|
+
document: () => openApiDocument(),
|
|
77
|
+
authorize: (req) => (session(req) ? true : { allow: false, status: 401 }),
|
|
78
|
+
unauthorized: { redirectTo: "/login" },
|
|
79
|
+
});
|
|
80
|
+
// A signed-out visit to /docs/http/listQueues
|
|
81
|
+
// → 303 to /login?returnTo=%2Fdocs%2Fhttp%2FlistQueues
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
| Field | Default | Notes |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `redirectTo` | — (required) | A path starting with one `/` (`"/login"`), or an absolute `http:`/`https:` URL. A path inside the viewer's own `basePath` is a `ConfigError` (a redirect loop). `javascript:`, `data:`, `//host`, a `\`, whitespace, control characters and credentials in a URL are refused too. |
|
|
87
|
+
| `returnParam` | `"returnTo"` | The query parameter that carries the page the user was on (path, query and, in the browser, fragment), always a relative URL starting with one `/`. `false` adds nothing. Letters, digits, `_`, `.`, `~` and `-` only. |
|
|
88
|
+
| `statuses` | `[401]` | Which failures redirect: `401`, `403` or both. |
|
|
89
|
+
|
|
90
|
+
What redirects, for a status in `statuses`:
|
|
91
|
+
|
|
92
|
+
- **The shell.** A page navigation that `authorize` denies answers
|
|
93
|
+
`303 See Other` with `Location: <redirectTo>?returnTo=<path and query>`. A
|
|
94
|
+
navigation is a `GET` or `HEAD` with `Sec-Fetch-Mode: navigate`, or, from a
|
|
95
|
+
client that sends no `Sec-Fetch-Mode`, an `Accept` naming `text/html`. A
|
|
96
|
+
bundle file, `document.json` and a script's `fetch` keep the 401 or 403
|
|
97
|
+
problem. A denial that your `middleware` answers itself is not redirected.
|
|
98
|
+
- **The viewer.** A document read that fails with such a status sends the
|
|
99
|
+
browser to `redirectTo` with `location.assign`, once per page load. The
|
|
100
|
+
try-it panel never does: a 401 there is the documented API's answer to the
|
|
101
|
+
request you tried, not the viewer's.
|
|
102
|
+
|
|
103
|
+
The target is fixed by the option, never read from the request; the sign-in
|
|
104
|
+
page must still check `returnTo` before sending the user back to it.
|
|
105
|
+
|
|
106
|
+
## The bundle
|
|
107
|
+
|
|
108
|
+
`prepack` builds `app/docs/main.tsx` into `dist/docs/` (`bun scripts/build.ts`): hashed
|
|
109
|
+
file names, a `manifest.json` with every file's SRI digest, type-checked
|
|
110
|
+
first. Without a `dist/docs/` (a source checkout), the first request builds the
|
|
111
|
+
same bundle in memory, once per process, and logs one line saying so.
|
|
112
|
+
|
|
113
|
+
The WebSocket reference's "try it" links and permission markers of
|
|
114
|
+
the jobs UI's Events console are jobs-specific and are not part
|
|
115
|
+
of this standalone viewer.
|
|
116
|
+
|
|
117
|
+
## Embedding the screens (`./docs/embed`)
|
|
118
|
+
|
|
119
|
+
`docsUi()` needs nothing beyond this package: React and TanStack Query are
|
|
120
|
+
bundled into `dist/docs/`. The `./docs/embed` entries are different. They export the
|
|
121
|
+
viewer's screens as source, from `app/docs/` and `app/kit/`, for a React app that renders them
|
|
122
|
+
inside its own UI (the package's own jobs UI does, by this name), and that app's bundler
|
|
123
|
+
builds them with its own copies of React and TanStack Query. This package
|
|
124
|
+
does not declare them, so install them yourself:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
bun add react@^19.2.0 @tanstack/react-query@^5.90.0
|
|
128
|
+
bun add -d @types/react@^19.2.0 # for TypeScript
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
| Entry | Imports |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `./docs/embed`, `./docs/embed/router` | `react`, `@tanstack/react-query` |
|
|
134
|
+
| `./docs/embed/routing`, `./docs/embed/context` | `react` |
|
|
135
|
+
| `./docs/embed/unauthorized` | `react`, and `@tanstack/react-query`'s types |
|
|
136
|
+
| `./docs/embed/permissions`, `./docs/embed/client`, `./docs/embed/errors` | nothing outside this package |
|
|
137
|
+
|
|
138
|
+
The screens also import their `.css` files, which your bundler has to
|
|
139
|
+
handle (`Bun.build` does).
|
|
140
|
+
|
|
141
|
+
The screens never redirect on their own. A host app that embeds them passes
|
|
142
|
+
`unauthorized: null` in the `DocsUiConfig` it provides, and sends the browser
|
|
143
|
+
to sign in through its own app, once: `./docs/embed/unauthorized`'s
|
|
144
|
+
`createUnauthorizedRedirect` and `watchAuthFailures` over the host's query
|
|
145
|
+
client, as the jobs UI does.
|
|
146
|
+
|
|
147
|
+
Because the entries are source, your TypeScript checks them with your
|
|
148
|
+
`tsconfig.json`, which needs two things (`skipLibCheck` does not cover `.ts`
|
|
149
|
+
files):
|
|
150
|
+
|
|
151
|
+
- `"allowImportingTsExtensions": true` (two modules import a `.ts` path;
|
|
152
|
+
`bun init`'s config already sets it), and
|
|
153
|
+
- a declaration for the stylesheets, in any `.d.ts` your project includes,
|
|
154
|
+
since TypeScript 6 checks side-effect imports:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
declare module "*.css";
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Development
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
bun run check && bun run lint && bun run format:check && bun run test
|
|
164
|
+
bun scripts/build.ts --ui docs # app/docs/main.tsx → dist/docs/
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The golden AsyncAPI fixtures under `__tests__/docs/app/docs/ws/fixtures/` are what
|
|
168
|
+
a real `@kingsleyweb/bun-jobs` API serves (a dev-only dependency, used by the
|
|
169
|
+
fixture test); `UPDATE_WS_FIXTURES=1 bun test __tests__/docs/server/docs-ws.integration.test.ts`
|
|
170
|
+
rewrites them.
|