diff --git a/src/sync/apply.ts b/src/sync/apply.ts index 6c5cd28..698f694 100644 --- a/src/sync/apply.ts +++ b/src/sync/apply.ts @@ -1,7 +1,14 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; -import { deepMerge, parseJsonc, pathExists, stripOverrides, writeJsonFile } from './config.js'; +import { + deepMerge, + hasOwn, + parseJsonc, + pathExists, + stripOverrides, + writeJsonFile, +} from './config.js'; import { extractMcpSecrets, hasOverrides, @@ -283,7 +290,7 @@ function isDeepEqual(left: unknown, right: unknown): boolean { const rightKeys = Object.keys(right as Record); if (leftKeys.length !== rightKeys.length) return false; for (const key of leftKeys) { - if (!Object.hasOwn(right, key)) return false; + if (!hasOwn(right as Record, key)) return false; if ( !isDeepEqual( (left as Record)[key], diff --git a/src/sync/config.ts b/src/sync/config.ts index 4ab9b0f..7cdeb11 100644 --- a/src/sync/config.ts +++ b/src/sync/config.ts @@ -178,11 +178,15 @@ export async function writeJsonFile( } } -function isPlainObject(value: unknown): value is Record { +export function isPlainObject(value: unknown): value is Record { if (!value || typeof value !== 'object') return false; return Object.getPrototypeOf(value) === Object.prototype; } +export function hasOwn(target: Record, key: string): boolean { + return Object.hasOwn(target, key); +} + function stripJsonComments(input: string): string { let output = ''; let inString = false; diff --git a/src/sync/mcp-secrets.ts b/src/sync/mcp-secrets.ts index 0c15b25..72dad4a 100644 --- a/src/sync/mcp-secrets.ts +++ b/src/sync/mcp-secrets.ts @@ -1,4 +1,4 @@ -import { deepMerge } from './config.js'; +import { deepMerge, hasOwn, isPlainObject } from './config.js'; export interface McpSecretExtraction { sanitizedConfig: Record; @@ -106,15 +106,7 @@ function getPlainObject(value: unknown): Record | null { return isPlainObject(value) ? (value as Record) : null; } -function isPlainObject(value: unknown): value is Record { - if (!value || typeof value !== 'object') return false; - return Object.getPrototypeOf(value) === Object.prototype; -} - function cloneConfig(config: Record): Record { - if (typeof structuredClone === 'function') { - return structuredClone(config); - } return JSON.parse(JSON.stringify(config)) as Record; } @@ -136,7 +128,7 @@ export function stripOverrideKeys( const result: Record = { ...base }; for (const [key, removeValue] of Object.entries(toRemove)) { - if (!Object.hasOwn(result, key)) continue; + if (!hasOwn(result, key)) continue; const currentValue = result[key]; if (isPlainObject(removeValue) && isPlainObject(currentValue)) { const stripped = stripOverrideKeys(