vue-docgen-web-types
Version:
197 lines (196 loc) • 9.41 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = __importStar(require("path"));
const globby_1 = __importDefault(require("globby"));
const chokidar = __importStar(require("chokidar"));
const vue_docgen_api_1 = require("vue-docgen-api");
const fs = __importStar(require("fs"));
const mkdirp_1 = __importDefault(require("mkdirp"));
const lodash_1 = __importDefault(require("lodash"));
function build(config) {
return __awaiter(this, void 0, void 0, function* () {
config.componentsRoot = path.resolve(config.cwd, config.componentsRoot);
config.outFile = path.resolve(config.cwd, config.outFile);
// then create the watcher if necessary
const { watcher, componentFiles } = yield getSources(config.components, config.componentsRoot);
console.log("Building web-types to " + config.outFile);
const cache = {};
const buildWebTypesBound = rebuild.bind(null, config, componentFiles, cache, watcher);
try {
yield buildWebTypesBound();
}
catch (e) {
console.error("Error building web-types: " + e.message);
yield watcher.close();
return;
}
if (config.watch) {
watcher.on('add', buildWebTypesBound)
.on('change', buildWebTypesBound)
.on('unlink', (filePath) => __awaiter(this, void 0, void 0, function* () {
console.log("Rebuilding on file removal " + filePath);
delete cache[filePath];
yield writeDownWebTypesFile(config, Object.values(cache), config.outFile);
}));
}
else {
yield watcher.close();
}
});
}
exports.default = build;
function getSources(components, cwd) {
return __awaiter(this, void 0, void 0, function* () {
const watcher = chokidar.watch(components, { cwd });
const allComponentFiles = yield globby_1.default(components, { cwd });
return { watcher, componentFiles: allComponentFiles };
});
}
function rebuild(config, files, cachedContent, watcher, changedFilePath) {
return __awaiter(this, void 0, void 0, function* () {
const cacheWebTypesContent = (filePath) => __awaiter(this, void 0, void 0, function* () {
cachedContent[filePath] = yield extractInformation(path.join(config.componentsRoot, filePath), config);
return true;
});
if (changedFilePath) {
console.log("Rebuilding on update file " + changedFilePath);
try {
// if in chokidar mode (watch), the path of the file that was just changed
// is passed as an argument. We only affect the changed file and avoid re-parsing the rest
yield cacheWebTypesContent(changedFilePath);
}
catch (e) {
throw new Error(`Error building file ${config.outFile} when file ${changedFilePath} has changed: ${e.message}`);
}
}
else {
try {
// if we are initializing the current file, parse all components
yield Promise.all(files.map(cacheWebTypesContent));
}
catch (e) {
throw new Error(`Error building file ${config.outFile}: ${e.message}`);
}
}
// and finally save all concatenated values to the markdown file
yield writeDownWebTypesFile(config, Object.values(cachedContent), config.outFile);
});
}
function writeDownWebTypesFile(config, definitions, destFilePath) {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
const destFolder = path.dirname(destFilePath);
yield mkdirp_1.default(destFolder);
let writeStream = fs.createWriteStream(destFilePath);
const contents = {
framework: "vue",
name: config.packageName,
version: config.packageVersion,
contributions: {
html: {
"description-markup": config.descriptionMarkup,
"types-syntax": config.typesSyntax,
tags: lodash_1.default(definitions).flatMap(d => d.tags || []).orderBy("name", "asc").value(),
attributes: lodash_1.default(definitions).flatMap(d => d.attributes || []).orderBy("name", "asc").value(),
"vue-filters": lodash_1.default(definitions).flatMap(d => d["vue-filters"] || []).orderBy("name", "asc").value(),
}
}
};
const html = contents.contributions.html;
if (((_a = html.tags) === null || _a === void 0 ? void 0 : _a.length) == 0)
html.tags = undefined;
if (((_b = html.attributes) === null || _b === void 0 ? void 0 : _b.length) == 0)
html.attributes = undefined;
if (((_c = html["vue-filters"]) === null || _c === void 0 ? void 0 : _c.length) == 0)
html["vue-filters"] = undefined;
writeStream.write(JSON.stringify(contents, null, 2));
// close the stream
writeStream.close();
});
}
function ensureRelative(path) {
// The .replace() is a fix for paths that end up like "./src\\components\\General\\VerticalButton.vue" on windows machines.
return (path.startsWith("./") || path.startsWith("../") ? path : "./" + path).replace(/\\/g, '/');
}
function extractInformation(absolutePath, config) {
var _a, _b, _c, _d, _e, _f;
return __awaiter(this, void 0, void 0, function* () {
const doc = yield vue_docgen_api_1.parse(absolutePath, config.apiOptions);
let description = (_b = (_a = doc.description) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : "";
(_c = doc.docsBlocks) === null || _c === void 0 ? void 0 : _c.forEach(block => {
if (description.length > 0) {
if (config.descriptionMarkup === "html") {
description += "<br/><br/>";
}
else {
description += "\n\n";
}
}
description += block;
});
return {
tags: [
{
name: doc.displayName,
description,
attributes: (_d = doc.props) === null || _d === void 0 ? void 0 : _d.map(prop => {
var _a, _b, _c;
return ({
name: prop.name,
required: prop.required,
description: prop.description,
value: {
kind: "expression",
type: (_b = (_a = prop.type) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "any"
},
default: (_c = prop.defaultValue) === null || _c === void 0 ? void 0 : _c.value,
});
}),
events: (_e = doc.events) === null || _e === void 0 ? void 0 : _e.map(event => ({
name: event.name,
description: event.description
})),
slots: (_f = doc.slots) === null || _f === void 0 ? void 0 : _f.map(slot => ({
name: slot.name,
description: slot.description
})),
source: {
module: ensureRelative(path.relative(config.cwd, absolutePath)),
symbol: doc.exportName
}
}
]
};
});
}