إنتقل إلى المحتوى الرئيسي

API Reference

Complete reference for @powerduck/conf-patch v0.3.4. Every exported symbol is documented with its exact signature and defaults.

There are two entry points:

  • @powerduck/conf-patch — everything below (core + file layer + OpenAPI validation + utilities).
  • @powerduck/conf-patch/core — only the browser-safe subset: patchContent, setContentValue, deleteContentValue, PatchContentOptions, the assertion helpers, and the types ConfigFormat, JsonPatchOp, JsonPathSegment.

Core layer (browser-safe)​

patchContent​

Applies an array of RFC 6902 patch operations to a configuration string. Pure function — no filesystem access.

function patchContent(
content: string,
ops: JsonPatchOp[],
format: ConfigFormat,
options?: PatchContentOptions,
): string;
ParameterTypeDescription
contentstringThe raw configuration content. Must be a valid format.
opsJsonPatchOp[]Operations to apply in order. An empty array returns content unchanged.
formatConfigFormat"json" | "jsonc" | "yaml".
options.strictbooleanWhen true (default), a failed operation throws. When false, it is skipped with a console.warn.

Returns: the patched configuration content (string).

Throws: TypeError if content is not a string or ops is invalid; an error describing the failing operation when strict is 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​

Sets or creates a single value. Internally calls patchContent with one add operation. add replaces an existing object property or inserts at an array index (RFC 6902).

function setContentValue(
content: string,
path: readonly (string | number)[],
value: unknown,
format: ConfigFormat,
): string;
ParameterTypeDescription
contentstringThe raw configuration content.
pathreadonly (string | number)[]Segment path, e.g. ["server", "port"]. Must be non-empty.
valueunknownThe value to write.
formatConfigFormatThe configuration format.

Returns: the updated content (string).

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

deleteContentValue​

Removes a key or array element. Internally calls patchContent with one remove operation. The path must exist.

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;
}

File layer (Node.js / Electron only)​

readConfigFile​

Reads UTF-8 text from a local file path or file:// URL.

function readConfigFile(filePath: string): Promise<string>;
ParameterTypeDescription
filePathstringAbsolute path, relative path, or file:// URL. Must be non-empty.

Returns: the raw UTF-8 content (Promise<string>).

Throws: an error wrapping the underlying filesystem failure if the file cannot be read.


writeConfigFile​

Writes content to a file using an atomic write (temp file + rename) and, by default, an exclusive file lock. Parent directories are created before locking.

function writeConfigFile(
filePath: string,
content: string,
options?: WriteConfigOptions,
): Promise<void>;
ParameterTypeDescription
filePathstringPath to the configuration file.
contentstringThe content to write. Must be a string.
optionsWriteConfigOptionsSee below.

Throws: TypeError on bad input; wraps filesystem failures on write.

WriteConfigOptions​

OptionTypeDefaultDescription
lockbooleantrueEnable file locking during the write.
lockTimeoutMsnumberwithFileLock default (10s)Max time (ms) to wait to acquire the lock.
lockRetryDelayMsnumberwithFileLock default (25ms)Initial retry delay (ms) before exponential backoff.
lockStaleThresholdMsnumberwithFileLock defaultLock age (ms) after which recovery is allowed.
allowStaleRecoverybooleanfalseWhether stale locks may be automatically reclaimed.
import { writeConfigFile } from "@powerduck/conf-patch";

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

patchConfigFile​

The primary file-layer transaction: read the file inside a lock, apply patchContent, and write back atomically only if the content changed. Format is auto-detected from the extension when options.format is omitted.

function patchConfigFile(
filePath: string,
ops: JsonPatchOp[],
options?: PatchConfigOptions,
): Promise<void>;
ParameterTypeDescription
filePathstringPath to the configuration file. Must be non-empty.
opsJsonPatchOp[]Operations to apply. An empty array returns without reading or writing.
optionsPatchConfigOptionsSee below.

Throws: TypeError if filePath is empty, lock options are invalid, or the format cannot be detected (and no format is given); the operation error when strict is true.

PatchConfigOptions​

OptionTypeDefaultDescription
formatConfigFormatauto-detectedExplicit format. Overrides extension detection.
strictbooleantrueFailed operations throw.
lockbooleantrueEnable file locking.
lockTimeoutMsnumber10sNon-negative. Max wait for the lock.
lockRetryDelayMsnumber25msPositive. Initial retry delay.
lockStaleThresholdMsnumberderivedPositive. Lock age for stale recovery.
allowStaleRecoverybooleanfalseAuto-reclaim stale locks.
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​

Adds or replaces a nested value in a file. Delegates to patchConfigFile with a single add operation.

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

deleteConfigValue​

Removes an existing nested value from a file. Delegates to patchConfigFile with a single remove operation.

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

withFileLock​

Runs an async callback under a process-local queue and an exclusive lock file (<file>.confedit.lock). Locks use ownership tokens; a stale lock is recovered only when allowStaleRecovery is true and the lock exceeds staleThresholdMs. PID checks are intentionally avoided (PIDs can be reused).

function withFileLock<T>(
filePath: string,
callback: () => Promise<T>,
options?: FileLockOptions,
): Promise<T>;
ParameterTypeDescription
filePathstringThe file to lock.
callback() => Promise<T>Work to run while holding the lock.
optionsFileLockOptionsSee below.

Returns: whatever callback returns (Promise<T>). The lock is always released in a finally block, even if the callback throws.

FileLockOptions​

OptionTypeDefaultDescription
timeoutMsnumber10000Max time (ms) to wait for the lock. Must be non-negative.
retryDelayMsnumber25Initial retry delay (ms). Must be positive. Backoff grows by 1.5x, capped at 1000ms.
staleThresholdMsnumbermax(timeoutMs * 2, 60000)Lock age (ms) after which recovery is allowed. Must be positive.
allowStaleRecoverybooleanfalseAuto-reclaim stale locks. Disabled by default for Electron's single main process to avoid preempting live transactions.
import { withFileLock } from "@powerduck/conf-patch";

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

releaseAllLocalLocks​

Unlinks every lock file owned by the current process. Designed for Electron's app.whenReady quit path (e.g. app.on("will-quit", ...)). Failures per lock are swallowed.

function releaseAllLocalLocks(): Promise<void>;

OpenAPI validation​

validateOpenAPISpec​

Validates raw OpenAPI/Swagger content (JSON or YAML). Input is treated as content by default; file-path interpretation only happens when inputKind: "file". Validation is delegated to @powerduck/openapi-parser; this function adds secure input handling.

function validateOpenAPISpec(
input: string,
options?: ValidateOpenApiOptions,
): Promise<AnyOpenAPIDocument>;
ParameterTypeDescription
inputstringRaw spec content, or a file path when inputKind: "file".
optionsValidateOpenApiOptionsSee below.

Returns: the validated document on success (Promise<AnyOpenAPIDocument>).

Throws: OpenApiValidationError on any failure.


validateOpenAPIFile​

Convenience wrapper that calls validateOpenAPISpec with inputKind: "file" and baseFilePath set to the given path. Requires allowedRootDirectory.

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

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

ValidateOpenApiOptions​

OptionTypeDefaultDescription
inputKind"content" | "file""content"How to interpret input.
baseFilePathstring—Base path for reference-resolution context.
allowedRootDirectorystring—Root directory for file input. Required when inputKind is "file".
timeoutMsnumber15000Operation deadline (ms).
maxInputBytesnumber5242880 (5 MB)Max raw input size in bytes.
maxDocumentNodesnumber100000Max nodes in the parsed document (DoS guard).
maxDocumentDepthnumber100Max nesting depth (DoS guard).
maxValidationErrorsnumber50Max errors included in the error message.
maxErrorMessageLengthnumber1000Max characters per validation error.
signalAbortSignal—Optional cancellation signal.

OpenApiValidationError​

Structured error thrown on validation failure. Safe to expose across an application boundary.

class OpenApiValidationError extends Error {
readonly code: string;
readonly cause?: unknown;
constructor(code: string, message: string, cause?: unknown);
}
PropertyTypeDescription
codestringMachine-readable error code (see table below).
messagestringHuman-readable detail.
causeunknownOptional underlying error.

Error codes​

CodeMeaning
INVALID_OPTIONInvalid option value provided.
INPUT_TOO_LARGERaw content exceeds maxInputBytes.
INPUT_FILE_TOO_LARGEInput file exceeds the size limit.
FILE_INPUT_FORBIDDENFile input used without allowedRootDirectory.
PATH_OUTSIDE_ROOTFile path resolves outside allowedRootDirectory.
PARSE_ERRORFailed to parse JSON/YAML content.
INVALID_DOCUMENT_SHAPEDocument is not a JSON object.
UNSUPPORTED_VERSIONDocument does not declare a supported OpenAPI/Swagger version (only major 2 and 3 are accepted).
DOCUMENT_TOO_DEEPNesting depth exceeds maxDocumentDepth.
DOCUMENT_TOO_LARGENode count exceeds maxDocumentNodes.
SPEC_VALIDATION_FAILEDThe spec failed OpenAPI validation.
OPERATION_TIMEOUTOperation exceeded timeoutMs.
OPERATION_ABORTEDOperation was aborted via signal.
UNKNOWN_ERRORUnexpected error.

Utilities​

detectFormat​

Detects a ConfigFormat from a file path or file:// URL based on its extension.

function detectFormat(filePath: string): ConfigFormat;
ExtensionResult
.json"json"
.jsonc"jsonc"
.yaml, .yml"yaml"
anything elsethrows an error

normalizeFilePath​

Converts a local path or file: URL into an absolute native path. Preserves valid whitespace and Unicode file names.

function normalizeFilePath(filePath: string): string;

A file: URL is decoded with fileURLToPath; an already-absolute path is returned as-is; a relative path is resolved against process.cwd().


Assertion helpers​

These are re-exported for advanced use and by internal modules. They are rarely needed directly by application code.

assertNonEmptyString​

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

Throws TypeError unless value is a non-empty string.

assertPatchPath​

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

Throws unless path is a non-empty array whose segments are non-empty strings or safe non-negative integers.

assertPatchOperations​

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

Validates each operation: op must be "add" | "replace" | "remove", path must pass assertPatchPath, and add/replace must carry a value own-property.

assertConfigFormat​

function assertConfigFormat(format: ConfigFormat): void;

Throws unless format is "json", "jsonc", or "yaml".

getErrorMessage​

function getErrorMessage(error: unknown): string;

Returns error.message for Error instances, otherwise String(error).

createError​

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

Creates an Error and attaches a cause property (using Object.defineProperty, with a fallback for older runtimes).


Types​

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;
}
حذر

Only "add", "replace", and "remove" are supported. "move", "copy", and "test" are intentionally excluded.

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​

A union of supported OpenAPI/Swagger document shapes returned by validation:

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 is a permissible structural type:

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

Export summary​

SymbolMain entryCore subpathKind
patchContent✓✓function
setContentValue✓✓function
deleteContentValue✓✓function
PatchContentOptions✓✓type
assertNonEmptyString✓✓function
assertPatchPath✓✓function
assertPatchOperations✓✓function
assertConfigFormat✓✓function
getErrorMessage✓✓function
createError✓✓function
ConfigFormat✓✓type
JsonPatchOp✓✓type
JsonPathSegment✓✓type
readConfigFile✓—function
writeConfigFile✓—function
WriteConfigOptions✓—type
patchConfigFile✓—function
setConfigValue✓—function
deleteConfigValue✓—function
withFileLock✓—function
releaseAllLocalLocks✓—function
PatchConfigOptions✓—type
FileLockOptions✓—type
detectFormat✓—function
normalizeFilePath✓—function
validateOpenAPISpec✓—function
validateOpenAPIFile✓—function
OpenApiValidationError✓—class
ValidateOpenApiOptions✓—type
OpenApiInputKind✓—type
AnyOpenAPIDocument✓—type