Saltar al contenido principal

Referencia de la API

Referencia completa de @powerduck/conf-patch, con las firmas y los valores predeterminados de cada símbolo exportado.

Hay dos puntos de entrada:

  • @powerduck/conf-patch — todo lo indicado a continuación: capa principal, archivos, validación OpenAPI y utilidades.
  • @powerduck/conf-patch/core — solo el subconjunto compatible con navegadores: patchContent, setContentValue, deleteContentValue, PatchContentOptions, las funciones de aserción y los tipos ConfigFormat, JsonPatchOp, JsonPathSegment.

Capa principal (compatible con navegadores)​

patchContent​

Aplica una lista de operaciones RFC 6902 a una cadena de configuración. Es una función pura, sin acceso al sistema de archivos.

function patchContent(
content: string,
ops: JsonPatchOp[],
format: ConfigFormat,
options?: PatchContentOptions,
): string;
ParámetroTipoDescripción
contentstringContenido de configuración sin procesar. Debe ajustarse al format indicado.
opsJsonPatchOp[]Operaciones que se aplican en orden. Un array vacío devuelve content sin cambios.
formatConfigFormat"json" | "jsonc" | "yaml".
options.strictbooleanCon true (predeterminado), una operación fallida lanza una excepción. Con false, se omite y se notifica mediante console.warn.

Devuelve: el contenido de configuración modificado (string).

Excepciones: TypeError si content no es una cadena o ops no es válido; un error que describe la operación fallida cuando strict es true.

import { patchContent } from "@powerduck/conf-patch/core";

patchContent(
'{"name": "app"}',
[{ op: "add", path: ["version"], value: "1.0.0" }],
"json",
);
// => '{\n "name": "app",\n "version": "1.0.0"\n}'

setContentValue​

Establece o crea un valor. Internamente llama a patchContent con una operación add. Según RFC 6902, add reemplaza una propiedad de objeto existente o inserta en un índice de array.

function setContentValue(
content: string,
path: readonly (string | number)[],
value: unknown,
format: ConfigFormat,
): string;
ParámetroTipoDescripción
contentstringContenido de configuración sin procesar.
pathreadonly (string | number)[]Ruta por segmentos, por ejemplo ["server", "port"]. No puede estar vacía.
valueunknownValor que se escribirá.
formatConfigFormatFormato de configuración.

Devuelve: el contenido actualizado (string).

setContentValue("server:\n port: 3000\n", ["server", "port"], 8080, "yaml");

deleteContentValue​

Elimina una clave o un elemento de array. Internamente llama a patchContent con una operación remove. La ruta debe existir.

function deleteContentValue(
content: string,
path: readonly (string | number)[],
format: ConfigFormat,
): string;
deleteContentValue(
'{"name": "app", "legacy": true}',
["legacy"],
"json",
);

PatchContentOptions​

interface PatchContentOptions {
/** When true, failed operations throw. When false, they are skipped with a warning. Default: true */
strict?: boolean;
}

Capa de archivos (solo Node.js / Electron)​

readConfigFile​

Lee texto UTF-8 desde una ruta local o una URL file://.

function readConfigFile(filePath: string): Promise<string>;
ParámetroTipoDescripción
filePathstringRuta absoluta, relativa o URL file://. No puede estar vacía.

Devuelve: el contenido UTF-8 sin procesar (Promise<string>).

Excepciones: si no se puede leer el archivo, un error que incluye el fallo subyacente del sistema de archivos.


writeConfigFile​

Escribe contenido de forma atómica mediante un archivo temporal y su renombrado, con un bloqueo de archivo exclusivo por defecto. Los directorios padre se crean antes de adquirir el bloqueo.

function writeConfigFile(
filePath: string,
content: string,
options?: WriteConfigOptions,
): Promise<void>;
ParámetroTipoDescripción
filePathstringRuta del archivo de configuración.
contentstringContenido que se escribirá. Debe ser una cadena.
optionsWriteConfigOptionsConsulta la sección siguiente.

Excepciones: TypeError por entradas inválidas; los fallos de escritura del sistema de archivos se encapsulan.

WriteConfigOptions​

OpciónTipoValor predeterminadoDescripción
lockbooleantrueActivar el bloqueo durante la escritura.
lockTimeoutMsnumberPredeterminado de withFileLock (10 s)Tiempo máximo para adquirir el bloqueo, en milisegundos.
lockRetryDelayMsnumberPredeterminado de withFileLock (25 ms)Espera inicial entre reintentos, en milisegundos, antes del incremento exponencial.
lockStaleThresholdMsnumberPredeterminado de withFileLockAntigüedad del bloqueo, en milisegundos, a partir de la cual se permite recuperarlo.
allowStaleRecoverybooleanfalsePermitir la recuperación automática de bloqueos obsoletos.
import { writeConfigFile } from "@powerduck/conf-patch";

await writeConfigFile("config.json", '{"name": "app"}');

patchConfigFile​

Transacción principal de la capa de archivos: lee bajo bloqueo, aplica patchContent y vuelve a escribir de forma atómica solo si el contenido cambió. Si se omite options.format, el formato se detecta por la extensión.

function patchConfigFile(
filePath: string,
ops: JsonPatchOp[],
options?: PatchConfigOptions,
): Promise<void>;
ParámetroTipoDescripción
filePathstringRuta del archivo de configuración. No puede estar vacía.
opsJsonPatchOp[]Operaciones que se aplicarán. Un array vacío devuelve el control sin leer ni escribir.
optionsPatchConfigOptionsConsulta la sección siguiente.

Excepciones: TypeError si filePath está vacío, las opciones de bloqueo no son válidas o no se detecta el formato y no se proporciona format; el error de la operación cuando strict es true.

PatchConfigOptions​

OpciónTipoValor predeterminadoDescripción
formatConfigFormatdetección automáticaFormato explícito, con prioridad sobre la detección por extensión.
strictbooleantrueLas operaciones fallidas lanzan excepciones.
lockbooleantrueActivar el bloqueo de archivos.
lockTimeoutMsnumber10 sNo negativo. Espera máxima para adquirir el bloqueo.
lockRetryDelayMsnumber25 msPositivo. Espera inicial entre reintentos.
lockStaleThresholdMsnumbercalculadoPositivo. Antigüedad necesaria para recuperar un bloqueo obsoleto.
allowStaleRecoverybooleanfalseRecuperar automáticamente bloqueos obsoletos.
await patchConfigFile("config.json", [
{ op: "replace", path: ["server", "host"], value: "0.0.0.0" },
{ op: "add", path: ["server", "ssl"], value: true },
{ op: "remove", path: ["legacySection"] },
]);

setConfigValue​

Añade o reemplaza un valor anidado en un archivo. Delega una operación add en patchConfigFile.

function setConfigValue(
filePath: string,
path: readonly (string | number)[],
value: unknown,
options?: PatchConfigOptions,
): Promise<void>;
await setConfigValue("config.yaml", ["database", "port"], 5432);

deleteConfigValue​

Elimina un valor anidado existente de un archivo. Delega una operación remove en patchConfigFile.

function deleteConfigValue(
filePath: string,
path: readonly (string | number)[],
options?: PatchConfigOptions,
): Promise<void>;
await deleteConfigValue("config.json", ["features", "betaPreview"]);

withFileLock​

Ejecuta una función asíncrona mediante una cola local al proceso y un archivo de bloqueo exclusivo (<file>.confedit.lock). Los bloqueos utilizan tokens de propiedad. Solo se recupera un bloqueo obsoleto si allowStaleRecovery es true y su antigüedad supera staleThresholdMs. No se comprueban los PID porque pueden reutilizarse.

function withFileLock<T>(
filePath: string,
callback: () => Promise<T>,
options?: FileLockOptions,
): Promise<T>;
ParámetroTipoDescripción
filePathstringArchivo que se bloqueará.
callback() => Promise<T>Trabajo que se ejecutará mientras se mantiene el bloqueo.
optionsFileLockOptionsConsulta la sección siguiente.

Devuelve: el resultado de callback (Promise<T>). El bloqueo siempre se libera en un bloque finally, incluso si la función lanza una excepción.

FileLockOptions​

OpciónTipoValor predeterminadoDescripción
timeoutMsnumber10000Espera máxima del bloqueo en milisegundos. Debe ser no negativa.
retryDelayMsnumber25Espera inicial en milisegundos. Debe ser positiva. Aumenta por un factor de 1,5 hasta un máximo de 1000 ms.
staleThresholdMsnumbermax(timeoutMs * 2, 60000)Antigüedad que permite recuperar el bloqueo, en milisegundos. Debe ser positiva.
allowStaleRecoverybooleanfalseRecuperación automática de bloqueos obsoletos. Desactivada por defecto para el proceso principal único de Electron, para no interrumpir transacciones activas.
import { withFileLock } from "@powerduck/conf-patch";

await withFileLock("state.json", async () => {
// ... read, modify, write ...
}, { timeoutMs: 5000 });

releaseAllLocalLocks​

Elimina todos los archivos de bloqueo del proceso actual. Úsala al cerrar la aplicación, una vez terminadas las transacciones activas. Para una limpieza asíncrona en Electron, impide el primer cierre y reanúdalo tras completar la limpieza, como muestran los ejemplos. Los fallos individuales se ignoran.

function releaseAllLocalLocks(): Promise<void>;

Validación de OpenAPI​

validateOpenAPISpec​

Valida contenido OpenAPI/Swagger sin procesar en JSON o YAML. La entrada se trata como contenido por defecto; solo se interpreta como ruta con inputKind: "file". La validación se delega en @powerduck/openapi-parser; esta función añade controles de seguridad a las entradas.

function validateOpenAPISpec(
input: string,
options?: ValidateOpenApiOptions,
): Promise<AnyOpenAPIDocument>;
ParámetroTipoDescripción
inputstringContenido de la especificación, o ruta de archivo con inputKind: "file".
optionsValidateOpenApiOptionsConsulta la sección siguiente.

Devuelve: el documento validado si la operación tiene éxito (Promise<AnyOpenAPIDocument>).

Excepciones: TypeError si la entrada está vacía o no es una cadena; OpenApiValidationError si las opciones son inválidas o falla la validación.


validateOpenAPIFile​

Función auxiliar que llama a validateOpenAPISpec con inputKind: "file" y baseFilePath establecido en la ruta indicada. Requiere allowedRootDirectory.

function validateOpenAPIFile(
filePath: string,
options?: ValidateOpenApiOptions,
): Promise<AnyOpenAPIDocument>;
import { validateOpenAPIFile } from "@powerduck/conf-patch";

const doc = await validateOpenAPIFile("./configs/openapi.yaml", {
allowedRootDirectory: "./configs",
});

ValidateOpenApiOptions​

OpciónTipoValor predeterminadoDescripción
inputKind"content" | "file""content"Cómo interpretar input.
baseFilePathstring—Ruta base para el contexto de resolución de referencias.
allowedRootDirectorystring—Directorio raíz para archivos de entrada. Obligatorio cuando inputKind es "file".
timeoutMsnumber15000Plazo máximo de la operación, en milisegundos.
maxInputBytesnumber5242880 (5 MB)Tamaño máximo de la entrada sin procesar, en bytes.
maxDocumentNodesnumber100000Número máximo de nodos del documento analizado, como protección frente a DoS.
maxDocumentDepthnumber100Profundidad máxima de anidamiento, como protección frente a DoS.
maxValidationErrorsnumber50Número máximo de errores incluidos en el mensaje.
maxErrorMessageLengthnumber1000Número máximo de caracteres por error de validación.
signalAbortSignal—Señal de cancelación opcional.

OpenApiValidationError​

Error estructurado que se lanza cuando falla la validación. Adapta los errores en el límite de la aplicación antes de devolverlos al cliente: los mensajes y las causas pueden contener rutas locales o detalles del documento.

class OpenApiValidationError extends Error {
readonly code: string;
readonly cause?: unknown;
constructor(code: string, message: string, cause?: unknown);
}
PropiedadTipoDescripción
codestringCódigo de error interpretable por programas; consulta la tabla siguiente.
messagestringDetalle legible para el usuario.
causeunknownError subyacente opcional.

Códigos de error​

CódigoSignificado
INVALID_OPTIONSe proporcionó un valor de opción no válido.
INPUT_TOO_LARGEEl contenido supera maxInputBytes.
INPUT_FILE_TOO_LARGEEl archivo de entrada supera el límite de tamaño.
FILE_INPUT_FORBIDDENSe utilizó una entrada de archivo sin allowedRootDirectory.
PATH_OUTSIDE_ROOTLa ruta resuelta queda fuera de allowedRootDirectory.
PARSE_ERRORNo se pudo analizar el contenido JSON/YAML.
INVALID_DOCUMENT_SHAPEEl documento no es un objeto JSON.
UNSUPPORTED_VERSIONEl documento no declara una versión OpenAPI/Swagger admitida; solo se aceptan las versiones principales 2 y 3.
DOCUMENT_TOO_DEEPLa profundidad supera maxDocumentDepth.
DOCUMENT_TOO_LARGEEl número de nodos supera maxDocumentNodes.
SPEC_VALIDATION_FAILEDLa especificación no supera la validación OpenAPI.
OPERATION_TIMEOUTLa operación superó timeoutMs.
OPERATION_ABORTEDLa operación se canceló mediante signal.
UNKNOWN_ERRORError inesperado.

Utilidades​

detectFormat​

Detecta un ConfigFormat a partir de la extensión de una ruta o URL file://.

function detectFormat(filePath: string): ConfigFormat;
ExtensiónResultado
.json"json"
.jsonc"jsonc"
.yaml, .yml"yaml"
cualquier otra extensiónlanza un error

normalizeFilePath​

Convierte una ruta local o una URL file: en una ruta nativa absoluta. Conserva espacios válidos y nombres de archivo Unicode.

function normalizeFilePath(filePath: string): string;

Una URL file: se decodifica con fileURLToPath; una ruta absoluta se devuelve sin cambios y una relativa se resuelve respecto a process.cwd().


Funciones de aserción​

Se reexportan para usos avanzados y módulos internos. El código de aplicación rara vez las necesita directamente.

assertNonEmptyString​

function assertNonEmptyString(value: unknown, label: string): asserts value is string;

Lanza TypeError si value no es una cadena no vacía.

assertPatchPath​

function assertPatchPath(
path: readonly (string | number)[],
label?: string, // default "path"
): void;

Lanza una excepción si path no es un array no vacío cuyos segmentos son cadenas no vacías o enteros seguros no negativos.

assertPatchOperations​

function assertPatchOperations(ops: JsonPatchOp[]): void;

Valida cada operación: op debe ser "add" | "replace" | "remove", path debe superar assertPatchPath y add/replace deben tener una propiedad propia value.

assertConfigFormat​

function assertConfigFormat(format: ConfigFormat): void;

Lanza una excepción si format no es "json", "jsonc" o "yaml".

getErrorMessage​

function getErrorMessage(error: unknown): string;

Devuelve error.message para instancias de Error; en los demás casos, String(error).

createError​

function createError(message: string, cause: unknown): Error;

Crea un Error y añade una propiedad cause mediante Object.defineProperty, con una alternativa para entornos de ejecución antiguos.


Tipos​

ConfigFormat​

type ConfigFormat = "json" | "jsonc" | "yaml";

JsonPathSegment​

type JsonPathSegment = string | number;

JsonPatchOp​

interface JsonPatchOp {
op: "add" | "replace" | "remove";
path: JsonPathSegment[];
/** Required for "add" and "replace". */
value?: unknown;
}
precaución

Solo se admiten "add", "replace" y "remove". "move", "copy" y "test" se excluyen deliberadamente.

PatchConfigOptions​

interface PatchConfigOptions {
format?: ConfigFormat;
strict?: boolean;
lock?: boolean;
lockTimeoutMs?: number;
lockRetryDelayMs?: number;
lockStaleThresholdMs?: number;
/** Whether stale locks can be automatically reclaimed. Defaults to false. */
allowStaleRecovery?: boolean;
}

FileLockOptions​

interface FileLockOptions {
/** Max time to wait for a lock. Defaults to 10 seconds. */
timeoutMs?: number;
/** Initial retry delay. Defaults to 25ms. */
retryDelayMs?: number;
/** Explicit lock age after which recovery is allowed. */
staleThresholdMs?: number;
/** Whether stale locks can be automatically reclaimed. Defaults to false. */
allowStaleRecovery?: boolean;
}

WriteConfigOptions​

interface WriteConfigOptions {
lock?: boolean;
lockTimeoutMs?: number;
lockRetryDelayMs?: number;
lockStaleThresholdMs?: number;
allowStaleRecovery?: boolean;
}

PatchContentOptions​

interface PatchContentOptions {
strict?: boolean;
}

OpenApiInputKind​

type OpenApiInputKind = "content" | "file";

AnyOpenAPIDocument​

Unión de las estructuras OpenAPI/Swagger admitidas que devuelve la validación:

type AnyOpenAPIDocument =
| OpenAPIV2.Document // Swagger 2.0
| OpenAPIV3.Document // OpenAPI 3.0.x
| OpenAPIV3_1.Document // OpenAPI 3.1.x
| OpenAPIV3_2Document; // OpenAPI 3.2 (permissive structural type)

OpenAPIV3_2Document es un tipo estructural permisivo:

interface OpenAPIV3_2Document {
openapi: string;
info: Record<string, unknown>;
paths?: Record<string, unknown>;
[key: string]: unknown;
}

Resumen de exportaciones​

SímboloEntrada principalSubruta del núcleoClase de símbolo
patchContent✓✓función
setContentValue✓✓función
deleteContentValue✓✓función
PatchContentOptions✓✓tipo
assertNonEmptyString✓✓función
assertPatchPath✓✓función
assertPatchOperations✓✓función
assertConfigFormat✓✓función
getErrorMessage✓✓función
createError✓✓función
ConfigFormat✓✓tipo
JsonPatchOp✓✓tipo
JsonPathSegment✓✓tipo
readConfigFile✓—función
writeConfigFile✓—función
WriteConfigOptions✓—tipo
patchConfigFile✓—función
setConfigValue✓—función
deleteConfigValue✓—función
withFileLock✓—función
releaseAllLocalLocks✓—función
PatchConfigOptions✓—tipo
FileLockOptions✓—tipo
detectFormat✓—función
normalizeFilePath✓—función
validateOpenAPISpec✓—función
validateOpenAPIFile✓—función
OpenApiValidationError✓—clase
ValidateOpenApiOptions✓—tipo
OpenApiInputKind✓—tipo
AnyOpenAPIDocument✓—tipo