feat(web): open the local settings file
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
import { Context, Service } from 'cordis'
|
||||
import z from 'schemastery'
|
||||
import { watch as chokidarWatch } from 'chokidar'
|
||||
import { mkdir, readFile } from 'node:fs/promises'
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||
import { dirname, extname, join, resolve } from 'node:path'
|
||||
import { Document, parseDocument } from 'yaml'
|
||||
import { withFileLock, writeFileAtomic } from '@deepseek-ai/dsh-atomic-write'
|
||||
@@ -96,6 +96,11 @@ function isENOENT(error: unknown): boolean {
|
||||
return (error as NodeJS.ErrnoException | null)?.code === 'ENOENT'
|
||||
}
|
||||
|
||||
/** Whether an exclusive file create found an existing document. */
|
||||
function isEEXIST(error: unknown): boolean {
|
||||
return (error as NodeJS.ErrnoException | null)?.code === 'EEXIST'
|
||||
}
|
||||
|
||||
/** File-backed settings provider (`settings.yaml`/`.json`). */
|
||||
export class SettingsLocal extends Settings {
|
||||
static Config: z<Config> = z.object({
|
||||
@@ -139,6 +144,29 @@ export class SettingsLocal extends Settings {
|
||||
return true
|
||||
}
|
||||
|
||||
/** The resolved YAML/JSON document path exposed to local configuration surfaces. */
|
||||
override get documentPath(): string {
|
||||
return this.spec.filename
|
||||
}
|
||||
|
||||
/** Materialize an absent owner-only document, then return its resolved path. */
|
||||
override prepareDocument(): Promise<string> {
|
||||
return this.enqueue(async () => {
|
||||
await mkdir(dirname(this.spec.filename), { recursive: true, mode: 0o700 })
|
||||
await withFileLock(this.spec.filename, async () => {
|
||||
try {
|
||||
await writeFile(this.spec.filename, '', { flag: 'wx', mode: 0o600 })
|
||||
} catch (error) {
|
||||
if (isEEXIST(error)) return
|
||||
throw error
|
||||
}
|
||||
this.text = ''
|
||||
if (!this.isClosed()) this.publish({})
|
||||
})
|
||||
return this.spec.filename
|
||||
})
|
||||
}
|
||||
|
||||
protected async load(): Promise<Record<string, unknown>> {
|
||||
let text: string
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user