Use stylistic for deprecated eslint rules

During the eslint 8 cycle the formatting rules were split out [1],
deprecating the corresponding rules in core.

This replaces all rules that where moved to @stylistic/eslint-plugin [2]
and accounts for the difference in the indenting rule behaviour.

To allow the pre-commit import hack to continue to work with the
stylisitc plugin for a recent nodejs version to be used.

[1] https://eslint.org/blog/2023/10/deprecating-formatting-rules/
[2] https://eslint.style/packages/default

Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
This commit is contained in:
Ralph Sennhauser 2025-05-30 21:33:49 +02:00
parent ff03dd45c4
commit 0ce889ca6d
No known key found for this signature in database
36 changed files with 114 additions and 102 deletions

View file

@ -76,9 +76,11 @@ repos:
rev: v9.27.0
hooks:
- id: eslint
language_version: 22.14.0
additional_dependencies:
- eslint@9.27.0
- eslint-plugin-brace-rules@0.1.6
- "@stylistic/eslint-plugin@4.4.0"
args:
- --max-warnings=0
- --no-warn-ignored

View file

@ -33,7 +33,7 @@ function test_deepCompare()
// Some nestling.
TS_ASSERT(deepCompare({ "foo": new Set([1, 2, { "baz": Infinity }]), "bar": [new Set([9]), { "foo": [0, 1, 2] }] },
{ "foo": new Set([1, 2, { "baz": Infinity }]), "bar": [new Set([9]), { "foo": [0, 1, 2] }] }));
{ "foo": new Set([1, 2, { "baz": Infinity }]), "bar": [new Set([9]), { "foo": [0, 1, 2] }] }));
}
test_deepCompare();

View file

@ -167,7 +167,7 @@ function tryAutoComplete(text, autoCompleteList)
}
if (matchingWords.length != 1)
return text;
return text;
text = wordSplit.join(" ");
if (text.length > 0)

View file

@ -153,7 +153,7 @@ function reportMismatchingSoftwareVersions(mismatchType, clientMismatch, serverM
{
messageBox(
400, 200,
translate("Failed to connect to the server.") +
translate("Failed to connect to the server.") +
"\n\n" + getMismatchMessage(mismatchType, clientMismatch, serverMismatch),
translate("Disconnected")
);

View file

@ -81,7 +81,7 @@ function loadSettingValuesFile(filename)
{
keyContext = {};
for (const key of json.TranslatedKeys)
keyContext[key] = json.TranslationContext;
keyContext[key] = json.TranslationContext;
}
translateObjectKeys(json.Data, keyContext);

View file

@ -153,7 +153,7 @@ class SavegameList
this.gameSelection.list = this.savedGamesMetadata.map(metadata => 0);
this.gameSelection.list_data = this.savedGamesMetadata.map(metadata => metadata.id);
// Restore selection if the selected savegame still exists.
// Restore selection if the selected savegame still exists.
// If the last savegame was deleted, or if it was hidden by the compatibility filter, select the new last item.
const selectedGameIndex = this.savedGamesMetadata.findIndex(metadata => metadata.id == selectedGameId);
if (selectedGameIndex != -1)

View file

@ -188,8 +188,8 @@ var g_MainMenuItems = [
"enabled": () => !!Engine.StartXmppClient,
"hotkey": "lobby",
"onPress": () => {
if (Engine.StartXmppClient)
Engine.OpenChildPage("page_prelobby_entrance.xml");
if (Engine.StartXmppClient)
Engine.OpenChildPage("page_prelobby_entrance.xml");
}
},
{

View file

@ -100,7 +100,7 @@ MenuButtons.prototype.Summary = class
closeOpenDialogs();
this.pauseControl.implicitPause();
// Allows players to see their own summary.
// Allows players to see their own summary.
// If they have shared ally vision researched, they are able to see the summary of there allies too.
const simState = Engine.GuiInterfaceCall("GetExtendedSimulationState");
const data = await Engine.OpenChildPage(

View file

@ -667,7 +667,7 @@ g_SelectionPanels.Research = {
const sortedEntStates = unitEntStates.sort((a, b) =>
(!b.upgrade || !b.upgrade.isUpgrading) - (!a.upgrade || !a.upgrade.isUpgrading) ||
(!a.production ? 0 : a.production.queue.length) - (!b.production ? 0 : b.production.queue.length)
);
);
for (const state of sortedEntStates)
{
@ -1193,8 +1193,8 @@ g_SelectionPanels.Upgrade = {
data.button.onPress = function() {
upgradeEntity(
data.item.entity,
upgradableEntStates.map(state => state.id));
data.item.entity,
upgradableEntStates.map(state => state.id));
};
if (!requirementsMet || limits.canBeAddedCount == 0 &&

View file

@ -98,8 +98,8 @@ function calculateTeamCounterDataHelper()
{
g_TeamHelperData[playerState.team] = {};
for (const value of ["food", "vegetarianFood", "femaleCitizen", "worker", "enemyUnitsKilled",
"unitsLost", "mapControl", "mapControlPeak",
"mapExploration", "totalBought", "totalSold"])
"unitsLost", "mapControl", "mapControlPeak",
"mapExploration", "totalBought", "totalSold"])
g_TeamHelperData[playerState.team][value] = new Array(playerState.sequences.time.length).fill(0);
}

View file

@ -231,20 +231,20 @@ function* GenerateMap(mapSettings)
g_Map.log("Creating dirt patches");
createLayeredPatches(
[scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)],
[[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]],
[1, 1],
[avoidClasses(clForest, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)],
scaleByMapSize(15, 45),
clDirt);
[scaleByMapSize(3, 6), scaleByMapSize(5, 10), scaleByMapSize(8, 21)],
[[tMainTerrain, tTier1Terrain], [tTier1Terrain, tTier2Terrain], [tTier2Terrain, tTier3Terrain]],
[1, 1],
[avoidClasses(clForest, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)],
scaleByMapSize(15, 45),
clDirt);
g_Map.log("Creating grass patches");
createPatches(
[scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)],
tTier4Terrain,
[avoidClasses(clForest, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)],
scaleByMapSize(15, 45),
clDirt);
[scaleByMapSize(2, 4), scaleByMapSize(3, 7), scaleByMapSize(5, 15)],
tTier4Terrain,
[avoidClasses(clForest, 0, clDirt, 5, clPlayer, 12), stayClasses(clLand, 5)],
scaleByMapSize(15, 45),
clDirt);
yield 55;
g_Map.log("Creating plentiful mountain metal mines");

View file

@ -224,7 +224,7 @@ function* GenerateMap(mapSettings)
g_TileClasses.rock, 2,
g_TileClasses.spine, 2,
g_TileClasses.water, 3
],
],
"sizes": g_AllSizes,
"mixes": g_AllMixes,
"amounts": g_AllAmounts
@ -242,7 +242,7 @@ function* GenerateMap(mapSettings)
g_TileClasses.rock, 2,
g_TileClasses.spine, 2,
g_TileClasses.water, 5
],
],
"sizes": g_AllSizes,
"mixes": g_AllMixes,
"amounts": g_AllAmounts

View file

@ -101,7 +101,7 @@ function* GenerateMap(mapSettings)
g_TileClasses.mountain, 2,
g_TileClasses.player, 12,
g_TileClasses.step, 2
],
],
"stay": [g_TileClasses.valley, 7],
"sizes": ["normal"],
"mixes": ["normal"],

View file

@ -16,7 +16,7 @@ ConvexPolygonPlacer.prototype.place = function(constraint)
for (const point of getPointsInBoundingBox(getBoundingBox(this.polygonVertices)))
{
if (this.polygonVertices.some((vertex, i) =>
distanceOfPointFromLine(this.polygonVertices[i], this.polygonVertices[(i + 1) % this.polygonVertices.length], point) > 0))
distanceOfPointFromLine(this.polygonVertices[i], this.polygonVertices[(i + 1) % this.polygonVertices.length], point) > 0))
continue;
++count;

View file

@ -451,7 +451,7 @@ function* GenerateMap(mapSettings)
// NOTE: Since terrain generation is quite unpredictable actual water
// coverage might vary much with the same value
const averageWaterCoverage = 1 / 5;
// Water height in environment and the engine
// Water height in environment and the engine
const heightSeaGround = -MIN_HEIGHT + heightRange.min + averageWaterCoverage *
(heightRange.max - heightRange.min);
// Water height as terrain height

View file

@ -342,7 +342,7 @@ m.Template = m.Class({
continue;
const civTech = tech.replace("{civ}", civ);
techs[i] = TechnologyTemplates.Has(civTech) ?
civTech : tech.replace("{civ}", "generic");
civTech : tech.replace("{civ}", "generic");
}
return techs;
},
@ -878,7 +878,7 @@ m.Entity = m.Class({
if (this.position() !== undefined && unitToFleeFrom.position() !== undefined)
{
const FleeDirection = [this.position()[0] - unitToFleeFrom.position()[0],
this.position()[1] - unitToFleeFrom.position()[1]];
this.position()[1] - unitToFleeFrom.position()[1]];
const dist = m.VectorDistance(unitToFleeFrom.position(), this.position());
FleeDirection[0] = 40 * FleeDirection[0] / dist;
FleeDirection[1] = 40 * FleeDirection[1] / dist;

View file

@ -5,8 +5,7 @@ API3 = function(m)
* The map module.
* Copied with changes from QuantumState's original for qBot, it's a component for storing 8 bit values.
*/
/** The function needs to be named too because of the copyConstructor functionality */
// The function needs to be named too because of the copyConstructor functionality
m.Map = function Map(sharedScript, type, originalMap, actualCopy)
{
// get the correct dimensions according to the map type

View file

@ -81,11 +81,11 @@ m.SharedScript.prototype.init = function(state, deserialization)
this.passabilityMap = state.passabilityMap;
if (this.mapSize % this.passabilityMap.width !== 0)
error("AI shared component inconsistent sizes: map=" + this.mapSize + " while passability=" + this.passabilityMap.width);
error("AI shared component inconsistent sizes: map=" + this.mapSize + " while passability=" + this.passabilityMap.width);
this.passabilityMap.cellSize = this.mapSize / this.passabilityMap.width;
this.territoryMap = state.territoryMap;
if (this.mapSize % this.territoryMap.width !== 0)
error("AI shared component inconsistent sizes: map=" + this.mapSize + " while territory=" + this.territoryMap.width);
error("AI shared component inconsistent sizes: map=" + this.mapSize + " while territory=" + this.territoryMap.width);
this.territoryMap.cellSize = this.mapSize / this.territoryMap.width;
/*

View file

@ -4,7 +4,6 @@ API3 = function(m)
{
/** Wrapper around a technology template */
m.Technology = function(templateName)
{
this._templateName = templateName;

View file

@ -11,7 +11,6 @@ API3 = function(m)
* This is intended for use with 8 bit maps for reduced memory usage.
* Upgraded from QuantumState's original TerrainAnalysis for qBot.
*/
m.TerrainAnalysis = function()
{
};

View file

@ -431,7 +431,7 @@ PETRA.AttackPlan.prototype.addSiegeUnits = function(gameState)
return true;
// no minsize as we don't want the plan to fail at the last minute though.
const stat = { "priority": 1, "minSize": 0, "targetSize": targetSize, "batchSize": Math.min(targetSize, 2),
"classes": classes[i], "interests": [ ["siegeStrength", 3] ] };
"classes": classes[i], "interests": [ ["siegeStrength", 3] ] };
this.addBuildOrder(gameState, "Siege", stat, true);
return true;
};
@ -995,7 +995,7 @@ PETRA.AttackPlan.prototype.defaultTargetFinder = function(gameState, playerEnemy
// TODO Should add naval attacks against the last remaining ships.
if (!targets.hasEntities())
targets = gameState.getEntities(playerEnemy).filter(API3.Filters.byClass("ConquestCritical")).
filter(API3.Filters.not(API3.Filters.byClass("Ship")));
filter(API3.Filters.not(API3.Filters.byClass("Ship")));
return targets;
};

View file

@ -113,7 +113,7 @@ PETRA.getLandAccess = function(gameState, ent)
for (let d = 3; d < halfDepth; d += 3)
{
const pos = [ entPos[0] - d * sina,
entPos[1] - d * cosa];
entPos[1] - d * cosa];
access = gameState.ai.accessibility.getAccessValue(pos);
if (access > 1)
break;
@ -140,7 +140,7 @@ PETRA.getSeaAccess = function(gameState, ent)
for (let d = 3; d < 15; d += 3)
{
const pos = [ entPos[0] + d * sina,
entPos[1] + d * cosa];
entPos[1] + d * cosa];
sea = gameState.ai.accessibility.getAccessValue(pos, true);
if (sea > 1)
break;
@ -231,7 +231,7 @@ PETRA.returnResources = function(gameState, ent)
let distmin = Math.min();
const access = PETRA.getLandAccess(gameState, ent);
const dropsiteCollection = gameState.playerData.hasSharedDropsites ?
gameState.getAnyDropsites(resource) : gameState.getOwnDropsites(resource);
gameState.getAnyDropsites(resource) : gameState.getOwnDropsites(resource);
for (const dropsite of dropsiteCollection.values())
{
if (!dropsite.position())

View file

@ -116,7 +116,7 @@ PETRA.NavalManager.prototype.init = function(gameState, deserializing)
if (!this.landingZones[land])
this.landingZones[land] = {};
if (!this.landingZones[land][naval])
this.landingZones[land][naval] = new Set();
this.landingZones[land][naval] = new Set();
this.landingZones[land][naval].add(i);
}
// and keep only thoses with enough room around when possible

View file

@ -181,7 +181,7 @@ PETRA.QueueManager.prototype.printQueues = function(gameState)
}
API3.warn("Accounts");
for (const p in this.accounts)
API3.warn(p + ": " + uneval(this.accounts[p]));
API3.warn(p + ": " + uneval(this.accounts[p]));
API3.warn("Current Resources: " + uneval(gameState.getResources()));
API3.warn("Available Resources: " + uneval(this.getAvailableResources(gameState)));
API3.warn("Wanted Gather Rates: " + uneval(gameState.ai.HQ.GetWantedGatherRates(gameState)));

View file

@ -739,7 +739,7 @@ PETRA.ConstructionPlan.prototype.checkDockPlacement = function(gameState, x, z,
* if wantedSea is given, this tile should be inside this sea
*/
PETRA.ConstructionPlan.prototype.around = [[ 1.0, 0.0], [ 0.87, 0.50], [ 0.50, 0.87], [ 0.0, 1.0], [-0.50, 0.87], [-0.87, 0.50],
[-1.0, 0.0], [-0.87, -0.50], [-0.50, -0.87], [ 0.0, -1.0], [ 0.50, -0.87], [ 0.87, -0.50]];
[-1.0, 0.0], [-0.87, -0.50], [-0.50, -0.87], [ 0.0, -1.0], [ 0.50, -0.87], [ 0.87, -0.50]];
PETRA.ConstructionPlan.prototype.isDockLocation = function(gameState, j, dimension, wantedLand, wantedSea)
{

View file

@ -133,7 +133,7 @@ PETRA.Worker.prototype.update = function(gameState, ent)
const distanceSquare = PETRA.isFastMoving(ent) ? 90000 : 30000;
const targetAccess = PETRA.getLandAccess(gameState, target);
const foodDropsites = gameState.playerData.hasSharedDropsites ?
gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food");
gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food");
let hasFoodDropsiteWithinDistance = false;
for (const dropsite of foodDropsites.values())
{
@ -153,7 +153,7 @@ PETRA.Worker.prototype.update = function(gameState, ent)
}
if (!hasFoodDropsiteWithinDistance)
{
if (this.retryWorking(gameState, subrole))
if (this.retryWorking(gameState, subrole))
return;
ent.stopMoving();
}
@ -766,7 +766,7 @@ PETRA.Worker.prototype.startHunting = function(gameState, position)
const isRanged = this.ent.hasClass("Ranged");
const entPosition = position ? position : this.ent.position();
const foodDropsites = gameState.playerData.hasSharedDropsites ?
gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food");
gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food");
const hasFoodDropsiteWithinDistance = function(supplyPosition, supplyAccess, distSquare)
{
@ -875,7 +875,7 @@ PETRA.Worker.prototype.startFishing = function(gameState)
const fisherSea = PETRA.getSeaAccess(gameState, this.ent);
const fishDropsites = (gameState.playerData.hasSharedDropsites ? gameState.getAnyDropsites("food") : gameState.getOwnDropsites("food")).
filter(API3.Filters.byClass("Dock")).toEntityArray();
filter(API3.Filters.byClass("Dock")).toEntityArray();
const nearestDropsiteDist = function(supply) {
let distMin = 1000000;

View file

@ -779,7 +779,7 @@ Attack.prototype.OnValueModification = function(msg)
return;
if (this.GetAttackTypes().some(type =>
msg.valueNames.indexOf("Attack/" + type + "/MaxRange") != -1))
msg.valueNames.indexOf("Attack/" + type + "/MaxRange") != -1))
cmpUnitAI.UpdateRangeQueries();
};

View file

@ -331,8 +331,8 @@ BuildingAI.prototype.FireArrows = function()
let targets = [];
const addTarget = function(target)
{
const pref = (cmpAttack.GetPreference(target) ?? 49);
targets.push({ "entityId": target, "preference": pref });
const pref = (cmpAttack.GetPreference(target) ?? 49);
targets.push({ "entityId": target, "preference": pref });
};
// Add the UnitAI target separately, as the UnitMotion and RangeManager implementations differ.
@ -345,7 +345,7 @@ BuildingAI.prototype.FireArrows = function()
if (!this.focusTargets.length)
{
for (const target of this.targetUnits)
addTarget(target);
addTarget(target);
// Sort targets by preference and then by proximity.
targets.sort((a, b) => {
if (a.preference > b.preference)

View file

@ -323,9 +323,9 @@ ProductionQueue.prototype.AddItem = function(templateName, type, count, metadata
const player = cmpPlayer.GetPlayerID();
const cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGUIInterface.PushNotification({
"players": [player],
"message": markForTranslation("The production queue is full."),
"translateMessage": true,
"players": [player],
"message": markForTranslation("The production queue is full."),
"translateMessage": true,
});
return false;
}

View file

@ -274,9 +274,9 @@ Researcher.prototype.GetTechCostMultiplier = function()
const techCostMultiplier = {};
for (const res of Resources.GetCodes().concat(["time"]))
techCostMultiplier[res] = ApplyValueModificationsToEntity(
"Researcher/TechCostMultiplier/" + res,
+(this.template?.TechCostMultiplier?.[res] || 1),
this.entity);
"Researcher/TechCostMultiplier/" + res,
+(this.template?.TechCostMultiplier?.[res] || 1),
this.entity);
return techCostMultiplier;
};

View file

@ -205,7 +205,7 @@ TechnologyManager.prototype.Init = function()
this.classCounts = {}; // stores the number of entities of each Class
this.typeCountsByClass = {}; // stores the number of entities of each type for each class i.e.
// {"someClass": {"unit/spearman": 2, "unit/cav": 5} "someOtherClass":...}
// {"someClass": {"unit/spearman": 2, "unit/cav": 5} "someOtherClass":...}
// Some technologies are automatically researched when their conditions are met. They have no cost and are
// researched instantly. This allows civ bonuses and more complicated technologies.

View file

@ -305,9 +305,9 @@ Trainer.prototype.Item.prototype.Spawn = function()
// Play a sound, but only for the first in the batch (to avoid nasty phasing effects).
PlaySound("trained", createdEnts[0]);
Engine.PostMessage(this.trainer, MT_TrainingFinished, {
"entities": createdEnts,
"owner": this.player,
"metadata": this.metadata
"entities": createdEnts,
"owner": this.player,
"metadata": this.metadata
});
}
if (this.count)
@ -317,9 +317,9 @@ Trainer.prototype.Item.prototype.Spawn = function()
if (!this.spawnNotified)
{
Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface).PushNotification({
"players": [cmpPlayer.GetPlayerID()],
"message": markForTranslation("Can't find free space to spawn trained units."),
"translateMessage": true
"players": [cmpPlayer.GetPlayerID()],
"message": markForTranslation("Can't find free space to spawn trained units."),
"translateMessage": true
});
this.spawnNotified = true;
}
@ -567,9 +567,9 @@ Trainer.prototype.CalculateTrainCostMultiplier = function()
{
for (const res of Resources.GetCodes().concat(["time"]))
this.trainCostMultiplier[res] = ApplyValueModificationsToEntity(
"Trainer/TrainCostMultiplier/" + res,
+(this.template?.TrainCostMultiplier?.[res] || 1),
this.entity);
"Trainer/TrainCostMultiplier/" + res,
+(this.template?.TrainCostMultiplier?.[res] || 1),
this.entity);
};
/**
@ -587,9 +587,9 @@ Trainer.prototype.GetBatchTime = function(batchSize)
{
// TODO: work out what equation we should use here.
return Math.pow(batchSize, ApplyValueModificationsToEntity(
"Trainer/BatchTimeModifier",
+(this.template?.BatchTimeModifier || 1),
this.entity));
"Trainer/BatchTimeModifier",
+(this.template?.BatchTimeModifier || 1),
this.entity));
};
/**

View file

@ -129,7 +129,7 @@ TS_ASSERT(!increased);
let looted;
AddMock(target, IID_Loot, {
"GetXp": () => {
looted = true; return 80;
looted = true; return 80;
}
});

View file

@ -56,9 +56,9 @@ PositionHelper.prototype.InterpolatedLocation = function(ent, lateness)
const cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
const turnLength = cmpTimer.GetLatestTurnLength();
return new Vector3D(
(curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
0,
(curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength
(curPos.x * (turnLength - lateness) + prevPos.x * lateness) / turnLength,
0,
(curPos.z * (turnLength - lateness) + prevPos.z * lateness) / turnLength
);
};

View file

@ -1,8 +1,10 @@
// Hack to get eslint run via pre-commit to find the braces plugin in the pre-commit cache,
// should be 'import braceRules from "eslint-plugin-brace-rules";'
// NODE_PATH isn't supprorted for ESM modules [1], so for eslint to be able to
// be run via pre-commit use a workaround instead of static import.
// [1] https://nodejs.org/api/esm.html#esm_no_node_path
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const braceRules = require("eslint-plugin-brace-rules");
const stylistic = require("@stylistic/eslint-plugin");
const configIgnores = {
@ -34,9 +36,6 @@ const configEslintBase = {
"no-duplicate-case": 1,
"no-empty": 1,
"no-extra-boolean-cast": 0,
"no-extra-parens": 0,
"no-extra-semi": 1,
"no-floating-decimal": 1,
"no-func-assign": 1,
"no-negated-in-lhs": 1,
"no-obj-calls": 1,
@ -53,10 +52,6 @@ const configEslintBase = {
"no-invalid-this": 1,
"no-loop-func": 0,
"no-multi-spaces": ["warn", {
"ignoreEOLComments": true,
}],
"no-new": 1,
"no-redeclare": 0,
"no-return-assign": 1,
@ -74,30 +69,13 @@ const configEslintBase = {
"no-undef": 0,
"no-undef-init": 1,
"no-unused-vars": 0,
"comma-spacing": 1,
"indent": ["warn", "tab", {
"outerIIFEBody": 0,
}],
"key-spacing": 1,
"new-cap": 0,
"new-parens": 1,
"no-mixed-spaces-and-tabs": ["warn", "smart-tabs"],
"no-multi-assign": 1,
"no-trailing-spaces": 1,
"no-unneeded-ternary": 1,
"no-irregular-whitespace": 1,
"object-curly-spacing": ["warn", "always"],
"operator-assignment": 1,
"operator-linebreak": ["warn", "after"],
"quote-props": 1,
"semi": 1,
"semi-spacing": 1,
"space-before-function-paren": ["warn", "never"],
"space-in-parens": 1,
"space-unary-ops": 1,
"spaced-comment": ["warn", "always"],
"no-class-assign": 1,
"no-const-assign": 1,
"no-dupe-class-members": 1,
@ -106,6 +84,35 @@ const configEslintBase = {
};
const configStylistic = {
"plugins": {
'@stylistic': stylistic
},
"rules": {
"@stylistic/comma-spacing": "warn",
"@stylistic/indent": ["warn", "tab", { "outerIIFEBody": "off" }],
"@stylistic/key-spacing": "warn",
"@stylistic/new-parens": "warn",
"@stylistic/no-extra-parens": "off",
"@stylistic/no-extra-semi": "warn",
"@stylistic/no-floating-decimal": "warn",
"@stylistic/no-mixed-spaces-and-tabs": ["warn", "smart-tabs"],
"@stylistic/no-multi-spaces": ["warn", { "ignoreEOLComments": true }],
"@stylistic/no-trailing-spaces": "warn",
"@stylistic/object-curly-spacing": ["warn", "always"],
"@stylistic/operator-linebreak": ["warn", "after"],
"@stylistic/quote-props": "warn",
"@stylistic/semi": "warn",
"@stylistic/semi-spacing": "warn",
"@stylistic/space-before-function-paren": ["warn", "never"],
"@stylistic/space-in-parens": "warn",
"@stylistic/space-unary-ops": "warn",
"@stylistic/spaced-comment": ["warn", "always"],
}
};
const configBracesRules = {
"plugins": {
"brace-rules": braceRules
@ -139,5 +146,7 @@ const configBracesRules = {
const configs = [configIgnores, configEslintBase];
configs[1].plugins = { ...configBracesRules.plugins };
Object.assign(configs[1].rules, configBracesRules.rules);
Object.assign(configs[1].plugins, configStylistic.plugins);
Object.assign(configs[1].rules, configStylistic.rules);
export default configs;

View file

@ -1,9 +1,13 @@
{
"type": "module",
"devDependencies": {
"@stylistic/eslint-plugin": "^4.4.0",
"eslint": "^9.27.0",
"eslint-plugin-brace-rules": "^0.1.6"
},
"engines": {
"node": ">=20.0.0"
},
"scripts": {
"lint": "eslint",
"lint:fix": "eslint --fix"