@pnp/cli-microsoft365 10.3.0-beta.d1b978f → 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 (47) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/allCommands.json +1 -1
  3. package/allCommandsFull.json +1 -1
  4. package/dist/config.js +2 -1
  5. package/dist/m365/entra/commands/app/app-add.js +3 -0
  6. package/dist/m365/entra/commands/pim/pim-role-assignment-remove.js +186 -0
  7. package/dist/m365/entra/commands/roledefinition/roledefinition-add.js +58 -0
  8. package/dist/m365/entra/commands/roledefinition/roledefinition-set.js +84 -0
  9. package/dist/m365/entra/commands/rolepermission/rolepermission-list.js +42 -0
  10. package/dist/m365/entra/commands.js +4 -0
  11. package/dist/m365/exo/commands/approleassignment/approleassignment-add.js +235 -0
  12. package/dist/m365/exo/commands.js +5 -0
  13. package/dist/m365/outlook/commands/mailbox/mailbox-settings-set.js +163 -0
  14. package/dist/m365/outlook/commands.js +1 -0
  15. package/dist/m365/pp/commands/website/website-get.js +60 -0
  16. package/dist/m365/pp/commands.js +2 -1
  17. package/dist/m365/spe/commands/container/container-activate.js +50 -0
  18. package/dist/m365/spe/commands.js +1 -0
  19. package/dist/m365/spo/commands/folder/folder-roleassignment-add.js +0 -13
  20. package/dist/m365/spo/commands/list/list-defaultvalue-clear.js +184 -0
  21. package/dist/m365/spo/commands/list/list-defaultvalue-remove.js +181 -0
  22. package/dist/m365/spo/commands/list/list-defaultvalue-set.js +210 -0
  23. package/dist/m365/spo/commands.js +3 -0
  24. package/dist/m365/tenant/commands/people/people-pronouns-set.js +46 -0
  25. package/dist/m365/tenant/commands/report/report-settings-set.js +47 -0
  26. package/dist/m365/tenant/commands.js +2 -0
  27. package/dist/utils/customAppScope.js +29 -0
  28. package/dist/utils/entraServicePrincipal.js +46 -0
  29. package/dist/utils/powerPlatform.js +38 -0
  30. package/dist/utils/roleDefinition.js +23 -0
  31. package/dist/utils/validation.js +4 -0
  32. package/docs/docs/cmd/entra/app/app-add.mdx +1 -1
  33. package/docs/docs/cmd/entra/pim/pim-role-assignment-remove.mdx +197 -0
  34. package/docs/docs/cmd/entra/roledefinition/roledefinition-add.mdx +131 -0
  35. package/docs/docs/cmd/entra/roledefinition/roledefinition-set.mdx +64 -0
  36. package/docs/docs/cmd/entra/rolepermission/rolepermission-list.mdx +162 -0
  37. package/docs/docs/cmd/exo/approleassignment/approleassignment-add.mdx +170 -0
  38. package/docs/docs/cmd/outlook/mailbox/mailbox-settings-set.mdx +166 -0
  39. package/docs/docs/cmd/pp/website/website-get.mdx +153 -0
  40. package/docs/docs/cmd/spe/container/container-activate.mdx +34 -0
  41. package/docs/docs/cmd/spo/list/list-defaultvalue-clear.mdx +62 -0
  42. package/docs/docs/cmd/spo/list/list-defaultvalue-remove.mdx +62 -0
  43. package/docs/docs/cmd/spo/list/list-defaultvalue-set.mdx +112 -0
  44. package/docs/docs/cmd/tenant/people/people-pronouns-set.mdx +82 -0
  45. package/docs/docs/cmd/tenant/report/report-settings-set.mdx +32 -0
  46. package/npm-shrinkwrap.json +54 -74
  47. package/package.json +9 -9
@@ -0,0 +1,181 @@
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(),
25
+ folderUrl: z.string().optional(),
26
+ force: zod.alias('f', z.boolean().optional())
27
+ })
28
+ .strict();
29
+ class SpoListDefaultValueRemoveCommand extends SpoCommand {
30
+ get name() {
31
+ return commands.LIST_DEFAULTVALUE_REMOVE;
32
+ }
33
+ get description() {
34
+ return 'Removes a specific default column value 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
+ }
45
+ async commandAction(logger, args) {
46
+ if (!args.options.force) {
47
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove default column value '${args.options.fieldName}' from ${args.options.folderUrl ? `'${args.options.folderUrl}'` : 'the root of the list'}?` });
48
+ if (!result) {
49
+ return;
50
+ }
51
+ }
52
+ try {
53
+ if (this.verbose) {
54
+ await logger.logToStderr(`Removing default column value '${args.options.fieldName}' from ${args.options.folderUrl ? `'${args.options.folderUrl}'` : 'the root of the list'}.`);
55
+ await logger.logToStderr(`Getting server-relative URL of the list...`);
56
+ }
57
+ const listServerRelUrl = await this.getServerRelativeListUrl(args.options);
58
+ let folderUrl = listServerRelUrl;
59
+ if (args.options.folderUrl) {
60
+ folderUrl = urlUtil.getServerRelativePath(args.options.webUrl, urlUtil.removeTrailingSlashes(args.options.folderUrl));
61
+ }
62
+ if (this.verbose) {
63
+ await logger.logToStderr(`Getting default column values...`);
64
+ }
65
+ const defaultValuesXml = await this.getDefaultColumnValuesXml(args.options.webUrl, listServerRelUrl);
66
+ const removeDefaultValueResult = this.removeFieldFromXml(defaultValuesXml, args.options.fieldName, folderUrl);
67
+ if (!removeDefaultValueResult.isFieldFound) {
68
+ throw `Default column value '${args.options.fieldName}' was not found.`;
69
+ }
70
+ if (this.verbose) {
71
+ await logger.logToStderr(`Uploading default column values to list...`);
72
+ }
73
+ await this.uploadDefaultColumnValuesXml(args.options.webUrl, listServerRelUrl, removeDefaultValueResult.xml);
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
+ removeFieldFromXml(xml, fieldName, folderUrl) {
133
+ if (xml === null) {
134
+ return { isFieldFound: false };
135
+ }
136
+ // Encode all spaces in the folder URL
137
+ const encodedFolderUrl = folderUrl.replace(/ /g, '%20');
138
+ const parser = new DOMParser();
139
+ const doc = parser.parseFromString(xml, 'application/xml');
140
+ const folderLinks = doc.getElementsByTagName('a');
141
+ for (let i = 0; i < folderLinks.length; i++) {
142
+ const folderNode = folderLinks[i];
143
+ const folderNodeUrl = folderNode.getAttribute('href');
144
+ if (encodedFolderUrl.toLowerCase() !== folderNodeUrl.toLowerCase()) {
145
+ continue;
146
+ }
147
+ const defaultValues = folderNode.getElementsByTagName('DefaultValue');
148
+ for (let j = 0; j < defaultValues.length; j++) {
149
+ const defaultValueNode = defaultValues[j];
150
+ const defaultValueNodeField = defaultValueNode.getAttribute('FieldName');
151
+ if (defaultValueNodeField !== fieldName) {
152
+ continue;
153
+ }
154
+ if (folderNode.childNodes.length === 1) {
155
+ // No other default values found in the folder, let's remove the folder node
156
+ folderNode.parentNode.removeChild(folderNode);
157
+ }
158
+ else {
159
+ // Default value node found, let's remove it
160
+ folderNode.removeChild(defaultValueNode);
161
+ }
162
+ return { isFieldFound: true, xml: doc.toString() };
163
+ }
164
+ }
165
+ return { isFieldFound: false };
166
+ }
167
+ async uploadDefaultColumnValuesXml(webUrl, listServerRelUrl, xml) {
168
+ const requestOptions = {
169
+ url: `${webUrl}/_api/Web/GetFileByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(listServerRelUrl + '/Forms/client_LocationBasedDefaults.html')}')/$value`,
170
+ headers: {
171
+ accept: 'application/json;odata=nometadata',
172
+ 'content-type': 'text/plain'
173
+ },
174
+ responseType: 'json',
175
+ data: xml
176
+ };
177
+ await request.put(requestOptions);
178
+ }
179
+ }
180
+ export default new SpoListDefaultValueRemoveCommand();
181
+ //# sourceMappingURL=list-defaultvalue-remove.js.map
@@ -0,0 +1,210 @@
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
+ fieldName: z.string(),
24
+ fieldValue: z.string()
25
+ .refine(value => value !== '', `The value cannot be empty. Use 'spo list defaultvalue remove' to remove a default column value.`),
26
+ folderUrl: z.string().optional()
27
+ .refine(url => url === undefined || (!url.includes('#') && !url.includes('%')), 'Due to limitations in SharePoint Online, setting default column values for folders with a # or % character in their path is not supported.')
28
+ })
29
+ .strict();
30
+ class SpoListDefaultValueSetCommand extends SpoCommand {
31
+ get name() {
32
+ return commands.LIST_DEFAULTVALUE_SET;
33
+ }
34
+ get description() {
35
+ return 'Sets default column values for a specific document library';
36
+ }
37
+ get schema() {
38
+ return options;
39
+ }
40
+ getRefinedSchema(schema) {
41
+ return schema
42
+ .refine(options => [options.listId, options.listTitle, options.listUrl].filter(o => o !== undefined).length === 1, {
43
+ message: 'Use one of the following options: listId, listTitle, listUrl.'
44
+ });
45
+ }
46
+ async commandAction(logger, args) {
47
+ try {
48
+ if (this.verbose) {
49
+ await logger.logToStderr(`Setting default column value '${args.options.fieldValue}' for field '${args.options.fieldName}'...`);
50
+ await logger.logToStderr(`Getting server-relative URL of the list...`);
51
+ }
52
+ const listServerRelUrl = await this.getServerRelativeListUrl(args.options);
53
+ let folderUrl = listServerRelUrl;
54
+ if (args.options.folderUrl) {
55
+ if (this.verbose) {
56
+ await logger.logToStderr(`Getting server-relative URL of folder '${args.options.folderUrl}'...`);
57
+ }
58
+ // Casing of the folder URL is important, let's retrieve the correct URL
59
+ const serverRelativeFolderUrl = urlUtil.getServerRelativePath(args.options.webUrl, urlUtil.removeTrailingSlashes(args.options.folderUrl));
60
+ folderUrl = await this.getCorrectFolderUrl(args.options.webUrl, serverRelativeFolderUrl);
61
+ }
62
+ if (this.verbose) {
63
+ await logger.logToStderr(`Getting default column values...`);
64
+ }
65
+ const defaultValuesXml = await this.ensureDefaultColumnValuesXml(args.options.webUrl, listServerRelUrl);
66
+ const modifiedXml = await this.updateFieldValueXml(logger, defaultValuesXml, args.options.fieldName, args.options.fieldValue, folderUrl);
67
+ await this.uploadDefaultColumnValuesXml(logger, args.options.webUrl, listServerRelUrl, modifiedXml);
68
+ }
69
+ catch (err) {
70
+ this.handleRejectedODataJsonPromise(err);
71
+ }
72
+ }
73
+ async getServerRelativeListUrl(options) {
74
+ const requestOptions = {
75
+ url: `${options.webUrl}/_api/Web`,
76
+ headers: {
77
+ accept: 'application/json;odata=nometadata'
78
+ },
79
+ responseType: 'json'
80
+ };
81
+ if (options.listUrl) {
82
+ const serverRelativeUrl = urlUtil.getServerRelativePath(options.webUrl, options.listUrl);
83
+ requestOptions.url += `/GetList('${formatting.encodeQueryParameter(serverRelativeUrl)}')`;
84
+ }
85
+ else if (options.listId) {
86
+ requestOptions.url += `/Lists('${options.listId}')`;
87
+ }
88
+ else if (options.listTitle) {
89
+ requestOptions.url += `/Lists/GetByTitle('${formatting.encodeQueryParameter(options.listTitle)}')`;
90
+ }
91
+ requestOptions.url += '?$expand=RootFolder&$select=RootFolder/ServerRelativeUrl,BaseTemplate';
92
+ try {
93
+ const response = await request.get(requestOptions);
94
+ if (response.BaseTemplate !== 101) {
95
+ throw `The specified list is not a document library.`;
96
+ }
97
+ return response.RootFolder.ServerRelativeUrl;
98
+ }
99
+ catch (error) {
100
+ if (error.status === 404) {
101
+ throw `List '${options.listId || options.listTitle || options.listUrl}' was not found.`;
102
+ }
103
+ throw error;
104
+ }
105
+ }
106
+ async getCorrectFolderUrl(webUrl, folderUrl) {
107
+ const requestOptions = {
108
+ // Using ListItemAllFields endpoint because GetFolderByServerRelativePath doesn't return the correctly cased URL
109
+ url: `${webUrl}/_api/Web/GetFolderByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(folderUrl)}')/ListItemAllFields?$select=FileRef`,
110
+ headers: {
111
+ accept: 'application/json;odata=nometadata'
112
+ },
113
+ responseType: 'json'
114
+ };
115
+ const response = await request.get(requestOptions);
116
+ if (!response.FileRef) {
117
+ throw `Folder '${folderUrl}' was not found.`;
118
+ }
119
+ return response.FileRef;
120
+ }
121
+ async ensureDefaultColumnValuesXml(webUrl, listServerRelUrl) {
122
+ try {
123
+ const requestOptions = {
124
+ url: `${webUrl}/_api/Web/GetFileByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(listServerRelUrl + '/Forms/client_LocationBasedDefaults.html')}')/$value`,
125
+ headers: {
126
+ accept: 'application/json;odata=nometadata'
127
+ },
128
+ responseType: 'json'
129
+ };
130
+ const defaultValuesXml = await request.get(requestOptions);
131
+ return defaultValuesXml;
132
+ }
133
+ catch (err) {
134
+ if (err.status !== 404) {
135
+ throw err;
136
+ }
137
+ // For lists that have never had default column values set, the client_LocationBasedDefaults.html file does not exist.
138
+ // In this case, we need to create the file with blank default metadata.
139
+ const requestOptions = {
140
+ url: `${webUrl}/_api/Web/GetFolderByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(listServerRelUrl + '/Forms')}')/Files/Add(url='client_LocationBasedDefaults.html', overwrite=false)`,
141
+ headers: {
142
+ accept: 'application/json;odata=nometadata',
143
+ 'content-type': 'text/plain'
144
+ },
145
+ responseType: 'json',
146
+ data: '<MetadataDefaults />'
147
+ };
148
+ await request.post(requestOptions);
149
+ return requestOptions.data;
150
+ }
151
+ }
152
+ async updateFieldValueXml(logger, xml, fieldName, fieldValue, folderUrl) {
153
+ if (this.verbose) {
154
+ await logger.logToStderr(`Modifying default column values...`);
155
+ }
156
+ // Encode all spaces in the folder URL
157
+ const encodedFolderUrl = folderUrl.replace(/ /g, '%20');
158
+ const parser = new DOMParser();
159
+ const doc = parser.parseFromString(xml, 'application/xml');
160
+ // Create a new DefaultValue node
161
+ const newDefaultValueNode = doc.createElement('DefaultValue');
162
+ newDefaultValueNode.setAttribute('FieldName', fieldName);
163
+ newDefaultValueNode.textContent = fieldValue;
164
+ const folderLinks = doc.getElementsByTagName('a');
165
+ for (let i = 0; i < folderLinks.length; i++) {
166
+ const folderNode = folderLinks[i];
167
+ const folderNodeUrl = folderNode.getAttribute('href');
168
+ if (encodedFolderUrl !== folderNodeUrl) {
169
+ continue;
170
+ }
171
+ const defaultValues = folderNode.getElementsByTagName('DefaultValue');
172
+ for (let j = 0; j < defaultValues.length; j++) {
173
+ const defaultValueNode = defaultValues[j];
174
+ const defaultValueNodeField = defaultValueNode.getAttribute('FieldName');
175
+ if (defaultValueNodeField !== fieldName) {
176
+ continue;
177
+ }
178
+ // Default value node found, let's update the value
179
+ defaultValueNode.textContent = fieldValue;
180
+ return doc.toString();
181
+ }
182
+ // Default value node not found, let's create it
183
+ folderNode.appendChild(newDefaultValueNode);
184
+ return doc.toString();
185
+ }
186
+ // Folder node was not found, let's create it
187
+ const newFolderNode = doc.createElement('a');
188
+ newFolderNode.setAttribute('href', encodedFolderUrl);
189
+ newFolderNode.appendChild(newDefaultValueNode);
190
+ doc.documentElement.appendChild(newFolderNode);
191
+ return doc.toString();
192
+ }
193
+ async uploadDefaultColumnValuesXml(logger, webUrl, listServerRelUrl, xml) {
194
+ if (this.verbose) {
195
+ await logger.logToStderr(`Uploading default column values to list...`);
196
+ }
197
+ const requestOptions = {
198
+ url: `${webUrl}/_api/Web/GetFileByServerRelativePath(decodedUrl='${formatting.encodeQueryParameter(listServerRelUrl + '/Forms/client_LocationBasedDefaults.html')}')/$value`,
199
+ headers: {
200
+ accept: 'application/json;odata=nometadata',
201
+ 'content-type': 'text/plain'
202
+ },
203
+ responseType: 'json',
204
+ data: xml
205
+ };
206
+ await request.put(requestOptions);
207
+ }
208
+ }
209
+ export default new SpoListDefaultValueSetCommand();
210
+ //# sourceMappingURL=list-defaultvalue-set.js.map
@@ -137,7 +137,10 @@ export default {
137
137
  LIST_CONTENTTYPE_LIST: `${prefix} list contenttype list`,
138
138
  LIST_CONTENTTYPE_REMOVE: `${prefix} list contenttype remove`,
139
139
  LIST_CONTENTTYPE_DEFAULT_SET: `${prefix} list contenttype default set`,
140
+ LIST_DEFAULTVALUE_CLEAR: `${prefix} list defaultvalue clear`,
140
141
  LIST_DEFAULTVALUE_LIST: `${prefix} list defaultvalue list`,
142
+ LIST_DEFAULTVALUE_REMOVE: `${prefix} list defaultvalue remove`,
143
+ LIST_DEFAULTVALUE_SET: `${prefix} list defaultvalue set`,
141
144
  LIST_GET: `${prefix} list get`,
142
145
  LIST_LIST: `${prefix} list list`,
143
146
  LIST_REMOVE: `${prefix} list remove`,
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import request from '../../../../request.js';
4
+ import { zod } from '../../../../utils/zod.js';
5
+ import GraphCommand from '../../../base/GraphCommand.js';
6
+ import commands from '../../commands.js';
7
+ const options = globalOptionsZod
8
+ .extend({
9
+ enabled: zod.alias('e', z.boolean())
10
+ })
11
+ .strict();
12
+ class TenantPeoplePronounsSetCommand extends GraphCommand {
13
+ get name() {
14
+ return commands.PEOPLE_PRONOUNS_SET;
15
+ }
16
+ get description() {
17
+ return 'Manage pronouns settings for an organization';
18
+ }
19
+ get schema() {
20
+ return options;
21
+ }
22
+ async commandAction(logger, args) {
23
+ try {
24
+ if (this.verbose) {
25
+ await logger.logToStderr('Updating pronouns settings...');
26
+ }
27
+ const requestOptions = {
28
+ url: `${this.resource}/v1.0/admin/people/pronouns`,
29
+ headers: {
30
+ accept: 'application/json;odata.metadata=none'
31
+ },
32
+ data: {
33
+ isEnabledInOrganization: args.options.enabled
34
+ },
35
+ responseType: 'json'
36
+ };
37
+ const pronouns = await request.patch(requestOptions);
38
+ await logger.log(pronouns);
39
+ }
40
+ catch (err) {
41
+ this.handleRejectedODataJsonPromise(err);
42
+ }
43
+ }
44
+ }
45
+ export default new TenantPeoplePronounsSetCommand();
46
+ //# sourceMappingURL=people-pronouns-set.js.map
@@ -0,0 +1,47 @@
1
+ import request from '../../../../request.js';
2
+ import GraphCommand from '../../../base/GraphCommand.js';
3
+ import commands from '../../commands.js';
4
+ import { z } from 'zod';
5
+ import { globalOptionsZod } from '../../../../Command.js';
6
+ import { zod } from '../../../../utils/zod.js';
7
+ const options = globalOptionsZod
8
+ .extend({
9
+ displayConcealedNames: zod.alias('d', z.boolean())
10
+ })
11
+ .strict();
12
+ class TenantReportSettingsSetCommand extends GraphCommand {
13
+ get name() {
14
+ return commands.REPORT_SETTINGS_SET;
15
+ }
16
+ get description() {
17
+ return 'Update tenant-level settings for Microsoft 365 reports';
18
+ }
19
+ get schema() {
20
+ return options;
21
+ }
22
+ async commandAction(logger, args) {
23
+ try {
24
+ const { displayConcealedNames } = args.options;
25
+ if (this.verbose) {
26
+ await logger.logToStderr(`Updating report setting displayConcealedNames to ${displayConcealedNames}`);
27
+ }
28
+ const requestOptions = {
29
+ url: `${this.resource}/v1.0/admin/reportSettings`,
30
+ headers: {
31
+ accept: 'application/json;odata.metadata=none',
32
+ 'content-type': 'application/json'
33
+ },
34
+ responseType: 'json',
35
+ data: {
36
+ displayConcealedNames
37
+ }
38
+ };
39
+ await request.patch(requestOptions);
40
+ }
41
+ catch (err) {
42
+ this.handleRejectedODataJsonPromise(err);
43
+ }
44
+ }
45
+ }
46
+ export default new TenantReportSettingsSetCommand();
47
+ //# sourceMappingURL=report-settings-set.js.map
@@ -8,12 +8,14 @@ export default {
8
8
  PEOPLE_PROFILECARDPROPERTY_REMOVE: `${prefix} people profilecardproperty remove`,
9
9
  PEOPLE_PROFILECARDPROPERTY_SET: `${prefix} people profilecardproperty set`,
10
10
  PEOPLE_PRONOUNS_GET: `${prefix} people pronouns get`,
11
+ PEOPLE_PRONOUNS_SET: `${prefix} people pronouns set`,
11
12
  REPORT_ACTIVEUSERCOUNTS: `${prefix} report activeusercounts`,
12
13
  REPORT_ACTIVEUSERDETAIL: `${prefix} report activeuserdetail`,
13
14
  REPORT_OFFICE365ACTIVATIONCOUNTS: `${prefix} report office365activationcounts`,
14
15
  REPORT_OFFICE365ACTIVATIONSUSERDETAIL: `${prefix} report office365activationsuserdetail`,
15
16
  REPORT_OFFICE365ACTIVATIONSUSERCOUNTS: `${prefix} report office365activationsusercounts`,
16
17
  REPORT_SERVICESUSERCOUNTS: `${prefix} report servicesusercounts`,
18
+ REPORT_SETTINGS_SET: `${prefix} report settings set`,
17
19
  SECURITY_ALERTS_LIST: `${prefix} security alerts list`,
18
20
  SERVICEANNOUNCEMENT_HEALTHISSUE_GET: `${prefix} serviceannouncement healthissue get`,
19
21
  SERVICEANNOUNCEMENT_HEALTH_GET: `${prefix} serviceannouncement health get`,
@@ -0,0 +1,29 @@
1
+ import { cli } from '../cli/cli.js';
2
+ import { formatting } from './formatting.js';
3
+ import { odata } from './odata.js';
4
+ export const customAppScope = {
5
+ /**
6
+ * Get a custom application scope by its name
7
+ * @param displayName Custom application scope display name.
8
+ * @param properties Comma-separated list of properties to include in the response.
9
+ * @returns The custom application scope.
10
+ * @throws Error when role definition was not found.
11
+ */
12
+ async getCustomAppScopeByDisplayName(displayName, properties) {
13
+ let url = `https://graph.microsoft.com/beta/roleManagement/exchange/customAppScopes?$filter=displayName eq '${formatting.encodeQueryParameter(displayName)}'`;
14
+ if (properties) {
15
+ url += `&$select=${properties}`;
16
+ }
17
+ const customAppScopes = await odata.getAllItems(url);
18
+ if (customAppScopes.length === 0) {
19
+ throw `The specified custom application scope '${displayName}' does not exist.`;
20
+ }
21
+ if (customAppScopes.length > 1) {
22
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', customAppScopes);
23
+ const selectedCustomAppScope = await cli.handleMultipleResultsFound(`Multiple custom application scopes with name '${displayName}' found.`, resultAsKeyValuePair);
24
+ return selectedCustomAppScope;
25
+ }
26
+ return customAppScopes[0];
27
+ }
28
+ };
29
+ //# sourceMappingURL=customAppScope.js.map
@@ -0,0 +1,46 @@
1
+ import { odata } from './odata.js';
2
+ import { formatting } from './formatting.js';
3
+ import { cli } from '../cli/cli.js';
4
+ export const entraServicePrincipal = {
5
+ /**
6
+ * Get service principal by its appId
7
+ * @param appId App id.
8
+ * @param properties Comma-separated list of properties to include in the response.
9
+ * @returns The service principal.
10
+ * @throws Error when service principal was not found.
11
+ */
12
+ async getServicePrincipalByAppId(appId, properties) {
13
+ let url = `https://graph.microsoft.com/v1.0/servicePrincipals?$filter=appId eq '${appId}'`;
14
+ if (properties) {
15
+ url += `&$select=${properties}`;
16
+ }
17
+ const apps = await odata.getAllItems(url);
18
+ if (apps.length === 0) {
19
+ throw `Service principal with appId '${appId}' not found in Microsoft Entra ID`;
20
+ }
21
+ return apps[0];
22
+ },
23
+ /**
24
+ * Get service principal by its name
25
+ * @param appName Service principal name.
26
+ * @param properties Comma-separated list of properties to include in the response.
27
+ * @returns The service principal.
28
+ * @throws Error when service principal was not found.
29
+ */
30
+ async getServicePrincipalByAppName(appName, properties) {
31
+ let url = `https://graph.microsoft.com/v1.0/servicePrincipals?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'`;
32
+ if (properties) {
33
+ url += `&$select=${properties}`;
34
+ }
35
+ const apps = await odata.getAllItems(url);
36
+ if (apps.length === 0) {
37
+ throw `Service principal with name '${appName}' not found in Microsoft Entra ID`;
38
+ }
39
+ if (apps.length > 1) {
40
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', apps);
41
+ return await cli.handleMultipleResultsFound(`Multiple service principals with name '${appName}' found in Microsoft Entra ID.`, resultAsKeyValuePair);
42
+ }
43
+ return apps[0];
44
+ }
45
+ };
46
+ //# sourceMappingURL=entraServicePrincipal.js.map
@@ -1,5 +1,7 @@
1
+ import { cli } from "../cli/cli.js";
1
2
  import request from "../request.js";
2
3
  import { formatting } from "./formatting.js";
4
+ import { odata } from "./odata.js";
3
5
  const powerPlatformResource = 'https://api.bap.microsoft.com';
4
6
  export const powerPlatform = {
5
7
  async getDynamicsInstanceApiUrl(environment, asAdmin) {
@@ -24,6 +26,42 @@ export const powerPlatform = {
24
26
  catch (ex) {
25
27
  throw Error(`The environment '${environment}' could not be retrieved. See the inner exception for more details: ${ex.message}`);
26
28
  }
29
+ },
30
+ async getWebsiteById(environment, id) {
31
+ const requestOptions = {
32
+ url: `https://api.powerplatform.com/powerpages/environments/${environment}/websites/${id}?api-version=2022-03-01-preview`,
33
+ headers: {
34
+ accept: 'application/json;odata.metadata=none'
35
+ },
36
+ responseType: 'json'
37
+ };
38
+ try {
39
+ const response = await request.get(requestOptions);
40
+ return response;
41
+ }
42
+ catch (ex) {
43
+ throw Error(`The specified Power Page website with id '${id}' does not exist.`);
44
+ }
45
+ },
46
+ async getWebsiteByName(environment, websiteName) {
47
+ const response = await odata.getAllItems(`https://api.powerplatform.com/powerpages/environments/${environment}/websites?api-version=2022-03-01-preview`);
48
+ const items = response.filter(response => response.name === websiteName);
49
+ if (items.length === 0) {
50
+ throw Error(`The specified Power Page website '${websiteName}' does not exist.`);
51
+ }
52
+ if (items.length > 1) {
53
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('websiteUrl', items);
54
+ return cli.handleMultipleResultsFound(`Multiple Power Page websites with name '${websiteName}' found`, resultAsKeyValuePair);
55
+ }
56
+ return items[0];
57
+ },
58
+ async getWebsiteByUrl(environment, url) {
59
+ const response = await odata.getAllItems(`https://api.powerplatform.com/powerpages/environments/${environment}/websites?api-version=2022-03-01-preview`);
60
+ const items = response.filter(response => response.websiteUrl === url);
61
+ if (items.length === 0) {
62
+ throw Error(`The specified Power Page website with url '${url}' does not exist.`);
63
+ }
64
+ return items[0];
27
65
  }
28
66
  };
29
67
  //# sourceMappingURL=powerPlatform.js.map
@@ -46,6 +46,29 @@ export const roleDefinition = {
46
46
  responseType: 'json'
47
47
  };
48
48
  return await request.get(requestOptions);
49
+ },
50
+ /**
51
+ * Get an Exchange role by its name
52
+ * @param displayName Role definition display name.
53
+ * @param properties Comma-separated list of properties to include in the response.
54
+ * @returns The role definition.
55
+ * @throws Error when role definition was not found.
56
+ */
57
+ async getExchangeRoleDefinitionByDisplayName(displayName, properties) {
58
+ let url = `https://graph.microsoft.com/beta/roleManagement/exchange/roleDefinitions?$filter=displayName eq '${formatting.encodeQueryParameter(displayName)}'`;
59
+ if (properties) {
60
+ url += `&$select=${properties}`;
61
+ }
62
+ const roleDefinitions = await odata.getAllItems(url);
63
+ if (roleDefinitions.length === 0) {
64
+ throw `The specified role definition '${displayName}' does not exist.`;
65
+ }
66
+ if (roleDefinitions.length > 1) {
67
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', roleDefinitions);
68
+ const selectedRoleDefinition = await cli.handleMultipleResultsFound(`Multiple role definitions with name '${displayName}' found.`, resultAsKeyValuePair);
69
+ return selectedRoleDefinition;
70
+ }
71
+ return roleDefinitions[0];
49
72
  }
50
73
  };
51
74
  //# sourceMappingURL=roleDefinition.js.map