ProxyClass
ProxyClass
Présentation
ProxyClass est un utilitaire avancé permettant de créer un objet proxy sécurisé et contrôlé à partir d’une instance de classe existante.
Son objectif est de restreindre et maîtriser l’API exposée, tout en conservant :
- le contexte (
this) de l’instance originale, - l’héritage,
- la possibilité d’intercepter les accès via
Proxy.
Cette classe est particulièrement adaptée aux architectures :
- plugin-based
- sandboxées
- orientées API publique / API interne
- exposition contrôlée de services
Concepts clés
- Exposition explicite des méthodes
- Filtrage par whitelist / blacklist
- Support de l’héritage
- Binding automatique des méthodes
- Compatibilité avec
ProxyHandler
Cas d’usage typiques
- Exposer une API limitée d’un plugin
- Isoler des services internes
- Empêcher l’accès à des méthodes sensibles
- Fournir une façade stable à une classe complexe
- Encapsuler une instance sans la copier
Architecture générale
Instance réelle (ClassInstance)
│
├── Prototype
│ └── Méthodes internes
│
└── ProxyClass
├── Sélection des méthodes exposées
├── Bind sur l’instance réelle
├── Héritage respecté
└── Proxy JavaScript (optionnel)
Typage et interfaces
ClassType
interface ClassType<ClassInstance> {
new(): ClassInstance;
[Exposed: string]: Array<string>;
}
Représente un constructeur de classe pouvant définir une propriété statique d’exposition.
DefaultExposed
type DefaultExposed = {
blacklist?: string[];
whitelist?: string[];
};
Permet de forcer ou d’interdire certaines méthodes indépendamment de la classe.
ProxyClassConstructor
Signature finale exportée par défaut.
new <ClassInstance, ProxyObject>(
instance: ClassInstance,
handler?: ProxyHandler<ProxyObject>
): ProxyObject;
Classe ProxyClassBase
Rôle
ProxyClassBase est le cœur logique du système. Elle analyse la classe cible, sélectionne les méthodes autorisées, et construit l’objet exposé.
Propriétés principales
| Propriété | Description |
|---|---|
MainClassInstance | Instance réelle |
NameStaticExposed | Nom de la propriété statique (Exposed par défaut) |
DefaultExposed | Règles globales whitelist / blacklist |
proxyObject | Objet proxy généré |
Constructeur
constructor(
instance: ClassInstance,
DefaultExposed: DefaultExposed = {},
NameStaticExposed: string = "Exposed"
)
CreateProxyObject
CreateProxyObject(): ProxyObject
Crée l’objet proxy si nécessaire en analysant la classe et son héritage.
GetProxyObject
GetProxyObject(): ProxyObject
Retourne l’objet proxy existant ou le crée à la demande.
Sélection des méthodes exposées
La méthode interne GetProperty() applique la logique suivante :
1. Détection de la propriété statique
static Exposed = ["methodA", "methodB"];
Si présente :
- seules ces méthodes sont candidates
2. Fusion avec les règles globales
authorKey = Exposed
+ whitelist
- blacklist
3. Analyse du prototype
- exclusion du constructeur
- uniquement les méthodes présentes sur le prototype
- respect de l’héritage (récursif)
4. Binding automatique
Toutes les fonctions exposées sont automatiquement liées :
descriptor.value.bind(this.MainClassInstance)
Cela garantit :
- un
thiscorrect - aucun accès direct à l’objet interne
Support de l’héritage
ProxyClass remonte la chaîne des prototypes :
const parentCtor = Object.getPrototypeOf(ctr);
Les méthodes exposées du parent sont fusionnées avec celles de l’enfant.
Conseil
Cela permet de construire des APIs hiérarchiques propres et cohérentes.
Classe ProxyClassImpl
Rôle
ProxyClassImpl est une implémentation concrète qui retourne directement un objet Proxy.
return new Proxy(this.Object, handler);
Elle permet :
- interception (
get,set,apply, etc.) - validation ou monitoring
- instrumentation avancée
Constructeur
new ProxyClass(
instance,
handler?,
DefaultExposed?
);
Export final
const ProxyClass = ProxyClassImpl as ProxyClassConstructor;
export default ProxyClass;
Cela permet une syntaxe simple et directe à l’utilisation.
Exemple simple
Classe source
class MyService {
static Exposed = ["sayHello"];
sayHello(name: string) {
return `Hello ${name}`;
}
secret() {
return "hidden";
}
}
Création du proxy
const service = new MyService();
const api = new ProxyClass(service);
api.sayHello("Jean"); // ✅ OK
api.secret(); // ❌ Undefined
Exemple avec whitelist / blacklist
const api = new ProxyClass(
service,
{},
{
whitelist: ["secret"],
blacklist: ["dangerousMethod"]
}
);
Bonnes pratiques
- Toujours définir
static Exposed - Ne jamais exposer de méthodes mutables critiques
- Utiliser la blacklist comme filet de sécurité
- Préférer plusieurs proxys spécialisés
- Documenter explicitement l’API exposée
Limites connues
- Ne protège pas contre la réflexion avancée
- Les propriétés d’instance non définies sur le prototype ne sont pas exposées
- Pas de contrôle fin par rôle ou permission
Conclusion
ProxyClass est un composant puissant et flexible pour maîtriser l’exposition d’API dans des architectures complexes. Il favorise une séparation nette entre implémentation interne et contrat public, tout en restant léger et sans dépendances externes.