mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
refactor(types): integrate generate docs in rollup.config.js
This commit is contained in:
parent
25e437b746
commit
010fe986e9
7 changed files with 386 additions and 563 deletions
|
@ -4,5 +4,4 @@ cache: yarn
|
||||||
script:
|
script:
|
||||||
- yarn prepack
|
- yarn prepack
|
||||||
- yarn build
|
- yarn build
|
||||||
- node scripts/generate-docs.js
|
|
||||||
- cd docs && yarn && yarn test
|
- cd docs && yarn && yarn test
|
||||||
|
|
|
@ -46,10 +46,10 @@
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/ibm/carbon-components-svelte.git"
|
"url": "https://github.com/IBM/carbon-components-svelte.git"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/ibm/carbon-components-svelte",
|
"homepage": "https://github.com/IBM/carbon-components-svelte",
|
||||||
"bugs": "https://github.com/ibm/carbon-components-svelte/issues",
|
"bugs": "https://github.com/IBM/carbon-components-svelte/issues",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"carbon",
|
"carbon",
|
||||||
"carbon components",
|
"carbon components",
|
||||||
|
|
|
@ -3,24 +3,26 @@ import pkg from "./package.json";
|
||||||
import resolve from "@rollup/plugin-node-resolve";
|
import resolve from "@rollup/plugin-node-resolve";
|
||||||
import commonjs from "@rollup/plugin-commonjs";
|
import commonjs from "@rollup/plugin-commonjs";
|
||||||
import svelte from "rollup-plugin-svelte";
|
import svelte from "rollup-plugin-svelte";
|
||||||
|
import generateDocs from "./scripts/rollup/plugin-generate-docs";
|
||||||
|
|
||||||
export default ["es", "umd"].map((format) => {
|
export default ["es", "umd"].map((format) => {
|
||||||
const UMD = format === "umd";
|
const UMD = format === "umd";
|
||||||
|
|
||||||
const output = {
|
|
||||||
format,
|
|
||||||
file: UMD ? pkg.main : pkg.module,
|
|
||||||
globals: { flatpickr: "flatpickr" },
|
|
||||||
};
|
|
||||||
|
|
||||||
if (UMD) {
|
|
||||||
output.name = "carbon-components-svelte";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
input: "src",
|
input: "src",
|
||||||
output,
|
output: {
|
||||||
|
format,
|
||||||
|
file: UMD ? pkg.main : pkg.module,
|
||||||
|
name: UMD ? "carbon-components-svelte" : undefined,
|
||||||
|
globals: { flatpickr: "flatpickr" },
|
||||||
|
},
|
||||||
external: Object.keys(pkg.dependencies),
|
external: Object.keys(pkg.dependencies),
|
||||||
plugins: [svelte(), resolve(), commonjs(), UMD && terser()],
|
plugins: [
|
||||||
|
svelte(),
|
||||||
|
resolve(),
|
||||||
|
commonjs(),
|
||||||
|
UMD && terser(),
|
||||||
|
!UMD && generateDocs(),
|
||||||
|
],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,134 +0,0 @@
|
||||||
const fs = require("fs");
|
|
||||||
const rollup = require("rollup");
|
|
||||||
const pkg = require("../package.json");
|
|
||||||
const svelte = require("rollup-plugin-svelte");
|
|
||||||
const resolve = require("@rollup/plugin-node-resolve").default;
|
|
||||||
const commonjs = require("@rollup/plugin-commonjs");
|
|
||||||
const path = require("path");
|
|
||||||
const prettier = require("prettier");
|
|
||||||
const { parseComponent } = require("./parse-component");
|
|
||||||
|
|
||||||
async function generateDocs() {
|
|
||||||
let definitions = `
|
|
||||||
// Type definitions for carbon-components-svelte ${pkg.version}
|
|
||||||
// Project: https://github.com/IBM/carbon-components-svelte
|
|
||||||
|
|
||||||
class CarbonSvelteBase {
|
|
||||||
$$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();
|
|
||||||
const bundle = await rollup.rollup({
|
|
||||||
input: "src",
|
|
||||||
plugins: [svelte(), resolve(), commonjs()],
|
|
||||||
});
|
|
||||||
const { output } = await bundle.generate({ format: "es", file: pkg.module });
|
|
||||||
|
|
||||||
for (const chunkOrAsset of output) {
|
|
||||||
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 CarbonSvelteBase {
|
|
||||||
${!!$$prop_def ? "$$prop_def: {\n" + $$prop_def + "\n}\n" : ""}
|
|
||||||
|
|
||||||
${!!$$slot_def ? "$$slot_def: {\n" + $$slot_def + "\n}\n" : ""}
|
|
||||||
}\n\n`;
|
|
||||||
|
|
||||||
components.set(moduleName, component);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatted_definitions = prettier.format(definitions, {
|
|
||||||
parser: "typescript",
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(pkg.types, formatted_definitions);
|
|
||||||
}
|
|
||||||
|
|
||||||
generateDocs();
|
|
|
@ -1,7 +1,12 @@
|
||||||
const { parse, walk } = require("svelte/compiler");
|
import { parse, walk } from "svelte/compiler";
|
||||||
const commentParser = require("comment-parser");
|
import commentParser from "comment-parser";
|
||||||
|
|
||||||
function parseComponent(source, hooks) {
|
/**
|
||||||
|
* Parse Svelte component for metadata using the Svelte compiler
|
||||||
|
* @param {string} source - raw Svelte component code
|
||||||
|
* @param {{ component: string; onTypeDef: (tag: { type: "typedef"; tag: string; name: string; }) => void;}} hooks
|
||||||
|
*/
|
||||||
|
export function parseComponent(source, hooks) {
|
||||||
const exported_props = new Map();
|
const exported_props = new Map();
|
||||||
const slots = new Map();
|
const slots = new Map();
|
||||||
const forwarded_events = new Map();
|
const forwarded_events = new Map();
|
||||||
|
@ -111,5 +116,3 @@ function parseComponent(source, hooks) {
|
||||||
dispatched_events,
|
dispatched_events,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { parseComponent };
|
|
133
scripts/rollup/plugin-generate-docs.js
Normal file
133
scripts/rollup/plugin-generate-docs.js
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
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;
|
636
types/index.d.ts
vendored
636
types/index.d.ts
vendored
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue