1+ import { PropertyIdSymbol , TypeIdsSymbol } from '@graphprotocol/hypergraph/constants' ;
2+ import { isRelation } from '@graphprotocol/hypergraph/utils/isRelation' ;
3+ import * as Option from 'effect/Option' ;
14import type * as Schema from 'effect/Schema' ;
5+ import * as SchemaAST from 'effect/SchemaAST' ;
26import { convertPropertyValue } from './convert-property-value.js' ;
37
48// A recursive representation of the entity structure returned by the public GraphQL
@@ -25,74 +29,132 @@ type RecursiveQueryEntity = {
2529export const convertRelations = < S extends Schema . Schema . AnyNoContext > ( queryEntity : RecursiveQueryEntity , type : S ) => {
2630 const rawEntity : Record < string , string | boolean | number | unknown [ ] | Date > = { } ;
2731
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 ;
4633
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);
5235
53- const relationTypeName = identifierAnnotation . value ;
36+ for ( const prop of ast . propertySignatures ) {
37+ const result = SchemaAST . getAnnotation < string > ( PropertyIdSymbol ) ( prop . type ) ;
5438
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 ) ] = [ ] ;
6041
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 ;
8044 }
8145
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+ }
8654
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+ } ;
8968
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+ }
9487 }
9588 }
9689
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+
97159 return rawEntity ;
98160} ;
0 commit comments