@emeryld/rrroutes-contract 2.7.0 → 2.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -0
- package/dist/export/exportFinalizedLeaves.cli.d.ts +12 -0
- package/dist/export/exportFinalizedLeaves.d.ts +42 -0
- package/dist/export/flattenSchema.d.ts +11 -0
- package/dist/export/index.d.ts +5 -0
- package/dist/export/schemaIntrospection.d.ts +47 -0
- package/dist/export/serializeLeafContract.d.ts +31 -0
- package/dist/index.cjs +602 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +577 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -22,19 +32,33 @@ var index_exports = {};
|
|
|
22
32
|
__export(index_exports, {
|
|
23
33
|
buildCacheKey: () => buildCacheKey,
|
|
24
34
|
buildLowProfileLeaf: () => buildLowProfileLeaf,
|
|
35
|
+
clearSchemaIntrospectionHandlers: () => clearSchemaIntrospectionHandlers,
|
|
25
36
|
collectNestedFieldSuggestions: () => collectNestedFieldSuggestions,
|
|
26
37
|
compilePath: () => compilePath,
|
|
38
|
+
createSchemaIntrospector: () => createSchemaIntrospector,
|
|
27
39
|
defineSocketEvents: () => defineSocketEvents,
|
|
40
|
+
exportFinalizedLeaves: () => exportFinalizedLeaves,
|
|
28
41
|
finalize: () => finalize,
|
|
42
|
+
flattenLeafSchemas: () => flattenLeafSchemas,
|
|
43
|
+
flattenSerializableSchema: () => flattenSerializableSchema,
|
|
29
44
|
getZodShape: () => getZodShape,
|
|
45
|
+
introspectSchema: () => introspectSchema,
|
|
30
46
|
keyOf: () => keyOf,
|
|
47
|
+
loadFinalizedLeavesInput: () => loadFinalizedLeavesInput,
|
|
31
48
|
lowProfileParse: () => lowProfileParse,
|
|
32
49
|
lowProfileSafeParse: () => lowProfileSafeParse,
|
|
33
50
|
mergeArrays: () => mergeArrays,
|
|
34
51
|
mergeSchemas: () => mergeSchemas,
|
|
52
|
+
parseFinalizedLeavesCliArgs: () => parseFinalizedLeavesCliArgs,
|
|
53
|
+
registerSchemaIntrospectionHandler: () => registerSchemaIntrospectionHandler,
|
|
35
54
|
resource: () => resource,
|
|
36
55
|
routeSchemaParse: () => routeSchemaParse,
|
|
37
|
-
|
|
56
|
+
runExportFinalizedLeavesCli: () => runExportFinalizedLeavesCli,
|
|
57
|
+
serializableSchemaKinds: () => serializableSchemaKinds,
|
|
58
|
+
serializeLeafContract: () => serializeLeafContract,
|
|
59
|
+
serializeLeavesContract: () => serializeLeavesContract,
|
|
60
|
+
staticBase: () => staticBase,
|
|
61
|
+
writeFinalizedLeavesExport: () => writeFinalizedLeavesExport
|
|
38
62
|
});
|
|
39
63
|
module.exports = __toCommonJS(index_exports);
|
|
40
64
|
|
|
@@ -82,9 +106,9 @@ function collectNestedFieldSuggestions(shape, prefix = []) {
|
|
|
82
106
|
}
|
|
83
107
|
return suggestions;
|
|
84
108
|
}
|
|
85
|
-
function compilePath(
|
|
86
|
-
if (!params) return
|
|
87
|
-
const withParams =
|
|
109
|
+
function compilePath(path3, params) {
|
|
110
|
+
if (!params) return path3;
|
|
111
|
+
const withParams = path3.replace(/:([A-Za-z0-9_]+)/g, (_, k) => {
|
|
88
112
|
const v = params[k];
|
|
89
113
|
if (v === void 0 || v === null) throw new Error(`Missing param :${k}`);
|
|
90
114
|
return String(v);
|
|
@@ -159,8 +183,8 @@ function buildLowProfileLeaf(leaf) {
|
|
|
159
183
|
}
|
|
160
184
|
};
|
|
161
185
|
}
|
|
162
|
-
var keyOf = (method,
|
|
163
|
-
const key = `${method.toUpperCase()} ${
|
|
186
|
+
var keyOf = (method, path3, encodeSafe) => {
|
|
187
|
+
const key = `${method.toUpperCase()} ${path3}`;
|
|
164
188
|
return encodeSafe ? encodeURIComponent(key) : key;
|
|
165
189
|
};
|
|
166
190
|
|
|
@@ -336,8 +360,8 @@ function joinPaths(parent, child) {
|
|
|
336
360
|
if (!trimmedChild) return trimmedParent;
|
|
337
361
|
return `${trimmedParent}/${trimmedChild}`;
|
|
338
362
|
}
|
|
339
|
-
function assertDynamicLayerUniqueness(
|
|
340
|
-
const segments =
|
|
363
|
+
function assertDynamicLayerUniqueness(path3, dynamicLayerMap) {
|
|
364
|
+
const segments = path3.split("/").filter(Boolean);
|
|
341
365
|
if (segments.length === 0) return;
|
|
342
366
|
for (let i = 0; i < segments.length; i++) {
|
|
343
367
|
const segment = segments[i];
|
|
@@ -375,22 +399,591 @@ function finalize(leaves) {
|
|
|
375
399
|
function defineSocketEvents(config, events) {
|
|
376
400
|
return { config, events };
|
|
377
401
|
}
|
|
402
|
+
|
|
403
|
+
// src/export/schemaIntrospection.ts
|
|
404
|
+
var z3 = __toESM(require("zod"), 1);
|
|
405
|
+
var serializableSchemaKinds = [
|
|
406
|
+
"object",
|
|
407
|
+
"string",
|
|
408
|
+
"number",
|
|
409
|
+
"boolean",
|
|
410
|
+
"bigint",
|
|
411
|
+
"date",
|
|
412
|
+
"array",
|
|
413
|
+
"enum",
|
|
414
|
+
"literal",
|
|
415
|
+
"union",
|
|
416
|
+
"record",
|
|
417
|
+
"tuple",
|
|
418
|
+
"unknown",
|
|
419
|
+
"any"
|
|
420
|
+
];
|
|
421
|
+
var globalHandlers = {};
|
|
422
|
+
function registerSchemaIntrospectionHandler(kind, handler) {
|
|
423
|
+
globalHandlers[kind] = handler;
|
|
424
|
+
}
|
|
425
|
+
function clearSchemaIntrospectionHandlers() {
|
|
426
|
+
for (const key of Object.keys(globalHandlers)) {
|
|
427
|
+
delete globalHandlers[key];
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
function getDef(schema) {
|
|
431
|
+
if (!schema || typeof schema !== "object") return void 0;
|
|
432
|
+
const anySchema = schema;
|
|
433
|
+
return anySchema._zod?.def ?? anySchema._def;
|
|
434
|
+
}
|
|
435
|
+
function getDescription(schema) {
|
|
436
|
+
const anyZ = z3;
|
|
437
|
+
const registry = anyZ.globalRegistry?.get ? anyZ.globalRegistry.get(schema) : void 0;
|
|
438
|
+
if (registry && typeof registry.description === "string") {
|
|
439
|
+
return registry.description;
|
|
440
|
+
}
|
|
441
|
+
const def = getDef(schema);
|
|
442
|
+
if (def && typeof def.description === "string") {
|
|
443
|
+
return def.description;
|
|
444
|
+
}
|
|
445
|
+
return void 0;
|
|
446
|
+
}
|
|
447
|
+
function unwrap(schema) {
|
|
448
|
+
let current = schema;
|
|
449
|
+
let optional = false;
|
|
450
|
+
let nullable = false;
|
|
451
|
+
const ZodEffectsCtor = z3.ZodEffects;
|
|
452
|
+
while (true) {
|
|
453
|
+
if (ZodEffectsCtor && current instanceof ZodEffectsCtor) {
|
|
454
|
+
const def = getDef(current) || {};
|
|
455
|
+
const sourceType = typeof current.sourceType === "function" ? current.sourceType() : def.schema;
|
|
456
|
+
if (!sourceType) break;
|
|
457
|
+
current = sourceType;
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
if (current instanceof z3.ZodOptional) {
|
|
461
|
+
optional = true;
|
|
462
|
+
const def = getDef(current);
|
|
463
|
+
current = def && def.innerType || current;
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
if (current instanceof z3.ZodNullable) {
|
|
467
|
+
nullable = true;
|
|
468
|
+
const def = getDef(current);
|
|
469
|
+
current = def && def.innerType || current;
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
if (current instanceof z3.ZodDefault) {
|
|
473
|
+
const def = getDef(current);
|
|
474
|
+
current = def && def.innerType || current;
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
return { base: current, optional, nullable };
|
|
480
|
+
}
|
|
481
|
+
function mergeProps(a, b) {
|
|
482
|
+
if (!a && !b) return void 0;
|
|
483
|
+
return { ...a ?? {}, ...b ?? {} };
|
|
484
|
+
}
|
|
485
|
+
function inferKind(schema) {
|
|
486
|
+
if (schema instanceof z3.ZodString) return "string";
|
|
487
|
+
if (schema instanceof z3.ZodNumber) return "number";
|
|
488
|
+
if (schema instanceof z3.ZodBoolean) return "boolean";
|
|
489
|
+
if (schema instanceof z3.ZodBigInt) return "bigint";
|
|
490
|
+
if (schema instanceof z3.ZodDate) return "date";
|
|
491
|
+
if (schema instanceof z3.ZodArray) return "array";
|
|
492
|
+
if (schema instanceof z3.ZodObject) return "object";
|
|
493
|
+
if (schema instanceof z3.ZodUnion) return "union";
|
|
494
|
+
if (schema instanceof z3.ZodLiteral) return "literal";
|
|
495
|
+
if (schema instanceof z3.ZodEnum) return "enum";
|
|
496
|
+
if (schema instanceof z3.ZodRecord) return "record";
|
|
497
|
+
if (schema instanceof z3.ZodTuple) return "tuple";
|
|
498
|
+
if (schema instanceof z3.ZodUnknown) return "unknown";
|
|
499
|
+
if (schema instanceof z3.ZodAny) return "any";
|
|
500
|
+
return "unknown";
|
|
501
|
+
}
|
|
502
|
+
var defaultHandlers = {
|
|
503
|
+
intersection({ base, def, node }, ctx) {
|
|
504
|
+
const left = def?.left;
|
|
505
|
+
const right = def?.right;
|
|
506
|
+
const leftNode = left ? ctx.introspect(left) : void 0;
|
|
507
|
+
const rightNode = right ? ctx.introspect(right) : void 0;
|
|
508
|
+
const leftIsObj = leftNode?.kind === "object" && !!leftNode.properties;
|
|
509
|
+
const rightIsObj = rightNode?.kind === "object" && !!rightNode.properties;
|
|
510
|
+
if (leftIsObj && rightIsObj) {
|
|
511
|
+
node.kind = "object";
|
|
512
|
+
node.description = node.description ?? leftNode.description ?? rightNode.description;
|
|
513
|
+
node.properties = mergeProps(leftNode.properties, rightNode.properties);
|
|
514
|
+
return node;
|
|
515
|
+
}
|
|
516
|
+
if (leftNode && rightNode) {
|
|
517
|
+
node.properties = {
|
|
518
|
+
left: leftNode,
|
|
519
|
+
right: rightNode
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
return node;
|
|
523
|
+
},
|
|
524
|
+
object({ base, def, node }, ctx) {
|
|
525
|
+
const rawShape = base.shape ?? (def && typeof def.shape === "function" ? def.shape() : def?.shape);
|
|
526
|
+
const shape = typeof rawShape === "function" ? rawShape() : rawShape ?? {};
|
|
527
|
+
const props = {};
|
|
528
|
+
for (const key of Object.keys(shape)) {
|
|
529
|
+
const child = shape[key];
|
|
530
|
+
const childNode = ctx.introspect(child);
|
|
531
|
+
if (childNode) props[key] = childNode;
|
|
532
|
+
}
|
|
533
|
+
node.properties = props;
|
|
534
|
+
return node;
|
|
535
|
+
},
|
|
536
|
+
array({ def, node }, ctx) {
|
|
537
|
+
const inner = def && def.element || def && def.type || void 0;
|
|
538
|
+
if (inner) {
|
|
539
|
+
node.element = ctx.introspect(inner);
|
|
540
|
+
}
|
|
541
|
+
return node;
|
|
542
|
+
},
|
|
543
|
+
union({ def, node }, ctx) {
|
|
544
|
+
const options = def && def.options || [];
|
|
545
|
+
node.union = options.map((opt) => ctx.introspect(opt)).filter(Boolean);
|
|
546
|
+
return node;
|
|
547
|
+
},
|
|
548
|
+
literal({ def, node }) {
|
|
549
|
+
if (def) {
|
|
550
|
+
if (Array.isArray(def.values)) {
|
|
551
|
+
node.literal = def.values.length === 1 ? def.values[0] : def.values.slice();
|
|
552
|
+
} else {
|
|
553
|
+
node.literal = def.value;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return node;
|
|
557
|
+
},
|
|
558
|
+
enum({ def, node }) {
|
|
559
|
+
if (def) {
|
|
560
|
+
if (Array.isArray(def.values)) {
|
|
561
|
+
node.enumValues = def.values.slice();
|
|
562
|
+
} else if (def.entries && typeof def.entries === "object") {
|
|
563
|
+
node.enumValues = Object.values(def.entries).map((v) => String(v));
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return node;
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
function createSchemaIntrospector(options = {}) {
|
|
570
|
+
const handlers = {
|
|
571
|
+
...defaultHandlers,
|
|
572
|
+
...globalHandlers,
|
|
573
|
+
...options.handlers ?? {}
|
|
574
|
+
};
|
|
575
|
+
const introspect = (schema) => {
|
|
576
|
+
if (!schema) return void 0;
|
|
577
|
+
const unwrapped = unwrap(schema);
|
|
578
|
+
const base = unwrapped.base;
|
|
579
|
+
const def = getDef(base);
|
|
580
|
+
const kind = base instanceof z3.ZodIntersection ? "intersection" : inferKind(base);
|
|
581
|
+
const node = {
|
|
582
|
+
kind: kind === "intersection" ? "unknown" : kind,
|
|
583
|
+
optional: unwrapped.optional || void 0,
|
|
584
|
+
nullable: unwrapped.nullable || void 0,
|
|
585
|
+
description: getDescription(base)
|
|
586
|
+
};
|
|
587
|
+
const handler = handlers[kind];
|
|
588
|
+
if (!handler) return node;
|
|
589
|
+
return handler(
|
|
590
|
+
{
|
|
591
|
+
schema,
|
|
592
|
+
base,
|
|
593
|
+
def,
|
|
594
|
+
kind,
|
|
595
|
+
optional: unwrapped.optional,
|
|
596
|
+
nullable: unwrapped.nullable,
|
|
597
|
+
node
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
zod: z3,
|
|
601
|
+
introspect,
|
|
602
|
+
getDef,
|
|
603
|
+
unwrap,
|
|
604
|
+
getDescription
|
|
605
|
+
}
|
|
606
|
+
);
|
|
607
|
+
};
|
|
608
|
+
return introspect;
|
|
609
|
+
}
|
|
610
|
+
function introspectSchema(schema, options = {}) {
|
|
611
|
+
const introspect = createSchemaIntrospector(options);
|
|
612
|
+
return introspect(schema);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// src/export/serializeLeafContract.ts
|
|
616
|
+
function serializeContractSchema(schema, options) {
|
|
617
|
+
return schema ? introspectSchema(routeSchemaParse(schema), options) : void 0;
|
|
618
|
+
}
|
|
619
|
+
function serializeBodyFiles(cfg) {
|
|
620
|
+
if (!Array.isArray(cfg.bodyFiles) || cfg.bodyFiles.length === 0) {
|
|
621
|
+
return void 0;
|
|
622
|
+
}
|
|
623
|
+
return cfg.bodyFiles.map(({ name, maxCount }) => ({ name, maxCount }));
|
|
624
|
+
}
|
|
625
|
+
function serializeLeafContract(leaf, options = {}) {
|
|
626
|
+
const cfg = leaf.cfg;
|
|
627
|
+
return {
|
|
628
|
+
key: `${leaf.method.toUpperCase()} ${leaf.path}`,
|
|
629
|
+
method: leaf.method,
|
|
630
|
+
path: leaf.path,
|
|
631
|
+
cfg: {
|
|
632
|
+
description: cfg.description,
|
|
633
|
+
summary: cfg.summary,
|
|
634
|
+
docsGroup: cfg.docsGroup,
|
|
635
|
+
tags: Array.isArray(cfg.tags) ? cfg.tags.slice() : void 0,
|
|
636
|
+
deprecated: cfg.deprecated,
|
|
637
|
+
stability: cfg.stability,
|
|
638
|
+
docsHidden: cfg.docsHidden,
|
|
639
|
+
docsMeta: cfg.docsMeta,
|
|
640
|
+
feed: cfg.feed,
|
|
641
|
+
bodyFiles: serializeBodyFiles(cfg),
|
|
642
|
+
schemas: {
|
|
643
|
+
body: serializeContractSchema(cfg.bodySchema, options),
|
|
644
|
+
query: serializeContractSchema(cfg.querySchema, options),
|
|
645
|
+
params: serializeContractSchema(cfg.paramsSchema, options),
|
|
646
|
+
output: serializeContractSchema(cfg.outputSchema, options),
|
|
647
|
+
outputMeta: serializeContractSchema(cfg.outputMetaSchema, options),
|
|
648
|
+
queryExtension: serializeContractSchema(cfg.queryExtensionSchema, options)
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
function serializeLeavesContract(leaves, options = {}) {
|
|
654
|
+
return leaves.map((leaf) => serializeLeafContract(leaf, options));
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/export/flattenSchema.ts
|
|
658
|
+
function normalizeType(schema) {
|
|
659
|
+
switch (schema.kind) {
|
|
660
|
+
case "string":
|
|
661
|
+
case "number":
|
|
662
|
+
case "date":
|
|
663
|
+
case "boolean":
|
|
664
|
+
case "object":
|
|
665
|
+
case "array":
|
|
666
|
+
return schema.kind;
|
|
667
|
+
case "enum": {
|
|
668
|
+
if (Array.isArray(schema.enumValues) && schema.enumValues.length > 0) {
|
|
669
|
+
return schema.enumValues.join("|");
|
|
670
|
+
}
|
|
671
|
+
return "unknown";
|
|
672
|
+
}
|
|
673
|
+
case "literal": {
|
|
674
|
+
const lit = schema.literal;
|
|
675
|
+
if (typeof lit === "string") return "string";
|
|
676
|
+
if (typeof lit === "number") return "number";
|
|
677
|
+
if (typeof lit === "boolean") return "boolean";
|
|
678
|
+
return "unknown";
|
|
679
|
+
}
|
|
680
|
+
default:
|
|
681
|
+
return "unknown";
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
function isNonEmptyPath(path3) {
|
|
685
|
+
return typeof path3 === "string" && path3.length > 0;
|
|
686
|
+
}
|
|
687
|
+
function setNode(out, path3, schema, inherited) {
|
|
688
|
+
if (!isNonEmptyPath(path3)) return;
|
|
689
|
+
out[path3] = {
|
|
690
|
+
type: normalizeType(schema),
|
|
691
|
+
nullable: inherited.nullable || Boolean(schema.nullable),
|
|
692
|
+
optional: inherited.optional || Boolean(schema.optional)
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
function flattenInto(out, schema, path3, inherited) {
|
|
696
|
+
if (!schema || !isNonEmptyPath(path3)) return;
|
|
697
|
+
const nextInherited = {
|
|
698
|
+
optional: inherited.optional || Boolean(schema.optional),
|
|
699
|
+
nullable: inherited.nullable || Boolean(schema.nullable)
|
|
700
|
+
};
|
|
701
|
+
if (schema.kind === "union" && Array.isArray(schema.union) && schema.union.length > 0) {
|
|
702
|
+
schema.union.forEach((option, index) => {
|
|
703
|
+
const optionPath = `${path3}-${index + 1}`;
|
|
704
|
+
flattenInto(out, option, optionPath, inherited);
|
|
705
|
+
});
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
setNode(out, path3, schema, inherited);
|
|
709
|
+
if (schema.kind === "object" && schema.properties) {
|
|
710
|
+
for (const [key, child] of Object.entries(schema.properties)) {
|
|
711
|
+
const childPath = `${path3}.${key}`;
|
|
712
|
+
flattenInto(out, child, childPath, nextInherited);
|
|
713
|
+
}
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
if (schema.kind === "array" && schema.element) {
|
|
717
|
+
flattenInto(out, schema.element, `${path3}[]`, nextInherited);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
function flattenSerializableSchema(schema, path3) {
|
|
721
|
+
const out = {};
|
|
722
|
+
flattenInto(out, schema, path3, { optional: false, nullable: false });
|
|
723
|
+
return out;
|
|
724
|
+
}
|
|
725
|
+
function isSerializedLeaf(value) {
|
|
726
|
+
if (!value || typeof value !== "object") return false;
|
|
727
|
+
const item = value;
|
|
728
|
+
return typeof item.key === "string" && !!item.cfg && typeof item.cfg === "object";
|
|
729
|
+
}
|
|
730
|
+
function flattenLeafSchemas(leaf) {
|
|
731
|
+
const serialized = isSerializedLeaf(leaf) ? leaf : serializeLeafContract(leaf);
|
|
732
|
+
const out = {};
|
|
733
|
+
const sections = serialized.cfg.schemas;
|
|
734
|
+
Object.assign(out, flattenSerializableSchema(sections.params, "params"));
|
|
735
|
+
Object.assign(out, flattenSerializableSchema(sections.query, "query"));
|
|
736
|
+
Object.assign(out, flattenSerializableSchema(sections.body, "body"));
|
|
737
|
+
Object.assign(out, flattenSerializableSchema(sections.output, "output"));
|
|
738
|
+
return out;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// src/export/exportFinalizedLeaves.ts
|
|
742
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
|
743
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
744
|
+
var import_node_child_process = require("child_process");
|
|
745
|
+
function isRegistry(value) {
|
|
746
|
+
return typeof value === "object" && value !== null && "all" in value && "byKey" in value;
|
|
747
|
+
}
|
|
748
|
+
function getLeaves(input) {
|
|
749
|
+
return isRegistry(input) ? input.all : input;
|
|
750
|
+
}
|
|
751
|
+
function buildMeta() {
|
|
752
|
+
return {
|
|
753
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
754
|
+
description: "Finalized RRRoutes leaves export with serialized schemas and flattened schema paths for downstream processing.",
|
|
755
|
+
fieldCatalog: {
|
|
756
|
+
leaf: ["key", "method", "path", "cfg"],
|
|
757
|
+
cfg: [
|
|
758
|
+
"description?",
|
|
759
|
+
"summary?",
|
|
760
|
+
"docsGroup?",
|
|
761
|
+
"tags?",
|
|
762
|
+
"deprecated?",
|
|
763
|
+
"stability?",
|
|
764
|
+
"docsHidden?",
|
|
765
|
+
"docsMeta?",
|
|
766
|
+
"feed?",
|
|
767
|
+
"bodyFiles?",
|
|
768
|
+
"schemas"
|
|
769
|
+
],
|
|
770
|
+
schemaNode: [
|
|
771
|
+
"kind",
|
|
772
|
+
"optional?",
|
|
773
|
+
"nullable?",
|
|
774
|
+
"description?",
|
|
775
|
+
"properties?",
|
|
776
|
+
"element?",
|
|
777
|
+
"union?",
|
|
778
|
+
"literal?",
|
|
779
|
+
"enumValues?"
|
|
780
|
+
],
|
|
781
|
+
flatSchemaEntry: ["type", "nullable", "optional"]
|
|
782
|
+
},
|
|
783
|
+
flattening: {
|
|
784
|
+
notation: "dot+[]",
|
|
785
|
+
unionBranchSuffix: "-N",
|
|
786
|
+
sections: ["params", "query", "body", "output"]
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
var BAKED_PAYLOAD_MARKER = "<!--__FINALIZED_LEAVES_BAKED_PAYLOAD__-->";
|
|
791
|
+
function escapePayloadForInlineScript(payload) {
|
|
792
|
+
return JSON.stringify(payload).replace(/<\//g, "<\\/").replace(/<!--/g, "<\\!--");
|
|
793
|
+
}
|
|
794
|
+
function injectPayloadIntoViewerHtml(htmlTemplate, payload) {
|
|
795
|
+
const payloadScript = `${BAKED_PAYLOAD_MARKER}
|
|
796
|
+
<script id="finalized-leaves-baked-payload">window.__FINALIZED_LEAVES_PAYLOAD = ${escapePayloadForInlineScript(
|
|
797
|
+
payload
|
|
798
|
+
)};</script>`;
|
|
799
|
+
if (htmlTemplate.includes(BAKED_PAYLOAD_MARKER)) {
|
|
800
|
+
return htmlTemplate.replace(BAKED_PAYLOAD_MARKER, payloadScript);
|
|
801
|
+
}
|
|
802
|
+
if (htmlTemplate.includes("</body>")) {
|
|
803
|
+
return htmlTemplate.replace("</body>", `${payloadScript}
|
|
804
|
+
</body>`);
|
|
805
|
+
}
|
|
806
|
+
return `${payloadScript}
|
|
807
|
+
${htmlTemplate}`;
|
|
808
|
+
}
|
|
809
|
+
async function resolveViewerTemplatePath(viewerTemplateFile) {
|
|
810
|
+
if (viewerTemplateFile) {
|
|
811
|
+
return import_node_path.default.resolve(viewerTemplateFile);
|
|
812
|
+
}
|
|
813
|
+
const candidates = [
|
|
814
|
+
import_node_path.default.resolve(process.cwd(), "tools/finalized-leaves-viewer.html"),
|
|
815
|
+
import_node_path.default.resolve(
|
|
816
|
+
process.cwd(),
|
|
817
|
+
"packages/contract/tools/finalized-leaves-viewer.html"
|
|
818
|
+
)
|
|
819
|
+
];
|
|
820
|
+
for (const candidate of candidates) {
|
|
821
|
+
try {
|
|
822
|
+
await import_promises.default.access(candidate);
|
|
823
|
+
return candidate;
|
|
824
|
+
} catch {
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
throw new Error(
|
|
828
|
+
`Could not locate finalized-leaves viewer template. Checked: ${candidates.join(
|
|
829
|
+
", "
|
|
830
|
+
)}`
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
async function writeJsonExport(payload, outFile) {
|
|
834
|
+
const resolved = import_node_path.default.resolve(outFile);
|
|
835
|
+
await import_promises.default.mkdir(import_node_path.default.dirname(resolved), { recursive: true });
|
|
836
|
+
await import_promises.default.writeFile(resolved, `${JSON.stringify(payload, null, 2)}
|
|
837
|
+
`, "utf8");
|
|
838
|
+
return resolved;
|
|
839
|
+
}
|
|
840
|
+
async function writeBakedHtmlExport(payload, htmlFile, viewerTemplateFile) {
|
|
841
|
+
const templatePath = await resolveViewerTemplatePath(viewerTemplateFile);
|
|
842
|
+
const template = await import_promises.default.readFile(templatePath, "utf8");
|
|
843
|
+
const baked = injectPayloadIntoViewerHtml(template, payload);
|
|
844
|
+
const resolved = import_node_path.default.resolve(htmlFile);
|
|
845
|
+
await import_promises.default.mkdir(import_node_path.default.dirname(resolved), { recursive: true });
|
|
846
|
+
await import_promises.default.writeFile(resolved, baked, "utf8");
|
|
847
|
+
return resolved;
|
|
848
|
+
}
|
|
849
|
+
async function openHtmlInBrowser(filePath) {
|
|
850
|
+
const resolved = import_node_path.default.resolve(filePath);
|
|
851
|
+
const platform = process.platform;
|
|
852
|
+
if (platform === "darwin") {
|
|
853
|
+
(0, import_node_child_process.spawn)("open", [resolved], { detached: true, stdio: "ignore" }).unref();
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
if (platform === "win32") {
|
|
857
|
+
(0, import_node_child_process.spawn)("cmd", ["/c", "start", "", resolved], {
|
|
858
|
+
detached: true,
|
|
859
|
+
stdio: "ignore"
|
|
860
|
+
}).unref();
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
(0, import_node_child_process.spawn)("xdg-open", [resolved], { detached: true, stdio: "ignore" }).unref();
|
|
864
|
+
}
|
|
865
|
+
async function writeFinalizedLeavesExport(payload, outFileOrOptions) {
|
|
866
|
+
const options = typeof outFileOrOptions === "string" ? { outFile: outFileOrOptions } : outFileOrOptions;
|
|
867
|
+
const written = {};
|
|
868
|
+
if (options.outFile) {
|
|
869
|
+
written.outFile = await writeJsonExport(payload, options.outFile);
|
|
870
|
+
}
|
|
871
|
+
if (options.htmlFile) {
|
|
872
|
+
written.htmlFile = await writeBakedHtmlExport(
|
|
873
|
+
payload,
|
|
874
|
+
options.htmlFile,
|
|
875
|
+
options.viewerTemplateFile
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
if (options.openOnFinish) {
|
|
879
|
+
if (!written.htmlFile) {
|
|
880
|
+
throw new Error(
|
|
881
|
+
"openOnFinish requires htmlFile. Provide htmlFile to open the baked viewer."
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
await openHtmlInBrowser(written.htmlFile);
|
|
885
|
+
}
|
|
886
|
+
return written;
|
|
887
|
+
}
|
|
888
|
+
async function exportFinalizedLeaves(input, options = {}) {
|
|
889
|
+
const leaves = getLeaves(input);
|
|
890
|
+
const serializedLeaves = serializeLeavesContract(leaves, options);
|
|
891
|
+
const schemaFlatByLeaf = Object.fromEntries(
|
|
892
|
+
serializedLeaves.map((leaf) => [leaf.key, flattenLeafSchemas(leaf)])
|
|
893
|
+
);
|
|
894
|
+
const payload = {
|
|
895
|
+
_meta: buildMeta(),
|
|
896
|
+
leaves: serializedLeaves,
|
|
897
|
+
schemaFlatByLeaf
|
|
898
|
+
};
|
|
899
|
+
if (options.outFile || options.htmlFile) {
|
|
900
|
+
await writeFinalizedLeavesExport(payload, {
|
|
901
|
+
outFile: options.outFile,
|
|
902
|
+
htmlFile: options.htmlFile,
|
|
903
|
+
viewerTemplateFile: options.viewerTemplateFile,
|
|
904
|
+
openOnFinish: options.openOnFinish
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
return payload;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/export/exportFinalizedLeaves.cli.ts
|
|
911
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
912
|
+
var import_node_url = require("url");
|
|
913
|
+
function parseFinalizedLeavesCliArgs(argv) {
|
|
914
|
+
const args = /* @__PURE__ */ new Map();
|
|
915
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
916
|
+
const key = argv[i];
|
|
917
|
+
if (key === "--") continue;
|
|
918
|
+
if (!key.startsWith("--")) continue;
|
|
919
|
+
const value = argv[i + 1];
|
|
920
|
+
if (!value || value.startsWith("--")) {
|
|
921
|
+
throw new Error(`Missing value for ${key}`);
|
|
922
|
+
}
|
|
923
|
+
args.set(key, value);
|
|
924
|
+
i += 1;
|
|
925
|
+
}
|
|
926
|
+
const modulePath = args.get("--module");
|
|
927
|
+
if (!modulePath) {
|
|
928
|
+
throw new Error("Missing required --module argument");
|
|
929
|
+
}
|
|
930
|
+
return {
|
|
931
|
+
modulePath,
|
|
932
|
+
exportName: args.get("--export") ?? "leaves",
|
|
933
|
+
outFile: args.get("--out") ?? "finalized-leaves.export.json"
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
async function loadFinalizedLeavesInput({
|
|
937
|
+
modulePath,
|
|
938
|
+
exportName
|
|
939
|
+
}) {
|
|
940
|
+
const resolvedModule = import_node_path2.default.resolve(process.cwd(), modulePath);
|
|
941
|
+
const mod = await import((0, import_node_url.pathToFileURL)(resolvedModule).href);
|
|
942
|
+
const value = mod[exportName] ?? (mod.default && mod.default[exportName]);
|
|
943
|
+
if (!value) {
|
|
944
|
+
throw new Error(`Export "${exportName}" not found in module: ${resolvedModule}`);
|
|
945
|
+
}
|
|
946
|
+
return value;
|
|
947
|
+
}
|
|
948
|
+
async function runExportFinalizedLeavesCli(argv) {
|
|
949
|
+
const args = parseFinalizedLeavesCliArgs(argv);
|
|
950
|
+
const input = await loadFinalizedLeavesInput(args);
|
|
951
|
+
const payload = await exportFinalizedLeaves(input, { outFile: args.outFile });
|
|
952
|
+
return {
|
|
953
|
+
payload,
|
|
954
|
+
outFile: import_node_path2.default.resolve(args.outFile)
|
|
955
|
+
};
|
|
956
|
+
}
|
|
378
957
|
// Annotate the CommonJS export names for ESM import in node:
|
|
379
958
|
0 && (module.exports = {
|
|
380
959
|
buildCacheKey,
|
|
381
960
|
buildLowProfileLeaf,
|
|
961
|
+
clearSchemaIntrospectionHandlers,
|
|
382
962
|
collectNestedFieldSuggestions,
|
|
383
963
|
compilePath,
|
|
964
|
+
createSchemaIntrospector,
|
|
384
965
|
defineSocketEvents,
|
|
966
|
+
exportFinalizedLeaves,
|
|
385
967
|
finalize,
|
|
968
|
+
flattenLeafSchemas,
|
|
969
|
+
flattenSerializableSchema,
|
|
386
970
|
getZodShape,
|
|
971
|
+
introspectSchema,
|
|
387
972
|
keyOf,
|
|
973
|
+
loadFinalizedLeavesInput,
|
|
388
974
|
lowProfileParse,
|
|
389
975
|
lowProfileSafeParse,
|
|
390
976
|
mergeArrays,
|
|
391
977
|
mergeSchemas,
|
|
978
|
+
parseFinalizedLeavesCliArgs,
|
|
979
|
+
registerSchemaIntrospectionHandler,
|
|
392
980
|
resource,
|
|
393
981
|
routeSchemaParse,
|
|
394
|
-
|
|
982
|
+
runExportFinalizedLeavesCli,
|
|
983
|
+
serializableSchemaKinds,
|
|
984
|
+
serializeLeafContract,
|
|
985
|
+
serializeLeavesContract,
|
|
986
|
+
staticBase,
|
|
987
|
+
writeFinalizedLeavesExport
|
|
395
988
|
});
|
|
396
989
|
//# sourceMappingURL=index.cjs.map
|