@pnp/cli-microsoft365 10.6.0-beta.add4854 → 10.7.0-beta.4bcc4fe

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 (56) hide show
  1. package/allCommands.json +1 -1
  2. package/allCommandsFull.json +1 -1
  3. package/dist/Auth.js +2 -1
  4. package/dist/Command.js +10 -0
  5. package/dist/auth/MsalNetworkClient.js +48 -0
  6. package/dist/config.js +1 -0
  7. package/dist/m365/app/commands/app-get.js +3 -13
  8. package/dist/m365/app/commands/permission/permission-list.js +4 -14
  9. package/dist/m365/entra/commands/app/app-get.js +27 -21
  10. package/dist/m365/entra/commands/app/app-permission-list.js +28 -22
  11. package/dist/m365/entra/commands/app/app-remove.js +22 -19
  12. package/dist/m365/entra/commands/app/app-role-add.js +22 -19
  13. package/dist/m365/entra/commands/app/app-role-list.js +22 -19
  14. package/dist/m365/entra/commands/app/app-role-remove.js +39 -36
  15. package/dist/m365/entra/commands/app/app-set.js +22 -19
  16. package/dist/m365/entra/commands/group/group-member-add.js +1 -1
  17. package/dist/m365/entra/commands/group/group-member-remove.js +197 -0
  18. package/dist/m365/entra/commands/policy/policy-list.js +46 -3
  19. package/dist/m365/entra/commands.js +1 -0
  20. package/dist/m365/flow/commands/flow-list.js +1 -1
  21. package/dist/m365/graph/commands/openextension/openextension-get.js +57 -0
  22. package/dist/m365/graph/commands/openextension/openextension-list.js +62 -0
  23. package/dist/m365/graph/commands/openextension/openextension-remove.js +68 -0
  24. package/dist/m365/graph/commands.js +3 -0
  25. package/dist/m365/pp/commands/card/card-clone.js +7 -1
  26. package/dist/m365/pp/commands/card/card-get.js +5 -2
  27. package/dist/m365/pp/commands/card/card-remove.js +7 -1
  28. package/dist/m365/pp/commands/solution/solution-get.js +5 -11
  29. package/dist/m365/pp/commands/solution/solution-publish.js +6 -16
  30. package/dist/m365/pp/commands/solution/solution-remove.js +4 -13
  31. package/dist/m365/spfx/commands/project/DeployWorkflow.js +9 -2
  32. package/dist/m365/spfx/commands/project/project-azuredevops-pipeline-add.js +0 -19
  33. package/dist/m365/spfx/commands/project/project-doctor/doctor-1.21.0.js +25 -0
  34. package/dist/m365/spfx/commands/project/project-doctor/doctor-1.21.1.js +25 -0
  35. package/dist/m365/spfx/commands/project/project-doctor.js +3 -1
  36. package/dist/m365/spfx/commands/project/project-github-workflow-add.js +0 -16
  37. package/dist/m365/spfx/commands/project/project-upgrade/rules/FN002029_DEVDEP_microsoft_rush_stack_compiler_5_3.js +13 -0
  38. package/dist/m365/spfx/commands/project/project-upgrade/upgrade-1.21.0.js +63 -0
  39. package/dist/m365/spfx/commands/project/project-upgrade/upgrade-1.21.1.js +53 -0
  40. package/dist/m365/spfx/commands/project/project-upgrade.js +3 -1
  41. package/dist/m365/spfx/commands/spfx-doctor.js +30 -0
  42. package/dist/m365/util/commands/accesstoken/accesstoken-get.js +13 -3
  43. package/dist/utils/accessToken.js +8 -0
  44. package/dist/utils/powerPlatform.js +25 -4
  45. package/dist/utils/prompt.js +9 -2
  46. package/dist/utils/types.js +1 -0
  47. package/docs/docs/cmd/entra/group/group-member-add.mdx +1 -1
  48. package/docs/docs/cmd/entra/group/group-member-remove.mdx +96 -0
  49. package/docs/docs/cmd/entra/policy/policy-list.mdx +1 -1
  50. package/docs/docs/cmd/graph/openextension/openextension-get.mdx +111 -0
  51. package/docs/docs/cmd/graph/openextension/openextension-list.mdx +129 -0
  52. package/docs/docs/cmd/graph/openextension/openextension-remove.mdx +59 -0
  53. package/docs/docs/cmd/spfx/project/project-upgrade.mdx +1 -4
  54. package/docs/docs/cmd/util/accesstoken/accesstoken-get.mdx +72 -0
  55. package/npm-shrinkwrap.json +517 -481
  56. package/package.json +14 -14
@@ -11,6 +11,7 @@ import GraphCommand from '../../../base/GraphCommand.js';
11
11
  import commands from '../../commands.js';
12
12
  import { cli } from '../../../../cli/cli.js';
13
13
  import { optionsUtils } from '../../../../utils/optionsUtils.js';
14
+ import { entraApp } from '../../../../utils/entraApp.js';
14
15
  class EntraAppSetCommand extends GraphCommand {
15
16
  get name() {
16
17
  return commands.APP_SET;
@@ -51,27 +52,29 @@ class EntraAppSetCommand extends GraphCommand {
51
52
  if (this.verbose) {
52
53
  await logger.logToStderr(`Retrieving information about Microsoft Entra app ${appId ? appId : name}...`);
53
54
  }
54
- const filter = appId ?
55
- `appId eq '${formatting.encodeQueryParameter(appId)}'` :
56
- `displayName eq '${formatting.encodeQueryParameter(name)}'`;
57
- const requestOptions = {
58
- url: `${this.resource}/v1.0/myorganization/applications?$filter=${filter}&$select=id`,
59
- headers: {
60
- accept: 'application/json;odata.metadata=none'
61
- },
62
- responseType: 'json'
63
- };
64
- const res = await request.get(requestOptions);
65
- if (res.value.length === 1) {
66
- return res.value[0].id;
55
+ if (appId) {
56
+ const app = await entraApp.getAppRegistrationByAppId(appId, ['id']);
57
+ return app.id;
67
58
  }
68
- if (res.value.length === 0) {
69
- const applicationIdentifier = appId ? `ID ${appId}` : `name ${name}`;
70
- throw `No Microsoft Entra application registration with ${applicationIdentifier} found`;
59
+ else {
60
+ const requestOptions = {
61
+ url: `${this.resource}/v1.0/myorganization/applications?$filter=displayName eq '${formatting.encodeQueryParameter(name)}'&$select=id`,
62
+ headers: {
63
+ accept: 'application/json;odata.metadata=none'
64
+ },
65
+ responseType: 'json'
66
+ };
67
+ const res = await request.get(requestOptions);
68
+ if (res.value.length === 1) {
69
+ return res.value[0].id;
70
+ }
71
+ if (res.value.length === 0) {
72
+ throw `No Microsoft Entra application registration with name ${name} found`;
73
+ }
74
+ const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', res.value);
75
+ const result = await cli.handleMultipleResultsFound(`Multiple Microsoft Entra application registration with name '${name}' found.`, resultAsKeyValuePair);
76
+ return result.id;
71
77
  }
72
- const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', res.value);
73
- const result = await cli.handleMultipleResultsFound(`Multiple Microsoft Entra application registration with name '${name}' found.`, resultAsKeyValuePair);
74
- return result.id;
75
78
  }
76
79
  async updateUnknownOptions(args, objectId) {
77
80
  const unknownOptions = optionsUtils.getUnknownOptions(args.options, this.options);
@@ -15,7 +15,7 @@ class EntraGroupMemberAddCommand extends GraphCommand {
15
15
  return commands.GROUP_MEMBER_ADD;
16
16
  }
17
17
  get description() {
18
- return 'Adds a member to a Microsoft Entra ID group';
18
+ return 'Adds members to a Microsoft Entra group';
19
19
  }
20
20
  constructor() {
21
21
  super();
@@ -0,0 +1,197 @@
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 _EntraGroupMemberRemoveCommand_instances, _EntraGroupMemberRemoveCommand_initTelemetry, _EntraGroupMemberRemoveCommand_initOptions, _EntraGroupMemberRemoveCommand_initValidators, _EntraGroupMemberRemoveCommand_initOptionSets, _EntraGroupMemberRemoveCommand_initTypes;
7
+ import GraphCommand from '../../../base/GraphCommand.js';
8
+ import commands from '../../commands.js';
9
+ import request from '../../../../request.js';
10
+ import { cli } from '../../../../cli/cli.js';
11
+ import { entraGroup } from '../../../../utils/entraGroup.js';
12
+ import { entraUser } from '../../../../utils/entraUser.js';
13
+ import { validation } from '../../../../utils/validation.js';
14
+ class EntraGroupMemberRemoveCommand extends GraphCommand {
15
+ get name() {
16
+ return commands.GROUP_MEMBER_REMOVE;
17
+ }
18
+ get description() {
19
+ return 'Removes members from a Microsoft Entra group';
20
+ }
21
+ constructor() {
22
+ super();
23
+ _EntraGroupMemberRemoveCommand_instances.add(this);
24
+ this.roleValues = ['Owner', 'Member'];
25
+ __classPrivateFieldGet(this, _EntraGroupMemberRemoveCommand_instances, "m", _EntraGroupMemberRemoveCommand_initTelemetry).call(this);
26
+ __classPrivateFieldGet(this, _EntraGroupMemberRemoveCommand_instances, "m", _EntraGroupMemberRemoveCommand_initOptions).call(this);
27
+ __classPrivateFieldGet(this, _EntraGroupMemberRemoveCommand_instances, "m", _EntraGroupMemberRemoveCommand_initValidators).call(this);
28
+ __classPrivateFieldGet(this, _EntraGroupMemberRemoveCommand_instances, "m", _EntraGroupMemberRemoveCommand_initOptionSets).call(this);
29
+ __classPrivateFieldGet(this, _EntraGroupMemberRemoveCommand_instances, "m", _EntraGroupMemberRemoveCommand_initTypes).call(this);
30
+ }
31
+ async commandAction(logger, args) {
32
+ try {
33
+ const removeUsers = async () => {
34
+ if (this.verbose) {
35
+ await logger.logToStderr(`Removing user(s) ${args.options.userIds || args.options.userNames || args.options.subgroupIds || args.options.subgroupNames} from group ${args.options.groupId || args.options.groupName}...`);
36
+ }
37
+ const groupId = await this.getGroupId(logger, args.options);
38
+ const userIds = await this.getPrincipalIds(logger, args.options);
39
+ const endpoints = [];
40
+ if (!args.options.role || args.options.role === 'Owner') {
41
+ endpoints.push(...userIds.map(id => `/groups/${groupId}/owners/${id}/$ref`));
42
+ }
43
+ if (!args.options.role || args.options.role === 'Member') {
44
+ endpoints.push(...userIds.map(id => `/groups/${groupId}/members/${id}/$ref`));
45
+ }
46
+ for (let i = 0; i < endpoints.length; i += 20) {
47
+ const endpointsBatch = endpoints.slice(i, i + 20);
48
+ const requestOptions = {
49
+ url: `${this.resource}/v1.0/$batch`,
50
+ headers: {
51
+ 'content-type': 'application/json;odata.metadata=none'
52
+ },
53
+ responseType: 'json',
54
+ data: {
55
+ requests: endpointsBatch.map((ep, index) => ({
56
+ id: index + 1,
57
+ method: 'DELETE',
58
+ url: ep,
59
+ headers: {
60
+ 'content-type': 'application/json;odata.metadata=none'
61
+ }
62
+ }))
63
+ }
64
+ };
65
+ const res = await request.post(requestOptions);
66
+ for (const response of res.responses) {
67
+ // Suppress 404 errors if suppressNotFound is set
68
+ if (response.status !== 204 && (!args.options.suppressNotFound || response.status !== 404)) {
69
+ throw response.body;
70
+ }
71
+ }
72
+ }
73
+ };
74
+ if (args.options.force) {
75
+ await removeUsers();
76
+ }
77
+ else {
78
+ const principals = args.options.userIds || args.options.userNames || args.options.subgroupIds || args.options.subgroupNames;
79
+ const principalsList = principals.split(',');
80
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove ${principalsList.length} principal(s) from group '${args.options.groupId || args.options.groupName}'?` });
81
+ if (result) {
82
+ await removeUsers();
83
+ }
84
+ }
85
+ }
86
+ catch (err) {
87
+ this.handleRejectedODataJsonPromise(err);
88
+ }
89
+ }
90
+ async getGroupId(logger, options) {
91
+ if (options.groupId) {
92
+ return options.groupId;
93
+ }
94
+ if (this.verbose) {
95
+ await logger.logToStderr(`Retrieving ID of group '${options.groupName}'...`);
96
+ }
97
+ return entraGroup.getGroupIdByDisplayName(options.groupName);
98
+ }
99
+ async getPrincipalIds(logger, options) {
100
+ if (options.userIds) {
101
+ return options.userIds.split(',').map(i => i.trim());
102
+ }
103
+ if (options.subgroupIds) {
104
+ return options.subgroupIds.split(',').map(i => i.trim());
105
+ }
106
+ if (options.userNames) {
107
+ if (this.verbose) {
108
+ await logger.logToStderr('Retrieving ID(s) of user(s)...');
109
+ }
110
+ return entraUser.getUserIdsByUpns(options.userNames.split(',').map(u => u.trim()));
111
+ }
112
+ // Subgroup names were specified
113
+ if (this.verbose) {
114
+ await logger.logToStderr('Retrieving ID(s) of subgroup(s)...');
115
+ }
116
+ const subGroupIds = [];
117
+ for (const subgroupName of options.subgroupNames.split(',')) {
118
+ const groupId = await entraGroup.getGroupIdByDisplayName(subgroupName.trim());
119
+ subGroupIds.push(groupId);
120
+ }
121
+ return subGroupIds;
122
+ }
123
+ }
124
+ _EntraGroupMemberRemoveCommand_instances = new WeakSet(), _EntraGroupMemberRemoveCommand_initTelemetry = function _EntraGroupMemberRemoveCommand_initTelemetry() {
125
+ this.telemetry.push((args) => {
126
+ Object.assign(this.telemetryProperties, {
127
+ groupId: typeof args.options.groupId !== 'undefined',
128
+ groupName: typeof args.options.groupName !== 'undefined',
129
+ userIds: typeof args.options.userIds !== 'undefined',
130
+ userNames: typeof args.options.userNames !== 'undefined',
131
+ subgroupIds: typeof args.options.subgroupIds !== 'undefined',
132
+ subgroupNames: typeof args.options.subgroupNames !== 'undefined',
133
+ role: typeof args.options.role !== 'undefined',
134
+ suppressNotFound: !!args.options.suppressNotFound,
135
+ force: !!args.options.force
136
+ });
137
+ });
138
+ }, _EntraGroupMemberRemoveCommand_initOptions = function _EntraGroupMemberRemoveCommand_initOptions() {
139
+ this.options.unshift({
140
+ option: '-i, --groupId [groupId]'
141
+ }, {
142
+ option: '-n, --groupName [groupName]'
143
+ }, {
144
+ option: '--userIds [userIds]'
145
+ }, {
146
+ option: '--userNames [userNames]'
147
+ }, {
148
+ option: '--subgroupIds [subgroupIds]'
149
+ }, {
150
+ option: '--subgroupNames [subgroupNames]'
151
+ }, {
152
+ option: '-r, --role [role]',
153
+ autocomplete: this.roleValues
154
+ }, {
155
+ option: '--suppressNotFound'
156
+ }, {
157
+ option: '-f, --force'
158
+ });
159
+ }, _EntraGroupMemberRemoveCommand_initValidators = function _EntraGroupMemberRemoveCommand_initValidators() {
160
+ this.validators.push(async (args) => {
161
+ if (args.options.groupId !== undefined && !validation.isValidGuid(args.options.groupId)) {
162
+ return `'${args.options.groupId}' is not a valid GUID for option 'groupId'.`;
163
+ }
164
+ if (args.options.userIds !== undefined) {
165
+ const invalidGuids = validation.isValidGuidArray(args.options.userIds);
166
+ if (invalidGuids !== true) {
167
+ return `Invalid GUIDs found for option 'ids': ${invalidGuids}.`;
168
+ }
169
+ }
170
+ if (args.options.userNames !== undefined) {
171
+ const invalidUpns = validation.isValidUserPrincipalNameArray(args.options.userNames);
172
+ if (invalidUpns !== true) {
173
+ return `Invalid UPNs found for option 'userNames': ${invalidUpns}.`;
174
+ }
175
+ }
176
+ if (args.options.subgroupIds !== undefined) {
177
+ const invalidGuids = validation.isValidGuidArray(args.options.subgroupIds);
178
+ if (invalidGuids !== true) {
179
+ return `Invalid GUIDs found for option 'subgroupIds': ${invalidGuids}.`;
180
+ }
181
+ }
182
+ if (args.options.role !== undefined && this.roleValues.indexOf(args.options.role) === -1) {
183
+ return `Option 'role' must be one of the following values: ${this.roleValues.join(', ')}.`;
184
+ }
185
+ if ((args.options.subgroupIds !== undefined || args.options.subgroupNames !== undefined) && args.options.role?.toLowerCase() !== 'member') {
186
+ return `When removing subgroups, the 'role' option must be set to 'Member'.`;
187
+ }
188
+ return true;
189
+ });
190
+ }, _EntraGroupMemberRemoveCommand_initOptionSets = function _EntraGroupMemberRemoveCommand_initOptionSets() {
191
+ this.optionSets.push({ options: ['groupId', 'groupName'] }, { options: ['userIds', 'userNames', 'subgroupIds', 'subgroupNames'] });
192
+ }, _EntraGroupMemberRemoveCommand_initTypes = function _EntraGroupMemberRemoveCommand_initTypes() {
193
+ this.types.string.push('groupId', 'groupName', 'ids', 'userNames', 'subgroupIds', 'subgroupNames', 'role');
194
+ this.types.boolean.push('force', 'suppressNotFound');
195
+ };
196
+ export default new EntraGroupMemberRemoveCommand();
197
+ //# sourceMappingURL=group-member-remove.js.map
@@ -9,10 +9,22 @@ import GraphCommand from '../../../base/GraphCommand.js';
9
9
  import commands from '../../commands.js';
10
10
  const policyEndPoints = {
11
11
  activitybasedtimeout: "activityBasedTimeoutPolicies",
12
+ adminconsentrequest: "adminConsentRequestPolicy",
13
+ appManagement: "appManagementPolicies",
14
+ authenticationflows: "authenticationFlowsPolicy",
15
+ authenticationmethods: "authenticationMethodsPolicy",
16
+ authenticationstrength: "authenticationStrengthPolicies",
12
17
  authorization: "authorizationPolicy",
13
18
  claimsmapping: "claimsMappingPolicies",
19
+ conditionalaccess: "conditionalAccessPolicies",
20
+ crosstenantaccess: "crossTenantAccessPolicy",
21
+ defaultappmanagement: "defaultAppManagementPolicy",
22
+ deviceregistration: "deviceRegistrationPolicy",
23
+ featurerolloutpolicy: "featureRolloutPolicies",
14
24
  homerealmdiscovery: "homeRealmDiscoveryPolicies",
15
25
  identitysecuritydefaultsenforcement: "identitySecurityDefaultsEnforcementPolicy",
26
+ permissiongrant: "permissionGrantPolicies",
27
+ rolemanagement: "roleManagementPolicies",
16
28
  tokenissuance: "tokenIssuancePolicies",
17
29
  tokenlifetime: "tokenLifetimePolicies"
18
30
  };
@@ -56,15 +68,26 @@ class EntraPolicyListCommand extends GraphCommand {
56
68
  }
57
69
  async getPolicies(policyType) {
58
70
  const endpoint = policyEndPoints[policyType];
71
+ let requestUrl = `${this.resource}/v1.0/policies/${endpoint}`;
72
+ if (endpoint === policyEndPoints.rolemanagement) {
73
+ // roleManagementPolicies endpoint requires $filter query parameter
74
+ requestUrl += `?$filter=scopeId eq '/' and scopeType eq 'DirectoryRole'`;
75
+ }
59
76
  const requestOptions = {
60
- url: `${this.resource}/v1.0/policies/${endpoint}`,
77
+ url: requestUrl,
61
78
  headers: {
62
79
  accept: 'application/json;odata.metadata=none'
63
80
  },
64
81
  responseType: 'json'
65
82
  };
66
83
  const response = await request.get(requestOptions);
67
- if (endpoint === policyEndPoints.authorization ||
84
+ if (endpoint === policyEndPoints.adminconsentrequest ||
85
+ endpoint === policyEndPoints.authenticationflows ||
86
+ endpoint === policyEndPoints.authenticationmethods ||
87
+ endpoint === policyEndPoints.authorization ||
88
+ endpoint === policyEndPoints.crosstenantaccess ||
89
+ endpoint === policyEndPoints.defaultappmanagement ||
90
+ endpoint === policyEndPoints.deviceregistration ||
68
91
  endpoint === policyEndPoints.identitysecuritydefaultsenforcement) {
69
92
  return response;
70
93
  }
@@ -95,6 +118,26 @@ _a = EntraPolicyListCommand, _EntraPolicyListCommand_instances = new WeakSet(),
95
118
  return true;
96
119
  });
97
120
  };
98
- EntraPolicyListCommand.supportedPolicyTypes = ['activityBasedTimeout', 'authorization', 'claimsMapping', 'homeRealmDiscovery', 'identitySecurityDefaultsEnforcement', 'tokenIssuance', 'tokenLifetime'];
121
+ EntraPolicyListCommand.supportedPolicyTypes = [
122
+ 'activityBasedTimeout',
123
+ 'adminConsentRequest',
124
+ 'appManagement',
125
+ 'authenticationFlows',
126
+ 'authenticationMethods',
127
+ 'authenticationStrength',
128
+ 'authorization',
129
+ 'claimsMapping',
130
+ 'conditionalAccess',
131
+ 'crossTenantAccess',
132
+ 'defaultAppManagement',
133
+ 'deviceRegistration',
134
+ 'featureRolloutPolicy',
135
+ 'homeRealmDiscovery',
136
+ 'identitySecurityDefaultsEnforcement',
137
+ 'permissionGrant',
138
+ 'roleManagement',
139
+ 'tokenIssuance',
140
+ 'tokenLifetime'
141
+ ];
99
142
  export default new EntraPolicyListCommand();
100
143
  //# sourceMappingURL=policy-list.js.map
@@ -39,6 +39,7 @@ export default {
39
39
  GROUP_ADD: `${prefix} group add`,
40
40
  GROUP_GET: `${prefix} group get`,
41
41
  GROUP_LIST: `${prefix} group list`,
42
+ GROUP_MEMBER_REMOVE: `${prefix} group member remove`,
42
43
  GROUP_REMOVE: `${prefix} group remove`,
43
44
  GROUP_SET: `${prefix} group set`,
44
45
  GROUP_MEMBER_ADD: `${prefix} group member add`,
@@ -29,7 +29,7 @@ class FlowListCommand extends PowerAutomateCommand {
29
29
  }
30
30
  async commandAction(logger, args) {
31
31
  if (this.verbose) {
32
- await logger.logToStderr(`Getting Power Automate flows${args.options.asAdmin && ' as admin'} in environment '${args.options.environmentName}'...`);
32
+ await logger.logToStderr(`Getting Power Automate flows${args.options.asAdmin ? ' as admin' : ''} in environment '${args.options.environmentName}'...`);
33
33
  }
34
34
  try {
35
35
  const { environmentName, asAdmin, sharingStatus, includeSolutions } = args.options;
@@ -0,0 +1,57 @@
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
+ const options = globalOptionsZod
9
+ .extend({
10
+ resourceId: zod.alias('i', z.string()),
11
+ resourceType: zod.alias('t', z.enum(['user', 'group', 'device', 'organization'])),
12
+ name: zod.alias('n', z.string())
13
+ })
14
+ .strict();
15
+ class GraphOpenExtensionGetCommand extends GraphCommand {
16
+ get name() {
17
+ return commands.OPENEXTENSION_GET;
18
+ }
19
+ get description() {
20
+ return 'Retrieves a specific open extension for a resource';
21
+ }
22
+ get schema() {
23
+ return options;
24
+ }
25
+ getRefinedSchema(schema) {
26
+ return schema
27
+ .refine(options => options.resourceType !== 'group' && options.resourceType !== 'device' && options.resourceType !== 'organization' || (options.resourceId && validation.isValidGuid(options.resourceId)), options => ({
28
+ message: `The '${options.resourceId}' must be a valid GUID`,
29
+ path: ['resourceId']
30
+ }))
31
+ .refine(options => options.resourceType !== 'user' || (options.resourceId && (validation.isValidGuid(options.resourceId) || validation.isValidUserPrincipalName(options.resourceId))), options => ({
32
+ message: `The '${options.resourceId}' must be a valid GUID or user principal name`,
33
+ path: ['resourceId']
34
+ }));
35
+ }
36
+ async commandAction(logger, args) {
37
+ try {
38
+ if (this.verbose) {
39
+ await logger.logToStderr(`Retrieving open extension for resource ${args.options.resourceId}...`);
40
+ }
41
+ const requestOptions = {
42
+ url: `${this.resource}/v1.0/${args.options.resourceType}${args.options.resourceType === 'organization' ? '' : 's'}/${args.options.resourceId}/extensions/${args.options.name}`,
43
+ headers: {
44
+ accept: 'application/json;odata.metadata=none'
45
+ },
46
+ responseType: 'json'
47
+ };
48
+ const res = await request.get(requestOptions);
49
+ await logger.log(res);
50
+ }
51
+ catch (err) {
52
+ this.handleRejectedODataJsonPromise(err);
53
+ }
54
+ }
55
+ }
56
+ export default new GraphOpenExtensionGetCommand();
57
+ //# sourceMappingURL=openextension-get.js.map
@@ -0,0 +1,62 @@
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 { odata } from '../../../../utils/odata.js';
8
+ const options = globalOptionsZod
9
+ .extend({
10
+ resourceId: zod.alias('i', z.string()),
11
+ resourceType: zod.alias('t', z.enum(['user', 'group', 'device', 'organization']))
12
+ })
13
+ .strict();
14
+ class GraphOpenExtensionListCommand extends GraphCommand {
15
+ get name() {
16
+ return commands.OPENEXTENSION_LIST;
17
+ }
18
+ get description() {
19
+ return 'Retrieves all open extensions for a resource';
20
+ }
21
+ defaultProperties() {
22
+ return ['id', 'extensionName'];
23
+ }
24
+ get schema() {
25
+ return options;
26
+ }
27
+ getRefinedSchema(schema) {
28
+ return schema
29
+ .refine(options => options.resourceType !== 'group' && options.resourceType !== 'device' && options.resourceType !== 'organization' ||
30
+ (options.resourceId && validation.isValidGuid(options.resourceId)), options => ({
31
+ message: `The '${options.resourceId}' must be a valid GUID`,
32
+ path: ['resourceId']
33
+ }))
34
+ .refine(options => options.resourceType !== 'user' ||
35
+ (options.resourceId && (validation.isValidGuid(options.resourceId) || validation.isValidUserPrincipalName(options.resourceId))), options => ({
36
+ message: `The '${options.resourceId}' must be a valid GUID or user principal name`,
37
+ path: ['resourceId']
38
+ }));
39
+ }
40
+ async commandAction(logger, args) {
41
+ try {
42
+ const requestOptions = {
43
+ url: `${this.resource}/v1.0/${args.options.resourceType}${args.options.resourceType === 'organization' ? '' : 's'}/${args.options.resourceId}/extensions`,
44
+ headers: {
45
+ accept: 'application/json;odata.metadata=none',
46
+ 'content-type': 'application/json'
47
+ },
48
+ responseType: 'json'
49
+ };
50
+ if (args.options.verbose) {
51
+ await logger.logToStderr(`Retrieving open extensions for the ${args.options.resourceType} with id '${args.options.resourceId}'...`);
52
+ }
53
+ const res = await odata.getAllItems(requestOptions);
54
+ await logger.log(res);
55
+ }
56
+ catch (err) {
57
+ this.handleRejectedODataJsonPromise(err);
58
+ }
59
+ }
60
+ }
61
+ export default new GraphOpenExtensionListCommand();
62
+ //# sourceMappingURL=openextension-list.js.map
@@ -0,0 +1,68 @@
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 { cli } from '../../../../cli/cli.js';
8
+ import request from '../../../../request.js';
9
+ const options = globalOptionsZod
10
+ .extend({
11
+ resourceId: zod.alias('i', z.string()),
12
+ resourceType: zod.alias('t', z.enum(['user', 'group', 'device', 'organization'])),
13
+ name: zod.alias('n', z.string()),
14
+ force: zod.alias('f', z.boolean().optional())
15
+ })
16
+ .strict();
17
+ class GraphOpenExtensionRemoveCommand extends GraphCommand {
18
+ get name() {
19
+ return commands.OPENEXTENSION_REMOVE;
20
+ }
21
+ get description() {
22
+ return 'Removes a specific open extension for a resource';
23
+ }
24
+ get schema() {
25
+ return options;
26
+ }
27
+ getRefinedSchema(schema) {
28
+ return schema
29
+ .refine(options => options.resourceType !== 'group' && options.resourceType !== 'device' && options.resourceType !== 'organization' || (options.resourceId && validation.isValidGuid(options.resourceId)), options => ({
30
+ message: `The '${options.resourceId}' must be a valid GUID`,
31
+ path: ['resourceId']
32
+ }))
33
+ .refine(options => options.resourceType !== 'user' || (options.resourceId && (validation.isValidGuid(options.resourceId) || validation.isValidUserPrincipalName(options.resourceId))), options => ({
34
+ message: `The '${options.resourceId}' must be a valid GUID or user principal name`,
35
+ path: ['resourceId']
36
+ }));
37
+ }
38
+ async commandAction(logger, args) {
39
+ const removeOpenExtension = async () => {
40
+ try {
41
+ if (this.verbose) {
42
+ await logger.logToStderr(`Removing open extension for resource ${args.options.resourceId}...`);
43
+ }
44
+ const requestOptions = {
45
+ url: `${this.resource}/v1.0/${args.options.resourceType}${args.options.resourceType === 'organization' ? '' : 's'}/${args.options.resourceId}/extensions/${args.options.name}`,
46
+ headers: {
47
+ accept: 'application/json;odata.metadata=none'
48
+ }
49
+ };
50
+ await request.delete(requestOptions);
51
+ }
52
+ catch (err) {
53
+ this.handleRejectedODataJsonPromise(err);
54
+ }
55
+ };
56
+ if (args.options.force) {
57
+ await removeOpenExtension();
58
+ }
59
+ else {
60
+ const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove open extension '${args.options.name}' from resource '${args.options.resourceId}' of type '${args.options.resourceType}'?` });
61
+ if (result) {
62
+ await removeOpenExtension();
63
+ }
64
+ }
65
+ }
66
+ }
67
+ export default new GraphOpenExtensionRemoveCommand();
68
+ //# sourceMappingURL=openextension-remove.js.map
@@ -5,6 +5,9 @@ export default {
5
5
  DIRECTORYEXTENSION_GET: `${prefix} directoryextension get`,
6
6
  DIRECTORYEXTENSION_REMOVE: `${prefix} directoryextension remove`,
7
7
  OPENEXTENSION_ADD: `${prefix} openextension add`,
8
+ OPENEXTENSION_GET: `${prefix} openextension get`,
9
+ OPENEXTENSION_LIST: `${prefix} openextension list`,
10
+ OPENEXTENSION_REMOVE: `${prefix} openextension remove`,
8
11
  SCHEMAEXTENSION_ADD: `${prefix} schemaextension add`,
9
12
  SCHEMAEXTENSION_GET: `${prefix} schemaextension get`,
10
13
  SCHEMAEXTENSION_LIST: `${prefix} schemaextension list`,
@@ -35,13 +35,19 @@ class PpCardCloneCommand extends PowerPlatformCommand {
35
35
  if (args.options.id) {
36
36
  return args.options.id;
37
37
  }
38
- const card = await powerPlatform.getCardByName(dynamicsApiUrl, args.options.name, logger, this.verbose);
38
+ if (this.verbose) {
39
+ await logger.logToStderr(`Retrieving the card Id for card '${args.options.name}'`);
40
+ }
41
+ const card = await powerPlatform.getCardByName(dynamicsApiUrl, args.options.name);
39
42
  return card.cardid;
40
43
  }
41
44
  async cloneCard(args, logger) {
42
45
  try {
43
46
  const dynamicsApiUrl = await powerPlatform.getDynamicsInstanceApiUrl(args.options.environmentName, args.options.asAdmin);
44
47
  const cardId = await this.getCardId(args, dynamicsApiUrl, logger);
48
+ if (this.verbose) {
49
+ await logger.logToStderr(`Cloning the card with id '${cardId}'`);
50
+ }
45
51
  const requestOptions = {
46
52
  url: `${dynamicsApiUrl}/api/data/v9.1/CardCreateClone`,
47
53
  headers: {
@@ -39,10 +39,13 @@ class PpCardGetCommand extends PowerPlatformCommand {
39
39
  }
40
40
  async getCard(dynamicsApiUrl, options, logger) {
41
41
  if (options.name) {
42
- return await powerPlatform.getCardByName(dynamicsApiUrl, options.name, logger, this.verbose);
42
+ if (this.verbose) {
43
+ await logger.logToStderr(`Retrieving the card with name '${options.name}'`);
44
+ }
45
+ return await powerPlatform.getCardByName(dynamicsApiUrl, options.name);
43
46
  }
44
47
  if (this.verbose) {
45
- await logger.logToStderr(`Retrieving the card with id ${options.id}`);
48
+ await logger.logToStderr(`Retrieving the card with id '${options.id}'`);
46
49
  }
47
50
  const requestOptions = {
48
51
  url: `${dynamicsApiUrl}/api/data/v9.1/cards(${options.id})`,
@@ -43,13 +43,19 @@ class PpCardRemoveCommand extends PowerPlatformCommand {
43
43
  if (args.options.id) {
44
44
  return args.options.id;
45
45
  }
46
- const card = await powerPlatform.getCardByName(dynamicsApiUrl, args.options.name, logger, this.verbose);
46
+ if (this.verbose) {
47
+ await logger.logToStderr(`Retrieving the card with name '${args.options.name}'`);
48
+ }
49
+ const card = await powerPlatform.getCardByName(dynamicsApiUrl, args.options.name);
47
50
  return card.cardid;
48
51
  }
49
52
  async deleteCard(args, logger) {
50
53
  try {
51
54
  const dynamicsApiUrl = await powerPlatform.getDynamicsInstanceApiUrl(args.options.environmentName, args.options.asAdmin);
52
55
  const cardId = await this.getCardId(args, dynamicsApiUrl, logger);
56
+ if (this.verbose) {
57
+ await logger.logToStderr(`Deleting card with Id '${cardId}'`);
58
+ }
53
59
  const requestOptions = {
54
60
  url: `${dynamicsApiUrl}/api/data/v9.1/cards(${cardId})`,
55
61
  headers: {
@@ -49,23 +49,17 @@ class PpSolutionGetCommand extends PowerPlatformCommand {
49
49
  }
50
50
  }
51
51
  async getSolution(dynamicsApiUrl, options) {
52
+ if (options.name) {
53
+ return powerPlatform.getSolutionByName(dynamicsApiUrl, options.name);
54
+ }
52
55
  const requestOptions = {
53
56
  headers: {
54
57
  accept: 'application/json;odata.metadata=none'
55
58
  },
56
59
  responseType: 'json'
57
60
  };
58
- if (options.id) {
59
- requestOptions.url = `${dynamicsApiUrl}/api/data/v9.0/solutions(${options.id})?$expand=publisherid($select=friendlyname)&$select=solutionid,uniquename,version,publisherid,installedon,solutionpackageversion,friendlyname,versionnumber&api-version=9.1`;
60
- const result = await request.get(requestOptions);
61
- return result;
62
- }
63
- requestOptions.url = `${dynamicsApiUrl}/api/data/v9.0/solutions?$filter=isvisible eq true and uniquename eq \'${options.name}\'&$expand=publisherid($select=friendlyname)&$select=solutionid,uniquename,version,publisherid,installedon,solutionpackageversion,friendlyname,versionnumber&api-version=9.1`;
64
- const result = await request.get(requestOptions);
65
- if (result.value.length === 0) {
66
- throw `The specified solution '${options.name}' does not exist.`;
67
- }
68
- return result.value[0];
61
+ requestOptions.url = `${dynamicsApiUrl}/api/data/v9.0/solutions(${options.id})?$expand=publisherid($select=friendlyname)&$select=solutionid,uniquename,version,publisherid,installedon,solutionpackageversion,friendlyname,versionnumber&api-version=9.1`;
62
+ return request.get(requestOptions);
69
63
  }
70
64
  }
71
65
  _PpSolutionGetCommand_instances = new WeakSet(), _PpSolutionGetCommand_initTelemetry = function _PpSolutionGetCommand_initTelemetry() {