@pnp/cli-microsoft365 6.11.0-beta.ee225fb → 6.11.0

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 (136) hide show
  1. package/dist/Auth.js +2 -1
  2. package/dist/Command.js +1 -1
  3. package/dist/m365/pa/commands/app/app-permission-ensure.js +177 -0
  4. package/dist/m365/pa/commands/app/app-permission-remove.js +170 -0
  5. package/dist/m365/pa/commands.js +2 -0
  6. package/dist/m365/planner/commands/task/task-add.js +17 -11
  7. package/dist/m365/planner/commands/task/task-get.js +35 -25
  8. package/dist/m365/planner/commands/task/task-list.js +26 -19
  9. package/dist/m365/planner/commands/task/task-remove.js +40 -35
  10. package/dist/m365/planner/commands/task/task-set.js +35 -23
  11. package/dist/m365/spfx/commands/project/DeployWorkflow.js +58 -0
  12. package/dist/m365/spfx/commands/project/project-doctor/{doctor-1.18.0-beta.1.js → doctor-1.18.0-beta.5.js} +1 -1
  13. package/dist/m365/spfx/commands/project/project-doctor.js +1 -1
  14. package/dist/m365/spfx/commands/project/project-externalize/rules/PnPJsRule.js +34 -23
  15. package/dist/m365/spfx/commands/project/project-github-workflow-add.js +171 -0
  16. package/dist/m365/spfx/commands/project/project-github-workflow-model.js +3 -0
  17. package/dist/m365/spfx/commands/project/project-upgrade/upgrade-1.15.2.js +1 -1
  18. package/dist/m365/spfx/commands/project/project-upgrade/{upgrade-1.18.0-beta.1.js → upgrade-1.18.0-beta.5.js} +26 -26
  19. package/dist/m365/spfx/commands/project/project-upgrade.js +1 -1
  20. package/dist/m365/spfx/commands/spfx-doctor.js +35 -51
  21. package/dist/m365/spfx/commands.js +1 -0
  22. package/dist/m365/spo/commands/app/SpoAppBaseCommand.js +26 -14
  23. package/dist/m365/spo/commands/app/app-add.js +9 -9
  24. package/dist/m365/spo/commands/file/file-add.js +13 -13
  25. package/dist/m365/spo/commands/file/file-checkin.js +1 -1
  26. package/dist/m365/spo/commands/file/file-checkout.js +1 -1
  27. package/dist/m365/spo/commands/file/file-copy.js +38 -4
  28. package/dist/m365/spo/commands/file/file-list.js +4 -4
  29. package/dist/m365/spo/commands/file/file-move.js +2 -2
  30. package/dist/m365/spo/commands/file/file-remove.js +6 -6
  31. package/dist/m365/spo/commands/file/file-rename.js +2 -2
  32. package/dist/m365/spo/commands/file/file-retentionlabel-ensure.js +1 -1
  33. package/dist/m365/spo/commands/file/file-retentionlabel-remove.js +1 -1
  34. package/dist/m365/spo/commands/file/file-roleassignment-add.js +1 -1
  35. package/dist/m365/spo/commands/file/file-roleassignment-remove.js +1 -1
  36. package/dist/m365/spo/commands/file/file-roleinheritance-break.js +1 -1
  37. package/dist/m365/spo/commands/file/file-roleinheritance-reset.js +1 -1
  38. package/dist/m365/spo/commands/file/file-version-clear.js +1 -1
  39. package/dist/m365/spo/commands/file/file-version-get.js +1 -1
  40. package/dist/m365/spo/commands/file/file-version-list.js +1 -1
  41. package/dist/m365/spo/commands/file/file-version-remove.js +1 -1
  42. package/dist/m365/spo/commands/file/file-version-restore.js +1 -1
  43. package/dist/m365/spo/commands/folder/folder-add.js +2 -4
  44. package/dist/m365/spo/commands/folder/folder-get.js +1 -1
  45. package/dist/m365/spo/commands/folder/folder-list.js +2 -2
  46. package/dist/m365/spo/commands/folder/folder-remove.js +7 -4
  47. package/dist/m365/spo/commands/folder/folder-rename.js +13 -17
  48. package/dist/m365/spo/commands/folder/folder-retentionlabel-ensure.js +1 -1
  49. package/dist/m365/spo/commands/folder/folder-retentionlabel-remove.js +1 -1
  50. package/dist/m365/spo/commands/folder/folder-roleassignment-add.js +1 -1
  51. package/dist/m365/spo/commands/folder/folder-roleassignment-remove.js +1 -1
  52. package/dist/m365/spo/commands/folder/folder-roleinheritance-break.js +1 -1
  53. package/dist/m365/spo/commands/folder/folder-roleinheritance-reset.js +1 -1
  54. package/dist/m365/spo/commands/group/group-list.js +0 -1
  55. package/dist/m365/spo/commands/orgassetslibrary/orgassetslibrary-add.js +32 -3
  56. package/dist/m365/spo/commands/page/Page.js +24 -32
  57. package/dist/m365/spo/commands/propertybag/propertybag-base.js +75 -54
  58. package/dist/m365/spo/commands/propertybag/propertybag-remove.js +41 -40
  59. package/dist/m365/spo/commands/serviceprincipal/serviceprincipal-set.js +32 -32
  60. package/dist/m365/spo/commands/site/FlowsPolicy.js +10 -0
  61. package/dist/m365/spo/commands/site/site-add.js +113 -154
  62. package/dist/m365/spo/commands/site/site-apppermission-add.js +26 -27
  63. package/dist/m365/spo/commands/site/site-apppermission-remove.js +37 -37
  64. package/dist/m365/spo/commands/site/site-apppermission-set.js +15 -16
  65. package/dist/m365/spo/commands/site/site-ensure.js +19 -70
  66. package/dist/m365/spo/commands/site/site-hubsite-disconnect.js +24 -22
  67. package/dist/m365/spo/commands/site/site-list.js +28 -36
  68. package/dist/m365/spo/commands/site/site-remove.js +139 -171
  69. package/dist/m365/spo/commands/site/site-set.js +179 -178
  70. package/dist/m365/spo/commands/theme/theme-remove.js +26 -24
  71. package/dist/m365/spo/commands/theme/theme-set.js +0 -1
  72. package/dist/m365/spo/commands/user/user-remove.js +29 -27
  73. package/dist/m365/spo/commands/web/web-reindex.js +17 -20
  74. package/dist/m365/spo/commands/web/web-remove.js +23 -21
  75. package/dist/m365/spo/commands/web/web-roleassignment-add.js +45 -52
  76. package/dist/m365/spo/commands/web/web-roleassignment-remove.js +58 -61
  77. package/dist/m365/spo/commands/web/web-roleinheritance-break.js +20 -18
  78. package/dist/m365/spo/commands/web/web-roleinheritance-reset.js +21 -19
  79. package/dist/m365/yammer/commands/message/message-like-set.js +29 -28
  80. package/dist/m365/yammer/commands/message/message-list.js +9 -26
  81. package/dist/m365/yammer/commands/message/message-remove.js +20 -18
  82. package/dist/m365/yammer/commands/yammer-search.js +42 -56
  83. package/dist/utils/aadGroup.js +20 -0
  84. package/dist/utils/fsUtil.js +5 -0
  85. package/dist/utils/spo.js +601 -1
  86. package/docs/docs/cmd/pa/app/app-permission-ensure.mdx +85 -0
  87. package/docs/docs/cmd/pa/app/app-permission-remove.mdx +74 -0
  88. package/docs/docs/cmd/planner/task/task-add.mdx +22 -7
  89. package/docs/docs/cmd/planner/task/task-get.mdx +13 -4
  90. package/docs/docs/cmd/planner/task/task-list.mdx +22 -7
  91. package/docs/docs/cmd/planner/task/task-remove.mdx +25 -8
  92. package/docs/docs/cmd/planner/task/task-set.mdx +22 -7
  93. package/docs/docs/cmd/spfx/project/project-github-workflow-add.mdx +94 -0
  94. package/docs/docs/cmd/spo/file/file-add.mdx +1 -1
  95. package/docs/docs/cmd/spo/file/file-checkin.mdx +1 -1
  96. package/docs/docs/cmd/spo/file/file-checkout-undo.mdx +1 -9
  97. package/docs/docs/cmd/spo/file/file-checkout.mdx +1 -1
  98. package/docs/docs/cmd/spo/file/file-copy.mdx +20 -16
  99. package/docs/docs/cmd/spo/file/file-get.mdx +1 -1
  100. package/docs/docs/cmd/spo/file/file-list.mdx +2 -2
  101. package/docs/docs/cmd/spo/file/file-move.mdx +2 -2
  102. package/docs/docs/cmd/spo/file/file-remove.mdx +8 -8
  103. package/docs/docs/cmd/spo/file/file-rename.mdx +3 -3
  104. package/docs/docs/cmd/spo/file/file-retentionlabel-ensure.mdx +2 -2
  105. package/docs/docs/cmd/spo/file/file-retentionlabel-remove.mdx +3 -3
  106. package/docs/docs/cmd/spo/file/file-roleassignment-add.mdx +1 -1
  107. package/docs/docs/cmd/spo/file/file-roleassignment-remove.mdx +1 -1
  108. package/docs/docs/cmd/spo/file/file-roleinheritance-break.mdx +1 -1
  109. package/docs/docs/cmd/spo/file/file-roleinheritance-reset.mdx +1 -1
  110. package/docs/docs/cmd/spo/file/file-sharinginfo-get.mdx +1 -1
  111. package/docs/docs/cmd/spo/file/file-sharinglink-add.mdx +1 -1
  112. package/docs/docs/cmd/spo/file/file-sharinglink-clear.mdx +1 -1
  113. package/docs/docs/cmd/spo/file/file-sharinglink-get.mdx +1 -1
  114. package/docs/docs/cmd/spo/file/file-sharinglink-list.mdx +1 -1
  115. package/docs/docs/cmd/spo/file/file-sharinglink-remove.mdx +1 -1
  116. package/docs/docs/cmd/spo/file/file-sharinglink-set.mdx +1 -1
  117. package/docs/docs/cmd/spo/file/file-version-clear.mdx +1 -1
  118. package/docs/docs/cmd/spo/file/file-version-get.mdx +1 -1
  119. package/docs/docs/cmd/spo/file/file-version-list.mdx +1 -1
  120. package/docs/docs/cmd/spo/file/file-version-remove.mdx +1 -1
  121. package/docs/docs/cmd/spo/file/file-version-restore.mdx +1 -1
  122. package/docs/docs/cmd/spo/folder/folder-add.mdx +76 -1
  123. package/docs/docs/cmd/spo/folder/folder-get.mdx +1 -1
  124. package/docs/docs/cmd/spo/folder/folder-list.mdx +1 -1
  125. package/docs/docs/cmd/spo/folder/folder-remove.mdx +1 -1
  126. package/docs/docs/cmd/spo/folder/folder-rename.mdx +5 -1
  127. package/docs/docs/cmd/spo/folder/folder-retentionlabel-ensure.mdx +1 -1
  128. package/docs/docs/cmd/spo/folder/folder-retentionlabel-remove.mdx +1 -1
  129. package/docs/docs/cmd/spo/folder/folder-roleassignment-add.mdx +2 -2
  130. package/docs/docs/cmd/spo/folder/folder-roleassignment-remove.mdx +1 -1
  131. package/docs/docs/cmd/spo/folder/folder-roleinheritance-break.mdx +1 -1
  132. package/docs/docs/cmd/spo/folder/folder-roleinheritance-reset.mdx +1 -1
  133. package/docs/docs/cmd/spo/orgassetslibrary/orgassetslibrary-add.mdx +14 -1
  134. package/docs/docs/cmd/spo/site/site-ensure.mdx +1 -1
  135. package/npm-shrinkwrap.json +698 -345
  136. package/package.json +16 -15
package/dist/utils/spo.js CHANGED
@@ -20,6 +20,8 @@ const request_1 = require("../request");
20
20
  const formatting_1 = require("./formatting");
21
21
  const odata_1 = require("./odata");
22
22
  const RoleType_1 = require("../m365/spo/commands/roledefinition/RoleType");
23
+ const aadGroup_1 = require("./aadGroup");
24
+ const SharingCapabilities_1 = require("../m365/spo/commands/site/SharingCapabilities");
23
25
  exports.spo = {
24
26
  getRequestDigest(siteUrl) {
25
27
  const requestOptions = {
@@ -306,7 +308,7 @@ exports.spo = {
306
308
  nextFolder += `/${folders[folderIndex]}`;
307
309
  const folderServerRelativeUrl = urlUtil_1.urlUtil.getServerRelativePath(webFullUrl, nextFolder);
308
310
  const requestOptions = {
309
- url: `${webFullUrl}/_api/web/GetFolderByServerRelativeUrl('${formatting_1.formatting.encodeQueryParameter(folderServerRelativeUrl)}')`,
311
+ url: `${webFullUrl}/_api/web/GetFolderByServerRelativePath(DecodedUrl='${formatting_1.formatting.encodeQueryParameter(folderServerRelativeUrl)}')`,
310
312
  headers: {
311
313
  'accept': 'application/json;odata=nometadata'
312
314
  }
@@ -702,6 +704,604 @@ exports.spo = {
702
704
  roledefinition.RoleTypeKindValue = RoleType_1.RoleType[roledefinition.RoleTypeKind];
703
705
  return roledefinition;
704
706
  });
707
+ },
708
+ /**
709
+ * Adds a SharePoint site.
710
+ * @param type Type of sites to add. Allowed values TeamSite, CommunicationSite, ClassicSite, default TeamSite
711
+ * @param title Site title
712
+ * @param alias Site alias, used in the URL and in the team site group e-mail (applies to type TeamSite)
713
+ * @param url Site URL (applies to type CommunicationSite, ClassicSite)
714
+ * @param timeZone Integer representing time zone to use for the site (applies to type ClassicSite)
715
+ * @param description Site description
716
+ * @param lcid Site language in the LCID format
717
+ * @param owners Comma-separated list of users to set as site owners (applies to type TeamSite, ClassicSite)
718
+ * @param isPublic Determines if the associated group is public or not (applies to type TeamSite)
719
+ * @param classification Site classification (applies to type TeamSite, CommunicationSite)
720
+ * @param siteDesignType of communication site to create. Allowed values Topic, Showcase, Blank, default Topic. When creating a communication site, specify either siteDesign or siteDesignId (applies to type CommunicationSite)
721
+ * @param siteDesignId Id of the custom site design to use to create the site. When creating a communication site, specify either siteDesign or siteDesignId (applies to type CommunicationSite)
722
+ * @param shareByEmailEnabled Determines whether it's allowed to share file with guests (applies to type CommunicationSite)
723
+ * @param webTemplate Template to use for creating the site. Default `STS#0` (applies to type ClassicSite)
724
+ * @param resourceQuota The quota for this site collection in Sandboxed Solutions units. Default 0 (applies to type ClassicSite)
725
+ * @param resourceQuotaWarningLevel The warning level for the resource quota. Default 0 (applies to type ClassicSite)
726
+ * @param storageQuota The storage quota for this site collection in megabytes. Default 100 (applies to type ClassicSite)
727
+ * @param storageQuotaWarningLevel The warning level for the storage quota in megabytes. Default 100 (applies to type ClassicSite)
728
+ * @param removeDeletedSite Set, to remove existing deleted site with the same URL from the Recycle Bin (applies to type ClassicSite)
729
+ * @param wait Wait for the site to be provisioned before completing the command (applies to type ClassicSite)
730
+ * @param logger the Logger object
731
+ * @param verbose set if verbose logging should be logged
732
+ */
733
+ addSite(title, logger, verbose, wait, type, alias, description, owners, shareByEmailEnabled, removeDeletedSite, classification, isPublic, lcid, url, siteDesign, siteDesignId, timeZone, webTemplate, resourceQuota, resourceQuotaWarningLevel, storageQuota, storageQuotaWarningLevel) {
734
+ return __awaiter(this, void 0, void 0, function* () {
735
+ if (type === 'ClassicSite') {
736
+ const spoAdminUrl = yield exports.spo.getSpoAdminUrl(logger, verbose);
737
+ let context = yield exports.spo.ensureFormDigest(spoAdminUrl, logger, undefined, verbose);
738
+ let exists;
739
+ if (removeDeletedSite) {
740
+ exists = yield exports.spo.siteExists(url, logger, verbose);
741
+ }
742
+ else {
743
+ // assume site doesn't exist
744
+ exists = false;
745
+ }
746
+ if (exists) {
747
+ if (verbose) {
748
+ logger.logToStderr('Site exists in the recycle bin');
749
+ }
750
+ yield exports.spo.deleteSiteFromTheRecycleBin(url, logger, verbose, wait);
751
+ }
752
+ else {
753
+ if (verbose) {
754
+ logger.logToStderr('Site not found');
755
+ }
756
+ }
757
+ context = yield exports.spo.ensureFormDigest(spoAdminUrl, logger, context, verbose);
758
+ if (verbose) {
759
+ logger.logToStderr(`Creating site collection ${url}...`);
760
+ }
761
+ const lcidOption = typeof lcid === 'number' ? lcid : 1033;
762
+ const storageQuotaOption = typeof storageQuota === 'number' ? storageQuota : 100;
763
+ const storageQuotaWarningLevelOption = typeof storageQuotaWarningLevel === 'number' ? storageQuotaWarningLevel : 100;
764
+ const resourceQuotaOption = typeof resourceQuota === 'number' ? resourceQuota : 0;
765
+ const resourceQuotaWarningLevelOption = typeof resourceQuotaWarningLevel === 'number' ? resourceQuotaWarningLevel : 0;
766
+ const webTemplateOption = webTemplate || 'STS#0';
767
+ const requestOptions = {
768
+ url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
769
+ headers: {
770
+ 'X-RequestDigest': context.FormDigestValue
771
+ },
772
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config_1.default.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="4" ObjectPathId="3" /><ObjectPath Id="6" ObjectPathId="5" /><Query Id="7" ObjectPathId="3"><Query SelectAllProperties="true"><Properties /></Query></Query><Query Id="8" ObjectPathId="5"><Query SelectAllProperties="false"><Properties><Property Name="IsComplete" ScalarProperty="true" /><Property Name="PollingInterval" ScalarProperty="true" /></Properties></Query></Query></Actions><ObjectPaths><Constructor Id="3" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /><Method Id="5" ParentId="3" Name="CreateSite"><Parameters><Parameter TypeId="{11f84fff-b8cf-47b6-8b50-34e692656606}"><Property Name="CompatibilityLevel" Type="Int32">0</Property><Property Name="Lcid" Type="UInt32">${lcidOption}</Property><Property Name="Owner" Type="String">${formatting_1.formatting.escapeXml(owners)}</Property><Property Name="StorageMaximumLevel" Type="Int64">${storageQuotaOption}</Property><Property Name="StorageWarningLevel" Type="Int64">${storageQuotaWarningLevelOption}</Property><Property Name="Template" Type="String">${formatting_1.formatting.escapeXml(webTemplateOption)}</Property><Property Name="TimeZoneId" Type="Int32">${timeZone}</Property><Property Name="Title" Type="String">${formatting_1.formatting.escapeXml(title)}</Property><Property Name="Url" Type="String">${formatting_1.formatting.escapeXml(url)}</Property><Property Name="UserCodeMaximumLevel" Type="Double">${resourceQuotaOption}</Property><Property Name="UserCodeWarningLevel" Type="Double">${resourceQuotaWarningLevelOption}</Property></Parameter></Parameters></Method></ObjectPaths></Request>`
773
+ };
774
+ const res = yield request_1.default.post(requestOptions);
775
+ const json = JSON.parse(res);
776
+ const response = json[0];
777
+ if (response.ErrorInfo) {
778
+ throw response.ErrorInfo.ErrorMessage;
779
+ }
780
+ else {
781
+ const operation = json[json.length - 1];
782
+ const isComplete = operation.IsComplete;
783
+ if (!wait || isComplete) {
784
+ return;
785
+ }
786
+ yield new Promise((resolve, reject) => {
787
+ setTimeout(() => {
788
+ exports.spo.waitUntilFinished({
789
+ operationId: JSON.stringify(operation._ObjectIdentity_),
790
+ siteUrl: spoAdminUrl,
791
+ resolve,
792
+ reject,
793
+ logger,
794
+ currentContext: context,
795
+ verbose: verbose,
796
+ debug: verbose
797
+ });
798
+ }, operation.PollingInterval);
799
+ });
800
+ }
801
+ }
802
+ else {
803
+ const isTeamSite = type !== 'CommunicationSite';
804
+ const spoUrl = yield exports.spo.getSpoUrl(logger, verbose);
805
+ if (verbose) {
806
+ logger.logToStderr(`Creating new site...`);
807
+ }
808
+ let requestOptions = {};
809
+ if (isTeamSite) {
810
+ requestOptions = {
811
+ url: `${spoUrl}/_api/GroupSiteManager/CreateGroupEx`,
812
+ headers: {
813
+ 'content-type': 'application/json; odata=verbose; charset=utf-8',
814
+ accept: 'application/json;odata=nometadata'
815
+ },
816
+ responseType: 'json',
817
+ data: {
818
+ displayName: title,
819
+ alias: alias,
820
+ isPublic: isPublic,
821
+ optionalParams: {
822
+ Description: description || '',
823
+ CreationOptions: {
824
+ results: [],
825
+ Classification: classification || ''
826
+ }
827
+ }
828
+ }
829
+ };
830
+ if (lcid) {
831
+ requestOptions.data.optionalParams.CreationOptions.results.push(`SPSiteLanguage:${lcid}`);
832
+ }
833
+ if (owners) {
834
+ requestOptions.data.optionalParams.Owners = {
835
+ results: owners.split(',').map(o => o.trim())
836
+ };
837
+ }
838
+ }
839
+ else {
840
+ if (siteDesignId) {
841
+ siteDesignId = siteDesignId;
842
+ }
843
+ else {
844
+ if (siteDesign) {
845
+ switch (siteDesign) {
846
+ case 'Topic':
847
+ siteDesignId = '00000000-0000-0000-0000-000000000000';
848
+ break;
849
+ case 'Showcase':
850
+ siteDesignId = '6142d2a0-63a5-4ba0-aede-d9fefca2c767';
851
+ break;
852
+ case 'Blank':
853
+ siteDesignId = 'f6cc5403-0d63-442e-96c0-285923709ffc';
854
+ break;
855
+ }
856
+ }
857
+ else {
858
+ siteDesignId = '00000000-0000-0000-0000-000000000000';
859
+ }
860
+ }
861
+ requestOptions = {
862
+ url: `${spoUrl}/_api/SPSiteManager/Create`,
863
+ headers: {
864
+ 'content-type': 'application/json;odata=nometadata',
865
+ accept: 'application/json;odata=nometadata'
866
+ },
867
+ responseType: 'json',
868
+ data: {
869
+ request: {
870
+ Title: title,
871
+ Url: url,
872
+ ShareByEmailEnabled: shareByEmailEnabled,
873
+ Description: description || '',
874
+ Classification: classification || '',
875
+ WebTemplate: 'SITEPAGEPUBLISHING#0',
876
+ SiteDesignId: siteDesignId
877
+ }
878
+ }
879
+ };
880
+ if (lcid) {
881
+ requestOptions.data.request.Lcid = lcid;
882
+ }
883
+ if (owners) {
884
+ requestOptions.data.request.Owner = owners;
885
+ }
886
+ }
887
+ const res = yield request_1.default.post(requestOptions);
888
+ if (isTeamSite) {
889
+ if (res.ErrorMessage !== null) {
890
+ throw res.ErrorMessage;
891
+ }
892
+ else {
893
+ return res.SiteUrl;
894
+ }
895
+ }
896
+ else {
897
+ if (res.SiteStatus === 2) {
898
+ return res.SiteUrl;
899
+ }
900
+ else {
901
+ throw 'An error has occurred while creating the site';
902
+ }
903
+ }
904
+ }
905
+ });
906
+ },
907
+ /**
908
+ * Checks if a site exists
909
+ * Returns a boolean
910
+ * @param url The url of the site
911
+ * @param logger the Logger object
912
+ * @param verbose set if verbose logging should be logged
913
+ */
914
+ siteExists(url, logger, verbose) {
915
+ return __awaiter(this, void 0, void 0, function* () {
916
+ const spoAdminUrl = yield exports.spo.getSpoAdminUrl(logger, verbose);
917
+ const context = yield exports.spo.ensureFormDigest(spoAdminUrl, logger, undefined, verbose);
918
+ if (verbose) {
919
+ logger.logToStderr(`Checking if the site ${url} exists...`);
920
+ }
921
+ const requestOptions = {
922
+ url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
923
+ headers: {
924
+ 'X-RequestDigest': context.FormDigestValue
925
+ },
926
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config_1.default.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="197" ObjectPathId="196" /><ObjectPath Id="199" ObjectPathId="198" /><Query Id="200" ObjectPathId="198"><Query SelectAllProperties="true"><Properties /></Query></Query></Actions><ObjectPaths><Constructor Id="196" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /><Method Id="198" ParentId="196" Name="GetSitePropertiesByUrl"><Parameters><Parameter Type="String">${formatting_1.formatting.escapeXml(url)}</Parameter><Parameter Type="Boolean">false</Parameter></Parameters></Method></ObjectPaths></Request>`
927
+ };
928
+ const res1 = yield request_1.default.post(requestOptions);
929
+ const json = JSON.parse(res1);
930
+ const response = json[0];
931
+ if (response.ErrorInfo) {
932
+ if (response.ErrorInfo.ErrorTypeName === 'Microsoft.Online.SharePoint.Common.SpoNoSiteException') {
933
+ return yield this.siteExistsInTheRecycleBin(url, logger, verbose);
934
+ }
935
+ else {
936
+ throw response.ErrorInfo.ErrorMessage;
937
+ }
938
+ }
939
+ else {
940
+ const site = json[json.length - 1];
941
+ return site.Status === 'Recycled';
942
+ }
943
+ });
944
+ },
945
+ /**
946
+ * Checks if a site exists in the recycle bin
947
+ * Returns a boolean
948
+ * @param url The url of the site
949
+ * @param logger the Logger object
950
+ * @param verbose set if verbose logging should be logged
951
+ */
952
+ siteExistsInTheRecycleBin(url, logger, verbose) {
953
+ return __awaiter(this, void 0, void 0, function* () {
954
+ if (verbose) {
955
+ logger.logToStderr(`Site doesn't exist. Checking if the site ${url} exists in the recycle bin...`);
956
+ }
957
+ const spoAdminUrl = yield exports.spo.getSpoAdminUrl(logger, verbose);
958
+ const context = yield exports.spo.ensureFormDigest(spoAdminUrl, logger, undefined, verbose);
959
+ const requestOptions = {
960
+ url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
961
+ headers: {
962
+ 'X-RequestDigest': context.FormDigestValue
963
+ },
964
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config_1.default.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="181" ObjectPathId="180" /><Query Id="182" ObjectPathId="180"><Query SelectAllProperties="true"><Properties /></Query></Query></Actions><ObjectPaths><Method Id="180" ParentId="175" Name="GetDeletedSitePropertiesByUrl"><Parameters><Parameter Type="String">${formatting_1.formatting.escapeXml(url)}</Parameter></Parameters></Method><Constructor Id="175" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>`
965
+ };
966
+ const res = yield request_1.default.post(requestOptions);
967
+ const json = JSON.parse(res);
968
+ const response = json[0];
969
+ if (response.ErrorInfo) {
970
+ if (response.ErrorInfo.ErrorTypeName === 'Microsoft.SharePoint.Client.UnknownError') {
971
+ return false;
972
+ }
973
+ throw response.ErrorInfo.ErrorMessage;
974
+ }
975
+ const site = json[json.length - 1];
976
+ return site.Status === 'Recycled';
977
+ });
978
+ },
979
+ /**
980
+ * Deletes a site from the recycle bin
981
+ * @param url The url of the site
982
+ * @param logger the Logger object
983
+ * @param verbose set if verbose logging should be logged
984
+ * @param wait set to wait until finished
985
+ */
986
+ deleteSiteFromTheRecycleBin(url, logger, verbose, wait) {
987
+ return __awaiter(this, void 0, void 0, function* () {
988
+ const spoAdminUrl = yield exports.spo.getSpoAdminUrl(logger, verbose);
989
+ const context = yield exports.spo.ensureFormDigest(spoAdminUrl, logger, undefined, verbose);
990
+ if (verbose) {
991
+ logger.logToStderr(`Deleting site ${url} from the recycle bin...`);
992
+ }
993
+ const requestOptions = {
994
+ url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
995
+ headers: {
996
+ 'X-RequestDigest': context.FormDigestValue
997
+ },
998
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config_1.default.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="185" ObjectPathId="184" /><Query Id="186" ObjectPathId="184"><Query SelectAllProperties="false"><Properties><Property Name="IsComplete" ScalarProperty="true" /><Property Name="PollingInterval" ScalarProperty="true" /></Properties></Query></Query></Actions><ObjectPaths><Method Id="184" ParentId="175" Name="RemoveDeletedSite"><Parameters><Parameter Type="String">${formatting_1.formatting.escapeXml(url)}</Parameter></Parameters></Method><Constructor Id="175" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>`
999
+ };
1000
+ const response = yield request_1.default.post(requestOptions);
1001
+ const json = JSON.parse(response);
1002
+ const responseContent = json[0];
1003
+ if (responseContent.ErrorInfo) {
1004
+ throw responseContent.ErrorInfo.ErrorMessage;
1005
+ }
1006
+ const operation = json[json.length - 1];
1007
+ const isComplete = operation.IsComplete;
1008
+ if (!wait || isComplete) {
1009
+ return;
1010
+ }
1011
+ yield new Promise((resolve, reject) => {
1012
+ setTimeout(() => {
1013
+ exports.spo.waitUntilFinished({
1014
+ operationId: JSON.stringify(operation._ObjectIdentity_),
1015
+ siteUrl: spoAdminUrl,
1016
+ resolve,
1017
+ reject,
1018
+ logger,
1019
+ currentContext: context,
1020
+ verbose: verbose,
1021
+ debug: verbose
1022
+ });
1023
+ }, operation.PollingInterval);
1024
+ });
1025
+ });
1026
+ },
1027
+ /**
1028
+ * Updates a site with the given properties
1029
+ * @param url The url of the site
1030
+ * @param logger The logger object
1031
+ * @param verbose Set for verbose logging
1032
+ * @param title The new title
1033
+ * @param classification The classification to be updated
1034
+ * @param disableFlows If flows should be disabled or not
1035
+ * @param isPublic If site should be public or private
1036
+ * @param owners The owners to be updated
1037
+ * @param shareByEmailEnabled If share by e-mail should be enabled or not
1038
+ * @param siteDesignId The site design to be updated
1039
+ * @param sharingCapability The sharing capability to be updated
1040
+ */
1041
+ updateSite(url, logger, verbose, title, classification, disableFlows, isPublic, owners, shareByEmailEnabled, siteDesignId, sharingCapability) {
1042
+ return __awaiter(this, void 0, void 0, function* () {
1043
+ const tenantId = yield exports.spo.getTenantId(logger, verbose);
1044
+ const spoAdminUrl = yield exports.spo.getSpoAdminUrl(logger, verbose);
1045
+ let context = yield exports.spo.ensureFormDigest(spoAdminUrl, logger, undefined, verbose);
1046
+ if (verbose) {
1047
+ logger.logToStderr('Loading site IDs...');
1048
+ }
1049
+ const requestOptions = {
1050
+ url: `${url}/_api/site?$select=GroupId,Id`,
1051
+ headers: {
1052
+ accept: 'application/json;odata=nometadata'
1053
+ },
1054
+ responseType: 'json'
1055
+ };
1056
+ const siteInfo = yield request_1.default.get(requestOptions);
1057
+ const groupId = siteInfo.GroupId;
1058
+ const siteId = siteInfo.Id;
1059
+ const isGroupConnectedSite = groupId !== '00000000-0000-0000-0000-000000000000';
1060
+ if (verbose) {
1061
+ logger.logToStderr(`Retrieved site IDs. siteId: ${siteId}, groupId: ${groupId}`);
1062
+ }
1063
+ if (isGroupConnectedSite) {
1064
+ if (verbose) {
1065
+ logger.logToStderr(`Site attached to group ${groupId}`);
1066
+ }
1067
+ if (typeof title !== 'undefined' &&
1068
+ typeof isPublic !== 'undefined' &&
1069
+ typeof owners !== 'undefined') {
1070
+ const promises = [];
1071
+ if (typeof title !== 'undefined') {
1072
+ const requestOptions = {
1073
+ url: `${spoAdminUrl}/_api/SPOGroup/UpdateGroupPropertiesBySiteId`,
1074
+ headers: {
1075
+ accept: 'application/json;odata=nometadata',
1076
+ 'content-type': 'application/json;charset=utf-8',
1077
+ 'X-RequestDigest': context.FormDigestValue
1078
+ },
1079
+ data: {
1080
+ groupId: groupId,
1081
+ siteId: siteId,
1082
+ displayName: title
1083
+ },
1084
+ responseType: 'json'
1085
+ };
1086
+ promises.push(request_1.default.post(requestOptions));
1087
+ }
1088
+ if (typeof isPublic !== 'undefined') {
1089
+ promises.push(aadGroup_1.aadGroup.setGroup(groupId, (isPublic === false), logger, verbose));
1090
+ }
1091
+ if (typeof owners !== 'undefined') {
1092
+ promises.push(exports.spo.setGroupifiedSiteOwners(spoAdminUrl, groupId, owners, logger, verbose));
1093
+ }
1094
+ yield Promise.all(promises);
1095
+ }
1096
+ }
1097
+ else {
1098
+ if (verbose) {
1099
+ logger.logToStderr('Site is not group connected');
1100
+ }
1101
+ if (typeof isPublic !== 'undefined') {
1102
+ throw `The isPublic option can't be set on a site that is not groupified`;
1103
+ }
1104
+ if (owners) {
1105
+ yield Promise.all(owners.split(',').map((o) => __awaiter(this, void 0, void 0, function* () {
1106
+ yield exports.spo.setSiteAdmin(spoAdminUrl, context, url, o.trim());
1107
+ })));
1108
+ }
1109
+ }
1110
+ context = yield exports.spo.ensureFormDigest(spoAdminUrl, logger, context, verbose);
1111
+ if (verbose) {
1112
+ logger.logToStderr(`Updating site ${url} properties...`);
1113
+ }
1114
+ let updatedProperties = false;
1115
+ if (!isGroupConnectedSite) {
1116
+ if (title !== undefined) {
1117
+ updatedProperties = true;
1118
+ }
1119
+ }
1120
+ else {
1121
+ if (classification !== undefined || disableFlows !== undefined || shareByEmailEnabled !== undefined || sharingCapability !== undefined) {
1122
+ updatedProperties = true;
1123
+ }
1124
+ }
1125
+ if (updatedProperties) {
1126
+ let propertyId = 27;
1127
+ const payload = [];
1128
+ if (!isGroupConnectedSite) {
1129
+ if (title) {
1130
+ payload.push(`<SetProperty Id="${propertyId++}" ObjectPathId="5" Name="Title"><Parameter Type="String">${formatting_1.formatting.escapeXml(title)}</Parameter></SetProperty>`);
1131
+ }
1132
+ }
1133
+ if (typeof classification === 'string') {
1134
+ payload.push(`<SetProperty Id="${propertyId++}" ObjectPathId="5" Name="Classification"><Parameter Type="String">${formatting_1.formatting.escapeXml(classification)}</Parameter></SetProperty>`);
1135
+ }
1136
+ if (typeof disableFlows !== 'undefined') {
1137
+ payload.push(`<SetProperty Id="${propertyId++}" ObjectPathId="5" Name="DisableFlows"><Parameter Type="Boolean">${disableFlows}</Parameter></SetProperty>`);
1138
+ }
1139
+ if (typeof shareByEmailEnabled !== 'undefined') {
1140
+ payload.push(`<SetProperty Id="${propertyId++}" ObjectPathId="5" Name="ShareByEmailEnabled"><Parameter Type="Boolean">${shareByEmailEnabled}</Parameter></SetProperty>`);
1141
+ }
1142
+ if (sharingCapability) {
1143
+ const sharingCapabilityOption = SharingCapabilities_1.SharingCapabilities[sharingCapability];
1144
+ payload.push(`<SetProperty Id="${propertyId++}" ObjectPathId="5" Name="SharingCapability"><Parameter Type="Enum">${sharingCapabilityOption}</Parameter></SetProperty>`);
1145
+ }
1146
+ const pos = tenantId.indexOf('|') + 1;
1147
+ const requestOptionsUpdateProperties = {
1148
+ url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
1149
+ headers: {
1150
+ 'X-RequestDigest': context.FormDigestValue
1151
+ },
1152
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config_1.default.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions>${payload.join('')}<ObjectPath Id="14" ObjectPathId="13" /><ObjectIdentityQuery Id="15" ObjectPathId="5" /><Query Id="16" ObjectPathId="13"><Query SelectAllProperties="false"><Properties><Property Name="IsComplete" ScalarProperty="true" /><Property Name="PollingInterval" ScalarProperty="true" /></Properties></Query></Query></Actions><ObjectPaths><Identity Id="5" Name="53d8499e-d0d2-5000-cb83-9ade5be42ca4|${tenantId.substr(pos, tenantId.indexOf('&') - pos)}&#xA;SiteProperties&#xA;${formatting_1.formatting.encodeQueryParameter(url)}" /><Method Id="13" ParentId="5" Name="Update" /></ObjectPaths></Request>`
1153
+ };
1154
+ const res = yield request_1.default.post(requestOptionsUpdateProperties);
1155
+ const json = JSON.parse(res);
1156
+ const response = json[0];
1157
+ if (response.ErrorInfo) {
1158
+ throw response.ErrorInfo.ErrorMessage;
1159
+ }
1160
+ else {
1161
+ const operation = json[json.length - 1];
1162
+ const isComplete = operation.IsComplete;
1163
+ if (!isComplete) {
1164
+ yield new Promise((resolve, reject) => {
1165
+ setTimeout(() => {
1166
+ exports.spo.waitUntilFinished({
1167
+ operationId: JSON.stringify(operation._ObjectIdentity_),
1168
+ siteUrl: spoAdminUrl,
1169
+ resolve,
1170
+ reject,
1171
+ logger,
1172
+ currentContext: context,
1173
+ verbose: verbose,
1174
+ debug: verbose
1175
+ });
1176
+ }, operation.PollingInterval);
1177
+ });
1178
+ }
1179
+ }
1180
+ }
1181
+ if (siteDesignId) {
1182
+ yield exports.spo.applySiteDesign(siteDesignId, url, logger, verbose);
1183
+ }
1184
+ });
1185
+ },
1186
+ /**
1187
+ * Updates the groupified site owners
1188
+ * @param spoAdminUrl The SharePoint admin url
1189
+ * @param groupId The ID of the group
1190
+ * @param owners The owners to be updated
1191
+ * @param logger The logger object
1192
+ * @param verbose Set for verbose logging
1193
+ */
1194
+ setGroupifiedSiteOwners(spoAdminUrl, groupId, owners, logger, verbose) {
1195
+ return __awaiter(this, void 0, void 0, function* () {
1196
+ const splittedOwners = owners.split(',').map(o => o.trim());
1197
+ if (verbose) {
1198
+ logger.logToStderr('Retrieving user information to set group owners...');
1199
+ }
1200
+ const requestOptions = {
1201
+ url: `https://graph.microsoft.com/v1.0/users?$filter=${splittedOwners.map(o => `userPrincipalName eq '${o}'`).join(' or ')}&$select=id`,
1202
+ headers: {
1203
+ 'content-type': 'application/json;odata.metadata=none'
1204
+ },
1205
+ responseType: 'json'
1206
+ };
1207
+ return request_1.default.get(requestOptions)
1208
+ .then((res) => {
1209
+ if (res.value.length === 0) {
1210
+ return Promise.resolve();
1211
+ }
1212
+ return Promise.all(res.value.map(user => {
1213
+ const requestOptions = {
1214
+ url: `${spoAdminUrl}/_api/SP.Directory.DirectorySession/Group('${groupId}')/Owners/Add(objectId='${user.id}', principalName='')`,
1215
+ headers: {
1216
+ 'content-type': 'application/json;odata=verbose'
1217
+ }
1218
+ };
1219
+ return request_1.default.post(requestOptions);
1220
+ }));
1221
+ });
1222
+ });
1223
+ },
1224
+ /**
1225
+ * Updates the site admin
1226
+ * @param spoAdminUrl The SharePoint admin url
1227
+ * @param context The FormDigestInfo
1228
+ * @param siteUrl The url of the site where the owners has to be updated
1229
+ * @param principal The principal of the admin
1230
+ * @param logger The logger object
1231
+ * @param verbose Set for verbose logging
1232
+ */
1233
+ setSiteAdmin(spoAdminUrl, context, siteUrl, principal, logger, verbose) {
1234
+ return __awaiter(this, void 0, void 0, function* () {
1235
+ if (verbose && logger) {
1236
+ logger.logToStderr(`Updating site admin ${principal} on ${siteUrl}...`);
1237
+ }
1238
+ const requestOptions = {
1239
+ url: `${spoAdminUrl}/_vti_bin/client.svc/ProcessQuery`,
1240
+ headers: {
1241
+ 'X-RequestDigest': context.FormDigestValue
1242
+ },
1243
+ data: `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${config_1.default.applicationName}" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="48" ObjectPathId="47" /></Actions><ObjectPaths><Method Id="47" ParentId="34" Name="SetSiteAdmin"><Parameters><Parameter Type="String">${formatting_1.formatting.escapeXml(siteUrl)}</Parameter><Parameter Type="String">${formatting_1.formatting.escapeXml(principal)}</Parameter><Parameter Type="Boolean">true</Parameter></Parameters></Method><Constructor Id="34" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>`
1244
+ };
1245
+ const res = yield request_1.default.post(requestOptions);
1246
+ const json = JSON.parse(res);
1247
+ const response = json[0];
1248
+ if (response.ErrorInfo) {
1249
+ throw response.ErrorInfo.ErrorMessage;
1250
+ }
1251
+ else {
1252
+ return;
1253
+ }
1254
+ });
1255
+ },
1256
+ /**
1257
+ * Applies a site design
1258
+ * @param id The ID of the site design (GUID)
1259
+ * @param webUrl The url of the site where the design should be applied
1260
+ * @param logger The logger object
1261
+ * @param verbose Set for verbose logging
1262
+ */
1263
+ applySiteDesign(id, webUrl, logger, verbose) {
1264
+ return __awaiter(this, void 0, void 0, function* () {
1265
+ if (verbose) {
1266
+ logger.logToStderr(`Applying site design ${id}...`);
1267
+ }
1268
+ const spoUrl = yield exports.spo.getSpoUrl(logger, verbose);
1269
+ const requestOptions = {
1270
+ url: `${spoUrl}/_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ApplySiteDesign`,
1271
+ headers: {
1272
+ 'content-type': 'application/json;charset=utf-8',
1273
+ accept: 'application/json;odata=nometadata'
1274
+ },
1275
+ data: {
1276
+ siteDesignId: id,
1277
+ webUrl: webUrl
1278
+ },
1279
+ responseType: 'json'
1280
+ };
1281
+ yield request_1.default.post(requestOptions);
1282
+ });
1283
+ },
1284
+ /**
1285
+ * Gets the web properties for a given url
1286
+ * @param url The url of the web
1287
+ * @param logger The logger object
1288
+ * @param verbose Set for verbose logging
1289
+ */
1290
+ getWeb(url, logger, verbose) {
1291
+ return __awaiter(this, void 0, void 0, function* () {
1292
+ if (verbose && logger) {
1293
+ logger.logToStderr(`Getting the web properties for ${url}`);
1294
+ }
1295
+ const requestOptions = {
1296
+ url: `${url}/_api/web`,
1297
+ headers: {
1298
+ 'accept': 'application/json;odata=nometadata'
1299
+ },
1300
+ responseType: 'json'
1301
+ };
1302
+ const webProperties = yield request_1.default.get(requestOptions);
1303
+ return webProperties;
1304
+ });
705
1305
  }
706
1306
  };
707
1307
  //# sourceMappingURL=spo.js.map