1
+ import { PropertyIdSymbol , TypeIdsSymbol } from '@graphprotocol/hypergraph/constants' ;
2
+ import { isRelation } from '@graphprotocol/hypergraph/utils/isRelation' ;
3
+ import * as Option from 'effect/Option' ;
1
4
import type * as Schema from 'effect/Schema' ;
5
+ import * as SchemaAST from 'effect/SchemaAST' ;
2
6
import { convertPropertyValue } from './convert-property-value.js' ;
3
7
4
8
// A recursive representation of the entity structure returned by the public GraphQL
@@ -25,74 +29,132 @@ type RecursiveQueryEntity = {
25
29
export const convertRelations = < S extends Schema . Schema . AnyNoContext > ( queryEntity : RecursiveQueryEntity , type : S ) => {
26
30
const rawEntity : Record < string , string | boolean | number | unknown [ ] | Date > = { } ;
27
31
28
- for ( const [ key , relationId ] of Object . entries ( mappingEntry ?. relations ?? { } ) ) {
29
- const properties = ( queryEntity . relationsList ?? [ ] ) . filter ( ( a ) => a . typeId === relationId ) ;
30
- if ( properties . length === 0 ) {
31
- rawEntity [ key ] = [ ] as unknown [ ] ;
32
- continue ;
33
- }
34
-
35
- const field = type . fields [ key ] ;
36
- if ( ! field ) {
37
- // @ts -expect-error TODO: properly access the type.name
38
- console . error ( `Field ${ key } not found in ${ type . name } ` ) ;
39
- continue ;
40
- }
41
- const relationTransformation = field . ast . rest ?. [ 0 ] ;
42
- if ( ! relationTransformation ) {
43
- console . error ( `Relation transformation for ${ key } not found` ) ;
44
- continue ;
45
- }
32
+ const ast = type . ast as SchemaAST . TypeLiteral ;
46
33
47
- const identifierAnnotation = SchemaAST . getIdentifierAnnotation ( relationTransformation . type . to ) ;
48
- if ( Option . isNone ( identifierAnnotation ) ) {
49
- console . error ( `Relation identifier for ${ key } not found` ) ;
50
- continue ;
51
- }
34
+ // console.log('queryEntity', queryEntity);
52
35
53
- const relationTypeName = identifierAnnotation . value ;
36
+ for ( const prop of ast . propertySignatures ) {
37
+ const result = SchemaAST . getAnnotation < string > ( PropertyIdSymbol ) ( prop . type ) ;
54
38
55
- const relationMappingEntry = mapping [ relationTypeName ] ;
56
- if ( ! relationMappingEntry ) {
57
- console . error ( `Relation mapping entry for ${ relationTypeName } not found` ) ;
58
- continue ;
59
- }
39
+ if ( isRelation ( prop . type ) ) {
40
+ rawEntity [ String ( prop . name ) ] = [ ] ;
60
41
61
- const newRelationEntities = properties . map ( ( propertyEntry ) => {
62
- // @ts -expect-error TODO: properly access the type.name
63
- const type = field . value ;
64
-
65
- let rawEntity : Record < string , string | boolean | number | unknown [ ] | Date > = {
66
- id : propertyEntry . toEntity . id ,
67
- name : propertyEntry . toEntity . name ,
68
- // TODO: should be determined by the actual value
69
- __deleted : false ,
70
- // TODO: should be determined by the actual value
71
- __version : '' ,
72
- } ;
73
-
74
- // take the mappingEntry and assign the attributes to the rawEntity
75
- for ( const [ key , value ] of Object . entries ( relationMappingEntry ?. properties ?? { } ) ) {
76
- const property = propertyEntry . toEntity . valuesList ?. find ( ( a ) => a . propertyId === value ) ;
77
- if ( property ) {
78
- rawEntity [ key ] = convertPropertyValue ( property , key , type ) ;
79
- }
42
+ if ( ! queryEntity . valuesList ) {
43
+ continue ;
80
44
}
81
45
82
- rawEntity = {
83
- ...rawEntity ,
84
- ...convertRelations ( propertyEntry . toEntity , type , relationMappingEntry , mapping ) ,
85
- } ;
46
+ if ( Option . isSome ( result ) ) {
47
+ const relationTransformation = prop . type . rest ?. [ 0 ] ?. type ;
48
+ const typeIds : string [ ] = SchemaAST . getAnnotation < string [ ] > ( TypeIdsSymbol ) ( relationTransformation ) . pipe (
49
+ Option . getOrElse ( ( ) => [ ] ) ,
50
+ ) ;
51
+ if ( typeIds . length === 0 ) {
52
+ continue ;
53
+ }
86
54
87
- return rawEntity ;
88
- } ) ;
55
+ const allRelationsWithTheCorrectPropertyTypeId = queryEntity . relationsList ?. filter (
56
+ ( a ) => a . typeId === result . value ,
57
+ ) ;
58
+ if ( allRelationsWithTheCorrectPropertyTypeId ) {
59
+ for ( const relationEntry of allRelationsWithTheCorrectPropertyTypeId ) {
60
+ const nestedRawEntity :
61
+ | Record < string , string | boolean | number | unknown [ ] | Date >
62
+ | { _relation : { id : string } } = {
63
+ id : relationEntry . toEntity . id ,
64
+ _relation : {
65
+ id : 'TODO: relation id' ,
66
+ } ,
67
+ } ;
89
68
90
- if ( rawEntity [ key ] ) {
91
- rawEntity [ key ] = [ ...( rawEntity [ key ] as unknown [ ] ) , ...newRelationEntities ] ;
92
- } else {
93
- rawEntity [ key ] = newRelationEntities ;
69
+ for ( const nestedProp of relationTransformation . propertySignatures ) {
70
+ const nestedResult = SchemaAST . getAnnotation < string > ( PropertyIdSymbol ) ( nestedProp . type ) ;
71
+ if ( Option . isSome ( nestedResult ) ) {
72
+ const value = relationEntry . toEntity . valuesList ?. find ( ( a ) => a . propertyId === nestedResult . value ) ;
73
+ if ( ! value ) {
74
+ continue ;
75
+ }
76
+ const rawValue = convertPropertyValue ( value , nestedProp . type ) ;
77
+ if ( rawValue ) {
78
+ nestedRawEntity [ String ( nestedProp . name ) ] = rawValue ;
79
+ }
80
+ }
81
+ // TODO: in the end every entry should be validated using the Schema?!?
82
+ rawEntity [ String ( prop . name ) ] = [ ...( rawEntity [ String ( prop . name ) ] as unknown [ ] ) , nestedRawEntity ] ;
83
+ }
84
+ }
85
+ }
86
+ }
94
87
}
95
88
}
96
89
90
+ // for (const [key, relationId] of Object.entries(mappingEntry?.relations ?? {})) {
91
+ // const properties = (queryEntity.relationsList ?? []).filter((a) => a.typeId === relationId);
92
+ // if (properties.length === 0) {
93
+ // rawEntity[key] = [] as unknown[];
94
+ // continue;
95
+ // }
96
+
97
+ // const field = type.fields[key];
98
+ // if (!field) {
99
+ // // @ts -expect-error TODO: properly access the type.name
100
+ // console.error(`Field ${key} not found in ${type.name}`);
101
+ // continue;
102
+ // }
103
+ // const relationTransformation = field.ast.rest?.[0];
104
+ // if (!relationTransformation) {
105
+ // console.error(`Relation transformation for ${key} not found`);
106
+ // continue;
107
+ // }
108
+
109
+ // const identifierAnnotation = SchemaAST.getIdentifierAnnotation(relationTransformation.type.to);
110
+ // if (Option.isNone(identifierAnnotation)) {
111
+ // console.error(`Relation identifier for ${key} not found`);
112
+ // continue;
113
+ // }
114
+
115
+ // const relationTypeName = identifierAnnotation.value;
116
+
117
+ // const relationMappingEntry = mapping[relationTypeName];
118
+ // if (!relationMappingEntry) {
119
+ // console.error(`Relation mapping entry for ${relationTypeName} not found`);
120
+ // continue;
121
+ // }
122
+
123
+ // const newRelationEntities = properties.map((propertyEntry) => {
124
+ // // @ts -expect-error TODO: properly access the type.name
125
+ // const type = field.value;
126
+
127
+ // let rawEntity: Record<string, string | boolean | number | unknown[] | Date> = {
128
+ // id: propertyEntry.toEntity.id,
129
+ // name: propertyEntry.toEntity.name,
130
+ // // TODO: should be determined by the actual value
131
+ // __deleted: false,
132
+ // // TODO: should be determined by the actual value
133
+ // __version: '',
134
+ // };
135
+
136
+ // // take the mappingEntry and assign the attributes to the rawEntity
137
+ // for (const [key, value] of Object.entries(relationMappingEntry?.properties ?? {})) {
138
+ // const property = propertyEntry.toEntity.valuesList?.find((a) => a.propertyId === value);
139
+ // if (property) {
140
+ // rawEntity[key] = convertPropertyValue(property, type);
141
+ // }
142
+ // }
143
+
144
+ // rawEntity = {
145
+ // ...rawEntity,
146
+ // ...convertRelations(propertyEntry.toEntity, type, relationMappingEntry, mapping),
147
+ // };
148
+
149
+ // return rawEntity;
150
+ // });
151
+
152
+ // if (rawEntity[key]) {
153
+ // rawEntity[key] = [...(rawEntity[key] as unknown[]), ...newRelationEntities];
154
+ // } else {
155
+ // rawEntity[key] = newRelationEntities;
156
+ // }
157
+ // }
158
+
97
159
return rawEntity ;
98
160
} ;
0 commit comments