@@ -18,7 +18,15 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
1818const  messages  =  Messages . loadMessages ( '@salesforce/plugin-lightning-dev' ,  'lightning.dev.component' ) ; 
1919const  sharedMessages  =  Messages . loadMessages ( '@salesforce/plugin-lightning-dev' ,  'shared.utils' ) ; 
2020
21- export  default  class  LightningDevComponent  extends  SfCommand < void >  { 
21+ export  type  ComponentPreviewResult  =  { 
22+   instanceUrl : string ; 
23+   ldpServerUrl : string ; 
24+   ldpServerId : string ; 
25+   componentName : string ; 
26+   previewUrl : string ; 
27+ } ; 
28+ 
29+ export  default  class  LightningDevComponent  extends  SfCommand < ComponentPreviewResult >  { 
2230  public  static  readonly  summary  =  messages . getMessage ( 'summary' ) ; 
2331  public  static  readonly  description  =  messages . getMessage ( 'description' ) ; 
2432  public  static  readonly  examples  =  messages . getMessages ( 'examples' ) ; 
@@ -29,6 +37,7 @@ export default class LightningDevComponent extends SfCommand<void> {
2937      char : 'n' , 
3038      requiredOrDefaulted : false , 
3139    } ) , 
40+     'api-version' : Flags . orgApiVersion ( ) , 
3241    'client-select' : Flags . boolean ( { 
3342      summary : messages . getMessage ( 'flags.client-select.summary' ) , 
3443      char : 'c' , 
@@ -37,7 +46,7 @@ export default class LightningDevComponent extends SfCommand<void> {
3746    'target-org' : Flags . requiredOrg ( ) , 
3847  } ; 
3948
40-   public  async  run ( ) : Promise < void >  { 
49+   public  async  run ( ) : Promise < ComponentPreviewResult >  { 
4150    const  {  flags }  =  await  this . parse ( LightningDevComponent ) ; 
4251    const  logger  =  await  Logger . child ( this . ctor . name ) ; 
4352    const  project  =  await  SfProject . resolve ( ) ; 
@@ -54,6 +63,7 @@ export default class LightningDevComponent extends SfCommand<void> {
5463    let  componentName  =  flags [ 'name' ] ; 
5564    const  clientSelect  =  flags [ 'client-select' ] ; 
5665    const  targetOrg  =  flags [ 'target-org' ] ; 
66+     const  apiVersion  =  flags [ 'api-version' ] ; 
5767
5868    const  {  ldpServerId,  ldpServerToken }  =  await  PreviewUtils . initializePreviewConnection ( targetOrg ) ; 
5969
@@ -62,44 +72,56 @@ export default class LightningDevComponent extends SfCommand<void> {
6272    logger . debug ( `Next available ports are http=${ serverPorts . httpPort } ${ serverPorts . httpsPort }  ) ; 
6373
6474    logger . debug ( 'Determining Local Dev Server url' ) ; 
65-     const  ldpServerUrl  =  PreviewUtils . generateWebSocketUrlForLocalDevServer ( Platform . desktop ,  serverPorts ,  logger ) ; 
75+     let  ldpServerUrl ; 
76+ 
77+     // In Code Builder, we cannot go to localhost - we need to use a proxy URI to get to the ldpServer 
78+     if  ( process . env . SF_CONTAINER_MODE  &&  process . env . VSCODE_PROXY_URI )  { 
79+       logger . debug ( 'In Code Builder Mode - using proxy URI' ) ; 
80+       ldpServerUrl  =  process . env . VSCODE_PROXY_URI . replace ( 'https://' ,  'ws://' ) . replace ( 
81+         '{{port}}' , 
82+         `${ serverPorts . httpPort }  
83+       ) ; 
84+     }  else  { 
85+       // Default behavior 
86+       ldpServerUrl  =  PreviewUtils . generateWebSocketUrlForLocalDevServer ( Platform . desktop ,  serverPorts ,  logger ) ; 
87+     } 
6688    logger . debug ( `Local Dev Server url is ${ ldpServerUrl }  ) ; 
6789
68-     const  namespacePaths  =  await  ComponentUtils . getNamespacePaths ( project ) ; 
69-     const  componentPaths  =  await  ComponentUtils . getAllComponentPaths ( namespacePaths ) ; 
70-     if  ( ! componentPaths )  { 
71-       throw  new  Error ( messages . getMessage ( 'error.directory' ) ) ; 
72-     } 
90+     if  ( ! clientSelect )  { 
91+       const  namespacePaths  =  await  ComponentUtils . getNamespacePaths ( project ) ; 
92+       const  componentPaths  =  await  ComponentUtils . getAllComponentPaths ( namespacePaths ) ; 
93+       if  ( ! componentPaths )  { 
94+         throw  new  Error ( messages . getMessage ( 'error.directory' ) ) ; 
95+       } 
7396
74-     const  components  =  ( 
75-       await  Promise . all ( 
76-         componentPaths . map ( async  ( componentPath )  =>  { 
77-           let  xml ; 
78- 
79-           try  { 
80-             xml  =  await  ComponentUtils . getComponentMetadata ( componentPath ) ; 
81-           }  catch  ( err )  { 
82-             this . warn ( messages . getMessage ( 'error.component-metadata' ,  [ componentPath ] ) ) ; 
83-           } 
84- 
85-           // components must have meta xml to be previewed 
86-           if  ( ! xml )  { 
87-             return  undefined ; 
88-           } 
89- 
90-           const  name  =  path . basename ( componentPath ) ; 
91-           const  label  =  ComponentUtils . componentNameToTitleCase ( name ) ; 
92- 
93-           return  { 
94-             name, 
95-             label : xml . LightningComponentBundle . masterLabel  ??  label , 
96-             description : xml . LightningComponentBundle . description  ??  '' , 
97-           } ; 
98-         } ) 
99-       ) 
100-     ) . filter ( ( component )  =>  ! ! component ) ; 
97+        const  components  =  ( 
98+          await  Promise . all ( 
99+            componentPaths . map ( async  ( componentPath )  =>  { 
100+              let  xml ; 
101+ 
102+              try  { 
103+                xml  =  await  ComponentUtils . getComponentMetadata ( componentPath ) ; 
104+              }  catch  ( err )  { 
105+                this . warn ( messages . getMessage ( 'error.component-metadata' ,  [ componentPath ] ) ) ; 
106+              } 
107+ 
108+              // components must have meta xml to be previewed 
109+              if  ( ! xml )  { 
110+                return  undefined ; 
111+              } 
112+ 
113+              const  name  =  path . basename ( componentPath ) ; 
114+              const  label  =  ComponentUtils . componentNameToTitleCase ( name ) ; 
115+ 
116+              return  { 
117+                name, 
118+                label : xml . LightningComponentBundle . masterLabel  ??  label , 
119+                description : xml . LightningComponentBundle . description  ??  '' , 
120+              } ; 
121+            } ) 
122+          ) 
123+        ) . filter ( ( component )  =>  ! ! component ) ; 
101124
102-     if  ( ! clientSelect )  { 
103125      if  ( componentName )  { 
104126        // validate that the component exists before launching the server 
105127        const  match  =  components . find ( 
@@ -129,7 +151,31 @@ export default class LightningDevComponent extends SfCommand<void> {
129151      targetOrgArg 
130152    ) ; 
131153
132-     // Open the browser and navigate to the right page 
133-     await  this . config . runCommand ( 'org:open' ,  launchArguments ) ; 
154+     // Construct and log the full URL that will be opened 
155+     const  connection  =  targetOrg . getConnection ( apiVersion ) ; 
156+ 
157+     const  previewUrl  =  PreviewUtils . generateComponentPreviewUrl ( 
158+       connection . instanceUrl , 
159+       ldpServerUrl , 
160+       ldpServerId , 
161+       componentName , 
162+       false 
163+     ) ; 
164+ 
165+     // Prepare the result for JSON output 
166+     const  result : ComponentPreviewResult  =  { 
167+       instanceUrl : connection . instanceUrl , 
168+       ldpServerUrl, 
169+       ldpServerId, 
170+       componentName : componentName  ??  '' , 
171+       previewUrl, 
172+     } ; 
173+ 
174+     // Open the browser and navigate to the right page (unless OPEN_BROWSER is set to true) 
175+     if  ( process . env . OPEN_BROWSER  !==  'false' )  { 
176+       await  this . config . runCommand ( 'org:open' ,  launchArguments ) ; 
177+     } 
178+ 
179+     return  result ; 
134180  } 
135181} 
0 commit comments