diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1fd3b1f59a9a0..1da82302f6c76 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -527,6 +527,9 @@ importers: specifier: ^2.3.1 version: 2.3.1 devDependencies: + '@automattic/jetpack-webpack-config': + specifier: workspace:* + version: link:../webpack-config '@babel/core': specifier: 7.24.7 version: 7.24.7 @@ -536,21 +539,6 @@ importers: '@babel/preset-typescript': specifier: 7.24.7 version: 7.24.7(@babel/core@7.24.7) - '@rollup/plugin-commonjs': - specifier: 26.0.1 - version: 26.0.1(rollup@3.29.5) - '@rollup/plugin-json': - specifier: 6.1.0 - version: 6.1.0(rollup@3.29.5) - '@rollup/plugin-node-resolve': - specifier: 15.3.0 - version: 15.3.0(rollup@3.29.5) - '@rollup/plugin-terser': - specifier: 0.4.3 - version: 0.4.3(rollup@3.29.5) - '@rollup/plugin-typescript': - specifier: 12.1.0 - version: 12.1.0(rollup@3.29.5)(tslib@2.5.0)(typescript@5.0.4) '@types/clean-css': specifier: 4.2.11 version: 4.2.11 @@ -566,6 +554,9 @@ importers: jest: specifier: 29.7.0 version: 29.7.0(@types/node@20.16.5) + path-browserify: + specifier: 1.0.1 + version: 1.0.1 playwright: specifier: 1.45.1 version: 1.45.1 @@ -575,12 +566,9 @@ importers: prettier: specifier: npm:wp-prettier@3.0.3 version: wp-prettier@3.0.3 - rollup: - specifier: 3.29.5 - version: 3.29.5 - rollup-plugin-polyfill-node: - specifier: 0.13.0 - version: 0.13.0(rollup@3.29.5) + process: + specifier: 0.11.10 + version: 0.11.10 source-map: specifier: 0.7.4 version: 0.7.4 @@ -595,10 +583,13 @@ importers: version: 5.0.4 webpack: specifier: 5.94.0 - version: 5.94.0 + version: 5.94.0(webpack-cli@4.9.1) + webpack-cli: + specifier: 4.9.1 + version: 4.9.1(webpack@5.94.0) webpack-dev-middleware: specifier: 5.3.4 - version: 5.3.4(webpack@5.94.0) + version: 5.3.4(webpack@5.94.0(webpack-cli@4.9.1)) projects/js-packages/eslint-changed: dependencies: @@ -3352,9 +3343,6 @@ importers: history: specifier: 5.3.0 version: 5.3.0 - jetpack-boost-critical-css-gen: - specifier: github:automattic/jetpack-boost-critical-css-gen#release-0.0.11 - version: https://codeload.github.com/automattic/jetpack-boost-critical-css-gen/tar.gz/56adf5a550475fd30962cd4e8f8bfcaf71f84177 prettier: specifier: npm:wp-prettier@3.0.3 version: wp-prettier@3.0.3 @@ -3380,6 +3368,9 @@ importers: '@automattic/jetpack-components': specifier: workspace:* version: link:../../js-packages/components + '@automattic/jetpack-critical-css-gen': + specifier: workspace:* + version: link:../../js-packages/critical-css-gen '@automattic/jetpack-image-guide': specifier: workspace:* version: link:../../js-packages/image-guide @@ -3422,9 +3413,15 @@ importers: livereload: specifier: 0.9.3 version: 0.9.3 + path-browserify: + specifier: 1.0.1 + version: 1.0.1 postcss: specifier: 8.4.31 version: 8.4.31 + process: + specifier: 0.11.10 + version: 0.11.10 react: specifier: 18.3.1 version: 18.3.1 @@ -6645,15 +6642,6 @@ packages: rollup: optional: true - '@rollup/plugin-inject@5.0.5': - resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/plugin-json@6.1.0': resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} @@ -9732,6 +9720,7 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -10490,10 +10479,6 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - install@0.13.0: - resolution: {integrity: sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==} - engines: {node: '>= 0.10'} - internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} @@ -10966,12 +10951,8 @@ packages: node-notifier: optional: true - jetpack-boost-critical-css-gen@https://codeload.github.com/automattic/jetpack-boost-critical-css-gen/tar.gz/56adf5a550475fd30962cd4e8f8bfcaf71f84177: - resolution: {tarball: https://codeload.github.com/automattic/jetpack-boost-critical-css-gen/tar.gz/56adf5a550475fd30962cd4e8f8bfcaf71f84177} - version: 0.0.11 - - jiti@2.0.0: - resolution: {integrity: sha512-CJ7e7Abb779OTRv3lomfp7Mns/Sy1+U4pcAx5VbjxCZD5ZM/VJaXPpPjNKjtSvWQy/H86E49REXR34dl1JEz9w==} + jiti@2.1.0: + resolution: {integrity: sha512-Nftp80J8poC3u+93ZxpjstsgfQ5d0o5qyD6yStv32sgnWr74xRxBppEwsUoA/GIdrJpgGRkC1930YkLcAsFdSw==} hasBin: true joi@17.13.3: @@ -11699,85 +11680,6 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - npm@8.19.4: - resolution: {integrity: sha512-3HANl8i9DKnUA89P4KEgVNN28EjSeDCmvEqbzOAuxCFDzdBZzjUl99zgnGpOUumvW5lvJo2HKcjrsc+tfyv1Hw==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - hasBin: true - bundledDependencies: - - '@isaacs/string-locale-compare' - - '@npmcli/arborist' - - '@npmcli/ci-detect' - - '@npmcli/config' - - '@npmcli/fs' - - '@npmcli/map-workspaces' - - '@npmcli/package-json' - - '@npmcli/run-script' - - abbrev - - archy - - cacache - - chalk - - chownr - - cli-columns - - cli-table3 - - columnify - - fastest-levenshtein - - fs-minipass - - glob - - graceful-fs - - hosted-git-info - - ini - - init-package-json - - is-cidr - - json-parse-even-better-errors - - libnpmaccess - - libnpmdiff - - libnpmexec - - libnpmfund - - libnpmhook - - libnpmorg - - libnpmpack - - libnpmpublish - - libnpmsearch - - libnpmteam - - libnpmversion - - make-fetch-happen - - minimatch - - minipass - - minipass-pipeline - - mkdirp - - mkdirp-infer-owner - - ms - - node-gyp - - nopt - - npm-audit-report - - npm-install-checks - - npm-package-arg - - npm-pick-manifest - - npm-profile - - npm-registry-fetch - - npm-user-validate - - npmlog - - opener - - p-map - - pacote - - parse-conflict-json - - proc-log - - qrcode-terminal - - read - - read-package-json - - read-package-json-fast - - readdir-scoped-modules - - rimraf - - semver - - ssri - - tar - - text-table - - tiny-relative-date - - treeverse - - validate-npm-package-name - - which - - write-file-atomic - nspell@2.1.5: resolution: {integrity: sha512-PSStyugKMiD9mHmqI/CR5xXrSIGejUXPlo88FBRq5Og1kO5QwQ5Ilu8D8O5I/SHpoS+mibpw6uKA8rd3vXd2Sg==} @@ -13000,11 +12902,6 @@ packages: resolution: {integrity: sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==} engines: {node: '>=8.3'} - rollup-plugin-polyfill-node@0.13.0: - resolution: {integrity: sha512-FYEvpCaD5jGtyBuBFcQImEGmTxDTPbiHjJdrYIp+mFIwgXiXabxvKUK7ZT9P31ozu2Tqm9llYQMRWsfvTMTAOw==} - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 - rollup-plugin-postcss@4.0.2: resolution: {integrity: sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==} engines: {node: '>=10'} @@ -13742,8 +13639,8 @@ packages: tinycolor2@1.4.2: resolution: {integrity: sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==} - tinyglobby@0.2.8: - resolution: {integrity: sha512-AMLZywN0vbhiZi2neFEaj9VIIxC+PjDMsp0nAK6tpR86LJavZgHqGz0S/FOONwBygC+mu7R0/TyAQw0gx0Mu9Q==} + tinyglobby@0.2.9: + resolution: {integrity: sha512-8or1+BGEdk1Zkkw2ii16qSS7uVrQJPre5A9o/XkWPATkk23FZh/15BKFxPnlTy6vkljZxLqYCzzBMj30ZrSvjw==} engines: {node: '>=12.0.0'} tinyqueue@2.0.3: @@ -16684,14 +16581,6 @@ snapshots: optionalDependencies: rollup: 3.29.5 - '@rollup/plugin-inject@5.0.5(rollup@3.29.5)': - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@3.29.5) - estree-walker: 2.0.2 - magic-string: 0.30.11 - optionalDependencies: - rollup: 3.29.5 - '@rollup/plugin-json@6.1.0(rollup@3.29.5)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@3.29.5) @@ -22818,8 +22707,6 @@ snapshots: ini@1.3.8: {} - install@0.13.0: {} - internal-slot@1.0.7: dependencies: es-errors: 1.3.0 @@ -23551,14 +23438,7 @@ snapshots: - supports-color - ts-node - jetpack-boost-critical-css-gen@https://codeload.github.com/automattic/jetpack-boost-critical-css-gen/tar.gz/56adf5a550475fd30962cd4e8f8bfcaf71f84177: - dependencies: - clean-css: 5.3.3 - css-tree: 2.3.1 - install: 0.13.0 - npm: 8.19.4 - - jiti@2.0.0: {} + jiti@2.1.0: {} joi@17.13.3: dependencies: @@ -24489,8 +24369,6 @@ snapshots: dependencies: path-key: 4.0.0 - npm@8.19.4: {} - nspell@2.1.5: dependencies: is-buffer: 2.0.5 @@ -25836,11 +25714,6 @@ snapshots: - bufferutil - utf-8-validate - rollup-plugin-polyfill-node@0.13.0(rollup@3.29.5): - dependencies: - '@rollup/plugin-inject': 5.0.5(rollup@3.29.5) - rollup: 3.29.5 - rollup-plugin-postcss@4.0.2(postcss@8.4.31): dependencies: chalk: 4.1.2 @@ -26108,11 +25981,11 @@ snapshots: dependencies: bytes-iec: 3.1.1 chokidar: 4.0.1 - jiti: 2.0.0 + jiti: 2.1.0 lilconfig: 3.1.2 nanospinner: 1.1.0 picocolors: 1.1.0 - tinyglobby: 0.2.8 + tinyglobby: 0.2.9 optionalDependencies: '@size-limit/preset-app': 11.1.6(size-limit@11.1.6) @@ -26673,15 +26546,6 @@ snapshots: terser: 5.32.0 webpack: 5.94.0(webpack-cli@4.9.1) - terser-webpack-plugin@5.3.10(webpack@5.94.0): - dependencies: - '@jridgewell/trace-mapping': 0.3.25 - jest-worker: 27.5.1 - schema-utils: 3.3.0 - serialize-javascript: 6.0.2 - terser: 5.32.0 - webpack: 5.94.0 - terser-webpack-plugin@5.3.3(webpack@5.94.0(webpack-cli@4.9.1)): dependencies: '@jridgewell/trace-mapping': 0.3.25 @@ -26733,7 +26597,7 @@ snapshots: tinycolor2@1.4.2: {} - tinyglobby@0.2.8: + tinyglobby@0.2.9: dependencies: fdir: 6.4.0(picomatch@4.0.2) picomatch: 4.0.2 @@ -27197,14 +27061,14 @@ snapshots: webpack: 5.94.0(webpack-cli@4.9.1) webpack-merge: 5.10.0 - webpack-dev-middleware@5.3.4(webpack@5.94.0): + webpack-dev-middleware@5.3.4(webpack@5.94.0(webpack-cli@4.9.1)): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.2.0 - webpack: 5.94.0 + webpack: 5.94.0(webpack-cli@4.9.1) webpack-dev-middleware@6.1.3(webpack@5.94.0(webpack-cli@4.9.1)): dependencies: @@ -27237,36 +27101,6 @@ snapshots: webpack-virtual-modules@0.6.2: {} - webpack@5.94.0: - dependencies: - '@types/estree': 1.0.5 - '@webassemblyjs/ast': 1.12.1 - '@webassemblyjs/wasm-edit': 1.12.1 - '@webassemblyjs/wasm-parser': 1.12.1 - acorn: 8.12.1 - acorn-import-attributes: 1.9.5(acorn@8.12.1) - browserslist: 4.23.1 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.17.1 - es-module-lexer: 1.5.4 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(webpack@5.94.0) - watchpack: 2.4.2 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - webpack@5.94.0(webpack-cli@4.9.1): dependencies: '@types/estree': 1.0.5 diff --git a/projects/js-packages/critical-css-gen/.gitignore b/projects/js-packages/critical-css-gen/.gitignore index 3c55ef1574d22..18c63403d3131 100644 --- a/projects/js-packages/critical-css-gen/.gitignore +++ b/projects/js-packages/critical-css-gen/.gitignore @@ -1,4 +1,4 @@ /vendor /node_modules -/build-node -/build-browser +/build +/tests/build diff --git a/projects/js-packages/critical-css-gen/CHANGELOG.md b/projects/js-packages/critical-css-gen/CHANGELOG.md index b43f3b87f0bd5..429481e6c094b 100644 --- a/projects/js-packages/critical-css-gen/CHANGELOG.md +++ b/projects/js-packages/critical-css-gen/CHANGELOG.md @@ -5,8 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.1.0 - 2024-09-24 +## [1.0.0] - 2024-10-07 + +### Security + +- Security: Fix XSS vulnerability. [#39507] ### Added +- Add /playwright entry point for BrowserInterfacePlaywright. [#39509] + +### Changed + +- Change default entry point of package to include BrowserInterfaceIframe instead of BrowserInterfacePlaywright. [#39509] + +## 0.1.0 - 2024-09-24 +### Added - Initial version. [#38429] + +[1.0.0]: https://github.com/Automattic/jetpack-critical-css-gen/compare/v0.1.0...v1.0.0 diff --git a/projects/js-packages/critical-css-gen/changelog/fix-xss-vulnerability b/projects/js-packages/critical-css-gen/changelog/fix-xss-vulnerability deleted file mode 100644 index 9343c331808dd..0000000000000 --- a/projects/js-packages/critical-css-gen/changelog/fix-xss-vulnerability +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: security - -Security: Fix XSS vulnerability. diff --git a/projects/js-packages/critical-css-gen/package.json b/projects/js-packages/critical-css-gen/package.json index feb13394492ae..1e7886679a3fe 100644 --- a/projects/js-packages/critical-css-gen/package.json +++ b/projects/js-packages/critical-css-gen/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@automattic/jetpack-critical-css-gen", - "version": "0.1.0", + "version": "1.0.0", "description": "A flexible Critical CSS Generator that supports multiple URLs and viewports, with both server-side and client-side generation capabilities.", "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/critical-css-gen/#readme", "bugs": { @@ -15,48 +15,46 @@ "license": "GPL-2.0-or-later", "author": "Automattic", "scripts": { - "build:browser": "rollup -c", - "build:node": "tsc", - "build": "pnpm run clean && pnpm run build:browser && pnpm run build:node", - "clean": "rm -rf build-node/ && rm -rf build-browser/", - "test": "pnpm build && NODE_ENV=test NODE_PATH=./node_modules jest --forceExit --config=tests/config/jest.config.js" + "build": "pnpm run clean && tsc", + "build:test": "pnpm run clean:test && webpack --config tests/data/webpack.config.cjs", + "clean": "rm -rf build/", + "clean:test": "rm -rf tests/build/", + "test": "pnpm build && pnpm build:test && NODE_ENV=test NODE_PATH=./node_modules jest --forceExit --config=tests/config/jest.config.js" }, - "main": "./build-node/node.js", - "browser": "./build-browser/bundle.js", + "main": "./build/browser.js", "devDependencies": { + "@automattic/jetpack-webpack-config": "workspace:*", "@babel/core": "7.24.7", "@babel/preset-env": "7.24.7", "@babel/preset-typescript": "7.24.7", - "@rollup/plugin-commonjs": "26.0.1", - "@rollup/plugin-json": "6.1.0", - "@rollup/plugin-node-resolve": "15.3.0", - "@rollup/plugin-terser": "0.4.3", - "@rollup/plugin-typescript": "12.1.0", "@types/clean-css": "4.2.11", "@types/css-tree": "2.3.8", "@types/node": "^20.4.2", "express": "4.20.0", "jest": "29.7.0", + "path-browserify": "1.0.1", "playwright": "1.45.1", "playwright-core": "^1.45.1", "prettier": "npm:wp-prettier@3.0.3", - "rollup": "3.29.5", - "rollup-plugin-polyfill-node": "0.13.0", + "process": "0.11.10", "source-map": "0.7.4", "source-map-js": "1.2.0", "tslib": "2.5.0", "typescript": "5.0.4", "webpack": "5.94.0", + "webpack-cli": "4.9.1", "webpack-dev-middleware": "5.3.4" }, "exports": { ".": { - "jetpack:src": "./src/node.ts", - "types": "./build-node/node.d.ts", - "browser": "./build-browser/bundle.js", - "import": "./build-node/node.js", - "require": "./build-node/node.js", - "default": "./build-node/node.js" + "jetpack:src": "./src/browser.ts", + "types": "./build/browser.d.ts", + "default": "./build/browser.js" + }, + "./playwright": { + "jetpack:src": "./src/playwright.ts", + "types": "./build/playwright.d.ts", + "default": "./build/playwright.js" } }, "dependencies": { diff --git a/projects/js-packages/critical-css-gen/rollup.config.js b/projects/js-packages/critical-css-gen/rollup.config.js deleted file mode 100644 index 25f20558cafd1..0000000000000 --- a/projects/js-packages/critical-css-gen/rollup.config.js +++ /dev/null @@ -1,47 +0,0 @@ -import commonjs from '@rollup/plugin-commonjs'; -import json from '@rollup/plugin-json'; -import resolve from '@rollup/plugin-node-resolve'; -import terser from '@rollup/plugin-terser'; -import typescript from '@rollup/plugin-typescript'; -import nodePolyfills from 'rollup-plugin-polyfill-node'; - -const sharedPlugins = [ - resolve( { - browser: true, - preferBuiltins: false, - modulesOnly: false, - } ), - typescript( { - tsconfig: 'tsconfig.browser.json', - sourceMap: true, - inlineSources: false, - declaration: false, - } ), - commonjs(), - nodePolyfills(), - json(), -]; - -export default { - input: 'src/browser.ts', - output: [ - { - sourcemap: true, - format: 'iife', - name: 'CriticalCSSGenerator', - file: 'build-browser/bundle.full.js', - }, - { - sourcemap: true, - format: 'iife', - name: 'CriticalCSSGenerator', - file: 'build-browser/bundle.js', - plugins: [ terser() ], - }, - ], - plugins: sharedPlugins, - preserveSymlinks: true, - watch: { - clearScreen: false, - }, -}; diff --git a/projects/js-packages/critical-css-gen/src/node.ts b/projects/js-packages/critical-css-gen/src/playwright.ts similarity index 100% rename from projects/js-packages/critical-css-gen/src/node.ts rename to projects/js-packages/critical-css-gen/src/playwright.ts diff --git a/projects/js-packages/critical-css-gen/tests/data/webpack.config.cjs b/projects/js-packages/critical-css-gen/tests/data/webpack.config.cjs new file mode 100644 index 0000000000000..170020dd2a080 --- /dev/null +++ b/projects/js-packages/critical-css-gen/tests/data/webpack.config.cjs @@ -0,0 +1,50 @@ +const path = require( 'path' ); +const jetpackWebpackConfig = require( '@automattic/jetpack-webpack-config/webpack' ); +const webpack = require( 'webpack' ); + +module.exports = { + entry: path.join( __dirname, '../../src/browser.ts' ), + mode: 'development', + devtool: false, + output: { + ...jetpackWebpackConfig.output, + path: path.join( __dirname, '../build' ), + filename: 'bundle.js', + library: 'CriticalCSSGenerator', + }, + resolve: { + ...jetpackWebpackConfig.resolve, + // These are needed for the build to work, + // otherwise it errors out because of the clean-css dependency. + fallback: { + ...jetpackWebpackConfig.resolve.fallback, + path: require.resolve( 'path-browserify' ), + process: require.resolve( 'process/browser' ), + url: false, + https: false, + http: false, + fs: false, + os: false, + }, + }, + node: false, + plugins: [ + new webpack.ProvidePlugin( { + process: require.resolve( 'process/browser' ), + } ), + ], + module: { + strictExportPresence: true, + rules: [ + // Transpile JavaScript + jetpackWebpackConfig.TranspileRule( { + exclude: /node_modules\//, + } ), + + // Transpile @automattic/jetpack-* in node_modules too. + jetpackWebpackConfig.TranspileRule( { + includeNodeModules: [ '@automattic/jetpack-' ], + } ), + ], + }, +}; diff --git a/projects/js-packages/critical-css-gen/tests/lib/test-server.js b/projects/js-packages/critical-css-gen/tests/lib/test-server.js index 253dc69477b07..580a1d44806ac 100644 --- a/projects/js-packages/critical-css-gen/tests/lib/test-server.js +++ b/projects/js-packages/critical-css-gen/tests/lib/test-server.js @@ -23,10 +23,7 @@ class TestServer { async start() { this.app = express(); - this.app.use( - '/bundle.js', - express.static( require.resolve( '../../build-browser/bundle.full.js' ) ) - ); + this.app.use( '/bundle.js', express.static( require.resolve( '../build/bundle.js' ) ) ); for ( const [ virtualPath, realDirectory ] of Object.entries( this.staticPaths ) ) { this.app.use( '/' + virtualPath, express.static( realDirectory ) ); diff --git a/projects/js-packages/critical-css-gen/tests/unit/generate-critical-css.test.js b/projects/js-packages/critical-css-gen/tests/unit/generate-critical-css.test.js index af4dfddaa15f0..6d5ae48735af6 100644 --- a/projects/js-packages/critical-css-gen/tests/unit/generate-critical-css.test.js +++ b/projects/js-packages/critical-css-gen/tests/unit/generate-critical-css.test.js @@ -1,6 +1,6 @@ const path = require( 'path' ); const { chromium } = require( 'playwright' ); -const { generateCriticalCSS, BrowserInterfacePlaywright } = require( '../../build-node/node.js' ); +const { generateCriticalCSS, BrowserInterfacePlaywright } = require( '../../build/playwright.js' ); const { dataDirectory } = require( '../lib/data-directory.js' ); const mockFetch = require( '../lib/mock-fetch.js' ); const TestServer = require( '../lib/test-server.js' ); diff --git a/projects/js-packages/critical-css-gen/tsconfig.browser.json b/projects/js-packages/critical-css-gen/tsconfig.browser.json deleted file mode 100644 index c9e55e8858add..0000000000000 --- a/projects/js-packages/critical-css-gen/tsconfig.browser.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": [ "src/browser.ts" ], - "compilerOptions": { - "outDir": "./build-browser" - } -} diff --git a/projects/js-packages/critical-css-gen/tsconfig.json b/projects/js-packages/critical-css-gen/tsconfig.json index 42e5c2a17fbde..5acf505050177 100644 --- a/projects/js-packages/critical-css-gen/tsconfig.json +++ b/projects/js-packages/critical-css-gen/tsconfig.json @@ -1,9 +1,9 @@ { "extends": "jetpack-js-tools/tsconfig.tsc.json", - "include": [ "src/node.ts" ], + "include": [ "src/browser.ts", "src/playwright.ts" ], "exclude": [ "node_modules/**/*" ], "compilerOptions": { - "outDir": "./build-node", + "outDir": "./build", "target": "es2019", "sourceMap": true, "allowJs": false, diff --git a/projects/js-packages/i18n-loader-webpack-plugin/CHANGELOG.md b/projects/js-packages/i18n-loader-webpack-plugin/CHANGELOG.md index 57aee6f6ed074..ffc383512f946 100644 --- a/projects/js-packages/i18n-loader-webpack-plugin/CHANGELOG.md +++ b/projects/js-packages/i18n-loader-webpack-plugin/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.59] - 2024-10-07 +### Changed +- Updated package dependencies. [#39594] + ## [2.0.58] - 2024-09-10 ### Changed - Updated package dependencies. [#39302] @@ -261,6 +265,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release. +[2.0.59]: https://github.com/Automattic/i18n-loader-webpack-plugin/compare/v2.0.58...v2.0.59 [2.0.58]: https://github.com/Automattic/i18n-loader-webpack-plugin/compare/v2.0.57...v2.0.58 [2.0.57]: https://github.com/Automattic/i18n-loader-webpack-plugin/compare/v2.0.56...v2.0.57 [2.0.56]: https://github.com/Automattic/i18n-loader-webpack-plugin/compare/v2.0.55...v2.0.56 diff --git a/projects/js-packages/i18n-loader-webpack-plugin/changelog/renovate-wordpress-monorepo b/projects/js-packages/i18n-loader-webpack-plugin/changelog/renovate-wordpress-monorepo deleted file mode 100644 index c47cb18e82997..0000000000000 --- a/projects/js-packages/i18n-loader-webpack-plugin/changelog/renovate-wordpress-monorepo +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: changed - -Updated package dependencies. diff --git a/projects/js-packages/i18n-loader-webpack-plugin/package.json b/projects/js-packages/i18n-loader-webpack-plugin/package.json index d41dd8387e9e0..f6eca5e5cf947 100644 --- a/projects/js-packages/i18n-loader-webpack-plugin/package.json +++ b/projects/js-packages/i18n-loader-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@automattic/i18n-loader-webpack-plugin", - "version": "2.0.58", + "version": "2.0.59", "description": "A Webpack plugin to load WordPress i18n when Webpack lazy-loads a bundle.", "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/i18n-loader-webpack-plugin/#readme", "bugs": { diff --git a/projects/js-packages/webpack-config/CHANGELOG.md b/projects/js-packages/webpack-config/CHANGELOG.md index 16ddaf42fd89d..e1b8b8b4bb234 100644 --- a/projects/js-packages/webpack-config/CHANGELOG.md +++ b/projects/js-packages/webpack-config/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 3.4.3 - 2024-10-07 +### Changed +- Updated package dependencies. [#39594] + ## 3.4.2 - 2024-09-26 ### Changed - Updated package dependencies. [#39534] diff --git a/projects/js-packages/webpack-config/changelog/renovate-wordpress-monorepo b/projects/js-packages/webpack-config/changelog/renovate-wordpress-monorepo deleted file mode 100644 index c47cb18e82997..0000000000000 --- a/projects/js-packages/webpack-config/changelog/renovate-wordpress-monorepo +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: changed - -Updated package dependencies. diff --git a/projects/js-packages/webpack-config/package.json b/projects/js-packages/webpack-config/package.json index 3935fdae594c1..987e11a987bb9 100644 --- a/projects/js-packages/webpack-config/package.json +++ b/projects/js-packages/webpack-config/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@automattic/jetpack-webpack-config", - "version": "3.4.2", + "version": "3.4.3", "description": "Library of pieces for webpack config in Jetpack projects.", "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/webpack-config/#readme", "bugs": { diff --git a/projects/packages/codesniffer/Jetpack-Compat-74/ruleset.xml b/projects/packages/codesniffer/Jetpack-Compat-74/ruleset.xml index 21d6e1cc7999e..69aa924c94c9d 100644 --- a/projects/packages/codesniffer/Jetpack-Compat-74/ruleset.xml +++ b/projects/packages/codesniffer/Jetpack-Compat-74/ruleset.xml @@ -90,6 +90,8 @@ + + diff --git a/projects/packages/codesniffer/changelog/renovate-mediawiki-mediawiki-codesniffer-44.x#3 b/projects/packages/codesniffer/changelog/fix-phpcompatibility-new-dev-sniff similarity index 100% rename from projects/packages/codesniffer/changelog/renovate-mediawiki-mediawiki-codesniffer-44.x#3 rename to projects/packages/codesniffer/changelog/fix-phpcompatibility-new-dev-sniff diff --git a/projects/packages/connection/changelog/update-optimize-connection-admin-notice-hook b/projects/packages/connection/changelog/update-optimize-connection-admin-notice-hook new file mode 100644 index 0000000000000..256ab91ca3838 --- /dev/null +++ b/projects/packages/connection/changelog/update-optimize-connection-admin-notice-hook @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Adjust conditions to optimize admin notices callback. diff --git a/projects/packages/connection/src/class-connection-notice.php b/projects/packages/connection/src/class-connection-notice.php index eaaebc1a35860..714eca4eb9a28 100644 --- a/projects/packages/connection/src/class-connection-notice.php +++ b/projects/packages/connection/src/class-connection-notice.php @@ -40,7 +40,7 @@ public function __construct() { * @return void */ public function initialize_notices( $screen ) { - if ( ! in_array( + if ( in_array( $screen->id, array( 'jetpack_page_akismet-key-config', @@ -48,16 +48,8 @@ public function initialize_notices( $screen ) { ), true ) ) { - add_action( 'admin_notices', array( $this, 'delete_user_update_connection_owner_notice' ) ); + return; } - } - - /** - * This is an entire admin notice dedicated to messaging and handling of the case where a user is trying to delete - * the connection owner. - */ - public function delete_user_update_connection_owner_notice() { - global $current_screen; /* * phpcs:disable WordPress.Security.NonceVerification.Recommended @@ -66,14 +58,18 @@ public function delete_user_update_connection_owner_notice() { * page. Nonce will be already checked by WordPress, so we do not need to check ourselves. */ - if ( ! isset( $current_screen->base ) || 'users' !== $current_screen->base ) { - return; - } - - if ( ! isset( $_REQUEST['action'] ) || 'delete' !== $_REQUEST['action'] ) { - return; + if ( isset( $screen->base ) && 'users' === $screen->base + && isset( $_REQUEST['action'] ) && 'delete' === $_REQUEST['action'] + ) { + add_action( 'admin_notices', array( $this, 'delete_user_update_connection_owner_notice' ) ); } + } + /** + * This is an entire admin notice dedicated to messaging and handling of the case where a user is trying to delete + * the connection owner. + */ + public function delete_user_update_connection_owner_notice() { // Get connection owner or bail. $connection_manager = new Manager(); $connection_owner_id = $connection_manager->get_connection_owner_id(); diff --git a/projects/packages/forms/changelog/fix-phpcompatibility-new-dev-sniff b/projects/packages/forms/changelog/fix-phpcompatibility-new-dev-sniff new file mode 100644 index 0000000000000..e7852b6f5a08b --- /dev/null +++ b/projects/packages/forms/changelog/fix-phpcompatibility-new-dev-sniff @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Explicitly pass `$escape` for `fputcsv` to fix new phpcompatibility-dev sniff. Note we may want to change it once we drop PHP <7.4 compat. + + diff --git a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php index fb14654d0ebd6..837f89c7a7bfd 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php +++ b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php @@ -1801,7 +1801,8 @@ public function download_feedback_as_csv() { /** * Print CSV headers */ - fputcsv( $output, $fields ); + // @todo When we drop support for PHP <7.4, consider passing empty-string for `$escape` here for better spec compatibility. + fputcsv( $output, $fields, ',', '"', '\\' ); /** * Print rows to the output. @@ -1820,7 +1821,8 @@ public function download_feedback_as_csv() { /** * Output the complete CSV row */ - fputcsv( $output, $current_row ); + // @todo When we drop support for PHP <7.4, consider passing empty-string for `$escape` here for better spec compatibility. + fputcsv( $output, $current_row, ',', '"', '\\' ); } fclose( $output ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose diff --git a/projects/packages/jetpack-mu-wpcom/changelog/add-review-site-task b/projects/packages/jetpack-mu-wpcom/changelog/add-review-site-task new file mode 100644 index 0000000000000..bbf00ab57fc59 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/add-review-site-task @@ -0,0 +1,4 @@ +Significance: patch +Type: added + +Add the Review site task diff --git a/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad-task-definitions.php b/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad-task-definitions.php index e2f1216493f01..6e6f181dfd897 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad-task-definitions.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad-task-definitions.php @@ -809,6 +809,13 @@ function wpcom_launchpad_get_task_definitions() { 'is_complete_callback' => 'wpcom_launchpad_is_task_option_completed', 'is_visible_callback' => '__return_true', ), + 'review_site' => array( + 'get_title' => function () { + return __( "Review the site's content", 'jetpack-mu-wpcom' ); + }, + 'is_complete_callback' => 'wpcom_launchpad_is_task_option_completed', + 'is_visible_callback' => '__return_true', + ), ); $extended_task_definitions = apply_filters( 'wpcom_launchpad_extended_task_definitions', array() ); diff --git a/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad.php b/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad.php index 4ff9f06c7b1d1..e313808a59b9f 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad.php +++ b/projects/packages/jetpack-mu-wpcom/src/features/launchpad/launchpad.php @@ -321,6 +321,7 @@ function wpcom_launchpad_get_task_list_definitions() { }, 'task_ids' => array( 'migrating_site', + 'review_site', ), ), ); diff --git a/projects/packages/my-jetpack/changelog/settings-disable-inactive-elements b/projects/packages/my-jetpack/changelog/settings-disable-inactive-elements new file mode 100644 index 0000000000000..cd89bbb31e2bb --- /dev/null +++ b/projects/packages/my-jetpack/changelog/settings-disable-inactive-elements @@ -0,0 +1,5 @@ +Significance: patch +Type: fixed +Comment: Disable controls that require user connection. + + diff --git a/projects/packages/videopress/changelog/update-videopress-update-thumb-placeholder-while-updating b/projects/packages/videopress/changelog/update-videopress-update-thumb-placeholder-while-updating new file mode 100644 index 0000000000000..d1cf9f41e5de8 --- /dev/null +++ b/projects/packages/videopress/changelog/update-videopress-update-thumb-placeholder-while-updating @@ -0,0 +1,4 @@ +Significance: patch +Type: fixed + +VideoPress: fix thumbnail update bug that showed the old thumbnail for a couple seconds on the details page. diff --git a/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx b/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx index 769695ec10655..61982c0e5930a 100644 --- a/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx +++ b/projects/packages/videopress/src/client/admin/components/edit-video-details/index.tsx @@ -223,6 +223,7 @@ const EditVideoDetails = () => { selectPosterImageFromLibrary, posterImageSource, libraryAttachment, + isUpdatingPoster, } = useEditDetails(); const { canPerformAction } = usePermission(); @@ -312,7 +313,7 @@ const EditVideoDetails = () => { { processing, isDeleting, updateVideoPrivacy, + isUpdatingPoster, } = useVideo( Number( videoId ), true ); const { playbackToken, isFetchingPlaybackToken } = usePlaybackToken( video ); @@ -331,5 +332,6 @@ export default () => { selectedTime, ...metaEditData, ...posterEditData, + isUpdatingPoster, }; }; diff --git a/projects/packages/waf/changelog/add-waf-body-processor b/projects/packages/waf/changelog/add-waf-body-processor new file mode 100644 index 0000000000000..df675355a4f53 --- /dev/null +++ b/projects/packages/waf/changelog/add-waf-body-processor @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Firewall Runtime: Added support for rule files to specify body parser type. diff --git a/projects/packages/waf/src/class-waf-request.php b/projects/packages/waf/src/class-waf-request.php index 5017a2e25f46c..bbb8bcf3e17f9 100644 --- a/projects/packages/waf/src/class-waf-request.php +++ b/projects/packages/waf/src/class-waf-request.php @@ -328,28 +328,59 @@ public function get_get_vars() { return flatten_array( $_GET ); } + /** + * Returns the POST variables from a JSON body + * + * @return array{string, scalar}[] + */ + private function get_json_post_vars() { + $decoded_json = json_decode( $this->get_body(), true ) ?? array(); + return flatten_array( $decoded_json, 'json', true ); + } + + /** + * Returns the POST variables from a urlencoded body + * + * @return array{string, scalar}[] + */ + private function get_urlencoded_post_vars() { + parse_str( $this->get_body(), $params ); + return flatten_array( $params ); + } + /** * Returns the POST variables * + * @param string $body_processor Manually specifiy the method to use to process the body. Options are 'URLENCODED' and 'JSON'. + * * @return array{string, scalar}[] */ - public function get_post_vars() { + public function get_post_vars( string $body_processor = '' ) { $content_type = $this->get_header( 'content-type' ); + + // If the body processor is specified by the rules file, trust it. + if ( 'URLENCODED' === $body_processor ) { + return $this->get_urlencoded_post_vars(); + } + if ( 'JSON' === $body_processor ) { + return $this->get_json_post_vars(); + } + + // Otherwise, use $_POST if it's not empty. if ( ! empty( $_POST ) ) { - // If $_POST is populated, use it. return flatten_array( $_POST ); - } elseif ( strpos( $content_type, 'application/json' ) !== false ) { - // Attempt to decode JSON requests. - $decoded_json = json_decode( $this->get_body(), true ) ?? array(); - return flatten_array( $decoded_json, 'json', true ); - } elseif ( strpos( $content_type, 'application/x-www-form-urlencoded' ) !== false ) { - // Attempt to decode url-encoded data - parse_str( $this->get_body(), $params ); - return flatten_array( $params ); - } else { - // Don't try to parse any other content types - return array(); } + + // Lastly, try to parse the body based on the content type. + if ( strpos( $content_type, 'application/json' ) !== false ) { + return $this->get_json_post_vars(); + } + if ( strpos( $content_type, 'application/x-www-form-urlencoded' ) !== false ) { + return $this->get_urlencoded_post_vars(); + } + + // Don't try to parse any other content types. + return array(); } /** diff --git a/projects/packages/waf/src/class-waf-runtime.php b/projects/packages/waf/src/class-waf-runtime.php index 394d46aa5a6f1..19300ea804582 100644 --- a/projects/packages/waf/src/class-waf-runtime.php +++ b/projects/packages/waf/src/class-waf-runtime.php @@ -38,6 +38,14 @@ class Waf_Runtime { */ const NORMALIZE_ARRAY_MATCH_VALUES = 2; + /** + * The version of this runtime class. Used by rule files to ensure compatibility. + * + * @since $$next-version$$ + * + * @var int + */ + public $version = 1; /** * Last rule. * @@ -68,6 +76,12 @@ class Waf_Runtime { * @var string */ public $matched_var_name = ''; + /** + * Body Processor. + * + * @var string 'URLENCODED' | 'JSON' | '' + */ + private $body_processor = ''; /** * State. @@ -438,7 +452,7 @@ public function meta( $key ) { $value = $this->args_names( $this->meta( 'args_get' ) ); break; case 'args_post': - $value = $this->request->get_post_vars(); + $value = $this->request->get_post_vars( $this->get_body_processor() ); break; case 'args_post_names': $value = $this->args_names( $this->meta( 'args_post' ) ); @@ -488,6 +502,28 @@ private function state_values( $prefix ) { return $output; } + /** + * Get the body processor. + * + * @return string + */ + private function get_body_processor() { + return $this->body_processor; + } + + /** + * Set the body processor. + * + * @param string $processor Processor to set. Either 'URLENCODED' or 'JSON'. + * + * @return void + */ + public function set_body_processor( $processor ) { + if ( $processor === 'URLENCODED' || $processor === 'JSON' ) { + $this->body_processor = $processor; + } + } + /** * Change a string to all lowercase and replace spaces and underscores with dashes. * diff --git a/projects/packages/waf/tests/php/unit/test-waf-request.php b/projects/packages/waf/tests/php/unit/test-waf-request.php index ce409a4b9e5ac..01c68e5aa5bea 100644 --- a/projects/packages/waf/tests/php/unit/test-waf-request.php +++ b/projects/packages/waf/tests/php/unit/test-waf-request.php @@ -301,6 +301,64 @@ public function testGetVarsPost() { $_POST = array(); } + /** + * Test that the Waf_Request class returns POST-ed data correctly decoded from JSON via Waf_Request::get_post_vars(). + */ + public function testGetVarsPostWithJsonBodyProcessor() { + $_SERVER['CONTENT_TYPE'] = 'irrelevant'; + + $request = $this->mock_request( + array( + 'body' => json_encode( + array( + 'str' => 'value', + 'arr' => array( 'a', 'b', 'c' ), + 'obj' => (object) array( 'foo' => 'bar' ), + ) + ), + ) + ); + $value = $request->get_post_vars( 'JSON' ); + $this->assertIsArray( $value ); + $this->assertContains( array( 'json.str', 'value' ), $value ); + $this->assertContains( array( 'json.arr.0', 'a' ), $value ); + $this->assertContains( array( 'json.arr.1', 'b' ), $value ); + $this->assertContains( array( 'json.arr.2', 'c' ), $value ); + $this->assertContains( array( 'json.obj.foo', 'bar' ), $value ); + + unset( $_SERVER['CONTENT_TYPE'] ); + } + + /** + * Test that the Waf_Request class returns POST-ed data correctly decoded from URLENCODED body via Waf_Request::get_post_vars(). + */ + public function testGetVarsPostWithUrlencodedBodyProcessor() { + $_SERVER['CONTENT_TYPE'] = 'irrelevant'; + + $request = $this->mock_request( + array( + 'body' => ( + http_build_query( + array( + 'str' => 'value', + 'arr' => array( 'a', 'b', 'c' ), + 'obj' => (object) array( 'foo' => 'bar' ), + ) + ) + ), + ) + ); + $value = $request->get_post_vars( 'URLENCODED' ); + $this->assertIsArray( $value ); + $this->assertContains( array( 'str', 'value' ), $value ); + $this->assertContains( array( 'arr[0]', 'a' ), $value ); + $this->assertContains( array( 'arr[1]', 'b' ), $value ); + $this->assertContains( array( 'arr[2]', 'c' ), $value ); + $this->assertContains( array( 'obj[foo]', 'bar' ), $value ); + + unset( $_SERVER['CONTENT_TYPE'] ); + } + /** * Test that the Waf_Request class returns POST-ed data correctly decoded from JSON via Waf_Request::get_post_vars(). */ diff --git a/projects/plugins/boost/app/admin/class-admin.php b/projects/plugins/boost/app/admin/class-admin.php index 81175df6157ec..522692c7f9513 100644 --- a/projects/plugins/boost/app/admin/class-admin.php +++ b/projects/plugins/boost/app/admin/class-admin.php @@ -14,9 +14,7 @@ use Automattic\Jetpack_Boost\Lib\Analytics; use Automattic\Jetpack_Boost\Lib\Environment_Change_Detector; use Automattic\Jetpack_Boost\Lib\Premium_Features; -use Automattic\Jetpack_Boost\Modules\Modules_Index; use Automattic\Jetpack_Boost\Modules\Modules_Setup; -use Automattic\Jetpack_Boost\Modules\Optimizations\Critical_CSS\Critical_CSS; class Admin { /** @@ -83,17 +81,6 @@ public function enqueue_scripts() { */ $internal_path = apply_filters( 'jetpack_boost_asset_internal_path', 'app/assets/dist/' ); - $critical_css_gen_handle = 'jetpack-boost-critical-css-gen'; - - Assets::register_script( - $critical_css_gen_handle, - $internal_path . 'critical-css-gen.js', - JETPACK_BOOST_PATH, - array( - 'in_footer' => true, - ) - ); - $admin_js_handle = 'jetpack-boost-admin'; $admin_js_dependencies = array( @@ -101,11 +88,6 @@ public function enqueue_scripts() { 'wp-components', ); - // Enqueue the critical CSS generator script if Critical CSS is available. - if ( ( new Modules_Index() )->is_module_available( Critical_CSS::get_slug() ) ) { - $admin_js_dependencies[] = $critical_css_gen_handle; - } - Assets::register_script( $admin_js_handle, $internal_path . 'jetpack-boost.js', diff --git a/projects/plugins/boost/app/assets/src/js/features/critical-css/lib/generate-critical-css.ts b/projects/plugins/boost/app/assets/src/js/features/critical-css/lib/generate-critical-css.ts index 94bddd77edbd9..d53a5d93d3453 100644 --- a/projects/plugins/boost/app/assets/src/js/features/critical-css/lib/generate-critical-css.ts +++ b/projects/plugins/boost/app/assets/src/js/features/critical-css/lib/generate-critical-css.ts @@ -6,7 +6,6 @@ import { logPreCriticalCSSGeneration } from '$lib/utils/console'; import { isSameOrigin } from '$lib/utils/is-same-origin'; import { prepareAdminAjaxRequest } from '$lib/utils/make-admin-ajax-request'; import { standardizeError } from '$lib/utils/standardize-error'; -import { SuccessTargetError } from 'jetpack-boost-critical-css-gen'; type Viewport = { width: number; @@ -47,6 +46,12 @@ interface GeneratorCallbacks extends ProviderCallbacks { onFinished: () => void; // Called when the generator is finished, regardless of success or failure. } +async function criticalCssGenerator() { + return await import( + /* webpackChunkName: "jetpack-critical-css-gen" */ '@automattic/jetpack-critical-css-gen' + ); +} + /** * Run the local Critical CSS Generator for a set of providers, if it is not already running. * The result of generation will not be returned to the caller; it will be sent to the given @@ -137,10 +142,11 @@ async function generateCriticalCss( * @param {Object} requestGetParameters - GET parameters to include with each request. * @param {string} proxyNonce - Nonce to use when proxying CSS requests. */ -function createBrowserInterface( +async function createBrowserInterface( requestGetParameters: Record< string, string >, proxyNonce: string ) { + const CriticalCSSGenerator = await criticalCssGenerator(); return new ( class extends CriticalCSSGenerator.BrowserInterfaceIframe { constructor() { super( { @@ -164,10 +170,6 @@ function createBrowserInterface( } )(); } -function isSuccessTargetError( err: unknown ): err is SuccessTargetError { - return err instanceof Error && 'isSuccessTargetError' in err; -} - /** * Generate Critical CSS for the specified Provider Keys, sending each block * to the server. Throws on error or cancellation. @@ -187,6 +189,7 @@ async function generateForKeys( callbacks: ProviderCallbacks, signal: AbortSignal ): Promise< void > { + const CriticalCSSGenerator = await criticalCssGenerator(); try { CriticalCSSGeneratorSchema.parse( CriticalCSSGenerator ); } catch ( err ) { @@ -194,6 +197,12 @@ async function generateForKeys( throw new Error( 'css-gen-library-failure' ); } + function isSuccessTargetError( + err: unknown + ): err is InstanceType< typeof CriticalCSSGenerator.SuccessTargetError > { + return err instanceof CriticalCSSGenerator.SuccessTargetError; + } + // eslint-disable-next-line @wordpress/no-unused-vars-before-return const startTime = Date.now(); let totalSize = 0; @@ -209,7 +218,7 @@ async function generateForKeys( try { const [ css ] = await CriticalCSSGenerator.generateCriticalCSS( { - browserInterface: createBrowserInterface( requestGetParameters, proxyNonce ), + browserInterface: await createBrowserInterface( requestGetParameters, proxyNonce ), urls, viewports, progressCallback: ( step: number, total: number ) => { @@ -336,7 +345,7 @@ function keepAtRule( name: string ): boolean { /** * Helper method to filter out properties that we don't want. * Note this function is used as a filter in the generateCriticalCSS function - * in the jetpack-boost-critical-css-gen library (https://github.com/Automattic/jetpack-boost-critical-css-gen). + * in the @automattic/jetpack-critical-css-gen library (https://github.com/Automattic/jetpack-critical-css-gen). * * This function has a value parameter which is not being used here but other implementations of this * helper function for the library may require the value parameter for filtering. @@ -355,7 +364,7 @@ function keepProperty( name: string, _value: string ): boolean { * Function to verify that a specific page is valid to run the Critical CSS process on it. * * Note that this function is used as a callback in the generateCriticalCSS function - * in the jetpack-boost-critical-css-gen library (https://github.com/Automattic/jetpack-boost-critical-css-gen). + * in the @automattic/jetpack-critical-css-gen library (https://github.com/Automattic/jetpack-critical-css-gen). * * This function has a url and innerWindow parameters which are not being used here but this method * is called with URL and InnerWindow in that library to offer flexibility of the verification for other implementation. diff --git a/projects/plugins/boost/app/assets/src/js/global.d.ts b/projects/plugins/boost/app/assets/src/js/global.d.ts index 2aecfb42192d7..b2f267885c8da 100644 --- a/projects/plugins/boost/app/assets/src/js/global.d.ts +++ b/projects/plugins/boost/app/assets/src/js/global.d.ts @@ -2,8 +2,6 @@ * Type definitions for the global namespace. i.e.: things we expect to find in window. */ -import type { BrowserInterfaceIframe, generateCriticalCSS } from 'jetpack-boost-critical-css-gen'; - // declare global { @@ -38,12 +36,6 @@ declare global { }; }; - // Critical CSS Generator library. - const CriticalCSSGenerator: { - generateCriticalCSS: typeof generateCriticalCSS; - BrowserInterfaceIframe: typeof BrowserInterfaceIframe; - }; - const jpTracksAJAX: { record_ajax_event: ( eventName: string, diff --git a/projects/plugins/boost/changelog/update-use-monorepo-css-gen-package b/projects/plugins/boost/changelog/update-use-monorepo-css-gen-package new file mode 100644 index 0000000000000..12aafd67db156 --- /dev/null +++ b/projects/plugins/boost/changelog/update-use-monorepo-css-gen-package @@ -0,0 +1,5 @@ +Significance: patch +Type: changed +Comment: Use css gen package from monorepo instead of external repo. + + diff --git a/projects/plugins/boost/package.json b/projects/plugins/boost/package.json index 4e538587cdf5f..e47a3b3d6913a 100644 --- a/projects/plugins/boost/package.json +++ b/projects/plugins/boost/package.json @@ -18,7 +18,6 @@ "clsx": "2.1.1", "copy-webpack-plugin": "11.0.0", "history": "5.3.0", - "jetpack-boost-critical-css-gen": "github:automattic/jetpack-boost-critical-css-gen#release-0.0.11", "prettier": "npm:wp-prettier@3.0.3", "react-router-dom": "6.21.0", "react-use-measure": "2.1.1", @@ -29,6 +28,7 @@ "@automattic/jetpack-analytics": "workspace:*", "@automattic/jetpack-boost-score-api": "workspace:*", "@automattic/jetpack-components": "workspace:*", + "@automattic/jetpack-critical-css-gen": "workspace:*", "@automattic/jetpack-image-guide": "workspace:*", "@automattic/jetpack-webpack-config": "workspace:*", "@babel/core": "7.24.7", @@ -43,7 +43,9 @@ "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "livereload": "0.9.3", + "path-browserify": "1.0.1", "postcss": "8.4.31", + "process": "0.11.10", "react": "18.3.1", "react-dom": "18.3.1", "sass": "1.64.1", @@ -71,9 +73,7 @@ "test-e2e:start": "pnpm --prefix tests/e2e run tunnel:up && pnpm --prefix tests/e2e run env:up", "test-e2e:run": "pnpm --prefix tests/e2e run test:run", "test-e2e:stop": "pnpm --prefix tests/e2e run tunnel:down && pnpm --prefix tests/e2e run env:down", - "test-e2e:decrypt-config": "pnpm --prefix tests/e2e run config:decrypt", - "postinstall": "pnpm run postyalc.jetpack-boost-critical-css-gen", - "postyalc.jetpack-boost-critical-css-gen": "symlink='./node_modules/jetpack-boost-critical-css-gen'; new_target='../.yalc/jetpack-boost-critical-css-gen'; [ -d ./.yalc ] && rm -f \"$symlink\" && ln -s \"$new_target\" \"$symlink\" && pnpm run build-concurrently || echo 'Proceeding without yalc'" + "test-e2e:decrypt-config": "pnpm --prefix tests/e2e run config:decrypt" }, "private": true, "repository": { diff --git a/projects/plugins/boost/tests/e2e/package.json b/projects/plugins/boost/tests/e2e/package.json index edea66e0476df..4b5ac7260b261 100644 --- a/projects/plugins/boost/tests/e2e/package.json +++ b/projects/plugins/boost/tests/e2e/package.json @@ -13,7 +13,7 @@ "license": "GPL-2.0-or-later", "author": "Automattic", "scripts": { - "build": "pnpm jetpack build plugins/jetpack plugins/boost js-packages/image-guide packages/plugin-deactivation -v --no-pnpm-install --production", + "build": "pnpm jetpack build plugins/jetpack plugins/boost js-packages/image-guide js-packages/critical-css-gen packages/plugin-deactivation -v --no-pnpm-install --production", "clean": "rm -rf output", "config:decrypt": "openssl enc -md sha1 -aes-256-cbc -d -pass env:CONFIG_KEY -in ./node_modules/jetpack-e2e-commons/config/encrypted.enc -out ./config/local.cjs", "distclean": "rm -rf node_modules", diff --git a/projects/plugins/boost/webpack.config.js b/projects/plugins/boost/webpack.config.js index e7b0392fac252..fd012c1c81f65 100644 --- a/projects/plugins/boost/webpack.config.js +++ b/projects/plugins/boost/webpack.config.js @@ -1,37 +1,10 @@ +const webpack = require( 'webpack' ); const path = require( 'path' ); // eslint-disable-next-line import/no-extraneous-dependencies const jetpackWebpackConfig = require( '@automattic/jetpack-webpack-config/webpack' ); // eslint-disable-next-line import/no-extraneous-dependencies const CopyPlugin = require( 'copy-webpack-plugin' ); -const isProduction = process.env.NODE_ENV === 'production'; - -const cssGenPath = path.dirname( - path.dirname( require.resolve( 'jetpack-boost-critical-css-gen' ) ) -); - -let cssGenCopyPatterns; - -if ( isProduction ) { - cssGenCopyPatterns = [ - { - from: path.join( cssGenPath, 'dist/bundle.js' ), - to: 'critical-css-gen.js', - }, - ]; -} else { - cssGenCopyPatterns = [ - { - from: path.join( cssGenPath, 'dist/bundle.full.js' ), - to: 'critical-css-gen.js', - }, - { - from: path.join( cssGenPath, 'dist/bundle.full.js.map' ), - to: 'bundle.full.js.map', - }, - ]; -} - const imageGuideCopyPatterns = [ { from: path.join( @@ -58,6 +31,9 @@ module.exports = [ }, optimization: { ...jetpackWebpackConfig.optimization, + splitChunks: { + minChunks: 2, + }, }, resolve: { ...jetpackWebpackConfig.resolve, @@ -70,6 +46,20 @@ module.exports = [ $css: path.resolve( './app/assets/src/css' ), $images: path.resolve( './app/assets/static/images' ), }, + // These are needed for the build to work, + // otherwise it errors out because of the clean-css dependency. + fallback: { + ...jetpackWebpackConfig.resolve.fallback, + path: require.resolve( 'path-browserify' ), + process: require.resolve( 'process/browser' ), + url: false, + https: false, + http: false, + os: false, + buffer: false, + events: false, + fs: false, + }, }, node: false, plugins: [ @@ -79,7 +69,9 @@ module.exports = [ }, DependencyExtractionPlugin: { injectPolyfill: true }, } ), - new CopyPlugin( { patterns: cssGenCopyPatterns } ), + new webpack.ProvidePlugin( { + process: require.resolve( 'process/browser' ), + } ), ], module: { strictExportPresence: true, diff --git a/projects/plugins/crm/changelog/fix-phpcompatibility-new-dev-sniff b/projects/plugins/crm/changelog/fix-phpcompatibility-new-dev-sniff new file mode 100644 index 0000000000000..4c112ce236ea6 --- /dev/null +++ b/projects/plugins/crm/changelog/fix-phpcompatibility-new-dev-sniff @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Improve spec compliance of CSV output: `\"` sequences will now be correctly escaped by doubling the `"`. diff --git a/projects/plugins/crm/includes/ZeroBSCRM.CSVImporter.php b/projects/plugins/crm/includes/ZeroBSCRM.CSVImporter.php index 6611b5797af15..83f0b75f28609 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.CSVImporter.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.CSVImporter.php @@ -253,7 +253,8 @@ function jpcrm_csvimporter_lite_preflight_checks( $stage ) { $file = fopen( $file_path, 'r' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen while ( ! feof( $file ) ) { - $csv_data[] = fgetcsv( $file ); + // @todo Consider passing empty-string for `$escape` for better spec compatibility. + $csv_data[] = fgetcsv( $file, 0, ',', '"', '\\' ); } fclose( $file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose diff --git a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Export.php b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Export.php index dbcccd4e4acee..e16fc51a27ebe 100644 --- a/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Export.php +++ b/projects/plugins/crm/includes/ZeroBSCRM.DAL3.Export.php @@ -288,7 +288,8 @@ function jpcrm_export_process_file_export() { $columnHeaders[] = __( 'Owner Username', 'zero-bs-crm' ); } } - fputcsv( $output, $columnHeaders ); + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase -- Just ignore until someone fixes all of these, otherwise we wind up having to rewrite half the function. + fputcsv( $output, $columnHeaders, ',', '"', '' ); // actual export lines @@ -421,7 +422,8 @@ function jpcrm_export_process_file_export() { } // / foreach field in each obj row // output row - fputcsv( $output, $objRow ); + // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase -- Just ignore until someone fixes all of these, otherwise we wind up having to rewrite half the function. + fputcsv( $output, $objRow, ',', '"', '' ); } // / foreach obj } diff --git a/projects/plugins/jetpack/_inc/client/components/settings-card/index.jsx b/projects/plugins/jetpack/_inc/client/components/settings-card/index.jsx index f388ffbb37235..4bc2a10179aa8 100644 --- a/projects/plugins/jetpack/_inc/client/components/settings-card/index.jsx +++ b/projects/plugins/jetpack/_inc/client/components/settings-card/index.jsx @@ -51,6 +51,7 @@ export const SettingsCard = inprops => { const props = { action: '', saveDisabled: false, + isDisabled: false, ...inprops, }; @@ -94,6 +95,7 @@ export const SettingsCard = inprops => { return ; } + const isDisabled = props.isDisabled; const isSaving = props.saveDisabled, feature = props.feature ? props.feature : false; let header = props.header ? props.header : ''; @@ -545,11 +547,17 @@ export const SettingsCard = inprops => {
{ ! props.hideButton && ( -