@knpkv/codecommit-core 0.18.0 → 0.19.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 (41) hide show
  1. package/dist/AwsClient/getCallerIdentity.d.ts +2 -0
  2. package/dist/AwsClient/getCallerIdentity.d.ts.map +1 -1
  3. package/dist/AwsClient/getCallerIdentity.js +8 -4
  4. package/dist/AwsClient/getCallerIdentity.js.map +1 -1
  5. package/dist/AwsClientConfig/internal/ProfileCredentialProvider.d.ts +2 -17
  6. package/dist/AwsClientConfig/internal/ProfileCredentialProvider.d.ts.map +1 -1
  7. package/dist/AwsClientConfig/internal/ProfileCredentialProvider.js +2 -6
  8. package/dist/AwsClientConfig/internal/ProfileCredentialProvider.js.map +1 -1
  9. package/dist/AwsClientConfig.js +1 -1
  10. package/dist/AwsClientConfig.js.map +1 -1
  11. package/dist/AwsCredentialErrors.d.ts +8 -0
  12. package/dist/AwsCredentialErrors.d.ts.map +1 -0
  13. package/dist/AwsCredentialErrors.js +40 -0
  14. package/dist/AwsCredentialErrors.js.map +1 -0
  15. package/dist/AwsProfileCredentials.d.ts +23 -0
  16. package/dist/AwsProfileCredentials.d.ts.map +1 -0
  17. package/dist/AwsProfileCredentials.js +29 -0
  18. package/dist/AwsProfileCredentials.js.map +1 -0
  19. package/dist/Domain.d.ts +83 -7
  20. package/dist/Domain.d.ts.map +1 -1
  21. package/dist/Domain.js +52 -0
  22. package/dist/Domain.js.map +1 -1
  23. package/dist/IdentityLifecycle.d.ts +288 -0
  24. package/dist/IdentityLifecycle.d.ts.map +1 -0
  25. package/dist/IdentityLifecycle.js +125 -0
  26. package/dist/IdentityLifecycle.js.map +1 -0
  27. package/dist/PRService/refresh.d.ts.map +1 -1
  28. package/dist/PRService/refresh.js +2 -1
  29. package/dist/PRService/refresh.js.map +1 -1
  30. package/dist/PRService/refreshFetch.d.ts +2 -0
  31. package/dist/PRService/refreshFetch.d.ts.map +1 -1
  32. package/dist/PRService/refreshFetch.js +25 -6
  33. package/dist/PRService/refreshFetch.js.map +1 -1
  34. package/dist/PRService/refreshHistory.d.ts.map +1 -1
  35. package/dist/PRService/refreshHistory.js +2 -1
  36. package/dist/PRService/refreshHistory.js.map +1 -1
  37. package/dist/PRService/refreshResolve.d.ts +10 -0
  38. package/dist/PRService/refreshResolve.d.ts.map +1 -1
  39. package/dist/PRService/refreshResolve.js +43 -28
  40. package/dist/PRService/refreshResolve.js.map +1 -1
  41. package/package.json +1 -1
@@ -0,0 +1,288 @@
1
+ /**
2
+ * The caller-identity lifecycle as one state machine: the only writer of `AppState.callerIdentities`
3
+ * and `AppState.currentUser`. Services and handlers emit {@link IdentityEvent}s through
4
+ * {@link applyIdentityEvent}; nothing else writes those fields.
5
+ *
6
+ * Per profile, the state is a {@link CallerIdentityState}: Resolved, or Unresolved with a lookup reason
7
+ * (`CredentialsUnavailable`, `StsRejected`, `Throttled`), `RefreshAuthFailed` or `SignedOut`. A
8
+ * profile with no entry is absent: not enabled, or not looked up yet.
9
+ *
10
+ * **Generation rule.** `RefreshStarted`, `SignedIn` and `SignedOut` bump the generation. Every other
11
+ * event carries the generation of the refresh that produced it and applies only while that generation
12
+ * is current and its profile is enabled, so a newer refresh, login or logout makes older in-flight
13
+ * work a no-op.
14
+ *
15
+ * **Invariants**, after every event:
16
+ * - a profile with an entry is in the enabled set;
17
+ * - `currentUser` is the owner's (first enabled profile's) username when it is Resolved, else unset.
18
+ *
19
+ * @category Domain
20
+ * @module
21
+ */
22
+ import { Data } from "effect";
23
+ import type { AppState, CallerIdentityState, CallerIdentityUnresolvedReason } from "./Domain.js";
24
+ /** The identity facts STS returns for a caller. */
25
+ export interface ResolvedIdentity {
26
+ readonly accountId: string;
27
+ readonly arn: string;
28
+ readonly username: string;
29
+ }
30
+ /** Why a caller-identity lookup itself failed. */
31
+ export type LookupFailureReason = Extract<CallerIdentityUnresolvedReason, {
32
+ readonly _tag: "CredentialsUnavailable" | "StsRejected" | "Throttled";
33
+ }>;
34
+ /** The identity slice of application state that {@link transition} owns. */
35
+ export interface IdentityLifecycle {
36
+ readonly generation: number;
37
+ /** Enabled profiles in config order, as of the latest refresh. The first one is the owner. */
38
+ readonly enabled: ReadonlyArray<string>;
39
+ readonly profiles: Readonly<Record<string, CallerIdentityState>>;
40
+ /** Whether a resolution pass has finished since start; until then the wire field is absent. */
41
+ readonly firstRefreshDone: boolean;
42
+ }
43
+ /** Every event that changes caller identity. */
44
+ export type IdentityEvent = Data.TaggedEnum<{
45
+ /** A refresh read the enabled profiles from config; it bumps the generation and returns the new one. */
46
+ RefreshStarted: {
47
+ readonly enabled: ReadonlyArray<string>;
48
+ };
49
+ LookupSucceeded: {
50
+ readonly generation: number;
51
+ readonly profile: string;
52
+ readonly identity: ResolvedIdentity;
53
+ };
54
+ LookupFailed: {
55
+ readonly generation: number;
56
+ readonly profile: string;
57
+ readonly reason: LookupFailureReason;
58
+ };
59
+ /** A refresh call for this profile hit an error saying its credentials are invalid. */
60
+ RefreshAuthFailed: {
61
+ readonly generation: number;
62
+ readonly profile: string;
63
+ };
64
+ ResolutionFinished: {
65
+ readonly generation: number;
66
+ };
67
+ /**
68
+ * `aws sso login` succeeded. Without an identity (its lookup failed) the session still changed, maybe
69
+ * to another principal: in-flight work goes stale and the profile is absent until the next refresh.
70
+ */
71
+ SignedIn: {
72
+ readonly profile: string;
73
+ readonly identity: ResolvedIdentity | undefined;
74
+ };
75
+ /** `aws sso logout` succeeded. */
76
+ SignedOut: {};
77
+ }>;
78
+ export declare const IdentityEvent: {
79
+ readonly $is: <Tag extends "LookupFailed" | "LookupSucceeded" | "RefreshAuthFailed" | "RefreshStarted" | "ResolutionFinished" | "SignedIn" | "SignedOut">(tag: Tag) => (u: unknown) => u is Extract<{
80
+ readonly _tag: "LookupFailed";
81
+ readonly generation: number;
82
+ readonly profile: string;
83
+ readonly reason: LookupFailureReason;
84
+ }, {
85
+ readonly _tag: Tag;
86
+ }> | Extract<{
87
+ readonly _tag: "LookupSucceeded";
88
+ readonly generation: number;
89
+ readonly profile: string;
90
+ readonly identity: ResolvedIdentity;
91
+ }, {
92
+ readonly _tag: Tag;
93
+ }> | Extract<{
94
+ readonly _tag: "RefreshAuthFailed";
95
+ readonly generation: number;
96
+ readonly profile: string;
97
+ }, {
98
+ readonly _tag: Tag;
99
+ }> | Extract<{
100
+ readonly _tag: "RefreshStarted";
101
+ readonly enabled: ReadonlyArray<string>;
102
+ }, {
103
+ readonly _tag: Tag;
104
+ }> | Extract<{
105
+ readonly _tag: "ResolutionFinished";
106
+ readonly generation: number;
107
+ }, {
108
+ readonly _tag: Tag;
109
+ }> | Extract<{
110
+ readonly _tag: "SignedIn";
111
+ readonly profile: string;
112
+ readonly identity: ResolvedIdentity | undefined;
113
+ }, {
114
+ readonly _tag: Tag;
115
+ }> | Extract<{
116
+ readonly _tag: "SignedOut";
117
+ }, {
118
+ readonly _tag: Tag;
119
+ }>;
120
+ readonly $match: {
121
+ <Cases extends { readonly [Tag in "LookupFailed" | "LookupSucceeded" | "RefreshAuthFailed" | "RefreshStarted" | "ResolutionFinished" | "SignedIn" | "SignedOut"]: (args: Extract<{
122
+ readonly _tag: "LookupFailed";
123
+ readonly generation: number;
124
+ readonly profile: string;
125
+ readonly reason: LookupFailureReason;
126
+ } | {
127
+ readonly _tag: "LookupSucceeded";
128
+ readonly generation: number;
129
+ readonly profile: string;
130
+ readonly identity: ResolvedIdentity;
131
+ } | {
132
+ readonly _tag: "RefreshAuthFailed";
133
+ readonly generation: number;
134
+ readonly profile: string;
135
+ } | {
136
+ readonly _tag: "RefreshStarted";
137
+ readonly enabled: ReadonlyArray<string>;
138
+ } | {
139
+ readonly _tag: "ResolutionFinished";
140
+ readonly generation: number;
141
+ } | {
142
+ readonly _tag: "SignedIn";
143
+ readonly profile: string;
144
+ readonly identity: ResolvedIdentity | undefined;
145
+ } | {
146
+ readonly _tag: "SignedOut";
147
+ }, {
148
+ readonly _tag: Tag;
149
+ }>) => any; }>(cases: Cases): (value: {
150
+ readonly _tag: "LookupFailed";
151
+ readonly generation: number;
152
+ readonly profile: string;
153
+ readonly reason: LookupFailureReason;
154
+ } | {
155
+ readonly _tag: "LookupSucceeded";
156
+ readonly generation: number;
157
+ readonly profile: string;
158
+ readonly identity: ResolvedIdentity;
159
+ } | {
160
+ readonly _tag: "RefreshAuthFailed";
161
+ readonly generation: number;
162
+ readonly profile: string;
163
+ } | {
164
+ readonly _tag: "RefreshStarted";
165
+ readonly enabled: ReadonlyArray<string>;
166
+ } | {
167
+ readonly _tag: "ResolutionFinished";
168
+ readonly generation: number;
169
+ } | {
170
+ readonly _tag: "SignedIn";
171
+ readonly profile: string;
172
+ readonly identity: ResolvedIdentity | undefined;
173
+ } | {
174
+ readonly _tag: "SignedOut";
175
+ }) => import("effect/Unify").Unify<ReturnType<Cases["LookupFailed" | "LookupSucceeded" | "RefreshAuthFailed" | "RefreshStarted" | "ResolutionFinished" | "SignedIn" | "SignedOut"]>>;
176
+ <Cases extends { readonly [Tag in "LookupFailed" | "LookupSucceeded" | "RefreshAuthFailed" | "RefreshStarted" | "ResolutionFinished" | "SignedIn" | "SignedOut"]: (args: Extract<{
177
+ readonly _tag: "LookupFailed";
178
+ readonly generation: number;
179
+ readonly profile: string;
180
+ readonly reason: LookupFailureReason;
181
+ } | {
182
+ readonly _tag: "LookupSucceeded";
183
+ readonly generation: number;
184
+ readonly profile: string;
185
+ readonly identity: ResolvedIdentity;
186
+ } | {
187
+ readonly _tag: "RefreshAuthFailed";
188
+ readonly generation: number;
189
+ readonly profile: string;
190
+ } | {
191
+ readonly _tag: "RefreshStarted";
192
+ readonly enabled: ReadonlyArray<string>;
193
+ } | {
194
+ readonly _tag: "ResolutionFinished";
195
+ readonly generation: number;
196
+ } | {
197
+ readonly _tag: "SignedIn";
198
+ readonly profile: string;
199
+ readonly identity: ResolvedIdentity | undefined;
200
+ } | {
201
+ readonly _tag: "SignedOut";
202
+ }, {
203
+ readonly _tag: Tag;
204
+ }>) => any; }>(value: {
205
+ readonly _tag: "LookupFailed";
206
+ readonly generation: number;
207
+ readonly profile: string;
208
+ readonly reason: LookupFailureReason;
209
+ } | {
210
+ readonly _tag: "LookupSucceeded";
211
+ readonly generation: number;
212
+ readonly profile: string;
213
+ readonly identity: ResolvedIdentity;
214
+ } | {
215
+ readonly _tag: "RefreshAuthFailed";
216
+ readonly generation: number;
217
+ readonly profile: string;
218
+ } | {
219
+ readonly _tag: "RefreshStarted";
220
+ readonly enabled: ReadonlyArray<string>;
221
+ } | {
222
+ readonly _tag: "ResolutionFinished";
223
+ readonly generation: number;
224
+ } | {
225
+ readonly _tag: "SignedIn";
226
+ readonly profile: string;
227
+ readonly identity: ResolvedIdentity | undefined;
228
+ } | {
229
+ readonly _tag: "SignedOut";
230
+ }, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["LookupFailed" | "LookupSucceeded" | "RefreshAuthFailed" | "RefreshStarted" | "ResolutionFinished" | "SignedIn" | "SignedOut"]>>;
231
+ };
232
+ readonly LookupFailed: Data.TaggedEnum.ConstructorFrom<{
233
+ readonly _tag: "LookupFailed";
234
+ readonly generation: number;
235
+ readonly profile: string;
236
+ readonly reason: LookupFailureReason;
237
+ }, "_tag">;
238
+ readonly LookupSucceeded: Data.TaggedEnum.ConstructorFrom<{
239
+ readonly _tag: "LookupSucceeded";
240
+ readonly generation: number;
241
+ readonly profile: string;
242
+ readonly identity: ResolvedIdentity;
243
+ }, "_tag">;
244
+ readonly RefreshAuthFailed: Data.TaggedEnum.ConstructorFrom<{
245
+ readonly _tag: "RefreshAuthFailed";
246
+ readonly generation: number;
247
+ readonly profile: string;
248
+ }, "_tag">;
249
+ readonly RefreshStarted: Data.TaggedEnum.ConstructorFrom<{
250
+ readonly _tag: "RefreshStarted";
251
+ readonly enabled: ReadonlyArray<string>;
252
+ }, "_tag">;
253
+ readonly ResolutionFinished: Data.TaggedEnum.ConstructorFrom<{
254
+ readonly _tag: "ResolutionFinished";
255
+ readonly generation: number;
256
+ }, "_tag">;
257
+ readonly SignedIn: Data.TaggedEnum.ConstructorFrom<{
258
+ readonly _tag: "SignedIn";
259
+ readonly profile: string;
260
+ readonly identity: ResolvedIdentity | undefined;
261
+ }, "_tag">;
262
+ readonly SignedOut: Data.TaggedEnum.ConstructorFrom<{
263
+ readonly _tag: "SignedOut";
264
+ }, "_tag">;
265
+ };
266
+ export declare const initialIdentityLifecycle: IdentityLifecycle;
267
+ /** The single transition function over the lifecycle table. */
268
+ export declare const transition: (s: IdentityLifecycle, event: IdentityEvent) => IdentityLifecycle;
269
+ /** The owner's username when its identity is resolved: the only source of `currentUser`. */
270
+ export declare const currentUserOf: (s: IdentityLifecycle) => string | undefined;
271
+ /** Apply one event and project the identity slice onto the application state it owns. */
272
+ export declare const applyIdentityEvent: (state: AppState, event: IdentityEvent) => AppState;
273
+ /**
274
+ * Start a refresh over the enabled profiles: apply `RefreshStarted` and return the new generation,
275
+ * which every event this refresh produces must carry. For use with `SubscriptionRef.modify`.
276
+ */
277
+ export declare const startRefresh: (state: AppState, enabled: ReadonlyArray<string>) => readonly [number, AppState];
278
+ /**
279
+ * A login that just succeeded, before its identity is known: apply `SignedIn` without an identity and
280
+ * return the new generation. The identity found afterwards is applied as a `LookupSucceeded` of that
281
+ * generation, so a logout during the lookup still wins. For use with `SubscriptionRef.modify`.
282
+ */
283
+ export declare const beginSignIn: (state: AppState, profile: string) => readonly [number, AppState];
284
+ /** The state after a successful SSO login to one account, with its identity when the lookup found it. */
285
+ export declare const signInState: (state: AppState, profile: string, identity: ResolvedIdentity | undefined) => AppState;
286
+ /** The state after a successful SSO logout, which ends every SSO session. */
287
+ export declare const signOutState: (state: AppState) => AppState;
288
+ //# sourceMappingURL=IdentityLifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdentityLifecycle.d.ts","sourceRoot":"","sources":["../src/IdentityLifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,IAAI,EAAS,MAAM,QAAQ,CAAA;AACpC,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAA;AAEhG,mDAAmD;AACnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,kDAAkD;AAClD,MAAM,MAAM,mBAAmB,GAAG,OAAO,CACvC,8BAA8B,EAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,wBAAwB,GAAG,aAAa,GAAG,WAAW,CAAA;CAAE,CAC1E,CAAA;AAED,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACvC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAA;IAChE,+FAA+F;IAC/F,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;CACnC;AAED,gDAAgD;AAChD,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC;IAC1C,wGAAwG;IACxG,cAAc,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;KAAE,CAAA;IAC3D,eAAe,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;KAAE,CAAA;IAC/G,YAAY,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAA;KAAE,CAAA;IAC7G,uFAAuF;IACvF,iBAAiB,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5E,kBAAkB,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;IACnD;;;OAGG;IACH,QAAQ,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG,SAAS,CAAA;KAAE,CAAA;IACvF,kCAAkC;IAClC,SAAS,EAAE,EAAE,CAAA;CACd,CAAC,CAAA;AAEF,eAAO,MAAM,aAAa;;;6BAba,MAAM;0BAAoB,MAAM;yBAAmB,mBAAmB;;;;;6BADnE,MAAM;0BAAoB,MAAM;2BAAqB,gBAAgB;;;;;6BAGnE,MAAM;0BAAoB,MAAM;;;;;0BAJtC,aAAa,CAAC,MAAM,CAAC;;;;;6BAKd,MAAM;;;;;0BAKnB,MAAM;2BAAqB,gBAAgB,GAAG,SAAS;;;;;;;;;;;iCARhD,MAAM;8BAAoB,MAAM;6BAAmB,mBAAmB;;;iCADnE,MAAM;8BAAoB,MAAM;+BAAqB,gBAAgB;;;iCAGnE,MAAM;8BAAoB,MAAM;;;8BAJtC,aAAa,CAAC,MAAM,CAAC;;;iCAKd,MAAM;;;8BAKnB,MAAM;+BAAqB,gBAAgB,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCARhD,MAAM;8BAAoB,MAAM;6BAAmB,mBAAmB;;;iCADnE,MAAM;8BAAoB,MAAM;+BAAqB,gBAAgB;;;iCAGnE,MAAM;8BAAoB,MAAM;;;8BAJtC,aAAa,CAAC,MAAM,CAAC;;;iCAKd,MAAM;;;8BAKnB,MAAM;+BAAqB,gBAAgB,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BARhD,MAAM;0BAAoB,MAAM;yBAAmB,mBAAmB;;;;6BADnE,MAAM;0BAAoB,MAAM;2BAAqB,gBAAgB;;;;6BAGnE,MAAM;0BAAoB,MAAM;;;;0BAJtC,aAAa,CAAC,MAAM,CAAC;;;;6BAKd,MAAM;;;;0BAKnB,MAAM;2BAAqB,gBAAgB,GAAG,SAAS;;;;;CAK1B,CAAA;AAE7D,eAAO,MAAM,wBAAwB,EAAE,iBAKtC,CAAA;AAmBD,+DAA+D;AAC/D,eAAO,MAAM,UAAU,MAAO,iBAAiB,SAAS,aAAa,KAAG,iBAqCpE,CAAA;AAEJ,4FAA4F;AAC5F,eAAO,MAAM,aAAa,MAAO,iBAAiB,KAAG,MAAM,GAAG,SAI7D,CAAA;AAmBD,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,UAAW,QAAQ,SAAS,aAAa,KAAG,QACa,CAAA;AAExF;;;GAGG;AACH,eAAO,MAAM,YAAY,UAAW,QAAQ,WAAW,aAAa,CAAC,MAAM,CAAC,KAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,CAMxG,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,UAAW,QAAQ,WAAW,MAAM,KAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,CAMxF,CAAA;AAED,yGAAyG;AACzG,eAAO,MAAM,WAAW,UAAW,QAAQ,WAAW,MAAM,YAAY,gBAAgB,GAAG,SAAS,KAAG,QAC7B,CAAA;AAE1E,6EAA6E;AAC7E,eAAO,MAAM,YAAY,UAAW,QAAQ,KAAG,QAAgE,CAAA"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * The caller-identity lifecycle as one state machine: the only writer of `AppState.callerIdentities`
3
+ * and `AppState.currentUser`. Services and handlers emit {@link IdentityEvent}s through
4
+ * {@link applyIdentityEvent}; nothing else writes those fields.
5
+ *
6
+ * Per profile, the state is a {@link CallerIdentityState}: Resolved, or Unresolved with a lookup reason
7
+ * (`CredentialsUnavailable`, `StsRejected`, `Throttled`), `RefreshAuthFailed` or `SignedOut`. A
8
+ * profile with no entry is absent: not enabled, or not looked up yet.
9
+ *
10
+ * **Generation rule.** `RefreshStarted`, `SignedIn` and `SignedOut` bump the generation. Every other
11
+ * event carries the generation of the refresh that produced it and applies only while that generation
12
+ * is current and its profile is enabled, so a newer refresh, login or logout makes older in-flight
13
+ * work a no-op.
14
+ *
15
+ * **Invariants**, after every event:
16
+ * - a profile with an entry is in the enabled set;
17
+ * - `currentUser` is the owner's (first enabled profile's) username when it is Resolved, else unset.
18
+ *
19
+ * @category Domain
20
+ * @module
21
+ */
22
+ import { Data, Match } from "effect";
23
+ export const IdentityEvent = Data.taggedEnum();
24
+ export const initialIdentityLifecycle = {
25
+ generation: 0,
26
+ enabled: [],
27
+ profiles: {},
28
+ firstRefreshDone: false
29
+ };
30
+ const resolvedState = (identity) => ({ _tag: "Resolved", ...identity });
31
+ const unresolvedState = (reason) => ({
32
+ _tag: "Unresolved",
33
+ reason
34
+ });
35
+ const signedOut = unresolvedState({ _tag: "SignedOut" });
36
+ const refreshAuthFailed = unresolvedState({ _tag: "RefreshAuthFailed" });
37
+ const withProfile = (s, profile, next) => ({
38
+ ...s,
39
+ profiles: { ...s.profiles, [profile]: next }
40
+ });
41
+ /** A stamped event applies only while its generation is current and, when it names one, its profile is enabled. */
42
+ const applies = (s, generation, profile) => generation === s.generation && (profile === undefined || s.enabled.includes(profile));
43
+ /** The single transition function over the lifecycle table. */
44
+ export const transition = (s, event) => Match.valueTags(event, {
45
+ RefreshStarted: ({ enabled }) => ({
46
+ ...s,
47
+ generation: s.generation + 1,
48
+ enabled,
49
+ profiles: Object.fromEntries(Object.entries(s.profiles).filter(([profile]) => enabled.includes(profile)))
50
+ }),
51
+ LookupSucceeded: ({ generation, identity, profile }) => applies(s, generation, profile) ? withProfile(s, profile, resolvedState(identity)) : s,
52
+ LookupFailed: ({ generation, profile, reason }) => {
53
+ if (!applies(s, generation, profile))
54
+ return s;
55
+ // After a logout, failing for lack of credentials is the logout's expected result, not news.
56
+ const current = s.profiles[profile];
57
+ const staysSignedOut = current?._tag === "Unresolved" && current.reason._tag === "SignedOut" &&
58
+ reason._tag === "CredentialsUnavailable";
59
+ return staysSignedOut ? s : withProfile(s, profile, unresolvedState(reason));
60
+ },
61
+ RefreshAuthFailed: ({ generation, profile }) => applies(s, generation, profile) && s.profiles[profile]?._tag === "Resolved"
62
+ ? withProfile(s, profile, refreshAuthFailed)
63
+ : s,
64
+ ResolutionFinished: ({ generation }) => applies(s, generation) ? { ...s, firstRefreshDone: true } : s,
65
+ SignedIn: ({ identity, profile }) => {
66
+ const bumped = { ...s, generation: s.generation + 1 };
67
+ if (!s.enabled.includes(profile))
68
+ return bumped;
69
+ if (identity !== undefined)
70
+ return withProfile(bumped, profile, resolvedState(identity));
71
+ // The old identity may belong to the previous principal, so it is not kept.
72
+ const { [profile]: _, ...rest } = bumped.profiles;
73
+ return { ...bumped, profiles: rest };
74
+ },
75
+ SignedOut: () => ({
76
+ ...s,
77
+ generation: s.generation + 1,
78
+ // Every enabled account is signed out, including one whose first lookup is still in flight.
79
+ profiles: Object.fromEntries(s.enabled.map((profile) => [profile, signedOut]))
80
+ })
81
+ });
82
+ /** The owner's username when its identity is resolved: the only source of `currentUser`. */
83
+ export const currentUserOf = (s) => {
84
+ const owner = s.enabled[0];
85
+ const identity = owner === undefined ? undefined : s.profiles[owner];
86
+ return identity?._tag === "Resolved" ? identity.username : undefined;
87
+ };
88
+ /** The wire field: absent until something is known or a resolution pass has finished. */
89
+ const callerIdentitiesOf = (s) => s.firstRefreshDone || Object.keys(s.profiles).length > 0 ? s.profiles : undefined;
90
+ /** Project the identity slice onto the application state fields it owns. */
91
+ const project = (state, lifecycle) => {
92
+ const { callerIdentities: _, currentUser: __, ...rest } = state;
93
+ const callerIdentities = callerIdentitiesOf(lifecycle);
94
+ const currentUser = currentUserOf(lifecycle);
95
+ return {
96
+ ...rest,
97
+ identityLifecycle: lifecycle,
98
+ ...(callerIdentities !== undefined && { callerIdentities }),
99
+ ...(currentUser !== undefined && { currentUser })
100
+ };
101
+ };
102
+ /** Apply one event and project the identity slice onto the application state it owns. */
103
+ export const applyIdentityEvent = (state, event) => project(state, transition(state.identityLifecycle ?? initialIdentityLifecycle, event));
104
+ /**
105
+ * Start a refresh over the enabled profiles: apply `RefreshStarted` and return the new generation,
106
+ * which every event this refresh produces must carry. For use with `SubscriptionRef.modify`.
107
+ */
108
+ export const startRefresh = (state, enabled) => {
109
+ const lifecycle = transition(state.identityLifecycle ?? initialIdentityLifecycle, IdentityEvent.RefreshStarted({ enabled }));
110
+ return [lifecycle.generation, project(state, lifecycle)];
111
+ };
112
+ /**
113
+ * A login that just succeeded, before its identity is known: apply `SignedIn` without an identity and
114
+ * return the new generation. The identity found afterwards is applied as a `LookupSucceeded` of that
115
+ * generation, so a logout during the lookup still wins. For use with `SubscriptionRef.modify`.
116
+ */
117
+ export const beginSignIn = (state, profile) => {
118
+ const lifecycle = transition(state.identityLifecycle ?? initialIdentityLifecycle, IdentityEvent.SignedIn({ profile, identity: undefined }));
119
+ return [lifecycle.generation, project(state, lifecycle)];
120
+ };
121
+ /** The state after a successful SSO login to one account, with its identity when the lookup found it. */
122
+ export const signInState = (state, profile, identity) => applyIdentityEvent(state, IdentityEvent.SignedIn({ profile, identity }));
123
+ /** The state after a successful SSO logout, which ends every SSO session. */
124
+ export const signOutState = (state) => applyIdentityEvent(state, IdentityEvent.SignedOut());
125
+ //# sourceMappingURL=IdentityLifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdentityLifecycle.js","sourceRoot":"","sources":["../src/IdentityLifecycle.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/PRService/refresh.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAmB,MAAM,EAA8C,MAAM,QAAQ,CAAA;AAC5F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAA;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAA;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAA;AA8C5D,MAAM,MAAM,WAAW,GACnB,aAAa,GACb,SAAS,GACT,eAAe,GACf,WAAW,GACX,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,CAAA;AAEb,eAAO,MAAM,WAAW,gLAoEvB,CAAA"}
1
+ {"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/PRService/refresh.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAmB,MAAM,EAA8C,MAAM,QAAQ,CAAA;AAC5F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAA;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAA;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAA;AA8C5D,MAAM,MAAM,WAAW,GACnB,aAAa,GACb,SAAS,GACT,eAAe,GACf,WAAW,GACX,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,CAAA;AAEb,eAAO,MAAM,WAAW,gLAqEvB,CAAA"}
@@ -46,7 +46,7 @@ export const makeRefresh = Effect.fn("PRService.refresh")(function* (state) {
46
46
  const resolved = yield* resolveAccounts(state);
47
47
  if (resolved === undefined)
48
48
  return;
49
- const { accountIdMap, currentUser, enabledAccounts, subscribedRef } = resolved;
49
+ const { accountIdMap, currentUser, enabledAccounts, identityGeneration, subscribedRef } = resolved;
50
50
  const staleNow = yield* Clock.currentTimeMillis;
51
51
  const staleThreshold = DateTime.toDate(DateTime.makeUnsafe(staleNow)).toISOString().slice(0, 19) + "Z";
52
52
  const { published, scopes: successfulRefreshScopes } = yield* hub.batch(Effect.gen(function* () {
@@ -56,6 +56,7 @@ export const makeRefresh = Effect.fn("PRService.refresh")(function* (state) {
56
56
  accountIdMap,
57
57
  subscribedRef,
58
58
  currentUser,
59
+ identityGeneration,
59
60
  staleThreshold
60
61
  });
61
62
  yield* enrichComments({ state, subscribedRef });
@@ -1 +1 @@
1
- {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/PRService/refresh.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/PRService/refresh.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,8 @@ export declare const fetchAndUpsertPRs: (params: {
20
20
  readonly accountIdMap: Map<string, string>;
21
21
  readonly subscribedRef: Ref.Ref<Set<string>>;
22
22
  readonly currentUser: string | undefined;
23
+ /** The refresh's identity generation, from `resolveAccounts`. */
24
+ readonly identityGeneration: number;
23
25
  readonly staleThreshold: string;
24
26
  }) => Effect.Effect<ReadonlyArray<PullRequestRefreshScope>, never, AwsClient | PullRequestRepo | NotificationRepo | SubscriptionRepo>;
25
27
  //# sourceMappingURL=refreshFetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"refreshFetch.d.ts","sourceRoot":"","sources":["../../src/PRService/refreshFetch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAuB,MAAM,EAAqB,GAAG,EAA2B,MAAM,QAAQ,CAAA;AACrG,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAIjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AAC5E,OAAO,EAEL,eAAe,EAEhB,MAAM,gDAAgD,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,EAAE,uBAAuB,EAA0B,MAAM,cAAc,CAAA;AAEnF,OAAO,EAAE,KAAK,OAAO,EAAmB,MAAM,eAAe,CAAA;AAqC7D,eAAO,MAAM,iBAAiB,WAAY;IACxC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IACtD,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,KAAG,MAAM,CAAC,MAAM,CACf,aAAa,CAAC,uBAAuB,CAAC,EACtC,KAAK,EACL,SAAS,GAAG,eAAe,GAAG,gBAAgB,GAAG,gBAAgB,CA0ShE,CAAA"}
1
+ {"version":3,"file":"refreshFetch.d.ts","sourceRoot":"","sources":["../../src/PRService/refreshFetch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAuB,MAAM,EAAqB,GAAG,EAA2B,MAAM,QAAQ,CAAA;AACrG,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAKjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AAC5E,OAAO,EAEL,eAAe,EAEhB,MAAM,gDAAgD,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,EAAE,uBAAuB,EAA0B,MAAM,cAAc,CAAA;AAGnF,OAAO,EAAE,KAAK,OAAO,EAAmB,MAAM,eAAe,CAAA;AAiD7D,eAAO,MAAM,iBAAiB,WAAY;IACxC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IACtD,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,iEAAiE;IACjE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,KAAG,MAAM,CAAC,MAAM,CACf,aAAa,CAAC,uBAAuB,CAAC,EACtC,KAAK,EACL,SAAS,GAAG,eAAe,GAAG,gBAAgB,GAAG,gBAAgB,CAuThE,CAAA"}
@@ -8,12 +8,22 @@
8
8
  */
9
9
  import { Array as Arr, Cause, Effect, Option, Predicate, Ref, Stream, SubscriptionRef } from "effect";
10
10
  import { AwsClient } from "../AwsClient/index.js";
11
+ import { isCredentialInvalidCause } from "../AwsCredentialErrors.js";
11
12
  import { diffApprovalPools, diffPR } from "../CacheService/diff.js";
12
13
  import { NotificationRepo } from "../CacheService/repos/NotificationRepo.js";
13
14
  import { PullRequestRepo } from "../CacheService/repos/PullRequestRepo/index.js";
14
15
  import { SubscriptionRepo } from "../CacheService/repos/SubscriptionRepo.js";
16
+ import { applyIdentityEvent, IdentityEvent } from "../IdentityLifecycle.js";
15
17
  import { prToUpsertInput } from "./internal.js";
16
18
  import { isSubscribedForCoordinates, subscriptionKey } from "./refreshResolve.js";
19
+ /**
20
+ * Whether a refresh failure means the account's credentials no longer work, decided from its type: a
21
+ * credential failure, or a provider error saying so, directly or inside a failed approval evaluation.
22
+ */
23
+ const isAuthFailure = (error) => error._tag === "AwsCredentialError" ||
24
+ (error._tag === "AwsApiError" && (isCredentialInvalidCause(error.cause) ||
25
+ (Predicate.isTagged(error.cause, "ApprovalEvaluationError") && Predicate.hasProperty(error.cause, "cause") &&
26
+ isCredentialInvalidCause(error.cause.cause))));
17
27
  /** A pull-request read that failed only because its approval rules could not be evaluated. */
18
28
  const failedOnlyOnApprovalEvaluation = (error) => error._tag === "AwsApiError" && Predicate.isTagged(error.cause, "ApprovalEvaluationError");
19
29
  /** The evaluation failure's own message, which names the operation and the provider's reason. */
@@ -31,7 +41,7 @@ export const fetchAndUpsertPRs = (params) => Effect.gen(function* () {
31
41
  const prRepo = yield* PullRequestRepo;
32
42
  const notificationRepo = yield* NotificationRepo;
33
43
  const subscriptionRepo = yield* SubscriptionRepo;
34
- const { accountIdMap, currentUser, enabledAccounts, staleThreshold, state, subscribedRef } = params;
44
+ const { accountIdMap, currentUser, enabledAccounts, identityGeneration, staleThreshold, state, subscribedRef } = params;
35
45
  // Stale rows are safe to reconcile only when their owning list operation
36
46
  // completed successfully. A failed account stream says nothing about which
37
47
  // cached PRs remain open and must never turn into cache deletion.
@@ -49,6 +59,9 @@ export const fetchAndUpsertPRs = (params) => Effect.gen(function* () {
49
59
  next.delete(accountRegionKey(profile, region));
50
60
  return next;
51
61
  });
62
+ // The account's credentials stopped working during this refresh: an identity event of this
63
+ // refresh's generation, so it does nothing once a newer refresh, login or logout has happened.
64
+ const markAuthFailed = (profile) => SubscriptionRef.update(state, (s) => applyIdentityEvent(s, IdentityEvent.RefreshAuthFailed({ generation: identityGeneration, profile })));
52
65
  const accountLabels = enabledAccounts.flatMap((a) => (a.regions ?? []).map((r) => `${a.profile}(${r})`));
53
66
  yield* SubscriptionRef.update(state, (s) => ({
54
67
  ...s,
@@ -67,7 +80,8 @@ export const fetchAndUpsertPRs = (params) => Effect.gen(function* () {
67
80
  region,
68
81
  cause: causeStr
69
82
  });
70
- const isAuthError = /ExpiredToken|Unauthorized|AuthFailure|credentials/i.test(causeStr);
83
+ const isAuthError = isAuthFailure(error) ||
84
+ /ExpiredToken|Unauthorized|AuthFailure|credentials/i.test(causeStr);
71
85
  return Stream.fromEffectDrain(Effect.gen(function* () {
72
86
  yield* Ref.update(successfullyFetchedScopes, (scopes) => {
73
87
  const next = new Set(scopes);
@@ -81,9 +95,9 @@ export const fetchAndUpsertPRs = (params) => Effect.gen(function* () {
81
95
  profile: account.profile,
82
96
  deduplicate: true
83
97
  }).pipe(Effect.catch(() => Effect.void));
84
- if (isAuthError) {
85
- yield* SubscriptionRef.update(state, ({ currentUser: _, ...rest }) => rest);
86
- }
98
+ // Typed first (credential failure, or a provider auth error), with the older text match as fallback.
99
+ if (isAuthError)
100
+ yield* markAuthFailed(account.profile);
87
101
  }));
88
102
  }));
89
103
  }));
@@ -98,6 +112,9 @@ export const fetchAndUpsertPRs = (params) => Effect.gen(function* () {
98
112
  }]), { discard: true }), { discard: true });
99
113
  yield* Stream.mergeAll(streams, { concurrency: 2 }).pipe(Stream.runForEach(({ awsAccountId, item, label, profile, region }) => Effect.gen(function* () {
100
114
  if (item._tag === "EvaluationFailed") {
115
+ // An evaluation that failed because the credentials stopped working is an auth failure too.
116
+ if (isCredentialInvalidCause(item.error.cause))
117
+ yield* markAuthFailed(profile);
101
118
  // Only this pull request is unknown: its cached row stays as it was, the account's other
102
119
  // pull requests carry on, and the account's refresh counts as partial rather than successful.
103
120
  yield* Ref.update(unevaluated, (all) => [...all, {
@@ -159,7 +176,9 @@ export const fetchAndUpsertPRs = (params) => Effect.gen(function* () {
159
176
  })
160
177
  .pipe(Effect.flatMap((detail) => detail.repositoryName === pr.repositoryName
161
178
  ? resolveStaleStatus(prRepo, detail, pr.awsAccountId, pr.id, pr.repositoryName, pr.accountRegion)
162
- : Effect.void), Effect.catch((error) => withholdScopeSuccess(pr.accountProfile, pr.accountRegion).pipe(Effect.andThen(
179
+ : Effect.void), Effect.catch((error) => withholdScopeSuccess(pr.accountProfile, pr.accountRegion).pipe(
180
+ // Credentials that stopped working while stale rows are re-read are an auth failure too.
181
+ Effect.andThen(isAuthFailure(error) ? markAuthFailed(pr.accountProfile) : Effect.void), Effect.andThen(
163
182
  // The pull request was read; only its approval enrichment failed. That is not
164
183
  // evidence it is gone, so the row stays for the next refresh to settle.
165
184
  failedOnlyOnApprovalEvaluation(error)