// @ts-check
+import { parse } from '@babel/parser'
import { existsSync, readdirSync, readFileSync } from 'fs'
+import MagicString from 'magic-string'
import dts from 'rollup-plugin-dts'
+import { walk } from 'estree-walker'
if (!existsSync('temp/packages')) {
console.warn(
})
/**
+ * Patch the dts generated by rollup-plugin-dts
+ * 1. remove exports marked as @internal
+ * 2. Convert all types to inline exports
+ * and remove them from the big export {} declaration
+ * otherwise it gets weird in vitepress `defineComponent` call with
+ * "the inferred type cannot be named without a reference"
+ * 3. Append custom agumentations (jsx, macros)
* @returns {import('rollup').Plugin}
*/
function patchTypes(pkg) {
return {
name: 'patch-types',
renderChunk(code) {
- // 1. TODO remove entries marked with @private
- // 2. append pkg specific types
+ const s = new MagicString(code)
+ const ast = parse(code, {
+ plugins: ['typescript'],
+ sourceType: 'module'
+ })
+
+ /**
+ * @param {import('@babel/types').Node} node
+ * @returns {boolean}
+ */
+ function removeInternal(node) {
+ if (
+ node.leadingComments &&
+ node.leadingComments.some(c => {
+ return c.type === 'CommentBlock' && /@internal\b/.test(c.value)
+ })
+ ) {
+ /** @type {any} */
+ const n = node
+ let id
+ if (n.id && n.id.type === 'Identifier') {
+ id = n.id.name
+ } else if (n.key && n.key.type === 'Identifier') {
+ id = n.key.name
+ }
+ if (id) {
+ s.overwrite(
+ // @ts-ignore
+ node.leadingComments[0].start,
+ node.end,
+ `/* removed internal: ${id} */`
+ )
+ } else {
+ // @ts-ignore
+ s.remove(node.leadingComments[0].start, node.end)
+ }
+ return true
+ }
+ return false
+ }
+
+ const shouldRemoveExport = new Set()
+ // pass 1: remove internals + add exports
+ for (const node of ast.program.body) {
+ if (
+ (node.type === 'TSTypeAliasDeclaration' ||
+ node.type === 'TSInterfaceDeclaration') &&
+ !node.id.name.startsWith(`_`)
+ ) {
+ shouldRemoveExport.add(node.id.name)
+ if (!removeInternal(node)) {
+ // @ts-ignore
+ s.prependLeft(node.start, `export `)
+ // traverse further for internal properties
+ if (node.type === 'TSInterfaceDeclaration') {
+ node.body.body.forEach(removeInternal)
+ } else if (node.type === 'TSTypeAliasDeclaration') {
+ // @ts-ignore
+ walk(node.typeAnnotation, {
+ enter(node) {
+ // @ts-ignore
+ if (removeInternal(node)) this.skip()
+ }
+ })
+ }
+ }
+ } else if (removeInternal(node)) {
+ if (node.type === 'VariableDeclaration') {
+ // declare const x
+ for (const decl of node.declarations) {
+ // @ts-ignore
+ shouldRemoveExport.add(decl.id.name)
+ }
+ } else if (
+ node.type === 'TSDeclareFunction' ||
+ node.type === 'TSEnumDeclaration'
+ ) {
+ // declare function
+ // @ts-ignore
+ shouldRemoveExport.add(node.id.name)
+ } else {
+ throw new Error(
+ `unhandled export type marked as @internal: ${node.type}`
+ )
+ }
+ }
+ }
+ // pass 2: remove exports
+ for (const node of ast.program.body) {
+ if (node.type === 'ExportNamedDeclaration' && !node.source) {
+ for (let i = 0; i < node.specifiers.length; i++) {
+ const spec = node.specifiers[i]
+ if (
+ spec.type === 'ExportSpecifier' &&
+ shouldRemoveExport.has(spec.local.name)
+ ) {
+ const next = node.specifiers[i + 1]
+ if (next) {
+ // @ts-ignore
+ s.remove(spec.start, next.start)
+ } else {
+ // last one
+ const prev = node.specifiers[i - 1]
+ // @ts-ignore
+ s.remove(prev ? prev.end : spec.start, spec.end)
+ }
+ }
+ }
+ }
+ }
+ code = s.toString()
+
+ // append pkg specific types
const additionalTypeDir = `packages/${pkg}/types`
if (existsSync(additionalTypeDir)) {
code +=