@@ -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,87 @@ 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+ 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+
279340 /**
280341 * Internal 'locked' status.
281342 */
282343 let locked : boolean = false ;
283344
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+
284351 /**
285352 * The namespace associated to a symbol.
286353 */
287- export const namespaces = new Map < symbol , string > ( ) ;
354+ export const namespaces = new SafeMapNs . SafeMap < symbol , string > ( ) ;
288355
289356 /**
290357 * The symbol associated to a namespace.
291358 */
292- export const symbols = new Map < string , symbol > ( ) ;
359+ export const symbols = new SafeMapNs . SafeMap < string , symbol > ( ) ;
293360
294361 /**
295362 * Lock the manager.
@@ -415,12 +482,15 @@ namespace Private {
415482 /**
416483 * The inputs elements attached to the manager.
417484 */
418- export const inputs = new Map < string , HTMLInputElement > ( ) ;
485+ export const inputs = new SafeMapNs . SafeMap < string , HTMLInputElement > ( ) ;
419486
420487 /**
421488 * The secret path associated to an input.
422489 */
423- export const secretPath = new Map < HTMLInputElement , SecretPath > ( ) ;
490+ export const secretPath = new SafeMapNs . SafeMap <
491+ HTMLInputElement ,
492+ SecretPath
493+ > ( ) ;
424494
425495 /**
426496 * Build the secret id from the namespace and id.
0 commit comments