Skip to content

Commit

Permalink
Fix type validation for workflow inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
davelopez committed Jun 20, 2024
1 parent d442ffc commit 5ae87d2
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ValidationRule } from "@gxwf/server-common/src/languageTypes";
import { isCompatibleType } from "@gxwf/server-common/src/utils";
import { ValidationRule, WorkflowDataType } from "@gxwf/server-common/src/languageTypes";
import { isCompatibleType, isWorkflowDataType } from "@gxwf/server-common/src/utils";
import { Diagnostic, DiagnosticSeverity } from "vscode-languageserver-types";
import { GxFormat2WorkflowDocument } from "../../gxFormat2WorkflowDocument";

Expand All @@ -16,13 +16,22 @@ export class InputTypeValidationRule implements ValidationRule {
inputNodes.forEach((input) => {
const inputName = String(input.keyNode.value);
const inputType = documentContext.nodeManager.getPropertyValueByName(input, "type") as string;

if (!isWorkflowDataType(inputType)) {
result.push({
message: `Input '${inputName}' has an invalid type. Expected a valid workflow data type but found '${inputType}'.`,
range: documentContext.nodeManager.getNodeRange(input),
severity: this.severity,
});
}

const defaultValueNode = documentContext.nodeManager.getPropertyNodeByName(input, "default");
const defaultValue = defaultValueNode?.valueNode?.value;

const defaultValueType = typeof defaultValue;

if (inputType && defaultValue) {
const defaultTypeMatchesValue = isCompatibleType(inputType, defaultValueType);
const defaultTypeMatchesValue = isCompatibleType(inputType as WorkflowDataType, defaultValueType);
if (!defaultTypeMatchesValue) {
result.push({
message: `Input '${inputName}' default value has invalid type. Expected '${inputType}' but found '${defaultValueType}'.`,
Expand Down
8 changes: 8 additions & 0 deletions server/packages/server-common/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { workflowDataTypes } from "../../../../shared/src/requestsDefinitions";
import { WorkflowDataType } from "./languageTypes";

/**
Expand Down Expand Up @@ -32,3 +33,10 @@ export function isCompatibleType(expectedType: WorkflowDataType, actualType: str
}
return isCompatible;
}

export function isWorkflowDataType(type?: string): type is WorkflowDataType {
if (!type) {
return false;
}
return type in workflowDataTypes;
}
41 changes: 27 additions & 14 deletions shared/src/requestsDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,33 @@ export interface TargetWorkflowDocumentParams {
uri: string;
}

export type WorkflowDataType =
| "color" //TODO: this type seems to be missing in format2 schema
| "null"
| "boolean"
| "int"
| "long"
| "float"
| "double"
| "string"
| "integer"
| "text"
| "File"
| "data"
| "collection";
/**
* This contains all the supported data types for workflow inputs.
*
* **Important**: This definition must be kept in sync with the schema definition.
*
* Note: Is defined as a const object to be used as a map and to be able to use the keys as a union type.
* This way we can maintain a single source of truth for the supported data types and generate WorkflowDataType
* type dynamically from it.
*/
export const workflowDataTypes = {
boolean: true,
collection: true,
color: true, //TODO: this type seems to be missing in format2 schema
data: true,
double: true,
File: true,
float: true,
int: true,
integer: true,
long: true,
null: true,
string: true,
text: true,
} as const;

// Extract the keys of the object to form the union type
export type WorkflowDataType = keyof typeof workflowDataTypes;

export interface WorkflowInput {
name: string;
Expand Down

0 comments on commit 5ae87d2

Please sign in to comment.