@emeryld/rrroutes-openapi 2.3.3 → 2.3.5
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/dist/docs/serializer.d.ts +3 -3
- package/dist/index.cjs +62 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +62 -26
- package/dist/index.mjs.map +1 -1
- package/dist/public/assets/docs.js +121 -89
- package/dist/web/utils/types.d.ts +1 -17
- package/dist/web/v2/components/endpoints/EndpointDetailPanel.d.ts +5 -0
- package/dist/web/v2/components/endpoints/EndpointPlayground.d.ts +6 -0
- package/dist/web/v2/components/endpoints/EndpointSummaryHeader.d.ts +6 -0
- package/dist/web/v2/components/endpoints/EndpointVolumeChart.d.ts +8 -0
- package/dist/web/v2/components/feedback/EmptyState.d.ts +8 -0
- package/dist/web/v2/components/feedback/ErrorState.d.ts +7 -0
- package/dist/web/v2/components/feedback/LoadingState.d.ts +5 -0
- package/dist/web/v2/components/filters/BaseFilterBar.d.ts +12 -0
- package/dist/web/v2/components/history/HistoryInsights.d.ts +6 -0
- package/dist/web/v2/components/history/RequestDetailDrawer.d.ts +9 -0
- package/dist/web/v2/components/history/RequestTable.d.ts +7 -0
- package/dist/web/v2/components/inputs/SearchInput.d.ts +12 -0
- package/dist/web/v2/components/json/JsonViewer.d.ts +7 -0
- package/dist/web/v2/components/layout/CardSection.d.ts +8 -0
- package/dist/web/v2/components/layout/PageContainer.d.ts +9 -0
- package/dist/web/v2/components/layout/SplitPane.d.ts +8 -0
- package/dist/web/v2/components/logs/CacheLogsTable.d.ts +6 -0
- package/dist/web/v2/components/logs/CacheSummaryTable.d.ts +6 -0
- package/dist/web/v2/components/logs/LogsTable.d.ts +7 -0
- package/dist/web/v2/components/presets/PresetCard.d.ts +7 -0
- package/dist/web/v2/components/presets/PresetForm.d.ts +7 -0
- package/dist/web/v2/components/presets/PresetOperationsEditor.d.ts +7 -0
- package/dist/web/v2/components/schema/SchemaTreeView.d.ts +7 -0
- package/dist/web/v2/components/tags/CacheOperationChip.d.ts +9 -0
- package/dist/web/v2/components/tags/HttpMethodChip.d.ts +10 -0
- package/dist/web/v2/components/tags/LogLevelChip.d.ts +10 -0
- package/dist/web/v2/components/tags/StatusChip.d.ts +8 -0
- package/dist/web/v2/hooks/useGlobalShortcuts.d.ts +6 -0
- package/dist/web/v2/hooks/useHttpColor.d.ts +2 -0
- package/dist/web/v2/hooks/useLeafEndpoint.d.ts +7 -0
- package/dist/web/v2/hooks/useQueryState.d.ts +7 -0
- package/dist/web/v2/hooks/useStatusColor.d.ts +1 -0
- package/dist/web/v2/pages/EndpointDetailPage.d.ts +1 -0
- package/dist/web/v2/pages/HistoryPage.d.ts +1 -0
- package/dist/web/v2/pages/LogsPage.d.ts +1 -0
- package/dist/web/v2/pages/NotFoundPage.d.ts +1 -0
- package/dist/web/v2/pages/PresetEditPage.d.ts +1 -0
- package/dist/web/v2/pages/PresetsPage.d.ts +1 -0
- package/dist/web/v2/pages/RoutesPage.d.ts +1 -0
- package/dist/web/v2/stores/playgroundStore.d.ts +33 -0
- package/dist/web/v2/types/filterTypes.d.ts +20 -0
- package/dist/web/v2/types/types.base.d.ts +13 -0
- package/dist/web/v2/types/types.cacheLog.d.ts +93 -45
- package/dist/web/v2/types/types.d.ts +17 -0
- package/dist/web/v2/types/types.endpoint.d.ts +51 -4
- package/dist/web/v2/types/types.log.d.ts +32 -1
- package/dist/web/v2/types/types.preset.d.ts +92 -4
- package/dist/web/v2/types/types.requestLog.d.ts +52 -3
- package/package.json +3 -3
- package/dist/web/v2/components/JsonInput.d.ts +0 -10
- package/dist/web/v2/components/JsonViewer.d.ts +0 -12
- package/dist/web/v2/components/MethodBadge.d.ts +0 -4
- package/dist/web/v2/components/New/HttpMethodChip.d.ts +0 -7
- package/dist/web/v2/components/New/ListToolBar.d.ts +0 -11
- package/dist/web/v2/components/New/MethodFiltersChips.d.ts +0 -7
- package/dist/web/v2/components/New/RequestStatusChip.d.ts +0 -6
- package/dist/web/v2/components/New/SplitPageLayout.d.ts +0 -7
- package/dist/web/v2/components/New/StabilityChip.d.ts +0 -7
- package/dist/web/v2/components/New/StatusRangeFilter.d.ts +0 -8
- package/dist/web/v2/components/RecordItem.d.ts +0 -34
- package/dist/web/v2/components/ResizableSidePanel.d.ts +0 -12
- package/dist/web/v2/components/SchemaTable.d.ts +0 -5
- package/dist/web/v2/components/SectionHeader.d.ts +0 -9
- package/dist/web/v2/endpoints/EndpointDetailsPanel.d.ts +0 -5
- package/dist/web/v2/endpoints/EndpointList.d.ts +0 -12
- package/dist/web/v2/endpoints/EndpointsPage.d.ts +0 -4
- package/dist/web/v2/endpoints/endpoints.utils.d.ts +0 -3
package/dist/index.mjs
CHANGED
|
@@ -408,7 +408,7 @@ function applyDocsSecurityHeaders(res) {
|
|
|
408
408
|
);
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
-
// src/web/
|
|
411
|
+
// src/web/v2/types/types.ts
|
|
412
412
|
import {
|
|
413
413
|
finalize,
|
|
414
414
|
resource as resource6
|
|
@@ -421,6 +421,7 @@ import z3 from "zod";
|
|
|
421
421
|
// src/web/v2/types/types.base.ts
|
|
422
422
|
import z2 from "zod";
|
|
423
423
|
var METHODS = ["get", "post", "put", "patch", "delete"];
|
|
424
|
+
var methodSchema = z2.enum(METHODS);
|
|
424
425
|
var baseEntitySchema = z2.object({
|
|
425
426
|
id: z2.string(),
|
|
426
427
|
name: z2.string(),
|
|
@@ -437,9 +438,15 @@ var baseQuerySchema = z2.object({
|
|
|
437
438
|
orderDirection: z2.enum(["asc", "desc"]).default("desc"),
|
|
438
439
|
searchQuery: z2.string().optional(),
|
|
439
440
|
groups: z2.string().array().optional(),
|
|
441
|
+
excludeGroups: z2.string().array().optional(),
|
|
440
442
|
tags: z2.string().array().optional(),
|
|
443
|
+
excludeTags: z2.string().array().optional(),
|
|
441
444
|
cursor: z2.string().optional()
|
|
442
445
|
});
|
|
446
|
+
var paginationSchema = z2.object({
|
|
447
|
+
cursor: z2.string().optional(),
|
|
448
|
+
pageSize: z2.number().optional()
|
|
449
|
+
});
|
|
443
450
|
|
|
444
451
|
// src/web/v2/types/types.cacheLog.ts
|
|
445
452
|
var operationEnum = z3.enum(["hit", "miss", "set", "delete"]);
|
|
@@ -453,7 +460,17 @@ var cacheLogSchema = baseEntitySchema.extend({
|
|
|
453
460
|
size: z3.number().optional()
|
|
454
461
|
});
|
|
455
462
|
var cacheLogQuerySchema = baseQuerySchema.extend({
|
|
456
|
-
operations: operationEnum.array().optional()
|
|
463
|
+
operations: operationEnum.array().optional(),
|
|
464
|
+
excludeOperations: operationEnum.array().optional()
|
|
465
|
+
});
|
|
466
|
+
var cacheSummarySchema = z3.object({
|
|
467
|
+
key: z3.string(),
|
|
468
|
+
lastSetAt: z3.number().nullable(),
|
|
469
|
+
lastHitAt: z3.number().nullable(),
|
|
470
|
+
lastMissAt: z3.number().nullable(),
|
|
471
|
+
totalHits: z3.number(),
|
|
472
|
+
totalMisses: z3.number(),
|
|
473
|
+
totalSets: z3.number()
|
|
457
474
|
});
|
|
458
475
|
var cacheLeaves = resource("cache").get({
|
|
459
476
|
feed: true,
|
|
@@ -461,10 +478,14 @@ var cacheLeaves = resource("cache").get({
|
|
|
461
478
|
querySchema: cacheLogQuerySchema,
|
|
462
479
|
outputMetaSchema: z3.object({
|
|
463
480
|
totalCount: z3.number().optional()
|
|
464
|
-
})
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
481
|
+
}),
|
|
482
|
+
queryExtensionSchema: paginationSchema
|
|
483
|
+
}).sub(
|
|
484
|
+
resource("clear").post({
|
|
485
|
+
outputSchema: z3.object({ success: z3.boolean() }),
|
|
486
|
+
querySchema: cacheLogQuerySchema
|
|
487
|
+
}).done()
|
|
488
|
+
).done();
|
|
468
489
|
|
|
469
490
|
// src/web/v2/types/types.endpoint.ts
|
|
470
491
|
import { resource as resource4 } from "@emeryld/rrroutes-contract";
|
|
@@ -483,7 +504,8 @@ var logSchema = baseEntitySchema.extend({
|
|
|
483
504
|
meta: z4.json()
|
|
484
505
|
});
|
|
485
506
|
var logQuerySchema = baseQuerySchema.extend({
|
|
486
|
-
level: levelSchema.array().optional()
|
|
507
|
+
level: levelSchema.array().optional(),
|
|
508
|
+
excludeLevel: levelSchema.array().optional()
|
|
487
509
|
});
|
|
488
510
|
var logLeaves = resource2("logs").get({
|
|
489
511
|
feed: true,
|
|
@@ -491,7 +513,8 @@ var logLeaves = resource2("logs").get({
|
|
|
491
513
|
querySchema: logQuerySchema,
|
|
492
514
|
outputMetaSchema: z4.object({
|
|
493
515
|
totalCount: z4.number().optional()
|
|
494
|
-
})
|
|
516
|
+
}),
|
|
517
|
+
queryExtensionSchema: paginationSchema
|
|
495
518
|
}).done();
|
|
496
519
|
|
|
497
520
|
// src/web/v2/types/types.requestLog.ts
|
|
@@ -500,18 +523,24 @@ var requestSchema = baseEntitySchema.extend({
|
|
|
500
523
|
body: z5.any().optional(),
|
|
501
524
|
fullUrl: z5.string(),
|
|
502
525
|
path: z5.string(),
|
|
503
|
-
method:
|
|
526
|
+
method: methodSchema,
|
|
504
527
|
query: z5.record(z5.string(), z5.any()).optional(),
|
|
505
528
|
params: z5.record(z5.string(), z5.any()).optional(),
|
|
506
529
|
output: z5.any().optional(),
|
|
507
530
|
headers: z5.record(z5.string(), z5.any()).optional(),
|
|
508
531
|
error: z5.string().optional(),
|
|
509
|
-
durationMs: z5.number()
|
|
532
|
+
durationMs: z5.number(),
|
|
533
|
+
ip: z5.string().optional(),
|
|
534
|
+
userAgent: z5.string().optional()
|
|
510
535
|
});
|
|
511
536
|
var requestQuerySchema = baseQuerySchema.extend({
|
|
512
|
-
methods:
|
|
513
|
-
|
|
514
|
-
|
|
537
|
+
methods: methodSchema.array().default([]),
|
|
538
|
+
excludeMethods: methodSchema.array().optional(),
|
|
539
|
+
statuses: z5.coerce.number().array().default([]),
|
|
540
|
+
excludeStatuses: z5.coerce.number().array().optional(),
|
|
541
|
+
path: z5.string().optional(),
|
|
542
|
+
endpointKey: z5.string().optional(),
|
|
543
|
+
excludeEndpointKey: z5.string().optional()
|
|
515
544
|
});
|
|
516
545
|
var requestLogLeaves = resource3("requests").get({
|
|
517
546
|
feed: true,
|
|
@@ -519,7 +548,8 @@ var requestLogLeaves = resource3("requests").get({
|
|
|
519
548
|
querySchema: requestQuerySchema,
|
|
520
549
|
outputMetaSchema: z5.object({
|
|
521
550
|
totalCount: z5.number().optional()
|
|
522
|
-
})
|
|
551
|
+
}),
|
|
552
|
+
queryExtensionSchema: paginationSchema
|
|
523
553
|
}).sub(
|
|
524
554
|
resource3(":requestId", void 0, z5.string()).get({
|
|
525
555
|
outputSchema: requestSchema.extend({
|
|
@@ -574,7 +604,7 @@ var STABILITIES = [
|
|
|
574
604
|
];
|
|
575
605
|
var stabilityEnum = z6.enum(STABILITIES);
|
|
576
606
|
var endpointSchema = baseEntitySchema.extend({
|
|
577
|
-
method:
|
|
607
|
+
method: methodSchema,
|
|
578
608
|
path: z6.string(),
|
|
579
609
|
contract: z6.object({
|
|
580
610
|
body: serializableSchemaSchema.optional(),
|
|
@@ -587,12 +617,15 @@ var endpointSchema = baseEntitySchema.extend({
|
|
|
587
617
|
summary: z6.string().optional(),
|
|
588
618
|
stability: stabilityEnum,
|
|
589
619
|
hidden: z6.boolean().optional(),
|
|
590
|
-
meta: z6.record(z6.string(), z6.string())
|
|
620
|
+
meta: z6.record(z6.string(), z6.string()),
|
|
621
|
+
implemented: z6.boolean().optional()
|
|
591
622
|
});
|
|
592
623
|
var endpointFilterSchema = baseQuerySchema.extend({
|
|
593
|
-
methods:
|
|
624
|
+
methods: methodSchema.array().optional(),
|
|
625
|
+
excludeMethods: methodSchema.array().optional(),
|
|
594
626
|
path: z6.string().optional(),
|
|
595
|
-
stability: stabilityEnum.array().optional()
|
|
627
|
+
stability: stabilityEnum.array().optional(),
|
|
628
|
+
excludeStability: stabilityEnum.array().optional()
|
|
596
629
|
});
|
|
597
630
|
var endpointLeaves = resource4("endpoints").get({
|
|
598
631
|
feed: true,
|
|
@@ -600,7 +633,8 @@ var endpointLeaves = resource4("endpoints").get({
|
|
|
600
633
|
outputSchema: endpointSchema.array(),
|
|
601
634
|
outputMetaSchema: z6.object({
|
|
602
635
|
totalCount: z6.number().optional()
|
|
603
|
-
})
|
|
636
|
+
}),
|
|
637
|
+
queryExtensionSchema: paginationSchema
|
|
604
638
|
}).sub(
|
|
605
639
|
resource4(":endpointId", void 0, z6.string()).get({
|
|
606
640
|
outputSchema: endpointSchema.extend({
|
|
@@ -609,7 +643,7 @@ var endpointLeaves = resource4("endpoints").get({
|
|
|
609
643
|
// Summary stats: return with the feed?
|
|
610
644
|
volumeTS: z6.array(
|
|
611
645
|
z6.object({
|
|
612
|
-
timestamp: z6.
|
|
646
|
+
timestamp: z6.number(),
|
|
613
647
|
count: z6.number()
|
|
614
648
|
})
|
|
615
649
|
),
|
|
@@ -627,8 +661,10 @@ import z7 from "zod";
|
|
|
627
661
|
var presetSchema = baseEntitySchema.extend({
|
|
628
662
|
operations: z7.array(
|
|
629
663
|
z7.object({
|
|
664
|
+
name: z7.string(),
|
|
665
|
+
stepNumber: z7.number(),
|
|
630
666
|
endpointId: z7.string().optional(),
|
|
631
|
-
method:
|
|
667
|
+
method: methodSchema,
|
|
632
668
|
path: z7.string(),
|
|
633
669
|
body: z7.json().optional(),
|
|
634
670
|
extraHeaders: z7.record(z7.string(), z7.any()).optional(),
|
|
@@ -638,16 +674,16 @@ var presetSchema = baseEntitySchema.extend({
|
|
|
638
674
|
});
|
|
639
675
|
var presetQuerySchema = baseQuerySchema.extend({
|
|
640
676
|
name: z7.string().optional(),
|
|
641
|
-
|
|
642
|
-
group: z7.string().optional()
|
|
677
|
+
excludeName: z7.string().optional()
|
|
643
678
|
});
|
|
644
679
|
var presetLeaves = resource5("presets").get({
|
|
645
680
|
feed: true,
|
|
646
|
-
querySchema: presetQuerySchema
|
|
681
|
+
querySchema: presetQuerySchema,
|
|
647
682
|
outputMetaSchema: z7.object({
|
|
648
683
|
totalCount: z7.number().optional()
|
|
649
684
|
}),
|
|
650
|
-
outputSchema: presetSchema
|
|
685
|
+
outputSchema: presetSchema.array(),
|
|
686
|
+
queryExtensionSchema: paginationSchema
|
|
651
687
|
}).post({
|
|
652
688
|
bodySchema: presetSchema,
|
|
653
689
|
outputSchema: presetSchema
|
|
@@ -656,7 +692,7 @@ var presetLeaves = resource5("presets").get({
|
|
|
656
692
|
outputSchema: presetSchema
|
|
657
693
|
}).done();
|
|
658
694
|
|
|
659
|
-
// src/web/
|
|
695
|
+
// src/web/v2/types/types.ts
|
|
660
696
|
var allLeaves = resource6().sub(
|
|
661
697
|
resource6("/__rrroutes").sub(
|
|
662
698
|
endpointLeaves,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/docs/LeafDocsPage.tsx","../src/docs/serializer.ts","../src/docs/schemaIntrospection.ts","../src/docs/docs.ts","../src/web/utils/security.ts","../src/web/utils/types.ts","../src/web/v2/types/types.cacheLog.ts","../src/web/v2/types/types.base.ts","../src/web/v2/types/types.endpoint.ts","../src/web/v2/types/types.requestLog.ts","../src/web/v2/types/types.log.ts","../src/web/v2/types/types.preset.ts"],"sourcesContent":["// index.ts\n\nimport { randomBytes } from 'crypto'\nimport type { RequestHandler, Router } from 'express'\nimport { static as expressStatic } from 'express'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { renderLeafDocsHTML } from './docs/docs.js'\nimport {\n applyDocsSecurityHeaders,\n createCookieGuard,\n createIpAllowListGuard,\n createMissingPasswordGuard,\n createPasswordGuard,\n} from './web/utils/security.js'\n\nexport type DocsAuthOptions = {\n /** Turn auth on/off. Enabled by default. */\n enabled?: boolean\n /** Password to require for docs access (HTTP Basic). */\n password?: string\n /** Realm used for the HTTP Basic challenge prompt. */\n realm?: string\n /**\n * Allow list of client IPs for docs access.\n * Supports:\n * - exact IPv4 or IPv6 strings (e.g. \"127.0.0.1\", \"::1\")\n * - IPv4 CIDR (e.g. \"10.0.0.0/8\", \"192.168.1.0/24\")\n */\n allowedIps?: string[]\n /**\n * Name of cookie used for cookie-based docs auth.\n * Requires `cookie-parser` or equivalent to populate `req.cookies`.\n */\n cookieName?: string\n /**\n * Optional exact value required for the cookie.\n * If omitted, the cookie only needs to exist (non-empty).\n */\n cookieSecret?: string\n /**\n * Fully custom guard middleware. If provided, it is used\n * instead of password/cookie auth (IP allow list still applies).\n */\n guardMiddleware?: RequestHandler\n /**\n * Whether to emit a CSP header + nonce. Defaults to true.\n */\n csp?: boolean\n}\n\nexport type MountDocsArgs = {\n router: Router\n auth: DocsAuthOptions\n}\n\nfunction resolvePublicDir() {\n const moduleDir =\n typeof __dirname !== 'undefined'\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url))\n const fromModule = path.resolve(moduleDir, '../public')\n if (fs.existsSync(fromModule)) return fromModule\n\n // When running from source (ts-node), fall back to the built output path.\n const fallback = path.resolve(moduleDir, '../dist/public')\n if (fs.existsSync(fallback)) return fallback\n\n return fromModule // fallback; express static will 404 if missing\n}\n\nexport function mountRRRoutesDocs({\n router,\n auth = {},\n}: MountDocsArgs): string {\n const docsPath = '/__rrroutes/docs'\n\n const publicDir = resolvePublicDir()\n const assetsDir = path.join(publicDir, 'assets')\n\n const cspEnabled = auth.csp !== false\n const authEnabled = auth.enabled !== false\n const docsPassword = auth.password\n const authRealm = auth.realm || 'RRRoutes Docs'\n const allowedIps = auth.allowedIps ?? []\n const cookieName = auth.cookieName\n const cookieSecret = auth?.cookieSecret\n const customGuard = auth?.guardMiddleware\n\n const ipGuard =\n allowedIps.length > 0 ? createIpAllowListGuard(allowedIps) : undefined\n\n const authGuard: RequestHandler = !authEnabled\n ? (_req, _res, next) => next()\n : customGuard\n ? customGuard\n : cookieName\n ? createCookieGuard(cookieName, cookieSecret)\n : docsPassword\n ? createPasswordGuard(docsPassword, authRealm)\n : createMissingPasswordGuard()\n\n // Protect docs HTML, static assets, and webhook feeds with IP guard (if any) + auth guard.\n ;[docsPath, `${docsPath}/assets`, `__rrroutes/`].forEach((p) => {\n if (ipGuard) router.use(p, ipGuard)\n router.use(p, authGuard)\n })\n\n router.use(\n `${docsPath}/assets`,\n expressStatic(assetsDir, { immutable: true, maxAge: '365d' }),\n )\n\n const docsRoutePaths = [docsPath, `${docsPath}/`, `${docsPath}/*id`]\n\n router.get(docsRoutePaths, (_req, res) => {\n const nonce = cspEnabled ? randomBytes(16).toString('base64') : undefined\n\n const html = renderLeafDocsHTML({\n cspNonce: nonce,\n assetBasePath: `${`${docsPath}/assets`}`,\n docsBasePath: `${docsPath}`,\n })\n\n applyDocsSecurityHeaders(res)\n\n if (cspEnabled && nonce) {\n res.setHeader(\n 'Content-Security-Policy',\n [\n \"default-src 'self'\",\n `script-src 'self' 'nonce-${nonce}'`,\n `style-src 'self' 'nonce-${nonce}'`,\n \"img-src 'self' data:\",\n \"connect-src 'self'\",\n \"font-src 'self'\",\n \"frame-ancestors 'self'\",\n \"object-src 'none'\",\n \"base-uri 'self'\",\n ].join('; '),\n )\n }\n\n res.send(html)\n })\n\n return docsPath\n}\n\nexport { renderLeafDocsHTML } from './docs/docs.js'\nexport { introspectSchema } from './docs/schemaIntrospection.js'\nexport { serializeLeaf } from './docs/serializer.js'\nexport type { SerializedLeaf as SerializableLeaf } from './docs/serializer.js'\nexport { leaves as requiredRoutes } from './web/utils/types.js'\n","// LeafDocsPage.tsx\n\nimport type { AnyLeafLowProfile } from '@emeryld/rrroutes-contract'\nimport type { ReactElement } from 'react'\nimport { renderToStaticMarkup } from 'react-dom/server'\nimport { serializeLeaf } from './serializer.js'\n\nexport interface RenderOptions {\n /** CSP nonce applied to data + script tags. */\n cspNonce?: string\n /** Base URL where static assets are served (e.g. `/__rrroutes/docs/assets`). */\n assetBasePath?: string\n /** Root path where the docs are mounted (e.g. `/__rrroutes/docs`). Used for client routing. */\n docsBasePath?: string\n}\n\nconst DEFAULT_ASSET_BASE = '/__rrroutes/docs/assets'\n\nfunction normalizeBase(base: string) {\n if (!base) return DEFAULT_ASSET_BASE\n return base.endsWith('/') ? base.slice(0, -1) : base\n}\n\nfunction normalizeDocsBase(base: string | undefined) {\n if (!base) return ''\n if (base === '/') return '/'\n return base.endsWith('/') && base.length > 1 ? base.slice(0, -1) : base\n}\n\nfunction normalizeBaseUrlSuffix(suffix: string | undefined) {\n if (!suffix) return ''\n const trimmed =\n suffix.endsWith('/') && suffix.length > 1 ? suffix.slice(0, -1) : suffix\n return trimmed.startsWith('/') ? trimmed : `/${trimmed}`\n}\n\ntype DocsDocumentProps = {\n assetBase: string\n docsBase: string\n cspNonce?: string\n}\n\nexport const DocsDocument = ({\n assetBase,\n docsBase,\n cspNonce,\n}: DocsDocumentProps) => {\n const cssHref = `${assetBase}/docs.css`\n const jsSrc = `${assetBase}/docs.js`\n const configJson = serializeConfig({\n docsBasePath: docsBase,\n cspNonce,\n })\n\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>API Reference</title>\n <link rel=\"stylesheet\" href={cssHref} />\n </head>\n <body>\n <div id=\"docs-root\"></div>\n <script\n id=\"docs-config\"\n type=\"application/json\"\n nonce={cspNonce}\n dangerouslySetInnerHTML={{ __html: configJson }}\n />\n <script type=\"module\" src={jsSrc} nonce={cspNonce} />\n </body>\n </html>\n )\n}\n\nfunction serializeLeaves(leaves: AnyLeafLowProfile[]) {\n return JSON.stringify(leaves.map(serializeLeaf)).replace(/<\\//g, '<\\\\/')\n}\n\ntype DocsConfig = {\n docsBasePath: string\n baseUrlSuffix?: string\n cspNonce?: string\n}\n\nfunction serializeConfig(config: DocsConfig) {\n return JSON.stringify(config).replace(/<\\//g, '<\\\\/')\n}\n\nexport function createLeafDocsDocument(\n options: RenderOptions = {},\n): ReactElement {\n const assetBase = normalizeBase(options.assetBasePath ?? DEFAULT_ASSET_BASE)\n\n const docsBase = normalizeDocsBase(options.docsBasePath)\n\n return (\n <DocsDocument\n assetBase={assetBase}\n docsBase={docsBase}\n cspNonce={options.cspNonce}\n />\n )\n}\n\nexport function renderLeafDocsHTML(options: RenderOptions = {}): string {\n const doc = createLeafDocsDocument(options)\n const html = renderToStaticMarkup(doc)\n return `<!DOCTYPE html>${html}`\n}\n\nexport type SerializableHistoryEntry = {\n id?: string\n timestamp: number\n method: string\n path: string\n fullUrl: string\n params?: Record<string, string>\n query?: Record<string, string>\n body?: string\n output?: string\n status?: number\n durationMs: number\n error?: string\n}\n","// serializer.ts\nimport {\n MethodCfgLowProfile,\n routeSchemaParse,\n type AnyLeafLowProfile,\n} from '@emeryld/rrroutes-contract'\nimport { MethodType } from '../web/v2/types/types.base.js'\nimport type { Endpoint } from '../web/v2/types/types.endpoint.js'\nimport { introspectSchema } from './schemaIntrospection.js'\n\nexport type SerializedLeaf = Endpoint\n\nexport type { SerializableSchemaNode } from './schemaIntrospection.js'\n\nexport function serializeLeaf(leaf: AnyLeafLowProfile): Endpoint {\n const cfg = leaf.cfg\n\n const tags = Array.isArray(cfg.tags) ? cfg.tags.slice() : []\n const stability = (cfg.stability ?? 'experimental') as Endpoint['stability']\n const now = Date.now()\n\n return {\n id: buildLeafId(leaf),\n name: inferName(cfg, leaf.path),\n description: cfg.description,\n groupId: cfg.docsGroup,\n tags: tags.length > 0 ? tags : undefined,\n createdAt: now,\n updatedAt: now,\n method: leaf.method as MethodType,\n path: leaf.path,\n contract: {\n body: serializeContractSchema(cfg.bodySchema),\n query: serializeContractSchema(cfg.querySchema),\n params: serializeContractSchema(cfg.paramsSchema),\n output: serializeContractSchema(cfg.outputSchema),\n bodyFiles: serializeBodyFiles(cfg),\n },\n feed: cfg.feed ?? undefined,\n summary: cfg.summary,\n stability,\n hidden: cfg.docsHidden,\n meta: serializeMeta(cfg.docsMeta),\n }\n}\n\nfunction serializeContractSchema(schema: MethodCfgLowProfile['bodySchema']) {\n return schema ? introspectSchema(routeSchemaParse(schema)) : undefined\n}\n\nfunction serializeBodyFiles(cfg: MethodCfgLowProfile) {\n if (!Array.isArray(cfg.bodyFiles) || cfg.bodyFiles.length === 0)\n return undefined\n return cfg.bodyFiles.map(({ name, maxCount }) => ({ name, maxCount }))\n}\n\nfunction serializeMeta(meta?: Record<string, unknown>): Record<string, string> {\n if (!meta) return {}\n const entries = Object.entries(meta)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => [\n key,\n typeof value === 'string' ? value : JSON.stringify(value),\n ])\n return Object.fromEntries(entries)\n}\n\nfunction buildLeafId(leaf: AnyLeafLowProfile) {\n return `${leaf.method.toUpperCase()} ${leaf.path}`\n}\n\nfunction inferName(cfg: MethodCfgLowProfile, path: string) {\n return cfg.summary || cfg.description || path\n}\n","// schemaIntrospection.ts\nimport * as z from 'zod'\nimport type { SerializableSchema } from '../web/v2/types/types.endpoint.js'\n\nexport type SerializableSchemaNode = SerializableSchema\n\ntype ZodAny = z.ZodTypeAny\n\n/**\n * Zod 3 uses `schema._def`, Zod 4 uses `schema._zod.def`.\n */\nfunction getDef(schema: unknown): any | undefined {\n if (!schema || typeof schema !== 'object') return undefined\n const anySchema = schema as any\n return anySchema._zod?.def ?? anySchema._def\n}\n\n/**\n * Try to get a human-readable description.\n * Zod 4: use metadata/registry; fallback to internal def.description.\n * Zod 3: only internal def.description exists.\n */\nfunction getDescription(schema: ZodAny): string | undefined {\n const anyZ: any = z as any\n\n // Zod 4 global registry metadata, if present\n const registry = anyZ.globalRegistry?.get\n ? anyZ.globalRegistry.get(schema)\n : undefined\n if (registry && typeof registry.description === 'string') {\n return registry.description\n }\n\n // Legacy / internal description\n const def = getDef(schema)\n if (def && typeof def.description === 'string') {\n return def.description\n }\n\n return undefined\n}\n\n/**\n * Peel off wrappers (effects, optional, nullable, default) and\n * return the inner schema + flags.\n *\n * Supports:\n * - Zod 3: ZodEffects, ZodOptional, ZodNullable, ZodDefault\n * - Zod 4: ZodOptional, ZodNullable, ZodDefault\n */\nfunction unwrap(schema: ZodAny): {\n base: ZodAny\n optional: boolean\n nullable: boolean\n} {\n let s: ZodAny = schema\n let optional = false\n let nullable = false\n\n // Zod 3 only (undefined in Zod 4)\n const ZodEffectsCtor: any = (z as any).ZodEffects\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n // Zod 3: ZodEffects wrapper\n if (ZodEffectsCtor && s instanceof ZodEffectsCtor) {\n const def = getDef(s) || {}\n const sourceType =\n typeof (s as any).sourceType === 'function'\n ? (s as any).sourceType()\n : def.schema\n if (!sourceType) break\n s = sourceType\n continue\n }\n\n // Zod 3 + 4: optional/nullable/default wrappers\n if (s instanceof z.ZodOptional) {\n optional = true\n const def = getDef(s)\n s = (def && def.innerType) || s // innerType exists in both 3 & 4\n continue\n }\n\n if (s instanceof z.ZodNullable) {\n nullable = true\n const def = getDef(s)\n s = (def && def.innerType) || s\n continue\n }\n\n if (s instanceof z.ZodDefault) {\n const def = getDef(s)\n s = (def && def.innerType) || s\n continue\n }\n\n break\n }\n\n return { base: s, optional, nullable }\n}\n\nexport function introspectSchema(\n schema: ZodAny | undefined,\n): SerializableSchema | undefined {\n if (!schema) return undefined\n\n const { base, optional, nullable } = unwrap(schema)\n const def = getDef(base)\n\n const node: SerializableSchema = {\n kind: inferKind(base),\n optional: optional || undefined,\n nullable: nullable || undefined,\n description: getDescription(base),\n }\n\n // OBJECT\n if (base instanceof z.ZodObject) {\n // Zod 3: _def.shape() (function)\n // Zod 4: .shape getter returns an object\n const rawShape: any =\n (base as any).shape ??\n (def && typeof def.shape === 'function' ? def.shape() : def?.shape)\n\n const shape = typeof rawShape === 'function' ? rawShape() : (rawShape ?? {})\n\n const props: Record<string, SerializableSchema> = {}\n for (const key of Object.keys(shape)) {\n const child = shape[key] as ZodAny\n const childNode = introspectSchema(child)\n if (childNode) props[key] = childNode\n }\n node.properties = props\n }\n\n // ARRAY\n if (base instanceof z.ZodArray) {\n // Zod 3: def.type is inner schema\n // Zod 4: def.element is inner schema\n const inner =\n (def && (def.element as ZodAny)) ||\n (def && (def.type as ZodAny)) ||\n undefined\n if (inner) {\n node.element = introspectSchema(inner)\n }\n }\n\n // UNION\n if (base instanceof z.ZodUnion) {\n const options: ZodAny[] = (def && def.options) || []\n node.union = options\n .map((opt) => introspectSchema(opt))\n .filter(Boolean) as SerializableSchema[]\n }\n\n // LITERAL\n if (base instanceof z.ZodLiteral) {\n if (def) {\n // Zod 4: def.values (multi-literal)\n if (Array.isArray(def.values)) {\n node.literal =\n def.values.length === 1 ? def.values[0] : def.values.slice()\n } else {\n // Zod 3: def.value\n node.literal = def.value\n }\n }\n }\n\n // ENUM\n if (base instanceof z.ZodEnum) {\n if (def) {\n if (Array.isArray(def.values)) {\n // Zod 3\n node.enumValues = def.values.slice()\n } else if (def.entries && typeof def.entries === 'object') {\n // Zod 4: entries is a { key: value } map\n node.enumValues = Object.values(def.entries).map((v: unknown) =>\n String(v),\n )\n }\n }\n }\n\n return node\n}\n\nfunction inferKind(schema: ZodAny): SerializableSchema['kind'] {\n // This path still uses instanceof; it works with Zod 4 Classic\n // (importing from \"zod\"). Anything unknown falls back to \"unknown\".\n if (schema instanceof z.ZodString) return 'string'\n if (schema instanceof z.ZodNumber) return 'number'\n if (schema instanceof z.ZodBoolean) return 'boolean'\n if (schema instanceof z.ZodBigInt) return 'bigint'\n if (schema instanceof z.ZodDate) return 'date'\n if (schema instanceof z.ZodArray) return 'array'\n if (schema instanceof z.ZodObject) return 'object'\n if (schema instanceof z.ZodUnion) return 'union'\n if (schema instanceof z.ZodLiteral) return 'literal'\n if (schema instanceof z.ZodEnum) return 'enum'\n if (schema instanceof z.ZodRecord) return 'record'\n if (schema instanceof z.ZodTuple) return 'tuple'\n if (schema instanceof z.ZodUnknown) return 'unknown'\n if (schema instanceof z.ZodAny) return 'any'\n\n return 'unknown'\n}\n","// renderLeafDocsHTML.ts\nimport {\n renderLeafDocsHTML as LeafDocsPage,\n RenderOptions,\n} from './LeafDocsPage.js'\n\nexport function renderLeafDocsHTML(options: RenderOptions = {}): string {\n return LeafDocsPage(options)\n}\n\nexport { createLeafDocsDocument } from './LeafDocsPage.js'\nexport type { RenderOptions } from './LeafDocsPage.js'\n","import type { Request, RequestHandler, Response } from 'express'\nimport net from 'node:net'\n\n/**\n * HTTP Basic password guard.\n */\nexport function createPasswordGuard(\n password: string,\n realm: string,\n): RequestHandler {\n const trimmed = password.trim()\n return (req: Request, res: Response, next: () => void) => {\n const provided = extractPassword(req.headers.authorization)\n if (provided && provided === trimmed) {\n return next()\n }\n applyDocsSecurityHeaders(res)\n res.setHeader('WWW-Authenticate', `Basic realm=\"${realm}\"`)\n res\n .status(401)\n .send(\n renderAuthErrorPage(\n 'Docs are password protected. Provide the configured password.',\n ),\n )\n }\n}\n/**\n * Cookie-based guard. Requires `req.cookies` to be populated\n * (e.g. via `cookie-parser`).\n */\nexport function createCookieGuard(\n cookieName: string,\n cookieSecret?: string,\n): RequestHandler {\n return (req: Request, res: Response, next: () => void) => {\n const cookies = (req as any).cookies as Record<string, string> | undefined\n const value = cookies?.[cookieName]\n\n const valid = cookieSecret ? value === cookieSecret : Boolean(value)\n\n if (valid) {\n return next()\n }\n\n applyDocsSecurityHeaders(res)\n res\n .status(401)\n .send(\n renderAuthErrorPage(\n 'Docs are protected. You must be authenticated to access this page.',\n ),\n )\n }\n}\n/**\n * When auth is enabled but no password/cookie/custom guard is provided,\n * fail closed.\n */\nexport function createMissingPasswordGuard(): RequestHandler {\n return (_req: Request, res: Response) => {\n applyDocsSecurityHeaders(res)\n res\n .status(500)\n .send(renderAuthErrorPage('Provide auth configuration to mounted docs'))\n }\n}\n/**\n * Extract password from HTTP Basic Authorization header.\n */\nfunction extractPassword(authHeader: string | string[] | undefined) {\n if (!authHeader) return undefined\n const header = Array.isArray(authHeader) ? authHeader[0] : authHeader\n if (typeof header !== 'string' || !header.startsWith('Basic '))\n return undefined\n const token = header.slice('Basic '.length)\n try {\n const decoded = Buffer.from(token, 'base64').toString('utf8')\n const parts = decoded.split(':')\n parts.shift() // username\n return parts.join(':')\n } catch {\n return undefined\n }\n}\n/**\n * Simple IP allow-list guard. For accurate client IPs behind proxies,\n * configure `app.set('trust proxy', true)` in your Express app.\n */\nexport function createIpAllowListGuard(allowed: string[]): RequestHandler {\n const ranges = allowed\n .map((raw) => raw.trim())\n .filter(Boolean)\n .map(parseIpPattern)\n .filter((r): r is IpRange => r !== null)\n\n return (req: Request, res: Response, next: () => void) => {\n const rawIp =\n req.ip || (req.connection && (req.connection as any).remoteAddress) || ''\n const ip = normalizeIp(rawIp)\n\n if (!ip || !isIpAllowed(ip, ranges)) {\n applyDocsSecurityHeaders(res)\n res\n .status(403)\n .send(\n renderAuthErrorPage(\n 'Access to docs is restricted from this IP address.',\n ),\n )\n return\n }\n\n next()\n }\n}\ntype IpRange =\n | { kind: 'exact'; value: string }\n | { kind: 'cidr'; base: number; mask: number }\n/**\n * Normalize typical Express IP formats, including IPv4-mapped IPv6.\n */\nfunction normalizeIp(ip: string): string {\n if (!ip) return ''\n if (ip.startsWith('::ffff:')) return ip.slice(7)\n if (ip === '::1') return '127.0.0.1'\n return ip\n}\nfunction parseIpPattern(raw: string): IpRange | null {\n if (raw.includes('/')) {\n const cidr = parseCidr(raw)\n if (!cidr) return null\n return { kind: 'cidr', base: cidr.base, mask: cidr.mask }\n }\n\n // Exact string match (IPv4 or IPv6).\n return { kind: 'exact', value: normalizeIp(raw) }\n}\nfunction parseCidr(raw: string): { base: number; mask: number } | null {\n const [baseIp, bitsStr] = raw.split('/')\n const bits = Number(bitsStr)\n if (!Number.isInteger(bits) || bits < 0 || bits > 32) return null\n if (net.isIP(baseIp) !== 4) return null // IPv4 CIDR only for simplicity\n\n const baseLong = ipToLong(baseIp)\n if (baseLong == null) return null\n\n const mask = bits === 0 ? 0 : (~0 << (32 - bits)) >>> 0\n return { base: (baseLong & mask) >>> 0, mask }\n}\nfunction ipToLong(ip: string): number | null {\n const parts = ip.split('.').map((n) => Number(n))\n if (parts.length !== 4) return null\n if (parts.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) return null\n return (\n ((parts[0] << 24) >>> 0) +\n ((parts[1] << 16) >>> 0) +\n ((parts[2] << 8) >>> 0) +\n parts[3]\n )\n}\nfunction isIpAllowed(ip: string, ranges: IpRange[]): boolean {\n const ipv4 = net.isIP(ip) === 4 ? ipToLong(ip) : null\n\n for (const r of ranges) {\n if (r.kind === 'exact') {\n if (ip === r.value) return true\n } else if (r.kind === 'cidr' && ipv4 != null) {\n if ((ipv4 & r.mask) === r.base) return true\n }\n }\n\n return false\n}\nfunction renderAuthErrorPage(message: string) {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>RRRoutes docs locked</title>\n <style>\n body { margin:0; font-family: system-ui, -apple-system, Segoe UI, sans-serif; background: #0f172a; color: #e2e8f0; display:flex; align-items:center; justify-content:center; min-height:100vh; }\n .card { padding:32px; border:1px solid #1e293b; border-radius:12px; max-width:420px; background: rgba(15,23,42,0.8); box-shadow:0 15px 45px rgba(0,0,0,0.35); }\n h1 { margin:0 0 12px; font-size:22px; }\n p { margin:0; line-height:1.5; color:#cbd5e1; }\n code { background: rgba(226,232,240,0.1); padding: 2px 4px; border-radius: 4px; }\n </style>\n</head>\n<body>\n <div class=\"card\">\n <h1>Docs locked</h1>\n <p>${message}</p>\n </div>\n</body>\n</html>`\n}\nexport function applyDocsSecurityHeaders(res: Response) {\n res.setHeader('X-Content-Type-Options', 'nosniff')\n res.setHeader('Referrer-Policy', 'same-origin')\n res.setHeader('X-Frame-Options', 'SAMEORIGIN')\n res.setHeader('Cache-Control', 'no-store')\n res.setHeader(\n 'Strict-Transport-Security',\n 'max-age=31536000; includeSubDomains',\n )\n}\n","import {\n AnyLeafLowProfile,\n AugmentLeaves,\n finalize,\n FinalizedRegistry,\n resource,\n} from '@emeryld/rrroutes-contract'\nimport { cacheLeaves } from '../v2/types/types.cacheLog'\nimport { endpointLeaves } from '../v2/types/types.endpoint'\nimport { logLeaves } from '../v2/types/types.log'\nimport { presetLeaves } from '../v2/types/types.preset'\nimport { requestLogLeaves } from '../v2/types/types.requestLog'\n\ntype MountedLeaves<Leaves extends readonly AnyLeafLowProfile[]> = AugmentLeaves<\n '/__rrroutes',\n undefined,\n Leaves\n>\ntype AllLeaves = readonly [\n ...MountedLeaves<typeof endpointLeaves>,\n ...MountedLeaves<typeof requestLogLeaves>,\n ...MountedLeaves<typeof logLeaves>,\n ...MountedLeaves<typeof cacheLeaves>,\n ...MountedLeaves<typeof presetLeaves>,\n]\n\nconst allLeaves: AllLeaves = resource()\n .sub(\n resource('/__rrroutes')\n .sub(\n endpointLeaves,\n requestLogLeaves,\n logLeaves,\n cacheLeaves,\n presetLeaves,\n )\n .done(),\n )\n .done()\n\nexport const leaves: FinalizedRegistry<typeof allLeaves> = finalize(allLeaves)\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport { baseEntitySchema, baseQuerySchema } from './types.base'\n\nconst operationEnum = z.enum(['hit', 'miss', 'set', 'delete'])\nexport const cacheLogSchema = baseEntitySchema.extend({\n operation: operationEnum,\n // on hit, value = value retrieved\n // on miss, value = null\n // on set, value = value set\n // on delete, value = value deleted\n value: z.any().nullable(),\n size: z.number().optional(),\n})\n\nexport const cacheLogQuerySchema = baseQuerySchema.extend({\n operations: operationEnum.array().optional(),\n})\n\nexport const cacheLeaves = resource('cache')\n .get({\n feed: true,\n outputSchema: cacheLogSchema.array(),\n querySchema: cacheLogQuerySchema,\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n })\n .post({\n querySchema: cacheLogQuerySchema,\n })\n .done()\n","import z from 'zod'\n\nexport const METHODS = ['get', 'post', 'put', 'patch', 'delete'] as const\nexport type MethodType = (typeof METHODS)[number]\n\nexport const baseEntitySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().optional(),\n groupId: z.string().optional(),\n tags: z.string().array().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n})\n\nexport const baseQuerySchema = z.object({\n beforeDate: z.string().optional(),\n afterDate: z.string().optional(),\n orderBy: z\n .enum(['timestamp', 'duration', 'level', 'path'])\n .default('timestamp'),\n orderDirection: z.enum(['asc', 'desc']).default('desc'),\n searchQuery: z.string().optional(),\n groups: z.string().array().optional(),\n tags: z.string().array().optional(),\n cursor: z.string().optional(),\n})\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z, { ZodType } from 'zod'\nimport { baseEntitySchema, baseQuerySchema, METHODS } from './types.base'\nimport { requestSchema } from './types.requestLog'\n\nexport const nodeKind = [\n 'object',\n 'string',\n 'number',\n 'boolean',\n 'bigint',\n 'date',\n 'array',\n 'enum',\n 'literal',\n 'union',\n 'record',\n 'tuple',\n 'unknown',\n 'any',\n] as const\n\nexport type SerializableSchema = {\n kind: (typeof nodeKind)[number]\n optional?: boolean\n nullable?: boolean\n description?: string\n\n // object\n properties?: Record<string, SerializableSchema>\n // array\n element?: SerializableSchema\n // union\n union?: SerializableSchema[]\n // literal\n literal?: unknown\n // enum\n enumValues?: string[]\n}\n\n// The Zod schema\nexport const serializableSchemaSchema: ZodType<\n SerializableSchema,\n SerializableSchema\n> = z.lazy(() =>\n z.object({\n kind: z.enum(nodeKind),\n\n optional: z.boolean().optional(),\n nullable: z.boolean().optional(),\n description: z.string().optional(),\n\n // object\n properties: z\n .record(z.string(), serializableSchemaSchema) // Record<string, SerializableSchemaNode>\n .optional(),\n\n // array\n element: serializableSchemaSchema.optional(),\n\n // union\n union: z.array(serializableSchemaSchema).optional(),\n\n // literal\n literal: z.unknown().optional(),\n\n // enum\n enumValues: z.array(z.string()).optional(),\n }),\n)\n\nexport const STABILITIES = [\n 'experimental',\n 'beta',\n 'stable',\n 'deprecated',\n] as const\nconst stabilityEnum = z.enum(STABILITIES)\nexport const endpointSchema = baseEntitySchema.extend({\n method: z.enum(METHODS),\n path: z.string(),\n contract: z.object({\n body: serializableSchemaSchema.optional(),\n query: serializableSchemaSchema.optional(),\n output: serializableSchemaSchema.optional(),\n params: serializableSchemaSchema.optional(),\n bodyFiles: z\n .array(z.object({ name: z.string(), maxCount: z.number() }))\n .optional(),\n }),\n feed: z.boolean().optional(),\n summary: z.string().optional(),\n stability: stabilityEnum,\n hidden: z.boolean().optional(),\n meta: z.record(z.string(), z.string()),\n})\n\nexport type Endpoint = z.output<typeof endpointSchema>\n\nexport const endpointFilterSchema = baseQuerySchema.extend({\n methods: z.enum(METHODS).array().optional(),\n path: z.string().optional(),\n stability: stabilityEnum.array().optional(),\n})\n\nexport const endpointLeaves = resource('endpoints')\n .get({\n feed: true,\n querySchema: endpointFilterSchema,\n outputSchema: endpointSchema.array(),\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n })\n .sub(\n resource(':endpointId', undefined, z.string())\n .get({\n outputSchema: endpointSchema.extend({\n // Related by groupId. Just use the existing feed endpoints with filter: groupId=?\n requests: z.array(requestSchema),\n // Summary stats: return with the feed?\n volumeTS: z.array(\n z.object({\n timestamp: z.string(),\n count: z.number(),\n }),\n ),\n averageDurationMs: z.number(),\n successRate: z.number(),\n // Add id as query param to the existing feed endpoints? This way \"requests\" field can also be only Ids\n latestErrorRequestIds: z.array(z.string()),\n }),\n })\n .done(),\n )\n .done()\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport { baseEntitySchema, baseQuerySchema, METHODS } from './types.base'\nimport { cacheLogSchema } from './types.cacheLog'\nimport { logSchema } from './types.log'\n\nexport const requestSchema = baseEntitySchema.extend({\n status: z.number(),\n body: z.any().optional(),\n fullUrl: z.string(),\n path: z.string(),\n method: z.enum(METHODS),\n query: z.record(z.string(), z.any()).optional(),\n params: z.record(z.string(), z.any()).optional(),\n output: z.any().optional(),\n headers: z.record(z.string(), z.any()).optional(),\n error: z.string().optional(),\n durationMs: z.number(),\n})\n\nexport type RequestLogType = z.infer<typeof requestSchema>\n\nexport const requestQuerySchema = baseQuerySchema.extend({\n methods: z.enum(METHODS).array().default([]),\n statuses: z.number().array().default([]),\n path: z.string().optional(),\n})\n\nexport const requestLogLeaves = resource('requests')\n .get({\n feed: true,\n outputSchema: requestSchema.array(),\n querySchema: requestQuerySchema,\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n })\n .sub(\n resource(':requestId', undefined, z.string())\n .get({\n outputSchema: requestSchema.extend({\n // Related by groupId\n // Do I just use the existing feed endpoints with filter: groupId=?\n logs: z.array(logSchema),\n caches: z.array(cacheLogSchema),\n }),\n })\n .done(),\n )\n .done()\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport { baseEntitySchema, baseQuerySchema } from './types.base'\n\nconst levelSchema = z.enum(['info', 'warning', 'error', 'debug', 'trace'])\nexport const logSchema = baseEntitySchema.extend({\n level: levelSchema,\n meta: z.json(),\n})\n\nexport const logQuerySchema = baseQuerySchema.extend({\n level: levelSchema.array().optional(),\n})\n\nexport const logLeaves = resource('logs')\n .get({\n feed: true,\n outputSchema: logSchema.array(),\n querySchema: logQuerySchema,\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n })\n .done()\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport { baseEntitySchema, baseQuerySchema, METHODS } from './types.base'\n\nconst presetSchema = baseEntitySchema.extend({\n operations: z.array(\n z.object({\n endpointId: z.string().optional(),\n method: z.enum(METHODS),\n path: z.string(),\n body: z.json().optional(),\n extraHeaders: z.record(z.string(), z.any()).optional(),\n query: z.record(z.string(), z.any()).optional(),\n }),\n ),\n})\n\nconst presetQuerySchema = baseQuerySchema.extend({\n name: z.string().optional(),\n tags: z.string().array().optional(),\n group: z.string().optional(),\n})\n\nexport const presetLeaves = resource('presets')\n .get({\n feed: true,\n querySchema: presetQuerySchema.array(),\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n outputSchema: presetSchema,\n })\n .post({\n bodySchema: presetSchema,\n outputSchema: presetSchema,\n })\n .put({\n bodySchema: presetSchema,\n outputSchema: presetSchema,\n })\n .done()\n"],"mappings":"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","names":["path","renderLeafDocsHTML","resource","z","z","z","resource","z","resource","z","resource","z","z","resource","z","resource","z","resource","resource","z","z","resource","resource","renderLeafDocsHTML"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/docs/LeafDocsPage.tsx","../src/docs/serializer.ts","../src/docs/schemaIntrospection.ts","../src/docs/docs.ts","../src/web/utils/security.ts","../src/web/v2/types/types.ts","../src/web/v2/types/types.cacheLog.ts","../src/web/v2/types/types.base.ts","../src/web/v2/types/types.endpoint.ts","../src/web/v2/types/types.requestLog.ts","../src/web/v2/types/types.log.ts","../src/web/v2/types/types.preset.ts"],"sourcesContent":["// index.ts\n\nimport { randomBytes } from 'crypto'\nimport type { RequestHandler, Router } from 'express'\nimport { static as expressStatic } from 'express'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { renderLeafDocsHTML } from './docs/docs.js'\nimport {\n applyDocsSecurityHeaders,\n createCookieGuard,\n createIpAllowListGuard,\n createMissingPasswordGuard,\n createPasswordGuard,\n} from './web/utils/security.js'\n\nexport type DocsAuthOptions = {\n /** Turn auth on/off. Enabled by default. */\n enabled?: boolean\n /** Password to require for docs access (HTTP Basic). */\n password?: string\n /** Realm used for the HTTP Basic challenge prompt. */\n realm?: string\n /**\n * Allow list of client IPs for docs access.\n * Supports:\n * - exact IPv4 or IPv6 strings (e.g. \"127.0.0.1\", \"::1\")\n * - IPv4 CIDR (e.g. \"10.0.0.0/8\", \"192.168.1.0/24\")\n */\n allowedIps?: string[]\n /**\n * Name of cookie used for cookie-based docs auth.\n * Requires `cookie-parser` or equivalent to populate `req.cookies`.\n */\n cookieName?: string\n /**\n * Optional exact value required for the cookie.\n * If omitted, the cookie only needs to exist (non-empty).\n */\n cookieSecret?: string\n /**\n * Fully custom guard middleware. If provided, it is used\n * instead of password/cookie auth (IP allow list still applies).\n */\n guardMiddleware?: RequestHandler\n /**\n * Whether to emit a CSP header + nonce. Defaults to true.\n */\n csp?: boolean\n}\n\nexport type MountDocsArgs = {\n router: Router\n auth: DocsAuthOptions\n}\n\nfunction resolvePublicDir() {\n const moduleDir =\n typeof __dirname !== 'undefined'\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url))\n const fromModule = path.resolve(moduleDir, '../public')\n if (fs.existsSync(fromModule)) return fromModule\n\n // When running from source (ts-node), fall back to the built output path.\n const fallback = path.resolve(moduleDir, '../dist/public')\n if (fs.existsSync(fallback)) return fallback\n\n return fromModule // fallback; express static will 404 if missing\n}\n\nexport function mountRRRoutesDocs({\n router,\n auth = {},\n}: MountDocsArgs): string {\n const docsPath = '/__rrroutes/docs'\n\n const publicDir = resolvePublicDir()\n const assetsDir = path.join(publicDir, 'assets')\n\n const cspEnabled = auth.csp !== false\n const authEnabled = auth.enabled !== false\n const docsPassword = auth.password\n const authRealm = auth.realm || 'RRRoutes Docs'\n const allowedIps = auth.allowedIps ?? []\n const cookieName = auth.cookieName\n const cookieSecret = auth?.cookieSecret\n const customGuard = auth?.guardMiddleware\n\n const ipGuard =\n allowedIps.length > 0 ? createIpAllowListGuard(allowedIps) : undefined\n\n const authGuard: RequestHandler = !authEnabled\n ? (_req, _res, next) => next()\n : customGuard\n ? customGuard\n : cookieName\n ? createCookieGuard(cookieName, cookieSecret)\n : docsPassword\n ? createPasswordGuard(docsPassword, authRealm)\n : createMissingPasswordGuard()\n\n // Protect docs HTML, static assets, and webhook feeds with IP guard (if any) + auth guard.\n ;[docsPath, `${docsPath}/assets`, `__rrroutes/`].forEach((p) => {\n if (ipGuard) router.use(p, ipGuard)\n router.use(p, authGuard)\n })\n\n router.use(\n `${docsPath}/assets`,\n expressStatic(assetsDir, { immutable: true, maxAge: '365d' }),\n )\n\n const docsRoutePaths = [docsPath, `${docsPath}/`, `${docsPath}/*id`]\n\n router.get(docsRoutePaths, (_req, res) => {\n const nonce = cspEnabled ? randomBytes(16).toString('base64') : undefined\n\n const html = renderLeafDocsHTML({\n cspNonce: nonce,\n assetBasePath: `${`${docsPath}/assets`}`,\n docsBasePath: `${docsPath}`,\n })\n\n applyDocsSecurityHeaders(res)\n\n if (cspEnabled && nonce) {\n res.setHeader(\n 'Content-Security-Policy',\n [\n \"default-src 'self'\",\n `script-src 'self' 'nonce-${nonce}'`,\n `style-src 'self' 'nonce-${nonce}'`,\n \"img-src 'self' data:\",\n \"connect-src 'self'\",\n \"font-src 'self'\",\n \"frame-ancestors 'self'\",\n \"object-src 'none'\",\n \"base-uri 'self'\",\n ].join('; '),\n )\n }\n\n res.send(html)\n })\n\n return docsPath\n}\n\nexport { renderLeafDocsHTML } from './docs/docs.js'\nexport { introspectSchema } from './docs/schemaIntrospection.js'\nexport { serializeLeaf } from './docs/serializer.js'\nexport type { SerializedLeaf as SerializableLeaf } from './docs/serializer.js'\nexport { leaves as requiredRoutes } from './web/utils/types.js'\n\nexport type { CacheLogType as RRRCacheLogType } from './web/v2/types/types.cacheLog.js'\nexport type { EndpointType as RRREndpointType } from './web/v2/types/types.endpoint.js'\nexport type { LogType as RRRLogType } from './web/v2/types/types.log.js'\nexport type { PresetType as RRRPresetType } from './web/v2/types/types.preset.js'\nexport type { RequestLogType as RRRRequestLogType } from './web/v2/types/types.requestLog.js'\n","// LeafDocsPage.tsx\n\nimport type { AnyLeafLowProfile } from '@emeryld/rrroutes-contract'\nimport type { ReactElement } from 'react'\nimport { renderToStaticMarkup } from 'react-dom/server'\nimport { serializeLeaf } from './serializer.js'\n\nexport interface RenderOptions {\n /** CSP nonce applied to data + script tags. */\n cspNonce?: string\n /** Base URL where static assets are served (e.g. `/__rrroutes/docs/assets`). */\n assetBasePath?: string\n /** Root path where the docs are mounted (e.g. `/__rrroutes/docs`). Used for client routing. */\n docsBasePath?: string\n}\n\nconst DEFAULT_ASSET_BASE = '/__rrroutes/docs/assets'\n\nfunction normalizeBase(base: string) {\n if (!base) return DEFAULT_ASSET_BASE\n return base.endsWith('/') ? base.slice(0, -1) : base\n}\n\nfunction normalizeDocsBase(base: string | undefined) {\n if (!base) return ''\n if (base === '/') return '/'\n return base.endsWith('/') && base.length > 1 ? base.slice(0, -1) : base\n}\n\nfunction normalizeBaseUrlSuffix(suffix: string | undefined) {\n if (!suffix) return ''\n const trimmed =\n suffix.endsWith('/') && suffix.length > 1 ? suffix.slice(0, -1) : suffix\n return trimmed.startsWith('/') ? trimmed : `/${trimmed}`\n}\n\ntype DocsDocumentProps = {\n assetBase: string\n docsBase: string\n cspNonce?: string\n}\n\nexport const DocsDocument = ({\n assetBase,\n docsBase,\n cspNonce,\n}: DocsDocumentProps) => {\n const cssHref = `${assetBase}/docs.css`\n const jsSrc = `${assetBase}/docs.js`\n const configJson = serializeConfig({\n docsBasePath: docsBase,\n cspNonce,\n })\n\n return (\n <html lang=\"en\">\n <head>\n <meta charSet=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>API Reference</title>\n <link rel=\"stylesheet\" href={cssHref} />\n </head>\n <body>\n <div id=\"docs-root\"></div>\n <script\n id=\"docs-config\"\n type=\"application/json\"\n nonce={cspNonce}\n dangerouslySetInnerHTML={{ __html: configJson }}\n />\n <script type=\"module\" src={jsSrc} nonce={cspNonce} />\n </body>\n </html>\n )\n}\n\nfunction serializeLeaves(leaves: AnyLeafLowProfile[]) {\n return JSON.stringify(leaves.map(serializeLeaf)).replace(/<\\//g, '<\\\\/')\n}\n\ntype DocsConfig = {\n docsBasePath: string\n baseUrlSuffix?: string\n cspNonce?: string\n}\n\nfunction serializeConfig(config: DocsConfig) {\n return JSON.stringify(config).replace(/<\\//g, '<\\\\/')\n}\n\nexport function createLeafDocsDocument(\n options: RenderOptions = {},\n): ReactElement {\n const assetBase = normalizeBase(options.assetBasePath ?? DEFAULT_ASSET_BASE)\n\n const docsBase = normalizeDocsBase(options.docsBasePath)\n\n return (\n <DocsDocument\n assetBase={assetBase}\n docsBase={docsBase}\n cspNonce={options.cspNonce}\n />\n )\n}\n\nexport function renderLeafDocsHTML(options: RenderOptions = {}): string {\n const doc = createLeafDocsDocument(options)\n const html = renderToStaticMarkup(doc)\n return `<!DOCTYPE html>${html}`\n}\n\nexport type SerializableHistoryEntry = {\n id?: string\n timestamp: number\n method: string\n path: string\n fullUrl: string\n params?: Record<string, string>\n query?: Record<string, string>\n body?: string\n output?: string\n status?: number\n durationMs: number\n error?: string\n}\n","// serializer.ts\nimport {\n MethodCfgLowProfile,\n routeSchemaParse,\n type AnyLeafLowProfile,\n} from '@emeryld/rrroutes-contract'\nimport { MethodType } from '../web/v2/types/types.base.js'\nimport type { EndpointType } from '../web/v2/types/types.endpoint.js'\nimport { introspectSchema } from './schemaIntrospection.js'\n\nexport type SerializedLeaf = EndpointType\n\nexport type { SerializableSchemaNode } from './schemaIntrospection.js'\n\nexport function serializeLeaf(leaf: AnyLeafLowProfile): EndpointType {\n const cfg = leaf.cfg\n\n const tags = Array.isArray(cfg.tags) ? cfg.tags.slice() : []\n const stability = (cfg.stability ??\n 'experimental') as EndpointType['stability']\n const now = Date.now()\n\n return {\n id: buildLeafId(leaf),\n name: inferName(cfg, leaf.path),\n description: cfg.description,\n groupId: cfg.docsGroup,\n tags: tags.length > 0 ? tags : undefined,\n createdAt: now,\n updatedAt: now,\n method: leaf.method as MethodType,\n path: leaf.path,\n contract: {\n body: serializeContractSchema(cfg.bodySchema),\n query: serializeContractSchema(cfg.querySchema),\n params: serializeContractSchema(cfg.paramsSchema),\n output: serializeContractSchema(cfg.outputSchema),\n bodyFiles: serializeBodyFiles(cfg),\n },\n feed: cfg.feed ?? undefined,\n summary: cfg.summary,\n stability,\n hidden: cfg.docsHidden,\n meta: serializeMeta(cfg.docsMeta),\n }\n}\n\nfunction serializeContractSchema(schema: MethodCfgLowProfile['bodySchema']) {\n return schema ? introspectSchema(routeSchemaParse(schema)) : undefined\n}\n\nfunction serializeBodyFiles(cfg: MethodCfgLowProfile) {\n if (!Array.isArray(cfg.bodyFiles) || cfg.bodyFiles.length === 0)\n return undefined\n return cfg.bodyFiles.map(({ name, maxCount }) => ({ name, maxCount }))\n}\n\nfunction serializeMeta(meta?: Record<string, unknown>): Record<string, string> {\n if (!meta) return {}\n const entries = Object.entries(meta)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => [\n key,\n typeof value === 'string' ? value : JSON.stringify(value),\n ])\n return Object.fromEntries(entries)\n}\n\nfunction buildLeafId(leaf: AnyLeafLowProfile) {\n return `${leaf.method.toUpperCase()} ${leaf.path}`\n}\n\nfunction inferName(cfg: MethodCfgLowProfile, path: string) {\n return cfg.summary || cfg.description || path\n}\n","// schemaIntrospection.ts\nimport * as z from 'zod'\nimport type { SerializableSchema } from '../web/v2/types/types.endpoint.js'\n\nexport type SerializableSchemaNode = SerializableSchema\n\ntype ZodAny = z.ZodTypeAny\n\n/**\n * Zod 3 uses `schema._def`, Zod 4 uses `schema._zod.def`.\n */\nfunction getDef(schema: unknown): any | undefined {\n if (!schema || typeof schema !== 'object') return undefined\n const anySchema = schema as any\n return anySchema._zod?.def ?? anySchema._def\n}\n\n/**\n * Try to get a human-readable description.\n * Zod 4: use metadata/registry; fallback to internal def.description.\n * Zod 3: only internal def.description exists.\n */\nfunction getDescription(schema: ZodAny): string | undefined {\n const anyZ: any = z as any\n\n // Zod 4 global registry metadata, if present\n const registry = anyZ.globalRegistry?.get\n ? anyZ.globalRegistry.get(schema)\n : undefined\n if (registry && typeof registry.description === 'string') {\n return registry.description\n }\n\n // Legacy / internal description\n const def = getDef(schema)\n if (def && typeof def.description === 'string') {\n return def.description\n }\n\n return undefined\n}\n\n/**\n * Peel off wrappers (effects, optional, nullable, default) and\n * return the inner schema + flags.\n *\n * Supports:\n * - Zod 3: ZodEffects, ZodOptional, ZodNullable, ZodDefault\n * - Zod 4: ZodOptional, ZodNullable, ZodDefault\n */\nfunction unwrap(schema: ZodAny): {\n base: ZodAny\n optional: boolean\n nullable: boolean\n} {\n let s: ZodAny = schema\n let optional = false\n let nullable = false\n\n // Zod 3 only (undefined in Zod 4)\n const ZodEffectsCtor: any = (z as any).ZodEffects\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n // Zod 3: ZodEffects wrapper\n if (ZodEffectsCtor && s instanceof ZodEffectsCtor) {\n const def = getDef(s) || {}\n const sourceType =\n typeof (s as any).sourceType === 'function'\n ? (s as any).sourceType()\n : def.schema\n if (!sourceType) break\n s = sourceType\n continue\n }\n\n // Zod 3 + 4: optional/nullable/default wrappers\n if (s instanceof z.ZodOptional) {\n optional = true\n const def = getDef(s)\n s = (def && def.innerType) || s // innerType exists in both 3 & 4\n continue\n }\n\n if (s instanceof z.ZodNullable) {\n nullable = true\n const def = getDef(s)\n s = (def && def.innerType) || s\n continue\n }\n\n if (s instanceof z.ZodDefault) {\n const def = getDef(s)\n s = (def && def.innerType) || s\n continue\n }\n\n break\n }\n\n return { base: s, optional, nullable }\n}\n\nexport function introspectSchema(\n schema: ZodAny | undefined,\n): SerializableSchema | undefined {\n if (!schema) return undefined\n\n const { base, optional, nullable } = unwrap(schema)\n const def = getDef(base)\n\n const node: SerializableSchema = {\n kind: inferKind(base),\n optional: optional || undefined,\n nullable: nullable || undefined,\n description: getDescription(base),\n }\n\n // OBJECT\n if (base instanceof z.ZodObject) {\n // Zod 3: _def.shape() (function)\n // Zod 4: .shape getter returns an object\n const rawShape: any =\n (base as any).shape ??\n (def && typeof def.shape === 'function' ? def.shape() : def?.shape)\n\n const shape = typeof rawShape === 'function' ? rawShape() : (rawShape ?? {})\n\n const props: Record<string, SerializableSchema> = {}\n for (const key of Object.keys(shape)) {\n const child = shape[key] as ZodAny\n const childNode = introspectSchema(child)\n if (childNode) props[key] = childNode\n }\n node.properties = props\n }\n\n // ARRAY\n if (base instanceof z.ZodArray) {\n // Zod 3: def.type is inner schema\n // Zod 4: def.element is inner schema\n const inner =\n (def && (def.element as ZodAny)) ||\n (def && (def.type as ZodAny)) ||\n undefined\n if (inner) {\n node.element = introspectSchema(inner)\n }\n }\n\n // UNION\n if (base instanceof z.ZodUnion) {\n const options: ZodAny[] = (def && def.options) || []\n node.union = options\n .map((opt) => introspectSchema(opt))\n .filter(Boolean) as SerializableSchema[]\n }\n\n // LITERAL\n if (base instanceof z.ZodLiteral) {\n if (def) {\n // Zod 4: def.values (multi-literal)\n if (Array.isArray(def.values)) {\n node.literal =\n def.values.length === 1 ? def.values[0] : def.values.slice()\n } else {\n // Zod 3: def.value\n node.literal = def.value\n }\n }\n }\n\n // ENUM\n if (base instanceof z.ZodEnum) {\n if (def) {\n if (Array.isArray(def.values)) {\n // Zod 3\n node.enumValues = def.values.slice()\n } else if (def.entries && typeof def.entries === 'object') {\n // Zod 4: entries is a { key: value } map\n node.enumValues = Object.values(def.entries).map((v: unknown) =>\n String(v),\n )\n }\n }\n }\n\n return node\n}\n\nfunction inferKind(schema: ZodAny): SerializableSchema['kind'] {\n // This path still uses instanceof; it works with Zod 4 Classic\n // (importing from \"zod\"). Anything unknown falls back to \"unknown\".\n if (schema instanceof z.ZodString) return 'string'\n if (schema instanceof z.ZodNumber) return 'number'\n if (schema instanceof z.ZodBoolean) return 'boolean'\n if (schema instanceof z.ZodBigInt) return 'bigint'\n if (schema instanceof z.ZodDate) return 'date'\n if (schema instanceof z.ZodArray) return 'array'\n if (schema instanceof z.ZodObject) return 'object'\n if (schema instanceof z.ZodUnion) return 'union'\n if (schema instanceof z.ZodLiteral) return 'literal'\n if (schema instanceof z.ZodEnum) return 'enum'\n if (schema instanceof z.ZodRecord) return 'record'\n if (schema instanceof z.ZodTuple) return 'tuple'\n if (schema instanceof z.ZodUnknown) return 'unknown'\n if (schema instanceof z.ZodAny) return 'any'\n\n return 'unknown'\n}\n","// renderLeafDocsHTML.ts\nimport {\n renderLeafDocsHTML as LeafDocsPage,\n RenderOptions,\n} from './LeafDocsPage.js'\n\nexport function renderLeafDocsHTML(options: RenderOptions = {}): string {\n return LeafDocsPage(options)\n}\n\nexport { createLeafDocsDocument } from './LeafDocsPage.js'\nexport type { RenderOptions } from './LeafDocsPage.js'\n","import type { Request, RequestHandler, Response } from 'express'\nimport net from 'node:net'\n\n/**\n * HTTP Basic password guard.\n */\nexport function createPasswordGuard(\n password: string,\n realm: string,\n): RequestHandler {\n const trimmed = password.trim()\n return (req: Request, res: Response, next: () => void) => {\n const provided = extractPassword(req.headers.authorization)\n if (provided && provided === trimmed) {\n return next()\n }\n applyDocsSecurityHeaders(res)\n res.setHeader('WWW-Authenticate', `Basic realm=\"${realm}\"`)\n res\n .status(401)\n .send(\n renderAuthErrorPage(\n 'Docs are password protected. Provide the configured password.',\n ),\n )\n }\n}\n/**\n * Cookie-based guard. Requires `req.cookies` to be populated\n * (e.g. via `cookie-parser`).\n */\nexport function createCookieGuard(\n cookieName: string,\n cookieSecret?: string,\n): RequestHandler {\n return (req: Request, res: Response, next: () => void) => {\n const cookies = (req as any).cookies as Record<string, string> | undefined\n const value = cookies?.[cookieName]\n\n const valid = cookieSecret ? value === cookieSecret : Boolean(value)\n\n if (valid) {\n return next()\n }\n\n applyDocsSecurityHeaders(res)\n res\n .status(401)\n .send(\n renderAuthErrorPage(\n 'Docs are protected. You must be authenticated to access this page.',\n ),\n )\n }\n}\n/**\n * When auth is enabled but no password/cookie/custom guard is provided,\n * fail closed.\n */\nexport function createMissingPasswordGuard(): RequestHandler {\n return (_req: Request, res: Response) => {\n applyDocsSecurityHeaders(res)\n res\n .status(500)\n .send(renderAuthErrorPage('Provide auth configuration to mounted docs'))\n }\n}\n/**\n * Extract password from HTTP Basic Authorization header.\n */\nfunction extractPassword(authHeader: string | string[] | undefined) {\n if (!authHeader) return undefined\n const header = Array.isArray(authHeader) ? authHeader[0] : authHeader\n if (typeof header !== 'string' || !header.startsWith('Basic '))\n return undefined\n const token = header.slice('Basic '.length)\n try {\n const decoded = Buffer.from(token, 'base64').toString('utf8')\n const parts = decoded.split(':')\n parts.shift() // username\n return parts.join(':')\n } catch {\n return undefined\n }\n}\n/**\n * Simple IP allow-list guard. For accurate client IPs behind proxies,\n * configure `app.set('trust proxy', true)` in your Express app.\n */\nexport function createIpAllowListGuard(allowed: string[]): RequestHandler {\n const ranges = allowed\n .map((raw) => raw.trim())\n .filter(Boolean)\n .map(parseIpPattern)\n .filter((r): r is IpRange => r !== null)\n\n return (req: Request, res: Response, next: () => void) => {\n const rawIp =\n req.ip || (req.connection && (req.connection as any).remoteAddress) || ''\n const ip = normalizeIp(rawIp)\n\n if (!ip || !isIpAllowed(ip, ranges)) {\n applyDocsSecurityHeaders(res)\n res\n .status(403)\n .send(\n renderAuthErrorPage(\n 'Access to docs is restricted from this IP address.',\n ),\n )\n return\n }\n\n next()\n }\n}\ntype IpRange =\n | { kind: 'exact'; value: string }\n | { kind: 'cidr'; base: number; mask: number }\n/**\n * Normalize typical Express IP formats, including IPv4-mapped IPv6.\n */\nfunction normalizeIp(ip: string): string {\n if (!ip) return ''\n if (ip.startsWith('::ffff:')) return ip.slice(7)\n if (ip === '::1') return '127.0.0.1'\n return ip\n}\nfunction parseIpPattern(raw: string): IpRange | null {\n if (raw.includes('/')) {\n const cidr = parseCidr(raw)\n if (!cidr) return null\n return { kind: 'cidr', base: cidr.base, mask: cidr.mask }\n }\n\n // Exact string match (IPv4 or IPv6).\n return { kind: 'exact', value: normalizeIp(raw) }\n}\nfunction parseCidr(raw: string): { base: number; mask: number } | null {\n const [baseIp, bitsStr] = raw.split('/')\n const bits = Number(bitsStr)\n if (!Number.isInteger(bits) || bits < 0 || bits > 32) return null\n if (net.isIP(baseIp) !== 4) return null // IPv4 CIDR only for simplicity\n\n const baseLong = ipToLong(baseIp)\n if (baseLong == null) return null\n\n const mask = bits === 0 ? 0 : (~0 << (32 - bits)) >>> 0\n return { base: (baseLong & mask) >>> 0, mask }\n}\nfunction ipToLong(ip: string): number | null {\n const parts = ip.split('.').map((n) => Number(n))\n if (parts.length !== 4) return null\n if (parts.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) return null\n return (\n ((parts[0] << 24) >>> 0) +\n ((parts[1] << 16) >>> 0) +\n ((parts[2] << 8) >>> 0) +\n parts[3]\n )\n}\nfunction isIpAllowed(ip: string, ranges: IpRange[]): boolean {\n const ipv4 = net.isIP(ip) === 4 ? ipToLong(ip) : null\n\n for (const r of ranges) {\n if (r.kind === 'exact') {\n if (ip === r.value) return true\n } else if (r.kind === 'cidr' && ipv4 != null) {\n if ((ipv4 & r.mask) === r.base) return true\n }\n }\n\n return false\n}\nfunction renderAuthErrorPage(message: string) {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>RRRoutes docs locked</title>\n <style>\n body { margin:0; font-family: system-ui, -apple-system, Segoe UI, sans-serif; background: #0f172a; color: #e2e8f0; display:flex; align-items:center; justify-content:center; min-height:100vh; }\n .card { padding:32px; border:1px solid #1e293b; border-radius:12px; max-width:420px; background: rgba(15,23,42,0.8); box-shadow:0 15px 45px rgba(0,0,0,0.35); }\n h1 { margin:0 0 12px; font-size:22px; }\n p { margin:0; line-height:1.5; color:#cbd5e1; }\n code { background: rgba(226,232,240,0.1); padding: 2px 4px; border-radius: 4px; }\n </style>\n</head>\n<body>\n <div class=\"card\">\n <h1>Docs locked</h1>\n <p>${message}</p>\n </div>\n</body>\n</html>`\n}\nexport function applyDocsSecurityHeaders(res: Response) {\n res.setHeader('X-Content-Type-Options', 'nosniff')\n res.setHeader('Referrer-Policy', 'same-origin')\n res.setHeader('X-Frame-Options', 'SAMEORIGIN')\n res.setHeader('Cache-Control', 'no-store')\n res.setHeader(\n 'Strict-Transport-Security',\n 'max-age=31536000; includeSubDomains',\n )\n}\n","import {\n AnyLeafLowProfile,\n AugmentLeaves,\n FinalizedRegistry,\n finalize,\n resource,\n} from '@emeryld/rrroutes-contract'\nimport { cacheLeaves } from './types.cacheLog.js'\nimport { endpointLeaves } from './types.endpoint.js'\nimport { logLeaves } from './types.log.js'\nimport { presetLeaves } from './types.preset.js'\nimport { requestLogLeaves } from './types.requestLog.js'\n\ntype MountedLeaves<Leaves extends readonly AnyLeafLowProfile[]> = AugmentLeaves<\n '/__rrroutes',\n undefined,\n Leaves\n>\ntype AllLeaves = readonly [\n ...MountedLeaves<typeof endpointLeaves>,\n ...MountedLeaves<typeof requestLogLeaves>,\n ...MountedLeaves<typeof logLeaves>,\n ...MountedLeaves<typeof cacheLeaves>,\n ...MountedLeaves<typeof presetLeaves>,\n]\n\nconst allLeaves: AllLeaves = resource()\n .sub(\n resource('/__rrroutes')\n .sub(\n endpointLeaves,\n requestLogLeaves,\n logLeaves,\n cacheLeaves,\n presetLeaves,\n )\n .done(),\n )\n .done()\n\nexport const leaves: FinalizedRegistry<typeof allLeaves> = finalize(allLeaves)\n// TODO: Fix query: if it is an array but you only provide one value, it breaks. Assumes its a string on the server side.\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport {\n baseEntitySchema,\n baseQuerySchema,\n paginationSchema,\n} from './types.base'\n\nconst operationEnum = z.enum(['hit', 'miss', 'set', 'delete'])\nexport const cacheLogSchema = baseEntitySchema.extend({\n operation: operationEnum,\n // on hit, value = value retrieved\n // on miss, value = null\n // on set, value = value set\n // on delete, value = value deleted\n value: z.any().nullable(),\n size: z.number().optional(),\n})\n\nexport type CacheLogType = z.infer<typeof cacheLogSchema>\n\nexport const cacheLogQuerySchema = baseQuerySchema.extend({\n operations: operationEnum.array().optional(),\n excludeOperations: operationEnum.array().optional(),\n})\n\nexport const cacheSummarySchema = z.object({\n key: z.string(),\n lastSetAt: z.number().nullable(),\n lastHitAt: z.number().nullable(),\n lastMissAt: z.number().nullable(),\n totalHits: z.number(),\n totalMisses: z.number(),\n totalSets: z.number(),\n})\n\nexport type CacheSummaryType = z.infer<typeof cacheSummarySchema>\n\nexport const cacheLeaves = resource('cache')\n .get({\n feed: true,\n outputSchema: cacheLogSchema.array(),\n querySchema: cacheLogQuerySchema,\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n queryExtensionSchema: paginationSchema,\n })\n .sub(\n resource('clear')\n .post({\n outputSchema: z.object({ success: z.boolean() }),\n querySchema: cacheLogQuerySchema,\n })\n .done(),\n )\n .done()\n","import z from 'zod'\n\nexport const METHODS = ['get', 'post', 'put', 'patch', 'delete'] as const\nexport type MethodType = (typeof METHODS)[number]\nexport const methodSchema = z.enum(METHODS)\nexport const baseEntitySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().optional(),\n groupId: z.string().optional(),\n tags: z.string().array().optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n})\n\nexport const baseQuerySchema = z.object({\n beforeDate: z.string().optional(),\n afterDate: z.string().optional(),\n orderBy: z\n .enum(['timestamp', 'duration', 'level', 'path'])\n .default('timestamp'),\n orderDirection: z.enum(['asc', 'desc']).default('desc'),\n searchQuery: z.string().optional(),\n groups: z.string().array().optional(),\n excludeGroups: z.string().array().optional(),\n tags: z.string().array().optional(),\n excludeTags: z.string().array().optional(),\n cursor: z.string().optional(),\n})\n\nexport const paginationSchema = z.object({\n cursor: z.string().optional(),\n pageSize: z.number().optional(),\n})\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z, { ZodType } from 'zod'\nimport {\n baseEntitySchema,\n baseQuerySchema,\n methodSchema,\n paginationSchema,\n} from './types.base'\nimport { requestSchema } from './types.requestLog'\n\nexport const nodeKind = [\n 'object',\n 'string',\n 'number',\n 'boolean',\n 'bigint',\n 'date',\n 'array',\n 'enum',\n 'literal',\n 'union',\n 'record',\n 'tuple',\n 'unknown',\n 'any',\n] as const\n\nexport type SerializableSchema = {\n kind: (typeof nodeKind)[number]\n optional?: boolean\n nullable?: boolean\n description?: string\n\n // object\n properties?: Record<string, SerializableSchema>\n // array\n element?: SerializableSchema\n // union\n union?: SerializableSchema[]\n // literal\n literal?: unknown\n // enum\n enumValues?: string[]\n}\n\n// The Zod schema\nexport const serializableSchemaSchema: ZodType<\n SerializableSchema,\n SerializableSchema\n> = z.lazy(() =>\n z.object({\n kind: z.enum(nodeKind),\n\n optional: z.boolean().optional(),\n nullable: z.boolean().optional(),\n description: z.string().optional(),\n\n // object\n properties: z\n .record(z.string(), serializableSchemaSchema) // Record<string, SerializableSchemaNode>\n .optional(),\n\n // array\n element: serializableSchemaSchema.optional(),\n\n // union\n union: z.array(serializableSchemaSchema).optional(),\n\n // literal\n literal: z.unknown().optional(),\n\n // enum\n enumValues: z.array(z.string()).optional(),\n }),\n)\n\nexport const STABILITIES = [\n 'experimental',\n 'beta',\n 'stable',\n 'deprecated',\n] as const\nconst stabilityEnum = z.enum(STABILITIES)\nexport const endpointSchema = baseEntitySchema.extend({\n method: methodSchema,\n path: z.string(),\n contract: z.object({\n body: serializableSchemaSchema.optional(),\n query: serializableSchemaSchema.optional(),\n output: serializableSchemaSchema.optional(),\n params: serializableSchemaSchema.optional(),\n bodyFiles: z\n .array(z.object({ name: z.string(), maxCount: z.number() }))\n .optional(),\n }),\n feed: z.boolean().optional(),\n summary: z.string().optional(),\n stability: stabilityEnum,\n hidden: z.boolean().optional(),\n meta: z.record(z.string(), z.string()),\n implemented: z.boolean().optional(),\n})\n\nexport type EndpointType = z.output<typeof endpointSchema>\n\nexport const endpointFilterSchema = baseQuerySchema.extend({\n methods: methodSchema.array().optional(),\n excludeMethods: methodSchema.array().optional(),\n path: z.string().optional(),\n stability: stabilityEnum.array().optional(),\n excludeStability: stabilityEnum.array().optional(),\n})\n\nexport const endpointLeaves = resource('endpoints')\n .get({\n feed: true,\n querySchema: endpointFilterSchema,\n outputSchema: endpointSchema.array(),\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n queryExtensionSchema: paginationSchema,\n })\n .sub(\n resource(':endpointId', undefined, z.string())\n .get({\n outputSchema: endpointSchema.extend({\n // Related by groupId. Just use the existing feed endpoints with filter: groupId=?\n requests: z.array(requestSchema),\n // Summary stats: return with the feed?\n volumeTS: z.array(\n z.object({\n timestamp: z.number(),\n count: z.number(),\n }),\n ),\n averageDurationMs: z.number(),\n successRate: z.number(),\n // Add id as query param to the existing feed endpoints? This way \"requests\" field can also be only Ids\n latestErrorRequestIds: z.array(z.string()),\n }),\n })\n .done(),\n )\n .done()\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport {\n baseEntitySchema,\n baseQuerySchema,\n methodSchema,\n paginationSchema,\n} from './types.base'\nimport { cacheLogSchema } from './types.cacheLog'\nimport { logSchema } from './types.log'\n\nexport const requestSchema = baseEntitySchema.extend({\n status: z.number(),\n body: z.any().optional(),\n fullUrl: z.string(),\n path: z.string(),\n method: methodSchema,\n query: z.record(z.string(), z.any()).optional(),\n params: z.record(z.string(), z.any()).optional(),\n output: z.any().optional(),\n headers: z.record(z.string(), z.any()).optional(),\n error: z.string().optional(),\n durationMs: z.number(),\n ip: z.string().optional(),\n userAgent: z.string().optional(),\n})\n\nexport type RequestLogType = z.infer<typeof requestSchema>\n\nexport const requestQuerySchema = baseQuerySchema.extend({\n methods: methodSchema.array().default([]),\n excludeMethods: methodSchema.array().optional(),\n statuses: z.coerce.number().array().default([]),\n excludeStatuses: z.coerce.number().array().optional(),\n path: z.string().optional(),\n endpointKey: z.string().optional(),\n excludeEndpointKey: z.string().optional(),\n})\n\nexport const requestLogLeaves = resource('requests')\n .get({\n feed: true,\n outputSchema: requestSchema.array(),\n querySchema: requestQuerySchema,\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n queryExtensionSchema: paginationSchema,\n })\n .sub(\n resource(':requestId', undefined, z.string())\n .get({\n outputSchema: requestSchema.extend({\n // Related by groupId\n // Do I just use the existing feed endpoints with filter: groupId=?\n logs: z.array(logSchema),\n caches: z.array(cacheLogSchema),\n }),\n })\n .done(),\n )\n .done()\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport {\n baseEntitySchema,\n baseQuerySchema,\n paginationSchema,\n} from './types.base'\n\nconst levelSchema = z.enum(['info', 'warning', 'error', 'debug', 'trace'])\nexport const logSchema = baseEntitySchema.extend({\n level: levelSchema,\n meta: z.json(),\n})\n\nexport type LogType = z.infer<typeof logSchema>\nexport const logQuerySchema = baseQuerySchema.extend({\n level: levelSchema.array().optional(),\n excludeLevel: levelSchema.array().optional(),\n})\n\nexport const logLeaves = resource('logs')\n .get({\n feed: true,\n outputSchema: logSchema.array(),\n querySchema: logQuerySchema,\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n queryExtensionSchema: paginationSchema,\n })\n .done()\n","import { resource } from '@emeryld/rrroutes-contract'\nimport z from 'zod'\nimport {\n baseEntitySchema,\n baseQuerySchema,\n methodSchema,\n paginationSchema,\n} from './types.base'\n\nconst presetSchema = baseEntitySchema.extend({\n operations: z.array(\n z.object({\n name: z.string(),\n stepNumber: z.number(),\n endpointId: z.string().optional(),\n method: methodSchema,\n path: z.string(),\n body: z.json().optional(),\n extraHeaders: z.record(z.string(), z.any()).optional(),\n query: z.record(z.string(), z.any()).optional(),\n }),\n ),\n})\nexport type PresetType = z.infer<typeof presetSchema>\n\nconst presetQuerySchema = baseQuerySchema.extend({\n name: z.string().optional(),\n excludeName: z.string().optional(),\n})\n\nexport const presetLeaves = resource('presets')\n .get({\n feed: true,\n querySchema: presetQuerySchema,\n outputMetaSchema: z.object({\n totalCount: z.number().optional(),\n }),\n outputSchema: presetSchema.array(),\n queryExtensionSchema: paginationSchema,\n })\n .post({\n bodySchema: presetSchema,\n outputSchema: presetSchema,\n })\n .put({\n bodySchema: presetSchema,\n outputSchema: presetSchema,\n })\n .done()\n"],"mappings":"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","names":["path","renderLeafDocsHTML","resource","z","z","z","resource","z","resource","z","resource","z","z","resource","z","resource","z","resource","resource","z","z","resource","resource","renderLeafDocsHTML"]}
|