@lindle/sharepoint_requests 0.1.12 → 0.1.13

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 (37) hide show
  1. package/dist/root/index.d.ts +16 -217
  2. package/dist/root/internal/context.d.ts +9 -0
  3. package/dist/root/internal/digest.d.ts +2 -0
  4. package/dist/root/internal/emailRequests.d.ts +10 -0
  5. package/dist/root/internal/listRequests/createAttachment.d.ts +3 -0
  6. package/dist/root/internal/listRequests/createListItem.d.ts +3 -0
  7. package/dist/root/internal/listRequests/deleteItem.d.ts +3 -0
  8. package/dist/root/internal/listRequests/getFiles.d.ts +8 -0
  9. package/dist/root/internal/listRequests/getListItems.d.ts +8 -0
  10. package/dist/root/internal/listRequests/getOnly.d.ts +3 -0
  11. package/dist/root/internal/listRequests/index.d.ts +7 -0
  12. package/dist/root/internal/listRequests/updateListItem.d.ts +3 -0
  13. package/dist/root/internal/odata.d.ts +5 -0
  14. package/dist/root/internal/userRequests.d.ts +15 -0
  15. package/dist/sharepoint_requests.cjs.development.js +597 -756
  16. package/dist/sharepoint_requests.cjs.development.js.map +1 -1
  17. package/dist/sharepoint_requests.cjs.production.min.js +1 -1
  18. package/dist/sharepoint_requests.cjs.production.min.js.map +1 -1
  19. package/dist/sharepoint_requests.esm.js +597 -756
  20. package/dist/sharepoint_requests.esm.js.map +1 -1
  21. package/dist/types.d.ts +38 -7
  22. package/package.json +1 -1
  23. package/src/root/index.ts +194 -598
  24. package/src/root/internal/context.ts +10 -0
  25. package/src/root/internal/digest.ts +22 -0
  26. package/src/root/internal/emailRequests.ts +45 -0
  27. package/src/root/internal/listRequests/createAttachment.ts +18 -0
  28. package/src/root/internal/listRequests/createListItem.ts +36 -0
  29. package/src/root/internal/listRequests/deleteItem.ts +10 -0
  30. package/src/root/internal/listRequests/getFiles.ts +31 -0
  31. package/src/root/internal/listRequests/getListItems.ts +50 -0
  32. package/src/root/internal/listRequests/getOnly.ts +18 -0
  33. package/src/root/internal/listRequests/index.ts +7 -0
  34. package/src/root/internal/listRequests/updateListItem.ts +32 -0
  35. package/src/root/internal/odata.ts +36 -0
  36. package/src/root/internal/userRequests.ts +109 -0
  37. package/src/types.ts +76 -36
package/src/root/index.ts CHANGED
@@ -1,605 +1,201 @@
1
+ import { AxiosInstance, CreateAxiosDefaults as AxiosConfig } from 'axios';
2
+ import instance from './instance';
1
3
  import {
2
- AxiosInstance,
3
- AxiosResponse,
4
- CreateAxiosDefaults as AxiosConfig,
5
- } from 'axios';
6
- import instance from './instance';
7
- import {
8
- CreateFileProps,
9
- CurrentUser,
10
- EmailProps,
11
- Field_Options,
12
- Folder_Options,
13
- IListName,
14
- ItemID,
15
- ListData,
16
- Options,
17
- PersonField,
18
- SHAREPOINT_VER,
19
- SPItem,
20
- UserPermision,
21
- UserProfile,
22
- } from '../types';
23
-
24
- class HTTPSharePointRequests<
25
- T extends { LISTS: Record<string, any>; FOLDERS?: Record<string, any> }
26
- > {
27
- private baseURL: string;
28
- private endpoint: string;
29
- private listName: string;
30
- private instance: AxiosInstance;
31
-
32
- /**
33
- * Creates an HTTP SharePoint requester bound to the provided base URL.
34
- *
35
- * @param baseURL The root SharePoint site URL (with or without trailing slash).
36
- * @param config Optional axios configuration overrides.
37
- */
4
+ CreateFileProps,
5
+ CurrentUser,
6
+ EmailProps,
7
+ Field_Options,
8
+ Folder_Options,
9
+ IListName,
10
+ ItemID,
11
+ ListData,
12
+ Options,
13
+ PersonField,
14
+ SHAREPOINT_VER,
15
+ UserPermision,
16
+ UserProfile,
17
+ } from '../types';
18
+ import { RequestContext } from './internal/context';
19
+ import {
20
+ createAttachment,
21
+ createListItem,
22
+ deleteItem,
23
+ getFiles,
24
+ getListItems,
25
+ getOnly,
26
+ updateListItem,
27
+ } from './internal/listRequests';
28
+ import { sendEmail as sendEmailRequest } from './internal/emailRequests';
29
+ import {
30
+ currentUserPermissions as resolveCurrentUserPermissions,
31
+ currentUserProperties as loadCurrentUserProperties,
32
+ getSiteUser as fetchSiteUser,
33
+ typeAhead,
34
+ } from './internal/userRequests';
35
+
36
+ class HTTPSharePointRequests<
37
+ T extends {
38
+ LISTS: Record<string, unknown>;
39
+ FOLDERS?: Record<string, unknown>;
40
+ }
41
+ > {
42
+ private baseURL: string;
43
+ private endpoint: string;
44
+ private listName: string;
45
+ private instance: AxiosInstance;
46
+ private sharepointVersion: SHAREPOINT_VER;
47
+
38
48
  constructor(baseURL: string, config?: AxiosConfig) {
39
49
  this.baseURL = baseURL.endsWith('/') ? baseURL : `${baseURL}/`;
40
50
  this.endpoint = '/api';
41
51
  this.listName = '';
42
-
43
52
  this.instance = instance(this.baseURL, config);
53
+ this.sharepointVersion = '2013';
54
+ }
55
+
56
+ private getContext<V extends SHAREPOINT_VER = '2013'>(): RequestContext<V> {
57
+ return {
58
+ instance: this.instance,
59
+ baseURL: this.baseURL,
60
+ endpoint: this.endpoint,
61
+ listName: this.listName,
62
+ sharepointVersion: this.sharepointVersion as V,
63
+ };
64
+ }
65
+
66
+ /**
67
+ * @deprecated Use `from` instead.
68
+ */
69
+ list(listName: IListName<T>) {
70
+ this.listName = listName;
71
+ this.endpoint = `_vti_bin/ListData.svc/${listName}`;
72
+ this.sharepointVersion = '2010';
73
+ return this;
74
+ }
75
+
76
+ public readonly lists = {
77
+ get: () => {
78
+ this.endpoint = '_api/web/lists';
79
+ this.sharepointVersion = '2013';
80
+ return getListItems(this.getContext());
81
+ },
82
+ };
83
+
84
+ from<
85
+ K extends Extract<keyof T['LISTS'], string>,
86
+ V extends SHAREPOINT_VER = '2013'
87
+ >(listName: K, sharepoint_ver?: V) {
88
+ const version = (sharepoint_ver ?? '2013') as V;
89
+
90
+ this.listName = listName;
91
+ this.sharepointVersion = version;
92
+ this.endpoint =
93
+ version === '2013'
94
+ ? `_api/web/lists/GetByTitle('${this.listName}')/items`
95
+ : `_vti_bin/ListData.svc/${listName}`;
96
+
97
+ const getContext = () => this.getContext<V>();
98
+
99
+ return {
100
+ create: (data: ListData) => createListItem(getContext(), data),
101
+ get: (options?: Options<T['LISTS'][K], V>) =>
102
+ getListItems<T['LISTS'][K], V>(getContext(), options),
103
+ update: (id: ItemID, data: ListData, digest?: string) =>
104
+ updateListItem(getContext(), id, data, digest),
105
+ delete: (id: ItemID) => deleteItem(getContext(), id),
106
+ createFile: (props: CreateFileProps) =>
107
+ createAttachment(getContext(), props),
108
+ fields: (options?: Field_Options<T['LISTS'][K], V>) => {
109
+ this.endpoint = !options?.fieldName
110
+ ? `_api/web/lists/GetByTitle('${this.listName}')/fields`
111
+ : `_api/web/lists/GetByTitle('${this.listName}')/fields/getbytitle('${options.fieldName}')`;
112
+ return {
113
+ get: () => getOnly<T['LISTS'][K], V>(this.instance, this.endpoint, options),
114
+ };
115
+ },
116
+ };
117
+ }
118
+
119
+ public folders = {
120
+ get: () => {
121
+ this.endpoint = '_api/web/folders';
122
+ this.sharepointVersion = '2013';
123
+ getListItems(this.getContext());
124
+ },
125
+ };
126
+
127
+ public folder(folderName?: string | string[]) {
128
+ let filePath = ['Shared Documents'];
129
+
130
+ if (folderName) {
131
+ filePath = Array.isArray(folderName)
132
+ ? [...filePath, ...folderName]
133
+ : [...filePath, folderName];
134
+ }
135
+
136
+ this.endpoint = `_api/web/GetFolderByServerRelativeUrl('${filePath.join(
137
+ '/'
138
+ )}')`;
139
+ this.sharepointVersion = '2013';
140
+
141
+ const getContext = () => this.getContext();
142
+
143
+ return {
144
+ get: (options?: Folder_Options<any>) => {
145
+ if (!options?.type) {
146
+ this.endpoint += '/Files';
147
+ } else {
148
+ this.endpoint += `/${options.type}`;
149
+ }
150
+ return getFiles(getContext(), options);
151
+ },
152
+ };
153
+ }
154
+
155
+ public users(options?: Options<any>) {
156
+ this.endpoint = '_api/web/SiteUserInfoList/items';
157
+ this.sharepointVersion = '2013';
158
+ return {
159
+ get: () => getListItems(this.getContext(), options),
160
+ };
44
161
  }
45
-
46
- /**
47
- * Converts array values in a payload to the `Collection(Edm.String)` structure
48
- * expected by SharePoint REST endpoints.
49
- *
50
- * @param data The list item payload to harmonise in-place.
51
- */
52
- private transformArraysToEdmStrings(data: ListData) {
53
- for (const key in data) {
54
- if (Array.isArray(data[key])) {
55
- data[key] = {
56
- __metadata: { type: 'Collection(Edm.String)' },
57
- results: data[key],
58
- };
59
- }
60
- }
61
- }
62
-
63
- /**
64
- * @deprecated Use `from` instead.
65
- */
66
- list(listName: IListName<T>) {
67
- this.listName = listName;
68
- this.endpoint = `_vti_bin/ListData.svc/${listName}`;
69
- return this;
70
- }
71
- public readonly lists = {
72
- /**
73
- * Fetches all SharePoint lists available to the current site.
74
- *
75
- * @returns Promise resolving to the list collection response payload.
76
- */
77
- get: () => {
78
- this.endpoint = '_api/web/lists';
79
- return this.get_v2();
80
- },
81
- };
82
-
83
- /**
84
- * Selects a SharePoint list and exposes list-scoped CRUD helpers.
85
- *
86
- * @param listName Logical list key configured in the generic type map.
87
- * @param sharepoint_ver SharePoint version used to choose the correct REST endpoint.
88
- * @returns Chainable helpers bound to the selected list.
89
- */
90
- from<K extends Extract<keyof T['LISTS'], string>>(
91
- listName: K,
92
- sharepoint_ver: SHAREPOINT_VER = '2013'
93
- ) {
94
- this.listName = listName;
95
- this.endpoint =
96
- sharepoint_ver === '2013'
97
- ? `_api/web/lists/GetByTitle('${this.listName}')/items`
98
- : `_vti_bin/ListData.svc/${listName}`;
99
- return {
100
- create: (data: ListData) => this.create_v2(data),
101
- get: (options?: Options<T['LISTS'][K]>) =>
102
- this.get_v2<T['LISTS'][K]>(options),
103
- update: (id: ItemID, data: ListData, digest?: string) =>
104
- this.update_2(id, data, digest),
105
- delete: (id: ItemID) => this.delete(id),
106
- createFile: (props: CreateFileProps) => this.createFile(props),
107
- fields: (options?: Field_Options<T['LISTS'][K]>) => {
108
- // return this.field_v2(options)
109
- this.endpoint = !options?.fieldName
110
- ? `_api/web/lists/GetByTitle('${this.listName}')/fields`
111
- : `_api/web/lists/GetByTitle('${this.listName}')/fields/getbytitle('${options.fieldName}')`;
112
- return {
113
- get: () => this.get_only(options),
114
- };
115
- },
116
- };
117
- }
118
-
119
- public folders = {
120
- /**
121
- * Retrieves SharePoint folders from the default folders endpoint.
122
- *
123
- * @returns A promise resolving with folder metadata.
124
- */
125
- get: () => {
126
- this.endpoint = '_api/web/folders';
127
- this.get_v2();
128
- },
129
- };
130
-
131
- /**
132
- * Targets a SharePoint folder path and exposes file retrieval helpers.
133
- *
134
- * @param folderName Optional folder path relative to `Shared Documents`.
135
- * @returns Helper exposing `get` to fetch files or sub-folders.
136
- */
137
- public folder(folderName?: string | string[]) {
138
- let filePath = ['Shared Documents'];
139
-
140
- if (folderName) {
141
- filePath = Array.isArray(folderName)
142
- ? [...filePath, ...folderName]
143
- : [...filePath, folderName];
144
- }
145
- this.endpoint = `_api/web/GetFolderByServerRelativeUrl('${filePath.join(
146
- '/'
147
- )}')`;
148
- return {
149
- /**
150
- * Fetches files or folders from the targeted path.
151
- *
152
- * @param options Optional REST query options to refine the result set.
153
- * @returns Promise resolving to folder contents and metadata.
154
- */
155
- get: (options?: Folder_Options<any>) => {
156
- if (!options?.type) {
157
- this.endpoint += '/Files';
158
- } else {
159
- this.endpoint += `/${options.type}`;
160
- }
161
-
162
- return this.get_files(options);
163
- },
164
- };
165
- }
166
-
167
- /**
168
- * Retrieves user list items and exposes a get helper with optional query parameters.
169
- *
170
- * @param options Optional REST query options.
171
- * @returns Helper exposing `get` returning SharePoint user rows.
172
- */
173
- public users(options?: Options<any>) {
174
- this.endpoint = '_api/web/SiteUserInfoList/items';
175
- return {
176
- /**
177
- * Executes the user list request using the specified options.
178
- *
179
- * @returns Promise resolving to the SharePoint user list response.
180
- */
181
- get: () => this.get_v2(options),
182
- };
183
- }
184
-
185
- /**
186
- * Asynchronously retrieves the Form Digest Value from the context information API.
187
- *
188
- * @returns {Promise<string>} A promise that resolves to the Form Digest Value.
189
- * @throws {Error} If the HTTP request fails or the response does not contain the expected data.
190
- */
191
- private async getDigest(): Promise<string> {
192
- try {
193
- const response = await this.instance.post(
194
- `${this.baseURL}_api/contextinfo`
195
- );
196
- if (!response.data?.d?.GetContextWebInformation?.FormDigestValue) {
197
- throw new Error('Invalid response structure: Missing FormDigestValue');
198
- }
199
- return response.data.d.GetContextWebInformation.FormDigestValue;
200
- } catch (error) {
201
- console.error('Failed to retrieve the Form Digest Value:', error);
202
- throw new Error(`Error retrieving Form Digest Value`);
203
- }
204
- '';
205
- }
206
-
207
- /**
208
- * Executes a GET request without additional metadata wrapping.
209
- *
210
- * @param options Optional REST query options.
211
- * @returns SharePoint response payload or undefined when empty.
212
- */
213
- private async get_only(options?: any) {
214
- const { expand, orderBy, limit, filter, cols, skip } = options || {};
215
-
216
- const params = {
217
- $expand: Array.isArray(expand) ? expand.join(',') : expand,
218
- $top: limit,
219
- $skip: skip,
220
- $select: Array.isArray(cols) ? cols.join(',') : cols,
221
- $filter: filter,
222
- $orderby: Array.isArray(orderBy) ? orderBy.join(',') : orderBy,
223
- };
224
- const { data } = await this.instance.get(this.endpoint, { params });
225
- if (data) {
226
- return data.d.results ? data.d.results : data.d;
227
- }
228
- }
229
-
230
- /**
231
- * Retrieves folder contents with optional filtering and returns the payload with metadata.
232
- *
233
- * @param options REST options describing expand/filter/order conditions.
234
- * @returns Folder data and the fully resolved request URL.
235
- */
236
- private async get_files(options?: Folder_Options<any>) {
237
- const { expand, orderBy, limit, filter, cols, skip } = options || {};
238
- const params = {
239
- $expand: Array.isArray(expand) ? expand.join(',') : expand,
240
- $top: limit,
241
- $skip: skip,
242
- $select: Array.isArray(cols) ? cols.join(',') : cols,
243
- $filter: filter,
244
- $orderby: Array.isArray(orderBy) ? orderBy.join(',') : orderBy,
245
- };
246
- const url = new URL(this.endpoint, this.instance.defaults.baseURL);
247
- Object.entries(params).forEach(([key, value]) => {
248
- if (value !== undefined && value !== null) {
249
- url.searchParams.append(key, String(value));
250
- }
251
- });
252
-
253
- const response = await this.instance.request({
254
- url: this.endpoint,
255
- method: 'GET',
256
- params,
257
- });
258
-
259
- const data =
260
- limit || !response.data.d.results
261
- ? response.data.d
262
- : response.data.d.results;
263
-
264
- const meta = { url };
265
-
266
- return { data, meta };
267
- }
268
-
269
- /**
270
- * Performs a typed list read against the current endpoint.
271
- *
272
- * @param options Optional REST query options governing expand, filter, ordering and pagination.
273
- * @returns SharePoint list items alongside the fully-resolved request URL.
274
- */
275
- private async get_v2<K = any>(
276
- options?: Options<K>
277
- ): Promise<{ data: (K & Partial<SPItem>)[]; meta: { url: URL } }> {
278
- const { expand, orderBy, limit, filter, cols, skip } = options || {};
279
-
280
- const params = {
281
- $expand: Array.isArray(expand) ? expand.join(',') : expand,
282
- $top: limit,
283
- $skip: skip,
284
- $select: Array.isArray(cols) ? cols.join(',') : cols,
285
- $filter: filter,
286
- $orderby: Array.isArray(orderBy) ? orderBy.join(' ') : orderBy,
287
- };
288
-
289
- const url = new URL(this.endpoint, this.instance.defaults.baseURL);
290
- Object.entries(params).forEach(([key, value]) => {
291
- if (value !== undefined && value !== null) {
292
- url.searchParams.append(key, String(value));
293
- }
294
- });
295
-
296
- const response = await this.instance.request({
297
- url: this.endpoint,
298
- method: 'GET',
299
- params,
300
- });
301
-
302
- const data =
303
- limit || !response.data.d.results
304
- ? response.data.d
305
- : response.data.d.results;
306
-
307
- const meta = { url };
308
-
309
- return { data, meta };
310
- }
311
-
312
- /**
313
- * Updates an item in the currently selected list.
314
- *
315
- * @param id Target list item identifier.
316
- * @param data Payload with fields to update.
317
- * @param digest Optional pre-fetched form digest to reuse.
318
- * @returns Axios response of the update request.
319
- */
320
- private async update_2(id: ItemID, data: ListData, digest?: string) {
321
- const formDigestValue = digest || (await this.getDigest());
322
-
323
- data.__metadata = {
324
- type: `SP.Data.${this.listName}ListItem`,
325
- };
326
- const url = `_api/lists/getbytitle('${this.listName}')/getItemById('${id}')`;
327
- const response = await this.instance({
328
- url,
329
- method: 'POST',
330
- data: JSON.stringify(data),
331
- headers: {
332
- 'X-RequestDigest': formDigestValue,
333
- 'IF-MATCH': '*',
334
- 'X-Http-Method': 'PATCH',
335
- },
336
- });
337
- return response;
338
- }
339
-
340
- /**
341
- * Creates a new item within the active list.
342
- *
343
- * @param listData SharePoint list item payload.
344
- * @returns Axios response resolved from the create request.
345
- */
346
- private async create_v2(listData: ListData) {
347
- this.transformArraysToEdmStrings(listData);
348
- listData.__metadata = {
349
- type: `SP.Data.${this.listName}ListItem`,
350
- };
351
- const response = await this.instance({
352
- url: this.endpoint,
353
- method: 'POST',
354
- data: JSON.stringify(listData),
355
- headers: {
356
- 'X-RequestDigest': await this.getDigest(),
357
- 'IF-MATCH': '*',
358
- },
359
- });
360
- return response;
361
- }
362
-
363
- /**
364
- * Uploads an attachment file to an existing list item.
365
- *
366
- * @param props File payload and target item identifier.
367
- * @returns Axios response describing the upload result.
368
- */
369
- private async createFile({ file, itemId }: CreateFileProps) {
370
- const requestUrl = `_api/lists/getbytitle('${this.listName}')/items(${itemId})/AttachmentFiles/add(FileName='${file.name}')`;
371
- const res = await this.instance.post(requestUrl, file, {
372
- headers: {
373
- 'X-RequestDigest': await this.getDigest(),
374
- },
375
- withCredentials: true,
376
- });
377
-
378
- return res;
379
- }
380
-
381
- /**
382
- * Deletes an item using the current endpoint.
383
- *
384
- * @param ID Identifier of the entity to remove.
385
- * @returns Axios response from the delete call.
386
- */
387
- private async delete(ID: string | number) {
388
- const response = await this.instance.delete(`${this.endpoint!}(${ID})`);
389
- return response;
390
- }
391
-
392
- public email = {
393
- /**
394
- * Sends an email using SharePoint's Utility.SendEmail API.
395
- *
396
- * @param {EmailProps} param0 - The email properties.
397
- * @param {string} param0.From - The sender's email address.
398
- * @example
399
- * Example of a sender's email address
400
- * "sender@example.com"
401
- * @param {string | string[]} param0.To - The recipient's email address or an array of email addresses.
402
- * @example
403
- * Example of a single recipient's email address
404
- * "recipient@example.com"
405
- * Example of multiple recipients' email addresses
406
- * ["recipient1@example.com", "recipient2@example.com"]
407
- * @param {string} param0.Subject - The subject of the email.
408
- * @example
409
- * Example of an email subject
410
- * "Meeting Reminder"
411
- * @param {string} param0.Body - The body content of the email.
412
- * @example
413
- * Example of an email body
414
- * "Dear team, please be reminded of the meeting scheduled for tomorrow at 10 AM."
415
- * @returns {Promise<any>} - A promise that resolves to the response of the email send request.
416
- */
417
- send: (props: EmailProps) => this.sendEmail(props),
418
- };
419
-
420
- private async sendEmail({
421
- From,
422
- To,
423
- Subject,
424
- Body,
425
- }: EmailProps): Promise<
426
- AxiosResponse<{
427
- d: {
428
- SendEmail: null;
429
- };
430
- }>
431
- > {
432
- const httpRequest = '_api/SP.Utilities.Utility.SendEmail';
433
- const response = await this.instance({
434
- url: httpRequest,
435
- method: 'POST',
436
- headers: {
437
- 'X-RequestDigest': await this.getDigest(),
438
- 'X-Http-Method': 'POST',
439
- 'Content-Type': 'application/json;odata=verbose',
440
- },
441
- data: JSON.stringify({
442
- properties: {
443
- __metadata: {
444
- type: 'SP.Utilities.EmailProperties',
445
- },
446
- From,
447
- To: {
448
- results: Array.isArray(To) ? To : [To],
449
- },
450
- Body,
451
- Subject,
452
- },
453
- }),
454
- });
455
-
456
- return response;
457
- }
458
-
459
- /**
460
- * Queries SharePoint's people picker endpoint for matching users.
461
- *
462
- * @param input Free-text search term.
463
- * @param filter Optional additional filter condition.
464
- * @returns Promise with type-ahead results payload.
465
- */
466
- private async typeAhead(input: string, filter?: string) {
467
- const filterValue = filter ? ` and ${filter}` : '';
468
- const response = await this.instance.get(
469
- `_vti_bin/listdata.svc/UserInformationList?$top=10&$filter=substringof('${input}',Name) or substringof('${input}',WorkEmail)${filterValue}`
470
- );
471
- return response.data.d;
472
- }
473
-
474
- /**
475
- * Retrieves the current user profile and flattens selected properties.
476
- *
477
- * @returns Promise containing the current user's profile information.
478
- */
479
- private async currentUserProperties() {
480
- const requestUrl = '_api/sp.userprofiles.peoplemanager/getmyproperties';
481
- let profile: any = await this.instance.get(requestUrl);
482
-
483
- profile = profile.data.d;
484
-
485
- profile.UserProfileProperties.results.forEach(
486
- (prop: { Key: string; Value: string }) => {
487
- if (prop.Key === 'FirstName') {
488
- profile.FirstName = prop.Value;
489
- }
490
- if (prop.Key === 'LastName') {
491
- profile.LastName = prop.Value;
492
- }
493
- if (prop.Key === 'Country') {
494
- profile.Country = prop.Value;
495
- }
496
- if (prop.Key === 'UserName') {
497
- profile.UserName = prop.Value;
498
- }
499
- }
500
- );
501
- return profile as Promise<UserProfile>;
502
- }
503
- public user = {
504
- /**
505
- * Provides accessors for the current user's profile information.
506
- *
507
- * @returns Helper exposing a `get` function to retrieve profile details.
508
- */
509
- properties: () => {
510
- return {
511
- get: () => this.currentUserProperties(),
512
- };
513
- },
514
- /**
515
- * Searches across site users and their groups.
516
- *
517
- * @param searchValue Query string to match site users.
518
- * @returns Promise resolving to matching site users.
519
- */
520
- searchSiteUser: (searchValue: string) => this.getSiteUser(searchValue),
521
- /**
522
- * Performs a people-picker search scoped to the current site collection.
523
- *
524
- * @param input Search prefix.
525
- * @param filter Optional additional filter condition.
526
- * @returns Promise with type-ahead person results.
527
- */
528
- searchUser: (input: string, filter?: string): Promise<PersonField> =>
529
- this.typeAhead(input, filter),
530
- /**
531
- * Fetches the currently authenticated SharePoint user.
532
- *
533
- * @returns Helper exposing `get` that resolves to the current user payload.
534
- */
535
- current: () => {
536
- this.endpoint = '_api/web/currentUser';
537
- return {
538
- get: (): Promise<CurrentUser> => this.get_only(),
539
- };
540
- },
541
- /**
542
- * Retrieves calculated permission level for the current user.
543
- *
544
- * @returns Helper exposing `get` resolving to the user's permission definition.
545
- */
546
- currentPermission: () => {
547
- return {
548
- get: () => this.currentUserPermissions(),
549
- };
550
- },
551
- };
552
-
553
- /**
554
- * Searches site users based on a substring match across common fields.
555
- *
556
- * @param searchValue Term to match against the SharePoint user directory.
557
- * @returns Promise with matching site users and their groups.
558
- */
559
- private async getSiteUser(searchValue: string) {
560
- const requestUrl = `_api/web/siteusers?&$filter=substringof('${searchValue}', Title) or substringof('${searchValue}', LoginName) or substringof('${searchValue}', Email)&$top=50&$expand=Groups`;
561
- const response = await this.instance.get(requestUrl);
562
- return response.data.d;
563
- }
564
-
565
- /**
566
- * Retrieves all available role definitions for the current site.
567
- *
568
- * @returns Promise resolving to an array of role definitions.
569
- */
570
- private async roleDefinitions() {
571
- const requestUrl = `_api/Web/RoleDefinitions`;
572
- const response = await this.instance.get(requestUrl);
573
- return response.data.d.results;
574
- }
575
-
576
- /**
577
- * Fetches the bit-encoded permissions of the current user.
578
- *
579
- * @returns Promise resolving to the `EffectiveBasePermissions` object.
580
- */
581
- private async getEffectiveBasePermissions() {
582
- const requestUrl = `_api/Web/effectiveBasePermissions`;
583
- const response = await this.instance.get(requestUrl);
584
- return response.data.d.EffectiveBasePermissions;
585
- }
586
-
587
- /**
588
- * Matches the current user's effective permissions against known role definitions.
589
- *
590
- * @returns The matching SharePoint role definition as a structured permission object.
591
- */
592
- private async currentUserPermissions() {
593
- const { High } = await this.getEffectiveBasePermissions();
594
- const roleDefinitions = await this.roleDefinitions();
595
-
596
- const result = roleDefinitions.find(
597
- ({ BasePermissions }: { BasePermissions: { High: string } }) =>
598
- BasePermissions.High === High
599
- );
600
-
601
- return result as UserPermision;
602
- }
603
- }
604
-
605
- export default HTTPSharePointRequests;
162
+
163
+ public email = {
164
+ send: (props: EmailProps) => {
165
+ this.sharepointVersion = '2013';
166
+ return sendEmailRequest(this.getContext(), props);
167
+ },
168
+ };
169
+
170
+ public user = {
171
+ properties: () => ({
172
+ get: (): Promise<UserProfile> => {
173
+ this.sharepointVersion = '2013';
174
+ return loadCurrentUserProperties(this.instance);
175
+ },
176
+ }),
177
+ searchSiteUser: (searchValue: string) => {
178
+ this.sharepointVersion = '2013';
179
+ return fetchSiteUser(this.instance, searchValue);
180
+ },
181
+ searchUser: (input: string, filter?: string): Promise<PersonField> => {
182
+ this.sharepointVersion = '2013';
183
+ return typeAhead(this.instance, input, filter);
184
+ },
185
+ current: () => {
186
+ this.endpoint = '_api/web/currentUser';
187
+ this.sharepointVersion = '2013';
188
+ return {
189
+ get: (): Promise<CurrentUser> => getOnly(this.instance, this.endpoint),
190
+ };
191
+ },
192
+ currentPermission: () => ({
193
+ get: (): Promise<UserPermision> => {
194
+ this.sharepointVersion = '2013';
195
+ return resolveCurrentUserPermissions(this.getContext());
196
+ },
197
+ }),
198
+ };
199
+ }
200
+
201
+ export default HTTPSharePointRequests;