chore: fix lint warnings

This commit is contained in:
3252a8
2026-05-13 14:13:39 +03:00
parent eec5635541
commit 2b7d1f0be8
21 changed files with 85 additions and 106 deletions
+3 -32
View File
@@ -90,8 +90,6 @@
let activeTab = "home"; let activeTab = "home";
let screen = "home"; let screen = "home";
let data = isPreviewBoard ? structuredCloneSafe(DEV_MOCK.data) : null; let data = isPreviewBoard ? structuredCloneSafe(DEV_MOCK.data) : null;
let selectedPlan = null;
let selectedMethod = "";
let trialBusy = false; let trialBusy = false;
let promoCode = ""; let promoCode = "";
let promoBusy = false; let promoBusy = false;
@@ -201,9 +199,7 @@
loginEmailFieldError, loginEmailFieldError,
loginEmailTooltipOpen, loginEmailTooltipOpen,
authResendCooldown, authResendCooldown,
email,
pendingEmail, pendingEmail,
emailCode,
} = $authStore); } = $authStore);
$: ({ $: ({
paymentModalOpen, paymentModalOpen,
@@ -234,12 +230,9 @@
linkEmailOpen, linkEmailOpen,
linkEmailBusy, linkEmailBusy,
linkTelegramBusy, linkTelegramBusy,
linkEmailValue,
linkEmailPending, linkEmailPending,
linkEmailCode,
linkEmailStatus, linkEmailStatus,
linkEmailIsError, linkEmailIsError,
linkEmailFieldError,
linkEmailResendCooldown, linkEmailResendCooldown,
languageBusy, languageBusy,
} = $accountStore); } = $accountStore);
@@ -489,16 +482,6 @@
}, 260); }, 260);
} }
function resolveTelegramWebApp() {
return telegramSdk.tg;
}
function refreshTelegramWebApp() {
tg = telegramSdk.refresh();
telegramMiniAppInitData = telegramSdk.initData;
return tg;
}
function readTelegramMiniAppInitDataFromLocation() { function readTelegramMiniAppInitDataFromLocation() {
return telegramSdk.readInitDataFromLocation(); return telegramSdk.readInitDataFromLocation();
} }
@@ -515,20 +498,6 @@
}); });
} }
async function ensureTelegramSdkForAction() {
tg = await telegramSdk.ensureForAction();
telegramMiniAppInitData = telegramSdk.initData;
return tg;
}
function createTelegramMiniAppAuthTimeout() {
return telegramSdk.createMiniAppAuthTimeout();
}
function shouldWaitForTelegramSdkBeforeOAuth() {
return hasTelegramLaunchParams() || !telegramOAuthClientId;
}
async function boot() { async function boot() {
await runWebappBoot({ await runWebappBoot({
MOCK, MOCK,
@@ -542,7 +511,9 @@
try { try {
tg.ready(); tg.ready();
tg.expand(); tg.expand();
} catch {} } catch (_error) {
void _error;
}
}, },
loadData, loadData,
showLogin, showLogin,
@@ -49,7 +49,6 @@
fmtDate, fmtDate,
fmtDateShort, fmtDateShort,
fmtMoney, fmtMoney,
optionLabel,
paymentStatusVariant, paymentStatusVariant,
trafficLeftLabel, trafficLeftLabel,
trafficOfLabel, trafficOfLabel,
@@ -79,7 +78,7 @@
export let languageOptions = []; export let languageOptions = [];
export let languageBusy = false; export let languageBusy = false;
export let onLanguageChange = () => {}; export let onLanguageChange = () => {};
export let t = (key, params = {}, fallback = "") => fallback || key; export let t = (key, _params = {}, fallback = "") => fallback || key;
const at = (key, params = {}, fallback = "") => t(`admin_${key}`, params, fallback || key); const at = (key, params = {}, fallback = "") => t(`admin_${key}`, params, fallback || key);
@@ -16,7 +16,7 @@
const adsStore = getContext("adsStore"); const adsStore = getContext("adsStore");
$: ({ ads, adsTotals, adsLoading, adCreateOpen, adDraft } = $adsStore); $: ({ ads, adsLoading, adCreateOpen, adDraft } = $adsStore);
$: adHeaders = [ $: adHeaders = [
at("id", {}, "ID"), at("id", {}, "ID"),
at("ads_col_source", {}, "Источник"), at("ads_col_source", {}, "Источник"),
@@ -527,7 +527,9 @@
<div class="admin-revenue-kpis" aria-hidden="true"> <div class="admin-revenue-kpis" aria-hidden="true">
{#each Array(6) as _, i (i)} {#each Array(6) as _, i (i)}
<div class="admin-revenue-kpi"> <div class="admin-revenue-kpi">
<span class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny" style="width:72%" <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny"
style="width:72%"
></span> ></span>
<span <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-strong" class="admin-skeleton admin-skeleton-line admin-skeleton-line-strong"
@@ -536,19 +538,25 @@
</div> </div>
{/each} {/each}
<div class="admin-revenue-kpi admin-revenue-kpi--wide"> <div class="admin-revenue-kpi admin-revenue-kpi--wide">
<span class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny" style="width:46%" <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny"
style="width:46%"
></span> ></span>
<span <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-strong" class="admin-skeleton admin-skeleton-line admin-skeleton-line-strong"
style="width:36%;height:20px;margin-top:4px" style="width:36%;height:20px;margin-top:4px"
></span> ></span>
<span class="admin-skeleton admin-skeleton-line" style="width:92%;height:9px;margin-top:6px" <span
class="admin-skeleton admin-skeleton-line"
style="width:92%;height:9px;margin-top:6px"
></span> ></span>
</div> </div>
</div> </div>
<div class="admin-revenue-chart"> <div class="admin-revenue-chart">
<div class="admin-revenue-chart-title"> <div class="admin-revenue-chart-title">
<span class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny" style="width:42%" <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny"
style="width:42%"
></span> ></span>
</div> </div>
<div class="admin-revenue-svg-frame"> <div class="admin-revenue-svg-frame">
@@ -579,7 +587,9 @@
<div class="admin-panel-dash-tiles" aria-hidden="true"> <div class="admin-panel-dash-tiles" aria-hidden="true">
{#each Array(9) as _, k (k)} {#each Array(9) as _, k (k)}
<div class="admin-panel-dash-tile"> <div class="admin-panel-dash-tile">
<span class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny" style="width:58%" <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny"
style="width:58%"
></span> ></span>
<span <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-strong" class="admin-skeleton admin-skeleton-line admin-skeleton-line-strong"
@@ -591,7 +601,9 @@
<div class="admin-panel-dash-nodes"> <div class="admin-panel-dash-nodes">
<div class="admin-panel-dash-nodes-head"> <div class="admin-panel-dash-nodes-head">
<span class="admin-skeleton admin-skeleton-line" style="width:40%;height:12px"></span> <span class="admin-skeleton admin-skeleton-line" style="width:40%;height:12px"></span>
<span class="admin-skeleton admin-skeleton-line" style="width:78%;height:9px;margin-top:6px" <span
class="admin-skeleton admin-skeleton-line"
style="width:78%;height:9px;margin-top:6px"
></span> ></span>
</div> </div>
<div class="admin-panel-dash-nodes-grid"> <div class="admin-panel-dash-nodes-grid">
@@ -615,7 +627,10 @@
</Card.Root> </Card.Root>
<Card.Root> <Card.Root>
<Card.Content class="admin-cn-card-content--flush" style="padding-top:12px;padding-bottom:12px;"> <Card.Content
class="admin-cn-card-content--flush"
style="padding-top:12px;padding-bottom:12px;"
>
<div class="admin-sync-strip" style="border:0;background:transparent;padding:0;"> <div class="admin-sync-strip" style="border:0;background:transparent;padding:0;">
<span <span
class="admin-skeleton admin-skeleton-line" class="admin-skeleton admin-skeleton-line"
@@ -632,7 +647,9 @@
<Card.Root> <Card.Root>
<Card.Header class="admin-cn-card-header--lead"> <Card.Header class="admin-cn-card-header--lead">
<span class="admin-skeleton admin-skeleton-line" style="width:44%;height:14px"></span> <span class="admin-skeleton admin-skeleton-line" style="width:44%;height:14px"></span>
<span class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny" style="width:30%;margin-top:8px" <span
class="admin-skeleton admin-skeleton-line admin-skeleton-line-tiny"
style="width:30%;margin-top:8px"
></span> ></span>
</Card.Header> </Card.Header>
<Card.Content class="admin-cn-card-content--flush"> <Card.Content class="admin-cn-card-content--flush">
@@ -852,7 +869,11 @@
{#if revenueGranularity !== "day"} {#if revenueGranularity !== "day"}
<span class="admin-revenue-chart-meta-sep" aria-hidden="true">·</span> <span class="admin-revenue-chart-meta-sep" aria-hidden="true">·</span>
<span <span
>{at("stats_revenue_chart_bucket_count", { count: revenueChartSeries.length }, "")}</span >{at(
"stats_revenue_chart_bucket_count",
{ count: revenueChartSeries.length },
""
)}</span
> >
{/if} {/if}
{#if revenueChartShortfall} {#if revenueChartShortfall}
@@ -867,11 +888,7 @@
{:else if revenueRangeMode === "custom" && revenueCustomDaySpan > 0} {:else if revenueRangeMode === "custom" && revenueCustomDaySpan > 0}
<span class="admin-revenue-chart-meta-sep" aria-hidden="true">·</span> <span class="admin-revenue-chart-meta-sep" aria-hidden="true">·</span>
<span <span
>{at( >{at("stats_revenue_chart_custom_span", { days: revenueCustomDaySpan }, "")}</span
"stats_revenue_chart_custom_span",
{ days: revenueCustomDaySpan },
""
)}</span
> >
{/if} {/if}
</div> </div>
@@ -16,11 +16,8 @@
tariffsSaving, tariffsSaving,
tariffDeleteOpen, tariffDeleteOpen,
tariffDeleteTarget, tariffDeleteTarget,
selectedBaseSquad,
selectedPremiumSquad,
panelSquadsLoading, panelSquadsLoading,
panelSquads, panelSquads,
tariffEditorTab,
} = $tariffsStore); } = $tariffsStore);
$: billingModelOptions = [ $: billingModelOptions = [
@@ -187,7 +184,7 @@
ariaLabel={at("btn_add_squad", {}, "Добавить основной сквад")} ariaLabel={at("btn_add_squad", {}, "Добавить основной сквад")}
onValueChange={(value) => { onValueChange={(value) => {
tariffsStore.addSquadToDraft("squadUuids", value); tariffsStore.addSquadToDraft("squadUuids", value);
selectedBaseSquad = ""; tariffsStore.update((s) => ({ ...s, selectedBaseSquad: "" }));
}} }}
/> />
<div class="admin-chip-list"> <div class="admin-chip-list">
@@ -331,7 +328,7 @@
ariaLabel={at("btn_add_premium_squad", {}, "Добавить premium-сквад")} ariaLabel={at("btn_add_premium_squad", {}, "Добавить premium-сквад")}
onValueChange={(value) => { onValueChange={(value) => {
tariffsStore.addSquadToDraft("premiumSquadUuids", value); tariffsStore.addSquadToDraft("premiumSquadUuids", value);
selectedPremiumSquad = ""; tariffsStore.update((s) => ({ ...s, selectedPremiumSquad: "" }));
}} }}
/> />
<div class="admin-chip-list"> <div class="admin-chip-list">
@@ -1,5 +1,5 @@
<script> <script>
import { Label, Select, Separator, Tabs } from "$components/ui/primitives.js"; import { Label, Separator, Tabs } from "$components/ui/primitives.js";
import Dialog from "$components/ui/dialog.svelte"; import Dialog from "$components/ui/dialog.svelte";
import { import {
AdminBadge, AdminBadge,
@@ -9,28 +9,14 @@
AdminTrafficCard, AdminTrafficCard,
} from "$components/patterns/admin/index.js"; } from "$components/patterns/admin/index.js";
import { import {
CalendarDays,
Copy, Copy,
CreditCard,
ExternalLink,
Eye, Eye,
Info,
Key,
Mail,
Map,
MessageSquare,
MousePointerClick,
QrCode,
RefreshCw, RefreshCw,
Send, Send,
Plus, Plus,
Settings,
Shield,
Trash2, Trash2,
User,
UserMinus, UserMinus,
UserPlus, UserPlus,
Users,
} from "$components/ui/icons.js"; } from "$components/ui/icons.js";
import { getContext } from "svelte"; import { getContext } from "svelte";
@@ -60,14 +46,11 @@
openedUserDetail, openedUserDetail,
userDetailLoading, userDetailLoading,
userMessageDraft, userMessageDraft,
userExtendDays,
userActionBusy, userActionBusy,
userDeleteOpen, userDeleteOpen,
userBanConfirmOpen, userBanConfirmOpen,
userMessageConfirmOpen, userMessageConfirmOpen,
userDetailTab,
premiumUnlimitedDraft, premiumUnlimitedDraft,
premiumBonusGbDraft,
} = $usersStore); } = $usersStore);
</script> </script>
@@ -1,6 +1,6 @@
import { writable } from "svelte/store"; import { writable } from "svelte/store";
export function createLogsStore({ api, at }) { export function createLogsStore({ api }) {
const state = writable({ const state = writable({
logs: [], logs: [],
logsTotal: 0, logsTotal: 0,
@@ -1,6 +1,6 @@
import { writable } from "svelte/store"; import { writable } from "svelte/store";
export function createPaymentsStore({ api, at }) { export function createPaymentsStore({ api }) {
const state = writable({ const state = writable({
payments: [], payments: [],
paymentsTotal: 0, paymentsTotal: 0,
@@ -8,7 +8,7 @@ export function createSettingsStore({ api, onToast, at }) {
settingsSaving: false, settingsSaving: false,
}); });
async function loadSettings(isCompact = false) { async function loadSettings() {
state.update((s) => ({ ...s, settingsLoading: true, settingsDirty: {} })); state.update((s) => ({ ...s, settingsLoading: true, settingsDirty: {} }));
try { try {
const data = await api("/admin/settings"); const data = await api("/admin/settings");
@@ -7,7 +7,7 @@ import {
normalizeUuidList, normalizeUuidList,
} from "../tariffDraft.js"; } from "../tariffDraft.js";
export function createTariffsStore({ api, onToast, onTariffsSaved, flash, at }) { export function createTariffsStore({ api, onTariffsSaved, flash, at }) {
const state = writable({ const state = writable({
tariffsCatalog: { tariffsCatalog: {
default_tariff: "", default_tariff: "",
@@ -62,7 +62,8 @@ export function createTariffsStore({ api, onToast, onTariffsSaved, flash, at })
try { try {
const data = await api("/admin/panel/internal-squads"); const data = await api("/admin/panel/internal-squads");
if (data?.ok) state.update((s) => ({ ...s, panelSquads: data.squads || [] })); if (data?.ok) state.update((s) => ({ ...s, panelSquads: data.squads || [] }));
} catch (e) { } catch (_error) {
void _error;
state.update((s) => ({ ...s, panelSquads: [] })); state.update((s) => ({ ...s, panelSquads: [] }));
} finally { } finally {
state.update((s) => ({ ...s, panelSquadsLoading: false })); state.update((s) => ({ ...s, panelSquadsLoading: false }));
@@ -118,7 +118,11 @@
{#each month.weeks as weekDates, wi (wi)} {#each month.weeks as weekDates, wi (wi)}
<RangeCalendar.GridRow class="admin-revenue-rcal__weekrow"> <RangeCalendar.GridRow class="admin-revenue-rcal__weekrow">
{#each weekDates as cellDate, di (`${wi}-${di}-${cellDate.toString()}`)} {#each weekDates as cellDate, di (`${wi}-${di}-${cellDate.toString()}`)}
<RangeCalendar.Cell date={cellDate} month={month.value} class="admin-revenue-rcal__cell"> <RangeCalendar.Cell
date={cellDate}
month={month.value}
class="admin-revenue-rcal__cell"
>
<RangeCalendar.Day class="admin-revenue-rcal__day"> <RangeCalendar.Day class="admin-revenue-rcal__day">
{cellDate.day} {cellDate.day}
</RangeCalendar.Day> </RangeCalendar.Day>
@@ -29,7 +29,7 @@
<tbody> <tbody>
{#each Array(rows) as _, rowIndex (rowIndex)} {#each Array(rows) as _, rowIndex (rowIndex)}
<tr> <tr>
{#each headers as header, colIndex (`${rowIndex}-${colIndex}`)} {#each headers as _header, colIndex (`${rowIndex}-${colIndex}`)}
<td> <td>
<Skeleton variant="line" width={widthFor(colIndex)} /> <Skeleton variant="line" width={widthFor(colIndex)} />
</td> </td>
@@ -16,8 +16,7 @@
function readReduceMotion() { function readReduceMotion() {
return ( return (
typeof window !== "undefined" && typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
window.matchMedia("(prefers-reduced-motion: reduce)").matches
); );
} }
@@ -35,9 +34,7 @@
}); });
$: backdropTransition = reduceMotion ? { duration: 0 } : { duration: 200 }; $: backdropTransition = reduceMotion ? { duration: 0 } : { duration: 200 };
$: cardIn = reduceMotion $: cardIn = reduceMotion ? { duration: 0, y: 0 } : { duration: 260, y: 16, easing: cubicOut };
? { duration: 0, y: 0 }
: { duration: 260, y: 16, easing: cubicOut };
$: cardOut = reduceMotion ? { duration: 0, y: 0 } : { duration: 200, y: 10, easing: cubicOut }; $: cardOut = reduceMotion ? { duration: 0, y: 0 } : { duration: 200, y: 10, easing: cubicOut };
</script> </script>
@@ -51,11 +48,7 @@
in:fade={backdropTransition} in:fade={backdropTransition}
out:fade={backdropTransition} out:fade={backdropTransition}
></button> ></button>
<section <section class={cn("dialog-card", className)} in:fly={cardIn} out:fly={cardOut}>
class={cn("dialog-card", className)}
in:fly={cardIn}
out:fly={cardOut}
>
<div class="dialog-head"> <div class="dialog-head">
<div> <div>
{#if title}<h2>{title}</h2>{/if} {#if title}<h2>{title}</h2>{/if}
@@ -1,4 +1,4 @@
export function createBillingActions({ api, t }) { export function createBillingActions({ api }) {
async function fetchTopupOptions(kind) { async function fetchTopupOptions(kind) {
return api(`/tariffs/topup-options?kind=${encodeURIComponent(kind)}`); return api(`/tariffs/topup-options?kind=${encodeURIComponent(kind)}`);
} }
@@ -226,7 +226,9 @@ export async function mockApi(path, options = {}, context = {}) {
let payload = {}; let payload = {};
try { try {
payload = options?.body ? JSON.parse(String(options.body)) : {}; payload = options?.body ? JSON.parse(String(options.body)) : {};
} catch {} } catch (_error) {
void _error;
}
DEV_MOCK.data.devices.devices = DEV_MOCK.data.devices.devices.filter( DEV_MOCK.data.devices.devices = DEV_MOCK.data.devices.devices.filter(
(device) => device.token !== payload.token (device) => device.token !== payload.token
); );
@@ -254,7 +256,9 @@ export async function mockApi(path, options = {}, context = {}) {
let payload = {}; let payload = {};
try { try {
payload = options?.body ? JSON.parse(String(options.body)) : {}; payload = options?.body ? JSON.parse(String(options.body)) : {};
} catch {} } catch (_error) {
void _error;
}
const language = normalizeLangCode(payload?.language || currentLang); const language = normalizeLangCode(payload?.language || currentLang);
DEV_MOCK.data.user.language_code = language; DEV_MOCK.data.user.language_code = language;
return { ok: true, language }; return { ok: true, language };
+13 -3
View File
@@ -2,6 +2,10 @@ export const TOKEN_STORAGE_KEY = "rw_webapp_token";
export const CSRF_COOKIE_NAME = "rw_webapp_csrf"; export const CSRF_COOKIE_NAME = "rw_webapp_csrf";
export const REFERRAL_STORAGE_KEY = "rw_webapp_referral"; export const REFERRAL_STORAGE_KEY = "rw_webapp_referral";
function ignoreStorageError(error) {
void error;
}
export function readCookie(name) { export function readCookie(name) {
if (typeof document === "undefined") return ""; if (typeof document === "undefined") return "";
const prefix = `${name}=`; const prefix = `${name}=`;
@@ -27,13 +31,17 @@ export function clearStoredToken(storageKey = TOKEN_STORAGE_KEY) {
export function markManualLogout(flagKey) { export function markManualLogout(flagKey) {
try { try {
localStorage.setItem(flagKey, "1"); localStorage.setItem(flagKey, "1");
} catch {} } catch (error) {
ignoreStorageError(error);
}
} }
export function clearManualLogoutFlag(flagKey) { export function clearManualLogoutFlag(flagKey) {
try { try {
localStorage.removeItem(flagKey); localStorage.removeItem(flagKey);
} catch {} } catch (error) {
ignoreStorageError(error);
}
} }
export function isManuallyLoggedOut(flagKey) { export function isManuallyLoggedOut(flagKey) {
@@ -49,7 +57,9 @@ export function rememberReferral(value) {
if (!normalized) return readReferral(); if (!normalized) return readReferral();
try { try {
localStorage.setItem(REFERRAL_STORAGE_KEY, normalized); localStorage.setItem(REFERRAL_STORAGE_KEY, normalized);
} catch {} } catch (error) {
ignoreStorageError(error);
}
return normalized; return normalized;
} }
@@ -216,7 +216,9 @@ export function createAccountStore({
clearToken(); clearToken();
try { try {
await publicApi("/auth/logout", { keepalive: true }); await publicApi("/auth/logout", { keepalive: true });
} catch {} } catch (_error) {
void _error;
}
showLogin(); showLogin();
} }
@@ -1,9 +1,6 @@
import { writable, get } from "svelte/store"; import { writable, get } from "svelte/store";
import { import {
readReferralParam, readReferralParam,
readTelegramAuthStatus,
readMagicLoginToken,
readTelegramLoginWidgetAuthData,
clearAuthQuery, clearAuthQuery,
buildTelegramOAuthStartUrl, buildTelegramOAuthStartUrl,
emailError, emailError,
@@ -17,7 +14,6 @@ export function createAuthStore({
getTg, getTg,
t, t,
currentLang, currentLang,
clearManualLogoutFlag,
}) { }) {
const state = writable({ const state = writable({
authStatus: "", authStatus: "",
@@ -73,7 +73,9 @@ export async function runWebappBoot({
if (initData) { if (initData) {
try { try {
if (await finalizeTelegramAuth(initData, "init_data")) return; if (await finalizeTelegramAuth(initData, "init_data")) return;
} catch {} } catch (_error) {
void _error;
}
} }
if (getToken() || getCsrfToken()) { if (getToken() || getCsrfToken()) {
@@ -8,10 +8,7 @@
priceLabel as priceLabelFn, priceLabel as priceLabelFn,
actionKey as actionKeyFn, actionKey as actionKeyFn,
} from "../lib/webapp/tariffs.js"; } from "../lib/webapp/tariffs.js";
import { import { premiumTitle as premiumTitleFn } from "../lib/webapp/traffic.js";
premiumTitle as premiumTitleFn,
trafficPercent as trafficPercentFn,
} from "../lib/webapp/traffic.js";
import { formatCompactNumber } from "../lib/webapp/formatters.js"; import { formatCompactNumber } from "../lib/webapp/formatters.js";
import Card from "$components/ui/card.svelte"; import Card from "$components/ui/card.svelte";
+4 -1
View File
@@ -29,7 +29,10 @@ export default defineConfig({
fileName: () => "subscription_webapp.js", fileName: () => "subscription_webapp.js",
cssFileName: "subscription_webapp", cssFileName: "subscription_webapp",
}, },
rollupOptions: { rolldownOptions: {
checks: {
pluginTimings: false,
},
output: { output: {
assetFileNames: (assetInfo) => { assetFileNames: (assetInfo) => {
if (assetInfo.name && assetInfo.name.endsWith(".css")) { if (assetInfo.name && assetInfo.name.endsWith(".css")) {