@arcteninc/core 0.0.49 → 0.0.51

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.49",
3
+ "version": "0.0.51",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
File without changes
@@ -747,10 +747,70 @@ function serializeTypeCustom(
747
747
  return { isOptional: false, schema: { enum: enumMembers } };
748
748
  }
749
749
  }
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
+ }
750
810
  }
751
811
  }
752
812
 
753
- // Handle object types with properties
813
+ // Handle object types with properties (anonymous types)
754
814
  if (type.flags & ts.TypeFlags.Object) {
755
815
  const props = checker.getPropertiesOfType(type);
756
816
  if (props.length > 0) {
@@ -930,9 +990,9 @@ async function serializeType(
930
990
  return result;
931
991
  }
932
992
 
933
- // Generator failed - log and return empty schema
934
- console.warn(`⚠️ Failed to generate schema for type "${typeInfo.typeName}" from ${typeInfo.sourceFile}. Using empty schema.`);
935
- return { isOptional: false, schema: {} }; // Empty schema = any value
993
+ // Generator failed - fall back to custom serializer
994
+ console.warn(`⚠️ Failed to generate schema for type "${typeInfo.typeName}" from ${typeInfo.sourceFile}. Falling back to custom serializer.`);
995
+ return serializeTypeCustom(type, checker, defs);
936
996
  }
937
997
 
938
998
  /**