@kya-os/provider-registry 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +592 -0
- package/dist/default-providers.d.ts +30 -0
- package/dist/default-providers.d.ts.map +1 -0
- package/dist/default-providers.js +162 -0
- package/dist/default-providers.js.map +1 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +173 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +291 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +339 -0
- package/dist/registry.js.map +1 -0
- package/dist/schemas.d.ts +780 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +104 -0
- package/dist/schemas.js.map +1 -0
- package/dist/types.d.ts +214 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Registry Implementation
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for provider definitions and provider-type mapping.
|
|
5
|
+
* Implements IProviderRegistry interface for dependency injection and testing.
|
|
6
|
+
*
|
|
7
|
+
* Key features:
|
|
8
|
+
* - Provider lookup by ID and oauthProviderId
|
|
9
|
+
* - Authentication mode to consent provider type mapping
|
|
10
|
+
* - oauthProviderId uniqueness enforcement
|
|
11
|
+
* - Seal capability to prevent runtime modifications
|
|
12
|
+
* - Consistent fallback behavior with logging
|
|
13
|
+
*/
|
|
14
|
+
import type { ProviderDefinition, ConsentProviderType, AuthMode } from './types';
|
|
15
|
+
/**
|
|
16
|
+
* Logger interface for deprecation and warning messages
|
|
17
|
+
*
|
|
18
|
+
* Allows injection of custom loggers for production metrics/alerting.
|
|
19
|
+
*/
|
|
20
|
+
export interface RegistryLogger {
|
|
21
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Provider Registry Interface
|
|
25
|
+
*
|
|
26
|
+
* Defines the contract for provider registry implementations.
|
|
27
|
+
* Allows dependency injection and testability.
|
|
28
|
+
*/
|
|
29
|
+
export interface IProviderRegistry {
|
|
30
|
+
/**
|
|
31
|
+
* Get a provider definition by ID
|
|
32
|
+
*
|
|
33
|
+
* @param id - Provider identifier
|
|
34
|
+
* @returns Provider definition or undefined if not found
|
|
35
|
+
*/
|
|
36
|
+
getProvider(id: string): ProviderDefinition | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Find a provider by its oauthProviderId
|
|
39
|
+
*
|
|
40
|
+
* This is useful when you have an OAuth identity provider field
|
|
41
|
+
* that may differ from the provider's primary ID.
|
|
42
|
+
*
|
|
43
|
+
* @param oauthProviderId - OAuth provider identifier
|
|
44
|
+
* @returns Provider definition or undefined if not found
|
|
45
|
+
*/
|
|
46
|
+
findByOauthProviderId(oauthProviderId: string): ProviderDefinition | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a provider is known (registered)
|
|
49
|
+
*
|
|
50
|
+
* @param id - Provider identifier
|
|
51
|
+
* @returns True if provider is registered
|
|
52
|
+
*/
|
|
53
|
+
isKnownProvider(id: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Check if a provider is an OAuth provider
|
|
56
|
+
*
|
|
57
|
+
* @param id - Provider identifier
|
|
58
|
+
* @returns True if provider exists and is OAuth category
|
|
59
|
+
*/
|
|
60
|
+
isOAuthProvider(id: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Check if a provider is a credential provider
|
|
63
|
+
*
|
|
64
|
+
* @param id - Provider identifier
|
|
65
|
+
* @returns True if provider exists and is credential category
|
|
66
|
+
*/
|
|
67
|
+
isCredentialProvider(id: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Map auth mode and OAuth provider ID to consent provider type
|
|
70
|
+
*
|
|
71
|
+
* Deterministic precedence rules with explicit mapping logic.
|
|
72
|
+
*
|
|
73
|
+
* @param authMode - Authentication mode (UI/flow level)
|
|
74
|
+
* @param oauthProviderId - OAuth provider identifier (if OAuth flow)
|
|
75
|
+
* @returns Consent provider type (backend routing vocabulary)
|
|
76
|
+
*/
|
|
77
|
+
mapAuthModeToConsentProvider(authMode?: AuthMode | string, oauthProviderId?: string): ConsentProviderType;
|
|
78
|
+
/**
|
|
79
|
+
* Map provider ID directly to consent provider type
|
|
80
|
+
*
|
|
81
|
+
* @param providerId - Provider identifier
|
|
82
|
+
* @returns Consent provider type
|
|
83
|
+
*/
|
|
84
|
+
mapProviderToConsentProvider(providerId: string): ConsentProviderType;
|
|
85
|
+
/**
|
|
86
|
+
* Determine provider type from auth mode and OAuth identity provider
|
|
87
|
+
*
|
|
88
|
+
* @deprecated Use mapAuthModeToConsentProvider instead
|
|
89
|
+
*/
|
|
90
|
+
determineProviderTypeFromAuthMode(authMode?: string, oauthIdentityProvider?: string): ConsentProviderType;
|
|
91
|
+
/**
|
|
92
|
+
* Register a new provider
|
|
93
|
+
*
|
|
94
|
+
* @param def - Provider definition to register
|
|
95
|
+
* @param opts - Registration options
|
|
96
|
+
* @throws Error if provider already exists and overwrite is false
|
|
97
|
+
* @throws Error if registry is sealed
|
|
98
|
+
*/
|
|
99
|
+
registerProvider(def: ProviderDefinition, opts?: {
|
|
100
|
+
overwrite?: boolean;
|
|
101
|
+
}): void;
|
|
102
|
+
/**
|
|
103
|
+
* List all registered providers
|
|
104
|
+
*
|
|
105
|
+
* @returns Array of all provider definitions
|
|
106
|
+
*/
|
|
107
|
+
listProviders(): ProviderDefinition[];
|
|
108
|
+
/**
|
|
109
|
+
* Load providers from configuration
|
|
110
|
+
*
|
|
111
|
+
* Validates and registers providers from a configuration object.
|
|
112
|
+
* Useful for loading custom providers from JSON config or environment variables.
|
|
113
|
+
*
|
|
114
|
+
* @param config - Configuration object (will be validated via zod)
|
|
115
|
+
* @throws ZodError if configuration is invalid
|
|
116
|
+
* @throws Error if registry is sealed
|
|
117
|
+
*/
|
|
118
|
+
loadFromConfig(config: unknown): void;
|
|
119
|
+
/**
|
|
120
|
+
* Seal the registry to prevent further modifications
|
|
121
|
+
*
|
|
122
|
+
* Once sealed, registerProvider() and loadFromConfig() will throw.
|
|
123
|
+
* Useful for long-running workers to prevent accidental runtime modifications.
|
|
124
|
+
*/
|
|
125
|
+
seal(): void;
|
|
126
|
+
/**
|
|
127
|
+
* Check if the registry is sealed
|
|
128
|
+
*
|
|
129
|
+
* @returns True if the registry is sealed
|
|
130
|
+
*/
|
|
131
|
+
isSealed(): boolean;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Provider Registry Implementation
|
|
135
|
+
*
|
|
136
|
+
* Maintains a registry of provider definitions and provides lookup/mapping methods.
|
|
137
|
+
*
|
|
138
|
+
* ## Fallback Behavior
|
|
139
|
+
*
|
|
140
|
+
* This registry implements consistent fallback behavior:
|
|
141
|
+
*
|
|
142
|
+
* - `mapAuthModeToConsentProvider`:
|
|
143
|
+
* - Unknown oauthProviderId with explicit presence → 'oauth2' (logs warning)
|
|
144
|
+
* - No oauthProviderId → 'none'
|
|
145
|
+
*
|
|
146
|
+
* - `mapProviderToConsentProvider`:
|
|
147
|
+
* - Unknown providerId → 'none' (logs warning)
|
|
148
|
+
*
|
|
149
|
+
* The difference is intentional:
|
|
150
|
+
* - If caller provides an oauthProviderId, they expect OAuth behavior
|
|
151
|
+
* - If caller provides a providerId that's unknown, fall back safely
|
|
152
|
+
*/
|
|
153
|
+
export declare class ProviderRegistry implements IProviderRegistry {
|
|
154
|
+
private providers;
|
|
155
|
+
private oauthProviderIdIndex;
|
|
156
|
+
private sealed;
|
|
157
|
+
private logger;
|
|
158
|
+
/**
|
|
159
|
+
* Create a new ProviderRegistry
|
|
160
|
+
*
|
|
161
|
+
* @param initial - Initial providers to register (defaults to common providers)
|
|
162
|
+
* @param logger - Optional logger for warnings (defaults to console.warn)
|
|
163
|
+
*/
|
|
164
|
+
constructor(initial?: ProviderDefinition[], logger?: RegistryLogger);
|
|
165
|
+
/**
|
|
166
|
+
* Register a provider definition
|
|
167
|
+
*
|
|
168
|
+
* Provider IDs are normalized to lowercase.
|
|
169
|
+
* oauthProviderId must be unique across the registry.
|
|
170
|
+
*
|
|
171
|
+
* @param def - Provider definition (will be validated)
|
|
172
|
+
* @param opts - Registration options
|
|
173
|
+
* @throws Error if provider already exists and overwrite is false
|
|
174
|
+
* @throws Error if oauthProviderId already exists for another provider
|
|
175
|
+
* @throws Error if registry is sealed
|
|
176
|
+
*/
|
|
177
|
+
registerProvider(def: ProviderDefinition, opts?: {
|
|
178
|
+
overwrite?: boolean;
|
|
179
|
+
}): void;
|
|
180
|
+
/**
|
|
181
|
+
* Get a provider definition by ID (case-insensitive)
|
|
182
|
+
*
|
|
183
|
+
* @param id - Provider identifier
|
|
184
|
+
* @returns Provider definition or undefined if not found
|
|
185
|
+
*/
|
|
186
|
+
getProvider(id: string): ProviderDefinition | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* Find a provider by its oauthProviderId (case-insensitive)
|
|
189
|
+
*
|
|
190
|
+
* This is useful when you have an OAuth identity provider field
|
|
191
|
+
* that may differ from the provider's primary ID.
|
|
192
|
+
*
|
|
193
|
+
* @param oauthProviderId - OAuth provider identifier to look up
|
|
194
|
+
* @returns Provider definition or undefined if not found
|
|
195
|
+
*/
|
|
196
|
+
findByOauthProviderId(oauthProviderId: string): ProviderDefinition | undefined;
|
|
197
|
+
/**
|
|
198
|
+
* Check if a provider is known (registered)
|
|
199
|
+
*
|
|
200
|
+
* @param id - Provider identifier
|
|
201
|
+
* @returns True if provider is registered
|
|
202
|
+
*/
|
|
203
|
+
isKnownProvider(id: string): boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Check if a provider is an OAuth provider
|
|
206
|
+
*
|
|
207
|
+
* @param id - Provider identifier
|
|
208
|
+
* @returns True if provider exists and has oauth2 authType
|
|
209
|
+
*/
|
|
210
|
+
isOAuthProvider(id: string): boolean;
|
|
211
|
+
/**
|
|
212
|
+
* Check if a provider is a credential provider
|
|
213
|
+
*
|
|
214
|
+
* @param id - Provider identifier
|
|
215
|
+
* @returns True if provider exists and has password authType
|
|
216
|
+
*/
|
|
217
|
+
isCredentialProvider(id: string): boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Map auth mode and OAuth provider ID to consent provider type
|
|
220
|
+
*
|
|
221
|
+
* Deterministic precedence rules:
|
|
222
|
+
* 1. Explicit authMode (non-oauth) → direct mapping
|
|
223
|
+
* 2. If authMode === 'oauth' or no explicit authMode but oauthProviderId present → consult registry
|
|
224
|
+
* 3. Unknown oauthProviderId → 'oauth2' (with warning log)
|
|
225
|
+
* 4. Fallback → 'none'
|
|
226
|
+
*
|
|
227
|
+
* @param authMode - Authentication mode (UI/flow level)
|
|
228
|
+
* @param oauthProviderId - OAuth provider identifier (if OAuth flow)
|
|
229
|
+
* @returns Consent provider type (backend routing vocabulary)
|
|
230
|
+
*/
|
|
231
|
+
mapAuthModeToConsentProvider(authMode?: AuthMode | string, oauthProviderId?: string): ConsentProviderType;
|
|
232
|
+
/**
|
|
233
|
+
* Map provider ID directly to consent provider type
|
|
234
|
+
*
|
|
235
|
+
* Thin wrapper that looks up provider.authType and maps it to consent provider type.
|
|
236
|
+
* For unknown providers, returns 'none' and logs a warning.
|
|
237
|
+
*
|
|
238
|
+
* @param providerId - Provider identifier
|
|
239
|
+
* @returns Consent provider type
|
|
240
|
+
*/
|
|
241
|
+
mapProviderToConsentProvider(providerId: string): ConsentProviderType;
|
|
242
|
+
/**
|
|
243
|
+
* Map provider auth type to consent provider type
|
|
244
|
+
*
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
private mapAuthTypeToConsentProvider;
|
|
248
|
+
/**
|
|
249
|
+
* Determine provider type from auth mode and OAuth identity provider
|
|
250
|
+
*
|
|
251
|
+
* @deprecated Use mapAuthModeToConsentProvider instead. This method is kept for backward compatibility.
|
|
252
|
+
*
|
|
253
|
+
* @param authMode - Authentication mode
|
|
254
|
+
* @param oauthIdentityProvider - OAuth provider identifier
|
|
255
|
+
* @returns Consent provider type
|
|
256
|
+
*/
|
|
257
|
+
determineProviderTypeFromAuthMode(authMode?: string, oauthIdentityProvider?: string): ConsentProviderType;
|
|
258
|
+
/**
|
|
259
|
+
* List all registered providers
|
|
260
|
+
*
|
|
261
|
+
* @returns Array of all provider definitions
|
|
262
|
+
*/
|
|
263
|
+
listProviders(): ProviderDefinition[];
|
|
264
|
+
/**
|
|
265
|
+
* Load providers from configuration
|
|
266
|
+
*
|
|
267
|
+
* Validates configuration via zod and registers all providers.
|
|
268
|
+
* Existing providers with same ID will be overwritten.
|
|
269
|
+
*
|
|
270
|
+
* @param config - Configuration object (will be validated)
|
|
271
|
+
* @throws ZodError if configuration is invalid
|
|
272
|
+
* @throws Error if registry is sealed
|
|
273
|
+
*/
|
|
274
|
+
loadFromConfig(config: unknown): void;
|
|
275
|
+
/**
|
|
276
|
+
* Seal the registry to prevent further modifications
|
|
277
|
+
*
|
|
278
|
+
* Once sealed, registerProvider() and loadFromConfig() will throw.
|
|
279
|
+
* Useful for long-running workers to prevent accidental runtime modifications.
|
|
280
|
+
*
|
|
281
|
+
* This operation is irreversible.
|
|
282
|
+
*/
|
|
283
|
+
seal(): void;
|
|
284
|
+
/**
|
|
285
|
+
* Check if the registry is sealed
|
|
286
|
+
*
|
|
287
|
+
* @returns True if the registry is sealed
|
|
288
|
+
*/
|
|
289
|
+
isSealed(): boolean;
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Registry Implementation
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for provider definitions and provider-type mapping.
|
|
5
|
+
* Implements IProviderRegistry interface for dependency injection and testing.
|
|
6
|
+
*
|
|
7
|
+
* Key features:
|
|
8
|
+
* - Provider lookup by ID and oauthProviderId
|
|
9
|
+
* - Authentication mode to consent provider type mapping
|
|
10
|
+
* - oauthProviderId uniqueness enforcement
|
|
11
|
+
* - Seal capability to prevent runtime modifications
|
|
12
|
+
* - Consistent fallback behavior with logging
|
|
13
|
+
*/
|
|
14
|
+
import { AUTH_MODES } from './types';
|
|
15
|
+
import { validateProviderDefinition, validateProviderConfig, } from './schemas';
|
|
16
|
+
/**
|
|
17
|
+
* Default logger using console.warn
|
|
18
|
+
*/
|
|
19
|
+
const defaultLogger = {
|
|
20
|
+
warn: (message, context) => {
|
|
21
|
+
if (context) {
|
|
22
|
+
console.warn(message, context);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
console.warn(message);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Provider Registry Implementation
|
|
31
|
+
*
|
|
32
|
+
* Maintains a registry of provider definitions and provides lookup/mapping methods.
|
|
33
|
+
*
|
|
34
|
+
* ## Fallback Behavior
|
|
35
|
+
*
|
|
36
|
+
* This registry implements consistent fallback behavior:
|
|
37
|
+
*
|
|
38
|
+
* - `mapAuthModeToConsentProvider`:
|
|
39
|
+
* - Unknown oauthProviderId with explicit presence → 'oauth2' (logs warning)
|
|
40
|
+
* - No oauthProviderId → 'none'
|
|
41
|
+
*
|
|
42
|
+
* - `mapProviderToConsentProvider`:
|
|
43
|
+
* - Unknown providerId → 'none' (logs warning)
|
|
44
|
+
*
|
|
45
|
+
* The difference is intentional:
|
|
46
|
+
* - If caller provides an oauthProviderId, they expect OAuth behavior
|
|
47
|
+
* - If caller provides a providerId that's unknown, fall back safely
|
|
48
|
+
*/
|
|
49
|
+
export class ProviderRegistry {
|
|
50
|
+
/**
|
|
51
|
+
* Create a new ProviderRegistry
|
|
52
|
+
*
|
|
53
|
+
* @param initial - Initial providers to register (defaults to common providers)
|
|
54
|
+
* @param logger - Optional logger for warnings (defaults to console.warn)
|
|
55
|
+
*/
|
|
56
|
+
constructor(initial = [], logger = defaultLogger) {
|
|
57
|
+
this.providers = new Map();
|
|
58
|
+
this.oauthProviderIdIndex = new Map(); // oauthProviderId -> provider id
|
|
59
|
+
this.sealed = false;
|
|
60
|
+
this.logger = logger;
|
|
61
|
+
initial.forEach((p) => this.registerProvider(p, { overwrite: false }));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Register a provider definition
|
|
65
|
+
*
|
|
66
|
+
* Provider IDs are normalized to lowercase.
|
|
67
|
+
* oauthProviderId must be unique across the registry.
|
|
68
|
+
*
|
|
69
|
+
* @param def - Provider definition (will be validated)
|
|
70
|
+
* @param opts - Registration options
|
|
71
|
+
* @throws Error if provider already exists and overwrite is false
|
|
72
|
+
* @throws Error if oauthProviderId already exists for another provider
|
|
73
|
+
* @throws Error if registry is sealed
|
|
74
|
+
*/
|
|
75
|
+
registerProvider(def, opts = {}) {
|
|
76
|
+
if (this.sealed) {
|
|
77
|
+
throw new Error('Registry is sealed. Cannot register new providers after seal() is called.');
|
|
78
|
+
}
|
|
79
|
+
const normalized = validateProviderDefinition(def);
|
|
80
|
+
const normalizedId = normalized.id.toLowerCase();
|
|
81
|
+
// Check for duplicate provider ID
|
|
82
|
+
if (this.providers.has(normalizedId) && !opts.overwrite) {
|
|
83
|
+
throw new Error(`Provider "${normalizedId}" is already registered. Use overwrite: true to replace.`);
|
|
84
|
+
}
|
|
85
|
+
// Handle oauthProviderId uniqueness
|
|
86
|
+
const normalizedOAuthProviderId = normalized.oauthProviderId?.toLowerCase();
|
|
87
|
+
if (normalizedOAuthProviderId) {
|
|
88
|
+
const existingOwnerId = this.oauthProviderIdIndex.get(normalizedOAuthProviderId);
|
|
89
|
+
// If oauthProviderId is used by a different provider, require overwrite
|
|
90
|
+
if (existingOwnerId && existingOwnerId !== normalizedId) {
|
|
91
|
+
if (!opts.overwrite) {
|
|
92
|
+
throw new Error(`oauthProviderId "${normalizedOAuthProviderId}" is already used by provider "${existingOwnerId}". ` +
|
|
93
|
+
`Use overwrite: true to replace or use a different oauthProviderId.`);
|
|
94
|
+
}
|
|
95
|
+
// If overwriting, remove old index entry
|
|
96
|
+
this.oauthProviderIdIndex.delete(normalizedOAuthProviderId);
|
|
97
|
+
}
|
|
98
|
+
// Update oauthProviderId index
|
|
99
|
+
this.oauthProviderIdIndex.set(normalizedOAuthProviderId, normalizedId);
|
|
100
|
+
}
|
|
101
|
+
// If we're overwriting, clean up old oauthProviderId index
|
|
102
|
+
if (opts.overwrite) {
|
|
103
|
+
const existing = this.providers.get(normalizedId);
|
|
104
|
+
if (existing?.oauthProviderId) {
|
|
105
|
+
const oldOAuthId = existing.oauthProviderId.toLowerCase();
|
|
106
|
+
if (oldOAuthId !== normalizedOAuthProviderId) {
|
|
107
|
+
this.oauthProviderIdIndex.delete(oldOAuthId);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
this.providers.set(normalizedId, normalized);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get a provider definition by ID (case-insensitive)
|
|
115
|
+
*
|
|
116
|
+
* @param id - Provider identifier
|
|
117
|
+
* @returns Provider definition or undefined if not found
|
|
118
|
+
*/
|
|
119
|
+
getProvider(id) {
|
|
120
|
+
return this.providers.get(id.toLowerCase());
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Find a provider by its oauthProviderId (case-insensitive)
|
|
124
|
+
*
|
|
125
|
+
* This is useful when you have an OAuth identity provider field
|
|
126
|
+
* that may differ from the provider's primary ID.
|
|
127
|
+
*
|
|
128
|
+
* @param oauthProviderId - OAuth provider identifier to look up
|
|
129
|
+
* @returns Provider definition or undefined if not found
|
|
130
|
+
*/
|
|
131
|
+
findByOauthProviderId(oauthProviderId) {
|
|
132
|
+
const normalizedOAuthId = oauthProviderId.toLowerCase();
|
|
133
|
+
const providerId = this.oauthProviderIdIndex.get(normalizedOAuthId);
|
|
134
|
+
if (providerId) {
|
|
135
|
+
return this.providers.get(providerId);
|
|
136
|
+
}
|
|
137
|
+
// Fallback: check if oauthProviderId matches a provider ID directly
|
|
138
|
+
// This handles cases where id === oauthProviderId
|
|
139
|
+
return this.providers.get(normalizedOAuthId);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Check if a provider is known (registered)
|
|
143
|
+
*
|
|
144
|
+
* @param id - Provider identifier
|
|
145
|
+
* @returns True if provider is registered
|
|
146
|
+
*/
|
|
147
|
+
isKnownProvider(id) {
|
|
148
|
+
return this.providers.has(id.toLowerCase());
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Check if a provider is an OAuth provider
|
|
152
|
+
*
|
|
153
|
+
* @param id - Provider identifier
|
|
154
|
+
* @returns True if provider exists and has oauth2 authType
|
|
155
|
+
*/
|
|
156
|
+
isOAuthProvider(id) {
|
|
157
|
+
const provider = this.getProvider(id);
|
|
158
|
+
return !!provider && provider.authType === 'oauth2';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Check if a provider is a credential provider
|
|
162
|
+
*
|
|
163
|
+
* @param id - Provider identifier
|
|
164
|
+
* @returns True if provider exists and has password authType
|
|
165
|
+
*/
|
|
166
|
+
isCredentialProvider(id) {
|
|
167
|
+
const provider = this.getProvider(id);
|
|
168
|
+
return !!provider && provider.authType === 'password';
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Map auth mode and OAuth provider ID to consent provider type
|
|
172
|
+
*
|
|
173
|
+
* Deterministic precedence rules:
|
|
174
|
+
* 1. Explicit authMode (non-oauth) → direct mapping
|
|
175
|
+
* 2. If authMode === 'oauth' or no explicit authMode but oauthProviderId present → consult registry
|
|
176
|
+
* 3. Unknown oauthProviderId → 'oauth2' (with warning log)
|
|
177
|
+
* 4. Fallback → 'none'
|
|
178
|
+
*
|
|
179
|
+
* @param authMode - Authentication mode (UI/flow level)
|
|
180
|
+
* @param oauthProviderId - OAuth provider identifier (if OAuth flow)
|
|
181
|
+
* @returns Consent provider type (backend routing vocabulary)
|
|
182
|
+
*/
|
|
183
|
+
mapAuthModeToConsentProvider(authMode, oauthProviderId) {
|
|
184
|
+
// 1. If explicit authMode (non-oauth) → direct mapping
|
|
185
|
+
if (authMode && authMode !== AUTH_MODES.OAUTH) {
|
|
186
|
+
switch (authMode) {
|
|
187
|
+
case AUTH_MODES.CREDENTIALS:
|
|
188
|
+
case 'credentials':
|
|
189
|
+
case 'password':
|
|
190
|
+
case 'credential':
|
|
191
|
+
return 'credential';
|
|
192
|
+
case AUTH_MODES.MAGIC_LINK:
|
|
193
|
+
case 'magic-link':
|
|
194
|
+
case 'magic_link':
|
|
195
|
+
return 'magic_link';
|
|
196
|
+
case AUTH_MODES.OTP:
|
|
197
|
+
case 'otp':
|
|
198
|
+
return 'otp';
|
|
199
|
+
case AUTH_MODES.PASSKEY:
|
|
200
|
+
case 'passkey':
|
|
201
|
+
return 'passkey';
|
|
202
|
+
case 'verifiable_credential':
|
|
203
|
+
return 'verifiable_credential';
|
|
204
|
+
case AUTH_MODES.IDV:
|
|
205
|
+
case 'idv':
|
|
206
|
+
return 'verifiable_credential';
|
|
207
|
+
case 'mdl':
|
|
208
|
+
return 'verifiable_credential';
|
|
209
|
+
case AUTH_MODES.CONSENT_ONLY:
|
|
210
|
+
case 'consent-only':
|
|
211
|
+
case 'none':
|
|
212
|
+
case '':
|
|
213
|
+
return 'none';
|
|
214
|
+
default:
|
|
215
|
+
return 'none';
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// 2. If authMode === 'oauth' or oauthProviderId present
|
|
219
|
+
if (authMode === AUTH_MODES.OAUTH || authMode === 'oauth' || oauthProviderId) {
|
|
220
|
+
// If oauthProviderId provided, try to look up the provider
|
|
221
|
+
if (oauthProviderId) {
|
|
222
|
+
// First try findByOauthProviderId for proper lookup
|
|
223
|
+
let provider = this.findByOauthProviderId(oauthProviderId);
|
|
224
|
+
// Also check by direct ID lookup (for backward compatibility)
|
|
225
|
+
if (!provider) {
|
|
226
|
+
provider = this.getProvider(oauthProviderId);
|
|
227
|
+
}
|
|
228
|
+
if (provider) {
|
|
229
|
+
return this.mapAuthTypeToConsentProvider(provider.authType);
|
|
230
|
+
}
|
|
231
|
+
// Unknown oauthProviderId: log warning and return 'oauth2'
|
|
232
|
+
this.logger.warn(`Provider "${oauthProviderId}" not registered in provider registry; assuming oauth2 flow.`, { oauthProviderId, fallback: 'oauth2' });
|
|
233
|
+
}
|
|
234
|
+
// authMode === 'oauth' without oauthProviderId, or unknown oauthProviderId
|
|
235
|
+
return 'oauth2';
|
|
236
|
+
}
|
|
237
|
+
// 3. Fallback
|
|
238
|
+
return 'none';
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Map provider ID directly to consent provider type
|
|
242
|
+
*
|
|
243
|
+
* Thin wrapper that looks up provider.authType and maps it to consent provider type.
|
|
244
|
+
* For unknown providers, returns 'none' and logs a warning.
|
|
245
|
+
*
|
|
246
|
+
* @param providerId - Provider identifier
|
|
247
|
+
* @returns Consent provider type
|
|
248
|
+
*/
|
|
249
|
+
mapProviderToConsentProvider(providerId) {
|
|
250
|
+
const provider = this.getProvider(providerId);
|
|
251
|
+
if (!provider) {
|
|
252
|
+
this.logger.warn(`Provider "${providerId}" not found in registry; returning 'none'.`, { providerId, fallback: 'none' });
|
|
253
|
+
return 'none';
|
|
254
|
+
}
|
|
255
|
+
return this.mapAuthTypeToConsentProvider(provider.authType);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Map provider auth type to consent provider type
|
|
259
|
+
*
|
|
260
|
+
* @internal
|
|
261
|
+
*/
|
|
262
|
+
mapAuthTypeToConsentProvider(authType) {
|
|
263
|
+
switch (authType) {
|
|
264
|
+
case 'oauth2':
|
|
265
|
+
return 'oauth2';
|
|
266
|
+
case 'password':
|
|
267
|
+
return 'credential';
|
|
268
|
+
case 'verifiable_credential':
|
|
269
|
+
return 'verifiable_credential';
|
|
270
|
+
case 'magic_link':
|
|
271
|
+
return 'magic_link';
|
|
272
|
+
case 'otp':
|
|
273
|
+
return 'otp';
|
|
274
|
+
case 'passkey':
|
|
275
|
+
return 'passkey';
|
|
276
|
+
case 'none':
|
|
277
|
+
return 'none';
|
|
278
|
+
default:
|
|
279
|
+
return 'none';
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Determine provider type from auth mode and OAuth identity provider
|
|
284
|
+
*
|
|
285
|
+
* @deprecated Use mapAuthModeToConsentProvider instead. This method is kept for backward compatibility.
|
|
286
|
+
*
|
|
287
|
+
* @param authMode - Authentication mode
|
|
288
|
+
* @param oauthIdentityProvider - OAuth provider identifier
|
|
289
|
+
* @returns Consent provider type
|
|
290
|
+
*/
|
|
291
|
+
determineProviderTypeFromAuthMode(authMode, oauthIdentityProvider) {
|
|
292
|
+
return this.mapAuthModeToConsentProvider(authMode, oauthIdentityProvider);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* List all registered providers
|
|
296
|
+
*
|
|
297
|
+
* @returns Array of all provider definitions
|
|
298
|
+
*/
|
|
299
|
+
listProviders() {
|
|
300
|
+
return Array.from(this.providers.values());
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Load providers from configuration
|
|
304
|
+
*
|
|
305
|
+
* Validates configuration via zod and registers all providers.
|
|
306
|
+
* Existing providers with same ID will be overwritten.
|
|
307
|
+
*
|
|
308
|
+
* @param config - Configuration object (will be validated)
|
|
309
|
+
* @throws ZodError if configuration is invalid
|
|
310
|
+
* @throws Error if registry is sealed
|
|
311
|
+
*/
|
|
312
|
+
loadFromConfig(config) {
|
|
313
|
+
if (this.sealed) {
|
|
314
|
+
throw new Error('Registry is sealed. Cannot load configuration after seal() is called.');
|
|
315
|
+
}
|
|
316
|
+
const validated = validateProviderConfig(config);
|
|
317
|
+
validated.providers.forEach((p) => this.registerProvider(p, { overwrite: true }));
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Seal the registry to prevent further modifications
|
|
321
|
+
*
|
|
322
|
+
* Once sealed, registerProvider() and loadFromConfig() will throw.
|
|
323
|
+
* Useful for long-running workers to prevent accidental runtime modifications.
|
|
324
|
+
*
|
|
325
|
+
* This operation is irreversible.
|
|
326
|
+
*/
|
|
327
|
+
seal() {
|
|
328
|
+
this.sealed = true;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Check if the registry is sealed
|
|
332
|
+
*
|
|
333
|
+
* @returns True if the registry is sealed
|
|
334
|
+
*/
|
|
335
|
+
isSealed() {
|
|
336
|
+
return this.sealed;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,WAAW,CAAC;AAWnB;;GAEG;AACH,MAAM,aAAa,GAAmB;IACpC,IAAI,EAAE,CAAC,OAAe,EAAE,OAAiC,EAAE,EAAE;QAC3D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;CACF,CAAC;AAoIF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,gBAAgB;IAM3B;;;;;OAKG;IACH,YAAY,UAAgC,EAAE,EAAE,SAAyB,aAAa;QAX9E,cAAS,GAAG,IAAI,GAAG,EAA8B,CAAC;QAClD,yBAAoB,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAC,iCAAiC;QACnF,WAAM,GAAG,KAAK,CAAC;QAUrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;IAED;;;;;;;;;;;OAWG;IACH,gBAAgB,CACd,GAAuB,EACvB,OAAgC,EAAE;QAElC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,0BAA0B,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;QAEjD,kCAAkC;QAClC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CACb,aAAa,YAAY,0DAA0D,CACpF,CAAC;QACJ,CAAC;QAED,oCAAoC;QACpC,MAAM,yBAAyB,GAAG,UAAU,CAAC,eAAe,EAAE,WAAW,EAAE,CAAC;QAC5E,IAAI,yBAAyB,EAAE,CAAC;YAC9B,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YAEjF,wEAAwE;YACxE,IAAI,eAAe,IAAI,eAAe,KAAK,YAAY,EAAE,CAAC;gBACxD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,MAAM,IAAI,KAAK,CACb,oBAAoB,yBAAyB,kCAAkC,eAAe,KAAK;wBACnG,oEAAoE,CACrE,CAAC;gBACJ,CAAC;gBACD,yCAAyC;gBACzC,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;YAC9D,CAAC;YAED,+BAA+B;YAC/B,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC;QACzE,CAAC;QAED,2DAA2D;QAC3D,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAClD,IAAI,QAAQ,EAAE,eAAe,EAAE,CAAC;gBAC9B,MAAM,UAAU,GAAG,QAAQ,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC;gBAC1D,IAAI,UAAU,KAAK,yBAAyB,EAAE,CAAC;oBAC7C,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,EAAU;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;OAQG;IACH,qBAAqB,CAAC,eAAuB;QAC3C,MAAM,iBAAiB,GAAG,eAAe,CAAC,WAAW,EAAE,CAAC;QACxD,MAAM,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAEpE,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;QAED,oEAAoE;QACpE,kDAAkD;QAClD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,EAAU;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,EAAU;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAAC,EAAU;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,KAAK,UAAU,CAAC;IACxD,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,4BAA4B,CAC1B,QAA4B,EAC5B,eAAwB;QAExB,uDAAuD;QACvD,IAAI,QAAQ,IAAI,QAAQ,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;YAC9C,QAAQ,QAAQ,EAAE,CAAC;gBACjB,KAAK,UAAU,CAAC,WAAW,CAAC;gBAC5B,KAAK,aAAa,CAAC;gBACnB,KAAK,UAAU,CAAC;gBAChB,KAAK,YAAY;oBACf,OAAO,YAAY,CAAC;gBACtB,KAAK,UAAU,CAAC,UAAU,CAAC;gBAC3B,KAAK,YAAY,CAAC;gBAClB,KAAK,YAAY;oBACf,OAAO,YAAY,CAAC;gBACtB,KAAK,UAAU,CAAC,GAAG,CAAC;gBACpB,KAAK,KAAK;oBACR,OAAO,KAAK,CAAC;gBACf,KAAK,UAAU,CAAC,OAAO,CAAC;gBACxB,KAAK,SAAS;oBACZ,OAAO,SAAS,CAAC;gBACnB,KAAK,uBAAuB;oBAC1B,OAAO,uBAAuB,CAAC;gBACjC,KAAK,UAAU,CAAC,GAAG,CAAC;gBACpB,KAAK,KAAK;oBACR,OAAO,uBAAuB,CAAC;gBACjC,KAAK,KAAK;oBACR,OAAO,uBAAuB,CAAC;gBACjC,KAAK,UAAU,CAAC,YAAY,CAAC;gBAC7B,KAAK,cAAc,CAAC;gBACpB,KAAK,MAAM,CAAC;gBACZ,KAAK,EAAE;oBACL,OAAO,MAAM,CAAC;gBAChB;oBACE,OAAO,MAAM,CAAC;YAClB,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,IAAI,QAAQ,KAAK,UAAU,CAAC,KAAK,IAAI,QAAQ,KAAK,OAAO,IAAI,eAAe,EAAE,CAAC;YAC7E,2DAA2D;YAC3D,IAAI,eAAe,EAAE,CAAC;gBACpB,oDAAoD;gBACpD,IAAI,QAAQ,GAAG,IAAI,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;gBAE3D,8DAA8D;gBAC9D,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;gBAC/C,CAAC;gBAED,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC9D,CAAC;gBAED,2DAA2D;gBAC3D,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,aAAa,eAAe,8DAA8D,EAC1F,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,CACxC,CAAC;YACJ,CAAC;YAED,2EAA2E;YAC3E,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,cAAc;QACd,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;OAQG;IACH,4BAA4B,CAAC,UAAkB;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAE9C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,aAAa,UAAU,4CAA4C,EACnE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,CACjC,CAAC;YACF,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,OAAO,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACK,4BAA4B,CAAC,QAA0B;QAC7D,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,OAAO,QAAQ,CAAC;YAClB,KAAK,UAAU;gBACb,OAAO,YAAY,CAAC;YACtB,KAAK,uBAAuB;gBAC1B,OAAO,uBAAuB,CAAC;YACjC,KAAK,YAAY;gBACf,OAAO,YAAY,CAAC;YACtB,KAAK,KAAK;gBACR,OAAO,KAAK,CAAC;YACf,KAAK,SAAS;gBACZ,OAAO,SAAS,CAAC;YACnB,KAAK,MAAM;gBACT,OAAO,MAAM,CAAC;YAChB;gBACE,OAAO,MAAM,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,iCAAiC,CAC/B,QAAiB,EACjB,qBAA8B;QAE9B,OAAO,IAAI,CAAC,4BAA4B,CACtC,QAAoB,EACpB,qBAAqB,CACtB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,aAAa;QACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;;;;;OASG;IACH,cAAc,CAAC,MAAe;QAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACjD,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAChC,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAC9C,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,IAAI;QACF,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
|