@@ -9,12 +9,16 @@ import { groupBy } from '../utils/index.js';
99import { ConfigBlock , ConfigType } from './config.js' ;
1010import { ProjectConfig } from './project-config.js' ;
1111import { ResourceConfig } from './resource-config.js' ;
12+ import { PlanRequest } from './plan-request.js' ;
1213
1314export class Project {
1415 projectConfig : ProjectConfig | null ;
1516 resourceConfigs : ResourceConfig [ ] ;
16- evaluationOrder : ResourceConfig [ ] = [ ] ;
17+ stateConfigs : ResourceConfig [ ] | null = null ;
18+ evaluationOrder : string [ ] | null = null ;
19+
1720 sourceMaps ?: SourceMapCache ;
21+ planRequestsCache ?: Map < string , PlanRequest >
1822
1923 static create ( configs : ConfigBlock [ ] , sourceMaps ?: SourceMapCache ) : Project {
2024 const projectConfigs = configs . filter ( ( u ) => u . configClass === ConfigType . PROJECT ) ;
@@ -42,23 +46,67 @@ ${JSON.stringify(projectConfigs, null, 2)}`);
4246 return this . resourceConfigs . length === 0 ;
4347 }
4448
45- findResource ( type : string , name ?: string ) : ResourceConfig | null {
46- return this . resourceConfigs . find ( ( r ) => r . isSame ( type , name ) ) ?? null ;
49+ isStateful ( ) : boolean {
50+ return this . stateConfigs !== null && this . stateConfigs !== undefined && this . stateConfigs . length > 0 ;
4751 }
4852
49- addUniqueNamesForDuplicateResources ( ) {
50- const groups = groupBy ( this . resourceConfigs , ( i ) => i . id )
51- const duplicates = Object . entries ( groups ) . filter ( ( [ , arr ] ) => arr . length > 1 ) ;
53+ filter ( ids : string [ ] ) : Project {
54+ this . resourceConfigs = this . resourceConfigs . filter ( ( r ) => ids . includes ( r . id ) ) ;
55+ this . stateConfigs = this . stateConfigs ? .filter ( ( s ) => ids . includes ( s . id ) ) ?? null ;
5256
53- for ( const [ id , resourceConfigs ] of duplicates ) {
54- if ( resourceConfigs . some ( ( r ) => r . name ) ) {
55- throw new Error ( `Duplicate name found for resource: ${ id } ` ) ;
56- }
57+ return this ;
58+ }
5759
58- for ( const [ idx , r ] of resourceConfigs . entries ( ) ) {
59- r . setName ( String ( idx ) )
60- }
60+ add ( ...configs : ResourceConfig [ ] ) : Project {
61+ this . resourceConfigs . push ( ...configs ) ;
62+
63+ return this ;
64+ }
65+
66+ getPlanRequest ( id : string ) : PlanRequest | undefined {
67+ // One time build a cache for plan requests to make it more efficient
68+ if ( ! this . planRequestsCache ) {
69+ const resourceConfigs = this . resourceConfigs
70+ const stateOnlyConfigs = this . stateConfigs ?. filter ( ( s ) =>
71+ resourceConfigs . find ( ( r ) => r . id === s . id ) === undefined
72+ )
73+
74+ const inputRequests = [
75+ ...this . resourceConfigs . map ( ( r ) => {
76+ return [
77+ r . id , new PlanRequest (
78+ this . isStateful ( ) , r , this . stateConfigs ?. find ( ( r ) => r . id )
79+ )
80+ ] as const
81+ } ) ,
82+ ...( stateOnlyConfigs ?. map ( ( s ) => {
83+ return [
84+ s . id , new PlanRequest ( this . isStateful ( ) , undefined , s )
85+ ] as const
86+ } ) ?? [ ] )
87+ ]
88+
89+ this . planRequestsCache = new Map ( inputRequests )
6190 }
91+
92+ return this . planRequestsCache . get ( id ) ;
93+ }
94+
95+ toUninstallProject ( ) : Project {
96+ const uninstallProject = new Project (
97+ this . projectConfig ,
98+ this . resourceConfigs ,
99+ this . sourceMaps ,
100+ )
101+
102+ uninstallProject . stateConfigs = uninstallProject . resourceConfigs ;
103+ uninstallProject . resourceConfigs = [ ] ;
104+
105+ return uninstallProject ;
106+ }
107+
108+ findResource ( type : string , name ?: string ) : ResourceConfig | null {
109+ return this . resourceConfigs . find ( ( r ) => r . isSame ( type , name ) ) ?? null ;
62110 }
63111
64112 addXCodeToolsConfig ( ) {
@@ -67,7 +115,7 @@ ${JSON.stringify(projectConfigs, null, 2)}`);
67115 } ) ) ;
68116 }
69117
70- validateWithResourceMap ( resourceMap : Map < string , string [ ] > ) {
118+ validateTypeIds ( resourceMap : Map < string , string [ ] > ) {
71119 const invalidConfigs = this . resourceConfigs . filter ( ( c ) => ! resourceMap . get ( c . type ) ) ;
72120
73121 if ( invalidConfigs . length > 0 ) {
@@ -113,12 +161,43 @@ ${JSON.stringify(projectConfigs, null, 2)}`);
113161 }
114162
115163 calculateEvaluationOrder ( ) {
116- this . evaluationOrder = DependencyGraphResolver . calculateDependencyList (
164+ const resourceOrder = DependencyGraphResolver . calculateDependencyList (
117165 this . resourceConfigs ,
118166 ( r ) => r . id ,
119167 ( r ) => r . dependencyIds
120168 ) ;
121169
122- ctx . debug ( `Resource Evaluation Order:\n${ JSON . stringify ( this . evaluationOrder , null , 2 ) } ` ) ;
170+ this . evaluationOrder = resourceOrder ;
171+
172+ if ( ! this . isStateful ( ) ) {
173+ ctx . debug ( `Resource Evaluation Order:\n${ this . evaluationOrder . join ( ',\n' ) } ` ) ;
174+ return ;
175+ }
176+
177+ const stateOrder = DependencyGraphResolver . calculateDependencyList (
178+ this . stateConfigs ! ,
179+ ( r ) => r . id ,
180+ ( r ) => r . dependencyIds
181+ ) ;
182+
183+ const stateOnly = stateOrder . filter ( ( s ) => ! resourceOrder . includes ( s ) )
184+ this . evaluationOrder . push ( ...stateOnly ) ;
185+
186+ ctx . debug ( `Resource Evaluation Order:\n${ this . evaluationOrder . join ( ',\n' ) } ` ) ;
187+ }
188+
189+ private addUniqueNamesForDuplicateResources ( ) {
190+ const groups = groupBy ( this . resourceConfigs , ( i ) => i . id )
191+ const duplicates = Object . entries ( groups ) . filter ( ( [ , arr ] ) => arr . length > 1 ) ;
192+
193+ for ( const [ id , resourceConfigs ] of duplicates ) {
194+ if ( resourceConfigs . some ( ( r ) => r . name ) ) {
195+ throw new Error ( `Duplicate name found for resource: ${ id } ` ) ;
196+ }
197+
198+ for ( const [ idx , r ] of resourceConfigs . entries ( ) ) {
199+ r . setName ( String ( idx ) )
200+ }
201+ }
123202 }
124203}
0 commit comments