1- import { ParserField , TypeDefinition , Options , TypeSystemDefinition , TypeExtension , ParserTree } from '@/Models' ;
2- import { getTypeName , createParserField } from '@/shared' ;
1+ import { ParserField , TypeDefinition , TypeSystemDefinition , TypeExtension , ParserTree } from '@/Models' ;
2+ import { getTypeName } from '@/shared' ;
33import {
4- deleteFieldFromInterface ,
54 changeInterfaceField ,
65 updateInterfaceNodeAddField ,
7- renameInterfaceNode ,
8- implementInterfaceOnNode ,
9- deImplementInterfaceOnNode ,
6+ _getAllConnectedInterfaces ,
107} from '@/TreeOperations/interface' ;
118import { ChangeAllRelatedNodes , filterNotNull , isExtensionNode , regenerateId } from '@/TreeOperations/shared' ;
129
1310export const mutate = ( tree : ParserTree , allNodes : ParserField [ ] ) => {
14- const mutateParentIfField = ( node : ParserField , nodeId : string ) => {
11+ const mutateParentIfField = ( node : ParserField ) => {
1512 if ( node . data . type === TypeSystemDefinition . FieldDefinition ) {
16- const parentNode = allNodes . find ( ( an ) => an . args . some ( ( a ) => a . id === nodeId ) ) ;
13+ const parentNode = allNodes . find ( ( an ) => an . args . some ( ( a ) => a . id === node . id ) ) ;
1714 if ( ! parentNode ) throw new Error ( 'Invalid field definition' ) ;
18- const fieldIndex = parentNode . args . findIndex ( ( a ) => a . id == nodeId ) ;
15+ const fieldIndex = parentNode . args . findIndex ( ( a ) => a . id == node . id ) ;
1916 updateFieldOnNode ( parentNode , fieldIndex , node ) ;
2017 return ;
2118 }
2219 } ;
2320 const deleteFieldFromNode = ( n : ParserField , i : number ) => {
24- const nodeId = n . id ;
2521 const argName = n . args [ i ] . name ;
2622 if ( n . data . type === TypeDefinition . InterfaceTypeDefinition ) {
27- deleteFieldFromInterface ( tree . nodes , n , argName ) ;
23+ tree . nodes
24+ . filter ( ( filterNode ) => filterNode . interfaces . includes ( n . name ) )
25+ . forEach ( ( nodeWithThisInterface ) => {
26+ nodeWithThisInterface . args = nodeWithThisInterface . args
27+ . map ( ( a ) => {
28+ if ( a . name !== argName || ! a . fromInterface ) return a ;
29+ if ( a . fromInterface . length === 1 ) return null ;
30+ return {
31+ ...a ,
32+ fromInterface : a . fromInterface . filter ( ( ai ) => ai !== n . name ) ,
33+ } ;
34+ } )
35+ . filter ( filterNotNull ) ;
36+ } ) ;
2837 }
2938 n . args . splice ( i , 1 ) ;
3039 regenerateId ( n ) ;
31- mutateParentIfField ( n , nodeId ) ;
40+ mutateParentIfField ( n ) ;
3241 } ;
3342
3443 const updateFieldOnNode = ( node : ParserField , i : number , updatedField : ParserField ) => {
35- const oldField = JSON . parse ( JSON . stringify ( node . args [ i ] ) ) ;
36- const nodeId = node . id ;
44+ regenerateId ( updatedField ) ;
3745 if ( node . data . type === TypeDefinition . InterfaceTypeDefinition ) {
46+ const oldField : ParserField = JSON . parse ( JSON . stringify ( node . args [ i ] ) ) ;
3847 changeInterfaceField ( tree . nodes , node , oldField , updatedField ) ;
3948 }
4049 node . args [ i ] = updatedField ;
4150 regenerateId ( node ) ;
42- mutateParentIfField ( node , nodeId ) ;
51+ mutateParentIfField ( node ) ;
4352 } ;
4453
45- const addFieldToNode = ( node : ParserField , { id, ...f } : ParserField , name ?: string ) => {
46- let newName = name || f . name [ 0 ] . toLowerCase ( ) + f . name . slice ( 1 ) ;
47- const existingNodes = node . args ?. filter ( ( a ) => a . name . match ( `${ newName } \d?` ) ) || [ ] ;
48- if ( existingNodes . length > 0 ) {
49- newName = `${ newName } ${ existingNodes . length } ` ;
50- }
51- const nodeId = id ;
52- node . args ?. push (
53- createParserField ( {
54- ...f ,
55- directives : [ ] ,
56- interfaces : [ ] ,
57- args : [ ] ,
58- type : {
59- fieldType : {
60- name : f . name ,
61- type : Options . name ,
62- } ,
63- } ,
64- name : newName ,
65- } ) ,
66- ) ;
54+ const addFieldToNode = ( node : ParserField , f : ParserField ) => {
55+ node . args ?. push ( { ...f } ) ;
6756 if ( node . data . type === TypeDefinition . InterfaceTypeDefinition ) {
6857 updateInterfaceNodeAddField ( tree . nodes , node ) ;
6958 }
70- mutateParentIfField ( node , nodeId ) ;
59+ regenerateId ( node ) ;
60+ mutateParentIfField ( node ) ;
7161 } ;
7262 const renameNode = ( node : ParserField , newName : string ) => {
7363 const isError = allNodes . map ( ( n ) => n . name ) . includes ( newName ) ;
7464 if ( isError ) {
7565 return ;
7666 }
7767 if ( node . data . type === TypeDefinition . InterfaceTypeDefinition ) {
78- renameInterfaceNode ( tree . nodes , newName , node . name ) ;
68+ const oldName = node . name ;
69+ tree . nodes
70+ . filter ( ( n ) => n . interfaces . includes ( oldName ) )
71+ . forEach ( ( n ) => {
72+ n . interfaces = n . interfaces . filter ( ( i ) => i !== oldName ) . concat ( [ newName ] ) ;
73+ n . args . forEach ( ( a ) => {
74+ a . fromInterface = a . fromInterface ?. filter ( ( fi ) => fi !== oldName ) . concat ( [ newName ] ) ;
75+ } ) ;
76+ regenerateId ( n ) ;
77+ } ) ;
7978 }
8079 ChangeAllRelatedNodes ( {
8180 newName,
@@ -88,11 +87,10 @@ export const mutate = (tree: ParserTree, allNodes: ParserField[]) => {
8887 const removeNode = ( node : ParserField ) => {
8988 const deletedNode = tree . nodes . findIndex ( ( n ) => n === node ) ;
9089 if ( deletedNode === - 1 ) throw new Error ( 'Error deleting a node' ) ;
91- const allNodes = [ ...tree . nodes ] ;
9290 // co jak usuwamy extension interface
9391 if ( node . data . type === TypeExtension . InterfaceTypeExtension ) {
9492 }
95- allNodes . splice ( deletedNode , 1 ) ;
93+ tree . nodes . splice ( deletedNode , 1 ) ;
9694 tree . nodes . forEach ( ( n ) => {
9795 n . args = n . args
9896 . filter ( ( a ) => {
@@ -103,13 +101,49 @@ export const mutate = (tree: ParserTree, allNodes: ParserField[]) => {
103101 return a ;
104102 } )
105103 . filter ( filterNotNull ) ;
104+ regenerateId ( n ) ;
106105 } ) ;
106+ if ( node . data . type === TypeDefinition . InterfaceTypeDefinition ) {
107+ tree . nodes
108+ . filter ( ( n ) => n . interfaces . includes ( node . name ) )
109+ . forEach ( ( n ) => {
110+ deImplementInterface ( n , node . name ) ;
111+ } ) ;
112+ }
107113 } ;
108114 const implementInterface = ( node : ParserField , interfaceNode : ParserField ) => {
109- implementInterfaceOnNode ( tree . nodes , node , interfaceNode ) ;
115+ const interfacesToPush = _getAllConnectedInterfaces ( allNodes , [ interfaceNode . name ] ) ;
116+ node . interfaces . push ( ...interfacesToPush ) ;
117+ const argsToPush = interfaceNode . args ?. filter ( ( a ) => ! node . args ?. find ( ( na ) => na . name === a . name ) ) || [ ] ;
118+ node . args = node . args . map ( ( a ) => {
119+ if ( interfaceNode . args . find ( ( interfaceArg ) => interfaceArg . name === a . name ) ) {
120+ return {
121+ ...a ,
122+ fromInterface : ( a . fromInterface || [ ] ) . concat ( [ interfaceNode . name ] ) ,
123+ } ;
124+ }
125+ return a ;
126+ } ) ;
127+ node . args = node . args ?. concat (
128+ argsToPush . map ( ( atp ) => ( {
129+ ...atp ,
130+ fromInterface : [ interfaceNode . name ] ,
131+ } ) ) ,
132+ ) ;
133+ regenerateId ( node ) ;
110134 } ;
111135 const deImplementInterface = ( node : ParserField , interfaceName : string ) => {
112- deImplementInterfaceOnNode ( tree . nodes , node , interfaceName ) ;
136+ const interfacesToDeImplement = _getAllConnectedInterfaces ( allNodes , [ interfaceName ] ) ;
137+ node . interfaces = node . interfaces . filter ( ( ni ) => ! interfacesToDeImplement . includes ( ni ) ) ;
138+ node . args = node . args
139+ . map ( ( a ) => {
140+ if ( ! a . fromInterface ?. length ) return a ;
141+ a . fromInterface = a . fromInterface . filter ( ( fi ) => ! interfacesToDeImplement . includes ( fi ) ) ;
142+ if ( a . fromInterface . length === 0 ) return null ;
143+ return a ;
144+ } )
145+ . filter ( filterNotNull ) ;
146+ regenerateId ( node ) ;
113147 } ;
114148 return {
115149 deleteFieldFromNode,
0 commit comments