Skip to content

Commit

Permalink
Refactor schemaValidationService to handle Union types
Browse files Browse the repository at this point in the history
  • Loading branch information
davelopez committed Jun 22, 2024
1 parent 4a795fa commit 9b1b53f
Showing 1 changed file with 42 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { ASTNodeManager } from "@gxwf/server-common/src/ast/nodeManager";
import { ASTNode, ObjectASTNode, StringASTNode } from "@gxwf/server-common/src/ast/types";
import { ASTNode, ObjectASTNode, PropertyASTNode, StringASTNode } from "@gxwf/server-common/src/ast/types";
import {
Diagnostic,
DiagnosticSeverity,
Range,
WorkflowDocument,
WorkflowValidator,
} from "@gxwf/server-common/src/languageTypes";
import { isSimpleType } from "@gxwf/server-common/src/utils";
import { SchemaNode, SchemaNodeResolver } from "../schema";
import { EnumSchemaNode, IdMapper, RecordSchemaNode } from "../schema/definitions";
import { EnumSchemaNode, FieldSchemaNode, IdMapper, RecordSchemaNode } from "../schema/definitions";

export class GxFormat2SchemaValidationService implements WorkflowValidator {
constructor(protected readonly schemaNodeResolver: SchemaNodeResolver) {}
Expand Down Expand Up @@ -89,8 +90,10 @@ export class GxFormat2SchemaValidationService implements WorkflowValidator {
Diagnostic.create(range, `The '${schemaFieldNode.name}' field is required.`, DiagnosticSeverity.Error)
);
}
if (nodeFound) {
if (schemaFieldNode.isPrimitiveType && propertyNode?.valueNode?.type) {
if (nodeFound && propertyNode?.valueNode?.type) {
const isPropertyTypeSimple = isSimpleType(propertyNode.valueNode.type);
// Primitive type validation
if (schemaFieldNode.isPrimitiveType && isPropertyTypeSimple) {
if (!schemaFieldNode.matchesType(propertyNode.valueNode.type)) {
diagnostics.push(
Diagnostic.create(
Expand All @@ -100,9 +103,30 @@ export class GxFormat2SchemaValidationService implements WorkflowValidator {
)
);
}
return;
}

// Union type validation
if (schemaFieldNode.isUnionType) {
if (isPropertyTypeSimple) {
const hasMatchingType = this.propetyTypeMatchesAnyPrimitiveRef(schemaFieldNode, propertyNode);
if (!hasMatchingType) {
diagnostics.push(
Diagnostic.create(
range,
`Type mismatch for field '${schemaFieldNode.name}'. Expected '${schemaFieldNode.typeRefs.join(
" | "
)}' but found '${propertyNode.valueNode.type}'.`,
DiagnosticSeverity.Error
)
);
}
return;
}
}

const childSchemaNode = this.schemaNodeResolver.getSchemaNodeByTypeRef(schemaFieldNode.typeRef);
if (childSchemaNode && propertyNode.valueNode) {
if (childSchemaNode) {
if (schemaFieldNode.canBeArray) {
propertyNode.valueNode.children?.forEach((item) => {
if (item.type === "property" && item.valueNode) {
Expand All @@ -117,6 +141,19 @@ export class GxFormat2SchemaValidationService implements WorkflowValidator {
});
}

private propetyTypeMatchesAnyPrimitiveRef(schemaFieldNode: FieldSchemaNode, propertyNode: PropertyASTNode): boolean {
let matchesSomeType = false;
const possibleTypes = schemaFieldNode.typeRefs;
for (const schemaFieldType of possibleTypes) {
const isPrimitive = this.schemaNodeResolver.definitions.isPrimitiveType(schemaFieldType);
if (isPrimitive && propertyNode.valueNode && schemaFieldNode.matchesType(propertyNode.valueNode.type)) {
matchesSomeType = true;
break;
}
}
return matchesSomeType;
}

private validateNodeTypeDefinition(
schemaNode: RecordSchemaNode,
node: ASTNode,
Expand Down

0 comments on commit 9b1b53f

Please sign in to comment.