@pnp/cli-microsoft365 7.2.0-beta.c7e1c03 → 7.2.0-beta.d29d172

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 (126) hide show
  1. package/allCommands.json +1 -0
  2. package/allCommandsFull.json +1 -0
  3. package/dist/Auth.js +1 -1
  4. package/dist/api.js +5 -7
  5. package/dist/cli/Cli.js +96 -118
  6. package/dist/cli/timings.js +9 -0
  7. package/dist/index.js +8 -14
  8. package/dist/m365/cli/commands/config/config-set.js +5 -0
  9. package/dist/m365/commands/login.js +12 -8
  10. package/dist/m365/flow/commands/environment/environment-list.js +6 -4
  11. package/dist/m365/spfx/commands/project/DeployWorkflow.js +4 -4
  12. package/dist/m365/spfx/commands/project/project-doctor/{doctor-1.18.1-rc.0.js → doctor-1.18.1.js} +1 -1
  13. package/dist/m365/spfx/commands/project/project-doctor.js +1 -1
  14. package/dist/m365/spfx/commands/project/project-github-workflow-add.js +17 -0
  15. package/dist/m365/spfx/commands/project/project-upgrade/{upgrade-1.18.1-rc.0.js → upgrade-1.18.1.js} +26 -26
  16. package/dist/m365/spfx/commands/project/project-upgrade.js +13 -15
  17. package/dist/m365/spfx/commands/spfx-doctor.js +1 -1
  18. package/dist/m365/spo/commands/file/file-retentionlabel-ensure.js +14 -23
  19. package/dist/m365/spo/commands/file/file-retentionlabel-remove.js +19 -27
  20. package/dist/m365/spo/commands/folder/folder-retentionlabel-ensure.js +9 -29
  21. package/dist/m365/spo/commands/folder/folder-retentionlabel-remove.js +9 -28
  22. package/dist/m365/spo/commands/list/list-retentionlabel-ensure.js +27 -37
  23. package/dist/m365/spo/commands/list/list-retentionlabel-remove.js +6 -19
  24. package/dist/m365/spo/commands/listitem/listitem-retentionlabel-ensure.js +36 -37
  25. package/dist/m365/spo/commands/listitem/listitem-retentionlabel-remove.js +36 -32
  26. package/dist/m365/spo/commands/site/site-add.js +45 -12
  27. package/dist/m365/spo/commands/sitescript/sitescript-get.js +8 -2
  28. package/dist/m365/spo/commands/tenant/tenant-recyclebinitem-restore.js +19 -2
  29. package/dist/request.js +6 -0
  30. package/dist/settingsNames.js +1 -0
  31. package/dist/utils/spo.js +109 -0
  32. package/docs/docs/_clisettings.mdx +1 -0
  33. package/docs/docs/cmd/aad/approleassignment/approleassignment-add.mdx +1 -1
  34. package/docs/docs/cmd/aad/approleassignment/approleassignment-list.mdx +2 -2
  35. package/docs/docs/cmd/aad/approleassignment/approleassignment-remove.mdx +1 -1
  36. package/docs/docs/cmd/aad/oauth2grant/oauth2grant-add.mdx +1 -1
  37. package/docs/docs/cmd/aad/oauth2grant/oauth2grant-list.mdx +2 -2
  38. package/docs/docs/cmd/aad/oauth2grant/oauth2grant-remove.mdx +2 -2
  39. package/docs/docs/cmd/aad/oauth2grant/oauth2grant-set.mdx +2 -2
  40. package/docs/docs/cmd/aad/policy/policy-list.mdx +1 -1
  41. package/docs/docs/cmd/aad/siteclassification/siteclassification-disable.mdx +1 -1
  42. package/docs/docs/cmd/aad/siteclassification/siteclassification-enable.mdx +1 -1
  43. package/docs/docs/cmd/aad/siteclassification/siteclassification-get.mdx +1 -1
  44. package/docs/docs/cmd/aad/siteclassification/siteclassification-set.mdx +1 -1
  45. package/docs/docs/cmd/aad/sp/sp-add.mdx +2 -2
  46. package/docs/docs/cmd/aad/sp/sp-get.mdx +2 -2
  47. package/docs/docs/cmd/aad/user/user-add.mdx +3 -3
  48. package/docs/docs/cmd/aad/user/user-guest-add.mdx +1 -1
  49. package/docs/docs/cmd/aad/user/user-set.mdx +3 -3
  50. package/docs/docs/cmd/graph/changelog/changelog-list.mdx +5 -5
  51. package/docs/docs/cmd/login.mdx +1 -1
  52. package/docs/docs/cmd/onenote/notebook/notebook-list.mdx +1 -1
  53. package/docs/docs/cmd/outlook/message/message-list.mdx +1 -1
  54. package/docs/docs/cmd/outlook/message/message-move.mdx +1 -1
  55. package/docs/docs/cmd/planner/bucket/bucket-add.mdx +1 -1
  56. package/docs/docs/cmd/planner/bucket/bucket-set.mdx +1 -1
  57. package/docs/docs/cmd/planner/plan/plan-set.mdx +3 -3
  58. package/docs/docs/cmd/planner/task/task-set.mdx +1 -1
  59. package/docs/docs/cmd/purview/auditlog/auditlog-list.mdx +3 -3
  60. package/docs/docs/cmd/purview/retentionevent/retentionevent-add.mdx +1 -1
  61. package/docs/docs/cmd/purview/retentionevent/retentionevent-get.mdx +1 -1
  62. package/docs/docs/cmd/purview/retentioneventtype/retentioneventtype-add.mdx +1 -1
  63. package/docs/docs/cmd/purview/retentioneventtype/retentioneventtype-get.mdx +1 -1
  64. package/docs/docs/cmd/purview/retentioneventtype/retentioneventtype-remove.mdx +1 -1
  65. package/docs/docs/cmd/purview/retentioneventtype/retentioneventtype-set.mdx +1 -1
  66. package/docs/docs/cmd/purview/retentionlabel/retentionlabel-add.mdx +1 -1
  67. package/docs/docs/cmd/purview/sensitivitylabel/sensitivitylabel-policysettings-list.mdx +4 -4
  68. package/docs/docs/cmd/spfx/project/project-upgrade.mdx +1 -1
  69. package/docs/docs/cmd/spo/app/app-add.mdx +1 -1
  70. package/docs/docs/cmd/spo/app/app-deploy.mdx +1 -1
  71. package/docs/docs/cmd/spo/app/app-get.mdx +1 -1
  72. package/docs/docs/cmd/spo/app/app-install.mdx +1 -1
  73. package/docs/docs/cmd/spo/app/app-list.mdx +1 -1
  74. package/docs/docs/cmd/spo/app/app-remove.mdx +1 -1
  75. package/docs/docs/cmd/spo/app/app-retract.mdx +1 -1
  76. package/docs/docs/cmd/spo/app/app-uninstall.mdx +1 -1
  77. package/docs/docs/cmd/spo/app/app-upgrade.mdx +1 -1
  78. package/docs/docs/cmd/spo/contenttype/contenttype-add.mdx +1 -1
  79. package/docs/docs/cmd/spo/contenttype/contenttype-set.mdx +1 -1
  80. package/docs/docs/cmd/spo/hidedefaultthemes/hidedefaultthemes-get.mdx +1 -1
  81. package/docs/docs/cmd/spo/hidedefaultthemes/hidedefaultthemes-set.mdx +1 -1
  82. package/docs/docs/cmd/spo/site/site-add.mdx +25 -4
  83. package/docs/docs/cmd/spo/site/site-appcatalog-add.mdx +1 -1
  84. package/docs/docs/cmd/spo/site/site-appcatalog-remove.mdx +1 -1
  85. package/docs/docs/cmd/spo/site/site-groupify.mdx +1 -1
  86. package/docs/docs/cmd/spo/sitedesign/sitedesign-add.mdx +3 -3
  87. package/docs/docs/cmd/spo/sitedesign/sitedesign-apply.mdx +1 -1
  88. package/docs/docs/cmd/spo/sitedesign/sitedesign-get.mdx +1 -1
  89. package/docs/docs/cmd/spo/sitedesign/sitedesign-list.mdx +1 -1
  90. package/docs/docs/cmd/spo/sitedesign/sitedesign-remove.mdx +1 -1
  91. package/docs/docs/cmd/spo/sitedesign/sitedesign-rights-grant.mdx +1 -1
  92. package/docs/docs/cmd/spo/sitedesign/sitedesign-rights-list.mdx +1 -1
  93. package/docs/docs/cmd/spo/sitedesign/sitedesign-rights-revoke.mdx +1 -1
  94. package/docs/docs/cmd/spo/sitedesign/sitedesign-run-list.mdx +1 -1
  95. package/docs/docs/cmd/spo/sitedesign/sitedesign-run-status-get.mdx +1 -1
  96. package/docs/docs/cmd/spo/sitedesign/sitedesign-set.mdx +3 -3
  97. package/docs/docs/cmd/spo/sitedesign/sitedesign-task-get.mdx +1 -1
  98. package/docs/docs/cmd/spo/sitedesign/sitedesign-task-list.mdx +1 -1
  99. package/docs/docs/cmd/spo/sitedesign/sitedesign-task-remove.mdx +1 -1
  100. package/docs/docs/cmd/spo/sitescript/sitescript-add.mdx +1 -1
  101. package/docs/docs/cmd/spo/sitescript/sitescript-get.mdx +73 -3
  102. package/docs/docs/cmd/spo/sitescript/sitescript-list.mdx +1 -1
  103. package/docs/docs/cmd/spo/sitescript/sitescript-remove.mdx +1 -1
  104. package/docs/docs/cmd/spo/sitescript/sitescript-set.mdx +1 -1
  105. package/docs/docs/cmd/spo/storageentity/storageentity-get.mdx +1 -1
  106. package/docs/docs/cmd/spo/storageentity/storageentity-list.mdx +1 -1
  107. package/docs/docs/cmd/spo/storageentity/storageentity-remove.mdx +1 -1
  108. package/docs/docs/cmd/spo/storageentity/storageentity-set.mdx +1 -1
  109. package/docs/docs/cmd/spo/theme/theme-apply.mdx +1 -1
  110. package/docs/docs/cmd/spo/theme/theme-get.mdx +1 -1
  111. package/docs/docs/cmd/spo/theme/theme-list.mdx +1 -1
  112. package/docs/docs/cmd/spo/theme/theme-remove.mdx +1 -1
  113. package/docs/docs/cmd/spo/user/user-remove.mdx +1 -1
  114. package/docs/docs/cmd/spo/web/web-set.mdx +1 -1
  115. package/docs/docs/cmd/teams/channel/channel-remove.mdx +1 -1
  116. package/docs/docs/cmd/teams/meeting/meeting-get.mdx +1 -1
  117. package/docs/docs/cmd/teams/meeting/meeting-transcript-list.mdx +1 -1
  118. package/docs/docs/cmd/teams/report/report-pstncalls.mdx +1 -1
  119. package/docs/docs/cmd/teams/tab/tab-remove.mdx +1 -1
  120. package/docs/docs/cmd/teams/team/team-remove.mdx +1 -1
  121. package/docs/docs/cmd/tenant/serviceannouncement/serviceannouncement-healthissue-list.mdx +1 -1
  122. package/docs/docs/cmd/tenant/serviceannouncement/serviceannouncement-message-get.mdx +1 -1
  123. package/docs/docs/cmd/tenant/serviceannouncement/serviceannouncement-message-list.mdx +1 -1
  124. package/docs/docs/cmd/todo/task/task-set.mdx +1 -1
  125. package/npm-shrinkwrap.json +480 -516
  126. package/package.json +28 -28
@@ -4,14 +4,15 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
6
  var _SpoListItemRetentionLabelEnsureCommand_instances, _SpoListItemRetentionLabelEnsureCommand_initTelemetry, _SpoListItemRetentionLabelEnsureCommand_initOptions, _SpoListItemRetentionLabelEnsureCommand_initValidators, _SpoListItemRetentionLabelEnsureCommand_initOptionSets;
7
- import { Cli } from '../../../../cli/Cli.js';
7
+ import * as url from 'url';
8
8
  import request from '../../../../request.js';
9
9
  import { formatting } from '../../../../utils/formatting.js';
10
10
  import { urlUtil } from '../../../../utils/urlUtil.js';
11
11
  import { validation } from '../../../../utils/validation.js';
12
12
  import SpoCommand from '../../../base/SpoCommand.js';
13
13
  import commands from '../../commands.js';
14
- import spoWebRetentionLabelListCommand from '../web/web-retentionlabel-list.js';
14
+ import { spo } from '../../../../utils/spo.js';
15
+ import { odata } from '../../../../utils/odata.js';
15
16
  class SpoListItemRetentionLabelEnsureCommand extends SpoCommand {
16
17
  get name() {
17
18
  return commands.LISTITEM_RETENTIONLABEL_ENSURE;
@@ -29,68 +30,66 @@ class SpoListItemRetentionLabelEnsureCommand extends SpoCommand {
29
30
  }
30
31
  async commandAction(logger, args) {
31
32
  try {
32
- const labelInformation = await this.getLabelInformation(args.options, logger);
33
+ const listAbsoluteUrl = await this.getListAbsoluteUrl(args.options, logger);
34
+ const labelName = await this.getLabelName(args.options, logger);
33
35
  if (args.options.assetId) {
34
36
  await this.applyAssetId(args.options, logger);
35
37
  }
36
- await this.applyLabel(args.options, labelInformation, logger);
38
+ await spo.applyRetentionLabelToListItems(args.options.webUrl, labelName, listAbsoluteUrl, [parseInt(args.options.listItemId)], logger, args.options.verbose);
37
39
  }
38
40
  catch (err) {
39
41
  this.handleRejectedODataJsonPromise(err);
40
42
  }
41
43
  }
42
- async getLabelInformation(options, logger) {
43
- const cmdOptions = {
44
- webUrl: options.webUrl,
45
- output: 'json',
46
- debug: options.debug,
47
- verbose: options.verbose
48
- };
49
- const output = await Cli.executeCommandWithOutput(spoWebRetentionLabelListCommand, { options: { ...cmdOptions, _: [] } });
44
+ async getLabelName(options, logger) {
45
+ if (options.name) {
46
+ return options.name;
47
+ }
50
48
  if (this.verbose) {
51
- await logger.logToStderr(output.stderr);
49
+ logger.logToStderr(`Retrieving the name of the retention label based on the Id '${options.id}'...`);
50
+ }
51
+ const requestUrl = `${options.webUrl}/_api/SP.CompliancePolicy.SPPolicyStoreProxy.GetAvailableTagsForSite(siteUrl=@a1)?@a1='${formatting.encodeQueryParameter(options.webUrl)}'`;
52
+ const labels = await odata.getAllItems(requestUrl);
53
+ const label = labels.find(l => l.TagId === options.id);
54
+ if (label === undefined) {
55
+ throw new Error(`The specified retention label does not exist or is not published to this SharePoint site. Use the name of the label if you want to apply an unpublished label.`);
52
56
  }
53
- const labels = JSON.parse(output.stdout);
54
- const label = labels.find(l => l.TagName === options.name || l.TagId === options.id);
55
57
  if (this.verbose && label !== undefined) {
56
58
  await logger.logToStderr(`Retention label found in the list of available labels: '${label.TagName}' / '${label.TagId}'...`);
57
59
  }
58
- if (label === undefined) {
59
- throw new Error(`The specified retention label does not exist`);
60
- }
61
- return {
62
- complianceTag: label.TagName,
63
- isTagPolicyHold: label.BlockDelete,
64
- isTagPolicyRecord: label.BlockEdit,
65
- isEventBasedTag: label.IsEventTag,
66
- isTagSuperLock: label.SuperLock,
67
- isUnlockedAsDefault: label.UnlockedAsDefault
68
- };
60
+ return label.TagName;
69
61
  }
70
- async applyLabel(options, labelInformation, logger) {
62
+ async getListAbsoluteUrl(options, logger) {
63
+ const parsedUrl = url.parse(options.webUrl);
64
+ const tenantUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}`;
65
+ if (options.listUrl) {
66
+ const serverRelativePath = urlUtil.getServerRelativePath(options.webUrl, options.listUrl);
67
+ return urlUtil.urlCombine(tenantUrl, serverRelativePath);
68
+ }
71
69
  if (this.verbose) {
72
- await logger.logToStderr(`Applying retention label to item in list '${options.listId || options.listTitle || options.listUrl}' in site at ${options.webUrl}...`);
70
+ await logger.logToStderr(`Retrieving list absolute URL...`);
73
71
  }
74
72
  let requestUrl = `${options.webUrl}/_api/web`;
75
73
  if (options.listId) {
76
- requestUrl += `/lists(guid'${formatting.encodeQueryParameter(options.listId)}')/items(${options.listItemId})/SetComplianceTag()`;
74
+ requestUrl += `/lists(guid'${formatting.encodeQueryParameter(options.listId)}')`;
77
75
  }
78
76
  else if (options.listTitle) {
79
- requestUrl += `/lists/getByTitle('${formatting.encodeQueryParameter(options.listTitle)}')/items(${options.listItemId})/SetComplianceTag()`;
80
- }
81
- else if (options.listUrl) {
82
- const listServerRelativeUrl = urlUtil.getServerRelativePath(options.webUrl, options.listUrl);
83
- requestUrl += `/GetList(@listUrl)/items(${options.listItemId})/SetComplianceTag()?@listUrl='${formatting.encodeQueryParameter(listServerRelativeUrl)}'`;
77
+ requestUrl += `/lists/getByTitle('${formatting.encodeQueryParameter(options.listTitle)}')`;
84
78
  }
85
79
  const requestOptions = {
86
- url: requestUrl,
80
+ url: `${requestUrl}?$expand=RootFolder&$select=RootFolder/ServerRelativeUrl`,
87
81
  headers: {
88
82
  'accept': 'application/json;odata=nometadata'
89
83
  },
90
- data: labelInformation,
91
84
  responseType: 'json'
92
85
  };
93
- await request.post(requestOptions);
86
+ const response = await request.get(requestOptions);
87
+ const serverRelativePath = urlUtil.getServerRelativePath(options.webUrl, response.RootFolder.ServerRelativeUrl);
88
+ const listAbsoluteUrl = urlUtil.urlCombine(tenantUrl, serverRelativePath);
89
+ if (this.verbose) {
90
+ logger.logToStderr(`List absolute URL found: '${listAbsoluteUrl}'`);
91
+ }
92
+ return listAbsoluteUrl;
94
93
  }
95
94
  async applyAssetId(options, logger) {
96
95
  if (this.verbose) {
@@ -4,6 +4,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
6
  var _SpoListItemRetentionLabelRemoveCommand_instances, _SpoListItemRetentionLabelRemoveCommand_initTelemetry, _SpoListItemRetentionLabelRemoveCommand_initOptions, _SpoListItemRetentionLabelRemoveCommand_initValidators, _SpoListItemRetentionLabelRemoveCommand_initOptionSets;
7
+ import * as url from 'url';
7
8
  import { Cli } from '../../../../cli/Cli.js';
8
9
  import request from '../../../../request.js';
9
10
  import { formatting } from '../../../../utils/formatting.js';
@@ -11,6 +12,7 @@ import { urlUtil } from '../../../../utils/urlUtil.js';
11
12
  import { validation } from '../../../../utils/validation.js';
12
13
  import SpoCommand from '../../../base/SpoCommand.js';
13
14
  import commands from '../../commands.js';
15
+ import { spo } from '../../../../utils/spo.js';
14
16
  class SpoListItemRetentionLabelRemoveCommand extends SpoCommand {
15
17
  get name() {
16
18
  return commands.LISTITEM_RETENTIONLABEL_REMOVE;
@@ -38,44 +40,46 @@ class SpoListItemRetentionLabelRemoveCommand extends SpoCommand {
38
40
  }
39
41
  }
40
42
  async removeListItemRetentionLabel(logger, args) {
41
- if (this.verbose) {
42
- await logger.logToStderr(`Removing retention label from list item ${args.options.listItemId} from list '${args.options.listId || args.options.listTitle || args.options.listUrl}' in site at ${args.options.webUrl}...`);
43
- }
44
43
  try {
45
- let url = `${args.options.webUrl}/_api/web`;
46
- if (args.options.listId) {
47
- url += `/lists(guid'${formatting.encodeQueryParameter(args.options.listId)}')/items(${args.options.listItemId})/SetComplianceTag()`;
48
- }
49
- else if (args.options.listTitle) {
50
- url += `/lists/getByTitle('${formatting.encodeQueryParameter(args.options.listTitle)}')/items(${args.options.listItemId})/SetComplianceTag()`;
51
- }
52
- else {
53
- const listServerRelativeUrl = urlUtil.getServerRelativePath(args.options.webUrl, args.options.listUrl);
54
- url += `/GetList(@a1)/items(@a2)/SetComplianceTag()?@a1='${formatting.encodeQueryParameter(listServerRelativeUrl)}'&@a2='${args.options.listItemId}'`;
55
- }
56
- const requestBody = {
57
- "complianceTag": "",
58
- "isTagPolicyHold": false,
59
- "isTagPolicyRecord": false,
60
- "isEventBasedTag": false,
61
- "isTagSuperLock": false,
62
- "isUnlockedAsDefault": false
63
- };
64
- const requestOptions = {
65
- url: url,
66
- method: 'POST',
67
- headers: {
68
- 'accept': 'application/json;odata=nometadata'
69
- },
70
- data: requestBody,
71
- responseType: 'json'
72
- };
73
- await request.post(requestOptions);
44
+ const listAbsoluteUrl = await this.getListAbsoluteUrl(args.options, logger);
45
+ await spo.removeRetentionLabelFromListItems(args.options.webUrl, listAbsoluteUrl, [parseInt(args.options.listItemId)], logger, args.options.verbose);
74
46
  }
75
47
  catch (err) {
76
48
  this.handleRejectedODataJsonPromise(err);
77
49
  }
78
50
  }
51
+ async getListAbsoluteUrl(options, logger) {
52
+ const parsedUrl = url.parse(options.webUrl);
53
+ const tenantUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}`;
54
+ if (options.listUrl) {
55
+ const serverRelativePath = urlUtil.getServerRelativePath(options.webUrl, options.listUrl);
56
+ return urlUtil.urlCombine(tenantUrl, serverRelativePath);
57
+ }
58
+ if (this.verbose) {
59
+ logger.logToStderr(`Retrieving list absolute URL...`);
60
+ }
61
+ let requestUrl = `${options.webUrl}/_api/web`;
62
+ if (options.listId) {
63
+ requestUrl += `/lists(guid'${formatting.encodeQueryParameter(options.listId)}')`;
64
+ }
65
+ else if (options.listTitle) {
66
+ requestUrl += `/lists/getByTitle('${formatting.encodeQueryParameter(options.listTitle)}')`;
67
+ }
68
+ const requestOptions = {
69
+ url: `${requestUrl}?$expand=RootFolder&$select=RootFolder/ServerRelativeUrl`,
70
+ headers: {
71
+ 'accept': 'application/json;odata=nometadata'
72
+ },
73
+ responseType: 'json'
74
+ };
75
+ const response = await request.get(requestOptions);
76
+ const serverRelativePath = urlUtil.getServerRelativePath(options.webUrl, response.RootFolder.ServerRelativeUrl);
77
+ const listAbsoluteUrl = urlUtil.urlCombine(tenantUrl, serverRelativePath);
78
+ if (this.verbose) {
79
+ logger.logToStderr(`List absolute URL found: '${listAbsoluteUrl}'`);
80
+ }
81
+ return listAbsoluteUrl;
82
+ }
79
83
  }
80
84
  _SpoListItemRetentionLabelRemoveCommand_instances = new WeakSet(), _SpoListItemRetentionLabelRemoveCommand_initTelemetry = function _SpoListItemRetentionLabelRemoveCommand_initTelemetry() {
81
85
  this.telemetry.push((args) => {
@@ -33,12 +33,13 @@ class SpoSiteAddCommand extends SpoCommand {
33
33
  }
34
34
  async commandAction(logger, args) {
35
35
  const isClassicSite = args.options.type === 'ClassicSite';
36
- if (isClassicSite) {
37
- await this.createClassicSite(logger, args);
38
- }
39
- else {
40
- await this.createModernSite(logger, args);
36
+ const siteUrl = isClassicSite
37
+ ? await this.createClassicSite(logger, args)
38
+ : await this.createModernSite(logger, args);
39
+ if (siteUrl && args.options.withAppCatalog) {
40
+ await this.addAppCatalog(siteUrl, logger);
41
41
  }
42
+ await logger.log(siteUrl);
42
43
  }
43
44
  async createModernSite(logger, args) {
44
45
  const isTeamSite = args.options.type !== 'CommunicationSite';
@@ -132,19 +133,18 @@ class SpoSiteAddCommand extends SpoCommand {
132
133
  if (response.ErrorMessage !== null) {
133
134
  throw response.ErrorMessage;
134
135
  }
135
- await logger.log(response.SiteUrl);
136
+ return response.SiteUrl;
136
137
  }
137
138
  else {
138
- if (response.SiteStatus === 2) {
139
- await logger.log(response.SiteUrl);
140
- }
141
- else {
139
+ if (response.SiteStatus !== 2) {
142
140
  throw 'An error has occurred while creating the site';
143
141
  }
142
+ return response.SiteUrl;
144
143
  }
145
144
  }
146
145
  catch (err) {
147
146
  this.handleRejectedODataJsonPromise(err);
147
+ return;
148
148
  }
149
149
  }
150
150
  async createClassicSite(logger, args) {
@@ -195,8 +195,8 @@ class SpoSiteAddCommand extends SpoCommand {
195
195
  }
196
196
  const operation = json[json.length - 1];
197
197
  const isComplete = operation.IsComplete;
198
- if (!args.options.wait || isComplete) {
199
- return;
198
+ if ((!args.options.wait && !args.options.withAppCatalog) || isComplete) {
199
+ return args.options.url;
200
200
  }
201
201
  await new Promise((resolve, reject) => {
202
202
  setTimeout(() => {
@@ -212,9 +212,11 @@ class SpoSiteAddCommand extends SpoCommand {
212
212
  });
213
213
  }, operation.PollingInterval);
214
214
  });
215
+ return args.options.url;
215
216
  }
216
217
  catch (err) {
217
218
  this.handleRejectedPromise(err);
219
+ return;
218
220
  }
219
221
  }
220
222
  async siteExists(url, logger) {
@@ -304,6 +306,34 @@ class SpoSiteAddCommand extends SpoCommand {
304
306
  }, operation.PollingInterval);
305
307
  });
306
308
  }
309
+ async addAppCatalog(url, logger) {
310
+ try {
311
+ this.spoAdminUrl = await spo.getSpoAdminUrl(logger, this.debug);
312
+ this.context = await spo.ensureFormDigest(this.spoAdminUrl, logger, this.context, this.debug);
313
+ if (this.verbose) {
314
+ await logger.logToStderr(`Adding site collection app catalog...`);
315
+ }
316
+ const requestOptions = {
317
+ url: `${this.spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
318
+ headers: {
319
+ 'X-RequestDigest': this.context.FormDigestValue
320
+ },
321
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="38" ObjectPathId="37" /><ObjectPath Id="40" ObjectPathId="39" /><ObjectPath Id="42" ObjectPathId="41" /><ObjectPath Id="44" ObjectPathId="43" /><ObjectPath Id="46" ObjectPathId="45" /><ObjectPath Id="48" ObjectPathId="47" /></Actions><ObjectPaths><Constructor Id="37" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /><Method Id="39" ParentId="37" Name="GetSiteByUrl"><Parameters><Parameter Type="String">${formatting.escapeXml(url)}</Parameter></Parameters></Method><Property Id="41" ParentId="39" Name="RootWeb" /><Property Id="43" ParentId="41" Name="TenantAppCatalog" /><Property Id="45" ParentId="43" Name="SiteCollectionAppCatalogsSites" /><Method Id="47" ParentId="45" Name="Add"><Parameters><Parameter Type="String">${formatting.escapeXml(url)}</Parameter></Parameters></Method></ObjectPaths></Request>`
322
+ };
323
+ const response = await request.post(requestOptions);
324
+ const json = JSON.parse(response);
325
+ const responseContents = json[0];
326
+ if (responseContents.ErrorInfo) {
327
+ throw responseContents.ErrorInfo.ErrorMessage;
328
+ }
329
+ if (this.verbose) {
330
+ await logger.logToStderr('Site collection app catalog created');
331
+ }
332
+ }
333
+ catch (err) {
334
+ this.handleRejectedPromise(err);
335
+ }
336
+ }
307
337
  }
308
338
  _SpoSiteAddCommand_instances = new WeakSet(), _SpoSiteAddCommand_initTelemetry = function _SpoSiteAddCommand_initTelemetry() {
309
339
  this.telemetry.push((args) => {
@@ -316,6 +346,7 @@ _SpoSiteAddCommand_instances = new WeakSet(), _SpoSiteAddCommand_initTelemetry =
316
346
  telemetryProps.isPublic = args.options.isPublic || false;
317
347
  telemetryProps.lcid = args.options.lcid;
318
348
  telemetryProps.owners = typeof args.options.owners !== 'undefined';
349
+ telemetryProps.withAppCatalog = args.options.withAppCatalog || false;
319
350
  if (isCommunicationSite) {
320
351
  telemetryProps.shareByEmailEnabled = args.options.shareByEmailEnabled || false;
321
352
  telemetryProps.siteDesign = args.options.siteDesign;
@@ -373,6 +404,8 @@ _SpoSiteAddCommand_instances = new WeakSet(), _SpoSiteAddCommand_initTelemetry =
373
404
  option: '--storageQuotaWarningLevel [storageQuotaWarningLevel]'
374
405
  }, {
375
406
  option: '--removeDeletedSite'
407
+ }, {
408
+ option: '--withAppCatalog'
376
409
  }, {
377
410
  option: '--wait'
378
411
  });
@@ -36,8 +36,12 @@ class SpoSiteScriptGetCommand extends SpoCommand {
36
36
  data: { id: args.options.id },
37
37
  responseType: 'json'
38
38
  };
39
- const res = await request.post(requestOptions);
40
- await logger.log(res);
39
+ const response = await request.post(requestOptions);
40
+ if (args.options.content === true) {
41
+ await logger.log(JSON.parse(response.Content));
42
+ return;
43
+ }
44
+ await logger.log(response);
41
45
  }
42
46
  catch (err) {
43
47
  this.handleRejectedODataJsonPromise(err);
@@ -47,6 +51,8 @@ class SpoSiteScriptGetCommand extends SpoCommand {
47
51
  _SpoSiteScriptGetCommand_instances = new WeakSet(), _SpoSiteScriptGetCommand_initOptions = function _SpoSiteScriptGetCommand_initOptions() {
48
52
  this.options.unshift({
49
53
  option: '-i, --id <id>'
54
+ }, {
55
+ option: '-c, --content'
50
56
  });
51
57
  }, _SpoSiteScriptGetCommand_initValidators = function _SpoSiteScriptGetCommand_initValidators() {
52
58
  this.validators.push(async (args) => {
@@ -9,6 +9,7 @@ import { spo } from '../../../../utils/spo.js';
9
9
  import { validation } from '../../../../utils/validation.js';
10
10
  import SpoCommand from '../../../base/SpoCommand.js';
11
11
  import commands from '../../commands.js';
12
+ import { setTimeout } from 'timers/promises';
12
13
  class SpoTenantRecycleBinItemRestoreCommand extends SpoCommand {
13
14
  get name() {
14
15
  return commands.TENANT_RECYCLEBINITEM_RESTORE;
@@ -36,13 +37,29 @@ class SpoTenantRecycleBinItemRestoreCommand extends SpoCommand {
36
37
  siteUrl: args.options.siteUrl
37
38
  }
38
39
  };
39
- const res = await request.post(requestOptions);
40
- await logger.log(JSON.parse(res));
40
+ const response = await request.post(requestOptions);
41
+ let responseContent = JSON.parse(response);
42
+ if (args.options.wait && !responseContent.IsComplete) {
43
+ responseContent = await this.waitUntilTenantRestoreFinished(responseContent.PollingInterval, requestOptions, logger);
44
+ }
45
+ await logger.log(responseContent);
41
46
  }
42
47
  catch (err) {
43
48
  this.handleRejectedODataJsonPromise(err);
44
49
  }
45
50
  }
51
+ async waitUntilTenantRestoreFinished(pollingInterval, requestOptions, logger) {
52
+ if (this.verbose) {
53
+ await logger.logToStderr(`Site collection still restoring. Retrying in ${pollingInterval / 1000} seconds...`);
54
+ }
55
+ await setTimeout(pollingInterval);
56
+ const response = await request.post(requestOptions);
57
+ const responseContent = JSON.parse(response);
58
+ if (responseContent.IsComplete) {
59
+ return responseContent;
60
+ }
61
+ return await this.waitUntilTenantRestoreFinished(responseContent.PollingInterval, requestOptions, logger);
62
+ }
46
63
  }
47
64
  _SpoTenantRecycleBinItemRestoreCommand_instances = new WeakSet(), _SpoTenantRecycleBinItemRestoreCommand_initTelemetry = function _SpoTenantRecycleBinItemRestoreCommand_initTelemetry() {
48
65
  this.telemetry.push((args) => {
package/dist/request.js CHANGED
@@ -3,6 +3,7 @@ import { Stream } from 'stream';
3
3
  import auth, { Auth } from './Auth.js';
4
4
  import { app } from './utils/app.js';
5
5
  import { formatting } from './utils/formatting.js';
6
+ import { timings } from './cli/timings.js';
6
7
  class Request {
7
8
  set debug(debug) {
8
9
  // if the value to set is the same as current value return early to avoid
@@ -125,6 +126,7 @@ class Request {
125
126
  return this.execute(options);
126
127
  }
127
128
  execute(options, resolve, reject) {
129
+ const start = process.hrtime.bigint();
128
130
  if (!this._logger) {
129
131
  return Promise.reject('Logger not set on the request object');
130
132
  }
@@ -159,6 +161,8 @@ class Request {
159
161
  resolve((options.responseType === 'stream' || options.fullResponse) ? res : res.data);
160
162
  }
161
163
  else {
164
+ const end = process.hrtime.bigint();
165
+ timings.api.push(Number(end - start));
162
166
  _resolve((options.responseType === 'stream' || options.fullResponse) ? res : res.data);
163
167
  }
164
168
  }, (error) => {
@@ -181,6 +185,8 @@ class Request {
181
185
  reject(error);
182
186
  }
183
187
  else {
188
+ const end = process.hrtime.bigint();
189
+ timings.api.push(Number(end - start));
184
190
  _reject(error);
185
191
  }
186
192
  }
@@ -1,4 +1,5 @@
1
1
  const settingsNames = {
2
+ authType: 'authType',
2
3
  autoOpenLinksInBrowser: 'autoOpenLinksInBrowser',
3
4
  copyDeviceCodeToClipboard: 'copyDeviceCodeToClipboard',
4
5
  csvEscape: 'csvEscape',
package/dist/utils/spo.js CHANGED
@@ -1203,6 +1203,115 @@ export const spo = {
1203
1203
  };
1204
1204
  const webProperties = await request.get(requestOptions);
1205
1205
  return webProperties;
1206
+ },
1207
+ /**
1208
+ * Applies the retention label to the items in the given list.
1209
+ * @param webUrl The url of the web
1210
+ * @param name The name of the label
1211
+ * @param listAbsoluteUrl The absolute Url to the list
1212
+ * @param itemIds The list item Ids to apply the label to. (A maximum 100 is allowed)
1213
+ * @param logger The logger object
1214
+ * @param verbose Set for verbose logging
1215
+ */
1216
+ async applyRetentionLabelToListItems(webUrl, name, listAbsoluteUrl, itemIds, logger, verbose) {
1217
+ if (verbose && logger) {
1218
+ logger.logToStderr(`Applying retention label '${name}' to item(s) in list '${listAbsoluteUrl}'...`);
1219
+ }
1220
+ const requestOptions = {
1221
+ url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetComplianceTagOnBulkItems`,
1222
+ headers: {
1223
+ 'accept': 'application/json;odata=nometadata'
1224
+ },
1225
+ data: {
1226
+ listUrl: listAbsoluteUrl,
1227
+ complianceTagValue: name,
1228
+ itemIds: itemIds
1229
+ },
1230
+ responseType: 'json'
1231
+ };
1232
+ await request.post(requestOptions);
1233
+ },
1234
+ /**
1235
+ * Removes the retention label from the items in the given list.
1236
+ * @param webUrl The url of the web
1237
+ * @param listAbsoluteUrl The absolute Url to the list
1238
+ * @param itemIds The list item Ids to clear the label from (A maximum 100 is allowed)
1239
+ * @param logger The logger object
1240
+ * @param verbose Set for verbose logging
1241
+ */
1242
+ async removeRetentionLabelFromListItems(webUrl, listAbsoluteUrl, itemIds, logger, verbose) {
1243
+ if (verbose && logger) {
1244
+ logger.logToStderr(`Removing retention label from item(s) in list '${listAbsoluteUrl}'...`);
1245
+ }
1246
+ const requestOptions = {
1247
+ url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetComplianceTagOnBulkItems`,
1248
+ headers: {
1249
+ 'accept': 'application/json;odata=nometadata'
1250
+ },
1251
+ data: {
1252
+ listUrl: listAbsoluteUrl,
1253
+ complianceTagValue: '',
1254
+ itemIds: itemIds
1255
+ },
1256
+ responseType: 'json'
1257
+ };
1258
+ await request.post(requestOptions);
1259
+ },
1260
+ /**
1261
+ * Applies a default retention label to a list or library.
1262
+ * @param webUrl The url of the web
1263
+ * @param name The name of the label
1264
+ * @param listAbsoluteUrl The absolute Url to the list
1265
+ * @param syncToItems If the label needs to be synced to existing items/files.
1266
+ * @param logger The logger object
1267
+ * @param verbose Set for verbose logging
1268
+ */
1269
+ async applyDefaultRetentionLabelToList(webUrl, name, listAbsoluteUrl, syncToItems, logger, verbose) {
1270
+ if (verbose && logger) {
1271
+ logger.logToStderr(`Applying default retention label '${name}' to the list '${listAbsoluteUrl}'...`);
1272
+ }
1273
+ const requestOptions = {
1274
+ url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetListComplianceTag`,
1275
+ headers: {
1276
+ 'accept': 'application/json;odata=nometadata'
1277
+ },
1278
+ data: {
1279
+ listUrl: listAbsoluteUrl,
1280
+ complianceTagValue: name,
1281
+ blockDelete: false,
1282
+ blockEdit: false,
1283
+ syncToItems: syncToItems || false
1284
+ },
1285
+ responseType: 'json'
1286
+ };
1287
+ await request.post(requestOptions);
1288
+ },
1289
+ /**
1290
+ * Removes the default retention label from a list or library.
1291
+ * @param webUrl The url of the web
1292
+ * @param listAbsoluteUrl The absolute Url to the list
1293
+ * @param logger The logger object
1294
+ * @param verbose Set for verbose logging
1295
+ */
1296
+ async removeDefaultRetentionLabelFromList(webUrl, listAbsoluteUrl, logger, verbose) {
1297
+ if (verbose && logger) {
1298
+ logger.logToStderr(`Removing the default retention label from the list '${listAbsoluteUrl}'...`);
1299
+ }
1300
+ const requestOptions = {
1301
+ url: `${webUrl}/_api/SP_CompliancePolicy_SPPolicyStoreProxy_SetListComplianceTag`,
1302
+ headers: {
1303
+ 'accept': 'application/json;odata=nometadata'
1304
+ },
1305
+ data: {
1306
+ listUrl: listAbsoluteUrl,
1307
+ complianceTagValue: '',
1308
+ blockDelete: false,
1309
+ blockEdit: false,
1310
+ syncToItems: false
1311
+ },
1312
+ responseType: 'json'
1313
+ };
1314
+ await request.post(requestOptions);
1206
1315
  }
1207
1316
  };
1208
1317
  //# sourceMappingURL=spo.js.map
@@ -1,5 +1,6 @@
1
1
  Setting name|Definition|Default value
2
2
  ------------|----------|-------------
3
+ `authType`|Default login method to use when running `m365 login` without the `--authType` option.|`deviceCode`
3
4
  `autoOpenLinksInBrowser`|Automatically open the browser for all commands which return a url and expect the user to copy paste this to the browser. For example when logging in, using `m365 login` in device code mode.|`false`
4
5
  `copyDeviceCodeToClipboard`|Automatically copy the device code to the clipboard when running `m365 login` command in device code mode|`false`
5
6
  `csvEscape`|Single character used for escaping; only apply to characters matching the quote and the escape options|`"`
@@ -124,4 +124,4 @@ m365 aad approleassignment add --appObjectId "57907bf8-73fa-43a6-89a5-1f603e29e4
124
124
 
125
125
  ## More information
126
126
 
127
- - Microsoft Graph permissions reference: [https://docs.microsoft.com/en-us/graph/permissions-reference](https://docs.microsoft.com/en-us/graph/permissions-reference)
127
+ - Microsoft Graph permissions reference: [https://learn.microsoft.com/graph/permissions-reference](https://learn.microsoft.com/graph/permissions-reference)
@@ -53,7 +53,7 @@ m365 aad approleassignment list --appObjectId b2307a39-e878-458b-bc90-03bc578531
53
53
 
54
54
  ## More information
55
55
 
56
- - Application and service principal objects in Azure Active Directory (Azure AD): [https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects)
56
+ - Application and service principal objects in Azure Active Directory (Azure AD): [https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects](https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects)
57
57
 
58
58
  ## Response
59
59
 
@@ -110,4 +110,4 @@ m365 aad approleassignment list --appObjectId b2307a39-e878-458b-bc90-03bc578531
110
110
  ```
111
111
 
112
112
  </TabItem>
113
- </Tabs>
113
+ </Tabs>
@@ -70,4 +70,4 @@ The command won't return a response on success.
70
70
 
71
71
  ## More information
72
72
 
73
- - Microsoft Graph permissions reference: [https://docs.microsoft.com/en-us/graph/permissions-reference](https://docs.microsoft.com/en-us/graph/permissions-reference)
73
+ - Microsoft Graph permissions reference: [https://learn.microsoft.com/graph/permissions-reference](https://learn.microsoft.com/graph/permissions-reference)
@@ -55,4 +55,4 @@ The command won't return a response on success.
55
55
 
56
56
  ## More information
57
57
 
58
- - Application and service principal objects in Azure Active Directory (Azure AD): [https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects)
58
+ - Application and service principal objects in Azure Active Directory (Azure AD): [https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects](https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects)
@@ -94,5 +94,5 @@ m365 aad oauth2grant list --spObjectId b2307a39-e878-458b-bc90-03bc578531d6
94
94
 
95
95
  ## More information
96
96
 
97
- - Application and service principal objects in Azure Active Directory (Azure AD): [https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects)
98
- - List oauth2PermissionGrants: [https://docs.microsoft.com/en-us/graph/api/oauth2permissiongrant-list?view=graph-rest-1.0](https://docs.microsoft.com/en-us/graph/api/oauth2permissiongrant-list?view=graph-rest-1.0)
97
+ - Application and service principal objects in Azure Active Directory (Azure AD): [https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects](https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects)
98
+ - List oauth2PermissionGrants: [https://learn.microsoft.com/graph/api/oauth2permissiongrant-list?view=graph-rest-1.0](https://learn.microsoft.com/graph/api/oauth2permissiongrant-list?view=graph-rest-1.0)
@@ -52,5 +52,5 @@ The command won't return a response on success.
52
52
 
53
53
  ## More information
54
54
 
55
- - Application and service principal objects in Azure Active Directory (Azure AD): [https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects)
56
- - Delete a delegated permission grant (oAuth2PermissionGrant): [https://docs.microsoft.com/en-us/graph/api/oauth2permissiongrant-delete?view=graph-rest-1.0](https://docs.microsoft.com/en-us/graph/api/oauth2permissiongrant-delete?view=graph-rest-1.0)
55
+ - Application and service principal objects in Azure Active Directory (Azure AD): [https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects](https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects)
56
+ - Delete a delegated permission grant (oAuth2PermissionGrant): [https://learn.microsoft.com/graph/api/oauth2permissiongrant-delete?view=graph-rest-1.0](https://learn.microsoft.com/graph/api/oauth2permissiongrant-delete?view=graph-rest-1.0)
@@ -46,5 +46,5 @@ The command won't return a response on success.
46
46
 
47
47
  ## More information
48
48
 
49
- - Application and service principal objects in Azure Active Directory (Azure AD): [https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-objects)
50
- - Update a delegated permission grant (oAuth2PermissionGrant): [https://docs.microsoft.com/en-us/graph/api/oauth2permissiongrant-update?view=graph-rest-1.0](https://docs.microsoft.com/en-us/graph/api/oauth2permissiongrant-update?view=graph-rest-1.0)
49
+ - Application and service principal objects in Azure Active Directory (Azure AD): [https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects](https://learn.microsoft.com/azure/active-directory/develop/active-directory-application-objects)
50
+ - Update a delegated permission grant (oAuth2PermissionGrant): [https://learn.microsoft.com/graph/api/oauth2permissiongrant-update?view=graph-rest-1.0](https://learn.microsoft.com/graph/api/oauth2permissiongrant-update?view=graph-rest-1.0)
@@ -112,4 +112,4 @@ m365 aad policy list --type "claimsMapping"
112
112
 
113
113
  ## More information
114
114
 
115
- - Microsoft Graph Azure AD policy overview: [https://docs.microsoft.com/en-us/graph/api/resources/policy-overview?view=graph-rest-1.0](https://docs.microsoft.com/en-us/graph/api/resources/policy-overview?view=graph-rest-1.0)
115
+ - Microsoft Graph Azure AD policy overview: [https://learn.microsoft.com/graph/api/resources/policy-overview?view=graph-rest-1.0](https://learn.microsoft.com/graph/api/resources/policy-overview?view=graph-rest-1.0)