Merge pull request #96 from y574444354/fix/compile-issue-0514
fix(utils): replace using syntax with withDisposable for node v20 compatibility
This commit is contained in:
commit
4703b608a8
|
|
@ -240,7 +240,7 @@ ${allSkillNames.map(n => ` "${n}": "${commitSha}"`).join(',\n')}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List all skill names
|
// List all skill names
|
||||||
export function listBuiltinSkillNames(): string[] {
|
export function listBuiltinSkills(): string[] {
|
||||||
return ${JSON.stringify(allSkillNames)}
|
return ${JSON.stringify(allSkillNames)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { type Options as ExecaOptions, execaSync } from 'execa'
|
import { type Options as ExecaOptions, execaSync } from 'execa'
|
||||||
import { getCwd } from '../utils/cwd.js'
|
import { getCwd } from '../utils/cwd.js'
|
||||||
import { slowLogging } from './slowOperations.js'
|
import { slowLogging, withDisposable } from './slowOperations.js'
|
||||||
|
|
||||||
const MS_IN_SECOND = 1000
|
const MS_IN_SECOND = 1000
|
||||||
const SECONDS_IN_MINUTE = 60
|
const SECONDS_IN_MINUTE = 60
|
||||||
|
|
@ -67,23 +67,24 @@ export function execSyncWithDefaults_DEPRECATED(
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
abortSignal?.throwIfAborted()
|
abortSignal?.throwIfAborted()
|
||||||
using _ = slowLogging`exec: ${command.slice(0, 200)}`
|
return withDisposable(() => {
|
||||||
try {
|
try {
|
||||||
const result = (execaSync as any)(command, {
|
const result = (execaSync as any)(command, {
|
||||||
env: process.env,
|
env: process.env,
|
||||||
maxBuffer: 1_000_000,
|
maxBuffer: 1_000_000,
|
||||||
timeout: finalTimeout,
|
timeout: finalTimeout,
|
||||||
cwd: getCwd(),
|
cwd: getCwd(),
|
||||||
stdio,
|
stdio,
|
||||||
shell: true, // execSync typically runs shell commands
|
shell: true, // execSync typically runs shell commands
|
||||||
reject: false, // Don't throw on non-zero exit codes
|
reject: false, // Don't throw on non-zero exit codes
|
||||||
input,
|
input,
|
||||||
})
|
})
|
||||||
if (!result.stdout) {
|
if (!result.stdout) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return result.stdout.trim() || null
|
||||||
|
} catch {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return result.stdout.trim() || null
|
}, slowLogging`exec: ${command.slice(0, 200)}`)
|
||||||
} catch {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import {
|
||||||
type ExecSyncOptionsWithStringEncoding,
|
type ExecSyncOptionsWithStringEncoding,
|
||||||
execSync as nodeExecSync,
|
execSync as nodeExecSync,
|
||||||
} from 'child_process'
|
} from 'child_process'
|
||||||
import { slowLogging } from './slowOperations.js'
|
import { slowLogging, withDisposable } from './slowOperations.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use async alternatives when possible. Sync exec calls block the event loop.
|
* @deprecated Use async alternatives when possible. Sync exec calls block the event loop.
|
||||||
|
|
@ -33,6 +33,8 @@ export function execSync_DEPRECATED(
|
||||||
command: string,
|
command: string,
|
||||||
options?: ExecSyncOptions,
|
options?: ExecSyncOptions,
|
||||||
): Buffer | string {
|
): Buffer | string {
|
||||||
using _ = slowLogging`execSync: ${command.slice(0, 100)}`
|
return withDisposable(
|
||||||
return nodeExecSync(command, options)
|
() => nodeExecSync(command, options),
|
||||||
|
slowLogging`execSync: ${command.slice(0, 100)}`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
import { homedir } from 'os'
|
import { homedir } from 'os'
|
||||||
import * as nodePath from 'path'
|
import * as nodePath from 'path'
|
||||||
import { getErrnoCode } from './errors.js'
|
import { getErrnoCode } from './errors.js'
|
||||||
import { slowLogging } from './slowOperations.js'
|
import { slowLogging, withDisposable } from './slowOperations.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplified filesystem operations interface based on Node.js fs module.
|
* Simplified filesystem operations interface based on Node.js fs module.
|
||||||
|
|
@ -387,8 +387,10 @@ export const NodeFsOperations: FsOperations = {
|
||||||
},
|
},
|
||||||
|
|
||||||
existsSync(fsPath) {
|
existsSync(fsPath) {
|
||||||
using _ = slowLogging`fs.existsSync(${fsPath})`
|
return withDisposable(
|
||||||
return fs.existsSync(fsPath)
|
() => fs.existsSync(fsPath),
|
||||||
|
slowLogging`fs.existsSync(${fsPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
async stat(fsPath) {
|
async stat(fsPath) {
|
||||||
|
|
@ -433,77 +435,95 @@ export const NodeFsOperations: FsOperations = {
|
||||||
},
|
},
|
||||||
|
|
||||||
statSync(fsPath) {
|
statSync(fsPath) {
|
||||||
using _ = slowLogging`fs.statSync(${fsPath})`
|
return withDisposable(
|
||||||
return fs.statSync(fsPath)
|
() => fs.statSync(fsPath),
|
||||||
|
slowLogging`fs.statSync(${fsPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
lstatSync(fsPath) {
|
lstatSync(fsPath) {
|
||||||
using _ = slowLogging`fs.lstatSync(${fsPath})`
|
return withDisposable(
|
||||||
return fs.lstatSync(fsPath)
|
() => fs.lstatSync(fsPath),
|
||||||
|
slowLogging`fs.lstatSync(${fsPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
readFileSync(fsPath, options) {
|
readFileSync(fsPath, options) {
|
||||||
using _ = slowLogging`fs.readFileSync(${fsPath})`
|
return withDisposable(
|
||||||
return fs.readFileSync(fsPath, { encoding: options.encoding })
|
() => fs.readFileSync(fsPath, { encoding: options.encoding }),
|
||||||
|
slowLogging`fs.readFileSync(${fsPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
readFileBytesSync(fsPath) {
|
readFileBytesSync(fsPath) {
|
||||||
using _ = slowLogging`fs.readFileBytesSync(${fsPath})`
|
return withDisposable(
|
||||||
return fs.readFileSync(fsPath)
|
() => fs.readFileSync(fsPath),
|
||||||
|
slowLogging`fs.readFileBytesSync(${fsPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
readSync(fsPath, options) {
|
readSync(fsPath, options) {
|
||||||
using _ = slowLogging`fs.readSync(${fsPath}, ${options.length} bytes)`
|
return withDisposable(() => {
|
||||||
let fd: number | undefined
|
let fd: number | undefined
|
||||||
try {
|
try {
|
||||||
fd = fs.openSync(fsPath, 'r')
|
fd = fs.openSync(fsPath, 'r')
|
||||||
const buffer = Buffer.alloc(options.length)
|
const buffer = Buffer.alloc(options.length)
|
||||||
const bytesRead = fs.readSync(fd, buffer, 0, options.length, 0)
|
const bytesRead = fs.readSync(fd, buffer, 0, options.length, 0)
|
||||||
return { buffer, bytesRead }
|
return { buffer, bytesRead }
|
||||||
} finally {
|
} finally {
|
||||||
if (fd) fs.closeSync(fd)
|
if (fd) fs.closeSync(fd)
|
||||||
}
|
}
|
||||||
|
}, slowLogging`fs.readSync(${fsPath}, ${options.length} bytes)`)
|
||||||
},
|
},
|
||||||
|
|
||||||
appendFileSync(path, data, options) {
|
appendFileSync(path, data, options) {
|
||||||
using _ = slowLogging`fs.appendFileSync(${path}, ${data.length} chars)`
|
withDisposable(() => {
|
||||||
// For new files with explicit mode, use 'ax' (atomic create-with-mode) to avoid
|
// For new files with explicit mode, use 'ax' (atomic create-with-mode) to avoid
|
||||||
// TOCTOU race between existence check and open. Fall back to normal append if exists.
|
// TOCTOU race between existence check and open. Fall back to normal append if exists.
|
||||||
if (options?.mode !== undefined) {
|
if (options?.mode !== undefined) {
|
||||||
try {
|
|
||||||
const fd = fs.openSync(path, 'ax', options.mode)
|
|
||||||
try {
|
try {
|
||||||
fs.appendFileSync(fd, data)
|
const fd = fs.openSync(path, 'ax', options.mode)
|
||||||
} finally {
|
try {
|
||||||
fs.closeSync(fd)
|
fs.appendFileSync(fd, data)
|
||||||
|
} finally {
|
||||||
|
fs.closeSync(fd)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} catch (e) {
|
||||||
|
if (getErrnoCode(e) !== 'EEXIST') throw e
|
||||||
|
// File exists — fall through to normal append
|
||||||
}
|
}
|
||||||
return
|
|
||||||
} catch (e) {
|
|
||||||
if (getErrnoCode(e) !== 'EEXIST') throw e
|
|
||||||
// File exists — fall through to normal append
|
|
||||||
}
|
}
|
||||||
}
|
fs.appendFileSync(path, data)
|
||||||
fs.appendFileSync(path, data)
|
}, slowLogging`fs.appendFileSync(${path}, ${data.length} chars)`)
|
||||||
},
|
},
|
||||||
|
|
||||||
copyFileSync(src, dest) {
|
copyFileSync(src, dest) {
|
||||||
using _ = slowLogging`fs.copyFileSync(${src} → ${dest})`
|
withDisposable(
|
||||||
fs.copyFileSync(src, dest)
|
() => fs.copyFileSync(src, dest),
|
||||||
|
slowLogging`fs.copyFileSync(${src} → ${dest})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
unlinkSync(path: string) {
|
unlinkSync(path: string) {
|
||||||
using _ = slowLogging`fs.unlinkSync(${path})`
|
withDisposable(
|
||||||
fs.unlinkSync(path)
|
() => fs.unlinkSync(path),
|
||||||
|
slowLogging`fs.unlinkSync(${path})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
renameSync(oldPath: string, newPath: string) {
|
renameSync(oldPath: string, newPath: string) {
|
||||||
using _ = slowLogging`fs.renameSync(${oldPath} → ${newPath})`
|
withDisposable(
|
||||||
fs.renameSync(oldPath, newPath)
|
() => fs.renameSync(oldPath, newPath),
|
||||||
|
slowLogging`fs.renameSync(${oldPath} → ${newPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
linkSync(target: string, path: string) {
|
linkSync(target: string, path: string) {
|
||||||
using _ = slowLogging`fs.linkSync(${target} → ${path})`
|
withDisposable(
|
||||||
fs.linkSync(target, path)
|
() => fs.linkSync(target, path),
|
||||||
|
slowLogging`fs.linkSync(${target} → ${path})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
symlinkSync(
|
symlinkSync(
|
||||||
|
|
@ -511,64 +531,80 @@ export const NodeFsOperations: FsOperations = {
|
||||||
path: string,
|
path: string,
|
||||||
type?: 'dir' | 'file' | 'junction',
|
type?: 'dir' | 'file' | 'junction',
|
||||||
) {
|
) {
|
||||||
using _ = slowLogging`fs.symlinkSync(${target} → ${path})`
|
withDisposable(
|
||||||
fs.symlinkSync(target, path, type)
|
() => fs.symlinkSync(target, path, type),
|
||||||
|
slowLogging`fs.symlinkSync(${target} → ${path})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
readlinkSync(path: string) {
|
readlinkSync(path: string) {
|
||||||
using _ = slowLogging`fs.readlinkSync(${path})`
|
return withDisposable(
|
||||||
return fs.readlinkSync(path)
|
() => fs.readlinkSync(path),
|
||||||
|
slowLogging`fs.readlinkSync(${path})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
realpathSync(path: string) {
|
realpathSync(path: string) {
|
||||||
using _ = slowLogging`fs.realpathSync(${path})`
|
return withDisposable(
|
||||||
return fs.realpathSync(path).normalize('NFC')
|
() => fs.realpathSync(path).normalize('NFC'),
|
||||||
|
slowLogging`fs.realpathSync(${path})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
mkdirSync(dirPath, options) {
|
mkdirSync(dirPath, options) {
|
||||||
using _ = slowLogging`fs.mkdirSync(${dirPath})`
|
withDisposable(() => {
|
||||||
const mkdirOptions: { recursive: boolean; mode?: number } = {
|
const mkdirOptions: { recursive: boolean; mode?: number } = {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
}
|
}
|
||||||
if (options?.mode !== undefined) {
|
if (options?.mode !== undefined) {
|
||||||
mkdirOptions.mode = options.mode
|
mkdirOptions.mode = options.mode
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
fs.mkdirSync(dirPath, mkdirOptions)
|
fs.mkdirSync(dirPath, mkdirOptions)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Bun/Windows: recursive:true throws EEXIST on directories with the
|
// Bun/Windows: recursive:true throws EEXIST on directories with the
|
||||||
// FILE_ATTRIBUTE_READONLY bit set (Group Policy, OneDrive, desktop.ini).
|
// FILE_ATTRIBUTE_READONLY bit set (Group Policy, OneDrive, desktop.ini).
|
||||||
// Bun's directoryExistsAt misclassifies DIRECTORY+READONLY as not-a-dir
|
// Bun's directoryExistsAt misclassifies DIRECTORY+READONLY as not-a-dir
|
||||||
// (bun-internal src/sys.zig existsAtType). The dir exists; ignore.
|
// (bun-internal src/sys.zig existsAtType). The dir exists; ignore.
|
||||||
// https://github.com/anthropics/claude-code/issues/30924
|
// https://github.com/anthropics/claude-code/issues/30924
|
||||||
if (getErrnoCode(e) !== 'EEXIST') throw e
|
if (getErrnoCode(e) !== 'EEXIST') throw e
|
||||||
}
|
}
|
||||||
|
}, slowLogging`fs.mkdirSync(${dirPath})`)
|
||||||
},
|
},
|
||||||
|
|
||||||
readdirSync(dirPath) {
|
readdirSync(dirPath) {
|
||||||
using _ = slowLogging`fs.readdirSync(${dirPath})`
|
return withDisposable(
|
||||||
return fs.readdirSync(dirPath, { withFileTypes: true })
|
() => fs.readdirSync(dirPath, { withFileTypes: true }),
|
||||||
|
slowLogging`fs.readdirSync(${dirPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
readdirStringSync(dirPath) {
|
readdirStringSync(dirPath) {
|
||||||
using _ = slowLogging`fs.readdirStringSync(${dirPath})`
|
return withDisposable(
|
||||||
return fs.readdirSync(dirPath)
|
() => fs.readdirSync(dirPath),
|
||||||
|
slowLogging`fs.readdirStringSync(${dirPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
isDirEmptySync(dirPath) {
|
isDirEmptySync(dirPath) {
|
||||||
using _ = slowLogging`fs.isDirEmptySync(${dirPath})`
|
return withDisposable(() => {
|
||||||
const files = this.readdirSync(dirPath)
|
const files = this.readdirSync(dirPath)
|
||||||
return files.length === 0
|
return files.length === 0
|
||||||
|
}, slowLogging`fs.isDirEmptySync(${dirPath})`)
|
||||||
},
|
},
|
||||||
|
|
||||||
rmdirSync(dirPath) {
|
rmdirSync(dirPath) {
|
||||||
using _ = slowLogging`fs.rmdirSync(${dirPath})`
|
withDisposable(
|
||||||
fs.rmdirSync(dirPath)
|
() => fs.rmdirSync(dirPath),
|
||||||
|
slowLogging`fs.rmdirSync(${dirPath})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
rmSync(path, options) {
|
rmSync(path, options) {
|
||||||
using _ = slowLogging`fs.rmSync(${path})`
|
withDisposable(
|
||||||
fs.rmSync(path, options)
|
() => fs.rmSync(path, options),
|
||||||
|
slowLogging`fs.rmSync(${path})`,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
createWriteStream(path: string) {
|
createWriteStream(path: string) {
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,7 @@ function slowLoggingExternal(): Disposable {
|
||||||
* zero timing. AntSlowLogger and buildDescription are dead-code-eliminated.
|
* zero timing. AntSlowLogger and buildDescription are dead-code-eliminated.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* using _ = slowLogging`structuredClone(${value})`
|
* const result = withDisposable(() => structuredClone(value), slowLogging`structuredClone(${value})`)
|
||||||
* const result = structuredClone(value)
|
|
||||||
*/
|
*/
|
||||||
export const slowLogging: (
|
export const slowLogging: (
|
||||||
strings: TemplateStringsArray,
|
strings: TemplateStringsArray,
|
||||||
|
|
@ -159,6 +158,19 @@ export const slowLogging: (
|
||||||
? slowLoggingAnt
|
? slowLoggingAnt
|
||||||
: slowLoggingExternal
|
: slowLoggingExternal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a function with a disposable that is disposed in a finally block.
|
||||||
|
* Use this instead of `using` declarations for Node.js compatibility (v20
|
||||||
|
* does not support the `using` syntax).
|
||||||
|
*/
|
||||||
|
export function withDisposable<T>(fn: () => T, disposable: Disposable): T {
|
||||||
|
try {
|
||||||
|
return fn()
|
||||||
|
} finally {
|
||||||
|
disposable[Symbol.dispose]()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- Wrapped operations ---
|
// --- Wrapped operations ---
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -188,11 +200,14 @@ export function jsonStringify(
|
||||||
| null,
|
| null,
|
||||||
space?: string | number,
|
space?: string | number,
|
||||||
): string {
|
): string {
|
||||||
using _ = slowLogging`JSON.stringify(${value})`
|
return withDisposable(
|
||||||
return JSON.stringify(
|
() =>
|
||||||
value,
|
JSON.stringify(
|
||||||
replacer as Parameters<typeof JSON.stringify>[1],
|
value,
|
||||||
space,
|
replacer as Parameters<typeof JSON.stringify>[1],
|
||||||
|
space,
|
||||||
|
),
|
||||||
|
slowLogging`JSON.stringify(${value})`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,14 +219,14 @@ export function jsonStringify(
|
||||||
* import { jsonParse } from './slowOperations.js'
|
* import { jsonParse } from './slowOperations.js'
|
||||||
* const data = jsonParse(jsonString)
|
* const data = jsonParse(jsonString)
|
||||||
*/
|
*/
|
||||||
export const jsonParse: typeof JSON.parse = (text, reviver) => {
|
export const jsonParse: typeof JSON.parse = (text, reviver) =>
|
||||||
using _ = slowLogging`JSON.parse(${text})`
|
withDisposable(() => {
|
||||||
// V8 de-opts JSON.parse when a second argument is passed, even if undefined.
|
// V8 de-opts JSON.parse when a second argument is passed, even if undefined.
|
||||||
// Branch explicitly so the common (no-reviver) path stays on the fast path.
|
// Branch explicitly so the common (no-reviver) path stays on the fast path.
|
||||||
return typeof reviver === 'undefined'
|
return typeof reviver === 'undefined'
|
||||||
? JSON.parse(text)
|
? JSON.parse(text)
|
||||||
: JSON.parse(text, reviver)
|
: JSON.parse(text, reviver)
|
||||||
}
|
}, slowLogging`JSON.parse(${text})`)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapped structuredClone with slow operation logging.
|
* Wrapped structuredClone with slow operation logging.
|
||||||
|
|
@ -222,8 +237,10 @@ export const jsonParse: typeof JSON.parse = (text, reviver) => {
|
||||||
* const copy = clone(originalObject)
|
* const copy = clone(originalObject)
|
||||||
*/
|
*/
|
||||||
export function clone<T>(value: T, options?: StructuredSerializeOptions): T {
|
export function clone<T>(value: T, options?: StructuredSerializeOptions): T {
|
||||||
using _ = slowLogging`structuredClone(${value})`
|
return withDisposable(
|
||||||
return structuredClone(value, options)
|
() => structuredClone(value, options),
|
||||||
|
slowLogging`structuredClone(${value})`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -235,8 +252,10 @@ export function clone<T>(value: T, options?: StructuredSerializeOptions): T {
|
||||||
* const copy = cloneDeep(originalObject)
|
* const copy = cloneDeep(originalObject)
|
||||||
*/
|
*/
|
||||||
export function cloneDeep<T>(value: T): T {
|
export function cloneDeep<T>(value: T): T {
|
||||||
using _ = slowLogging`cloneDeep(${value})`
|
return withDisposable(
|
||||||
return lodashCloneDeep(value)
|
() => lodashCloneDeep(value),
|
||||||
|
slowLogging`cloneDeep(${value})`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -253,37 +272,37 @@ export function writeFileSync_DEPRECATED(
|
||||||
data: string | NodeJS.ArrayBufferView,
|
data: string | NodeJS.ArrayBufferView,
|
||||||
options?: WriteFileOptionsWithFlush,
|
options?: WriteFileOptionsWithFlush,
|
||||||
): void {
|
): void {
|
||||||
using _ = slowLogging`fs.writeFileSync(${filePath}, ${data})`
|
withDisposable(() => {
|
||||||
|
// Check if flush is requested (for object-style options)
|
||||||
|
const needsFlush =
|
||||||
|
options !== null &&
|
||||||
|
typeof options === 'object' &&
|
||||||
|
'flush' in options &&
|
||||||
|
options.flush === true
|
||||||
|
|
||||||
// Check if flush is requested (for object-style options)
|
if (needsFlush) {
|
||||||
const needsFlush =
|
// Manual flush: open file, write, fsync, close
|
||||||
options !== null &&
|
const encoding =
|
||||||
typeof options === 'object' &&
|
typeof options === 'object' && 'encoding' in options
|
||||||
'flush' in options &&
|
? options.encoding
|
||||||
options.flush === true
|
: undefined
|
||||||
|
const mode =
|
||||||
if (needsFlush) {
|
typeof options === 'object' && 'mode' in options
|
||||||
// Manual flush: open file, write, fsync, close
|
? options.mode
|
||||||
const encoding =
|
: undefined
|
||||||
typeof options === 'object' && 'encoding' in options
|
let fd: number | undefined
|
||||||
? options.encoding
|
try {
|
||||||
: undefined
|
fd = openSync(filePath, 'w', mode)
|
||||||
const mode =
|
fsWriteFileSync(fd, data, { encoding: encoding ?? undefined })
|
||||||
typeof options === 'object' && 'mode' in options
|
fsyncSync(fd)
|
||||||
? options.mode
|
} finally {
|
||||||
: undefined
|
if (fd !== undefined) {
|
||||||
let fd: number | undefined
|
closeSync(fd)
|
||||||
try {
|
}
|
||||||
fd = openSync(filePath, 'w', mode)
|
|
||||||
fsWriteFileSync(fd, data, { encoding: encoding ?? undefined })
|
|
||||||
fsyncSync(fd)
|
|
||||||
} finally {
|
|
||||||
if (fd !== undefined) {
|
|
||||||
closeSync(fd)
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// No flush needed, use standard writeFileSync
|
||||||
|
fsWriteFileSync(filePath, data, options as WriteFileOptions)
|
||||||
}
|
}
|
||||||
} else {
|
}, slowLogging`fs.writeFileSync(${filePath}, ${data})`)
|
||||||
// No flush needed, use standard writeFileSync
|
|
||||||
fsWriteFileSync(filePath, data, options as WriteFileOptions)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user