diff --git a/extensions/oc-path/src/cli.ts b/extensions/oc-path/src/cli.ts index c0beb9f4560..76efefdcd14 100644 --- a/extensions/oc-path/src/cli.ts +++ b/extensions/oc-path/src/cli.ts @@ -63,13 +63,13 @@ const defaultRuntime: OutputRuntimeEnv = { // Defense-in-depth: replace the redaction sentinel with `[REDACTED]` // before writing, even if upstream emits it. export function scrubSentinel(s: string): string { - if (!s.includes(REDACTED_SENTINEL)) return s; + if (!s.includes(REDACTED_SENTINEL)) {return s;} return s.split(REDACTED_SENTINEL).join(SCRUB_PLACEHOLDER); } function detectMode(options: PathCommandOptions): OutputMode { - if (options.json === true) return "json"; - if (options.human === true) return "human"; + if (options.json === true) {return "json";} + if (options.human === true) {return "human";} return process.stdout.isTTY ? "human" : "json"; } @@ -157,8 +157,8 @@ function catchSentinel( async function loadAst(absPath: string, fileName: string): Promise { const raw = await fs.readFile(absPath, "utf-8"); const kind = inferKind(fileName); - if (kind === "jsonc") return parseJsonc(raw).ast; - if (kind === "jsonl") return parseJsonl(raw).ast; + if (kind === "jsonc") {return parseJsonc(raw).ast;} + if (kind === "jsonl") {return parseJsonl(raw).ast;} return parseMd(raw).ast; } @@ -176,7 +176,7 @@ function emitForKind(ast: OcAst, fileName?: string): string { } function resolveFsPath(path: OcPath, options: PathCommandOptions): string { - if (options.file !== undefined) return resolvePath(options.file); + if (options.file !== undefined) {return resolvePath(options.file);} return resolvePath(options.cwd ?? process.cwd(), path.file); } @@ -184,7 +184,7 @@ function formatMatchHuman(match: OcMatch): string { if (match.kind === "leaf") { return `leaf @ L${match.line}: ${JSON.stringify(match.valueText)} (${match.leafType})`; } - if (match.kind === "node") return `node @ L${match.line} [${match.descriptor}]`; + if (match.kind === "node") {return `node @ L${match.line} [${match.descriptor}]`;} if (match.kind === "insertion-point") { return `insertion-point @ L${match.line} [${match.container}]`; } @@ -199,9 +199,9 @@ export async function pathResolveCommand( runtime: OutputRuntimeEnv, ): Promise { const mode = detectMode(options); - if (!requireArg(pathStr, "resolve: missing argument", runtime, mode)) return; + if (!requireArg(pathStr, "resolve: missing argument", runtime, mode)) {return;} const ocPath = tryParse(pathStr, runtime, mode); - if (ocPath === null) return; + if (ocPath === null) {return;} const ast = await loadAst(resolveFsPath(ocPath, options), ocPath.file); let match: OcMatch | null; try { @@ -230,15 +230,15 @@ export async function pathSetCommand( runtime: OutputRuntimeEnv, ): Promise { const mode = detectMode(options); - if (!requireArg(pathStr, "set: requires ", runtime, mode)) return; - if (!requireArg(value, "set: requires ", runtime, mode)) return; + if (!requireArg(pathStr, "set: requires ", runtime, mode)) {return;} + if (!requireArg(value, "set: requires ", runtime, mode)) {return;} const ocPath = tryParse(pathStr, runtime, mode); - if (ocPath === null) return; + if (ocPath === null) {return;} const fsPath = resolveFsPath(ocPath, options); const ast = await loadAst(fsPath, ocPath.file); const result = catchSentinel("set", runtime, mode, () => setOcPath(ast, ocPath, value)); - if (result === null) return; + if (result === null) {return;} if (!result.ok) { const detail = "detail" in result ? result.detail : undefined; emit( @@ -254,7 +254,7 @@ export async function pathSetCommand( const newBytes = catchSentinel("emit", runtime, mode, () => emitForKind(result.ast, ocPath.file), ); - if (newBytes === null) return; + if (newBytes === null) {return;} if (options.dryRun === true) { emit( @@ -280,9 +280,9 @@ export async function pathFindCommand( runtime: OutputRuntimeEnv, ): Promise { const mode = detectMode(options); - if (!requireArg(patternStr, "find: missing argument", runtime, mode)) return; + if (!requireArg(patternStr, "find: missing argument", runtime, mode)) {return;} const pattern = tryParse(patternStr, runtime, mode); - if (pattern === null) return; + if (pattern === null) {return;} // File-slot wildcards would silently ENOENT during readFile; reject. if (/[*?]/.test(pattern.file)) { emitError( @@ -306,7 +306,7 @@ export async function pathFindCommand( matches: matches.map((m) => ({ path: formatOcPath(m.path), match: m.match })), }, () => { - if (matches.length === 0) return `0 matches for ${patternStr}`; + if (matches.length === 0) {return `0 matches for ${patternStr}`;} const plural = matches.length === 1 ? "" : "es"; const lines = [`${matches.length} match${plural} for ${patternStr}:`]; for (const m of matches) { @@ -315,7 +315,7 @@ export async function pathFindCommand( return lines.join("\n"); }, ); - if (matches.length === 0) runtime.exit(1); + if (matches.length === 0) {runtime.exit(1);} } export function pathValidateCommand( @@ -324,7 +324,7 @@ export function pathValidateCommand( runtime: OutputRuntimeEnv, ): void { const mode = detectMode(options); - if (!requireArg(pathStr, "validate: missing argument", runtime, mode)) return; + if (!requireArg(pathStr, "validate: missing argument", runtime, mode)) {return;} try { const ocPath = parseOcPath(pathStr); emit( @@ -344,10 +344,10 @@ export function pathValidateCommand( }, () => { const lines = [`valid: ${pathStr}`, ` file: ${ocPath.file}`]; - if (ocPath.section !== undefined) lines.push(` section: ${ocPath.section}`); - if (ocPath.item !== undefined) lines.push(` item: ${ocPath.item}`); - if (ocPath.field !== undefined) lines.push(` field: ${ocPath.field}`); - if (ocPath.session !== undefined) lines.push(` session: ${ocPath.session}`); + if (ocPath.section !== undefined) {lines.push(` section: ${ocPath.section}`);} + if (ocPath.item !== undefined) {lines.push(` item: ${ocPath.item}`);} + if (ocPath.field !== undefined) {lines.push(` field: ${ocPath.field}`);} + if (ocPath.session !== undefined) {lines.push(` session: ${ocPath.session}`);} return lines.join("\n"); }, ); @@ -372,7 +372,7 @@ export async function pathEmitCommand( runtime: OutputRuntimeEnv, ): Promise { const mode = detectMode(options); - if (!requireArg(fileArg, "emit: missing argument", runtime, mode)) return; + if (!requireArg(fileArg, "emit: missing argument", runtime, mode)) {return;} const fsPath = options.file !== undefined ? resolvePath(options.file) @@ -380,7 +380,7 @@ export async function pathEmitCommand( const fileName = fsPath.split(/[\\/]/).pop() ?? fileArg; const ast = await loadAst(fsPath, fileName); const bytes = catchSentinel("emit", runtime, mode, () => emitForKind(ast, fileName)); - if (bytes === null) return; + if (bytes === null) {return;} if (mode === "json") { runtime.writeStdout(scrubSentinel(JSON.stringify({ ok: true, kind: ast.kind, bytes }))); return; diff --git a/extensions/oc-path/src/oc-path/edit.ts b/extensions/oc-path/src/oc-path/edit.ts index 00d9690769f..c1cd01db587 100644 --- a/extensions/oc-path/src/oc-path/edit.ts +++ b/extensions/oc-path/src/oc-path/edit.ts @@ -26,11 +26,11 @@ export function setMdOcPath(ast: MdAst, path: OcPath, newValue: string): MdEditR guardSentinel(newValue, formatOcPath(path)); if (path.section === "[frontmatter]") { const key = path.item ?? path.field; - if (key === undefined) return { ok: false, reason: "unresolved" }; + if (key === undefined) {return { ok: false, reason: "unresolved" };} const idx = ast.frontmatter.findIndex((e) => e.key === key); - if (idx === -1) return { ok: false, reason: "unresolved" }; + if (idx === -1) {return { ok: false, reason: "unresolved" };} const existing = ast.frontmatter[idx]; - if (existing === undefined) return { ok: false, reason: "unresolved" }; + if (existing === undefined) {return { ok: false, reason: "unresolved" };} const newEntry: FrontmatterEntry = { ...existing, value: newValue }; const newFm = ast.frontmatter.slice(); newFm[idx] = newEntry; @@ -43,16 +43,16 @@ export function setMdOcPath(ast: MdAst, path: OcPath, newValue: string): MdEditR const sectionSlug = path.section.toLowerCase(); const blockIdx = ast.blocks.findIndex((b) => b.slug === sectionSlug); - if (blockIdx === -1) return { ok: false, reason: "unresolved" }; + if (blockIdx === -1) {return { ok: false, reason: "unresolved" };} const block = ast.blocks[blockIdx]; - if (block === undefined) return { ok: false, reason: "unresolved" }; + if (block === undefined) {return { ok: false, reason: "unresolved" };} const itemSlug = path.item.toLowerCase(); const itemIdx = block.items.findIndex((i) => i.slug === itemSlug); - if (itemIdx === -1) return { ok: false, reason: "unresolved" }; + if (itemIdx === -1) {return { ok: false, reason: "unresolved" };} const item = block.items[itemIdx]; - if (item === undefined) return { ok: false, reason: "unresolved" }; - if (item.kv === undefined) return { ok: false, reason: "no-item-kv" }; + if (item === undefined) {return { ok: false, reason: "unresolved" };} + if (item.kv === undefined) {return { ok: false, reason: "no-item-kv" };} if (item.kv.key.toLowerCase() !== path.field.toLowerCase()) { return { ok: false, reason: "unresolved" }; } @@ -78,9 +78,9 @@ function rebuildBlockBody(block: AstBlock, newItems: readonly AstItem[]): string for (let i = 0; i < newItems.length; i++) { const newItem = newItems[i]; const oldItem = block.items[i]; - if (newItem === undefined || oldItem === undefined) continue; - if (newItem.kv === undefined || oldItem.kv === undefined) continue; - if (newItem.kv.value === oldItem.kv.value) continue; + if (newItem === undefined || oldItem === undefined) {continue;} + if (newItem.kv === undefined || oldItem.kv === undefined) {continue;} + if (newItem.kv.value === oldItem.kv.value) {continue;} const re = new RegExp(`^(\\s*-\\s*${escapeRegex(oldItem.kv.key)}\\s*:\\s*).*$`, "m"); body = body.replace(re, `$1${newItem.kv.value}`); } @@ -101,19 +101,19 @@ function finalize(ast: MdAst): MdEditResult { parts.push("---"); } if (ast.preamble.length > 0) { - if (parts.length > 0) parts.push(""); + if (parts.length > 0) {parts.push("");} parts.push(ast.preamble); } for (const block of ast.blocks) { - if (parts.length > 0) parts.push(""); + if (parts.length > 0) {parts.push("");} parts.push(`## ${block.heading}`); - if (block.bodyText.length > 0) parts.push(block.bodyText); + if (block.bodyText.length > 0) {parts.push(block.bodyText);} } return { ok: true, ast: { ...ast, raw: parts.join("\n") } }; } function formatFrontmatterValue(value: string): string { - if (value.length === 0) return '""'; - if (/[:#&*?|<>=!%@`,[\]{}\r\n]/.test(value)) return JSON.stringify(value); + if (value.length === 0) {return '""';} + if (/[:#&*?|<>=!%@`,[\]{}\r\n]/.test(value)) {return JSON.stringify(value);} return value; } diff --git a/extensions/oc-path/src/oc-path/find.ts b/extensions/oc-path/src/oc-path/find.ts index e92abdba9dd..6d9d864c5ec 100644 --- a/extensions/oc-path/src/oc-path/find.ts +++ b/extensions/oc-path/src/oc-path/find.ts @@ -129,9 +129,9 @@ function repackSlotSubs(pattern: OcPath, slotSubs: readonly SlotSub[]): OcPath { const itemSubs: string[] = []; const fieldSubs: string[] = []; for (const s of slotSubs) { - if (s.slot === "section") sectionSubs.push(s.value); - else if (s.slot === "item") itemSubs.push(s.value); - else fieldSubs.push(s.value); + if (s.slot === "section") {sectionSubs.push(s.value);} + else if (s.slot === "item") {itemSubs.push(s.value);} + else {fieldSubs.push(s.value);} } return { file: pattern.file, @@ -176,7 +176,7 @@ function dispatchSeg( if (isUnionSeg(cur.value)) { const alts = parseUnionSeg(cur.value); - if (alts === null) return; + if (alts === null) {return;} for (const alt of alts) { const altSubs = subs.slice(); altSubs[i] = { slot: cur.slot, value: alt }; @@ -187,7 +187,7 @@ function dispatchSeg( if (isPredicateSeg(cur.value)) { const pred = parsePredicateSeg(cur.value); - if (pred === null) return; + if (pred === null) {return;} for (const m of ops.predicate(node, pred)) { ops.walk(m.child, subs, i + 1, [...walked, { slot: cur.slot, value: m.keySub }], onMatch); } @@ -197,7 +197,7 @@ function dispatchSeg( if (cur.value === WILDCARD_RECURSIVE) { // `**` — descend with `**` consumed (i+1) AND retained (i) so // deeper structures still match. Emit if no subs remain. - if (i + 1 >= subs.length) onMatch(walked); + if (i + 1 >= subs.length) {onMatch(walked);} for (const m of ops.enumerate(node)) { const nextWalked: readonly SlotSub[] = [...walked, { slot: cur.slot, value: m.keySub }]; ops.walk(m.child, subs, i + 1, nextWalked, onMatch); @@ -215,13 +215,13 @@ function dispatchSeg( if (isPositionalSeg(cur.value)) { const m = ops.positional(node, cur.value); - if (m === null) return; + if (m === null) {return;} ops.walk(m.child, subs, i + 1, [...walked, { slot: cur.slot, value: m.keySub }], onMatch); return; } const m = ops.lookup(node, cur.value); - if (m === null) return; + if (m === null) {return;} ops.walk(m.child, subs, i + 1, [...walked, { slot: cur.slot, value: m.keySub }], onMatch); } @@ -245,7 +245,7 @@ function walkJsonc( const jsoncOps: WalkOps = { *enumerate(node) { if (node.kind === "object") { - for (const e of node.entries) yield { keySub: quoteSeg(e.key), child: e.value }; + for (const e of node.entries) {yield { keySub: quoteSeg(e.key), child: e.value };} } else if (node.kind === "array") { for (let idx = 0; idx < node.items.length; idx++) { yield { keySub: String(idx), child: node.items[idx] }; @@ -262,14 +262,14 @@ const jsoncOps: WalkOps = { } if (node.kind === "array") { const idx = Number(key); - if (!Number.isInteger(idx) || idx < 0 || idx >= node.items.length) return null; + if (!Number.isInteger(idx) || idx < 0 || idx >= node.items.length) {return null;} return { keySub: key, child: node.items[idx] }; } return null; }, positional(node, seg) { const concrete = positionalForJsoncNode(node, seg); - if (concrete === null) return null; + if (concrete === null) {return null;} return jsoncOps.lookup(node, concrete); }, *predicate(node, pred) { @@ -325,12 +325,12 @@ function walkJsonl( const jsonlOps: WalkOps = { *enumerate(ast) { for (const l of ast.lines) { - if (l.kind === "value") yield { keySub: `L${l.line}`, child: lineHolder(ast, l) }; + if (l.kind === "value") {yield { keySub: `L${l.line}`, child: lineHolder(ast, l) };} } }, lookup(ast, key) { const line = pickLine(ast, key); - if (line === null) return null; + if (line === null) {return null;} const concreteAddr = line.kind === "value" ? `L${line.line}` : key; return { keySub: concreteAddr, child: lineHolder(ast, line) }; }, @@ -339,7 +339,7 @@ const jsonlOps: WalkOps = { }, *predicate(ast, pred) { for (const l of ast.lines) { - if (l.kind !== "value") continue; + if (l.kind !== "value") {continue;} const actual = topLevelLeafText(l.value, pred.key); if (evaluatePredicate(actual, pred)) { yield { keySub: `L${l.line}`, child: lineHolder(ast, l) }; @@ -359,7 +359,7 @@ const jsonlOps: WalkOps = { onMatch(walked); return; } - if (line.kind !== "value") return; + if (line.kind !== "value") {return;} walkJsonc(line.value, subs, i, walked, onMatch); }, }; @@ -382,12 +382,12 @@ function unwrapHolder(holder: JsonlAst): JsonlLine | null { } function topLevelLeafText(value: JsoncValue, key: string): string | null { - if (value.kind !== "object") return null; + if (value.kind !== "object") {return null;} const entry = value.entries.find((e) => e.key === key); - if (entry === undefined) return null; + if (entry === undefined) {return null;} const v = entry.value; - if (v.kind === "string") return v.value; - if (v.kind === "number" || v.kind === "boolean") return String(v.value); + if (v.kind === "string") {return v.value;} + if (v.kind === "number" || v.kind === "boolean") {return String(v.value);} return null; } @@ -395,15 +395,15 @@ function pickLine(ast: JsonlAst, addr: string): JsonlLine | null { if (addr === "$last") { for (let i = ast.lines.length - 1; i >= 0; i--) { const l = ast.lines[i]; - if (l !== undefined && l.kind === "value") return l; + if (l !== undefined && l.kind === "value") {return l;} } return null; } const m = /^L(\d+)$/.exec(addr); - if (m === null || m[1] === undefined) return null; + if (m === null || m[1] === undefined) {return null;} const target = Number(m[1]); for (const l of ast.lines) { - if (l.line === target) return l; + if (l.line === target) {return l;} } return null; } @@ -449,7 +449,7 @@ function walkMd( } const fmKey = isQuotedSeg(next.value) ? unquoteSeg(next.value) : next.value; const entry = level.ast.frontmatter.find((e) => e.key === fmKey); - if (entry === undefined) return; + if (entry === undefined) {return;} onMatch([ { slot: cur.slot, value: cur.value }, { slot: next.slot, value: next.value }, @@ -472,34 +472,34 @@ function walkMdItemField( walked: readonly SlotSub[], onMatch: OnMatch, ): void { - if (item.kv === undefined) return; + if (item.kv === undefined) {return;} const key = item.kv.key; const emit = (value: string): void => { onMatch([...walked, { slot: cur.slot, value }]); }; if (isUnionSeg(cur.value)) { const alts = parseUnionSeg(cur.value); - if (alts === null) return; + if (alts === null) {return;} for (const alt of alts) { - if (alt.toLowerCase() === key.toLowerCase()) emit(key); + if (alt.toLowerCase() === key.toLowerCase()) {emit(key);} } return; } if (isPredicateSeg(cur.value)) { const pred = parsePredicateSeg(cur.value); - if (pred !== null && mdItemMatchesPredicate(item, pred)) emit(key); + if (pred !== null && mdItemMatchesPredicate(item, pred)) {emit(key);} return; } if (cur.value === WILDCARD_SINGLE || cur.value === WILDCARD_RECURSIVE) { emit(key); return; } - if (key.toLowerCase() === cur.value.toLowerCase()) emit(cur.value); + if (key.toLowerCase() === cur.value.toLowerCase()) {emit(cur.value);} } function blockSlugCounts(items: readonly MdItem[]): Map { const counts = new Map(); - for (const item of items) counts.set(item.slug, (counts.get(item.slug) ?? 0) + 1); + for (const item of items) {counts.set(item.slug, (counts.get(item.slug) ?? 0) + 1);} return counts; } @@ -534,7 +534,7 @@ const mdOps: WalkOps = { // Ordinal `#N` short-circuits slug lookup. if (isOrdinalSeg(key)) { const n = parseOrdinalSeg(key); - if (n === null || n < 0 || n >= level.block.items.length) return null; + if (n === null || n < 0 || n >= level.block.items.length) {return null;} return { keySub: key, child: { kind: "item", item: level.block.items[n], ast: level.ast } }; } const target = key.toLowerCase(); @@ -544,12 +544,12 @@ const mdOps: WalkOps = { return null; }, positional(level, seg) { - if (level.kind !== "block") return null; + if (level.kind !== "block") {return null;} const concrete = resolvePositionalSeg(seg, { indexable: true, size: level.block.items.length, }); - if (concrete === null) return null; + if (concrete === null) {return null;} // Preserve the positional token in keySub so the resolver // re-evaluates positionally on round-trip. const item = level.block.items[Number(concrete)]; @@ -579,14 +579,14 @@ const mdOps: WalkOps = { }; function mdItemMatchesPredicate(item: MdItem, pred: PredicateSpec): boolean { - if (item.kv === undefined) return false; - if (item.kv.key.toLowerCase() !== pred.key.toLowerCase()) return false; + if (item.kv === undefined) {return false;} + if (item.kv.key.toLowerCase() !== pred.key.toLowerCase()) {return false;} return evaluatePredicate(item.kv.value, pred); } function mdBlockHasMatchingItem(block: MdBlock, pred: PredicateSpec): boolean { for (const item of block.items) { - if (mdItemMatchesPredicate(item, pred)) return true; + if (mdItemMatchesPredicate(item, pred)) {return true;} } return false; } @@ -596,12 +596,12 @@ function jsoncChildMatchesPredicate(node: JsoncValue, pred: PredicateSpec): bool } function jsoncChildFieldText(node: JsoncValue, key: string): string | null { - if (node.kind !== "object") return null; + if (node.kind !== "object") {return null;} const e = node.entries.find((entry) => entry.key === key); - if (e === undefined) return null; + if (e === undefined) {return null;} const v = e.value; - if (v.kind === "string") return v.value; - if (v.kind === "number" || v.kind === "boolean") return String(v.value); - if (v.kind === "null") return "null"; + if (v.kind === "string") {return v.value;} + if (v.kind === "number" || v.kind === "boolean") {return String(v.value);} + if (v.kind === "null") {return "null";} return null; } diff --git a/extensions/oc-path/src/oc-path/jsonc/emit.ts b/extensions/oc-path/src/oc-path/jsonc/emit.ts index 1c4c614a981..867b4875161 100644 --- a/extensions/oc-path/src/oc-path/jsonc/emit.ts +++ b/extensions/oc-path/src/oc-path/jsonc/emit.ts @@ -33,7 +33,7 @@ export function emitJsonc(ast: JsoncAst, opts: JsoncEmitOptions = {}): string { } // Render mode loses comments; walks leaves for caller-injected sentinel. - if (ast.root === null) return ""; + if (ast.root === null) {return "";} return renderValue(ast.root, guardPath, []); } diff --git a/extensions/oc-path/src/oc-path/jsonc/resolve.ts b/extensions/oc-path/src/oc-path/jsonc/resolve.ts index c941c10323b..5069d1de0a1 100644 --- a/extensions/oc-path/src/oc-path/jsonc/resolve.ts +++ b/extensions/oc-path/src/oc-path/jsonc/resolve.ts @@ -26,11 +26,11 @@ export type JsoncOcPathMatch = }; export function resolveJsoncOcPath(ast: JsoncAst, path: OcPath): JsoncOcPathMatch | null { - if (ast.root === null) return null; + if (ast.root === null) {return null;} const segments: string[] = []; const collect = (slot: string | undefined): void => { - if (slot === undefined) return; + if (slot === undefined) {return;} for (const s of splitRespectingBrackets(slot, ".")) { segments.push(isQuotedSeg(s) ? unquoteSeg(s) : s); } @@ -39,35 +39,35 @@ export function resolveJsoncOcPath(ast: JsoncAst, path: OcPath): JsoncOcPathMatc collect(path.item); collect(path.field); - if (segments.length === 0) return { kind: "root", node: ast }; + if (segments.length === 0) {return { kind: "root", node: ast };} let current: JsoncValue = ast.root; let lastEntry: JsoncEntry | null = null; const walked: string[] = []; for (let seg of segments) { - if (seg.length === 0) return null; + if (seg.length === 0) {return null;} // `-N` on an indexable container is positional; on a keyed // container it falls through to literal-key lookup (e.g. Telegram // supergroup IDs — openclaw#59934). if (isPositionalSeg(seg)) { const concrete = positionalForJsonc(current, seg); - if (concrete !== null) seg = concrete; + if (concrete !== null) {seg = concrete;} } walked.push(seg); if (current.kind === "object") { const entry = current.entries.find((e) => e.key === seg); - if (entry === undefined) return null; + if (entry === undefined) {return null;} lastEntry = entry; current = entry.value; continue; } if (current.kind === "array") { const idx = Number(seg); - if (!Number.isInteger(idx) || idx < 0 || idx >= current.items.length) return null; + if (!Number.isInteger(idx) || idx < 0 || idx >= current.items.length) {return null;} lastEntry = null; const item = current.items[idx]; - if (item === undefined) return null; + if (item === undefined) {return null;} current = item; continue; } diff --git a/extensions/oc-path/src/oc-path/jsonl/edit.ts b/extensions/oc-path/src/oc-path/jsonl/edit.ts index 59e656e4312..397f3d30f22 100644 --- a/extensions/oc-path/src/oc-path/jsonl/edit.ts +++ b/extensions/oc-path/src/oc-path/jsonl/edit.ts @@ -83,8 +83,8 @@ function replaceAt( newValue: JsoncValue, ): JsoncValue | null { const seg = segments[i]; - if (seg === undefined) return newValue; - if (seg.length === 0) return null; + if (seg === undefined) {return newValue;} + if (seg.length === 0) {return null;} if (current.kind === "object") { // Positional tokens resolve against the entries' ordered key list; @@ -96,16 +96,16 @@ function replaceAt( size: current.entries.length, keys: current.entries.map((e) => e.key), }); - if (resolved === null) return null; + if (resolved === null) {return null;} segNorm = resolved; } const lookupKey = isQuotedSeg(segNorm) ? unquoteSeg(segNorm) : segNorm; const idx = current.entries.findIndex((e) => e.key === lookupKey); - if (idx === -1) return null; + if (idx === -1) {return null;} const child = current.entries[idx]; - if (child === undefined) return null; + if (child === undefined) {return null;} const replacedChild = replaceAt(child.value, segments, i + 1, newValue); - if (replacedChild === null) return null; + if (replacedChild === null) {return null;} const newEntry: JsoncEntry = { ...child, value: replacedChild }; const newEntries = current.entries.slice(); newEntries[idx] = newEntry; @@ -123,15 +123,15 @@ function replaceAt( indexable: true, size: current.items.length, }); - if (resolved === null) return null; + if (resolved === null) {return null;} segNorm = resolved; } const idx = Number(segNorm); - if (!Number.isInteger(idx) || idx < 0 || idx >= current.items.length) return null; + if (!Number.isInteger(idx) || idx < 0 || idx >= current.items.length) {return null;} const child = current.items[idx]; - if (child === undefined) return null; + if (child === undefined) {return null;} const replacedChild = replaceAt(child, segments, i + 1, newValue); - if (replacedChild === null) return null; + if (replacedChild === null) {return null;} const newItems = current.items.slice(); newItems[idx] = replacedChild; return { @@ -147,12 +147,12 @@ function replaceAt( function pickLineIndex(ast: JsonlAst, addr: string): number { if (addr === "$last") { for (let i = ast.lines.length - 1; i >= 0; i--) { - if (ast.lines[i]?.kind === "value") return i; + if (ast.lines[i]?.kind === "value") {return i;} } return -1; } const m = /^L(\d+)$/.exec(addr); - if (m === null || m[1] === undefined) return -1; + if (m === null || m[1] === undefined) {return -1;} const target = Number(m[1]); return ast.lines.findIndex((l) => l.line === target); } diff --git a/extensions/oc-path/src/oc-path/oc-path.ts b/extensions/oc-path/src/oc-path/oc-path.ts index c2cad068af1..2e591329643 100644 --- a/extensions/oc-path/src/oc-path/oc-path.ts +++ b/extensions/oc-path/src/oc-path/oc-path.ts @@ -24,7 +24,7 @@ const BOM = ""; function hasControlChar(s: string): boolean { for (let i = 0; i < s.length; i++) { const cc = s.charCodeAt(i); - if (cc <= 0x1f || cc === 0x7f) return true; + if (cc <= 0x1f || cc === 0x7f) {return true;} } return false; } @@ -206,9 +206,9 @@ export function formatOcPath(path: OcPath): string { // (quoted, predicate, union, sentinel). Plain concatenation would // silently split a raw `foo/bar` slot into two segments at parse. const formatSubSegment = (sub: string): string => { - if (isQuotedSeg(sub)) return sub; - if (sub.startsWith("[") && sub.endsWith("]")) return sub; - if (sub.startsWith("{") && sub.endsWith("}")) return sub; + if (isQuotedSeg(sub)) {return sub;} + if (sub.startsWith("[") && sub.endsWith("]")) {return sub;} + if (sub.startsWith("{") && sub.endsWith("}")) {return sub;} return quoteSeg(sub); }; const validateSubForFormat = (sub: string, slotName: string): void => { @@ -241,10 +241,10 @@ export function formatOcPath(path: OcPath): string { const fileNeedsQuote = /[/[\]{}?&%"\s]/.test(path.file); const formattedFile = fileNeedsQuote ? quoteSeg(path.file) : path.file; let out = OC_SCHEME + formattedFile; - if (path.section !== undefined) out += "/" + formatSlot(path.section, "section"); - if (path.item !== undefined) out += "/" + formatSlot(path.item, "item"); - if (path.field !== undefined) out += "/" + formatSlot(path.field, "field"); - if (path.session !== undefined) out += "?session=" + path.session; + if (path.section !== undefined) {out += "/" + formatSlot(path.section, "section");} + if (path.item !== undefined) {out += "/" + formatSlot(path.item, "item");} + if (path.field !== undefined) {out += "/" + formatSlot(path.field, "field");} + if (path.session !== undefined) {out += "?session=" + path.session;} if (out.length > MAX_PATH_LENGTH) { fail( @@ -263,7 +263,7 @@ export function formatOcPath(path: OcPath): string { /** True iff `input` is a string `parseOcPath` would accept. */ export function isValidOcPath(input: unknown): input is string { - if (typeof input !== "string") return false; + if (typeof input !== "string") {return false;} try { parseOcPath(input); return true; @@ -305,8 +305,8 @@ export interface PositionalContainer { // Resolve `$last` against a container; null when empty. export function resolvePositionalSeg(seg: string, container: PositionalContainer): string | null { - if (seg !== POS_LAST || container.size === 0) return null; - if (!container.indexable) return container.keys?.[container.keys.length - 1] ?? null; + if (seg !== POS_LAST || container.size === 0) {return null;} + if (!container.indexable) {return container.keys?.[container.keys.length - 1] ?? null;} return String(container.size - 1); } @@ -325,13 +325,13 @@ export const WILDCARD_RECURSIVE = "**"; */ export function isPattern(path: OcPath): boolean { for (const slot of [path.section, path.item, path.field]) { - if (slot === undefined) continue; + if (slot === undefined) {continue;} // Quote-aware split — `slot.split('.')` would shred quoted keys // containing literal `*` and falsely flag them as wildcards. for (const sub of splitRespectingBrackets(slot, ".")) { - if (sub === WILDCARD_SINGLE || sub === WILDCARD_RECURSIVE) return true; - if (isUnionSeg(sub)) return true; - if (isPredicateSeg(sub)) return true; + if (sub === WILDCARD_SINGLE || sub === WILDCARD_RECURSIVE) {return true;} + if (isUnionSeg(sub)) {return true;} + if (isPredicateSeg(sub)) {return true;} } } return false; @@ -346,11 +346,11 @@ export function isUnionSeg(seg: string): boolean { } export function parseUnionSeg(seg: string): readonly string[] | null { - if (!isUnionSeg(seg)) return null; + if (!isUnionSeg(seg)) {return null;} const inner = seg.slice(1, -1); - if (inner.length === 0) return null; + if (inner.length === 0) {return null;} const alts = inner.split(","); - if (alts.some((a) => a.length === 0)) return null; + if (alts.some((a) => a.length === 0)) {return null;} return alts; } @@ -363,7 +363,7 @@ export type PredicateOp = "=" | "!=" | "<" | "<=" | ">" | ">="; const PREDICATE_OPS: readonly PredicateOp[] = ["!=", "<=", ">=", "<", ">", "="]; export function isPredicateSeg(seg: string): boolean { - if (seg.length < 4 || !seg.startsWith("[") || !seg.endsWith("]")) return false; + if (seg.length < 4 || !seg.startsWith("[") || !seg.endsWith("]")) {return false;} const inner = new Set(seg.slice(1, -1)); return PREDICATE_OPS.some((op) => inner.has(op)); } @@ -375,14 +375,14 @@ export interface PredicateSpec { } export function parsePredicateSeg(seg: string): PredicateSpec | null { - if (seg.length < 4 || !seg.startsWith("[") || !seg.endsWith("]")) return null; + if (seg.length < 4 || !seg.startsWith("[") || !seg.endsWith("]")) {return null;} const inner = seg.slice(1, -1); // Leftmost operator wins; at each position, multi-char beats single // (so `[a<=b]` parses as op=`<=`, not op=`<`). for (let i = 1; i < inner.length; i++) { for (const op of PREDICATE_OPS) { - if (!inner.startsWith(op, i)) continue; - if (i + op.length >= inner.length) continue; // empty value + if (!inner.startsWith(op, i)) {continue;} + if (i + op.length >= inner.length) {continue;} // empty value return { key: inner.slice(0, i), op, value: inner.slice(i + op.length) }; } } @@ -391,7 +391,7 @@ export function parsePredicateSeg(seg: string): PredicateSpec | null { // Numeric ops require both sides to coerce to finite numbers. export function evaluatePredicate(actual: string | null, pred: PredicateSpec): boolean { - if (actual === null) return false; + if (actual === null) {return false;} switch (pred.op) { case "=": return actual === pred.value; @@ -403,10 +403,10 @@ export function evaluatePredicate(actual: string | null, pred: PredicateSpec): b case ">=": { const a = Number(actual); const b = Number(pred.value); - if (!Number.isFinite(a) || !Number.isFinite(b)) return false; - if (pred.op === "<") return a < b; - if (pred.op === "<=") return a <= b; - if (pred.op === ">") return a > b; + if (!Number.isFinite(a) || !Number.isFinite(b)) {return false;} + if (pred.op === "<") {return a < b;} + if (pred.op === "<=") {return a <= b;} + if (pred.op === ">") {return a > b;} return a >= b; } } @@ -464,13 +464,13 @@ export function repackPath(pattern: OcPath, subs: readonly string[]): OcPath { } function extractSession(queryPart: string): string | undefined { - if (queryPart.length === 0) return undefined; + if (queryPart.length === 0) {return undefined;} for (const pair of queryPart.split("&")) { const eqIndex = pair.indexOf("="); - if (eqIndex === -1) continue; + if (eqIndex === -1) {continue;} const key = pair.slice(0, eqIndex); const value = pair.slice(eqIndex + 1); - if (key === "session" && value.length > 0) return value; + if (key === "session" && value.length > 0) {return value;} } return undefined; } @@ -486,23 +486,23 @@ function scanBracketAware(s: string, onChar: ScanCallback, onUnbalanced: () => n for (let i = 0; i < s.length; i++) { const c = s[i]; if (inQuote) { - if (c === '"') inQuote = false; - if (onChar(c, i, false) === "stop") return; + if (c === '"') {inQuote = false;} + if (onChar(c, i, false) === "stop") {return;} continue; } if (c === '"') { inQuote = true; - if (onChar(c, i, false) === "stop") return; + if (onChar(c, i, false) === "stop") {return;} continue; } - if (c === "[") depthBracket++; - else if (c === "]") depthBracket--; - else if (c === "{") depthBrace++; - else if (c === "}") depthBrace--; - if (depthBracket < 0 || depthBrace < 0) onUnbalanced(); - if (onChar(c, i, depthBracket === 0 && depthBrace === 0) === "stop") return; + if (c === "[") {depthBracket++;} + else if (c === "]") {depthBracket--;} + else if (c === "{") {depthBrace++;} + else if (c === "}") {depthBrace--;} + if (depthBracket < 0 || depthBrace < 0) {onUnbalanced();} + if (onChar(c, i, depthBracket === 0 && depthBrace === 0) === "stop") {return;} } - if (depthBracket !== 0 || depthBrace !== 0 || inQuote) onUnbalanced(); + if (depthBracket !== 0 || depthBrace !== 0 || inQuote) {onUnbalanced();} } /** First top-level occurrence of `ch` in `s`; -1 when absent. */ @@ -563,7 +563,7 @@ export function unquoteSeg(seg: string): string { // Refuses values with `"` or `\` — no escape mechanism. export function quoteSeg(value: string): string { - if (value.length === 0) return '""'; + if (value.length === 0) {return '""';} if (value.includes('"') || value.includes("\\")) { fail( `Cannot quote value containing '"' or '\\\\': ${printable(value)}`, @@ -607,8 +607,8 @@ function validateSubSegment(sub: string, input: string): void { } // Quoted content is byte-literal but can't contain `"` or `\`. if (isQuotedSeg(sub)) { - const inner = sub.slice(1, -1); - if (inner.includes('"') || inner.includes("\\")) { + const inner = new Set(sub.slice(1, -1)); + if (inner.has('"') || inner.has("\\")) { fail( `Quoted segment cannot contain '"' or '\\\\': ${printable(sub)}`, input, diff --git a/extensions/oc-path/src/oc-path/parse.ts b/extensions/oc-path/src/oc-path/parse.ts index 0cc853b35fb..3fa0b725308 100644 --- a/extensions/oc-path/src/oc-path/parse.ts +++ b/extensions/oc-path/src/oc-path/parse.ts @@ -18,7 +18,6 @@ import type { AstItem, Diagnostic, FrontmatterEntry, - MdAst, ParseResult, } from "./ast.js"; import { slugify } from "./slug.js"; @@ -154,7 +153,7 @@ function extractItems(tokens: readonly Token[], bodyFileLine: number): AstItem[] const items: AstItem[] = []; for (let i = 0; i < tokens.length; i++) { const t = tokens[i]; - if (t.type !== "list_item_open" || t.map === null) continue; + if (t.type !== "list_item_open" || t.map === null) {continue;} // First inline at the item's own depth is the item text. let nestedDepth = 0; let text = ""; diff --git a/extensions/oc-path/src/oc-path/resolve.ts b/extensions/oc-path/src/oc-path/resolve.ts index 98f6a408612..6bd6f8f2242 100644 --- a/extensions/oc-path/src/oc-path/resolve.ts +++ b/extensions/oc-path/src/oc-path/resolve.ts @@ -35,39 +35,39 @@ export type OcPathMatch = export function resolveMdOcPath(ast: MdAst, path: OcPath): OcPathMatch | null { if (path.section === "[frontmatter]") { const key = path.item ?? path.field; - if (key === undefined) return null; + if (key === undefined) {return null;} const entry = ast.frontmatter.find((e) => e.key === key); - if (entry === undefined) return null; + if (entry === undefined) {return null;} return { kind: "frontmatter", node: entry }; } - if (path.section === undefined) return { kind: "root", node: ast }; + if (path.section === undefined) {return { kind: "root", node: ast };} const block = ast.blocks.find((b) => b.slug === path.section!.toLowerCase()); - if (block === undefined) return null; - if (path.item === undefined) return { kind: "block", node: block }; + if (block === undefined) {return null;} + if (path.item === undefined) {return { kind: "block", node: block };} // Item dispatch: ordinal (#N) > positional ($first/$last/-N) > slug. // Ordinal uses document order so duplicate-slug items stay distinct. let item: AstItem | undefined; if (isOrdinalSeg(path.item)) { const n = parseOrdinalSeg(path.item); - if (n === null || n < 0 || n >= block.items.length) return null; + if (n === null || n < 0 || n >= block.items.length) {return null;} item = block.items[n]; } else if (isPositionalSeg(path.item)) { const concrete = resolvePositionalSeg(path.item, { indexable: true, size: block.items.length, }); - if (concrete === null) return null; + if (concrete === null) {return null;} item = block.items[Number(concrete)]; } else { item = block.items.find((i) => i.slug === path.item!.toLowerCase()); } - if (item === undefined) return null; - if (path.field === undefined) return { kind: "item", node: item, block }; + if (item === undefined) {return null;} + if (path.field === undefined) {return { kind: "item", node: item, block };} - if (item.kv === undefined) return null; - if (item.kv.key.toLowerCase() !== path.field.toLowerCase()) return null; + if (item.kv === undefined) {return null;} + if (item.kv.key.toLowerCase() !== path.field.toLowerCase()) {return null;} return { kind: "item-field", node: item, block, value: item.kv.value }; } diff --git a/extensions/oc-path/src/oc-path/universal.ts b/extensions/oc-path/src/oc-path/universal.ts index dc41bc89c63..a97e4a63069 100644 --- a/extensions/oc-path/src/oc-path/universal.ts +++ b/extensions/oc-path/src/oc-path/universal.ts @@ -99,13 +99,13 @@ export interface InsertionInfo { export function detectInsertion(path: OcPath): InsertionInfo | null { const segments: Array<{ slot: "section" | "item" | "field"; value: string }> = []; - if (path.section !== undefined) segments.push({ slot: "section", value: path.section }); - if (path.item !== undefined) segments.push({ slot: "item", value: path.item }); - if (path.field !== undefined) segments.push({ slot: "field", value: path.field }); - if (segments.length === 0) return null; + if (path.section !== undefined) {segments.push({ slot: "section", value: path.section });} + if (path.item !== undefined) {segments.push({ slot: "item", value: path.item });} + if (path.field !== undefined) {segments.push({ slot: "field", value: path.field });} + if (segments.length === 0) {return null;} const last = segments[segments.length - 1]; - if (!last.value.startsWith("+")) return null; + if (!last.value.startsWith("+")) {return null;} const rest = last.value.slice(1); const marker: InsertionInfo["marker"] = @@ -137,7 +137,7 @@ export function resolveOcPath(ast: OcAst, path: OcPath): OcMatch | null { ); } const insertion = detectInsertion(path); - if (insertion !== null) return resolveInsertion(ast, insertion); + if (insertion !== null) {return resolveInsertion(ast, insertion);} switch (ast.kind) { case "md": @@ -151,7 +151,7 @@ export function resolveOcPath(ast: OcAst, path: OcPath): OcMatch | null { function resolveMdToUniversal(ast: MdAst, path: OcPath): OcMatch | null { const m = resolveMdOcPath(ast, path); - if (m === null) return null; + if (m === null) {return null;} switch (m.kind) { case "root": return { kind: "root", ast, line: 1 }; @@ -168,9 +168,9 @@ function resolveMdToUniversal(ast: MdAst, path: OcPath): OcMatch | null { function resolveJsoncToUniversal(ast: JsoncAst, path: OcPath): OcMatch | null { const m = resolveJsoncOcPath(ast, path); - if (m === null) return null; - if (m.kind === "root") return { kind: "root", ast, line: 1 }; - if (m.kind === "object-entry") return jsoncValueToMatch(m.node.value, m.node.line); + if (m === null) {return null;} + if (m.kind === "root") {return { kind: "root", ast, line: 1 };} + if (m.kind === "object-entry") {return jsoncValueToMatch(m.node.value, m.node.line);} return jsoncValueToMatch(m.node, m.node.line ?? 1); } @@ -193,12 +193,12 @@ function jsoncValueToMatch(value: JsoncValue, line: number): OcMatch { function resolveJsonlToUniversal(ast: JsonlAst, path: OcPath): OcMatch | null { const m = resolveJsonlOcPath(ast, path); - if (m === null) return null; - if (m.kind === "root") return { kind: "root", ast, line: 1 }; - if (m.kind === "line") return { kind: "node", descriptor: "jsonl-line", line: m.node.line }; + if (m === null) {return null;} + if (m.kind === "root") {return { kind: "root", ast, line: 1 };} + if (m.kind === "line") {return { kind: "node", descriptor: "jsonl-line", line: m.node.line };} // Inside-line jsonc nodes always have line=1; use the JsonlLine's // file-level line instead since every inside-line node sits there. - if (m.kind === "object-entry") return jsoncValueToMatch(m.node.value, m.line); + if (m.kind === "object-entry") {return jsoncValueToMatch(m.node.value, m.line);} return jsoncValueToMatch(m.node, m.line); } @@ -215,13 +215,13 @@ function resolveInsertion(ast: OcAst, info: InsertionInfo): OcMatch | null { function resolveMdInsertion(ast: MdAst, info: InsertionInfo): OcMatch | null { const p = info.parentPath; - if (p.section === undefined) return { kind: "insertion-point", container: "md-file", line: 1 }; + if (p.section === undefined) {return { kind: "insertion-point", container: "md-file", line: 1 };} if (p.section === "[frontmatter]") { return { kind: "insertion-point", container: "md-frontmatter", line: 1 }; } if (p.item === undefined && p.field === undefined) { const m = resolveMdOcPath(ast, p); - if (m === null || m.kind !== "block") return null; + if (m === null || m.kind !== "block") {return null;} return { kind: "insertion-point", container: "md-section", line: m.node.line }; } return null; @@ -256,7 +256,7 @@ function resolveJsoncInsertion(ast: JsoncAst, info: InsertionInfo): OcMatch | nu function resolveJsonlInsertion(ast: JsonlAst, info: InsertionInfo): OcMatch | null { // jsonl insertion only makes sense at file level (`oc://FILE/+`). // Surfaced line is lastLine+1 so consumers render correctly. - if (info.parentPath.section !== undefined) return null; + if (info.parentPath.section !== undefined) {return null;} const lastLine = ast.lines.length > 0 ? ast.lines[ast.lines.length - 1].line : 0; return { kind: "insertion-point", container: "jsonl-file", line: lastLine + 1 }; } @@ -317,7 +317,7 @@ function setStructuredLeaf( onLine?: () => SetResult, ): SetResult { const existing = resolve(ast, path); - if (existing === null) return { ok: false, reason: "unresolved" }; + if (existing === null) {return { ok: false, reason: "unresolved" };} if (existing.kind === "root") { return { ok: false, reason: "not-writable", detail: "root replacement is not supported via setOcPath" }; } @@ -445,9 +445,9 @@ function setJsoncInsertion(ast: JsoncAst, info: InsertionInfo, value: string): S return { ok: false, reason: "type-mismatch", detail: "cannot insert by key into array" }; } return mutateJsoncContainer(ast, info.parentPath, (container) => { - if (container.kind !== "array") return null; + if (container.kind !== "array") {return null;} const items = container.items.slice(); - if (info.marker === "+") items.push(newJsoncValue); + if (info.marker === "+") {items.push(newJsoncValue);} else if (typeof info.marker === "object" && info.marker.kind === "indexed") { const idx = Math.min(info.marker.index, items.length); items.splice(idx, 0, newJsoncValue); @@ -465,8 +465,8 @@ function setJsoncInsertion(ast: JsoncAst, info: InsertionInfo, value: string): S } const key = info.marker.key; return mutateJsoncContainer(ast, info.parentPath, (container) => { - if (container.kind !== "object") return null; - if (container.entries.some((e) => e.key === key)) return null; // duplicate + if (container.kind !== "object") {return null;} + if (container.entries.some((e) => e.key === key)) {return null;} // duplicate const newEntry: JsoncEntry = { key, value: newJsoncValue, line: 0 }; return { kind: "object", @@ -495,14 +495,14 @@ function setJsonlInsertion(ast: JsonlAst, info: InsertionInfo, value: string): S // semantic node, only the bytes change. function coerceJsoncLeaf(valueText: string, existing: JsoncValue): JsoncValue | null { const lineExt = existing.line !== undefined ? { line: existing.line } : {}; - if (existing.kind === "string") return { kind: "string", value: valueText, ...lineExt }; + if (existing.kind === "string") {return { kind: "string", value: valueText, ...lineExt };} if (existing.kind === "number") { const n = Number(valueText); return Number.isFinite(n) ? { kind: "number", value: n, ...lineExt } : null; } if (existing.kind === "boolean") { - if (valueText === "true") return { kind: "boolean", value: true, ...lineExt }; - if (valueText === "false") return { kind: "boolean", value: false, ...lineExt }; + if (valueText === "true") {return { kind: "boolean", value: true, ...lineExt };} + if (valueText === "false") {return { kind: "boolean", value: false, ...lineExt };} return null; } if (existing.kind === "null") { @@ -522,10 +522,10 @@ function tryParseJson(value: string): unknown { function jsonToJsoncValue(v: unknown): JsoncValue { // Synthetic values omit `line` — only the parser sets line metadata. - if (v === null) return { kind: "null" }; - if (typeof v === "string") return { kind: "string", value: v }; - if (typeof v === "number") return { kind: "number", value: v }; - if (typeof v === "boolean") return { kind: "boolean", value: v }; + if (v === null) {return { kind: "null" };} + if (typeof v === "string") {return { kind: "string", value: v };} + if (typeof v === "number") {return { kind: "number", value: v };} + if (typeof v === "boolean") {return { kind: "boolean", value: v };} if (Array.isArray(v)) { return { kind: "array", items: v.map(jsonToJsoncValue) }; } @@ -549,7 +549,7 @@ function mutateJsoncContainer( parentPath: OcPath, mutate: (container: JsoncValue) => JsoncValue | null, ): SetResult { - if (ast.root === null) return { ok: false, reason: "no-root" }; + if (ast.root === null) {return { ok: false, reason: "no-root" };} // Quote-aware split so insertion under a key with `/`/`.`/etc. works. const segments: string[] = []; @@ -565,7 +565,7 @@ function mutateJsoncContainer( const newRoot = segments.length === 0 ? mutate(ast.root) : mutateAt(ast.root, segments, 0, mutate); - if (newRoot === null) return { ok: false, reason: "unresolved" }; + if (newRoot === null) {return { ok: false, reason: "unresolved" };} const next: JsoncAst = { kind: "jsonc", raw: "", root: newRoot }; return { ok: true, ast: { ...next, raw: emitJsonc(next, { mode: "render" }) } }; @@ -578,17 +578,17 @@ function mutateAt( mutate: (container: JsoncValue) => JsoncValue | null, ): JsoncValue | null { const seg = segments[i]; - if (seg === undefined) return mutate(current); - if (seg.length === 0) return null; + if (seg === undefined) {return mutate(current);} + if (seg.length === 0) {return null;} if (current.kind === "object") { // AST keys are unquoted; strip quotes from the path segment. const lookupKey = isQuotedSeg(seg) ? unquoteSeg(seg) : seg; const idx = current.entries.findIndex((e) => e.key === lookupKey); - if (idx === -1) return null; + if (idx === -1) {return null;} const child = current.entries[idx]; const replaced = mutateAt(child.value, segments, i + 1, mutate); - if (replaced === null) return null; + if (replaced === null) {return null;} const newEntries = current.entries.slice(); newEntries[idx] = { ...child, value: replaced }; return { @@ -599,10 +599,10 @@ function mutateAt( } if (current.kind === "array") { const idx = Number(seg); - if (!Number.isInteger(idx) || idx < 0 || idx >= current.items.length) return null; + if (!Number.isInteger(idx) || idx < 0 || idx >= current.items.length) {return null;} const child = current.items[idx]; const replaced = mutateAt(child, segments, i + 1, mutate); - if (replaced === null) return null; + if (replaced === null) {return null;} const newItems = current.items.slice(); newItems[idx] = replaced; return { @@ -624,21 +624,21 @@ function rebuildMdRaw(ast: MdAst): MdAst { parts.push("---"); } if (ast.preamble.length > 0) { - if (parts.length > 0) parts.push(""); + if (parts.length > 0) {parts.push("");} parts.push(ast.preamble); } for (const block of ast.blocks) { - if (parts.length > 0) parts.push(""); + if (parts.length > 0) {parts.push("");} parts.push(`## ${block.heading}`); - if (block.bodyText.length > 0) parts.push(block.bodyText); + if (block.bodyText.length > 0) {parts.push(block.bodyText);} } void emitJsonl; return { ...ast, raw: parts.join("\n") }; } function formatFrontmatterValue(value: string): string { - if (value.length === 0) return '""'; - if (/[:#&*?|<>=!%@`,[\]{}\r\n]/.test(value)) return JSON.stringify(value); + if (value.length === 0) {return '""';} + if (/[:#&*?|<>=!%@`,[\]{}\r\n]/.test(value)) {return JSON.stringify(value);} return value; }