@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.
@@ -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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"}
@@ -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":"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"}