diff --git a/build-scripts/bundle.ts b/build-scripts/bundle.ts index cc65c34674..dd5246b837 100644 --- a/build-scripts/bundle.ts +++ b/build-scripts/bundle.ts @@ -1,34 +1,33 @@ -import path from "path"; -import { dependencies } from "../package.json"; -import env from "./env"; -import paths from "./paths"; +import path from "node:path"; +import packageJson from "../package.json" assert { type: "json" }; +import paths, { dirname } from "./paths.ts"; +import { version } from "./env.ts"; -const BABEL_PLUGINS = path.join(__dirname, "babel-plugins"); +const dependencies = packageJson.dependencies; + +const BABEL_PLUGINS = path.join(dirname, "babel-plugins"); // GitHub base URL to use for production source maps // Nightly builds use the commit SHA, otherwise assumes there is a tag that matches the version export const sourceMapURL = () => { - const ref = env.version().endsWith("dev") + const ref = version().endsWith("dev") ? process.env.GITHUB_SHA || "dev" - : env.version(); + : version(); return `https://raw.githubusercontent.com/home-assistant/frontend/${ref}/`; }; -// Files from NPM Packages that should not be imported -export const ignorePackages = () => []; - // Files from NPM packages that we should replace with empty file export const emptyPackages = ({ isHassioBuild }) => [ - require.resolve("@vaadin/vaadin-material-styles/typography.js"), - require.resolve("@vaadin/vaadin-material-styles/font-icons.js"), + import.meta.resolve("@vaadin/vaadin-material-styles/typography.js"), + import.meta.resolve("@vaadin/vaadin-material-styles/font-icons.js"), // Icons in supervisor conflict with icons in HA so we don't load. isHassioBuild && - require.resolve( + import.meta.resolve( path.resolve(paths.root_dir, "src/components/ha-icon.ts") ), isHassioBuild && - require.resolve( + import.meta.resolve( path.resolve(paths.root_dir, "src/components/ha-icon-picker.ts") ), ].filter(Boolean); @@ -36,7 +35,7 @@ export const emptyPackages = ({ isHassioBuild }) => export const definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({ __DEV__: !isProdBuild, __BUILD__: JSON.stringify(latestBuild ? "modern" : "legacy"), - __VERSION__: JSON.stringify(env.version()), + __VERSION__: JSON.stringify(version()), __DEMO__: false, __SUPERVISOR__: false, __BACKWARDS_COMPAT__: false, @@ -67,7 +66,7 @@ export const htmlMinifierOptions = { export const terserOptions = ({ latestBuild, isTestBuild }) => ({ safari10: !latestBuild, - ecma: latestBuild ? 2015 : 5, + ecma: latestBuild ? (2015 as const) : (5 as const), module: latestBuild, format: { comments: false }, sourceMap: !isTestBuild, @@ -91,6 +90,11 @@ export const babelOptions = ({ isProdBuild, isTestBuild, sw, +}: { + latestBuild?: boolean; + isProdBuild?: boolean; + isTestBuild?: boolean; + sw?: boolean; }) => ({ babelrc: false, compact: false, @@ -137,7 +141,7 @@ export const babelOptions = ({ "@polymer/polymer/lib/utils/html-tag.js": ["html"], }, strictCSS: true, - htmlMinifier: module.exports.htmlMinifierOptions, + htmlMinifier: htmlMinifierOptions, failOnError: false, // we can turn this off in case of false positives }, ], @@ -222,7 +226,19 @@ const publicPath = (latestBuild, root = "") => */ export const config = { - app({ isProdBuild, latestBuild, isStatsBuild, isTestBuild, isWDS }) { + app({ + isProdBuild, + latestBuild, + isStatsBuild, + isTestBuild, + isWDS, + }: { + isProdBuild?: boolean; + latestBuild?: boolean; + isStatsBuild?: boolean; + isTestBuild?: boolean; + isWDS?: boolean; + }) { return { name: "frontend" + nameSuffix(latestBuild), entry: { @@ -257,7 +273,7 @@ export const config = { outputPath: outputPath(paths.demo_output_root, latestBuild), publicPath: publicPath(latestBuild), defineOverlay: { - __VERSION__: JSON.stringify(`DEMO-${env.version()}`), + __VERSION__: JSON.stringify(`DEMO-${version()}`), __DEMO__: true, }, isProdBuild, @@ -267,13 +283,12 @@ export const config = { }, cast({ isProdBuild, latestBuild }) { - const entry = { + const entry: Record = { launcher: path.resolve(paths.cast_dir, "src/launcher/entrypoint.ts"), media: path.resolve(paths.cast_dir, "src/media/entrypoint.ts"), }; if (latestBuild) { - // @ts-ignore entry.receiver = path.resolve( paths.cast_dir, "src/receiver/entrypoint.ts" diff --git a/build-scripts/env.ts b/build-scripts/env.ts index b57f52e52e..33a6733517 100644 --- a/build-scripts/env.ts +++ b/build-scripts/env.ts @@ -1,34 +1,21 @@ -import fs from "fs"; -import path from "path"; -import paths from "./paths"; +import fs from "node:fs"; +import path from "node:path"; +import paths from "./paths.ts"; const isTrue = (value) => value === "1" || value?.toLowerCase() === "true"; -export default { - isProdBuild() { - return ( - process.env.NODE_ENV === "production" || module.exports.isStatsBuild() - ); - }, - isStatsBuild() { - return isTrue(process.env.STATS); - }, - isTestBuild() { - return isTrue(process.env.IS_TEST); - }, - isNetlify() { - return isTrue(process.env.NETLIFY); - }, - version() { - const version = fs - .readFileSync(path.resolve(paths.root_dir, "pyproject.toml"), "utf8") - .match(/version\W+=\W"(\d{8}\.\d(?:\.dev)?)"/); - if (!version) { - throw Error("Version not found"); - } - return version[1]; - }, - isDevContainer() { - return isTrue(process.env.DEV_CONTAINER); - }, +export const isProdBuild = () => + process.env.NODE_ENV === "production" || isStatsBuild(); +export const isStatsBuild = () => isTrue(process.env.STATS); +export const isTestBuild = () => isTrue(process.env.IS_TEST); +export const isNetlify = () => isTrue(process.env.NETLIFY); +export const version = () => { + const pyProjectVersion = fs + .readFileSync(path.resolve(paths.root_dir, "pyproject.toml"), "utf8") + .match(/version\W+=\W"(\d{8}\.\d(?:\.dev)?)"/); + if (!pyProjectVersion) { + throw Error("Version not found"); + } + return pyProjectVersion[1]; }; +export const isDevContainer = () => isTrue(process.env.DEV_CONTAINER); diff --git a/build-scripts/eslint.config.ts b/build-scripts/eslint.config.mjs similarity index 100% rename from build-scripts/eslint.config.ts rename to build-scripts/eslint.config.mjs diff --git a/build-scripts/gulp/app.ts b/build-scripts/gulp/app.ts index 9e93d05c27..e310a5151f 100644 --- a/build-scripts/gulp/app.ts +++ b/build-scripts/gulp/app.ts @@ -1,8 +1,7 @@ -// eslint-disable-next-line import/no-extraneous-dependencies -import gulp from "gulp"; +import { parallel, series, task } from "gulp"; +import { isStatsBuild, isTestBuild } from "../env.ts"; import "./clean.ts"; import "./compress.ts"; -import env from "../env"; import "./entry-html.ts"; import "./gather-static.ts"; import "./gen-icons-json.ts"; @@ -11,14 +10,14 @@ import "./rspack.ts"; import "./service-worker.ts"; import "./translations.ts"; -gulp.task( +task( "develop-app", - gulp.series( + series( async () => { process.env.NODE_ENV = "development"; }, "clean", - gulp.parallel( + parallel( "gen-service-worker-app-dev", "gen-icons-json", "gen-pages-app-dev", @@ -30,25 +29,25 @@ gulp.task( ) ); -gulp.task( +task( "build-app", - gulp.series( + series( async () => { process.env.NODE_ENV = "production"; }, "clean", - gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), + parallel("gen-icons-json", "build-translations", "build-locale-data"), "copy-static-app", "rspack-prod-app", - gulp.parallel("gen-pages-app-prod", "gen-service-worker-app-prod"), + parallel("gen-pages-app-prod", "gen-service-worker-app-prod"), // Don't compress running tests - ...(env.isTestBuild() || env.isStatsBuild() ? [] : ["compress-app"]) + ...(isTestBuild() || isStatsBuild() ? [] : ["compress-app"]) ) ); -gulp.task( +task( "analyze-app", - gulp.series( + series( async () => { process.env.STATS = "1"; }, diff --git a/build-scripts/gulp/cast.ts b/build-scripts/gulp/cast.ts index 397e19dc42..85ce284b65 100644 --- a/build-scripts/gulp/cast.ts +++ b/build-scripts/gulp/cast.ts @@ -1,5 +1,4 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import gulp from "gulp"; +import { parallel, series, task } from "gulp"; import "./clean.ts"; import "./entry-html.ts"; import "./gather-static.ts"; @@ -7,30 +6,30 @@ import "./rspack.ts"; import "./service-worker.ts"; import "./translations.ts"; -gulp.task( +task( "develop-cast", - gulp.series( + series( async () => { process.env.NODE_ENV = "development"; }, "clean-cast", "translations-enable-merge-backend", - gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), + parallel("gen-icons-json", "build-translations", "build-locale-data"), "copy-static-cast", "gen-pages-cast-dev", "rspack-dev-server-cast" ) ); -gulp.task( +task( "build-cast", - gulp.series( + series( async () => { process.env.NODE_ENV = "production"; }, "clean-cast", "translations-enable-merge-backend", - gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), + parallel("gen-icons-json", "build-translations", "build-locale-data"), "copy-static-cast", "rspack-prod-cast", "gen-pages-cast-prod" diff --git a/build-scripts/gulp/clean.ts b/build-scripts/gulp/clean.ts index 3658f33129..5ad4308dc5 100644 --- a/build-scripts/gulp/clean.ts +++ b/build-scripts/gulp/clean.ts @@ -1,36 +1,36 @@ import { deleteSync } from "del"; -import gulp from "gulp"; -import paths from "../paths"; -import "./translations.js"; +import { parallel, task } from "gulp"; +import paths from "../paths.ts"; +import "./translations.ts"; -gulp.task( +task( "clean", - gulp.parallel("clean-translations", async () => + parallel("clean-translations", async () => deleteSync([paths.app_output_root, paths.build_dir]) ) ); -gulp.task( +task( "clean-demo", - gulp.parallel("clean-translations", async () => + parallel("clean-translations", async () => deleteSync([paths.demo_output_root, paths.build_dir]) ) ); -gulp.task( +task( "clean-cast", - gulp.parallel("clean-translations", async () => + parallel("clean-translations", async () => deleteSync([paths.cast_output_root, paths.build_dir]) ) ); -gulp.task("clean-hassio", async () => +task("clean-hassio", async () => deleteSync([paths.hassio_output_root, paths.build_dir]) ); -gulp.task( +task( "clean-gallery", - gulp.parallel("clean-translations", async () => + parallel("clean-translations", async () => deleteSync([ paths.gallery_output_root, paths.gallery_build, @@ -39,9 +39,9 @@ gulp.task( ) ); -gulp.task( +task( "clean-landing-page", - gulp.parallel("clean-translations", async () => + parallel("clean-translations", async () => deleteSync([ paths.landingPage_output_root, paths.landingPage_build, diff --git a/build-scripts/gulp/compress.ts b/build-scripts/gulp/compress.ts index 578f5910b0..5f440c5c1e 100644 --- a/build-scripts/gulp/compress.ts +++ b/build-scripts/gulp/compress.ts @@ -1,10 +1,10 @@ // Tasks to compress -import gulp from "gulp"; +import { dest, parallel, src, task } from "gulp"; import brotli from "gulp-brotli"; import zopfli from "gulp-zopfli-green"; import { constants } from "node:zlib"; -import paths from "../paths"; +import paths from "../paths.ts"; const filesGlob = "*.{js,json,css,svg,xml}"; const brotliOptions = { @@ -16,27 +16,25 @@ const brotliOptions = { const zopfliOptions = { threshold: 150 }; const compressModern = (rootDir, modernDir, compress) => - gulp - .src([`${modernDir}/**/${filesGlob}`, `${rootDir}/sw-modern.js`], { - base: rootDir, - allowEmpty: true, - }) + src([`${modernDir}/**/${filesGlob}`, `${rootDir}/sw-modern.js`], { + base: rootDir, + allowEmpty: true, + }) .pipe(compress === "zopfli" ? zopfli(zopfliOptions) : brotli(brotliOptions)) - .pipe(gulp.dest(rootDir)); + .pipe(dest(rootDir)); const compressOther = (rootDir, modernDir, compress) => - gulp - .src( - [ - `${rootDir}/**/${filesGlob}`, - `!${modernDir}/**/${filesGlob}`, - `!${rootDir}/{sw-modern,service_worker}.js`, - `${rootDir}/{authorize,onboarding}.html`, - ], - { base: rootDir, allowEmpty: true } - ) + src( + [ + `${rootDir}/**/${filesGlob}`, + `!${modernDir}/**/${filesGlob}`, + `!${rootDir}/{sw-modern,service_worker}.js`, + `${rootDir}/{authorize,onboarding}.html`, + ], + { base: rootDir, allowEmpty: true } + ) .pipe(compress === "zopfli" ? zopfli(zopfliOptions) : brotli(brotliOptions)) - .pipe(gulp.dest(rootDir)); + .pipe(dest(rootDir)); const compressAppModernBrotli = () => compressModern(paths.app_output_root, paths.app_output_latest, "brotli"); @@ -66,18 +64,18 @@ const compressHassioOtherBrotli = () => const compressHassioOtherZopfli = () => compressOther(paths.hassio_output_root, paths.hassio_output_latest, "zopfli"); -gulp.task( +task( "compress-app", - gulp.parallel( + parallel( compressAppModernBrotli, compressAppOtherBrotli, compressAppModernZopfli, compressAppOtherZopfli ) ); -gulp.task( +task( "compress-hassio", - gulp.parallel( + parallel( compressHassioModernBrotli, compressHassioOtherBrotli, compressHassioModernZopfli, diff --git a/build-scripts/gulp/demo.ts b/build-scripts/gulp/demo.ts index 65af10e5b4..3e87f81892 100644 --- a/build-scripts/gulp/demo.ts +++ b/build-scripts/gulp/demo.ts @@ -1,21 +1,21 @@ -import gulp from "gulp"; -import "./clean.js"; -import "./entry-html.js"; -import "./gather-static.js"; -import "./gen-icons-json.js"; -import "./service-worker.js"; -import "./translations.js"; -import "./rspack.js"; +import { parallel, series, task } from "gulp"; +import "./clean.ts"; +import "./entry-html.ts"; +import "./gather-static.ts"; +import "./gen-icons-json.ts"; +import "./rspack.ts"; +import "./service-worker.ts"; +import "./translations.ts"; -gulp.task( +task( "develop-demo", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "development"; }, "clean-demo", "translations-enable-merge-backend", - gulp.parallel( + parallel( "gen-icons-json", "gen-pages-demo-dev", "build-translations", @@ -26,25 +26,25 @@ gulp.task( ) ); -gulp.task( +task( "build-demo", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "production"; }, "clean-demo", // Cast needs to be backwards compatible and older HA has no translations "translations-enable-merge-backend", - gulp.parallel("gen-icons-json", "build-translations", "build-locale-data"), + parallel("gen-icons-json", "build-translations", "build-locale-data"), "copy-static-demo", "rspack-prod-demo", "gen-pages-demo-prod" ) ); -gulp.task( +task( "analyze-demo", - gulp.series( + series( async function setEnv() { process.env.STATS = "1"; }, diff --git a/build-scripts/gulp/download-translations.ts b/build-scripts/gulp/download-translations.ts index 56e208cd40..e09a37d72d 100644 --- a/build-scripts/gulp/download-translations.ts +++ b/build-scripts/gulp/download-translations.ts @@ -1,10 +1,10 @@ import { LokaliseApi } from "@lokalise/node-api"; -import fs from "fs/promises"; -import gulp from "gulp"; +import fs from "node:fs/promises"; +import { dest, series, src, task } from "gulp"; import transform from "gulp-json-transform"; import JSZip from "jszip"; import mapStream from "map-stream"; -import path from "path"; +import path from "node:path"; const inDir = "translations"; const inDirFrontend = `${inDir}/frontend`; @@ -64,20 +64,19 @@ function convertBackendTranslations(data, _file) { return output; } -gulp.task("convert-backend-translations", function () { - return gulp - .src([`${inDirBackend}/*.json`]) +task("convert-backend-translations", function () { + return src([`${inDirBackend}/*.json`]) .pipe(transform((data, file) => convertBackendTranslations(data, file))) - .pipe(gulp.dest(inDirBackend)); + .pipe(dest(inDirBackend)); }); -gulp.task("check-translations-html", function () { - return gulp - .src([`${inDirFrontend}/*.json`, `${inDirBackend}/*.json`]) - .pipe(checkHtml()); +task("check-translations-html", function () { + return src([`${inDirFrontend}/*.json`, `${inDirBackend}/*.json`]).pipe( + checkHtml() + ); }); -gulp.task("check-all-files-exist", async function () { +task("check-all-files-exist", async function () { const file = await fs.readFile(srcMeta, { encoding }); const meta = JSON.parse(file); const writings: Promise[] = []; @@ -99,7 +98,7 @@ const lokaliseProjects = { frontend: "3420425759f6d6d241f598.13594006", }; -gulp.task("fetch-lokalise", async function () { +task("fetch-lokalise", async function () { let apiKey; try { apiKey = @@ -170,9 +169,9 @@ gulp.task("fetch-lokalise", async function () { ); }); -gulp.task( +task( "download-translations", - gulp.series( + series( "fetch-lokalise", "convert-backend-translations", "check-translations-html", diff --git a/build-scripts/gulp/entry-html.ts b/build-scripts/gulp/entry-html.ts index cd71520f8f..40e93a70d4 100644 --- a/build-scripts/gulp/entry-html.ts +++ b/build-scripts/gulp/entry-html.ts @@ -6,12 +6,12 @@ import { getPreUserAgentRegexes, } from "browserslist-useragent-regexp"; import fs from "fs-extra"; -import gulp from "gulp"; +import { task } from "gulp"; import { minify } from "html-minifier-terser"; import template from "lodash.template"; import { dirname, extname, resolve } from "node:path"; -import { htmlMinifierOptions, terserOptions } from "../bundle"; -import paths from "../paths"; +import { htmlMinifierOptions, terserOptions } from "../bundle.ts"; +import paths from "../paths.ts"; // macOS companion app has no way to obtain the Safari version used by WKWebView, // and it is not in the default user agent string. So we add an additional regex @@ -34,9 +34,9 @@ const getCommonTemplateVars = () => { mobileToDesktop: true, throwOnMissing: true, }); - const minSafariVersion = browserRegexes.find( - (regex) => regex.family === "safari" - )?.matchedVersions[0][0] ?? 18; + const minSafariVersion = + browserRegexes.find((regex) => regex.family === "safari") + ?.matchedVersions[0][0] ?? 18; const minMacOSVersion = SAFARI_TO_MACOS[minSafariVersion]; if (!minMacOSVersion) { throw Error( @@ -145,8 +145,12 @@ const genPagesProdTask = resolve(inputRoot, inputSub, `${page}.template`), { ...commonVars, - latestEntryJS: (entries as string[]).map((entry) => latestManifest[`${entry}.js`]), - es5EntryJS: (entries as string[]).map((entry) => es5Manifest[`${entry}.js`]), + latestEntryJS: (entries as string[]).map( + (entry) => latestManifest[`${entry}.js`] + ), + es5EntryJS: (entries as string[]).map( + (entry) => es5Manifest[`${entry}.js`] + ), latestCustomPanelJS: latestManifest["custom-panel.js"], es5CustomPanelJS: es5Manifest["custom-panel.js"], } @@ -167,12 +171,12 @@ const APP_PAGE_ENTRIES = { "index.html": ["core", "app"], }; -gulp.task( +task( "gen-pages-app-dev", genPagesDevTask(APP_PAGE_ENTRIES, paths.root_dir, paths.app_output_root) ); -gulp.task( +task( "gen-pages-app-prod", genPagesProdTask( APP_PAGE_ENTRIES, @@ -190,12 +194,12 @@ const CAST_PAGE_ENTRIES = { "receiver.html": ["receiver"], }; -gulp.task( +task( "gen-pages-cast-dev", genPagesDevTask(CAST_PAGE_ENTRIES, paths.cast_dir, paths.cast_output_root) ); -gulp.task( +task( "gen-pages-cast-prod", genPagesProdTask( CAST_PAGE_ENTRIES, @@ -208,12 +212,12 @@ gulp.task( const DEMO_PAGE_ENTRIES = { "index.html": ["main"] }; -gulp.task( +task( "gen-pages-demo-dev", genPagesDevTask(DEMO_PAGE_ENTRIES, paths.demo_dir, paths.demo_output_root) ); -gulp.task( +task( "gen-pages-demo-prod", genPagesProdTask( DEMO_PAGE_ENTRIES, @@ -226,7 +230,7 @@ gulp.task( const GALLERY_PAGE_ENTRIES = { "index.html": ["entrypoint"] }; -gulp.task( +task( "gen-pages-gallery-dev", genPagesDevTask( GALLERY_PAGE_ENTRIES, @@ -235,7 +239,7 @@ gulp.task( ) ); -gulp.task( +task( "gen-pages-gallery-prod", genPagesProdTask( GALLERY_PAGE_ENTRIES, @@ -247,7 +251,7 @@ gulp.task( const LANDING_PAGE_PAGE_ENTRIES = { "index.html": ["entrypoint"] }; -gulp.task( +task( "gen-pages-landing-page-dev", genPagesDevTask( LANDING_PAGE_PAGE_ENTRIES, @@ -256,7 +260,7 @@ gulp.task( ) ); -gulp.task( +task( "gen-pages-landing-page-prod", genPagesProdTask( LANDING_PAGE_PAGE_ENTRIES, @@ -269,7 +273,7 @@ gulp.task( const HASSIO_PAGE_ENTRIES = { "entrypoint.js": ["entrypoint"] }; -gulp.task( +task( "gen-pages-hassio-dev", genPagesDevTask( HASSIO_PAGE_ENTRIES, @@ -280,7 +284,7 @@ gulp.task( ) ); -gulp.task( +task( "gen-pages-hassio-prod", genPagesProdTask( HASSIO_PAGE_ENTRIES, diff --git a/build-scripts/gulp/fetch-nightly-translations.ts b/build-scripts/gulp/fetch-nightly-translations.ts index 2a8e7148f9..d28011cba4 100644 --- a/build-scripts/gulp/fetch-nightly-translations.ts +++ b/build-scripts/gulp/fetch-nightly-translations.ts @@ -1,14 +1,14 @@ -// Task to download the latest Lokalise translations from the nightly workflow artifacts +// Task to download the latest 00Lokalise translations from the nightly workflow artifacts import { createOAuthDeviceAuth } from "@octokit/auth-oauth-device"; import { retry } from "@octokit/plugin-retry"; import { Octokit } from "@octokit/rest"; import { deleteAsync } from "del"; -import { mkdir, readFile, writeFile } from "fs/promises"; -import gulp from "gulp"; +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { series, task } from "gulp"; import jszip from "jszip"; -import path from "path"; -import process from "process"; +import path from "node:path"; +import process from "node:process"; import { extract } from "tar"; const MAX_AGE = 24; // hours @@ -22,12 +22,12 @@ const TOKEN_FILE = path.posix.join(EXTRACT_DIR, "token.json"); const ARTIFACT_FILE = path.posix.join(EXTRACT_DIR, "artifact.json"); let allowTokenSetup = false; -gulp.task("allow-setup-fetch-nightly-translations", (done) => { +task("allow-setup-fetch-nightly-translations", (done) => { allowTokenSetup = true; done(); }); -gulp.task("fetch-nightly-translations", async function () { +task("fetch-nightly-translations", async function () { // Skip all when environment flag is set (assumes translations are already in place) if (process.env?.SKIP_FETCH_NIGHTLY_TRANSLATIONS) { console.log("Skipping fetch due to environment signal"); @@ -148,7 +148,7 @@ gulp.task("fetch-nightly-translations", async function () { artifact_id: latestArtifact.id, archive_format: "zip", }); - // @ts-ignore + // @ts-ignore OctokitResponse doesn't allow to check for 200 if (downloadResponse.status !== 200) { throw Error("Failure downloading translations artifact"); } @@ -163,10 +163,7 @@ gulp.task("fetch-nightly-translations", async function () { }); }); -gulp.task( +task( "setup-and-fetch-nightly-translations", - gulp.series( - "allow-setup-fetch-nightly-translations", - "fetch-nightly-translations" - ) + series("allow-setup-fetch-nightly-translations", "fetch-nightly-translations") ); diff --git a/build-scripts/gulp/gallery.ts b/build-scripts/gulp/gallery.ts index 59e9f8fa18..78f6807403 100644 --- a/build-scripts/gulp/gallery.ts +++ b/build-scripts/gulp/gallery.ts @@ -1,19 +1,19 @@ -import fs from "fs"; +import fs from "node:fs"; import { glob } from "glob"; -import gulp from "gulp"; +import { parallel, series, task, watch } from "gulp"; import yaml from "js-yaml"; import { marked } from "marked"; -import path from "path"; -import paths from "../paths"; -import "./clean.js"; -import "./entry-html.js"; -import "./gather-static.js"; -import "./gen-icons-json.js"; -import "./rspack"; -import "./service-worker.js"; -import "./translations.js"; +import path from "node:path"; +import paths from "../paths.ts"; +import "./clean.ts"; +import "./entry-html.ts"; +import "./gather-static.ts"; +import "./gen-icons-json.ts"; +import "./rspack.ts"; +import "./service-worker.ts"; +import "./translations.ts"; -gulp.task("gather-gallery-pages", async function gatherPages() { +task("gather-gallery-pages", async function gatherPages() { const pageDir = path.resolve(paths.gallery_dir, "src/pages"); const files = await glob(path.resolve(pageDir, "**/*")); @@ -99,7 +99,10 @@ gulp.task("gather-gallery-pages", async function gatherPages() { pagesToProcess[category].add(page); } - for (const group of Object.values(sidebar) as Array<{ category: string; pages?: string[] }>) { + for (const group of Object.values(sidebar) as { + category: string; + pages?: string[]; + }[]) { const toProcess = pagesToProcess[group.category]; delete pagesToProcess[group.category]; @@ -143,15 +146,15 @@ gulp.task("gather-gallery-pages", async function gatherPages() { ); }); -gulp.task( +task( "develop-gallery", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "development"; }, "clean-gallery", "translations-enable-merge-backend", - gulp.parallel( + parallel( "gen-icons-json", "build-translations", "build-locale-data", @@ -159,30 +162,27 @@ gulp.task( ), "copy-static-gallery", "gen-pages-gallery-dev", - gulp.parallel( - "rspack-dev-server-gallery", - async function watchMarkdownFiles() { - gulp.watch( - [ - path.resolve(paths.gallery_dir, "src/pages/**/*.markdown"), - path.resolve(paths.gallery_dir, "sidebar.js"), - ], - gulp.series("gather-gallery-pages") - ); - } - ) + parallel("rspack-dev-server-gallery", async function watchMarkdownFiles() { + watch( + [ + path.resolve(paths.gallery_dir, "src/pages/**/*.markdown"), + path.resolve(paths.gallery_dir, "sidebar.js"), + ], + series("gather-gallery-pages") + ); + }) ) ); -gulp.task( +task( "build-gallery", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "production"; }, "clean-gallery", "translations-enable-merge-backend", - gulp.parallel( + parallel( "gen-icons-json", "build-translations", "build-locale-data", diff --git a/build-scripts/gulp/gather-static.ts b/build-scripts/gulp/gather-static.ts index d0f42b2dac..32c4cf5faa 100644 --- a/build-scripts/gulp/gather-static.ts +++ b/build-scripts/gulp/gather-static.ts @@ -1,9 +1,9 @@ // Gulp task to gather all static files. import fs from "fs-extra"; -import gulp from "gulp"; -import path from "path"; -import paths from "../paths"; +import { task } from "gulp"; +import path from "node:path"; +import paths from "../paths.ts"; const npmPath = (...parts) => path.resolve(paths.root_dir, "node_modules", ...parts); @@ -113,33 +113,33 @@ function copyZXingWasm(staticDir) { ); } -gulp.task("copy-locale-data", async () => { +task("copy-locale-data", async () => { const staticDir = paths.app_output_static; copyLocaleData(staticDir); }); -gulp.task("copy-translations-app", async () => { +task("copy-translations-app", async () => { const staticDir = paths.app_output_static; copyTranslations(staticDir); }); -gulp.task("copy-translations-supervisor", async () => { +task("copy-translations-supervisor", async () => { const staticDir = paths.hassio_output_static; copyTranslations(staticDir); }); -gulp.task("copy-translations-landing-page", async () => { +task("copy-translations-landing-page", async () => { const staticDir = paths.landingPage_output_static; copyTranslations(staticDir); }); -gulp.task("copy-static-supervisor", async () => { +task("copy-static-supervisor", async () => { const staticDir = paths.hassio_output_static; copyLocaleData(staticDir); copyFonts(staticDir); }); -gulp.task("copy-static-app", async () => { +task("copy-static-app", async () => { const staticDir = paths.app_output_static; // Basic static files fs.copySync(polyPath("public"), paths.app_output_root); @@ -157,7 +157,7 @@ gulp.task("copy-static-app", async () => { copyQrScannerWorker(staticDir); }); -gulp.task("copy-static-demo", async () => { +task("copy-static-demo", async () => { // Copy app static files fs.copySync( polyPath("public/static"), @@ -173,7 +173,7 @@ gulp.task("copy-static-demo", async () => { copyMdiIcons(paths.demo_output_static); }); -gulp.task("copy-static-cast", async () => { +task("copy-static-cast", async () => { // Copy app static files fs.copySync(polyPath("public/static"), paths.cast_output_static); // Copy cast static files @@ -186,7 +186,7 @@ gulp.task("copy-static-cast", async () => { copyMdiIcons(paths.cast_output_static); }); -gulp.task("copy-static-gallery", async () => { +task("copy-static-gallery", async () => { // Copy app static files fs.copySync(polyPath("public/static"), paths.gallery_output_static); // Copy gallery static files @@ -202,7 +202,7 @@ gulp.task("copy-static-gallery", async () => { copyMdiIcons(paths.gallery_output_static); }); -gulp.task("copy-static-landing-page", async () => { +task("copy-static-landing-page", async () => { // Copy landing-page static files fs.copySync( path.resolve(paths.landingPage_dir, "public"), diff --git a/build-scripts/gulp/gen-icons-json.ts b/build-scripts/gulp/gen-icons-json.ts index 50e508c71d..1d1f63a24c 100644 --- a/build-scripts/gulp/gen-icons-json.ts +++ b/build-scripts/gulp/gen-icons-json.ts @@ -1,8 +1,8 @@ -import fs from "fs"; -import gulp from "gulp"; +import fs from "node:fs"; +import { task } from "gulp"; import hash from "object-hash"; -import path from "path"; -import paths from "../paths"; +import path from "node:path"; +import paths from "../paths.ts"; const ICON_PACKAGE_PATH = path.resolve("node_modules/@mdi/svg/"); const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json"); @@ -97,7 +97,7 @@ const findDifferentiator = (curString, prevString) => { throw new Error(`Cannot find differentiator; ${curString}; ${prevString}`); }; -gulp.task("gen-icons-json", (done) => { +task("gen-icons-json", (done) => { const meta = getMeta(); const metaAndRemoved = addRemovedMeta(meta); @@ -155,7 +155,7 @@ gulp.task("gen-icons-json", (done) => { done(); }); -gulp.task("gen-dummy-icons-json", (done) => { +task("gen-dummy-icons-json", (done) => { if (!fs.existsSync(OUTPUT_DIR)) { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); } diff --git a/build-scripts/gulp/hassio.ts b/build-scripts/gulp/hassio.ts index ef9b7fd92e..c0acd0229f 100644 --- a/build-scripts/gulp/hassio.ts +++ b/build-scripts/gulp/hassio.ts @@ -1,16 +1,16 @@ -import gulp from "gulp"; -import env from "../env"; -import "./clean.js"; -import "./compress.js"; -import "./entry-html.js"; -import "./gather-static.js"; -import "./gen-icons-json.js"; -import "./rspack.js"; -import "./translations.js"; +import { series, task } from "gulp"; +import { isTestBuild } from "../env.ts"; +import "./clean.ts"; +import "./compress.ts"; +import "./entry-html.ts"; +import "./gather-static.ts"; +import "./gen-icons-json.ts"; +import "./rspack.ts"; +import "./translations.ts"; -gulp.task( +task( "develop-hassio", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "development"; }, @@ -25,9 +25,9 @@ gulp.task( ) ); -gulp.task( +task( "build-hassio", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "production"; }, @@ -40,6 +40,6 @@ gulp.task( "rspack-prod-hassio", "gen-pages-hassio-prod", ...// Don't compress running tests - (env.isTestBuild() ? [] : ["compress-hassio"]) + (isTestBuild() ? [] : ["compress-hassio"]) ) ); diff --git a/build-scripts/gulp/landing-page.ts b/build-scripts/gulp/landing-page.ts index d3909cea12..e9ccc0af82 100644 --- a/build-scripts/gulp/landing-page.ts +++ b/build-scripts/gulp/landing-page.ts @@ -1,15 +1,15 @@ -import gulp from "gulp"; -import "./clean.js"; -import "./compress.js"; -import "./entry-html.js"; -import "./gather-static.js"; -import "./gen-icons-json.js"; -import "./rspack.js"; -import "./translations.js"; +import { series, task } from "gulp"; +import "./clean.ts"; +import "./compress.ts"; +import "./entry-html.ts"; +import "./gather-static.ts"; +import "./gen-icons-json.ts"; +import "./rspack.ts"; +import "./translations.ts"; -gulp.task( +task( "develop-landing-page", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "development"; }, @@ -24,9 +24,9 @@ gulp.task( ) ); -gulp.task( +task( "build-landing-page", - gulp.series( + series( async function setEnv() { process.env.NODE_ENV = "production"; }, diff --git a/build-scripts/gulp/locale-data.ts b/build-scripts/gulp/locale-data.ts index 1c7a48ec86..f88bc4e5f6 100755 --- a/build-scripts/gulp/locale-data.ts +++ b/build-scripts/gulp/locale-data.ts @@ -1,8 +1,8 @@ import { deleteSync } from "del"; -import { mkdir, readFile, writeFile } from "fs/promises"; -import gulp from "gulp"; +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import { series, task } from "gulp"; import { join, resolve } from "node:path"; -import paths from "../paths"; +import paths from "../paths.ts"; const formatjsDir = join(paths.root_dir, "node_modules", "@formatjs"); const outDir = join(paths.build_dir, "locale-data"); @@ -54,9 +54,9 @@ const convertToJSON = async ( await writeFile(join(outDir, `${pkg}/${lang}.json`), localeData); }; -gulp.task("clean-locale-data", async () => deleteSync([outDir])); +task("clean-locale-data", async () => deleteSync([outDir])); -gulp.task("create-locale-data", async () => { +task("create-locale-data", async () => { const translationMeta = JSON.parse( await readFile( resolve(paths.translations_src, "translationMetadata.json"), @@ -83,7 +83,4 @@ gulp.task("create-locale-data", async () => { await Promise.all(conversions); }); -gulp.task( - "build-locale-data", - gulp.series("clean-locale-data", "create-locale-data") -); +task("build-locale-data", series("clean-locale-data", "create-locale-data")); diff --git a/build-scripts/gulp/rspack.ts b/build-scripts/gulp/rspack.ts index 08dd782602..4b15924494 100644 --- a/build-scripts/gulp/rspack.ts +++ b/build-scripts/gulp/rspack.ts @@ -3,11 +3,10 @@ import rspack from "@rspack/core"; import { RspackDevServer } from "@rspack/dev-server"; import log from "fancy-log"; -import fs from "fs"; -import gulp from "gulp"; -import path from "path"; -import env from "../env"; -import paths from "../paths"; +import fs from "node:fs"; +import { task, watch, series } from "gulp"; +import path from "node:path"; +import paths from "../paths.ts"; import { createAppConfig, createCastConfig, @@ -15,7 +14,8 @@ import { createGalleryConfig, createHassioConfig, createLandingPageConfig, -} from "../rspack"; +} from "../rspack.ts"; +import { isDevContainer, isStatsBuild, isTestBuild } from "../env.ts"; const bothBuilds = (createConfigFunc, params) => [ createConfigFunc({ ...params, latestBuild: true }), @@ -34,7 +34,7 @@ interface RunDevServer { contentBase: string; port: number; listenHost?: string; - proxy: any; + proxy?: any; } /** @@ -49,12 +49,12 @@ const runDevServer = async ({ compiler, contentBase, port, - listenHost = undefined, - proxy = undefined, + listenHost, + proxy, }: RunDevServer) => { if (listenHost === undefined) { // For dev container, we need to listen on all hosts - listenHost = env.isDevContainer() ? "0.0.0.0" : "localhost"; + listenHost = isDevContainer() ? "0.0.0.0" : "localhost"; } const server = new RspackDevServer( { @@ -105,30 +105,30 @@ const prodBuild = (conf) => ); }); -gulp.task("rspack-watch-app", () => { +task("rspack-watch-app", () => { // This command will run forever because we don't close compiler rspack( process.env.ES5 ? bothBuilds(createAppConfig, { isProdBuild: false }) : createAppConfig({ isProdBuild: false, latestBuild: true }) ).watch({ poll: isWsl }, doneHandler()); - gulp.watch( + watch( path.join(paths.translations_src, "en.json"), - gulp.series("build-translations", "copy-translations-app") + series("build-translations", "copy-translations-app") ); }); -gulp.task("rspack-prod-app", () => +task("rspack-prod-app", () => prodBuild( bothBuilds(createAppConfig, { isProdBuild: true, - isStatsBuild: env.isStatsBuild(), - isTestBuild: env.isTestBuild(), + isStatsBuild: isStatsBuild(), + isTestBuild: isTestBuild(), }) ) ); -gulp.task("rspack-dev-server-demo", () => +task("rspack-dev-server-demo", () => runDevServer({ compiler: rspack( createDemoConfig({ isProdBuild: false, latestBuild: true }) @@ -138,16 +138,16 @@ gulp.task("rspack-dev-server-demo", () => }) ); -gulp.task("rspack-prod-demo", () => +task("rspack-prod-demo", () => prodBuild( bothBuilds(createDemoConfig, { isProdBuild: true, - isStatsBuild: env.isStatsBuild(), + isStatsBuild: isStatsBuild(), }) ) ); -gulp.task("rspack-dev-server-cast", () => +task("rspack-dev-server-cast", () => runDevServer({ compiler: rspack( createCastConfig({ isProdBuild: false, latestBuild: true }) @@ -159,7 +159,7 @@ gulp.task("rspack-dev-server-cast", () => }) ); -gulp.task("rspack-prod-cast", () => +task("rspack-prod-cast", () => prodBuild( bothBuilds(createCastConfig, { isProdBuild: true, @@ -167,7 +167,7 @@ gulp.task("rspack-prod-cast", () => ) ); -gulp.task("rspack-watch-hassio", () => { +task("rspack-watch-hassio", () => { // This command will run forever because we don't close compiler rspack( createHassioConfig({ @@ -176,23 +176,23 @@ gulp.task("rspack-watch-hassio", () => { }) ).watch({ ignored: /build/, poll: isWsl }, doneHandler()); - gulp.watch( + watch( path.join(paths.translations_src, "en.json"), - gulp.series("build-supervisor-translations", "copy-translations-supervisor") + series("build-supervisor-translations", "copy-translations-supervisor") ); }); -gulp.task("rspack-prod-hassio", () => +task("rspack-prod-hassio", () => prodBuild( bothBuilds(createHassioConfig, { isProdBuild: true, - isStatsBuild: env.isStatsBuild(), - isTestBuild: env.isTestBuild(), + isStatsBuild: isStatsBuild(), + isTestBuild: isTestBuild(), }) ) ); -gulp.task("rspack-dev-server-gallery", () => +task("rspack-dev-server-gallery", () => runDevServer({ compiler: rspack( createGalleryConfig({ isProdBuild: false, latestBuild: true }) @@ -203,7 +203,7 @@ gulp.task("rspack-dev-server-gallery", () => }) ); -gulp.task("rspack-prod-gallery", () => +task("rspack-prod-gallery", () => prodBuild( createGalleryConfig({ isProdBuild: true, @@ -212,7 +212,7 @@ gulp.task("rspack-prod-gallery", () => ) ); -gulp.task("rspack-watch-landing-page", () => { +task("rspack-watch-landing-page", () => { // This command will run forever because we don't close compiler rspack( process.env.ES5 @@ -220,21 +220,18 @@ gulp.task("rspack-watch-landing-page", () => { : createLandingPageConfig({ isProdBuild: false, latestBuild: true }) ).watch({ poll: isWsl }, doneHandler()); - gulp.watch( + watch( path.join(paths.translations_src, "en.json"), - gulp.series( - "build-landing-page-translations", - "copy-translations-landing-page" - ) + series("build-landing-page-translations", "copy-translations-landing-page") ); }); -gulp.task("rspack-prod-landing-page", () => +task("rspack-prod-landing-page", () => prodBuild( bothBuilds(createLandingPageConfig, { isProdBuild: true, - isStatsBuild: env.isStatsBuild(), - isTestBuild: env.isTestBuild(), + isStatsBuild: isStatsBuild(), + isTestBuild: isTestBuild(), }) ) ); diff --git a/build-scripts/gulp/service-worker.ts b/build-scripts/gulp/service-worker.ts index 8fb8a2f964..fb487fee13 100644 --- a/build-scripts/gulp/service-worker.ts +++ b/build-scripts/gulp/service-worker.ts @@ -1,11 +1,11 @@ // Generate service workers import { deleteAsync } from "del"; -import gulp from "gulp"; +import { task } from "gulp"; import { mkdir, readFile, symlink, writeFile } from "node:fs/promises"; import { basename, join, relative } from "node:path"; import { injectManifest } from "workbox-build"; -import paths from "../paths"; +import paths from "../paths.ts"; const SW_MAP = { [paths.app_output_latest]: "modern", @@ -23,7 +23,7 @@ self.addEventListener('install', (event) => { }); `.trim() + "\n"; -gulp.task("gen-service-worker-app-dev", async () => { +task("gen-service-worker-app-dev", async () => { await mkdir(paths.app_output_root, { recursive: true }); await Promise.all( Object.values(SW_MAP).map((build) => @@ -34,7 +34,7 @@ gulp.task("gen-service-worker-app-dev", async () => { ); }); -gulp.task("gen-service-worker-app-prod", () => +task("gen-service-worker-app-prod", () => Promise.all( Object.entries(SW_MAP).map(async ([outPath, build]) => { const manifest = JSON.parse( diff --git a/build-scripts/gulp/translations.ts b/build-scripts/gulp/translations.ts index e192d3e410..bedf1e1396 100755 --- a/build-scripts/gulp/translations.ts +++ b/build-scripts/gulp/translations.ts @@ -1,9 +1,8 @@ -/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable max-classes-per-file */ import { deleteAsync } from "del"; import { glob } from "glob"; -import gulp from "gulp"; +import { src as glupSrc, dest as gulpDest, parallel, series, task } from "gulp"; import rename from "gulp-rename"; import merge from "lodash.merge"; import { createHash } from "node:crypto"; @@ -11,8 +10,8 @@ import { mkdir, readFile } from "node:fs/promises"; import { basename, join } from "node:path"; import { PassThrough, Transform } from "node:stream"; import { finished } from "node:stream/promises"; -import env from "../env"; -import paths from "../paths"; +import { isProdBuild } from "../env.ts"; +import paths from "../paths.ts"; import "./fetch-nightly-translations.ts"; const inFrontendDir = "translations/frontend"; @@ -24,9 +23,9 @@ const TEST_LOCALE = "en-x-test"; let mergeBackend = false; -gulp.task( +task( "translations-enable-merge-backend", - gulp.parallel(async () => { + parallel(async () => { mergeBackend = true; }, "allow-setup-fetch-nightly-translations") ); @@ -35,7 +34,11 @@ gulp.task( // The provided function can either return a new object, or an array of // [object, subdirectory] pairs for fragmentizing the JSON. class CustomJSON extends Transform { - constructor(func, reviver = null) { + _func: any; + + _reviver: any; + + constructor(func, reviver: any = null) { super({ objectMode: true }); this._func = func; this._reviver = reviver; @@ -57,9 +60,17 @@ class CustomJSON extends Transform { // Transform stream to merge Vinyl JSON files (buffer mode only). class MergeJSON extends Transform { - _objects = []; + _objects: any[] = []; - constructor(stem, startObj = {}, reviver = null) { + _stem: any; + + _startObj: any; + + _reviver: any; + + _outFile: any; + + constructor(stem, startObj = {}, reviver: any = null) { super({ objectMode: true, allowHalfOpen: false }); this._stem = stem; this._startObj = structuredClone(startObj); @@ -134,18 +145,17 @@ const lokaliseTransform = (data, path, original = data) => { return output; }; -gulp.task("clean-translations", () => deleteAsync([workDir])); +task("clean-translations", () => deleteAsync([workDir])); const makeWorkDir = () => mkdir(workDir, { recursive: true }); const createTestTranslation = () => - env.isProdBuild() + isProdBuild() ? Promise.resolve() - : gulp - .src(EN_SRC) + : glupSrc(EN_SRC) .pipe(new CustomJSON(null, testReviver)) .pipe(rename(`${TEST_LOCALE}.json`)) - .pipe(gulp.dest(workDir)); + .pipe(gulpDest(workDir)); /** * This task will build a master translation file, to be used as the base for @@ -157,11 +167,10 @@ const createTestTranslation = () => * the Lokalise update to translations/en.json will not happen immediately. */ const createMasterTranslation = () => - gulp - .src([EN_SRC, ...(mergeBackend ? [`${inBackendDir}/en.json`] : [])]) + glupSrc([EN_SRC, ...(mergeBackend ? [`${inBackendDir}/en.json`] : [])]) .pipe(new CustomJSON(lokaliseTransform)) .pipe(new MergeJSON("en")) - .pipe(gulp.dest(workDir)); + .pipe(gulpDest(workDir)); const FRAGMENTS = ["base"]; @@ -188,12 +197,12 @@ const createTranslations = async () => { // each locale, then fragmentizes and flattens the data for final output. const translationFiles = await glob([ `${inFrontendDir}/!(en).json`, - ...(env.isProdBuild() ? [] : [`${workDir}/${TEST_LOCALE}.json`]), + ...(isProdBuild() ? [] : [`${workDir}/${TEST_LOCALE}.json`]), ]); const hashStream = new Transform({ objectMode: true, transform: async (file, _, callback) => { - const hash = env.isProdBuild() + const hash = isProdBuild() ? createHash("md5").update(file.contents).digest("hex") : "dev"; HASHES.set(file.stem, hash); @@ -232,7 +241,7 @@ const createTranslations = async () => { }) ) ) - .pipe(gulp.dest(outDir)); + .pipe(gulpDest(outDir)); // Send the English master downstream first, then for each other locale // generate merged JSON data to continue piping. It begins with the master @@ -242,9 +251,9 @@ const createTranslations = async () => { // TODO: This is a naive interpretation of BCP47 that should be improved. // Will be OK for now as long as we don't have anything more complicated // than a base translation + region. - const masterStream = gulp - .src(`${workDir}/en.json`) - .pipe(new PassThrough({ objectMode: true })); + const masterStream = glupSrc(`${workDir}/en.json`).pipe( + new PassThrough({ objectMode: true }) + ); masterStream.pipe(hashStream, { end: false }); const mergesFinished = [finished(masterStream)]; for (const translationFile of translationFiles) { @@ -262,9 +271,9 @@ const createTranslations = async () => { } } } - const mergeStream = gulp - .src(mergeFiles, { allowEmpty: true }) - .pipe(new MergeJSON(locale, enMaster, emptyReviver)); + const mergeStream = glupSrc(mergeFiles, { allowEmpty: true }).pipe( + new MergeJSON(locale, enMaster, emptyReviver) + ); mergesFinished.push(finished(mergeStream)); mergeStream.pipe(hashStream, { end: false }); } @@ -277,12 +286,11 @@ const createTranslations = async () => { }; const writeTranslationMetaData = () => - gulp - .src([`${paths.translations_src}/translationMetadata.json`]) + glupSrc([`${paths.translations_src}/translationMetadata.json`]) .pipe( new CustomJSON((meta) => { // Add the test translation in development. - if (!env.isProdBuild()) { + if (!isProdBuild()) { meta[TEST_LOCALE] = { nativeName: "Translation Test" }; } // Filter out locales without a native name, and add the hashes. @@ -302,14 +310,14 @@ const writeTranslationMetaData = () => }; }) ) - .pipe(gulp.dest(workDir)); + .pipe(gulpDest(workDir)); -gulp.task( +task( "build-translations", - gulp.series( - gulp.parallel( + series( + parallel( "fetch-nightly-translations", - gulp.series("clean-translations", makeWorkDir) + series("clean-translations", makeWorkDir) ), createTestTranslation, createMasterTranslation, @@ -318,12 +326,12 @@ gulp.task( ) ); -gulp.task( +task( "build-supervisor-translations", - gulp.series(setFragment("supervisor"), "build-translations") + series(setFragment("supervisor"), "build-translations") ); -gulp.task( +task( "build-landing-page-translations", - gulp.series(setFragment("landing-page"), "build-translations") + series(setFragment("landing-page"), "build-translations") ); diff --git a/build-scripts/list-plugins-and-polyfills.ts b/build-scripts/list-plugins-and-polyfills.ts index 0aa2d9f29e..d4dba17a2f 100755 --- a/build-scripts/list-plugins-and-polyfills.ts +++ b/build-scripts/list-plugins-and-polyfills.ts @@ -1,17 +1,15 @@ #!/usr/bin/env node // Script to print Babel plugins and Core JS polyfills that will be used by browserslist environments -/* eslint-disable import/no-extraneous-dependencies */ -/* eslint-disable no-console */ import { version as babelVersion } from "@babel/core"; import presetEnv from "@babel/preset-env"; import compilationTargets from "@babel/helper-compilation-targets"; import coreJSCompat from "core-js-compat"; -// eslint-disable-next-line import/extensions + import { logPlugin } from "@babel/preset-env/lib/debug.js"; -// eslint-disable-next-line import/no-relative-packages, import/extensions +// eslint-disable-next-line import/no-relative-packages import shippedPolyfills from "../node_modules/babel-plugin-polyfill-corejs3/lib/shipped-proposals.js"; -import { babelOptions } from "./bundle"; +import { babelOptions } from "./bundle.ts"; const detailsOpen = (heading) => `
\n

${heading}

\n`; @@ -52,7 +50,7 @@ for (const buildType of ["Modern", "Legacy"]) { const browserslistEnv = buildType.toLowerCase(); const babelOpts = babelOptions({ latestBuild: browserslistEnv === "modern" }); const presetEnvOpts = babelOpts.presets[0][1]; - + if (typeof presetEnvOpts !== "object") { throw new Error( "The first preset in babelOptions is not an object. This is unexpected." diff --git a/build-scripts/paths.ts b/build-scripts/paths.ts index a670f721bf..54829211bc 100644 --- a/build-scripts/paths.ts +++ b/build-scripts/paths.ts @@ -1,63 +1,63 @@ -import path from "path"; +import path, { dirname as pathDirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +export const dirname = pathDirname(fileURLToPath(import.meta.url)); export default { - root_dir: path.resolve(__dirname, ".."), + root_dir: path.resolve(dirname, ".."), - build_dir: path.resolve(__dirname, "../build"), - app_output_root: path.resolve(__dirname, "../hass_frontend"), - app_output_static: path.resolve(__dirname, "../hass_frontend/static"), - app_output_latest: path.resolve( - __dirname, - "../hass_frontend/frontend_latest" - ), - app_output_es5: path.resolve(__dirname, "../hass_frontend/frontend_es5"), + build_dir: path.resolve(dirname, "../build"), + app_output_root: path.resolve(dirname, "../hass_frontend"), + app_output_static: path.resolve(dirname, "../hass_frontend/static"), + app_output_latest: path.resolve(dirname, "../hass_frontend/frontend_latest"), + app_output_es5: path.resolve(dirname, "../hass_frontend/frontend_es5"), - demo_dir: path.resolve(__dirname, "../demo"), - demo_output_root: path.resolve(__dirname, "../demo/dist"), - demo_output_static: path.resolve(__dirname, "../demo/dist/static"), - demo_output_latest: path.resolve(__dirname, "../demo/dist/frontend_latest"), - demo_output_es5: path.resolve(__dirname, "../demo/dist/frontend_es5"), + demo_dir: path.resolve(dirname, "../demo"), + demo_output_root: path.resolve(dirname, "../demo/dist"), + demo_output_static: path.resolve(dirname, "../demo/dist/static"), + demo_output_latest: path.resolve(dirname, "../demo/dist/frontend_latest"), + demo_output_es5: path.resolve(dirname, "../demo/dist/frontend_es5"), - cast_dir: path.resolve(__dirname, "../cast"), - cast_output_root: path.resolve(__dirname, "../cast/dist"), - cast_output_static: path.resolve(__dirname, "../cast/dist/static"), - cast_output_latest: path.resolve(__dirname, "../cast/dist/frontend_latest"), - cast_output_es5: path.resolve(__dirname, "../cast/dist/frontend_es5"), + cast_dir: path.resolve(dirname, "../cast"), + cast_output_root: path.resolve(dirname, "../cast/dist"), + cast_output_static: path.resolve(dirname, "../cast/dist/static"), + cast_output_latest: path.resolve(dirname, "../cast/dist/frontend_latest"), + cast_output_es5: path.resolve(dirname, "../cast/dist/frontend_es5"), - gallery_dir: path.resolve(__dirname, "../gallery"), - gallery_build: path.resolve(__dirname, "../gallery/build"), - gallery_output_root: path.resolve(__dirname, "../gallery/dist"), + gallery_dir: path.resolve(dirname, "../gallery"), + gallery_build: path.resolve(dirname, "../gallery/build"), + gallery_output_root: path.resolve(dirname, "../gallery/dist"), gallery_output_latest: path.resolve( - __dirname, + dirname, "../gallery/dist/frontend_latest" ), - gallery_output_static: path.resolve(__dirname, "../gallery/dist/static"), + gallery_output_static: path.resolve(dirname, "../gallery/dist/static"), - landingPage_dir: path.resolve(__dirname, "../landing-page"), - landingPage_build: path.resolve(__dirname, "../landing-page/build"), - landingPage_output_root: path.resolve(__dirname, "../landing-page/dist"), + landingPage_dir: path.resolve(dirname, "../landing-page"), + landingPage_build: path.resolve(dirname, "../landing-page/build"), + landingPage_output_root: path.resolve(dirname, "../landing-page/dist"), landingPage_output_latest: path.resolve( - __dirname, + dirname, "../landing-page/dist/frontend_latest" ), landingPage_output_es5: path.resolve( - __dirname, + dirname, "../landing-page/dist/frontend_es5" ), landingPage_output_static: path.resolve( - __dirname, + dirname, "../landing-page/dist/static" ), - hassio_dir: path.resolve(__dirname, "../hassio"), - hassio_output_root: path.resolve(__dirname, "../hassio/build"), - hassio_output_static: path.resolve(__dirname, "../hassio/build/static"), + hassio_dir: path.resolve(dirname, "../hassio"), + hassio_output_root: path.resolve(dirname, "../hassio/build"), + hassio_output_static: path.resolve(dirname, "../hassio/build/static"), hassio_output_latest: path.resolve( - __dirname, + dirname, "../hassio/build/frontend_latest" ), - hassio_output_es5: path.resolve(__dirname, "../hassio/build/frontend_es5"), + hassio_output_es5: path.resolve(dirname, "../hassio/build/frontend_es5"), hassio_publicPath: "/api/hassio/app", - translations_src: path.resolve(__dirname, "../src/translations"), + translations_src: path.resolve(dirname, "../src/translations"), }; diff --git a/build-scripts/rspack.ts b/build-scripts/rspack.ts index 15d03fcace..4b38727fc4 100644 --- a/build-scripts/rspack.ts +++ b/build-scripts/rspack.ts @@ -1,17 +1,25 @@ -/* eslint-disable import/no-extraneous-dependencies */ -/* eslint-disable import/no-import-module-exports */ import filterStats from "@bundle-stats/plugin-webpack-filter"; import { RsdoctorRspackPlugin } from "@rsdoctor/rspack-plugin"; -import * as rspack from "@rspack/core"; +import { DefinePlugin, NormalModuleReplacementPlugin } from "@rspack/core"; +import { defineConfig } from "@rspack/cli"; import log from "fancy-log"; -import { existsSync } from "fs"; -import path from "path"; +import { existsSync } from "node:fs"; +import path from "node:path"; import { WebpackManifestPlugin } from "rspack-manifest-plugin"; import TerserPlugin from "terser-webpack-plugin"; import { StatsWriterPlugin } from "webpack-stats-plugin"; +// @ts-ignore import WebpackBar from "webpackbar/rspack"; -import * as bundle from "./bundle"; -import * as paths from "./paths"; +import { + babelOptions, + config, + definedVars, + emptyPackages, + sourceMapURL, + swcOptions, + terserOptions, +} from "./bundle.ts"; +import paths from "./paths.ts"; class LogStartCompilePlugin { ignoredFirst = false; @@ -39,12 +47,23 @@ export const createRspackConfig = ({ isTestBuild, isHassioBuild, dontHash, +}: { + name: string; + entry: any; + outputPath: string; + publicPath: string; + defineOverlay?: Record; + isProdBuild?: boolean; + latestBuild?: boolean; + isStatsBuild?: boolean; + isTestBuild?: boolean; + isHassioBuild?: boolean; + dontHash?: Set; }) => { if (!dontHash) { dontHash = new Set(); } - const ignorePackages = bundle.ignorePackages({ latestBuild }); - return { + return defineConfig({ name, mode: isProdBuild ? "production" : "development", target: `browserslist:${latestBuild ? "modern" : "legacy"}`, @@ -67,7 +86,7 @@ export const createRspackConfig = ({ { loader: "babel-loader", options: { - ...bundle.babelOptions({ + ...babelOptions({ latestBuild, isProdBuild, isTestBuild, @@ -79,7 +98,7 @@ export const createRspackConfig = ({ }, { loader: "builtin:swc-loader", - options: bundle.swcOptions(), + options: swcOptions(), }, ], resolve: { @@ -100,7 +119,7 @@ export const createRspackConfig = ({ new TerserPlugin({ parallel: true, extractComments: true, - terserOptions: bundle.terserOptions({ latestBuild, isTestBuild }), + terserOptions: terserOptions({ latestBuild, isTestBuild }), }), ], moduleIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", @@ -119,7 +138,7 @@ export const createRspackConfig = ({ !chunk.canBeInitial() && !new RegExp( `^.+-work${latestBuild ? "(?:let|er)" : "let"}$` - ).test(chunk.name), + ).test(chunk?.name || ""), }, }, plugins: [ @@ -128,44 +147,11 @@ export const createRspackConfig = ({ // Only include the JS of entrypoints filter: (file) => file.isInitial && !file.name.endsWith(".map"), }), - new rspack.DefinePlugin( - bundle.definedVars({ isProdBuild, latestBuild, defineOverlay }) + new DefinePlugin( + definedVars({ isProdBuild, latestBuild, defineOverlay }) ), - new rspack.IgnorePlugin({ - checkResource(resource, context) { - // Only use ignore to intercept imports that we don't control - // inside node_module dependencies. - if ( - !context.includes("/node_modules/") || - // calling define.amd will call require("!!webpack amd options") - resource.startsWith("!!webpack") || - // loaded by webpack dev server but doesn't exist. - resource === "webpack/hot" || - resource.startsWith("@swc/helpers") - ) { - return false; - } - let fullPath; - try { - fullPath = resource.startsWith(".") - ? path.resolve(context, resource) - : require.resolve(resource); - } catch (err) { - console.error( - "Error in Home Assistant ignore plugin", - resource, - context - ); - throw err; - } - - return ignorePackages.some((toIgnorePath) => - fullPath.startsWith(toIgnorePath) - ); - }, - }), - new rspack.NormalModuleReplacementPlugin( - new RegExp(bundle.emptyPackages({ isHassioBuild }).join("|")), + new NormalModuleReplacementPlugin( + new RegExp(emptyPackages({ isHassioBuild }).join("|")), path.resolve(paths.root_dir, "src/util/empty.js") ), !isProdBuild && new LogStartCompilePlugin(), @@ -181,7 +167,9 @@ export const createRspackConfig = ({ isProdBuild && isStatsBuild && new RsdoctorRspackPlugin({ - reportDir: path.join(paths.build_dir, "rsdoctor"), + output: { + reportDir: path.join(paths.build_dir, "rsdoctor"), + }, features: ["plugins", "bundle"], supports: { generateTileGraph: true, @@ -216,7 +204,9 @@ export const createRspackConfig = ({ output: { module: latestBuild, filename: ({ chunk }) => - !isProdBuild || isStatsBuild || dontHash.has(chunk.name) + !isProdBuild || + isStatsBuild || + (chunk?.name && dontHash.has(chunk.name)) ? "[name].js" : "[name].[contenthash].js", chunkFilename: @@ -247,7 +237,7 @@ export const createRspackConfig = ({ // dev tools, and they stay happy getting 404s with valid requests. return `/unknown${path.resolve("/", info.resourcePath)}`; } - return new URL(info.resourcePath, bundle.sourceMapURL()).href; + return new URL(info.resourcePath, sourceMapURL()).href; } : undefined, ]) @@ -257,7 +247,7 @@ export const createRspackConfig = ({ layers: true, outputModule: true, }, - }; + }); }; export const createAppConfig = ({ @@ -265,27 +255,43 @@ export const createAppConfig = ({ latestBuild, isStatsBuild, isTestBuild, +}: { + isProdBuild?: boolean; + latestBuild?: boolean; + isStatsBuild?: boolean; + isTestBuild?: boolean; }) => createRspackConfig( - bundle.config.app({ isProdBuild, latestBuild, isStatsBuild, isTestBuild }) + config.app({ isProdBuild, latestBuild, isStatsBuild, isTestBuild }) ); -export const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => - createRspackConfig( - bundle.config.demo({ isProdBuild, latestBuild, isStatsBuild }) - ); +export const createDemoConfig = ({ + isProdBuild, + latestBuild, + isStatsBuild, +}: { + isProdBuild?: boolean; + latestBuild?: boolean; + isStatsBuild?: boolean; +}) => + createRspackConfig(config.demo({ isProdBuild, latestBuild, isStatsBuild })); export const createCastConfig = ({ isProdBuild, latestBuild }) => - createRspackConfig(bundle.config.cast({ isProdBuild, latestBuild })); + createRspackConfig(config.cast({ isProdBuild, latestBuild })); export const createHassioConfig = ({ isProdBuild, latestBuild, isStatsBuild, isTestBuild, +}: { + isProdBuild?: boolean; + latestBuild?: boolean; + isStatsBuild?: boolean; + isTestBuild?: boolean; }) => createRspackConfig( - bundle.config.hassio({ + config.hassio({ isProdBuild, latestBuild, isStatsBuild, @@ -294,7 +300,7 @@ export const createHassioConfig = ({ ); export const createGalleryConfig = ({ isProdBuild, latestBuild }) => - createRspackConfig(bundle.config.gallery({ isProdBuild, latestBuild })); + createRspackConfig(config.gallery({ isProdBuild, latestBuild })); export const createLandingPageConfig = ({ isProdBuild, latestBuild }) => - createRspackConfig(bundle.config.landingPage({ isProdBuild, latestBuild })); \ No newline at end of file + createRspackConfig(config.landingPage({ isProdBuild, latestBuild })); diff --git a/package.json b/package.json index 445aa15da0..85536681a0 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,7 @@ "prepack": "pinst --disable", "postpack": "pinst --enable", "test": "vitest run --config test/vitest.config.ts", - "test:coverage": "vitest run --config test/vitest.config.ts --coverage", - "gulp": "node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js" + "test:coverage": "vitest run --config test/vitest.config.ts --coverage" }, "author": "Paulus Schoutsen (http://paulusschoutsen.nl)", "license": "Apache-2.0", diff --git a/script/build_frontend b/script/build_frontend index 257a1ba5a4..a58f016649 100755 --- a/script/build_frontend +++ b/script/build_frontend @@ -6,4 +6,4 @@ set -e cd "$(dirname "$0")/.." -./node_modules/.bin/gulp build-app +node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js build-app diff --git a/script/develop b/script/develop index a695a1015a..81951f8b35 100755 --- a/script/develop +++ b/script/develop @@ -6,4 +6,4 @@ set -e cd "$(dirname "$0")/.." -./node_modules/.bin/gulp develop-app +node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js develop-app diff --git a/script/setup_translations b/script/setup_translations index 6a87c6106c..157aa58cc8 100755 --- a/script/setup_translations +++ b/script/setup_translations @@ -6,4 +6,4 @@ set -e cd "$(dirname "$0")/.." -./node_modules/.bin/gulp setup-and-fetch-nightly-translations \ No newline at end of file +node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js setup-and-fetch-nightly-translations \ No newline at end of file diff --git a/script/size_stats b/script/size_stats index 7f66b80449..da79f87573 100755 --- a/script/size_stats +++ b/script/size_stats @@ -6,4 +6,4 @@ set -e cd "$(dirname "$0")/.." -./node_modules/.bin/gulp analyze-app +node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js analyze-app diff --git a/script/translations_download b/script/translations_download index 6c1770f2df..ff1337ce22 100755 --- a/script/translations_download +++ b/script/translations_download @@ -8,4 +8,4 @@ set -eu -o pipefail cd "$(dirname "$0")/.." -./node_modules/.bin/gulp download-translations \ No newline at end of file +node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js download-translations \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index db58791d12..b502a2cb58 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,6 +26,7 @@ // Interop with CommonJS and other tools "esModuleInterop": true, "isolatedModules": true, + "allowImportingTsExtensions": true, "plugins": [ { "name": "ts-lit-plugin", diff --git a/yarn.lock b/yarn.lock index d53f762a38..198f1366b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4719,12 +4719,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=10.0.0": - version: 22.14.1 - resolution: "@types/node@npm:22.14.1" +"@types/node@npm:*, @types/node@npm:22.15.16, @types/node@npm:>=10.0.0": + version: 22.15.16 + resolution: "@types/node@npm:22.15.16" dependencies: undici-types: "npm:~6.21.0" - checksum: 10/561b1ad98ef5176d6da856ffbbe494f16655149f6a7d561de0423c8784910c81267d7d6459f59d68a97b3cbae9b5996b3b5dfe64f4de3de2239d295dcf4a4dcc + checksum: 10/d8055a0ab033ed16368109183f7e11d5364e5d8d5bd9a12df7fa1673a624823aaaaa54c0afef1648d0bfa7e12ef20b600f9d006accebecdb9931d2b72d05c7be languageName: node linkType: hard @@ -4735,15 +4735,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:22.15.16": - version: 22.15.16 - resolution: "@types/node@npm:22.15.16" - dependencies: - undici-types: "npm:~6.21.0" - checksum: 10/d8055a0ab033ed16368109183f7e11d5364e5d8d5bd9a12df7fa1673a624823aaaaa54c0afef1648d0bfa7e12ef20b600f9d006accebecdb9931d2b72d05c7be - languageName: node - linkType: hard - "@types/node@npm:^18.15.3": version: 18.19.86 resolution: "@types/node@npm:18.19.86" @@ -7641,17 +7632,6 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^0.9.1": - version: 0.9.1 - resolution: "enhanced-resolve@npm:0.9.1" - dependencies: - graceful-fs: "npm:^4.1.2" - memory-fs: "npm:^0.2.0" - tapable: "npm:^0.1.8" - checksum: 10/0044dad5e27adb608ba6c87939aef39ac3131d7f189470e5e3643ce78ec6ed06ccaed9e887103c64a2d36718d38e4568c0ffbdce5eed2bc6921cafc38d250ddc - languageName: node - linkType: hard - "entities@npm:^4.2.0, entities@npm:^4.4.0, entities@npm:^4.5.0": version: 4.5.0 resolution: "entities@npm:4.5.0" @@ -7977,27 +7957,6 @@ __metadata: languageName: node linkType: hard -"eslint-import-resolver-webpack@npm:0.13.10": - version: 0.13.10 - resolution: "eslint-import-resolver-webpack@npm:0.13.10" - dependencies: - debug: "npm:^3.2.7" - enhanced-resolve: "npm:^0.9.1" - find-root: "npm:^1.1.0" - hasown: "npm:^2.0.2" - interpret: "npm:^1.4.0" - is-core-module: "npm:^2.15.1" - is-regex: "npm:^1.2.0" - lodash: "npm:^4.17.21" - resolve: "npm:^2.0.0-next.5" - semver: "npm:^5.7.2" - peerDependencies: - eslint-plugin-import: ">=1.4.0" - webpack: ">=1.11.0" - checksum: 10/7d317bc96b2590ba83f0f2af2e64f67693452756bc95ffd77381e8177365ac10c2fb288776fc6620376d7fc811902a7efe4932010bc250a1ac5fd4171e2402fb - languageName: node - linkType: hard - "eslint-module-utils@npm:^2.12.0": version: 2.12.0 resolution: "eslint-module-utils@npm:2.12.0" @@ -8692,13 +8651,6 @@ __metadata: languageName: node linkType: hard -"find-root@npm:^1.1.0": - version: 1.1.0 - resolution: "find-root@npm:1.1.0" - checksum: 10/caa799c976a14925ba7f31ca1a226fe73d3aa270f4f1b623fcfeb1c6e263111db4beb807d8acd31bd4d48d44c343b93688a9288dfbccca27463c36a0301b0bb9 - languageName: node - linkType: hard - "find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -9222,7 +9174,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.8": +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.8": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 @@ -9554,7 +9506,6 @@ __metadata: eslint: "npm:9.26.0" eslint-config-airbnb-base: "npm:15.0.0" eslint-config-prettier: "npm:10.1.2" - eslint-import-resolver-webpack: "npm:0.13.10" eslint-plugin-import: "npm:2.31.0" eslint-plugin-lit: "npm:2.1.1" eslint-plugin-lit-a11y: "npm:4.1.4" @@ -9978,13 +9929,6 @@ __metadata: languageName: node linkType: hard -"interpret@npm:^1.4.0": - version: 1.4.0 - resolution: "interpret@npm:1.4.0" - checksum: 10/5beec568d3f60543d0f61f2c5969d44dffcb1a372fe5abcdb8013968114d4e4aaac06bc971a4c9f5bd52d150881d8ebad72a8c60686b1361f5f0522f39c0e1a3 - languageName: node - linkType: hard - "interpret@npm:^3.1.1": version: 3.1.1 resolution: "interpret@npm:3.1.1" @@ -10344,7 +10288,7 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.2.0, is-regex@npm:^1.2.1": +"is-regex@npm:^1.2.1": version: 1.2.1 resolution: "is-regex@npm:1.2.1" dependencies: @@ -11336,13 +11280,6 @@ __metadata: languageName: node linkType: hard -"memory-fs@npm:^0.2.0": - version: 0.2.0 - resolution: "memory-fs@npm:0.2.0" - checksum: 10/67ff4642b7767bf00159c248dbaa1203369866e9224579f8a7c7c0c3b0ed0a6e5eaa38b4753a9aa59e0f063bd09e2c9a2a97a8e593ec395b06ce216f75fc573d - languageName: node - linkType: hard - "merge-descriptors@npm:1.0.3": version: 1.0.3 resolution: "merge-descriptors@npm:1.0.3" @@ -13004,19 +12941,6 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^2.0.0-next.5": - version: 2.0.0-next.5 - resolution: "resolve@npm:2.0.0-next.5" - dependencies: - is-core-module: "npm:^2.13.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/2d6fd28699f901744368e6f2032b4268b4c7b9185fd8beb64f68c93ac6b22e52ae13560ceefc96241a665b985edf9ffd393ae26d2946a7d3a07b7007b7d51e79 - languageName: node - linkType: hard - "resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin": version: 1.22.10 resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d" @@ -13030,19 +12954,6 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin": - version: 2.0.0-next.5 - resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin::version=2.0.0-next.5&hash=c3c19d" - dependencies: - is-core-module: "npm:^2.13.0" - path-parse: "npm:^1.0.7" - supports-preserve-symlinks-flag: "npm:^1.0.0" - bin: - resolve: bin/resolve - checksum: 10/05fa778de9d0347c8b889eb7a18f1f06bf0f801b0eb4610b4871a4b2f22e220900cf0ad525e94f990bb8d8921c07754ab2122c0c225ab4cdcea98f36e64fa4c2 - languageName: node - linkType: hard - "restore-cursor@npm:^5.0.0": version: 5.1.0 resolution: "restore-cursor@npm:5.1.0" @@ -13345,15 +13256,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:^5.7.2": - version: 5.7.2 - resolution: "semver@npm:5.7.2" - bin: - semver: bin/semver - checksum: 10/fca14418a174d4b4ef1fecb32c5941e3412d52a4d3d85165924ce3a47fbc7073372c26faf7484ceb4bbc2bde25880c6b97e492473dc7e9708fdfb1c6a02d546e - languageName: node - linkType: hard - "semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -14279,13 +14181,6 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^0.1.8": - version: 0.1.10 - resolution: "tapable@npm:0.1.10" - checksum: 10/c1059b232ff4626dd032bc5620348983071c90edee5ebf779fb11bab59b31663d9d474da0d7c43c2004145f6dac260634a60b8dbd20691f514fc5d84fe5eda1f - languageName: node - linkType: hard - "tar@npm:7.4.3, tar@npm:^7.4.3": version: 7.4.3 resolution: "tar@npm:7.4.3"