1- import cheerio , { CheerioAPI } from 'cheerio'
1+ import { CheerioAPI , load as cheerioLoad } from 'cheerio'
22import consola from 'consola'
3+ import ContentSecurityPolicy , { type DirectiveDescriptor } from 'csp-dev'
34import debugFactory from 'debug'
45import fse from 'fs-extra'
56import path from 'path'
@@ -24,7 +25,7 @@ export async function prepare() {
2425 }
2526
2627 const htmlContent = fse . readFileSync ( HTML_FILE , 'utf-8' )
27- const $ = cheerio . load ( htmlContent , { decodeEntities : false } )
28+ const $ = cheerioLoad ( htmlContent , { decodeEntities : false } )
2829 return $
2930}
3031
@@ -40,6 +41,33 @@ export function save($: CheerioAPI) {
4041export async function applyData ( ) {
4142 const $ = await prepare ( )
4243
44+ // <meta http-equiv="Content-Security-Policy" content="
45+ {
46+ const cspMeta = $ ( `meta[http-equiv="Content-Security-Policy"]` )
47+ const cspContent = cspMeta . attr ( 'content' )
48+
49+ // csp-dev 没有 trim, 包含很多 `\t\t`
50+ const fixJson = ( json : DirectiveDescriptor ) => {
51+ Object . keys ( json ) . forEach ( ( key ) => {
52+ const value = json [ key ] as string [ ]
53+ json [ key ] = value . map ( ( x ) => x . trim ( ) )
54+ } )
55+ return json
56+ }
57+
58+ debugger
59+ const cspModel = new ContentSecurityPolicy ( cspContent )
60+ const parsed = fixJson ( cspModel . share ( 'json' ) )
61+
62+ if ( ! parsed [ 'script-src' ] ?. includes ( `'unsafe-inline'` ) ) {
63+ parsed [ 'script-src' ] = [ ...( parsed [ 'script-src' ] || [ ] ) , `'unsafe-inline'` ]
64+ const newModel = new ContentSecurityPolicy ( )
65+ newModel . load ( parsed )
66+ const cspContentNew = newModel . share ( 'string' )
67+ cspMeta . attr ( 'content' , cspContentNew )
68+ }
69+ }
70+
4371 // remove all existing tags
4472 $ ( `[${ DATA_ATTR_NAME } ]` ) . remove ( )
4573
@@ -50,17 +78,17 @@ export async function applyData() {
5078 const content = await getContent ( file )
5179 return { file, content }
5280 } ,
53- 5
81+ 5 ,
5482 )
5583
5684 debug (
5785 'after filter out disabled: %O' ,
58- listData . map ( ( x ) => x . file )
86+ listData . map ( ( x ) => x . file ) ,
5987 )
6088
6189 // create new tags
6290 for ( let { file, content } of listData ) {
63- const ext = path . extname ( file )
91+ const ext = path . extname ( file ) . slice ( 1 )
6492 const tagName = ext === 'js' ? 'script' : 'style'
6593 const tag = `\n<${ tagName } ${ DATA_ATTR_NAME } ='${ file } '>\n${ content } \n</${ tagName } >\n`
6694 $ ( 'html' ) . append ( tag )
0 commit comments