1- import { promises as fs } from 'fs' ;
1+ import { readFile } from 'fs/promises ' ;
22import { collectGmApi , getMetadata } from './util' ;
33
4- export default ( metafile , transform ) => {
4+ const suffix = '?userscript-metadata' ;
5+
6+ export default ( transform ) => {
7+ const metadataMap = new Map ( ) ;
58 const grantMap = new Map ( ) ;
69 return {
710 name : 'userscript-metadata' ,
8- buildStart ( ) {
9- this . addWatchFile ( metafile ) ;
11+ async resolveId ( source , importer , options ) {
12+ if ( source . endsWith ( suffix ) ) {
13+ const { id } = await this . resolve ( source , importer , options ) ;
14+ metadataMap . set ( importer , id . slice ( 0 , - suffix . length ) ) ;
15+ }
16+ } ,
17+ load ( id ) {
18+ if ( id . endsWith ( suffix ) ) {
19+ return '' ;
20+ }
1021 } ,
1122 transform ( code , id ) {
1223 const ast = this . parse ( code ) ;
@@ -17,8 +28,14 @@ export default (metafile, transform) => {
1728 * Use `renderChunk` instead of `banner` to preserve the metadata after minimization.
1829 * Note that this plugin must be put after `@rollup/plugin-terser`.
1930 */
20- async renderChunk ( code ) {
21- const meta = await fs . readFile ( metafile , 'utf8' ) ;
31+ async renderChunk ( code , chunk ) {
32+ const metadataFile =
33+ chunk . isEntry &&
34+ [ chunk . facadeModuleId , ...Object . keys ( chunk . modules ) ]
35+ . map ( ( id ) => metadataMap . get ( id ) )
36+ . find ( Boolean ) ;
37+ if ( ! metadataFile ) return ;
38+ let metadata = await readFile ( metadataFile , 'utf8' ) ;
2239 const grantSet = new Set ( ) ;
2340 for ( const id of this . getModuleIds ( ) ) {
2441 const grantSetPerFile = grantMap . get ( id ) ;
@@ -28,7 +45,7 @@ export default (metafile, transform) => {
2845 }
2946 }
3047 }
31- let metadata = getMetadata ( meta , grantSet ) ;
48+ metadata = getMetadata ( metadata , grantSet ) ;
3249 if ( transform ) metadata = transform ( metadata ) ;
3350 return `${ metadata } \n\n${ code } ` ;
3451 } ,
0 commit comments