@@ -4,9 +4,9 @@ import {Output} from '@/application/cli/io/output';
44import { Input } from '@/application/cli/io/input' ;
55import { Sdk } from '@/application/project/sdk/sdk' ;
66import { ProjectConfiguration } from '@/application/project/configuration/projectConfiguration' ;
7- import { OrganizationOptions } from '@/application/cli/form/organization/organizationForm' ;
7+ import { OrganizationOptions , SelectedOrganization } from '@/application/cli/form/organization/organizationForm' ;
88import { ApplicationOptions } from '@/application/cli/form/application/applicationForm' ;
9- import { WorkspaceOptions } from '@/application/cli/form/workspace/workspaceForm' ;
9+ import { SelectedWorkspace , WorkspaceOptions } from '@/application/cli/form/workspace/workspaceForm' ;
1010import { Form } from '@/application/cli/form/form' ;
1111import { ConfigurationManager } from '@/application/project/configuration/manager/configurationManager' ;
1212import { UserApi } from '@/application/api/user' ;
@@ -67,7 +67,7 @@ export class InitCommand implements Command<InitInput> {
6767 const { configurationManager, platformProvider, sdkProvider, io : { output} } = this . config ;
6868
6969 const currentConfiguration = input . override !== true && await configurationManager . isInitialized ( )
70- ? await configurationManager . loadPartial ( )
70+ ? { ... await configurationManager . loadPartial ( ) }
7171 : null ;
7272
7373 const platform = await platformProvider . get ( ) ;
@@ -88,36 +88,36 @@ export class InitCommand implements Command<InitInput> {
8888
8989 const organization = await this . getOrganization (
9090 { new : input . new === 'organization' } ,
91- input . organization ?? currentConfiguration ?. organization ,
91+ input . new === 'organization'
92+ ? undefined
93+ : ( input . organization ?? currentConfiguration ?. organization ) ,
9294 ) ;
9395
94- if ( organization === null ) {
95- throw new HelpfulError ( `Organization not found: ${ input . organization } ` , {
96- reason : ErrorReason . INVALID_INPUT ,
97- } ) ;
98- }
99-
10096 const workspace = await this . getWorkspace (
10197 {
10298 organization : organization ,
103- new : input . new === 'workspace' ,
99+ new : organization . new !== true && input . new === 'workspace' ,
104100 } ,
105- input . workspace ?? currentConfiguration ?. workspace ,
101+ ( input . new === 'workspace' || organization . new === true )
102+ ? undefined
103+ : ( input . workspace ?? currentConfiguration ?. workspace ) ,
106104 ) ;
107105
108106 const applicationOptions : Omit < ApplicationOptions , 'environment' > = {
109107 organization : organization ,
110108 workspace : workspace ,
111109 platform : platform ?? Platform . JAVASCRIPT ,
112- new : input . new === 'application' ,
110+ new : workspace . new !== true && input . new === 'application' ,
113111 } ;
114112
115113 const devApplication = await this . getApplication (
116114 {
117115 ...applicationOptions ,
118116 environment : ApplicationEnvironment . DEVELOPMENT ,
119117 } ,
120- input . devApplication ?? currentConfiguration ?. applications ?. development ,
118+ ( input . new !== undefined || workspace . new === true )
119+ ? undefined
120+ : ( input . devApplication ?? currentConfiguration ?. applications ?. development ) ,
121121 ) ;
122122
123123 const updatedConfiguration : ProjectConfiguration = {
@@ -133,17 +133,17 @@ export class InitCommand implements Command<InitInput> {
133133 paths : currentConfiguration ?. paths ?? { } ,
134134 } ;
135135
136- const defaultWebsite = workspace . website ?? organization . website ?? undefined ;
137-
138- if ( defaultWebsite !== undefined && new URL ( defaultWebsite ) . hostname !== 'localhost' ) {
139- const prodApplication = await this . getApplication (
140- {
141- ...applicationOptions ,
142- environment : ApplicationEnvironment . PRODUCTION ,
143- } ,
144- input . prodApplication ?? currentConfiguration ?. applications ?. production ,
145- ) ;
136+ const prodApplication = await this . resolveApplication (
137+ {
138+ ...applicationOptions ,
139+ environment : ApplicationEnvironment . PRODUCTION ,
140+ } ,
141+ input . new !== undefined
142+ ? undefined
143+ : ( input . prodApplication ?? currentConfiguration ?. applications ?. production ) ,
144+ ) ;
146145
146+ if ( prodApplication !== null ) {
147147 updatedConfiguration . applications . production = prodApplication . slug ;
148148 }
149149
@@ -170,7 +170,10 @@ export class InitCommand implements Command<InitInput> {
170170 ) ;
171171 }
172172
173- private async getOrganization ( options : OrganizationOptions , organizationSlug ?: string ) : Promise < Organization > {
173+ private async getOrganization (
174+ options : OrganizationOptions ,
175+ organizationSlug ?: string ,
176+ ) : Promise < SelectedOrganization > {
174177 const { form, api} = this . config ;
175178
176179 const organization = organizationSlug === undefined
@@ -194,7 +197,7 @@ export class InitCommand implements Command<InitInput> {
194197 return organization ;
195198 }
196199
197- private async getWorkspace ( options : WorkspaceOptions , workspaceSlug ?: string ) : Promise < Workspace > {
200+ private async getWorkspace ( options : WorkspaceOptions , workspaceSlug ?: string ) : Promise < SelectedWorkspace > {
198201 const { form, api} = this . config ;
199202
200203 const workspace = workspaceSlug === undefined
@@ -221,6 +224,40 @@ export class InitCommand implements Command<InitInput> {
221224 return workspace ;
222225 }
223226
227+ private async resolveApplication ( options : ApplicationOptions , applicationSlug ?: string ) : Promise < Application | null > {
228+ const { api} = this . config ;
229+
230+ const defaultWebsite = options . workspace . website ?? options . organization . website ?? undefined ;
231+ // Prod application can only be created if the default website is not localhost
232+ const isPublicUrl = defaultWebsite !== undefined && new URL ( defaultWebsite ) . hostname !== 'localhost' ;
233+
234+ if (
235+ ( options . environment === ApplicationEnvironment . DEVELOPMENT || isPublicUrl )
236+ || applicationSlug !== undefined
237+ || options . new === true
238+ ) {
239+ // Continue to the regular flow if either creating a new application
240+ // is possible (dev environment or public URL), a specific application slug is provided,
241+ // or the user wants to create a new application.
242+ return this . getApplication ( options , applicationSlug ) ;
243+ }
244+
245+ const applications = api . workspace . getApplications ( {
246+ organizationSlug : options . organization . slug ,
247+ workspaceSlug : options . workspace . slug ,
248+ } ) ;
249+
250+ for ( const application of await applications ) {
251+ if ( application . environment === options . environment ) {
252+ // There is an existing application for the specified environment,
253+ // auto-select it or prompt the user to select it.
254+ return this . getApplication ( options , applicationSlug ) ;
255+ }
256+ }
257+
258+ return null ;
259+ }
260+
224261 private async getApplication ( options : ApplicationOptions , applicationSlug ?: string ) : Promise < Application > {
225262 const { form, api} = this . config ;
226263
0 commit comments