@@ -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,87 @@ 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
+ s ;
299
+ get ( key : K ) : V | undefined {
300
+ return _get . call ( this . _map , key ) ;
301
+ }
302
+ has ( key : K ) : boolean {
303
+ return _has . call ( this . _map , key ) ;
304
+ }
305
+ entries ( ) {
306
+ return _entries . call ( this . _map ) ;
307
+ }
308
+ keys ( ) {
309
+ return _keys . call ( this . _map ) ;
310
+ }
311
+ values ( ) {
312
+ return _values . call ( this . _map ) ;
313
+ }
314
+ forEach ( cb : ( v : V , k : K , m : Map < K , V > ) => void ) {
315
+ return _forEach . call ( this . _map , cb ) ;
316
+ }
317
+
318
+ set ( key : K , value : V ) : this {
319
+ _set . call ( this . _map , key , value ) ;
320
+ return this ;
321
+ }
322
+ delete ( key : K ) : boolean {
323
+ return _delete . call ( this . _map , key ) ;
324
+ }
325
+ clear ( ) : void {
326
+ _clear . call ( this . _map ) ;
327
+ }
328
+
329
+ get size ( ) : number {
330
+ return this . _map . size ;
331
+ }
332
+
333
+ // Iterator
334
+ [ Symbol . iterator ] ( ) {
335
+ return _entries . call ( this . _map ) ;
336
+ }
337
+ }
338
+ }
339
+
279
340
/**
280
341
* Internal 'locked' status.
281
342
*/
282
343
let locked : boolean = false ;
283
344
345
+ /**
346
+ * The original Symbol constructor, used to create unique symbols for plugin
347
+ * identification and namespace protection.
348
+ */
349
+ export const OriginalSymbol = Symbol ;
350
+
284
351
/**
285
352
* The namespace associated to a symbol.
286
353
*/
287
- export const namespaces = new Map < symbol , string > ( ) ;
354
+ export const namespaces = new SafeMapNs . SafeMap < symbol , string > ( ) ;
288
355
289
356
/**
290
357
* The symbol associated to a namespace.
291
358
*/
292
- export const symbols = new Map < string , symbol > ( ) ;
359
+ export const symbols = new SafeMapNs . SafeMap < string , symbol > ( ) ;
293
360
294
361
/**
295
362
* Lock the manager.
@@ -415,12 +482,15 @@ namespace Private {
415
482
/**
416
483
* The inputs elements attached to the manager.
417
484
*/
418
- export const inputs = new Map < string , HTMLInputElement > ( ) ;
485
+ export const inputs = new SafeMapNs . SafeMap < string , HTMLInputElement > ( ) ;
419
486
420
487
/**
421
488
* The secret path associated to an input.
422
489
*/
423
- export const secretPath = new Map < HTMLInputElement , SecretPath > ( ) ;
490
+ export const secretPath = new SafeMapNs . SafeMap <
491
+ HTMLInputElement ,
492
+ SecretPath
493
+ > ( ) ;
424
494
425
495
/**
426
496
* Build the secret id from the namespace and id.
0 commit comments