diff --git a/packages/core/package.json b/packages/core/package.json index b5dbba0b..989eb28a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -24,7 +24,8 @@ "scripts": { "prepare": "ts-patch install -s", "build": "vite build", - "types": "pnpm prepare && vue-tsc --declaration --emitDeclarationOnly && tsc -p tsconfig.build.json && shx rm -rf tmp && pnpm lint:dist", + "types": "pnpm prepare && vue-tsc --declaration --emitDeclarationOnly && tsc -p tsconfig.build.json && shx rm -rf tmp && pnpm lint:dist && pnpm run patch", + "patch": "node patch/slots.js && pnpm lint:dist", "theme": "postcss src/style.css -o dist/style.css && postcss src/theme-default.css -o dist/theme-default.css", "lint": "eslint --ext \".js,.jsx,.ts,.tsx\" --fix --ignore-path ../../.gitignore .", "lint:dist": "eslint --ext \".ts,.tsx\" -c .eslintrc.js --fix ./dist", diff --git a/packages/core/patch/slots.js b/packages/core/patch/slots.js new file mode 100644 index 00000000..0ac20c77 --- /dev/null +++ b/packages/core/patch/slots.js @@ -0,0 +1,79 @@ +const { readFile, writeFile } = require('fs/promises') +const { resolve } = require('path') + +/** + * This is a workaround until slots can be properly typed from inside the VueFlow component + * It will overwrite `{}` typings with the correct prop types and add slot types for dynamic node and edge slots + */ + +async function content(path) { + return readFile(path, 'utf8') +} + +const filePath = resolve(__dirname, '../dist/container/VueFlow/VueFlow.vue.d.ts') + +const typeImportsString = `import type { + Connection, + EdgeChange, + EdgeMouseEvent, + EdgeUpdateEvent, + GraphEdge, + GraphNode, + NodeChange, + NodeDragEvent, + NodeMouseEvent, + OnConnectStartParams, + ViewpaneTransform, + VueFlowStore, +} from '../../types'` + +const patchedTypeImports = `import type { + Connection, + ConnectionLineProps, + EdgeChange, + EdgeMouseEvent, + EdgeProps, + EdgeUpdateEvent, + GraphEdge, + GraphNode, + NodeChange, + NodeDragEvent, + NodeMouseEvent, + NodeProps, + OnConnectStartParams, + ViewpaneTransform, + VueFlowStore, +} from '../../types'` + +const unpatchedSlots = `(new () => { + $slots: Record & + Record & { + 'connection-line': (_: {}) => any + 'zoom-pane': (_: {}) => any + 'default': (_: {}) => any + } + })` + +const patchedSlots = `(new () => { + $slots: Record & { + 'connection-line': (connectionLineProps: ConnectionLineProps) => any + 'zoom-pane': () => any + 'default': () => any + } & { + [key: \`node-\${string}\`]: (nodeProps: NodeProps) => any + } & { + [key: \`edge-\${string}\`]: (edgeProps: EdgeProps) => any + } + })` + +const patchSlots = async () => { + const fileContents = await content(filePath) + + const patchedFileContents = fileContents.replace(typeImportsString, patchedTypeImports).replace(unpatchedSlots, patchedSlots) + + await writeFile(filePath, patchedFileContents) +} + +patchSlots() + .then(() => console.log('slots patched')) + .catch(console.log)