import TokenManager from './token-manager.js'
/** Gère l'assocation des token-manager au resource (layer, control, service...)
* Permet de mutualiser les token-manager entre plusieurs resources
*/
export default class TokenManagerPool {
/**
* @ type {Map<String, {tokenManager: TokenManager, resources: Array<{resourceType: String, resourceId: String}>}>}
*/
#tokenManagers = new Map()
/**
*
* @param {String} resourceType type de resource (layer, control, service...)
* @param {String} resourceId identifiant de la resource
* @param {import("./token-manager").tokenOptions | String} tokenOptions options de gestion du token ou token en clair (historique)
* @returns {TokenManager}
*/
async addTokenSource (resourceType, resourceId, tokenOptions) {
const tokenSourceOptions = typeof tokenOptions === 'object'
? {
autoStart: true,
...tokenOptions,
}
: tokenOptions
const autoStart = typeof tokenSourceOptions === 'string' ? true : tokenSourceOptions.autoStart
const tokenManagerKey = this.#getTokenManagerKey(tokenSourceOptions)
if (!this.#tokenManagers.has(tokenManagerKey)) {
// si le token manager n'existe pas, on le crée
const tokenManager = new TokenManager(tokenSourceOptions)
if (autoStart) {
await tokenManager.init()
}
this.#tokenManagers.set(tokenManagerKey, {
tokenManager,
resources: [{ resourceType, resourceId }],
})
} else {
// on ajoute la resource à la liste des resources utilisant ce token manager
const tokenManagerEntry = this.#tokenManagers.get(tokenManagerKey)
tokenManagerEntry.resources.push({ resourceType, resourceId })
}
return this.#tokenManagers.get(tokenManagerKey).tokenManager
}
/**
* supprime un token manager et toutes les resources qui l'utilisent
* @param {import("./token-manager").tokenOptions | String} tokenOptions options de gestion du token ou token en clair (historique)
* @returns {Boolean}
*/
removeTokenSource (tokenOptions) {
const tokenKey = this.#getTokenManagerKey(tokenOptions)
return this.#tokenManagers.delete(tokenKey)
}
/**
* Retire une source de la liste des resources utilisant un token manager, si plus aucune resource n'utilise ce token manager, on le supprime
* @param {String} resourceType type de resource (layer, control, service...)
* @param {String} resourceId identifiant de la resource
* @param {Boolean} [removeTokenManagerIfNoResource=false] indique si le token manager doit être supprimé si aucune ressource ne l'utilise
*/
removeResource (resourceType, resourceId, removeTokenManagerIfNoResource = false) {
for (const [key, entry] of this.#tokenManagers.entries()) {
const index = entry.resources.findIndex(r => r.resourceType === resourceType && r.resourceId === resourceId)
if (index !== -1) {
entry.resources.splice(index, 1)
// si plus aucune resource n'utilise ce token manager, on le supprime
if (entry.resources.length === 0 && removeTokenManagerIfNoResource) {
this.#tokenManagers.delete(key)
}
break
}
}
}
/**
* Est-ce que la clé de token manager existe déjà?
* @param {import("./token-manager").tokenOptions | String} tokenOptions options de gestion du token ou token en clair (historique)
* @returns {Boolean}
*/
tokenSourceExists (tokenOptions) {
const tokenKey = this.#getTokenManagerKey(tokenOptions)
return this.#tokenManagers.has(tokenKey)
}
getTokenManager (tokenOptions) {
const tokenKey = this.#getTokenManagerKey(tokenOptions)
return this.#tokenManagers.has(tokenKey) ? this.#tokenManagers.get(tokenKey).tokenManager : null
}
/**
* @param {import("./token-manager").tokenOptions | String} tokenOptions options de gestion du token ou token en clair (historique)
* @returns {String}
*/
#getTokenManagerKey (tokenOptions) {
// génère une clé de token, si c'est une chaine de caractère, on la prend telle quelle
// Sinon prend la propriété id
// sinon calcule une clé en fonction de la chaine
return typeof tokenOptions === 'string'
? tokenOptions
: tokenOptions?.id
? tokenOptions.id
: tokenOptions.type.toUpperCase() === 'FUNCTION'
? tokenOptions.toString()
: JSON.stringify(tokenOptions)
}
}