Skip to content

Commit 2d078e0

Browse files
author
nicosammito
committed
feat: enhance data type validation with accurate generic and return type resolution
- Refactor data type rule interfaces and implementations to support both dataTypeService and functionService for improved type resolution - Update value and node validation hooks to utilize enhanced generic and return type inference - Add useReturnTypes hook for efficient batch return type resolution in flows - Refactor generic key resolution to handle ReferenceValue and function return types correctly - Improve reference suggestion logic to use resolved return types for accurate type matching - Clean up unused code and improve null safety in type checks
1 parent e43dbfa commit 2d078e0

16 files changed

Lines changed: 134 additions & 84 deletions

src/components/d-flow-data-type/DFlowDataType.service.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
DataTypeIdentifier,
66
DataTypeRule,
77
DataTypeRulesContainsKeyConfig,
8-
DataTypeRulesInputTypesConfig, DataTypeRulesVariant,
8+
DataTypeRulesInputTypesConfig,
9+
DataTypeRulesVariant,
910
Flow,
1011
GenericMapper,
1112
LiteralValue,
@@ -19,6 +20,7 @@ import {
1920
import {useValueValidation} from "../d-flow-validation/DValueValidation.hook";
2021
import {findReturnNode} from "./rules/DFlowDataTypeReturnTypeRule";
2122
import {md5} from "js-md5";
23+
import {useReturnTypes} from "../d-flow-node/DFlowNode.return.hook";
2224

2325
export type DFlowDataTypeDependencies = {
2426
namespaceId: Namespace['id']
@@ -150,8 +152,6 @@ export abstract class DFlowDataTypeReactiveService extends ReactiveArrayService<
150152

151153
if (!value) return undefined
152154

153-
if (value.__typename === "ReferenceValue") return value.dataTypeIdentifier
154-
155155
const dataType = this.getDataTypeFromValue(value, flow, dependencies)
156156
if ((dataType?.genericKeys?.length ?? 0) <= 0 || !dataType?.genericKeys) return {
157157
dataType: {

src/components/d-flow-data-type/rules/DFlowDataTypeContainsKeyRule.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,28 @@ import {useValueValidation} from "../../d-flow-validation/DValueValidation.hook"
1212

1313
@staticImplements<DFlowDataTypeRule>()
1414
export class DFlowDataTypeContainsKeyRule {
15-
public static validate(value: NodeParameterValue, config: DataTypeRulesContainsKeyConfig, generics?: Map<string, GenericMapper>, service?: DFlowDataTypeReactiveService, flow?: Flow): boolean {
15+
public static validate(value: NodeParameterValue, config: DataTypeRulesContainsKeyConfig, generics?: Map<string, GenericMapper>, flow?: Flow, dataTypeService?: DFlowDataTypeReactiveService): boolean {
1616

1717
const genericMapper = generics?.get(config?.dataTypeIdentifier?.genericKey!!)
1818
const genericTypes = generics?.get(config?.dataTypeIdentifier?.genericKey!!)?.sourceDataTypeIdentifiers
1919
const genericCombination = generics?.get(config?.dataTypeIdentifier?.genericKey!!)?.genericCombinationStrategies
2020

2121
//TODO: seperate general validation
2222
//if (!(isObject(value))) return false
23-
if ((config?.key ?? "") in value && config?.dataTypeIdentifier?.genericKey && !genericMapper && !service?.getDataType(config.dataTypeIdentifier)) return true
23+
if ((config?.key ?? "") in value && config?.dataTypeIdentifier?.genericKey && !genericMapper && !dataTypeService?.getDataType(config.dataTypeIdentifier)) return true
2424

25-
if (!(service?.getDataType(config.dataTypeIdentifier!!) || genericMapper)) return false
25+
if (!(dataTypeService?.getDataType(config.dataTypeIdentifier!!) || genericMapper)) return false
2626

2727
//use of generic key but datatypes does not exist
28-
if (genericMapper && !service?.hasDataTypes(genericTypes!!)) return false
28+
if (genericMapper && !dataTypeService?.hasDataTypes(genericTypes!!)) return false
2929

3030
//check if all generic combinations are set
3131
if (genericMapper && !(((genericCombination?.length ?? 0) + 1) == genericTypes!!.length)) return false
3232

3333
//use generic given type for checking against value
3434
if (config?.dataTypeIdentifier?.genericKey && genericMapper && genericTypes) {
3535
const checkAllTypes: boolean[] = genericTypes.map(genericType => {
36-
return useValueValidation((value as LiteralValue).value[(config?.key ?? "")], service?.getDataType(genericType)!!, service!!, flow, ((genericType.genericType)!!.genericMappers as GenericMapper[]))
36+
return useValueValidation((value as LiteralValue).value[(config?.key ?? "")], dataTypeService?.getDataType(genericType)!!, dataTypeService!!, flow, ((genericType.genericType)!!.genericMappers as GenericMapper[]))
3737
})
3838

3939
const combination = checkAllTypes.length > 1 ? checkAllTypes.reduce((previousValue, currentValue, currentIndex) => {
@@ -49,9 +49,9 @@ export class DFlowDataTypeContainsKeyRule {
4949

5050
//normal datatype link
5151
if (config?.dataTypeIdentifier?.dataType) {
52-
return ((config?.key ?? "") in value) && useValueValidation((value as LiteralValue).value[(config?.key ?? "")], service?.getDataType(config.dataTypeIdentifier)!!, service!!)
52+
return ((config?.key ?? "") in value) && useValueValidation((value as LiteralValue).value[(config?.key ?? "")], dataTypeService?.getDataType(config.dataTypeIdentifier)!!, dataTypeService!!)
5353
}
5454

55-
return ((config?.key ?? "") in value) && useValueValidation((value as LiteralValue).value[(config?.key ?? "")], service?.getDataType(config.dataTypeIdentifier!!)!!, service!!, flow, genericMapping(config?.dataTypeIdentifier?.genericType?.genericMappers!!, generics))
55+
return ((config?.key ?? "") in value) && useValueValidation((value as LiteralValue).value[(config?.key ?? "")], dataTypeService?.getDataType(config.dataTypeIdentifier!!)!!, dataTypeService!!, flow, genericMapping(config?.dataTypeIdentifier?.genericType?.genericMappers!!, generics))
5656
}
5757
}

src/components/d-flow-data-type/rules/DFlowDataTypeContainsTypeRule.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {useValueValidation} from "../../d-flow-validation/DValueValidation.hook"
1212

1313
@staticImplements<DFlowDataTypeRule>()
1414
export class DFlowDataTypeContainsTypeRule {
15-
public static validate(value: NodeParameterValue, config: DataTypeRulesContainsKeyConfig, generics?: Map<string, GenericMapper>, service?: DFlowDataTypeReactiveService, flow?: Flow): boolean {
15+
public static validate(value: NodeParameterValue, config: DataTypeRulesContainsKeyConfig, generics?: Map<string, GenericMapper>, flow?: Flow, dataTypeService?: DFlowDataTypeReactiveService): boolean {
1616

1717
const genericMapper = generics?.get(config?.dataTypeIdentifier?.genericKey!!)
1818
const genericTypes = generics?.get(config?.dataTypeIdentifier?.genericKey!!)?.sourceDataTypeIdentifiers
@@ -21,12 +21,12 @@ export class DFlowDataTypeContainsTypeRule {
2121
//TODO: seperate general validation
2222
if ("value" in value && !(Array.isArray(value.value))) return false
2323

24-
if (config?.dataTypeIdentifier?.genericKey && !genericMapper && !service?.getDataType(config.dataTypeIdentifier)) return true
24+
if (config?.dataTypeIdentifier?.genericKey && !genericMapper && !dataTypeService?.getDataType(config.dataTypeIdentifier)) return true
2525

26-
if (!(service?.getDataType(config.dataTypeIdentifier!!) || genericMapper)) return false
26+
if (!(dataTypeService?.getDataType(config.dataTypeIdentifier!!) || genericMapper)) return false
2727

2828
//use of generic key but datatype does not exist
29-
if (genericMapper && !service?.hasDataTypes(genericTypes!!)) return false
29+
if (genericMapper && !dataTypeService?.hasDataTypes(genericTypes!!)) return false
3030

3131
//check if all generic combinations are set
3232
if (genericMapper && !(((genericCombination?.length ?? 0) + 1) == genericTypes!!.length)) return false
@@ -39,12 +39,12 @@ export class DFlowDataTypeContainsTypeRule {
3939
return useValueValidation({
4040
__typename: "LiteralValue",
4141
value: value1
42-
}, service?.getDataType(genericType)!!, service!!, flow, ((genericType.genericType as GenericType)!!.genericMappers as GenericMapper[]))
42+
}, dataTypeService?.getDataType(genericType)!!, dataTypeService!!, flow, ((genericType.genericType as GenericType)!!.genericMappers as GenericMapper[]))
4343
}
4444
return useValueValidation({
4545
__typename: "LiteralValue",
4646
value: value1
47-
}, service?.getDataType(genericType)!!, service!!, flow)
47+
}, dataTypeService?.getDataType(genericType)!!, dataTypeService!!, flow)
4848
})
4949
})
5050

@@ -59,10 +59,10 @@ export class DFlowDataTypeContainsTypeRule {
5959

6060
//normal datatype link
6161
if (config?.dataTypeIdentifier?.dataType) {
62-
return (value as LiteralValue).value.every((value1: any) => useValueValidation(value1, service?.getDataType(config.dataTypeIdentifier!!)!!, service!!))
62+
return (value as LiteralValue).value.every((value1: any) => useValueValidation(value1, dataTypeService?.getDataType(config.dataTypeIdentifier!!)!!, dataTypeService!!))
6363
}
6464

65-
return (value as LiteralValue).value.every((value1: any) => useValueValidation(value1, service?.getDataType(config.dataTypeIdentifier!!)!!, service!!, flow, genericMapping((config.dataTypeIdentifier?.genericType as GenericType).genericMappers!!, generics)))
65+
return (value as LiteralValue).value.every((value1: any) => useValueValidation(value1, dataTypeService?.getDataType(config.dataTypeIdentifier!!)!!, dataTypeService!!, flow, genericMapping((config.dataTypeIdentifier?.genericType as GenericType).genericMappers!!, generics)))
6666

6767
}
6868
}

src/components/d-flow-data-type/rules/DFlowDataTypeParentRule.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ export interface DFlowDataTypeParentRuleConfig {
1010

1111
@staticImplements<DFlowDataTypeRule>()
1212
export class DFlowDataTypeParentRule {
13-
public static validate(value: NodeParameterValue, config: DFlowDataTypeParentRuleConfig, generics?: Map<string, GenericMapper>, service?: DFlowDataTypeReactiveService, flow?: Flow): boolean {
13+
public static validate(value: NodeParameterValue, config: DFlowDataTypeParentRuleConfig, generics?: Map<string, GenericMapper>, flow?: Flow, dataTypeService?: DFlowDataTypeReactiveService): boolean {
1414

1515
const replacedType = generics ? replaceGenericKeysInType(config.type, generics) : config.type
1616

17-
if (!service) return false
18-
return useValueValidation(value, service.getDataType(replacedType)!!, service, flow, Array.from(generics!!, ([_, value]) => value))
17+
if (!dataTypeService) return false
18+
return useValueValidation(value, dataTypeService.getDataType(replacedType)!!, dataTypeService, flow, Array.from(generics!!, ([_, value]) => value))
1919

2020
}
2121
}

src/components/d-flow-data-type/rules/DFlowDataTypeReturnTypeRule.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import type {
1212
} from "@code0-tech/sagittarius-graphql-types";
1313
import {useDataTypeValidation} from "../../d-flow-validation/DDataTypeValidation.hook";
1414
import {useValueValidation} from "../../d-flow-validation/DValueValidation.hook";
15+
import {DFlowFunctionReactiveService} from "../../d-flow-function";
16+
import {useReturnType} from "../../d-flow-function/DFlowFunction.return.hook";
1517

1618
//TODO: simple use useReturnType function
1719
@staticImplements<DFlowDataTypeRule>()
@@ -20,8 +22,9 @@ export class DFlowDataTypeReturnTypeRule {
2022
value: NodeParameterValue,
2123
config: DataTypeRulesReturnTypeConfig,
2224
generics?: Map<string, GenericMapper>,
23-
service?: DFlowDataTypeReactiveService,
24-
flow?: Flow
25+
flow?: Flow,
26+
dataTypeService?: DFlowDataTypeReactiveService,
27+
functionService?: DFlowFunctionReactiveService
2528
): boolean {
2629

2730
const genericMapper = generics?.get(config?.dataTypeIdentifier?.genericKey!!)
@@ -30,27 +33,32 @@ export class DFlowDataTypeReturnTypeRule {
3033

3134
if (value.__typename != "NodeFunctionIdWrapper") return false
3235

33-
if (config?.dataTypeIdentifier?.genericKey && !genericMapper && !service?.getDataType(config.dataTypeIdentifier)) return true
36+
if (config?.dataTypeIdentifier?.genericKey && !genericMapper && !dataTypeService?.getDataType(config.dataTypeIdentifier)) return true
3437

3538
const foundReturnFunction = findReturnNode(value, flow!!)
3639
if (!foundReturnFunction) return false
3740
if (!foundReturnFunction?.parameters?.nodes?.[0]?.value) return false
3841

39-
if (!(service?.getDataType(config.dataTypeIdentifier!!) || genericMapper)) return false
42+
if (!(dataTypeService?.getDataType(config.dataTypeIdentifier!!) || genericMapper)) return false
4043

4144
//use of generic key but datatypes does not exist
42-
if (genericMapper && !service?.hasDataTypes(genericTypes!!)) return false
45+
if (genericMapper && !dataTypeService?.hasDataTypes(genericTypes!!)) return false
4346

4447
//check if all generic combinations are set
4548
if (genericMapper && !(((genericCombination?.length ?? 0) + 1) == genericTypes!!.length)) return false
4649

4750
if (foundReturnFunction?.parameters?.nodes?.[0]?.value?.__typename === "ReferenceValue") {
4851

52+
const value = (foundReturnFunction?.parameters?.nodes?.[0]?.value as ReferenceValue)
53+
const node = flow?.nodes?.nodes?.find(node => node?.id === value.nodeFunctionId) as NodeFunction
54+
const funcDef = functionService?.getById(node?.functionDefinition?.id!)
55+
const values = node.parameters?.nodes?.map(p => p?.value!) ?? []
56+
4957
//use generic given type for checking against value
5058
if (config?.dataTypeIdentifier?.genericKey && genericMapper && genericTypes) {
5159

5260
const checkAllTypes: boolean[] = genericTypes.map(genericType => {
53-
return useDataTypeValidation(service?.getDataType(genericType)!!, service?.getDataType((foundReturnFunction?.parameters?.nodes?.[0]?.value as ReferenceValue).dataTypeIdentifier!)!)
61+
return useDataTypeValidation(dataTypeService?.getDataType(genericType)!!, dataTypeService?.getDataType(useReturnType(funcDef!, values, dataTypeService, functionService!)!)!)
5462
})
5563

5664
return checkAllTypes.length > 1 ? checkAllTypes.reduce((previousValue, currentValue, currentIndex) => {
@@ -63,7 +71,7 @@ export class DFlowDataTypeReturnTypeRule {
6371
}
6472

6573
if (config?.dataTypeIdentifier?.dataType) {
66-
return useDataTypeValidation(service?.getDataType(config.dataTypeIdentifier!)!, service?.getDataType(foundReturnFunction?.parameters?.nodes?.[0]?.value?.dataTypeIdentifier!)!)
74+
return useDataTypeValidation(dataTypeService?.getDataType(config.dataTypeIdentifier!)!, dataTypeService?.getDataType(useReturnType(funcDef!, values, dataTypeService, functionService!)!)!)
6775
}
6876

6977
} else if (foundReturnFunction?.parameters?.nodes?.[0]?.value?.__typename == "NodeFunctionIdWrapper") {
@@ -74,7 +82,7 @@ export class DFlowDataTypeReturnTypeRule {
7482
if (config?.dataTypeIdentifier?.genericKey && genericMapper && genericTypes) {
7583

7684
const checkAllTypes: boolean[] = genericTypes.map(genericType => {
77-
return useValueValidation(foundReturnFunction?.parameters?.nodes?.[0]?.value!, service?.getDataType(genericType)!!, service!!, flow, ((genericType.genericType as GenericType)!!.genericMappers as GenericMapper[]))
85+
return useValueValidation(foundReturnFunction?.parameters?.nodes?.[0]?.value!, dataTypeService?.getDataType(genericType)!!, dataTypeService!!, flow, ((genericType.genericType as GenericType)!!.genericMappers as GenericMapper[]))
7886
})
7987

8088
return checkAllTypes.length > 1 ? checkAllTypes.reduce((previousValue, currentValue, currentIndex) => {
@@ -87,10 +95,10 @@ export class DFlowDataTypeReturnTypeRule {
8795
}
8896

8997
if (config?.dataTypeIdentifier?.dataType) {
90-
return useValueValidation(foundReturnFunction?.parameters?.nodes?.[0]?.value!, service?.getDataType(config.dataTypeIdentifier!)!, service!!)
98+
return useValueValidation(foundReturnFunction?.parameters?.nodes?.[0]?.value!, dataTypeService?.getDataType(config.dataTypeIdentifier!)!, dataTypeService!!)
9199
}
92100

93-
return useValueValidation(foundReturnFunction?.parameters?.nodes?.[0]?.value!, service?.getDataType(config.dataTypeIdentifier!)!, service!!, flow, genericMapping(config.dataTypeIdentifier?.genericType?.genericMappers!, generics))
101+
return useValueValidation(foundReturnFunction?.parameters?.nodes?.[0]?.value!, dataTypeService?.getDataType(config.dataTypeIdentifier!)!, dataTypeService!!, flow, genericMapping(config.dataTypeIdentifier?.genericType?.genericMappers!, generics))
94102

95103
}
96104

src/components/d-flow-data-type/rules/DFlowDataTypeRule.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import {DFlowDataTypeReactiveService} from "../DFlowDataType.service";
22
import type {Flow, GenericMapper, NodeParameterValue} from "@code0-tech/sagittarius-graphql-types";
3+
import {DFlowFunctionReactiveService} from "../../d-flow-function";
34

45
export interface DFlowDataTypeRule {
5-
validate(value: NodeParameterValue, config: object, generics?: Map<string, GenericMapper>, service?: DFlowDataTypeReactiveService, flow?: Flow): boolean
6+
validate(value: NodeParameterValue, config: object, generics?: Map<string, GenericMapper>, flow?: Flow, dataTypeService?: DFlowDataTypeReactiveService, functionService?: DFlowFunctionReactiveService): boolean
67
}
78

89
export const staticImplements = <T>() => {

src/components/d-flow-function/DFlowFunction.input.hook.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@ import {FunctionDefinitionView} from "./DFlowFunction.view";
22
import {DFlowDataTypeReactiveService} from "../d-flow-data-type";
33
import {replaceGenericKeysInType, resolveGenericKeys} from "../../utils/generics";
44
import type {DataTypeIdentifier, NodeParameterValue} from "@code0-tech/sagittarius-graphql-types";
5+
import {DFlowFunctionReactiveService} from "./DFlowFunction.service";
56

67
export const useInputType = (
78
type: DataTypeIdentifier,
89
func: FunctionDefinitionView,
910
values: NodeParameterValue[],
10-
dataTypeService: DFlowDataTypeReactiveService
11+
dataTypeService: DFlowDataTypeReactiveService,
12+
functionService: DFlowFunctionReactiveService,
1113
): DataTypeIdentifier | null => {
1214

13-
const genericTypeMap = resolveGenericKeys(func, values, dataTypeService)
15+
const genericTypeMap = resolveGenericKeys(func, values, dataTypeService, functionService)
1416
return replaceGenericKeysInType(type, genericTypeMap)
1517

1618
}

src/components/d-flow-function/DFlowFunction.return.hook.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import {FunctionDefinitionView} from "./DFlowFunction.view";
22
import {DFlowDataTypeReactiveService} from "../d-flow-data-type";
33
import {replaceGenericKeysInType, resolveGenericKeys} from "../../utils/generics";
44
import type {DataTypeIdentifier, NodeParameterValue} from "@code0-tech/sagittarius-graphql-types";
5+
import {DFlowFunctionReactiveService} from "./DFlowFunction.service";
56

67
export const useReturnType = (
78
func: FunctionDefinitionView,
89
values: NodeParameterValue[],
9-
dataTypeService: DFlowDataTypeReactiveService
10+
dataTypeService: DFlowDataTypeReactiveService,
11+
functionService: DFlowFunctionReactiveService,
1012
): DataTypeIdentifier | null => {
1113

1214
if (!func?.returnType) return null
1315

14-
const genericTypeMap = resolveGenericKeys(func, values, dataTypeService)
16+
const genericTypeMap = resolveGenericKeys(func, values, dataTypeService, functionService)
1517
return replaceGenericKeysInType(func.returnType, genericTypeMap)
1618

1719
}

src/components/d-flow-input/DFlowInputReferenceBadge.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const DFlowInputReferenceBadge: React.FC<DFlowInputReferenceBadge> = (pro
2828
{value.referencePath ? "." + (value.referencePath?.map(path => path.path).join(".") ?? "") : ""}
2929
</Flex>
3030
}
31-
return `{{ ${String(value.depth)}-${String(value.scope)}-${String(value.node)}-${value.referencePath?.map(path => path.path).join(".") ?? ""} }}`
31+
return `undefineds`
3232
}, [value])
3333

3434
return <Badge style={{verticalAlign: "middle"}}

0 commit comments

Comments
 (0)