44 * Licensed under the BSD 3-Clause license.
55 * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66 */
7- import { Messages , SfError } from '@salesforce/core' ;
8- import { SfCommand , Flags } from '@salesforce/sf-plugins-core' ;
7+ import { AuthInfo , AuthRemover , Messages , Org , SfError , StateAggregator } from '@salesforce/core' ;
8+ import { Flags , SfCommand } from '@salesforce/sf-plugins-core' ;
99
1010Messages . importMessagesDirectory ( __dirname ) ;
1111const messages = Messages . loadMessages ( '@salesforce/plugin-org' , 'delete_sandbox' ) ;
@@ -14,16 +14,19 @@ export interface SandboxDeleteResponse {
1414 orgId : string ;
1515 username : string ;
1616}
17+
1718export default class EnvDeleteSandbox extends SfCommand < SandboxDeleteResponse > {
1819 public static readonly summary = messages . getMessage ( 'summary' ) ;
1920 public static readonly description = messages . getMessage ( 'description' ) ;
2021 public static readonly examples = messages . getMessages ( 'examples' ) ;
2122 public static readonly aliases = [ 'env:delete:sandbox' ] ;
2223 public static readonly deprecateAliases = true ;
2324 public static readonly flags = {
24- 'target-org' : Flags . requiredOrg ( {
25- summary : messages . getMessage ( 'flags.target-org.summary' ) ,
25+ 'target-org' : Flags . string ( {
26+ // we're recreating the flag without all the validation
27+ // eslint-disable-next-line sf-plugin/dash-o
2628 char : 'o' ,
29+ summary : messages . getMessage ( 'flags.target-org.summary' ) ,
2730 required : true ,
2831 } ) ,
2932 'no-prompt' : Flags . boolean ( {
@@ -34,28 +37,40 @@ export default class EnvDeleteSandbox extends SfCommand<SandboxDeleteResponse> {
3437
3538 public async run ( ) : Promise < SandboxDeleteResponse > {
3639 const flags = ( await this . parse ( EnvDeleteSandbox ) ) . flags ;
37- const org = flags [ 'target-org' ] ;
38- const username = org . getUsername ( ) ;
40+ const username = // from -o alias -> -o username -> [default username]
41+ ( await StateAggregator . getInstance ( ) ) . aliases . getUsername ( flags [ 'target-org' ] ?? '' ) ??
42+ flags [ 'target-org' ] ??
43+ ( this . configAggregator . getPropertyValue ( 'target-org' ) as string ) ;
3944 if ( ! username ) {
4045 throw new SfError ( 'The org does not have a username.' ) ;
4146 }
4247
43- if ( ! ( await org . isSandbox ( ) ) ) {
48+ const orgId = ( await AuthInfo . create ( { username } ) ) . getFields ( ) . orgId as string ;
49+ const isSandbox = await ( await StateAggregator . getInstance ( ) ) . sandboxes . hasFile ( orgId ) ;
50+
51+ if ( ! isSandbox ) {
4452 throw messages . createError ( 'error.isNotSandbox' , [ username ] ) ;
4553 }
4654
4755 if ( flags [ 'no-prompt' ] || ( await this . confirm ( messages . getMessage ( 'prompt.confirm' , [ username ] ) ) ) ) {
4856 try {
57+ const org = await Org . create ( { aliasOrUsername : username } ) ;
4958 await org . delete ( ) ;
5059 this . logSuccess ( messages . getMessage ( 'success' , [ username ] ) ) ;
5160 } catch ( e ) {
52- if ( e instanceof Error && e . name === 'SandboxNotFound' ) {
61+ if ( e instanceof Error && e . name === 'DomainNotFoundError' ) {
62+ // the org has expired, so remote operations won't work
63+ // let's clean up the files locally
64+ const authRemover = await AuthRemover . create ( ) ;
65+ await authRemover . removeAuth ( username ) ;
66+ this . logSuccess ( messages . getMessage ( 'success.Idempotent' , [ username ] ) ) ;
67+ } else if ( e instanceof Error && e . name === 'SandboxNotFound' ) {
5368 this . logSuccess ( messages . getMessage ( 'success.Idempotent' , [ username ] ) ) ;
5469 } else {
5570 throw e ;
5671 }
5772 }
5873 }
59- return { username, orgId : org . getOrgId ( ) } ;
74+ return { username, orgId } ;
6075 }
6176}
0 commit comments