apache-autoindex-parse
Version:
parse apache's autoindex html files
57 lines (55 loc) • 2.11 kB
JavaScript
import { i as trimTrailingSlash, n as parse, r as trimLeadingSlash } from "./src-Dc2VUN4U.js";
//#region src/traverse.ts
/**
* Recursively traverses an Apache autoindex directory structure.
*
* This function fetches the HTML content from the provided URL, parses it to extract directory entries,
* and then recursively traverses any subdirectories found.
*
* @param {string} rootUrl - The URL of the Apache autoindex directory to traverse
* @param {TraverseOptions?} options - Optional configuration for the traversal process
* @returns {Promise<TraverseEntry[]>} A promise that resolves to a RootEntry object representing the directory structure, or null if parsing failed
*
* @example
* ```typescript
* import { traverse } from 'apache-autoindex-parse/traverse';
*
* const directoryStructure = await traverse('https://example.com/files');
* ```
*/
async function traverse(rootUrl, options) {
return traverseInternal(rootUrl, "", options);
}
async function traverseInternal(rootUrl, pathPrefix, options) {
try {
const res = await fetch(rootUrl, {
headers: {
"User-Agent": "github.com/luxass/apache-autoindex-parse",
...options?.extraHeaders
},
signal: options?.abortSignal
});
if (!res.ok) throw new Error(`failed to fetch directory listing from ${rootUrl}: ${res.status} ${res.statusText}`);
const rootEntries = parse(await res.text(), options?.format);
if (!rootEntries) return [];
return await Promise.all(rootEntries.map(async (entry) => {
let fullPath = pathPrefix ? `${pathPrefix}/${entry.path}` : entry.path;
fullPath = trimTrailingSlash(trimLeadingSlash(fullPath));
if (entry.type === "file") return {
...entry,
path: fullPath
};
const child = await traverseInternal(rootUrl.endsWith("/") ? rootUrl + (entry.path.startsWith("/") ? entry.path.slice(1) : entry.path) : rootUrl + (entry.path.startsWith("/") ? entry.path : `/${entry.path}`), fullPath, options);
entry.name = trimTrailingSlash(entry.name);
return {
...entry,
path: fullPath,
children: child
};
}));
} catch {
return [];
}
}
//#endregion
export { traverse };