@knowttl/mg-axi 0.1.0

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 (57) hide show
  1. package/README.md +1138 -0
  2. package/dist/api.js +953 -0
  3. package/dist/app-auth.js +47 -0
  4. package/dist/auth.js +59 -0
  5. package/dist/bin/mg-axi.js +7 -0
  6. package/dist/catalogue.js +2191 -0
  7. package/dist/cli.js +1314 -0
  8. package/dist/docs.js +559 -0
  9. package/dist/doctor.js +75 -0
  10. package/dist/entra-access-reviews.js +425 -0
  11. package/dist/entra-apps.js +374 -0
  12. package/dist/entra-audit-logs.js +381 -0
  13. package/dist/entra-auth-methods.js +296 -0
  14. package/dist/entra-ca-policy-update.js +353 -0
  15. package/dist/entra-certificate-auth.js +384 -0
  16. package/dist/entra-conditional-access.js +317 -0
  17. package/dist/entra-contacts.js +827 -0
  18. package/dist/entra-contracts.js +252 -0
  19. package/dist/entra-custom-security-attributes.js +464 -0
  20. package/dist/entra-data-policy-operations.js +274 -0
  21. package/dist/entra-delegated-admin.js +468 -0
  22. package/dist/entra-deleted-items.js +461 -0
  23. package/dist/entra-directory-objects.js +274 -0
  24. package/dist/entra-directory.js +411 -0
  25. package/dist/entra-domains.js +399 -0
  26. package/dist/entra-entitlement-management.js +645 -0
  27. package/dist/entra-federation-configurations.js +290 -0
  28. package/dist/entra-grants.js +272 -0
  29. package/dist/entra-group-lifecycle.js +349 -0
  30. package/dist/entra-group-member-add.js +278 -0
  31. package/dist/entra-groups.js +336 -0
  32. package/dist/entra-identity-providers.js +297 -0
  33. package/dist/entra-lifecycle-workflows.js +673 -0
  34. package/dist/entra-multi-tenant-organization.js +309 -0
  35. package/dist/entra-on-premises-synchronization.js +231 -0
  36. package/dist/entra-organization.js +398 -0
  37. package/dist/entra-risk-dismiss.js +191 -0
  38. package/dist/entra-risk.js +404 -0
  39. package/dist/entra-roles.js +310 -0
  40. package/dist/entra-subscriptions.js +289 -0
  41. package/dist/entra-tenant-information.js +152 -0
  42. package/dist/entra-terms-of-use.js +380 -0
  43. package/dist/entra-user-revoke-sessions.js +170 -0
  44. package/dist/entra-user-update.js +170 -0
  45. package/dist/entra-users.js +211 -0
  46. package/dist/graph-session.js +1034 -0
  47. package/dist/msal-app-provider.js +42 -0
  48. package/dist/msal-provider.js +82 -0
  49. package/dist/mutations.js +529 -0
  50. package/dist/profiles.js +139 -0
  51. package/dist/setup.js +116 -0
  52. package/dist/version.js +2 -0
  53. package/docs/coverage.md +1028 -0
  54. package/inventory/operations.json +4 -0
  55. package/inventory/schema.json +71 -0
  56. package/package.json +32 -0
  57. package/skills/mg-axi/SKILL.md +293 -0
package/dist/cli.js ADDED
@@ -0,0 +1,1314 @@
1
+ import { encode } from "@toon-format/toon";
2
+ import { AxiError, runAxiCli } from "axi-sdk-js";
3
+ import { LEAVES, home, leafHelp, operationFor, resolveCommand, DESCRIPTION, TOP_LEVEL_HELP } from "./catalogue.js";
4
+ import { VERSION } from "./version.js";
5
+ import { Profiles } from "./profiles.js";
6
+ import { GraphSession, MAX_CURSOR_BYTES } from "./graph-session.js";
7
+ import { listUsers, showUser } from "./entra-users.js";
8
+ import { updateUserAccount } from "./entra-user-update.js";
9
+ import { revokeUserSessions } from "./entra-user-revoke-sessions.js";
10
+ import { createMutationCoordinator, mutationFetchTransport } from "./mutations.js";
11
+ import { TRANSITIVE_OPERATION, listGroupMemberOf, listGroupMembers, listGroups, showGroup } from "./entra-groups.js";
12
+ import { listDirectoryRoles, showDirectoryRole, listRoleAssignments, listPimEligible, listPimActive } from "./entra-roles.js";
13
+ import { listAdministrativeUnitMembers, listAdministrativeUnits, listDevices, showAdministrativeUnit, showDevice } from "./entra-directory.js";
14
+ import { listSignIns, showSignIn, listDirectoryAudits, showDirectoryAudit } from "./entra-audit-logs.js";
15
+ import { listApplicationOwners, listApplications, listServicePrincipalOwners, listServicePrincipals, showApplication, showServicePrincipal } from "./entra-apps.js";
16
+ import { listAppRoleAssignments, listOAuth2Grants } from "./entra-grants.js";
17
+ import { listRiskyUsers, showRiskyUser, listRiskDetections, showRiskDetection } from "./entra-risk.js";
18
+ import { dismissRiskyUser } from "./entra-risk-dismiss.js";
19
+ import { listPolicies, showPolicy, listNamedLocations, showNamedLocation } from "./entra-conditional-access.js";
20
+ import { listBrandingLocalizations, listOrganizations, showBranding, showBrandingLocalization, showOrganization } from "./entra-organization.js";
21
+ import { updateCaPolicy } from "./entra-ca-policy-update.js";
22
+ import { listDomains, showDomain, listVerificationDnsRecords, showVerificationDnsRecord, listServiceConfigurationRecords, showServiceConfigurationRecord, listDomainDnsRecords, showDomainDnsRecord } from "./entra-domains.js";
23
+ import { listCertificateAuthPkis, showCertificateAuthPki, countCertificateAuthPkis, listCertificateAuthorities, showCertificateAuthority, countCertificateAuthorities } from "./entra-certificate-auth.js";
24
+ import { listSubscriptions, showSubscription, countSubscriptions } from "./entra-subscriptions.js";
25
+ import { listSynchronizations, showSynchronization } from "./entra-on-premises-synchronization.js";
26
+ import { listAgreements, showAgreement, listAgreementAcceptances, showAgreementAcceptance, listAcceptances, showAcceptance } from "./entra-terms-of-use.js";
27
+ import { listDirectoryObjects, showDirectoryObject, countDirectoryObjects } from "./entra-directory-objects.js";
28
+ import { listDeletedItems, showDeletedItem, countDeletedItems } from "./entra-deleted-items.js";
29
+ import { listContacts, showContact, countContacts, showContactManager, listContactDirectReports, showContactDirectReport, countContactDirectReports, castDirectReports, listContactMemberOf, showContactMemberOf, countContactMemberOf, transitMembership, castMembership } from "./entra-contacts.js";
30
+ import { countContracts, listContracts, showContract } from "./entra-contracts.js";
31
+ import { listDelegatedAdminCustomers, showDelegatedAdminCustomer, listDelegatedAdminRelationships, showDelegatedAdminRelationship, listDelegatedAdminAccessAssignments, showDelegatedAdminAccessAssignment, listDelegatedAdminOperations, showDelegatedAdminOperation, listDelegatedAdminRequests, showDelegatedAdminRequest, listDelegatedAdminServiceManagementDetails, showDelegatedAdminServiceManagementDetail } from "./entra-delegated-admin.js";
32
+ import { listMultiTenantOrganizationTenants, showMultiTenantOrganization, showMultiTenantOrganizationJoinRequest, countMultiTenantOrganizationTenants } from "./entra-multi-tenant-organization.js";
33
+ import { showTenantInformation } from "./entra-tenant-information.js";
34
+ import { countLifecyclePolicies, listLifecyclePolicies, showLifecyclePolicy, countSettingTemplates, listSettingTemplates, showSettingTemplate } from "./entra-group-lifecycle.js";
35
+ import { listAttributeSets, showAttributeSet, countAttributeSets, listCustomSecurityAttributeDefinitions, showCustomSecurityAttributeDefinition, countCustomSecurityAttributeDefinitions, listAllowedValues, showAllowedValue, countAllowedValues } from "./entra-custom-security-attributes.js";
36
+ import { listIdentityProviders, showIdentityProvider, countIdentityProviders, availableIdentityProviderTypes } from "./entra-identity-providers.js";
37
+ import { listFederationConfigurations, showFederationConfiguration, countFederationConfigurations, availableFederationProviderTypes } from "./entra-federation-configurations.js";
38
+ import { listDataPolicyOperations, showDataPolicyOperation, countDataPolicyOperations } from "./entra-data-policy-operations.js";
39
+ import { listDefinitions, showDefinition, listInstances, showInstance, listDecisions, showDecision, listContactedReviewers, showContactedReviewer, listStages, showStage } from "./entra-access-reviews.js";
40
+ import { listCatalogs, showCatalog, countCatalogs, listAccessPackages, showAccessPackage, countAccessPackages, listAssignmentPolicies, showAssignmentPolicy, countAssignmentPolicies, listResourceRoleScopes, showResourceRoleScope, countResourceRoleScopes, listAssignments, showAssignment, countAssignments, listAssignmentRequests, showAssignmentRequest, countAssignmentRequests } from "./entra-entitlement-management.js";
41
+ import { listWorkflows, showWorkflow, countWorkflows, listWorkflowTemplates, showWorkflowTemplate, countWorkflowTemplates, listTaskDefinitions, showTaskDefinition, countTaskDefinitions, showLifecycleSettings, listRuns, showRun, countRuns, listUserProcessingResults, showUserProcessingResult, countUserProcessingResults, listSubjectProcessingResults, showSubjectProcessingResult, countSubjectProcessingResults, listTaskReports, showTaskReport, countTaskReports, showTaskReportTask, showTaskReportTaskDefinition } from "./entra-lifecycle-workflows.js";
42
+ import { listAuthenticationMethods, listRegistrationDetails } from "./entra-auth-methods.js";
43
+ import { addGroupMember } from "./entra-group-member-add.js";
44
+ import { fetchTransport } from "./api.js";
45
+ import { doctorTargets, runDoctor } from "./doctor.js";
46
+ import { setupView } from "./setup.js";
47
+ function localHome(name) {
48
+ const output = home();
49
+ const store = new Profiles();
50
+ if (name || store.list().length) {
51
+ try {
52
+ const selected = store.resolve(name);
53
+ output.profile = selected.name;
54
+ output.tenant = selected.profile.tenantId;
55
+ }
56
+ catch (error) {
57
+ if (name || !(error instanceof AxiError) || error.code !== "AUTH_REQUIRED")
58
+ throw error;
59
+ output.profile = "unavailable: no default profile selected";
60
+ }
61
+ }
62
+ output.help.unshift("npx -y @knowttl/mg-axi profile list", "npx -y @knowttl/mg-axi login --help");
63
+ return output;
64
+ }
65
+ async function readCursor(cursor) {
66
+ if (cursor !== "-")
67
+ return cursor;
68
+ const chunks = [];
69
+ let bytes = 0;
70
+ for await (const chunk of process.stdin) {
71
+ const buffer = Buffer.from(chunk);
72
+ bytes += buffer.length;
73
+ if (bytes > MAX_CURSOR_BYTES)
74
+ throw new AxiError(`Collection cursor exceeds ${MAX_CURSOR_BYTES} bytes`, "VALIDATION_ERROR", ["Use a cursor within the supported size ceiling"]);
75
+ chunks.push(buffer);
76
+ }
77
+ return Buffer.concat(chunks).toString("utf8");
78
+ }
79
+ export async function executeArgv(argv, overrides = {}) {
80
+ const { leaf, flags, positional } = resolveCommand(argv);
81
+ if (flags.help)
82
+ return leafHelp(leaf);
83
+ if (leaf.path === "home")
84
+ return localHome(flags.profile);
85
+ const profiles = new Profiles();
86
+ if (leaf.path === "profile create") {
87
+ if (String(flags.mode ?? "delegated") !== "application" && (flags["certificate-thumbprint"] !== undefined || flags.federated))
88
+ throw new AxiError("Certificate and federated credentials belong to application profiles; pass --mode application", "VALIDATION_ERROR", [leafHelp(leaf)]);
89
+ return profiles.create(String(flags.name), String(flags.tenant), String(flags.client), String(flags.cloud), !!flags["allow-device-code"], String(flags.mode ?? "delegated") === "application"
90
+ ? { certificateThumbprint: flags["certificate-thumbprint"] === undefined ? undefined : String(flags["certificate-thumbprint"]), federated: !!flags.federated }
91
+ : undefined);
92
+ }
93
+ if (leaf.path === "profile list") {
94
+ const items = profiles.list();
95
+ return items.length ? { profiles: items, help: ["npx -y @knowttl/mg-axi profile show --profile <name>", "npx -y @knowttl/mg-axi login --help"] } : { profiles: "0 profiles configured", help: ["npx -y @knowttl/mg-axi profile create --help"] };
96
+ }
97
+ if (leaf.path === "profile show")
98
+ return profiles.resolve(flags.profile);
99
+ if (leaf.path === "setup")
100
+ return setupView(profiles);
101
+ if (leaf.path === "doctor") {
102
+ const names = doctorTargets(profiles, flags.profile);
103
+ let delegated = overrides.delegated;
104
+ let application = overrides.application;
105
+ if (!delegated) {
106
+ const { DelegatedAuth: Service } = await import("./auth.js");
107
+ const { MsalProvider } = await import("./msal-provider.js");
108
+ delegated = new Service(new MsalProvider());
109
+ }
110
+ if (!application) {
111
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
112
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
113
+ application = new Service(new MsalApplicationProvider());
114
+ }
115
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
116
+ // A failing profile still reports its bounded read on stdout; the
117
+ // nonzero exit travels through process state, never the payload.
118
+ const result = await runDoctor({ store: profiles, names, session });
119
+ if (result.failed)
120
+ process.exitCode = 1;
121
+ return result.output;
122
+ }
123
+ if (leaf.path === "login") {
124
+ const selected = profiles.resolve(flags.profile);
125
+ if (selected.profile.mode !== "delegated")
126
+ throw new AxiError("Application profiles authenticate with client credentials; interactive login is unavailable", "VALIDATION_ERROR", ["mg-axi profile show --profile <name>", "Application tokens are acquired silently with the configured Graph .default audience"]);
127
+ const { DelegatedAuth } = await import("./auth.js");
128
+ const { MsalProvider } = await import("./msal-provider.js");
129
+ return { profile: selected.name, ...await new DelegatedAuth(new MsalProvider()).login(selected.profile, String(flags.method ?? "browser"), String(flags.scopes).split(",")) };
130
+ }
131
+ if (leaf.path === "entra conditional-access policy list" || leaf.path === "entra conditional-access policy show" || leaf.path === "entra conditional-access named-location list" || leaf.path === "entra conditional-access named-location show") {
132
+ const selected = profiles.resolve(flags.profile);
133
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
134
+ if (!operation || operation.method !== "GET") {
135
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
136
+ }
137
+ if (flags.cursor !== undefined)
138
+ flags.cursor = (await readCursor(String(flags.cursor)));
139
+ let delegated = overrides.delegated;
140
+ let application = overrides.application;
141
+ if (!delegated) {
142
+ const { DelegatedAuth: Service } = await import("./auth.js");
143
+ const { MsalProvider } = await import("./msal-provider.js");
144
+ delegated = new Service(new MsalProvider());
145
+ }
146
+ if (!application) {
147
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
148
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
149
+ application = new Service(new MsalApplicationProvider());
150
+ }
151
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
152
+ const help = leafHelp(leaf);
153
+ switch (leaf.path) {
154
+ case "entra conditional-access policy list": return listPolicies(session, flags, selected.profile, operation, help, selected.name);
155
+ case "entra conditional-access policy show": return showPolicy(session, flags, selected.profile, operation, help, selected.name);
156
+ case "entra conditional-access named-location list": return listNamedLocations(session, flags, selected.profile, operation, help, selected.name);
157
+ default: return showNamedLocation(session, flags, selected.profile, operation, help, selected.name);
158
+ }
159
+ }
160
+ if (leaf.path === "entra access-review definition list" || leaf.path === "entra access-review definition show" || leaf.path === "entra access-review instance list" || leaf.path === "entra access-review instance show" || leaf.path === "entra access-review decision list" || leaf.path === "entra access-review decision show" || leaf.path === "entra access-review contacted-reviewer list" || leaf.path === "entra access-review contacted-reviewer show" || leaf.path === "entra access-review stage list" || leaf.path === "entra access-review stage show") {
161
+ const selected = profiles.resolve(flags.profile);
162
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
163
+ if (!operation || operation.method !== "GET") {
164
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
165
+ }
166
+ if (flags.cursor !== undefined)
167
+ flags.cursor = (await readCursor(String(flags.cursor)));
168
+ let delegated = overrides.delegated;
169
+ let application = overrides.application;
170
+ if (!delegated) {
171
+ const { DelegatedAuth: Service } = await import("./auth.js");
172
+ const { MsalProvider } = await import("./msal-provider.js");
173
+ delegated = new Service(new MsalProvider());
174
+ }
175
+ if (!application) {
176
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
177
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
178
+ application = new Service(new MsalApplicationProvider());
179
+ }
180
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
181
+ const help = leafHelp(leaf);
182
+ switch (leaf.path) {
183
+ case "entra access-review definition list": return listDefinitions(session, flags, selected.profile, operation, help, selected.name);
184
+ case "entra access-review definition show": return showDefinition(session, flags, selected.profile, operation, help, selected.name);
185
+ case "entra access-review instance list": return listInstances(session, flags, selected.profile, operation, help, selected.name);
186
+ case "entra access-review instance show": return showInstance(session, flags, selected.profile, operation, help, selected.name);
187
+ case "entra access-review decision show": return showDecision(session, flags, selected.profile, operation, help, selected.name);
188
+ case "entra access-review contacted-reviewer list": return listContactedReviewers(session, flags, selected.profile, operation, help, selected.name);
189
+ case "entra access-review contacted-reviewer show": return showContactedReviewer(session, flags, selected.profile, operation, help, selected.name);
190
+ case "entra access-review stage list": return listStages(session, flags, selected.profile, operation, help, selected.name);
191
+ case "entra access-review stage show": return showStage(session, flags, selected.profile, operation, help, selected.name);
192
+ default: return listDecisions(session, flags, selected.profile, operation, help, selected.name);
193
+ }
194
+ }
195
+ if (leaf.path === "entra entitlement catalog list" || leaf.path === "entra entitlement catalog show" || leaf.path === "entra entitlement catalog count" || leaf.path === "entra entitlement access-package list" || leaf.path === "entra entitlement access-package show" || leaf.path === "entra entitlement access-package count" || leaf.path === "entra entitlement assignment-policy list" || leaf.path === "entra entitlement assignment-policy show" || leaf.path === "entra entitlement assignment-policy count" || leaf.path === "entra entitlement resource-role-scope list" || leaf.path === "entra entitlement resource-role-scope show" || leaf.path === "entra entitlement resource-role-scope count" || leaf.path === "entra entitlement assignment list" || leaf.path === "entra entitlement assignment show" || leaf.path === "entra entitlement assignment count" || leaf.path === "entra entitlement assignment-request list" || leaf.path === "entra entitlement assignment-request show" || leaf.path === "entra entitlement assignment-request count") {
196
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
197
+ throw new AxiError("Entitlement-management reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
198
+ }
199
+ const selected = profiles.resolve(flags.profile);
200
+ const operation = operationFor(leaf, "v1.0");
201
+ if (!operation || operation.method !== "GET") {
202
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
203
+ }
204
+ if (flags.cursor !== undefined)
205
+ flags.cursor = (await readCursor(String(flags.cursor)));
206
+ let delegated = overrides.delegated;
207
+ let application = overrides.application;
208
+ if (!delegated) {
209
+ const { DelegatedAuth: Service } = await import("./auth.js");
210
+ const { MsalProvider } = await import("./msal-provider.js");
211
+ delegated = new Service(new MsalProvider());
212
+ }
213
+ if (!application) {
214
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
215
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
216
+ application = new Service(new MsalApplicationProvider());
217
+ }
218
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
219
+ const help = leafHelp(leaf);
220
+ switch (leaf.path) {
221
+ case "entra entitlement catalog list": return listCatalogs(session, flags, selected.profile, operation, help, selected.name);
222
+ case "entra entitlement catalog show": return showCatalog(session, flags, selected.profile, operation, help, selected.name);
223
+ case "entra entitlement catalog count": return countCatalogs(session, flags, selected.profile, operation, help, selected.name);
224
+ case "entra entitlement access-package list": return listAccessPackages(session, flags, selected.profile, operation, help, selected.name);
225
+ case "entra entitlement access-package show": return showAccessPackage(session, flags, selected.profile, operation, help, selected.name);
226
+ case "entra entitlement access-package count": return countAccessPackages(session, flags, selected.profile, operation, help, selected.name);
227
+ case "entra entitlement assignment-policy list": return listAssignmentPolicies(session, flags, selected.profile, operation, help, selected.name);
228
+ case "entra entitlement assignment-policy show": return showAssignmentPolicy(session, flags, selected.profile, operation, help, selected.name);
229
+ case "entra entitlement assignment-policy count": return countAssignmentPolicies(session, flags, selected.profile, operation, help, selected.name);
230
+ case "entra entitlement resource-role-scope list": return listResourceRoleScopes(session, flags, selected.profile, operation, help, selected.name);
231
+ case "entra entitlement resource-role-scope show": return showResourceRoleScope(session, flags, selected.profile, operation, help, selected.name);
232
+ case "entra entitlement assignment list": return listAssignments(session, flags, selected.profile, operation, help, selected.name);
233
+ case "entra entitlement assignment show": return showAssignment(session, flags, selected.profile, operation, help, selected.name);
234
+ case "entra entitlement assignment count": return countAssignments(session, flags, selected.profile, operation, help, selected.name);
235
+ case "entra entitlement assignment-request list": return listAssignmentRequests(session, flags, selected.profile, operation, help, selected.name);
236
+ case "entra entitlement assignment-request show": return showAssignmentRequest(session, flags, selected.profile, operation, help, selected.name);
237
+ case "entra entitlement assignment-request count": return countAssignmentRequests(session, flags, selected.profile, operation, help, selected.name);
238
+ default: return countResourceRoleScopes(session, flags, selected.profile, operation, help, selected.name);
239
+ }
240
+ }
241
+ if (leaf.path === "entra lifecycle workflow list" || leaf.path === "entra lifecycle workflow show" || leaf.path === "entra lifecycle workflow count" || leaf.path === "entra lifecycle workflow-template list" || leaf.path === "entra lifecycle workflow-template show" || leaf.path === "entra lifecycle workflow-template count" || leaf.path === "entra lifecycle task-definition list" || leaf.path === "entra lifecycle task-definition show" || leaf.path === "entra lifecycle task-definition count" || leaf.path === "entra lifecycle settings show" || leaf.path === "entra lifecycle run list" || leaf.path === "entra lifecycle run show" || leaf.path === "entra lifecycle run count" || leaf.path === "entra lifecycle user-processing-result list" || leaf.path === "entra lifecycle user-processing-result show" || leaf.path === "entra lifecycle user-processing-result count" || leaf.path === "entra lifecycle subject-processing-result list" || leaf.path === "entra lifecycle subject-processing-result show" || leaf.path === "entra lifecycle subject-processing-result count" || leaf.path === "entra lifecycle task-report list" || leaf.path === "entra lifecycle task-report show" || leaf.path === "entra lifecycle task-report count" || leaf.path === "entra lifecycle task-report task show" || leaf.path === "entra lifecycle task-report task-definition show") {
242
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
243
+ throw new AxiError("Lifecycle-workflow reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
244
+ }
245
+ const selected = profiles.resolve(flags.profile);
246
+ const operation = operationFor(leaf, "v1.0");
247
+ if (!operation || operation.method !== "GET") {
248
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
249
+ }
250
+ if (flags.cursor !== undefined)
251
+ flags.cursor = (await readCursor(String(flags.cursor)));
252
+ let delegated = overrides.delegated;
253
+ let application = overrides.application;
254
+ if (!delegated) {
255
+ const { DelegatedAuth: Service } = await import("./auth.js");
256
+ const { MsalProvider } = await import("./msal-provider.js");
257
+ delegated = new Service(new MsalProvider());
258
+ }
259
+ if (!application) {
260
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
261
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
262
+ application = new Service(new MsalApplicationProvider());
263
+ }
264
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
265
+ const help = leafHelp(leaf);
266
+ switch (leaf.path) {
267
+ case "entra lifecycle workflow list": return listWorkflows(session, flags, selected.profile, operation, help, selected.name);
268
+ case "entra lifecycle workflow show": return showWorkflow(session, flags, selected.profile, operation, help, selected.name);
269
+ case "entra lifecycle workflow count": return countWorkflows(session, flags, selected.profile, operation, help, selected.name);
270
+ case "entra lifecycle workflow-template list": return listWorkflowTemplates(session, flags, selected.profile, operation, help, selected.name);
271
+ case "entra lifecycle workflow-template show": return showWorkflowTemplate(session, flags, selected.profile, operation, help, selected.name);
272
+ case "entra lifecycle workflow-template count": return countWorkflowTemplates(session, flags, selected.profile, operation, help, selected.name);
273
+ case "entra lifecycle task-definition list": return listTaskDefinitions(session, flags, selected.profile, operation, help, selected.name);
274
+ case "entra lifecycle task-definition show": return showTaskDefinition(session, flags, selected.profile, operation, help, selected.name);
275
+ case "entra lifecycle task-definition count": return countTaskDefinitions(session, flags, selected.profile, operation, help, selected.name);
276
+ case "entra lifecycle run list": return listRuns(session, flags, selected.profile, operation, help, selected.name);
277
+ case "entra lifecycle run show": return showRun(session, flags, selected.profile, operation, help, selected.name);
278
+ case "entra lifecycle run count": return countRuns(session, flags, selected.profile, operation, help, selected.name);
279
+ case "entra lifecycle user-processing-result list": return listUserProcessingResults(session, flags, selected.profile, operation, help, selected.name);
280
+ case "entra lifecycle user-processing-result show": return showUserProcessingResult(session, flags, selected.profile, operation, help, selected.name);
281
+ case "entra lifecycle user-processing-result count": return countUserProcessingResults(session, flags, selected.profile, operation, help, selected.name);
282
+ case "entra lifecycle subject-processing-result list": return listSubjectProcessingResults(session, flags, selected.profile, operation, help, selected.name);
283
+ case "entra lifecycle subject-processing-result show": return showSubjectProcessingResult(session, flags, selected.profile, operation, help, selected.name);
284
+ case "entra lifecycle subject-processing-result count": return countSubjectProcessingResults(session, flags, selected.profile, operation, help, selected.name);
285
+ case "entra lifecycle task-report list": return listTaskReports(session, flags, selected.profile, operation, help, selected.name);
286
+ case "entra lifecycle task-report show": return showTaskReport(session, flags, selected.profile, operation, help, selected.name);
287
+ case "entra lifecycle task-report count": return countTaskReports(session, flags, selected.profile, operation, help, selected.name);
288
+ case "entra lifecycle task-report task show": return showTaskReportTask(session, flags, selected.profile, operation, help, selected.name);
289
+ case "entra lifecycle task-report task-definition show": return showTaskReportTaskDefinition(session, flags, selected.profile, operation, help, selected.name);
290
+ default: return showLifecycleSettings(session, flags, selected.profile, operation, help, selected.name);
291
+ }
292
+ }
293
+ if (leaf.path === "api get") {
294
+ const selected = profiles.resolve(flags.profile);
295
+ const { runApiGet } = await import("./api.js");
296
+ const { DelegatedAuth } = await import("./auth.js");
297
+ const { ApplicationAuth } = await import("./app-auth.js");
298
+ const { MsalProvider } = await import("./msal-provider.js");
299
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
300
+ const cursor = await readCursor(flags.cursor === undefined ? undefined : String(flags.cursor));
301
+ return runApiGet({
302
+ path: positional,
303
+ apiVersion: String(flags["api-version"] ?? "v1.0"),
304
+ odata: flags.odata === undefined ? undefined : String(flags.odata),
305
+ cursor,
306
+ scopes: flags.scopes === undefined ? undefined : String(flags.scopes),
307
+ limit: flags.all ? undefined : flags.limit === undefined ? 100 : Number(flags.limit),
308
+ full: !!flags.full,
309
+ profile: selected.profile,
310
+ }, {
311
+ delegated: new DelegatedAuth(new MsalProvider()),
312
+ application: new ApplicationAuth(new MsalApplicationProvider()),
313
+ transport: fetchTransport,
314
+ });
315
+ }
316
+ if (leaf.path === "entra user list" || leaf.path === "entra user show") {
317
+ const selected = profiles.resolve(flags.profile);
318
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
319
+ if (!operation || operation.method !== "GET") {
320
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
321
+ }
322
+ let delegated = overrides.delegated;
323
+ let application = overrides.application;
324
+ if (!delegated) {
325
+ const { DelegatedAuth: Service } = await import("./auth.js");
326
+ const { MsalProvider } = await import("./msal-provider.js");
327
+ delegated = new Service(new MsalProvider());
328
+ }
329
+ if (!application) {
330
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
331
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
332
+ application = new Service(new MsalApplicationProvider());
333
+ }
334
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
335
+ return leaf.path === "entra user list"
336
+ ? listUsers(session, flags, selected.profile, operation, leafHelp(leaf), selected.name)
337
+ : showUser(session, flags, selected.profile, operation, leafHelp(leaf), selected.name);
338
+ }
339
+ if (leaf.path === "entra user update") {
340
+ const selected = profiles.resolve(flags.profile);
341
+ const readLeaf = LEAVES.find(item => item.path === "entra user show");
342
+ const readOperation = operationFor(readLeaf, "v1.0");
343
+ if (!readOperation || readOperation.method !== "GET") {
344
+ throw new AxiError(`Unknown catalogued Graph operation for ${readLeaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
345
+ }
346
+ let delegated = overrides.delegated;
347
+ let application = overrides.application;
348
+ if (!delegated) {
349
+ const { DelegatedAuth: Service } = await import("./auth.js");
350
+ const { MsalProvider } = await import("./msal-provider.js");
351
+ delegated = new Service(new MsalProvider());
352
+ }
353
+ if (!application) {
354
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
355
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
356
+ application = new Service(new MsalApplicationProvider());
357
+ }
358
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
359
+ const coordinator = createMutationCoordinator({
360
+ profile: selected.profile,
361
+ delegated,
362
+ application,
363
+ transport: overrides.mutationTransport ?? mutationFetchTransport,
364
+ ...(overrides.journalPath !== undefined ? { journalPath: overrides.journalPath } : {}),
365
+ });
366
+ return updateUserAccount({
367
+ session,
368
+ coordinator,
369
+ flags,
370
+ profile: selected.profile,
371
+ profileName: selected.name,
372
+ readOperation,
373
+ help: leafHelp(leaf),
374
+ });
375
+ }
376
+ if (leaf.path === "entra user revoke-sessions") {
377
+ const selected = profiles.resolve(flags.profile);
378
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
379
+ if (!operation || operation.method !== "POST") {
380
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
381
+ }
382
+ const readLeaf = LEAVES.find(item => item.path === "entra user show");
383
+ const readOperation = operationFor(readLeaf, "v1.0");
384
+ if (!readOperation || readOperation.method !== "GET") {
385
+ throw new AxiError(`Unknown catalogued Graph operation for ${readLeaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
386
+ }
387
+ let delegated = overrides.delegated;
388
+ let application = overrides.application;
389
+ if (!delegated) {
390
+ const { DelegatedAuth: Service } = await import("./auth.js");
391
+ const { MsalProvider } = await import("./msal-provider.js");
392
+ delegated = new Service(new MsalProvider());
393
+ }
394
+ if (!application) {
395
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
396
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
397
+ application = new Service(new MsalApplicationProvider());
398
+ }
399
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
400
+ const coordinator = createMutationCoordinator({
401
+ profile: selected.profile,
402
+ delegated,
403
+ application,
404
+ transport: overrides.mutationTransport ?? mutationFetchTransport,
405
+ ...(overrides.journalPath !== undefined ? { journalPath: overrides.journalPath } : {}),
406
+ });
407
+ return revokeUserSessions({
408
+ session,
409
+ coordinator,
410
+ flags,
411
+ profile: selected.profile,
412
+ profileName: selected.name,
413
+ readOperation,
414
+ help: leafHelp(leaf),
415
+ });
416
+ }
417
+ if (leaf.path === "entra conditional-access policy update") {
418
+ const selected = profiles.resolve(flags.profile);
419
+ const readLeaf = LEAVES.find(item => item.path === "entra conditional-access policy show");
420
+ const readOperation = operationFor(readLeaf, "v1.0");
421
+ if (!readOperation || readOperation.method !== "GET") {
422
+ throw new AxiError(`Unknown catalogued Graph operation for ${readLeaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
423
+ }
424
+ let delegated = overrides.delegated;
425
+ let application = overrides.application;
426
+ if (!delegated) {
427
+ const { DelegatedAuth: Service } = await import("./auth.js");
428
+ const { MsalProvider } = await import("./msal-provider.js");
429
+ delegated = new Service(new MsalProvider());
430
+ }
431
+ if (!application) {
432
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
433
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
434
+ application = new Service(new MsalApplicationProvider());
435
+ }
436
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
437
+ const coordinator = createMutationCoordinator({
438
+ profile: selected.profile,
439
+ delegated,
440
+ application,
441
+ transport: overrides.mutationTransport ?? mutationFetchTransport,
442
+ ...(overrides.journalPath !== undefined ? { journalPath: overrides.journalPath } : {}),
443
+ });
444
+ return updateCaPolicy({
445
+ session,
446
+ coordinator,
447
+ flags,
448
+ profile: selected.profile,
449
+ profileName: selected.name,
450
+ readOperation,
451
+ help: leafHelp(leaf),
452
+ });
453
+ }
454
+ if (leaf.path === "entra user authentication-method list" || leaf.path === "entra registration list") {
455
+ const selected = profiles.resolve(flags.profile);
456
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
457
+ if (!operation || operation.method !== "GET") {
458
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
459
+ }
460
+ let delegated = overrides.delegated;
461
+ let application = overrides.application;
462
+ if (!delegated) {
463
+ const { DelegatedAuth: Service } = await import("./auth.js");
464
+ const { MsalProvider } = await import("./msal-provider.js");
465
+ delegated = new Service(new MsalProvider());
466
+ }
467
+ if (!application) {
468
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
469
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
470
+ application = new Service(new MsalApplicationProvider());
471
+ }
472
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
473
+ const help = leafHelp(leaf);
474
+ return leaf.path === "entra user authentication-method list"
475
+ ? listAuthenticationMethods(session, flags, selected.profile, operation, help, selected.name)
476
+ : listRegistrationDetails(session, flags, selected.profile, operation, help, selected.name);
477
+ }
478
+ if (leaf.path === "entra group list" || leaf.path === "entra group show" || leaf.path === "entra group member list" || leaf.path === "entra group member-of list") {
479
+ const selected = profiles.resolve(flags.profile);
480
+ const template = flags.transitive === true
481
+ ? (() => {
482
+ const alternate = TRANSITIVE_OPERATION[leaf.operation];
483
+ if (!alternate)
484
+ throw new AxiError("--transitive is available for group member and member-of lists only", "VALIDATION_ERROR", [leafHelp(leaf)]);
485
+ return alternate;
486
+ })()
487
+ : leaf.operation;
488
+ const operation = operationFor({ ...leaf, operation: template }, String(flags["api-version"] ?? "v1.0"));
489
+ if (!operation || operation.method !== "GET") {
490
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
491
+ }
492
+ let delegated = overrides.delegated;
493
+ let application = overrides.application;
494
+ if (!delegated) {
495
+ const { DelegatedAuth: Service } = await import("./auth.js");
496
+ const { MsalProvider } = await import("./msal-provider.js");
497
+ delegated = new Service(new MsalProvider());
498
+ }
499
+ if (!application) {
500
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
501
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
502
+ application = new Service(new MsalApplicationProvider());
503
+ }
504
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
505
+ if (leaf.path === "entra group list")
506
+ return listGroups(session, flags, selected.profile, operation, leafHelp(leaf), selected.name);
507
+ if (leaf.path === "entra group show")
508
+ return showGroup(session, flags, selected.profile, operation, leafHelp(leaf), selected.name);
509
+ return leaf.path === "entra group member list"
510
+ ? listGroupMembers(session, flags, selected.profile, operation, leafHelp(leaf), selected.name)
511
+ : listGroupMemberOf(session, flags, selected.profile, operation, leafHelp(leaf), selected.name);
512
+ }
513
+ if (leaf.path === "entra group member add") {
514
+ const selected = profiles.resolve(flags.profile);
515
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
516
+ if (!operation || operation.method !== "POST") {
517
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
518
+ }
519
+ let delegated = overrides.delegated;
520
+ let application = overrides.application;
521
+ if (!delegated) {
522
+ const { DelegatedAuth: Service } = await import("./auth.js");
523
+ const { MsalProvider } = await import("./msal-provider.js");
524
+ delegated = new Service(new MsalProvider());
525
+ }
526
+ if (!application) {
527
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
528
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
529
+ application = new Service(new MsalApplicationProvider());
530
+ }
531
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
532
+ return addGroupMember({
533
+ session,
534
+ profile: selected.profile,
535
+ delegated,
536
+ application,
537
+ transport: overrides.mutationTransport ?? mutationFetchTransport,
538
+ flags,
539
+ profileName: selected.name,
540
+ help: leafHelp(leaf),
541
+ });
542
+ }
543
+ if (leaf.path === "entra directory-role list" || leaf.path === "entra directory-role show" || leaf.path === "entra role-assignment list" || leaf.path === "entra pim eligible list" || leaf.path === "entra pim active list"
544
+ || leaf.path === "entra device list" || leaf.path === "entra device show"
545
+ || leaf.path === "entra administrative-unit list" || leaf.path === "entra administrative-unit show"
546
+ || leaf.path === "entra administrative-unit member list") {
547
+ const selected = profiles.resolve(flags.profile);
548
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
549
+ if (!operation || operation.method !== "GET") {
550
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
551
+ }
552
+ let delegated = overrides.delegated;
553
+ let application = overrides.application;
554
+ if (!delegated) {
555
+ const { DelegatedAuth: Service } = await import("./auth.js");
556
+ const { MsalProvider } = await import("./msal-provider.js");
557
+ delegated = new Service(new MsalProvider());
558
+ }
559
+ if (!application) {
560
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
561
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
562
+ application = new Service(new MsalApplicationProvider());
563
+ }
564
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
565
+ const help = leafHelp(leaf);
566
+ switch (leaf.path) {
567
+ case "entra directory-role list": return listDirectoryRoles(session, flags, selected.profile, operation, help, selected.name);
568
+ case "entra directory-role show": return showDirectoryRole(session, flags, selected.profile, operation, help, selected.name);
569
+ case "entra role-assignment list": return listRoleAssignments(session, flags, selected.profile, operation, help, selected.name);
570
+ case "entra pim eligible list": return listPimEligible(session, flags, selected.profile, operation, help, selected.name);
571
+ case "entra pim active list": return listPimActive(session, flags, selected.profile, operation, help, selected.name);
572
+ case "entra device list": return listDevices(session, flags, selected.profile, operation, help, selected.name);
573
+ case "entra device show": return showDevice(session, flags, selected.profile, operation, help, selected.name);
574
+ case "entra administrative-unit list": return listAdministrativeUnits(session, flags, selected.profile, operation, help, selected.name);
575
+ case "entra administrative-unit show": return showAdministrativeUnit(session, flags, selected.profile, operation, help, selected.name);
576
+ default: return listAdministrativeUnitMembers(session, flags, selected.profile, operation, help, selected.name);
577
+ }
578
+ }
579
+ if (leaf.path === "entra organization list" || leaf.path === "entra organization show"
580
+ || leaf.path === "entra organization branding show"
581
+ || leaf.path === "entra organization branding-localization list" || leaf.path === "entra organization branding-localization show") {
582
+ const selected = profiles.resolve(flags.profile);
583
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
584
+ if (!operation || operation.method !== "GET") {
585
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
586
+ }
587
+ let delegated = overrides.delegated;
588
+ let application = overrides.application;
589
+ if (!delegated) {
590
+ const { DelegatedAuth: Service } = await import("./auth.js");
591
+ const { MsalProvider } = await import("./msal-provider.js");
592
+ delegated = new Service(new MsalProvider());
593
+ }
594
+ if (!application) {
595
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
596
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
597
+ application = new Service(new MsalApplicationProvider());
598
+ }
599
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
600
+ const help = leafHelp(leaf);
601
+ switch (leaf.path) {
602
+ case "entra organization list": return listOrganizations(session, flags, selected.profile, operation, help, selected.name);
603
+ case "entra organization show": return showOrganization(session, flags, selected.profile, operation, help, selected.name);
604
+ case "entra organization branding show": return showBranding(session, flags, selected.profile, operation, help, selected.name);
605
+ case "entra organization branding-localization list": return listBrandingLocalizations(session, flags, selected.profile, operation, help, selected.name);
606
+ default: return showBrandingLocalization(session, flags, selected.profile, operation, help, selected.name);
607
+ }
608
+ }
609
+ if (leaf.path === "entra sign-in list" || leaf.path === "entra sign-in show" || leaf.path === "entra directory-audit list" || leaf.path === "entra directory-audit show" || leaf.path === "entra application list" || leaf.path === "entra application show" || leaf.path === "entra service-principal list" || leaf.path === "entra service-principal show" || leaf.path === "entra application owner list" || leaf.path === "entra service-principal owner list") {
610
+ const selected = profiles.resolve(flags.profile);
611
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
612
+ if (!operation || operation.method !== "GET") {
613
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
614
+ }
615
+ if ((leaf.path.startsWith("entra sign-in ") || leaf.path.startsWith("entra directory-audit ")) && flags.cursor !== undefined)
616
+ flags.cursor = (await readCursor(String(flags.cursor)));
617
+ let delegated = overrides.delegated;
618
+ let application = overrides.application;
619
+ if (!delegated) {
620
+ const { DelegatedAuth: Service } = await import("./auth.js");
621
+ const { MsalProvider } = await import("./msal-provider.js");
622
+ delegated = new Service(new MsalProvider());
623
+ }
624
+ if (!application) {
625
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
626
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
627
+ application = new Service(new MsalApplicationProvider());
628
+ }
629
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
630
+ const help = leafHelp(leaf);
631
+ switch (leaf.path) {
632
+ case "entra sign-in list": return listSignIns(session, flags, selected.profile, operation, help, selected.name);
633
+ case "entra sign-in show": return showSignIn(session, flags, selected.profile, operation, help, selected.name);
634
+ case "entra directory-audit list": return listDirectoryAudits(session, flags, selected.profile, operation, help, selected.name);
635
+ case "entra directory-audit show": return showDirectoryAudit(session, flags, selected.profile, operation, help, selected.name);
636
+ case "entra application list": return listApplications(session, flags, selected.profile, operation, help, selected.name);
637
+ case "entra application show": return showApplication(session, flags, selected.profile, operation, help, selected.name);
638
+ case "entra service-principal list": return listServicePrincipals(session, flags, selected.profile, operation, help, selected.name);
639
+ case "entra service-principal show": return showServicePrincipal(session, flags, selected.profile, operation, help, selected.name);
640
+ case "entra application owner list": return listApplicationOwners(session, flags, selected.profile, operation, help, selected.name);
641
+ default: return listServicePrincipalOwners(session, flags, selected.profile, operation, help, selected.name);
642
+ }
643
+ }
644
+ if (leaf.path === "entra service-principal oauth2-grant list" || leaf.path === "entra service-principal app-role-assignment list") {
645
+ const selected = profiles.resolve(flags.profile);
646
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
647
+ if (!operation || operation.method !== "GET") {
648
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
649
+ }
650
+ let delegated = overrides.delegated;
651
+ let application = overrides.application;
652
+ if (!delegated) {
653
+ const { DelegatedAuth: Service } = await import("./auth.js");
654
+ const { MsalProvider } = await import("./msal-provider.js");
655
+ delegated = new Service(new MsalProvider());
656
+ }
657
+ if (!application) {
658
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
659
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
660
+ application = new Service(new MsalApplicationProvider());
661
+ }
662
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
663
+ const help = leafHelp(leaf);
664
+ return leaf.path === "entra service-principal oauth2-grant list"
665
+ ? listOAuth2Grants(session, flags, selected.profile, operation, help, selected.name)
666
+ : listAppRoleAssignments(session, flags, selected.profile, operation, help, selected.name);
667
+ }
668
+ if (leaf.path === "entra risky-user dismiss") {
669
+ const selected = profiles.resolve(flags.profile);
670
+ const readLeaf = LEAVES.find(item => item.path === "entra risky-user show");
671
+ const readOperation = operationFor(readLeaf, "v1.0");
672
+ if (!readOperation || readOperation.method !== "GET") {
673
+ throw new AxiError(`Unknown catalogued Graph operation for ${readLeaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
674
+ }
675
+ let delegated = overrides.delegated;
676
+ let application = overrides.application;
677
+ if (!delegated) {
678
+ const { DelegatedAuth: Service } = await import("./auth.js");
679
+ const { MsalProvider } = await import("./msal-provider.js");
680
+ delegated = new Service(new MsalProvider());
681
+ }
682
+ if (!application) {
683
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
684
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
685
+ application = new Service(new MsalApplicationProvider());
686
+ }
687
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
688
+ const coordinator = createMutationCoordinator({
689
+ profile: selected.profile,
690
+ delegated,
691
+ application,
692
+ transport: overrides.mutationTransport ?? mutationFetchTransport,
693
+ ...(overrides.journalPath !== undefined ? { journalPath: overrides.journalPath } : {}),
694
+ });
695
+ return dismissRiskyUser({
696
+ session,
697
+ coordinator,
698
+ flags,
699
+ profile: selected.profile,
700
+ profileName: selected.name,
701
+ readOperation,
702
+ help: leafHelp(leaf),
703
+ });
704
+ }
705
+ if (leaf.path === "entra risky-user list" || leaf.path === "entra risky-user show" || leaf.path === "entra risk-detection list" || leaf.path === "entra risk-detection show") {
706
+ const selected = profiles.resolve(flags.profile);
707
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
708
+ if (!operation || operation.method !== "GET") {
709
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
710
+ }
711
+ if (flags.cursor !== undefined)
712
+ flags.cursor = (await readCursor(String(flags.cursor)));
713
+ let delegated = overrides.delegated;
714
+ let application = overrides.application;
715
+ if (!delegated) {
716
+ const { DelegatedAuth: Service } = await import("./auth.js");
717
+ const { MsalProvider } = await import("./msal-provider.js");
718
+ delegated = new Service(new MsalProvider());
719
+ }
720
+ if (!application) {
721
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
722
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
723
+ application = new Service(new MsalApplicationProvider());
724
+ }
725
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
726
+ const help = leafHelp(leaf);
727
+ switch (leaf.path) {
728
+ case "entra risky-user list": return listRiskyUsers(session, flags, selected.profile, operation, help, selected.name);
729
+ case "entra risky-user show": return showRiskyUser(session, flags, selected.profile, operation, help, selected.name);
730
+ case "entra risk-detection list": return listRiskDetections(session, flags, selected.profile, operation, help, selected.name);
731
+ default: return showRiskDetection(session, flags, selected.profile, operation, help, selected.name);
732
+ }
733
+ }
734
+ if (leaf.path === "entra domain list" || leaf.path === "entra domain show"
735
+ || leaf.path === "entra domain verification-dns-record list" || leaf.path === "entra domain verification-dns-record show"
736
+ || leaf.path === "entra domain service-configuration-record list" || leaf.path === "entra domain service-configuration-record show"
737
+ || leaf.path === "entra domain-dns-record list" || leaf.path === "entra domain-dns-record show") {
738
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
739
+ throw new AxiError("Domain reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
740
+ }
741
+ const selected = profiles.resolve(flags.profile);
742
+ const operation = operationFor(leaf, "v1.0");
743
+ if (!operation || operation.method !== "GET") {
744
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
745
+ }
746
+ let delegated = overrides.delegated;
747
+ let application = overrides.application;
748
+ if (!delegated) {
749
+ const { DelegatedAuth: Service } = await import("./auth.js");
750
+ const { MsalProvider } = await import("./msal-provider.js");
751
+ delegated = new Service(new MsalProvider());
752
+ }
753
+ if (!application) {
754
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
755
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
756
+ application = new Service(new MsalApplicationProvider());
757
+ }
758
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
759
+ const help = leafHelp(leaf);
760
+ switch (leaf.path) {
761
+ case "entra domain list": return listDomains(session, flags, selected.profile, operation, help, selected.name);
762
+ case "entra domain show": return showDomain(session, flags, selected.profile, operation, help, selected.name);
763
+ case "entra domain verification-dns-record list": return listVerificationDnsRecords(session, flags, selected.profile, operation, help, selected.name);
764
+ case "entra domain verification-dns-record show": return showVerificationDnsRecord(session, flags, selected.profile, operation, help, selected.name);
765
+ case "entra domain service-configuration-record list": return listServiceConfigurationRecords(session, flags, selected.profile, operation, help, selected.name);
766
+ case "entra domain service-configuration-record show": return showServiceConfigurationRecord(session, flags, selected.profile, operation, help, selected.name);
767
+ case "entra domain-dns-record list": return listDomainDnsRecords(session, flags, selected.profile, operation, help, selected.name);
768
+ default: return showDomainDnsRecord(session, flags, selected.profile, operation, help, selected.name);
769
+ }
770
+ }
771
+ if (leaf.path === "entra certificate-auth-pki list" || leaf.path === "entra certificate-auth-pki show" || leaf.path === "entra certificate-auth-pki count"
772
+ || leaf.path === "entra certificate-authority list" || leaf.path === "entra certificate-authority show" || leaf.path === "entra certificate-authority count") {
773
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
774
+ throw new AxiError("Certificate-auth reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
775
+ }
776
+ const selected = profiles.resolve(flags.profile);
777
+ const operation = operationFor(leaf, "v1.0");
778
+ if (!operation || operation.method !== "GET") {
779
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
780
+ }
781
+ let delegated = overrides.delegated;
782
+ let application = overrides.application;
783
+ if (!delegated) {
784
+ const { DelegatedAuth: Service } = await import("./auth.js");
785
+ const { MsalProvider } = await import("./msal-provider.js");
786
+ delegated = new Service(new MsalProvider());
787
+ }
788
+ if (!application) {
789
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
790
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
791
+ application = new Service(new MsalApplicationProvider());
792
+ }
793
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
794
+ const help = leafHelp(leaf);
795
+ switch (leaf.path) {
796
+ case "entra certificate-auth-pki list": return listCertificateAuthPkis(session, flags, selected.profile, operation, help, selected.name);
797
+ case "entra certificate-auth-pki show": return showCertificateAuthPki(session, flags, selected.profile, operation, help, selected.name);
798
+ case "entra certificate-auth-pki count": return countCertificateAuthPkis(session, flags, selected.profile, operation, help, selected.name);
799
+ case "entra certificate-authority list": return listCertificateAuthorities(session, flags, selected.profile, operation, help, selected.name);
800
+ case "entra certificate-authority show": return showCertificateAuthority(session, flags, selected.profile, operation, help, selected.name);
801
+ default: return countCertificateAuthorities(session, flags, selected.profile, operation, help, selected.name);
802
+ }
803
+ }
804
+ if (leaf.path === "entra subscription list" || leaf.path === "entra subscription show" || leaf.path === "entra subscription count") {
805
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
806
+ throw new AxiError("Subscription reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
807
+ }
808
+ const selected = profiles.resolve(flags.profile);
809
+ const operation = operationFor(leaf, "v1.0");
810
+ if (!operation || operation.method !== "GET") {
811
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
812
+ }
813
+ let delegated = overrides.delegated;
814
+ let application = overrides.application;
815
+ if (!delegated) {
816
+ const { DelegatedAuth: Service } = await import("./auth.js");
817
+ const { MsalProvider } = await import("./msal-provider.js");
818
+ delegated = new Service(new MsalProvider());
819
+ }
820
+ if (!application) {
821
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
822
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
823
+ application = new Service(new MsalApplicationProvider());
824
+ }
825
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
826
+ const help = leafHelp(leaf);
827
+ switch (leaf.path) {
828
+ case "entra subscription list": return listSubscriptions(session, flags, selected.profile, operation, help, selected.name);
829
+ case "entra subscription show": return showSubscription(session, flags, selected.profile, operation, help, selected.name);
830
+ default: return countSubscriptions(session, flags, selected.profile, operation, help, selected.name);
831
+ }
832
+ }
833
+ if (leaf.path === "entra on-premises-synchronization list" || leaf.path === "entra on-premises-synchronization show") {
834
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
835
+ throw new AxiError("On-premises-synchronization reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
836
+ }
837
+ const selected = profiles.resolve(flags.profile);
838
+ const operation = operationFor(leaf, "v1.0");
839
+ if (!operation || operation.method !== "GET") {
840
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
841
+ }
842
+ let delegated = overrides.delegated;
843
+ let application = overrides.application;
844
+ if (!delegated) {
845
+ const { DelegatedAuth: Service } = await import("./auth.js");
846
+ const { MsalProvider } = await import("./msal-provider.js");
847
+ delegated = new Service(new MsalProvider());
848
+ }
849
+ if (!application) {
850
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
851
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
852
+ application = new Service(new MsalApplicationProvider());
853
+ }
854
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
855
+ const help = leafHelp(leaf);
856
+ switch (leaf.path) {
857
+ case "entra on-premises-synchronization list": return listSynchronizations(session, flags, selected.profile, operation, help, selected.name);
858
+ default: return showSynchronization(session, flags, selected.profile, operation, help, selected.name);
859
+ }
860
+ }
861
+ if (leaf.path === "entra agreement list" || leaf.path === "entra agreement show"
862
+ || leaf.path === "entra agreement acceptance list" || leaf.path === "entra agreement acceptance show"
863
+ || leaf.path === "entra agreement-acceptance list" || leaf.path === "entra agreement-acceptance show") {
864
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
865
+ throw new AxiError("Terms-of-use reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
866
+ }
867
+ const selected = profiles.resolve(flags.profile);
868
+ const operation = operationFor(leaf, "v1.0");
869
+ if (!operation || operation.method !== "GET") {
870
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
871
+ }
872
+ let delegated = overrides.delegated;
873
+ let application = overrides.application;
874
+ if (!delegated) {
875
+ const { DelegatedAuth: Service } = await import("./auth.js");
876
+ const { MsalProvider } = await import("./msal-provider.js");
877
+ delegated = new Service(new MsalProvider());
878
+ }
879
+ if (!application) {
880
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
881
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
882
+ application = new Service(new MsalApplicationProvider());
883
+ }
884
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
885
+ const help = leafHelp(leaf);
886
+ switch (leaf.path) {
887
+ case "entra agreement list": return listAgreements(session, flags, selected.profile, operation, help, selected.name);
888
+ case "entra agreement show": return showAgreement(session, flags, selected.profile, operation, help, selected.name);
889
+ case "entra agreement acceptance list": return listAgreementAcceptances(session, flags, selected.profile, operation, help, selected.name);
890
+ case "entra agreement acceptance show": return showAgreementAcceptance(session, flags, selected.profile, operation, help, selected.name);
891
+ case "entra agreement-acceptance list": return listAcceptances(session, flags, selected.profile, operation, help, selected.name);
892
+ default: return showAcceptance(session, flags, selected.profile, operation, help, selected.name);
893
+ }
894
+ }
895
+ if (leaf.path === "entra directory-object list" || leaf.path === "entra directory-object show" || leaf.path === "entra directory-object count") {
896
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
897
+ throw new AxiError("Directory-object reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
898
+ }
899
+ const selected = profiles.resolve(flags.profile);
900
+ const operation = operationFor(leaf, "v1.0");
901
+ if (!operation || operation.method !== "GET") {
902
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
903
+ }
904
+ let delegated = overrides.delegated;
905
+ let application = overrides.application;
906
+ if (!delegated) {
907
+ const { DelegatedAuth: Service } = await import("./auth.js");
908
+ const { MsalProvider } = await import("./msal-provider.js");
909
+ delegated = new Service(new MsalProvider());
910
+ }
911
+ if (!application) {
912
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
913
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
914
+ application = new Service(new MsalApplicationProvider());
915
+ }
916
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
917
+ const help = leafHelp(leaf);
918
+ switch (leaf.path) {
919
+ case "entra directory-object list": return listDirectoryObjects(session, flags, selected.profile, operation, help, selected.name);
920
+ case "entra directory-object show": return showDirectoryObject(session, flags, selected.profile, operation, help, selected.name);
921
+ default: return countDirectoryObjects(session, flags, selected.profile, operation, help, selected.name);
922
+ }
923
+ }
924
+ if (leaf.path === "entra deleted-user list" || leaf.path === "entra deleted-user count"
925
+ || leaf.path === "entra deleted-group list" || leaf.path === "entra deleted-group count"
926
+ || leaf.path === "entra deleted-application list" || leaf.path === "entra deleted-application count"
927
+ || leaf.path === "entra deleted-service-principal list" || leaf.path === "entra deleted-service-principal count"
928
+ || leaf.path === "entra deleted-administrative-unit list" || leaf.path === "entra deleted-administrative-unit count"
929
+ || leaf.path === "entra deleted-item show") {
930
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
931
+ throw new AxiError("Deleted-item reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
932
+ }
933
+ const selected = profiles.resolve(flags.profile);
934
+ const operation = operationFor(leaf, "v1.0");
935
+ if (!operation || operation.method !== "GET") {
936
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
937
+ }
938
+ let delegated = overrides.delegated;
939
+ let application = overrides.application;
940
+ if (!delegated) {
941
+ const { DelegatedAuth: Service } = await import("./auth.js");
942
+ const { MsalProvider } = await import("./msal-provider.js");
943
+ delegated = new Service(new MsalProvider());
944
+ }
945
+ if (!application) {
946
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
947
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
948
+ application = new Service(new MsalApplicationProvider());
949
+ }
950
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
951
+ const help = leafHelp(leaf);
952
+ switch (leaf.path) {
953
+ case "entra deleted-item show": return showDeletedItem(session, flags, selected.profile, operation, help, selected.name);
954
+ case "entra deleted-user count":
955
+ case "entra deleted-group count":
956
+ case "entra deleted-application count":
957
+ case "entra deleted-service-principal count":
958
+ case "entra deleted-administrative-unit count": return countDeletedItems(session, flags, selected.profile, operation, help, selected.name);
959
+ default: return listDeletedItems(session, flags, selected.profile, operation, help, selected.name);
960
+ }
961
+ }
962
+ if (leaf.path === "entra contact list" || leaf.path === "entra contact show" || leaf.path === "entra contact count"
963
+ || leaf.path === "entra contact show-manager" || leaf.path === "entra contact list-direct-reports"
964
+ || leaf.path === "entra contact show-direct-report" || leaf.path === "entra contact count-direct-reports"
965
+ || leaf.path === "entra contact list-member-of" || leaf.path === "entra contact show-member-of"
966
+ || leaf.path === "entra contact count-member-of") {
967
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
968
+ throw new AxiError("Contact reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
969
+ }
970
+ const selected = profiles.resolve(flags.profile);
971
+ const isMembership = leaf.path === "entra contact list-member-of" || leaf.path === "entra contact show-member-of"
972
+ || leaf.path === "entra contact count-member-of";
973
+ // --transitive selects the transitiveMemberOf route on member-of reads
974
+ // and --as selects the typed-cast route; anything else is refused before
975
+ // credentials and never falls back silently.
976
+ const routed = isMembership && flags.transitive === true ? transitMembership(leaf.operation, leafHelp(leaf)) : leaf.operation;
977
+ const template = flags.as === undefined ? routed
978
+ : isMembership ? castMembership(routed, flags.as, leafHelp(leaf)) : castDirectReports(routed, flags.as, leafHelp(leaf));
979
+ const operation = operationFor({ ...leaf, operation: template }, "v1.0");
980
+ if (!operation || operation.method !== "GET") {
981
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
982
+ }
983
+ let delegated = overrides.delegated;
984
+ let application = overrides.application;
985
+ if (!delegated) {
986
+ const { DelegatedAuth: Service } = await import("./auth.js");
987
+ const { MsalProvider } = await import("./msal-provider.js");
988
+ delegated = new Service(new MsalProvider());
989
+ }
990
+ if (!application) {
991
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
992
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
993
+ application = new Service(new MsalApplicationProvider());
994
+ }
995
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
996
+ const help = leafHelp(leaf);
997
+ switch (leaf.path) {
998
+ case "entra contact list": return listContacts(session, flags, selected.profile, operation, help, selected.name);
999
+ case "entra contact show": return showContact(session, flags, selected.profile, operation, help, selected.name);
1000
+ case "entra contact show-manager": return showContactManager(session, flags, selected.profile, operation, help, selected.name);
1001
+ case "entra contact list-direct-reports": return listContactDirectReports(session, flags, selected.profile, operation, help, selected.name);
1002
+ case "entra contact show-direct-report": return showContactDirectReport(session, flags, selected.profile, operation, help, selected.name);
1003
+ case "entra contact list-member-of": return listContactMemberOf(session, flags, selected.profile, operation, help, selected.name);
1004
+ case "entra contact show-member-of": return showContactMemberOf(session, flags, selected.profile, operation, help, selected.name);
1005
+ case "entra contact count-member-of": return countContactMemberOf(session, flags, selected.profile, operation, help, selected.name);
1006
+ case "entra contact count": return countContacts(session, flags, selected.profile, operation, help, selected.name);
1007
+ default: return countContactDirectReports(session, flags, selected.profile, operation, help, selected.name);
1008
+ }
1009
+ }
1010
+ if (leaf.path === "entra group-lifecycle-policy list" || leaf.path === "entra group-lifecycle-policy show" || leaf.path === "entra group-lifecycle-policy count"
1011
+ || leaf.path === "entra group-setting-template list" || leaf.path === "entra group-setting-template show" || leaf.path === "entra group-setting-template count") {
1012
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1013
+ throw new AxiError("Group lifecycle policy and setting-template reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1014
+ }
1015
+ const selected = profiles.resolve(flags.profile);
1016
+ const operation = operationFor(leaf, "v1.0");
1017
+ if (!operation || operation.method !== "GET") {
1018
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1019
+ }
1020
+ let delegated = overrides.delegated;
1021
+ let application = overrides.application;
1022
+ if (!delegated) {
1023
+ const { DelegatedAuth: Service } = await import("./auth.js");
1024
+ const { MsalProvider } = await import("./msal-provider.js");
1025
+ delegated = new Service(new MsalProvider());
1026
+ }
1027
+ if (!application) {
1028
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1029
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1030
+ application = new Service(new MsalApplicationProvider());
1031
+ }
1032
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1033
+ const help = leafHelp(leaf);
1034
+ switch (leaf.path) {
1035
+ case "entra group-lifecycle-policy list": return listLifecyclePolicies(session, flags, selected.profile, operation, help, selected.name);
1036
+ case "entra group-lifecycle-policy show": return showLifecyclePolicy(session, flags, selected.profile, operation, help, selected.name);
1037
+ case "entra group-lifecycle-policy count": return countLifecyclePolicies(session, flags, selected.profile, operation, help, selected.name);
1038
+ case "entra group-setting-template list": return listSettingTemplates(session, flags, selected.profile, operation, help, selected.name);
1039
+ case "entra group-setting-template show": return showSettingTemplate(session, flags, selected.profile, operation, help, selected.name);
1040
+ default: return countSettingTemplates(session, flags, selected.profile, operation, help, selected.name);
1041
+ }
1042
+ }
1043
+ if (leaf.path === "entra attribute-set list" || leaf.path === "entra attribute-set show" || leaf.path === "entra attribute-set count"
1044
+ || leaf.path === "entra custom-security-attribute-definition list" || leaf.path === "entra custom-security-attribute-definition show" || leaf.path === "entra custom-security-attribute-definition count"
1045
+ || leaf.path === "entra allowed-value list" || leaf.path === "entra allowed-value show" || leaf.path === "entra allowed-value count") {
1046
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1047
+ throw new AxiError("Custom-security-attribute reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1048
+ }
1049
+ const selected = profiles.resolve(flags.profile);
1050
+ const operation = operationFor(leaf, "v1.0");
1051
+ if (!operation || operation.method !== "GET") {
1052
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1053
+ }
1054
+ let delegated = overrides.delegated;
1055
+ let application = overrides.application;
1056
+ if (!delegated) {
1057
+ const { DelegatedAuth: Service } = await import("./auth.js");
1058
+ const { MsalProvider } = await import("./msal-provider.js");
1059
+ delegated = new Service(new MsalProvider());
1060
+ }
1061
+ if (!application) {
1062
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1063
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1064
+ application = new Service(new MsalApplicationProvider());
1065
+ }
1066
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1067
+ const help = leafHelp(leaf);
1068
+ switch (leaf.path) {
1069
+ case "entra attribute-set list": return listAttributeSets(session, flags, selected.profile, operation, help, selected.name);
1070
+ case "entra attribute-set show": return showAttributeSet(session, flags, selected.profile, operation, help, selected.name);
1071
+ case "entra attribute-set count": return countAttributeSets(session, flags, selected.profile, operation, help, selected.name);
1072
+ case "entra custom-security-attribute-definition list": return listCustomSecurityAttributeDefinitions(session, flags, selected.profile, operation, help, selected.name);
1073
+ case "entra custom-security-attribute-definition show": return showCustomSecurityAttributeDefinition(session, flags, selected.profile, operation, help, selected.name);
1074
+ case "entra custom-security-attribute-definition count": return countCustomSecurityAttributeDefinitions(session, flags, selected.profile, operation, help, selected.name);
1075
+ case "entra allowed-value list": return listAllowedValues(session, flags, selected.profile, operation, help, selected.name);
1076
+ case "entra allowed-value show": return showAllowedValue(session, flags, selected.profile, operation, help, selected.name);
1077
+ default: return countAllowedValues(session, flags, selected.profile, operation, help, selected.name);
1078
+ }
1079
+ }
1080
+ if (leaf.path === "entra contract list" || leaf.path === "entra contract show" || leaf.path === "entra contract count") {
1081
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1082
+ throw new AxiError("Contract reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1083
+ }
1084
+ const selected = profiles.resolve(flags.profile);
1085
+ const operation = operationFor(leaf, "v1.0");
1086
+ if (!operation || operation.method !== "GET") {
1087
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1088
+ }
1089
+ let delegated = overrides.delegated;
1090
+ let application = overrides.application;
1091
+ if (!delegated) {
1092
+ const { DelegatedAuth: Service } = await import("./auth.js");
1093
+ const { MsalProvider } = await import("./msal-provider.js");
1094
+ delegated = new Service(new MsalProvider());
1095
+ }
1096
+ if (!application) {
1097
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1098
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1099
+ application = new Service(new MsalApplicationProvider());
1100
+ }
1101
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1102
+ const help = leafHelp(leaf);
1103
+ switch (leaf.path) {
1104
+ case "entra contract list": return listContracts(session, flags, selected.profile, operation, help, selected.name);
1105
+ case "entra contract show": return showContract(session, flags, selected.profile, operation, help, selected.name);
1106
+ default: return countContracts(session, flags, selected.profile, operation, help, selected.name);
1107
+ }
1108
+ }
1109
+ if (leaf.path === "entra delegated-admin-customer list" || leaf.path === "entra delegated-admin-customer show" || leaf.path === "entra delegated-admin-relationship list" || leaf.path === "entra delegated-admin-relationship show" || leaf.path === "entra delegated-admin-relationship list-access-assignments" || leaf.path === "entra delegated-admin-relationship show-access-assignment" || leaf.path === "entra delegated-admin-relationship list-operations" || leaf.path === "entra delegated-admin-relationship show-operation" || leaf.path === "entra delegated-admin-relationship list-requests" || leaf.path === "entra delegated-admin-relationship show-request" || leaf.path === "entra delegated-admin-customer list-service-management-details" || leaf.path === "entra delegated-admin-customer show-service-management-detail") {
1110
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1111
+ throw new AxiError("Delegated-admin reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1112
+ }
1113
+ const selected = profiles.resolve(flags.profile);
1114
+ const operation = operationFor(leaf, "v1.0");
1115
+ if (!operation || operation.method !== "GET") {
1116
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1117
+ }
1118
+ let delegated = overrides.delegated;
1119
+ let application = overrides.application;
1120
+ if (!delegated) {
1121
+ const { DelegatedAuth: Service } = await import("./auth.js");
1122
+ const { MsalProvider } = await import("./msal-provider.js");
1123
+ delegated = new Service(new MsalProvider());
1124
+ }
1125
+ if (!application) {
1126
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1127
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1128
+ application = new Service(new MsalApplicationProvider());
1129
+ }
1130
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1131
+ const help = leafHelp(leaf);
1132
+ switch (leaf.path) {
1133
+ case "entra delegated-admin-customer list": return listDelegatedAdminCustomers(session, flags, selected.profile, operation, help, selected.name);
1134
+ case "entra delegated-admin-customer show": return showDelegatedAdminCustomer(session, flags, selected.profile, operation, help, selected.name);
1135
+ case "entra delegated-admin-relationship list": return listDelegatedAdminRelationships(session, flags, selected.profile, operation, help, selected.name);
1136
+ case "entra delegated-admin-relationship show": return showDelegatedAdminRelationship(session, flags, selected.profile, operation, help, selected.name);
1137
+ case "entra delegated-admin-relationship list-access-assignments": return listDelegatedAdminAccessAssignments(session, flags, selected.profile, operation, help, selected.name);
1138
+ case "entra delegated-admin-relationship show-access-assignment": return showDelegatedAdminAccessAssignment(session, flags, selected.profile, operation, help, selected.name);
1139
+ case "entra delegated-admin-relationship list-operations": return listDelegatedAdminOperations(session, flags, selected.profile, operation, help, selected.name);
1140
+ case "entra delegated-admin-relationship show-operation": return showDelegatedAdminOperation(session, flags, selected.profile, operation, help, selected.name);
1141
+ case "entra delegated-admin-relationship list-requests": return listDelegatedAdminRequests(session, flags, selected.profile, operation, help, selected.name);
1142
+ case "entra delegated-admin-relationship show-request": return showDelegatedAdminRequest(session, flags, selected.profile, operation, help, selected.name);
1143
+ case "entra delegated-admin-customer list-service-management-details": return listDelegatedAdminServiceManagementDetails(session, flags, selected.profile, operation, help, selected.name);
1144
+ default: return showDelegatedAdminServiceManagementDetail(session, flags, selected.profile, operation, help, selected.name);
1145
+ }
1146
+ }
1147
+ if (leaf.path === "entra multi-tenant-organization show" || leaf.path === "entra multi-tenant-organization join-request show" || leaf.path === "entra multi-tenant-organization tenant list" || leaf.path === "entra multi-tenant-organization tenant count") {
1148
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1149
+ throw new AxiError("Multi-tenant-organization reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1150
+ }
1151
+ const selected = profiles.resolve(flags.profile);
1152
+ const operation = operationFor(leaf, "v1.0");
1153
+ if (!operation || operation.method !== "GET") {
1154
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1155
+ }
1156
+ let delegated = overrides.delegated;
1157
+ let application = overrides.application;
1158
+ if (!delegated) {
1159
+ const { DelegatedAuth: Service } = await import("./auth.js");
1160
+ const { MsalProvider } = await import("./msal-provider.js");
1161
+ delegated = new Service(new MsalProvider());
1162
+ }
1163
+ if (!application) {
1164
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1165
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1166
+ application = new Service(new MsalApplicationProvider());
1167
+ }
1168
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1169
+ const help = leafHelp(leaf);
1170
+ switch (leaf.path) {
1171
+ case "entra multi-tenant-organization show": return showMultiTenantOrganization(session, flags, selected.profile, operation, help, selected.name);
1172
+ case "entra multi-tenant-organization join-request show": return showMultiTenantOrganizationJoinRequest(session, flags, selected.profile, operation, help, selected.name);
1173
+ case "entra multi-tenant-organization tenant list": return listMultiTenantOrganizationTenants(session, flags, selected.profile, operation, help, selected.name);
1174
+ default: return countMultiTenantOrganizationTenants(session, flags, selected.profile, operation, help, selected.name);
1175
+ }
1176
+ }
1177
+ if (leaf.path === "entra tenant-information show") {
1178
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1179
+ throw new AxiError("Tenant-information lookups support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1180
+ }
1181
+ const selected = profiles.resolve(flags.profile);
1182
+ const operation = operationFor(leaf, "v1.0");
1183
+ if (!operation || operation.method !== "GET") {
1184
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1185
+ }
1186
+ let delegated = overrides.delegated;
1187
+ let application = overrides.application;
1188
+ if (!delegated) {
1189
+ const { DelegatedAuth: Service } = await import("./auth.js");
1190
+ const { MsalProvider } = await import("./msal-provider.js");
1191
+ delegated = new Service(new MsalProvider());
1192
+ }
1193
+ if (!application) {
1194
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1195
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1196
+ application = new Service(new MsalApplicationProvider());
1197
+ }
1198
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1199
+ const help = leafHelp(leaf);
1200
+ return showTenantInformation(session, flags, selected.profile, operation, help, selected.name);
1201
+ }
1202
+ if (leaf.path === "entra identity-provider list" || leaf.path === "entra identity-provider show" || leaf.path === "entra identity-provider count" || leaf.path === "entra identity-provider available-types") {
1203
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1204
+ throw new AxiError("Identity-provider reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1205
+ }
1206
+ const selected = profiles.resolve(flags.profile);
1207
+ const operation = operationFor(leaf, "v1.0");
1208
+ if (!operation || operation.method !== "GET") {
1209
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1210
+ }
1211
+ let delegated = overrides.delegated;
1212
+ let application = overrides.application;
1213
+ if (!delegated) {
1214
+ const { DelegatedAuth: Service } = await import("./auth.js");
1215
+ const { MsalProvider } = await import("./msal-provider.js");
1216
+ delegated = new Service(new MsalProvider());
1217
+ }
1218
+ if (!application) {
1219
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1220
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1221
+ application = new Service(new MsalApplicationProvider());
1222
+ }
1223
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1224
+ const help = leafHelp(leaf);
1225
+ switch (leaf.path) {
1226
+ case "entra identity-provider list": return listIdentityProviders(session, flags, selected.profile, operation, help, selected.name);
1227
+ case "entra identity-provider show": return showIdentityProvider(session, flags, selected.profile, operation, help, selected.name);
1228
+ case "entra identity-provider available-types": return availableIdentityProviderTypes(session, flags, selected.profile, operation, help);
1229
+ default: return countIdentityProviders(session, flags, selected.profile, operation, help, selected.name);
1230
+ }
1231
+ }
1232
+ if (leaf.path === "entra federation-configuration list" || leaf.path === "entra federation-configuration show" || leaf.path === "entra federation-configuration count" || leaf.path === "entra federation-configuration available-types") {
1233
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1234
+ throw new AxiError("Federation-configuration reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1235
+ }
1236
+ const selected = profiles.resolve(flags.profile);
1237
+ const operation = operationFor(leaf, "v1.0");
1238
+ if (!operation || operation.method !== "GET") {
1239
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1240
+ }
1241
+ let delegated = overrides.delegated;
1242
+ let application = overrides.application;
1243
+ if (!delegated) {
1244
+ const { DelegatedAuth: Service } = await import("./auth.js");
1245
+ const { MsalProvider } = await import("./msal-provider.js");
1246
+ delegated = new Service(new MsalProvider());
1247
+ }
1248
+ if (!application) {
1249
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1250
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1251
+ application = new Service(new MsalApplicationProvider());
1252
+ }
1253
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1254
+ const help = leafHelp(leaf);
1255
+ switch (leaf.path) {
1256
+ case "entra federation-configuration list": return listFederationConfigurations(session, flags, selected.profile, operation, help, selected.name);
1257
+ case "entra federation-configuration show": return showFederationConfiguration(session, flags, selected.profile, operation, help, selected.name);
1258
+ case "entra federation-configuration available-types": return availableFederationProviderTypes(session, flags, selected.profile, operation, help);
1259
+ default: return countFederationConfigurations(session, flags, selected.profile, operation, help, selected.name);
1260
+ }
1261
+ }
1262
+ if (leaf.path === "entra data-policy-operation list" || leaf.path === "entra data-policy-operation show" || leaf.path === "entra data-policy-operation count") {
1263
+ if (String(flags["api-version"] ?? "v1.0") !== "v1.0") {
1264
+ throw new AxiError("Data-policy-operation reads support v1.0 only; beta needs its own review", "VALIDATION_ERROR", [leafHelp(leaf)]);
1265
+ }
1266
+ const selected = profiles.resolve(flags.profile);
1267
+ const operation = operationFor(leaf, "v1.0");
1268
+ if (!operation || operation.method !== "GET") {
1269
+ throw new AxiError(`Unknown catalogued Graph operation for ${leaf.path}`, "VALIDATION_ERROR", [leafHelp(leaf)]);
1270
+ }
1271
+ let delegated = overrides.delegated;
1272
+ let application = overrides.application;
1273
+ if (!delegated) {
1274
+ const { DelegatedAuth: Service } = await import("./auth.js");
1275
+ const { MsalProvider } = await import("./msal-provider.js");
1276
+ delegated = new Service(new MsalProvider());
1277
+ }
1278
+ if (!application) {
1279
+ const { ApplicationAuth: Service } = await import("./app-auth.js");
1280
+ const { MsalApplicationProvider } = await import("./msal-app-provider.js");
1281
+ application = new Service(new MsalApplicationProvider());
1282
+ }
1283
+ const session = new GraphSession({ delegated, application, transport: overrides.transport ?? fetchTransport });
1284
+ const help = leafHelp(leaf);
1285
+ switch (leaf.path) {
1286
+ case "entra data-policy-operation list": return listDataPolicyOperations(session, flags, selected.profile, operation, help, selected.name);
1287
+ case "entra data-policy-operation show": return showDataPolicyOperation(session, flags, selected.profile, operation, help, selected.name);
1288
+ default: return countDataPolicyOperations(session, flags, selected.profile, operation, help, selected.name);
1289
+ }
1290
+ }
1291
+ const operation = operationFor(leaf, String(flags["api-version"] ?? "v1.0"));
1292
+ throw new AxiError(`Command is not executable: ${operation?.disposition ?? "unavailable"} (${operation?.owningSlice ?? "no inventory mapping"})`, "NOT_IMPLEMENTED", [leafHelp(leaf)]);
1293
+ }
1294
+ export async function main() {
1295
+ await runAxiCli({
1296
+ description: DESCRIPTION,
1297
+ version: VERSION,
1298
+ topLevelHelp: TOP_LEVEL_HELP,
1299
+ // Strict resolution owns leaf help, so SDK help cannot bypass validation.
1300
+ argv: ["dispatch"],
1301
+ home: () => localHome(),
1302
+ commands: {
1303
+ dispatch: async () => {
1304
+ if (process.argv.length === 3 && process.argv[2] === "--help")
1305
+ return TOP_LEVEL_HELP;
1306
+ return executeArgv(process.argv.slice(2));
1307
+ },
1308
+ },
1309
+ formatError: error => ({
1310
+ output: `${encode(error instanceof AxiError ? { error: error.message, code: error.code, help: error.suggestions } : { error: "Unable to run mg-axi", help: ["mg-axi --help"] })}\n`,
1311
+ exitCode: error instanceof AxiError && error.code === "VALIDATION_ERROR" ? 2 : 1,
1312
+ }),
1313
+ });
1314
+ }