mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
133 lines
4 KiB
JavaScript
133 lines
4 KiB
JavaScript
import fs from "fs";
|
|
import path from "path";
|
|
import prettier from "prettier";
|
|
import pkg from "../../package.json";
|
|
import { parseComponent } from "./parse-component";
|
|
|
|
function pluginGenerateDocs() {
|
|
let definitions = `
|
|
// Type definitions for ${pkg.name} ${pkg.version}
|
|
// Project: ${pkg.homepage}
|
|
|
|
class SvelteComponent {
|
|
$$prop_def: {};
|
|
|
|
$$slot_def: {};
|
|
|
|
// stub all 'on:{event}' directives
|
|
$on(eventname: string, handler: (e: Event) => any): () => void;
|
|
}\n\n`;
|
|
|
|
const shared_types = new Set();
|
|
const groups = new Map();
|
|
const components = new Map();
|
|
|
|
return {
|
|
name: "generate-docs",
|
|
async generateBundle(options, bundle) {
|
|
for (const filename in bundle) {
|
|
const chunkOrAsset = bundle[filename];
|
|
|
|
if (chunkOrAsset.type !== "asset" && chunkOrAsset.isEntry) {
|
|
chunkOrAsset.exports.forEach((exportee) => {
|
|
components.set(exportee, {});
|
|
});
|
|
|
|
Object.keys(chunkOrAsset.modules)
|
|
.sort()
|
|
.forEach(async (filename) => {
|
|
const { dir, ext, name } = path.parse(filename);
|
|
const moduleName = name.replace(/\./g, "");
|
|
|
|
if (ext === ".svelte" && components.has(moduleName)) {
|
|
const group = dir.split("src/").pop().split("/")[0];
|
|
|
|
if (groups.has(group)) {
|
|
groups.set(group, [...groups.get(group), moduleName]);
|
|
} else {
|
|
groups.set(group, [moduleName]);
|
|
}
|
|
|
|
const source = fs.readFileSync(filename, "utf-8");
|
|
const component = parseComponent(source, {
|
|
component: moduleName,
|
|
onTypeDef: (tag) => {
|
|
if (shared_types.has(tag.name)) return;
|
|
|
|
shared_types.add(tag.name);
|
|
|
|
const ts_type = tag.type.startsWith("{")
|
|
? `interface ${tag.name} ${tag.type}`
|
|
: `type ${tag.name} = ${tag.type};`;
|
|
|
|
definitions += ts_type + "\n\n";
|
|
},
|
|
});
|
|
|
|
let $$prop_def = "";
|
|
|
|
component.exported_props.forEach((prop, name) => {
|
|
$$prop_def += "/**\n";
|
|
|
|
prop.description.split("\n").forEach((line) => {
|
|
$$prop_def += "* " + line + "\n";
|
|
});
|
|
|
|
if (prop.value !== undefined) {
|
|
$$prop_def += "* @default " + prop.value + "\n";
|
|
}
|
|
|
|
$$prop_def += "*/\n";
|
|
|
|
let value = "undefined";
|
|
|
|
if (prop.type) {
|
|
value = prop.type;
|
|
}
|
|
|
|
$$prop_def += name + "?: " + value + ";" + "\n\n";
|
|
});
|
|
|
|
let $$slot_def = "";
|
|
|
|
component.slots.forEach((slot, slot_name) => {
|
|
let value = "";
|
|
|
|
slot.attributes.forEach((attribute) => {
|
|
if (attribute.name !== "name") {
|
|
value += attribute.name + ": any;";
|
|
}
|
|
});
|
|
|
|
if (slot.default) {
|
|
$$slot_def += "default: {" + value + "};" + "\n";
|
|
} else {
|
|
$$slot_def +=
|
|
JSON.stringify(slot_name) + ": {" + value + "};" + "\n";
|
|
}
|
|
});
|
|
|
|
definitions += `
|
|
export class ${moduleName} extends SvelteComponent {
|
|
${!!$$prop_def ? "$$prop_def: {" + $$prop_def + "}\n" : ""}
|
|
|
|
${!!$$slot_def ? "$$slot_def: {" + $$slot_def + "}\n" : ""}
|
|
}\n\n`;
|
|
|
|
components.set(moduleName, component);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
writeBundle() {
|
|
const formatted_definitions = prettier.format(definitions, {
|
|
parser: "typescript",
|
|
});
|
|
|
|
fs.writeFileSync(pkg.types, formatted_definitions);
|
|
},
|
|
};
|
|
}
|
|
|
|
export default pluginGenerateDocs;
|