Skip to content
1 change: 1 addition & 0 deletions eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,7 @@ export default defineConfig([
files: ['tests/e2e/**'],
rules: {
...playwright.configs['flat/recommended'].rules,
'playwright/no-conditional-in-test': [0],
},
},
{
Expand Down
5 changes: 3 additions & 2 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {readFileSync} from 'node:fs';
import {env} from 'node:process';
import {parse} from 'postcss';
import plugin from 'tailwindcss/plugin.js';
import {isTruthy} from './tools/utils.ts';
import type {Config} from 'tailwindcss';

const isProduction = env.NODE_ENV !== 'development';
Expand Down Expand Up @@ -37,7 +38,7 @@ export default {
'./{build,models,modules,routers,services}/**/*.go',
'./templates/**/*.tmpl',
'./web_src/js/**/*.{ts,js,vue}',
].filter(Boolean),
].filter(isTruthy),
blocklist: [
// classes that don't work without CSS variables from "@tailwind base" which we don't use
'transform', 'shadow', 'ring', 'blur', 'grayscale', 'invert', '!invert', 'filter', '!filter',
Expand Down Expand Up @@ -121,4 +122,4 @@ export default {
});
}),
],
} satisfies Config;
} satisfies Config as Config;
3 changes: 2 additions & 1 deletion tests/e2e/example.test.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ test('login', async ({page}, workerInfo) => {

test('logged in user', async ({browser}, workerInfo) => {
const context = await load_logged_in_context(browser, workerInfo, 'user2');
const page = await context.newPage();
if (!context) return;

const page = await context.newPage();
await page.goto('/');

// Make sure we routed to the home page. Else login failed.
Expand Down
21 changes: 16 additions & 5 deletions tools/generate-svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ function processAssetsSvgFiles(pattern: string, opts: Opts = {}) {
return glob(pattern).map((path) => processAssetsSvgFile(path, opts));
}

function lowercaseKeys(obj: Record<string, any> | undefined) {
if (!obj) return obj;
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key.toLowerCase(), value]));
}

async function processMaterialFileIcons() {
const paths = glob('node_modules/material-icon-theme/icons/*.svg');
const svgSymbols: Record<string, string> = {};
Expand Down Expand Up @@ -76,18 +81,24 @@ async function processMaterialFileIcons() {
// * https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers
// * https://github.com/microsoft/vscode/tree/1.98.0/extensions
delete iconRules.iconDefinitions;
for (const [k, v] of Object.entries(iconRules.fileNames)) iconRules.fileNames[k.toLowerCase()] = v;
for (const [k, v] of Object.entries(iconRules.folderNames)) iconRules.folderNames[k.toLowerCase()] = v;
for (const [k, v] of Object.entries(iconRules.fileExtensions)) iconRules.fileExtensions[k.toLowerCase()] = v;

iconRules.fileNames = lowercaseKeys(iconRules.fileNames);
iconRules.folderNames = lowercaseKeys(iconRules.fileNames);
iconRules.fileExtensions = lowercaseKeys(iconRules.fileNames);

// Use VSCode's "Language ID" mapping from its extensions
for (const [_, langIdExtMap] of Object.entries(vscodeExtensions)) {
for (const [langId, names] of Object.entries(langIdExtMap)) {
for (const name of names) {
const nameLower = name.toLowerCase();
if (nameLower[0] === '.') {
iconRules.fileExtensions[nameLower.substring(1)] ??= langId;
if (iconRules.fileExtensions) {
iconRules.fileExtensions[nameLower.substring(1)] ??= langId;
}
} else {
iconRules.fileNames[nameLower] ??= langId;
if (iconRules.fileNames) {
iconRules.fileNames[nameLower] ??= langId;
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions tools/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isTruthy<T>(value: T): value is T extends false | '' | 0 | null | undefined ? never : T { // eslint-disable-line unicorn/prefer-native-coercion-functions
return Boolean(value);
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"strictBindCallApply": true,
"strictBuiltinIteratorReturn": true,
"strictFunctionTypes": true,
"strictNullChecks": false,
"stripInternal": true,
"verbatimModuleSyntax": true,
"types": [
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/features/repo-issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ export function initRepoPullRequestReview() {
if (commentDiv) {
// get the name of the parent id
const groupID = commentDiv.closest('div[id^="code-comments-"]')?.getAttribute('id');
if (groupID && groupID.startsWith('code-comments-')) {
if (groupID?.startsWith('code-comments-')) {
const id = groupID.slice(14);
const ancestorDiffBox = commentDiv.closest<HTMLElement>('.diff-file-box');

Expand Down
7 changes: 4 additions & 3 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {readFileSync, globSync} from 'node:fs';
import {env} from 'node:process';
import tailwindcss from 'tailwindcss';
import tailwindConfig from './tailwind.config.ts';
import {isTruthy} from './tools/utils.ts';

const {EsbuildPlugin} = EsBuildLoader;
const {SourceMapDevToolPlugin, DefinePlugin, EnvironmentPlugin} = webpack;
Expand All @@ -30,7 +31,7 @@ const isProduction = env.NODE_ENV !== 'development';
// false - all disabled
let sourceMaps;
if ('ENABLE_SOURCEMAP' in env) {
sourceMaps = ['true', 'false'].includes(env.ENABLE_SOURCEMAP) ? env.ENABLE_SOURCEMAP : 'reduced';
sourceMaps = ['true', 'false'].includes(env.ENABLE_SOURCEMAP || '') ? env.ENABLE_SOURCEMAP : 'reduced';
} else {
sourceMaps = isProduction ? 'reduced' : 'true';
}
Expand Down Expand Up @@ -95,7 +96,7 @@ export default {
path: fileURLToPath(new URL('public/assets', import.meta.url)),
filename: () => 'js/[name].js',
chunkFilename: ({chunk}) => {
const language = (/monaco.*languages?_.+?_(.+?)_/.exec(String(chunk.id)) || [])[1];
const language = (/monaco.*languages?_.+?_(.+?)_/.exec(String(chunk?.id)) || [])[1];
return `js/${language ? `monaco-language-${language.toLowerCase()}` : `[name]`}.[contenthash:8].js`;
},
},
Expand Down Expand Up @@ -270,7 +271,7 @@ export default {
excludeAssets: [
/^js\/monaco-language-.+\.js$/,
!isProduction && /^licenses.txt$/,
].filter(Boolean),
].filter(isTruthy),
groupAssetsByChunk: false,
groupAssetsByEmitStatus: false,
groupAssetsByInfo: false,
Expand Down