@pnp/cli-microsoft365 5.1.0 → 5.2.0-beta.4df87d9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.mocharc.json +1 -0
  3. package/dist/Auth.js +2 -1
  4. package/dist/Command.js +10 -1
  5. package/dist/cli/Cli.js +2 -18
  6. package/dist/m365/app/commands/app-get.js +3 -0
  7. package/dist/m365/cli/commands/cli-reconsent.js +20 -2
  8. package/dist/m365/cli/commands/config/config-set.js +1 -0
  9. package/dist/m365/pp/commands/environment/environment-list.js +57 -0
  10. package/dist/m365/pp/commands.js +1 -0
  11. package/dist/m365/spfx/commands/project/project-upgrade.js +4 -1
  12. package/dist/m365/spo/commands/file/file-checkout.js +2 -2
  13. package/dist/m365/spo/commands/site/site-remove.js +4 -3
  14. package/dist/m365/spo/commands/tenant/tenant-recyclebinitem-restore.js +10 -44
  15. package/dist/m365/spo/commands/tenant/tenant-settings-set.js +21 -0
  16. package/dist/m365/teams/commands/channel/channel-add.js +44 -14
  17. package/dist/m365/teams/commands/channel/channel-list.js +11 -1
  18. package/dist/m365/teams/commands/channel/channel-member-set.js +203 -0
  19. package/dist/m365/teams/commands/channel/channel-membership-list.js +150 -0
  20. package/dist/m365/teams/commands/chat/chat-get.js +143 -0
  21. package/dist/m365/teams/commands/chat/chat-message-send.js +5 -30
  22. package/dist/m365/teams/commands/chat/chatUtil.js +62 -0
  23. package/dist/m365/teams/commands.js +3 -0
  24. package/dist/settingsNames.js +1 -0
  25. package/dist/utils/index.js +1 -0
  26. package/dist/utils/md.js +81 -0
  27. package/docs/docs/cmd/pp/environment/environment-list.md +37 -0
  28. package/docs/docs/cmd/spo/tenant/tenant-settings-set.md +52 -33
  29. package/docs/docs/cmd/teams/channel/channel-add.md +18 -0
  30. package/docs/docs/cmd/teams/channel/channel-list.md +11 -2
  31. package/docs/docs/cmd/teams/channel/channel-member-set.md +51 -0
  32. package/docs/docs/cmd/teams/channel/channel-membership-list.md +48 -0
  33. package/docs/docs/cmd/teams/chat/chat-get.md +53 -0
  34. package/npm-shrinkwrap.json +24 -738
  35. package/package.json +3 -4
package/.eslintrc.js CHANGED
@@ -37,6 +37,7 @@ const dictionary = [
37
37
  'list',
38
38
  'management',
39
39
  'member',
40
+ 'membership',
40
41
  'messaging',
41
42
  'news',
42
43
  'oauth2',
package/.mocharc.json CHANGED
@@ -5,5 +5,6 @@
5
5
  "spec": "dist/**/*.spec.js",
6
6
  "require": "source-map-support/register",
7
7
  "watch": "dist/**/*.js",
8
+ "timeout": 10000,
8
9
  "logpanel": true
9
10
  }
package/dist/Auth.js CHANGED
@@ -301,7 +301,8 @@ class Auth {
301
301
  logger.logToStderr('');
302
302
  }
303
303
  logger.log(response.message);
304
- if (cli_1.Cli.getInstance().getSettingWithDefaultValue(settingsNames_1.settingsNames.autoOpenBrowserOnLogin, false)) {
304
+ if (cli_1.Cli.getInstance().getSettingWithDefaultValue(settingsNames_1.settingsNames.autoOpenBrowserOnLogin, false)
305
+ || cli_1.Cli.getInstance().getSettingWithDefaultValue(settingsNames_1.settingsNames.autoOpenLinksInBrowser, false)) {
305
306
  // _open is never set before hitting this line, but this check
306
307
  // is implemented so that we can support lazy loading
307
308
  // but also stub it for testing
package/dist/Command.js CHANGED
@@ -47,6 +47,10 @@ class Command {
47
47
  logger.logToStderr(chalk.yellow(`Command '${deprecated}' is deprecated. Please use '${recommended}' instead`));
48
48
  }
49
49
  }
50
+ warn(logger, warning) {
51
+ const chalk = require('chalk');
52
+ logger.logToStderr(chalk.yellow(warning));
53
+ }
50
54
  getUsedCommandName() {
51
55
  const cli = cli_1.Cli.getInstance();
52
56
  const commandName = this.getCommandName();
@@ -144,7 +148,12 @@ class Command {
144
148
  return __awaiter(this, void 0, void 0, function* () {
145
149
  });
146
150
  }
147
- getCommandName() {
151
+ getCommandName(alias) {
152
+ var _a;
153
+ if (alias &&
154
+ ((_a = this.alias()) === null || _a === void 0 ? void 0 : _a.includes(alias))) {
155
+ return alias;
156
+ }
148
157
  let commandName = this.name;
149
158
  let pos = commandName.indexOf('<');
150
159
  const pos1 = commandName.indexOf('[');
package/dist/cli/Cli.js CHANGED
@@ -202,7 +202,7 @@ class Cli {
202
202
  // the command to execute
203
203
  const cli = Cli.getInstance();
204
204
  const parentCommandName = cli.currentCommandName;
205
- cli.currentCommandName = command.getCommandName();
205
+ cli.currentCommandName = command.getCommandName(cli.currentCommandName);
206
206
  command.action(logger, args, (err) => {
207
207
  // restore the original command name
208
208
  cli.currentCommandName = parentCommandName;
@@ -586,23 +586,7 @@ class Cli {
586
586
  helpFilePath = path.join(...pathChunks);
587
587
  if (fs.existsSync(helpFilePath)) {
588
588
  Cli.log();
589
- // because of prism, loading markshell slows down CLI a lot
590
- // let's lazy-load it only when it's needed (help was requested)
591
- const markshell = require('markshell');
592
- const chalk = require('chalk');
593
- const theme = markshell.getTheme();
594
- const admonitionStyles = theme.admonitions.getStyles();
595
- admonitionStyles.indent.beforeIndent = 0;
596
- admonitionStyles.indent.titleIndent = 3;
597
- admonitionStyles.indent.afterIndent = 0;
598
- theme.admonitions.setStyles(admonitionStyles);
599
- theme.indents.definitionList = 2;
600
- theme.headline = chalk.white;
601
- theme.inlineCode = chalk.cyan;
602
- theme.sourceCodeTheme = 'solarizelight';
603
- theme.includePath = path.join(this.commandsFolder, '..', '..', 'docs');
604
- markshell.setTheme(theme);
605
- Cli.log(markshell.toRawContent(helpFilePath));
589
+ Cli.log(utils_1.md.md2plain(fs.readFileSync(helpFilePath, 'utf8'), path.join(this.commandsFolder, '..', '..', 'docs')));
606
590
  }
607
591
  }
608
592
  printAvailableCommands() {
@@ -21,6 +21,9 @@ class AppGetCommand extends AppCommand_1.default {
21
21
  cli_1.Cli
22
22
  .executeCommandWithOutput(AadAppGetCommand, { options: Object.assign(Object.assign({}, options), { _: [] }) })
23
23
  .then((appGetOutput) => {
24
+ if (this.verbose) {
25
+ logger.logToStderr(appGetOutput.stderr);
26
+ }
24
27
  logger.log(JSON.parse(appGetOutput.stdout));
25
28
  cb();
26
29
  }, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cli_1 = require("../../../cli");
3
4
  const config_1 = require("../../../config");
5
+ const settingsNames_1 = require("../../../settingsNames");
4
6
  const AnonymousCommand_1 = require("../../base/AnonymousCommand");
5
7
  const commands_1 = require("../commands");
6
8
  class CliReconsentCommand extends AnonymousCommand_1.default {
@@ -11,8 +13,24 @@ class CliReconsentCommand extends AnonymousCommand_1.default {
11
13
  return 'Returns Azure AD URL to open in the browser to re-consent CLI for Microsoft 365 permissions';
12
14
  }
13
15
  commandAction(logger, args, cb) {
14
- logger.log(`To re-consent the PnP Microsoft 365 Management Shell Azure AD application navigate in your web browser to https://login.microsoftonline.com/${config_1.default.tenant}/oauth2/authorize?client_id=${config_1.default.cliAadAppId}&response_type=code&prompt=admin_consent`);
15
- cb();
16
+ const url = `https://login.microsoftonline.com/${config_1.default.tenant}/oauth2/authorize?client_id=${config_1.default.cliAadAppId}&response_type=code&prompt=admin_consent`;
17
+ if (cli_1.Cli.getInstance().getSettingWithDefaultValue(settingsNames_1.settingsNames.autoOpenLinksInBrowser, false) === false) {
18
+ logger.log(`To re-consent the PnP Microsoft 365 Management Shell Azure AD application navigate in your web browser to ${url}`);
19
+ return cb();
20
+ }
21
+ logger.log(`Opening the following page in your browser: ${url}`);
22
+ // _open is never set before hitting this line, but this check
23
+ // is implemented so that we can support lazy loading
24
+ // but also stub it for testing
25
+ /* c8 ignore next 3 */
26
+ if (!this._open) {
27
+ this._open = require('open');
28
+ }
29
+ this._open(url).then(() => {
30
+ cb();
31
+ }, (error) => {
32
+ this.handleRejectedODataJsonPromise(error, logger, cb);
33
+ });
16
34
  }
17
35
  }
18
36
  module.exports = new CliReconsentCommand();
@@ -20,6 +20,7 @@ class CliConfigSetCommand extends AnonymousCommand_1.default {
20
20
  let value = undefined;
21
21
  switch (args.options.key) {
22
22
  case settingsNames_1.settingsNames.autoOpenBrowserOnLogin:
23
+ case settingsNames_1.settingsNames.autoOpenLinksInBrowser:
23
24
  case settingsNames_1.settingsNames.copyDeviceCodeToClipboard:
24
25
  case settingsNames_1.settingsNames.csvHeader:
25
26
  case settingsNames_1.settingsNames.csvQuoted:
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const request_1 = require("../../../../request");
4
+ const PowerPlatformCommand_1 = require("../../../base/PowerPlatformCommand");
5
+ const commands_1 = require("../../commands");
6
+ class PpEnvironmentListCommand extends PowerPlatformCommand_1.default {
7
+ get name() {
8
+ return commands_1.default.ENVIRONMENT_LIST;
9
+ }
10
+ get description() {
11
+ return 'Lists Microsoft Power Platform environments';
12
+ }
13
+ defaultProperties() {
14
+ return ['name', 'displayName'];
15
+ }
16
+ commandAction(logger, args, cb) {
17
+ if (this.verbose) {
18
+ logger.logToStderr(`Retrieving list of Microsoft Power Platform environments...`);
19
+ }
20
+ let url = '';
21
+ if (args.options.asAdmin) {
22
+ url = `${this.resource}/providers/Microsoft.BusinessAppPlatform/scopes/admin/environments`;
23
+ }
24
+ else {
25
+ url = `${this.resource}/providers/Microsoft.BusinessAppPlatform/environments`;
26
+ }
27
+ const requestOptions = {
28
+ url: `${url}?api-version=2020-10-01`,
29
+ headers: {
30
+ accept: 'application/json'
31
+ },
32
+ responseType: 'json'
33
+ };
34
+ request_1.default
35
+ .get(requestOptions)
36
+ .then((res) => {
37
+ if (res.value && res.value.length > 0) {
38
+ res.value.forEach(e => {
39
+ e.displayName = e.properties.displayName;
40
+ });
41
+ logger.log(res.value);
42
+ }
43
+ cb();
44
+ }, (rawRes) => this.handleRejectedODataJsonPromise(rawRes, logger, cb));
45
+ }
46
+ options() {
47
+ const options = [
48
+ {
49
+ option: '-a, --asAdmin [teamId]'
50
+ }
51
+ ];
52
+ const parentOptions = super.options();
53
+ return options.concat(parentOptions);
54
+ }
55
+ }
56
+ module.exports = new PpEnvironmentListCommand();
57
+ //# sourceMappingURL=environment-list.js.map
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const prefix = 'pp';
4
4
  exports.default = {
5
+ ENVIRONMENT_LIST: `${prefix} environment list`,
5
6
  MANAGEMENTAPP_ADD: `${prefix} managementapp add`
6
7
  };
7
8
  //# sourceMappingURL=commands.js.map
@@ -242,6 +242,9 @@ class SpfxProjectUpgradeCommand extends base_project_command_1.BaseProjectComman
242
242
  }
243
243
  });
244
244
  switch (args.options.output) {
245
+ case 'text':
246
+ logger.log(this.getTextReport(findingsToReport));
247
+ break;
245
248
  case 'json':
246
249
  logger.log(findingsToReport);
247
250
  break;
@@ -252,7 +255,7 @@ class SpfxProjectUpgradeCommand extends base_project_command_1.BaseProjectComman
252
255
  logger.log(this.getMdReport(findingsToReport));
253
256
  break;
254
257
  default:
255
- logger.log(this.getTextReport(findingsToReport));
258
+ logger.log(findingsToReport);
256
259
  }
257
260
  cb();
258
261
  }
@@ -62,10 +62,10 @@ class SpoFileCheckoutCommand extends SpoCommand_1.default {
62
62
  }
63
63
  }
64
64
  if (args.options.id && args.options.fileUrl) {
65
- return 'Specify either URL or UniqueId but not both';
65
+ return 'Specify either id or fileUrl but not both';
66
66
  }
67
67
  if (!args.options.id && !args.options.fileUrl) {
68
- return 'Specify URL or UniqueId, one is required';
68
+ return 'Specify id or fileUrl, one is required';
69
69
  }
70
70
  return true;
71
71
  }
@@ -50,7 +50,7 @@ class SpoSiteRemoveCommand extends SpoCommand_1.default {
50
50
  if (args.options.skipRecycleBin || args.options.wait) {
51
51
  logger.logToStderr(chalk.yellow(`Entered site is a groupified site. Hence, the parameters 'skipRecycleBin' and 'wait' will not be applicable.`));
52
52
  }
53
- return this.deleteGroupifiedSite(group.id, logger);
53
+ return this.deleteGroup(group.id, logger);
54
54
  })
55
55
  .catch((err) => {
56
56
  if (err.response.status === 404) {
@@ -79,7 +79,8 @@ class SpoSiteRemoveCommand extends SpoCommand_1.default {
79
79
  else {
80
80
  return Promise.reject(err);
81
81
  }
82
- });
82
+ })
83
+ .then(_ => this.deleteSite(args.options.url, args.options.wait, logger));
83
84
  }
84
85
  })
85
86
  .then(_ => cb(), (err) => this.handleRejectedPromise(err, logger, cb));
@@ -296,7 +297,7 @@ class SpoSiteRemoveCommand extends SpoCommand_1.default {
296
297
  }
297
298
  });
298
299
  }
299
- deleteGroupifiedSite(groupId, logger) {
300
+ deleteGroup(groupId, logger) {
300
301
  if (this.verbose) {
301
302
  logger.logToStderr(`Removing Microsoft 365 Group: ${groupId}...`);
302
303
  }
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const config_1 = require("../../../../config");
4
3
  const request_1 = require("../../../../request");
5
4
  const utils_1 = require("../../../../utils");
6
5
  const SpoCommand_1 = require("../../../base/SpoCommand");
@@ -18,58 +17,25 @@ class SpoTenantRecycleBinItemRestoreCommand extends SpoCommand_1.default {
18
17
  return telemetryProps;
19
18
  }
20
19
  commandAction(logger, args, cb) {
21
- this.dots = '';
22
20
  utils_1.spo
23
21
  .getSpoAdminUrl(logger, this.debug)
24
22
  .then((adminUrl) => {
25
- this.spoAdminUrl = adminUrl;
26
- return utils_1.spo.ensureFormDigest(this.spoAdminUrl, logger, this.context, this.debug);
27
- })
28
- .then((res) => {
29
- this.context = res;
30
- if (this.verbose) {
31
- logger.logToStderr(`Restoring deleted site collection ${args.options.url}...`);
32
- }
33
23
  const requestOptions = {
34
- url: `${this.spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
24
+ url: `${adminUrl}/_api/SPOInternalUseOnly.Tenant/RestoreDeletedSite`,
35
25
  headers: {
36
- 'X-RequestDigest': this.context.FormDigestValue
26
+ accept: 'application/json;odata=nometadata',
27
+ 'content-type': 'application/json;charset=utf-8'
37
28
  },
38
- data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config_1.default.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="2" ObjectPathId="1" /><ObjectPath Id="4" ObjectPathId="3" /><Query Id="5" ObjectPathId="3"><Query SelectAllProperties="false"><Properties><Property Name="PollingInterval" ScalarProperty="true" /><Property Name="IsComplete" ScalarProperty="true" /></Properties></Query></Query></Actions><ObjectPaths><Constructor Id="1" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /><Method Id="3" ParentId="1" Name="RestoreDeletedSite"><Parameters><Parameter Type="String">${utils_1.formatting.escapeXml(args.options.url)}</Parameter></Parameters></Method></ObjectPaths></Request>`
29
+ data: {
30
+ siteUrl: args.options.url
31
+ }
39
32
  };
40
33
  return request_1.default.post(requestOptions);
41
34
  })
42
- .then((res) => {
43
- return new Promise((resolve, reject) => {
44
- const json = JSON.parse(res);
45
- const response = json[0];
46
- if (response.ErrorInfo) {
47
- reject(response.ErrorInfo.ErrorMessage);
48
- }
49
- else {
50
- const operation = json[json.length - 1];
51
- const isComplete = operation.IsComplete;
52
- if (!args.options.wait || isComplete) {
53
- resolve();
54
- return;
55
- }
56
- setTimeout(() => {
57
- utils_1.spo.waitUntilFinished({
58
- operationId: JSON.stringify(operation._ObjectIdentity_),
59
- siteUrl: this.spoAdminUrl,
60
- resolve,
61
- reject,
62
- logger,
63
- currentContext: this.context,
64
- dots: this.dots,
65
- debug: this.debug,
66
- verbose: this.verbose
67
- });
68
- }, operation.PollingInterval);
69
- }
70
- });
71
- })
72
- .then(_ => cb(), (err) => this.handleRejectedPromise(err, logger, cb));
35
+ .then(res => {
36
+ logger.log(JSON.parse(res));
37
+ cb();
38
+ }, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
73
39
  }
74
40
  options() {
75
41
  const options = [
@@ -13,6 +13,14 @@ class SpoTenantSettingsSetCommand extends SpoCommand_1.default {
13
13
  get description() {
14
14
  return 'Sets tenant global settings';
15
15
  }
16
+ types() {
17
+ return {
18
+ boolean: [
19
+ 'EnableAzureADB2BIntegration',
20
+ 'SyncAadB2BManagementPolicy'
21
+ ]
22
+ };
23
+ }
16
24
  getTelemetryProperties(args) {
17
25
  const telemetryProps = super.getTelemetryProperties(args);
18
26
  telemetryProps.MinCompatibilityLevel = (!(!args.options.MinCompatibilityLevel)).toString();
@@ -97,6 +105,8 @@ class SpoTenantSettingsSetCommand extends SpoCommand_1.default {
97
105
  telemetryProps.DisabledWebPartIds = (!(!args.options.DisabledWebPartIds)).toString();
98
106
  telemetryProps.AllowedDomainListForSyncClient = (!(!args.options.AllowedDomainListForSyncClient)).toString();
99
107
  telemetryProps.DisableCustomAppAuthentication = (!(!args.options.DisableCustomAppAuthentication)).toString();
108
+ telemetryProps.EnableAzureADB2BIntegration = typeof args.options.EnableAzureADB2BIntegration !== 'undefined';
109
+ telemetryProps.SyncAadB2BManagementPolicy = typeof args.options.SyncAadB2BManagementPolicy !== 'undefined';
100
110
  return telemetryProps;
101
111
  }
102
112
  getAllEnumOptions() {
@@ -176,6 +186,9 @@ class SpoTenantSettingsSetCommand extends SpoCommand_1.default {
176
186
  cb(new Command_1.CommandError(response.ErrorInfo.ErrorMessage));
177
187
  return;
178
188
  }
189
+ if (args.options.EnableAzureADB2BIntegration === true) {
190
+ this.warn(logger, 'WARNING: Make sure to also enable the Azure AD one-time passcode authentication preview. If it is not enabled then SharePoint will not use Azure AD B2B even if EnableAzureADB2BIntegration is set to true. Learn more at http://aka.ms/spo-b2b-integration.');
191
+ }
179
192
  cb();
180
193
  }, (err) => this.handleRejectedPromise(err, logger, cb));
181
194
  }
@@ -490,6 +503,14 @@ class SpoTenantSettingsSetCommand extends SpoCommand_1.default {
490
503
  {
491
504
  option: '--DisableCustomAppAuthentication [DisableCustomAppAuthentication]',
492
505
  autocomplete: ['true', 'false']
506
+ },
507
+ {
508
+ option: '--EnableAzureADB2BIntegration [EnableAzureADB2BIntegration]',
509
+ autocomplete: ['true', 'false']
510
+ },
511
+ {
512
+ option: '--SyncAadB2BManagementPolicy [SyncAadB2BManagementPolicy]',
513
+ autocomplete: ['true', 'false']
493
514
  }
494
515
  ];
495
516
  const parentOptions = super.options();
@@ -16,6 +16,8 @@ class TeamsChannelAddCommand extends GraphCommand_1.default {
16
16
  telemetryProps.description = typeof args.options.description !== 'undefined';
17
17
  telemetryProps.teamId = typeof args.options.teamId !== 'undefined';
18
18
  telemetryProps.teamName = typeof args.options.teamName !== 'undefined';
19
+ telemetryProps.type = args.options.type || 'standard';
20
+ telemetryProps.owner = typeof args.options.owner !== 'undefined';
19
21
  return telemetryProps;
20
22
  }
21
23
  getTeamId(args) {
@@ -44,23 +46,35 @@ class TeamsChannelAddCommand extends GraphCommand_1.default {
44
46
  return Promise.resolve(matchingTeams[0]);
45
47
  });
46
48
  }
49
+ createChannel(args, teamId) {
50
+ const requestOptions = {
51
+ url: `${this.resource}/v1.0/teams/${teamId}/channels`,
52
+ headers: {
53
+ accept: 'application/json;odata.metadata=none',
54
+ 'content-type': 'application/json;odata=nometadata'
55
+ },
56
+ data: {
57
+ membershipType: args.options.type || 'standard',
58
+ displayName: args.options.name
59
+ },
60
+ responseType: 'json'
61
+ };
62
+ if (args.options.type === 'private') {
63
+ // Private channels must have at least 1 owner
64
+ requestOptions.data.members = [
65
+ {
66
+ '@odata.type': '#microsoft.graph.aadUserConversationMember',
67
+ 'user@odata.bind': `https://graph.microsoft.com/v1.0/users('${args.options.owner}')`,
68
+ roles: ['owner']
69
+ }
70
+ ];
71
+ }
72
+ return request_1.default.post(requestOptions);
73
+ }
47
74
  commandAction(logger, args, cb) {
48
75
  this
49
76
  .getTeamId(args)
50
- .then((teamId) => {
51
- const requestOptions = {
52
- url: `${this.resource}/v1.0/teams/${teamId}/channels`,
53
- headers: {
54
- accept: 'application/json;odata.metadata=none',
55
- 'content-type': 'application/json;odata=nometadata'
56
- },
57
- data: {
58
- displayName: args.options.name
59
- },
60
- responseType: 'json'
61
- };
62
- return request_1.default.post(requestOptions);
63
- })
77
+ .then((teamId) => this.createChannel(args, teamId))
64
78
  .then((res) => {
65
79
  logger.log(res);
66
80
  cb();
@@ -79,6 +93,13 @@ class TeamsChannelAddCommand extends GraphCommand_1.default {
79
93
  },
80
94
  {
81
95
  option: '-d, --description [description]'
96
+ },
97
+ {
98
+ option: '--type [type]',
99
+ autocomplete: ['standard', 'private']
100
+ },
101
+ {
102
+ option: '--owner [owner]'
82
103
  }
83
104
  ];
84
105
  const parentOptions = super.options();
@@ -94,6 +115,15 @@ class TeamsChannelAddCommand extends GraphCommand_1.default {
94
115
  if (args.options.teamId && !utils_1.validation.isValidGuid(args.options.teamId)) {
95
116
  return `${args.options.teamId} is not a valid GUID`;
96
117
  }
118
+ if (args.options.type && ['standard', 'private'].indexOf(args.options.type) === -1) {
119
+ return `${args.options.type} is not a valid type value. Allowed values standard|private.`;
120
+ }
121
+ if (args.options.type === 'private' && !args.options.owner) {
122
+ return 'Specify owner when creating a private channel.';
123
+ }
124
+ if (args.options.type !== 'private' && args.options.owner) {
125
+ return 'Specify owner only when creating a private channel.';
126
+ }
97
127
  return true;
98
128
  }
99
129
  }
@@ -49,7 +49,10 @@ class TeamsChannelListCommand extends GraphCommand_1.default {
49
49
  this
50
50
  .getTeamId(args)
51
51
  .then((teamId) => {
52
- const endpoint = `${this.resource}/v1.0/teams/${teamId}/channels`;
52
+ let endpoint = `${this.resource}/v1.0/teams/${teamId}/channels`;
53
+ if (args.options.type) {
54
+ endpoint += `?$filter=membershipType eq '${args.options.type}'`;
55
+ }
53
56
  return utils_1.odata.getAllItems(endpoint, logger);
54
57
  })
55
58
  .then((items) => {
@@ -64,6 +67,10 @@ class TeamsChannelListCommand extends GraphCommand_1.default {
64
67
  },
65
68
  {
66
69
  option: '--teamName [teamName]'
70
+ },
71
+ {
72
+ option: '--type [type]',
73
+ autocomplete: ['standard', 'private']
67
74
  }
68
75
  ];
69
76
  const parentOptions = super.options();
@@ -79,6 +86,9 @@ class TeamsChannelListCommand extends GraphCommand_1.default {
79
86
  if (args.options.teamId && !utils_1.validation.isValidGuid(args.options.teamId)) {
80
87
  return `${args.options.teamId} is not a valid GUID`;
81
88
  }
89
+ if (args.options.type && ['standard', 'private'].indexOf(args.options.type.toLowerCase()) === -1) {
90
+ return `${args.options.type} is not a valid type value. Allowed values standard|private`;
91
+ }
82
92
  return true;
83
93
  }
84
94
  }