@luckystack/docs-ui 0.1.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@luckystack/docs-ui` are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0]
11
+
12
+ ### Added
13
+
14
+ - Initial public release as part of the LuckyStack package split.
package/CLAUDE.md ADDED
@@ -0,0 +1,55 @@
1
+ # @luckystack/docs-ui
2
+
3
+ > AI summary + function INDEX. For deep specs see `docs/` next to this file.
4
+
5
+ ## What this package does
6
+
7
+ Dev-only API docs browser for LuckyStack. Mounts a single page (default `/_docs`) that fetches the framework's generated `apiDocs.generated.json` and renders every API endpoint grouped by page, with HTTP method, auth, rate limit, input shape, and output shape. Sync events appear alongside APIs when the type-map emitter has produced metadata for them. Ships a `customRoutes` handler — composable with `createLuckyStackServer`'s `customRoutes` option without taking ownership of the request pipeline.
8
+
9
+ ## When to USE this package
10
+
11
+ - Local development: developer wants a Swagger-style overview of every route in the project without leaving the browser.
12
+ - Internal developer-portal: opt-in production rendering via `enabledInProd: true` for an authenticated team-only deploy.
13
+ - Custom branded API docs: replace the default template via the `template: DocsTemplateBuilder` option to render in a sidebar/tabs/marketing layout while reusing the JSON endpoint.
14
+ - Inline request runner: enable `enableTryItOut` so each endpoint gets a textarea + Send button that posts against the live server using the browser session cookie.
15
+
16
+ ## When to NOT suggest this (yet)
17
+
18
+ - Public production surface where API discoverability is sensitive — keep the default `enabledInProd: false` and don't mount in prod.
19
+ - Replacement for `apiDocs.generated.json` itself — this package only reads/renders that file; regenerate via `@luckystack/devkit`'s type-map emitter (`npm run generateArtifacts`).
20
+ - A non-HTTP transport — the handler is bound to `IncomingMessage` / `ServerResponse`; do not wire it directly into Socket.io handlers.
21
+ - React-tree integration — the docs UI is a single self-contained HTML document with no React/Tailwind dependency on the client; do not import `renderDocsHtml` into the app bundle.
22
+
23
+ ## Function Index
24
+
25
+ | Function / Export | 1-regel | Deep doc |
26
+ |---|---|---|
27
+ | `mountDocsUi(options?)` | Returns a `DocsRouteHandler` for `customRoutes`; serves HTML + JSON | → docs/mounting.md |
28
+ | `renderDocsHtml(jsonPath, pageTitle, options?)` | Builds the self-contained docs HTML document | → docs/html-generation.md |
29
+ | Type: `DocsRouteHandler` | `(req, res) => Promise<boolean>`; returns `true` when route handled | → docs/mounting.md |
30
+ | Type: `DocsTemplateBuilder` | Custom HTML builder hook: `({ jsonPath, pageTitle, branding }) => string` | → docs/html-generation.md |
31
+ | Type: `MountDocsUiOptions` | All mount inputs (routePath, enabledInProd, branding, template, enableTryItOut, ...) | → docs/mounting.md |
32
+ | Type: `DocsBranding` | `{ logoUrl?, brandColor?, fontFamily? }` applied by default template | → docs/theming.md |
33
+ | Type: `RenderDocsHtmlOptions` | `{ branding?, enableTryItOut? }` passed to `renderDocsHtml` | → docs/html-generation.md |
34
+ | Extension field: `meta.stream` | Per-endpoint stream shape rendered in expanded detail panel | → docs/extension-fields.md |
35
+ | Extension field: `meta.owner` | Owner string rendered in expanded detail panel | → docs/extension-fields.md |
36
+ | Extension field: `meta.tags` | Tag badges rendered in expanded detail panel | → docs/extension-fields.md |
37
+ | Extension field: `meta.deprecated` | Deprecation note (red) rendered in expanded detail panel | → docs/extension-fields.md |
38
+
39
+ ## Config keys (env vars + registerProjectConfig slots)
40
+
41
+ - `NODE_ENV` (env) — when `'production'`, the route returns `404` unless `enabledInProd: true` is set.
42
+ - `ProjectConfig.paths.generatedApiDocs` (config, resolved via `getGeneratedApiDocsPath()` from `@luckystack/core`) — default JSON file path; override per-mount via `options.apiDocsPath`.
43
+ - No package-private env vars. All behavior is controlled via `MountDocsUiOptions`.
44
+
45
+ ## Peer dependencies
46
+
47
+ - **Required**: `@luckystack/core` (provides `getGeneratedApiDocsPath` + `tryCatch`).
48
+ - **Required (runtime composition)**: `@luckystack/server` — the handler is intended to be passed to `createLuckyStackServer({ customRoutes })` / `bootstrapLuckyStack({ customRoutes })`. The package itself does not import `@luckystack/server`; the dependency is on the consumer side.
49
+ - **Required (data source)**: `@luckystack/devkit` (build-time) — emits `apiDocs.generated.json`. Without it the JSON endpoint returns a 404 with a hint to run `npm run generateArtifacts`.
50
+
51
+ ## Related
52
+
53
+ - Architecture deep-dives: `/docs/ARCHITECTURE_API.md` (lifecycle of documented endpoints), `/docs/ARCHITECTURE_PACKAGING.md` (how the JSON artifact is produced).
54
+ - README (consumer quickstart): `./README.md`.
55
+ - Source: `./src/index.ts` (mount + route handling), `./src/docsHtml.ts` (embedded HTML renderer).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mathijs van Melick
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @luckystack/docs-ui
2
+
3
+ Dev-only API docs UI for [LuckyStack](https://github.com/ItsLucky23/LuckyStack-v2).
4
+
5
+ Mounts a single page at `/_docs` that fetches the framework's generated
6
+ `apiDocs.generated.json` and renders every API endpoint grouped by page,
7
+ with HTTP method, auth requirements, rate limit, input shape, and output
8
+ shape.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm install @luckystack/docs-ui
14
+ ```
15
+
16
+ Peer deps (already installed if you have any other LuckyStack package):
17
+
18
+ - `@luckystack/core`
19
+ - `@luckystack/server` (the docs UI is mounted via `createLuckyStackServer`'s `customRoutes` option)
20
+
21
+ ## Quickstart
22
+
23
+ ```ts
24
+ // luckystack/docs-ui/index.ts (overlay file — auto-imported by bootstrapLuckyStack)
25
+ import { mountDocsUi } from '@luckystack/docs-ui';
26
+
27
+ export const docsUiHandler = mountDocsUi({
28
+ // Title shown in the header + browser tab. Defaults to 'LuckyStack — API docs'.
29
+ // Pass your project name explicitly — there's no implicit lookup from
30
+ // ProjectConfig because consumer config shapes vary too widely to introspect.
31
+ pageTitle: 'My App — API docs',
32
+ });
33
+ ```
34
+
35
+ ```ts
36
+ // server/server.ts
37
+ import { docsUiHandler } from '../luckystack/docs-ui';
38
+ import { bootstrapLuckyStack } from '@luckystack/server';
39
+ import { serveFile, serveFavicon } from './prod/serveFile';
40
+
41
+ await (await bootstrapLuckyStack({
42
+ serveFile,
43
+ serveFavicon,
44
+ customRoutes: docsUiHandler,
45
+ })).listen();
46
+ ```
47
+
48
+ Open `http://localhost/_docs` and you'll see every API in your project,
49
+ grouped by page, with one-click expand for each endpoint's input/output.
50
+
51
+ ## Production
52
+
53
+ By default the route returns 404 in production (`NODE_ENV === 'production'`).
54
+ Pass `{ enabledInProd: true }` to render it anyway — useful for an internal
55
+ developer-portal deployment, but **never** safe on a public surface unless
56
+ your APIs are intentionally documented to the world.
57
+
58
+ ## Options
59
+
60
+ | Option | Default | Notes |
61
+ | --- | --- | --- |
62
+ | `routePath` | `/_docs` | Path the page is served from. The JSON is at `${routePath}/api.json`. |
63
+ | `pageTitle` | `LuckyStack — API docs` | Shown in the header + browser tab. Pass your project name explicitly — there is no implicit lookup from `ProjectConfig`. |
64
+ | `enabledInProd` | `false` | Set to `true` to render the docs in production. |
65
+ | `apiDocsPath` | `getGeneratedApiDocsPath()` | Override the JSON file path. Default reads from `ProjectConfig.paths.generatedApiDocs`. |
66
+
67
+ ## How it works
68
+
69
+ The docs page is a single embedded HTML file (no build step, no React, no
70
+ external dependencies). It fetches `${routePath}/api.json` at runtime,
71
+ which is served from the project's `apiDocs.generated.json` — generated by
72
+ `@luckystack/devkit`'s type-map emitter on every dev-server reload and on
73
+ every `npm run generateArtifacts`.
74
+
75
+ The handler is a `customRoutes` predicate: it returns `true` when it
76
+ matches the configured paths, `false` otherwise — so it composes cleanly
77
+ with any other custom HTTP handler.
78
+
79
+ ## Related architecture docs
80
+
81
+ - [`docs/ARCHITECTURE_API.md`](../../docs/ARCHITECTURE_API.md) — the lifecycle these endpoints document.
82
+ - [`docs/ARCHITECTURE_PACKAGING.md`](../../docs/ARCHITECTURE_PACKAGING.md) — how `apiDocs.generated.json` is produced.
83
+
84
+ ## License
85
+
86
+ MIT — see the [repository LICENSE](https://github.com/ItsLucky23/LuckyStack-v2/blob/master/LICENSE).
@@ -0,0 +1,70 @@
1
+ import { IncomingMessage, ServerResponse } from 'node:http';
2
+
3
+ interface DocsBranding {
4
+ /** Logo URL shown in the header. PNG / SVG / data: URLs all accepted. */
5
+ logoUrl?: string;
6
+ /** CSS color for the header / accent (`#hex` or `rgb()` literal). */
7
+ brandColor?: string;
8
+ /** Web-safe font family for the page. */
9
+ fontFamily?: string;
10
+ }
11
+ /**
12
+ * Custom HTML builder. Receives the JSON-endpoint path the page should
13
+ * fetch from + page title + branding; returns the full HTML document
14
+ * (`<!doctype html>` + everything). Use to swap layout entirely (sidebar
15
+ * vs tabs, dark/light theme, embedded auth-token field).
16
+ */
17
+ type DocsTemplateBuilder = (input: {
18
+ jsonPath: string;
19
+ pageTitle: string;
20
+ branding: DocsBranding;
21
+ }) => string;
22
+ interface MountDocsUiOptions {
23
+ /** Path the docs UI is served from. Default: `/_docs`. */
24
+ routePath?: string;
25
+ /**
26
+ * Page title shown in the header + browser tab. Defaults to
27
+ * "LuckyStack — API docs". Pass an explicit string to brand for a consumer.
28
+ */
29
+ pageTitle?: string;
30
+ /**
31
+ * Allow rendering the docs UI in production. Default: false. Useful only
32
+ * when the docs are intentionally public (developer-portal, internal-only
33
+ * deployment, etc.). When false, the route returns 404 in production.
34
+ */
35
+ enabledInProd?: boolean;
36
+ /**
37
+ * Override the path to `apiDocs.generated.json`. Defaults to whatever
38
+ * `getGeneratedApiDocsPath()` resolves to via ProjectConfig.paths.
39
+ */
40
+ apiDocsPath?: string;
41
+ /**
42
+ * Optional branding inputs (logo, brand color, font). Applied by the
43
+ * default template. Custom templates may ignore these.
44
+ */
45
+ branding?: DocsBranding;
46
+ /**
47
+ * Custom HTML template builder. When provided, the default `renderDocsHtml`
48
+ * is bypassed entirely. Use for radically different layouts (sidebar,
49
+ * tabs, dark mode, marketing-page-style). Receives a tested JSON path +
50
+ * title + branding so your template doesn't need to know about
51
+ * `getGeneratedApiDocsPath`.
52
+ */
53
+ template?: DocsTemplateBuilder;
54
+ /**
55
+ * Enable the inline "try-it-out" runner. When true, the default template
56
+ * renders a request-input box + send button per endpoint that calls
57
+ * `apiRequest` against the live server. Off by default because the
58
+ * runner needs a logged-in session.
59
+ */
60
+ enableTryItOut?: boolean;
61
+ }
62
+ type DocsRouteHandler = (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
63
+ /**
64
+ * Returns a route handler compatible with `createLuckyStackServer`'s
65
+ * `customRoutes` option. The handler returns `true` (response sent) when
66
+ * the URL matches the configured docs route, `false` otherwise.
67
+ */
68
+ declare const mountDocsUi: (options?: MountDocsUiOptions) => DocsRouteHandler;
69
+
70
+ export { type DocsBranding, type DocsRouteHandler, type DocsTemplateBuilder, type MountDocsUiOptions, mountDocsUi };