-
Notifications
You must be signed in to change notification settings - Fork 65
/
emitSes.js
79 lines (74 loc) · 2.63 KB
/
emitSes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
const { readFileSync } = require('node:fs')
const path = require('node:path')
const {
sources: { RawSource, ConcatSource },
} = require('webpack')
const lockdownSource = readFileSync(
path.join(require.resolve('ses'), '../lockdown.umd.min.js'),
'utf-8'
)
const lockdownSourcePrefix = `;(function(){\n${lockdownSource}\n})();\n`
module.exports = {
/**
* @param {object} options
* @param {import('webpack').Compilation} options.compilation
* @param {string[]} options.inlineLockdown
* @returns {() => void}
*/
sesPrefixFiles:
({ compilation, inlineLockdown: files }) =>
() => {
files.forEach((file) => {
const asset = compilation.assets[file]
if (!asset) {
throw new Error(
`LavaMoatPlugin: file specified in inlineLockdown not found in compilation: ${file}`
)
}
compilation.assets[file] = new ConcatSource(lockdownSourcePrefix, asset)
})
},
/**
* @param {object} options
* @param {import('webpack').Compilation} options.compilation
* @param {import('webpack').WebpackPluginInstance} [options.HtmlWebpackPluginInUse]
* @param {boolean} [options.HtmlWebpackPluginInterop]
* @returns {() => void}
*/
sesEmitHook:
({ compilation, HtmlWebpackPluginInUse, HtmlWebpackPluginInterop }) =>
() => {
// TODO: to consider: instead manually copy to compiler.options.output.path
const asset = new RawSource(lockdownSource)
compilation.emitAsset('lockdown', asset)
if (HtmlWebpackPluginInUse && HtmlWebpackPluginInterop) {
HtmlWebpackPluginInUse.constructor
// @ts-expect-error - incomplete types
.getHooks(compilation)
.beforeEmit.tapAsync(
'LavaMoatWebpackPlugin-lockdown',
(
/** @type {{ html: string }} */ data,
/** @type {(arg0: null, arg1: any) => void} */ cb
) => {
const scriptTag = '<script src="./lockdown"></script>'
const headTagRegex = /<head[^>]*>/iu
const scriptTagRegex = /<script/iu
if (headTagRegex.test(data.html)) {
data.html = data.html.replace(headTagRegex, `$&${scriptTag}`)
} else if (scriptTagRegex.test(data.html)) {
data.html = data.html.replace(
scriptTagRegex,
`${scriptTag}$&`
)
} else {
throw Error(
'LavaMoat: Could not insert lockdown script tag, no suitable location found in the html template'
)
}
cb(null, data)
}
)
}
},
}