API de Plugins¶
Interfaz¶
Un plugin es una funcion asincrona que recibe el objeto parsed:
Carga de plugins¶
Los plugins se definen como strings (rutas a modulos) en el array plugin del YAML:
El pipeline de carga:
for (const fn of [resolve, validate, ...parsed.plugin, aws, docker, gcp]) {
const mod = typeof fn === 'string' ? require(fn) : (typeof fn === 'function' ? fn : null);
const handler = typeof mod === 'function' ? mod : mod?.default;
if (typeof handler !== 'function') continue;
await handler(parsed);
}
- Si
fnes un string →require(fn) - Si
fnes una funcion → se usa directamente - Del modulo, busca primero el modulo como funcion, luego
module.default - Si no es funcion, se omite silenciosamente
- Se llama con
await handler(parsed)
Orden del pipeline¶
Los plugins del usuario se ejecutan despues de resolve y validate, pero antes de los proveedores. Esto significa que:
- Los resolvers ya procesaron todos los
${...}del YAML - El schema ya se valido
- Los plugins pueden mutar el objeto antes de que los proveedores lo lean
Mutacion de parsed¶
Los plugins reciben la referencia directa al objeto parsed. Cualquier mutacion persiste:
module.exports = async function addDefaults(parsed) {
for (const service of Object.values(parsed.services)) {
service.env = service.env ?? {};
service.env.STACK_NAME = parsed.name;
}
};
Los proveedores que se ejecutan despues veran STACK_NAME en las variables de entorno de cada servicio.
Plugin validate (integrado)¶
El plugin validate hace dos verificaciones:
- Schema Zod: Ejecuta
schema.safeParse(parsed). Si falla, formatea los errores y lanza:
Schema validation failed:
- services.api.scale.replica: Expected number, received string
- services.api.image: Required
- Regla de negocio: Si
scale.replicaes un array[min, max], verifica quemin <= max:
Formato del modulo¶
CommonJS¶
// module.exports directo
module.exports = async function myPlugin(parsed) { };
// module.exports.default
module.exports.default = async function myPlugin(parsed) { };
ESM (compilado a CJS)¶
pctl usa require() para cargar plugins, por lo que modulos ESM puros necesitan ser compilados a CommonJS o usar una extension que lo soporte.