Files
orca/src/shared/quick-open-directory-reader.ts
T
NeilandOrca 879aad7dd6 oom(foundation): bound shared readers/limits + add BoundedMap primitive (#10299)
* oom(01): A1-shared-readers — reintroduce #10179 subset

Files: 18 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(02): A2-shared-image-media — reintroduce #10179 subset

Files: 7 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(03): A3-shared-fs-listing — reintroduce #10179 subset

Files: 21 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(04): A4-shared-remote-relay — reintroduce #10179 subset

Files: 8 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(05): A5-shared-misc — reintroduce #10179 subset

Files: 28 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(06): B-shared-wiring — reintroduce #10179 subset

Files: 81 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-24 21:36:57 -07:00

63 lines
2.2 KiB
TypeScript

import { lstat, opendir } from 'node:fs/promises'
import { isFileListingCancellation, throwIfFileListingCancelled } from './file-listing-cancellation'
import { isQuickOpenReadableDirectory } from './quick-open-directory-validation'
import {
assertQuickOpenReaddirDeadline,
consumeQuickOpenReaddirEntryBudget,
consumeQuickOpenReaddirPathBudget,
isQuickOpenReaddirBudgetError,
type QuickOpenReaddirBudget
} from './quick-open-readdir-budget'
export type QuickOpenDirectoryEntry = {
name: string
kind: 'directory' | 'file' | 'symlink' | 'other'
}
export async function readQuickOpenDirectoryEntries(opts: {
absPath: string
allowSymlinkedRoot: boolean
budget: QuickOpenReaddirBudget
signal?: AbortSignal
}): Promise<QuickOpenDirectoryEntry[]> {
try {
const stat = await lstat(opts.absPath)
if (!isQuickOpenReadableDirectory(stat, opts.allowSymlinkedRoot)) {
return []
}
const entries: QuickOpenDirectoryEntry[] = []
const directory = await opendir(opts.absPath)
throwIfFileListingCancelled(opts.signal)
assertQuickOpenReaddirDeadline(opts.budget)
for await (const entry of directory) {
throwIfFileListingCancelled(opts.signal)
assertQuickOpenReaddirDeadline(opts.budget)
consumeQuickOpenReaddirEntryBudget(opts.budget)
consumeQuickOpenReaddirPathBudget(opts.budget, entry.name)
entries.push({
name: entry.name,
kind: entry.isDirectory()
? 'directory'
: entry.isFile()
? 'file'
: entry.isSymbolicLink()
? 'symlink'
: 'other'
})
}
entries.sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0))
// Why: discard buffered names if the path became a symlink while its
// directory handle was open; descendants must never escape the root.
const statAfterRead = await lstat(opts.absPath)
return isQuickOpenReadableDirectory(statAfterRead, opts.allowSymlinkedRoot) ? entries : []
} catch (error) {
if (isQuickOpenReaddirBudgetError(error) || isFileListingCancellation(error)) {
throw error
}
// Permission denied or a vanished subtree must not hide readable siblings.
return []
}
}