@@ -264,7 +264,7 @@ export namespace SecretsManager {
264
264
if ( symbols . has ( id ) ) {
265
265
lock ( `Sign error: another plugin signed as "${ id } ".` ) ;
266
266
}
267
- const token = Symbol ( id ) ;
267
+ const token = Private . OriginalSymbol ( id ) ;
268
268
const plugin = factory ( token ) ;
269
269
if ( id !== plugin . id ) {
270
270
lock ( `Sign error: plugin ID mismatch "${ plugin . id } "≠"${ id } ".` ) ;
@@ -276,20 +276,86 @@ export namespace SecretsManager {
276
276
}
277
277
278
278
namespace Private {
279
+ namespace SafeMapNs {
280
+ // Capture the original Map constructor and prototype methods.
281
+ const MapConstructor = Object . getPrototypeOf ( new Map ( ) ) . constructor ;
282
+ const _get = MapConstructor . prototype . get ;
283
+ const _has = MapConstructor . prototype . has ;
284
+ const _set = MapConstructor . prototype . set ;
285
+ const _delete = MapConstructor . prototype . delete ;
286
+ const _clear = MapConstructor . prototype . clear ;
287
+ const _entries = MapConstructor . prototype . entries ;
288
+ const _keys = MapConstructor . prototype . keys ;
289
+ const _values = MapConstructor . prototype . values ;
290
+ const _forEach = MapConstructor . prototype . forEach ;
291
+
292
+ export class SafeMap < K , V > {
293
+ private _map : InstanceType < typeof MapConstructor > ;
294
+
295
+ constructor ( entries ?: readonly ( readonly [ K , V ] ) [ ] | null ) {
296
+ this . _map = Reflect . construct ( MapConstructor , entries ? [ entries ] : [ ] ) ;
297
+ }
298
+ get ( key : K ) : V | undefined {
299
+ return _get . call ( this . _map , key ) ;
300
+ }
301
+ has ( key : K ) : boolean {
302
+ return _has . call ( this . _map , key ) ;
303
+ }
304
+ entries ( ) {
305
+ return _entries . call ( this . _map ) ;
306
+ }
307
+ keys ( ) {
308
+ return _keys . call ( this . _map ) ;
309
+ }
310
+ values ( ) {
311
+ return _values . call ( this . _map ) ;
312
+ }
313
+ forEach ( cb : ( v : V , k : K , m : Map < K , V > ) => void ) {
314
+ return _forEach . call ( this . _map , cb ) ;
315
+ }
316
+
317
+ set ( key : K , value : V ) : this {
318
+ _set . call ( this . _map , key , value ) ;
319
+ return this ;
320
+ }
321
+ delete ( key : K ) : boolean {
322
+ return _delete . call ( this . _map , key ) ;
323
+ }
324
+ clear ( ) : void {
325
+ _clear . call ( this . _map ) ;
326
+ }
327
+
328
+ get size ( ) : number {
329
+ return this . _map . size ;
330
+ }
331
+
332
+ // Iterator
333
+ [ Symbol . iterator ] ( ) {
334
+ return _entries . call ( this . _map ) ;
335
+ }
336
+ }
337
+ }
338
+
279
339
/**
280
340
* Internal 'locked' status.
281
341
*/
282
342
let locked : boolean = false ;
283
343
344
+ /**
345
+ * The original Symbol constructor, used to create unique symbols for plugin
346
+ * identification and namespace protection.
347
+ */
348
+ export const OriginalSymbol = Symbol ;
349
+
284
350
/**
285
351
* The namespace associated to a symbol.
286
352
*/
287
- export const namespaces = new Map < symbol , string > ( ) ;
353
+ export const namespaces = new SafeMapNs . SafeMap < symbol , string > ( ) ;
288
354
289
355
/**
290
356
* The symbol associated to a namespace.
291
357
*/
292
- export const symbols = new Map < string , symbol > ( ) ;
358
+ export const symbols = new SafeMapNs . SafeMap < string , symbol > ( ) ;
293
359
294
360
/**
295
361
* Lock the manager.
@@ -415,12 +481,15 @@ namespace Private {
415
481
/**
416
482
* The inputs elements attached to the manager.
417
483
*/
418
- export const inputs = new Map < string , HTMLInputElement > ( ) ;
484
+ export const inputs = new SafeMapNs . SafeMap < string , HTMLInputElement > ( ) ;
419
485
420
486
/**
421
487
* The secret path associated to an input.
422
488
*/
423
- export const secretPath = new Map < HTMLInputElement , SecretPath > ( ) ;
489
+ export const secretPath = new SafeMapNs . SafeMap <
490
+ HTMLInputElement ,
491
+ SecretPath
492
+ > ( ) ;
424
493
425
494
/**
426
495
* Build the secret id from the namespace and id.
0 commit comments