@apvee/spfx-react-toolkit 1.0.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 (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2012 -0
  3. package/lib/core/atoms.internal.d.ts +53 -0
  4. package/lib/core/atoms.internal.d.ts.map +1 -0
  5. package/lib/core/atoms.internal.js +35 -0
  6. package/lib/core/atoms.internal.js.map +1 -0
  7. package/lib/core/context.internal.d.ts +23 -0
  8. package/lib/core/context.internal.d.ts.map +1 -0
  9. package/lib/core/context.internal.js +34 -0
  10. package/lib/core/context.internal.js.map +1 -0
  11. package/lib/core/index.d.ts +6 -0
  12. package/lib/core/index.d.ts.map +1 -0
  13. package/lib/core/index.js +6 -0
  14. package/lib/core/index.js.map +1 -0
  15. package/lib/core/provider-application-customizer.d.ts +57 -0
  16. package/lib/core/provider-application-customizer.d.ts.map +1 -0
  17. package/lib/core/provider-application-customizer.js +45 -0
  18. package/lib/core/provider-application-customizer.js.map +1 -0
  19. package/lib/core/provider-base.internal.d.ts +20 -0
  20. package/lib/core/provider-base.internal.d.ts.map +1 -0
  21. package/lib/core/provider-base.internal.js +126 -0
  22. package/lib/core/provider-base.internal.js.map +1 -0
  23. package/lib/core/provider-field-customizer.d.ts +58 -0
  24. package/lib/core/provider-field-customizer.d.ts.map +1 -0
  25. package/lib/core/provider-field-customizer.js +46 -0
  26. package/lib/core/provider-field-customizer.js.map +1 -0
  27. package/lib/core/provider-listview-commandset.d.ts +60 -0
  28. package/lib/core/provider-listview-commandset.d.ts.map +1 -0
  29. package/lib/core/provider-listview-commandset.js +48 -0
  30. package/lib/core/provider-listview-commandset.js.map +1 -0
  31. package/lib/core/provider-webpart.d.ts +48 -0
  32. package/lib/core/provider-webpart.d.ts.map +1 -0
  33. package/lib/core/provider-webpart.js +36 -0
  34. package/lib/core/provider-webpart.js.map +1 -0
  35. package/lib/core/types.d.ts +84 -0
  36. package/lib/core/types.d.ts.map +1 -0
  37. package/lib/core/types.js +4 -0
  38. package/lib/core/types.js.map +1 -0
  39. package/lib/hooks/index.d.ts +34 -0
  40. package/lib/hooks/index.d.ts.map +1 -0
  41. package/lib/hooks/index.js +34 -0
  42. package/lib/hooks/index.js.map +1 -0
  43. package/lib/hooks/useSPFxAadHttpClient.d.ts +231 -0
  44. package/lib/hooks/useSPFxAadHttpClient.d.ts.map +1 -0
  45. package/lib/hooks/useSPFxAadHttpClient.js +299 -0
  46. package/lib/hooks/useSPFxAadHttpClient.js.map +1 -0
  47. package/lib/hooks/useSPFxContainerInfo.d.ts +41 -0
  48. package/lib/hooks/useSPFxContainerInfo.d.ts.map +1 -0
  49. package/lib/hooks/useSPFxContainerInfo.js +47 -0
  50. package/lib/hooks/useSPFxContainerInfo.js.map +1 -0
  51. package/lib/hooks/useSPFxContainerSize.d.ts +119 -0
  52. package/lib/hooks/useSPFxContainerSize.d.ts.map +1 -0
  53. package/lib/hooks/useSPFxContainerSize.js +150 -0
  54. package/lib/hooks/useSPFxContainerSize.js.map +1 -0
  55. package/lib/hooks/useSPFxContext.d.ts +14 -0
  56. package/lib/hooks/useSPFxContext.d.ts.map +1 -0
  57. package/lib/hooks/useSPFxContext.js +16 -0
  58. package/lib/hooks/useSPFxContext.js.map +1 -0
  59. package/lib/hooks/useSPFxCorrelationInfo.d.ts +51 -0
  60. package/lib/hooks/useSPFxCorrelationInfo.d.ts.map +1 -0
  61. package/lib/hooks/useSPFxCorrelationInfo.js +58 -0
  62. package/lib/hooks/useSPFxCorrelationInfo.js.map +1 -0
  63. package/lib/hooks/useSPFxCrossSitePermissions.d.ts +81 -0
  64. package/lib/hooks/useSPFxCrossSitePermissions.d.ts.map +1 -0
  65. package/lib/hooks/useSPFxCrossSitePermissions.js +132 -0
  66. package/lib/hooks/useSPFxCrossSitePermissions.js.map +1 -0
  67. package/lib/hooks/useSPFxDisplayMode.d.ts +61 -0
  68. package/lib/hooks/useSPFxDisplayMode.d.ts.map +1 -0
  69. package/lib/hooks/useSPFxDisplayMode.js +69 -0
  70. package/lib/hooks/useSPFxDisplayMode.js.map +1 -0
  71. package/lib/hooks/useSPFxEnvironmentInfo.d.ts +63 -0
  72. package/lib/hooks/useSPFxEnvironmentInfo.d.ts.map +1 -0
  73. package/lib/hooks/useSPFxEnvironmentInfo.js +91 -0
  74. package/lib/hooks/useSPFxEnvironmentInfo.js.map +1 -0
  75. package/lib/hooks/useSPFxFluent9ThemeInfo.d.ts +105 -0
  76. package/lib/hooks/useSPFxFluent9ThemeInfo.d.ts.map +1 -0
  77. package/lib/hooks/useSPFxFluent9ThemeInfo.js +136 -0
  78. package/lib/hooks/useSPFxFluent9ThemeInfo.js.map +1 -0
  79. package/lib/hooks/useSPFxHubSiteInfo.d.ts +80 -0
  80. package/lib/hooks/useSPFxHubSiteInfo.d.ts.map +1 -0
  81. package/lib/hooks/useSPFxHubSiteInfo.js +127 -0
  82. package/lib/hooks/useSPFxHubSiteInfo.js.map +1 -0
  83. package/lib/hooks/useSPFxInstanceInfo.d.ts +41 -0
  84. package/lib/hooks/useSPFxInstanceInfo.d.ts.map +1 -0
  85. package/lib/hooks/useSPFxInstanceInfo.js +40 -0
  86. package/lib/hooks/useSPFxInstanceInfo.js.map +1 -0
  87. package/lib/hooks/useSPFxListInfo.d.ts +64 -0
  88. package/lib/hooks/useSPFxListInfo.d.ts.map +1 -0
  89. package/lib/hooks/useSPFxListInfo.js +70 -0
  90. package/lib/hooks/useSPFxListInfo.js.map +1 -0
  91. package/lib/hooks/useSPFxLocaleInfo.d.ts +123 -0
  92. package/lib/hooks/useSPFxLocaleInfo.d.ts.map +1 -0
  93. package/lib/hooks/useSPFxLocaleInfo.js +109 -0
  94. package/lib/hooks/useSPFxLocaleInfo.js.map +1 -0
  95. package/lib/hooks/useSPFxLogger.d.ts +108 -0
  96. package/lib/hooks/useSPFxLogger.d.ts.map +1 -0
  97. package/lib/hooks/useSPFxLogger.js +117 -0
  98. package/lib/hooks/useSPFxLogger.js.map +1 -0
  99. package/lib/hooks/useSPFxMSGraphClient.d.ts +200 -0
  100. package/lib/hooks/useSPFxMSGraphClient.d.ts.map +1 -0
  101. package/lib/hooks/useSPFxMSGraphClient.js +264 -0
  102. package/lib/hooks/useSPFxMSGraphClient.js.map +1 -0
  103. package/lib/hooks/useSPFxOneDriveAppData.d.ts +264 -0
  104. package/lib/hooks/useSPFxOneDriveAppData.d.ts.map +1 -0
  105. package/lib/hooks/useSPFxOneDriveAppData.js +395 -0
  106. package/lib/hooks/useSPFxOneDriveAppData.js.map +1 -0
  107. package/lib/hooks/useSPFxPageContext.d.ts +37 -0
  108. package/lib/hooks/useSPFxPageContext.d.ts.map +1 -0
  109. package/lib/hooks/useSPFxPageContext.js +49 -0
  110. package/lib/hooks/useSPFxPageContext.js.map +1 -0
  111. package/lib/hooks/useSPFxPageType.d.ts +82 -0
  112. package/lib/hooks/useSPFxPageType.d.ts.map +1 -0
  113. package/lib/hooks/useSPFxPageType.js +137 -0
  114. package/lib/hooks/useSPFxPageType.js.map +1 -0
  115. package/lib/hooks/useSPFxPerformance.d.ts +72 -0
  116. package/lib/hooks/useSPFxPerformance.d.ts.map +1 -0
  117. package/lib/hooks/useSPFxPerformance.js +167 -0
  118. package/lib/hooks/useSPFxPerformance.js.map +1 -0
  119. package/lib/hooks/useSPFxPermissions.d.ts +61 -0
  120. package/lib/hooks/useSPFxPermissions.d.ts.map +1 -0
  121. package/lib/hooks/useSPFxPermissions.js +73 -0
  122. package/lib/hooks/useSPFxPermissions.js.map +1 -0
  123. package/lib/hooks/useSPFxPnP.d.ts +539 -0
  124. package/lib/hooks/useSPFxPnP.d.ts.map +1 -0
  125. package/lib/hooks/useSPFxPnP.js +533 -0
  126. package/lib/hooks/useSPFxPnP.js.map +1 -0
  127. package/lib/hooks/useSPFxPnPContext.d.ts +290 -0
  128. package/lib/hooks/useSPFxPnPContext.d.ts.map +1 -0
  129. package/lib/hooks/useSPFxPnPContext.js +340 -0
  130. package/lib/hooks/useSPFxPnPContext.js.map +1 -0
  131. package/lib/hooks/useSPFxPnPList.d.ts +545 -0
  132. package/lib/hooks/useSPFxPnPList.d.ts.map +1 -0
  133. package/lib/hooks/useSPFxPnPList.js +906 -0
  134. package/lib/hooks/useSPFxPnPList.js.map +1 -0
  135. package/lib/hooks/useSPFxPnPSearch.d.ts +540 -0
  136. package/lib/hooks/useSPFxPnPSearch.d.ts.map +1 -0
  137. package/lib/hooks/useSPFxPnPSearch.js +672 -0
  138. package/lib/hooks/useSPFxPnPSearch.js.map +1 -0
  139. package/lib/hooks/useSPFxProperties.d.ts +80 -0
  140. package/lib/hooks/useSPFxProperties.d.ts.map +1 -0
  141. package/lib/hooks/useSPFxProperties.js +95 -0
  142. package/lib/hooks/useSPFxProperties.js.map +1 -0
  143. package/lib/hooks/useSPFxSPHttpClient.d.ts +218 -0
  144. package/lib/hooks/useSPFxSPHttpClient.d.ts.map +1 -0
  145. package/lib/hooks/useSPFxSPHttpClient.js +287 -0
  146. package/lib/hooks/useSPFxSPHttpClient.js.map +1 -0
  147. package/lib/hooks/useSPFxServiceScope.d.ts +107 -0
  148. package/lib/hooks/useSPFxServiceScope.d.ts.map +1 -0
  149. package/lib/hooks/useSPFxServiceScope.js +105 -0
  150. package/lib/hooks/useSPFxServiceScope.js.map +1 -0
  151. package/lib/hooks/useSPFxSiteInfo.d.ts +116 -0
  152. package/lib/hooks/useSPFxSiteInfo.d.ts.map +1 -0
  153. package/lib/hooks/useSPFxSiteInfo.js +109 -0
  154. package/lib/hooks/useSPFxSiteInfo.js.map +1 -0
  155. package/lib/hooks/useSPFxStorage.d.ts +81 -0
  156. package/lib/hooks/useSPFxStorage.d.ts.map +1 -0
  157. package/lib/hooks/useSPFxStorage.js +140 -0
  158. package/lib/hooks/useSPFxStorage.js.map +1 -0
  159. package/lib/hooks/useSPFxTeams.d.ts +63 -0
  160. package/lib/hooks/useSPFxTeams.d.ts.map +1 -0
  161. package/lib/hooks/useSPFxTeams.js +198 -0
  162. package/lib/hooks/useSPFxTeams.js.map +1 -0
  163. package/lib/hooks/useSPFxTenantProperty.d.ts +389 -0
  164. package/lib/hooks/useSPFxTenantProperty.d.ts.map +1 -0
  165. package/lib/hooks/useSPFxTenantProperty.js +683 -0
  166. package/lib/hooks/useSPFxTenantProperty.js.map +1 -0
  167. package/lib/hooks/useSPFxThemeInfo.d.ts +27 -0
  168. package/lib/hooks/useSPFxThemeInfo.d.ts.map +1 -0
  169. package/lib/hooks/useSPFxThemeInfo.js +33 -0
  170. package/lib/hooks/useSPFxThemeInfo.js.map +1 -0
  171. package/lib/hooks/useSPFxUserInfo.d.ts +47 -0
  172. package/lib/hooks/useSPFxUserInfo.d.ts.map +1 -0
  173. package/lib/hooks/useSPFxUserInfo.js +47 -0
  174. package/lib/hooks/useSPFxUserInfo.js.map +1 -0
  175. package/lib/hooks/useSPFxUserPhoto.d.ts +270 -0
  176. package/lib/hooks/useSPFxUserPhoto.d.ts.map +1 -0
  177. package/lib/hooks/useSPFxUserPhoto.js +346 -0
  178. package/lib/hooks/useSPFxUserPhoto.js.map +1 -0
  179. package/lib/index.d.ts +3 -0
  180. package/lib/index.d.ts.map +1 -0
  181. package/lib/index.js +3 -0
  182. package/lib/index.js.map +1 -0
  183. package/lib/utils/index.d.ts +1 -0
  184. package/lib/utils/index.d.ts.map +1 -0
  185. package/lib/utils/index.js +3 -0
  186. package/lib/utils/index.js.map +1 -0
  187. package/lib/utils/resize-observer.internal.d.ts +10 -0
  188. package/lib/utils/resize-observer.internal.d.ts.map +1 -0
  189. package/lib/utils/resize-observer.internal.js +34 -0
  190. package/lib/utils/resize-observer.internal.js.map +1 -0
  191. package/lib/utils/theme-subscription.internal.d.ts +11 -0
  192. package/lib/utils/theme-subscription.internal.d.ts.map +1 -0
  193. package/lib/utils/theme-subscription.internal.js +58 -0
  194. package/lib/utils/theme-subscription.internal.js.map +1 -0
  195. package/lib/utils/type-guards.internal.d.ts +35 -0
  196. package/lib/utils/type-guards.internal.d.ts.map +1 -0
  197. package/lib/utils/type-guards.internal.js +88 -0
  198. package/lib/utils/type-guards.internal.js.map +1 -0
  199. package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.d.ts +13 -0
  200. package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.d.ts.map +1 -0
  201. package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js +67 -0
  202. package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.js.map +1 -0
  203. package/lib/webparts/spFxReactToolkitTest/SpFxReactToolkitTestWebPart.manifest.json +21 -0
  204. package/lib/webparts/spFxReactToolkitTest/assets/welcome-dark.png +0 -0
  205. package/lib/webparts/spFxReactToolkitTest/assets/welcome-light.png +0 -0
  206. package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.d.ts +8 -0
  207. package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.d.ts.map +1 -0
  208. package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.js +2 -0
  209. package/lib/webparts/spFxReactToolkitTest/components/ISpFxReactToolkitTestProps.js.map +1 -0
  210. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts +8 -0
  211. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.d.ts.map +1 -0
  212. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js +1351 -0
  213. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.js.map +1 -0
  214. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.css +2 -0
  215. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.d.ts +18 -0
  216. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.d.ts.map +1 -0
  217. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js +19 -0
  218. package/lib/webparts/spFxReactToolkitTest/components/SpFxReactToolkitTest.module.scss.js.map +1 -0
  219. package/lib/webparts/spFxReactToolkitTest/loc/en-us.js +16 -0
  220. package/package.json +95 -0
@@ -0,0 +1,73 @@
1
+ // useSPFxPermissions.ts
2
+ // Hook for SharePoint permissions checking
3
+ import { useCallback } from 'react';
4
+ import { useSPFxPageContext } from './useSPFxPageContext';
5
+ /**
6
+ * Hook for SharePoint permissions checking
7
+ *
8
+ * Provides access to current user's permissions at different scopes:
9
+ * - Site collection level
10
+ * - Web (subsite) level
11
+ * - List level (if applicable)
12
+ *
13
+ * Includes helper methods for permission checks using SPPermission enum.
14
+ *
15
+ * Common permissions to check:
16
+ * - SPPermission.manageWeb
17
+ * - SPPermission.addListItems
18
+ * - SPPermission.editListItems
19
+ * - SPPermission.deleteListItems
20
+ * - SPPermission.viewListItems
21
+ * - SPPermission.managePermissions
22
+ *
23
+ * Useful for:
24
+ * - Conditional UI rendering
25
+ * - Feature availability
26
+ * - Security trimming
27
+ * - Authorization checks
28
+ *
29
+ * @returns Permissions and helper methods
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * function MyComponent() {
34
+ * const { web, hasWebPermission } = useSPFxPermissions();
35
+ * const canManage = hasWebPermission(SPPermission.manageWeb);
36
+ *
37
+ * return (
38
+ * <div>
39
+ * {canManage && <button>Manage Settings</button>}
40
+ * <p>Can manage: {canManage ? 'Yes' : 'No'}</p>
41
+ * </div>
42
+ * );
43
+ * }
44
+ * ```
45
+ */
46
+ export function useSPFxPermissions() {
47
+ var _a, _b, _c;
48
+ var pageContext = useSPFxPageContext();
49
+ // Extract permissions from pageContext
50
+ var sitePermissions = (_a = pageContext.site) === null || _a === void 0 ? void 0 : _a.permissions;
51
+ var webPermissions = (_b = pageContext.web) === null || _b === void 0 ? void 0 : _b.permissions;
52
+ var listPermissions = (_c = pageContext.list) === null || _c === void 0 ? void 0 : _c.permissions;
53
+ // Helper to check permission
54
+ var has = useCallback(function (perms, permission) {
55
+ if (!perms) {
56
+ return false;
57
+ }
58
+ return perms.hasPermission(permission);
59
+ }, []);
60
+ // Specific helpers for each scope
61
+ var hasWebPermission = useCallback(function (permission) { return has(webPermissions, permission); }, [has, webPermissions]);
62
+ var hasSitePermission = useCallback(function (permission) { return has(sitePermissions, permission); }, [has, sitePermissions]);
63
+ var hasListPermission = useCallback(function (permission) { return has(listPermissions, permission); }, [has, listPermissions]);
64
+ return {
65
+ sitePermissions: sitePermissions,
66
+ webPermissions: webPermissions,
67
+ listPermissions: listPermissions,
68
+ hasWebPermission: hasWebPermission,
69
+ hasSitePermission: hasSitePermission,
70
+ hasListPermission: hasListPermission,
71
+ };
72
+ }
73
+ //# sourceMappingURL=useSPFxPermissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSPFxPermissions.js","sourceRoot":"","sources":["../../src/hooks/useSPFxPermissions.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,2CAA2C;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAyB1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,UAAU,kBAAkB;;IAChC,IAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;IAEzC,uCAAuC;IACvC,IAAM,eAAe,GAAG,MAAC,WAAW,CAAC,IAAkD,0CAAE,WAAW,CAAC;IACrG,IAAM,cAAc,GAAG,MAAC,WAAW,CAAC,GAAiD,0CAAE,WAAW,CAAC;IACnG,IAAM,eAAe,GAAG,MAAC,WAAW,CAAC,IAAkD,0CAAE,WAAW,CAAC;IAErG,6BAA6B;IAC7B,IAAM,GAAG,GAAG,WAAW,CACrB,UAAC,KAA+B,EAAE,UAAwB;QACxD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC,EACD,EAAE,CACH,CAAC;IAEF,kCAAkC;IAClC,IAAM,gBAAgB,GAAG,WAAW,CAClC,UAAC,UAAwB,IAAc,OAAA,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,EAA/B,CAA+B,EACtE,CAAC,GAAG,EAAE,cAAc,CAAC,CACtB,CAAC;IAEF,IAAM,iBAAiB,GAAG,WAAW,CACnC,UAAC,UAAwB,IAAc,OAAA,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,EAAhC,CAAgC,EACvE,CAAC,GAAG,EAAE,eAAe,CAAC,CACvB,CAAC;IAEF,IAAM,iBAAiB,GAAG,WAAW,CACnC,UAAC,UAAwB,IAAc,OAAA,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,EAAhC,CAAgC,EACvE,CAAC,GAAG,EAAE,eAAe,CAAC,CACvB,CAAC;IAEF,OAAO;QACL,eAAe,iBAAA;QACf,cAAc,gBAAA;QACd,eAAe,iBAAA;QACf,gBAAgB,kBAAA;QAChB,iBAAiB,mBAAA;QACjB,iBAAiB,mBAAA;KAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,539 @@
1
+ import type { SPFI } from '@pnp/sp';
2
+ import { PnPContextInfo } from './useSPFxPnPContext';
3
+ /**
4
+ * Return type for useSPFxPnP hook
5
+ */
6
+ export interface SPFxPnPInfo {
7
+ /**
8
+ * Configured SPFI instance for direct access.
9
+ * Undefined if initialization failed.
10
+ *
11
+ * Use this for advanced scenarios or when you need full control:
12
+ * ```tsx
13
+ * const { sp } = useSPFxPnP();
14
+ * const [batchedSP, execute] = sp.batched();
15
+ * // manual batch control
16
+ * ```
17
+ */
18
+ readonly sp: SPFI | undefined;
19
+ /**
20
+ * Execute single PnPjs operation with automatic state management.
21
+ * Tracks loading state and captures errors automatically.
22
+ * Does NOT track errors from direct sp usage.
23
+ *
24
+ * @param fn - Function that receives SPFI instance and returns a promise
25
+ * @returns Promise with the result
26
+ *
27
+ * @example Basic list query
28
+ * ```tsx
29
+ * const { invoke } = useSPFxPnP();
30
+ *
31
+ * const lists = await invoke(sp => sp.web.lists());
32
+ * ```
33
+ *
34
+ * @example With OData query
35
+ * ```tsx
36
+ * import '@pnp/sp/lists';
37
+ * import '@pnp/sp/items';
38
+ *
39
+ * const items = await invoke(sp =>
40
+ * sp.web.lists
41
+ * .getByTitle('Tasks')
42
+ * .items
43
+ * .select('Id', 'Title', 'Status')
44
+ * .filter("Status eq 'Active'")
45
+ * .orderBy('Created', false)
46
+ * .top(50)()
47
+ * );
48
+ * ```
49
+ */
50
+ readonly invoke: <T>(fn: (sp: SPFI) => Promise<T>) => Promise<T>;
51
+ /**
52
+ * Execute multiple PnPjs operations in a single batch request.
53
+ * Automatically handles batch execution and state management.
54
+ *
55
+ * Batching reduces network roundtrips by combining multiple operations
56
+ * into a single HTTP request to SharePoint.
57
+ *
58
+ * @param fn - Function that receives batched SPFI instance and returns a promise
59
+ * @returns Promise with the result
60
+ *
61
+ * @example Load multiple resources in one request
62
+ * ```tsx
63
+ * import '@pnp/sp/lists';
64
+ * import '@pnp/sp/items';
65
+ *
66
+ * const { batch } = useSPFxPnP();
67
+ *
68
+ * const [lists, user, tasks] = await batch(async (batchedSP) => {
69
+ * const lists = batchedSP.web.lists();
70
+ * const user = batchedSP.web.currentUser();
71
+ * const tasks = batchedSP.web.lists.getByTitle('Tasks').items.top(10)();
72
+ *
73
+ * return Promise.all([lists, user, tasks]);
74
+ * });
75
+ * ```
76
+ *
77
+ * @example Dashboard with multiple lists
78
+ * ```tsx
79
+ * const results = await batch(async (batchedSP) => {
80
+ * const announcements = batchedSP.web.lists.getByTitle('Announcements').items.top(5)();
81
+ * const events = batchedSP.web.lists.getByTitle('Events').items.top(10)();
82
+ * const tasks = batchedSP.web.lists.getByTitle('Tasks').items.top(20)();
83
+ *
84
+ * return Promise.all([announcements, events, tasks]);
85
+ * });
86
+ *
87
+ * const [announcements, events, tasks] = results;
88
+ * ```
89
+ */
90
+ readonly batch: <T>(fn: (batchedSP: SPFI) => Promise<T>) => Promise<T>;
91
+ /**
92
+ * Loading state - true during invoke() or batch() calls.
93
+ * Does not track direct sp usage.
94
+ *
95
+ * Shared between invoke and batch operations.
96
+ */
97
+ readonly isLoading: boolean;
98
+ /**
99
+ * Last error from invoke() or batch() calls, or initialization error from context.
100
+ * Does not capture errors from direct sp usage.
101
+ *
102
+ * Priority: invoke/batch errors take precedence over context initialization errors.
103
+ */
104
+ readonly error: Error | undefined;
105
+ /**
106
+ * Clear the current error state.
107
+ * Useful for retry patterns in UI.
108
+ *
109
+ * @example Retry pattern
110
+ * ```tsx
111
+ * const { invoke, error, clearError, isLoading } = useSPFxPnP();
112
+ * const [data, setData] = useState(null);
113
+ *
114
+ * const loadData = async () => {
115
+ * try {
116
+ * const items = await invoke(sp => sp.web.lists.getByTitle('Tasks').items());
117
+ * setData(items);
118
+ * } catch (err) {
119
+ * // Error already tracked in state
120
+ * }
121
+ * };
122
+ *
123
+ * if (error) {
124
+ * return (
125
+ * <MessageBar messageBarType={MessageBarType.error}>
126
+ * {error.message}
127
+ * <Link onClick={() => { clearError(); loadData(); }}>
128
+ * Retry
129
+ * </Link>
130
+ * </MessageBar>
131
+ * );
132
+ * }
133
+ * ```
134
+ */
135
+ readonly clearError: () => void;
136
+ /**
137
+ * True if sp instance is successfully initialized and ready to use.
138
+ * False if initialization failed or context error occurred.
139
+ */
140
+ readonly isInitialized: boolean;
141
+ /**
142
+ * Effective site URL being used.
143
+ * Resolved from context or current site.
144
+ */
145
+ readonly siteUrl: string;
146
+ }
147
+ /**
148
+ * Hook to access PnPjs with built-in state management and batching support
149
+ *
150
+ * Provides convenient wrappers around PnPjs SPFI instance with automatic
151
+ * loading and error state tracking. Offers three usage patterns:
152
+ *
153
+ * 1. **invoke()** - Single operations with automatic state management
154
+ * 2. **batch()** - Multiple operations in one request with state management
155
+ * 3. **sp** - Direct access for full control (advanced scenarios)
156
+ *
157
+ * This hook wraps the SPFI instance from useSPFxPnPContext and adds
158
+ * React state management for common patterns.
159
+ *
160
+ * **Selective Imports Required**:
161
+ * This hook provides access to the base PnPjs instance with minimal imports.
162
+ * To use specific PnP modules, import them in your code:
163
+ *
164
+ * ```typescript
165
+ * // For lists and items
166
+ * import '@pnp/sp/lists';
167
+ * import '@pnp/sp/items';
168
+ *
169
+ * // For files and folders
170
+ * import '@pnp/sp/files';
171
+ * import '@pnp/sp/folders';
172
+ *
173
+ * // For search
174
+ * import '@pnp/sp/search';
175
+ *
176
+ * // For user profiles
177
+ * import '@pnp/sp/profiles';
178
+ *
179
+ * // For taxonomy (managed metadata)
180
+ * import '@pnp/sp/taxonomy';
181
+ *
182
+ * // For site users and groups
183
+ * import '@pnp/sp/site-users';
184
+ * import '@pnp/sp/site-groups';
185
+ * ```
186
+ *
187
+ * This approach enables optimal tree-shaking and keeps bundle size minimal.
188
+ *
189
+ * @param pnpContext - Optional PnPContextInfo from useSPFxPnPContext.
190
+ * If not provided, creates default context for current site.
191
+ *
192
+ * @returns SPFxPnPInfo object with sp, invoke, batch, and state management
193
+ *
194
+ * @example Current site with invoke
195
+ * ```tsx
196
+ * import '@pnp/sp/lists';
197
+ *
198
+ * function ListsViewer() {
199
+ * const { invoke, isLoading, error } = useSPFxPnP();
200
+ * const [lists, setLists] = useState([]);
201
+ *
202
+ * useEffect(() => {
203
+ * invoke(sp => sp.web.lists()).then(setLists);
204
+ * }, []);
205
+ *
206
+ * if (isLoading) return <Spinner />;
207
+ * if (error) return <MessageBar messageBarType={MessageBarType.error}>
208
+ * {error.message}
209
+ * </MessageBar>;
210
+ *
211
+ * return <DetailsList items={lists} />;
212
+ * }
213
+ * ```
214
+ *
215
+ * @example Cross-site with context injection
216
+ * ```tsx
217
+ * import '@pnp/sp/lists';
218
+ * import '@pnp/sp/items';
219
+ *
220
+ * function HRDashboard() {
221
+ * // Create context for HR site
222
+ * const hrContext = useSPFxPnPContext('/sites/hr');
223
+ * const { invoke, isLoading, error } = useSPFxPnP(hrContext);
224
+ *
225
+ * const [employees, setEmployees] = useState([]);
226
+ *
227
+ * const loadEmployees = async () => {
228
+ * const items = await invoke(sp =>
229
+ * sp.web.lists
230
+ * .getByTitle('Employees')
231
+ * .items
232
+ * .select('Id', 'Title', 'Department')
233
+ * .top(100)()
234
+ * );
235
+ * setEmployees(items);
236
+ * };
237
+ *
238
+ * if (error) return <MessageBar>{error.message}</MessageBar>;
239
+ *
240
+ * return (
241
+ * <div>
242
+ * <button onClick={loadEmployees} disabled={isLoading}>
243
+ * {isLoading ? 'Loading...' : 'Load Employees'}
244
+ * </button>
245
+ * <DetailsList items={employees} />
246
+ * </div>
247
+ * );
248
+ * }
249
+ * ```
250
+ *
251
+ * @example With caching configuration
252
+ * ```tsx
253
+ * function CachedDataViewer() {
254
+ * // Create context with caching enabled
255
+ * const context = useSPFxPnPContext(undefined, {
256
+ * cache: {
257
+ * enabled: true,
258
+ * storage: 'session',
259
+ * timeout: 600000 // 10 minutes
260
+ * }
261
+ * });
262
+ *
263
+ * const { invoke } = useSPFxPnP(context);
264
+ *
265
+ * // Subsequent calls within 10 minutes use cached data
266
+ * const lists = await invoke(sp => sp.web.lists());
267
+ * }
268
+ * ```
269
+ *
270
+ * @example Batch operations for dashboard
271
+ * ```tsx
272
+ * import '@pnp/sp/lists';
273
+ * import '@pnp/sp/items';
274
+ *
275
+ * function Dashboard() {
276
+ * const { batch, isLoading, error } = useSPFxPnP();
277
+ * const [data, setData] = useState(null);
278
+ *
279
+ * const loadDashboard = async () => {
280
+ * // All operations in ONE HTTP request
281
+ * const [user, tasks, announcements, events] = await batch(async (batchedSP) => {
282
+ * const user = batchedSP.web.currentUser();
283
+ * const tasks = batchedSP.web.lists.getByTitle('Tasks').items.top(10)();
284
+ * const announcements = batchedSP.web.lists.getByTitle('Announcements').items.top(5)();
285
+ * const events = batchedSP.web.lists.getByTitle('Events').items.top(10)();
286
+ *
287
+ * return Promise.all([user, tasks, announcements, events]);
288
+ * });
289
+ *
290
+ * setData({ user, tasks, announcements, events });
291
+ * };
292
+ *
293
+ * useEffect(() => { loadDashboard(); }, []);
294
+ *
295
+ * if (isLoading) return <Spinner label="Loading dashboard..." />;
296
+ * if (error) return <MessageBar messageBarType={MessageBarType.error}>
297
+ * Failed to load dashboard: {error.message}
298
+ * </MessageBar>;
299
+ *
300
+ * return (
301
+ * <Stack tokens={{ childrenGap: 20 }}>
302
+ * <Text variant="xLarge">Welcome, {data?.user?.Title}</Text>
303
+ * <TasksSection items={data?.tasks} />
304
+ * <AnnouncementsSection items={data?.announcements} />
305
+ * <EventsSection items={data?.events} />
306
+ * </Stack>
307
+ * );
308
+ * }
309
+ * ```
310
+ *
311
+ * @example Multi-site dashboard
312
+ * ```tsx
313
+ * function MultiSiteDashboard() {
314
+ * const hrContext = useSPFxPnPContext('/sites/hr');
315
+ * const financeContext = useSPFxPnPContext('/sites/finance');
316
+ *
317
+ * const { invoke: hrInvoke, isLoading: hrLoading } = useSPFxPnP(hrContext);
318
+ * const { invoke: financeInvoke, isLoading: financeLoading } = useSPFxPnP(financeContext);
319
+ *
320
+ * const [hrData, setHrData] = useState([]);
321
+ * const [financeData, setFinanceData] = useState([]);
322
+ *
323
+ * useEffect(() => {
324
+ * hrInvoke(sp => sp.web.lists.getByTitle('Employees').items.top(10)())
325
+ * .then(setHrData);
326
+ *
327
+ * financeInvoke(sp => sp.web.lists.getByTitle('Invoices').items.top(10)())
328
+ * .then(setFinanceData);
329
+ * }, []);
330
+ *
331
+ * return (
332
+ * <Stack tokens={{ childrenGap: 20 }}>
333
+ * <Section title="HR" loading={hrLoading}>
334
+ * <DetailsList items={hrData} />
335
+ * </Section>
336
+ * <Section title="Finance" loading={financeLoading}>
337
+ * <DetailsList items={financeData} />
338
+ * </Section>
339
+ * </Stack>
340
+ * );
341
+ * }
342
+ * ```
343
+ *
344
+ * @example Direct sp access for advanced control
345
+ * ```tsx
346
+ * function AdvancedBatchingComponent() {
347
+ * const { sp, isLoading, error } = useSPFxPnP();
348
+ * const [data, setData] = useState(null);
349
+ * const [customLoading, setCustomLoading] = useState(false);
350
+ *
351
+ * if (!sp) return <Spinner label="Initializing..." />;
352
+ *
353
+ * const loadWithCustomBatch = async () => {
354
+ * setCustomLoading(true);
355
+ * try {
356
+ * // Manual batch control
357
+ * const [batchedSP, execute] = sp.batched();
358
+ *
359
+ * const promise1 = batchedSP.web.lists();
360
+ * const promise2 = batchedSP.web.currentUser();
361
+ *
362
+ * // Execute when ready
363
+ * await execute();
364
+ *
365
+ * const [lists, user] = await Promise.all([promise1, promise2]);
366
+ * setData({ lists, user });
367
+ * } finally {
368
+ * setCustomLoading(false);
369
+ * }
370
+ * };
371
+ *
372
+ * return (
373
+ * <button onClick={loadWithCustomBatch} disabled={customLoading}>
374
+ * {customLoading ? 'Loading...' : 'Load Data'}
375
+ * </button>
376
+ * );
377
+ * }
378
+ * ```
379
+ *
380
+ * @example Combining invoke and batch
381
+ * ```tsx
382
+ * function MixedOperationsComponent() {
383
+ * const { invoke, batch, isLoading } = useSPFxPnP();
384
+ * const [lists, setLists] = useState([]);
385
+ * const [dashboardData, setDashboardData] = useState(null);
386
+ *
387
+ * // Single operation with invoke
388
+ * const loadLists = async () => {
389
+ * const data = await invoke(sp => sp.web.lists());
390
+ * setLists(data);
391
+ * };
392
+ *
393
+ * // Multiple operations with batch
394
+ * const loadDashboard = async () => {
395
+ * const data = await batch(async (batchedSP) => {
396
+ * const tasks = batchedSP.web.lists.getByTitle('Tasks').items.top(10)();
397
+ * const events = batchedSP.web.lists.getByTitle('Events').items.top(10)();
398
+ * return Promise.all([tasks, events]);
399
+ * });
400
+ * setDashboardData(data);
401
+ * };
402
+ *
403
+ * return (
404
+ * <Stack>
405
+ * <button onClick={loadLists} disabled={isLoading}>Load Lists</button>
406
+ * <button onClick={loadDashboard} disabled={isLoading}>Load Dashboard</button>
407
+ * </Stack>
408
+ * );
409
+ * }
410
+ * ```
411
+ *
412
+ * @example Error handling with retry
413
+ * ```tsx
414
+ * function RobustDataLoader() {
415
+ * const { invoke, error, clearError, isLoading } = useSPFxPnP();
416
+ * const [items, setItems] = useState([]);
417
+ * const [retryCount, setRetryCount] = useState(0);
418
+ *
419
+ * const loadItems = async () => {
420
+ * try {
421
+ * const data = await invoke(sp =>
422
+ * sp.web.lists.getByTitle('Tasks').items()
423
+ * );
424
+ * setItems(data);
425
+ * setRetryCount(0); // Reset on success
426
+ * } catch (err) {
427
+ * console.error('Failed to load items:', err);
428
+ * // Error already in state
429
+ * }
430
+ * };
431
+ *
432
+ * const handleRetry = () => {
433
+ * clearError();
434
+ * setRetryCount(prev => prev + 1);
435
+ * loadItems();
436
+ * };
437
+ *
438
+ * useEffect(() => { loadItems(); }, []);
439
+ *
440
+ * if (error) {
441
+ * return (
442
+ * <MessageBar
443
+ * messageBarType={MessageBarType.error}
444
+ * actions={
445
+ * <MessageBarButton onClick={handleRetry}>
446
+ * Retry {retryCount > 0 && `(${retryCount})`}
447
+ * </MessageBarButton>
448
+ * }
449
+ * >
450
+ * {error.message}
451
+ * </MessageBar>
452
+ * );
453
+ * }
454
+ *
455
+ * if (isLoading) {
456
+ * return <Spinner label="Loading items..." />;
457
+ * }
458
+ *
459
+ * return <DetailsList items={items} />;
460
+ * }
461
+ * ```
462
+ *
463
+ * @example Loading states best practices
464
+ * ```tsx
465
+ * function OptimizedLoadingStates() {
466
+ * const { invoke, isLoading, error, isInitialized } = useSPFxPnP();
467
+ * const [items, setItems] = useState([]);
468
+ * const [hasLoaded, setHasLoaded] = useState(false);
469
+ *
470
+ * useEffect(() => {
471
+ * if (isInitialized) {
472
+ * invoke(sp => sp.web.lists.getByTitle('Tasks').items())
473
+ * .then(data => {
474
+ * setItems(data);
475
+ * setHasLoaded(true);
476
+ * });
477
+ * }
478
+ * }, [isInitialized]);
479
+ *
480
+ * // Initial loading (no data yet)
481
+ * if (!hasLoaded && isLoading) {
482
+ * return <Spinner label="Loading tasks..." />;
483
+ * }
484
+ *
485
+ * // Initialization failed
486
+ * if (!isInitialized && error) {
487
+ * return <MessageBar messageBarType={MessageBarType.error}>
488
+ * Failed to initialize: {error.message}
489
+ * </MessageBar>;
490
+ * }
491
+ *
492
+ * // Data error
493
+ * if (error) {
494
+ * return <MessageBar messageBarType={MessageBarType.error}>
495
+ * {error.message}
496
+ * </MessageBar>;
497
+ * }
498
+ *
499
+ * // Refreshing (show data with shimmer)
500
+ * if (hasLoaded && isLoading) {
501
+ * return (
502
+ * <div style={{ position: 'relative' }}>
503
+ * <Shimmer />
504
+ * <DetailsList items={items} />
505
+ * </div>
506
+ * );
507
+ * }
508
+ *
509
+ * // Success
510
+ * return <DetailsList items={items} />;
511
+ * }
512
+ * ```
513
+ *
514
+ * @remarks
515
+ * **State Management**:
516
+ * - `isLoading` is shared between invoke() and batch() operations
517
+ * - `error` prioritizes invoke/batch errors over context initialization errors
518
+ * - Direct `sp` usage does not update isLoading or error states
519
+ *
520
+ * **Performance**:
521
+ * - invoke() and batch() are memoized with useCallback
522
+ * - Reuses SPFI instance from context (no re-initialization)
523
+ * - Batching reduces network roundtrips significantly
524
+ *
525
+ * **Cross-Site Operations**:
526
+ * - Pass PnPContextInfo from useSPFxPnPContext for different sites
527
+ * - Each context maintains separate configuration (cache, headers, etc.)
528
+ * - Requires appropriate permissions on target sites
529
+ *
530
+ * **Tree-Shaking**:
531
+ * - This hook imports no additional PnP modules
532
+ * - User-side selective imports enable optimal bundle size
533
+ * - Only import what you actually use
534
+ *
535
+ * @see {@link useSPFxPnPContext} for creating configured SPFI instances
536
+ * @see {@link useSPFxPnPList} for specialized list operations
537
+ */
538
+ export declare function useSPFxPnP(pnpContext?: PnPContextInfo): SPFxPnPInfo;
539
+ //# sourceMappingURL=useSPFxPnP.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSPFxPnP.d.ts","sourceRoot":"","sources":["../../src/hooks/useSPFxPnP.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAqB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,EAAE,IAAI,GAAG,SAAS,CAAC;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAEvE;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAEhC;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsYG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,cAAc,GAAG,WAAW,CAoGnE"}