Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(types): solve a type generation problems #1072

Merged
merged 8 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 41 additions & 19 deletions .scripts/gen-comp-types.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,48 @@ const replaceValues = [
];

const __dirname = process.cwd()

if(!exist(path.resolve(__dirname, componentDirectory)))
throw new Error("Path not exist: " + componentDirectory);

console.log("Creating vue-component-meta checker...")
// create component meta checker
const checker = createChecker(
path.resolve(__dirname, './packages/oruga/tsconfig.json'),
{
forceUseTs: true,
printer: { newLine: 1 },
// schema: { ignore: ['MyIgnoredNestedProps'] },
},
let checker = createChecker(
path.resolve(__dirname, './packages/oruga/tsconfig.app.json'),
{ forceUseTs: true, printer: { newLine: 1 } },
);

// get all component folders
const component_folders = getFolders(componentDirectory);

console.log(`Processing components...`);

const components = component_folders.map(folder => {
const name = folder.toLowerCase();
const folderPath = path.resolve(__dirname, componentDirectory, folder);

// get all components in component folder
const components = getComponents(folderPath)

// get all configruable props from all components in folder
const props = components.flatMap(comp => {
const file = comp.toLocaleLowerCase()+".vue";
const componentPath = path.resolve(__dirname, componentDirectory, name, file);
const meta = checker.getComponentMeta(componentPath);
const folderComponents = getComponents(folderPath);

// get all configurable props from all components in folder
const props = folderComponents.flatMap(comp => {
const file = comp+".vue";
const componentPath = path.resolve(__dirname, componentDirectory, folder, file);
let meta = checker.getComponentMeta(componentPath);

if(!meta.props.length) {
console.warn(`Failure parsing component '${name}'. No properties found.`);
console.log("Recreating vue-component-meta checker...")
// Recreate component meta checker
// Due to some inconsistencies and unexpected empty extracted props,
// creating a new checker helps to extract the props.
// The reason could be some internal memory out of bound exceptions.
checker = createChecker(
path.resolve(__dirname, './packages/oruga/tsconfig.app.json'),
{ forceUseTs: true, printer: { newLine: 1 } },
);
meta = checker.getComponentMeta(componentPath);
}

return meta.props.filter(prop => {
// filter only class props and configurable props
Expand All @@ -51,6 +64,10 @@ const components = component_folders.map(folder => {
}
return false;
}).map(prop => {
// remove undefined because we wrap the object with partial
if(prop.type.includes("| undefined"))
prop.type = prop.type.replace(" | undefined", '');

// change type for class props
if(prop.type === "ComponentClass")
prop.type = "ClassDefinition";
Expand All @@ -75,11 +92,14 @@ const components = component_folders.map(folder => {
// filter duplicates
.filter((item, idx, self) =>
idx === self.findIndex(p => p.name === item.name)
);
)

console.log(`Processed '${name}' component with ${props.length} global props.`);
return { name, props };
});
})
.sort((a,b) => a.name.localeCompare(b.name))

console.log(`Processed ${components.length} components.`);

let code = `import type {
ClassDefinition,
Expand All @@ -96,7 +116,7 @@ declare module "../index" {
props.map(prop =>`
/** ${prop.description} */
${prop.name}: ${prop.type};`
).sort((a,b) => a.localeCompare(b)) .join("")
).join("")
}
}>;`
).join(`
Expand All @@ -111,5 +131,7 @@ replaceValues.forEach((lookup) => {
})

const file = path.resolve(__dirname, componentDirectory, "types.ts");
fs.writeFileSync(path.resolve(__dirname, file), code, 'utf-8')
fs.writeFileSync(file, code, 'utf-8');

console.log(`File '${file}' generated.`);

3 changes: 2 additions & 1 deletion .scripts/utils.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const IGNORE = [
"DatepickerTable",
"DatepickerTableRow",
"DatepickerMonth",
"Programmatic"
];

export const componentDirectory = './packages/oruga/src/components';
Expand All @@ -19,7 +20,7 @@ export function exist (path) {
return fs.existsSync(path)
}

const filter = (f) => !f.includes("tests") && !f.includes("examples") && !f.includes("utils") && !f.includes(".ts");
const filter = (f) => !f.includes("tests") && !f.includes("examples") && !f.includes("utils") && !f.includes(".ts") && !f.includes("programmatic");

export function getFolders(dir) {
const folders = fs.readdirSync(dir)
Expand Down
Loading