diff --git a/.gitea/workflows/stale.yml b/.gitea/workflows/stale.yml new file mode 100644 index 0000000..7ba5af9 --- /dev/null +++ b/.gitea/workflows/stale.yml @@ -0,0 +1,15 @@ +name: "Close stale issues and PRs" +on: + workflow_dispatch: + schedule: + - cron: "@hourly" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-pr-message: "Will be closed in x days bc yo mom is a bitch. im not telling you when it will be closed fuckface" + days-before-pr-stale: 2 + days-before-pr-close: 3 diff --git a/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java b/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java index c9f57d7..4f22c9d 100644 --- a/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java +++ b/backend/src/main/java/de/szut/casino/blackjack/BlackJackGameEntity.java @@ -4,8 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonManagedReference; import de.szut.casino.user.UserEntity; import jakarta.persistence.*; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Positive; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/backend/src/main/java/de/szut/casino/dice/DiceDto.java b/backend/src/main/java/de/szut/casino/dice/DiceDto.java index ecbf3d7..f0caf48 100644 --- a/backend/src/main/java/de/szut/casino/dice/DiceDto.java +++ b/backend/src/main/java/de/szut/casino/dice/DiceDto.java @@ -5,12 +5,14 @@ import jakarta.validation.constraints.DecimalMax; import jakarta.validation.constraints.DecimalMin; import jakarta.validation.constraints.NotNull; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import java.math.BigDecimal; @Getter @Setter +@NoArgsConstructor public class DiceDto extends BetDto { private boolean rollOver; diff --git a/backend/src/main/java/de/szut/casino/dice/DiceService.java b/backend/src/main/java/de/szut/casino/dice/DiceService.java index 71e4584..836620b 100644 --- a/backend/src/main/java/de/szut/casino/dice/DiceService.java +++ b/backend/src/main/java/de/szut/casino/dice/DiceService.java @@ -11,10 +11,11 @@ import java.util.Random; @Service public class DiceService { private static final int MAX_DICE_VALUE = 100; - private final Random random = new Random(); + private final Random random; private final BalanceService balanceService; - public DiceService(BalanceService balanceService) { + public DiceService(Random random, BalanceService balanceService) { + this.random = random; this.balanceService = balanceService; } diff --git a/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java new file mode 100644 index 0000000..6b2e230 --- /dev/null +++ b/backend/src/test/java/de/szut/casino/dice/DiceServiceTest.java @@ -0,0 +1,251 @@ +package de.szut.casino.dice; + +import de.szut.casino.shared.service.BalanceService; +import de.szut.casino.user.UserEntity; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class DiceServiceTest { + + @Mock + private BalanceService balanceService; + + @Mock + private Random random; + + @InjectMocks + private DiceService diceService; + + private UserEntity user; + private DiceDto diceDto; + + @BeforeEach + void setUp() { + user = new UserEntity(); + user.setId(1L); + user.setBalance(BigDecimal.valueOf(1000)); + + diceDto = new DiceDto(); + diceDto.setBetAmount(BigDecimal.valueOf(10)); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + diceDto.setRollOver(true); + } + + @Test + void play_rollOver_win() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(55); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(56), result.getRolledValue()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollOver_lose() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(49); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(50), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_win() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(48); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(49), result.getRolledValue()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_lose() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(50)); + when(random.nextInt(anyInt())).thenReturn(50); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(51), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollOver_targetValueOne_rolledOne_lose() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(1)); + when(random.nextInt(anyInt())).thenReturn(0); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(1), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollOver_targetValueOne_rolledTwo_win() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(1)); + when(random.nextInt(anyInt())).thenReturn(1); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(2), result.getRolledValue()); + // Win chance for target 1 (roll over) is 99. Multiplier = (100-1)/99 = 1 + assertEquals(diceDto.getBetAmount().stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_targetValueOne_alwaysLose_winChanceZero() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(1)); + when(random.nextInt(anyInt())).thenReturn(0); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(1), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollOver_targetValueNinetyNine_rolledHundred_win() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(99)); + when(random.nextInt(anyInt())).thenReturn(99); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(100), result.getRolledValue()); + // Win chance for target 99 (roll over) is 1. Multiplier = (100-1)/1 = 99 + assertEquals(diceDto.getBetAmount().multiply(BigDecimal.valueOf(99)).stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_targetValueNinetyNine_rolledNinetyEight_win() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(99)); + when(random.nextInt(anyInt())).thenReturn(97); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(98), result.getRolledValue()); + // Win chance for target 99 (roll under) is 98. Multiplier = (100-1)/98 = 99/98 + assertEquals(diceDto.getBetAmount().multiply(BigDecimal.valueOf(99).divide(BigDecimal.valueOf(98), 4, RoundingMode.HALF_UP)), result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollOver_targetValueOneHundred_alwaysLose_winChanceZero() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(100)); + when(random.nextInt(anyInt())).thenReturn(99); + + DiceResult result = diceService.play(user, diceDto); + + assertFalse(result.isWin()); + assertEquals(BigDecimal.valueOf(100), result.getRolledValue()); + assertEquals(BigDecimal.ZERO, result.getPayout()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, never()).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_rollUnder_targetValueOneHundred_rolledNinetyNine_win() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(100)); + when(random.nextInt(anyInt())).thenReturn(98); + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(99), result.getRolledValue()); + // Win chance for target 100 (roll under) is 99. Multiplier = (100-1)/99 = 1 + assertEquals(diceDto.getBetAmount().stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + verify(balanceService, times(1)).addFunds(eq(user), any(BigDecimal.class)); + } + + @Test + void play_payoutCalculationCorrect() { + diceDto.setRollOver(true); + diceDto.setTargetValue(BigDecimal.valueOf(75)); + when(random.nextInt(anyInt())).thenReturn(75); + + // Multiplier for win chance 25: (100-1)/25 = 99/25 = 3.96 + // Payout: 10 * 3.96 = 39.6 + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(39.6).stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + } + + @Test + void play_payoutCalculationCorrect_rollUnder() { + diceDto.setRollOver(false); + diceDto.setTargetValue(BigDecimal.valueOf(25)); + when(random.nextInt(anyInt())).thenReturn(0); + + // Multiplier for win chance 24: (100-1)/24 = 99/24 = 4.125 + // Payout: 10 * 4.125 = 41.25 + + DiceResult result = diceService.play(user, diceDto); + + assertTrue(result.isWin()); + assertEquals(BigDecimal.valueOf(41.25).stripTrailingZeros(), result.getPayout().stripTrailingZeros()); + } + + @Test + void play_betAmountSubtracted() { + when(random.nextInt(anyInt())).thenReturn(50); + + diceService.play(user, diceDto); + + verify(balanceService, times(1)).subtractFunds(user, diceDto.getBetAmount()); + } +} diff --git a/frontend/bun.lock b/frontend/bun.lock index c0b164d..ab6a6c9 100644 --- a/frontend/bun.lock +++ b/frontend/bun.lock @@ -33,7 +33,7 @@ "@angular/cli": "^19.2.5", "@angular/compiler-cli": "^19.0.0", "@types/jasmine": "~5.1.0", - "angular-eslint": "19.6.0", + "angular-eslint": "19.7.0", "eslint": "^9.25.1", "jasmine-core": "~5.7.0", "karma": "~6.4.0", @@ -62,19 +62,19 @@ "@angular-devkit/schematics": ["@angular-devkit/schematics@19.2.6", "", { "dependencies": { "@angular-devkit/core": "19.2.6", "jsonc-parser": "3.3.1", "magic-string": "0.30.17", "ora": "5.4.1", "rxjs": "7.8.1" } }, "sha512-YTAxNnT++5eflx19OUHmOWu597/TbTel+QARiZCv1xQw99+X8DCKKOUXtqBRd53CAHlREDI33Rn/JLY3NYgMLQ=="], - "@angular-eslint/builder": ["@angular-eslint/builder@19.6.0", "", { "dependencies": { "@angular-devkit/architect": ">= 0.1900.0 < 0.2000.0", "@angular-devkit/core": ">= 19.0.0 < 20.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-hUdYS1mSB09b5ABi2tuWeMTVprYHW+x6KmeAFJfXC6aMOa4NYQBdetIjOLwr7qUDlq1S/+2+HiX/FO76FPHClw=="], + "@angular-eslint/builder": ["@angular-eslint/builder@19.7.0", "", { "dependencies": { "@angular-devkit/architect": ">= 0.1900.0 < 0.2000.0", "@angular-devkit/core": ">= 19.0.0 < 20.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-tnanOOwUKzeS0FwhjJd/dNeb8gVzcF0+cI4/ZgohOjZxm8fZqtzXcKfGS1C7KsR/CPHBdY9cbF1OVPJEarrnsQ=="], - "@angular-eslint/bundled-angular-compiler": ["@angular-eslint/bundled-angular-compiler@19.6.0", "", {}, "sha512-ro+seaTAg5GvtJ72uWEEnP9J5mT0vtgdqH6YMrmMt4pZbSZxvkLfLjZGkXo/HjVDVcCjPnmZeMwKN+uoEc27Jg=="], + "@angular-eslint/bundled-angular-compiler": ["@angular-eslint/bundled-angular-compiler@19.7.0", "", {}, "sha512-95Z30MhQ93s1G1mEnsVuG45te82I+6dp8Y0MamRgyh4OZvOajmEXpvCwT+hkr/9WAroLZ7p5nlMbzAA+OXZ+YQ=="], - "@angular-eslint/eslint-plugin": ["@angular-eslint/eslint-plugin@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0", "@angular-eslint/utils": "19.6.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-IOMfFi/rPNrPwxZwIGTqWw0C5pC2Facwg3llmJoQFq8w2sUE0nNBL5uSQv5dT8s6ucum4g+RFNYHNe20SEOvRw=="], + "@angular-eslint/eslint-plugin": ["@angular-eslint/eslint-plugin@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0", "@angular-eslint/utils": "19.7.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-M8OqDgiFSSxMinW/Gkdrvy2O2Oeo8bGk1DQc0s3aEKB44PYAjXC49jMSihvdozqtu1qjPBcTN5kvUwzwN5oWxA=="], - "@angular-eslint/eslint-plugin-template": ["@angular-eslint/eslint-plugin-template@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0", "@angular-eslint/utils": "19.6.0", "aria-query": "5.3.2", "axobject-query": "4.1.0" }, "peerDependencies": { "@typescript-eslint/types": "^7.11.0 || ^8.0.0", "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-SDGbNSCUuPmqVesy5SvRE2MV7AKvvA/bVJwL9Fz5KYCHYxJz1rrJ8FknjWAfmg0qO2TMs1ZI9hov8JL+Bc4BBw=="], + "@angular-eslint/eslint-plugin-template": ["@angular-eslint/eslint-plugin-template@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0", "@angular-eslint/utils": "19.7.0", "aria-query": "5.3.2", "axobject-query": "4.1.0" }, "peerDependencies": { "@angular-eslint/template-parser": "19.7.0", "@typescript-eslint/types": "^7.11.0 || ^8.0.0", "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-gR+RH7ZDFctupUsCcxWWloD0I7m9pE8HiDX9TrwrSQbNgzvp/P7+Mgv709rR1Jju9GSVavPh7EG3VgiCyR2m5w=="], - "@angular-eslint/schematics": ["@angular-eslint/schematics@19.6.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/eslint-plugin": "19.6.0", "@angular-eslint/eslint-plugin-template": "19.6.0", "ignore": "7.0.4", "semver": "7.7.2", "strip-json-comments": "3.1.1" } }, "sha512-lJzwHju7bhJ3p+SZnY0JVwGjxF2q68gUdOYhdU62pglfYkS5lm+A5LM/VznRvdpZOH69vvZ9gizQ8W1P525cdw=="], + "@angular-eslint/schematics": ["@angular-eslint/schematics@19.7.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/eslint-plugin": "19.7.0", "@angular-eslint/eslint-plugin-template": "19.7.0", "ignore": "7.0.5", "semver": "7.7.2", "strip-json-comments": "3.1.1" } }, "sha512-07j/qXfSLvLsUq8a7WJlGYgcgfVEJ1ODuwJ2R4686dh2lqZ5GRV75fpdOtOBdC38MILLwd5el+8LfdaIG19Yog=="], - "@angular-eslint/template-parser": ["@angular-eslint/template-parser@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0", "eslint-scope": "^8.0.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-NGxXUZkI5lXjoKnmL51C8DoJx8AjwF9sonieC2EVxgXycK2MYAamFWYGHMiVemzFsg1nIv+JvhHITgjSjyC3HQ=="], + "@angular-eslint/template-parser": ["@angular-eslint/template-parser@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0", "eslint-scope": "^8.0.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-XLPt6gk8VMOrUO9NWRpXN8zgwJuCDV+9y3KbVnd4WyakO0sOz9SVzktuI4AeY9jWS9/tqU6P8Uj0WZsMVz7F8w=="], - "@angular-eslint/utils": ["@angular-eslint/utils@19.6.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.6.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-ygtsmRKHNqrzG2mpUj1XwLNRoG+ikYkizsOuq5xPRM8o6dCw03H5eel4s7hnXT4c09WbpnoaVNi9O3xFLIETJQ=="], + "@angular-eslint/utils": ["@angular-eslint/utils@19.7.0", "", { "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.7.0" }, "peerDependencies": { "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "sha512-F4JcZtc2/Wl0AwRaeUywupPHdaOtldpwfrGYewT1dYDikFafyDk5T6E9JYv/HgLXROPNMDVPFquwikNvAPlfAg=="], "@angular/animations": ["@angular/animations@19.2.5", "", { "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/common": "19.2.5", "@angular/core": "19.2.5" } }, "sha512-m4RtY3z1JuHFCh6OrOHxo25oKEigBDdR/XmdCfXIwfTiObZzNA7VQhysgdrb9IISO99kXbjZUYKDtLzgWT8Klg=="], @@ -692,7 +692,7 @@ "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.33.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.33.0", "@typescript-eslint/utils": "8.33.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ=="], - "@typescript-eslint/types": ["@typescript-eslint/types@8.32.1", "", {}, "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="], "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.33.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.33.0", "@typescript-eslint/tsconfig-utils": "8.33.0", "@typescript-eslint/types": "8.33.0", "@typescript-eslint/visitor-keys": "8.33.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ=="], @@ -756,7 +756,7 @@ "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - "angular-eslint": ["angular-eslint@19.6.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/builder": "19.6.0", "@angular-eslint/eslint-plugin": "19.6.0", "@angular-eslint/eslint-plugin-template": "19.6.0", "@angular-eslint/schematics": "19.6.0", "@angular-eslint/template-parser": "19.6.0", "@typescript-eslint/types": "^8.0.0", "@typescript-eslint/utils": "^8.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*", "typescript-eslint": "^8.0.0" } }, "sha512-9qfP6rR6De5xe9WyviD9Vdpg2F3iHTlo7T1129ms0AQXrG9/U/upIQmNUN+Jz9CiJcHDUsniyd+EL8hjuNYnOg=="], + "angular-eslint": ["angular-eslint@19.7.0", "", { "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", "@angular-eslint/builder": "19.7.0", "@angular-eslint/eslint-plugin": "19.7.0", "@angular-eslint/eslint-plugin-template": "19.7.0", "@angular-eslint/schematics": "19.7.0", "@angular-eslint/template-parser": "19.7.0", "@typescript-eslint/types": "^8.0.0", "@typescript-eslint/utils": "^8.0.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": "*", "typescript-eslint": "^8.0.0" } }, "sha512-ujlc8CR40RYEWUctpVEg41ZCtmKnWeJH0mzORhzf0NVZb6FLhoNhmDPr1byw4Bcxzl0DAoNgKBhJymt6FNL6Rw=="], "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], @@ -1884,7 +1884,7 @@ "@angular-devkit/schematics/rxjs": ["rxjs@7.8.1", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg=="], - "@angular-eslint/schematics/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="], + "@angular-eslint/schematics/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "@angular-eslint/schematics/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], @@ -1972,24 +1972,12 @@ "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="], - "@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="], - - "@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="], - - "@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="], - - "@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="], - "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@typescript-eslint/typescript-estree/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], "@typescript-eslint/utils/@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="], - "@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="], - - "@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.33.0", "", {}, "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg=="], - "accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], "adjust-sourcemap-loader/loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="], diff --git a/frontend/package.json b/frontend/package.json index d5460c5..3b9b86e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -43,7 +43,7 @@ "@angular/cli": "^19.2.5", "@angular/compiler-cli": "^19.0.0", "@types/jasmine": "~5.1.0", - "angular-eslint": "19.6.0", + "angular-eslint": "19.7.0", "eslint": "^9.25.1", "jasmine-core": "~5.7.0", "karma": "~6.4.0",