mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 06:05:11 +00:00
103 lines
2.8 KiB
TypeScript
103 lines
2.8 KiB
TypeScript
|
import crypto from 'crypto'
|
||
|
import { createUnplugin } from 'unplugin'
|
||
|
import { parse } from 'acorn'
|
||
|
import MagicString from 'magic-string'
|
||
|
import { walk } from 'estree-walker'
|
||
|
import { parseQuery, parseURL } from 'ufo'
|
||
|
|
||
|
function createKey (
|
||
|
source: string,
|
||
|
method: crypto.BinaryToTextEncoding = 'base64'
|
||
|
) {
|
||
|
const hash = crypto.createHash('md5')
|
||
|
hash.update(source)
|
||
|
return hash.digest(method).toString()
|
||
|
}
|
||
|
|
||
|
const keyedFunctions =
|
||
|
/(useStatic|shallowSsrRef|ssrPromise|ssrRef|reqSsrRef|useAsync)/
|
||
|
|
||
|
export const KeyPlugin = createUnplugin(() => {
|
||
|
return {
|
||
|
name: 'nuxt-legacy-capi-key-transform',
|
||
|
enforce: 'pre',
|
||
|
transformInclude (id) {
|
||
|
const { pathname, search } = parseURL(id)
|
||
|
const query = parseQuery(search)
|
||
|
|
||
|
if (id.includes('node_modules')) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
// vue files
|
||
|
if (pathname.endsWith('.vue') && (query.type === 'script' || !search)) {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
// js files
|
||
|
if (pathname.match(/\.((c|m)?j|t)sx?/g)) {
|
||
|
return true
|
||
|
}
|
||
|
},
|
||
|
transform (code, id) {
|
||
|
if (!keyedFunctions.test(code)) { return null }
|
||
|
|
||
|
try {
|
||
|
const { 0: script = code, index: codeIndex = 0 } =
|
||
|
code.match(/(?<=<script[^>]*>)[\S\s.]*?(?=<\/script>)/) || []
|
||
|
const ast = parse(script, { ecmaVersion: 2020, sourceType: 'module' })
|
||
|
const s = new MagicString(code)
|
||
|
|
||
|
walk(ast, {
|
||
|
enter (node) {
|
||
|
const { end } = node as unknown as {
|
||
|
end: number
|
||
|
}
|
||
|
const { callee, arguments: args = [] } = node as {
|
||
|
callee?: {
|
||
|
type?: string
|
||
|
name?: string
|
||
|
property?: { type: string; name: string }
|
||
|
}
|
||
|
arguments?: any[]
|
||
|
}
|
||
|
if (
|
||
|
callee?.type === 'Identifier' ||
|
||
|
callee?.property?.type === 'Identifier'
|
||
|
) {
|
||
|
let method: crypto.BinaryToTextEncoding = 'base64'
|
||
|
|
||
|
switch (callee.name || callee.property?.name) {
|
||
|
case 'useStatic':
|
||
|
if (args.length > 2) { return }
|
||
|
if (args.length === 2) {
|
||
|
s.prependLeft(codeIndex + end - 1, ', undefined')
|
||
|
}
|
||
|
method = 'hex'
|
||
|
break
|
||
|
|
||
|
case 'shallowSsrRef':
|
||
|
case 'ssrPromise':
|
||
|
case 'ssrRef':
|
||
|
case 'reqSsrRef':
|
||
|
case 'useAsync':
|
||
|
if (args.length > 1) { return }
|
||
|
break
|
||
|
|
||
|
default:
|
||
|
return
|
||
|
}
|
||
|
s.appendLeft(
|
||
|
codeIndex + end - 1,
|
||
|
", '" + createKey(`${id}-${end}`, method) + "'"
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
|
||
|
return s.toString()
|
||
|
} catch { }
|
||
|
}
|
||
|
}
|
||
|
})
|