@kwiz/common 1.0.1

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 (310) hide show
  1. package/LICENSE +21 -0
  2. package/dist/_dependencies.d.ts +1 -0
  3. package/dist/_dependencies.js +8 -0
  4. package/dist/_dependencies.js.map +1 -0
  5. package/dist/helpers/Guid.d.ts +119 -0
  6. package/dist/helpers/Guid.js +183 -0
  7. package/dist/helpers/Guid.js.map +1 -0
  8. package/dist/helpers/_dependencies.d.ts +2 -0
  9. package/dist/helpers/_dependencies.js +21 -0
  10. package/dist/helpers/_dependencies.js.map +1 -0
  11. package/dist/helpers/base64.d.ts +8 -0
  12. package/dist/helpers/base64.js +178 -0
  13. package/dist/helpers/base64.js.map +1 -0
  14. package/dist/helpers/browser.d.ts +144 -0
  15. package/dist/helpers/browser.js +1200 -0
  16. package/dist/helpers/browser.js.map +1 -0
  17. package/dist/helpers/browserinfo.d.ts +23 -0
  18. package/dist/helpers/browserinfo.js +215 -0
  19. package/dist/helpers/browserinfo.js.map +1 -0
  20. package/dist/helpers/collections.base.d.ts +128 -0
  21. package/dist/helpers/collections.base.js +430 -0
  22. package/dist/helpers/collections.base.js.map +1 -0
  23. package/dist/helpers/collections.d.ts +18 -0
  24. package/dist/helpers/collections.js +99 -0
  25. package/dist/helpers/collections.js.map +1 -0
  26. package/dist/helpers/color.d.ts +11 -0
  27. package/dist/helpers/color.js +57 -0
  28. package/dist/helpers/color.js.map +1 -0
  29. package/dist/helpers/cookies.d.ts +6 -0
  30. package/dist/helpers/cookies.js +56 -0
  31. package/dist/helpers/cookies.js.map +1 -0
  32. package/dist/helpers/date.d.ts +43 -0
  33. package/dist/helpers/date.js +158 -0
  34. package/dist/helpers/date.js.map +1 -0
  35. package/dist/helpers/debug.d.ts +33 -0
  36. package/dist/helpers/debug.js +177 -0
  37. package/dist/helpers/debug.js.map +1 -0
  38. package/dist/helpers/emails.d.ts +2 -0
  39. package/dist/helpers/emails.js +10 -0
  40. package/dist/helpers/emails.js.map +1 -0
  41. package/dist/helpers/eval.d.ts +1 -0
  42. package/dist/helpers/eval.js +10 -0
  43. package/dist/helpers/eval.js.map +1 -0
  44. package/dist/helpers/file.d.ts +11 -0
  45. package/dist/helpers/file.js +55 -0
  46. package/dist/helpers/file.js.map +1 -0
  47. package/dist/helpers/flatted.d.ts +20 -0
  48. package/dist/helpers/flatted.js +135 -0
  49. package/dist/helpers/flatted.js.map +1 -0
  50. package/dist/helpers/functions.d.ts +4 -0
  51. package/dist/helpers/functions.js +17 -0
  52. package/dist/helpers/functions.js.map +1 -0
  53. package/dist/helpers/graph/calendar.types.d.ts +3 -0
  54. package/dist/helpers/graph/calendar.types.js +15 -0
  55. package/dist/helpers/graph/calendar.types.js.map +1 -0
  56. package/dist/helpers/http.d.ts +25 -0
  57. package/dist/helpers/http.js +70 -0
  58. package/dist/helpers/http.js.map +1 -0
  59. package/dist/helpers/images.d.ts +16 -0
  60. package/dist/helpers/images.js +21 -0
  61. package/dist/helpers/images.js.map +1 -0
  62. package/dist/helpers/index.d.ts +29 -0
  63. package/dist/helpers/index.js +46 -0
  64. package/dist/helpers/index.js.map +1 -0
  65. package/dist/helpers/json.d.ts +3 -0
  66. package/dist/helpers/json.js +44 -0
  67. package/dist/helpers/json.js.map +1 -0
  68. package/dist/helpers/md5.d.ts +5 -0
  69. package/dist/helpers/md5.js +172 -0
  70. package/dist/helpers/md5.js.map +1 -0
  71. package/dist/helpers/objects.d.ts +49 -0
  72. package/dist/helpers/objects.js +271 -0
  73. package/dist/helpers/objects.js.map +1 -0
  74. package/dist/helpers/promises.d.ts +14 -0
  75. package/dist/helpers/promises.js +112 -0
  76. package/dist/helpers/promises.js.map +1 -0
  77. package/dist/helpers/random.d.ts +2 -0
  78. package/dist/helpers/random.js +32 -0
  79. package/dist/helpers/random.js.map +1 -0
  80. package/dist/helpers/scheduler/scheduler.d.ts +39 -0
  81. package/dist/helpers/scheduler/scheduler.js +109 -0
  82. package/dist/helpers/scheduler/scheduler.js.map +1 -0
  83. package/dist/helpers/sharepoint.d.ts +112 -0
  84. package/dist/helpers/sharepoint.js +629 -0
  85. package/dist/helpers/sharepoint.js.map +1 -0
  86. package/dist/helpers/strings.d.ts +56 -0
  87. package/dist/helpers/strings.js +282 -0
  88. package/dist/helpers/strings.js.map +1 -0
  89. package/dist/helpers/typecheckers.d.ts +56 -0
  90. package/dist/helpers/typecheckers.js +274 -0
  91. package/dist/helpers/typecheckers.js.map +1 -0
  92. package/dist/helpers/url.d.ts +46 -0
  93. package/dist/helpers/url.js +199 -0
  94. package/dist/helpers/url.js.map +1 -0
  95. package/dist/helpers/urlhelper.d.ts +16 -0
  96. package/dist/helpers/urlhelper.js +96 -0
  97. package/dist/helpers/urlhelper.js.map +1 -0
  98. package/dist/index.d.ts +15 -0
  99. package/dist/index.js +37 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/types/common.types.d.ts +19 -0
  102. package/dist/types/common.types.js +4 -0
  103. package/dist/types/common.types.js.map +1 -0
  104. package/dist/types/flatted.types.d.ts +49 -0
  105. package/dist/types/flatted.types.js +3 -0
  106. package/dist/types/flatted.types.js.map +1 -0
  107. package/dist/types/globals.types.d.ts +6 -0
  108. package/dist/types/globals.types.js +3 -0
  109. package/dist/types/globals.types.js.map +1 -0
  110. package/dist/types/graph/calendar.types.d.ts +79 -0
  111. package/dist/types/graph/calendar.types.js +3 -0
  112. package/dist/types/graph/calendar.types.js.map +1 -0
  113. package/dist/types/graph/index.d.ts +1 -0
  114. package/dist/types/graph/index.js +18 -0
  115. package/dist/types/graph/index.js.map +1 -0
  116. package/dist/types/index.d.ts +11 -0
  117. package/dist/types/index.js +28 -0
  118. package/dist/types/index.js.map +1 -0
  119. package/dist/types/knownscript.types.d.ts +22 -0
  120. package/dist/types/knownscript.types.js +3 -0
  121. package/dist/types/knownscript.types.js.map +1 -0
  122. package/dist/types/libs/datajs.types.d.ts +29 -0
  123. package/dist/types/libs/datajs.types.js +3 -0
  124. package/dist/types/libs/datajs.types.js.map +1 -0
  125. package/dist/types/libs/ics.types.d.ts +29 -0
  126. package/dist/types/libs/ics.types.js +3 -0
  127. package/dist/types/libs/ics.types.js.map +1 -0
  128. package/dist/types/libs/index.d.ts +3 -0
  129. package/dist/types/libs/index.js +20 -0
  130. package/dist/types/libs/index.js.map +1 -0
  131. package/dist/types/libs/msal.types.d.ts +33 -0
  132. package/dist/types/libs/msal.types.js +63 -0
  133. package/dist/types/libs/msal.types.js.map +1 -0
  134. package/dist/types/locales.d.ts +122 -0
  135. package/dist/types/locales.js +1 -0
  136. package/dist/types/locales.js.map +1 -0
  137. package/dist/types/localstoragecache.types.d.ts +8 -0
  138. package/dist/types/localstoragecache.types.js +3 -0
  139. package/dist/types/localstoragecache.types.js.map +1 -0
  140. package/dist/types/moment.d.ts +6 -0
  141. package/dist/types/moment.js +1 -0
  142. package/dist/types/moment.js.map +1 -0
  143. package/dist/types/regex.types.d.ts +14 -0
  144. package/dist/types/regex.types.js +3 -0
  145. package/dist/types/regex.types.js.map +1 -0
  146. package/dist/types/rest.types.d.ts +81 -0
  147. package/dist/types/rest.types.js +24 -0
  148. package/dist/types/rest.types.js.map +1 -0
  149. package/dist/types/sharepoint.types.d.ts +1432 -0
  150. package/dist/types/sharepoint.types.js +629 -0
  151. package/dist/types/sharepoint.types.js.map +1 -0
  152. package/dist/types/sharepoint.utils.types.d.ts +246 -0
  153. package/dist/types/sharepoint.utils.types.js +26 -0
  154. package/dist/types/sharepoint.utils.types.js.map +1 -0
  155. package/dist/utils/_dependencies.d.ts +3 -0
  156. package/dist/utils/_dependencies.js +24 -0
  157. package/dist/utils/_dependencies.js.map +1 -0
  158. package/dist/utils/base64.d.ts +2 -0
  159. package/dist/utils/base64.js +41 -0
  160. package/dist/utils/base64.js.map +1 -0
  161. package/dist/utils/consolelogger.d.ts +73 -0
  162. package/dist/utils/consolelogger.js +281 -0
  163. package/dist/utils/consolelogger.js.map +1 -0
  164. package/dist/utils/date.d.ts +10 -0
  165. package/dist/utils/date.js +30 -0
  166. package/dist/utils/date.js.map +1 -0
  167. package/dist/utils/emails.d.ts +2 -0
  168. package/dist/utils/emails.js +24 -0
  169. package/dist/utils/emails.js.map +1 -0
  170. package/dist/utils/index.d.ts +13 -0
  171. package/dist/utils/index.js +31 -0
  172. package/dist/utils/index.js.map +1 -0
  173. package/dist/utils/knownscript.d.ts +99 -0
  174. package/dist/utils/knownscript.js +261 -0
  175. package/dist/utils/knownscript.js.map +1 -0
  176. package/dist/utils/localstoragecache.d.ts +19 -0
  177. package/dist/utils/localstoragecache.js +372 -0
  178. package/dist/utils/localstoragecache.js.map +1 -0
  179. package/dist/utils/rest.d.ts +17 -0
  180. package/dist/utils/rest.js +402 -0
  181. package/dist/utils/rest.js.map +1 -0
  182. package/dist/utils/script.d.ts +33 -0
  183. package/dist/utils/script.js +169 -0
  184. package/dist/utils/script.js.map +1 -0
  185. package/dist/utils/sharepoint.rest/common.d.ts +32 -0
  186. package/dist/utils/sharepoint.rest/common.js +146 -0
  187. package/dist/utils/sharepoint.rest/common.js.map +1 -0
  188. package/dist/utils/sharepoint.rest/date.d.ts +2 -0
  189. package/dist/utils/sharepoint.rest/date.js +57 -0
  190. package/dist/utils/sharepoint.rest/date.js.map +1 -0
  191. package/dist/utils/sharepoint.rest/file.folder.d.ts +58 -0
  192. package/dist/utils/sharepoint.rest/file.folder.js +305 -0
  193. package/dist/utils/sharepoint.rest/file.folder.js.map +1 -0
  194. package/dist/utils/sharepoint.rest/index.d.ts +11 -0
  195. package/dist/utils/sharepoint.rest/index.js +28 -0
  196. package/dist/utils/sharepoint.rest/index.js.map +1 -0
  197. package/dist/utils/sharepoint.rest/item.d.ts +81 -0
  198. package/dist/utils/sharepoint.rest/item.js +444 -0
  199. package/dist/utils/sharepoint.rest/item.js.map +1 -0
  200. package/dist/utils/sharepoint.rest/list.d.ts +228 -0
  201. package/dist/utils/sharepoint.rest/list.js +868 -0
  202. package/dist/utils/sharepoint.rest/list.js.map +1 -0
  203. package/dist/utils/sharepoint.rest/listutils/GetListItemsByCaml.d.ts +19 -0
  204. package/dist/utils/sharepoint.rest/listutils/GetListItemsByCaml.js +629 -0
  205. package/dist/utils/sharepoint.rest/listutils/GetListItemsByCaml.js.map +1 -0
  206. package/dist/utils/sharepoint.rest/listutils/GetListItemsById.d.ts +14 -0
  207. package/dist/utils/sharepoint.rest/listutils/GetListItemsById.js +222 -0
  208. package/dist/utils/sharepoint.rest/listutils/GetListItemsById.js.map +1 -0
  209. package/dist/utils/sharepoint.rest/listutils/common.d.ts +3 -0
  210. package/dist/utils/sharepoint.rest/listutils/common.js +198 -0
  211. package/dist/utils/sharepoint.rest/listutils/common.js.map +1 -0
  212. package/dist/utils/sharepoint.rest/user-search.d.ts +76 -0
  213. package/dist/utils/sharepoint.rest/user-search.js +239 -0
  214. package/dist/utils/sharepoint.rest/user-search.js.map +1 -0
  215. package/dist/utils/sharepoint.rest/user.d.ts +71 -0
  216. package/dist/utils/sharepoint.rest/user.js +404 -0
  217. package/dist/utils/sharepoint.rest/user.js.map +1 -0
  218. package/dist/utils/sharepoint.rest/web.d.ts +107 -0
  219. package/dist/utils/sharepoint.rest/web.js +929 -0
  220. package/dist/utils/sharepoint.rest/web.js.map +1 -0
  221. package/dist/utils/sod.d.ts +29 -0
  222. package/dist/utils/sod.js +177 -0
  223. package/dist/utils/sod.js.map +1 -0
  224. package/package.json +60 -0
  225. package/readme.md +13 -0
  226. package/src/_dependencies.ts +2 -0
  227. package/src/helpers/Guid.ts +182 -0
  228. package/src/helpers/_dependencies.ts +3 -0
  229. package/src/helpers/base64.ts +174 -0
  230. package/src/helpers/browser.test.js +9 -0
  231. package/src/helpers/browser.ts +1299 -0
  232. package/src/helpers/browserinfo.ts +293 -0
  233. package/src/helpers/collections.base.test.js +26 -0
  234. package/src/helpers/collections.base.ts +439 -0
  235. package/src/helpers/collections.ts +108 -0
  236. package/src/helpers/color.ts +55 -0
  237. package/src/helpers/cookies.ts +55 -0
  238. package/src/helpers/date.test.js +97 -0
  239. package/src/helpers/date.ts +163 -0
  240. package/src/helpers/debug.ts +187 -0
  241. package/src/helpers/emails.ts +7 -0
  242. package/src/helpers/eval.ts +5 -0
  243. package/src/helpers/file.test.js +51 -0
  244. package/src/helpers/file.ts +59 -0
  245. package/src/helpers/flatted.ts +150 -0
  246. package/src/helpers/functions.ts +17 -0
  247. package/src/helpers/graph/calendar.types.ts +11 -0
  248. package/src/helpers/http.ts +70 -0
  249. package/src/helpers/images.ts +23 -0
  250. package/src/helpers/index.ts +29 -0
  251. package/src/helpers/json.ts +39 -0
  252. package/src/helpers/md5.ts +190 -0
  253. package/src/helpers/objects.test.js +27 -0
  254. package/src/helpers/objects.ts +256 -0
  255. package/src/helpers/promises.test.js +18 -0
  256. package/src/helpers/promises.ts +102 -0
  257. package/src/helpers/random.ts +27 -0
  258. package/src/helpers/scheduler/scheduler.test.js +104 -0
  259. package/src/helpers/scheduler/scheduler.ts +132 -0
  260. package/src/helpers/sharepoint.ts +681 -0
  261. package/src/helpers/strings.test.js +43 -0
  262. package/src/helpers/strings.ts +288 -0
  263. package/src/helpers/typecheckers.test.js +35 -0
  264. package/src/helpers/typecheckers.ts +263 -0
  265. package/src/helpers/url.test.js +18 -0
  266. package/src/helpers/url.ts +202 -0
  267. package/src/helpers/urlhelper.ts +104 -0
  268. package/src/index.ts +24 -0
  269. package/src/types/common.types.ts +16 -0
  270. package/src/types/flatted.types.ts +60 -0
  271. package/src/types/globals.types.ts +7 -0
  272. package/src/types/graph/calendar.types.ts +81 -0
  273. package/src/types/graph/index.ts +1 -0
  274. package/src/types/index.ts +12 -0
  275. package/src/types/knownscript.types.ts +19 -0
  276. package/src/types/libs/datajs.types.ts +29 -0
  277. package/src/types/libs/ics.types.ts +31 -0
  278. package/src/types/libs/index.ts +4 -0
  279. package/src/types/libs/msal.types.ts +79 -0
  280. package/src/types/locales.ts +125 -0
  281. package/src/types/localstoragecache.types.ts +9 -0
  282. package/src/types/moment.ts +7 -0
  283. package/src/types/regex.types.ts +17 -0
  284. package/src/types/rest.types.ts +94 -0
  285. package/src/types/sharepoint.types.ts +1413 -0
  286. package/src/types/sharepoint.utils.types.ts +246 -0
  287. package/src/utils/_dependencies.ts +4 -0
  288. package/src/utils/base64.ts +27 -0
  289. package/src/utils/consolelogger.ts +315 -0
  290. package/src/utils/date.ts +36 -0
  291. package/src/utils/emails.ts +25 -0
  292. package/src/utils/index.ts +13 -0
  293. package/src/utils/knownscript.ts +280 -0
  294. package/src/utils/localstoragecache.ts +419 -0
  295. package/src/utils/rest.ts +465 -0
  296. package/src/utils/script.ts +168 -0
  297. package/src/utils/sharepoint.rest/common.ts +149 -0
  298. package/src/utils/sharepoint.rest/date.ts +61 -0
  299. package/src/utils/sharepoint.rest/file.folder.ts +368 -0
  300. package/src/utils/sharepoint.rest/index.ts +11 -0
  301. package/src/utils/sharepoint.rest/item.ts +456 -0
  302. package/src/utils/sharepoint.rest/list.ts +1144 -0
  303. package/src/utils/sharepoint.rest/listutils/GetListItemsByCaml.ts +750 -0
  304. package/src/utils/sharepoint.rest/listutils/GetListItemsById.ts +265 -0
  305. package/src/utils/sharepoint.rest/listutils/common.ts +202 -0
  306. package/src/utils/sharepoint.rest/user-search.ts +254 -0
  307. package/src/utils/sharepoint.rest/user.ts +447 -0
  308. package/src/utils/sharepoint.rest/web.ts +1031 -0
  309. package/src/utils/sod.ts +193 -0
  310. package/tsconfig.json +21 -0
@@ -0,0 +1,1031 @@
1
+ import { IAppTile, IContextWebInformation, IDictionary, IFieldInfoEX, IRestOptions, IRestRoleDefinition, IRootWebInfo, ISiteInfo, ITimeZone, IUserCustomActionInfo, IWebBasicInfo, IWebInfo, IWebRegionalSettings, SPBasePermissionKind, SPBasePermissions, WebTypes, extendFieldInfo, getGlobal, iContentType, iList, isDate, isNotEmptyArray, isNullOrEmptyArray, isNullOrEmptyString, isNullOrUndefined, isString, isTypeofFullNameNullOrUndefined, isValidGuid, jsonTypes, makeServerRelativeUrl, normalizeGuid, normalizeUrl, sortArray } from "../_dependencies";
2
+ import { ConsoleLogger } from "../consolelogger";
3
+ import { toIsoDateFormat } from "../date";
4
+ import { GetJson, GetJsonSync, longLocalCache, mediumLocalCache, shortLocalCache, weeekLongLocalCache } from "../rest";
5
+ import { CONTENT_TYPES_SELECT, CONTENT_TYPES_SELECT_WITH_FIELDS, GetRestBaseUrl, GetSiteUrl, LIST_EXPAND, LIST_SELECT, WEB_SELECT, hasGlobalContext } from "./common";
6
+ import { GetListFields, GetListFieldsSync, GetListRestUrl } from "./list";
7
+
8
+ const logger = ConsoleLogger.get("SharePoint.Rest.Web");
9
+
10
+ export function GetSiteInfo(siteUrl?: string): Promise<ISiteInfo> {
11
+ siteUrl = GetSiteUrl(siteUrl);
12
+
13
+ return GetJson<{ d: { Id: string; ServerRelativeUrl: string; }; }>(GetRestBaseUrl(siteUrl) + "/site?$select=id,serverRelativeUrl", null, { ...longLocalCache })
14
+ .then(r => {
15
+ var id = normalizeGuid(r.d.Id);
16
+ var serverRelativeUrl = normalizeUrl(r.d.ServerRelativeUrl);
17
+ if (isNullOrEmptyString(serverRelativeUrl)) serverRelativeUrl = "/";//can't return "" since it will be treated as current sub site, when tyring to access the root site from a sub-site
18
+ //console.log("site id: " + id);
19
+ return { Id: id, ServerRelativeUrl: serverRelativeUrl };
20
+ })
21
+ .catch<ISiteInfo>(() => null);
22
+ }
23
+
24
+ export function GetSiteInfoSync(siteUrl?: string): ISiteInfo {
25
+ siteUrl = GetSiteUrl(siteUrl);
26
+
27
+ let result = GetJsonSync<{ d: { Id: string; ServerRelativeUrl: string; }; }>(GetRestBaseUrl(siteUrl) + "/site?$select=id,serverRelativeUrl", null, { ...longLocalCache });
28
+ if (result.success) {
29
+ var id = normalizeGuid(result.result.d.Id);
30
+ var serverRelativeUrl = normalizeUrl(result.result.d.ServerRelativeUrl);
31
+ return { Id: id, ServerRelativeUrl: serverRelativeUrl };
32
+ }
33
+ return null;
34
+ }
35
+
36
+ function _getSiteIdFromContext(siteUrl?: string) {
37
+ if (hasGlobalContext()) {
38
+ //issue 7295
39
+ //make sure we return false for /sites/ab/c is not under /sites/a by adding a / at the end
40
+ let normalizedWebUrl = normalizeUrl(makeServerRelativeUrl(siteUrl), true).toLowerCase();
41
+ let normalizedCurrentSiteUrl = normalizeUrl(_spPageContextInfo.siteServerRelativeUrl, true).toLowerCase();
42
+ //test cases
43
+ //if (!testSub("/", "/hello")) console.error("1");
44
+ //if (testSub("/", "/sites/hello")) console.error("2");
45
+ //if (testSub("/sites/a", "/sites/b")) console.error("3");
46
+ //if (!testSub("/sites/a", "/sites/a/b")) console.error("4");
47
+ //if (!testSub("/", "/")) console.error("5");
48
+ //if (!testSub("/sites/a", "/sites/a")) console.error("6");
49
+ //if (testSub("/sites/a", "/hello")) console.error("7");
50
+
51
+ if (isNullOrUndefined(siteUrl)
52
+ || normalizedCurrentSiteUrl === "/" && !normalizedWebUrl.startsWith("/sites")
53
+ || normalizedCurrentSiteUrl !== "/" && normalizedWebUrl.startsWith(normalizedCurrentSiteUrl)) {
54
+ if (!isNullOrEmptyString(_spPageContextInfo.siteId)) {
55
+ return normalizeGuid(_spPageContextInfo.siteId);
56
+ }
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+
62
+ /** Get site id lower case no {} */
63
+ export async function GetSiteId(siteUrl?: string): Promise<string> {
64
+ let siteId = _getSiteIdFromContext(siteUrl);
65
+ if (!isNullOrEmptyString(siteId)) {
66
+ return siteId;
67
+ }
68
+
69
+ return GetSiteInfo(siteUrl).then((info) => {
70
+ if (!isNullOrUndefined(info) && !isNullOrEmptyString(info.Id)) {
71
+ return normalizeGuid(info.Id);
72
+ }
73
+ return null;
74
+ }).catch<string>(() => {
75
+ return null;
76
+ });
77
+ }
78
+
79
+ /** Get site id lower case no {} */
80
+ export function GetSiteIdSync(siteUrl?: string): string {
81
+ let siteId = _getSiteIdFromContext(siteUrl);
82
+ if (!isNullOrEmptyString(siteId)) {
83
+ return siteId;
84
+ }
85
+
86
+ let result = GetSiteInfoSync(siteUrl);
87
+ return !isNullOrUndefined(result) ? normalizeGuid(result.Id) : null;
88
+ }
89
+
90
+ /** Get root web id lower case no {} */
91
+ export function GetRootWebInfo(siteUrl?: string): Promise<IRootWebInfo> {
92
+ siteUrl = GetSiteUrl(siteUrl);
93
+
94
+ return GetJson<{ d: { Id: string; ServerRelativeUrl: string; }; }>(GetRestBaseUrl(siteUrl) + "/site/rootWeb?$select=id,serverRelativeUrl", null, { ...longLocalCache })
95
+ .then(r => {
96
+ var id = normalizeGuid(r.d.Id);
97
+ var serverRelativeUrl = normalizeUrl(r.d.ServerRelativeUrl);
98
+ //console.log("site id: " + id);
99
+ return { Id: id, ServerRelativeUrl: serverRelativeUrl };
100
+ })
101
+ .catch<IRootWebInfo>(() => null);
102
+ }
103
+
104
+ /** Return the web Title */
105
+ export function GetWebTitle(siteUrl: string): Promise<string> {
106
+ siteUrl = GetSiteUrl(siteUrl);
107
+
108
+ return GetJson<{ d: { Title: string; }; }>(GetRestBaseUrl(siteUrl) + `/web/Title`, null, { ...shortLocalCache })
109
+ .then(r => {
110
+ return r.d.Title;
111
+ })
112
+ .catch<string>(() => null);
113
+ }
114
+
115
+ function _getWebIdRequestUrl(siteUrl: string) {
116
+ return `${GetRestBaseUrl(siteUrl)}/web/Id`;
117
+ }
118
+
119
+ /** Return the web id */
120
+ export function GetWebId(siteUrl: string): Promise<string> {
121
+ return GetJson<{ d: { Id: string; }; }>(_getWebIdRequestUrl(siteUrl), null, { ...longLocalCache })
122
+ .then(r => {
123
+ return normalizeGuid(r.d.Id);
124
+ })
125
+ .catch<string>(() => null);
126
+ }
127
+
128
+ /** Return the web id */
129
+ export function GetWebIdSync(siteUrl: string): string {
130
+ let syncResult = GetJsonSync<{ d: { Id: string; }; }>(_getWebIdRequestUrl(siteUrl), null, { ...longLocalCache });
131
+ if (syncResult.success)
132
+ return syncResult.result.d.Id;
133
+ else return null;
134
+ }
135
+
136
+ /** Return the web id */
137
+ export async function IsRootWeb(siteUrl: string): Promise<boolean> {
138
+ siteUrl = GetSiteUrl(siteUrl);
139
+
140
+ let webId = await GetWebId(siteUrl);
141
+ let rootWeb = await GetRootWebInfo(siteUrl);
142
+ return webId === rootWeb.Id;
143
+ }
144
+
145
+ export function UserHasAllPermissions(siteUrl: string, permissions: SPBasePermissionKind[]): Promise<boolean> {
146
+ siteUrl = GetSiteUrl(siteUrl);
147
+
148
+ return GetJson<{ d: { EffectiveBasePermissions: { High: number; Low: number; }; }; }>(GetRestBaseUrl(siteUrl) + `/web/EffectiveBasePermissions`, null,
149
+ { ...shortLocalCache })
150
+ .then(r => {
151
+ var effectivePermissions = new SPBasePermissions(r.d.EffectiveBasePermissions);
152
+ return permissions.every((perm) => {
153
+ return effectivePermissions.has(perm);
154
+ });
155
+ })
156
+ .catch<boolean>(() => null);
157
+ }
158
+
159
+ export function UserHasManageSitePermissions(siteUrl: string): Promise<boolean> {
160
+ siteUrl = GetSiteUrl(siteUrl);
161
+
162
+ return GetJson<{ d: { EffectiveBasePermissions: { High: number; Low: number; }; }; }>(GetRestBaseUrl(siteUrl) + `/web/EffectiveBasePermissions`, null,
163
+ { ...shortLocalCache })
164
+ .then(r => {
165
+ return new SPBasePermissions(r.d.EffectiveBasePermissions).has(SPBasePermissionKind.ManageWeb);
166
+ })
167
+ .catch<boolean>(() => null);
168
+ }
169
+
170
+ export interface IGetContentTypesOptions {
171
+ /** if you want content types for a specific list under site URL - ignores fromRootWeb */
172
+ listIdOrTitle?: string;
173
+ /** if you want content types from the root web - ignores listIdOrTitle */
174
+ fromRootWeb?: boolean;
175
+ ignoreFolders?: boolean;
176
+ ignoreHidden?: boolean;
177
+ /** Include fields associated with the content type */
178
+ includeFields?: boolean;
179
+ }
180
+
181
+ function _getContentTypesRequestUrl(siteUrl: string, options: Omit<IGetContentTypesOptions, "ignoreFolders" | "ignoreHidden"> = {}) {
182
+ const { fromRootWeb, includeFields, listIdOrTitle } = options;
183
+
184
+ let query = `$select=${includeFields === true ? CONTENT_TYPES_SELECT : CONTENT_TYPES_SELECT_WITH_FIELDS}${includeFields === true ? "&$expand=Fields" : ""}`;
185
+
186
+ if (!isNullOrEmptyString(listIdOrTitle)) {
187
+ return `${GetListRestUrl(siteUrl, listIdOrTitle)}/contenttypes?${query}`;
188
+ } else if (fromRootWeb) {
189
+ return `${GetRestBaseUrl(siteUrl)}/site/rootweb/contenttypes?${query}`;
190
+ } else {
191
+ return `${GetRestBaseUrl(siteUrl)}/web/contenttypes?${query}`;
192
+ }
193
+ }
194
+
195
+ function _postProcessGetContentTypes(contentTypes: iContentType[],
196
+ options: Omit<IGetContentTypesOptions, "listIdOrTitle" | "fromRootWeb"> = {},
197
+ allListFields?: IFieldInfoEX[]) {
198
+ const { ignoreHidden, ignoreFolders, includeFields } = options;
199
+ if (!isNullOrEmptyArray(contentTypes)) {
200
+ if (ignoreFolders === true || ignoreHidden === true) {
201
+ contentTypes = contentTypes.filter(rr => {
202
+ if (options.ignoreFolders && rr.StringId.startsWith('0x0120')) return false;
203
+ if (options.ignoreHidden && rr.Hidden) return false;
204
+ return true;
205
+ });
206
+ }
207
+
208
+ if (includeFields === true) {
209
+ contentTypes.forEach((result) => {
210
+ if (!isNullOrEmptyArray(result.Fields)) {
211
+ result.Fields = result.Fields.map((field) => {
212
+ return extendFieldInfo(field, allListFields || result.Fields);
213
+ });
214
+ }
215
+ });
216
+ }
217
+ return contentTypes;
218
+ }
219
+ return null;
220
+ }
221
+
222
+ export async function GetContentTypes(siteUrl: string, options: IGetContentTypesOptions = {}): Promise<iContentType[]> {
223
+ let url = _getContentTypesRequestUrl(siteUrl, options);
224
+
225
+ let allListFields: IFieldInfoEX[] = null;
226
+
227
+ if (options.includeFields) {
228
+ allListFields = await GetListFields(siteUrl, options.listIdOrTitle);
229
+ }
230
+
231
+ return GetJson<{ value: iContentType[]; }>(url, null, { allowCache: true, jsonMetadata: jsonTypes.nometadata })
232
+ .then(result => {
233
+ if (!isNullOrUndefined(result)) {
234
+ return _postProcessGetContentTypes(result.value, options, allListFields);
235
+ }
236
+ return null;
237
+ })
238
+ .catch<iContentType[]>(() => null);
239
+ }
240
+
241
+ export function GetContentTypesSync(siteUrl: string, options: IGetContentTypesOptions = {}): iContentType[] {
242
+ let url = _getContentTypesRequestUrl(siteUrl, options);
243
+
244
+ let allListFields: IFieldInfoEX[] = null;
245
+
246
+ if (options.includeFields) {
247
+ allListFields = GetListFieldsSync(siteUrl, options.listIdOrTitle);
248
+ }
249
+
250
+ let result = GetJsonSync<{ value: iContentType[]; }>(url, null, { allowCache: true, jsonMetadata: jsonTypes.nometadata });
251
+ if (!isNullOrUndefined(result) && result.success === true && !isNullOrUndefined(result.result)) {
252
+ return _postProcessGetContentTypes(result.result.value, options, allListFields);
253
+ }
254
+ return null;
255
+ }
256
+
257
+
258
+ interface IGetListsOptions {
259
+ includeRootFolders?: boolean;
260
+ includeViews?: boolean;
261
+ }
262
+
263
+ function _getListsRequestUrl(siteUrl: string, options: IGetListsOptions) {
264
+ let select = LIST_SELECT;
265
+ let expand = LIST_EXPAND;
266
+ if (options.includeRootFolders === true) {
267
+ select += ",RootFolder/Name,RootFolder/ServerRelativeUrl";
268
+ expand += ",RootFolder";
269
+ }
270
+ if (options.includeViews === true) {
271
+ expand += ",Views";
272
+ }
273
+
274
+ return GetRestBaseUrl(siteUrl) + `/web/lists?$select=${select}&$expand=${expand}`;
275
+ }
276
+
277
+ function _postProcessGetLists(lists: iList[], options: Omit<IGetListsOptions, "includeRootFolders"> = {}) {
278
+ lists = lists || [];
279
+ if (options && options.includeViews) {
280
+ lists.forEach(l => {
281
+ if (isNullOrEmptyArray(l.Views)) {
282
+ l.Views = [];
283
+ }
284
+ l.Views.forEach(v => { v.Id = normalizeGuid(v.Id); });
285
+ });
286
+ }
287
+
288
+ lists.forEach((list) => {
289
+ if (list.EffectiveBasePermissions
290
+ && (isString(list.EffectiveBasePermissions.High)
291
+ || isString(list.EffectiveBasePermissions.Low))) {
292
+ list.EffectiveBasePermissions = {
293
+ High: Number(list.EffectiveBasePermissions.High),
294
+ Low: Number(list.EffectiveBasePermissions.Low)
295
+ };
296
+ }
297
+ });
298
+ return lists;
299
+ }
300
+
301
+ export function GetLists(siteUrl: string, options: IGetListsOptions = {}): Promise<iList[]> {
302
+ let url = _getListsRequestUrl(siteUrl, options);
303
+
304
+ return GetJson<{ value: iList[]; }>(url, null, { allowCache: true, jsonMetadata: jsonTypes.nometadata })
305
+ .then(result => {
306
+ return _postProcessGetLists(result.value, options);
307
+ })
308
+ .catch<iList[]>(() => []);
309
+ }
310
+
311
+ export function GetListsSync(siteUrl: string, options: IGetListsOptions = {}): iList[] {
312
+ let url = _getListsRequestUrl(siteUrl, options);
313
+
314
+ let response = GetJsonSync<{ value: iList[]; }>(url, null, { ...shortLocalCache, jsonMetadata: jsonTypes.nometadata });
315
+ if (response && response.success && response.result && isNotEmptyArray(response.result.value)) {
316
+ return _postProcessGetLists(response.result.value, options);
317
+ }
318
+ return [];
319
+ }
320
+
321
+ /**
322
+ * Get all sub webs. Results will be cached in memory and sorted
323
+ * @param siteUrl the starting URL you want to get the sites for
324
+ * @param allowAppWebs send true if you would like to inlucde app webs as well
325
+ */
326
+ export async function GetAllSubWebs(siteUrl: string, options?: { allSiteCollections?: boolean; allowAppWebs?: boolean; }): Promise<IWebBasicInfo[]> {
327
+ siteUrl = GetSiteUrl(siteUrl);
328
+
329
+ let sites: IWebBasicInfo[] = [];
330
+ options = options || {};
331
+ var currentSite: IWebBasicInfo;
332
+ var queryFailed = false;
333
+
334
+ try {
335
+ currentSite = await GetWebInfo(siteUrl);
336
+ let queryFilter = '';
337
+ if (!options.allSiteCollections) {
338
+ //filter by site id
339
+ let siteId = await GetSiteId(siteUrl);
340
+ queryFilter = `SiteId:${siteId}`;
341
+ }
342
+
343
+ //Issue 6735 missing WebId for some customer (US, government GCC tenant will not return WebId)
344
+ let queryUrl = `${GetRestBaseUrl(siteUrl)}/search/query?querytext=%27${queryFilter}(contentclass:STS_Site)%20(contentclass:STS_Web)%27&trimduplicates=false&rowlimit=5000&selectproperties=%27Title,Url,WebTemplate,WebId%27`;
345
+ let response = await GetJson<{
346
+ d: {
347
+ query: {
348
+ PrimaryQueryResult: {
349
+ RelevantResults: {
350
+ RowCount: number;
351
+ TotalRows: number;
352
+ TotalRowsIncludingCuplicates: number;
353
+ Table: {
354
+ Rows: {
355
+ results: {
356
+ Cells: {
357
+ results: {
358
+ Key: "Title" | "Url" | "SiteId" | "WebId" | "WebTemplate";
359
+ Value: string;
360
+ ValueType: "Edm.String" | "Edm.Double" | "Edm.Int64" | "Edm.Int32" | "Edm.Guid" | "Null";
361
+ }[];
362
+ };
363
+ }[];
364
+ };
365
+ };
366
+ };
367
+ };
368
+ };
369
+ };
370
+ }>(queryUrl, null, { ...shortLocalCache });
371
+
372
+ let results = response && response.d && response.d.query && response.d.query.PrimaryQueryResult;
373
+
374
+ let addedSites: string[] = [];
375
+ if (results && results.RelevantResults.RowCount >= 0) {
376
+ let allPropsFound = false;
377
+ results.RelevantResults.Table.Rows.results.forEach(row => {
378
+ let Title: string = null;
379
+ let Url: string = null;
380
+ let WebId: string = null;
381
+ let WebTemplate: string = null;
382
+ let skip = false;
383
+ for (var i = 0; i < row.Cells.results.length; i++) {
384
+ let cell = row.Cells.results[i];
385
+ let value = isNullOrEmptyString(cell.Value) ? "" : cell.Value;
386
+ switch (cell.Key) {
387
+ case "WebTemplate":
388
+ WebTemplate = value;
389
+ if (!options.allowAppWebs && value === "APP")
390
+ skip = true;
391
+ break;
392
+ case "Title":
393
+ Title = value;
394
+ break;
395
+ case "WebId":
396
+ WebId = normalizeGuid(value);
397
+ break;
398
+ case "Url":
399
+ if (addedSites.indexOf(value.toLowerCase()) >= 0) {
400
+ //duplicate, skip
401
+ skip = true;
402
+ }
403
+ else {
404
+ Url = value;
405
+ }
406
+ break;
407
+ }
408
+ if (skip)
409
+ break;//stop the cells loop
410
+ allPropsFound =
411
+ Title !== null &&
412
+ Url !== null &&
413
+ WebId !== null &&
414
+ WebTemplate !== null;
415
+ if (allPropsFound)
416
+ break;
417
+ }
418
+
419
+ if (!skip && allPropsFound)//don't skip, and we found all needed props
420
+ {
421
+ sites.push({
422
+ Title: Title,
423
+ ServerRelativeUrl: makeServerRelativeUrl(Url),
424
+ WebId: WebId,
425
+ WebTemplate: WebTemplate,
426
+ WebType: WebTemplate === "APP" ? WebTypes.App :
427
+ WebTemplate === "GROUP" ? WebTypes.Group :
428
+ WebTemplate === "STS" ? WebTypes.Team :
429
+ WebTypes.Other
430
+ });
431
+ }
432
+ });
433
+ }
434
+
435
+ //Issue 7161
436
+ if (sites.length === 1 || (!isNullOrUndefined(currentSite) && !sites.filter((site) => {
437
+ return site.WebId !== currentSite.WebId;
438
+ })[0])) {
439
+ queryFailed = true;
440
+ }
441
+ } catch (e) {
442
+ queryFailed = true;
443
+ }
444
+
445
+ if (queryFailed) {
446
+ // Igor: Issue #7702
447
+ if (_spPageContextInfo && _spPageContextInfo.siteServerRelativeUrl.toLowerCase() !== siteUrl.toLowerCase()) {
448
+ //siteUrl = _spPageContextInfo.siteServerRelativeUrl;
449
+ //currentSite = await GetWebInfo(siteUrl);
450
+ //Kevin: Issue 1028
451
+ //The user may not have permission to the site collection root web. Instead of overwirting the currentSite/siteUrl,
452
+ //we make a request for the site collection root web. If we get a valid response, replace currentSite/siteUrl with
453
+ //the site collection root web info.
454
+ let currentSiteCollection = await GetWebInfo(_spPageContextInfo.siteServerRelativeUrl);
455
+
456
+ if (currentSiteCollection && !isNullOrEmptyString(currentSiteCollection.ServerRelativeUrl)) {
457
+ currentSite = currentSiteCollection;
458
+ siteUrl = _spPageContextInfo.siteServerRelativeUrl;
459
+ }
460
+ }
461
+
462
+ //add current site
463
+ if (currentSite && (options.allowAppWebs || currentSite.WebType !== WebTypes.App)) {
464
+ sites.push(currentSite);
465
+ }
466
+
467
+ //Issue 6651
468
+ //add sub sites
469
+ //if the query failed, we can't rely on search to get the subwebs
470
+ var currentSiteSubSites = await __getSubSites(siteUrl, options.allowAppWebs);
471
+ if (isNotEmptyArray(currentSiteSubSites)) {
472
+ sites = [...sites, ...currentSiteSubSites];
473
+ }
474
+ }
475
+
476
+ var webIds = [];
477
+ var filteredSites: IWebBasicInfo[] = [];
478
+ for (let site of sites) {
479
+ if (webIds.indexOf(site.WebId) === -1) {
480
+ webIds.push(site.WebId);
481
+ filteredSites.push(site);
482
+ }
483
+ }
484
+
485
+ sortArray(filteredSites, s => s.ServerRelativeUrl);
486
+
487
+ return filteredSites;
488
+ }
489
+
490
+ export async function __getSubSites(siteUrl: string, allowAppWebs?: boolean) {
491
+ siteUrl = GetSiteUrl(siteUrl);
492
+
493
+ let sites: IWebBasicInfo[] = [];
494
+
495
+ //try {
496
+ //maybe search is not wokring? use regular REST API
497
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/getsubwebsfilteredforcurrentuser(nwebtemplatefilter=-1,nconfigurationfilter=0)?$Select=Title,ServerRelativeUrl,Id,WebTemplate`;
498
+ let result = await GetJson<{
499
+ d: {
500
+ results: {
501
+ Title: string;
502
+ ServerRelativeUrl: string;
503
+ Id: string;
504
+ WebTemplate: string;
505
+ }[];
506
+ };
507
+ }>(restUrl, null, { ...shortLocalCache });
508
+ if (result && result.d && isNotEmptyArray(result.d.results)) {
509
+ let results = (allowAppWebs) ? result.d.results : result.d.results.filter(s => s.WebTemplate !== "APP");
510
+ let promises: Promise<IWebBasicInfo[]>[] = [];
511
+ results.forEach(s => {
512
+ sites.push({
513
+ Title: s.Title,
514
+ ServerRelativeUrl: s.ServerRelativeUrl,
515
+ WebId: s.Id,
516
+ WebTemplate: s.WebTemplate,
517
+ WebType: s.WebTemplate === "APP" ? WebTypes.App :
518
+ s.WebTemplate === "GROUP" ? WebTypes.Group :
519
+ s.WebTemplate === "STS" ? WebTypes.Team :
520
+ WebTypes.Other
521
+ });
522
+ promises.push(__getSubSites(s.ServerRelativeUrl, allowAppWebs));
523
+ });
524
+ //loop and add all sub sites
525
+ let allSubs = await Promise.all(promises);
526
+ allSubs.forEach(subSubs => {
527
+ sites.push(...subSubs);
528
+ });
529
+ }
530
+ //}
531
+ //catch {
532
+ //}
533
+ return sites;
534
+ }
535
+
536
+ interface IGetWebInfoResponse {
537
+ Title: string;
538
+ ServerRelativeUrl: string;
539
+ Id: string;
540
+ WebTemplate: string;
541
+ Description: string,
542
+ SiteLogoUrl: string
543
+ }
544
+
545
+ function _getWebInfoByIdRequestUrl(siteUrl: string, webId: string) {
546
+ return `${GetRestBaseUrl(siteUrl)}/site/openWebById('${webId}')?$Select=${WEB_SELECT}`;
547
+ }
548
+
549
+ function _getCurrentWebInfoRequestUrl(siteUrl: string) {
550
+ return `${GetRestBaseUrl(siteUrl)}/web?$Select=${WEB_SELECT}`;
551
+ }
552
+
553
+ function _postProcessGetWebInfo(webInfo: IGetWebInfoResponse) {
554
+ if (!isNullOrUndefined(webInfo)) {
555
+ return {
556
+ Title: webInfo.Title,
557
+ ServerRelativeUrl: webInfo.ServerRelativeUrl,
558
+ WebId: webInfo.Id,
559
+ WebTemplate: webInfo.WebTemplate,
560
+ WebType: GetWebType(webInfo.WebTemplate),
561
+ Description: webInfo.Description,
562
+ SiteLogoUrl: webInfo.SiteLogoUrl
563
+ } as IWebBasicInfo;
564
+ }
565
+ return null;
566
+ }
567
+
568
+ export async function GetWebInfo(siteUrl: string, webId?: string, refreshCache?: boolean): Promise<IWebBasicInfo> {
569
+ let webInfoResponse: IGetWebInfoResponse = null;
570
+
571
+ try {
572
+ if (!isNullOrEmptyString(webId) && isValidGuid(webId)) {
573
+ webId = normalizeGuid(webId);
574
+ let currentWebId = await GetWebId(siteUrl);
575
+ if (currentWebId !== webId) {
576
+ let url = _getWebInfoByIdRequestUrl(siteUrl, webId);
577
+ webInfoResponse = await GetJson<IGetWebInfoResponse>(url, null, {
578
+ method: "POST", spWebUrl: GetSiteUrl(siteUrl), ...shortLocalCache,
579
+ jsonMetadata: jsonTypes.nometadata,
580
+ allowCache: refreshCache !== true
581
+ });
582
+ }
583
+ }
584
+
585
+ if (isNullOrUndefined(webInfoResponse)) {
586
+ let url = _getCurrentWebInfoRequestUrl(siteUrl);
587
+ webInfoResponse = await GetJson<IGetWebInfoResponse>(url, null, {
588
+ ...shortLocalCache,
589
+ jsonMetadata: jsonTypes.nometadata,
590
+ allowCache: refreshCache !== true
591
+ });
592
+ }
593
+
594
+ } catch (e) { }
595
+
596
+ return _postProcessGetWebInfo(webInfoResponse);
597
+ }
598
+
599
+ export function GetWebInfoSync(siteUrl: string, webId?: string): IWebBasicInfo {
600
+ let webInfoResponse: IGetWebInfoResponse = null;
601
+
602
+ if (!isNullOrEmptyString(webId) && isValidGuid(webId)) {
603
+ webId = normalizeGuid(webId);
604
+ let currentWebId = GetWebIdSync(siteUrl);
605
+ if (currentWebId !== webId) {
606
+ let url = _getWebInfoByIdRequestUrl(siteUrl, webId);
607
+ let syncResult = GetJsonSync<IGetWebInfoResponse>(url, null, {
608
+ method: "POST", spWebUrl: GetSiteUrl(siteUrl), ...shortLocalCache,
609
+ jsonMetadata: jsonTypes.nometadata
610
+ });
611
+ if (syncResult.success) {
612
+ webInfoResponse = syncResult.result;
613
+ }
614
+ }
615
+ }
616
+
617
+ if (isNullOrUndefined(webInfoResponse)) {
618
+ let url = _getCurrentWebInfoRequestUrl(siteUrl);
619
+ let syncResult = GetJsonSync<IGetWebInfoResponse>(url, null, {
620
+ ...shortLocalCache,
621
+ jsonMetadata: jsonTypes.nometadata
622
+ });
623
+ if (syncResult.success) {
624
+ webInfoResponse = syncResult.result;
625
+ }
626
+ }
627
+
628
+ return _postProcessGetWebInfo(webInfoResponse);
629
+ }
630
+
631
+ export async function GetWebRoleDefinitions(siteUrl: string): Promise<IRestRoleDefinition[]> {
632
+ return GetJson<{ d: { results: IRestRoleDefinition[]; }; }>(GetRestBaseUrl(siteUrl) + `/web/RoleDefinitions?filter=Hidden ne true`, null, { ...longLocalCache })
633
+ .then(r => {
634
+ return r.d.results || [];
635
+ })
636
+ .catch<IRestRoleDefinition[]>(() => []);
637
+ }
638
+
639
+ /** Web sub webs for the selected site */
640
+ export async function GetSubWebs(siteUrl: string, options?: { allowAppWebs?: boolean; }): Promise<IWebInfo[]> {
641
+ return GetJson<{ d: { results: IWebInfo[]; }; }>(GetRestBaseUrl(siteUrl) + `/web/webs${options && options.allowAppWebs ? "" : "&$filter=WebTemplate ne 'APP'"}`, null,
642
+ { ...shortLocalCache })
643
+ .then(r => {
644
+ return r.d.results;
645
+ })
646
+ .catch<IWebInfo[]>(() => []);
647
+ }
648
+
649
+ /** Web sub webs for the selected site */
650
+ export async function GetAppTiles(siteUrl: string): Promise<IAppTile[]> {
651
+ //Issue 933 this api does not work in a classic app web
652
+ if (hasGlobalContext() && _spPageContextInfo.isAppWeb) {
653
+ logger.warn('GetAppTiles does not work in an app web');
654
+ return null;
655
+ }
656
+
657
+ return GetJson<{ value: IAppTile[]; }>(GetRestBaseUrl(siteUrl) + "/web/AppTiles?$filter=AppType%20eq%203&$select=Title,ProductId", null,
658
+ { ...shortLocalCache, jsonMetadata: jsonTypes.nometadata })
659
+ .then(r => {
660
+ return isNotEmptyArray(r.value) ? r.value.map(t => {
661
+ return {
662
+ Title: t.Title,
663
+ ProductId: normalizeGuid(t.ProductId)
664
+ } as IAppTile;
665
+ }) : [];
666
+ })
667
+ .catch<IAppTile[]>(() => []);
668
+ }
669
+
670
+ /** Web sub webs for the selected site */
671
+ export function GetAppTilesSync(siteUrl: string): IAppTile[] {
672
+ siteUrl = GetSiteUrl(siteUrl);
673
+
674
+ //Issue 933 this api does not work in a classic app web
675
+ if (hasGlobalContext() && _spPageContextInfo.isAppWeb) {
676
+ logger.warn('GetAppTiles does not work in an app web');
677
+ return null;
678
+ }
679
+
680
+ let r = GetJsonSync<{ value: IAppTile[]; }>(GetRestBaseUrl(siteUrl) + "/web/AppTiles?$filter=AppType%20eq%203&$select=Title,ProductId", null,
681
+ { ...shortLocalCache, jsonMetadata: jsonTypes.nometadata });
682
+ return r.success && r.result && isNotEmptyArray(r.result.value) ? r.result.value.map(t => {
683
+ return {
684
+ Title: t.Title,
685
+ ProductId: normalizeGuid(t.ProductId)
686
+ } as IAppTile;
687
+ }) : [];
688
+ }
689
+
690
+ function GetWebType(WebTemplate: string): WebTypes {
691
+ return WebTemplate === "APP" ? WebTypes.App :
692
+ WebTemplate === "GROUP" ? WebTypes.Group :
693
+ WebTemplate === "STS" ? WebTypes.Team :
694
+ WebTypes.Other;
695
+ }
696
+
697
+ export async function GetServerTimeZone(siteUrl: string) {
698
+ siteUrl = GetSiteUrl(siteUrl);
699
+
700
+ let getTimeZoneUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings/timeZone`;
701
+
702
+ let result = await GetJson<{
703
+ d: ITimeZone;
704
+ }>(getTimeZoneUrl, null, { ...longLocalCache });
705
+
706
+ if (result && result.d && !isNullOrUndefined(result.d)) {
707
+ return result.d;
708
+ }
709
+ else return null;
710
+ }
711
+
712
+ /**
713
+ * to be used when parsing string date to date object in JavaScript like so:
714
+ * var clientTimezoneOffset = new Date().getTimezoneOffset() * 60 * 1000;
715
+ * var clientDate = new Date(value);
716
+ * var serverDate = new Date(clientDate.getTime() + clientTimezoneOffset + GetServerTimeOffset);
717
+ * We must send a date in, since places like Israel have different offset for specific dates (GMT+2 or GMT+3)
718
+ * or just call SPServerLocalTimeToUTCDate
719
+ */
720
+ async function GetServerTimeOffset(siteUrl: string, date: Date) {
721
+ siteUrl = GetSiteUrl(siteUrl);
722
+
723
+ let dateStr = toIsoDateFormat(date, { zeroTime: true, omitZ: true });
724
+ let inputDate = new Date(dateStr);
725
+
726
+ let getTimeZoneOffsetUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings/timeZone/localTimeToUTC(@date)?@date='${encodeURIComponent(dateStr)}'`;
727
+
728
+ let result = await GetJson<{ value: string; }>(getTimeZoneOffsetUrl, null, { ...weeekLongLocalCache, jsonMetadata: jsonTypes.nometadata });
729
+ if (result && !isNullOrEmptyString(result.value)) {
730
+ let resultDate = new Date(result.value.slice(0, result.value.length - 1));//remove Z and get as date.
731
+
732
+ return (resultDate.getTime() - inputDate.getTime());
733
+ }
734
+ else return 0;
735
+ }
736
+ /**
737
+ * to be used when parsing string date to date object in JavaScript like so:
738
+ * var clientTimezoneOffset = new Date().getTimezoneOffset() * 60 * 1000;
739
+ * var clientDate = new Date(value);
740
+ * var serverDate = new Date(clientDate.getTime() + clientTimezoneOffset + GetServerTimeOffset);
741
+ * We must send a date in, since places like Israel have different offset for specific dates (GMT+2 or GMT+3)
742
+ * or just call SPServerLocalTimeToUTCDate
743
+ */
744
+ function GetServerTimeOffsetSync(siteUrl: string, date: Date) {
745
+ siteUrl = GetSiteUrl(siteUrl);
746
+
747
+ let dateStr = toIsoDateFormat(date, { zeroTime: true, omitZ: true });
748
+ let inputDate = new Date(dateStr);
749
+
750
+ let getTimeZoneOffsetUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings/timeZone/localTimeToUTC(@date)?@date='${encodeURIComponent(dateStr)}'`;
751
+
752
+ let result = GetJsonSync<{ value: string; }>(getTimeZoneOffsetUrl, null, { ...weeekLongLocalCache, jsonMetadata: jsonTypes.nometadata });
753
+ if (result && result.success && !isNullOrEmptyString(result.result.value)) {
754
+ let resultDate = new Date(result.result.value.slice(0, result.result.value.length - 1));//remove Z and get as date.
755
+
756
+ return (resultDate.getTime() - inputDate.getTime());
757
+ }
758
+ else return 0;
759
+ }
760
+
761
+ /** get date yyyy:MM:ddTHH:mm:ss NO ZED, or a date object created in the server local time, and return a date object of the corrected UTC time */
762
+ export async function SPServerLocalTimeToUTCDate(siteUrl: string, date: string | Date) {
763
+ //used in 7700
764
+ if (isNullOrEmptyString(date)) return null;
765
+ siteUrl = GetSiteUrl(siteUrl);
766
+ if (!isDate(date))
767
+ date = new Date(date);
768
+
769
+ let serverTimeOffset = await GetServerTimeOffset(siteUrl, date);
770
+ return _SPServerLocalTimeToUTCDate(date, serverTimeOffset);
771
+ }
772
+ /** get date yyyy:MM:ddTHH:mm:ss NO ZED, or a date object created in the server local time, and return a date object of the corrected UTC time */
773
+ export function SPServerLocalTimeToUTCDateSync(siteUrl: string, date: string | Date) {
774
+ //used in 7700
775
+ if (isNullOrEmptyString(date)) return null;
776
+ siteUrl = GetSiteUrl(siteUrl);
777
+ if (!isDate(date))
778
+ date = new Date(date);
779
+
780
+ let serverTimeOffset = GetServerTimeOffsetSync(siteUrl, date);
781
+ return _SPServerLocalTimeToUTCDate(date, serverTimeOffset);
782
+ }
783
+ function _SPServerLocalTimeToUTCDate(date: Date, serverTimeOffset: number) {
784
+ let localTimeOffset = date.getTimezoneOffset() * 60000;
785
+ return new Date(serverTimeOffset - localTimeOffset + date.getTime());
786
+ }
787
+
788
+ /** get date yyyy:MM:ddTHH:mm:ss NO ZED
789
+ * returns yyyy:MM:ddTHH:mm:ssZ
790
+ * expensive, but works. for faster bulk parsing use toIsoDateFormat(new Date(GetServerTimeOffset + date.getTime()))
791
+ * or: SPServerLocalTimeToUTCDate
792
+ */
793
+ export async function SPServerLocalTimeToUTC(siteUrl: string, date: string | Date) {
794
+ siteUrl = GetSiteUrl(siteUrl);
795
+
796
+ if (isDate(date)) {
797
+ date = toIsoDateFormat(date, { omitZ: true });
798
+ }
799
+
800
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings/timeZone/localTimeToUTC(@date)?@date='${encodeURIComponent(date)}'`;
801
+
802
+ let result = await GetJson<{ value: string; }>(restUrl, null, { ...weeekLongLocalCache, jsonMetadata: jsonTypes.nometadata });
803
+ return result && result.value || null;
804
+ }
805
+ /**
806
+ * convert date in ISO format (yyyy:MM:ddTHH:mm:ss) or SPServerLocalTime (5/27/2020 11:34, 5-27-2020 11:34)
807
+ * returns date in ISO UTC (yyyy:MM:ddTHH:mm:ssZ)
808
+ * expensive, but works. for faster bulk parsing use toIsoDateFormat(new Date(GetServerTimeOffset + date.getTime()))
809
+ * or: SPServerLocalTimeToUTCDateSync
810
+ */
811
+ export function SPServerLocalTimeToUTCSync(siteUrl: string, date: string | Date) {
812
+ siteUrl = GetSiteUrl(siteUrl);
813
+
814
+ if (isDate(date)) {
815
+ date = toIsoDateFormat(date, { omitZ: true });
816
+ }
817
+
818
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings/timeZone/localTimeToUTC(@date)?@date='${encodeURIComponent(date)}'`;
819
+
820
+ let result = GetJsonSync<{ value: string; }>(restUrl, null, { ...weeekLongLocalCache, jsonMetadata: jsonTypes.nometadata });
821
+ return result.success && result.result.value || null;
822
+ }
823
+
824
+ /** get utc date yyyy:MM:ddTHH:mm:ssZ
825
+ * returns yyyy:MM:ddTHH:mm:ss NO ZED
826
+ * expensive, but works. for faster bulk parsing use toIsoDateFormat(new Date(date.getTime()-GetServerTimeOffset,{omitZ:true}))
827
+ */
828
+ export async function UTCToSPServerLocalTime(siteUrl: string, date: string | Date) {
829
+ siteUrl = GetSiteUrl(siteUrl);
830
+
831
+ if (isDate(date)) {
832
+ date = toIsoDateFormat(date);
833
+ }
834
+
835
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings/timeZone/utcToLocalTime(@date)?@date='${encodeURIComponent(date)}'`;
836
+
837
+ let result = await GetJson<{ value: string; }>(restUrl, null, { ...longLocalCache, jsonMetadata: jsonTypes.nometadata });
838
+ return result && result.value || null;
839
+ }
840
+ /** get utc date yyyy:MM:ddTHH:mm:ssZ
841
+ * returns yyyy:MM:ddTHH:mm:ss NO ZED
842
+ * expensive, but works. for faster bulk parsing use toIsoDateFormat(new Date(date.getTime()-GetServerTimeOffset,{omitZ:true}))
843
+ */
844
+ export function UTCToSPServerLocalTimeSync(siteUrl: string, date: string | Date) {
845
+ siteUrl = GetSiteUrl(siteUrl);
846
+
847
+ if (isDate(date)) {
848
+ date = toIsoDateFormat(date);
849
+ }
850
+
851
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings/timeZone/utcToLocalTime(@date)?@date='${encodeURIComponent(date)}'`;
852
+
853
+ let result = GetJsonSync<{ value: string; }>(restUrl, null, { ...longLocalCache, jsonMetadata: jsonTypes.nometadata });
854
+ return result.success && result.result.value || null;
855
+ }
856
+
857
+
858
+ export function SPServerLocalTimeSync(siteUrl?: string) {
859
+ siteUrl = GetSiteUrl(siteUrl);
860
+
861
+ var clientNowServerDeltas = getGlobal<{ [url: string]: number; }>("ClientNowServerDeltas");
862
+ var clientNowServerDelta = clientNowServerDeltas[siteUrl];
863
+ var now = new Date();
864
+
865
+ if (isNullOrUndefined(clientNowServerDelta)) {
866
+ var local = UTCToSPServerLocalTimeSync(siteUrl, now.toISOString());
867
+ clientNowServerDelta = (+now - +(new Date(local)));
868
+ clientNowServerDeltas[siteUrl] = clientNowServerDelta;
869
+ }
870
+
871
+ var newdate = new Date(+now - clientNowServerDelta);
872
+ return toIsoDateFormat(newdate, { omitZ: true });
873
+ }
874
+
875
+ export async function SPServerLocalTime(siteUrl: string) {
876
+ siteUrl = GetSiteUrl(siteUrl);
877
+
878
+ var clientNowServerDeltas = getGlobal<{ [url: string]: number; }>("ClientNowServerDeltas");
879
+ var clientNowServerDelta = clientNowServerDeltas[siteUrl];
880
+ var now = new Date();
881
+
882
+ if (isNullOrUndefined(clientNowServerDelta)) {
883
+ var local = await UTCToSPServerLocalTime(siteUrl, now.toISOString());
884
+ clientNowServerDelta = (+now - +(new Date(local)));
885
+ clientNowServerDeltas[siteUrl] = clientNowServerDelta;
886
+ }
887
+
888
+ var newdate = new Date(+now - clientNowServerDelta);
889
+ return toIsoDateFormat(newdate, { omitZ: true });
890
+ }
891
+
892
+ export function GetContextWebInformationSync(siteUrl: string): IContextWebInformation {
893
+ var siteId: string = null;
894
+ if (_spPageContextInfo && _spPageContextInfo.isAppWeb) {
895
+ //inside an app web you can't get the contextinfo for any other site
896
+ siteUrl = _spPageContextInfo.webServerRelativeUrl;
897
+ siteId = _spPageContextInfo.siteId;
898
+ } else {
899
+ siteId = GetSiteIdSync(siteUrl);
900
+
901
+ if (isNullOrEmptyString(siteId)) {
902
+ return null;
903
+ }
904
+ }
905
+
906
+ let result = GetJsonSync<{ d: { GetContextWebInformation: IContextWebInformation; }; }>(`${GetRestBaseUrl(siteUrl)}/contextinfo`, null, {
907
+ method: "POST",
908
+ maxAge: 5 * 60,
909
+ includeDigestInPost: false,
910
+ allowCache: true,
911
+ postCacheKey: `GetContextWebInformation_${normalizeGuid(siteId)}`
912
+ });
913
+
914
+ if (result && result.success) {
915
+ return result.result.d.GetContextWebInformation;
916
+ } else {
917
+ return null;
918
+ }
919
+ }
920
+
921
+ /** Get UserCustomActions for web */
922
+ export async function GetUserCustomActions(siteUrl?: string, allowCache = true): Promise<IUserCustomActionInfo[]> {
923
+ siteUrl = GetSiteUrl(siteUrl);
924
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/UserCustomActions?&select=Name,ScriptSrc,Title`;
925
+ let cacheOptions = allowCache === true ? shortLocalCache : { allowCache: false };
926
+ let restOptions: IRestOptions = {
927
+ jsonMetadata: jsonTypes.nometadata,
928
+ ...cacheOptions
929
+ };
930
+ let result = await GetJson<{ value: IUserCustomActionInfo[]; }>(restUrl, null, restOptions);
931
+ return result && result.value || null;
932
+ }
933
+
934
+ /** Get web regional settings */
935
+ export async function GetRegionalSettings(siteUrl?: string) {
936
+ siteUrl = GetSiteUrl(siteUrl);
937
+
938
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/regionalSettings`;
939
+ try {
940
+ let result = await GetJson<IWebRegionalSettings>(restUrl, null, { ...mediumLocalCache, jsonMetadata: jsonTypes.nometadata });
941
+ return result;
942
+ } catch {
943
+ }
944
+ return null;
945
+ }
946
+
947
+ /** Get all web properties */
948
+ export async function GetAllWebProperties(siteUrl?: string) {
949
+ siteUrl = GetSiteUrl(siteUrl);
950
+
951
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/AllProperties`;
952
+ try {
953
+ let result = await GetJson<IDictionary<string>>(restUrl, null, { ...shortLocalCache, jsonMetadata: jsonTypes.nometadata });
954
+ return result;
955
+ } catch {
956
+ }
957
+ return null;
958
+ }
959
+
960
+ /** Get web property by name */
961
+ export async function GetWebPropertyByName(name: string, siteUrl?: string) {
962
+ siteUrl = GetSiteUrl(siteUrl);
963
+
964
+ let restUrl = `${GetRestBaseUrl(siteUrl)}/web/AllProperties?$select=${name}`;
965
+ try {
966
+ let result = await GetJson<IDictionary<string>>(restUrl, null, { ...shortLocalCache, jsonMetadata: jsonTypes.nometadata });
967
+ if (!isNullOrUndefined(result) && !isNullOrUndefined(result[name])) {
968
+ return result[name];
969
+ }
970
+ } catch {
971
+ }
972
+ return null;
973
+ }
974
+
975
+ export function getFormDigest(serverRelativeWebUrl?: string) {
976
+ var contextWebInformation = GetContextWebInformationSync(serverRelativeWebUrl);
977
+ return contextWebInformation && contextWebInformation.FormDigestValue || null;
978
+ }
979
+
980
+ export interface spfxContext { legacyPageContext: typeof _spPageContextInfo }
981
+ export function ensureLegacyProps(pageContext: spfxContext) {
982
+ try {
983
+ let isContextOk = (ctx: typeof _spPageContextInfo) => !isNullOrUndefined(ctx) && !isNullOrUndefined(ctx.webServerRelativeUrl);
984
+ let getLegacyContext = (ctx: spfxContext) => !isNullOrUndefined(ctx) && !isNullOrUndefined(ctx.legacyPageContext) ? ctx.legacyPageContext : null;
985
+ let getContext = (ctx: (typeof _spPageContextInfo) | spfxContext) => isContextOk(ctx as typeof _spPageContextInfo) ? ctx : getLegacyContext(ctx as spfxContext);
986
+
987
+ if (isTypeofFullNameNullOrUndefined("_spPageContextInfo") || !isContextOk(_spPageContextInfo)) {
988
+ logger.info(`_spPageContextInfo ${isTypeofFullNameNullOrUndefined("_spPageContextInfo") ? 'is missing' : 'is broken'}, wrapping with our property`);
989
+ //bug in SPFx during inplace left navigation will put an SPFx object into this global. Correct it using the setter.
990
+ let _currentContext = pageContext.legacyPageContext;
991
+ Object.defineProperty(window, "_spPageContextInfo", {
992
+ set: (newContext) => {
993
+ if (!isNullOrUndefined(newContext)) {
994
+ if (isContextOk(newContext)) {
995
+ logger.debug("Context ok");
996
+ _currentContext = newContext;
997
+ }
998
+ else {
999
+ let legacy = getLegacyContext(newContext);
1000
+ if (!isNullOrUndefined(legacy)) {
1001
+ logger.error("Context NOT ok - using legacy context");
1002
+ _currentContext = legacy;
1003
+ }
1004
+ else logger.error("Context NOT ok - no legacy context either.");
1005
+ }
1006
+ }
1007
+ },
1008
+ get: () => getContext(_currentContext)
1009
+ });
1010
+ }
1011
+ } catch (ex) {
1012
+ }
1013
+ }
1014
+
1015
+ export async function WebHasUniquePermissions(siteUrl: string): Promise<boolean> {
1016
+ let url = `${GetRestBaseUrl(siteUrl)}/web?$select=hasuniqueroleassignments`;
1017
+ let has = await GetJson<{ HasUniqueRoleAssignments: boolean }>(url, undefined, { allowCache: false, jsonMetadata: jsonTypes.nometadata });
1018
+ return has.HasUniqueRoleAssignments === true;
1019
+ }
1020
+ export async function BreakWebPermissionInheritance(siteUrl: string, clear = true): Promise<void> {
1021
+ let url = `${GetRestBaseUrl(siteUrl)}/web/breakroleinheritance(copyRoleAssignments=${clear ? 'false' : 'true'}, clearSubscopes=true)`;
1022
+ await GetJson(url, undefined, { method: "POST", allowCache: false, jsonMetadata: jsonTypes.nometadata });
1023
+ }
1024
+ export async function AssignWebPermission(siteUrl: string, principalId: number, roleId: number) {
1025
+ let url = `${GetRestBaseUrl(siteUrl)}/web/roleassignments/addroleassignment(principalid=${principalId},roleDefId=${roleId})`;
1026
+ await GetJson(url, undefined, { method: "POST", allowCache: false, jsonMetadata: jsonTypes.nometadata });
1027
+ }
1028
+ export async function RemoveWebPermission(siteUrl: string, principalId: number, roleId: number) {
1029
+ let url = `${GetRestBaseUrl(siteUrl)}/web/roleassignments/removeroleassignment(principalid=${principalId},roleDefId=${roleId})`;
1030
+ await GetJson(url, undefined, { method: "POST", allowCache: false, jsonMetadata: jsonTypes.nometadata });
1031
+ }