mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-31 05:06:38 +00:00
Implement correct types
This commit is contained in:
parent
ff3b65605e
commit
8f7760f88f
@ -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<string, string> = {
|
||||
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"
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
},
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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";
|
||||
},
|
||||
|
@ -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<void>[] = [];
|
||||
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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<unknown, 302> 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")
|
||||
);
|
||||
|
@ -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",
|
||||
|
@ -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"),
|
||||
|
@ -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 });
|
||||
}
|
||||
|
@ -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"])
|
||||
)
|
||||
);
|
||||
|
@ -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";
|
||||
},
|
||||
|
@ -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"));
|
||||
|
@ -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(),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -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(
|
||||
|
@ -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")
|
||||
);
|
||||
|
@ -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) =>
|
||||
`<details>\n<summary><h4>${heading}</h4></summary>\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."
|
||||
|
@ -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"),
|
||||
};
|
||||
|
@ -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<string, any>;
|
||||
isProdBuild?: boolean;
|
||||
latestBuild?: boolean;
|
||||
isStatsBuild?: boolean;
|
||||
isTestBuild?: boolean;
|
||||
isHassioBuild?: boolean;
|
||||
dontHash?: Set<string>;
|
||||
}) => {
|
||||
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 }));
|
||||
createRspackConfig(config.landingPage({ isProdBuild, latestBuild }));
|
||||
|
@ -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 <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
|
||||
"license": "Apache-2.0",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -6,4 +6,4 @@ set -e
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
./node_modules/.bin/gulp setup-and-fetch-nightly-translations
|
||||
node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js setup-and-fetch-nightly-translations
|
@ -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
|
||||
|
@ -8,4 +8,4 @@ set -eu -o pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
./node_modules/.bin/gulp download-translations
|
||||
node --import ./ts-node-register.js node_modules/gulp/bin/gulp.js download-translations
|
@ -26,6 +26,7 @@
|
||||
// Interop with CommonJS and other tools
|
||||
"esModuleInterop": true,
|
||||
"isolatedModules": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "ts-lit-plugin",
|
||||
|
117
yarn.lock
117
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<compat/resolve>, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin<compat/resolve>":
|
||||
version: 1.22.10
|
||||
resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin<compat/resolve>::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<compat/resolve>":
|
||||
version: 2.0.0-next.5
|
||||
resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#optional!builtin<compat/resolve>::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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user