@pnp/cli-microsoft365 6.0.0-beta.f73c4f8 → 6.0.0-beta.fe4e66d

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 (32) hide show
  1. package/dist/Auth.js +2 -2
  2. package/dist/m365/base/PowerAppsCommand.js +10 -0
  3. package/dist/m365/pa/commands/app/app-get.js +3 -5
  4. package/dist/m365/pa/commands/app/app-list.js +10 -9
  5. package/dist/m365/pa/commands/app/app-remove.js +3 -3
  6. package/dist/m365/pa/commands/connector/connector-export.js +3 -3
  7. package/dist/m365/pa/commands/connector/connector-list.js +10 -9
  8. package/dist/m365/pa/commands/environment/environment-get.js +3 -3
  9. package/dist/m365/pa/commands/environment/environment-list.js +4 -4
  10. package/dist/m365/planner/commands/plan/plan-add.js +98 -5
  11. package/dist/m365/spo/commands/field/field-set.js +16 -9
  12. package/dist/m365/spo/commands/group/group-add.js +96 -0
  13. package/dist/m365/spo/commands/group/group-set.js +167 -0
  14. package/dist/m365/spo/commands/hubsite/hubsite-get.js +38 -2
  15. package/dist/m365/spo/commands/listitem/listitem-get.js +9 -9
  16. package/dist/m365/spo/commands/listitem/listitem-list.js +5 -1
  17. package/dist/m365/spo/commands.js +2 -0
  18. package/dist/m365/teams/commands/team/team-archive.js +51 -15
  19. package/dist/m365/teams/commands/team/team-remove.js +47 -11
  20. package/dist/m365/teams/commands/team/team-unarchive.js +48 -12
  21. package/docs/docs/cmd/planner/plan/plan-add.md +18 -2
  22. package/docs/docs/cmd/planner/task/task-get.md +6 -0
  23. package/docs/docs/cmd/spo/field/field-set.md +7 -4
  24. package/docs/docs/cmd/spo/group/group-add.md +51 -0
  25. package/docs/docs/cmd/spo/group/group-set.md +69 -0
  26. package/docs/docs/cmd/spo/hubsite/hubsite-get.md +21 -0
  27. package/docs/docs/cmd/spo/listitem/listitem-get.md +11 -2
  28. package/docs/docs/cmd/spo/listitem/listitem-list.md +8 -0
  29. package/docs/docs/cmd/teams/team/team-archive.md +20 -5
  30. package/docs/docs/cmd/teams/team/team-remove.md +19 -5
  31. package/docs/docs/cmd/teams/team/team-unarchive.md +18 -4
  32. package/package.json +1 -1
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const AadUserGetCommand = require("../../../aad/commands/user/user-get");
4
+ const cli_1 = require("../../../../cli");
5
+ const utils_1 = require("../../../../utils");
6
+ const request_1 = require("../../../../request");
7
+ const SpoCommand_1 = require("../../../base/SpoCommand");
8
+ const commands_1 = require("../../commands");
9
+ class SpoGroupSetCommand extends SpoCommand_1.default {
10
+ get name() {
11
+ return commands_1.default.GROUP_SET;
12
+ }
13
+ get description() {
14
+ return 'Updates a group in the specified site';
15
+ }
16
+ getTelemetryProperties(args) {
17
+ const telemetryProps = super.getTelemetryProperties(args);
18
+ telemetryProps.id = typeof args.options.id !== 'undefined';
19
+ telemetryProps.name = typeof args.options.name !== 'undefined';
20
+ telemetryProps.newName = typeof args.options.newName !== 'undefined';
21
+ telemetryProps.description = typeof args.options.description !== 'undefined';
22
+ telemetryProps.allowMembersEditMembership = typeof args.options.allowMembersEditMembership !== 'undefined';
23
+ telemetryProps.onlyAllowMembersViewMembership = typeof args.options.onlyAllowMembersViewMembership !== 'undefined';
24
+ telemetryProps.allowRequestToJoinLeave = typeof args.options.allowRequestToJoinLeave !== 'undefined';
25
+ telemetryProps.autoAcceptRequestToJoinLeave = typeof args.options.autoAcceptRequestToJoinLeave !== 'undefined';
26
+ telemetryProps.requestToJoinLeaveEmailSetting = typeof args.options.requestToJoinLeaveEmailSetting !== 'undefined';
27
+ telemetryProps.ownerEmail = typeof args.options.ownerEmail !== 'undefined';
28
+ telemetryProps.ownerUserName = typeof args.options.ownerUserName !== 'undefined';
29
+ return telemetryProps;
30
+ }
31
+ commandAction(logger, args, cb) {
32
+ const requestOptions = {
33
+ url: `${args.options.webUrl}/_api/web/sitegroups/${args.options.id ? `GetById(${args.options.id})` : `GetByName('${args.options.name}')`}`,
34
+ headers: {
35
+ accept: 'application/json;odata.metadata=none',
36
+ 'content-type': 'application/json'
37
+ },
38
+ responseType: 'json',
39
+ data: {
40
+ Title: args.options.newName,
41
+ Description: args.options.description,
42
+ AllowMembersEditMembership: args.options.allowMembersEditMembership,
43
+ OnlyAllowMembersViewMembership: args.options.onlyAllowMembersViewMembership,
44
+ AllowRequestToJoinLeave: args.options.allowRequestToJoinLeave,
45
+ AutoAcceptRequestToJoinLeave: args.options.autoAcceptRequestToJoinLeave,
46
+ RequestToJoinLeaveEmailSetting: args.options.requestToJoinLeaveEmailSetting
47
+ }
48
+ };
49
+ request_1.default
50
+ .patch(requestOptions)
51
+ .then(() => this.setGroupOwner(args.options))
52
+ .then(_ => cb(), (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
53
+ }
54
+ setGroupOwner(options) {
55
+ if (!options.ownerEmail && !options.ownerUserName) {
56
+ return Promise.resolve();
57
+ }
58
+ return this
59
+ .getOwnerId(options)
60
+ .then((ownerId) => {
61
+ const requestOptions = {
62
+ url: `${options.webUrl}/_api/web/sitegroups/${options.id ? `GetById(${options.id})` : `GetByName('${options.name}')`}/SetUserAsOwner(${ownerId})`,
63
+ headers: {
64
+ accept: 'application/json;odata.metadata=none',
65
+ 'content-type': 'application/json'
66
+ },
67
+ responseType: 'json'
68
+ };
69
+ return request_1.default.post(requestOptions);
70
+ });
71
+ }
72
+ getOwnerId(options) {
73
+ const cmdOptions = {
74
+ userName: options.ownerUserName,
75
+ email: options.ownerEmail,
76
+ output: 'json',
77
+ debug: options.debug,
78
+ verbose: options.verbose
79
+ };
80
+ return cli_1.Cli
81
+ .executeCommandWithOutput(AadUserGetCommand, { options: Object.assign(Object.assign({}, cmdOptions), { _: [] }) })
82
+ .then((output) => {
83
+ const getUserOutput = JSON.parse(output.stdout);
84
+ const requestOptions = {
85
+ url: `${options.webUrl}/_api/web/ensureUser('${getUserOutput.userPrincipalName}')?$select=Id`,
86
+ headers: {
87
+ accept: 'application/json',
88
+ 'content-type': 'application/json'
89
+ },
90
+ responseType: 'json'
91
+ };
92
+ return request_1.default.post(requestOptions);
93
+ })
94
+ .then((response) => response.Id);
95
+ }
96
+ options() {
97
+ const options = [
98
+ {
99
+ option: '-u, --webUrl <webUrl>'
100
+ },
101
+ {
102
+ option: '-i, --id [id]'
103
+ },
104
+ {
105
+ option: '-n, --name [name]'
106
+ },
107
+ {
108
+ option: '--newName [newName]'
109
+ },
110
+ {
111
+ option: '--description [description]'
112
+ },
113
+ {
114
+ option: '--allowMembersEditMembership [allowMembersEditMembership]'
115
+ },
116
+ {
117
+ option: '--onlyAllowMembersViewMembership [onlyAllowMembersViewMembership]'
118
+ },
119
+ {
120
+ option: '--allowRequestToJoinLeave [allowRequestToJoinLeave]'
121
+ },
122
+ {
123
+ option: '--autoAcceptRequestToJoinLeave [autoAcceptRequestToJoinLeave]'
124
+ },
125
+ {
126
+ option: '--requestToJoinLeaveEmailSetting [requestToJoinLeaveEmailSetting]'
127
+ },
128
+ {
129
+ option: '--ownerEmail [ownerEmail]'
130
+ },
131
+ {
132
+ option: '--ownerUserName [ownerUserName]'
133
+ }
134
+ ];
135
+ const parentOptions = super.options();
136
+ return options.concat(parentOptions);
137
+ }
138
+ optionSets() {
139
+ return [
140
+ ['id', 'name']
141
+ ];
142
+ }
143
+ validate(args) {
144
+ const isValidSharePointUrl = utils_1.validation.isValidSharePointUrl(args.options.webUrl);
145
+ if (isValidSharePointUrl !== true) {
146
+ return isValidSharePointUrl;
147
+ }
148
+ if (args.options.id && isNaN(args.options.id)) {
149
+ return `Specified id ${args.options.id} is not a number`;
150
+ }
151
+ if (args.options.ownerEmail && args.options.ownerUserName) {
152
+ return 'Specify either ownerEmail or ownerUserName but not both';
153
+ }
154
+ const booleanOptions = [
155
+ args.options.allowMembersEditMembership, args.options.onlyAllowMembersViewMembership,
156
+ args.options.allowRequestToJoinLeave, args.options.autoAcceptRequestToJoinLeave
157
+ ];
158
+ for (const option of booleanOptions) {
159
+ if (typeof option !== 'undefined' && !utils_1.validation.isValidBoolean(option)) {
160
+ return `Value '${option}' is not a valid boolean`;
161
+ }
162
+ }
163
+ return true;
164
+ }
165
+ }
166
+ module.exports = new SpoGroupSetCommand();
167
+ //# sourceMappingURL=group-set.js.map
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cli_1 = require("../../../../cli");
3
4
  const request_1 = require("../../../../request");
4
5
  const utils_1 = require("../../../../utils");
5
6
  const SpoCommand_1 = require("../../../base/SpoCommand");
6
7
  const commands_1 = require("../../commands");
8
+ const SpoListItemListCommand = require("../listitem/listitem-list");
7
9
  class SpoHubSiteGetCommand extends SpoCommand_1.default {
8
10
  get name() {
9
11
  return commands_1.default.HUBSITE_GET;
@@ -16,9 +18,24 @@ class SpoHubSiteGetCommand extends SpoCommand_1.default {
16
18
  telemetryProps.id = typeof args.options.id !== 'undefined';
17
19
  telemetryProps.title = typeof args.options.title !== 'undefined';
18
20
  telemetryProps.url = typeof args.options.url !== 'undefined';
21
+ telemetryProps.includeAssociatedSites = args.options.includeAssociatedSites === true;
19
22
  return telemetryProps;
20
23
  }
24
+ getAssociatedSites(spoAdminUrl, hubSiteId, logger, args) {
25
+ const options = {
26
+ output: 'json',
27
+ debug: args.options.debug,
28
+ verbose: args.options.verbose,
29
+ listTitle: 'DO_NOT_DELETE_SPLIST_TENANTADMIN_AGGREGATED_SITECOLLECTIONS',
30
+ webUrl: spoAdminUrl,
31
+ filter: `HubSiteId eq '${hubSiteId}'`,
32
+ fields: 'Title,SiteUrl,SiteId'
33
+ };
34
+ return cli_1.Cli
35
+ .executeCommandWithOutput(SpoListItemListCommand, { options: Object.assign(Object.assign({}, options), { _: [] }) });
36
+ }
21
37
  commandAction(logger, args, cb) {
38
+ let hubSite;
22
39
  utils_1.spo
23
40
  .getSpoUrl(logger, this.debug)
24
41
  .then((spoUrl) => {
@@ -30,7 +47,25 @@ class SpoHubSiteGetCommand extends SpoCommand_1.default {
30
47
  }
31
48
  })
32
49
  .then((res) => {
33
- logger.log(res);
50
+ hubSite = res;
51
+ if (args.options.includeAssociatedSites && (args.options.output && args.options.output !== 'json')) {
52
+ throw Error('includeAssociatedSites option is only allowed with json output mode');
53
+ }
54
+ if (args.options.includeAssociatedSites !== true || args.options.output && args.options.output !== 'json') {
55
+ return Promise.resolve();
56
+ }
57
+ return utils_1.spo
58
+ .getSpoAdminUrl(logger, this.debug)
59
+ .then((spoAdminUrl) => {
60
+ return this.getAssociatedSites(spoAdminUrl, hubSite.SiteId, logger, args);
61
+ });
62
+ })
63
+ .then((associatedSitesCommandOutput) => {
64
+ if (args.options.includeAssociatedSites) {
65
+ const associatedSites = JSON.parse(associatedSitesCommandOutput.stdout);
66
+ hubSite.AssociatedSites = associatedSites.filter(s => s.SiteId !== hubSite.SiteId);
67
+ }
68
+ logger.log(hubSite);
34
69
  cb();
35
70
  }, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
36
71
  }
@@ -75,7 +110,8 @@ class SpoHubSiteGetCommand extends SpoCommand_1.default {
75
110
  const options = [
76
111
  { option: '-i, --id [id]' },
77
112
  { option: '-t, --title [title]' },
78
- { option: '-u, --url [url]' }
113
+ { option: '-u, --url [url]' },
114
+ { option: '--includeAssociatedSites' }
79
115
  ];
80
116
  const parentOptions = super.options();
81
117
  return options.concat(parentOptions);
@@ -24,15 +24,15 @@ class SpoListItemGetCommand extends SpoCommand_1.default {
24
24
  const listIdArgument = args.options.listId || '';
25
25
  const listTitleArgument = args.options.listTitle || '';
26
26
  const listRestUrl = (args.options.listId ?
27
- `${args.options.webUrl}/_api/web/lists(guid'${utils_1.formatting.encodeQueryParameter(listIdArgument)}')`
28
- : `${args.options.webUrl}/_api/web/lists/getByTitle('${utils_1.formatting.encodeQueryParameter(listTitleArgument)}')`);
29
- const propertiesSelect = args.options.properties ?
30
- `?$select=${encodeURIComponent(args.options.properties)}` :
31
- ((!args.options.output || args.options.output === 'text') ?
32
- `?$select=Id,Title` :
33
- ``);
27
+ `${args.options.webUrl}/_api/web/lists(guid'${utils_1.formatting.encodeQueryParameter(listIdArgument)}')` :
28
+ `${args.options.webUrl}/_api/web/lists/getByTitle('${utils_1.formatting.encodeQueryParameter(listTitleArgument)}')`);
29
+ const propertiesSelect = args.options.properties ? args.options.properties.split(',') : [];
30
+ const propertiesWithSlash = propertiesSelect.filter(item => item.includes('/'));
31
+ const propertiesToExpand = propertiesWithSlash.map(e => e.split('/')[0]);
32
+ const expandPropertiesArray = propertiesToExpand.filter((item, pos) => propertiesToExpand.indexOf(item) === pos);
33
+ const fieldExpand = expandPropertiesArray.length > 0 ? `&$expand=${expandPropertiesArray.join(",")}` : ``;
34
34
  const requestOptions = {
35
- url: `${listRestUrl}/items(${args.options.id})${propertiesSelect}`,
35
+ url: `${listRestUrl}/items(${args.options.id})?$select=${encodeURIComponent(propertiesSelect.join(","))}${fieldExpand}`,
36
36
  headers: {
37
37
  'accept': 'application/json;odata=nometadata'
38
38
  },
@@ -41,7 +41,7 @@ class SpoListItemGetCommand extends SpoCommand_1.default {
41
41
  request_1.default
42
42
  .get(requestOptions)
43
43
  .then((response) => {
44
- delete response["ID"];
44
+ delete response['ID'];
45
45
  logger.log(response);
46
46
  cb();
47
47
  }, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
@@ -36,6 +36,9 @@ class SpoListItemListCommand extends SpoCommand_1.default {
36
36
  let formDigestValue = '';
37
37
  const fieldsArray = args.options.fields ? args.options.fields.split(",")
38
38
  : (!args.options.output || args.options.output === "text") ? ["Title", "Id"] : [];
39
+ const fieldsWithSlash = fieldsArray.filter(item => item.includes('/'));
40
+ const fieldsToExpand = fieldsWithSlash.map(e => e.split('/')[0]);
41
+ const expandFieldsArray = fieldsToExpand.filter((item, pos) => fieldsToExpand.indexOf(item) === pos);
39
42
  const listRestUrl = listIdArgument ?
40
43
  `${args.options.webUrl}/_api/web/lists(guid'${utils_1.formatting.encodeQueryParameter(listIdArgument)}')`
41
44
  : `${args.options.webUrl}/_api/web/lists/getByTitle('${utils_1.formatting.encodeQueryParameter(listTitleArgument)}')`;
@@ -75,8 +78,9 @@ class SpoListItemListCommand extends SpoCommand_1.default {
75
78
  const skipToken = (args.options.pageNumber && Number(args.options.pageNumber) > 0 && skipTokenId > 0) ? `$skiptoken=Paged=TRUE%26p_ID=${res.value[res.value.length - 1].Id}` : ``;
76
79
  const rowLimit = args.options.pageSize ? `$top=${args.options.pageSize}` : ``;
77
80
  const filter = args.options.filter ? `$filter=${encodeURIComponent(args.options.filter)}` : ``;
81
+ const fieldExpand = expandFieldsArray.length > 0 ? `&$expand=${expandFieldsArray.join(",")}` : ``;
78
82
  const fieldSelect = fieldsArray.length > 0 ?
79
- `?$select=${encodeURIComponent(fieldsArray.join(","))}&${rowLimit}&${skipToken}&${filter}` :
83
+ `?$select=${encodeURIComponent(fieldsArray.join(","))}${fieldExpand}&${rowLimit}&${skipToken}&${filter}` :
80
84
  `?${rowLimit}&${skipToken}&${filter}`;
81
85
  const requestBody = args.options.camlQuery ?
82
86
  {
@@ -63,9 +63,11 @@ exports.default = {
63
63
  FOLDER_REMOVE: `${prefix} folder remove`,
64
64
  FOLDER_RENAME: `${prefix} folder rename`,
65
65
  GET: `${prefix} get`,
66
+ GROUP_ADD: `${prefix} group add`,
66
67
  GROUP_GET: `${prefix} group get`,
67
68
  GROUP_LIST: `${prefix} group list`,
68
69
  GROUP_REMOVE: `${prefix} group remove`,
70
+ GROUP_SET: `${prefix} group set`,
69
71
  GROUP_USER_ADD: `${prefix} group user add`,
70
72
  GROUP_USER_LIST: `${prefix} group user list`,
71
73
  GROUP_USER_REMOVE: `${prefix} group user remove`,
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const request_1 = require("../../../../request");
4
4
  const utils_1 = require("../../../../utils");
5
+ const aadGroup_1 = require("../../../../utils/aadGroup");
5
6
  const GraphCommand_1 = require("../../../base/GraphCommand");
6
7
  const commands_1 = require("../../commands");
7
8
  class TeamsTeamArchiveCommand extends GraphCommand_1.default {
@@ -16,27 +17,53 @@ class TeamsTeamArchiveCommand extends GraphCommand_1.default {
16
17
  telemetryProps.shouldSetSpoSiteReadOnlyForMembers = args.options.shouldSetSpoSiteReadOnlyForMembers === true;
17
18
  return telemetryProps;
18
19
  }
20
+ getTeamId(args) {
21
+ if (args.options.id) {
22
+ return Promise.resolve(args.options.id);
23
+ }
24
+ return aadGroup_1.aadGroup
25
+ .getGroupByDisplayName(args.options.name)
26
+ .then(group => {
27
+ if (group.resourceProvisioningOptions.indexOf('Team') === -1) {
28
+ return Promise.reject(`The specified team does not exist in the Microsoft Teams`);
29
+ }
30
+ return group.id;
31
+ });
32
+ }
19
33
  commandAction(logger, args, cb) {
34
+ if (args.options.teamId) {
35
+ args.options.id = args.options.teamId;
36
+ this.warn(logger, `Option 'teamId' is deprecated. Please use 'id' instead.`);
37
+ }
20
38
  const siteReadOnlyForMembers = args.options.shouldSetSpoSiteReadOnlyForMembers === true;
21
- const requestOptions = {
22
- url: `${this.resource}/v1.0/teams/${encodeURIComponent(args.options.teamId)}/archive`,
23
- headers: {
24
- 'content-type': 'application/json;odata=nometadata',
25
- 'accept': 'application/json;odata.metadata=none'
26
- },
27
- responseType: 'json',
28
- data: {
29
- shouldSetSpoSiteReadOnlyForMembers: siteReadOnlyForMembers
30
- }
31
- };
32
- request_1.default
33
- .post(requestOptions)
39
+ this
40
+ .getTeamId(args)
41
+ .then((teamId) => {
42
+ const requestOptions = {
43
+ url: `${this.resource}/v1.0/teams/${encodeURIComponent(teamId)}/archive`,
44
+ headers: {
45
+ 'content-type': 'application/json;odata=nometadata',
46
+ 'accept': 'application/json;odata.metadata=none'
47
+ },
48
+ responseType: 'json',
49
+ data: {
50
+ shouldSetSpoSiteReadOnlyForMembers: siteReadOnlyForMembers
51
+ }
52
+ };
53
+ return request_1.default.post(requestOptions);
54
+ })
34
55
  .then(_ => cb(), (res) => this.handleRejectedODataJsonPromise(res, logger, cb));
35
56
  }
36
57
  options() {
37
58
  const options = [
38
59
  {
39
- option: '-i, --teamId <teamId>'
60
+ option: '-i, --id [id]'
61
+ },
62
+ {
63
+ option: '-n, --name [name]'
64
+ },
65
+ {
66
+ option: '--teamId [teamId]'
40
67
  },
41
68
  {
42
69
  option: '--shouldSetSpoSiteReadOnlyForMembers'
@@ -46,9 +73,18 @@ class TeamsTeamArchiveCommand extends GraphCommand_1.default {
46
73
  return options.concat(parentOptions);
47
74
  }
48
75
  validate(args) {
49
- if (!utils_1.validation.isValidGuid(args.options.teamId)) {
76
+ if (!args.options.id && !args.options.name && !args.options.teamId) {
77
+ return 'Specify either id or name';
78
+ }
79
+ if (args.options.name && (args.options.id || args.options.teamId)) {
80
+ return 'Specify either id or name but not both';
81
+ }
82
+ if (args.options.teamId && !utils_1.validation.isValidGuid(args.options.teamId)) {
50
83
  return `${args.options.teamId} is not a valid GUID`;
51
84
  }
85
+ if (args.options.id && !utils_1.validation.isValidGuid(args.options.id)) {
86
+ return `${args.options.id} is not a valid GUID`;
87
+ }
52
88
  return true;
53
89
  }
54
90
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const cli_1 = require("../../../../cli");
4
4
  const request_1 = require("../../../../request");
5
5
  const utils_1 = require("../../../../utils");
6
+ const aadGroup_1 = require("../../../../utils/aadGroup");
6
7
  const GraphCommand_1 = require("../../../base/GraphCommand");
7
8
  const commands_1 = require("../../commands");
8
9
  class TeamsTeamRemoveCommand extends GraphCommand_1.default {
@@ -17,17 +18,37 @@ class TeamsTeamRemoveCommand extends GraphCommand_1.default {
17
18
  telemetryProps.confirm = (!(!args.options.confirm)).toString();
18
19
  return telemetryProps;
19
20
  }
21
+ getTeamId(args) {
22
+ if (args.options.id) {
23
+ return Promise.resolve(args.options.id);
24
+ }
25
+ return aadGroup_1.aadGroup
26
+ .getGroupByDisplayName(args.options.name)
27
+ .then(group => {
28
+ if (group.resourceProvisioningOptions.indexOf('Team') === -1) {
29
+ return Promise.reject(`The specified team does not exist in the Microsoft Teams`);
30
+ }
31
+ return group.id;
32
+ });
33
+ }
20
34
  commandAction(logger, args, cb) {
35
+ if (args.options.teamId) {
36
+ args.options.id = args.options.teamId;
37
+ this.warn(logger, `Option 'teamId' is deprecated. Please use 'id' instead.`);
38
+ }
21
39
  const removeTeam = () => {
22
- const requestOptions = {
23
- url: `${this.resource}/v1.0/groups/${encodeURIComponent(args.options.teamId)}`,
24
- headers: {
25
- accept: 'application/json;odata.metadata=none'
26
- },
27
- responseType: 'json'
28
- };
29
- request_1.default
30
- .delete(requestOptions)
40
+ this
41
+ .getTeamId(args)
42
+ .then((teamId) => {
43
+ const requestOptions = {
44
+ url: `${this.resource}/v1.0/groups/${encodeURIComponent(teamId)}`,
45
+ headers: {
46
+ accept: 'application/json;odata.metadata=none'
47
+ },
48
+ responseType: 'json'
49
+ };
50
+ return request_1.default.delete(requestOptions);
51
+ })
31
52
  .then(_ => cb(), (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
32
53
  };
33
54
  if (args.options.confirm) {
@@ -52,7 +73,13 @@ class TeamsTeamRemoveCommand extends GraphCommand_1.default {
52
73
  options() {
53
74
  const options = [
54
75
  {
55
- option: '-i, --teamId <teamId>'
76
+ option: '-i, --id [id]'
77
+ },
78
+ {
79
+ option: '-n, --name [name]'
80
+ },
81
+ {
82
+ option: '--teamId [teamId]'
56
83
  },
57
84
  {
58
85
  option: '--confirm'
@@ -62,9 +89,18 @@ class TeamsTeamRemoveCommand extends GraphCommand_1.default {
62
89
  return options.concat(parentOptions);
63
90
  }
64
91
  validate(args) {
65
- if (!utils_1.validation.isValidGuid(args.options.teamId)) {
92
+ if (!args.options.id && !args.options.name && !args.options.teamId) {
93
+ return 'Specify either id or name';
94
+ }
95
+ if (args.options.name && (args.options.id || args.options.teamId)) {
96
+ return 'Specify either id or name but not both';
97
+ }
98
+ if (args.options.teamId && !utils_1.validation.isValidGuid(args.options.teamId)) {
66
99
  return `${args.options.teamId} is not a valid GUID`;
67
100
  }
101
+ if (args.options.id && !utils_1.validation.isValidGuid(args.options.id)) {
102
+ return `${args.options.id} is not a valid GUID`;
103
+ }
68
104
  return true;
69
105
  }
70
106
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const request_1 = require("../../../../request");
4
4
  const utils_1 = require("../../../../utils");
5
+ const aadGroup_1 = require("../../../../utils/aadGroup");
5
6
  const GraphCommand_1 = require("../../../base/GraphCommand");
6
7
  const commands_1 = require("../../commands");
7
8
  class TeamsTeamUnarchiveCommand extends GraphCommand_1.default {
@@ -11,33 +12,68 @@ class TeamsTeamUnarchiveCommand extends GraphCommand_1.default {
11
12
  get description() {
12
13
  return 'Restores an archived Microsoft Teams team';
13
14
  }
15
+ getTeamId(args) {
16
+ if (args.options.id) {
17
+ return Promise.resolve(args.options.id);
18
+ }
19
+ return aadGroup_1.aadGroup
20
+ .getGroupByDisplayName(args.options.name)
21
+ .then(group => {
22
+ if (group.resourceProvisioningOptions.indexOf('Team') === -1) {
23
+ return Promise.reject(`The specified team does not exist in the Microsoft Teams`);
24
+ }
25
+ return group.id;
26
+ });
27
+ }
14
28
  commandAction(logger, args, cb) {
29
+ if (args.options.teamId) {
30
+ args.options.id = args.options.teamId;
31
+ this.warn(logger, `Option 'teamId' is deprecated. Please use 'id' instead.`);
32
+ }
15
33
  const endpoint = `${this.resource}/v1.0`;
16
- const requestOptions = {
17
- url: `${endpoint}/teams/${encodeURIComponent(args.options.teamId)}/unarchive`,
18
- headers: {
19
- 'content-type': 'application/json;odata=nometadata',
20
- 'accept': 'application/json;odata.metadata=none'
21
- },
22
- responseType: 'json'
23
- };
24
- request_1.default
25
- .post(requestOptions)
34
+ this
35
+ .getTeamId(args)
36
+ .then((teamId) => {
37
+ const requestOptions = {
38
+ url: `${endpoint}/teams/${encodeURIComponent(teamId)}/unarchive`,
39
+ headers: {
40
+ 'content-type': 'application/json;odata=nometadata',
41
+ 'accept': 'application/json;odata.metadata=none'
42
+ },
43
+ responseType: 'json'
44
+ };
45
+ return request_1.default.post(requestOptions);
46
+ })
26
47
  .then(_ => cb(), (res) => this.handleRejectedODataJsonPromise(res, logger, cb));
27
48
  }
28
49
  options() {
29
50
  const options = [
30
51
  {
31
- option: '-i, --teamId <teamId>'
52
+ option: '-i, --id [id]'
53
+ },
54
+ {
55
+ option: '-n, --name [name]'
56
+ },
57
+ {
58
+ option: '--teamId [teamId]'
32
59
  }
33
60
  ];
34
61
  const parentOptions = super.options();
35
62
  return options.concat(parentOptions);
36
63
  }
37
64
  validate(args) {
38
- if (!utils_1.validation.isValidGuid(args.options.teamId)) {
65
+ if (!args.options.id && !args.options.name && !args.options.teamId) {
66
+ return 'Specify either id or name';
67
+ }
68
+ if (args.options.name && (args.options.id || args.options.teamId)) {
69
+ return 'Specify either id or name but not both';
70
+ }
71
+ if (args.options.teamId && !utils_1.validation.isValidGuid(args.options.teamId)) {
39
72
  return `${args.options.teamId} is not a valid GUID`;
40
73
  }
74
+ if (args.options.id && !utils_1.validation.isValidGuid(args.options.id)) {
75
+ return `${args.options.id} is not a valid GUID`;
76
+ }
41
77
  return true;
42
78
  }
43
79
  }
@@ -19,18 +19,34 @@ m365 planner plan add [options]
19
19
  `--ownerGroupName [ownerGroupName]`
20
20
  : Name of the Group that owns the plan. A valid group must exist before this option can be set. Specify either `ownerGroupId` or `ownerGroupName` but not both.
21
21
 
22
+ `--shareWithUserIds [shareWithUserIds]`
23
+ : The comma-separated IDs of the users with whom you want to share the plan. Specify either `shareWithUserIds` or `shareWithUserNames` but not both.
24
+
25
+ `--shareWithUserNames [shareWithUserNames]`
26
+ : The comma-separated UPNs of the users with whom you want to share the plan. Specify either `shareWithUserIds` or `shareWithUserNames` but not both.
27
+
22
28
  --8<-- "docs/cmd/_global.md"
23
29
 
30
+ ## Remarks
31
+
32
+ Related to the options `--shareWithUserIds` and `--shareWithUserNames`. If you are leveraging Microsoft 365 groups, use the `aad o365group user` commands to manage group membership to share the [group's](https://pnp.github.io/cli-microsoft365/cmd/aad/o365group/o365group-user-add/) plan. You can also add existing members of the group to this collection though it is not required for them to access the plan owned by the group.
33
+
24
34
  ## Examples
25
35
 
26
36
  Adds a Microsoft Planner plan with the name _My Planner Plan_ for Group _233e43d0-dc6a-482e-9b4e-0de7a7bce9b4_
27
37
 
28
38
  ```sh
29
- m365 planner plan add --title "My Planner Plan" --ownerGroupId "233e43d0-dc6a-482e-9b4e-0de7a7bce9b4"
39
+ m365 planner plan add --title 'My Planner Plan' --ownerGroupId '233e43d0-dc6a-482e-9b4e-0de7a7bce9b4'
30
40
  ```
31
41
 
32
42
  Adds a Microsoft Planner plan with the name _My Planner Plan_ for Group _My Planner Group_
33
43
 
34
44
  ```sh
35
- m365 planner plan add --title "My Planner Plan" --ownerGroupName "My Planner Group"
45
+ m365 planner plan add --title 'My Planner Plan' --ownerGroupName 'My Planner Group'
46
+ ```
47
+
48
+ Adds a Microsoft Planner plan with the name _My Planner Plan_ for Group _My Planner Group_ and share it with the users _Allan.Carroll@contoso.com_ and _Ida.Stevens@contoso.com_
49
+
50
+ ```sh
51
+ m365 planner plan add --title 'My Planner Plan' --ownerGroupName 'My Planner Group' --shareWithUserNames 'Allan.Carroll@contoso.com,Ida.Stevens@contoso.com'
36
52
  ```
@@ -8,6 +8,12 @@ Retrieve the specified planner task
8
8
  m365 planner task get [options]
9
9
  ```
10
10
 
11
+ ## Alias
12
+
13
+ ```sh
14
+ m365 planner task details get [options]
15
+ ```
16
+
11
17
  ## Options
12
18
 
13
19
  `-i, --id [id]`