| 
									
										
										
										
											2023-02-03 15:48:12 +08:00
										 |  |  | // @ts-check
 | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  | import assert from 'node:assert/strict' | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  | import { parse } from '@babel/parser' | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  | import { existsSync, readFileSync, readdirSync, writeFileSync } from 'node:fs' | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  | import MagicString from 'magic-string' | 
					
						
							| 
									
										
										
										
											2023-02-03 15:48:12 +08:00
										 |  |  | import dts from 'rollup-plugin-dts' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (!existsSync('temp/packages')) { | 
					
						
							|  |  |  |   console.warn( | 
					
						
							| 
									
										
										
										
											2024-06-14 16:12:47 +08:00
										 |  |  |     'no temp dts files found. run `tsc -p tsconfig.build-browser.json && tsc -p tsconfig.build-node.json` first.', | 
					
						
							| 
									
										
										
										
											2023-02-03 15:48:12 +08:00
										 |  |  |   ) | 
					
						
							|  |  |  |   process.exit(1) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-18 11:39:21 +08:00
										 |  |  | const packages = readdirSync('temp/packages') | 
					
						
							|  |  |  | const targets = process.env.TARGETS ? process.env.TARGETS.split(',') : null | 
					
						
							|  |  |  | const targetPackages = targets | 
					
						
							|  |  |  |   ? packages.filter(pkg => targets.includes(pkg)) | 
					
						
							|  |  |  |   : packages | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-29 12:24:50 +08:00
										 |  |  | export default targetPackages.map( | 
					
						
							|  |  |  |   /** @returns {import('rollup').RollupOptions} */ | 
					
						
							|  |  |  |   pkg => { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       input: `./temp/packages/${pkg}/src/index.d.ts`, | 
					
						
							|  |  |  |       output: { | 
					
						
							|  |  |  |         file: `packages/${pkg}/dist/${pkg}.d.ts`, | 
					
						
							|  |  |  |         format: 'es', | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       plugins: [dts(), patchTypes(pkg), ...(pkg === 'vue' ? [copyMts()] : [])], | 
					
						
							|  |  |  |       onwarn(warning, warn) { | 
					
						
							|  |  |  |         // during dts rollup, everything is externalized by default
 | 
					
						
							|  |  |  |         if ( | 
					
						
							|  |  |  |           warning.code === 'UNRESOLVED_IMPORT' && | 
					
						
							|  |  |  |           !warning.exporter?.startsWith('.') | 
					
						
							|  |  |  |         ) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         warn(warning) | 
					
						
							| 
									
										
										
										
											2023-02-03 15:48:12 +08:00
										 |  |  |       }, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2023-11-29 12:24:50 +08:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2023-02-03 15:48:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |  * Patch the dts generated by rollup-plugin-dts | 
					
						
							| 
									
										
										
										
											2023-10-17 21:10:14 +08:00
										 |  |  |  * 1. Convert all types to inline exports | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |  *    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" | 
					
						
							| 
									
										
										
										
											2023-10-17 21:10:14 +08:00
										 |  |  |  * 2. Append custom augmentations (jsx, macros) | 
					
						
							| 
									
										
										
										
											2023-11-29 12:24:50 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @param {string} pkg | 
					
						
							| 
									
										
										
										
											2023-02-03 15:48:12 +08:00
										 |  |  |  * @returns {import('rollup').Plugin} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function patchTypes(pkg) { | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     name: 'patch-types', | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |     renderChunk(code, chunk) { | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |       const s = new MagicString(code) | 
					
						
							|  |  |  |       const ast = parse(code, { | 
					
						
							|  |  |  |         plugins: ['typescript'], | 
					
						
							|  |  |  |         sourceType: 'module', | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * @param {import('@babel/types').VariableDeclarator | import('@babel/types').TSTypeAliasDeclaration | import('@babel/types').TSInterfaceDeclaration | import('@babel/types').TSDeclareFunction | import('@babel/types').TSInterfaceDeclaration | import('@babel/types').TSEnumDeclaration | import('@babel/types').ClassDeclaration} node | 
					
						
							|  |  |  |        * @param {import('@babel/types').VariableDeclaration} [parentDecl] | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       function processDeclaration(node, parentDecl) { | 
					
						
							|  |  |  |         if (!node.id) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |         assert(node.id.type === 'Identifier') | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |         const name = node.id.name | 
					
						
							|  |  |  |         if (name.startsWith('_')) { | 
					
						
							|  |  |  |           return | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         shouldRemoveExport.add(name) | 
					
						
							| 
									
										
										
										
											2023-10-17 21:10:14 +08:00
										 |  |  |         if (isExported.has(name)) { | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |           const start = (parentDecl || node).start | 
					
						
							|  |  |  |           assert(typeof start === 'number') | 
					
						
							|  |  |  |           s.prependLeft(start, `export `) | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 20:22:29 +08:00
										 |  |  |       const isExported = new Set() | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |       const shouldRemoveExport = new Set() | 
					
						
							| 
									
										
										
										
											2023-03-29 20:22:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // pass 0: check all exported types
 | 
					
						
							|  |  |  |       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') { | 
					
						
							|  |  |  |               isExported.add(spec.local.name) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-17 21:10:14 +08:00
										 |  |  |       // pass 1: add exports
 | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |       for (const node of ast.program.body) { | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |         if (node.type === 'VariableDeclaration') { | 
					
						
							|  |  |  |           processDeclaration(node.declarations[0], node) | 
					
						
							|  |  |  |           if (node.declarations.length > 1) { | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |             assert(typeof node.start === 'number') | 
					
						
							|  |  |  |             assert(typeof node.end === 'number') | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |             throw new Error( | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |               `unhandled declare const with more than one declarators:\n${code.slice( | 
					
						
							|  |  |  |                 node.start, | 
					
						
							|  |  |  |                 node.end, | 
					
						
							|  |  |  |               )}`,
 | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |             ) | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |         } else if ( | 
					
						
							|  |  |  |           node.type === 'TSTypeAliasDeclaration' || | 
					
						
							|  |  |  |           node.type === 'TSInterfaceDeclaration' || | 
					
						
							|  |  |  |           node.type === 'TSDeclareFunction' || | 
					
						
							|  |  |  |           node.type === 'TSEnumDeclaration' || | 
					
						
							|  |  |  |           node.type === 'ClassDeclaration' | 
					
						
							|  |  |  |         ) { | 
					
						
							|  |  |  |           processDeclaration(node) | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |       // pass 2: remove exports
 | 
					
						
							|  |  |  |       for (const node of ast.program.body) { | 
					
						
							|  |  |  |         if (node.type === 'ExportNamedDeclaration' && !node.source) { | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |           let removed = 0 | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |           for (let i = 0; i < node.specifiers.length; i++) { | 
					
						
							|  |  |  |             const spec = node.specifiers[i] | 
					
						
							|  |  |  |             if ( | 
					
						
							|  |  |  |               spec.type === 'ExportSpecifier' && | 
					
						
							|  |  |  |               shouldRemoveExport.has(spec.local.name) | 
					
						
							|  |  |  |             ) { | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |               assert(spec.exported.type === 'Identifier') | 
					
						
							| 
									
										
										
										
											2023-02-06 09:02:41 +08:00
										 |  |  |               const exported = spec.exported.name | 
					
						
							|  |  |  |               if (exported !== spec.local.name) { | 
					
						
							|  |  |  |                 // this only happens if we have something like
 | 
					
						
							|  |  |  |                 //   type Foo
 | 
					
						
							|  |  |  |                 //   export { Foo as Bar }
 | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2023-02-06 09:02:41 +08:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |               const next = node.specifiers[i + 1] | 
					
						
							|  |  |  |               if (next) { | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |                 assert(typeof spec.start === 'number') | 
					
						
							|  |  |  |                 assert(typeof next.start === 'number') | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |                 s.remove(spec.start, next.start) | 
					
						
							|  |  |  |               } else { | 
					
						
							|  |  |  |                 // last one
 | 
					
						
							|  |  |  |                 const prev = node.specifiers[i - 1] | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |                 assert(typeof spec.start === 'number') | 
					
						
							|  |  |  |                 assert(typeof spec.end === 'number') | 
					
						
							|  |  |  |                 s.remove( | 
					
						
							|  |  |  |                   prev | 
					
						
							|  |  |  |                     ? (assert(typeof prev.end === 'number'), prev.end) | 
					
						
							|  |  |  |                     : spec.start, | 
					
						
							|  |  |  |                   spec.end, | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |               removed++ | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |           if (removed === node.specifiers.length) { | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |             assert(typeof node.start === 'number') | 
					
						
							|  |  |  |             assert(typeof node.end === 'number') | 
					
						
							| 
									
										
										
										
											2023-03-30 18:02:27 +08:00
										 |  |  |             s.remove(node.start, node.end) | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2023-02-04 11:59:42 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       code = s.toString() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // append pkg specific types
 | 
					
						
							| 
									
										
										
										
											2023-02-03 15:48:12 +08:00
										 |  |  |       const additionalTypeDir = `packages/${pkg}/types` | 
					
						
							|  |  |  |       if (existsSync(additionalTypeDir)) { | 
					
						
							|  |  |  |         code += | 
					
						
							|  |  |  |           '\n' + | 
					
						
							|  |  |  |           readdirSync(additionalTypeDir) | 
					
						
							|  |  |  |             .map(file => readFileSync(`${additionalTypeDir}/${file}`, 'utf-8')) | 
					
						
							|  |  |  |             .join('\n') | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return code | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-05-18 13:53:51 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * According to https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#packagejson-exports-imports-and-self-referencing
 | 
					
						
							|  |  |  |  * the only way to correct provide types for both Node ESM and CJS is to have | 
					
						
							|  |  |  |  * two separate declaration files, so we need to copy vue.d.ts to vue.d.mts | 
					
						
							|  |  |  |  * upon build. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @returns {import('rollup').Plugin} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function copyMts() { | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     name: 'copy-vue-mts', | 
					
						
							|  |  |  |     writeBundle(_, bundle) { | 
					
						
							| 
									
										
										
										
											2023-11-30 14:17:51 +08:00
										 |  |  |       assert('code' in bundle['vue.d.ts']) | 
					
						
							|  |  |  |       writeFileSync('packages/vue/dist/vue.d.mts', bundle['vue.d.ts'].code) | 
					
						
							| 
									
										
										
										
											2023-05-18 13:53:51 +08:00
										 |  |  |     }, | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |