diff --git a/injected/entry-points/chrome.js b/injected/entry-points/chrome.js index ebae03cd2..61def457f 100644 --- a/injected/entry-points/chrome.js +++ b/injected/entry-points/chrome.js @@ -3,6 +3,7 @@ */ import { isTrackerOrigin } from '../src/trackers'; import { computeLimitedSiteObject } from '../src/utils'; +import contentScopeFeatures from 'ddg:contentScopeFeatures'; /** * Inject all the overwrites into the page. @@ -48,9 +49,10 @@ function init() { const reusableMethodName = '_rm' + randomString(); const reusableSecret = '_r' + randomString(); const siteObject = computeLimitedSiteObject(); - const initialScript = ` - /* global contentScopeFeatures */ - contentScopeFeatures.load({ + + // prettier-ignore + const initialScript = contentScopeFeatures + + `;contentScopeFeatures.load({ platform: { name: 'extension' }, diff --git a/injected/package.json b/injected/package.json index 5e11f8cd4..c10f89fb7 100644 --- a/injected/package.json +++ b/injected/package.json @@ -3,31 +3,22 @@ "scripts": { "postinstall": "npm run copy-sjcl", "copy-sjcl": "node scripts/generateSJCL.js", + "build": "npm run build-types && npm run build-locales && npm run bundle-trackers && npm run bundle-entry-points", "bundle-config": "node scripts/bundleConfig.mjs", - "build": "npm run build-types && npm run build-locales && npm run bundle-trackers && npm run build-firefox && npm run build-chrome && npm run build-apple && npm run build-android && npm run build-windows && npm run build-integration && npm run build-chrome-mv3", + "bundle-entry-points": "node scripts/entry-points.js", + "build-chrome-mv3": "node scripts/entry-points.js", "build-locales": "node scripts/buildLocales.js", - "build-firefox": "node scripts/entry-points.js --platform firefox", - "build-chrome": "node scripts/entry-points.js --platform chrome", - "build-chrome-mv3": "node scripts/entry-points.js --platform chrome-mv3", - "build-apple": "node scripts/entry-points.js --platform apple && node scripts/entry-points.js --platform apple-isolated", - "build-android": "node scripts/entry-points.js --platform android && node scripts/entry-points.js --platform android-autofill-password-import && node scripts/entry-points.js --platform android-broker-protection", - "build-windows": "node scripts/entry-points.js --platform windows", - "build-integration": "node scripts/entry-points.js --platform integration", "build-types": "node scripts/types.mjs", "bundle-trackers": "node scripts/bundleTrackers.mjs --output ../build/tracker-lookup.json", "test-unit": "jasmine --config=unit-test/config.json", - "test-int": "npm run build-integration && npm run playwright", + "test-int": "npm run playwright", "test-int-x": "xvfb-run --server-args='-screen 0 1024x768x24' npm run test-int", "test": "npm run lint && npm run test-unit && npm run test-int && npm run playwright", "serve": "http-server -c-1 --port 3220 integration-test/test-pages", "playwright": "playwright test --grep-invert '@screenshots'", "playwright-screenshots": "playwright test --grep '@screenshots'", - "playwright-headed": "playwright test --headed", - "preplaywright": "npm run build-windows && npm run build-apple && npm run build-android", - "preplaywright-headed": "npm run build-windows && npm run build-apple && npm run build-android", "playwright-e2e": "playwright test -c playwright-e2e.config.js --project duckplayer-e2e", - "playwright-e2e-headed": "npm run playwright-e2e -- --headed", - "preplaywright-e2e": "npm run build-windows && npm run build-apple" + "playwright-e2e-headed": "npm run playwright-e2e -- --headed" }, "type": "module", "dependencies": { @@ -39,18 +30,12 @@ "@canvas/image-data": "^1.0.0", "@duckduckgo/privacy-configuration": "github:duckduckgo/privacy-configuration#main", "@fingerprintjs/fingerprintjs": "^4.5.1", - "@rollup/plugin-commonjs": "^28.0.2", - "@rollup/plugin-node-resolve": "^16.0.0", - "@rollup/plugin-replace": "^6.0.2", "@types/chrome": "^0.0.306", "@types/jasmine": "^5.1.7", "@types/node": "^22.13.5", "@typescript-eslint/eslint-plugin": "^8.20.0", "fast-check": "^3.23.2", "jasmine": "^5.6.0", - "minimist": "^1.2.8", - "rollup": "^4.34.8", - "rollup-plugin-import-css": "^3.5.8", - "rollup-plugin-svg-import": "^3.0.0" + "minimist": "^1.2.8" } } diff --git a/injected/playwright.config.js b/injected/playwright.config.js index fe6cde2fb..3d077bcd8 100644 --- a/injected/playwright.config.js +++ b/injected/playwright.config.js @@ -93,7 +93,7 @@ export default defineConfig({ webServer: { reuseExistingServer: true, ignoreHTTPSErrors: true, - command: 'npm run serve', + command: 'npm run bundle-entry-points && npm run serve', port: 3220, }, use: { diff --git a/injected/scripts/entry-points.js b/injected/scripts/entry-points.js index 6ba06e7d8..64465cf37 100644 --- a/injected/scripts/entry-points.js +++ b/injected/scripts/entry-points.js @@ -1,9 +1,5 @@ -import { postProcess, rollupScript } from './utils/build.js'; +import { bundle } from './utils/build.js'; import { parseArgs, write } from '../../scripts/script-utils.js'; -import { camelcase } from '../src/utils.js'; - -const contentScopePath = 'src/content-scope-features.js'; -const contentScopeName = 'contentScopeFeatures'; /** * @typedef Build @@ -34,11 +30,11 @@ const builds = { output: ['../build/android/contentScope.js'], }, 'android-broker-protection': { - input: 'entry-points/android', + input: 'entry-points/android.js', output: ['../build/android/brokerProtection.js'], }, 'android-autofill-password-import': { - input: 'entry-points/android', + input: 'entry-points/android.js', output: ['../build/android/autofillPasswordImport.js'], }, windows: { @@ -63,59 +59,31 @@ const builds = { }, }; -async function initOther(injectScriptPath, platformName) { - const identName = `inject${camelcase(platformName)}`; - const injectScript = await rollupScript({ - scriptPath: injectScriptPath, - name: identName, - platform: platformName, - }); - const outputScript = injectScript; - return outputScript; -} - -/** - * @param {string} entry - * @param {string} platformName - */ -async function initChrome(entry, platformName) { - const replaceString = '/* global contentScopeFeatures */'; - const injectScript = await rollupScript({ scriptPath: entry, platform: platformName }); - const contentScope = await rollupScript({ - scriptPath: contentScopePath, - name: contentScopeName, - platform: platformName, - }); - // Encode in URI format to prevent breakage (we could choose to just escape ` instead) - // NB: .replace(/\r\n/g, "\n") is needed because in Windows rollup generates CRLF line endings - const encodedString = encodeURI(contentScope.toString().replace(/\r\n/g, '\n')); - const outputScript = injectScript.toString().replace(replaceString, '${decodeURI("' + encodedString + '")}'); - return outputScript; -} - async function init() { // verify the input - const requiredFields = ['platform']; + const requiredFields = []; const args = parseArgs(process.argv.slice(2), requiredFields); - const build = builds[args.platform]; - - if (!build) { - throw new Error('unsupported platform: ' + args.platform); - } - let output; - if (args.platform === 'chrome') { - output = await initChrome(build.input, args.platform); - } else { - output = await initOther(build.input, args.platform); - if (build.postProcess) { - const processResult = await postProcess(output); - output = processResult.code; + // if a platform was given as an argument, just build that platform + if (args.platform) { + const build = builds[args.platform]; + if (!build) { + throw new Error('unsupported platform: ' + args.platform); } + const output = await bundle({ scriptPath: build.input, platform: args.platform }); + + // bundle and write the output + write([build.output], output); + + return; } - // bundle and write the output - write([build.output], output); + // otherwise, just build them all + for (const [injectName, build] of Object.entries(builds)) { + const output = await bundle({ scriptPath: build.input, platform: injectName }); + write(build.output, output); + console.log('✅', injectName, build.output[0]); + } } init(); diff --git a/injected/scripts/utils/build.js b/injected/scripts/utils/build.js index bfca08680..a69680f13 100644 --- a/injected/scripts/utils/build.js +++ b/injected/scripts/utils/build.js @@ -1,30 +1,13 @@ -import * as rollup from 'rollup'; -import * as esbuild from 'esbuild'; -import commonjs from '@rollup/plugin-commonjs'; -import replace from '@rollup/plugin-replace'; -import resolve from '@rollup/plugin-node-resolve'; -import css from 'rollup-plugin-import-css'; -import svg from 'rollup-plugin-svg-import'; import { platformSupport } from '../../src/features.js'; import { readFileSync } from 'fs'; +import { cwd } from '../../../scripts/script-utils.js'; +import { join } from 'path'; +import * as esbuild from 'esbuild'; +const ROOT = join(cwd(import.meta.url), '..', '..'); +const DEBUG = false; -function prefixPlugin(prefixMessage) { - return { - name: 'prefix-plugin', - renderChunk(code) { - return `${prefixMessage}\n${code}`; - }, - }; -} - -function suffixPlugin(suffixMessage) { - return { - name: 'suffix-plugin', - renderChunk(code) { - return `${code}\n${suffixMessage}`; - }, - }; -} +const contentScopePath = 'src/content-scope-features.js'; +const contentScopeName = 'contentScopeFeatures'; const prefixMessage = '/*! © DuckDuckGo ContentScopeScripts protections https://github.com/duckduckgo/content-scope-scripts/ */'; @@ -36,7 +19,7 @@ const prefixMessage = '/*! © DuckDuckGo ContentScopeScripts protections https:/ * @param {string} [params.name] * @return {Promise} */ -export async function rollupScript(params) { +export async function bundle(params) { const { scriptPath, platform, name, featureNames } = params; const extensions = ['firefox', 'chrome', 'chrome-mv3']; @@ -46,45 +29,51 @@ export async function rollupScript(params) { const trackerLookupData = readFileSync('../build/tracker-lookup.json', 'utf8'); trackerLookup = trackerLookupData; } - const suffixMessage = `/*# sourceURL=duckduckgo-privacy-protection.js?scope=${name} */`; - const plugins = [ - css(), - svg({ - stringify: true, - }), - loadFeatures(platform, featureNames), - resolve(), - commonjs(), - replace({ - preventAssignment: true, - values: { - 'import.meta.injectName': JSON.stringify(platform), - // To be replaced by the extension, but prevents tree shaking - 'import.meta.trackerLookup': trackerLookup, - }, - }), - prefixPlugin(prefixMessage), - ]; - - if (platform === 'firefox') { - plugins.push(suffixPlugin(suffixMessage)); - } + const suffixMessage = platform === 'firefox' ? `/*# sourceURL=duckduckgo-privacy-protection.js?scope=${name} */` : ''; + const loadFeaturesPlugin = loadFeatures(platform, featureNames); + // The code is using a global, that we define here which means once tree shaken we get a browser specific output. + + /** @type {import("esbuild").BuildOptions} */ + const buildOptions = { + entryPoints: [scriptPath], + write: false, + outdir: 'build', + target: 'es2021', + format: 'iife', + bundle: true, + metafile: true, + globalName: name, + loader: { + '.css': 'text', + '.svg': 'text', + }, + define: { + 'import.meta.env': 'development', + 'import.meta.injectName': JSON.stringify(platform), + 'import.meta.trackerLookup': trackerLookup, + }, + plugins: [loadFeaturesPlugin, contentFeaturesAsString(platform)], + footer: { + js: suffixMessage, + }, + banner: { + js: prefixMessage, + }, + }; - const bundle = await rollup.rollup({ - input: scriptPath, - plugins, - }); + const result = await esbuild.build(buildOptions); - const generated = await bundle.generate({ - dir: 'build', - format: 'iife', - inlineDynamicImports: true, - name, - // This if for seedrandom causing build issues - globals: { crypto: 'undefined' }, - }); + if (result.metafile && DEBUG) { + console.log(await esbuild.analyzeMetafile(result.metafile)); + } - return generated.output[0].code; + if (result.errors.length === 0 && result.outputFiles) { + return result.outputFiles[0].text || ''; + } else { + console.log(result.errors); + console.log(result.warnings); + throw new Error('could not continue'); + } } /** @@ -92,36 +81,82 @@ export async function rollupScript(params) { * * @param {string} platform * @param {string[]} featureNames + * @returns {import("esbuild").Plugin} */ function loadFeatures(platform, featureNames = platformSupport[platform]) { const pluginId = 'ddg:platformFeatures'; return { - name: pluginId, - resolveId(id) { - if (id === pluginId) return id; - return null; - }, - load(id) { - if (id !== pluginId) return null; - - // convert a list of feature names to - const imports = featureNames.map((featureName) => { - const fileName = getFileName(featureName); - const path = `./src/features/${fileName}.js`; - const ident = `ddg_feature_${featureName}`; + name: 'ddg:platformFeatures', + setup(build) { + build.onResolve({ filter: new RegExp(pluginId) }, (args) => { return { - ident, - importPath: path, + path: args.path, + namespace: pluginId, }; }); + build.onLoad({ filter: /.*/, namespace: pluginId }, () => { + // convert a list of feature names to + const imports = featureNames.map((featureName) => { + const fileName = getFileName(featureName); + const path = `./src/features/${fileName}.js`; + const ident = `ddg_feature_${featureName}`; + return { + ident, + importPath: path, + }; + }); + + const importString = imports.map((imp) => `import ${imp.ident} from ${JSON.stringify(imp.importPath)}`).join(';\n'); + + const exportsString = imports.map((imp) => `${imp.ident}`).join(',\n '); - const importString = imports.map((imp) => `import ${imp.ident} from ${JSON.stringify(imp.importPath)}`).join(';\n'); + const exportString = `export default {\n ${exportsString}\n}`; - const exportsString = imports.map((imp) => `${imp.ident}`).join(',\n '); + return { + loader: 'js', + resolveDir: ROOT, + contents: [importString, exportString].join('\n'), + }; + }); + }, + }; +} - const exportString = `export default {\n ${exportsString}\n}`; +/** + * Create a bundle and allow it to be imported as a string via + * `import bundle from 'ddg:contentScopeFeatures'` + * + * @param {string} platform + */ +function contentFeaturesAsString(platform) { + const pluginId = 'ddg:contentScopeFeatures'; + return { + /** + * Load all platform features based on current + */ + name: pluginId, + setup(build) { + build.onResolve({ filter: new RegExp(pluginId) }, (args) => { + return { + path: args.path, + namespace: pluginId, + }; + }); + build.onLoad({ filter: /.*/, namespace: pluginId }, async () => { + const result = await bundle({ + scriptPath: contentScopePath, + name: contentScopeName, + platform, + }); + + const encodedString = result.replace(/\r\n/g, '\n'); - return [importString, exportString].join('\n'); + return { + loader: 'text', + resolveDir: ROOT, + contents: encodedString, + }; + }); }, }; } @@ -135,18 +170,3 @@ function loadFeatures(platform, featureNames = platformSupport[platform]) { function getFileName(featureName) { return featureName.replace(/([a-zA-Z])(?=[A-Z0-9])/g, '$1-').toLowerCase(); } - -/** - * Apply additional processing to a bundle. This was - * added to solve an issue where certain syntax caused - * parsing to fail in macOS Catalina. - * - * `target: "es2021"` seems to be a 'low enough' target - it's also what's - * used in Autoconsent too. - * - * @param {string} content - * @return {Promise} - */ -export function postProcess(content) { - return esbuild.transform(content, { target: 'es2021', format: 'iife' }); -} diff --git a/injected/src/globals.d.ts b/injected/src/globals.d.ts index cb14b677a..f8c8fe5c6 100644 --- a/injected/src/globals.d.ts +++ b/injected/src/globals.d.ts @@ -47,3 +47,7 @@ declare module 'ddg:platformFeatures' { const output: Record import('./content-feature').default>; export default output; } +declare module 'ddg:contentScopeFeatures' { + const output: string; + export default output; +} diff --git a/injected/unit-test/verify-artifacts.js b/injected/unit-test/verify-artifacts.js index 144d12970..7898f8bb8 100644 --- a/injected/unit-test/verify-artifacts.js +++ b/injected/unit-test/verify-artifacts.js @@ -19,7 +19,7 @@ const checks = { file: join(BUILD, 'android/contentScope.js'), tests: [ { kind: 'maxFileSize', value: CSS_OUTPUT_SIZE }, - { kind: 'containsString', text: 'output.trackerLookup = {', includes: true }, + { kind: 'containsString', text: 'define_import_meta_trackerLookup_default', includes: true }, ], }, chrome: { @@ -45,20 +45,20 @@ const checks = { }, integration: { file: join(BUILD, 'integration/contentScope.js'), - tests: [{ kind: 'containsString', text: 'const trackerLookup = {', includes: true }], + tests: [{ kind: 'containsString', text: 'define_import_meta_trackerLookup_default', includes: true }], }, windows: { file: join(BUILD, 'windows/contentScope.js'), tests: [ { kind: 'maxFileSize', value: CSS_OUTPUT_SIZE }, - { kind: 'containsString', text: 'output.trackerLookup = {', includes: true }, + { kind: 'containsString', text: 'define_import_meta_trackerLookup_default', includes: true }, ], }, apple: { file: join(APPLE_BUILD, 'contentScope.js'), tests: [ { kind: 'maxFileSize', value: CSS_OUTPUT_SIZE }, - { kind: 'containsString', text: 'output.trackerLookup = {', includes: true }, + { kind: 'containsString', text: 'output.trackerLookup = define_import_meta_trackerLookup_default', includes: true }, { kind: 'containsString', text: '#bundledConfig', includes: false }, ], }, diff --git a/package-lock.json b/package-lock.json index a0c4727c5..7c3413c6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "devDependencies": { "@duckduckgo/eslint-config": "github:duckduckgo/eslint-config#v0.1.0", "@playwright/test": "^1.50.1", + "esbuild": "^0.25.0", "eslint": "^9.21.0", "minimist": "^1.2.8", "prettier": "3.4.2", @@ -40,19 +41,13 @@ "@canvas/image-data": "^1.0.0", "@duckduckgo/privacy-configuration": "github:duckduckgo/privacy-configuration#main", "@fingerprintjs/fingerprintjs": "^4.5.1", - "@rollup/plugin-commonjs": "^28.0.2", - "@rollup/plugin-node-resolve": "^16.0.0", - "@rollup/plugin-replace": "^6.0.2", "@types/chrome": "^0.0.306", "@types/jasmine": "^5.1.7", "@types/node": "^22.13.5", "@typescript-eslint/eslint-plugin": "^8.20.0", "fast-check": "^3.23.2", "jasmine": "^5.6.0", - "minimist": "^1.2.8", - "rollup": "^4.34.8", - "rollup-plugin-import-css": "^3.5.8", - "rollup-plugin-svg-import": "^3.0.0" + "minimist": "^1.2.8" } }, "messaging": { @@ -983,13 +978,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@jsdevtools/ono": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", @@ -1093,407 +1081,6 @@ "integrity": "sha512-g5exYbB96NW7+BqtMJ35xFZzgYMijCp4HxQbJtt5UtYCZivMdRl7Hnz7s5Z4jRvX9iBm3goip60eCT7pK96BnQ==", "license": "MIT" }, - "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.2.tgz", - "integrity": "sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.2.0", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/fdir": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.0.tgz", - "integrity": "sha512-0FPvAeVUT/zdWoO0jnb/V5BlBsUSNfkIOtFHzMO4H9MOklrmQFY6FduVHKucNb/aTFxvnGhj4MNj/T1oNdDfNg==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-6.0.2.tgz", - "integrity": "sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "magic-string": "^0.30.3" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", - "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", - "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", - "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", - "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", - "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", - "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", - "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", - "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", - "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", - "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", - "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", - "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", - "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", - "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", - "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", - "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", - "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", - "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", - "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", - "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -1630,13 +1217,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -2298,13 +1878,6 @@ "dev": true, "license": "MIT" }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, - "license": "MIT" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2539,16 +2112,6 @@ "dev": true, "license": "MIT" }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -3380,13 +2943,6 @@ "node": ">=4.0" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4439,13 +3995,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true, - "license": "MIT" - }, "node_modules/is-negative-zero": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", @@ -4505,16 +4054,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -4873,16 +4412,6 @@ "dev": true, "license": "MIT" }, - "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -5954,76 +5483,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rollup": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", - "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.8", - "@rollup/rollup-android-arm64": "4.34.8", - "@rollup/rollup-darwin-arm64": "4.34.8", - "@rollup/rollup-darwin-x64": "4.34.8", - "@rollup/rollup-freebsd-arm64": "4.34.8", - "@rollup/rollup-freebsd-x64": "4.34.8", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", - "@rollup/rollup-linux-arm-musleabihf": "4.34.8", - "@rollup/rollup-linux-arm64-gnu": "4.34.8", - "@rollup/rollup-linux-arm64-musl": "4.34.8", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", - "@rollup/rollup-linux-riscv64-gnu": "4.34.8", - "@rollup/rollup-linux-s390x-gnu": "4.34.8", - "@rollup/rollup-linux-x64-gnu": "4.34.8", - "@rollup/rollup-linux-x64-musl": "4.34.8", - "@rollup/rollup-win32-arm64-msvc": "4.34.8", - "@rollup/rollup-win32-ia32-msvc": "4.34.8", - "@rollup/rollup-win32-x64-msvc": "4.34.8", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-import-css": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/rollup-plugin-import-css/-/rollup-plugin-import-css-3.5.8.tgz", - "integrity": "sha512-a3YsZnwHz66mRHCKHjaPCSfWczczvS/HTkgDc+Eogn0mt/0JZXz0WjK0fzM5WwBpVtOqHB4/gHdmEY40ILsaVg==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.1.3" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "rollup": "^2.x.x || ^3.x.x || ^4.x.x" - } - }, - "node_modules/rollup-plugin-svg-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-svg-import/-/rollup-plugin-svg-import-3.0.0.tgz", - "integrity": "sha512-5fUESTM5hdqJojrwO53JQUO7NespLNx4iLeMsToQfuaGGqGT5sz85Ns5gCDNxLO6yBPbn7p0A/6YA+Rq3clg4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "rollup": "^3.0.0||^4.0.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7495,7 +6954,6 @@ "devDependencies": { "@duckduckgo/messaging": "*", "chokidar": "^4.0.3", - "esbuild": "^0.25.0", "fast-check": "^3.23.2", "http-server": "^14.1.1", "web-resource-inliner": "^6.0.1" diff --git a/package.json b/package.json index 0fc2009ec..987778d9b 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "devDependencies": { "@duckduckgo/eslint-config": "github:duckduckgo/eslint-config#v0.1.0", "@playwright/test": "^1.50.1", + "esbuild": "^0.25.0", "eslint": "^9.21.0", "minimist": "^1.2.8", "prettier": "3.4.2", diff --git a/special-pages/package.json b/special-pages/package.json index 0bac7b631..2f44ed817 100644 --- a/special-pages/package.json +++ b/special-pages/package.json @@ -28,7 +28,6 @@ "devDependencies": { "@duckduckgo/messaging": "*", "chokidar": "^4.0.3", - "esbuild": "^0.25.0", "fast-check": "^3.23.2", "http-server": "^14.1.1", "web-resource-inliner": "^6.0.1"