@pnp/cli-microsoft365 10.7.0 → 10.8.0-beta.26ade35

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.
package/dist/Auth.js CHANGED
@@ -562,19 +562,93 @@ export class Auth {
562
562
  if (debug) {
563
563
  await logger.logToStderr('Trying to retrieve access token using federated identity...');
564
564
  }
565
- if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL || !process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN) {
566
- throw new CommandError('Federated identity is currently only supported in GitHub Actions.');
565
+ if (process.env.ACTIONS_ID_TOKEN_REQUEST_URL && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN) {
566
+ if (debug) {
567
+ await logger.logToStderr('ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN env variables found. The context is GitHub Actions...');
568
+ }
569
+ const federationToken = await this.getFederationTokenFromGithub(logger, debug);
570
+ return this.getAccessTokenWithFederatedToken(resource, federationToken, logger, debug);
571
+ }
572
+ else if (process.env.SYSTEM_OIDCREQUESTURI) {
573
+ if (debug) {
574
+ await logger.logToStderr('SYSTEM_OIDCREQUESTURI env variable found. The context is Azure DevOps...');
575
+ }
576
+ if (!process.env.SYSTEM_ACCESSTOKEN) {
577
+ throw new CommandError(`The SYSTEM_ACCESSTOKEN environment variable is not available. Please check the Azure DevOps pipeline task configuration. It should contain 'SYSTEM_ACCESSTOKEN: $(System.AccessToken)' in the env section.`);
578
+ }
579
+ const serviceConnectionId = process.env.AZURESUBSCRIPTION_SERVICE_CONNECTION_ID;
580
+ const serviceConnectionAppId = process.env.AZURESUBSCRIPTION_CLIENT_ID;
581
+ const serviceConnectionTenantId = process.env.AZURESUBSCRIPTION_TENANT_ID;
582
+ const useServiceConnection = serviceConnectionId && serviceConnectionAppId && serviceConnectionTenantId;
583
+ if (!useServiceConnection) {
584
+ if (debug) {
585
+ await logger.logToStderr('Not using a service connection. Run this command in an AzurePowerShell task to be able to use a service connection.');
586
+ }
587
+ if (!this.connection.appId || this.connection.tenant === 'common') {
588
+ throw new CommandError('The appId and tenant parameters are required when not using a service connection.');
589
+ }
590
+ }
591
+ else {
592
+ if (debug) {
593
+ if (this.connection.appId || this.connection.tenant !== 'common') {
594
+ await logger.logToStderr('When using a service connection, the appId and tenant values are updated to the values of the service connection.');
595
+ }
596
+ await logger.logToStderr(`Using service connection '${serviceConnectionId}' with app Id '${serviceConnectionAppId}' and tenant Id '${serviceConnectionTenantId}'...`);
597
+ }
598
+ this.connection.appId = serviceConnectionAppId;
599
+ this.connection.tenant = serviceConnectionTenantId;
600
+ }
601
+ const federationToken = await this.getFederationTokenFromAzureDevOps(logger, debug, serviceConnectionId);
602
+ return this.getAccessTokenWithFederatedToken(resource, federationToken, logger, debug);
603
+ }
604
+ else {
605
+ throw new CommandError('Federated identity is currently only supported in GitHub Actions and Azure DevOps.');
606
+ }
607
+ }
608
+ async getFederationTokenFromGithub(logger, debug) {
609
+ if (debug) {
610
+ await logger.logToStderr('Retrieving GitHub federation token...');
611
+ }
612
+ const requestOptions = {
613
+ url: `${process.env.ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${encodeURIComponent('api://AzureADTokenExchange')}`,
614
+ headers: {
615
+ Authorization: `Bearer ${process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}`,
616
+ Accept: 'application/json',
617
+ 'x-anonymous': true
618
+ },
619
+ responseType: 'json'
620
+ };
621
+ const accessTokenResponse = await request.get(requestOptions);
622
+ return accessTokenResponse.value;
623
+ }
624
+ async getFederationTokenFromAzureDevOps(logger, debug, serviceConnectionId) {
625
+ if (debug) {
626
+ await logger.logToStderr('Retrieving Azure DevOps federation token...');
567
627
  }
628
+ const urlSuffix = serviceConnectionId ? `&serviceConnectionId=${serviceConnectionId}` : '';
629
+ const requestOptions = {
630
+ url: `${process.env.SYSTEM_OIDCREQUESTURI}?api-version=7.1${urlSuffix}`,
631
+ headers: {
632
+ Authorization: `Bearer ${process.env.SYSTEM_ACCESSTOKEN}`,
633
+ Accept: 'application/json',
634
+ 'Content-Type': 'application/json',
635
+ 'x-anonymous': true
636
+ },
637
+ responseType: 'json'
638
+ };
639
+ const accessTokenResponse = await request.post(requestOptions);
640
+ return accessTokenResponse.oidcToken;
641
+ }
642
+ async getAccessTokenWithFederatedToken(resource, federatedToken, logger, debug) {
568
643
  if (debug) {
569
- await logger.logToStderr('ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN env variables found. The context is GitHub Actions...');
644
+ await logger.logToStderr('Retrieving Entra ID Access Token with federated token...');
570
645
  }
571
- const federationToken = await this.getFederationTokenFromGithub(logger, debug);
572
646
  const queryParams = [
573
647
  'grant_type=client_credentials',
574
648
  `scope=${encodeURIComponent(`${resource}/.default`)}`,
575
649
  `client_id=${this.connection.appId}`,
576
650
  `client_assertion_type=${encodeURIComponent('urn:ietf:params:oauth:client-assertion-type:jwt-bearer')}`,
577
- `client_assertion=${federationToken}`
651
+ `client_assertion=${federatedToken}`
578
652
  ];
579
653
  const requestOptions = {
580
654
  url: `https://login.microsoftonline.com/${this.connection.tenant}/oauth2/v2.0/token`,
@@ -587,27 +661,13 @@ export class Auth {
587
661
  responseType: 'json'
588
662
  };
589
663
  const accessTokenResponse = await request.post(requestOptions);
664
+ const expiresIn = parseInt(accessTokenResponse.expires_in) * 1000;
665
+ const now = new Date();
590
666
  return {
591
667
  accessToken: accessTokenResponse.access_token,
592
- expiresOn: new Date(parseInt(accessTokenResponse.expires_on) * 1000)
668
+ expiresOn: new Date(now.getTime() + expiresIn)
593
669
  };
594
670
  }
595
- async getFederationTokenFromGithub(logger, debug) {
596
- if (debug) {
597
- await logger.logToStderr('Retrieving GitHub federation token...');
598
- }
599
- const requestOptions = {
600
- url: `${process.env.ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${encodeURIComponent('api://AzureADTokenExchange')}`,
601
- headers: {
602
- Authorization: `Bearer ${process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}`,
603
- accept: 'application/json',
604
- 'x-anonymous': true
605
- },
606
- responseType: 'json'
607
- };
608
- const accessTokenResponse = await request.get(requestOptions);
609
- return accessTokenResponse.value;
610
- }
611
671
  async ensureAccessTokenWithSecret(resource, logger, debug, fetchNew) {
612
672
  this.clientApplication = await this.getConfidentialClient(logger, debug, undefined, undefined, this.connection.secret);
613
673
  return this.clientApplication.acquireTokenByClientCredential({
package/dist/cli/cli.js CHANGED
@@ -406,7 +406,7 @@ async function loadCommandFromFile(commandFileUrl) {
406
406
  catch { }
407
407
  }
408
408
  function getCommandInfo(command, filePath = '', helpFilePath = '') {
409
- const options = command.schema ? zod.schemaToOptions(command.schema) : getCommandOptions(command);
409
+ const options = command.schema ? zod.schemaToOptionInfo(command.schema) : getCommandOptions(command);
410
410
  command.optionsInfo = options;
411
411
  return {
412
412
  aliases: command.alias(),
@@ -1,13 +1,21 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var _AdaptiveCardSendCommand_instances, _AdaptiveCardSendCommand_initTelemetry, _AdaptiveCardSendCommand_initOptions, _AdaptiveCardSendCommand_initValidators, _AdaptiveCardSendCommand_initOptionSets;
1
+ import { z } from 'zod';
2
+ import { globalOptionsZod } from '../../../Command.js';
7
3
  import request from '../../../request.js';
4
+ import { optionsUtils } from '../../../utils/optionsUtils.js';
5
+ import { zod } from '../../../utils/zod.js';
8
6
  import AnonymousCommand from '../../base/AnonymousCommand.js';
9
7
  import commands from '../commands.js';
10
- import { optionsUtils } from '../../../utils/optionsUtils.js';
8
+ export const options = globalOptionsZod
9
+ .extend({
10
+ url: z.string(),
11
+ title: zod.alias('t', z.string().optional()),
12
+ description: zod.alias('d', z.string().optional()),
13
+ imageUrl: zod.alias('i', z.string().optional()),
14
+ actionUrl: zod.alias('a', z.string().optional()),
15
+ card: z.string().optional(),
16
+ cardData: z.string().optional()
17
+ })
18
+ .and(z.any());
11
19
  class AdaptiveCardSendCommand extends AnonymousCommand {
12
20
  get name() {
13
21
  return commands.SEND;
@@ -15,19 +23,48 @@ class AdaptiveCardSendCommand extends AnonymousCommand {
15
23
  get description() {
16
24
  return 'Sends adaptive card to the specified URL';
17
25
  }
18
- constructor() {
19
- super();
20
- _AdaptiveCardSendCommand_instances.add(this);
21
- __classPrivateFieldGet(this, _AdaptiveCardSendCommand_instances, "m", _AdaptiveCardSendCommand_initTelemetry).call(this);
22
- __classPrivateFieldGet(this, _AdaptiveCardSendCommand_instances, "m", _AdaptiveCardSendCommand_initOptions).call(this);
23
- __classPrivateFieldGet(this, _AdaptiveCardSendCommand_instances, "m", _AdaptiveCardSendCommand_initValidators).call(this);
24
- __classPrivateFieldGet(this, _AdaptiveCardSendCommand_instances, "m", _AdaptiveCardSendCommand_initOptionSets).call(this);
26
+ get schema() {
27
+ return options;
25
28
  }
26
- allowUnknownOptions() {
27
- return true;
29
+ getRefinedSchema(schema) {
30
+ return schema
31
+ .refine(options => !options.cardData || options.card, {
32
+ message: 'When you specify cardData, you must also specify card.',
33
+ path: ['cardData']
34
+ })
35
+ .refine(options => {
36
+ if (options.card) {
37
+ try {
38
+ JSON.parse(options.card);
39
+ return true;
40
+ }
41
+ catch (e) {
42
+ return false;
43
+ }
44
+ }
45
+ return true;
46
+ }, {
47
+ message: 'Specified card is not a valid JSON string.',
48
+ path: ['card']
49
+ })
50
+ .refine(options => {
51
+ if (options.cardData) {
52
+ try {
53
+ JSON.parse(options.cardData);
54
+ return true;
55
+ }
56
+ catch (e) {
57
+ return false;
58
+ }
59
+ }
60
+ return true;
61
+ }, {
62
+ message: 'Specified cardData is not a valid JSON string.',
63
+ path: ['cardData']
64
+ });
28
65
  }
29
66
  async commandAction(logger, args) {
30
- const unknownOptions = optionsUtils.getUnknownOptions(args.options, this.options);
67
+ const unknownOptions = optionsUtils.getUnknownOptions(args.options, zod.schemaToOptions(this.schema));
31
68
  const unknownOptionNames = Object.getOwnPropertyNames(unknownOptions);
32
69
  const card = await this.getCard(args, unknownOptionNames, unknownOptions);
33
70
  const requestOptions = {
@@ -166,55 +203,5 @@ class AdaptiveCardSendCommand extends AnonymousCommand {
166
203
  return cardData;
167
204
  }
168
205
  }
169
- _AdaptiveCardSendCommand_instances = new WeakSet(), _AdaptiveCardSendCommand_initTelemetry = function _AdaptiveCardSendCommand_initTelemetry() {
170
- this.telemetry.push((args) => {
171
- Object.assign(this.telemetryProperties, {
172
- actionUrl: typeof args.options.actionUrl !== 'undefined',
173
- card: typeof args.options.card !== 'undefined',
174
- cardData: typeof args.options.cardData !== 'undefined',
175
- description: typeof args.options.description !== 'undefined',
176
- imageUrl: typeof args.options.imageUrl !== 'undefined',
177
- title: typeof args.options.title !== 'undefined'
178
- });
179
- });
180
- }, _AdaptiveCardSendCommand_initOptions = function _AdaptiveCardSendCommand_initOptions() {
181
- this.options.unshift({
182
- option: '-u, --url <url>'
183
- }, {
184
- option: '-t, --title [title]'
185
- }, {
186
- option: '-d, --description [description]'
187
- }, {
188
- option: '-i, --imageUrl [imageUrl]'
189
- }, {
190
- option: '-a, --actionUrl [actionUrl]'
191
- }, {
192
- option: '--card [card]'
193
- }, {
194
- option: '--cardData [cardData]'
195
- });
196
- }, _AdaptiveCardSendCommand_initValidators = function _AdaptiveCardSendCommand_initValidators() {
197
- this.validators.push(async (args) => {
198
- if (args.options.card) {
199
- try {
200
- JSON.parse(args.options.card);
201
- }
202
- catch (e) {
203
- return `Error while parsing the card: ${e}`;
204
- }
205
- }
206
- if (args.options.cardData) {
207
- try {
208
- JSON.parse(args.options.cardData);
209
- }
210
- catch (e) {
211
- return `Error while parsing card data: ${e}`;
212
- }
213
- }
214
- return true;
215
- });
216
- }, _AdaptiveCardSendCommand_initOptionSets = function _AdaptiveCardSendCommand_initOptionSets() {
217
- this.optionSets.push({ options: ['title', 'card'] });
218
- };
219
206
  export default new AdaptiveCardSendCommand();
220
207
  //# sourceMappingURL=adaptivecard-send.js.map
@@ -37,7 +37,7 @@ class LoginCommand extends Command {
37
37
  }
38
38
  getRefinedSchema(schema) {
39
39
  return schema
40
- .refine(options => typeof options.appId !== 'undefined' || cli.getClientId() || options.authType === 'identity', {
40
+ .refine(options => typeof options.appId !== 'undefined' || cli.getClientId() || options.authType === 'identity' || options.authType === 'federatedIdentity', {
41
41
  message: `appId is required. TIP: use the "m365 setup" command to configure the default appId.`,
42
42
  path: ['appId']
43
43
  })
@@ -18,7 +18,6 @@ import { validation } from '../../utils/validation.js';
18
18
  import AnonymousCommand from '../base/AnonymousCommand.js';
19
19
  import commands from './commands.js';
20
20
  import { interactivePreset, powerShellPreset, scriptingPreset } from './setupPresets.js';
21
- import { optionsUtils } from '../../utils/optionsUtils.js';
22
21
  export var CliUsageMode;
23
22
  (function (CliUsageMode) {
24
23
  CliUsageMode["Interactively"] = "interactively";
@@ -228,7 +227,7 @@ class SetupCommand extends AnonymousCommand {
228
227
  });
229
228
  const appInfo = await entraApp.createAppRegistration({
230
229
  options,
231
- unknownOptions: optionsUtils.getUnknownOptions(options, this.options),
230
+ unknownOptions: {},
232
231
  apis,
233
232
  logger,
234
233
  verbose: this.verbose,
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { zod } from '../../../../utils/zod.js';
4
+ import GraphCommand from '../../../base/GraphCommand.js';
5
+ import commands from '../../commands.js';
6
+ import { odata } from '../../../../utils/odata.js';
7
+ const options = globalOptionsZod
8
+ .extend({
9
+ properties: zod.alias('p', z.string().optional())
10
+ })
11
+ .strict();
12
+ class EntraOrganizationListCommand extends GraphCommand {
13
+ get name() {
14
+ return commands.ORGANIZATION_LIST;
15
+ }
16
+ get description() {
17
+ return 'Lists all Microsoft Entra ID organizations';
18
+ }
19
+ defaultProperties() {
20
+ return ['id', 'displayName', 'tenantType'];
21
+ }
22
+ get schema() {
23
+ return options;
24
+ }
25
+ async commandAction(logger, args) {
26
+ try {
27
+ let url = `${this.resource}/v1.0/organization`;
28
+ if (args.options.properties) {
29
+ url += `?$select=${args.options.properties}`;
30
+ }
31
+ const requestOptions = {
32
+ url: url,
33
+ headers: {
34
+ accept: 'application/json;odata.metadata=none',
35
+ 'content-type': 'application/json'
36
+ },
37
+ responseType: 'json'
38
+ };
39
+ if (args.options.verbose) {
40
+ await logger.logToStderr(`Retrieving organizations...`);
41
+ }
42
+ const res = await odata.getAllItems(requestOptions);
43
+ await logger.log(res);
44
+ }
45
+ catch (err) {
46
+ this.handleRejectedODataJsonPromise(err);
47
+ }
48
+ }
49
+ }
50
+ export default new EntraOrganizationListCommand();
51
+ //# sourceMappingURL=organization-list.js.map
@@ -83,6 +83,7 @@ export default {
83
83
  OAUTH2GRANT_LIST: `${prefix} oauth2grant list`,
84
84
  OAUTH2GRANT_REMOVE: `${prefix} oauth2grant remove`,
85
85
  OAUTH2GRANT_SET: `${prefix} oauth2grant set`,
86
+ ORGANIZATION_LIST: `${prefix} organization list`,
86
87
  PIM_ROLE_ASSIGNMENT_ADD: `${prefix} pim role assignment add`,
87
88
  PIM_ROLE_ASSIGNMENT_LIST: `${prefix} pim role assignment list`,
88
89
  PIM_ROLE_ASSIGNMENT_REMOVE: `${prefix} pim role assignment remove`,
@@ -0,0 +1,107 @@
1
+ import { z } from 'zod';
2
+ import { globalOptionsZod } from '../../../../Command.js';
3
+ import { zod } from '../../../../utils/zod.js';
4
+ import { validation } from '../../../../utils/validation.js';
5
+ import GraphCommand from '../../../base/GraphCommand.js';
6
+ import commands from '../../commands.js';
7
+ import request from '../../../../request.js';
8
+ import { optionsUtils } from '../../../../utils/optionsUtils.js';
9
+ const options = globalOptionsZod
10
+ .extend({
11
+ name: zod.alias('n', z.string()),
12
+ resourceId: zod.alias('i', z.string()),
13
+ resourceType: zod.alias('t', z.enum(['user', 'group', 'device', 'organization'])),
14
+ keepUnchangedProperties: zod.alias('k', z.boolean().optional())
15
+ })
16
+ .and(z.any());
17
+ class GraphOpenExtensionSetCommand extends GraphCommand {
18
+ constructor() {
19
+ super(...arguments);
20
+ this.commandOptions = ['keepUnchangedProperties', 'resourceType', 'resourceId', 'name'];
21
+ this.defaultOpenExtensionProperties = ['id', 'extensionName'];
22
+ }
23
+ get name() {
24
+ return commands.OPENEXTENSION_SET;
25
+ }
26
+ get description() {
27
+ return 'Updates an open extension for a resource';
28
+ }
29
+ get schema() {
30
+ return options;
31
+ }
32
+ getRefinedSchema(schema) {
33
+ return schema
34
+ .refine(options => options.resourceType !== 'group' && options.resourceType !== 'device' && options.resourceType !== 'organization' || (options.resourceId && validation.isValidGuid(options.resourceId)), options => ({
35
+ message: `The '${options.resourceId}' must be a valid GUID`,
36
+ path: ['resourceId']
37
+ }))
38
+ .refine(options => options.resourceType !== 'user' || (options.resourceId && (validation.isValidGuid(options.resourceId) || validation.isValidUserPrincipalName(options.resourceId))), options => ({
39
+ message: `The '${options.resourceId}' must be a valid GUID or user principal name`,
40
+ path: ['resourceId']
41
+ }));
42
+ }
43
+ async commandAction(logger, args) {
44
+ try {
45
+ const currentExtension = await this.getOpenExtension(logger, args);
46
+ const currentExtensionNames = Object.getOwnPropertyNames(currentExtension);
47
+ const requestBody = {};
48
+ requestBody["@odata.type"] = '#microsoft.graph.openTypeExtension';
49
+ const unknownOptions = optionsUtils.getUnknownOptions(args.options, this.options);
50
+ const unknownOptionsNames = Object.getOwnPropertyNames(unknownOptions);
51
+ unknownOptionsNames.forEach(async (option) => {
52
+ if (this.commandOptions.includes(option)) {
53
+ return;
54
+ }
55
+ const value = unknownOptions[option];
56
+ if (value === "") {
57
+ requestBody[option] = null;
58
+ }
59
+ else {
60
+ try {
61
+ const jsonObject = JSON.parse(value);
62
+ requestBody[option] = jsonObject;
63
+ }
64
+ catch {
65
+ requestBody[option] = value;
66
+ }
67
+ }
68
+ });
69
+ currentExtensionNames.forEach(async (name) => {
70
+ if (!unknownOptionsNames.includes(name) && (args.options.keepUnchangedProperties || this.defaultOpenExtensionProperties.includes(name))) {
71
+ requestBody[name] = currentExtension[name];
72
+ }
73
+ });
74
+ const requestOptions = {
75
+ url: `${this.resource}/v1.0/${args.options.resourceType}${args.options.resourceType === 'organization' ? '' : 's'}/${args.options.resourceId}/extensions/${args.options.name}`,
76
+ headers: {
77
+ accept: 'application/json;odata.metadata=none',
78
+ 'content-type': 'application/json'
79
+ },
80
+ data: requestBody,
81
+ responseType: 'json'
82
+ };
83
+ if (args.options.verbose) {
84
+ await logger.logToStderr(`Updating open extension of the ${args.options.resourceType} with id '${args.options.resourceId}'...`);
85
+ }
86
+ await request.patch(requestOptions);
87
+ }
88
+ catch (err) {
89
+ this.handleRejectedODataJsonPromise(err);
90
+ }
91
+ }
92
+ async getOpenExtension(logger, args) {
93
+ if (this.verbose) {
94
+ await logger.logToStderr(`Retrieving open extension for resource ${args.options.resourceId}...`);
95
+ }
96
+ const requestOptions = {
97
+ url: `${this.resource}/v1.0/${args.options.resourceType}${args.options.resourceType === 'organization' ? '' : 's'}/${args.options.resourceId}/extensions/${args.options.name}`,
98
+ headers: {
99
+ accept: 'application/json;odata.metadata=none'
100
+ },
101
+ responseType: 'json'
102
+ };
103
+ return await request.get(requestOptions);
104
+ }
105
+ }
106
+ export default new GraphOpenExtensionSetCommand();
107
+ //# sourceMappingURL=openextension-set.js.map
@@ -8,6 +8,7 @@ export default {
8
8
  OPENEXTENSION_GET: `${prefix} openextension get`,
9
9
  OPENEXTENSION_LIST: `${prefix} openextension list`,
10
10
  OPENEXTENSION_REMOVE: `${prefix} openextension remove`,
11
+ OPENEXTENSION_SET: `${prefix} openextension set`,
11
12
  SCHEMAEXTENSION_ADD: `${prefix} schemaextension add`,
12
13
  SCHEMAEXTENSION_GET: `${prefix} schemaextension get`,
13
14
  SCHEMAEXTENSION_LIST: `${prefix} schemaextension list`,
@@ -0,0 +1,52 @@
1
+ import { cli } from '../../../../cli/cli.js';
2
+ import { z } from 'zod';
3
+ import { zod } from '../../../../utils/zod.js';
4
+ import { globalOptionsZod } from '../../../../Command.js';
5
+ import commands from '../../commands.js';
6
+ import GraphCommand from '../../../base/GraphCommand.js';
7
+ import { odata } from '../../../../utils/odata.js';
8
+ import { formatting } from '../../../../utils/formatting.js';
9
+ const options = globalOptionsZod
10
+ .extend({
11
+ containerId: zod.alias('i', z.string())
12
+ })
13
+ .strict();
14
+ class SpeContainerPermissionListCommand extends GraphCommand {
15
+ get name() {
16
+ return commands.CONTAINER_PERMISSION_LIST;
17
+ }
18
+ get description() {
19
+ return 'Lists permissions of a SharePoint Embedded Container';
20
+ }
21
+ defaultProperties() {
22
+ return ['id', 'userPrincipalName', 'roles'];
23
+ }
24
+ get schema() {
25
+ return options;
26
+ }
27
+ async commandAction(logger, args) {
28
+ try {
29
+ if (this.verbose) {
30
+ await logger.logToStderr(`Retrieving permissions of a SharePoint Embedded Container with id '${args.options.containerId}'...`);
31
+ }
32
+ const containerPermission = await odata.getAllItems(`${this.resource}/v1.0/storage/fileStorage/containers/${formatting.encodeQueryParameter(args.options.containerId)}/permissions`);
33
+ if (!cli.shouldTrimOutput(args.options.output)) {
34
+ await logger.log(containerPermission);
35
+ }
36
+ else {
37
+ await logger.log(containerPermission.map(i => {
38
+ return {
39
+ id: i.id,
40
+ roles: i.roles.join(','),
41
+ userPrincipalName: i.grantedToV2.user.userPrincipalName
42
+ };
43
+ }));
44
+ }
45
+ }
46
+ catch (err) {
47
+ this.handleRejectedODataJsonPromise(err);
48
+ }
49
+ }
50
+ }
51
+ export default new SpeContainerPermissionListCommand();
52
+ //# sourceMappingURL=container-permission-list.js.map
@@ -3,6 +3,7 @@ export default {
3
3
  CONTAINER_ACTIVATE: `${prefix} container activate`,
4
4
  CONTAINER_GET: `${prefix} container get`,
5
5
  CONTAINER_LIST: `${prefix} container list`,
6
+ CONTAINER_PERMISSION_LIST: `${prefix} container permission list`,
6
7
  CONTAINERTYPE_ADD: `${prefix} containertype add`,
7
8
  CONTAINERTYPE_GET: `${prefix} containertype get`,
8
9
  CONTAINERTYPE_LIST: `${prefix} containertype list`
@@ -59,19 +59,25 @@ class SpoPageSectionAddCommand extends SpoCommand {
59
59
  };
60
60
  await request.post(requestOptions);
61
61
  }
62
- // get columns
63
- const columns = canvasContent
64
- .filter(c => typeof c.controlType === 'undefined');
65
62
  // get unique zoneIndex values given each section can have 1 or more
66
63
  // columns each assigned to the zoneIndex of the corresponding section
67
- const zoneIndices = columns
64
+ const zoneIndices = canvasContent
65
+ // Exclude the vertical section
66
+ .filter(c => c.position)
68
67
  .map(c => c.position.zoneIndex)
69
68
  .filter((value, index, array) => {
70
69
  return array.indexOf(value) === index;
71
70
  })
72
- .sort();
73
- // zoneIndex for the new section to add
74
- const zoneIndex = this.getSectionIndex(zoneIndices, args.options.order);
71
+ .sort((a, b) => a - b);
72
+ // Add a new zoneIndex at the end of the array
73
+ zoneIndices.push(zoneIndices.length > 0 ? zoneIndices[zoneIndices.length - 1] + 1 : 1);
74
+ // get section number. if not specified, get the last section
75
+ let section = args.options.order || zoneIndices.length;
76
+ if (section > zoneIndices.length) {
77
+ section = zoneIndices.length;
78
+ }
79
+ // zoneIndex that represents the section where the web part should be added
80
+ const zoneIndex = zoneIndices[section - 1];
75
81
  let zoneId;
76
82
  let backgroundControlToAdd = undefined;
77
83
  if (args.options.zoneEmphasis && ['image', 'gradient'].includes(args.options.zoneEmphasis.toLowerCase())) {
@@ -83,11 +89,17 @@ class SpoPageSectionAddCommand extends SpoCommand {
83
89
  canvasContent.push(backgroundControlToAdd);
84
90
  }
85
91
  }
92
+ // Increment the zoneIndex of all columns that are greater than or equal to the new zoneIndex
93
+ canvasContent.forEach((c) => {
94
+ if (c.position && c.position.zoneIndex >= zoneIndex) {
95
+ c.position.zoneIndex += 1;
96
+ }
97
+ });
86
98
  // get the list of columns to insert based on the selected template
87
99
  const columnsToAdd = this.getColumns(zoneIndex, args, zoneId);
88
100
  // insert the column in the right place in the array so that
89
101
  // it stays sorted ascending by zoneIndex
90
- let pos = canvasContent.findIndex(c => typeof c.controlType === 'undefined' && c.position && c.position.zoneIndex > zoneIndex);
102
+ let pos = canvasContent.findIndex(c => c.position && c.position.zoneIndex >= zoneIndex);
91
103
  if (pos === -1) {
92
104
  pos = canvasContent.length - 1;
93
105
  }
@@ -109,21 +121,6 @@ class SpoPageSectionAddCommand extends SpoCommand {
109
121
  this.handleRejectedODataJsonPromise(err);
110
122
  }
111
123
  }
112
- getSectionIndex(zoneIndices, order) {
113
- // zoneIndex of the first column on the page
114
- const minIndex = zoneIndices.length === 0 ? 0 : zoneIndices[0];
115
- // zoneIndex of the last column on the page
116
- const maxIndex = zoneIndices.length === 0 ? 0 : zoneIndices[zoneIndices.length - 1];
117
- if (!order || order > zoneIndices.length) {
118
- // no order specified, add section to the end
119
- return maxIndex === 0 ? 1 : maxIndex * 2;
120
- }
121
- // add to the beginning
122
- if (order === 1) {
123
- return minIndex / 2;
124
- }
125
- return zoneIndices[order - 2] + ((zoneIndices[order - 1] - zoneIndices[order - 2]) / 2);
126
- }
127
124
  getColumns(zoneIndex, args, zoneId) {
128
125
  const columns = [];
129
126
  let sectionIndex = 1;