@@ -264,7 +264,7 @@ export namespace SecretsManager {
264264 if ( symbols . has ( id ) ) {
265265 lock ( `Sign error: another plugin signed as "${ id } ".` ) ;
266266 }
267- const token = Symbol ( id ) ;
267+ const token = Private . OriginalSymbol ( id ) ;
268268 const plugin = factory ( token ) ;
269269 if ( id !== plugin . id ) {
270270 lock ( `Sign error: plugin ID mismatch "${ plugin . id } "≠"${ id } ".` ) ;
@@ -276,20 +276,86 @@ export namespace SecretsManager {
276276}
277277
278278namespace 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+
279339 /**
280340 * Internal 'locked' status.
281341 */
282342 let locked : boolean = false ;
283343
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+
284350 /**
285351 * The namespace associated to a symbol.
286352 */
287- export const namespaces = new Map < symbol , string > ( ) ;
353+ export const namespaces = new SafeMapNs . SafeMap < symbol , string > ( ) ;
288354
289355 /**
290356 * The symbol associated to a namespace.
291357 */
292- export const symbols = new Map < string , symbol > ( ) ;
358+ export const symbols = new SafeMapNs . SafeMap < string , symbol > ( ) ;
293359
294360 /**
295361 * Lock the manager.
@@ -415,12 +481,15 @@ namespace Private {
415481 /**
416482 * The inputs elements attached to the manager.
417483 */
418- export const inputs = new Map < string , HTMLInputElement > ( ) ;
484+ export const inputs = new SafeMapNs . SafeMap < string , HTMLInputElement > ( ) ;
419485
420486 /**
421487 * The secret path associated to an input.
422488 */
423- export const secretPath = new Map < HTMLInputElement , SecretPath > ( ) ;
489+ export const secretPath = new SafeMapNs . SafeMap <
490+ HTMLInputElement ,
491+ SecretPath
492+ > ( ) ;
424493
425494 /**
426495 * Build the secret id from the namespace and id.
0 commit comments