diff --git a/.buildkite/scripts/steps/security/third_party_packages.txt b/.buildkite/scripts/steps/security/third_party_packages.txt index a0754034aed94..bcdda8a14b75a 100644 --- a/.buildkite/scripts/steps/security/third_party_packages.txt +++ b/.buildkite/scripts/steps/security/third_party_packages.txt @@ -25,3 +25,7 @@ ink @hey-api/openapi-ts vscode-languageserver-textdocument yaml-language-server +@swc/core +lightningcss +tar-fs +browserslist diff --git a/package.json b/package.json index d4b284f502052..ae734f793e6ea 100644 --- a/package.json +++ b/package.json @@ -1771,6 +1771,7 @@ "@storybook/test": "8.6.17", "@storybook/theming": "8.6.17", "@storybook/types": "8.6.17", + "@swc/core": "1.15.18", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.9.1", "@testing-library/react": "16.3.2", @@ -1914,6 +1915,7 @@ "babel-plugin-transform-typescript-metadata": "0.3.2", "backport": "10.2.0", "blob-polyfill": "9.0.20240710", + "browserslist": "4.28.0", "buildkite-test-collector": "1.8.1", "cache-manager": "7.0.0", "cache-manager-fs-hash": "2.0.0", @@ -2000,6 +2002,7 @@ "keyv": "5.3.4", "license-checker": "25.0.1", "lighthouse": "12.8.2", + "lightningcss": "1.31.1", "listr2": "8.2.5", "lmdb": "3.4.4", "marge": "1.0.1", @@ -2058,6 +2061,7 @@ "swagger-ui-express": "5.0.1", "table": "6.9.0", "tape": "5.9.0", + "tar-fs": "3.1.1", "terser": "5.40.0", "terser-webpack-plugin": "5.3.17", "tough-cookie": "6.0.0", diff --git a/packages/kbn-yarn-install-scripts/config.json b/packages/kbn-yarn-install-scripts/config.json index 5098ef8699e7a..362ef09938ecc 100644 --- a/packages/kbn-yarn-install-scripts/config.json +++ b/packages/kbn-yarn-install-scripts/config.json @@ -113,6 +113,12 @@ "lifecycle": "install", "required": false, "reason": "Builds from source if npm_config_build_from_source=true. Prebuilds are sufficient." + }, + { + "path": "@swc/core", + "lifecycle": "postinstall", + "required": false, + "reason": "Builds native for @swc/core, used by proxy at src/dev/build to optimize assets. Prebuilds are sufficient." } ] -} \ No newline at end of file +} diff --git a/renovate.json b/renovate.json index a007b32ee3752..78d9b961cc4a8 100644 --- a/renovate.json +++ b/renovate.json @@ -4868,6 +4868,42 @@ ], "enabled": true, "minimumReleaseAge": "14 days" + }, + { + "groupName": "@swc/core", + "matchDepNames": ["@swc/core"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "minimumReleaseAge": "14 days", + "enabled": true + }, + { + "groupName": "lightningcss", + "matchDepNames": ["lightningcss"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "minimumReleaseAge": "14 days", + "enabled": true + }, + { + "groupName": "tar-fs", + "matchDepNames": ["tar-fs"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "minimumReleaseAge": "14 days", + "enabled": true + }, + { + "groupName": "browserslist", + "matchDepNames": ["browserslist"], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "minimumReleaseAge": "14 days", + "enabled": true } ], "customManagers": [ @@ -4906,4 +4942,4 @@ "datasourceTemplate": "docker" } ] -} +} \ No newline at end of file diff --git a/src/dev/build/build_distributables.ts b/src/dev/build/build_distributables.ts index 9cd5e42d11e75..7f48786aaf147 100644 --- a/src/dev/build/build_distributables.ts +++ b/src/dev/build/build_distributables.ts @@ -88,10 +88,12 @@ export async function buildDistributables(log: ToolingLog, options: BuildOptions await globalRun(Tasks.CreateXPackNoticeFile); await globalRun(Tasks.DeletePackagesFromBuildRoot); + await globalRun(Tasks.UpdateLicenseFile); await globalRun(Tasks.RemovePackageJsonDeps); await globalRun(Tasks.CleanPackageManagerRelatedFiles); await globalRun(Tasks.CleanExtraFilesFromModules); + await globalRun(Tasks.CleanEmptyFolders); await globalRun(Tasks.FetchAgentVersionsList); } diff --git a/src/dev/build/lib/fs.ts b/src/dev/build/lib/fs.ts index 57ff0078dbe58..aed84eb566560 100644 --- a/src/dev/build/lib/fs.ts +++ b/src/dev/build/lib/fs.ts @@ -12,8 +12,8 @@ import Fsp from 'fs/promises'; import * as Rx from 'rxjs'; import { createHash } from 'crypto'; import { pipeline } from 'stream/promises'; -import { resolve, dirname, isAbsolute, sep } from 'path'; -import { createGunzip } from 'zlib'; +import { resolve, dirname, isAbsolute, basename, sep } from 'path'; +import { createGunzip, createGzip } from 'zlib'; import { inspect } from 'util'; import archiver from 'archiver'; @@ -21,6 +21,7 @@ import globby from 'globby'; import cpy from 'cpy'; import del from 'del'; import * as tar from 'tar'; +import { pack as tarFsPack } from 'tar-fs'; import type { ToolingLog } from '@kbn/tooling-log'; export function assertAbsolute(path: string) { @@ -231,29 +232,37 @@ interface CompressTarOptions { rootDirectoryName?: string; source: string; destination: string; - archiverOptions?: archiver.TarOptions & archiver.CoreOptions; + gzipLevel?: number; } export async function compressTar({ source, destination, - archiverOptions, + gzipLevel = 9, createRootDirectory, rootDirectoryName, -}: CompressTarOptions) { - const output = fs.createWriteStream(destination); - const archive = archiver('tar', archiverOptions); - const folder = rootDirectoryName ? rootDirectoryName : source.split(sep).slice(-1)[0]; - const name = createRootDirectory ? folder : false; - archive.pipe(output); +}: CompressTarOptions): Promise { + assertAbsolute(source); + assertAbsolute(destination); + + const folder = rootDirectoryName || basename(source); let fileCount = 0; - archive.on('entry', (entry) => { - if (entry.stats?.isFile()) { - fileCount += 1; - } + const packStream = tarFsPack(source, { + map(header) { + if (header.type === 'file') { + fileCount += 1; + } + if (createRootDirectory) { + header.name = folder + '/' + header.name; + } + return header; + }, }); - await archive.directory(source, name).finalize(); + const gzip = createGzip({ level: gzipLevel }); + const output = fs.createWriteStream(destination); + + await pipeline(packStream, gzip, output); return fileCount; } @@ -271,7 +280,10 @@ export async function compressZip({ archiverOptions, createRootDirectory, rootDirectoryName, -}: CompressZipOptions) { +}: CompressZipOptions): Promise { + assertAbsolute(source); + assertAbsolute(destination); + const output = fs.createWriteStream(destination); const archive = archiver('zip', archiverOptions); const folder = rootDirectoryName ? rootDirectoryName : source.split(sep).slice(-1)[0]; diff --git a/src/dev/build/lib/integration_tests/fs.test.ts b/src/dev/build/lib/integration_tests/fs.test.ts index 4a24da0e0b5f6..5dba23f31ebd0 100644 --- a/src/dev/build/lib/integration_tests/fs.test.ts +++ b/src/dev/build/lib/integration_tests/fs.test.ts @@ -12,7 +12,17 @@ import { chmodSync, statSync } from 'fs'; import del from 'del'; -import { mkdirp, write, read, getChildPaths, copyAll, getFileHash, untar, gunzip } from '../fs'; +import { + mkdirp, + write, + read, + getChildPaths, + copyAll, + getFileHash, + untar, + gunzip, + compressTar, +} from '../fs'; import { getFips } from 'crypto'; const TMP = resolve(__dirname, '../__tmp__'); @@ -356,3 +366,66 @@ describe('gunzip()', () => { expect(await read(resolve(destination))).toBe('foo\n'); }); }); + +describe('compressTar()', () => { + it('creates a valid .tar.gz that can be extracted with untar', async () => { + const tarPath = resolve(TMP, 'test.tar.gz'); + const fileCount = await compressTar({ + source: resolve(FIXTURES, 'foo_dir'), + destination: tarPath, + createRootDirectory: false, + }); + + expect(fileCount).toBeGreaterThan(0); + expect(statSync(tarPath).size).toBeGreaterThan(0); + + const extracted = resolve(TMP, 'extracted'); + await untar(tarPath, extracted); + + expect(await read(resolve(extracted, 'bar.txt'))).toBe('bar\n'); + expect(await read(resolve(extracted, 'foo/foo.txt'))).toBe('foo\n'); + }); + + it('wraps contents in a root directory when createRootDirectory is true', async () => { + const tarPath = resolve(TMP, 'rooted.tar.gz'); + await compressTar({ + source: resolve(FIXTURES, 'foo_dir'), + destination: tarPath, + createRootDirectory: true, + }); + + const extracted = resolve(TMP, 'extracted_rooted'); + await untar(tarPath, extracted); + + expect(await read(resolve(extracted, 'foo_dir/bar.txt'))).toBe('bar\n'); + expect(await read(resolve(extracted, 'foo_dir/foo/foo.txt'))).toBe('foo\n'); + }); + + it('uses rootDirectoryName when provided', async () => { + const tarPath = resolve(TMP, 'custom_root.tar.gz'); + await compressTar({ + source: resolve(FIXTURES, 'foo_dir'), + destination: tarPath, + createRootDirectory: true, + rootDirectoryName: 'my-custom-root', + }); + + const extracted = resolve(TMP, 'extracted_custom'); + await untar(tarPath, extracted); + + expect(await read(resolve(extracted, 'my-custom-root/bar.txt'))).toBe('bar\n'); + expect(await read(resolve(extracted, 'my-custom-root/foo/foo.txt'))).toBe('foo\n'); + }); + + it('returns accurate file count', async () => { + const tarPath = resolve(TMP, 'count.tar.gz'); + const fileCount = await compressTar({ + source: resolve(FIXTURES, 'foo_dir'), + destination: tarPath, + createRootDirectory: false, + }); + + // foo_dir contains: .bar, bar.txt, foo/foo.txt + expect(fileCount).toBe(3); + }); +}); diff --git a/src/dev/build/lib/scan_copy.ts b/src/dev/build/lib/scan_copy.ts index 5909cf53df878..ac166d1f3a061 100644 --- a/src/dev/build/lib/scan_copy.ts +++ b/src/dev/build/lib/scan_copy.ts @@ -14,6 +14,9 @@ import * as Rx from 'rxjs'; import { assertAbsolute, mkdirp, fsReadDir$ } from './fs'; import { type DirRecord, type FileRecord, type Record, SomePath } from './fs_records'; +// Exclusive create + copy-on-write (reflink) when the filesystem supports it +const COPY_FLAGS = Fs.constants.COPYFILE_EXCL + Fs.constants.COPYFILE_FICLONE; + interface Options { /** * directory to copy from @@ -73,7 +76,7 @@ export async function scanCopy(options: Options) { } return Rx.of(rec); - }) + }, 100) ); const handleGenericRec = async (rec: Record) => { @@ -95,7 +98,7 @@ export async function scanCopy(options: Options) { await handleGenericRec(rec); }).pipe( Rx.mergeMap(() => readDir$(rec)), - Rx.mergeMap((ent) => (ent.type === 'dir' ? handleDir$(ent) : handleFile$(ent))) + Rx.mergeMap((ent) => (ent.type === 'dir' ? handleDir$(ent) : handleFile$(ent)), 100) ); const handleFile$ = (srcRec: FileRecord): Rx.Observable => @@ -107,7 +110,7 @@ export async function scanCopy(options: Options) { flag: 'wx', }); } else { - await Fsp.copyFile(rec.source.abs, rec.dest.abs, Fs.constants.COPYFILE_EXCL); + await Fsp.copyFile(rec.source.abs, rec.dest.abs, COPY_FLAGS); } await handleGenericRec(rec); diff --git a/src/dev/build/lib/scan_delete.ts b/src/dev/build/lib/scan_delete.ts index 2ebaede02c479..b45e075aae116 100644 --- a/src/dev/build/lib/scan_delete.ts +++ b/src/dev/build/lib/scan_delete.ts @@ -68,7 +68,7 @@ export async function scanDelete(directory: string, options: Options) { getPathsToDelete$(directory).pipe( Rx.mergeMap( async (path) => await Fsp.rm(path, { recursive: true, maxRetries: 1 }), - options.concurrency + options.concurrency ?? 20 ), Rx.count() ) diff --git a/src/dev/build/lib/tar_fs.d.ts b/src/dev/build/lib/tar_fs.d.ts new file mode 100644 index 0000000000000..46d456b3ac4e7 --- /dev/null +++ b/src/dev/build/lib/tar_fs.d.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +declare module 'tar-fs' { + interface PackOptions { + map?: (header: { name: string; type: string }) => { name: string; type: string }; + filter?: (name: string) => boolean; + } + + function pack(cwd: string, opts?: PackOptions): NodeJS.ReadableStream; +} diff --git a/src/dev/build/tasks/build_packages_task.ts b/src/dev/build/tasks/build_packages_task.ts index f7d5206a98e94..8ee4d76fe70fd 100644 --- a/src/dev/build/tasks/build_packages_task.ts +++ b/src/dev/build/tasks/build_packages_task.ts @@ -9,10 +9,11 @@ import Path from 'path'; import * as Fsp from 'fs/promises'; +import { cpus } from 'os'; import * as Peggy from '@kbn/peggy'; import * as DotText from '@kbn/dot-text'; -import { asyncForEach } from '@kbn/std'; +import { asyncForEachWithLimit } from '@kbn/std'; import type { TransformConfig } from '@kbn/babel-transform'; import { withFastAsyncTransform } from '@kbn/babel-transform'; import { makeMatcher } from '@kbn/picomatcher'; @@ -121,7 +122,7 @@ export const BuildPackages: Task = { }; await withFastAsyncTransform(transformConfig, async (transform) => { - await asyncForEach(packages, async (pkg) => { + await asyncForEachWithLimit(packages, cpus().length, async (pkg) => { const allPaths = new Set(Array.from(pkgFileMap.getFiles(pkg), (p) => p.abs)); const pkgDistPath = build.resolvePath(pkg.normalizedRepoRelativeDir); const peggyConfigOutputPaths = new Set(); diff --git a/src/dev/build/tasks/create_archives_task.ts b/src/dev/build/tasks/create_archives_task.ts index b5e823c99d15c..93256aca19f7f 100644 --- a/src/dev/build/tasks/create_archives_task.ts +++ b/src/dev/build/tasks/create_archives_task.ts @@ -49,7 +49,7 @@ export const CreateArchives: Task = { destination, archiverOptions: { zlib: { - level: 9, + level: config.isRelease ? 9 : 6, }, }, createRootDirectory: true, @@ -65,12 +65,7 @@ export const CreateArchives: Task = { fileCount: await compressTar({ source, destination, - archiverOptions: { - gzip: true, - gzipOptions: { - level: 9, - }, - }, + gzipLevel: config.isRelease ? 9 : 6, createRootDirectory: true, rootDirectoryName: build.getRootDirectory(platform), }), diff --git a/src/dev/build/tasks/create_cdn_assets_task.ts b/src/dev/build/tasks/create_cdn_assets_task.ts index 0eae63d9980f1..f998629d30136 100644 --- a/src/dev/build/tasks/create_cdn_assets_task.ts +++ b/src/dev/build/tasks/create_cdn_assets_task.ts @@ -108,12 +108,7 @@ export const CreateCdnAssets: Task = { await compressTar({ source: assets, destination: config.resolveFromTarget(`kibana-${buildVersion}-cdn-assets.tar.gz`), - archiverOptions: { - gzip: true, - gzipOptions: { - level: 9, - }, - }, + gzipLevel: 6, createRootDirectory: true, rootDirectoryName: `kibana-${buildVersion}-cdn-assets`, }); diff --git a/src/dev/build/tasks/generate_packages_optimized_assets.ts b/src/dev/build/tasks/generate_packages_optimized_assets.ts index 64b8747185e5e..930c2ae369557 100644 --- a/src/dev/build/tasks/generate_packages_optimized_assets.ts +++ b/src/dev/build/tasks/generate_packages_optimized_assets.ts @@ -8,64 +8,78 @@ */ import Path from 'path'; - -import { pipeline } from 'stream'; -import { promisify } from 'util'; +import Fsp from 'fs/promises'; import fs from 'fs'; +import zlib from 'zlib'; +import { cpus } from 'os'; +import { promisify } from 'util'; -import gulpBrotli from 'gulp-brotli'; -// @ts-expect-error -import gulpPostCSS from 'gulp-postcss'; -// @ts-expect-error -import gulpTerser from 'gulp-terser'; +import { minify } from '@swc/core'; +import { transform as lightningTransform, browserslistToTargets } from 'lightningcss'; +import browserslist from 'browserslist'; +import { asyncForEachWithLimit } from '@kbn/std'; import type { ToolingLog } from '@kbn/tooling-log'; -import terser from 'terser'; -import vfs from 'vinyl-fs'; import globby from 'globby'; import del from 'del'; -import zlib from 'zlib'; import type { Task } from '../lib'; import { write } from '../lib'; const EUI_THEME_RE = /\.v\d\.(light|dark)\.css$/; const ASYNC_CHUNK_RE = /\.chunk\.\d+\.js$/; -const asyncPipeline = promisify(pipeline); const getSize = (paths: string[]) => paths.reduce((acc, path) => acc + fs.statSync(path).size, 0); -async function optimizeAssets(log: ToolingLog, assetDir: string) { +const BROTLI_QUALITY_RELEASE = zlib.constants.BROTLI_MAX_QUALITY; +const BROTLI_QUALITY_SNAPSHOT = 9; +const PARALLEL_CONCURRENCY = cpus().length; +const brotliCompressAsync = promisify(zlib.brotliCompress); +const cssTargets = browserslistToTargets(browserslist()); + +async function optimizeAssets(log: ToolingLog, assetDir: string, brotliQuality: number) { log.info('Creating optimized assets for', assetDir); log.indent(4); try { log.debug('Remove Pre Minify Sourcemaps'); await del(['**/*.map'], { cwd: assetDir }); - log.debug('Minify CSS'); - await asyncPipeline( - vfs.src(['**/*.css'], { cwd: assetDir }), - // eslint-disable-next-line @typescript-eslint/no-var-requires - gulpPostCSS(require('@kbn/optimizer/postcss.config').plugins), - vfs.dest(assetDir) - ); - - log.debug('Minify JS'); - await asyncPipeline( - vfs.src(['**/*.js'], { cwd: assetDir }), - gulpTerser({ compress: { passes: 2 }, mangle: true }, terser.minify), - vfs.dest(assetDir) - ); + log.debug('Minify CSS with Lightning CSS'); + const cssFiles = await globby(['**/*.css'], { cwd: assetDir, absolute: true }); + // lightningcss only exposes a synchronous transform() API (no async variant) + await asyncForEachWithLimit(cssFiles, PARALLEL_CONCURRENCY, async (file) => { + const code = await Fsp.readFile(file); + const result = lightningTransform({ + filename: Path.basename(file), + code, + minify: true, + targets: cssTargets, + }); + await Fsp.writeFile(file, result.code); + }); + + log.debug('Minify JS with SWC'); + const jsFiles = await globby(['**/*.js'], { cwd: assetDir, absolute: true }); + await asyncForEachWithLimit(jsFiles, PARALLEL_CONCURRENCY, async (file) => { + const source = await Fsp.readFile(file, 'utf8'); + const result = await minify(source, { + compress: { passes: 2 }, + mangle: true, + sourceMap: false, + }); + await Fsp.writeFile(file, result.code); + }); log.debug('Brotli compress'); - await asyncPipeline( - vfs.src(['**/*.{js,css}'], { cwd: assetDir }), - gulpBrotli({ + const compressFiles = await globby(['**/*.{js,css}'], { cwd: assetDir, absolute: true }); + await asyncForEachWithLimit(compressFiles, PARALLEL_CONCURRENCY, async (file) => { + const content = await Fsp.readFile(file); + const compressed = await brotliCompressAsync(content, { params: { - [zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_MAX_QUALITY, + [zlib.constants.BROTLI_PARAM_QUALITY]: brotliQuality, }, - }), - vfs.dest(assetDir) - ); + }); + await Fsp.writeFile(file + '.br', compressed); + }); } finally { log.indent(-4); } @@ -148,9 +162,11 @@ export const GeneratePackagesOptimizedAssets: Task = { ); const assetDirs = [npmAssetDir, srcAssetDir]; + const brotliQuality = config.isRelease ? BROTLI_QUALITY_RELEASE : BROTLI_QUALITY_SNAPSHOT; + // process assets in each ui-shared-deps package for (const assetDir of assetDirs) { - await optimizeAssets(log, assetDir); + await optimizeAssets(log, assetDir, brotliQuality); } // analyze assets to produce metrics.json file diff --git a/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts b/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts index 0fce2566d0f80..13aaaf2a61746 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/bundle_dockerfiles.ts @@ -69,12 +69,7 @@ export async function bundleDockerFiles(config: Config, log: ToolingLog, scope: await compressTar({ source: dockerFilesBuildDir, destination: dockerFilesOutputDir, - archiverOptions: { - gzip: true, - gzipOptions: { - level: 9, - }, - }, + gzipLevel: config.isRelease ? 9 : 6, createRootDirectory: false, }); } diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 178d9d40b82a5..ce9a45c244425 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -70,6 +70,7 @@ export const LICENSE_ALLOWED = [ 'Nuclide software', 'Python-2.0', '(Apache-2.0 AND MIT)', + 'Apache-2.0 AND MIT', 'BlueOak-1.0.0', 'WTFPL OR CC0-1.0', ]; diff --git a/typings/tar_fs.d.ts b/typings/tar_fs.d.ts new file mode 100644 index 0000000000000..9730e26f856b7 --- /dev/null +++ b/typings/tar_fs.d.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +declare module 'tar-fs' { + interface PackOptions { + map?: (header: { name: string; type: string }) => { name: string; type: string }; + filter?: (name: string) => boolean; + } + + function pack( + cwd: string, + opts?: PackOptions + ): NodeJS.ReadableStream & { + on(event: 'entry', cb: (header: { type: string }) => void): void; + on(event: string, cb: (...args: unknown[]) => void): void; + }; +} diff --git a/yarn.lock b/yarn.lock index 418aa0a884a46..eddfdadb9a6a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12748,6 +12748,80 @@ resolved "https://registry.yarnpkg.com/@storybook/types/-/types-8.6.17.tgz#720ccd40f57459f96361e2bfca8dc01f3734cf93" integrity sha512-nNlbGulqqk2XzroD5jxcsw+13nWlGxBD9XRAht4Peh71Z4OcdBJCnc9UmHkTgUakmRJ/T6p7xabURDG3KpayIQ== +"@swc/core-darwin-arm64@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.18.tgz#fb487392f7bbe3179166b9b0d128916e39a627af" + integrity sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ== + +"@swc/core-darwin-x64@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.15.18.tgz#0e11fb0a80ebd56cb4417138a938ffc789ead492" + integrity sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg== + +"@swc/core-linux-arm-gnueabihf@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.18.tgz#e7cac4b46d66dfd6b0fedea68877a5678fcf3579" + integrity sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw== + +"@swc/core-linux-arm64-gnu@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.18.tgz#ca888f41be89887f9f6b4afd1cc38a1a596a655d" + integrity sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg== + +"@swc/core-linux-arm64-musl@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.18.tgz#292bb894cf08be522487897f6e2a616cbdd6198a" + integrity sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw== + +"@swc/core-linux-x64-gnu@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.18.tgz#2241fd6a01d88bac32334812660d80ebae88fd12" + integrity sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA== + +"@swc/core-linux-x64-musl@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.18.tgz#7d70f02a383d9dbae18b0d2906ee8b49dfb0b533" + integrity sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g== + +"@swc/core-win32-arm64-msvc@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.18.tgz#6ea2b41d224a5ac84e1addf19fbc584e49698b08" + integrity sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ== + +"@swc/core-win32-ia32-msvc@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.18.tgz#0c498802837ef53452c744964cac1391eb889e4d" + integrity sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg== + +"@swc/core-win32-x64-msvc@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.18.tgz#878b48b38225680aad1e486880a6835461519e53" + integrity sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg== + +"@swc/core@1.15.18": + version "1.15.18" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.15.18.tgz#9eed29c0267d2c262391d4a2e75a3978e3f9dc74" + integrity sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA== + dependencies: + "@swc/counter" "^0.1.3" + "@swc/types" "^0.1.25" + optionalDependencies: + "@swc/core-darwin-arm64" "1.15.18" + "@swc/core-darwin-x64" "1.15.18" + "@swc/core-linux-arm-gnueabihf" "1.15.18" + "@swc/core-linux-arm64-gnu" "1.15.18" + "@swc/core-linux-arm64-musl" "1.15.18" + "@swc/core-linux-x64-gnu" "1.15.18" + "@swc/core-linux-x64-musl" "1.15.18" + "@swc/core-win32-arm64-msvc" "1.15.18" + "@swc/core-win32-ia32-msvc" "1.15.18" + "@swc/core-win32-x64-msvc" "1.15.18" + +"@swc/counter@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== + "@swc/helpers@^0.5.11": version "0.5.15" resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7" @@ -12755,6 +12829,13 @@ dependencies: tslib "^2.8.0" +"@swc/types@^0.1.25": + version "0.1.25" + resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.25.tgz#b517b2a60feb37dd933e542d93093719e4cf1078" + integrity sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g== + dependencies: + "@swc/counter" "^0.1.3" + "@szmarczak/http-timer@^4.0.5": version "4.0.5" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" @@ -16601,7 +16682,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.20.3, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.5, browserslist@^4.27.0: +browserslist@4.28.0, browserslist@^4.0.0, browserslist@^4.20.3, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.24.5, browserslist@^4.27.0: version "4.28.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.0.tgz#9cefece0a386a17a3cd3d22ebf67b9deca1b5929" integrity sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ== @@ -19199,7 +19280,7 @@ detect-libc@^1.0.3: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== -detect-libc@^2.0.1, detect-libc@^2.0.4, detect-libc@^2.1.0: +detect-libc@^2.0.1, detect-libc@^2.0.3, detect-libc@^2.0.4, detect-libc@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== @@ -25049,6 +25130,80 @@ lighthouse@12.8.2: yargs "^17.3.1" yargs-parser "^21.0.0" +lightningcss-android-arm64@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz#609ff48332adff452a8157a7c2842fd692a8eac4" + integrity sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg== + +lightningcss-darwin-arm64@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz#a13da040a7929582bab3ace9a67bdc146e99fc2d" + integrity sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg== + +lightningcss-darwin-x64@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz#f7482c311273571ec0c2bd8277c1f5f6e90e03a4" + integrity sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA== + +lightningcss-freebsd-x64@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz#91df1bb290f1cb7bb2af832d7d0d8809225e0124" + integrity sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A== + +lightningcss-linux-arm-gnueabihf@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz#c3cad5ae8b70045f21600dc95295ab6166acf57e" + integrity sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g== + +lightningcss-linux-arm64-gnu@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz#a5c4f6a5ac77447093f61b209c0bd7fef1f0a3e3" + integrity sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg== + +lightningcss-linux-arm64-musl@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz#af26ab8f829b727ada0a200938a6c8796ff36900" + integrity sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg== + +lightningcss-linux-x64-gnu@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz#a891d44e84b71c0d88959feb9a7522bbf61450ee" + integrity sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA== + +lightningcss-linux-x64-musl@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz#8c8b21def851f4d477fa897b80cb3db2b650bc6e" + integrity sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA== + +lightningcss-win32-arm64-msvc@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz#79000fb8c57e94a91b8fc643e74d5a54407d7080" + integrity sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w== + +lightningcss-win32-x64-msvc@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz#7f025274c81c7d659829731e09c8b6f442209837" + integrity sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw== + +lightningcss@1.31.1: + version "1.31.1" + resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.31.1.tgz#1a19dd327b547a7eda1d5c296ebe1e72df5a184b" + integrity sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ== + dependencies: + detect-libc "^2.0.3" + optionalDependencies: + lightningcss-android-arm64 "1.31.1" + lightningcss-darwin-arm64 "1.31.1" + lightningcss-darwin-x64 "1.31.1" + lightningcss-freebsd-x64 "1.31.1" + lightningcss-linux-arm-gnueabihf "1.31.1" + lightningcss-linux-arm64-gnu "1.31.1" + lightningcss-linux-arm64-musl "1.31.1" + lightningcss-linux-x64-gnu "1.31.1" + lightningcss-linux-x64-musl "1.31.1" + lightningcss-win32-arm64-msvc "1.31.1" + lightningcss-win32-x64-msvc "1.31.1" + lilconfig@^3.1.1, lilconfig@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" @@ -32375,7 +32530,7 @@ tape@5.9.0: resolve "^2.0.0-next.5" string.prototype.trim "^1.2.9" -tar-fs@^3.1.1: +tar-fs@3.1.1, tar-fs@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.1.1.tgz#4f164e59fb60f103d472360731e8c6bb4a7fe9ef" integrity sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==