@knowttl/mg-axi 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -45
- package/dist/api.js +119 -0
- package/dist/app-auth.js +5 -1
- package/dist/catalogue.js +311 -3
- package/dist/cli.js +44 -12
- package/dist/docs.js +139 -47
- package/dist/entra-apps.js +158 -6
- package/dist/entra-audit-logs.js +93 -12
- package/dist/entra-conditional-access.js +416 -11
- package/dist/entra-federation-configurations.js +7 -4
- package/dist/entra-grants.js +8 -4
- package/dist/entra-group-lifecycle.js +13 -8
- package/dist/entra-identity-providers.js +7 -4
- package/dist/entra-lifecycle-workflows.js +16 -4
- package/dist/entra-multi-tenant-organization.js +7 -4
- package/dist/entra-on-premises-synchronization.js +6 -4
- package/dist/entra-risk-prevention.js +10 -4
- package/dist/entra-risk.js +11 -4
- package/dist/entra-roles.js +194 -8
- package/dist/entra-terms-of-use.js +13 -8
- package/dist/graph-session.js +1 -0
- package/dist/msal-app-provider.js +96 -13
- package/dist/profiles.js +55 -9
- package/dist/setup.js +5 -2
- package/docs/coverage.md +721 -654
- package/inventory/operations.json +2 -2
- package/inventory/schema.json +1 -1
- package/package.json +1 -1
- package/skills/mg-axi/SKILL.md +34 -1
|
@@ -3,7 +3,11 @@ import { listTotals } from "./list-totals.js";
|
|
|
3
3
|
// READ-03: the Conditional Access read mapping behind
|
|
4
4
|
// `mg-axi entra conditional-access policy list/show` and
|
|
5
5
|
// `mg-axi entra conditional-access named-location list/show` as separate
|
|
6
|
-
// az-style grammar
|
|
6
|
+
// az-style grammar, plus the remaining v1.0 named collections under
|
|
7
|
+
// `identity/conditionalAccess`: authentication-strength policies, each
|
|
8
|
+
// policy's combination configurations, authentication method modes,
|
|
9
|
+
// templates, authentication context class references and the deleted
|
|
10
|
+
// policy and named-location collections. Operation construction stays beside its command; the
|
|
7
11
|
// shared session owns URLs, credentials, paging, retries and error
|
|
8
12
|
// translation, and the SDK owns TOON rendering. This module only maps flags
|
|
9
13
|
// to session calls and projects rows for compact output. No policy mutation
|
|
@@ -11,13 +15,45 @@ import { listTotals } from "./list-totals.js";
|
|
|
11
15
|
//
|
|
12
16
|
// Reviewed against the v1.0 conditionalaccessroot-list-policies,
|
|
13
17
|
// conditionalaccesspolicy-get, conditionalaccessroot-list-namedlocations and
|
|
14
|
-
// countrynamedlocation-get operation documentation on 2026-10-04
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
+
// countrynamedlocation-get operation documentation on 2026-10-04, and the
|
|
19
|
+
// authenticationstrengthroot-list-policies,
|
|
20
|
+
// authenticationstrengthpolicy-get,
|
|
21
|
+
// authenticationstrengthpolicy-list-combinationconfigurations,
|
|
22
|
+
// authenticationcombinationconfiguration-get,
|
|
23
|
+
// authenticationstrengthroot-list-authenticationmethodmodes,
|
|
24
|
+
// authenticationmethodmodedetail-get, conditionalaccessroot-list-templates,
|
|
25
|
+
// conditionalaccesstemplate-get, conditionalaccessroot-list-
|
|
26
|
+
// authenticationcontextclassreferences and authenticationcontextclassreference-
|
|
27
|
+
// get operation documentation on 2026-10-06. The deleted policy and
|
|
28
|
+
// named-location collections carry no v1.0 operation-level documentation
|
|
29
|
+
// page; their review follows the beta policyDeletableItem list/get contract
|
|
30
|
+
// for conditional-access objects with the conditionalAccessPolicy,
|
|
31
|
+
// namedLocation and policyDeletableItem resource references.
|
|
32
|
+
// Policy and named-location reads need D/A Policy.Read.All; the
|
|
33
|
+
// authentication-strength family (policies, combination configurations and
|
|
34
|
+
// authentication method modes) reads D/A Policy.Read.AuthenticationMethod
|
|
35
|
+
// instead, and template reads D/A Policy.Read.All. Delegated callers
|
|
36
|
+
// additionally need a supported directory role (Conditional Access
|
|
37
|
+
// Administrator, Security Administrator or Security Reader for the
|
|
38
|
+
// strength family; those plus Global Reader and Global Secure Access
|
|
39
|
+
// Administrator for policies, named locations and templates). The
|
|
40
|
+
// authentication context class references read D/A
|
|
41
|
+
// AuthenticationContext.Read.All with the same broad delegated role set.
|
|
42
|
+
// Deleted policies and named locations read D/A Policy.Read.All with the
|
|
43
|
+
// same broad delegated role set; restore is a beta-only mutation and stays
|
|
44
|
+
// out of scope.
|
|
18
45
|
// Conditional Access needs P1; risk-based Conditional Access needs P2. The
|
|
19
46
|
// reviewed raw surface in src/api.ts carries exactly these routes, fields
|
|
20
47
|
// and access choices; the named commands below reuse that contract.
|
|
48
|
+
//
|
|
49
|
+
// Deferred with reason: the parameterless
|
|
50
|
+
// `authenticationStrength/policies/{id}/usage()` binds no placeholder, so
|
|
51
|
+
// it never passes through the session's validated function-argument
|
|
52
|
+
// binding (FUNCTION_ARGUMENT_BINDINGS covers only named-parameter
|
|
53
|
+
// segments); widening the request-path guard for one function is out of
|
|
54
|
+
// scope. Authentication context class references land here: the former
|
|
55
|
+
// needs an AuthenticationContext.Read.All allowlist addition, now carried
|
|
56
|
+
// in the session's READ_SCOPES set.
|
|
21
57
|
// Every policy property this slice may request or display, matching the
|
|
22
58
|
// reviewed raw surface. Anything else fails before credentials.
|
|
23
59
|
export const KNOWN_POLICY_FIELDS = [
|
|
@@ -44,6 +80,61 @@ export const KNOWN_LOCATION_FIELDS = [
|
|
|
44
80
|
];
|
|
45
81
|
const POLICY_KNOWN = new Set(KNOWN_POLICY_FIELDS);
|
|
46
82
|
const LOCATION_KNOWN = new Set(KNOWN_LOCATION_FIELDS);
|
|
83
|
+
// Every authentication-strength policy property this slice may request or
|
|
84
|
+
// display, matching the reviewed raw surface.
|
|
85
|
+
export const KNOWN_STRENGTH_FIELDS = [
|
|
86
|
+
"id",
|
|
87
|
+
"displayName",
|
|
88
|
+
"description",
|
|
89
|
+
"policyType",
|
|
90
|
+
"requirementsSatisfied",
|
|
91
|
+
"allowedCombinations",
|
|
92
|
+
"createdDateTime",
|
|
93
|
+
"modifiedDateTime",
|
|
94
|
+
];
|
|
95
|
+
// Every combination-configuration property this slice may request or
|
|
96
|
+
// display: the base type carries only an identifier and the combinations
|
|
97
|
+
// it applies to; subtype detail rides on @odata.type instead.
|
|
98
|
+
export const KNOWN_COMBO_FIELDS = [
|
|
99
|
+
"id",
|
|
100
|
+
"appliesToCombinations",
|
|
101
|
+
];
|
|
102
|
+
// Every authentication method mode property this slice may request or
|
|
103
|
+
// display, matching the reviewed raw surface.
|
|
104
|
+
export const KNOWN_MODE_FIELDS = [
|
|
105
|
+
"id",
|
|
106
|
+
"displayName",
|
|
107
|
+
"authenticationMethod",
|
|
108
|
+
];
|
|
109
|
+
// Every Conditional Access template property this slice may request or
|
|
110
|
+
// display, matching the reviewed raw surface.
|
|
111
|
+
export const KNOWN_TEMPLATE_FIELDS = [
|
|
112
|
+
"id",
|
|
113
|
+
"name",
|
|
114
|
+
"description",
|
|
115
|
+
"scenarios",
|
|
116
|
+
"details",
|
|
117
|
+
];
|
|
118
|
+
// Every authentication context class reference property this slice may
|
|
119
|
+
// request or display, matching the reviewed v1.0 resource shape.
|
|
120
|
+
export const KNOWN_AUTH_CONTEXT_FIELDS = [
|
|
121
|
+
"id",
|
|
122
|
+
"displayName",
|
|
123
|
+
"description",
|
|
124
|
+
"isAvailable",
|
|
125
|
+
];
|
|
126
|
+
// Deleted policies and named locations return the underlying policy and
|
|
127
|
+
// location objects with the soft-delete timestamp the policyDeletableItem
|
|
128
|
+
// base type adds, so the reviewed sets extend the live ones.
|
|
129
|
+
export const KNOWN_DELETED_POLICY_FIELDS = [...KNOWN_POLICY_FIELDS, "deletedDateTime"];
|
|
130
|
+
export const KNOWN_DELETED_LOCATION_FIELDS = [...KNOWN_LOCATION_FIELDS, "deletedDateTime"];
|
|
131
|
+
const STRENGTH_KNOWN = new Set(KNOWN_STRENGTH_FIELDS);
|
|
132
|
+
const COMBO_KNOWN = new Set(KNOWN_COMBO_FIELDS);
|
|
133
|
+
const MODE_KNOWN = new Set(KNOWN_MODE_FIELDS);
|
|
134
|
+
const TEMPLATE_KNOWN = new Set(KNOWN_TEMPLATE_FIELDS);
|
|
135
|
+
const AUTH_CONTEXT_KNOWN = new Set(KNOWN_AUTH_CONTEXT_FIELDS);
|
|
136
|
+
const DELETED_POLICY_KNOWN = new Set(KNOWN_DELETED_POLICY_FIELDS);
|
|
137
|
+
const DELETED_LOCATION_KNOWN = new Set(KNOWN_DELETED_LOCATION_FIELDS);
|
|
47
138
|
// @odata.type is preserved on named-location rows without being selectable:
|
|
48
139
|
// it names the location kind (ipNamedLocation versus countryNamedLocation).
|
|
49
140
|
const LOCATION_TYPE_PROPERTY = "@odata.type";
|
|
@@ -58,8 +149,44 @@ const DEFAULT_POLICY_SHOW_SELECT = [...KNOWN_POLICY_FIELDS];
|
|
|
58
149
|
const DEFAULT_LOCATION_LIST_SELECT = ["id", "displayName"];
|
|
59
150
|
// Show rows: the full reviewed location set.
|
|
60
151
|
const DEFAULT_LOCATION_SHOW_SELECT = [...KNOWN_LOCATION_FIELDS];
|
|
61
|
-
//
|
|
152
|
+
// Compact strength rows: identifier, name and the built-in/custom kind.
|
|
153
|
+
const DEFAULT_STRENGTH_LIST_SELECT = ["id", "displayName", "policyType"];
|
|
154
|
+
// Fetch the full reviewed strength set for inspection.
|
|
155
|
+
const DEFAULT_STRENGTH_SHOW_SELECT = [...KNOWN_STRENGTH_FIELDS];
|
|
156
|
+
// Compact combination rows: the identifier; the kind rides as @odata.type.
|
|
157
|
+
const DEFAULT_COMBO_LIST_SELECT = ["id"];
|
|
158
|
+
// Show rows: the full reviewed base set.
|
|
159
|
+
const DEFAULT_COMBO_SHOW_SELECT = [...KNOWN_COMBO_FIELDS];
|
|
160
|
+
// Compact mode rows: identifier and name.
|
|
161
|
+
const DEFAULT_MODE_LIST_SELECT = ["id", "displayName"];
|
|
162
|
+
// Show rows: the full reviewed mode set.
|
|
163
|
+
const DEFAULT_MODE_SHOW_SELECT = [...KNOWN_MODE_FIELDS];
|
|
164
|
+
// Compact template rows: identifier and name.
|
|
165
|
+
const DEFAULT_TEMPLATE_LIST_SELECT = ["id", "name"];
|
|
166
|
+
// Show rows: the full reviewed template set.
|
|
167
|
+
const DEFAULT_TEMPLATE_SHOW_SELECT = [...KNOWN_TEMPLATE_FIELDS];
|
|
168
|
+
// Compact authentication-context rows: identifier and name.
|
|
169
|
+
const DEFAULT_AUTH_CONTEXT_LIST_SELECT = ["id", "displayName"];
|
|
170
|
+
// Show rows: the full reviewed authentication-context set.
|
|
171
|
+
const DEFAULT_AUTH_CONTEXT_SHOW_SELECT = [...KNOWN_AUTH_CONTEXT_FIELDS];
|
|
172
|
+
// Compact deleted-policy rows: identifier, name, enforcement state and the
|
|
173
|
+
// soft-delete timestamp, which is the point of the deleted collection.
|
|
174
|
+
const DEFAULT_DELETED_POLICY_LIST_SELECT = ["id", "displayName", "state", "deletedDateTime"];
|
|
175
|
+
// Show rows: the full reviewed deleted-policy set.
|
|
176
|
+
const DEFAULT_DELETED_POLICY_SHOW_SELECT = [...KNOWN_DELETED_POLICY_FIELDS];
|
|
177
|
+
// Compact deleted-location rows: identifier, name and deletion timestamp;
|
|
178
|
+
// the kind rides as @odata.type.
|
|
179
|
+
const DEFAULT_DELETED_LOCATION_LIST_SELECT = ["id", "displayName", "deletedDateTime"];
|
|
180
|
+
// Show rows: the full reviewed deleted-location set.
|
|
181
|
+
const DEFAULT_DELETED_LOCATION_SHOW_SELECT = [...KNOWN_DELETED_LOCATION_FIELDS];
|
|
182
|
+
// Policy.Read.All covers policies, named locations and templates in both modes.
|
|
62
183
|
export const DEFAULT_DELEGATED_SCOPES = ["https://graph.microsoft.com/Policy.Read.All"];
|
|
184
|
+
// Policy.Read.AuthenticationMethod is the least-privileged read for the
|
|
185
|
+
// authentication-strength family in both modes.
|
|
186
|
+
export const DEFAULT_STRENGTH_SCOPES = ["https://graph.microsoft.com/Policy.Read.AuthenticationMethod"];
|
|
187
|
+
// AuthenticationContext.Read.All is the least-privileged read for the
|
|
188
|
+
// authentication context class references in both modes.
|
|
189
|
+
export const DEFAULT_AUTH_CONTEXT_SCOPES = ["https://graph.microsoft.com/AuthenticationContext.Read.All"];
|
|
63
190
|
const TRUNCATE_AT = 500;
|
|
64
191
|
function fieldList(raw, flag, known, knownList, noun, help) {
|
|
65
192
|
const parts = String(raw)
|
|
@@ -81,7 +208,7 @@ function fieldList(raw, flag, known, knownList, noun, help) {
|
|
|
81
208
|
}
|
|
82
209
|
return fields;
|
|
83
210
|
}
|
|
84
|
-
function scopesFor(flags, profile, help) {
|
|
211
|
+
function scopesFor(flags, profile, help, defaults = DEFAULT_DELEGATED_SCOPES) {
|
|
85
212
|
if (profile.mode === "application") {
|
|
86
213
|
if (flags.scopes !== undefined) {
|
|
87
214
|
throw new AxiError("Application profiles use the configured Graph .default audience; delegated scopes are unavailable", "VALIDATION_ERROR", [help, "mg-axi profile show --profile <name>"]);
|
|
@@ -89,7 +216,7 @@ function scopesFor(flags, profile, help) {
|
|
|
89
216
|
return undefined;
|
|
90
217
|
}
|
|
91
218
|
if (flags.scopes === undefined)
|
|
92
|
-
return [...
|
|
219
|
+
return [...defaults];
|
|
93
220
|
const scopes = String(flags.scopes)
|
|
94
221
|
.split(",")
|
|
95
222
|
.map(scope => scope.trim())
|
|
@@ -180,6 +307,39 @@ const LOCATION_DENIAL_HINTS = [
|
|
|
180
307
|
"Named-location reads need Policy.Read.All plus a supported directory role: Conditional Access Administrator, Global Reader, Global Secure Access Administrator, Security Administrator or Security Reader for delegated access, or admin-consented Policy.Read.All for application access",
|
|
181
308
|
"Conditional Access and named locations need P1; risk-based Conditional Access needs P2",
|
|
182
309
|
];
|
|
310
|
+
// The authentication-strength family (strength policies, combination
|
|
311
|
+
// configurations, authentication method modes) reads the least-privileged
|
|
312
|
+
// Policy.Read.AuthenticationMethod instead of Policy.Read.All, with the
|
|
313
|
+
// narrower Conditional Access Administrator / Security Administrator /
|
|
314
|
+
// Security Reader role set.
|
|
315
|
+
const STRENGTH_DENIAL_HINTS = [
|
|
316
|
+
"Authentication-strength reads need Policy.Read.AuthenticationMethod plus a supported directory role: Conditional Access Administrator, Security Administrator or Security Reader for delegated access, or admin-consented Policy.Read.AuthenticationMethod for application access",
|
|
317
|
+
"Conditional Access needs P1",
|
|
318
|
+
];
|
|
319
|
+
const TEMPLATE_DENIAL_HINTS = [
|
|
320
|
+
"Conditional Access template reads need Policy.Read.All plus a supported directory role: Conditional Access Administrator, Global Reader, Global Secure Access Administrator, Security Administrator or Security Reader for delegated access, or admin-consented Policy.Read.All for application access",
|
|
321
|
+
"Conditional Access needs P1",
|
|
322
|
+
];
|
|
323
|
+
// Authentication-context reads carry the least-privileged
|
|
324
|
+
// AuthenticationContext.Read.All with the broad Conditional Access role
|
|
325
|
+
// set shared with policies, named locations and templates.
|
|
326
|
+
const AUTH_CONTEXT_DENIAL_HINTS = [
|
|
327
|
+
"Authentication-context reads need AuthenticationContext.Read.All plus a supported directory role: Conditional Access Administrator, Global Reader, Global Secure Access Administrator, Security Administrator or Security Reader for delegated access, or admin-consented AuthenticationContext.Read.All for application access",
|
|
328
|
+
"Conditional Access needs P1",
|
|
329
|
+
];
|
|
330
|
+
// Deleted policy and named-location reads keep Policy.Read.All with the
|
|
331
|
+
// broad Conditional Access role set; restore is a beta-only mutation, so
|
|
332
|
+
// denial guidance never offers it as a next step.
|
|
333
|
+
const DELETED_POLICY_DENIAL_HINTS = [
|
|
334
|
+
"Deleted-policy reads need Policy.Read.All plus a supported directory role: Conditional Access Administrator, Global Reader, Global Secure Access Administrator, Security Administrator or Security Reader for delegated access, or admin-consented Policy.Read.All for application access",
|
|
335
|
+
"Deleted policies restore within 30 days; restore is a beta-only mutation outside mg-axi scope",
|
|
336
|
+
"Conditional Access needs P1",
|
|
337
|
+
];
|
|
338
|
+
const DELETED_LOCATION_DENIAL_HINTS = [
|
|
339
|
+
"Deleted named-location reads need Policy.Read.All plus a supported directory role: Conditional Access Administrator, Global Reader, Global Secure Access Administrator, Security Administrator or Security Reader for delegated access, or admin-consented Policy.Read.All for application access",
|
|
340
|
+
"Deleted named locations restore within 30 days; restore is a beta-only mutation outside mg-axi scope",
|
|
341
|
+
"Conditional Access and named locations need P1",
|
|
342
|
+
];
|
|
183
343
|
const POLICY_LIST = {
|
|
184
344
|
command: "entra conditional-access policy list",
|
|
185
345
|
key: "policies",
|
|
@@ -188,6 +348,7 @@ const POLICY_LIST = {
|
|
|
188
348
|
known: POLICY_KNOWN,
|
|
189
349
|
knownList: KNOWN_POLICY_FIELDS,
|
|
190
350
|
defaultSelect: DEFAULT_POLICY_LIST_SELECT,
|
|
351
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
191
352
|
denialHints: POLICY_DENIAL_HINTS,
|
|
192
353
|
showHint: "mg-axi entra conditional-access policy show --id <policy-id>",
|
|
193
354
|
emptyHint: "0 conditional-access policies matched; the absence of results is the answer, not an error",
|
|
@@ -201,6 +362,7 @@ const LOCATION_LIST = {
|
|
|
201
362
|
known: LOCATION_KNOWN,
|
|
202
363
|
knownList: KNOWN_LOCATION_FIELDS,
|
|
203
364
|
defaultSelect: DEFAULT_LOCATION_LIST_SELECT,
|
|
365
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
204
366
|
denialHints: LOCATION_DENIAL_HINTS,
|
|
205
367
|
showHint: "mg-axi entra conditional-access named-location show --id <named-location-id>",
|
|
206
368
|
emptyHint: "0 named locations matched; the absence of results is the answer, not an error",
|
|
@@ -212,12 +374,19 @@ async function listCollection(shape, session, flags, profile, operation, help, p
|
|
|
212
374
|
throw new AxiError("--cursor needs the opaque cursor from a partial result", "VALIDATION_ERROR", [help]);
|
|
213
375
|
const savedSelect = cursor === undefined ? undefined : session.cursorQuery(operation, cursor).$select;
|
|
214
376
|
const { select, fields } = selectedFields(flags, savedSelect === undefined ? shape.defaultSelect : fieldList(savedSelect, "select", shape.known, shape.knownList, shape.noun, help), shape.known, shape.knownList, shape.noun, help);
|
|
215
|
-
const scopes = scopesFor(flags, profile, help);
|
|
377
|
+
const scopes = scopesFor(flags, profile, help, shape.defaultScopes);
|
|
216
378
|
const full = flags.full === true;
|
|
217
379
|
const query = { $select: select.join(",") };
|
|
218
380
|
if (flags.filter !== undefined)
|
|
219
381
|
query.$filter = String(flags.filter);
|
|
220
382
|
const args = { profile, operation, query, scopes };
|
|
383
|
+
if (shape.parent !== undefined) {
|
|
384
|
+
const raw = flags[shape.parent.flag];
|
|
385
|
+
if (raw === undefined || !String(raw).trim()) {
|
|
386
|
+
throw new AxiError(`--${shape.parent.flag} needs the ${shape.parent.label}`, "VALIDATION_ERROR", [help]);
|
|
387
|
+
}
|
|
388
|
+
args.params = { [shape.parent.param]: String(raw) };
|
|
389
|
+
}
|
|
221
390
|
if (cursor !== undefined)
|
|
222
391
|
args.cursor = cursor;
|
|
223
392
|
if (flags.all === true) {
|
|
@@ -273,6 +442,7 @@ const POLICY_SHOW = {
|
|
|
273
442
|
known: POLICY_KNOWN,
|
|
274
443
|
knownList: KNOWN_POLICY_FIELDS,
|
|
275
444
|
defaultSelect: DEFAULT_POLICY_SHOW_SELECT,
|
|
445
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
276
446
|
denialHints: POLICY_DENIAL_HINTS,
|
|
277
447
|
preserveType: false,
|
|
278
448
|
};
|
|
@@ -284,17 +454,26 @@ const LOCATION_SHOW = {
|
|
|
284
454
|
known: LOCATION_KNOWN,
|
|
285
455
|
knownList: KNOWN_LOCATION_FIELDS,
|
|
286
456
|
defaultSelect: DEFAULT_LOCATION_SHOW_SELECT,
|
|
457
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
287
458
|
denialHints: LOCATION_DENIAL_HINTS,
|
|
288
459
|
preserveType: true,
|
|
289
460
|
};
|
|
290
461
|
async function showSingle(shape, session, flags, profile, operation, help, profileName) {
|
|
291
462
|
const { select, fields } = selectedFields(flags, shape.defaultSelect, shape.known, shape.knownList, shape.noun, help);
|
|
292
|
-
const scopes = scopesFor(flags, profile, help);
|
|
463
|
+
const scopes = scopesFor(flags, profile, help, shape.defaultScopes);
|
|
293
464
|
const full = flags.full === true;
|
|
465
|
+
const params = { [shape.param]: String(flags.id) };
|
|
466
|
+
if (shape.parent !== undefined) {
|
|
467
|
+
const raw = flags[shape.parent.flag];
|
|
468
|
+
if (raw === undefined || !String(raw).trim()) {
|
|
469
|
+
throw new AxiError(`--${shape.parent.flag} needs the ${shape.parent.label}`, "VALIDATION_ERROR", [help]);
|
|
470
|
+
}
|
|
471
|
+
params[shape.parent.param] = String(raw);
|
|
472
|
+
}
|
|
294
473
|
const raw = await withGuidance(shape.denialHints, () => session.execute({
|
|
295
474
|
profile,
|
|
296
475
|
operation,
|
|
297
|
-
params
|
|
476
|
+
params,
|
|
298
477
|
query: { $select: select.join(",") },
|
|
299
478
|
scopes,
|
|
300
479
|
}));
|
|
@@ -320,3 +499,229 @@ export async function listNamedLocations(session, flags, profile, operation, hel
|
|
|
320
499
|
export async function showNamedLocation(session, flags, profile, operation, help, profileName) {
|
|
321
500
|
return showSingle(LOCATION_SHOW, session, flags, profile, operation, help, profileName);
|
|
322
501
|
}
|
|
502
|
+
const STRENGTH_LIST = {
|
|
503
|
+
command: "entra conditional-access auth-strength-policy list",
|
|
504
|
+
key: "authStrengthPolicies",
|
|
505
|
+
noun: "auth-strength-policy",
|
|
506
|
+
known: STRENGTH_KNOWN,
|
|
507
|
+
knownList: KNOWN_STRENGTH_FIELDS,
|
|
508
|
+
defaultSelect: DEFAULT_STRENGTH_LIST_SELECT,
|
|
509
|
+
defaultScopes: DEFAULT_STRENGTH_SCOPES,
|
|
510
|
+
denialHints: STRENGTH_DENIAL_HINTS,
|
|
511
|
+
showHint: "mg-axi entra conditional-access auth-strength-policy show --id <auth-strength-policy-id>",
|
|
512
|
+
emptyHint: "0 authentication-strength policies matched; the absence of results is the answer, not an error",
|
|
513
|
+
preserveType: false,
|
|
514
|
+
plural: "auth-strength policies",
|
|
515
|
+
};
|
|
516
|
+
const COMBO_LIST = {
|
|
517
|
+
command: "entra conditional-access combination-configuration list",
|
|
518
|
+
key: "combinationConfigurations",
|
|
519
|
+
noun: "combination-configuration",
|
|
520
|
+
known: COMBO_KNOWN,
|
|
521
|
+
knownList: KNOWN_COMBO_FIELDS,
|
|
522
|
+
defaultSelect: DEFAULT_COMBO_LIST_SELECT,
|
|
523
|
+
defaultScopes: DEFAULT_STRENGTH_SCOPES,
|
|
524
|
+
denialHints: STRENGTH_DENIAL_HINTS,
|
|
525
|
+
showHint: "mg-axi entra conditional-access combination-configuration show --policy <auth-strength-policy-id> --id <combination-configuration-id>",
|
|
526
|
+
emptyHint: "0 combination configurations matched; the absence of results is the answer, not an error",
|
|
527
|
+
preserveType: true,
|
|
528
|
+
parent: { param: "authenticationStrengthPolicy-id", flag: "policy", label: "authentication-strength policy ID owning the combination configurations" },
|
|
529
|
+
plural: "combination configurations",
|
|
530
|
+
};
|
|
531
|
+
const MODE_LIST = {
|
|
532
|
+
command: "entra conditional-access auth-method-mode list",
|
|
533
|
+
key: "authMethodModes",
|
|
534
|
+
noun: "auth-method-mode",
|
|
535
|
+
known: MODE_KNOWN,
|
|
536
|
+
knownList: KNOWN_MODE_FIELDS,
|
|
537
|
+
defaultSelect: DEFAULT_MODE_LIST_SELECT,
|
|
538
|
+
defaultScopes: DEFAULT_STRENGTH_SCOPES,
|
|
539
|
+
denialHints: STRENGTH_DENIAL_HINTS,
|
|
540
|
+
showHint: "mg-axi entra conditional-access auth-method-mode show --id <auth-method-mode-id>",
|
|
541
|
+
emptyHint: "0 authentication method modes matched; the absence of results is the answer, not an error",
|
|
542
|
+
preserveType: false,
|
|
543
|
+
plural: "auth-method modes",
|
|
544
|
+
};
|
|
545
|
+
const TEMPLATE_LIST = {
|
|
546
|
+
command: "entra conditional-access template list",
|
|
547
|
+
key: "templates",
|
|
548
|
+
noun: "template",
|
|
549
|
+
known: TEMPLATE_KNOWN,
|
|
550
|
+
knownList: KNOWN_TEMPLATE_FIELDS,
|
|
551
|
+
defaultSelect: DEFAULT_TEMPLATE_LIST_SELECT,
|
|
552
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
553
|
+
denialHints: TEMPLATE_DENIAL_HINTS,
|
|
554
|
+
showHint: "mg-axi entra conditional-access template show --id <template-id>",
|
|
555
|
+
emptyHint: "0 Conditional Access templates matched; the absence of results is the answer, not an error",
|
|
556
|
+
preserveType: false,
|
|
557
|
+
plural: "templates",
|
|
558
|
+
};
|
|
559
|
+
const STRENGTH_SHOW = {
|
|
560
|
+
command: "entra conditional-access auth-strength-policy show",
|
|
561
|
+
key: "authStrengthPolicy",
|
|
562
|
+
param: "authenticationStrengthPolicy-id",
|
|
563
|
+
noun: "auth-strength-policy",
|
|
564
|
+
known: STRENGTH_KNOWN,
|
|
565
|
+
knownList: KNOWN_STRENGTH_FIELDS,
|
|
566
|
+
defaultSelect: DEFAULT_STRENGTH_SHOW_SELECT,
|
|
567
|
+
defaultScopes: DEFAULT_STRENGTH_SCOPES,
|
|
568
|
+
denialHints: STRENGTH_DENIAL_HINTS,
|
|
569
|
+
preserveType: false,
|
|
570
|
+
};
|
|
571
|
+
const COMBO_SHOW = {
|
|
572
|
+
command: "entra conditional-access combination-configuration show",
|
|
573
|
+
key: "combinationConfiguration",
|
|
574
|
+
param: "authenticationCombinationConfiguration-id",
|
|
575
|
+
noun: "combination-configuration",
|
|
576
|
+
known: COMBO_KNOWN,
|
|
577
|
+
knownList: KNOWN_COMBO_FIELDS,
|
|
578
|
+
defaultSelect: DEFAULT_COMBO_SHOW_SELECT,
|
|
579
|
+
defaultScopes: DEFAULT_STRENGTH_SCOPES,
|
|
580
|
+
denialHints: STRENGTH_DENIAL_HINTS,
|
|
581
|
+
preserveType: true,
|
|
582
|
+
parent: { param: "authenticationStrengthPolicy-id", flag: "policy", label: "authentication-strength policy ID owning the combination configuration" },
|
|
583
|
+
};
|
|
584
|
+
const MODE_SHOW = {
|
|
585
|
+
command: "entra conditional-access auth-method-mode show",
|
|
586
|
+
key: "authMethodMode",
|
|
587
|
+
param: "authenticationMethodModeDetail-id",
|
|
588
|
+
noun: "auth-method-mode",
|
|
589
|
+
known: MODE_KNOWN,
|
|
590
|
+
knownList: KNOWN_MODE_FIELDS,
|
|
591
|
+
defaultSelect: DEFAULT_MODE_SHOW_SELECT,
|
|
592
|
+
defaultScopes: DEFAULT_STRENGTH_SCOPES,
|
|
593
|
+
denialHints: STRENGTH_DENIAL_HINTS,
|
|
594
|
+
preserveType: false,
|
|
595
|
+
};
|
|
596
|
+
const TEMPLATE_SHOW = {
|
|
597
|
+
command: "entra conditional-access template show",
|
|
598
|
+
key: "template",
|
|
599
|
+
param: "conditionalAccessTemplate-id",
|
|
600
|
+
noun: "template",
|
|
601
|
+
known: TEMPLATE_KNOWN,
|
|
602
|
+
knownList: KNOWN_TEMPLATE_FIELDS,
|
|
603
|
+
defaultSelect: DEFAULT_TEMPLATE_SHOW_SELECT,
|
|
604
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
605
|
+
denialHints: TEMPLATE_DENIAL_HINTS,
|
|
606
|
+
preserveType: false,
|
|
607
|
+
};
|
|
608
|
+
export async function listAuthStrengthPolicies(session, flags, profile, operation, help, profileName) {
|
|
609
|
+
return listCollection(STRENGTH_LIST, session, flags, profile, operation, help, profileName);
|
|
610
|
+
}
|
|
611
|
+
export async function showAuthStrengthPolicy(session, flags, profile, operation, help, profileName) {
|
|
612
|
+
return showSingle(STRENGTH_SHOW, session, flags, profile, operation, help, profileName);
|
|
613
|
+
}
|
|
614
|
+
export async function listCombinationConfigurations(session, flags, profile, operation, help, profileName) {
|
|
615
|
+
return listCollection(COMBO_LIST, session, flags, profile, operation, help, profileName);
|
|
616
|
+
}
|
|
617
|
+
export async function showCombinationConfiguration(session, flags, profile, operation, help, profileName) {
|
|
618
|
+
return showSingle(COMBO_SHOW, session, flags, profile, operation, help, profileName);
|
|
619
|
+
}
|
|
620
|
+
export async function listAuthMethodModes(session, flags, profile, operation, help, profileName) {
|
|
621
|
+
return listCollection(MODE_LIST, session, flags, profile, operation, help, profileName);
|
|
622
|
+
}
|
|
623
|
+
export async function showAuthMethodMode(session, flags, profile, operation, help, profileName) {
|
|
624
|
+
return showSingle(MODE_SHOW, session, flags, profile, operation, help, profileName);
|
|
625
|
+
}
|
|
626
|
+
export async function listTemplates(session, flags, profile, operation, help, profileName) {
|
|
627
|
+
return listCollection(TEMPLATE_LIST, session, flags, profile, operation, help, profileName);
|
|
628
|
+
}
|
|
629
|
+
export async function showTemplate(session, flags, profile, operation, help, profileName) {
|
|
630
|
+
return showSingle(TEMPLATE_SHOW, session, flags, profile, operation, help, profileName);
|
|
631
|
+
}
|
|
632
|
+
const AUTH_CONTEXT_LIST = {
|
|
633
|
+
command: "entra conditional-access auth-context list",
|
|
634
|
+
key: "authContexts",
|
|
635
|
+
noun: "auth-context",
|
|
636
|
+
plural: "auth contexts",
|
|
637
|
+
known: AUTH_CONTEXT_KNOWN,
|
|
638
|
+
knownList: KNOWN_AUTH_CONTEXT_FIELDS,
|
|
639
|
+
defaultSelect: DEFAULT_AUTH_CONTEXT_LIST_SELECT,
|
|
640
|
+
defaultScopes: DEFAULT_AUTH_CONTEXT_SCOPES,
|
|
641
|
+
denialHints: AUTH_CONTEXT_DENIAL_HINTS,
|
|
642
|
+
showHint: "mg-axi entra conditional-access auth-context show --id <auth-context-id>",
|
|
643
|
+
emptyHint: "0 authentication context class references matched; the absence of results is the answer, not an error",
|
|
644
|
+
preserveType: false,
|
|
645
|
+
};
|
|
646
|
+
const DELETED_POLICY_LIST = {
|
|
647
|
+
command: "entra conditional-access deleted-policy list",
|
|
648
|
+
key: "deletedPolicies",
|
|
649
|
+
noun: "deleted-policy",
|
|
650
|
+
plural: "deleted policies",
|
|
651
|
+
known: DELETED_POLICY_KNOWN,
|
|
652
|
+
knownList: KNOWN_DELETED_POLICY_FIELDS,
|
|
653
|
+
defaultSelect: DEFAULT_DELETED_POLICY_LIST_SELECT,
|
|
654
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
655
|
+
denialHints: DELETED_POLICY_DENIAL_HINTS,
|
|
656
|
+
showHint: "mg-axi entra conditional-access deleted-policy show --id <deleted-policy-id>",
|
|
657
|
+
emptyHint: "0 deleted policies matched; the absence of results is the answer, not an error",
|
|
658
|
+
preserveType: false,
|
|
659
|
+
};
|
|
660
|
+
const DELETED_LOCATION_LIST = {
|
|
661
|
+
command: "entra conditional-access deleted-named-location list",
|
|
662
|
+
key: "deletedNamedLocations",
|
|
663
|
+
noun: "deleted-named-location",
|
|
664
|
+
plural: "deleted named locations",
|
|
665
|
+
known: DELETED_LOCATION_KNOWN,
|
|
666
|
+
knownList: KNOWN_DELETED_LOCATION_FIELDS,
|
|
667
|
+
defaultSelect: DEFAULT_DELETED_LOCATION_LIST_SELECT,
|
|
668
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
669
|
+
denialHints: DELETED_LOCATION_DENIAL_HINTS,
|
|
670
|
+
showHint: "mg-axi entra conditional-access deleted-named-location show --id <deleted-named-location-id>",
|
|
671
|
+
emptyHint: "0 deleted named locations matched; the absence of results is the answer, not an error",
|
|
672
|
+
preserveType: true,
|
|
673
|
+
};
|
|
674
|
+
const AUTH_CONTEXT_SHOW = {
|
|
675
|
+
command: "entra conditional-access auth-context show",
|
|
676
|
+
key: "authContext",
|
|
677
|
+
param: "authenticationContextClassReference-id",
|
|
678
|
+
noun: "auth-context",
|
|
679
|
+
known: AUTH_CONTEXT_KNOWN,
|
|
680
|
+
knownList: KNOWN_AUTH_CONTEXT_FIELDS,
|
|
681
|
+
defaultSelect: DEFAULT_AUTH_CONTEXT_SHOW_SELECT,
|
|
682
|
+
defaultScopes: DEFAULT_AUTH_CONTEXT_SCOPES,
|
|
683
|
+
denialHints: AUTH_CONTEXT_DENIAL_HINTS,
|
|
684
|
+
preserveType: false,
|
|
685
|
+
};
|
|
686
|
+
const DELETED_POLICY_SHOW = {
|
|
687
|
+
command: "entra conditional-access deleted-policy show",
|
|
688
|
+
key: "deletedPolicy",
|
|
689
|
+
param: "conditionalAccessPolicy-id",
|
|
690
|
+
noun: "deleted-policy",
|
|
691
|
+
known: DELETED_POLICY_KNOWN,
|
|
692
|
+
knownList: KNOWN_DELETED_POLICY_FIELDS,
|
|
693
|
+
defaultSelect: DEFAULT_DELETED_POLICY_SHOW_SELECT,
|
|
694
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
695
|
+
denialHints: DELETED_POLICY_DENIAL_HINTS,
|
|
696
|
+
preserveType: false,
|
|
697
|
+
};
|
|
698
|
+
const DELETED_LOCATION_SHOW = {
|
|
699
|
+
command: "entra conditional-access deleted-named-location show",
|
|
700
|
+
key: "deletedNamedLocation",
|
|
701
|
+
param: "namedLocation-id",
|
|
702
|
+
noun: "deleted-named-location",
|
|
703
|
+
known: DELETED_LOCATION_KNOWN,
|
|
704
|
+
knownList: KNOWN_DELETED_LOCATION_FIELDS,
|
|
705
|
+
defaultSelect: DEFAULT_DELETED_LOCATION_SHOW_SELECT,
|
|
706
|
+
defaultScopes: DEFAULT_DELEGATED_SCOPES,
|
|
707
|
+
denialHints: DELETED_LOCATION_DENIAL_HINTS,
|
|
708
|
+
preserveType: true,
|
|
709
|
+
};
|
|
710
|
+
export async function listAuthContexts(session, flags, profile, operation, help, profileName) {
|
|
711
|
+
return listCollection(AUTH_CONTEXT_LIST, session, flags, profile, operation, help, profileName);
|
|
712
|
+
}
|
|
713
|
+
export async function showAuthContext(session, flags, profile, operation, help, profileName) {
|
|
714
|
+
return showSingle(AUTH_CONTEXT_SHOW, session, flags, profile, operation, help, profileName);
|
|
715
|
+
}
|
|
716
|
+
export async function listDeletedPolicies(session, flags, profile, operation, help, profileName) {
|
|
717
|
+
return listCollection(DELETED_POLICY_LIST, session, flags, profile, operation, help, profileName);
|
|
718
|
+
}
|
|
719
|
+
export async function showDeletedPolicy(session, flags, profile, operation, help, profileName) {
|
|
720
|
+
return showSingle(DELETED_POLICY_SHOW, session, flags, profile, operation, help, profileName);
|
|
721
|
+
}
|
|
722
|
+
export async function listDeletedNamedLocations(session, flags, profile, operation, help, profileName) {
|
|
723
|
+
return listCollection(DELETED_LOCATION_LIST, session, flags, profile, operation, help, profileName);
|
|
724
|
+
}
|
|
725
|
+
export async function showDeletedNamedLocation(session, flags, profile, operation, help, profileName) {
|
|
726
|
+
return showSingle(DELETED_LOCATION_SHOW, session, flags, profile, operation, help, profileName);
|
|
727
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { listTotals } from "./list-totals.js";
|
|
2
3
|
// EXT-01 directory federation-configurations subfamily: the read mapping
|
|
3
4
|
// behind `mg-axi entra federation-configuration list/show/count/available-types`.
|
|
4
5
|
// Operation construction stays beside its command; the shared session owns
|
|
@@ -203,20 +204,22 @@ export async function listFederationConfigurations(session, flags, profile, oper
|
|
|
203
204
|
if (!result.complete) {
|
|
204
205
|
return {
|
|
205
206
|
federationConfigurations: configurations,
|
|
206
|
-
|
|
207
|
+
...listTotals(configurations.length, result.total, "federation configurations", false),
|
|
208
|
+
complete: false,
|
|
209
|
+
reason: result.reason,
|
|
207
210
|
cursor: result.cursor,
|
|
208
211
|
help: [...truncationHints, `Resume losslessly with the same flags plus --cursor <cursor-from-output> ${profileHint(profileName)}`, showHint, CERT_BLOB_NOTE, WORKFORCE_NOTE],
|
|
209
212
|
};
|
|
210
213
|
}
|
|
211
|
-
const count = { returned: configurations.length, complete: true };
|
|
212
214
|
if (!configurations.length) {
|
|
213
215
|
return {
|
|
214
216
|
federationConfigurations: configurations,
|
|
215
|
-
|
|
217
|
+
...listTotals(configurations.length, result.total, "federation configurations", true),
|
|
218
|
+
complete: true,
|
|
216
219
|
help: ["0 federation configurations matched; no SAML or WS-Fed federation is configured for the tenant, or no row passed --filter", CERT_BLOB_NOTE, WORKFORCE_NOTE],
|
|
217
220
|
};
|
|
218
221
|
}
|
|
219
|
-
return { federationConfigurations: configurations,
|
|
222
|
+
return { federationConfigurations: configurations, ...listTotals(configurations.length, result.total, "federation configurations", true), complete: true, help: [...truncationHints, showHint, CERT_BLOB_NOTE, WORKFORCE_NOTE] };
|
|
220
223
|
}
|
|
221
224
|
export async function showFederationConfiguration(session, flags, profile, operation, help, profileName) {
|
|
222
225
|
const { select, fields } = selectedFields(flags, DEFAULT_SHOW_SELECT, help);
|
package/dist/entra-grants.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { listTotals } from "./list-totals.js";
|
|
2
3
|
// READ-08: the Entra consent-grant read mapping behind
|
|
3
4
|
// `mg-axi entra service-principal oauth2-grant list` and
|
|
4
5
|
// `mg-axi entra service-principal app-role-assignment list` for a named
|
|
@@ -181,6 +182,7 @@ const APP_ROLE_DENIAL_HINTS = [
|
|
|
181
182
|
const OAUTH2_GRANT_LIST = {
|
|
182
183
|
command: "entra service-principal oauth2-grant list",
|
|
183
184
|
key: "oauth2PermissionGrants",
|
|
185
|
+
noun: "oauth2 grants",
|
|
184
186
|
known: GRANT_KNOWN,
|
|
185
187
|
knownList: KNOWN_GRANT_FIELDS,
|
|
186
188
|
defaultSelect: DEFAULT_GRANT_SELECT,
|
|
@@ -192,6 +194,7 @@ const OAUTH2_GRANT_LIST = {
|
|
|
192
194
|
const APP_ROLE_LIST = {
|
|
193
195
|
command: "entra service-principal app-role-assignment list",
|
|
194
196
|
key: "appRoleAssignments",
|
|
197
|
+
noun: "app role assignments",
|
|
195
198
|
known: APP_ROLE_KNOWN,
|
|
196
199
|
knownList: KNOWN_APP_ROLE_FIELDS,
|
|
197
200
|
defaultSelect: DEFAULT_APP_ROLE_SELECT,
|
|
@@ -253,16 +256,17 @@ async function listCollection(shape, session, flags, profile, operation, help, p
|
|
|
253
256
|
if (!result.complete) {
|
|
254
257
|
return {
|
|
255
258
|
[shape.key]: rows,
|
|
256
|
-
|
|
259
|
+
...listTotals(rows.length, result.total, shape.noun, false),
|
|
260
|
+
complete: false,
|
|
261
|
+
reason: result.reason,
|
|
257
262
|
cursor: result.cursor,
|
|
258
263
|
help: [...truncationHints, `Resume losslessly with the same flags plus --cursor <cursor-from-output> ${profileHint(profileName)}`, ...standing],
|
|
259
264
|
};
|
|
260
265
|
}
|
|
261
|
-
const count = { returned: rows.length, complete: true };
|
|
262
266
|
if (!rows.length) {
|
|
263
|
-
return { [shape.key]: rows,
|
|
267
|
+
return { [shape.key]: rows, ...listTotals(rows.length, result.total, shape.noun, true), complete: true, help: [shape.emptyNote, ...standing] };
|
|
264
268
|
}
|
|
265
|
-
return { [shape.key]: rows,
|
|
269
|
+
return { [shape.key]: rows, ...listTotals(rows.length, result.total, shape.noun, true), complete: true, help: [...truncationHints, ...standing] };
|
|
266
270
|
}
|
|
267
271
|
export async function listOAuth2Grants(session, flags, profile, operation, help, profileName) {
|
|
268
272
|
return listCollection(OAUTH2_GRANT_LIST, session, flags, profile, operation, help, profileName);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { listTotals } from "./list-totals.js";
|
|
2
3
|
// EXT-01 group lifecycle subfamily: the read mapping behind
|
|
3
4
|
// `mg-axi entra group-lifecycle-policy list/show/count` and
|
|
4
5
|
// `mg-axi entra group-setting-template list/show/count`. Operation
|
|
@@ -241,20 +242,22 @@ export async function listLifecyclePolicies(session, flags, profile, operation,
|
|
|
241
242
|
if (!result.complete) {
|
|
242
243
|
return {
|
|
243
244
|
groupLifecyclePolicies: policies,
|
|
244
|
-
|
|
245
|
+
...listTotals(policies.length, result.total, "lifecycle policies", false),
|
|
246
|
+
complete: false,
|
|
247
|
+
reason: result.reason,
|
|
245
248
|
cursor: result.cursor,
|
|
246
249
|
help: [...truncationHints, resumeHint(profileName), showHint],
|
|
247
250
|
};
|
|
248
251
|
}
|
|
249
|
-
const count = { returned: policies.length, complete: true };
|
|
250
252
|
if (!policies.length) {
|
|
251
253
|
return {
|
|
252
254
|
groupLifecyclePolicies: policies,
|
|
253
|
-
|
|
255
|
+
...listTotals(policies.length, result.total, "lifecycle policies", true),
|
|
256
|
+
complete: true,
|
|
254
257
|
help: ["0 lifecycle policies matched; the absence of results is the answer, not an error"],
|
|
255
258
|
};
|
|
256
259
|
}
|
|
257
|
-
return { groupLifecyclePolicies: policies,
|
|
260
|
+
return { groupLifecyclePolicies: policies, ...listTotals(policies.length, result.total, "lifecycle policies", true), complete: true, help: [...truncationHints, showHint] };
|
|
258
261
|
}
|
|
259
262
|
export async function showLifecyclePolicy(session, flags, profile, operation, help, profileName) {
|
|
260
263
|
const { select, fields } = selectedFields(flags, KNOWN_LIFECYCLE, KNOWN_LIFECYCLE_FIELDS, DEFAULT_LIFECYCLE_SHOW_SELECT, help);
|
|
@@ -305,20 +308,22 @@ export async function listSettingTemplates(session, flags, profile, operation, h
|
|
|
305
308
|
if (!result.complete) {
|
|
306
309
|
return {
|
|
307
310
|
groupSettingTemplates: templates,
|
|
308
|
-
|
|
311
|
+
...listTotals(templates.length, result.total, "setting templates", false),
|
|
312
|
+
complete: false,
|
|
313
|
+
reason: result.reason,
|
|
309
314
|
cursor: result.cursor,
|
|
310
315
|
help: [...truncationHints, resumeHint(profileName), showHint, filterNote],
|
|
311
316
|
};
|
|
312
317
|
}
|
|
313
|
-
const count = { returned: templates.length, complete: true };
|
|
314
318
|
if (!templates.length) {
|
|
315
319
|
return {
|
|
316
320
|
groupSettingTemplates: templates,
|
|
317
|
-
|
|
321
|
+
...listTotals(templates.length, result.total, "setting templates", true),
|
|
322
|
+
complete: true,
|
|
318
323
|
help: [filterNote, "0 setting templates matched; the absence of results is the answer, not an error"],
|
|
319
324
|
};
|
|
320
325
|
}
|
|
321
|
-
return { groupSettingTemplates: templates,
|
|
326
|
+
return { groupSettingTemplates: templates, ...listTotals(templates.length, result.total, "setting templates", true), complete: true, help: [...truncationHints, showHint, filterNote] };
|
|
322
327
|
}
|
|
323
328
|
export async function showSettingTemplate(session, flags, profile, operation, help, profileName) {
|
|
324
329
|
const { select, fields } = selectedFields(flags, KNOWN_TEMPLATES, KNOWN_TEMPLATE_FIELDS, DEFAULT_TEMPLATE_SHOW_SELECT, help);
|