@pnp/cli-microsoft365 10.0.0-beta.303b62c → 10.0.0-beta.558f289

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.
@@ -0,0 +1,90 @@
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 _SpoFolderSharingLinkSetCommand_instances, _SpoFolderSharingLinkSetCommand_initTelemetry, _SpoFolderSharingLinkSetCommand_initOptions, _SpoFolderSharingLinkSetCommand_initValidators, _SpoFolderSharingLinkSetCommand_initOptionSets, _SpoFolderSharingLinkSetCommand_initTypes;
7
+ import request from '../../../../request.js';
8
+ import { spo } from '../../../../utils/spo.js';
9
+ import { urlUtil } from '../../../../utils/urlUtil.js';
10
+ import { drive } from '../../../../utils/drive.js';
11
+ import { validation } from '../../../../utils/validation.js';
12
+ import SpoCommand from '../../../base/SpoCommand.js';
13
+ import commands from '../../commands.js';
14
+ class SpoFolderSharingLinkSetCommand extends SpoCommand {
15
+ get name() {
16
+ return commands.FOLDER_SHARINGLINK_SET;
17
+ }
18
+ get description() {
19
+ return 'Updates a specific sharing link to a folder';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _SpoFolderSharingLinkSetCommand_instances.add(this);
24
+ __classPrivateFieldGet(this, _SpoFolderSharingLinkSetCommand_instances, "m", _SpoFolderSharingLinkSetCommand_initTelemetry).call(this);
25
+ __classPrivateFieldGet(this, _SpoFolderSharingLinkSetCommand_instances, "m", _SpoFolderSharingLinkSetCommand_initOptions).call(this);
26
+ __classPrivateFieldGet(this, _SpoFolderSharingLinkSetCommand_instances, "m", _SpoFolderSharingLinkSetCommand_initValidators).call(this);
27
+ __classPrivateFieldGet(this, _SpoFolderSharingLinkSetCommand_instances, "m", _SpoFolderSharingLinkSetCommand_initOptionSets).call(this);
28
+ __classPrivateFieldGet(this, _SpoFolderSharingLinkSetCommand_instances, "m", _SpoFolderSharingLinkSetCommand_initTypes).call(this);
29
+ }
30
+ async commandAction(logger, args) {
31
+ if (this.verbose) {
32
+ await logger.logToStderr(`Updating sharing link to a folder ${args.options.folderId || args.options.folderUrl}...`);
33
+ }
34
+ try {
35
+ const relFolderUrl = await spo.getFolderServerRelativeUrl(args.options.webUrl, args.options.folderUrl, args.options.folderId, logger, args.options.verbose);
36
+ const absoluteFolderUrl = urlUtil.getAbsoluteUrl(args.options.webUrl, relFolderUrl);
37
+ const folderUrl = new URL(absoluteFolderUrl);
38
+ const siteId = await spo.getSiteId(args.options.webUrl);
39
+ const driveDetails = await drive.getDriveByUrl(siteId, folderUrl, logger, args.options.verbose);
40
+ const itemId = await drive.getDriveItemId(driveDetails, folderUrl, logger, args.options.verbose);
41
+ const requestOptions = {
42
+ url: `https://graph.microsoft.com/v1.0/drives/${driveDetails.id}/items/${itemId}/permissions/${args.options.id}`,
43
+ headers: {
44
+ accept: 'application/json;odata.metadata=none',
45
+ 'content-type': 'application/json'
46
+ },
47
+ responseType: 'json',
48
+ data: {
49
+ expirationDateTime: args.options.expirationDateTime
50
+ }
51
+ };
52
+ const sharingLink = await request.patch(requestOptions);
53
+ await logger.log(sharingLink);
54
+ }
55
+ catch (err) {
56
+ this.handleRejectedODataJsonPromise(err);
57
+ }
58
+ }
59
+ }
60
+ _SpoFolderSharingLinkSetCommand_instances = new WeakSet(), _SpoFolderSharingLinkSetCommand_initTelemetry = function _SpoFolderSharingLinkSetCommand_initTelemetry() {
61
+ this.telemetry.push((args) => {
62
+ Object.assign(this.telemetryProperties, {
63
+ folderUrl: typeof args.options.folderUrl !== 'undefined',
64
+ folderId: typeof args.options.folderId !== 'undefined',
65
+ expirationDateTime: typeof args.options.expirationDateTime !== 'undefined'
66
+ });
67
+ });
68
+ }, _SpoFolderSharingLinkSetCommand_initOptions = function _SpoFolderSharingLinkSetCommand_initOptions() {
69
+ this.options.unshift({ option: '-u, --webUrl <webUrl>' }, { option: '--folderUrl [folderUrl]' }, { option: '--folderId [folderId]' }, { option: '-i, --id <id>' }, { option: '--expirationDateTime [expirationDateTime]' });
70
+ }, _SpoFolderSharingLinkSetCommand_initValidators = function _SpoFolderSharingLinkSetCommand_initValidators() {
71
+ this.validators.push(async (args) => {
72
+ const isValidSharePointUrl = validation.isValidSharePointUrl(args.options.webUrl);
73
+ if (isValidSharePointUrl !== true) {
74
+ return isValidSharePointUrl;
75
+ }
76
+ if (args.options.folderId && !validation.isValidGuid(args.options.folderId)) {
77
+ return `${args.options.folderId} is not a valid GUID`;
78
+ }
79
+ if (args.options.expirationDateTime && !validation.isValidISODateTime(args.options.expirationDateTime)) {
80
+ return `${args.options.expirationDateTime} is not a valid ISO date string.`;
81
+ }
82
+ return true;
83
+ });
84
+ }, _SpoFolderSharingLinkSetCommand_initOptionSets = function _SpoFolderSharingLinkSetCommand_initOptionSets() {
85
+ this.optionSets.push({ options: ['folderId', 'folderUrl'] });
86
+ }, _SpoFolderSharingLinkSetCommand_initTypes = function _SpoFolderSharingLinkSetCommand_initTypes() {
87
+ this.types.string.push('webUrl', 'folderId', 'folderUrl', 'id', 'expirationDateTime');
88
+ };
89
+ export default new SpoFolderSharingLinkSetCommand();
90
+ //# sourceMappingURL=folder-sharinglink-set.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SPOTenantSitePropertiesEnumerable.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TenantSiteProperties.js.map
@@ -3,16 +3,16 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
3
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
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
- var _SpoSiteListCommand_instances, _SpoSiteListCommand_initTelemetry, _SpoSiteListCommand_initOptions, _SpoSiteListCommand_initValidators;
6
+ var _SpoTenantSiteListCommand_instances, _SpoTenantSiteListCommand_initTelemetry, _SpoTenantSiteListCommand_initOptions, _SpoTenantSiteListCommand_initValidators;
7
7
  import config from '../../../../config.js';
8
8
  import request from '../../../../request.js';
9
9
  import { formatting } from '../../../../utils/formatting.js';
10
10
  import { spo } from '../../../../utils/spo.js';
11
11
  import SpoCommand from '../../../base/SpoCommand.js';
12
12
  import commands from '../../commands.js';
13
- class SpoSiteListCommand extends SpoCommand {
13
+ class SpoTenantSiteListCommand extends SpoCommand {
14
14
  get name() {
15
- return commands.SITE_LIST;
15
+ return commands.TENANT_SITE_LIST;
16
16
  }
17
17
  get description() {
18
18
  return 'Lists sites of the given type';
@@ -22,10 +22,13 @@ class SpoSiteListCommand extends SpoCommand {
22
22
  }
23
23
  constructor() {
24
24
  super();
25
- _SpoSiteListCommand_instances.add(this);
26
- __classPrivateFieldGet(this, _SpoSiteListCommand_instances, "m", _SpoSiteListCommand_initTelemetry).call(this);
27
- __classPrivateFieldGet(this, _SpoSiteListCommand_instances, "m", _SpoSiteListCommand_initOptions).call(this);
28
- __classPrivateFieldGet(this, _SpoSiteListCommand_instances, "m", _SpoSiteListCommand_initValidators).call(this);
25
+ _SpoTenantSiteListCommand_instances.add(this);
26
+ __classPrivateFieldGet(this, _SpoTenantSiteListCommand_instances, "m", _SpoTenantSiteListCommand_initTelemetry).call(this);
27
+ __classPrivateFieldGet(this, _SpoTenantSiteListCommand_instances, "m", _SpoTenantSiteListCommand_initOptions).call(this);
28
+ __classPrivateFieldGet(this, _SpoTenantSiteListCommand_instances, "m", _SpoTenantSiteListCommand_initValidators).call(this);
29
+ }
30
+ alias() {
31
+ return [commands.SITE_LIST];
29
32
  }
30
33
  async commandAction(logger, args) {
31
34
  const webTemplate = this.getWebTemplateId(args.options);
@@ -86,7 +89,7 @@ class SpoSiteListCommand extends SpoCommand {
86
89
  }
87
90
  }
88
91
  }
89
- _SpoSiteListCommand_instances = new WeakSet(), _SpoSiteListCommand_initTelemetry = function _SpoSiteListCommand_initTelemetry() {
92
+ _SpoTenantSiteListCommand_instances = new WeakSet(), _SpoTenantSiteListCommand_initTelemetry = function _SpoTenantSiteListCommand_initTelemetry() {
90
93
  this.telemetry.push((args) => {
91
94
  Object.assign(this.telemetryProperties, {
92
95
  webTemplate: args.options.webTemplate,
@@ -95,7 +98,7 @@ _SpoSiteListCommand_instances = new WeakSet(), _SpoSiteListCommand_initTelemetry
95
98
  includeOneDriveSites: typeof args.options.includeOneDriveSites !== 'undefined'
96
99
  });
97
100
  });
98
- }, _SpoSiteListCommand_initOptions = function _SpoSiteListCommand_initOptions() {
101
+ }, _SpoTenantSiteListCommand_initOptions = function _SpoTenantSiteListCommand_initOptions() {
99
102
  this.options.unshift({
100
103
  option: '-t, --type [type]',
101
104
  autocomplete: ['TeamSite', 'CommunicationSite']
@@ -106,7 +109,7 @@ _SpoSiteListCommand_instances = new WeakSet(), _SpoSiteListCommand_initTelemetry
106
109
  }, {
107
110
  option: '--includeOneDriveSites'
108
111
  });
109
- }, _SpoSiteListCommand_initValidators = function _SpoSiteListCommand_initValidators() {
112
+ }, _SpoTenantSiteListCommand_initValidators = function _SpoTenantSiteListCommand_initValidators() {
110
113
  this.validators.push(async (args) => {
111
114
  if (args.options.type && args.options.webTemplate) {
112
115
  return 'Specify either type or webTemplate, but not both';
@@ -123,5 +126,5 @@ _SpoSiteListCommand_instances = new WeakSet(), _SpoSiteListCommand_initTelemetry
123
126
  return true;
124
127
  });
125
128
  };
126
- export default new SpoSiteListCommand();
127
- //# sourceMappingURL=site-list.js.map
129
+ export default new SpoTenantSiteListCommand();
130
+ //# sourceMappingURL=tenant-site-list.js.map
@@ -104,6 +104,7 @@ export default {
104
104
  FOLDER_SHARINGLINK_GET: `${prefix} folder sharinglink get`,
105
105
  FOLDER_SHARINGLINK_LIST: `${prefix} folder sharinglink list`,
106
106
  FOLDER_SHARINGLINK_REMOVE: `${prefix} folder sharinglink remove`,
107
+ FOLDER_SHARINGLINK_SET: `${prefix} folder sharinglink set`,
107
108
  GET: `${prefix} get`,
108
109
  GROUP_ADD: `${prefix} group add`,
109
110
  GROUP_GET: `${prefix} group get`,
@@ -322,8 +323,9 @@ export default {
322
323
  TENANT_SETTINGS_LIST: `${prefix} tenant settings list`,
323
324
  TENANT_SETTINGS_SET: `${prefix} tenant settings set`,
324
325
  TENANT_SITE_ARCHIVE: `${prefix} tenant site archive`,
325
- TENANT_SITE_MEMBERSHIP_LIST: `${prefix} tenant site membership list`,
326
+ TENANT_SITE_LIST: `${prefix} tenant site list`,
326
327
  TENANT_SITE_RENAME: `${prefix} tenant site rename`,
328
+ TENANT_SITE_MEMBERSHIP_LIST: `${prefix} tenant site membership list`,
327
329
  TENANT_SITE_UNARCHIVE: `${prefix} tenant site unarchive`,
328
330
  TERM_ADD: `${prefix} term add`,
329
331
  TERM_GET: `${prefix} term get`,
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
3
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
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
- var _TeamsCacheRemoveCommand_instances, _TeamsCacheRemoveCommand_initTelemetry, _TeamsCacheRemoveCommand_initOptions, _TeamsCacheRemoveCommand_initValidators;
6
+ var _TeamsCacheRemoveCommand_instances, _a, _TeamsCacheRemoveCommand_initTelemetry, _TeamsCacheRemoveCommand_initOptions, _TeamsCacheRemoveCommand_initValidators;
7
7
  import child_process from 'child_process';
8
8
  import fs from 'fs';
9
9
  import { homedir } from 'os';
@@ -30,7 +30,7 @@ class TeamsCacheRemoveCommand extends AnonymousCommand {
30
30
  async commandAction(logger, args) {
31
31
  try {
32
32
  if (args.options.force) {
33
- await this.clearTeamsCache(logger);
33
+ await this.clearTeamsCache(args.options.client?.toLowerCase() || 'new', logger);
34
34
  }
35
35
  else {
36
36
  await logger.logToStderr('This command will execute the following steps.');
@@ -38,7 +38,7 @@ class TeamsCacheRemoveCommand extends AnonymousCommand {
38
38
  await logger.logToStderr('- Clear the Microsoft Teams cached files.');
39
39
  const result = await cli.promptForConfirmation({ message: `Are you sure you want to clear your Microsoft Teams cache?` });
40
40
  if (result) {
41
- await this.clearTeamsCache(logger);
41
+ await this.clearTeamsCache(args.options.client?.toLowerCase() || 'new', logger);
42
42
  }
43
43
  }
44
44
  }
@@ -46,33 +46,50 @@ class TeamsCacheRemoveCommand extends AnonymousCommand {
46
46
  this.handleError(err);
47
47
  }
48
48
  }
49
- async clearTeamsCache(logger) {
50
- const filePath = await this.getTeamsCacheFolderPath(logger);
51
- const folderExists = await this.checkIfCacheFolderExists(filePath, logger);
49
+ async clearTeamsCache(client, logger) {
50
+ const filePaths = await this.getTeamsCacheFolderPaths(client, logger);
51
+ let folderExists = true;
52
+ for (const filePath of filePaths) {
53
+ const exists = await this.checkIfCacheFolderExists(filePath, logger);
54
+ if (!exists) {
55
+ folderExists = false;
56
+ }
57
+ }
52
58
  if (folderExists) {
53
- await this.killRunningProcess(logger);
54
- await this.removeCacheFiles(filePath, logger);
59
+ await this.killRunningProcess(client, logger);
60
+ await this.removeCacheFiles(filePaths, logger);
55
61
  await logger.logToStderr('Teams cache cleared!');
56
62
  }
57
63
  else {
58
64
  await logger.logToStderr('Cache folder does not exist. Nothing to remove.');
59
65
  }
60
66
  }
61
- async getTeamsCacheFolderPath(logger) {
67
+ async getTeamsCacheFolderPaths(client, logger) {
62
68
  const platform = process.platform;
63
69
  if (this.verbose) {
64
70
  await logger.logToStderr(`Getting path of Teams cache folder for platform ${platform}...`);
65
71
  }
66
- let filePath = '';
72
+ const filePaths = [];
67
73
  switch (platform) {
68
74
  case 'win32':
69
- filePath = `${process.env.APPDATA}\\Microsoft\\Teams`;
75
+ if (client === 'classic') {
76
+ filePaths.push(`${process.env.APPDATA}\\Microsoft\\Teams`);
77
+ }
78
+ else {
79
+ filePaths.push(`${process.env.LOCALAPPDATA}\\Packages\\MSTeams_8wekyb3d8bbwe\\LocalCache\\Microsoft\\MSTeams`);
80
+ }
70
81
  break;
71
82
  case 'darwin':
72
- filePath = `${homedir}/Library/Application Support/Microsoft/Teams`;
83
+ if (client === 'classic') {
84
+ filePaths.push(`${homedir}/Library/Application Support/Microsoft/Teams`);
85
+ }
86
+ else {
87
+ filePaths.push(`${homedir}/Library/Group Containers/UBF8T346G9.com.microsoft.teams`);
88
+ filePaths.push(`${homedir}/Library/Containers/com.microsoft.teams2`);
89
+ }
73
90
  break;
74
91
  }
75
- return filePath;
92
+ return filePaths;
76
93
  }
77
94
  async checkIfCacheFolderExists(filePath, logger) {
78
95
  if (this.verbose) {
@@ -80,7 +97,7 @@ class TeamsCacheRemoveCommand extends AnonymousCommand {
80
97
  }
81
98
  return fs.existsSync(filePath);
82
99
  }
83
- async killRunningProcess(logger) {
100
+ async killRunningProcess(client, logger) {
84
101
  if (this.verbose) {
85
102
  await logger.logToStderr('Stopping Teams client...');
86
103
  }
@@ -88,61 +105,83 @@ class TeamsCacheRemoveCommand extends AnonymousCommand {
88
105
  let cmd = '';
89
106
  switch (platform) {
90
107
  case 'win32':
91
- cmd = 'wmic process where caption="Teams.exe" get ProcessId';
108
+ if (client === 'classic') {
109
+ cmd = 'wmic process where caption="Teams.exe" get ProcessId';
110
+ }
111
+ else {
112
+ cmd = 'wmic process where caption="ms-teams.exe" get ProcessId';
113
+ }
92
114
  break;
93
115
  case 'darwin':
94
- cmd = `ps ax | grep MacOS/Teams -m 1 | grep -v grep | awk '{ print $1 }'`;
116
+ if (client === 'classic') {
117
+ cmd = `ps ax | grep MacOS/Teams -m 1 | grep -v grep | awk '{ print $1 }'`;
118
+ }
119
+ else {
120
+ cmd = `ps ax | grep MacOS/MSTeams -m 1 | grep -v grep | awk '{ print $1 }'`;
121
+ }
95
122
  break;
96
123
  }
97
124
  if (this.debug) {
98
125
  await logger.logToStderr(cmd);
99
126
  }
100
127
  const cmdOutput = await this.exec(cmd);
101
- if (platform === 'darwin') {
128
+ if (platform === 'darwin' && cmdOutput.stdout) {
102
129
  process.kill(parseInt(cmdOutput.stdout));
103
130
  }
104
131
  else if (platform === 'win32') {
105
132
  const processJson = formatting.parseCsvToJson(cmdOutput.stdout);
106
- processJson.filter(proc => proc.ProcessId).map((proc) => {
133
+ for (const proc of processJson) {
107
134
  process.kill(proc.ProcessId);
108
- });
135
+ }
109
136
  }
110
137
  if (this.verbose) {
111
138
  await logger.logToStderr('Teams client closed');
112
139
  }
113
140
  }
114
- async removeCacheFiles(filePath, logger) {
141
+ async removeCacheFiles(filePaths, logger) {
115
142
  if (this.verbose) {
116
143
  await logger.logToStderr('Removing Teams cache files...');
117
144
  }
118
145
  const platform = process.platform;
119
- let cmd = '';
120
- switch (platform) {
121
- case 'win32':
122
- cmd = `rmdir /s /q "${filePath}"`;
123
- break;
124
- case 'darwin':
125
- cmd = `rm -r "${filePath}"`;
126
- break;
127
- }
128
- if (this.debug) {
129
- await logger.logToStderr(cmd);
146
+ const baseCmd = platform === 'win32' ? 'rmdir /s /q ' : 'rm -r ';
147
+ for (const filePath of filePaths) {
148
+ const cmd = `${baseCmd}"${filePath}"`;
149
+ if (this.debug) {
150
+ await logger.logToStderr(cmd);
151
+ }
152
+ try {
153
+ await this.exec(cmd);
154
+ }
155
+ catch (err) {
156
+ if (err?.stderr?.includes('Operation not permitted')) {
157
+ await logger.log('Deleting the folder failed. Please have a look at the following URL to delete the folders manually: https://answers.microsoft.com/en-us/msteams/forum/all/clearing-cache-on-microsoft-teams/35876f6b-eb1a-4b77-bed1-02ce3277091f');
158
+ }
159
+ else {
160
+ throw err;
161
+ }
162
+ }
130
163
  }
131
- await this.exec(cmd);
132
164
  }
133
165
  }
134
- _TeamsCacheRemoveCommand_instances = new WeakSet(), _TeamsCacheRemoveCommand_initTelemetry = function _TeamsCacheRemoveCommand_initTelemetry() {
166
+ _a = TeamsCacheRemoveCommand, _TeamsCacheRemoveCommand_instances = new WeakSet(), _TeamsCacheRemoveCommand_initTelemetry = function _TeamsCacheRemoveCommand_initTelemetry() {
135
167
  this.telemetry.push((args) => {
136
168
  Object.assign(this.telemetryProperties, {
169
+ client: args.options.client,
137
170
  force: !!args.options.force
138
171
  });
139
172
  });
140
173
  }, _TeamsCacheRemoveCommand_initOptions = function _TeamsCacheRemoveCommand_initOptions() {
141
174
  this.options.unshift({
175
+ option: '-c, --client',
176
+ autocomplete: _a.allowedClients
177
+ }, {
142
178
  option: '-f, --force'
143
179
  });
144
180
  }, _TeamsCacheRemoveCommand_initValidators = function _TeamsCacheRemoveCommand_initValidators() {
145
- this.validators.push(async () => {
181
+ this.validators.push(async (args) => {
182
+ if (args.options.client && !_a.allowedClients.includes(args.options.client.toLowerCase())) {
183
+ return `'${args.options.client}' is not a valid value for option 'client'. Allowed values are ${_a.allowedClients.join(', ')}`;
184
+ }
146
185
  if (process.env.CLIMICROSOFT365_ENV === 'docker') {
147
186
  return 'Because you\'re running CLI for Microsoft 365 in a Docker container, we can\'t clear the cache on your host. Instead run this command on your host using "npx ..."';
148
187
  }
@@ -152,5 +191,6 @@ _TeamsCacheRemoveCommand_instances = new WeakSet(), _TeamsCacheRemoveCommand_ini
152
191
  return true;
153
192
  });
154
193
  };
194
+ TeamsCacheRemoveCommand.allowedClients = ['new', 'classic'];
155
195
  export default new TeamsCacheRemoveCommand();
156
196
  //# sourceMappingURL=cache-remove.js.map
@@ -0,0 +1,98 @@
1
+ import { z } from 'zod';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { zod } from '../../../../utils/zod.js';
4
+ import GraphCommand from '../../../base/GraphCommand.js';
5
+ import commands from '../../commands.js';
6
+ import { validation } from '../../../../utils/validation.js';
7
+ import { vivaEngage } from '../../../../utils/vivaEngage.js';
8
+ import { odata } from '../../../../utils/odata.js';
9
+ const options = globalOptionsZod
10
+ .extend({
11
+ communityId: z.string().optional(),
12
+ communityDisplayName: zod.alias('n', z.string().optional()),
13
+ entraGroupId: z.string()
14
+ .refine(name => validation.isValidGuid(name), name => ({
15
+ message: `'${name}' is not a valid GUID.`
16
+ })).optional(),
17
+ role: zod.alias('r', z.enum(['Admin', 'Member']).optional())
18
+ })
19
+ .strict();
20
+ class VivaEngageCommunityUserListCommand extends GraphCommand {
21
+ get name() {
22
+ return commands.ENGAGE_COMMUNITY_USER_LIST;
23
+ }
24
+ get description() {
25
+ return 'Lists all users within a specified Microsoft 365 Viva Engage community';
26
+ }
27
+ get schema() {
28
+ return options;
29
+ }
30
+ getRefinedSchema(schema) {
31
+ return schema
32
+ .refine(options => [options.communityId, options.communityDisplayName, options.entraGroupId].filter(x => x !== undefined).length === 1, {
33
+ message: 'Specify either communityId, communityDisplayName, or entraGroupId, but not multiple.'
34
+ })
35
+ .refine(options => options.communityId || options.communityDisplayName || options.entraGroupId, {
36
+ message: 'Specify at least one of communityId, communityDisplayName, or entraGroupId.'
37
+ });
38
+ }
39
+ defaultProperties() {
40
+ return ['id', 'displayName', 'userPrincipalName', 'roles'];
41
+ }
42
+ async commandAction(logger, args) {
43
+ try {
44
+ if (this.verbose) {
45
+ await logger.logToStderr('Getting list of users in community...');
46
+ }
47
+ let entraGroupId = args.options.entraGroupId;
48
+ if (args.options.communityDisplayName) {
49
+ const community = await vivaEngage.getCommunityByDisplayName(args.options.communityDisplayName, ['groupId']);
50
+ entraGroupId = community.groupId;
51
+ }
52
+ if (args.options.communityId) {
53
+ const community = await vivaEngage.getCommunityById(args.options.communityId, ['groupId']);
54
+ entraGroupId = community.groupId;
55
+ }
56
+ const requestOptions = {
57
+ url: `${this.resource}/v1.0/groups/${entraGroupId}/members`,
58
+ headers: {
59
+ accept: 'application/json;odata.metadata=none'
60
+ },
61
+ responseType: 'json'
62
+ };
63
+ const members = await odata.getAllItems(requestOptions);
64
+ requestOptions.url = `${this.resource}/v1.0/groups/${entraGroupId}/owners`;
65
+ const owners = await odata.getAllItems(requestOptions);
66
+ const extendedMembers = members.map(m => {
67
+ return {
68
+ ...m,
69
+ roles: ['Member']
70
+ };
71
+ });
72
+ const extendedOwners = owners.map(o => {
73
+ return {
74
+ ...o,
75
+ roles: ['Admin']
76
+ };
77
+ });
78
+ let users = [];
79
+ if (args.options.role) {
80
+ if (args.options.role === 'Member') {
81
+ users = users.concat(extendedMembers);
82
+ }
83
+ if (args.options.role === 'Admin') {
84
+ users = users.concat(extendedOwners);
85
+ }
86
+ }
87
+ else {
88
+ users = extendedOwners.concat(extendedMembers);
89
+ }
90
+ await logger.log(users);
91
+ }
92
+ catch (err) {
93
+ this.handleRejectedODataJsonPromise(err);
94
+ }
95
+ }
96
+ }
97
+ export default new VivaEngageCommunityUserListCommand();
98
+ //# sourceMappingURL=engage-community-user-list.js.map
@@ -4,6 +4,7 @@ export default {
4
4
  ENGAGE_COMMUNITY_ADD: `${prefix} engage community add`,
5
5
  ENGAGE_COMMUNITY_GET: `${prefix} engage community get`,
6
6
  ENGAGE_COMMUNITY_LIST: `${prefix} engage community list`,
7
+ ENGAGE_COMMUNITY_USER_LIST: `${prefix} engage community user list`,
7
8
  ENGAGE_GROUP_LIST: `${prefix} engage group list`,
8
9
  ENGAGE_GROUP_USER_ADD: `${prefix} engage group user add`,
9
10
  ENGAGE_GROUP_USER_REMOVE: `${prefix} engage group user remove`,
@@ -0,0 +1,61 @@
1
+ import { cli } from '../cli/cli.js';
2
+ import request from '../request.js';
3
+ import { formatting } from './formatting.js';
4
+ import { odata } from './odata.js';
5
+ export const vivaEngage = {
6
+ /**
7
+ * Get Viva Engage group ID by community ID.
8
+ * @param communityId The ID of the Viva Engage community.
9
+ * @returns The ID of the Viva Engage group.
10
+ * @returns The Viva Engage community.
11
+ */
12
+ async getCommunityById(communityId, selectProperties) {
13
+ const requestOptions = {
14
+ url: `https://graph.microsoft.com/v1.0/employeeExperience/communities/${communityId}?$select=${selectProperties.join(',')}`,
15
+ headers: {
16
+ accept: 'application/json;odata.metadata=none'
17
+ },
18
+ responseType: 'json'
19
+ };
20
+ const community = await request.get(requestOptions);
21
+ if (!community) {
22
+ throw `The specified Viva Engage community with ID '${communityId}' does not exist.`;
23
+ }
24
+ return community;
25
+ },
26
+ /**
27
+ * Get Viva Engage community by display name.
28
+ * @param displayName Community display name.
29
+ * @param selectProperties Properties to select.
30
+ * @returns The Viva Engage community.
31
+ */
32
+ async getCommunityByDisplayName(displayName, selectProperties) {
33
+ const communities = await odata.getAllItems(`https://graph.microsoft.com/v1.0/employeeExperience/communities?$filter=displayName eq '${formatting.encodeQueryParameter(displayName)}'&$select=${selectProperties.join(',')}`);
34
+ if (communities.length === 0) {
35
+ throw `The specified Viva Engage community '${displayName}' does not exist.`;
36
+ }
37
+ if (communities.length > 1) {
38
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', communities);
39
+ const selectedCommunity = await cli.handleMultipleResultsFound(`Multiple Viva Engage communities with name '${displayName}' found.`, resultAsKeyValuePair);
40
+ return selectedCommunity;
41
+ }
42
+ return communities[0];
43
+ },
44
+ /**
45
+ * Get Viva Engage community by Microsoft Entra group ID.
46
+ * Note: The Graph API doesn't support filtering by groupId, so we need to retrieve all communities and filter them in memory.
47
+ * @param entraGroupId The ID of the Microsoft Entra group.
48
+ * @param selectProperties Properties to select.
49
+ * @returns The Viva Engage community.
50
+ */
51
+ async getCommunityByEntraGroupId(entraGroupId, selectProperties) {
52
+ const properties = selectProperties.includes('groupId') ? selectProperties : [...selectProperties, 'groupId'];
53
+ const communities = await odata.getAllItems(`https://graph.microsoft.com/v1.0/employeeExperience/communities?$select=${properties.join(',')}`);
54
+ const filteredCommunity = communities.find(c => c.groupId === entraGroupId);
55
+ if (!filteredCommunity) {
56
+ throw `The Microsoft Entra group with id '${entraGroupId}' is not associated with any Viva Engage community.`;
57
+ }
58
+ return filteredCommunity;
59
+ }
60
+ };
61
+ //# sourceMappingURL=vivaEngage.js.map