@arcteninc/core 0.0.50 → 0.0.52
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/package.json
CHANGED
|
File without changes
|
|
@@ -692,6 +692,81 @@ function serializeTypeCustom(
|
|
|
692
692
|
}
|
|
693
693
|
|
|
694
694
|
const typeId = (type as any).id;
|
|
695
|
+
|
|
696
|
+
// Check for interfaces/type aliases FIRST (before general visited check)
|
|
697
|
+
// This allows us to handle recursive types properly with $defs
|
|
698
|
+
const symbol = type.getSymbol();
|
|
699
|
+
if (symbol) {
|
|
700
|
+
const declarations = symbol.getDeclarations();
|
|
701
|
+
if (declarations && declarations.length > 0) {
|
|
702
|
+
const firstDecl = declarations[0];
|
|
703
|
+
|
|
704
|
+
// Handle interfaces and type aliases (for recursive types)
|
|
705
|
+
if (ts.isInterfaceDeclaration(firstDecl) || ts.isTypeAliasDeclaration(firstDecl)) {
|
|
706
|
+
const typeName = symbol.getName();
|
|
707
|
+
if (typeName && defs) {
|
|
708
|
+
const defsKey = typeName; // Use the type name as key
|
|
709
|
+
|
|
710
|
+
// Check if already defined (from a previous call)
|
|
711
|
+
if (defs[defsKey]) {
|
|
712
|
+
return { isOptional: false, schema: { $ref: `#/$defs/${defsKey}` } };
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// Check if we've visited this type before (circular/recursive reference)
|
|
716
|
+
// This happens when we encounter the same type while building its properties
|
|
717
|
+
if (typeId !== undefined && visited.has(typeId)) {
|
|
718
|
+
// Create a placeholder that will be filled in by the original call
|
|
719
|
+
if (!defs[defsKey]) {
|
|
720
|
+
defs[defsKey] = { type: 'object', properties: {} };
|
|
721
|
+
}
|
|
722
|
+
return { isOptional: false, schema: { $ref: `#/$defs/${defsKey}` } };
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Create placeholder first to handle recursion
|
|
726
|
+
defs[defsKey] = { type: 'object', properties: {} };
|
|
727
|
+
|
|
728
|
+
// Mark as visited BEFORE building properties (so recursion is detected)
|
|
729
|
+
if (typeId !== undefined) {
|
|
730
|
+
visited.add(typeId);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// Build the schema for this type
|
|
734
|
+
const props = checker.getPropertiesOfType(type);
|
|
735
|
+
if (props.length > 0) {
|
|
736
|
+
const properties: Record<string, JsonSchemaProperty> = {};
|
|
737
|
+
const required: string[] = [];
|
|
738
|
+
|
|
739
|
+
// Use the same visited set for properties to detect recursion
|
|
740
|
+
for (const prop of props) {
|
|
741
|
+
const propName = prop.getName();
|
|
742
|
+
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration || prop.declarations?.[0] || checker.getDeclaredTypeOfSymbol(prop).symbol?.valueDeclaration || null as any);
|
|
743
|
+
const isOptional = (prop.flags & ts.SymbolFlags.Optional) !== 0;
|
|
744
|
+
|
|
745
|
+
// Recursively serialize the property type (will detect recursion via visited set)
|
|
746
|
+
const propResult = serializeTypeCustom(propType, checker, defs, visited, depth + 1);
|
|
747
|
+
properties[propName] = propResult.schema;
|
|
748
|
+
|
|
749
|
+
if (!isOptional && !propResult.isOptional) {
|
|
750
|
+
required.push(propName);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Update the placeholder with the actual schema
|
|
755
|
+
defs[defsKey] = {
|
|
756
|
+
type: 'object',
|
|
757
|
+
properties,
|
|
758
|
+
...(required.length > 0 && { required })
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Return reference
|
|
763
|
+
return { isOptional: false, schema: { $ref: `#/$defs/${defsKey}` } };
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// General recursion check for non-interface types
|
|
695
770
|
if (typeId !== undefined && visited.has(typeId)) {
|
|
696
771
|
return { isOptional: false, schema: {} };
|
|
697
772
|
}
|
|
@@ -725,7 +800,6 @@ function serializeTypeCustom(
|
|
|
725
800
|
}
|
|
726
801
|
|
|
727
802
|
// Handle enums (TypeScript enum types)
|
|
728
|
-
const symbol = type.getSymbol();
|
|
729
803
|
if (symbol) {
|
|
730
804
|
const declarations = symbol.getDeclarations();
|
|
731
805
|
if (declarations && declarations.length > 0) {
|
|
@@ -747,66 +821,6 @@ function serializeTypeCustom(
|
|
|
747
821
|
return { isOptional: false, schema: { enum: enumMembers } };
|
|
748
822
|
}
|
|
749
823
|
}
|
|
750
|
-
|
|
751
|
-
// Handle interfaces and type aliases (for recursive types)
|
|
752
|
-
if (ts.isInterfaceDeclaration(firstDecl) || ts.isTypeAliasDeclaration(firstDecl)) {
|
|
753
|
-
const typeName = symbol.getName();
|
|
754
|
-
if (typeName && defs) {
|
|
755
|
-
const defsKey = typeName; // Use the type name as key
|
|
756
|
-
|
|
757
|
-
// Check if we've visited this type before (circular/recursive reference)
|
|
758
|
-
if (visited.has(typeId)) {
|
|
759
|
-
// Create a reference to avoid infinite recursion
|
|
760
|
-
if (!defs[defsKey]) {
|
|
761
|
-
// Create placeholder - will be filled in below
|
|
762
|
-
defs[defsKey] = { type: 'object', properties: {} };
|
|
763
|
-
}
|
|
764
|
-
return { isOptional: false, schema: { $ref: `#/$defs/${defsKey}` } };
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
// Check if already defined (from a previous call)
|
|
768
|
-
if (defs[defsKey]) {
|
|
769
|
-
return { isOptional: false, schema: { $ref: `#/$defs/${defsKey}` } };
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
// Mark as visited and build the definition
|
|
773
|
-
visited.add(typeId);
|
|
774
|
-
|
|
775
|
-
// Build the schema for this type
|
|
776
|
-
const props = checker.getPropertiesOfType(type);
|
|
777
|
-
if (props.length > 0) {
|
|
778
|
-
const properties: Record<string, JsonSchemaProperty> = {};
|
|
779
|
-
const required: string[] = [];
|
|
780
|
-
|
|
781
|
-
// Use the same visited set for properties to detect recursion
|
|
782
|
-
for (const prop of props) {
|
|
783
|
-
const propName = prop.getName();
|
|
784
|
-
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration || prop.declarations?.[0] || checker.getDeclaredTypeOfSymbol(prop).symbol?.valueDeclaration || null as any);
|
|
785
|
-
const isOptional = (prop.flags & ts.SymbolFlags.Optional) !== 0;
|
|
786
|
-
|
|
787
|
-
// Recursively serialize the property type (will detect recursion via visited set)
|
|
788
|
-
const propResult = serializeTypeCustom(propType, checker, defs, visited, depth + 1);
|
|
789
|
-
properties[propName] = propResult.schema;
|
|
790
|
-
|
|
791
|
-
if (!isOptional && !propResult.isOptional) {
|
|
792
|
-
required.push(propName);
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
const schema: JsonSchemaProperty = {
|
|
797
|
-
type: 'object',
|
|
798
|
-
properties,
|
|
799
|
-
...(required.length > 0 && { required })
|
|
800
|
-
};
|
|
801
|
-
|
|
802
|
-
// Store in defs
|
|
803
|
-
defs[defsKey] = schema;
|
|
804
|
-
|
|
805
|
-
// Return reference
|
|
806
|
-
return { isOptional: false, schema: { $ref: `#/$defs/${defsKey}` } };
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
824
|
}
|
|
811
825
|
}
|
|
812
826
|
|