@pnp/cli-microsoft365 10.3.0-beta.cd20f0c → 10.3.0-beta.df85113

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 (68) hide show
  1. package/.eslintrc.cjs +2 -0
  2. package/README.md +11 -6
  3. package/allCommands.json +1 -1
  4. package/allCommandsFull.json +1 -1
  5. package/dist/config.js +2 -1
  6. package/dist/m365/commands/login.js +6 -6
  7. package/dist/m365/entra/commands/app/app-add.js +3 -0
  8. package/dist/m365/entra/commands/approleassignment/approleassignment-remove.js +1 -1
  9. package/dist/m365/entra/commands/group/group-list.js +3 -2
  10. package/dist/m365/entra/commands/pim/pim-role-assignment-remove.js +186 -0
  11. package/dist/m365/entra/commands/roledefinition/roledefinition-add.js +58 -0
  12. package/dist/m365/entra/commands/roledefinition/roledefinition-set.js +84 -0
  13. package/dist/m365/entra/commands/rolepermission/rolepermission-list.js +42 -0
  14. package/dist/m365/entra/commands.js +4 -0
  15. package/dist/m365/exo/commands/approleassignment/approleassignment-add.js +235 -0
  16. package/dist/m365/exo/commands.js +5 -0
  17. package/dist/m365/outlook/commands/mailbox/mailbox-settings-set.js +163 -0
  18. package/dist/m365/outlook/commands.js +1 -0
  19. package/dist/m365/pp/commands/website/website-get.js +60 -0
  20. package/dist/m365/pp/commands.js +2 -1
  21. package/dist/m365/spe/commands/container/container-activate.js +50 -0
  22. package/dist/m365/spe/commands.js +1 -0
  23. package/dist/m365/spo/commands/file/file-roleassignment-add.js +26 -2
  24. package/dist/m365/spo/commands/file/file-roleassignment-remove.js +26 -2
  25. package/dist/m365/spo/commands/folder/folder-roleassignment-add.js +27 -24
  26. package/dist/m365/spo/commands/folder/folder-roleassignment-remove.js +24 -7
  27. package/dist/m365/spo/commands/list/list-defaultvalue-clear.js +184 -0
  28. package/dist/m365/spo/commands/list/list-defaultvalue-list.js +140 -0
  29. package/dist/m365/spo/commands/list/list-defaultvalue-remove.js +181 -0
  30. package/dist/m365/spo/commands/list/list-defaultvalue-set.js +210 -0
  31. package/dist/m365/spo/commands/listitem/listitem-roleassignment-add.js +25 -7
  32. package/dist/m365/spo/commands/listitem/listitem-roleassignment-remove.js +22 -5
  33. package/dist/m365/spo/commands/web/web-roleassignment-add.js +22 -5
  34. package/dist/m365/spo/commands/web/web-roleassignment-remove.js +22 -5
  35. package/dist/m365/spo/commands.js +4 -0
  36. package/dist/m365/tenant/commands/people/people-pronouns-set.js +46 -0
  37. package/dist/m365/tenant/commands/report/report-settings-set.js +47 -0
  38. package/dist/m365/tenant/commands.js +2 -0
  39. package/dist/utils/customAppScope.js +29 -0
  40. package/dist/utils/entraServicePrincipal.js +46 -0
  41. package/dist/utils/powerPlatform.js +38 -0
  42. package/dist/utils/roleDefinition.js +23 -0
  43. package/dist/utils/validation.js +4 -0
  44. package/docs/docs/cmd/entra/app/app-add.mdx +1 -1
  45. package/docs/docs/cmd/entra/pim/pim-role-assignment-remove.mdx +197 -0
  46. package/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx +131 -0
  47. package/docs/docs/cmd/entra/roledefinition/roledefinition-set.mdx +64 -0
  48. package/docs/docs/cmd/entra/rolepermission/rolepermission-list.mdx +162 -0
  49. package/docs/docs/cmd/exo/approleassignment/approleassignment-add.mdx +170 -0
  50. package/docs/docs/cmd/outlook/mailbox/mailbox-settings-set.mdx +166 -0
  51. package/docs/docs/cmd/pp/website/website-get.mdx +153 -0
  52. package/docs/docs/cmd/spe/container/container-activate.mdx +34 -0
  53. package/docs/docs/cmd/spo/file/file-roleassignment-add.mdx +21 -4
  54. package/docs/docs/cmd/spo/file/file-roleassignment-remove.mdx +21 -3
  55. package/docs/docs/cmd/spo/folder/folder-roleassignment-add.mdx +15 -3
  56. package/docs/docs/cmd/spo/folder/folder-roleassignment-remove.mdx +15 -3
  57. package/docs/docs/cmd/spo/list/list-defaultvalue-clear.mdx +62 -0
  58. package/docs/docs/cmd/spo/list/list-defaultvalue-list.mdx +110 -0
  59. package/docs/docs/cmd/spo/list/list-defaultvalue-remove.mdx +62 -0
  60. package/docs/docs/cmd/spo/list/list-defaultvalue-set.mdx +112 -0
  61. package/docs/docs/cmd/spo/listitem/listitem-roleassignment-add.mdx +15 -3
  62. package/docs/docs/cmd/spo/listitem/listitem-roleassignment-remove.mdx +17 -5
  63. package/docs/docs/cmd/spo/web/web-roleassignment-add.mdx +15 -3
  64. package/docs/docs/cmd/spo/web/web-roleassignment-remove.mdx +15 -3
  65. package/docs/docs/cmd/tenant/people/people-pronouns-set.mdx +82 -0
  66. package/docs/docs/cmd/tenant/report/report-settings-set.mdx +32 -0
  67. package/npm-shrinkwrap.json +54 -74
  68. package/package.json +9 -9
@@ -12,6 +12,7 @@ import { urlUtil } from '../../../../utils/urlUtil.js';
12
12
  import { validation } from '../../../../utils/validation.js';
13
13
  import SpoCommand from '../../../base/SpoCommand.js';
14
14
  import commands from '../../commands.js';
15
+ import { entraGroup } from '../../../../utils/entraGroup.js';
15
16
  class SpoFileRoleAssignmentRemoveCommand extends SpoCommand {
16
17
  get name() {
17
18
  return commands.FILE_ROLEASSIGNMENT_REMOVE;
@@ -42,6 +43,20 @@ class SpoFileRoleAssignmentRemoveCommand extends SpoCommand {
42
43
  else if (args.options.upn) {
43
44
  principalId = await this.getUserPrincipalId(args.options, logger);
44
45
  }
46
+ else if (args.options.entraGroupId || args.options.entraGroupName) {
47
+ if (this.verbose) {
48
+ await logger.logToStderr('Retrieving group information...');
49
+ }
50
+ let group;
51
+ if (args.options.entraGroupId) {
52
+ group = await entraGroup.getGroupById(args.options.entraGroupId);
53
+ }
54
+ else {
55
+ group = await entraGroup.getGroupByDisplayName(args.options.entraGroupName);
56
+ }
57
+ const entraSiteUser = await spo.ensureEntraGroup(args.options.webUrl, group);
58
+ principalId = entraSiteUser.Id;
59
+ }
45
60
  else {
46
61
  principalId = args.options.principalId;
47
62
  }
@@ -93,6 +108,8 @@ _SpoFileRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoFileRoleAssig
93
108
  principalId: typeof args.options.principalId !== 'undefined',
94
109
  upn: typeof args.options.upn !== 'undefined',
95
110
  groupName: typeof args.options.groupName !== 'undefined',
111
+ entraGroupId: typeof args.options.entraGroupId !== 'undefined',
112
+ entraGroupName: typeof args.options.entraGroupName !== 'undefined',
96
113
  force: !!args.options.force
97
114
  });
98
115
  });
@@ -109,6 +126,10 @@ _SpoFileRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoFileRoleAssig
109
126
  option: '--upn [upn]'
110
127
  }, {
111
128
  option: '--groupName [groupName]'
129
+ }, {
130
+ option: '--entraGroupId [entraGroupId]'
131
+ }, {
132
+ option: '--entraGroupName [entraGroupName]'
112
133
  }, {
113
134
  option: '-f, --force'
114
135
  });
@@ -121,15 +142,18 @@ _SpoFileRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoFileRoleAssig
121
142
  if (args.options.principalId && isNaN(args.options.principalId)) {
122
143
  return `Specified principalId ${args.options.principalId} is not a number`;
123
144
  }
145
+ if (args.options.entraGroupId && !validation.isValidGuid(args.options.entraGroupId)) {
146
+ return `'${args.options.entraGroupId}' is not a valid GUID for option entraGroupId`;
147
+ }
124
148
  if (args.options.fileId && !validation.isValidGuid(args.options.fileId)) {
125
149
  return `${args.options.fileId} is not a valid GUID`;
126
150
  }
127
151
  return true;
128
152
  });
129
153
  }, _SpoFileRoleAssignmentRemoveCommand_initOptionSets = function _SpoFileRoleAssignmentRemoveCommand_initOptionSets() {
130
- this.optionSets.push({ options: ['fileUrl', 'fileId'] }, { options: ['upn', 'groupName', 'principalId'] });
154
+ this.optionSets.push({ options: ['fileUrl', 'fileId'] }, { options: ['upn', 'groupName', 'principalId', 'entraGroupId', 'entraGroupName'] });
131
155
  }, _SpoFileRoleAssignmentRemoveCommand_initTypes = function _SpoFileRoleAssignmentRemoveCommand_initTypes() {
132
- this.types.string.push('webUrl', 'fileUrl', 'fileId', 'upn', 'groupName');
156
+ this.types.string.push('webUrl', 'fileUrl', 'fileId', 'upn', 'groupName', 'entraGroupId', 'entraGroupName');
133
157
  this.types.boolean.push('force');
134
158
  };
135
159
  export default new SpoFileRoleAssignmentRemoveCommand();
@@ -14,6 +14,8 @@ import commands from '../../commands.js';
14
14
  import spoGroupGetCommand from '../group/group-get.js';
15
15
  import spoRoleDefinitionFolderCommand from '../roledefinition/roledefinition-list.js';
16
16
  import spoUserGetCommand from '../user/user-get.js';
17
+ import { entraGroup } from '../../../../utils/entraGroup.js';
18
+ import { spo } from '../../../../utils/spo.js';
17
19
  class SpoFolderRoleAssignmentAddCommand extends SpoCommand {
18
20
  get name() {
19
21
  return commands.FOLDER_ROLEASSIGNMENT_ADD;
@@ -45,37 +47,29 @@ class SpoFolderRoleAssignmentAddCommand extends SpoCommand {
45
47
  requestUrl += `GetFolderByServerRelativePath(DecodedUrl='${formatting.encodeQueryParameter(serverRelativeUrl)}')/ListItemAllFields`;
46
48
  }
47
49
  const roleDefinitionId = await this.getRoleDefinitionId(args.options);
50
+ let principalId = args.options.principalId;
48
51
  if (args.options.upn) {
49
- const upnPrincipalId = await this.getUserPrincipalId(args.options);
50
- await this.breakRoleAssignment(requestUrl);
51
- await this.addRoleAssignment(requestUrl, upnPrincipalId, roleDefinitionId);
52
+ principalId = await this.getUserPrincipalId(args.options);
52
53
  }
53
54
  else if (args.options.groupName) {
54
- const groupPrincipalId = await this.getGroupPrincipalId(args.options);
55
- await this.breakRoleAssignment(requestUrl);
56
- await this.addRoleAssignment(requestUrl, groupPrincipalId, roleDefinitionId);
55
+ principalId = await this.getGroupPrincipalId(args.options);
57
56
  }
58
- else {
59
- await this.breakRoleAssignment(requestUrl);
60
- await this.addRoleAssignment(requestUrl, args.options.principalId, roleDefinitionId);
57
+ else if (args.options.entraGroupId || args.options.entraGroupName) {
58
+ if (this.verbose) {
59
+ await logger.logToStderr('Retrieving group information...');
60
+ }
61
+ const group = args.options.entraGroupId
62
+ ? await entraGroup.getGroupById(args.options.entraGroupId)
63
+ : await entraGroup.getGroupByDisplayName(args.options.entraGroupName);
64
+ const siteUser = await spo.ensureEntraGroup(args.options.webUrl, group);
65
+ principalId = siteUser.Id;
61
66
  }
67
+ await this.addRoleAssignment(requestUrl, principalId, roleDefinitionId);
62
68
  }
63
69
  catch (err) {
64
70
  this.handleRejectedODataJsonPromise(err);
65
71
  }
66
72
  }
67
- async breakRoleAssignment(requestUrl) {
68
- const requestOptions = {
69
- url: `${requestUrl}/breakroleinheritance(true)`,
70
- method: 'POST',
71
- headers: {
72
- 'accept': 'application/json;odata=nometadata',
73
- 'content-type': 'application/json'
74
- },
75
- responseType: 'json'
76
- };
77
- return request.post(requestOptions);
78
- }
79
73
  async addRoleAssignment(requestUrl, principalId, roleDefinitionId) {
80
74
  const requestOptions = {
81
75
  url: `${requestUrl}/roleassignments/addroleassignment(principalid='${principalId}',roledefid='${roleDefinitionId}')`,
@@ -140,6 +134,8 @@ _SpoFolderRoleAssignmentAddCommand_instances = new WeakSet(), _SpoFolderRoleAssi
140
134
  principalId: typeof args.options.principalId !== 'undefined',
141
135
  upn: typeof args.options.upn !== 'undefined',
142
136
  groupName: typeof args.options.groupName !== 'undefined',
137
+ entraGroupId: typeof args.options.entraGroupId !== 'undefined',
138
+ entraGroupName: typeof args.options.entraGroupName !== 'undefined',
143
139
  roleDefinitionId: typeof args.options.roleDefinitionId !== 'undefined',
144
140
  roleDefinitionName: typeof args.options.roleDefinitionName !== 'undefined'
145
141
  });
@@ -155,6 +151,10 @@ _SpoFolderRoleAssignmentAddCommand_instances = new WeakSet(), _SpoFolderRoleAssi
155
151
  option: '--upn [upn]'
156
152
  }, {
157
153
  option: '--groupName [groupName]'
154
+ }, {
155
+ option: '--entraGroupId [entraGroupId]'
156
+ }, {
157
+ option: '--entraGroupName [entraGroupName]'
158
158
  }, {
159
159
  option: '--roleDefinitionId [roleDefinitionId]'
160
160
  }, {
@@ -169,15 +169,18 @@ _SpoFolderRoleAssignmentAddCommand_instances = new WeakSet(), _SpoFolderRoleAssi
169
169
  if (args.options.principalId && isNaN(args.options.principalId)) {
170
170
  return `Specified principalId ${args.options.principalId} is not a number`;
171
171
  }
172
+ if (args.options.entraGroupId && !validation.isValidGuid(args.options.entraGroupId)) {
173
+ return `'${args.options.entraGroupId}' is not a valid GUID for option entraGroupId.`;
174
+ }
172
175
  if (args.options.roleDefinitionId && isNaN(args.options.roleDefinitionId)) {
173
176
  return `Specified roleDefinitionId ${args.options.roleDefinitionId} is not a number`;
174
177
  }
175
- const principalOptions = [args.options.principalId, args.options.upn, args.options.groupName];
178
+ const principalOptions = [args.options.principalId, args.options.upn, args.options.groupName, args.options.entraGroupId, args.options.entraGroupName];
176
179
  if (!principalOptions.some(item => item !== undefined)) {
177
- return `Specify either principalId, upn or groupName`;
180
+ return `Specify either principalId, upn, groupName, entraGroupId or entraGroupName`;
178
181
  }
179
182
  if (principalOptions.filter(item => item !== undefined).length > 1) {
180
- return `Specify either principalId, upn or groupName but not multiple`;
183
+ return `Specify either principalId, upn, groupName, entraGroupId or entraGroupName but not multiple`;
181
184
  }
182
185
  const roleDefinitionOptions = [args.options.roleDefinitionId, args.options.roleDefinitionName];
183
186
  if (!roleDefinitionOptions.some(item => item !== undefined)) {
@@ -13,6 +13,8 @@ import SpoCommand from '../../../base/SpoCommand.js';
13
13
  import commands from '../../commands.js';
14
14
  import spoGroupGetCommand from '../group/group-get.js';
15
15
  import spoUserGetCommand from '../user/user-get.js';
16
+ import { entraGroup } from '../../../../utils/entraGroup.js';
17
+ import { spo } from '../../../../utils/spo.js';
16
18
  class SpoFolderRoleAssignmentRemoveCommand extends SpoCommand {
17
19
  get name() {
18
20
  return commands.FOLDER_ROLEASSIGNMENT_REMOVE;
@@ -38,15 +40,21 @@ class SpoFolderRoleAssignmentRemoveCommand extends SpoCommand {
38
40
  try {
39
41
  if (args.options.upn) {
40
42
  args.options.principalId = await this.getUserPrincipalId(args.options);
41
- await this.removeRoleAssignment(requestUrl, logger, args.options);
42
43
  }
43
44
  else if (args.options.groupName) {
44
45
  args.options.principalId = await this.getGroupPrincipalId(args.options);
45
- await this.removeRoleAssignment(requestUrl, logger, args.options);
46
46
  }
47
- else {
48
- await this.removeRoleAssignment(requestUrl, logger, args.options);
47
+ else if (args.options.entraGroupId || args.options.entraGroupName) {
48
+ if (this.verbose) {
49
+ await logger.logToStderr('Retrieving group information...');
50
+ }
51
+ const group = args.options.entraGroupId
52
+ ? await entraGroup.getGroupById(args.options.entraGroupId)
53
+ : await entraGroup.getGroupByDisplayName(args.options.entraGroupName);
54
+ const siteUser = await spo.ensureEntraGroup(args.options.webUrl, group);
55
+ args.options.principalId = siteUser.Id;
49
56
  }
57
+ await this.removeRoleAssignment(requestUrl, logger, args.options);
50
58
  }
51
59
  catch (err) {
52
60
  this.handleRejectedODataJsonPromise(err);
@@ -106,6 +114,8 @@ _SpoFolderRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoFolderRoleA
106
114
  principalId: typeof args.options.principalId !== 'undefined',
107
115
  upn: typeof args.options.upn !== 'undefined',
108
116
  groupName: typeof args.options.groupName !== 'undefined',
117
+ entraGroupId: typeof args.options.entraGroupId !== 'undefined',
118
+ entraGroupName: typeof args.options.entraGroupName !== 'undefined',
109
119
  force: !!args.options.force
110
120
  });
111
121
  });
@@ -120,6 +130,10 @@ _SpoFolderRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoFolderRoleA
120
130
  option: '--upn [upn]'
121
131
  }, {
122
132
  option: '--groupName [groupName]'
133
+ }, {
134
+ option: '--entraGroupId [entraGroupId]'
135
+ }, {
136
+ option: '--entraGroupName [entraGroupName]'
123
137
  }, {
124
138
  option: '-f, --force'
125
139
  });
@@ -132,12 +146,15 @@ _SpoFolderRoleAssignmentRemoveCommand_instances = new WeakSet(), _SpoFolderRoleA
132
146
  if (args.options.principalId && isNaN(args.options.principalId)) {
133
147
  return `Specified principalId ${args.options.principalId} is not a number`;
134
148
  }
135
- const principalOptions = [args.options.principalId, args.options.upn, args.options.groupName];
149
+ if (args.options.entraGroupId && !validation.isValidGuid(args.options.entraGroupId)) {
150
+ return `'${args.options.entraGroupId}' is not a valid GUID for option entraGroupId.`;
151
+ }
152
+ const principalOptions = [args.options.principalId, args.options.upn, args.options.groupName, args.options.entraGroupId, args.options.entraGroupName];
136
153
  if (principalOptions.some(item => item !== undefined) && principalOptions.filter(item => item !== undefined).length > 1) {
137
- return `Specify either principalId id, upn or groupName`;
154
+ return `Specify either principalId id, upn, groupName, entraGroupId or entraGroupName`;
138
155
  }
139
156
  if (principalOptions.filter(item => item !== undefined).length === 0) {
140
- return `Specify at least principalId id, upn or groupName`;
157
+ return `Specify at least principalId id, upn, groupName, entraGroupId or entraGroupName`;
141
158
  }
142
159
  return true;
143
160
  });
@@ -0,0 +1,184 @@
1
+ import SpoCommand from '../../../base/SpoCommand.js';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { z } from 'zod';
4
+ import { zod } from '../../../../utils/zod.js';
5
+ import commands from '../../commands.js';
6
+ import { DOMParser } from '@xmldom/xmldom';
7
+ import { validation } from '../../../../utils/validation.js';
8
+ import { urlUtil } from '../../../../utils/urlUtil.js';
9
+ import request from '../../../../request.js';
10
+ import { formatting } from '../../../../utils/formatting.js';
11
+ import { cli } from '../../../../cli/cli.js';
12
+ const options = globalOptionsZod
13
+ .extend({
14
+ webUrl: zod.alias('u', z.string()
15
+ .refine(url => validation.isValidSharePointUrl(url) === true, url => ({
16
+ message: `'${url}' is not a valid SharePoint Online site URL.`
17
+ }))),
18
+ listId: zod.alias('i', z.string().optional()
19
+ .refine(id => id === undefined || validation.isValidGuid(id), id => ({
20
+ message: `'${id}' is not a valid GUID.`
21
+ }))),
22
+ listTitle: zod.alias('t', z.string().optional()),
23
+ listUrl: z.string().optional(),
24
+ fieldName: z.string().optional(),
25
+ folderUrl: z.string().optional(),
26
+ force: zod.alias('f', z.boolean().optional())
27
+ })
28
+ .strict();
29
+ class SpoListDefaultValueClearCommand extends SpoCommand {
30
+ get name() {
31
+ return commands.LIST_DEFAULTVALUE_CLEAR;
32
+ }
33
+ get description() {
34
+ return 'Clears default column values for a specific document library';
35
+ }
36
+ get schema() {
37
+ return options;
38
+ }
39
+ getRefinedSchema(schema) {
40
+ return schema
41
+ .refine(options => [options.listId, options.listTitle, options.listUrl].filter(o => o !== undefined).length === 1, {
42
+ message: 'Use one of the following options: listId, listTitle, listUrl.'
43
+ })
44
+ .refine(options => (options.fieldName !== undefined) !== (options.folderUrl !== undefined) || (options.fieldName === undefined && options.folderUrl === undefined), {
45
+ message: `Specify 'fieldName' or 'folderUrl', but not both.`
46
+ });
47
+ }
48
+ async commandAction(logger, args) {
49
+ if (!args.options.force) {
50
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to clear all default values${args.options.fieldName ? ` for field '${args.options.fieldName}'` : args.options.folderUrl ? ` for folder ${args.options.folderUrl}` : ''}?` });
51
+ if (!result) {
52
+ return;
53
+ }
54
+ }
55
+ try {
56
+ if (this.verbose) {
57
+ await logger.logToStderr(`Clearing all default column values${args.options.fieldName ? ` for field ${args.options.fieldName}` : args.options.folderUrl ? `for folder '${args.options.folderUrl}'` : ''}...`);
58
+ await logger.logToStderr(`Getting server-relative URL of the list...`);
59
+ }
60
+ const listServerRelUrl = await this.getServerRelativeListUrl(args.options);
61
+ if (this.verbose) {
62
+ await logger.logToStderr(`List server-relative URL: ${listServerRelUrl}`);
63
+ await logger.logToStderr(`Getting default column values...`);
64
+ }
65
+ const defaultValuesXml = await this.getDefaultColumnValuesXml(args.options.webUrl, listServerRelUrl);
66
+ if (defaultValuesXml === null) {
67
+ if (this.verbose) {
68
+ await logger.logToStderr(`No default column values found.`);
69
+ }
70
+ return;
71
+ }
72
+ const trimmedXml = this.removeFieldsFromXml(defaultValuesXml, args.options);
73
+ await this.uploadDefaultColumnValuesXml(args.options.webUrl, listServerRelUrl, trimmedXml);
74
+ }
75
+ catch (err) {
76
+ this.handleRejectedODataJsonPromise(err);
77
+ }
78
+ }
79
+ async getServerRelativeListUrl(options) {
80
+ const requestOptions = {
81
+ url: `${options.webUrl}/_api/Web`,
82
+ headers: {
83
+ accept: 'application/json;odata=nometadata'
84
+ },
85
+ responseType: 'json'
86
+ };
87
+ if (options.listUrl) {
88
+ const serverRelativeUrl = urlUtil.getServerRelativePath(options.webUrl, options.listUrl);
89
+ requestOptions.url += `/GetList('${formatting.encodeQueryParameter(serverRelativeUrl)}')`;
90
+ }
91
+ else if (options.listId) {
92
+ requestOptions.url += `/Lists('${options.listId}')`;
93
+ }
94
+ else if (options.listTitle) {
95
+ requestOptions.url += `/Lists/GetByTitle('${formatting.encodeQueryParameter(options.listTitle)}')`;
96
+ }
97
+ requestOptions.url += '?$expand=RootFolder&$select=RootFolder/ServerRelativeUrl,BaseTemplate';
98
+ try {
99
+ const response = await request.get(requestOptions);
100
+ if (response.BaseTemplate !== 101) {
101
+ throw `The specified list is not a document library.`;
102
+ }
103
+ return response.RootFolder.ServerRelativeUrl;
104
+ }
105
+ catch (error) {
106
+ if (error.status === 404) {
107
+ throw `List '${options.listId || options.listTitle || options.listUrl}' was not found.`;
108
+ }
109
+ throw error;
110
+ }
111
+ }
112
+ async getDefaultColumnValuesXml(webUrl, listServerRelUrl) {
113
+ try {
114
+ const requestOptions = {
115
+ url: `${webUrl}/_api/Web/GetFileByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(listServerRelUrl + '/Forms/client_LocationBasedDefaults.html')}')/$value`,
116
+ headers: {
117
+ accept: 'application/json;odata=nometadata'
118
+ },
119
+ responseType: 'json'
120
+ };
121
+ const defaultValuesXml = await request.get(requestOptions);
122
+ return defaultValuesXml;
123
+ }
124
+ catch (err) {
125
+ // For lists that have never had default column values set, the client_LocationBasedDefaults.html file does not exist.
126
+ if (err.status === 404) {
127
+ return null;
128
+ }
129
+ throw err;
130
+ }
131
+ }
132
+ removeFieldsFromXml(xml, options) {
133
+ if (!options.fieldName && !options.folderUrl) {
134
+ return '<MetadataDefaults />';
135
+ }
136
+ let folderUrlToRemove = null;
137
+ if (options.folderUrl) {
138
+ folderUrlToRemove = urlUtil.removeTrailingSlashes(urlUtil.getServerRelativePath(options.webUrl, options.folderUrl));
139
+ }
140
+ const parser = new DOMParser();
141
+ const doc = parser.parseFromString(xml, 'application/xml');
142
+ const folderLinks = doc.getElementsByTagName('a');
143
+ for (let i = 0; i < folderLinks.length; i++) {
144
+ const folderNode = folderLinks[i];
145
+ const folderUrl = folderNode.getAttribute('href');
146
+ if (folderUrlToRemove && folderUrlToRemove.toLowerCase() === decodeURIComponent(folderUrl).toLowerCase()) {
147
+ folderNode.parentNode.removeChild(folderNode);
148
+ break;
149
+ }
150
+ else if (options.fieldName) {
151
+ const defaultValues = folderNode.getElementsByTagName('DefaultValue');
152
+ for (let j = 0; j < defaultValues.length; j++) {
153
+ const defaultValueNode = defaultValues[j];
154
+ const fieldName = defaultValueNode.getAttribute('FieldName');
155
+ if (fieldName.toLowerCase() === options.fieldName.toLowerCase()) {
156
+ // Remove the entire folder node if it becomes empty
157
+ if (folderNode.childNodes.length === 1) {
158
+ folderNode.parentNode.removeChild(defaultValueNode.parentNode);
159
+ }
160
+ else {
161
+ folderNode.removeChild(defaultValueNode);
162
+ }
163
+ break;
164
+ }
165
+ }
166
+ }
167
+ }
168
+ return doc.toString();
169
+ }
170
+ async uploadDefaultColumnValuesXml(webUrl, listServerRelUrl, xml) {
171
+ const requestOptions = {
172
+ url: `${webUrl}/_api/Web/GetFileByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(listServerRelUrl + '/Forms/client_LocationBasedDefaults.html')}')/$value`,
173
+ headers: {
174
+ accept: 'application/json;odata=nometadata',
175
+ 'If-Match': '*'
176
+ },
177
+ responseType: 'json',
178
+ data: xml
179
+ };
180
+ await request.put(requestOptions);
181
+ }
182
+ }
183
+ export default new SpoListDefaultValueClearCommand();
184
+ //# sourceMappingURL=list-defaultvalue-clear.js.map
@@ -0,0 +1,140 @@
1
+ import SpoCommand from '../../../base/SpoCommand.js';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { z } from 'zod';
4
+ import { zod } from '../../../../utils/zod.js';
5
+ import commands from '../../commands.js';
6
+ import { DOMParser } from '@xmldom/xmldom';
7
+ import { validation } from '../../../../utils/validation.js';
8
+ import { urlUtil } from '../../../../utils/urlUtil.js';
9
+ import request from '../../../../request.js';
10
+ import { formatting } from '../../../../utils/formatting.js';
11
+ const options = globalOptionsZod
12
+ .extend({
13
+ webUrl: zod.alias('u', z.string()
14
+ .refine(url => validation.isValidSharePointUrl(url) === true, url => ({
15
+ message: `'${url}' is not a valid SharePoint Online site URL.`
16
+ }))),
17
+ listId: zod.alias('i', z.string().optional()
18
+ .refine(id => id === undefined || validation.isValidGuid(id), id => ({
19
+ message: `'${id}' is not a valid GUID.`
20
+ }))),
21
+ listTitle: zod.alias('t', z.string().optional()),
22
+ listUrl: z.string().optional(),
23
+ folderUrl: z.string().optional()
24
+ })
25
+ .strict();
26
+ class SpoListDefaultValueListCommand extends SpoCommand {
27
+ get name() {
28
+ return commands.LIST_DEFAULTVALUE_LIST;
29
+ }
30
+ get description() {
31
+ return 'Retrieves default column values for a specific document library';
32
+ }
33
+ get schema() {
34
+ return options;
35
+ }
36
+ getRefinedSchema(schema) {
37
+ return schema
38
+ .refine(options => [options.listId, options.listTitle, options.listUrl].filter(o => o !== undefined).length === 1, {
39
+ message: 'Use one of the following options: listId, listTitle, listUrl.'
40
+ });
41
+ }
42
+ async commandAction(logger, args) {
43
+ try {
44
+ if (this.verbose) {
45
+ await logger.logToStderr(`Retrieving default column values for list '${args.options.listId || args.options.listTitle || args.options.listUrl}'...`);
46
+ await logger.logToStderr('Retrieving list information...');
47
+ }
48
+ const listServerRelUrl = await this.getServerRelativeListUrl(args.options);
49
+ if (this.verbose) {
50
+ await logger.logToStderr('Retrieving default column values...');
51
+ }
52
+ let defaultValues;
53
+ try {
54
+ const defaultValuesXml = await this.getDefaultColumnValuesXml(args.options.webUrl, listServerRelUrl);
55
+ defaultValues = this.convertXmlToJson(defaultValuesXml);
56
+ }
57
+ catch (err) {
58
+ if (err.status !== 404) {
59
+ throw err;
60
+ }
61
+ // For lists that have never had default column values set, the client_LocationBasedDefaults.html file does not exist.
62
+ defaultValues = [];
63
+ }
64
+ if (args.options.folderUrl) {
65
+ const serverRelFolderUrl = urlUtil.removeTrailingSlashes(urlUtil.getServerRelativePath(args.options.webUrl, args.options.folderUrl));
66
+ defaultValues = defaultValues.filter(d => d.folderUrl.toLowerCase() === serverRelFolderUrl.toLowerCase());
67
+ }
68
+ await logger.log(defaultValues);
69
+ }
70
+ catch (err) {
71
+ this.handleRejectedODataJsonPromise(err);
72
+ }
73
+ }
74
+ async getServerRelativeListUrl(options) {
75
+ const requestOptions = {
76
+ url: `${options.webUrl}/_api/Web`,
77
+ headers: {
78
+ accept: 'application/json;odata=nometadata'
79
+ },
80
+ responseType: 'json'
81
+ };
82
+ if (options.listUrl) {
83
+ const serverRelativeUrl = urlUtil.getServerRelativePath(options.webUrl, options.listUrl);
84
+ requestOptions.url += `/GetList('${serverRelativeUrl}')`;
85
+ }
86
+ else if (options.listId) {
87
+ requestOptions.url += `/Lists('${options.listId}')`;
88
+ }
89
+ else if (options.listTitle) {
90
+ requestOptions.url += `/Lists/GetByTitle('${formatting.encodeQueryParameter(options.listTitle)}')`;
91
+ }
92
+ requestOptions.url += '?$expand=RootFolder&$select=RootFolder/ServerRelativeUrl,BaseTemplate';
93
+ try {
94
+ const response = await request.get(requestOptions);
95
+ if (response.BaseTemplate !== 101) {
96
+ throw `List '${options.listId || options.listTitle || options.listUrl}' is not a document library.`;
97
+ }
98
+ return response.RootFolder.ServerRelativeUrl;
99
+ }
100
+ catch (error) {
101
+ if (error.status === 404) {
102
+ throw `List '${options.listId || options.listTitle || options.listUrl}' was not found.`;
103
+ }
104
+ throw error;
105
+ }
106
+ }
107
+ async getDefaultColumnValuesXml(webUrl, listServerRelUrl) {
108
+ const requestOptions = {
109
+ url: `${webUrl}/_api/Web/GetFileByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(listServerRelUrl + '/Forms/client_LocationBasedDefaults.html')}')/$value`,
110
+ headers: {
111
+ accept: 'application/json;odata=nometadata'
112
+ },
113
+ responseType: 'json'
114
+ };
115
+ const defaultValuesXml = await request.get(requestOptions);
116
+ return defaultValuesXml;
117
+ }
118
+ convertXmlToJson(xml) {
119
+ const results = [];
120
+ const parser = new DOMParser();
121
+ const doc = parser.parseFromString(xml, 'application/xml');
122
+ const folderLinks = doc.getElementsByTagName('a');
123
+ for (let i = 0; i < folderLinks.length; i++) {
124
+ const folderUrl = folderLinks[i].getAttribute('href');
125
+ const defaultValues = folderLinks[i].getElementsByTagName('DefaultValue');
126
+ for (let j = 0; j < defaultValues.length; j++) {
127
+ const fieldName = defaultValues[j].getAttribute('FieldName');
128
+ const fieldValue = defaultValues[j].textContent;
129
+ results.push({
130
+ fieldName: fieldName,
131
+ fieldValue: fieldValue,
132
+ folderUrl: decodeURIComponent(folderUrl)
133
+ });
134
+ }
135
+ }
136
+ return results;
137
+ }
138
+ }
139
+ export default new SpoListDefaultValueListCommand();
140
+ //# sourceMappingURL=list-defaultvalue-list.js.map