diff --git a/.gitignore b/.gitignore index 946d5a10..ceda7a4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -web/tailchat.d.ts - locales .vercel .DS_Store diff --git a/package.json b/package.json index ed138b88..e84012c3 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "devDependencies": { "@commitlint/cli": "^12.1.4", "@commitlint/config-conventional": "^12.1.4", + "@types/fs-extra": "^9.0.13", "@types/jest": "^27.0.3", "@types/node": "^15.12.5", "@typescript-eslint/eslint-plugin": "^4.28.1", diff --git a/packages/plugin-declaration-generator/src/index.ts b/packages/plugin-declaration-generator/src/index.ts index 33d46eec..708fc3cb 100644 --- a/packages/plugin-declaration-generator/src/index.ts +++ b/packages/plugin-declaration-generator/src/index.ts @@ -7,6 +7,8 @@ import { program, isFunctionDeclaration } from '@babel/types'; import fs from 'fs-extra'; import _ from 'lodash'; +export * from './tsgenerator'; + const babelPlugins: ParserPlugin[] = ['jsx', 'typescript']; const buildNamedExport = template('export function %%name%%(): any', { plugins: babelPlugins, diff --git a/packages/plugin-declaration-generator/src/tsgenerator.ts b/packages/plugin-declaration-generator/src/tsgenerator.ts index 8db8a2c1..19a64e3d 100644 --- a/packages/plugin-declaration-generator/src/tsgenerator.ts +++ b/packages/plugin-declaration-generator/src/tsgenerator.ts @@ -1,11 +1,11 @@ -import ts from 'typescript'; +import ts, { isExportDeclaration, isVariableStatement } from 'typescript'; import fs from 'fs-extra'; /** * Tools: https://ts-ast-viewer.com/ */ -interface ExportModuleItem { +export interface ExportModuleItem { name: string; comment?: string; } @@ -33,7 +33,10 @@ export function parseModuleDeclaration( if (ts.isVariableStatement(item)) { item.declarationList.declarations.forEach((declaration) => { const name = declaration.name.getText(); - modules[moduleName].push(name); + modules[moduleName].push({ + name, + text: declaration.getText(), + }); }); } }); @@ -70,6 +73,25 @@ export function parseExports(filePath: string, options: ts.CompilerOptions) { comment: getNodeComments(node), }); } + } else if ( + isVariableStatement(node) && + node.modifiers?.some((v) => v.kind === ts.SyntaxKind.ExportKeyword) + ) { + // 如果为导出变量 + // export const foo = '' + node.declarationList.declarations.forEach((d) => { + if (ts.isIdentifier(d.name)) { + exportModules.push({ + name: d.name.getText(), + }); + } else { + d.name.elements.forEach((n) => { + exportModules.push({ + name: n.getText(), + }); + }); + } + }); } }); diff --git a/packages/plugin-declaration-generator/test/index.d.ts b/packages/plugin-declaration-generator/test/index.d.ts index b11ae915..0297f22a 100644 --- a/packages/plugin-declaration-generator/test/index.d.ts +++ b/packages/plugin-declaration-generator/test/index.d.ts @@ -1,4 +1,4 @@ declare module '@capital/foo' { export const a: any; - export const b: any; + export const b: string; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b507fb9b..8adf3ff1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,7 @@ importers: specifiers: '@commitlint/cli': ^12.1.4 '@commitlint/config-conventional': ^12.1.4 + '@types/fs-extra': ^9.0.13 '@types/jest': ^27.0.3 '@types/node': ^15.12.5 '@typescript-eslint/eslint-plugin': ^4.28.1 @@ -34,6 +35,7 @@ importers: devDependencies: '@commitlint/cli': 12.1.4 '@commitlint/config-conventional': 12.1.4 + '@types/fs-extra': 9.0.13 '@types/jest': 27.5.1 '@types/node': 15.14.9 '@typescript-eslint/eslint-plugin': 4.33.0_lzzr7k3tjtqil7aczuhmzzwame diff --git a/web/package.json b/web/package.json index 027c5299..cae80f84 100644 --- a/web/package.json +++ b/web/package.json @@ -21,7 +21,7 @@ "plugins:all": "ministar buildPlugin all", "plugins:watch": "ministar watchPlugin all", "plugins:declaration": "cross-env TS_NODE_PROJECT='tsconfig.node.json' ts-node ./scripts/plugin-declaration.ts", - "plugins:declaration:generate": "cross-env TS_NODE_PROJECT='tsconfig.node.json' ts-node ./scripts/generate-plugin-declaration.ts" + "plugins:declaration:generate": "cross-env TS_NODE_PROJECT='tsconfig.node.json' ts-node ./scripts/generate-plugin-declaration.typescript.ts" }, "dependencies": { "@loadable/component": "^5.15.2", diff --git a/web/scripts/generate-plugin-declaration.ts b/web/scripts/generate-plugin-declaration.babel.ts similarity index 100% rename from web/scripts/generate-plugin-declaration.ts rename to web/scripts/generate-plugin-declaration.babel.ts diff --git a/web/scripts/generate-plugin-declaration.typescript.ts b/web/scripts/generate-plugin-declaration.typescript.ts new file mode 100644 index 00000000..73abee61 --- /dev/null +++ b/web/scripts/generate-plugin-declaration.typescript.ts @@ -0,0 +1,63 @@ +import { + parseModuleDeclaration, + parseExports, + ExportModuleItem, +} from 'tailchat-plugin-declaration-generator'; +import path from 'path'; +import fs from 'fs-extra'; + +const outputPath = path.resolve(__dirname, '../tailchat.d.ts'); + +function exportModulesTemplate(items: ExportModuleItem[]) { + return items + .map((item) => { + return `export const ${item.name}: any;`; + }) + .join('\n\n '); +} + +function generateDeclarationFile() { + const { exportModules: commonExportModules } = parseExports( + path.resolve(__dirname, '../src/plugin/common/index.ts'), + {} + ); + + const { exportModules: commonRegExportModules } = parseExports( + path.resolve(__dirname, '../src/plugin/common/reg.ts'), + {} + ); + + const { exportModules: componentExportModules } = parseExports( + path.resolve(__dirname, '../src/plugin/component/index.tsx'), + {} + ); + + const output = `/** + * 该文件由 Tailchat 自动生成 + * 用于插件的类型声明 + * 生成命令: pnpm run plugins:declaration:generate + */ + +/** + * Tailchat 通用 + */ +declare module '@capital/common' { + ${exportModulesTemplate(commonExportModules)} + + ${exportModulesTemplate(commonRegExportModules)} +} + + +/** + * Tailchat 组件 + */ +declare module '@capital/component' { + ${exportModulesTemplate(componentExportModules)} +}`; + + fs.writeFile(outputPath, output, { + encoding: 'utf8', + }); +} + +generateDeclarationFile(); diff --git a/web/tailchat.d.ts b/web/tailchat.d.ts new file mode 100644 index 00000000..3aabf9f0 --- /dev/null +++ b/web/tailchat.d.ts @@ -0,0 +1,214 @@ +/** + * 该文件由 Tailchat 自动生成 + * 生成命令: pnpm run plugins:declaration:generate + */ + +/** + * Tailchat 通用 + */ +declare module '@capital/common' { + export const useGroupPanelParams: any; + + export const openModal: any; + + export const closeModal: any; + + export const ModalWrapper: any; + + export const useModalContext: any; + + export const openConfirmModal: any; + + export const openReconfirmModal: any; + + export const Loadable: any; + + export const getGlobalState: any; + + export const getJWTUserInfo: any; + + export const dataUrlToFile: any; + + export const urlSearchStringify: any; + + export const urlSearchParse: any; + + export const appendUrlSearch: any; + + export const useGroupIdContext: any; + + export const getServiceUrl: any; + + export const getCachedUserInfo: any; + + export const getCachedConverseInfo: any; + + export const localTrans: any; + + export const getLanguage: any; + + export const sharedEvent: any; + + export const useAsync: any; + + export const useAsyncFn: any; + + export const useAsyncRefresh: any; + + export const useAsyncRequest: any; + + export const uploadFile: any; + + export const showToasts: any; + + export const showErrorToasts: any; + + export const fetchAvailableServices: any; + + export const isValidStr: any; + + export const useGroupPanelInfo: any; + + export const sendMessage: any; + + export const useLocation: any; + + export const useHistory: any; + + export const createFastFormSchema: any; + + export const fieldSchema: any; + + export const useCurrentUserInfo: any; + + export const createPluginRequest: any; + + export const postRequest: any; + + export const pluginCustomPanel: any; + + export const regCustomPanel: any; + + export const pluginGroupPanel: any; + + export const regGroupPanel: any; + + export const messageInterpreter: any; + + export const regMessageInterpreter: any; + + export const getMessageRender: any; + + export const regMessageRender: any; + + export const getMessageTextDecorators: any; + + export const regMessageTextDecorators: any; + + export const ChatInputActionContextProps: any; + + export const pluginChatInputActions: any; + + export const regChatInputAction: any; + + export const regSocketEventListener: any; + + export const pluginColorScheme: any; + + export const regPluginColorScheme: any; + + export const pluginInspectServices: any; + + export const regInspectService: any; + + export const pluginMessageExtraParsers: any; + + export const regMessageExtraParser: any; + + export const pluginRootRoute: any; + + export const regPluginRootRoute: any; + + export const pluginPanelActions: any; + + export const regPluginPanelAction: any; +} + +/** + * Tailchat 组件 + */ +declare module '@capital/component' { + export const Button: any; + + export const Checkbox: any; + + export const Input: any; + + export const Divider: any; + + export const Space: any; + + export const Menu: any; + + export const Table: any; + + export const Switch: any; + + export const Tooltip: any; + + export const Avatar: any; + + export const TextArea: any; + + export const Image: any; + + export const Icon: any; + + export const IconBtn: any; + + export const PillTabs: any; + + export const PillTabPane: any; + + export const LoadingSpinner: any; + + export const WebFastForm: any; + + export const WebMetaForm: any; + + export const createMetaFormSchema: any; + + export const metaFormFieldSchema: any; + + export const FullModalField: any; + + export const DefaultFullModalInputEditorRender: any; + + export const DefaultFullModalTextAreaEditorRender: any; + + export const openModal: any; + + export const closeModal: any; + + export const ModalWrapper: any; + + export const useModalContext: any; + + export const openConfirmModal: any; + + export const openReconfirmModal: any; + + export const Loading: any; + + export const SidebarView: any; + + export const GroupPanelSelector: any; + + export const Emoji: any; + + export const PortalAdd: any; + + export const PortalRemove: any; + + export const ErrorBoundary: any; +}