@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcteninc/core",
3
- "version": "0.0.50",
3
+ "version": "0.0.52",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
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