This repository has been archived by the owner on Jun 13, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
index.cjs
73 lines (63 loc) · 2.45 KB
/
index.cjs
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
////////////////////////////////////////////////////////////////////////////////
//
// @small-tech/vite-plugin-sri
//
// Subresource integrity (SRI) plugin for Vite (https://vitejs.dev/)
//
// Adds subresource integrity hashes to script and stylesheet
// imports from your index.html file at build time.
//
// If you’re looking for a generic Rollup plugin that does the same thing,
// see rollup-plugin-sri by Jonas Kruckenberg that this one was inspired by:
// https://github.com/JonasKruckenberg/rollup-plugin-sri
//
// Like this? Fund us!
// https://small-tech.org/fund-us
//
// Copyright ⓒ 2021-present Aral Balkan, Small Technology Foundation
// License: ISC.
//
////////////////////////////////////////////////////////////////////////////////
'use strict';
const crypto = require('crypto');
const cheerio = require('cheerio');
const fetch = require('node-fetch');
////////////////////////////////////////////////////////////////////////////////
function sri () {
return {
name: 'vite-plugin-sri',
enforce: 'post',
apply: 'build',
async transformIndexHtml(html, context) {
const bundle = context.bundle;
const calculateIntegrityHashes = async (element) => {
let source;
let attributeName = element.attribs.src ? 'src' : 'href';
const resourcePath = element.attribs[attributeName];
if (resourcePath.startsWith('http')) {
// Load remote source from URL.
source = await (await fetch(resourcePath)).buffer();
} else {
// Load local source from bundle.
const resourcePathWithoutLeadingSlash = element.attribs[attributeName].slice(1);
const bundleItem = bundle[resourcePathWithoutLeadingSlash];
source = bundleItem.code || bundleItem.source;
}
element.attribs.integrity = `sha384-${crypto.createHash('sha384').update(source).digest().toString('base64')}`;
};
const $ = cheerio.load(html);
$.prototype.asyncForEach = async function (callback) {
for (let index = 0; index < this.length; index++) {
await callback(this[index], index, this);
}
};
// Implement SRI for scripts and stylesheets.
const scripts = $('script').filter('[src]');
const stylesheets = $('link[rel=stylesheet]').filter('[href]');
await scripts.asyncForEach(calculateIntegrityHashes);
await stylesheets.asyncForEach(calculateIntegrityHashes);
return $.html()
}
}
}
module.exports = sri;