@pnp/cli-microsoft365 10.0.0-beta.04ac437 → 10.0.0-beta.0b765ef

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 (70) hide show
  1. package/allCommands.json +1 -1
  2. package/allCommandsFull.json +1 -1
  3. package/dist/Auth.js +3 -3
  4. package/dist/AuthServer.js +7 -7
  5. package/dist/api.js +1 -1
  6. package/dist/config.js +1 -0
  7. package/dist/m365/cli/commands/cli-doctor.js +2 -2
  8. package/dist/m365/cli/commands.js +1 -2
  9. package/dist/m365/entra/commands/group/{group-user-add.js → group-member-add.js} +18 -18
  10. package/dist/m365/entra/commands/group/{group-user-list.js → group-member-list.js} +17 -17
  11. package/dist/m365/entra/commands/group/{group-user-set.js → group-member-set.js} +19 -19
  12. package/dist/m365/entra/commands/m365group/m365group-set.js +24 -16
  13. package/dist/m365/entra/commands/m365group/m365group-user-add.js +5 -12
  14. package/dist/m365/entra/commands/oauth2grant/oauth2grant-list.js +3 -12
  15. package/dist/m365/entra/commands.js +3 -3
  16. package/dist/m365/external/commands/item/item-add.js +2 -5
  17. package/dist/m365/flow/commands/environment/environment-list.js +1 -1
  18. package/dist/m365/pa/commands/app/app-list.js +1 -6
  19. package/dist/m365/pa/commands/connector/connector-list.js +1 -6
  20. package/dist/m365/pa/commands/environment/environment-list.js +1 -1
  21. package/dist/m365/pp/commands/environment/environment-list.js +1 -1
  22. package/dist/m365/spfx/commands/project/project-doctor/{doctor-1.20.0-rc.1.js → doctor-1.20.0.js} +4 -2
  23. package/dist/m365/spfx/commands/project/project-doctor/rules/FN002021_DEVDEP_rushstack_eslint_config.js +10 -0
  24. package/dist/m365/spfx/commands/project/project-doctor.js +1 -1
  25. package/dist/m365/spfx/commands/project/project-upgrade/{upgrade-1.20.0-rc.1.js → upgrade-1.20.0.js} +28 -26
  26. package/dist/m365/spfx/commands/project/project-upgrade.js +13 -15
  27. package/dist/m365/spfx/commands/spfx-doctor.js +1 -1
  28. package/dist/m365/spo/commands/app/app-instance-list.js +3 -18
  29. package/dist/m365/spo/commands/app/app-list.js +1 -8
  30. package/dist/m365/spo/commands/feature/feature-list.js +1 -8
  31. package/dist/m365/spo/commands/list/list-webhook-list.js +1 -6
  32. package/dist/m365/spo/commands/listitem/listitem-attachment-list.js +1 -8
  33. package/dist/m365/spo/commands/page/page-list.js +1 -1
  34. package/dist/m365/spo/commands/page/page-remove.js +37 -16
  35. package/dist/m365/spo/commands/page/page-template-list.js +1 -3
  36. package/dist/m365/spo/commands/site/site-admin-list.js +8 -9
  37. package/dist/m365/spo/commands/site/site-admin-remove.js +5 -4
  38. package/dist/m365/spo/commands/site/site-sharingpermission-set.js +68 -0
  39. package/dist/m365/spo/commands/sitescript/sitescript-list.js +1 -3
  40. package/dist/m365/spo/commands/{site/site-rename.js → tenant/tenant-site-rename.js} +29 -32
  41. package/dist/m365/spo/commands/theme/theme-list.js +1 -1
  42. package/dist/m365/spo/commands/web/web-clientsidewebpart-list.js +1 -6
  43. package/dist/m365/spo/commands.js +2 -1
  44. package/dist/m365/teams/commands/tab/tab-list.js +5 -3
  45. package/dist/m365/viva/commands/engage/Community.js +2 -0
  46. package/dist/m365/viva/commands/engage/engage-community-list.js +28 -0
  47. package/dist/m365/viva/commands.js +1 -0
  48. package/dist/request.js +46 -61
  49. package/dist/utils/spo.js +5 -7
  50. package/dist/utils/timersUtil.js +12 -0
  51. package/dist/utils/urlUtil.js +8 -0
  52. package/docs/docs/cmd/cli/cli-doctor.mdx +24 -23
  53. package/docs/docs/cmd/entra/group/group-member-add.mdx +62 -0
  54. package/docs/docs/cmd/entra/group/{group-user-list.mdx → group-member-list.mdx} +14 -14
  55. package/docs/docs/cmd/entra/group/group-member-set.mdx +62 -0
  56. package/docs/docs/cmd/entra/m365group/m365group-set.mdx +9 -6
  57. package/docs/docs/cmd/entra/m365group/m365group-user-add.mdx +0 -3
  58. package/docs/docs/cmd/external/item/item-add.mdx +3 -3
  59. package/docs/docs/cmd/spfx/project/project-upgrade.mdx +1 -1
  60. package/docs/docs/cmd/spo/page/page-remove.mdx +30 -12
  61. package/docs/docs/cmd/spo/site/site-admin-list.mdx +64 -12
  62. package/docs/docs/cmd/spo/site/site-sharingpermission-set.mdx +58 -0
  63. package/docs/docs/cmd/spo/{site/site-rename.mdx → tenant/tenant-site-rename.mdx} +7 -7
  64. package/docs/docs/cmd/teams/tab/tab-list.mdx +1 -2
  65. package/docs/docs/cmd/viva/engage/engage-community-list.mdx +81 -0
  66. package/package.json +1 -1
  67. package/dist/m365/cli/commands/cli-reconsent.js +0 -29
  68. package/docs/docs/cmd/cli/cli-reconsent.mdx +0 -62
  69. package/docs/docs/cmd/entra/group/group-user-add.mdx +0 -62
  70. package/docs/docs/cmd/entra/group/group-user-set.mdx +0 -62
@@ -22,9 +22,7 @@ class SpoSiteScriptListCommand extends SpoCommand {
22
22
  responseType: 'json'
23
23
  };
24
24
  const res = await request.post(requestOptions);
25
- if (res.value && res.value.length > 0) {
26
- await logger.log(res.value);
27
- }
25
+ await logger.log(res.value);
28
26
  }
29
27
  catch (err) {
30
28
  this.handleRejectedODataJsonPromise(err);
@@ -3,25 +3,26 @@ 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 _SpoSiteRenameCommand_instances, _SpoSiteRenameCommand_initTelemetry, _SpoSiteRenameCommand_initOptions, _SpoSiteRenameCommand_initValidators;
6
+ var _SpoTenantSiteRenameCommand_instances, _SpoTenantSiteRenameCommand_initTelemetry, _SpoTenantSiteRenameCommand_initOptions, _SpoTenantSiteRenameCommand_initValidators;
7
7
  import request from '../../../../request.js';
8
8
  import { formatting } from '../../../../utils/formatting.js';
9
9
  import { spo } from '../../../../utils/spo.js';
10
+ import { timersUtil } from '../../../../utils/timersUtil.js';
10
11
  import SpoCommand from '../../../base/SpoCommand.js';
11
12
  import commands from '../../commands.js';
12
- class SpoSiteRenameCommand extends SpoCommand {
13
+ class SpoTenantSiteRenameCommand extends SpoCommand {
13
14
  get name() {
14
- return commands.SITE_RENAME;
15
+ return commands.TENANT_SITE_RENAME;
15
16
  }
16
17
  get description() {
17
18
  return 'Renames the URL and title of a site collection';
18
19
  }
19
20
  constructor() {
20
21
  super();
21
- _SpoSiteRenameCommand_instances.add(this);
22
- __classPrivateFieldGet(this, _SpoSiteRenameCommand_instances, "m", _SpoSiteRenameCommand_initTelemetry).call(this);
23
- __classPrivateFieldGet(this, _SpoSiteRenameCommand_instances, "m", _SpoSiteRenameCommand_initOptions).call(this);
24
- __classPrivateFieldGet(this, _SpoSiteRenameCommand_instances, "m", _SpoSiteRenameCommand_initValidators).call(this);
22
+ _SpoTenantSiteRenameCommand_instances.add(this);
23
+ __classPrivateFieldGet(this, _SpoTenantSiteRenameCommand_instances, "m", _SpoTenantSiteRenameCommand_initTelemetry).call(this);
24
+ __classPrivateFieldGet(this, _SpoTenantSiteRenameCommand_instances, "m", _SpoTenantSiteRenameCommand_initOptions).call(this);
25
+ __classPrivateFieldGet(this, _SpoTenantSiteRenameCommand_instances, "m", _SpoTenantSiteRenameCommand_initValidators).call(this);
25
26
  }
26
27
  async commandAction(logger, args) {
27
28
  try {
@@ -40,24 +41,23 @@ class SpoSiteRenameCommand extends SpoCommand {
40
41
  optionsBitmask = optionsBitmask | 16;
41
42
  }
42
43
  const requestOptions = {
43
- "SourceSiteUrl": options.url,
44
- "TargetSiteUrl": options.newUrl,
45
- "TargetSiteTitle": options.newTitle || null,
46
- "Option": optionsBitmask,
47
- "Reserve": null,
48
- "SkipGestures": null,
49
- "OperationId": "00000000-0000-0000-0000-000000000000"
50
- };
51
- const postData = {
52
44
  url: `${spoAdminUrl}/_api/SiteRenameJobs?api-version=1.4.7`,
53
45
  headers: {
54
46
  'X-RequestDigest': this.context.FormDigestValue,
55
47
  'Content-Type': 'application/json'
56
48
  },
57
49
  responseType: 'json',
58
- data: requestOptions
50
+ data: {
51
+ SourceSiteUrl: options.url,
52
+ TargetSiteUrl: options.newUrl,
53
+ TargetSiteTitle: options.newTitle || null,
54
+ Option: optionsBitmask,
55
+ Reserve: null,
56
+ SkipGestures: null,
57
+ OperationId: '00000000-0000-0000-0000-000000000000'
58
+ }
59
59
  };
60
- const res = await request.post(postData);
60
+ const res = await request.post(requestOptions);
61
61
  if (options.verbose) {
62
62
  await logger.logToStderr(res);
63
63
  }
@@ -92,23 +92,20 @@ class SpoSiteRenameCommand extends SpoCommand {
92
92
  if (this.operationData.JobState === "Success") {
93
93
  return;
94
94
  }
95
- await this.sleep(SpoSiteRenameCommand.checkIntervalInMs);
95
+ await timersUtil.setTimeout(SpoTenantSiteRenameCommand.checkIntervalInMs);
96
96
  await command.waitForRenameCompletion(command, isVerbose, spoAdminUrl, siteUrl, iteration);
97
97
  }
98
- sleep(ms) {
99
- return new Promise(resolve => setTimeout(resolve, ms));
100
- }
101
98
  }
102
- _SpoSiteRenameCommand_instances = new WeakSet(), _SpoSiteRenameCommand_initTelemetry = function _SpoSiteRenameCommand_initTelemetry() {
99
+ _SpoTenantSiteRenameCommand_instances = new WeakSet(), _SpoTenantSiteRenameCommand_initTelemetry = function _SpoTenantSiteRenameCommand_initTelemetry() {
103
100
  this.telemetry.push((args) => {
104
101
  Object.assign(this.telemetryProperties, {
105
- newTitle: args.options.newTitle ? true : false,
106
- suppressMarketplaceAppCheck: args.options.suppressMarketplaceAppCheck,
107
- suppressWorkflow2013Check: args.options.suppressWorkflow2013Check,
108
- wait: args.options.wait
102
+ newTitle: typeof args.options.newTitle !== 'undefined',
103
+ suppressMarketplaceAppCheck: !!args.options.suppressMarketplaceAppCheck,
104
+ suppressWorkflow2013Check: !!args.options.suppressWorkflow2013Check,
105
+ wait: !!args.options.wait
109
106
  });
110
107
  });
111
- }, _SpoSiteRenameCommand_initOptions = function _SpoSiteRenameCommand_initOptions() {
108
+ }, _SpoTenantSiteRenameCommand_initOptions = function _SpoTenantSiteRenameCommand_initOptions() {
112
109
  this.options.unshift({
113
110
  option: '-u, --url <url>'
114
111
  }, {
@@ -122,7 +119,7 @@ _SpoSiteRenameCommand_instances = new WeakSet(), _SpoSiteRenameCommand_initTelem
122
119
  }, {
123
120
  option: '--wait'
124
121
  });
125
- }, _SpoSiteRenameCommand_initValidators = function _SpoSiteRenameCommand_initValidators() {
122
+ }, _SpoTenantSiteRenameCommand_initValidators = function _SpoTenantSiteRenameCommand_initValidators() {
126
123
  this.validators.push(async (args) => {
127
124
  if (args.options.url.toLowerCase() === args.options.newUrl.toLowerCase()) {
128
125
  return 'The new URL cannot be the same as the target URL.';
@@ -130,6 +127,6 @@ _SpoSiteRenameCommand_instances = new WeakSet(), _SpoSiteRenameCommand_initTelem
130
127
  return true;
131
128
  });
132
129
  };
133
- SpoSiteRenameCommand.checkIntervalInMs = 5000;
134
- export default new SpoSiteRenameCommand();
135
- //# sourceMappingURL=site-rename.js.map
130
+ SpoTenantSiteRenameCommand.checkIntervalInMs = 5000;
131
+ export default new SpoTenantSiteRenameCommand();
132
+ //# sourceMappingURL=tenant-site-rename.js.map
@@ -26,7 +26,7 @@ class SpoThemeListCommand extends SpoCommand {
26
26
  responseType: 'json'
27
27
  };
28
28
  const rawRes = await request.post(requestOptions);
29
- await logger.log(rawRes.themePreviews);
29
+ await logger.log(rawRes.themePreviews || []);
30
30
  }
31
31
  catch (err) {
32
32
  this.handleRejectedODataJsonPromise(err);
@@ -41,12 +41,7 @@ class SpoWebClientSideWebPartListCommand extends SpoCommand {
41
41
  });
42
42
  }
43
43
  });
44
- if (clientSideWebParts.length === 0 && this.verbose) {
45
- await logger.logToStderr("No client-side web parts available for this site");
46
- }
47
- if (clientSideWebParts.length > 0) {
48
- await logger.log(clientSideWebParts);
49
- }
44
+ await logger.log(clientSideWebParts);
50
45
  }
51
46
  catch (err) {
52
47
  this.handleRejectedODataJsonPromise(err);
@@ -270,8 +270,8 @@ export default {
270
270
  SITE_RECYCLEBINITEM_REMOVE: `${prefix} site recyclebinitem remove`,
271
271
  SITE_RECYCLEBINITEM_RESTORE: `${prefix} site recyclebinitem restore`,
272
272
  SITE_REMOVE: `${prefix} site remove`,
273
- SITE_RENAME: `${prefix} site rename`,
274
273
  SITE_SET: `${prefix} site set`,
274
+ SITE_SHARINGPERMISSION_SET: `${prefix} site sharingpermission set`,
275
275
  SITE_CHROME_SET: `${prefix} site chrome set`,
276
276
  SITEDESIGN_ADD: `${prefix} sitedesign add`,
277
277
  SITEDESIGN_APPLY: `${prefix} sitedesign apply`,
@@ -321,6 +321,7 @@ export default {
321
321
  TENANT_SETTINGS_LIST: `${prefix} tenant settings list`,
322
322
  TENANT_SETTINGS_SET: `${prefix} tenant settings set`,
323
323
  TENANT_SITE_ARCHIVE: `${prefix} tenant site archive`,
324
+ TENANT_SITE_RENAME: `${prefix} tenant site rename`,
324
325
  TENANT_SITE_UNARCHIVE: `${prefix} tenant site unarchive`,
325
326
  TERM_ADD: `${prefix} term add`,
326
327
  TERM_GET: `${prefix} term get`,
@@ -29,9 +29,11 @@ class TeamsTabListCommand extends GraphCommand {
29
29
  const endpoint = `${this.resource}/v1.0/teams/${args.options.teamId}/channels/${formatting.encodeQueryParameter(args.options.channelId)}/tabs?$expand=teamsApp`;
30
30
  try {
31
31
  const items = await odata.getAllItems(endpoint);
32
- items.forEach(i => {
33
- i.teamsAppTabId = i.teamsApp.id;
34
- });
32
+ if (args.options.output !== 'json') {
33
+ items.forEach(i => {
34
+ i.teamsAppTabId = i.teamsApp.id;
35
+ });
36
+ }
35
37
  await logger.log(items);
36
38
  }
37
39
  catch (err) {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Community.js.map
@@ -0,0 +1,28 @@
1
+ import { odata } from '../../../../utils/odata.js';
2
+ import GraphCommand from '../../../base/GraphCommand.js';
3
+ import commands from '../../commands.js';
4
+ class VivaEngageCommunityListCommand extends GraphCommand {
5
+ get name() {
6
+ return commands.ENGAGE_COMMUNITY_LIST;
7
+ }
8
+ get description() {
9
+ return 'Lists all Viva Engage communities';
10
+ }
11
+ defaultProperties() {
12
+ return ['id', 'displayName', 'privacy'];
13
+ }
14
+ async commandAction(logger) {
15
+ if (this.verbose) {
16
+ await logger.logToStderr('Getting all Viva Engage communities...');
17
+ }
18
+ try {
19
+ const results = await odata.getAllItems(`${this.resource}/v1.0/employeeExperience/communities`);
20
+ await logger.log(results);
21
+ }
22
+ catch (err) {
23
+ this.handleRejectedODataJsonPromise(err);
24
+ }
25
+ }
26
+ }
27
+ export default new VivaEngageCommunityListCommand();
28
+ //# sourceMappingURL=engage-community-list.js.map
@@ -3,6 +3,7 @@ export default {
3
3
  CONNECTIONS_APP_CREATE: `${prefix} connections app create`,
4
4
  ENGAGE_COMMUNITY_ADD: `${prefix} engage community add`,
5
5
  ENGAGE_COMMUNITY_GET: `${prefix} engage community get`,
6
+ ENGAGE_COMMUNITY_LIST: `${prefix} engage community list`,
6
7
  ENGAGE_GROUP_LIST: `${prefix} engage group list`,
7
8
  ENGAGE_GROUP_USER_ADD: `${prefix} engage group user add`,
8
9
  ENGAGE_GROUP_USER_REMOVE: `${prefix} engage group user remove`,
package/dist/request.js CHANGED
@@ -4,6 +4,7 @@ import auth, { Auth } from './Auth.js';
4
4
  import { app } from './utils/app.js';
5
5
  import { formatting } from './utils/formatting.js';
6
6
  import { timings } from './cli/timings.js';
7
+ import { timersUtil } from './utils/timersUtil.js';
7
8
  class Request {
8
9
  set debug(debug) {
9
10
  // if the value to set is the same as current value return early to avoid
@@ -125,76 +126,60 @@ class Request {
125
126
  options.method = 'HEAD';
126
127
  return this.execute(options);
127
128
  }
128
- execute(options, resolve, reject) {
129
+ async execute(options) {
129
130
  const start = process.hrtime.bigint();
130
131
  if (!this._logger) {
131
- return Promise.reject('Logger not set on the request object');
132
+ throw 'Logger not set on the request object';
132
133
  }
133
134
  this.updateRequestForCloudType(options, auth.connection.cloudType);
134
- return new Promise((_resolve, _reject) => {
135
- (() => {
136
- if (options.headers && options.headers['x-anonymous']) {
137
- return Promise.resolve('');
138
- }
139
- else {
140
- const url = options.headers && options.headers['x-resource'] ? options.headers['x-resource'] : options.url;
141
- const resource = Auth.getResourceFromUrl(url);
142
- return auth.ensureAccessToken(resource, this._logger, this._debug);
143
- }
144
- })()
145
- .then((accessToken) => {
146
- if (options.headers) {
147
- if (options.headers['x-anonymous']) {
148
- delete options.headers['x-anonymous'];
149
- }
150
- if (options.headers['x-resource']) {
151
- delete options.headers['x-resource'];
152
- }
153
- if (accessToken !== '') {
154
- options.headers.authorization = `Bearer ${accessToken}`;
155
- }
156
- }
157
- const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
158
- if (proxyUrl) {
159
- options.proxy = this.createProxyConfigFromUrl(proxyUrl);
135
+ try {
136
+ let accessToken = '';
137
+ if (options.headers && options.headers['x-anonymous']) {
138
+ accessToken = '';
139
+ }
140
+ else {
141
+ const url = options.headers && options.headers['x-resource'] ? options.headers['x-resource'] : options.url;
142
+ const resource = Auth.getResourceFromUrl(url);
143
+ accessToken = await auth.ensureAccessToken(resource, this._logger, this._debug);
144
+ }
145
+ if (options.headers) {
146
+ if (options.headers['x-anonymous']) {
147
+ delete options.headers['x-anonymous'];
160
148
  }
161
- return this.req(options);
162
- })
163
- .then((res) => {
164
- if (resolve) {
165
- resolve((options.responseType === 'stream' || options.fullResponse) ? res : res.data);
149
+ if (options.headers['x-resource']) {
150
+ delete options.headers['x-resource'];
166
151
  }
167
- else {
168
- const end = process.hrtime.bigint();
169
- timings.api.push(Number(end - start));
170
- _resolve((options.responseType === 'stream' || options.fullResponse) ? res : res.data);
152
+ if (accessToken !== '') {
153
+ options.headers.authorization = `Bearer ${accessToken}`;
171
154
  }
172
- }, async (error) => {
173
- if (error && error.response &&
174
- (error.response.status === 429 ||
175
- error.response.status === 503)) {
176
- let retryAfter = parseInt(error.response.headers['retry-after'] || '10');
177
- if (isNaN(retryAfter)) {
178
- retryAfter = 10;
179
- }
180
- if (this._debug) {
181
- await this._logger.log(`Request throttled. Waiting ${retryAfter}sec before retrying...`);
182
- }
183
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
184
- setTimeout(async () => { this.execute(options, resolve || _resolve, reject || _reject); }, retryAfter * 1000);
155
+ }
156
+ const proxyUrl = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
157
+ if (proxyUrl) {
158
+ options.proxy = this.createProxyConfigFromUrl(proxyUrl);
159
+ }
160
+ const res = await this.req(options);
161
+ const end = process.hrtime.bigint();
162
+ timings.api.push(Number(end - start));
163
+ return options.responseType === 'stream' || options.fullResponse ?
164
+ res :
165
+ res.data;
166
+ }
167
+ catch (error) {
168
+ const end = process.hrtime.bigint();
169
+ timings.api.push(Number(end - start));
170
+ if (error && error.response && (error.response.status === 429 || error.response.status === 503)) {
171
+ let retryAfter = parseInt(error.response.headers['retry-after'] || '10');
172
+ if (isNaN(retryAfter)) {
173
+ retryAfter = 10;
185
174
  }
186
- else {
187
- if (reject) {
188
- reject(error);
189
- }
190
- else {
191
- const end = process.hrtime.bigint();
192
- timings.api.push(Number(end - start));
193
- _reject(error);
194
- }
175
+ if (this._debug) {
176
+ await this._logger.log(`Request throttled. Waiting ${retryAfter} sec before retrying...`);
195
177
  }
196
- });
197
- });
178
+ await timersUtil.setTimeout(retryAfter * 1000);
179
+ return this.execute(options);
180
+ }
181
+ throw error;
182
+ }
198
183
  }
199
184
  updateRequestForCloudType(options, cloudType) {
200
185
  const url = new URL(options.url);
package/dist/utils/spo.js CHANGED
@@ -1617,7 +1617,7 @@ export const spo = {
1617
1617
  return objectInfo;
1618
1618
  },
1619
1619
  /**
1620
- * Gets the site collection URL for a given web URL using SP Admin site.
1620
+ * Gets the primary owner login from a site as admin.
1621
1621
  * @param adminUrl The SharePoint admin URL
1622
1622
  * @param siteId The site ID
1623
1623
  * @param logger The logger object
@@ -1631,13 +1631,12 @@ export const spo = {
1631
1631
  const requestOptions = {
1632
1632
  url: `${adminUrl}/_api/SPO.Tenant/sites('${siteId}')?$select=OwnerLoginName`,
1633
1633
  headers: {
1634
- accept: 'application/json;odata=nometadata',
1635
- 'content-type': 'application/json;charset=utf-8'
1636
- }
1634
+ accept: 'application/json;odata=nometadata'
1635
+ },
1636
+ responseType: 'json'
1637
1637
  };
1638
1638
  const response = await request.get(requestOptions);
1639
- const responseContent = JSON.parse(response);
1640
- return responseContent.OwnerLoginName;
1639
+ return response.OwnerLoginName;
1641
1640
  },
1642
1641
  /**
1643
1642
  * Gets the primary owner login from a site.
@@ -1652,7 +1651,6 @@ export const spo = {
1652
1651
  }
1653
1652
  const requestOptions = {
1654
1653
  url: `${siteUrl}/_api/site/owner`,
1655
- method: 'GET',
1656
1654
  headers: {
1657
1655
  'accept': 'application/json;odata=nometadata'
1658
1656
  },
@@ -0,0 +1,12 @@
1
+ import { setTimeout } from "timers/promises";
2
+ export const timersUtil = {
3
+ /**
4
+ * Timeout for a specific duration.
5
+ * @param duration Duration in milliseconds.
6
+ */
7
+ /* c8 ignore next 3 */
8
+ async setTimeout(duration) {
9
+ return setTimeout(duration);
10
+ }
11
+ };
12
+ //# sourceMappingURL=timersUtil.js.map
@@ -198,6 +198,14 @@ export const urlUtil = {
198
198
  return rootUrl.origin;
199
199
  }
200
200
  },
201
+ /**
202
+ * Removes leading slashes from the URL.
203
+ * @param url The URL to process.
204
+ * @returns The URL without leading slashes.
205
+ */
206
+ removeLeadingSlashes(url) {
207
+ return url.replace(/^\/+/, '');
208
+ },
201
209
  /**
202
210
  * Removes trailing slashes from the URL.
203
211
  * @param url The URL to process.
@@ -22,7 +22,7 @@ This command gets all the necessary diagnostic information needed to triage and
22
22
 
23
23
  ## Examples
24
24
 
25
- Retrieve diagnostic information
25
+ Retrieve diagnostic information.
26
26
 
27
27
  ```sh
28
28
  m365 cli doctor
@@ -42,18 +42,20 @@ m365 cli doctor
42
42
  },
43
43
  "cliVersion": "6.1.0",
44
44
  "nodeVersion": "v16.13.0",
45
- "cliAadAppId": "31359c7f-bd7e-475c-86db-fdb8c937548e",
46
- "cliAadAppTenant": "common",
47
- "authMode": "DeviceCode",
45
+ "cliEntraAppId": "31359c7f-bd7e-475c-86db-fdb8c937548e",
46
+ "cliEntraAppTenant": "common",
47
+ "authMode": "deviceCode",
48
48
  "cliEnvironment": "",
49
49
  "cliConfig": {
50
50
  "output": "json",
51
51
  "showHelpOnFailure": false
52
52
  },
53
53
  "roles": [],
54
- "scopes": [
55
- "AllSites.FullControl"
56
- ]
54
+ "scopes": {
55
+ "https://graph.microsoft.com": [
56
+ "AllSites.FullControl"
57
+ ]
58
+ }
57
59
  }
58
60
  ```
59
61
 
@@ -61,24 +63,24 @@ m365 cli doctor
61
63
  <TabItem value="Text">
62
64
 
63
65
  ```text
64
- authMode : DeviceCode
65
- cliAadAppId : 31359c7f-bd7e-475c-86db-fdb8c937548e
66
- cliAadAppTenant: common
67
- cliConfig : {"output":"json","showHelpOnFailure":false}
68
- cliEnvironment :
69
- cliVersion : 6.1.0
70
- nodeVersion : v16.13.0
71
- os : {"platform":"win32","version":"Windows 10 Pro","release":"10.0.19045"}
72
- roles : []
73
- scopes : ["AllSites.FullControl"]
66
+ authMode : deviceCode
67
+ cliConfig : {"output":"json","showHelpOnFailure":false}
68
+ cliEntraAppId : 31359c7f-bd7e-475c-86db-fdb8c937548e
69
+ cliEntraAppTenant: common
70
+ cliEnvironment :
71
+ cliVersion : 6.1.0
72
+ nodeVersion : v16.13.0
73
+ os : {"platform":"win32","version":"Windows 10 Pro","release":"10.0.19045"}
74
+ roles : []
75
+ scopes : {"https://graph.microsoft.com":["AllSites.FullControl"]}
74
76
  ```
75
77
 
76
78
  </TabItem>
77
79
  <TabItem value="CSV">
78
80
 
79
81
  ```csv
80
- os,cliVersion,nodeVersion,cliAadAppId,cliAadAppTenant,authMode,cliEnvironment,cliConfig,roles,scopes
81
- "{""platform"":""win32"",""version"":""Windows 10 Pro"",""release"":""10.0.19045""}",6.1.0,v16.13.0,31359c7f-bd7e-475c-86db-fdb8c937548e,common,DeviceCode,,"{""output"":""json"",""showHelpOnFailure"":false}",[],"[""AllSites.FullControl""]"
82
+ os,cliVersion,nodeVersion,cliEntraAppId,cliEntraAppTenant,authMode,cliEnvironment,cliConfig,roles,scopes
83
+ "{""platform"":""win32"",""version"":""Windows 10 Pro"",""release"":""10.0.19045""}",6.1.0,v16.13.0,31359c7f-bd7e-475c-86db-fdb8c937548e,common,deviceCode,,"{""output"":""json"",""showHelpOnFailure"":false}",[],"{""https://graph.microsoft.com"":[""AllSites.FullControl""]}"
82
84
  ```
83
85
 
84
86
  </TabItem>
@@ -93,12 +95,11 @@ m365 cli doctor
93
95
  ---------|-------
94
96
  cliVersion | 6.1.0
95
97
  nodeVersion | v16.13.0
96
- cliAadAppId | 31359c7f-bd7e-475c-86db-fdb8c937548e
97
- cliAadAppTenant | common
98
- authMode | DeviceCode
98
+ cliEntraAppId | 31359c7f-bd7e-475c-86db-fdb8c937548e
99
+ cliEntraAppTenant | common
100
+ authMode | deviceCode
99
101
  cliEnvironment |
100
102
  ```
101
103
 
102
104
  </TabItem>
103
105
  </Tabs>
104
-
@@ -0,0 +1,62 @@
1
+ import Global from '/docs/cmd/_global.mdx';
2
+
3
+ # entra group member add
4
+
5
+ Adds a member to a Microsoft Entra ID group
6
+
7
+ ## Usage
8
+
9
+ ```sh
10
+ m365 entra group member add [options]
11
+ ```
12
+
13
+ ## Options
14
+
15
+ ```md definition-list
16
+ `-i, --groupId [groupId]`
17
+ : The ID of the Microsoft Entra group. Specify `groupId` or `groupDisplayName` but not both.
18
+
19
+ `-n, --groupDisplayName [groupDisplayName]`
20
+ : The display name of the Microsoft Entra group. Specify `groupId` or `groupDisplayName` but not both.
21
+
22
+ `--ids [ids]`
23
+ : Microsoft Entra IDs of users. You can also pass a comma-separated list of IDs. Specify either `ids` or `userNames` but not both.
24
+
25
+ `--userNames [userNames]`
26
+ : The user principal names of users. You can also pass a comma-separated list of UPNs. Specify either `ids` or `userNames` but not both.
27
+
28
+ `-r, --role <role>`
29
+ : The role to be assigned to the new users. Valid values: `Owner`, `Member`.
30
+ ```
31
+
32
+ <Global />
33
+
34
+ ## Examples
35
+
36
+ Add a single member specified by ID as a member to a group specified by display name.
37
+
38
+ ```sh
39
+ m365 entra group member add --groupDisplayName Developers --ids 098b9f52-f48c-4401-819f-29c33794c3f5 --role Member
40
+ ```
41
+
42
+ Add multiple members specified by ID as members to a group specified by ID.
43
+
44
+ ```sh
45
+ m365 entra group member add --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --ids "098b9f52-f48c-4401-819f-29c33794c3f5,f1e06e31-3abf-4746-83c2-1513d71f38b8" --role Member
46
+ ```
47
+
48
+ Add a single member specified by UPN as an owner to a group specified by display name.
49
+
50
+ ```sh
51
+ m365 entra group member add --groupDisplayName Developers --userNames john.doe@contoso.com --role Owner
52
+ ```
53
+
54
+ Adds multiple members specified by UPN as owners to a group specified by ID.
55
+
56
+ ```sh
57
+ m365 entra group member add --groupId a03c0c35-ef9a-419b-8cab-f89e0a8d2d2a --userNames "john.doe@contoso.com,adele.vance@contoso.com" --role Owner
58
+ ```
59
+
60
+ ## Response
61
+
62
+ The command won't return a response on success.