Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/scripts/bundle-size.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function formatBytes(bytes, decimals = 2) {

const i = Math.floor(Math.log(bytes) / Math.log(k));

return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

export default async function checkBundleSize({ github, context }) {
Expand Down
31 changes: 28 additions & 3 deletions biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
"style": {
"useNodejsImportProtocol": "error",
// Enforce separate type imports for type-only imports to avoid bundling unneeded code
"useImportType": "error"
"useImportType": "error",
"useExportType": "error",
"useNumberNamespace": "warn"
},
"suspicious": {
// This one is specific to catch `console.log`. The rest of logs are permitted
Expand All @@ -53,7 +55,15 @@
"options": {
"allow": ["error", "warn", "info", "debug"]
}
}
},
"noVar": "error",
"noDoubleEquals": "error",
"noDebugger": "error",
"noDuplicateCase": "error",
"noExplicitAny": "off",
// To enable later
"noImplicitAnyLet": "off",
"noSparseArray": "error"
},
"correctness": {
"noUnusedVariables": {
Expand All @@ -63,7 +73,22 @@
}
},
"noUnusedFunctionParameters": "error",
"noUnusedImports": "error"
"noUnusedImports": "error",
"noUnreachable": "error",
"noConstantCondition": "warn",
"noConstructorReturn": "error",
"noEmptyPattern": "error"
},
"complexity": {
// There are many violations which require manual check
"noForEach": "off",
"noUselessFragments": "warn",
"useFlatMap": "warn",
// To enable later, as there are many warnings
"useOptionalChain": "off"
},
"performance": {
"noAccumulatingSpread": "warn"
}
}
},
Expand Down
30 changes: 8 additions & 22 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,16 @@ export default [
regexp: regexpEslint,
},
rules: {
// These off/configured-differently-by-default rules fit well for us
// Type-aware rules that Biome cannot replace
'@typescript-eslint/switch-exhaustiveness-check': 'error',
'@typescript-eslint/no-shadow': 'error',
'no-console': 'off',

// Todo: do we want these?
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
// Disabled - now handled by Biome
'no-console': 'off', // Biome: suspicious.noConsole
'@typescript-eslint/no-unused-vars': 'off', // Biome: correctness.noUnusedVariables
'prefer-const': 'off', // Biome: style.useConst
'@typescript-eslint/consistent-type-imports': 'off', // Biome: style.useImportType
'@typescript-eslint/await-thenable': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/class-literal-property-style': 'off',
Expand Down Expand Up @@ -99,13 +91,7 @@ export default [
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/no-explicit-any': 'off',

// Used by Biome
'@typescript-eslint/consistent-type-imports': 'off',
// These rules enabled by the preset configs don't work well for us
'@typescript-eslint/await-thenable': 'off',
'prefer-const': 'off',

// In some cases, using explicit letter-casing is more performant than the `i` flag
// Regex-specific rules (no Biome equivalent)
'regexp/use-ignore-case': 'off',
'regexp/prefer-regexp-exec': 'warn',
'regexp/prefer-regexp-test': 'warn',
Expand Down
2 changes: 1 addition & 1 deletion examples/hackernews/src/pages/[...stories].astro
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const mapStories = {

function safeParseInt(value: any, fallback: number) {
try {
return parseInt(value) || fallback;
return Number.parseInt(value) || fallback;
} catch {
return fallback;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/bin/astro.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const skipSemverCheckIfAbove = IS_STACKBLITZ ? 21 : 23;
async function main() {
const version = process.versions.node;
// Fast-path for higher Node.js versions
if ((parseInt(version) || 0) <= skipSemverCheckIfAbove) {
if ((Number.parseInt(version) || 0) <= skipSemverCheckIfAbove) {
const semver = await import('semver');
try {
if (!semver.satisfies(version, engines)) {
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/components/Image.astro
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ if (props.alt === undefined || props.alt === null) {

// As a convenience, allow width and height to be string with a number in them, to match HTML's native `img`.
if (typeof props.width === 'string') {
props.width = parseInt(props.width);
props.width = Number.parseInt(props.width);
}

if (typeof props.height === 'string') {
props.height = parseInt(props.height);
props.height = Number.parseInt(props.height);
}

const layout = props.layout ?? imageConfig.layout ?? 'none';
Expand Down
1 change: 1 addition & 0 deletions packages/astro/e2e/nested-recursive.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { test as base, expect } from '@playwright/test';
import { loadFixture, waitForHydrate } from './test-utils.js';

const test = base.extend({
// biome-ignore lint/correctness/noEmptyPattern: playwright needs this
astro: async ({}, use) => {
const fixture = await loadFixture(import.meta.url, { root: './fixtures/nested-recursive/' });
await use(fixture);
Expand Down
1 change: 1 addition & 0 deletions packages/astro/e2e/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function testFactory(testFile, inlineConfig) {
let fixture;

const test = testBase.extend({
// biome-ignore lint/correctness/noEmptyPattern: playwright needs this
astro: async ({}, use) => {
fixture = fixture || (await loadFixture(testFile, inlineConfig));
await use(fixture);
Expand Down
9 changes: 4 additions & 5 deletions packages/astro/src/actions/runtime/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,10 @@ export const codeToStatusMap = {
NETWORK_AUTHENTICATION_REQUIRED: 511,
} satisfies Record<string, number>;

const statusToCodeMap: Record<number, ActionErrorCode> = Object.entries(codeToStatusMap).reduce(
// reverse the key-value pairs
(acc, [key, value]) => ({ ...acc, [value]: key }),
{},
);
// reverse the key-value pairs
const statusToCodeMap: Record<number, ActionErrorCode> = Object.fromEntries(
Object.entries(codeToStatusMap).map(([key, value]) => [value, key]),
) as Record<number, ActionErrorCode>;

// T is used for error inference with SafeInput -> isInputError.
// See: https://github.com/withastro/astro/pull/11173/files#r1622767246
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function filterRequiredMetrics({

// Source: https://github.com/seek-oss/capsize/blob/b752693428b45994442433f7e3476ca4e3e3c507/packages/core/src/round.ts
function round(value: number) {
return parseFloat(value.toFixed(4));
return Number.parseFloat(value.toFixed(4));
}

// Source: https://github.com/seek-oss/capsize/blob/b752693428b45994442433f7e3476ca4e3e3c507/packages/core/src/createFontStack.ts#L5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export class LevenshteinStringMatcher implements StringMatcher {
}

#closest(str: string, arr: readonly string[]): string {
let min_distance = Infinity;
let min_distance = Number.POSITIVE_INFINITY;
let min_index = 0;
for (let i = 0; i < arr.length; i++) {
const dist = this.#distance(str, arr[i]);
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/assets/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { getConfiguredImageService, getImage } from './internal.js';
export { baseService, isLocalService } from './services/service.js';
export { type LocalImageProps, type RemoteImageProps } from './types.js';
export type { LocalImageProps, RemoteImageProps } from './types.js';
10 changes: 5 additions & 5 deletions packages/astro/src/assets/services/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function isLocalService(service: ImageService | undefined): service is Lo
}

export function parseQuality(quality: string): string | number {
let result = parseInt(quality);
let result = Number.parseInt(quality);
if (Number.isNaN(result)) {
return quality;
}
Expand Down Expand Up @@ -285,7 +285,7 @@ export const baseService: Omit<LocalImageService, 'transform'> = {
// For remote images, we don't know the original image's dimensions, so we cannot know the maximum width
// It is ultimately the user's responsibility to make sure they don't request images larger than the original
let imageWidth = options.width;
let maxWidth = Infinity;
let maxWidth = Number.POSITIVE_INFINITY;

// However, if it's an imported image, we can use the original image's width as a maximum width
if (isESMImportedImage(options.src)) {
Expand Down Expand Up @@ -322,7 +322,7 @@ export const baseService: Omit<LocalImageService, 'transform'> = {
if (typeof density === 'number') {
return density;
} else {
return parseFloat(density);
return Number.parseFloat(density);
}
});

Expand Down Expand Up @@ -402,8 +402,8 @@ export const baseService: Omit<LocalImageService, 'transform'> = {

const transform: BaseServiceTransform = {
src: params.get('href')!,
width: params.has('w') ? parseInt(params.get('w')!) : undefined,
height: params.has('h') ? parseInt(params.get('h')!) : undefined,
width: params.has('w') ? Number.parseInt(params.get('w')!) : undefined,
height: params.has('h') ? Number.parseInt(params.get('h')!) : undefined,
format: params.get('f') as ImageOutputFormat,
quality: params.get('q'),
fit: params.get('fit') as ImageFit,
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/assets/utils/queryParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export function getOrigQueryParams(
}

return {
width: parseInt(width),
height: parseInt(height),
width: Number.parseInt(width),
height: Number.parseInt(height),
format: format as ImageInputFormat,
};
}
2 changes: 1 addition & 1 deletion packages/astro/src/cli/add/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ async function tryToInstallIntegrations({

const inheritedFlags = Object.entries(flags)
.map(([flag]) => {
if (flag == '_') return;
if (flag === '_') return;
if (INHERITED_FLAGS.has(flag)) {
if (flag.length === 1) return `-${flag}`;
return `--${flag}`;
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/content/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,11 @@ export async function getEntryData<
}

export function getContentEntryExts(settings: Pick<AstroSettings, 'contentEntryTypes'>) {
return settings.contentEntryTypes.map((t) => t.extensions).flat();
return settings.contentEntryTypes.flatMap((t) => t.extensions);
}

export function getDataEntryExts(settings: Pick<AstroSettings, 'dataEntryTypes'>) {
return settings.dataEntryTypes.map((t) => t.extensions).flat();
return settings.dataEntryTypes.flatMap((t) => t.extensions);
}

export function getEntryConfigByExtMap<TEntryType extends ContentEntryType | DataEntryType>(
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ async function generatePathWithPrerenderer(
(url) =>
url.href
.replace(config.outDir.toString(), '')
.replace(/(?:\/index\.html|\.html)$/, '') == trimSlashes(pathname),
.replace(/(?:\/index\.html|\.html)$/, '') === trimSlashes(pathname),
)
) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/config/schemas/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export const AstroConfigSchema = z.object({
adapter: z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }).optional(),
integrations: z.preprocess(
// preprocess
(val) => (Array.isArray(val) ? val.flat(Infinity).filter(Boolean) : val),
(val) => (Array.isArray(val) ? val.flat(Number.POSITIVE_INFINITY).filter(Boolean) : val),
// validate
z
.array(z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }))
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/create-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ export async function createVite(
{ command: command === 'dev' ? 'serve' : command, mode },
];
// @ts-expect-error ignore TS2589: Type instantiation is excessively deep and possibly infinite.
plugins = plugins.flat(Infinity).filter((p) => {
plugins = plugins.flat(Number.POSITIVE_INFINITY).filter((p) => {
if (!p || p?.apply === applyToFilter) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/dev/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export async function createContainer({
// expected behavior: do not spawn a new tab
// ------------------------------------------------------
// Non-config files don't reach this point
const isServerOpenURL = typeof serverOpen == 'string' && !isRestart;
const isServerOpenURL = typeof serverOpen === 'string' && !isRestart;
const isServerOpenBoolean = serverOpen && !isRestart;

// Open server to the correct path. We pass the `base` here as we didn't pass the
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/core/preview/vite-plugin-astro-preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ export function vitePluginAstroPreview(settings: AstroSettings): Plugin {
if (!isRoot) {
const hasTrailingSlash = pathname.endsWith('/');

if (hasTrailingSlash && trailingSlash == 'never') {
if (hasTrailingSlash && trailingSlash === 'never') {
res.statusCode = 404;
res.end(notFoundTemplate(pathname, 'Not Found (trailingSlash is set to "never")'));
return;
}

if (
!hasTrailingSlash &&
trailingSlash == 'always' &&
trailingSlash === 'always' &&
!HAS_FILE_EXTENSION_REGEXP.test(pathname)
) {
res.statusCode = 404;
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/render/paginate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function generatePaginateFunction(

const result = [...Array(lastPage).keys()].map((num) => {
const pageNum = num + 1;
const start = pageSize === Infinity ? 0 : (pageNum - 1) * pageSize; // currentPage is 1-indexed
const start = pageSize === Number.POSITIVE_INFINITY ? 0 : (pageNum - 1) * pageSize; // currentPage is 1-indexed
const end = Math.min(start + pageSize, data.length);
const params = {
...additionalParams,
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/routing/rewrite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function findRouteToRewrite({
if (
!route.distURL.find(
(url) =>
url.href.replace(outDir.toString(), '').replace(/(?:\/index\.html|\.html)$/, '') ==
url.href.replace(outDir.toString(), '').replace(/(?:\/index\.html|\.html)$/, '') ===
trimSlashes(pathname),
)
) {
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/env/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const stringValidator =
const numberValidator =
({ gt, min, lt, max, int }: NumberSchema): ValueValidator =>
(input) => {
const num = parseFloat(input ?? '');
const num = Number.parseFloat(input ?? '');
if (isNaN(num)) {
return {
ok: false,
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/events/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export function eventCliSession(
flags?: Record<string, any>,
): { eventName: string; payload: EventPayload }[] {
// Filter out yargs default `_` flag which is the cli command
const cliFlags = flags ? Object.keys(flags).filter((name) => name != '_') : undefined;
const cliFlags = flags ? Object.keys(flags).filter((name) => name !== '_') : undefined;

const payload: EventPayload = {
cliCommand,
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/integrations/features-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function validateSupportedFeatures(
adapterName,
logger,
'hybridOutput',
() => settings.config.output == 'static' && settings.buildOutput === 'server',
() => settings.config.output === 'static' && settings.buildOutput === 'server',
);

validationResult.serverOutput = validateSupportKind(
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/integrations/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ export async function runHookConfigSetup({
// though accessible to integration authors if discovered.

function addPageExtension(...input: (string | string[])[]) {
const exts = (input.flat(Infinity) as string[]).map(
const exts = (input.flat(Number.POSITIVE_INFINITY) as string[]).map(
(ext) => `.${ext.replace(/^\./, '')}`,
);
updatedSettings.pageExtensions.push(...exts);
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/manifest/virtual-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export { base, i18n, trailingSlash, site, compressHTML, build, image };
`;
return { code };
}
if (id == RESOLVED_VIRTUAL_SERVER_ID) {
if (id === RESOLVED_VIRTUAL_SERVER_ID) {
if (this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.client) {
throw new AstroError({
...AstroErrorData.ServerOnlyModule,
Expand Down
Loading
Loading