azp-cli 0.0.1

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 (77) hide show
  1. package/.vscode/extensions.json +3 -0
  2. package/.vscode/launch.json +25 -0
  3. package/.vscode/settings.json +25 -0
  4. package/.vscode/tasks.json +28 -0
  5. package/README.md +203 -0
  6. package/dist/auth.d.ts +11 -0
  7. package/dist/auth.d.ts.map +1 -0
  8. package/dist/auth.js +52 -0
  9. package/dist/auth.js.map +1 -0
  10. package/dist/azure-pim.d.ts +44 -0
  11. package/dist/azure-pim.d.ts.map +1 -0
  12. package/dist/azure-pim.js +183 -0
  13. package/dist/azure-pim.js.map +1 -0
  14. package/dist/cli.d.ts +5 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +339 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +54 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/ui/App.d.ts +9 -0
  23. package/dist/ui/App.d.ts.map +1 -0
  24. package/dist/ui/App.js +85 -0
  25. package/dist/ui/App.js.map +1 -0
  26. package/dist/ui/components.d.ts +18 -0
  27. package/dist/ui/components.d.ts.map +1 -0
  28. package/dist/ui/components.js +13 -0
  29. package/dist/ui/components.js.map +1 -0
  30. package/dist/ui/router.d.ts +22 -0
  31. package/dist/ui/router.d.ts.map +1 -0
  32. package/dist/ui/router.js +19 -0
  33. package/dist/ui/router.js.map +1 -0
  34. package/dist/ui/screens/ActivateFlow.d.ts +25 -0
  35. package/dist/ui/screens/ActivateFlow.d.ts.map +1 -0
  36. package/dist/ui/screens/ActivateFlow.js +195 -0
  37. package/dist/ui/screens/ActivateFlow.js.map +1 -0
  38. package/dist/ui/screens/DeactivateFlow.d.ts +22 -0
  39. package/dist/ui/screens/DeactivateFlow.d.ts.map +1 -0
  40. package/dist/ui/screens/DeactivateFlow.js +115 -0
  41. package/dist/ui/screens/DeactivateFlow.js.map +1 -0
  42. package/dist/ui/useExitConfirmation.d.ts +7 -0
  43. package/dist/ui/useExitConfirmation.d.ts.map +1 -0
  44. package/dist/ui/useExitConfirmation.js +17 -0
  45. package/dist/ui/useExitConfirmation.js.map +1 -0
  46. package/dist/ui/widgets/CheckboxList.d.ts +14 -0
  47. package/dist/ui/widgets/CheckboxList.d.ts.map +1 -0
  48. package/dist/ui/widgets/CheckboxList.js +59 -0
  49. package/dist/ui/widgets/CheckboxList.js.map +1 -0
  50. package/dist/ui/widgets/ConfirmPrompt.d.ts +8 -0
  51. package/dist/ui/widgets/ConfirmPrompt.d.ts.map +1 -0
  52. package/dist/ui/widgets/ConfirmPrompt.js +19 -0
  53. package/dist/ui/widgets/ConfirmPrompt.js.map +1 -0
  54. package/dist/ui/widgets/NumberPrompt.d.ts +10 -0
  55. package/dist/ui/widgets/NumberPrompt.d.ts.map +1 -0
  56. package/dist/ui/widgets/NumberPrompt.js +38 -0
  57. package/dist/ui/widgets/NumberPrompt.js.map +1 -0
  58. package/dist/ui/widgets/SelectList.d.ts +14 -0
  59. package/dist/ui/widgets/SelectList.d.ts.map +1 -0
  60. package/dist/ui/widgets/SelectList.js +34 -0
  61. package/dist/ui/widgets/SelectList.js.map +1 -0
  62. package/dist/ui/widgets/TextPrompt.d.ts +10 -0
  63. package/dist/ui/widgets/TextPrompt.d.ts.map +1 -0
  64. package/dist/ui/widgets/TextPrompt.js +30 -0
  65. package/dist/ui/widgets/TextPrompt.js.map +1 -0
  66. package/dist/ui.d.ts +26 -0
  67. package/dist/ui.d.ts.map +1 -0
  68. package/dist/ui.js +183 -0
  69. package/dist/ui.js.map +1 -0
  70. package/package.json +47 -0
  71. package/pnpm-workspace.yaml +2 -0
  72. package/src/auth.ts +66 -0
  73. package/src/azure-pim.ts +262 -0
  74. package/src/cli.ts +401 -0
  75. package/src/index.ts +65 -0
  76. package/src/ui.ts +253 -0
  77. package/tsconfig.json +45 -0
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import type { AuthContext } from "../../auth";
3
+ import { type AzureSubscription, type EligibleAzureRole } from "../../azure-pim";
4
+ import type { NavigateAction, ScreenId } from "../router";
5
+ export type ActivateFlowState = {
6
+ subscription?: AzureSubscription;
7
+ eligibleRoles?: EligibleAzureRole[];
8
+ selectedRoleIds: string[];
9
+ durationHours?: number;
10
+ justification?: string;
11
+ results?: Array<{
12
+ roleId: string;
13
+ ok: boolean;
14
+ error?: string;
15
+ }>;
16
+ };
17
+ export type ActivateFlowProps = {
18
+ authContext: AuthContext;
19
+ screen: ScreenId;
20
+ state: ActivateFlowState;
21
+ setState: (updater: (prev: ActivateFlowState) => ActivateFlowState) => void;
22
+ navigate: (action: NavigateAction) => void;
23
+ };
24
+ export declare const ActivateFlow: React.FC<ActivateFlowProps>;
25
+ //# sourceMappingURL=ActivateFlow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivateFlow.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/ActivateFlow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAGvB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;IACzB,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,iBAAiB,KAAK,IAAI,CAAC;IAC5E,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqQpD,CAAC"}
@@ -0,0 +1,195 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { activateAzureRole, fetchEligibleRolesForSubscription, fetchSubscriptions, } from "../../azure-pim";
5
+ import { EmptyState, ErrorState } from "../components";
6
+ import { CheckboxList } from "../widgets/CheckboxList";
7
+ import { ConfirmPrompt } from "../widgets/ConfirmPrompt";
8
+ import { NumberPrompt } from "../widgets/NumberPrompt";
9
+ import { SelectList } from "../widgets/SelectList";
10
+ import { TextPrompt } from "../widgets/TextPrompt";
11
+ export const ActivateFlow = ({ authContext, screen, state, setState, navigate }) => {
12
+ const [isLoading, setIsLoading] = useState(false);
13
+ const [error, setError] = useState(null);
14
+ const [subscriptions, setSubscriptions] = useState(null);
15
+ useEffect(() => {
16
+ if (screen !== "activate/subscriptions")
17
+ return;
18
+ let cancelled = false;
19
+ (async () => {
20
+ setIsLoading(true);
21
+ setError(null);
22
+ try {
23
+ const subs = await fetchSubscriptions(authContext.credential);
24
+ if (cancelled)
25
+ return;
26
+ setSubscriptions(subs);
27
+ }
28
+ catch (e) {
29
+ if (cancelled)
30
+ return;
31
+ setError(e instanceof Error ? e.message : String(e));
32
+ }
33
+ finally {
34
+ if (!cancelled)
35
+ setIsLoading(false);
36
+ }
37
+ })();
38
+ return () => {
39
+ cancelled = true;
40
+ };
41
+ }, [screen, authContext.credential]);
42
+ const subscriptionItems = useMemo(() => {
43
+ return (subscriptions ?? []).map((s) => ({
44
+ key: s.subscriptionId,
45
+ label: s.displayName,
46
+ meta: s.subscriptionId,
47
+ value: s,
48
+ }));
49
+ }, [subscriptions]);
50
+ useEffect(() => {
51
+ if (screen !== "activate/eligible-roles")
52
+ return;
53
+ const subscription = state.subscription;
54
+ if (!subscription) {
55
+ navigate({ type: "replace", route: { id: "activate/subscriptions" } });
56
+ return;
57
+ }
58
+ let cancelled = false;
59
+ (async () => {
60
+ setIsLoading(true);
61
+ setError(null);
62
+ try {
63
+ const roles = await fetchEligibleRolesForSubscription(authContext.credential, subscription.subscriptionId, subscription.displayName, authContext.userId);
64
+ if (cancelled)
65
+ return;
66
+ setState((prev) => ({ ...prev, eligibleRoles: roles }));
67
+ }
68
+ catch (e) {
69
+ if (cancelled)
70
+ return;
71
+ setError(e instanceof Error ? e.message : String(e));
72
+ }
73
+ finally {
74
+ if (!cancelled)
75
+ setIsLoading(false);
76
+ }
77
+ })();
78
+ return () => {
79
+ cancelled = true;
80
+ };
81
+ }, [screen, state.subscription, authContext.credential, authContext.userId, navigate, setState]);
82
+ const roleItems = useMemo(() => {
83
+ const roles = state.eligibleRoles ?? [];
84
+ return roles.map((r) => ({
85
+ key: r.id,
86
+ label: `${r.roleName} — ${r.scopeDisplayName}`,
87
+ }));
88
+ }, [state.eligibleRoles]);
89
+ useEffect(() => {
90
+ if (screen !== "activate/progress")
91
+ return;
92
+ if (!state.subscription || !state.eligibleRoles || state.selectedRoleIds.length === 0 || !state.durationHours || !state.justification) {
93
+ navigate({ type: "home" });
94
+ return;
95
+ }
96
+ const subscription = state.subscription;
97
+ const eligibleRoles = state.eligibleRoles;
98
+ const durationHours = state.durationHours;
99
+ const justification = state.justification;
100
+ let cancelled = false;
101
+ (async () => {
102
+ setIsLoading(true);
103
+ setError(null);
104
+ setState((prev) => ({ ...prev, results: [] }));
105
+ const results = [];
106
+ for (const roleId of state.selectedRoleIds) {
107
+ if (cancelled)
108
+ return;
109
+ const role = eligibleRoles.find((r) => r.id === roleId);
110
+ if (!role) {
111
+ results.push({ roleId, ok: false, error: "Role not found" });
112
+ setState((prev) => ({ ...prev, results: [...results] }));
113
+ continue;
114
+ }
115
+ const req = {
116
+ principalId: authContext.userId,
117
+ roleDefinitionId: role.roleDefinitionId,
118
+ roleName: `${role.roleName} - ${role.scopeDisplayName}`,
119
+ roleEligibilityScheduleId: role.roleEligibilityScheduleId,
120
+ scope: role.scope,
121
+ durationHours,
122
+ justification,
123
+ };
124
+ try {
125
+ await activateAzureRole(authContext.credential, req, subscription.subscriptionId);
126
+ results.push({ roleId, ok: true });
127
+ }
128
+ catch (e) {
129
+ results.push({ roleId, ok: false, error: e instanceof Error ? e.message : String(e) });
130
+ }
131
+ setState((prev) => ({ ...prev, results: [...results] }));
132
+ }
133
+ setIsLoading(false);
134
+ })();
135
+ return () => {
136
+ cancelled = true;
137
+ };
138
+ }, [screen, state.subscription, state.eligibleRoles, state.selectedRoleIds, state.durationHours, state.justification, authContext, navigate, setState]);
139
+ if (error) {
140
+ return _jsx(ErrorState, { message: "Activation flow error", details: error });
141
+ }
142
+ if (screen === "activate/subscriptions") {
143
+ if (isLoading && !subscriptions)
144
+ return _jsx(Text, { dimColor: true, children: "Loading subscriptions\u2026" });
145
+ if (!subscriptions)
146
+ return _jsx(Text, { dimColor: true, children: "Loading\u2026" });
147
+ if (subscriptions.length === 0)
148
+ return _jsx(EmptyState, { message: "No subscriptions found." });
149
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: "Select a subscription:" }), _jsx(SelectList, { items: subscriptionItems, isLoading: isLoading, onSelect: (sub) => {
150
+ setState((prev) => ({ ...prev, subscription: sub, eligibleRoles: undefined, selectedRoleIds: [] }));
151
+ navigate({ type: "push", route: { id: "activate/eligible-roles" } });
152
+ } })] }));
153
+ }
154
+ if (screen === "activate/eligible-roles") {
155
+ const roles = state.eligibleRoles;
156
+ if (!roles && isLoading)
157
+ return _jsx(Text, { dimColor: true, children: "Loading eligible roles\u2026" });
158
+ if (!roles)
159
+ return _jsx(Text, { dimColor: true, children: "Loading\u2026" });
160
+ if (roles.length === 0)
161
+ return _jsx(EmptyState, { message: "No eligible roles found for this subscription." });
162
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: "Pick eligible roles to activate:" }), _jsx(CheckboxList, { items: roleItems, onSubmit: (selectedKeys) => {
163
+ if (selectedKeys.length === 0)
164
+ return;
165
+ setState((prev) => ({ ...prev, selectedRoleIds: selectedKeys }));
166
+ navigate({ type: "push", route: { id: "activate/duration" } });
167
+ } }), _jsx(Text, { dimColor: true, children: "Tip: press \u201Ca\u201D to toggle all." })] }));
168
+ }
169
+ if (screen === "activate/duration") {
170
+ return (_jsx(NumberPrompt, { label: "Duration in hours (1-8):", initialValue: state.durationHours ?? 8, min: 1, max: 8, onSubmit: (hours) => {
171
+ setState((prev) => ({ ...prev, durationHours: hours }));
172
+ navigate({ type: "push", route: { id: "activate/justification" } });
173
+ } }));
174
+ }
175
+ if (screen === "activate/justification") {
176
+ return (_jsx(TextPrompt, { label: "Justification:", initialValue: state.justification ?? "Activated via azp-cli", validate: (v) => (v.trim().length >= 5 ? true : "Justification should be at least 5 characters"), onSubmit: (value) => {
177
+ setState((prev) => ({ ...prev, justification: value }));
178
+ navigate({ type: "push", route: { id: "activate/confirm" } });
179
+ } }));
180
+ }
181
+ if (screen === "activate/confirm") {
182
+ const subscriptionName = state.subscription?.displayName ?? "(unknown)";
183
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { children: ["Activate ", _jsx(Text, { bold: true, children: state.selectedRoleIds.length }), " role(s) on ", _jsx(Text, { bold: true, children: subscriptionName }), "?"] }), _jsxs(Text, { dimColor: true, children: ["Duration: ", state.durationHours ?? "?", "h"] }), _jsxs(Text, { dimColor: true, children: ["Justification: ", state.justification ?? "?"] }), _jsx(ConfirmPrompt, { message: "Confirm activation?", onConfirm: () => navigate({ type: "push", route: { id: "activate/progress" } }), onCancel: () => navigate({ type: "back" }) })] }));
184
+ }
185
+ if (screen === "activate/progress") {
186
+ const results = state.results ?? [];
187
+ const total = state.selectedRoleIds.length;
188
+ const done = results.length;
189
+ const ok = results.filter((r) => r.ok).length;
190
+ const fail = results.filter((r) => !r.ok).length;
191
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { children: ["Progress: ", done, "/", total, " (ok: ", ok, ", failed: ", fail, ")"] }), _jsx(Box, { flexDirection: "column", children: results.slice(-8).map((r) => (_jsxs(Text, { color: r.ok ? "green" : "red", children: [r.ok ? "✓" : "✗", " ", r.roleId] }, r.roleId))) }), done === total && !isLoading ? _jsx(Text, { dimColor: true, children: "Done. Press m for menu." }) : _jsx(Text, { dimColor: true, children: "Working\u2026" })] }));
192
+ }
193
+ return _jsx(Text, { dimColor: true, children: "Unknown activate screen." });
194
+ };
195
+ //# sourceMappingURL=ActivateFlow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivateFlow.js","sourceRoot":"","sources":["../../../src/ui/screens/ActivateFlow.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import type { AuthContext } from "../../auth";
3
+ import { type ActiveAzureRole } from "../../azure-pim";
4
+ import type { NavigateAction, ScreenId } from "../router";
5
+ export type DeactivateFlowState = {
6
+ activeRoles?: ActiveAzureRole[];
7
+ selectedLinkedIds: string[];
8
+ results?: Array<{
9
+ linkedId: string;
10
+ ok: boolean;
11
+ error?: string;
12
+ }>;
13
+ };
14
+ export type DeactivateFlowProps = {
15
+ authContext: AuthContext;
16
+ screen: ScreenId;
17
+ state: DeactivateFlowState;
18
+ setState: (updater: (prev: DeactivateFlowState) => DeactivateFlowState) => void;
19
+ navigate: (action: NavigateAction) => void;
20
+ };
21
+ export declare const DeactivateFlow: React.FC<DeactivateFlowProps>;
22
+ //# sourceMappingURL=DeactivateFlow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeactivateFlow.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/DeactivateFlow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1D,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,mBAAmB,KAAK,IAAI,CAAC;IAChF,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAsJxD,CAAC"}
@@ -0,0 +1,115 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { deactivateAzureRole, listActiveAzureRolesForUser, } from "../../azure-pim";
5
+ import { EmptyState, ErrorState } from "../components";
6
+ import { CheckboxList } from "../widgets/CheckboxList";
7
+ import { ConfirmPrompt } from "../widgets/ConfirmPrompt";
8
+ export const DeactivateFlow = ({ authContext, screen, state, setState, navigate }) => {
9
+ const [isLoading, setIsLoading] = useState(false);
10
+ const [error, setError] = useState(null);
11
+ useEffect(() => {
12
+ if (screen !== "deactivate/roles")
13
+ return;
14
+ let cancelled = false;
15
+ (async () => {
16
+ setIsLoading(true);
17
+ setError(null);
18
+ try {
19
+ const roles = await listActiveAzureRolesForUser(authContext.credential, authContext.userId);
20
+ if (cancelled)
21
+ return;
22
+ setState((prev) => ({ ...prev, activeRoles: roles }));
23
+ }
24
+ catch (e) {
25
+ if (cancelled)
26
+ return;
27
+ setError(e instanceof Error ? e.message : String(e));
28
+ }
29
+ finally {
30
+ if (!cancelled)
31
+ setIsLoading(false);
32
+ }
33
+ })();
34
+ return () => {
35
+ cancelled = true;
36
+ };
37
+ }, [screen, authContext.credential, authContext.userId, setState]);
38
+ const roleItems = useMemo(() => {
39
+ const roles = state.activeRoles ?? [];
40
+ return roles.map((r) => ({
41
+ key: r.linkedRoleEligibilityScheduleId,
42
+ label: `${r.roleName} — ${r.scopeDisplayName}`,
43
+ meta: `${r.subscriptionName} (${r.subscriptionId})`,
44
+ }));
45
+ }, [state.activeRoles]);
46
+ useEffect(() => {
47
+ if (screen !== "deactivate/progress")
48
+ return;
49
+ if (!state.activeRoles || state.selectedLinkedIds.length === 0) {
50
+ navigate({ type: "home" });
51
+ return;
52
+ }
53
+ const activeRoles = state.activeRoles;
54
+ let cancelled = false;
55
+ (async () => {
56
+ setIsLoading(true);
57
+ setError(null);
58
+ setState((prev) => ({ ...prev, results: [] }));
59
+ const results = [];
60
+ for (const linkedId of state.selectedLinkedIds) {
61
+ if (cancelled)
62
+ return;
63
+ const role = activeRoles.find((r) => r.linkedRoleEligibilityScheduleId === linkedId);
64
+ if (!role) {
65
+ results.push({ linkedId, ok: false, error: "Role not found" });
66
+ setState((prev) => ({ ...prev, results: [...results] }));
67
+ continue;
68
+ }
69
+ try {
70
+ await deactivateAzureRole(authContext.credential, role.scope, role.linkedRoleEligibilityScheduleId, role.subscriptionId, authContext.userId, role.roleDefinitionId);
71
+ results.push({ linkedId, ok: true });
72
+ }
73
+ catch (e) {
74
+ results.push({ linkedId, ok: false, error: e instanceof Error ? e.message : String(e) });
75
+ }
76
+ setState((prev) => ({ ...prev, results: [...results] }));
77
+ }
78
+ setIsLoading(false);
79
+ })();
80
+ return () => {
81
+ cancelled = true;
82
+ };
83
+ }, [screen, state.activeRoles, state.selectedLinkedIds, authContext, navigate, setState]);
84
+ if (error) {
85
+ return _jsx(ErrorState, { message: "Deactivation flow error", details: error });
86
+ }
87
+ if (screen === "deactivate/roles") {
88
+ const roles = state.activeRoles;
89
+ if (!roles && isLoading)
90
+ return _jsx(Text, { dimColor: true, children: "Loading active roles\u2026" });
91
+ if (!roles)
92
+ return _jsx(Text, { dimColor: true, children: "Loading\u2026" });
93
+ if (roles.length === 0)
94
+ return _jsx(EmptyState, { message: "No active roles found." });
95
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: "Select active roles to deactivate:" }), _jsx(CheckboxList, { items: roleItems, onSubmit: (selectedKeys) => {
96
+ if (selectedKeys.length === 0)
97
+ return;
98
+ setState((prev) => ({ ...prev, selectedLinkedIds: selectedKeys }));
99
+ navigate({ type: "push", route: { id: "deactivate/confirm" } });
100
+ } }), _jsx(Text, { dimColor: true, children: "Tip: press \u201Ca\u201D to toggle all." })] }));
101
+ }
102
+ if (screen === "deactivate/confirm") {
103
+ return (_jsx(ConfirmPrompt, { message: `Deactivate ${state.selectedLinkedIds.length} role(s)?`, onConfirm: () => navigate({ type: "push", route: { id: "deactivate/progress" } }), onCancel: () => navigate({ type: "back" }) }));
104
+ }
105
+ if (screen === "deactivate/progress") {
106
+ const results = state.results ?? [];
107
+ const total = state.selectedLinkedIds.length;
108
+ const done = results.length;
109
+ const ok = results.filter((r) => r.ok).length;
110
+ const fail = results.filter((r) => !r.ok).length;
111
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { children: ["Progress: ", done, "/", total, " (ok: ", ok, ", failed: ", fail, ")"] }), _jsx(Box, { flexDirection: "column", children: results.slice(-8).map((r) => (_jsxs(Text, { color: r.ok ? "green" : "red", children: [r.ok ? "✓" : "✗", " ", r.linkedId] }, r.linkedId))) }), done === total && !isLoading ? _jsx(Text, { dimColor: true, children: "Done. Press m for menu." }) : _jsx(Text, { dimColor: true, children: "Working\u2026" })] }));
112
+ }
113
+ return _jsx(Text, { dimColor: true, children: "Unknown deactivate screen." });
114
+ };
115
+ //# sourceMappingURL=DeactivateFlow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeactivateFlow.js","sourceRoot":"","sources":["../../../src/ui/screens/DeactivateFlow.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type ExitState = {
2
+ isExitConfirmOpen: boolean;
3
+ openExitConfirm: () => void;
4
+ closeExitConfirm: () => void;
5
+ };
6
+ export declare const useExitConfirmation: () => ExitState;
7
+ //# sourceMappingURL=useExitConfirmation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useExitConfirmation.d.ts","sourceRoot":"","sources":["../../src/ui/useExitConfirmation.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,QAAO,SAkBtC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from "react";
2
+ export const useExitConfirmation = () => {
3
+ const [isExitConfirmOpen, setIsExitConfirmOpen] = useState(false);
4
+ const openExitConfirm = () => setIsExitConfirmOpen(true);
5
+ const closeExitConfirm = () => setIsExitConfirmOpen(false);
6
+ useEffect(() => {
7
+ const onSigint = () => {
8
+ setIsExitConfirmOpen(true);
9
+ };
10
+ process.on("SIGINT", onSigint);
11
+ return () => {
12
+ process.off("SIGINT", onSigint);
13
+ };
14
+ }, []);
15
+ return { isExitConfirmOpen, openExitConfirm, closeExitConfirm };
16
+ };
17
+ //# sourceMappingURL=useExitConfirmation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useExitConfirmation.js","sourceRoot":"","sources":["../../src/ui/useExitConfirmation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAQ5C,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAc,EAAE;IACjD,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElE,MAAM,eAAe,GAAG,GAAS,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,gBAAgB,GAAG,GAAS,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,GAAS,EAAE;YAC1B,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/B,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC;AAClE,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ export type CheckboxItem = {
3
+ key: string;
4
+ label: string;
5
+ meta?: string;
6
+ };
7
+ export type CheckboxListProps = {
8
+ items: CheckboxItem[];
9
+ isLoading?: boolean;
10
+ emptyLabel?: string;
11
+ onSubmit: (selectedKeys: string[]) => void;
12
+ };
13
+ export declare const CheckboxList: React.FC<CheckboxListProps>;
14
+ //# sourceMappingURL=CheckboxList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckboxList.d.ts","sourceRoot":"","sources":["../../../src/ui/widgets/CheckboxList.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAEjD,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA4FpD,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from "ink";
3
+ import { useMemo, useState } from "react";
4
+ export const CheckboxList = ({ items, isLoading, emptyLabel, onSubmit }) => {
5
+ const [cursor, setCursor] = useState(0);
6
+ const [selected, setSelected] = useState({});
7
+ const safeItems = useMemo(() => items ?? [], [items]);
8
+ const maxIndex = Math.max(0, safeItems.length - 1);
9
+ const selectedKeys = useMemo(() => Object.keys(selected).filter((k) => selected[k]), [selected]);
10
+ useInput((input, key) => {
11
+ if (isLoading)
12
+ return;
13
+ if (safeItems.length === 0)
14
+ return;
15
+ if (key.upArrow)
16
+ setCursor((i) => (i <= 0 ? maxIndex : i - 1));
17
+ if (key.downArrow)
18
+ setCursor((i) => (i >= maxIndex ? 0 : i + 1));
19
+ if (input === " ") {
20
+ const item = safeItems[cursor];
21
+ if (!item)
22
+ return;
23
+ setSelected((prev) => ({ ...prev, [item.key]: !prev[item.key] }));
24
+ }
25
+ if (input === "a") {
26
+ const allSelected = safeItems.every((it) => selected[it.key]);
27
+ if (allSelected) {
28
+ setSelected({});
29
+ }
30
+ else {
31
+ const next = {};
32
+ for (const it of safeItems)
33
+ next[it.key] = true;
34
+ setSelected(next);
35
+ }
36
+ }
37
+ if (input === "i") {
38
+ const next = {};
39
+ for (const it of safeItems)
40
+ next[it.key] = !selected[it.key];
41
+ setSelected(next);
42
+ }
43
+ if (key.return) {
44
+ onSubmit(selectedKeys);
45
+ }
46
+ }, { isActive: !isLoading });
47
+ if (isLoading) {
48
+ return (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Loading\u2026" }) }));
49
+ }
50
+ if (safeItems.length === 0) {
51
+ return (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: emptyLabel ?? "No items." }) }));
52
+ }
53
+ return (_jsxs(Box, { flexDirection: "column", children: [safeItems.map((item, i) => {
54
+ const isActive = i === cursor;
55
+ const isChecked = !!selected[item.key];
56
+ return (_jsxs(Box, { children: [_jsx(Text, { color: isActive ? "green" : undefined, children: isActive ? "❯" : " " }), _jsx(Text, { children: " " }), _jsx(Text, { children: isChecked ? "◉" : "◯" }), _jsx(Text, { children: " " }), _jsx(Text, { children: item.label }), item.meta ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: item.meta })] })) : null] }, item.key));
57
+ }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate \u00B7 Space toggle \u00B7 a all \u00B7 i invert \u00B7 Enter submit" }) }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["Selected: ", selectedKeys.length] }) })] }));
58
+ };
59
+ //# sourceMappingURL=CheckboxList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckboxList.js","sourceRoot":"","sources":["../../../src/ui/widgets/CheckboxList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ export type ConfirmPromptProps = {
3
+ message: string;
4
+ onConfirm: () => void;
5
+ onCancel: () => void;
6
+ };
7
+ export declare const ConfirmPrompt: React.FC<ConfirmPromptProps>;
8
+ //# sourceMappingURL=ConfirmPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmPrompt.d.ts","sourceRoot":"","sources":["../../../src/ui/widgets/ConfirmPrompt.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAuBtD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from "ink";
3
+ export const ConfirmPrompt = ({ message, onConfirm, onCancel }) => {
4
+ useInput((input, key) => {
5
+ if (key.return) {
6
+ onConfirm();
7
+ return;
8
+ }
9
+ if (input.toLowerCase() === "y") {
10
+ onConfirm();
11
+ return;
12
+ }
13
+ if (input.toLowerCase() === "n") {
14
+ onCancel();
15
+ }
16
+ });
17
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: message }), _jsx(Text, { dimColor: true, children: "y = confirm \u00B7 n = cancel \u00B7 Enter = confirm" })] }));
18
+ };
19
+ //# sourceMappingURL=ConfirmPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmPrompt.js","sourceRoot":"","sources":["../../../src/ui/widgets/ConfirmPrompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAS1C,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC9F,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YAChC,SAAS,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;YAChC,QAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,KAAC,IAAI,cAAE,OAAO,GAAQ,EACtB,KAAC,IAAI,IAAC,QAAQ,2EAAkD,IAC5D,CACP,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ export type NumberPromptProps = {
3
+ label: string;
4
+ initialValue?: number;
5
+ min?: number;
6
+ max?: number;
7
+ onSubmit: (value: number) => void;
8
+ };
9
+ export declare const NumberPrompt: React.FC<NumberPromptProps>;
10
+ //# sourceMappingURL=NumberPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberPrompt.d.ts","sourceRoot":"","sources":["../../../src/ui/widgets/NumberPrompt.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA8CpD,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from "ink";
3
+ import { useState } from "react";
4
+ export const NumberPrompt = ({ label, initialValue, min, max, onSubmit }) => {
5
+ const [value, setValue] = useState(initialValue ?? 0);
6
+ const [error, setError] = useState(null);
7
+ useInput((input, key) => {
8
+ if (key.upArrow)
9
+ setValue((v) => v + 1);
10
+ if (key.downArrow)
11
+ setValue((v) => v - 1);
12
+ if (input >= "0" && input <= "9") {
13
+ setValue((v) => {
14
+ const next = Number(String(v) === "0" ? input : `${v}${input}`);
15
+ return Number.isFinite(next) ? next : v;
16
+ });
17
+ return;
18
+ }
19
+ if (key.backspace || key.delete) {
20
+ setValue((v) => Math.floor(v / 10));
21
+ return;
22
+ }
23
+ if (key.return) {
24
+ if (min !== undefined && value < min) {
25
+ setError(`Must be ≥ ${min}`);
26
+ return;
27
+ }
28
+ if (max !== undefined && value > max) {
29
+ setError(`Must be ≤ ${max}`);
30
+ return;
31
+ }
32
+ setError(null);
33
+ onSubmit(value);
34
+ }
35
+ });
36
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { children: label }), _jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: "\u203A " }), _jsx(Text, { children: value })] }), error ? _jsx(Text, { color: "red", children: error }) : null, _jsx(Text, { dimColor: true, children: "Digits / \u2191\u2193 adjust / Backspace / Enter submit" })] }));
37
+ };
38
+ //# sourceMappingURL=NumberPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberPrompt.js","sourceRoot":"","sources":["../../../src/ui/widgets/NumberPrompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAUxC,MAAM,CAAC,MAAM,YAAY,GAAgC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE;IACvG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,YAAY,IAAI,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,OAAO;YAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,IAAI,GAAG,CAAC,SAAS;YAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAE1C,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;YACjC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE;gBACb,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;gBAChE,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAChC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;gBACrC,QAAQ,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;gBACrC,QAAQ,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,aAChC,KAAC,IAAI,cAAE,KAAK,GAAQ,EACpB,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wBAAU,EAC5B,KAAC,IAAI,cAAE,KAAK,GAAQ,IACf,EACN,KAAK,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,YAAE,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI,EAChD,KAAC,IAAI,IAAC,QAAQ,8EAAqD,IAC/D,CACP,CAAC;AACJ,CAAC,CAAC"}