-
Notifications
You must be signed in to change notification settings - Fork 388
Extends 'teams app remove' command with support for name option. Closes #5445 #5454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -2,6 +2,7 @@ import { Cli } from '../../../../cli/Cli.js'; | |||||||
| import { Logger } from '../../../../cli/Logger.js'; | ||||||||
| import GlobalOptions from '../../../../GlobalOptions.js'; | ||||||||
| import request, { CliRequestOptions } from '../../../../request.js'; | ||||||||
| import { formatting } from '../../../../utils/formatting.js'; | ||||||||
| import { validation } from '../../../../utils/validation.js'; | ||||||||
| import GraphCommand from '../../../base/GraphCommand.js'; | ||||||||
| import commands from '../../commands.js'; | ||||||||
|
|
@@ -12,7 +13,8 @@ interface CommandArgs { | |||||||
|
|
||||||||
| interface Options extends GlobalOptions { | ||||||||
| force?: boolean; | ||||||||
| id: string; | ||||||||
| id?: string; | ||||||||
| name?: string; | ||||||||
| } | ||||||||
|
|
||||||||
| class TeamsAppRemoveCommand extends GraphCommand { | ||||||||
|
|
@@ -30,20 +32,26 @@ class TeamsAppRemoveCommand extends GraphCommand { | |||||||
| this.#initTelemetry(); | ||||||||
| this.#initOptions(); | ||||||||
| this.#initValidators(); | ||||||||
| this.#initOptionSets(); | ||||||||
| } | ||||||||
|
|
||||||||
| #initTelemetry(): void { | ||||||||
| this.telemetry.push((args: CommandArgs) => { | ||||||||
| Object.assign(this.telemetryProperties, { | ||||||||
| force: (!(!args.options.force)).toString() | ||||||||
| force: (!(!args.options.force)).toString(), | ||||||||
| id: typeof args.options.id !== 'undefined', | ||||||||
| name: typeof args.options.name !== 'undefined' | ||||||||
| }); | ||||||||
| }); | ||||||||
| } | ||||||||
|
|
||||||||
| #initOptions(): void { | ||||||||
| this.options.unshift( | ||||||||
| { | ||||||||
| option: '-i, --id <id>' | ||||||||
| option: '-i, --id [id]' | ||||||||
| }, | ||||||||
| { | ||||||||
| option: '-n, --name [name]' | ||||||||
| }, | ||||||||
| { | ||||||||
| option: '-f, --force' | ||||||||
|
|
@@ -54,7 +62,7 @@ class TeamsAppRemoveCommand extends GraphCommand { | |||||||
| #initValidators(): void { | ||||||||
| this.validators.push( | ||||||||
| async (args: CommandArgs) => { | ||||||||
| if (!validation.isValidGuid(args.options.id)) { | ||||||||
| if (args.options.id && !validation.isValidGuid(args.options.id)) { | ||||||||
| return `${args.options.id} is not a valid GUID`; | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -63,22 +71,26 @@ class TeamsAppRemoveCommand extends GraphCommand { | |||||||
| ); | ||||||||
| } | ||||||||
|
|
||||||||
| public async commandAction(logger: Logger, args: CommandArgs): Promise<void> { | ||||||||
| const { id: appId } = args.options; | ||||||||
| #initOptionSets(): void { | ||||||||
| this.optionSets.push({ options: ['id', 'name'] }); | ||||||||
| } | ||||||||
|
|
||||||||
| public async commandAction(logger: Logger, args: CommandArgs): Promise<void> { | ||||||||
| const removeApp = async (): Promise<void> => { | ||||||||
| if (this.verbose) { | ||||||||
| await logger.logToStderr(`Removing app with ID ${args.options.id}`); | ||||||||
| } | ||||||||
| try { | ||||||||
| const appId: string = await this.getAppId(args.options); | ||||||||
|
|
||||||||
| const requestOptions: CliRequestOptions = { | ||||||||
| url: `${this.resource}/v1.0/appCatalogs/teamsApps/${appId}`, | ||||||||
| headers: { | ||||||||
| accept: 'application/json;odata.metadata=none' | ||||||||
| if (this.verbose) { | ||||||||
| await logger.logToStderr(`Removing app with ID ${args.options.id}`); | ||||||||
| } | ||||||||
| }; | ||||||||
|
|
||||||||
| try { | ||||||||
| const requestOptions: CliRequestOptions = { | ||||||||
| url: `${this.resource}/v1.0/appCatalogs/teamsApps/${appId}`, | ||||||||
| headers: { | ||||||||
| accept: 'application/json;odata.metadata=none' | ||||||||
| } | ||||||||
| }; | ||||||||
|
|
||||||||
| await request.delete(requestOptions); | ||||||||
| } | ||||||||
| catch (err: any) { | ||||||||
|
|
@@ -94,14 +106,46 @@ class TeamsAppRemoveCommand extends GraphCommand { | |||||||
| type: 'confirm', | ||||||||
| name: 'continue', | ||||||||
| default: false, | ||||||||
| message: `Are you sure you want to remove the Teams app ${appId} from the app catalog?` | ||||||||
| message: `Are you sure you want to remove the Teams app ${args.options.id || args.options.name} from the app catalog?` | ||||||||
| }); | ||||||||
|
|
||||||||
| if (result.continue) { | ||||||||
| await removeApp(); | ||||||||
| } | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| private async getAppId(options: Options): Promise<any> { | ||||||||
| if (options.id) { | ||||||||
| return options.id; | ||||||||
| } | ||||||||
|
|
||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add a verbose logging line here |
||||||||
| const requestOptions: CliRequestOptions = { | ||||||||
| url: `${this.resource}/v1.0/appCatalogs/teamsApps?$filter=displayName eq '${formatting.encodeQueryParameter(options.name as string)}'&$select=id`, | ||||||||
| headers: { | ||||||||
| accept: 'application/json;odata.metadata=none' | ||||||||
| }, | ||||||||
| responseType: 'json' | ||||||||
| }; | ||||||||
|
|
||||||||
| const response = await request.get<{ value: { id: string; }[] }>(requestOptions); | ||||||||
| const app: { id: string; } | undefined = response.value[0]; | ||||||||
|
|
||||||||
| if (!app) { | ||||||||
| throw `The specified Teams app does not exist`; | ||||||||
| } | ||||||||
|
|
||||||||
| if (response.value.length > 1) { | ||||||||
| const resultAsKeyValuePair: any = {}; | ||||||||
| response.value.forEach((obj) => { | ||||||||
| resultAsKeyValuePair[obj.id] = obj; | ||||||||
| }); | ||||||||
|
|
||||||||
| return Cli.handleMultipleResultsFound(`Multiple Teams apps with name '${options.name}' found.`, resultAsKeyValuePair); | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should await this and type the result.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, and we also missed a test case for this :-) |
||||||||
| } | ||||||||
|
|
||||||||
| return app.id; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| export default new TeamsAppRemoveCommand(); | ||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.