@arcteninc/core 0.0.53 → 0.0.54
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
|
@@ -731,54 +731,18 @@ function serializeTypeCustom(
|
|
|
731
731
|
}
|
|
732
732
|
|
|
733
733
|
// Build the schema for this type
|
|
734
|
-
// For interfaces, get properties from both the type and the declaration
|
|
735
734
|
const props = checker.getPropertiesOfType(type);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
for (const member of firstDecl.members) {
|
|
742
|
-
if (ts.isPropertySignature(member) && ts.isIdentifier(member.name)) {
|
|
743
|
-
const propName = member.name.text;
|
|
744
|
-
const isOptional = member.questionToken !== undefined;
|
|
745
|
-
|
|
746
|
-
if (member.type) {
|
|
747
|
-
const propType = checker.getTypeFromTypeNode(member.type);
|
|
748
|
-
const propResult = serializeTypeCustom(propType, checker, defs, visited, depth + 1);
|
|
749
|
-
properties[propName] = propResult.schema;
|
|
750
|
-
|
|
751
|
-
if (!isOptional && !propResult.isOptional) {
|
|
752
|
-
required.push(propName);
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
} else if (ts.isTypeAliasDeclaration(firstDecl) && firstDecl.type) {
|
|
758
|
-
// For type aliases, resolve the underlying type
|
|
759
|
-
const underlyingType = checker.getTypeFromTypeNode(firstDecl.type);
|
|
760
|
-
if (underlyingType.flags & ts.TypeFlags.Object) {
|
|
761
|
-
const aliasProps = checker.getPropertiesOfType(underlyingType);
|
|
762
|
-
for (const prop of aliasProps) {
|
|
763
|
-
const propName = prop.getName();
|
|
764
|
-
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration || prop.declarations?.[0] || null as any);
|
|
765
|
-
const isOptional = (prop.flags & ts.SymbolFlags.Optional) !== 0;
|
|
766
|
-
|
|
767
|
-
const propResult = serializeTypeCustom(propType, checker, defs, visited, depth + 1);
|
|
768
|
-
properties[propName] = propResult.schema;
|
|
769
|
-
|
|
770
|
-
if (!isOptional && !propResult.isOptional) {
|
|
771
|
-
required.push(propName);
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
} else if (props.length > 0) {
|
|
776
|
-
// Fallback: use getPropertiesOfType if declaration parsing didn't work
|
|
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
|
|
777
740
|
for (const prop of props) {
|
|
778
741
|
const propName = prop.getName();
|
|
779
|
-
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration || prop.declarations?.[0] || null as any);
|
|
742
|
+
const propType = checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration || prop.declarations?.[0] || checker.getDeclaredTypeOfSymbol(prop).symbol?.valueDeclaration || null as any);
|
|
780
743
|
const isOptional = (prop.flags & ts.SymbolFlags.Optional) !== 0;
|
|
781
744
|
|
|
745
|
+
// Recursively serialize the property type (will detect recursion via visited set)
|
|
782
746
|
const propResult = serializeTypeCustom(propType, checker, defs, visited, depth + 1);
|
|
783
747
|
properties[propName] = propResult.schema;
|
|
784
748
|
|
|
@@ -786,15 +750,15 @@ function serializeTypeCustom(
|
|
|
786
750
|
required.push(propName);
|
|
787
751
|
}
|
|
788
752
|
}
|
|
753
|
+
|
|
754
|
+
// Update the placeholder with the actual schema
|
|
755
|
+
defs[defsKey] = {
|
|
756
|
+
type: 'object',
|
|
757
|
+
properties,
|
|
758
|
+
...(required.length > 0 && { required })
|
|
759
|
+
};
|
|
789
760
|
}
|
|
790
761
|
|
|
791
|
-
// Update the placeholder with the actual schema (even if empty, to avoid infinite loops)
|
|
792
|
-
defs[defsKey] = {
|
|
793
|
-
type: 'object',
|
|
794
|
-
properties,
|
|
795
|
-
...(required.length > 0 && { required })
|
|
796
|
-
};
|
|
797
|
-
|
|
798
762
|
// Return reference
|
|
799
763
|
return { isOptional: false, schema: { $ref: `#/$defs/${defsKey}` } };
|
|
800
764
|
}
|
|
@@ -860,6 +824,73 @@ function serializeTypeCustom(
|
|
|
860
824
|
}
|
|
861
825
|
}
|
|
862
826
|
|
|
827
|
+
// Handle arrays
|
|
828
|
+
if (checker.isArrayType(type)) {
|
|
829
|
+
const typeArgs = (type as ts.TypeReference).typeArguments;
|
|
830
|
+
if (typeArgs && typeArgs.length > 0) {
|
|
831
|
+
const itemResult = serializeTypeCustom(typeArgs[0], checker, defs, visited, depth + 1);
|
|
832
|
+
return {
|
|
833
|
+
isOptional: false,
|
|
834
|
+
schema: { type: 'array', items: itemResult.schema }
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
return { isOptional: false, schema: { type: 'array' } };
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// Handle union types (like "file" | "folder" or string | null)
|
|
841
|
+
if (type.isUnion()) {
|
|
842
|
+
const types = type.types;
|
|
843
|
+
const hasNull = types.some(t => t.flags & ts.TypeFlags.Null);
|
|
844
|
+
const hasUndefined = types.some(t => t.flags & ts.TypeFlags.Undefined);
|
|
845
|
+
const nonNullUndefinedTypes = types.filter(
|
|
846
|
+
t => !(t.flags & ts.TypeFlags.Null) && !(t.flags & ts.TypeFlags.Undefined)
|
|
847
|
+
);
|
|
848
|
+
|
|
849
|
+
// If it's just T | undefined, make it optional
|
|
850
|
+
if (hasUndefined && nonNullUndefinedTypes.length === 1 && !hasNull) {
|
|
851
|
+
const result = serializeTypeCustom(nonNullUndefinedTypes[0], checker, defs, visited, depth + 1);
|
|
852
|
+
return { isOptional: true, schema: result.schema };
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// Check if union is all string/number literals (enum-like union)
|
|
856
|
+
const allStringLiterals = nonNullUndefinedTypes.every(t => t.flags & ts.TypeFlags.StringLiteral);
|
|
857
|
+
const allNumberLiterals = nonNullUndefinedTypes.every(t => t.flags & ts.TypeFlags.NumberLiteral);
|
|
858
|
+
|
|
859
|
+
if (allStringLiterals && nonNullUndefinedTypes.length > 0) {
|
|
860
|
+
const enumValues = nonNullUndefinedTypes.map(t => {
|
|
861
|
+
const literalType = t as ts.StringLiteralType;
|
|
862
|
+
return literalType.value;
|
|
863
|
+
});
|
|
864
|
+
const schema: JsonSchemaProperty = { enum: enumValues };
|
|
865
|
+
return { isOptional: hasNull || hasUndefined, schema };
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
if (allNumberLiterals && nonNullUndefinedTypes.length > 0) {
|
|
869
|
+
const enumValues = nonNullUndefinedTypes.map(t => {
|
|
870
|
+
const literalType = t as ts.NumberLiteralType;
|
|
871
|
+
return literalType.value;
|
|
872
|
+
});
|
|
873
|
+
const schema: JsonSchemaProperty = { enum: enumValues };
|
|
874
|
+
return { isOptional: hasNull || hasUndefined, schema };
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
// Build anyOf for unions
|
|
878
|
+
if (nonNullUndefinedTypes.length > 0 || hasNull) {
|
|
879
|
+
const anyOf: JsonSchemaProperty[] = [];
|
|
880
|
+
if (hasNull || hasUndefined) {
|
|
881
|
+
anyOf.push({ type: 'null' });
|
|
882
|
+
}
|
|
883
|
+
for (const unionType of nonNullUndefinedTypes) {
|
|
884
|
+
const result = serializeTypeCustom(unionType, checker, defs, visited, depth + 1);
|
|
885
|
+
anyOf.push(result.schema);
|
|
886
|
+
}
|
|
887
|
+
if (anyOf.length === 1) {
|
|
888
|
+
return { isOptional: hasNull || hasUndefined, schema: anyOf[0] };
|
|
889
|
+
}
|
|
890
|
+
return { isOptional: false, schema: { anyOf } };
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
863
894
|
// Handle object types with properties (anonymous types)
|
|
864
895
|
if (type.flags & ts.TypeFlags.Object) {
|
|
865
896
|
const props = checker.getPropertiesOfType(type);
|
|
@@ -873,7 +904,7 @@ function serializeTypeCustom(
|
|
|
873
904
|
const isOptional = (prop.flags & ts.SymbolFlags.Optional) !== 0;
|
|
874
905
|
|
|
875
906
|
// Recursively serialize the property type
|
|
876
|
-
const propResult = serializeTypeCustom(propType, checker, defs,
|
|
907
|
+
const propResult = serializeTypeCustom(propType, checker, defs, visited, depth + 1);
|
|
877
908
|
properties[propName] = propResult.schema;
|
|
878
909
|
|
|
879
910
|
if (!isOptional && !propResult.isOptional) {
|