mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-02 03:58:05 +08:00
Fixed some errors in generator-types (#6095)
Co-authored-by: starasov <starasov@sportmaster.ru>
This commit is contained in:
parent
8a0c8a8fb1
commit
75c65e094f
@ -3,18 +3,21 @@ const pkg = require('../../package.json');
|
||||
const { parseAndWrite } = require('./lib/index.js');
|
||||
const rootPath = path.resolve(__dirname, '../../');
|
||||
|
||||
try {
|
||||
parseAndWrite({
|
||||
version: pkg.version,
|
||||
name: 'ant-design-vue',
|
||||
path: path.resolve(rootPath, './components'),
|
||||
// default match lang
|
||||
test: /en-US\.md/,
|
||||
outputDir: path.resolve(rootPath, './vetur'),
|
||||
tagPrefix: 'a-',
|
||||
parseAndWrite({
|
||||
version: pkg.version,
|
||||
name: 'ant-design-vue',
|
||||
path: path.resolve(rootPath, './components'),
|
||||
typingsPath: path.resolve(rootPath, './typings/global.d.ts'),
|
||||
// default match lang
|
||||
test: /en-US\.md/,
|
||||
outputDir: path.resolve(rootPath, './vetur'),
|
||||
tagPrefix: 'a-',
|
||||
})
|
||||
.then(result => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`generator types success: ${result} tags generated`);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('generator types error', error);
|
||||
return Promise.reject(error);
|
||||
});
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('generator types success');
|
||||
} catch (e) {
|
||||
console.error('generator types error', e);
|
||||
}
|
||||
|
@ -34,14 +34,19 @@ function parserProps(tag: VueTag, line: any) {
|
||||
});
|
||||
}
|
||||
|
||||
export function formatter(articals: Articals, componentName: string, tagPrefix = '') {
|
||||
export function formatter(
|
||||
articals: Articals,
|
||||
componentName: string,
|
||||
kebabComponentName: string,
|
||||
tagPrefix = '',
|
||||
) {
|
||||
if (!articals.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tags: VueTag[] = [];
|
||||
const tag: VueTag = {
|
||||
name: getComponentName(componentName, tagPrefix),
|
||||
name: kebabComponentName,
|
||||
slots: [],
|
||||
events: [],
|
||||
attributes: [],
|
||||
@ -80,9 +85,13 @@ export function formatter(articals: Articals, componentName: string, tagPrefix =
|
||||
}
|
||||
|
||||
// 额外的子组件
|
||||
if (tableTitle.includes(componentName) && !tableTitle.includes('events')) {
|
||||
if (
|
||||
tableTitle.includes(componentName) &&
|
||||
!tableTitle.includes('events') &&
|
||||
!tableTitle.includes('()')
|
||||
) {
|
||||
const childTag: VueTag = {
|
||||
name: getComponentName(tableTitle.replace('.', ''), tagPrefix),
|
||||
name: getComponentName(tableTitle.replaceAll('.', '').replaceAll('/', ''), tagPrefix),
|
||||
slots: [],
|
||||
events: [],
|
||||
attributes: [],
|
||||
@ -93,6 +102,7 @@ export function formatter(articals: Articals, componentName: string, tagPrefix =
|
||||
tags.push(childTag);
|
||||
return;
|
||||
}
|
||||
|
||||
// 额外的子组件事件
|
||||
if (tableTitle.includes(componentName) && tableTitle.includes('events')) {
|
||||
const childTagName = getComponentName(
|
||||
|
@ -1,52 +1,91 @@
|
||||
import glob from 'fast-glob';
|
||||
import { join, dirname } from 'path';
|
||||
import { dirname, join } from 'path';
|
||||
import { mdParser } from './parser';
|
||||
import { formatter } from './formatter';
|
||||
import { genWebTypes } from './web-types';
|
||||
import { readFileSync, outputFileSync } from 'fs-extra';
|
||||
import { outputFileSync, readFileSync } from 'fs-extra';
|
||||
import type { Options, VueTag } from './type';
|
||||
import { normalizePath, getComponentName } from './utils';
|
||||
import { genVeturTags, genVeturAttributes } from './vetur';
|
||||
import { getComponentName, normalizePath, toKebabCase } from './utils';
|
||||
import { genVeturAttributes, genVeturTags } from './vetur';
|
||||
|
||||
async function readMarkdown(options: Options) {
|
||||
// const mds = await glob(normalizePath(`${options.path}/**/*.md`))
|
||||
const mds = await glob(normalizePath(`${options.path}/**/*.md`));
|
||||
return mds
|
||||
async function readMarkdown(options: Options): Promise<Map<String, VueTag>> {
|
||||
const mdPaths = await glob(normalizePath(`${options.path}/**/*.md`));
|
||||
const data = mdPaths
|
||||
.filter(md => options.test.test(md))
|
||||
.map(path => {
|
||||
const docPath = dirname(path);
|
||||
const componentName = docPath.substring(docPath.lastIndexOf('/') + 1);
|
||||
return {
|
||||
componentName: getComponentName(componentName || ''),
|
||||
md: readFileSync(path, 'utf-8'),
|
||||
};
|
||||
});
|
||||
const kebabComponentName =
|
||||
options.tagPrefix + docPath.substring(docPath.lastIndexOf('/') + 1) || '';
|
||||
const componentName = getComponentName(docPath.substring(docPath.lastIndexOf('/') + 1) || '');
|
||||
const fileContent = readFileSync(path, 'utf-8');
|
||||
return formatter(mdParser(fileContent), componentName, kebabComponentName, options.tagPrefix);
|
||||
})
|
||||
.filter(item => item) as VueTag[][];
|
||||
const tags: Map<String, VueTag> = new Map();
|
||||
data.flatMap(item => item).forEach(mergedTag => mergeTag(tags, mergedTag));
|
||||
return tags;
|
||||
}
|
||||
|
||||
export async function parseAndWrite(options: Options) {
|
||||
function readTypings(options: Options): Map<String, VueTag> {
|
||||
const tags: Map<String, VueTag> = new Map();
|
||||
const fileContent = readFileSync(options.typingsPath, 'utf-8');
|
||||
fileContent
|
||||
.split('\n')
|
||||
.filter(line => line && line.includes('typeof'))
|
||||
.map(line => {
|
||||
const l = line.trim();
|
||||
return toKebabCase(l.substring(0, l.indexOf(':')));
|
||||
})
|
||||
.forEach(tagName =>
|
||||
tags.set(tagName, {
|
||||
name: tagName,
|
||||
slots: [],
|
||||
events: [],
|
||||
attributes: [],
|
||||
}),
|
||||
);
|
||||
return tags;
|
||||
}
|
||||
|
||||
function mergeTag(tags: Map<String, VueTag>, mergedTag: VueTag) {
|
||||
const tagName = mergedTag.name;
|
||||
const vueTag = tags.get(tagName);
|
||||
if (vueTag) {
|
||||
vueTag.slots = [...vueTag.slots, ...mergedTag.slots];
|
||||
vueTag.events = [...vueTag.events, ...mergedTag.events];
|
||||
vueTag.attributes = [...vueTag.attributes, ...mergedTag.attributes];
|
||||
} else {
|
||||
tags.set(tagName, mergedTag);
|
||||
}
|
||||
}
|
||||
|
||||
function mergeTags(mergedTagsArr: Map<String, VueTag>[]): VueTag[] {
|
||||
if (mergedTagsArr.length === 1) return [...mergedTagsArr[0].values()];
|
||||
const tags: Map<String, VueTag> = new Map();
|
||||
if (mergedTagsArr.length === 0) return [];
|
||||
mergedTagsArr.forEach(mergedTags => {
|
||||
mergedTags.forEach(mergedTag => mergeTag(tags, mergedTag));
|
||||
});
|
||||
return [...tags.values()];
|
||||
}
|
||||
|
||||
export async function parseAndWrite(options: Options): Promise<Number> {
|
||||
if (!options.outputDir) {
|
||||
throw new Error('outputDir can not be empty.');
|
||||
}
|
||||
|
||||
const docs = await readMarkdown(options);
|
||||
const datas = docs
|
||||
.map(doc => formatter(mdParser(doc.md), doc.componentName, options.tagPrefix))
|
||||
.filter(item => item) as VueTag[][];
|
||||
const tags: VueTag[] = [];
|
||||
datas.forEach(arr => {
|
||||
tags.push(...arr);
|
||||
});
|
||||
|
||||
const tagsFromMarkdown = await readMarkdown(options);
|
||||
const tagsFromTypings = await readTypings(options);
|
||||
const tags = mergeTags([tagsFromMarkdown, tagsFromTypings]);
|
||||
const webTypes = genWebTypes(tags, options);
|
||||
const veturTags = genVeturTags(tags);
|
||||
const veturAttributes = genVeturAttributes(tags);
|
||||
|
||||
outputFileSync(join(options.outputDir, 'tags.json'), JSON.stringify(veturTags, null, 2));
|
||||
outputFileSync(
|
||||
join(options.outputDir, 'attributes.json'),
|
||||
JSON.stringify(veturAttributes, null, 2),
|
||||
);
|
||||
outputFileSync(join(options.outputDir, 'web-types.json'), JSON.stringify(webTypes, null, 2));
|
||||
return tags.length;
|
||||
}
|
||||
|
||||
export default { parseAndWrite };
|
||||
|
@ -27,7 +27,7 @@ function readLine(input: string) {
|
||||
function splitTableLine(line: string) {
|
||||
line = line.replace(/\\\|/g, 'JOIN');
|
||||
|
||||
const items = line.split('|').map(item => item.trim().replace('JOIN', '|'));
|
||||
const items = line.split('|').map(item => item.trim().replaceAll('JOIN', '|'));
|
||||
|
||||
// remove pipe character on both sides
|
||||
items.pop();
|
||||
@ -77,11 +77,6 @@ export function mdParser(input: string): Articals {
|
||||
const artical = [];
|
||||
let start = 0;
|
||||
const end = input.length;
|
||||
// artical.push({
|
||||
// type: 'title',
|
||||
// content: title,
|
||||
// level: 0,
|
||||
// });
|
||||
|
||||
while (start < end) {
|
||||
const target = input.substr(start);
|
||||
@ -108,6 +103,5 @@ export function mdParser(input: string): Articals {
|
||||
}
|
||||
}
|
||||
|
||||
// artical[0].content = title
|
||||
return artical;
|
||||
}
|
||||
|
@ -28,9 +28,9 @@ export type VueAttribute = {
|
||||
|
||||
export type VueTag = {
|
||||
name: string;
|
||||
slots?: VueSlot[];
|
||||
events?: VueEvent[];
|
||||
attributes?: VueAttribute[];
|
||||
slots: VueSlot[];
|
||||
events: VueEvent[];
|
||||
attributes: VueAttribute[];
|
||||
description?: string;
|
||||
};
|
||||
|
||||
@ -56,6 +56,7 @@ export type VeturResult = {
|
||||
export type Options = {
|
||||
name: string;
|
||||
path: PathLike;
|
||||
typingsPath: PathLike;
|
||||
test: RegExp;
|
||||
version: string;
|
||||
outputDir?: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// myName -> my-name
|
||||
export function toKebabCase(input: string): string {
|
||||
return input.replace(/[A-Z]/g, (val, index) => (index === 0 ? '' : '-') + val.toLowerCase());
|
||||
export function toKebabCase(camel: string): string {
|
||||
return camel.replace(/((?<=[a-z\d])[A-Z]|(?<=[A-Z\d])[A-Z](?=[a-z]))/g, '-$1').toLowerCase();
|
||||
}
|
||||
|
||||
// name `v2.0.0` -> name
|
||||
|
Loading…
Reference in New Issue
Block a user