fuckdoc
Version:
An NPM package for component document generator
438 lines (433 loc) • 13.2 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
// src/utils.ts
var import_axios = __toESM(require("axios"));
var path = require("path");
var fs = require("fs");
var glob = require("glob");
var { parse: CommentParser } = require("comment-parser");
var CWD = process.cwd();
var DefaultConfig = {
paths: ["src/**/*"]
};
var fileExists = (filePath) => new Promise((r) => {
fs.exists(filePath, (exists) => {
if (exists) {
r(true);
} else {
r(false);
}
});
});
var isDirectory = (filePath) => {
const stat = fs.lstatSync(filePath);
return stat.isDirectory();
};
var isAllowSuffix = (suffix, userSuffix) => [...["js", "ts", "tsx", "jsx", "mjs", "vue", "weex"], ...[userSuffix]].includes(suffix);
var commonRequire = (path4) => {
const res = require(path4);
return res;
};
var loadConfig = async () => {
const configFilePath = path.join(CWD, "/fuckdoc.config.js");
let config = DefaultConfig;
const isConfigFileExists = await fileExists(configFilePath);
if (isConfigFileExists) {
const userConfig = commonRequire(configFilePath);
if (Object.keys(userConfig).length) {
config = userConfig;
}
}
return config;
};
var scanFile = async () => {
const config = await loadConfig();
const { paths = [], suffix = [] } = config;
const allFilePathsMap = /* @__PURE__ */ new Map();
paths.forEach((path4) => {
let files = glob.sync(path4, {});
files = files.forEach((filePath) => {
const fullPath = `${CWD}/${filePath}`;
if (!isDirectory(fullPath)) {
if (!allFilePathsMap.has(fullPath)) {
allFilePathsMap.set(fullPath, fullPath);
}
}
});
});
const fileFiltedPath = [...allFilePathsMap.values()];
const imgFilePath = [];
const codeFilePath = [];
fileFiltedPath.forEach((item) => {
if (item.indexOf(".fuckdoc.") > 0) {
return imgFilePath.push(item);
}
const strArr = item.split(".");
const suf = strArr[strArr.length - 1];
if (isAllowSuffix(suf, suffix)) {
return codeFilePath.push(item);
}
});
return [imgFilePath, codeFilePath, fileFiltedPath];
};
var scanData = async () => {
const [imgFilePath, codeFilePath, fileFiltedPath] = await scanFile();
const codeCommentFCMap = /* @__PURE__ */ new Map();
const codeCommentFFMap = /* @__PURE__ */ new Map();
codeFilePath.forEach((codePath) => {
const temp = fs.readFileSync(codePath, { encoding: "utf-8" });
const parsed = CommentParser(temp) || [];
const tempFCArr = [];
const tempFFArr = [];
parsed.forEach((parseItem) => {
const { description = "", tags = [] } = parseItem;
const isFC = description.indexOf("F:C") >= 0;
const isFF = description.indexOf("F:F") >= 0;
const params = [];
if (isFC || isFF) {
let title = "";
let desc = "";
let startLine = 0;
tags.forEach((tag, index) => {
if (tag.tag === "title") {
title = `${tag.name} ${tag.description}`;
}
if (tag.tag === "description") {
desc = `${tag.name} ${tag.description}`;
}
if (tag.source[0] && tag.source[0].number != null) {
startLine = tag.source[0].number;
}
if (tag.tag === "param") {
params.push({
name: tag.name,
type: tag.type,
description: tag.description
});
}
});
if (isFC) {
tempFCArr.push({
type: "FC" /* FC */,
title,
desc,
startLine,
params
});
}
if (isFF) {
tempFFArr.push({
type: "FF" /* FF */,
title,
desc,
startLine,
params
});
}
}
});
if (tempFCArr.length) {
codeCommentFCMap.set(codePath, tempFCArr);
}
if (tempFFArr.length) {
codeCommentFFMap.set(codePath, tempFFArr);
}
});
const FCArr = [];
const FFArr = [];
const imgFilePathMap = /* @__PURE__ */ new Map();
imgFilePath.forEach((imgFullPath) => {
const codeFullPath = imgFullPath.split(".fuckdoc.")[0];
if (imgFilePathMap.get(codeFullPath)) {
imgFilePathMap.get(codeFullPath).push(imgFullPath);
} else {
imgFilePathMap.set(codeFullPath, [imgFullPath]);
}
});
[...imgFilePathMap.keys()].forEach((codeFullPath) => {
const imgPaths = imgFilePathMap.get(codeFullPath);
if (fileFiltedPath.includes(codeFullPath)) {
if (codeCommentFCMap.has(codeFullPath)) {
const infos = codeCommentFCMap.get(codeFullPath);
infos.forEach((info) => {
FCArr.push({
imgPaths,
codePath: codeFullPath,
info
});
});
codeCommentFCMap.delete(codeFullPath);
} else {
FCArr.push({
imgPaths,
codePath: codeFullPath
});
}
} else {
FCArr.push({
imgPaths
});
}
});
[...codeCommentFCMap.keys()].forEach((codePath) => {
codeCommentFCMap.get(codePath).forEach((info) => {
FCArr.push({
codePath,
info
});
});
});
[...codeCommentFFMap.keys()].forEach((codePath) => {
codeCommentFFMap.get(codePath).forEach((info) => {
FFArr.push({
codePath,
info
});
});
});
const config = await loadConfig();
reportLog({
where: "scan_data",
c_num: FCArr.length,
f_num: FFArr.length
});
return {
["FC" /* FC */]: FCArr,
["FF" /* FF */]: FFArr,
title: config.title
};
};
function debounce(fn, wait2 = 50) {
let timer = null;
return function(...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, wait2);
};
}
var reportLog = ({ where = "unknown", c_num = 0, f_num = 0 }) => {
try {
const { platform } = process;
import_axios.default.get(`http://fuckdoc-log.cn-beijing.log.aliyuncs.com/logstores/npm/track?APIVersion=0.6.0&platform=${platform}&where=${where}&c_num=${c_num}&f_num=${f_num}`);
} catch (e) {
}
};
// src/server/index.ts
var import_ws = require("ws");
var path2 = require("path");
var glob2 = require("glob");
var Koa = require("koa");
var koaStatic = require("koa-static");
var koaRouter = require("koa-router");
var fs2 = require("fs");
var mime = require("mime-types");
var childProcess = require("child_process");
var cors = require("koa2-cors");
var launch = require("launch-editor");
var openInEditor = require("open-in-editor");
var portfinder = require("portfinder");
var colors = require("ansi-colors");
var chokidar = require("chokidar");
var globalData;
var globalWs;
var globalWsPort;
var wait = (time) => new Promise((r) => {
setTimeout(() => {
r(true);
}, time);
});
var doOpenEditor = (path4) => new Promise((r, j) => {
launch(path4, "code", (fileName, errorMsg) => {
j(errorMsg);
});
r(true);
});
var initServer = (config) => {
const app = new Koa();
const router = new koaRouter();
app.use(cors());
app.use(router.routes());
app.use(koaStatic(path2.join(__dirname, "../", "client"), {
index: "index.html",
hidden: false,
defer: true
}));
router.get("/img", async (ctx) => {
const { path: path4 } = ctx.request.query;
const file = fs2.readFileSync(path4);
const mimeType = mime.lookup(path4);
ctx.set("content-type", mimeType);
ctx.body = file;
});
router.get("/open-source", async (ctx) => {
const { path: path4 } = ctx.request.query;
try {
const res = await doOpenEditor(path4);
await wait(1500);
ctx.body = JSON.stringify({
success: true
});
} catch (e) {
ctx.body = JSON.stringify({
success: false,
msg: e
});
}
});
router.get("/data", async (ctx) => {
ctx.type = "json";
ctx.body = JSON.stringify({
data: __spreadProps(__spreadValues({}, globalData), {
wsPort: globalWsPort
})
});
});
portfinder.getPort({
port: 9527,
stopPort: 9999
}, (err, port) => {
const { port: configPort } = config;
const finalPort = configPort || port;
app.listen(finalPort, () => {
console.log("\n");
console.log(colors.green("\u{1F389}\u{1F389}\u{1F389} fuckdoc\u5DF2\u7ECF\u542F\u52A8 \u{1F389}\u{1F389}\u{1F389}"));
console.log("\n");
console.log(colors.green(`\u70B9\u51FB http://127.0.0.1:${finalPort} \u8BD5\u8BD5\u5427\uFF01`));
console.log("\n");
});
});
};
async function refreshData() {
globalData = await scanData();
globalWs && globalWs.send(JSON.stringify({
type: "Refresh"
}));
}
function initWatch(config) {
const { paths } = config;
const watcher = chokidar.watch(paths, {
ignored: /(^|[\/\\])\../,
persistent: true
});
const debounceRefreshData = debounce(refreshData, 1e3);
watcher.on("all", (path4) => {
debounceRefreshData();
});
}
function initWs(callback) {
portfinder.getPort({
port: 10357,
stopPort: 10400
}, (err, port) => {
globalWsPort = port;
callback();
const wss = new import_ws.WebSocketServer({ port });
wss.on("connection", function connection(ws) {
globalWs = ws;
});
});
}
async function startServer() {
const config = await loadConfig();
globalData = await scanData();
initWs(() => {
initServer(config);
initWatch(config);
});
}
// src/sharp/index.ts
var sharp = require("sharp");
var path3 = require("path");
var cliProgress = require("cli-progress");
var colors2 = require("ansi-colors");
var deleteFile = require("delete");
async function startSharp() {
const [imgFilePath] = await scanFile();
const filtedImgPath = imgFilePath.filter((imgPath) => !imgPath.endsWith(".webp"));
const imageTotal = filtedImgPath.length;
if (imageTotal === 0) {
console.log("\n");
console.log(colors2.green("\u{1F389}\u{1F389}\u{1F389} \u5DF2\u5B8C\u6210\u538B\u7F29 \u{1F389}\u{1F389}\u{1F389}"));
console.log("\n");
console.log(colors2.green("fuckdoc \u5DF2\u5C06\u56FE\u7247\u5168\u90E8\u538B\u7F29\u4E3Awebp\u683C\u5F0F"));
console.log("\n");
return;
}
const progressBar = new cliProgress.SingleBar({
format: `fuckdoc \u56FE\u7247\u538B\u7F29 |${colors2.cyan("{bar}")}| {percentage}% || {value}/{total} images`,
barCompleteChar: "\u2588",
barIncompleteChar: "\u2591",
hideCursor: true,
clearOnComplete: false
});
progressBar.start(imageTotal, 0);
let sharpedCount = 0;
filtedImgPath.forEach(async (imagePath) => {
const imgPathArr = imagePath.split(".");
imgPathArr[imgPathArr.length - 1] = "webp";
const webpImgPath = imgPathArr.join(".");
sharp(imagePath).toFile(webpImgPath, (err, info) => {
deleteFile.sync([imagePath]);
sharpedCount += 1;
progressBar.update(sharpedCount);
if (sharpedCount >= imageTotal) {
setTimeout(() => {
progressBar.stop();
console.log("\n");
console.log(colors2.green("\u{1F389}\u{1F389}\u{1F389} \u538B\u7F29\u5B8C\u6BD5 \u{1F389}\u{1F389}\u{1F389}"));
console.log("\n");
console.log(colors2.green("fuckdoc \u5DF2\u5C06\u56FE\u7247\u5168\u90E8\u538B\u7F29\u4E3Awebp\u683C\u5F0F"));
console.log("\n");
}, 500);
}
});
});
}
var sharp_default = startSharp;
// src/index.ts
var isSharp = process.argv.filter((item) => item.indexOf("sharp") >= 0).length > 0;
if (isSharp) {
reportLog({
where: "sharp"
});
sharp_default();
} else {
reportLog({
where: "start"
});
startServer();
}