@pnp/cli-microsoft365 7.11.0-beta.c513557 → 8.0.0-beta.3c404b8

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 (96) hide show
  1. package/.eslintrc.cjs +6 -2
  2. package/allCommands.json +1 -1
  3. package/allCommandsFull.json +1 -1
  4. package/dist/Auth.js +2 -10
  5. package/dist/AuthServer.js +10 -10
  6. package/dist/Command.js +10 -10
  7. package/dist/chili/chili.js +0 -23
  8. package/dist/chili/index.js +1 -1
  9. package/dist/cli/cli.js +12 -74
  10. package/dist/index.js +1 -1
  11. package/dist/m365/base/AnonymousCommand.js +1 -1
  12. package/dist/m365/base/DelegatedGraphCommand.js +2 -2
  13. package/dist/m365/base/PowerAppsCommand.js +2 -2
  14. package/dist/m365/base/PowerAutomateCommand.js +2 -2
  15. package/dist/m365/base/PowerBICommand.js +2 -2
  16. package/dist/m365/base/PowerPlatformCommand.js +2 -2
  17. package/dist/m365/base/VivaEngageCommand.js +2 -2
  18. package/dist/m365/cli/commands/cli-consent.js +1 -1
  19. package/dist/m365/commands/login.js +1 -1
  20. package/dist/m365/commands/logout.js +1 -1
  21. package/dist/m365/commands/setup.js +0 -4
  22. package/dist/m365/commands/status.js +1 -1
  23. package/dist/m365/connection/commands/connection-list.js +1 -1
  24. package/dist/m365/connection/commands/connection-remove.js +1 -1
  25. package/dist/m365/connection/commands/connection-set.js +1 -1
  26. package/dist/m365/connection/commands/connection-use.js +1 -1
  27. package/dist/m365/entra/commands/app/app-permission-add.js +21 -1
  28. package/dist/m365/entra/commands/app/app-permission-remove.js +17 -0
  29. package/dist/m365/entra/commands/m365group/m365group-add.js +1 -0
  30. package/dist/m365/entra/commands/m365group/m365group-set.js +66 -29
  31. package/dist/m365/entra/commands/m365group/m365group-user-list.js +1 -1
  32. package/dist/m365/entra/commands/multitenant/MultitenantOrganization.js +2 -0
  33. package/dist/m365/entra/commands/multitenant/multitenant-get.js +32 -0
  34. package/dist/m365/entra/commands.js +1 -0
  35. package/dist/m365/external/commands/connection/connection-doctor.js +11 -25
  36. package/dist/m365/external/commands/connection/connection-schema-add.js +4 -4
  37. package/dist/m365/file/commands/file-copy.js +3 -3
  38. package/dist/m365/flow/commands/flow-list.js +23 -24
  39. package/dist/m365/graph/commands/subscription/subscription-add.js +4 -2
  40. package/dist/m365/pa/commands/app/app-export.js +1 -1
  41. package/dist/m365/pa/commands/app/app-owner-set.js +1 -1
  42. package/dist/m365/pp/commands/solution/solution-publish.js +1 -1
  43. package/dist/m365/purview/commands/threatassessment/threatassessment-list.js +1 -1
  44. package/dist/m365/spfx/commands/project/base-project-command.js +36 -126
  45. package/dist/m365/spfx/commands/project/project-azuredevops-pipeline-add.js +1 -1
  46. package/dist/m365/spfx/commands/project/project-externalize.js +1 -1
  47. package/dist/m365/spfx/commands/project/project-github-workflow-add.js +1 -1
  48. package/dist/m365/spfx/commands/spfx-doctor.js +4 -4
  49. package/dist/m365/spo/commands/cdn/cdn-get.js +12 -15
  50. package/dist/m365/spo/commands/cdn/cdn-set.js +6 -4
  51. package/dist/m365/spo/commands/commandset/commandset-get.js +1 -1
  52. package/dist/m365/spo/commands/contenttype/contenttype-field-list.js +124 -0
  53. package/dist/m365/spo/commands/field/field-list.js +1 -1
  54. package/dist/m365/spo/commands/file/file-retentionlabel-remove.js +1 -1
  55. package/dist/m365/spo/commands/group/group-member-add.js +103 -99
  56. package/dist/m365/spo/commands/group/group-member-remove.js +2 -2
  57. package/dist/m365/spo/commands/list/list-retentionlabel-ensure.js +1 -1
  58. package/dist/m365/spo/commands/listitem/listitem-batch-remove.js +1 -1
  59. package/dist/m365/spo/commands/listitem/listitem-retentionlabel-ensure.js +2 -2
  60. package/dist/m365/spo/commands/listitem/listitem-retentionlabel-remove.js +2 -2
  61. package/dist/m365/spo/commands/page/page-clientsidewebpart-add.js +2 -3
  62. package/dist/m365/spo/commands/page/page-text-add.js +2 -3
  63. package/dist/m365/spo/commands/site/site-commsite-enable.js +1 -1
  64. package/dist/m365/spo/commands/spo-search.js +4 -5
  65. package/dist/m365/spo/commands/tenant/tenant-applicationcustomizer-set.js +4 -4
  66. package/dist/m365/spo/commands/tenant/tenant-commandset-set.js +2 -2
  67. package/dist/m365/spo/commands/user/user-ensure.js +1 -1
  68. package/dist/m365/spo/commands.js +1 -0
  69. package/dist/m365/teams/commands/chat/chat-member-add.js +1 -1
  70. package/dist/m365/teams/commands/meeting/meeting-attendancereport-get.js +119 -0
  71. package/dist/m365/teams/commands/meeting/meeting-list.js +1 -1
  72. package/dist/m365/teams/commands/message/message-remove.js +112 -0
  73. package/dist/m365/teams/commands.js +2 -0
  74. package/dist/m365/viva/commands/engage/engage-community-add.js +166 -0
  75. package/dist/m365/viva/commands/engage/engage-community-get.js +1 -1
  76. package/dist/m365/viva/commands.js +1 -0
  77. package/dist/request.js +13 -14
  78. package/dist/utils/formatting.js +14 -1
  79. package/dist/utils/spo.js +5 -5
  80. package/dist/utils/teams.js +49 -0
  81. package/dist/utils/validation.js +25 -0
  82. package/docs/docs/cmd/entra/m365group/m365group-set.mdx +37 -7
  83. package/docs/docs/cmd/entra/multitenant/multitenant-get.mdx +94 -0
  84. package/docs/docs/cmd/external/connection/connection-doctor.mdx +9 -9
  85. package/docs/docs/cmd/flow/flow-list.mdx +114 -56
  86. package/docs/docs/cmd/graph/subscription/subscription-add.mdx +18 -0
  87. package/docs/docs/cmd/spo/cdn/cdn-set.mdx +3 -3
  88. package/docs/docs/cmd/spo/contenttype/contenttype-field-list.mdx +172 -0
  89. package/docs/docs/cmd/spo/contenttype/contenttype-list.mdx +3 -3
  90. package/docs/docs/cmd/spo/field/field-list.mdx +3 -3
  91. package/docs/docs/cmd/spo/group/group-member-add.mdx +34 -27
  92. package/docs/docs/cmd/teams/meeting/meeting-attendancereport-get.mdx +138 -0
  93. package/docs/docs/cmd/teams/message/message-remove.mdx +63 -0
  94. package/docs/docs/cmd/viva/engage/engage-community-add.mdx +168 -0
  95. package/npm-shrinkwrap.json +809 -803
  96. package/package.json +13 -13
@@ -0,0 +1,119 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _TeamsMeetingAttendancereportGetCommand_instances, _TeamsMeetingAttendancereportGetCommand_initTelemetry, _TeamsMeetingAttendancereportGetCommand_initOptions, _TeamsMeetingAttendancereportGetCommand_initTypes, _TeamsMeetingAttendancereportGetCommand_initValidators, _TeamsMeetingAttendancereportGetCommand_initOptionSets;
7
+ import auth from '../../../../Auth.js';
8
+ import { accessToken } from '../../../../utils/accessToken.js';
9
+ import { validation } from '../../../../utils/validation.js';
10
+ import GraphCommand from "../../../base/GraphCommand.js";
11
+ import commands from '../../commands.js';
12
+ import { entraUser } from '../../../../utils/entraUser.js';
13
+ import request from '../../../../request.js';
14
+ class TeamsMeetingAttendancereportGetCommand extends GraphCommand {
15
+ get name() {
16
+ return commands.MEETING_ATTENDANCEREPORT_GET;
17
+ }
18
+ get description() {
19
+ return 'Gets attendance report for a given meeting';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _TeamsMeetingAttendancereportGetCommand_instances.add(this);
24
+ __classPrivateFieldGet(this, _TeamsMeetingAttendancereportGetCommand_instances, "m", _TeamsMeetingAttendancereportGetCommand_initTelemetry).call(this);
25
+ __classPrivateFieldGet(this, _TeamsMeetingAttendancereportGetCommand_instances, "m", _TeamsMeetingAttendancereportGetCommand_initOptions).call(this);
26
+ __classPrivateFieldGet(this, _TeamsMeetingAttendancereportGetCommand_instances, "m", _TeamsMeetingAttendancereportGetCommand_initTypes).call(this);
27
+ __classPrivateFieldGet(this, _TeamsMeetingAttendancereportGetCommand_instances, "m", _TeamsMeetingAttendancereportGetCommand_initValidators).call(this);
28
+ __classPrivateFieldGet(this, _TeamsMeetingAttendancereportGetCommand_instances, "m", _TeamsMeetingAttendancereportGetCommand_initOptionSets).call(this);
29
+ }
30
+ async commandAction(logger, args) {
31
+ try {
32
+ const isAppOnlyAccessToken = accessToken.isAppOnlyAccessToken(auth.connection.accessTokens[auth.defaultResource].accessToken);
33
+ if (isAppOnlyAccessToken && !args.options.userId && !args.options.userName && !args.options.email) {
34
+ throw `The option 'userId', 'userName' or 'email' is required when retrieving meeting attendance report using app only permissions.`;
35
+ }
36
+ else if (!isAppOnlyAccessToken && (args.options.userId || args.options.userName || args.options.email)) {
37
+ throw `The options 'userId', 'userName' and 'email' cannot be used when retrieving meeting attendance report using delegated permissions.`;
38
+ }
39
+ if (this.verbose) {
40
+ await logger.logToStderr(`Retrieving attendance report for ${isAppOnlyAccessToken ? `specific user ${args.options.userId || args.options.userName || args.options.email}.` : 'currently logged in user'}.`);
41
+ }
42
+ let userUrl = '';
43
+ if (isAppOnlyAccessToken) {
44
+ const userId = await this.getUserId(args.options);
45
+ userUrl += `users/${userId}`;
46
+ }
47
+ else {
48
+ userUrl += 'me';
49
+ }
50
+ const requestOptions = {
51
+ url: `${this.resource}/v1.0/${userUrl}/onlineMeetings/${args.options.meetingId}/attendanceReports/${args.options.id}?$expand=attendanceRecords`,
52
+ headers: {
53
+ accept: 'application/json;odata.metadata=none'
54
+ },
55
+ responseType: 'json'
56
+ };
57
+ const attendanceReport = await request.get(requestOptions);
58
+ await logger.log(attendanceReport);
59
+ }
60
+ catch (err) {
61
+ this.handleRejectedODataJsonPromise(err);
62
+ }
63
+ }
64
+ async getUserId(options) {
65
+ if (options.userId) {
66
+ return options.userId;
67
+ }
68
+ if (options.userName) {
69
+ return entraUser.getUserIdByUpn(options.userName);
70
+ }
71
+ return entraUser.getUserIdByEmail(options.email);
72
+ }
73
+ }
74
+ _TeamsMeetingAttendancereportGetCommand_instances = new WeakSet(), _TeamsMeetingAttendancereportGetCommand_initTelemetry = function _TeamsMeetingAttendancereportGetCommand_initTelemetry() {
75
+ this.telemetry.push((args) => {
76
+ Object.assign(this.telemetryProperties, {
77
+ userId: typeof args.options.userId !== 'undefined',
78
+ userName: typeof args.options.userName !== 'undefined',
79
+ email: typeof args.options.email !== 'undefined'
80
+ });
81
+ });
82
+ }, _TeamsMeetingAttendancereportGetCommand_initOptions = function _TeamsMeetingAttendancereportGetCommand_initOptions() {
83
+ this.options.unshift({
84
+ option: '-u, --userId [userId]'
85
+ }, {
86
+ option: '-n, --userName [userName]'
87
+ }, {
88
+ option: '--email [email]'
89
+ }, {
90
+ option: '-m, --meetingId <meetingId>'
91
+ }, {
92
+ option: '-i, --id <id>'
93
+ });
94
+ }, _TeamsMeetingAttendancereportGetCommand_initTypes = function _TeamsMeetingAttendancereportGetCommand_initTypes() {
95
+ this.types.string.push('userId', 'userName', 'email', 'meetingId', 'id');
96
+ }, _TeamsMeetingAttendancereportGetCommand_initValidators = function _TeamsMeetingAttendancereportGetCommand_initValidators() {
97
+ this.validators.push(async (args) => {
98
+ if (!validation.isValidGuid(args.options.id)) {
99
+ return `${args.options.id} is not a valid GUID for option 'id'.`;
100
+ }
101
+ if (args.options.userId && !validation.isValidGuid(args.options.userId)) {
102
+ return `${args.options.userId} is not a valid GUID for option 'userId'.`;
103
+ }
104
+ if (args.options.userName && !validation.isValidUserPrincipalName(args.options.userName)) {
105
+ return `${args.options.userName} is not a valid UPN.`;
106
+ }
107
+ if (args.options.email && !validation.isValidUserPrincipalName(args.options.email)) {
108
+ return `${args.options.email} is not a valid email.`;
109
+ }
110
+ return true;
111
+ });
112
+ }, _TeamsMeetingAttendancereportGetCommand_initOptionSets = function _TeamsMeetingAttendancereportGetCommand_initOptionSets() {
113
+ this.optionSets.push({
114
+ options: ['userId', 'userName', 'email'],
115
+ runsWhen: (args) => args.options.userId || args.options.userName || args.options.email
116
+ });
117
+ };
118
+ export default new TeamsMeetingAttendancereportGetCommand();
119
+ //# sourceMappingURL=meeting-attendancereport-get.js.map
@@ -90,7 +90,7 @@ class TeamsMeetingListCommand extends GraphCommand {
90
90
  let result = [];
91
91
  for (let i = 0; i < meetingUrls.length; i += 20) {
92
92
  if (this.verbose) {
93
- logger.logToStderr(`Retrieving meetings ${i + 1}-${Math.min(i + 20, meetingUrls.length)}...`);
93
+ await logger.logToStderr(`Retrieving meetings ${i + 1}-${Math.min(i + 20, meetingUrls.length)}...`);
94
94
  }
95
95
  const batch = meetingUrls.slice(i, i + 20);
96
96
  const requestOptions = {
@@ -0,0 +1,112 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _TeamsMessageRemoveCommand_instances, _TeamsMessageRemoveCommand_initTelemetry, _TeamsMessageRemoveCommand_initOptions, _TeamsMessageRemoveCommand_initValidators, _TeamsMessageRemoveCommand_initOptionSets, _TeamsMessageRemoveCommand_initTypes;
7
+ import { cli } from '../../../../cli/cli.js';
8
+ import request from '../../../../request.js';
9
+ import { formatting } from '../../../../utils/formatting.js';
10
+ import { teams } from '../../../../utils/teams.js';
11
+ import { validation } from '../../../../utils/validation.js';
12
+ import DelegatedGraphCommand from '../../../base/DelegatedGraphCommand.js';
13
+ import commands from '../../commands.js';
14
+ class TeamsMessageRemoveCommand extends DelegatedGraphCommand {
15
+ get name() {
16
+ return commands.MESSAGE_REMOVE;
17
+ }
18
+ get description() {
19
+ return 'Removes a message from a channel in a Microsoft Teams team';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _TeamsMessageRemoveCommand_instances.add(this);
24
+ __classPrivateFieldGet(this, _TeamsMessageRemoveCommand_instances, "m", _TeamsMessageRemoveCommand_initTelemetry).call(this);
25
+ __classPrivateFieldGet(this, _TeamsMessageRemoveCommand_instances, "m", _TeamsMessageRemoveCommand_initOptions).call(this);
26
+ __classPrivateFieldGet(this, _TeamsMessageRemoveCommand_instances, "m", _TeamsMessageRemoveCommand_initValidators).call(this);
27
+ __classPrivateFieldGet(this, _TeamsMessageRemoveCommand_instances, "m", _TeamsMessageRemoveCommand_initOptionSets).call(this);
28
+ __classPrivateFieldGet(this, _TeamsMessageRemoveCommand_instances, "m", _TeamsMessageRemoveCommand_initTypes).call(this);
29
+ }
30
+ async commandAction(logger, args) {
31
+ const removeTeamMessage = async () => {
32
+ try {
33
+ if (this.verbose) {
34
+ await logger.logToStderr(`Removing message '${args.options.id}' from channel '${args.options.channelId || args.options.channelName}' in team '${args.options.teamId || args.options.teamName}'.`);
35
+ }
36
+ const teamId = args.options.teamId || await teams.getTeamIdByDisplayName(args.options.teamName);
37
+ const channelId = args.options.channelId || await teams.getChannelIdByDisplayName(teamId, args.options.channelName);
38
+ const requestOptions = {
39
+ url: `${this.resource}/v1.0/teams/${teamId}/channels/${formatting.encodeQueryParameter(channelId)}/messages/${args.options.id}/softDelete`,
40
+ headers: {
41
+ accept: 'application/json;odata.metadata=none'
42
+ },
43
+ responseType: 'json'
44
+ };
45
+ await request.post(requestOptions);
46
+ }
47
+ catch (err) {
48
+ if (err.error?.error?.code === 'NotFound') {
49
+ this.handleError('The message was not found in the Teams channel.');
50
+ }
51
+ else {
52
+ this.handleRejectedODataJsonPromise(err);
53
+ }
54
+ }
55
+ };
56
+ if (args.options.force) {
57
+ await removeTeamMessage();
58
+ }
59
+ else {
60
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove this message?` });
61
+ if (result) {
62
+ await removeTeamMessage();
63
+ }
64
+ }
65
+ }
66
+ }
67
+ _TeamsMessageRemoveCommand_instances = new WeakSet(), _TeamsMessageRemoveCommand_initTelemetry = function _TeamsMessageRemoveCommand_initTelemetry() {
68
+ this.telemetry.push((args) => {
69
+ Object.assign(this.telemetryProperties, {
70
+ teamId: typeof args.options.teamId !== 'undefined',
71
+ teamName: typeof args.options.teamName !== 'undefined',
72
+ channelId: typeof args.options.channelId !== 'undefined',
73
+ channelName: typeof args.options.channelName !== 'undefined',
74
+ force: !!args.options.force
75
+ });
76
+ });
77
+ }, _TeamsMessageRemoveCommand_initOptions = function _TeamsMessageRemoveCommand_initOptions() {
78
+ this.options.unshift({
79
+ option: '--teamId [teamId]'
80
+ }, {
81
+ option: '--teamName [teamName]'
82
+ }, {
83
+ option: '--channelId [channelId]'
84
+ }, {
85
+ option: '--channelName [channelName]'
86
+ }, {
87
+ option: '-i, --id <id>'
88
+ }, {
89
+ option: '-f, --force'
90
+ });
91
+ }, _TeamsMessageRemoveCommand_initValidators = function _TeamsMessageRemoveCommand_initValidators() {
92
+ this.validators.push(async (args) => {
93
+ if (args.options.teamId && !validation.isValidGuid(args.options.teamId)) {
94
+ return `'${args.options.teamId}' is not a valid GUID for 'teamId'.`;
95
+ }
96
+ if (args.options.channelId && !validation.isValidTeamsChannelId(args.options.channelId)) {
97
+ return `'${args.options.channelId}' is not a valid ID for 'channelId'.`;
98
+ }
99
+ return true;
100
+ });
101
+ }, _TeamsMessageRemoveCommand_initOptionSets = function _TeamsMessageRemoveCommand_initOptionSets() {
102
+ this.optionSets.push({
103
+ options: ['teamId', 'teamName']
104
+ }, {
105
+ options: ['channelId', 'channelName']
106
+ });
107
+ }, _TeamsMessageRemoveCommand_initTypes = function _TeamsMessageRemoveCommand_initTypes() {
108
+ this.types.string.push('teamId', 'teamName', 'channelId', 'channelName', 'id');
109
+ this.types.boolean.push('force');
110
+ };
111
+ export default new TeamsMessageRemoveCommand();
112
+ //# sourceMappingURL=message-remove.js.map
@@ -30,12 +30,14 @@ export default {
30
30
  MEETING_ADD: `${prefix} meeting add`,
31
31
  MEETING_GET: `${prefix} meeting get`,
32
32
  MEETING_LIST: `${prefix} meeting list`,
33
+ MEETING_ATTENDANCEREPORT_GET: `${prefix} meeting attendancereport get`,
33
34
  MEETING_ATTENDANCEREPORT_LIST: `${prefix} meeting attendancereport list`,
34
35
  MEETING_TRANSCRIPT_LIST: `${prefix} meeting transcript list`,
35
36
  MEMBERSETTINGS_LIST: `${prefix} membersettings list`,
36
37
  MEMBERSETTINGS_SET: `${prefix} membersettings set`,
37
38
  MESSAGE_GET: `${prefix} message get`,
38
39
  MESSAGE_LIST: `${prefix} message list`,
40
+ MESSAGE_REMOVE: `${prefix} message remove`,
39
41
  MESSAGE_REPLY_LIST: `${prefix} message reply list`,
40
42
  MESSAGE_SEND: `${prefix} message send`,
41
43
  MESSAGINGSETTINGS_LIST: `${prefix} messagingsettings list`,
@@ -0,0 +1,166 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _VivaEngageCommunityAddCommand_instances, _VivaEngageCommunityAddCommand_initTelemetry, _VivaEngageCommunityAddCommand_initOptions, _VivaEngageCommunityAddCommand_initValidators, _VivaEngageCommunityAddCommand_initTypes, _VivaEngageCommunityAddCommand_initOptionSets;
7
+ import GraphCommand from '../../../base/GraphCommand.js';
8
+ import commands from '../../commands.js';
9
+ import request from '../../../../request.js';
10
+ import { validation } from '../../../../utils/validation.js';
11
+ import { accessToken } from '../../../../utils/accessToken.js';
12
+ import auth from '../../../../Auth.js';
13
+ import { formatting } from '../../../../utils/formatting.js';
14
+ import { entraUser } from '../../../../utils/entraUser.js';
15
+ import { setTimeout } from 'timers/promises';
16
+ class VivaEngageCommunityAddCommand extends GraphCommand {
17
+ get name() {
18
+ return commands.ENGAGE_COMMUNITY_ADD;
19
+ }
20
+ get description() {
21
+ return 'Creates a new community in Viva Engage';
22
+ }
23
+ constructor() {
24
+ super();
25
+ _VivaEngageCommunityAddCommand_instances.add(this);
26
+ this.pollingInterval = 5000;
27
+ this.privacyOptions = ['public', 'private'];
28
+ __classPrivateFieldGet(this, _VivaEngageCommunityAddCommand_instances, "m", _VivaEngageCommunityAddCommand_initTelemetry).call(this);
29
+ __classPrivateFieldGet(this, _VivaEngageCommunityAddCommand_instances, "m", _VivaEngageCommunityAddCommand_initOptions).call(this);
30
+ __classPrivateFieldGet(this, _VivaEngageCommunityAddCommand_instances, "m", _VivaEngageCommunityAddCommand_initValidators).call(this);
31
+ __classPrivateFieldGet(this, _VivaEngageCommunityAddCommand_instances, "m", _VivaEngageCommunityAddCommand_initTypes).call(this);
32
+ __classPrivateFieldGet(this, _VivaEngageCommunityAddCommand_instances, "m", _VivaEngageCommunityAddCommand_initOptionSets).call(this);
33
+ }
34
+ async commandAction(logger, args) {
35
+ const { displayName, description, privacy, adminEntraIds, adminEntraUserNames, wait } = args.options;
36
+ const isAppOnlyAccessToken = accessToken.isAppOnlyAccessToken(auth.connection.accessTokens[auth.defaultResource].accessToken);
37
+ if (isAppOnlyAccessToken && !adminEntraIds && !adminEntraUserNames) {
38
+ this.handleError(`Specify at least one admin using either adminEntraIds or adminEntraUserNames options when using application permissions.`);
39
+ }
40
+ if (this.verbose) {
41
+ await logger.logToStderr(`Creating a Viva Engage community with display name '${displayName}'...`);
42
+ }
43
+ try {
44
+ const requestOptions = {
45
+ url: `${this.resource}/beta/employeeExperience/communities`,
46
+ headers: {
47
+ accept: 'application/json;odata.metadata=none',
48
+ 'content-type': 'application/json'
49
+ },
50
+ responseType: 'json',
51
+ fullResponse: true,
52
+ data: {
53
+ displayName: displayName,
54
+ description: description,
55
+ privacy: privacy
56
+ }
57
+ };
58
+ const entraIds = await this.getGraphUserUrls(args.options);
59
+ if (entraIds.length > 0) {
60
+ requestOptions.data['owners@odata.bind'] = entraIds;
61
+ }
62
+ const res = await request.post(requestOptions);
63
+ const location = res.headers.location;
64
+ if (!wait) {
65
+ await logger.log(location);
66
+ return;
67
+ }
68
+ let status;
69
+ do {
70
+ if (this.verbose) {
71
+ await logger.logToStderr(`Community still provisioning. Retrying in ${this.pollingInterval / 1000} seconds...`);
72
+ }
73
+ await setTimeout(this.pollingInterval);
74
+ if (this.verbose) {
75
+ await logger.logToStderr(`Checking create community operation status...`);
76
+ }
77
+ const operation = await request.get({
78
+ url: location,
79
+ headers: {
80
+ accept: 'application/json;odata.metadata=none'
81
+ },
82
+ responseType: 'json'
83
+ });
84
+ status = operation.status;
85
+ if (this.verbose) {
86
+ await logger.logToStderr(`Community creation operation status: ${status}`);
87
+ }
88
+ if (status === 'failed') {
89
+ throw `Community creation failed: ${operation.statusDetail}`;
90
+ }
91
+ if (status === 'succeeded') {
92
+ await logger.log(operation);
93
+ }
94
+ } while (status === 'notStarted' || status === 'running');
95
+ }
96
+ catch (err) {
97
+ this.handleRejectedODataJsonPromise(err);
98
+ }
99
+ }
100
+ async getGraphUserUrls(options) {
101
+ let entraIds = [];
102
+ if (options.adminEntraIds) {
103
+ entraIds = formatting.splitAndTrim(options.adminEntraIds);
104
+ }
105
+ else if (options.adminEntraUserNames) {
106
+ entraIds = await entraUser.getUserIdsByUpns(formatting.splitAndTrim(options.adminEntraUserNames));
107
+ }
108
+ const graphUserUrls = entraIds.map(id => `${this.resource}/beta/users/${id}`);
109
+ return graphUserUrls;
110
+ }
111
+ }
112
+ _VivaEngageCommunityAddCommand_instances = new WeakSet(), _VivaEngageCommunityAddCommand_initTelemetry = function _VivaEngageCommunityAddCommand_initTelemetry() {
113
+ this.telemetry.push((args) => {
114
+ Object.assign(this.telemetryProperties, {
115
+ adminEntraIds: typeof args.options.adminEntraIds !== 'undefined',
116
+ adminEntraUserNames: typeof args.options.adminEntraUserNames !== 'undefined',
117
+ wait: !!args.options.wait
118
+ });
119
+ });
120
+ }, _VivaEngageCommunityAddCommand_initOptions = function _VivaEngageCommunityAddCommand_initOptions() {
121
+ this.options.unshift({ option: '--displayName <displayName>' }, { option: '--description <description>' }, {
122
+ option: '--privacy <privacy>',
123
+ autocomplete: this.privacyOptions
124
+ }, { option: '--adminEntraIds [adminEntraIds]' }, { option: '--adminEntraUserNames [adminEntraUserNames]' }, { option: '--wait' });
125
+ }, _VivaEngageCommunityAddCommand_initValidators = function _VivaEngageCommunityAddCommand_initValidators() {
126
+ this.validators.push(async (args) => {
127
+ if (args.options.displayName.length > 255) {
128
+ return `The maximum amount of characters for 'displayName' is 255.`;
129
+ }
130
+ if (args.options.description.length > 1024) {
131
+ return `The maximum amount of characters for 'description' is 1024.`;
132
+ }
133
+ if (this.privacyOptions.indexOf(args.options.privacy) === -1) {
134
+ return `'${args.options.privacy}' is not a valid value for privacy. Allowed values are: ${this.privacyOptions.join(', ')}.`;
135
+ }
136
+ if (args.options.adminEntraIds) {
137
+ const isValidGUIDArrayResult = validation.isValidGuidArray(args.options.adminEntraIds);
138
+ if (isValidGUIDArrayResult !== true) {
139
+ return `The following GUIDs are invalid for the option 'adminEntraIds': ${isValidGUIDArrayResult}.`;
140
+ }
141
+ if (formatting.splitAndTrim(args.options.adminEntraIds).length > 20) {
142
+ return `Maximum of 20 admins allowed. Please reduce the number of users and try again.`;
143
+ }
144
+ }
145
+ if (args.options.adminEntraUserNames) {
146
+ const isValidUPNArrayResult = validation.isValidUserPrincipalNameArray(args.options.adminEntraUserNames);
147
+ if (isValidUPNArrayResult !== true) {
148
+ return `The following user principal names are invalid for the option 'adminEntraUserNames': ${isValidUPNArrayResult}.`;
149
+ }
150
+ if (formatting.splitAndTrim(args.options.adminEntraUserNames).length > 20) {
151
+ return `Maximum of 20 admins allowed. Please reduce the number of users and try again.`;
152
+ }
153
+ }
154
+ return true;
155
+ });
156
+ }, _VivaEngageCommunityAddCommand_initTypes = function _VivaEngageCommunityAddCommand_initTypes() {
157
+ this.types.string.push('displayName', 'description', 'privacy', 'adminEntraIds', 'adminEntraUserNames');
158
+ this.types.boolean.push('wait');
159
+ }, _VivaEngageCommunityAddCommand_initOptionSets = function _VivaEngageCommunityAddCommand_initOptionSets() {
160
+ this.optionSets.push({
161
+ options: ['adminEntraIds', 'adminEntraUserNames'],
162
+ runsWhen: (args) => args.options.adminEntraIds || args.options.adminEntraUserNames
163
+ });
164
+ };
165
+ export default new VivaEngageCommunityAddCommand();
166
+ //# sourceMappingURL=engage-community-add.js.map
@@ -22,7 +22,7 @@ class VivaEngageCommunityGetCommand extends GraphCommand {
22
22
  }
23
23
  async commandAction(logger, args) {
24
24
  if (this.verbose) {
25
- logger.logToStderr(`Getting the information of Viva Engage community with id '${args.options.id}'...`);
25
+ await logger.logToStderr(`Getting the information of Viva Engage community with id '${args.options.id}'...`);
26
26
  }
27
27
  const requestOptions = {
28
28
  url: `${this.resource}/beta/employeeExperience/communities/${args.options.id}`,
@@ -1,6 +1,7 @@
1
1
  const prefix = 'viva';
2
2
  export default {
3
3
  CONNECTIONS_APP_CREATE: `${prefix} connections app create`,
4
+ ENGAGE_COMMUNITY_ADD: `${prefix} engage community add`,
4
5
  ENGAGE_COMMUNITY_GET: `${prefix} engage community get`,
5
6
  ENGAGE_GROUP_LIST: `${prefix} engage group list`,
6
7
  ENGAGE_GROUP_USER_ADD: `${prefix} engage group user add`,
package/dist/request.js CHANGED
@@ -14,39 +14,39 @@ class Request {
14
14
  }
15
15
  this._debug = debug;
16
16
  if (this._debug) {
17
- this.req.interceptors.request.use(config => {
17
+ this.req.interceptors.request.use(async (config) => {
18
18
  if (this._logger) {
19
- this._logger.logToStderr('Request:');
19
+ await this._logger.logToStderr('Request:');
20
20
  const properties = ['url', 'method', 'headers', 'responseType', 'decompress'];
21
21
  if (config.responseType !== 'stream') {
22
22
  properties.push('data');
23
23
  }
24
- this._logger.logToStderr(JSON.stringify(formatting.filterObject(config, properties), null, 2));
24
+ await this._logger.logToStderr(JSON.stringify(formatting.filterObject(config, properties), null, 2));
25
25
  }
26
26
  return config;
27
27
  });
28
28
  // since we're stubbing requests, response interceptor is never called in
29
29
  // tests, so let's exclude it from coverage
30
30
  /* c8 ignore next 26 */
31
- this.req.interceptors.response.use((response) => {
31
+ this.req.interceptors.response.use(async (response) => {
32
32
  if (this._logger) {
33
- this._logger.logToStderr('Response:');
33
+ await this._logger.logToStderr('Response:');
34
34
  const properties = ['status', 'statusText', 'headers'];
35
35
  if (response.headers['content-type'] &&
36
36
  response.headers['content-type'].indexOf('json') > -1) {
37
37
  properties.push('data');
38
38
  }
39
- this._logger.logToStderr(JSON.stringify({
39
+ await this._logger.logToStderr(JSON.stringify({
40
40
  url: response.config.url,
41
41
  ...formatting.filterObject(response, properties)
42
42
  }, null, 2));
43
43
  }
44
44
  return response;
45
- }, (error) => {
45
+ }, async (error) => {
46
46
  if (this._logger) {
47
47
  const properties = ['status', 'statusText', 'headers'];
48
- this._logger.logToStderr('Request error:');
49
- this._logger.logToStderr(JSON.stringify({
48
+ await this._logger.logToStderr('Request error:');
49
+ await this._logger.logToStderr(JSON.stringify({
50
50
  url: error.config?.url,
51
51
  ...formatting.filterObject(error.response, properties),
52
52
  error: error.error
@@ -169,7 +169,7 @@ class Request {
169
169
  timings.api.push(Number(end - start));
170
170
  _resolve((options.responseType === 'stream' || options.fullResponse) ? res : res.data);
171
171
  }
172
- }, (error) => {
172
+ }, async (error) => {
173
173
  if (error && error.response &&
174
174
  (error.response.status === 429 ||
175
175
  error.response.status === 503)) {
@@ -178,11 +178,10 @@ class Request {
178
178
  retryAfter = 10;
179
179
  }
180
180
  if (this._debug) {
181
- this._logger.log(`Request throttled. Waiting ${retryAfter}sec before retrying...`);
181
+ await this._logger.log(`Request throttled. Waiting ${retryAfter}sec before retrying...`);
182
182
  }
183
- setTimeout(() => {
184
- this.execute(options, resolve || _resolve, reject || _reject);
185
- }, retryAfter * 1000);
183
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
184
+ setTimeout(async () => { this.execute(options, resolve || _resolve, reject || _reject); }, retryAfter * 1000);
186
185
  }
187
186
  else {
188
187
  if (reject) {
@@ -9,6 +9,8 @@ export var CheckStatus;
9
9
  (function (CheckStatus) {
10
10
  CheckStatus[CheckStatus["Success"] = 0] = "Success";
11
11
  CheckStatus[CheckStatus["Failure"] = 1] = "Failure";
12
+ CheckStatus[CheckStatus["Information"] = 2] = "Information";
13
+ CheckStatus[CheckStatus["Warning"] = 3] = "Warning";
12
14
  })(CheckStatus || (CheckStatus = {}));
13
15
  export const formatting = {
14
16
  escapeXml(s) {
@@ -152,7 +154,18 @@ export const formatting = {
152
154
  process.env.TERM === 'xterm-256color';
153
155
  const success = primarySupported ? '✔' : '√';
154
156
  const failure = primarySupported ? '✖' : '×';
155
- return `${result === CheckStatus.Success ? chalk.green(success) : chalk.red(failure)} ${message}`;
157
+ const information = 'i';
158
+ const warning = '!';
159
+ switch (result) {
160
+ case CheckStatus.Success:
161
+ return `${chalk.green(success)} ${message}`;
162
+ case CheckStatus.Failure:
163
+ return `${chalk.red(failure)} ${message}`;
164
+ case CheckStatus.Information:
165
+ return `${chalk.blue(information)} ${message}`;
166
+ case CheckStatus.Warning:
167
+ return `${chalk.yellow(warning)} ${message}`;
168
+ }
156
169
  },
157
170
  convertArrayToHashTable(key, array) {
158
171
  const resultAsKeyValuePair = {};
package/dist/utils/spo.js CHANGED
@@ -1173,7 +1173,7 @@ export const spo = {
1173
1173
  */
1174
1174
  async getFileAsListItemByUrl(absoluteListUrl, url, logger, verbose) {
1175
1175
  if (verbose && logger) {
1176
- logger.logToStderr(`Getting the file properties with url ${url}`);
1176
+ await logger.logToStderr(`Getting the file properties with url ${url}`);
1177
1177
  }
1178
1178
  const serverRelativePath = urlUtil.getServerRelativePath(absoluteListUrl, url);
1179
1179
  const requestUrl = `${absoluteListUrl}/_api/web/GetFileByServerRelativePath(DecodedUrl=@f)?$expand=ListItemAllFields&@f='${formatting.encodeQueryParameter(serverRelativePath)}'`;
@@ -1206,7 +1206,7 @@ export const spo = {
1206
1206
  const serverRelativeSiteMatch = absoluteListUrl.match(new RegExp('/sites/[^/]+'));
1207
1207
  const webUrl = `${parsedUrl.protocol}//${parsedUrl.host}${serverRelativeSiteMatch ?? ''}`;
1208
1208
  if (verbose && logger) {
1209
- logger.logToStderr(`Getting list id...`);
1209
+ await logger.logToStderr(`Getting list id...`);
1210
1210
  }
1211
1211
  const listRequestOptions = {
1212
1212
  url: `${absoluteListUrl}?$select=Id`,
@@ -1218,7 +1218,7 @@ export const spo = {
1218
1218
  const list = await request.get(listRequestOptions);
1219
1219
  const listId = list.Id;
1220
1220
  if (verbose && logger) {
1221
- logger.logToStderr(`Getting request digest for systemUpdate request`);
1221
+ await logger.logToStderr(`Getting request digest for systemUpdate request`);
1222
1222
  }
1223
1223
  const res = await spo.getRequestDigest(webUrl);
1224
1224
  const formDigestValue = res.FormDigestValue;
@@ -1361,7 +1361,7 @@ export const spo = {
1361
1361
  */
1362
1362
  async getSiteId(webUrl, logger, verbose) {
1363
1363
  if (verbose && logger) {
1364
- logger.logToStderr(`Getting site id for URL: ${webUrl}...`);
1364
+ await logger.logToStderr(`Getting site id for URL: ${webUrl}...`);
1365
1365
  }
1366
1366
  const url = new URL(webUrl);
1367
1367
  const requestOptions = {
@@ -1393,7 +1393,7 @@ export const spo = {
1393
1393
  };
1394
1394
  const response = await request.post(requestOptions);
1395
1395
  if (verbose) {
1396
- logger.logToStderr('Attempt to get _ObjectIdentity_ key values');
1396
+ await logger.logToStderr('Attempt to get _ObjectIdentity_ key values');
1397
1397
  }
1398
1398
  const json = JSON.parse(response);
1399
1399
  const contents = json.find(x => { return x.ErrorInfo; });
@@ -0,0 +1,49 @@
1
+ import { formatting } from './formatting.js';
2
+ import { odata } from './odata.js';
3
+ import { cli } from '../cli/cli.js';
4
+ const graphResource = 'https://graph.microsoft.com';
5
+ export const teams = {
6
+ /**
7
+ * Retrieve the id of a team by its name.
8
+ * @param displayName Name of the team to retrieve.
9
+ * @throws Error if the team cannot be found.
10
+ * @throws Error when multiple teams with the same name and prompting is disabled.
11
+ * @returns The ID of the team.
12
+ */
13
+ async getTeamIdByDisplayName(displayName) {
14
+ const teams = await odata.getAllItems(`${graphResource}/v1.0/teams?$filter=displayName eq '${formatting.encodeQueryParameter(displayName)}'&$select=id`);
15
+ if (!teams.length) {
16
+ throw Error(`The specified team '${displayName}' does not exist.`);
17
+ }
18
+ if (teams.length > 1) {
19
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', teams);
20
+ const result = await cli.handleMultipleResultsFound(`Multiple teams with name '${displayName}' found.`, resultAsKeyValuePair);
21
+ return result.id;
22
+ }
23
+ return teams[0].id;
24
+ },
25
+ /**
26
+ * Retrieves the channel ID by its name in a Microsoft Teams team.
27
+ * @param teamId The ID of the team.
28
+ * @param name The name of the channel.
29
+ * @returns The ID of the channel.
30
+ * @throws Throws an error if the specified channel does not exist in the team.
31
+ */
32
+ async getChannelIdByDisplayName(teamId, name) {
33
+ const channelRequestOptions = {
34
+ url: `${graphResource}/v1.0/teams/${teamId}/channels?$filter=displayName eq '${formatting.encodeQueryParameter(name)}'&$select=id`,
35
+ headers: {
36
+ accept: 'application/json;odata.metadata=none'
37
+ },
38
+ responseType: 'json'
39
+ };
40
+ const response = await odata.getAllItems(channelRequestOptions);
41
+ // Only one channel can have the same name in a team
42
+ const channelItem = response[0];
43
+ if (!channelItem) {
44
+ throw Error(`The channel '${name}' does not exist in the Microsoft Teams team with ID '${teamId}'.`);
45
+ }
46
+ return channelItem.id;
47
+ }
48
+ };
49
+ //# sourceMappingURL=teams.js.map