@docuify/engine
Version:
A flexible, pluggable engine for building and transforming documentation content from source files.
116 lines (112 loc) • 3.41 kB
JavaScript
// lib/base/baseSource.ts
var BaseSource = class {
};
// lib/utils/extract_file_ext.ts
function getFileExtension(filename) {
const match = filename.match(/(?:\.([^.\/\\]+))?$/);
return match?.[1] ?? null;
}
// lib/sources/github.ts
var Github = class extends BaseSource {
name = "Github";
config;
constructor(config) {
super();
if (!config.token || !config.branch || !config.repoFullName) {
throw new Error("Invalid config passed to Github source.");
}
this.config = config;
}
async fetch() {
const data = await this.request();
const parsedData = await this.parse(data.tree);
return parsedData;
}
get requestHeaders() {
return {
Authorization: `Bearer ${this.config.token}`,
"X-GitHub-Api-Version": this.config.github_api_version ?? "2022-11-28"
};
}
async parse(data) {
const fields = this.config.metadataFields || ["sha"];
return data.map((item) => {
const isFolder = item.type === "tree";
const metadata = {};
for (const field of fields) {
if (field in item) {
metadata[field] = item[field];
}
}
const file = {
path: item.path,
type: isFolder ? "folder" : "file",
metadata,
extension: isFolder ? null : getFileExtension(item.path),
loadContent: isFolder ? void 0 : async () => this.fetchFileContent(item.path)
};
return file;
});
}
async fetchFileContent(path2) {
const url = `https://raw.githubusercontent.com/${this.config.repoFullName}/${this.config.branch}/${path2}`;
const res = await fetch(url, { headers: this.requestHeaders });
if (!res.ok) {
throw new Error(
`Failed to fetch file content from GitHub: ${res.status} ${res.statusText}`
);
}
return await res.text();
}
async request() {
const url = `https://api.github.com/repos/${this.config.repoFullName}/git/trees/${this.config.branch}?recursive=1`;
const res = await fetch(url, { headers: this.requestHeaders });
if (!res.ok) {
throw new Error(
`Failed to fetch data from GitHub: ${res.status} ${res.statusText}`
);
}
return await res.json();
}
};
// lib/sources/localfile.ts
import fs from "fs/promises";
import path from "path";
var LocalFile = class extends BaseSource {
constructor(rootDir) {
super();
this.rootDir = rootDir;
this.rootDir = path.resolve(process.cwd(), rootDir);
}
name = "local-file-source";
// Recursively fetch files from the local directory
async fetch() {
const files = [];
await this._readDirRecursive(this.rootDir, files);
return files;
}
async _readDirRecursive(dir, files, parentPath = "") {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
const relativePath = parentPath ? `${parentPath}/${entry.name}` : entry.name;
if (entry.isDirectory()) {
await this._readDirRecursive(fullPath, files, relativePath);
} else if (entry.isFile()) {
files.push({
path: relativePath,
type: "file",
extension: path.extname(entry.name).slice(1),
// remove dot
loadContent: async () => {
return fs.readFile(fullPath, "utf-8");
}
});
}
}
}
};
export {
Github,
LocalFile
};