Skip to content

Commit

Permalink
test: add many tests
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Correa Casablanca <andreu@kindspells.dev>
  • Loading branch information
castarco committed Feb 15, 2024
1 parent eea6d3f commit 164ca85
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ root = true
end_of_line = lf
insert_final_newline = true

[*.{js,mjs,json,ts}]
[*.{js,mjs,mts,json,ts}]
charset = utf-8
indent_style = tab
indent_size = 2
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
#
# SPDX-License-Identifier: MIT

coverage/
node_modules/
pnpm-lock.yaml
4 changes: 2 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"recommended": true
},
"ignore": ["./node_modules/**/*"],
"include": ["./*.json", "./*.js", "./*.mjs", "./*.d.ts"]
"include": ["./*.json", "./*.js", "./*.mjs", "./*.mts", "./*.d.ts"]
},
"formatter": {
"enabled": true,
Expand All @@ -17,7 +17,7 @@
"lineWidth": 80,
"lineEnding": "lf",
"ignore": ["./node_modules/**/*"],
"include": ["./*.json", "./*.mjs", "./*.d.ts"]
"include": ["./*.json", "./*.mjs", "./*.mts", "./*.d.ts"]
},
"javascript": {
"formatter": {
Expand Down
60 changes: 37 additions & 23 deletions core.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ const styleReplacer = (hash, attrs, content) =>
const linkStyleReplacer = (hash, attrs) => `<link${attrs} integrity="${hash}"/>`

const srcRegex = /\s+(src|href)\s*=\s*("(?<src1>.*?)"|'(?<src2>.*?)')/i
const integrityRegex = /\s+integrity\s*=\s*("(?<integrity1>.*?)"|'(?<integrity2>.*?)')/i
const integrityRegex =
/\s+integrity\s*=\s*("(?<integrity1>.*?)"|'(?<integrity2>.*?)')/i
const relStylesheetRegex = /\s+rel\s*=\s*('stylesheet'|"stylesheet")/i

/**
Expand All @@ -63,25 +64,28 @@ const relStylesheetRegex = /\s+rel\s*=\s*('stylesheet'|"stylesheet")/i
* @param {HashesCollection} h
* @returns {Promise<string>}
*/
const updateSriHashes = async (logger, distDir, content, h) => {
export const updateSriHashes = async (logger, distDir, content, h) => {
const processors = /** @type {const} */ ([
{
t: 'Script',
regex: /<script(?<attrs>(\s+[a-z][a-z0-9\-_]*(=('[^']*?'|"[^"]*?"))?)*?)\s*>(?<content>[\s\S]*?)<\/\s*script>/gi,
regex:
/<script(?<attrs>(\s+[a-z][a-z0-9\-_]*(=('[^']*?'|"[^"]*?"))?)*?)\s*>(?<content>[\s\S]*?)<\/\s*script>/gi,
replacer: scriptReplacer,
hasContent: true,
attrsRegex: undefined,
},
{
t: 'Style',
regex: /<style(?<attrs>(\s+[a-z][a-z0-9\-_]*(=('[^']*?'|"[^"]*?"))?)*?)\s*>(?<content>[\s\S]*?)<\/\s*style>/gi,
regex:
/<style(?<attrs>(\s+[a-z][a-z0-9\-_]*(=('[^']*?'|"[^"]*?"))?)*?)\s*>(?<content>[\s\S]*?)<\/\s*style>/gi,
replacer: styleReplacer,
hasContent: true,
attrsRegex: undefined,
},
{
t: 'Style',
regex: /<link(?<attrs>(\s+[a-z][a-z0-9\-_]*(=('[^']*?'|"[^"]*?"))?)*?)\s*\/?>/gi,
regex:
/<link(?<attrs>(\s+[a-z][a-z0-9\-_]*(=('[^']*?'|"[^"]*?"))?)*?)\s*\/?>/gi,
replacer: linkStyleReplacer,
hasContent: false,
attrsRegex: relStylesheetRegex,
Expand Down Expand Up @@ -109,9 +113,13 @@ const updateSriHashes = async (logger, distDir, content, h) => {
const integrityMatch = integrityRegex.exec(attrs)

if (integrityMatch) {
sriHash = integrityMatch.groups?.integrity1 ?? integrityMatch.groups?.integrity2
sriHash =
integrityMatch.groups?.integrity1 ??
integrityMatch.groups?.integrity2
if (sriHash) {
(srcMatch ? h[`ext${t}Hashes`] : h[`inline${t}Hashes`]).add(sriHash)
;(srcMatch ? h[`ext${t}Hashes`] : h[`inline${t}Hashes`]).add(
sriHash,
)
continue
}
}
Expand Down Expand Up @@ -192,7 +200,7 @@ const scanDirectory = async (logger, dirPath, distDir, h) => {
* @param {string} path
* @returns {Promise<boolean>}
*/
const doesFileExist = async path => {
export const doesFileExist = async path => {
try {
await stat(path)
return true
Expand All @@ -209,7 +217,7 @@ const doesFileExist = async path => {
* @param {unknown[]} b
* @returns {boolean}
*/
const arraysEqual = (a, b) => {
export const arraysEqual = (a, b) => {
if (a.length !== b.length) {
return false
}
Expand Down Expand Up @@ -243,7 +251,10 @@ const scanForNestedScripts = async (dirPath, extScriptHashes) => {
for (const file of await readdir(nestedScriptsDir)) {
const filePath = resolve(nestedScriptsDir, file)

if ((await stat(filePath)).isFile() && (['.js', '.mjs'].includes(extname(file)))) {
if (
(await stat(filePath)).isFile() &&
['.js', '.mjs'].includes(extname(file))
) {
const sriHash = generateSRIHash(await readFile(filePath))
extScriptHashes.add(sriHash)
}
Expand All @@ -254,7 +265,10 @@ const scanForNestedScripts = async (dirPath, extScriptHashes) => {
* @param {import('astro').AstroIntegrationLogger} logger
* @param {import('./main.d.ts').StrictSriCspOptions} sriCspOptions
*/
export const generateSRIHashes = async (logger, { distDir, sriHashesModule }) => {
export const generateSRIHashes = async (
logger,
{ distDir, sriHashesModule },
) => {
const h = {
inlineScriptHashes: new Set(),
inlineStyleHashes: new Set(),
Expand Down Expand Up @@ -296,18 +310,18 @@ export const generateSRIHashes = async (logger, { distDir, sriHashesModule }) =>

if (persistHashes) {
let hashesFileContent = '// Do not edit this file manually\n\n'
hashesFileContent += `export const inlineScriptHashes = /** @type {string[]} */ ([${
inlineScriptHashes.map(h => `\n\t'${h}',`).join('')
}${inlineScriptHashes.length > 0 ? '\n' : ''}])\n\n`
hashesFileContent += `export const inlineStyleHashes = /** @type {string[]} */ ([${
inlineStyleHashes.map(h => `\n\t'${h}',`).join('')
}${inlineStyleHashes.length > 0 ? '\n' : ''}])\n\n`
hashesFileContent += `export const extScriptHashes = /** @type {string[]} */ ([${
extScriptHashes.map(h => `\n\t'${h}',`).join('')
}${extScriptHashes.length > 0 ? '\n' : ''}])\n\n`
hashesFileContent += `export const extStyleHashes = /** @type {string[]} */ ([${
extStyleHashes.map(h => `\n\t'${h}',`).join('')
}${extStyleHashes.length > 0 ? '\n' : ''}])\n`
hashesFileContent += `export const inlineScriptHashes = /** @type {string[]} */ ([${inlineScriptHashes
.map(h => `\n\t'${h}',`)
.join('')}${inlineScriptHashes.length > 0 ? '\n' : ''}])\n\n`
hashesFileContent += `export const inlineStyleHashes = /** @type {string[]} */ ([${inlineStyleHashes
.map(h => `\n\t'${h}',`)
.join('')}${inlineStyleHashes.length > 0 ? '\n' : ''}])\n\n`
hashesFileContent += `export const extScriptHashes = /** @type {string[]} */ ([${extScriptHashes
.map(h => `\n\t'${h}',`)
.join('')}${extScriptHashes.length > 0 ? '\n' : ''}])\n\n`
hashesFileContent += `export const extStyleHashes = /** @type {string[]} */ ([${extStyleHashes
.map(h => `\n\t'${h}',`)
.join('')}${extStyleHashes.length > 0 ? '\n' : ''}])\n`

await writeFile(sriHashesModule, hashesFileContent)
}
Expand Down
4 changes: 2 additions & 2 deletions main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { generateSRIHashes } from './core.mjs'
* @param {import('./main.d.ts').SriCspOptions} sriCspOptions
* @returns {import('./main.d.ts').Integration}
*/
export const sriCSP = sriCspOptions =>
/** @satisfies {import('astro').AstroIntegration} */ ({
export const sriCSP =
sriCspOptions => /** @satisfies {import('astro').AstroIntegration} */ ({
name: 'scp-sri-postbuild',
hooks: {
'astro:build:done': async ({ dir, logger }) =>
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
"lint": "pnpm run lint:biome && pnpm run lint:tsc",
"lint:biome": "biome lint .",
"lint:tsc": "tsc -p .",
"test": "pnpm run lint"
"test": "vitest run",
"test:coverage": "vitest run --coverage"
},
"keywords": [
"astro",
Expand All @@ -47,8 +48,10 @@
"devDependencies": {
"@biomejs/biome": "^1.5.3",
"@types/node": "^20.11.19",
"@vitest/coverage-v8": "^1.2.2",
"astro": "^4.4.0",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"vitest": "^1.2.2"
},
"repository": "github:KindSpells/astro-sri-csp",
"funding": [
Expand Down
Loading

0 comments on commit 164ca85

Please sign in to comment.