diff --git a/.oxlintrc.json b/.oxlintrc.json index a4bac9efc..f1a2eb70a 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,5 +1,8 @@ { - "plugins": ["import", "promise", "unicorn"], + "plugins": ["import", "promise", "unicorn", "typescript"], + "options": { + "typeAware": true + }, "categories": { "correctness": "error", "pedantic": "warn", @@ -9,6 +12,50 @@ "suspicious": "warn" }, "rules": { + // Type-aware linting: keep the rules that catch real defects and switch off + // the stylistic ones, which fight Vue/vue-router idioms and drown the signal. + "no-void": "off", // typescript/no-floating-promises prescribes `void` as the fix + "typescript/no-floating-promises": "error", + "typescript/await-thenable": "error", + "typescript/no-misused-promises": "error", + "typescript/require-array-sort-compare": "error", + "typescript/no-wrapper-object-types": "error", + "typescript/no-redundant-type-constituents": "error", + "typescript/prefer-readonly-parameter-types": "off", // Unsatisfiable against vue-router callback signatures + "typescript/strict-boolean-expressions": "off", // Contradicts documented vue-router idioms; cannot see templates + "typescript/no-unsafe-type-assertion": "off", + "typescript/no-unsafe-member-access": "off", + "typescript/no-unsafe-assignment": "off", + "typescript/no-unsafe-call": "off", + "typescript/no-unsafe-argument": "off", + "typescript/no-unsafe-return": "off", + "typescript/no-unnecessary-type-assertion": "off", // Open upstream false-positive regression + "typescript/unbound-method": "off", + "typescript/prefer-nullish-coalescing": "off", + "typescript/no-confusing-void-expression": "off", + "typescript/return-await": "off", + "typescript/strict-void-return": "off", + "typescript/no-extraneous-class": "off", + "typescript/consistent-return": "off", + "typescript/no-unnecessary-type-conversion": "off", + "typescript/no-unnecessary-boolean-literal-compare": "off", + "typescript/ban-types": "off", + // Syntactic rules the typescript plugin brings along; the repo never opted + // into these style positions, so keep them off rather than reformat the app. + "typescript/explicit-function-return-type": "off", + "typescript/explicit-module-boundary-types": "off", + "typescript/explicit-member-accessibility": "off", + "typescript/consistent-type-definitions": "off", + "typescript/no-non-null-assertion": "off", + "typescript/promise-function-async": "off", + "typescript/no-explicit-any": "off", + "typescript/prefer-readonly": "off", + "typescript/no-inferrable-types": "off", + "typescript/consistent-type-imports": "off", + "typescript/array-type": "off", + "typescript/consistent-indexed-object-style": "off", + "typescript/prefer-regexp-exec": "off", + "typescript/dot-notation": "off", "import/no-cycle": "error", "import/no-duplicates": "error", "import/no-self-import": "error", diff --git a/VueApp/src/CMS/__tests__/use-url-filtered-table.test.ts b/VueApp/src/CMS/__tests__/use-url-filtered-table.test.ts index 2f3bea190..a53bb82c4 100644 --- a/VueApp/src/CMS/__tests__/use-url-filtered-table.test.ts +++ b/VueApp/src/CMS/__tests__/use-url-filtered-table.test.ts @@ -64,7 +64,7 @@ describe("useUrlFilteredTable", () => { it("initializes the primary id and filters from route.query and sends them, omitting empties", async () => { const { table } = await mountTable({ fileGuid: "g1", search: "report" }) - table.reload() + void table.reload() await flushPromises() const url = lastUrl() @@ -80,7 +80,7 @@ describe("useUrlFilteredTable", () => { const { table, router } = await mountTable() table.filters.value.search = "hello" - table.reload() + void table.reload() await flushRouter() expect(router.currentRoute.value.query.search).toBe("hello") @@ -90,11 +90,11 @@ describe("useUrlFilteredTable", () => { it("clearPrimaryFilter drops the deep-link id from the request and the URL, then refetches", async () => { const { table, router } = await mountTable({ fileGuid: "g1" }) - table.reload() + void table.reload() await flushRouter() const before = mockGet.mock.calls.length - table.clearPrimaryFilter() + void table.clearPrimaryFilter() await flushRouter() expect(table.primary.value).toBeNull() @@ -105,7 +105,7 @@ describe("useUrlFilteredTable", () => { it("re-syncs filters and refetches when external navigation changes the query", async () => { const { table, router } = await mountTable() - table.reload() + void table.reload() await flushRouter() const before = mockGet.mock.calls.length @@ -122,7 +122,7 @@ describe("useUrlFilteredTable", () => { const { table } = await mountTable() table.filters.value.search = "abc" - table.reload() + void table.reload() await flushPromises() const afterReload = mockGet.mock.calls.length diff --git a/VueApp/src/CMS/composables/use-url-filtered-table.ts b/VueApp/src/CMS/composables/use-url-filtered-table.ts index 2053eedc5..c6050e1a2 100644 --- a/VueApp/src/CMS/composables/use-url-filtered-table.ts +++ b/VueApp/src/CMS/composables/use-url-filtered-table.ts @@ -95,7 +95,7 @@ export function useUrlFilteredTable(options: UrlFilt } primary.value = nextPrimary filters.value = next - table.reloadFirstPage() + void table.reloadFirstPage() }, ) diff --git a/VueApp/src/CTS/__tests__/assessment-bubble.test.ts b/VueApp/src/CTS/__tests__/assessment-bubble.test.ts index 10b6a99e7..854bc3db0 100644 --- a/VueApp/src/CTS/__tests__/assessment-bubble.test.ts +++ b/VueApp/src/CTS/__tests__/assessment-bubble.test.ts @@ -25,7 +25,7 @@ function createWrapper(props: Record) { }) } -describe(AssessmentBubble, () => { +describe("AssessmentBubble", () => { describe("aria-label privacy", () => { it("uses levelName on the clickable button and does not expose the numeric value", () => { const wrapper = createWrapper({ diff --git a/VueApp/src/CTS/types/index.ts b/VueApp/src/CTS/types/index.ts index 83e0fa800..90715e38b 100644 --- a/VueApp/src/CTS/types/index.ts +++ b/VueApp/src/CTS/types/index.ts @@ -91,15 +91,6 @@ type Assessment = { serviceName: string | null } -type StudentEpaFormData = { - epaId: number - levelId: number - comment: string - studentId: number - serviceId: number - encounterDate: Date | null -} - type Level = { levelId: number levelName: string @@ -161,12 +152,6 @@ type Bundle = { roles: Role[] } -type BundleRole = { - bundleRoleId: number - bundleId: number - roleId: number -} - type BundleCompetency = { bundleCompetencyId: number bundleId: number @@ -229,11 +214,6 @@ type MilestoneLevel = { description: string } -type MilestoneLevelUpdate = { - levelId: number - description: string -} - type Course = { courseId: number status: string diff --git a/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home-qa.test.ts b/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home-qa.test.ts index 816b888b0..797ad204f 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home-qa.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home-qa.test.ts @@ -89,7 +89,9 @@ describe("ClinicalSchedulerHome - Quality Assurance", () => { describe("Error Handling", () => { it("handles permission store initialization errors gracefully", () => { mockPermissionsStore.hasAnyEditPermission = true - mockPermissionsStore.initialize = vi.fn().mockRejectedValue(new Error("API Error")) + mockPermissionsStore.initialize = vi + .fn<(...args: unknown[]) => unknown>() + .mockRejectedValue(new Error("API Error")) // Should not throw error expect(() => @@ -113,8 +115,8 @@ describe("ClinicalSchedulerHome - Quality Assurance", () => { userPermissions: null, isLoading: false, editableServiceCount: 0, - getEditableServicesDisplay: vi.fn().mockReturnValue("None"), - initialize: vi.fn().mockResolvedValue(undefined), // oxlint-disable-line unicorn/no-useless-undefined -- TS requires the argument + getEditableServicesDisplay: vi.fn<(...args: unknown[]) => unknown>().mockReturnValue("None"), + initialize: vi.fn<(...args: unknown[]) => unknown>().mockResolvedValue(undefined), // oxlint-disable-line unicorn/no-useless-undefined -- TS requires the argument } as any) // Should not throw error @@ -135,7 +137,7 @@ describe("ClinicalSchedulerHome - Quality Assurance", () => { // Mock router.push to throw an error const mockRouter = { ...router, - push: vi.fn().mockRejectedValue(new Error("Navigation Error")), + push: vi.fn<(...args: unknown[]) => unknown>().mockRejectedValue(new Error("Navigation Error")), } const wrapper = createTestWrapper({ diff --git a/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home.test.ts b/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home.test.ts index 6437754b4..3697ad8f4 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/clinical-scheduler-home.test.ts @@ -309,7 +309,9 @@ describe("ClinicalSchedulerHome Component - Accessibility & Error Handling", () describe("Error Handling", () => { it("handles permission store initialization errors gracefully", () => { mockPermissionsStore.hasAnyEditPermission = true - mockPermissionsStore.initialize = vi.fn().mockRejectedValue(new Error("API Error")) + mockPermissionsStore.initialize = vi + .fn<(...args: unknown[]) => unknown>() + .mockRejectedValue(new Error("API Error")) // Should not throw error expect(() => createWrapper(router)).not.toThrow() @@ -326,8 +328,8 @@ describe("ClinicalSchedulerHome Component - Accessibility & Error Handling", () userPermissions: null, isLoading: false, editableServiceCount: 0, - getEditableServicesDisplay: vi.fn().mockReturnValue("None"), - initialize: vi.fn().mockResolvedValue(undefined), // oxlint-disable-line unicorn/no-useless-undefined -- TS requires the argument + getEditableServicesDisplay: vi.fn<(...args: unknown[]) => unknown>().mockReturnValue("None"), + initialize: vi.fn<(...args: unknown[]) => unknown>().mockResolvedValue(undefined), // oxlint-disable-line unicorn/no-useless-undefined -- TS requires the argument } as any) // Should not throw error diff --git a/VueApp/src/ClinicalScheduler/__tests__/normalize-schedule-semesters.test.ts b/VueApp/src/ClinicalScheduler/__tests__/normalize-schedule-semesters.test.ts index b279576e4..3fed969bb 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/normalize-schedule-semesters.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/normalize-schedule-semesters.test.ts @@ -1,7 +1,7 @@ import { normalizeScheduleSemesters } from "../composables/use-schedule-normalization" import type { ScheduleSemester } from "../components/schedule-view-types" -describe(normalizeScheduleSemesters, () => { +describe("normalizeScheduleSemesters", () => { it("should return empty array when input is undefined", () => { // oxlint-disable-next-line unicorn/no-useless-undefined -- Explicitly testing undefined input const result = normalizeScheduleSemesters(undefined) diff --git a/VueApp/src/ClinicalScheduler/__tests__/normalize-week.test.ts b/VueApp/src/ClinicalScheduler/__tests__/normalize-week.test.ts index fd106058a..613918f5b 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/normalize-week.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/normalize-week.test.ts @@ -1,6 +1,6 @@ import { normalizeWeek } from "../composables/use-schedule-normalization" -describe(normalizeWeek, () => { +describe("normalizeWeek", () => { it("should preserve existing dateEnd when it has a value", () => { const week = { weekId: 1, diff --git a/VueApp/src/ClinicalScheduler/__tests__/permissions-store-computed.test.ts b/VueApp/src/ClinicalScheduler/__tests__/permissions-store-computed.test.ts index 138198c4d..943459f50 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/permissions-store-computed.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/permissions-store-computed.test.ts @@ -6,11 +6,11 @@ import { PermissionService } from "../services/permission-service" // Mock the permission service vi.mock("../services/permission-service", () => ({ PermissionService: { - getUserPermissions: vi.fn(), - getPermissionSummary: vi.fn(), - canEditService: vi.fn(), - canEditRotation: vi.fn(), - canEditOwnSchedule: vi.fn(), + getUserPermissions: vi.fn<(...args: unknown[]) => unknown>(), + getPermissionSummary: vi.fn<(...args: unknown[]) => unknown>(), + canEditService: vi.fn<(...args: unknown[]) => unknown>(), + canEditRotation: vi.fn<(...args: unknown[]) => unknown>(), + canEditOwnSchedule: vi.fn<(...args: unknown[]) => unknown>(), }, permissionService: {}, })) diff --git a/VueApp/src/ClinicalScheduler/__tests__/permissions-store-error-handling.test.ts b/VueApp/src/ClinicalScheduler/__tests__/permissions-store-error-handling.test.ts index 65dc1228f..570fe970c 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/permissions-store-error-handling.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/permissions-store-error-handling.test.ts @@ -5,11 +5,11 @@ import { PermissionService, createMockUserPermissions } from "./test-utils" // Mock the permission service vi.mock("../services/permission-service", () => ({ PermissionService: { - getUserPermissions: vi.fn(), - getPermissionSummary: vi.fn(), - canEditService: vi.fn(), - canEditRotation: vi.fn(), - canEditOwnSchedule: vi.fn(), + getUserPermissions: vi.fn<(...args: unknown[]) => unknown>(), + getPermissionSummary: vi.fn<(...args: unknown[]) => unknown>(), + canEditService: vi.fn<(...args: unknown[]) => unknown>(), + canEditRotation: vi.fn<(...args: unknown[]) => unknown>(), + canEditOwnSchedule: vi.fn<(...args: unknown[]) => unknown>(), }, permissionService: {}, })) diff --git a/VueApp/src/ClinicalScheduler/__tests__/permissions-store-utilities.test.ts b/VueApp/src/ClinicalScheduler/__tests__/permissions-store-utilities.test.ts index 914128ef6..003247e02 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/permissions-store-utilities.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/permissions-store-utilities.test.ts @@ -5,11 +5,11 @@ import { PermissionService, createMockUserPermissions } from "./test-utils" // Mock the permission service vi.mock("../services/permission-service", () => ({ PermissionService: { - getUserPermissions: vi.fn(), - getPermissionSummary: vi.fn(), - canEditService: vi.fn(), - canEditRotation: vi.fn(), - canEditOwnSchedule: vi.fn(), + getUserPermissions: vi.fn<(...args: unknown[]) => unknown>(), + getPermissionSummary: vi.fn<(...args: unknown[]) => unknown>(), + canEditService: vi.fn<(...args: unknown[]) => unknown>(), + canEditRotation: vi.fn<(...args: unknown[]) => unknown>(), + canEditOwnSchedule: vi.fn<(...args: unknown[]) => unknown>(), }, permissionService: {}, })) diff --git a/VueApp/src/ClinicalScheduler/__tests__/rotation-selector-api.test.ts b/VueApp/src/ClinicalScheduler/__tests__/rotation-selector-api.test.ts index 20fd406a7..b3e35fd05 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/rotation-selector-api.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/rotation-selector-api.test.ts @@ -4,8 +4,8 @@ import { createComponentLogic } from "./rotation-selector-helpers.test" // Mock the RotationService vi.mock("../services/rotation-service", () => ({ RotationService: { - getRotations: vi.fn(), - getRotationsWithScheduledWeeks: vi.fn(), + getRotations: vi.fn<(...args: unknown[]) => unknown>(), + getRotationsWithScheduledWeeks: vi.fn<(...args: unknown[]) => unknown>(), }, })) diff --git a/VueApp/src/ClinicalScheduler/__tests__/rotation-selector.test.ts b/VueApp/src/ClinicalScheduler/__tests__/rotation-selector.test.ts index 55a41e8c9..4ebc753bf 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/rotation-selector.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/rotation-selector.test.ts @@ -4,8 +4,8 @@ import { createComponentLogic } from "./rotation-selector-helpers.test" // Mock the RotationService vi.mock("../services/rotation-service", () => ({ RotationService: { - getRotations: vi.fn(), - getRotationsWithScheduledWeeks: vi.fn(), + getRotations: vi.fn<(...args: unknown[]) => unknown>(), + getRotationsWithScheduledWeeks: vi.fn<(...args: unknown[]) => unknown>(), }, })) diff --git a/VueApp/src/ClinicalScheduler/__tests__/test-utils.ts b/VueApp/src/ClinicalScheduler/__tests__/test-utils.ts index 2ca007990..260af076e 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/test-utils.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/test-utils.ts @@ -14,10 +14,10 @@ import type { UserPermissions } from "../types" // Mock localStorage for tests that need it const mockLocalStorage = { - getItem: vi.fn(), - setItem: vi.fn(), - removeItem: vi.fn(), - clear: vi.fn(), + getItem: vi.fn<(...args: unknown[]) => unknown>(), + setItem: vi.fn<(...args: unknown[]) => unknown>(), + removeItem: vi.fn<(...args: unknown[]) => unknown>(), + clear: vi.fn<(...args: unknown[]) => unknown>(), } // Setup localStorage mock @@ -58,8 +58,8 @@ function createMockPermissionsStore() { userPermissions: null, isLoading: false, editableServiceCount: 0, - getEditableServicesDisplay: vi.fn().mockReturnValue("None"), - initialize: vi.fn().mockResolvedValue(undefined), // oxlint-disable-line unicorn/no-useless-undefined -- TS requires the argument + getEditableServicesDisplay: vi.fn<(...args: unknown[]) => unknown>().mockReturnValue("None"), + initialize: vi.fn<(...args: unknown[]) => unknown>().mockResolvedValue(undefined), // oxlint-disable-line unicorn/no-useless-undefined -- TS requires the argument } } diff --git a/VueApp/src/ClinicalScheduler/__tests__/use-bulk-deletion.test.ts b/VueApp/src/ClinicalScheduler/__tests__/use-bulk-deletion.test.ts new file mode 100644 index 000000000..1406c9107 --- /dev/null +++ b/VueApp/src/ClinicalScheduler/__tests__/use-bulk-deletion.test.ts @@ -0,0 +1,135 @@ +import { useBulkDeletion } from "../composables/use-bulk-deletion" +import type { ScheduleData } from "../utils/schedule-update-helpers" + +type RemoveScheduleFn = ( + scheduleData: ScheduleData, + scheduleId: number, + options: { onSuccess: (wasPrimary?: boolean, instructorName?: string) => void; onError: () => void }, +) => void + +// $q.dialog() returns a chainable DialogChainObject, not a Promise. The mock +// mirrors that shape so a regression back to `await $q.dialog(...)` fails here. +type DialogOutcome = "ok" | "cancel" | "dismiss" + +const { mockDialog, mockNotify, setUserChoice } = vi.hoisted(() => { + let choice: DialogOutcome = "ok" + const chain: Record = {} + const handler = (outcome: DialogOutcome) => + vi.fn<(callback: () => void) => unknown>((callback) => { + if (choice === outcome) { + callback() + } + return chain + }) + chain.onOk = handler("ok") + chain.onCancel = handler("cancel") + chain.onDismiss = handler("dismiss") + return { + mockDialog: vi.fn<(...args: unknown[]) => unknown>(() => chain), + mockNotify: vi.fn<(...args: unknown[]) => unknown>(), + setUserChoice: (next: DialogOutcome) => { + choice = next + }, + } +}) + +vi.mock("quasar", () => ({ + useQuasar: () => ({ dialog: mockDialog, notify: mockNotify }), +})) + +describe("useBulkDeletion - confirmation gate", () => { + const scheduleData = { rotationId: 1 } as unknown as ScheduleData + const items = [ + { scheduleId: 10, displayName: "Alex Doe", weekNumber: 1 }, + { scheduleId: 11, displayName: "Sam Roe", weekNumber: 2 }, + ] + + const buildOptions = (removeScheduleWithRollback: RemoveScheduleFn) => ({ + confirmationTitle: "Remove assignments", + confirmationMessage: "Are you sure?", + successMessage: (count: number) => `${count} removed`, + errorMessage: "Failed", + removeScheduleWithRollback, + clearSelections: vi.fn<() => void>(), + }) + + beforeEach(() => { + vi.clearAllMocks() + }) + + it("lists affected weeks in numeric order in the primary-evaluator warning", async () => { + expect.hasAssertions() + // 1, 2 and 10 expose lexicographic sorting, which would render "1, 10, 2". + const weeks = [ + { scheduleId: 1, displayName: "Alex Doe", weekNumber: 2 }, + { scheduleId: 2, displayName: "Alex Doe", weekNumber: 10 }, + { scheduleId: 3, displayName: "Alex Doe", weekNumber: 1 }, + ] + const removeScheduleWithRollback: RemoveScheduleFn = (scheduleData_, scheduleId_, callbacks) => { + callbacks.onSuccess(true, "Alex Doe") + } + const { executeBulkDeletion } = useBulkDeletion() + + await executeBulkDeletion(scheduleData, weeks, { + ...buildOptions(removeScheduleWithRollback), + skipConfirmation: true, + }) + + const warning = mockNotify.mock.calls + .map((call) => call[0] as { icon?: string; message?: string }) + .find((arg) => arg?.icon === "star_outline") + expect(warning?.message).toContain("Weeks 1, 2, 10") + }) + + it("does not delete anything when the user cancels", async () => { + expect.hasAssertions() + setUserChoice("cancel") + const removeScheduleWithRollback = vi.fn() + const { executeBulkDeletion, isDeleting } = useBulkDeletion() + + await executeBulkDeletion(scheduleData, items, buildOptions(removeScheduleWithRollback)) + + expect(mockDialog).toHaveBeenCalledTimes(1) + expect(removeScheduleWithRollback).not.toHaveBeenCalled() + expect(isDeleting.value).toBe(false) + }) + + it("settles without deleting when the dialog is dismissed rather than answered", async () => { + expect.hasAssertions() + // A programmatic close fires neither onOk nor onCancel; without an onDismiss + // handler this await never settles and the flow wedges instead of failing. + setUserChoice("dismiss") + const removeScheduleWithRollback = vi.fn() + const { executeBulkDeletion, isDeleting } = useBulkDeletion() + + await executeBulkDeletion(scheduleData, items, buildOptions(removeScheduleWithRollback)) + + expect(removeScheduleWithRollback).not.toHaveBeenCalled() + expect(isDeleting.value).toBe(false) + }) + + it("deletes every selected item when the user confirms", async () => { + expect.hasAssertions() + setUserChoice("ok") + const removeScheduleWithRollback = vi.fn() + const { executeBulkDeletion } = useBulkDeletion() + + await executeBulkDeletion(scheduleData, items, buildOptions(removeScheduleWithRollback)) + + expect(removeScheduleWithRollback).toHaveBeenCalledTimes(items.length) + }) + + it("skips the dialog entirely when skipConfirmation is set", async () => { + expect.hasAssertions() + const removeScheduleWithRollback = vi.fn() + const { executeBulkDeletion } = useBulkDeletion() + + await executeBulkDeletion(scheduleData, items, { + ...buildOptions(removeScheduleWithRollback), + skipConfirmation: true, + }) + + expect(mockDialog).not.toHaveBeenCalled() + expect(removeScheduleWithRollback).toHaveBeenCalledTimes(items.length) + }) +}) diff --git a/VueApp/src/ClinicalScheduler/__tests__/use-optimistic-schedule-updates.test.ts b/VueApp/src/ClinicalScheduler/__tests__/use-optimistic-schedule-updates.test.ts index b0d618f58..9dd881738 100644 --- a/VueApp/src/ClinicalScheduler/__tests__/use-optimistic-schedule-updates.test.ts +++ b/VueApp/src/ClinicalScheduler/__tests__/use-optimistic-schedule-updates.test.ts @@ -3,16 +3,18 @@ import { InstructorScheduleService } from "../services/instructor-schedule-servi vi.mock("../services/instructor-schedule-service") vi.mock("../composables/use-schedule-state-updater", () => ({ - useScheduleStateUpdater: vi.fn(() => ({ - addScheduleToWeek: vi.fn(), - removeScheduleFromWeek: vi.fn(), - updateSchedulePrimaryStatus: vi.fn(), + useScheduleStateUpdater: vi.fn<() => unknown>(() => ({ + addScheduleToWeek: vi.fn<(...args: unknown[]) => unknown>(), + removeScheduleFromWeek: vi.fn<(...args: unknown[]) => unknown>(), + updateSchedulePrimaryStatus: vi.fn<(...args: unknown[]) => unknown>(), })), })) // Mock structuredClone to handle test data // eslint-disable-next-line prefer-structured-clone -- Mocking structuredClone for tests -globalThis.structuredClone = vi.fn((obj) => JSON.parse(JSON.stringify(obj))) +globalThis.structuredClone = vi.fn<(value: unknown) => unknown>((obj) => + JSON.parse(JSON.stringify(obj)), +) as typeof structuredClone describe("useScheduleUpdatesWithRollback - Operation Queue", () => { let mockScheduleData: any = null @@ -35,7 +37,7 @@ describe("useScheduleUpdatesWithRollback - Operation Queue", () => { it("should queue concurrent add operations for sequential processing", async () => { const { addScheduleWithRollback } = useScheduleUpdatesWithRollback() - const onSuccess = vi.fn() + const onSuccess = vi.fn<(...args: unknown[]) => unknown>() const callOrder: number[] = [] let callIndex = 0 @@ -183,8 +185,8 @@ describe("useScheduleUpdatesWithRollback - Error Handling", () => { it("should continue processing queue even when an operation fails", async () => { const { addScheduleWithRollback } = useScheduleUpdatesWithRollback() - const onError = vi.fn() - const onSuccess = vi.fn() + const onError = vi.fn<(...args: unknown[]) => unknown>() + const onSuccess = vi.fn<(...args: unknown[]) => unknown>() // First call will fail, second and third will succeed vi.mocked(InstructorScheduleService.addInstructor) diff --git a/VueApp/src/ClinicalScheduler/components/ScheduleView.vue b/VueApp/src/ClinicalScheduler/components/ScheduleView.vue index 65fcd462b..d1d1579a2 100644 --- a/VueApp/src/ClinicalScheduler/components/ScheduleView.vue +++ b/VueApp/src/ClinicalScheduler/components/ScheduleView.vue @@ -376,16 +376,6 @@ defineExpose({ width: 100%; } -.assignment-item { - padding: 2px 0; -} - -.assignment-item .text-body2 { - overflow-wrap: break-word; - hyphens: auto; - line-height: 1.2; -} - .cursor-pointer { cursor: pointer; } diff --git a/VueApp/src/ClinicalScheduler/composables/use-bulk-deletion.ts b/VueApp/src/ClinicalScheduler/composables/use-bulk-deletion.ts index 433c31e11..12fbcfd62 100644 --- a/VueApp/src/ClinicalScheduler/composables/use-bulk-deletion.ts +++ b/VueApp/src/ClinicalScheduler/composables/use-bulk-deletion.ts @@ -51,20 +51,30 @@ export function useBulkDeletion() { // If confirmation was already handled, set isDeleting immediately isDeleting.value = true } else { - try { - await $q.dialog({ + // $q.dialog() returns a DialogChainObject, not a Promise, so awaiting it + // resolves immediately and never waits for the user. Gate on the + // onOk/onCancel callbacks instead. + // oxlint-disable-next-line promise/avoid-new -- wrapping Quasar's callback-based DialogChainObject + const confirmed = await new Promise((resolve) => { + $q.dialog({ title: options.confirmationTitle, message: options.confirmationMessage, cancel: true, persistent: true, }) - // User clicked OK, now set isDeleting and proceed - isDeleting.value = true - } catch { + .onOk(() => resolve(true)) + .onCancel(() => resolve(false)) + // A programmatic close fires neither onOk nor onCancel, which would leave + // this await pending forever and wedge the bulk-delete flow. + .onDismiss(() => resolve(false)) + }) + if (!confirmed) { // User clicked Cancel or dismissed dialog // Don't set isDeleting, just return return } + // User clicked OK, now set isDeleting and proceed + isDeleting.value = true } try { @@ -95,7 +105,11 @@ export function useBulkDeletion() { // Show warning for removed primary evaluators if (removedPrimaryEvaluators.length > 0) { - const uniqueWeeks = [...new Set(removedPrimaryEvaluators.map((pe) => pe.weekNumber))].toSorted() + // Numeric compare: the default sort is lexicographic, which orders + // week numbers as 1, 10, 2 in the notification below. + const uniqueWeeks = [...new Set(removedPrimaryEvaluators.map((pe) => pe.weekNumber))].toSorted( + (a, b) => a - b, + ) const uniqueInstructorNames = [...new Set(removedPrimaryEvaluators.map((pe) => pe.name))] const instructorNames = uniqueInstructorNames.join(", ") $q.notify({ diff --git a/VueApp/src/ClinicalScheduler/composables/use-optimistic-schedule-updates.ts b/VueApp/src/ClinicalScheduler/composables/use-optimistic-schedule-updates.ts index 78d79c0b0..bc5cfcc9f 100644 --- a/VueApp/src/ClinicalScheduler/composables/use-optimistic-schedule-updates.ts +++ b/VueApp/src/ClinicalScheduler/composables/use-optimistic-schedule-updates.ts @@ -252,7 +252,7 @@ export function useScheduleUpdatesWithRollback() { const queueOperation = (operation: () => Promise) => { operationQueue.push(operation) // Start processing if not already running - processQueue() + void processQueue() } return { diff --git a/VueApp/src/ClinicalScheduler/composables/use-permission-checks.ts b/VueApp/src/ClinicalScheduler/composables/use-permission-checks.ts index 55bf7e20c..fba2a3a92 100644 --- a/VueApp/src/ClinicalScheduler/composables/use-permission-checks.ts +++ b/VueApp/src/ClinicalScheduler/composables/use-permission-checks.ts @@ -22,15 +22,15 @@ export function usePermissionChecks() { // Navigation helpers function goToHome() { - router.push("/ClinicalScheduler") + void router.push("/ClinicalScheduler") } function goToClinicianView() { - router.push("/ClinicalScheduler/clinician") + void router.push("/ClinicalScheduler/clinician") } function goToRotationView() { - router.push("/ClinicalScheduler/rotation") + void router.push("/ClinicalScheduler/rotation") } return { diff --git a/VueApp/src/ClinicalScheduler/pages/ClinicalSchedulerHome.vue b/VueApp/src/ClinicalScheduler/pages/ClinicalSchedulerHome.vue index d330f4bf6..5abee728e 100644 --- a/VueApp/src/ClinicalScheduler/pages/ClinicalSchedulerHome.vue +++ b/VueApp/src/ClinicalScheduler/pages/ClinicalSchedulerHome.vue @@ -220,10 +220,6 @@ onMounted(() => initPage()) opacity: 0.7; } -.opacity-60 { - opacity: 0.6; -} - /* Reduced motion support */ @media screen and (prefers-reduced-motion: reduce) { .view-card-custom { diff --git a/VueApp/src/ClinicalScheduler/services/error-transformer.ts b/VueApp/src/ClinicalScheduler/services/error-transformer.ts index 6cb44b3de..fb6dedb96 100644 --- a/VueApp/src/ClinicalScheduler/services/error-transformer.ts +++ b/VueApp/src/ClinicalScheduler/services/error-transformer.ts @@ -1,4 +1,4 @@ -import type { ApiError } from "../types/api-responses" +import type { ApiError } from "../types/api" /** * Transforms various error types into strongly-typed ApiError objects diff --git a/VueApp/src/ClinicalScheduler/types/api-responses.ts b/VueApp/src/ClinicalScheduler/types/api-responses.ts deleted file mode 100644 index c94439f53..000000000 --- a/VueApp/src/ClinicalScheduler/types/api-responses.ts +++ /dev/null @@ -1,80 +0,0 @@ -/** - * API Response DTOs for Clinical Scheduler - * - * These types mirror backend contract responses and are consumed by - * services and components in the Clinical Scheduler module. - */ - -import type { ApiResult } from "./api" - -/** - * Standard error payload returned by backend endpoints (when present). - */ -interface ErrorResponse { - /** Machine-readable error code (e.g., "ValidationFailed", "Forbidden"). */ - code: string - /** Message safe for display to end users. */ - userMessage: string - /** Correlates client logs with server logs. */ - correlationId: string - /** ISO timestamp when the error occurred on the server. */ - timestamp: string -} - -/** - * Discriminated client-side API error representation used in UI flows. - */ -type ApiError = - | { kind: "NetworkError"; message: string } - | { kind: "HttpError"; status: number; message: string } - | { kind: "ValidationError"; message: string; details?: Record } - | { kind: "PermissionError"; message: string } - | { kind: "NotFoundError"; message: string } - | { kind: "ConflictError"; message: string } - | { kind: "UnknownError"; message: string } - -/** - * Instructor schedule item returned from create/list APIs. - */ -interface InstructorScheduleResponse { - instructorScheduleId: number - mothraId: string - rotationId: number - weekId: number - isPrimaryEvaluator: boolean - /** Whether the current user has permission to remove this schedule. */ - canRemove: boolean -} - -/** - * Response of add-instructor endpoint, including created schedules - * and optional warning when conflicts were detected. - */ -interface AddInstructorResponse { - schedules: InstructorScheduleResponse[] - scheduleIds: number[] - /** Optional informational warning shown in the UI. */ - warningMessage?: string -} - -/** - * Conflict check result for proposed instructor-week assignments. - */ -interface ScheduleConflictResponse { - conflicts: InstructorScheduleResponse[] - message: string - hasConflicts: boolean -} - -/** Generic success envelope with message. */ -interface SuccessResponse { - message: string -} - -// Specific typed results -type AddInstructorApiResult = ApiResult -type ConflictCheckApiResult = ApiResult -// 204 No Content -type RemoveInstructorApiResult = ApiResult - -export { type ApiError } diff --git a/VueApp/src/ClinicalScheduler/types/api.ts b/VueApp/src/ClinicalScheduler/types/api.ts index aeaf9535c..d64037249 100644 --- a/VueApp/src/ClinicalScheduler/types/api.ts +++ b/VueApp/src/ClinicalScheduler/types/api.ts @@ -2,7 +2,17 @@ * Shared API types for Clinical Scheduler */ -import type { ApiError } from "./api-responses" +/** + * Discriminated client-side API error representation used in UI flows. + */ +type ApiError = + | { kind: "NetworkError"; message: string } + | { kind: "HttpError"; status: number; message: string } + | { kind: "ValidationError"; message: string; details?: Record } + | { kind: "PermissionError"; message: string } + | { kind: "NotFoundError"; message: string } + | { kind: "ConflictError"; message: string } + | { kind: "UnknownError"; message: string } // Standard API result wrapper used throughout the clinical scheduler interface ApiResult { @@ -19,4 +29,4 @@ interface TypedApiResult { errors: string[] // Keep for backward compatibility } -export type { ApiResult, TypedApiResult } +export type { ApiError, ApiResult, TypedApiResult } diff --git a/VueApp/src/ClinicalScheduler/types/index.ts b/VueApp/src/ClinicalScheduler/types/index.ts index 7bcd9587c..5358fba8a 100644 --- a/VueApp/src/ClinicalScheduler/types/index.ts +++ b/VueApp/src/ClinicalScheduler/types/index.ts @@ -51,43 +51,6 @@ interface InstructorSchedulePermissionCheck { canEditOwn: boolean } -// Instructor Schedule types for edit functionality -interface InstructorScheduleRequest { - mothraId: string - rotationId: number - weekIds: number[] - isPrimaryEvaluator?: boolean -} - -interface InstructorScheduleResponse { - scheduleIds: number[] - message?: string -} - -interface ScheduleConflict { - weekId: number - weekNumber: number - rotationId: number - name: string - dateStart: string - dateEnd: string - isAlreadyScheduled: boolean -} - -interface SetPrimaryEvaluatorRequest { - isPrimary: boolean -} - -interface AuditEntry { - auditId: number - action: string - details: string - modifiedBy: string - modifiedDate: string - mothraId?: string - instructorName?: string -} - export { type ViewContext, type Rotation, diff --git a/VueApp/src/ClinicalScheduler/utils/confirmation-dialog.ts b/VueApp/src/ClinicalScheduler/utils/confirmation-dialog.ts index f6fed8a97..3dad4a28c 100644 --- a/VueApp/src/ClinicalScheduler/utils/confirmation-dialog.ts +++ b/VueApp/src/ClinicalScheduler/utils/confirmation-dialog.ts @@ -18,6 +18,9 @@ function showConfirmationDialog($q: QVueGlobals, title: string, message: string) }) .onOk(() => resolve(true)) .onCancel(() => resolve(false)) + // A programmatic close fires neither onOk nor onCancel, which would leave + // callers awaiting forever. + .onDismiss(() => resolve(false)) }) } diff --git a/VueApp/src/Effort/__tests__/course-add-dialog.test.ts b/VueApp/src/Effort/__tests__/course-add-dialog.test.ts index dadc70edb..57ec27d09 100644 --- a/VueApp/src/Effort/__tests__/course-add-dialog.test.ts +++ b/VueApp/src/Effort/__tests__/course-add-dialog.test.ts @@ -9,7 +9,7 @@ import { setActivePinia, createPinia } from "pinia" */ // Mock the course service -const mockCreateCourse = vi.fn() +const mockCreateCourse = vi.fn<(...args: unknown[]) => any>() vi.mock("../services/course-service", () => ({ courseService: { createCourse: (...args: unknown[]) => mockCreateCourse(...args), diff --git a/VueApp/src/Effort/__tests__/course-edit-dialog.test.ts b/VueApp/src/Effort/__tests__/course-edit-dialog.test.ts index b64e481aa..133d9dfc3 100644 --- a/VueApp/src/Effort/__tests__/course-edit-dialog.test.ts +++ b/VueApp/src/Effort/__tests__/course-edit-dialog.test.ts @@ -9,8 +9,8 @@ import { setActivePinia, createPinia } from "pinia" */ // Mock the course service -const mockUpdateCourse = vi.fn() -const mockUpdateCourseEnrollment = vi.fn() +const mockUpdateCourse = vi.fn<(...args: unknown[]) => any>() +const mockUpdateCourseEnrollment = vi.fn<(...args: unknown[]) => any>() vi.mock("../services/course-service", () => ({ courseService: { updateCourse: (...args: unknown[]) => mockUpdateCourse(...args), diff --git a/VueApp/src/Effort/__tests__/course-import-dialog.test.ts b/VueApp/src/Effort/__tests__/course-import-dialog.test.ts index 21ee23818..8cd7334d8 100644 --- a/VueApp/src/Effort/__tests__/course-import-dialog.test.ts +++ b/VueApp/src/Effort/__tests__/course-import-dialog.test.ts @@ -10,8 +10,8 @@ import { shouldShowImportButton, importButtonLabel, shouldShortcutToImport } fro */ // Mock the course service -const mockSearchBannerCourses = vi.fn() -const mockImportCourse = vi.fn() +const mockSearchBannerCourses = vi.fn<(...args: unknown[]) => any>() +const mockImportCourse = vi.fn<(...args: unknown[]) => any>() vi.mock("../services/course-service", () => ({ courseService: { searchBannerCourses: (...args: unknown[]) => mockSearchBannerCourses(...args), diff --git a/VueApp/src/Effort/__tests__/course-link-dialog.test.ts b/VueApp/src/Effort/__tests__/course-link-dialog.test.ts index e0c77a601..6e2f22860 100644 --- a/VueApp/src/Effort/__tests__/course-link-dialog.test.ts +++ b/VueApp/src/Effort/__tests__/course-link-dialog.test.ts @@ -9,10 +9,10 @@ import { setActivePinia, createPinia } from "pinia" */ // Mock the course service -const mockGetCourseRelationships = vi.fn() -const mockGetAvailableChildCourses = vi.fn() -const mockCreateCourseRelationship = vi.fn() -const mockDeleteCourseRelationship = vi.fn() +const mockGetCourseRelationships = vi.fn<(...args: unknown[]) => any>() +const mockGetAvailableChildCourses = vi.fn<(...args: unknown[]) => any>() +const mockCreateCourseRelationship = vi.fn<(...args: unknown[]) => any>() +const mockDeleteCourseRelationship = vi.fn<(...args: unknown[]) => any>() vi.mock("../services/course-service", () => ({ courseService: { diff --git a/VueApp/src/Effort/__tests__/course-service.test.ts b/VueApp/src/Effort/__tests__/course-service.test.ts index 75f43d25f..051cb5d0f 100644 --- a/VueApp/src/Effort/__tests__/course-service.test.ts +++ b/VueApp/src/Effort/__tests__/course-service.test.ts @@ -6,10 +6,10 @@ import { courseService } from "../services/course-service" */ // Mock the ViperFetch composable -const mockGet = vi.fn() -const mockPost = vi.fn() -const mockPut = vi.fn() -const mockDel = vi.fn() +const mockGet = vi.fn<(...args: unknown[]) => unknown>() +const mockPost = vi.fn<(...args: unknown[]) => unknown>() +const mockPut = vi.fn<(...args: unknown[]) => unknown>() +const mockDel = vi.fn<(...args: unknown[]) => unknown>() vi.mock("@/composables/ViperFetch", () => ({ useFetch: () => ({ get: (...args: unknown[]) => mockGet(...args), diff --git a/VueApp/src/Effort/__tests__/dashboard-service.test.ts b/VueApp/src/Effort/__tests__/dashboard-service.test.ts index ee3b30ded..940278f7e 100644 --- a/VueApp/src/Effort/__tests__/dashboard-service.test.ts +++ b/VueApp/src/Effort/__tests__/dashboard-service.test.ts @@ -8,8 +8,8 @@ import { dashboardService } from "../services/dashboard-service" */ // Mock the ViperFetch composable -const mockGet = vi.fn() -const mockPost = vi.fn() +const mockGet = vi.fn<(...args: unknown[]) => unknown>() +const mockPost = vi.fn<(...args: unknown[]) => unknown>() vi.mock("@/composables/ViperFetch", () => ({ useFetch: () => ({ get: (...args: unknown[]) => mockGet(...args), diff --git a/VueApp/src/Effort/__tests__/effort-records-table.test.ts b/VueApp/src/Effort/__tests__/effort-records-table.test.ts index ca1860eb4..534e0441e 100644 --- a/VueApp/src/Effort/__tests__/effort-records-table.test.ts +++ b/VueApp/src/Effort/__tests__/effort-records-table.test.ts @@ -23,7 +23,7 @@ interface MockRecord { * Generates unique effort type legend items from records. * Extracted from EffortRecordsTable.vue uniqueEffortTypes computed. */ -function getUniqueEffortTypes(records: MockRecord[]): EffortTypeLegendItem[] { +const getUniqueEffortTypes = (records: MockRecord[]): EffortTypeLegendItem[] => { const seen = new Map() for (const record of records) { if (!seen.has(record.effortType)) { @@ -39,7 +39,7 @@ function getUniqueEffortTypes(records: MockRecord[]): EffortTypeLegendItem[] { * Checks if a record has zero effort for styling. * Extracted from EffortRecordsTable.vue isZeroEffort function. */ -function isZeroEffort(record: MockRecord, zeroEffortRecordIds: number[]): boolean { +const isZeroEffort = (record: MockRecord, zeroEffortRecordIds: number[]): boolean => { if (zeroEffortRecordIds.length > 0) { return zeroEffortRecordIds.includes(record.id) } @@ -50,7 +50,7 @@ function isZeroEffort(record: MockRecord, zeroEffortRecordIds: number[]): boolea * Formats the effort display value with label. * Based on EffortRecordsTable.vue body-cell-effort template. */ -function formatEffortDisplay(effortValue: number | null, effortLabel: string): string { +const formatEffortDisplay = (effortValue: number | null, effortLabel: string): string => { const value = effortValue ?? 0 const label = effortLabel === "weeks" ? "Weeks" : "Hours" return `${value} ${label}` diff --git a/VueApp/src/Effort/__tests__/harvest-dialog.test.ts b/VueApp/src/Effort/__tests__/harvest-dialog.test.ts index d6eac8b79..67c8a8bcd 100644 --- a/VueApp/src/Effort/__tests__/harvest-dialog.test.ts +++ b/VueApp/src/Effort/__tests__/harvest-dialog.test.ts @@ -10,8 +10,8 @@ import type { HarvestPreviewDto, HarvestResultDto } from "../types" */ // Mock the harvest service -const mockGetPreview = vi.fn() -const mockCommitHarvest = vi.fn() +const mockGetPreview = vi.fn<(...args: unknown[]) => any>() +const mockCommitHarvest = vi.fn<(...args: unknown[]) => any>() vi.mock("../services/harvest-service", () => ({ harvestService: { getPreview: (...args: unknown[]) => mockGetPreview(...args), diff --git a/VueApp/src/Effort/__tests__/instructor-add-dialog.test.ts b/VueApp/src/Effort/__tests__/instructor-add-dialog.test.ts index 3f4a06866..d5279eb4f 100644 --- a/VueApp/src/Effort/__tests__/instructor-add-dialog.test.ts +++ b/VueApp/src/Effort/__tests__/instructor-add-dialog.test.ts @@ -9,8 +9,8 @@ import { setActivePinia, createPinia } from "pinia" */ // Mock the instructor service -const mockCreateInstructor = vi.fn() -const mockSearchPossibleInstructors = vi.fn() +const mockCreateInstructor = vi.fn<(...args: unknown[]) => unknown>() +const mockSearchPossibleInstructors = vi.fn<(...args: unknown[]) => unknown>() vi.mock("../services/instructor-service", () => ({ instructorService: { createInstructor: (...args: unknown[]) => mockCreateInstructor(...args), diff --git a/VueApp/src/Effort/__tests__/instructor-edit-dialog.test.ts b/VueApp/src/Effort/__tests__/instructor-edit-dialog.test.ts index 0c389d727..a144b73cc 100644 --- a/VueApp/src/Effort/__tests__/instructor-edit-dialog.test.ts +++ b/VueApp/src/Effort/__tests__/instructor-edit-dialog.test.ts @@ -9,9 +9,9 @@ import { setActivePinia, createPinia } from "pinia" */ // Mock the instructor service -const mockUpdateInstructor = vi.fn() -const mockGetDepartments = vi.fn() -const mockGetReportUnits = vi.fn() +const mockUpdateInstructor = vi.fn<(...args: unknown[]) => unknown>() +const mockGetDepartments = vi.fn<(...args: unknown[]) => unknown>() +const mockGetReportUnits = vi.fn<(...args: unknown[]) => unknown>() vi.mock("../services/instructor-service", () => ({ instructorService: { updateInstructor: (...args: unknown[]) => mockUpdateInstructor(...args), diff --git a/VueApp/src/Effort/__tests__/instructor-service.test.ts b/VueApp/src/Effort/__tests__/instructor-service.test.ts index b8e686f6e..b7196957d 100644 --- a/VueApp/src/Effort/__tests__/instructor-service.test.ts +++ b/VueApp/src/Effort/__tests__/instructor-service.test.ts @@ -6,10 +6,10 @@ import { instructorService } from "../services/instructor-service" */ // Mock the ViperFetch composable -const mockGet = vi.fn() -const mockPost = vi.fn() -const mockPut = vi.fn() -const mockDel = vi.fn() +const mockGet = vi.fn<(...args: unknown[]) => unknown>() +const mockPost = vi.fn<(...args: unknown[]) => unknown>() +const mockPut = vi.fn<(...args: unknown[]) => unknown>() +const mockDel = vi.fn<(...args: unknown[]) => unknown>() vi.mock("@/composables/ViperFetch", () => ({ useFetch: () => ({ get: (...args: unknown[]) => mockGet(...args), diff --git a/VueApp/src/Effort/__tests__/report-service.test.ts b/VueApp/src/Effort/__tests__/report-service.test.ts index fc24fa87e..3264ea74a 100644 --- a/VueApp/src/Effort/__tests__/report-service.test.ts +++ b/VueApp/src/Effort/__tests__/report-service.test.ts @@ -8,9 +8,9 @@ import { reportService } from "../services/report-service" */ // Mock the ViperFetch composable -const mockGet = vi.fn() -const mockPostForBlob = vi.fn() -const mockDownloadBlob = vi.fn() +const mockGet = vi.fn<(...args: unknown[]) => unknown>() +const mockPostForBlob = vi.fn<(...args: unknown[]) => unknown>() +const mockDownloadBlob = vi.fn<(...args: unknown[]) => unknown>() vi.mock("@/composables/ViperFetch", () => ({ useFetch: () => ({ get: (...args: unknown[]) => mockGet(...args), diff --git a/VueApp/src/Effort/__tests__/use-report-url-params.test.ts b/VueApp/src/Effort/__tests__/use-report-url-params.test.ts index 379915fb9..b5b2be90b 100644 --- a/VueApp/src/Effort/__tests__/use-report-url-params.test.ts +++ b/VueApp/src/Effort/__tests__/use-report-url-params.test.ts @@ -5,7 +5,7 @@ const mockRoute = { params: {} as Record, name: "test-route", } -const mockReplace = vi.fn() +const mockReplace = vi.fn<(...args: unknown[]) => unknown>() vi.mock("vue-router", () => ({ useRoute: () => mockRoute, useRouter: () => ({ replace: mockReplace }), diff --git a/VueApp/src/Effort/composables/use-report-url-params.ts b/VueApp/src/Effort/composables/use-report-url-params.ts index d0f8c717b..9742bf72d 100644 --- a/VueApp/src/Effort/composables/use-report-url-params.ts +++ b/VueApp/src/Effort/composables/use-report-url-params.ts @@ -63,7 +63,7 @@ export function useReportUrlParams() { const termCode = params.academicYear ? undefined : params.termCode?.toString() || (route.params.termCode as string) || undefined - router.replace({ name: route.name as string, params: { termCode }, query }) + void router.replace({ name: route.name as string, params: { termCode }, query }) } return { initialFilters: getInitialFilters(), updateUrlParams } diff --git a/VueApp/src/Effort/services/harvest-service.ts b/VueApp/src/Effort/services/harvest-service.ts index 18af7db0e..30991ebd2 100644 --- a/VueApp/src/Effort/services/harvest-service.ts +++ b/VueApp/src/Effort/services/harvest-service.ts @@ -7,19 +7,6 @@ function getHarvestUrl(termCode: number) { return `${import.meta.env.VITE_API_URL}effort/terms/${termCode}/harvest` } -/** - * Progress event from SSE stream. - */ -type HarvestProgressEvent = { - type: "progress" | "complete" | "error" - phase: string - progress: number - message: string - detail?: string - result?: HarvestResultDto - error?: string -} - /** * Service for Harvest API calls. */ diff --git a/VueApp/src/Effort/types/harvest-types.ts b/VueApp/src/Effort/types/harvest-types.ts index 7b91c9041..507ab01ae 100644 --- a/VueApp/src/Effort/types/harvest-types.ts +++ b/VueApp/src/Effort/types/harvest-types.ts @@ -89,30 +89,6 @@ type PercentRolloverPreviewDto = { excludedByAudit: PercentRolloverItemPreview[] } -/** - * Progress event from SSE stream for percent rollover. - */ -type RolloverProgressEvent = { - type: "progress" | "complete" | "error" - phase: string - progress: number - message: string - detail?: string - result?: RolloverResult - error?: string -} - -/** - * Result of percent rollover operation. - */ -type RolloverResult = { - success: boolean - assignmentsCreated: number - errorMessage?: string - sourceAcademicYear: string - targetAcademicYear: string -} - type HarvestPreviewDto = { termCode: number termName: string @@ -175,29 +151,6 @@ type ClinicalAssignmentPreview = { roleName: string } -/** - * Progress event from SSE stream for clinical import. - */ -type ClinicalImportProgressEvent = { - type: string - progress: number - message: string - detail?: string - result?: ClinicalImportResultDto -} - -/** - * Result of clinical import operation. - */ -type ClinicalImportResultDto = { - success: boolean - recordsAdded: number - recordsUpdated: number - recordsDeleted: number - recordsSkipped: number - errorMessage?: string -} - export type { HarvestRecordPreview, PercentRolloverItemPreview, diff --git a/VueApp/src/Students/EmergencyContact/__tests__/completeness-icon.test.ts b/VueApp/src/Students/EmergencyContact/__tests__/completeness-icon.test.ts index dea3abe8b..d16dfe646 100644 --- a/VueApp/src/Students/EmergencyContact/__tests__/completeness-icon.test.ts +++ b/VueApp/src/Students/EmergencyContact/__tests__/completeness-icon.test.ts @@ -18,7 +18,7 @@ function mountIcon(props: Props) { return { iconName: icon.props("name") as string, iconColor: icon.props("color") as string, - tooltipText: icon.attributes("aria-label") as string, + tooltipText: icon.attributes("aria-label")!, } } diff --git a/VueApp/src/Students/EmergencyContact/__tests__/emergency-contact-service.test.ts b/VueApp/src/Students/EmergencyContact/__tests__/emergency-contact-service.test.ts index ada740727..001967c19 100644 --- a/VueApp/src/Students/EmergencyContact/__tests__/emergency-contact-service.test.ts +++ b/VueApp/src/Students/EmergencyContact/__tests__/emergency-contact-service.test.ts @@ -7,11 +7,11 @@ import type { UpdateStudentContactRequest } from "../types" */ // Mock the ViperFetch composable -const mockGet = vi.fn() -const mockPut = vi.fn() -const mockPost = vi.fn() -const mockPostForBlob = vi.fn() -const mockDownloadBlob = vi.fn() +const mockGet = vi.fn<(...args: unknown[]) => unknown>() +const mockPut = vi.fn<(...args: unknown[]) => unknown>() +const mockPost = vi.fn<(...args: unknown[]) => unknown>() +const mockPostForBlob = vi.fn<(...args: unknown[]) => unknown>() +const mockDownloadBlob = vi.fn<(...args: unknown[]) => unknown>() vi.mock("@/composables/ViperFetch", () => ({ useFetch: () => ({ get: (...args: unknown[]) => mockGet(...args), diff --git a/VueApp/src/Students/EmergencyContact/__tests__/use-emergency-contact.test.ts b/VueApp/src/Students/EmergencyContact/__tests__/use-emergency-contact.test.ts index 5ae3d872a..7fdc73181 100644 --- a/VueApp/src/Students/EmergencyContact/__tests__/use-emergency-contact.test.ts +++ b/VueApp/src/Students/EmergencyContact/__tests__/use-emergency-contact.test.ts @@ -54,7 +54,7 @@ describe("useEmergencyContact utilities", () => { vi.clearAllMocks() }) - describe(contactCompleteness, () => { + describe("contactCompleteness", () => { it("should return 0 for empty contact", () => { const contact: ContactInfo = { name: null, @@ -104,7 +104,7 @@ describe("useEmergencyContact utilities", () => { }) }) - describe(studentInfoCompleteness, () => { + describe("studentInfoCompleteness", () => { it("should return 0 for empty info", () => { const info: StudentInfo = { address: null, diff --git a/VueApp/src/Students/__tests__/photo-gallery-ross-checkbox.test.ts b/VueApp/src/Students/__tests__/photo-gallery-ross-checkbox.test.ts index 98b9aced8..8a63928fe 100644 --- a/VueApp/src/Students/__tests__/photo-gallery-ross-checkbox.test.ts +++ b/VueApp/src/Students/__tests__/photo-gallery-ross-checkbox.test.ts @@ -133,15 +133,9 @@ describe("PhotoGallery - Ross Checkbox Visibility", () => { { label: "2026 (V4)", year: 2026, classLevel: "V4" }, ]) - if (!selectedStudentListYear.value) { - expect(true).toBeTruthy() // Should return false when no year selected - return - } - const selectedYear = classYearOptions.value.find((cy) => cy.year === selectedStudentListYear.value) const showRossCheckboxInList = selectedYear?.classLevel === "V3" || selectedYear?.classLevel === "V4" - // This code won't execute due to early return expect(showRossCheckboxInList).toBeFalsy() }) diff --git a/VueApp/src/Students/__tests__/photo-gallery-store.test.ts b/VueApp/src/Students/__tests__/photo-gallery-store.test.ts index 14dc9f8ef..52bac1d66 100644 --- a/VueApp/src/Students/__tests__/photo-gallery-store.test.ts +++ b/VueApp/src/Students/__tests__/photo-gallery-store.test.ts @@ -8,16 +8,16 @@ import type { PhotoGalleryViewModel, GalleryMenu, CourseInfo } from "../services // Mock the photo gallery service vi.mock("../services/photo-gallery-service", () => ({ photoGalleryService: { - getClassGallery: vi.fn(), - getGroupGallery: vi.fn(), - getGalleryMenu: vi.fn(), - getAvailableCourses: vi.fn(), - getCourseGallery: vi.fn(), - exportToWord: vi.fn(), - exportToPDF: vi.fn(), + getClassGallery: vi.fn<(...args: unknown[]) => unknown>(), + getGroupGallery: vi.fn<(...args: unknown[]) => unknown>(), + getGalleryMenu: vi.fn<(...args: unknown[]) => unknown>(), + getAvailableCourses: vi.fn<(...args: unknown[]) => unknown>(), + getCourseGallery: vi.fn<(...args: unknown[]) => unknown>(), + exportToWord: vi.fn<(...args: unknown[]) => unknown>(), + exportToPDF: vi.fn<(...args: unknown[]) => unknown>(), }, - PhotoGalleryService: vi.fn(), - downloadFile: vi.fn(), + PhotoGalleryService: vi.fn<(...args: unknown[]) => unknown>(), + downloadFile: vi.fn<(...args: unknown[]) => unknown>(), })) // eslint-disable-next-line max-lines-per-function -- Test suite requires comprehensive coverage with multiple test cases @@ -594,7 +594,7 @@ describe("photo-gallery-store", () => { expect(store.galleryView).toBe("list") }) - it("toggleRossStudents should refetch class when class is selected", async () => { + it("toggleRossStudents should refetch class when class is selected", () => { const store = usePhotoGalleryStore() store.selectedClassLevel = "V4" @@ -604,7 +604,7 @@ describe("photo-gallery-store", () => { } vi.mocked(photoGalleryService.getClassGallery).mockResolvedValue(mockResponse) - await store.toggleRossStudents() + store.toggleRossStudents() expect(photoGalleryService.getClassGallery).toHaveBeenCalled() }) diff --git a/VueApp/src/Students/__tests__/use-photo-gallery-groups.test.ts b/VueApp/src/Students/__tests__/use-photo-gallery-groups.test.ts index aff06d882..e151f2300 100644 --- a/VueApp/src/Students/__tests__/use-photo-gallery-groups.test.ts +++ b/VueApp/src/Students/__tests__/use-photo-gallery-groups.test.ts @@ -3,7 +3,7 @@ import { setActivePinia, createPinia } from "pinia" import { usePhotoGalleryGroups } from "../composables/use-photo-gallery-groups" import { usePhotoGalleryStore } from "../stores/photo-gallery-store" -describe(usePhotoGalleryGroups, () => { +describe("usePhotoGalleryGroups", () => { beforeEach(() => { // Create a fresh pinia instance for each test setActivePinia(createPinia()) diff --git a/VueApp/src/Students/__tests__/use-photo-gallery-options.test.ts b/VueApp/src/Students/__tests__/use-photo-gallery-options.test.ts index 4e43571fc..b760a7be4 100644 --- a/VueApp/src/Students/__tests__/use-photo-gallery-options.test.ts +++ b/VueApp/src/Students/__tests__/use-photo-gallery-options.test.ts @@ -2,7 +2,7 @@ import { ref } from "vue" import { usePhotoGalleryOptions } from "../composables/use-photo-gallery-options" import type { ClassYear, CourseInfo } from "../services/photo-gallery-service" -describe(usePhotoGalleryOptions, () => { +describe("usePhotoGalleryOptions", () => { describe("classYearOptions", () => { it("should generate correct class year options with year and classLevel", () => { const classYears = ref([ diff --git a/VueApp/src/components/__tests__/rich-text-editor.test.ts b/VueApp/src/components/__tests__/rich-text-editor.test.ts index a160b3851..f8de735aa 100644 --- a/VueApp/src/components/__tests__/rich-text-editor.test.ts +++ b/VueApp/src/components/__tests__/rich-text-editor.test.ts @@ -50,6 +50,7 @@ afterAll(() => { if (key in savedCommands && savedCommands[key] !== undefined) { d[key] = savedCommands[key] } else { + // oxlint-disable-next-line typescript/no-dynamic-delete -- restoring document requires removing the key, not setting it undefined delete d[key] } } diff --git a/VueApp/src/composables/QuasarTableUtilities.ts b/VueApp/src/composables/QuasarTableUtilities.ts index 703343dd1..3b426be65 100644 --- a/VueApp/src/composables/QuasarTableUtilities.ts +++ b/VueApp/src/composables/QuasarTableUtilities.ts @@ -41,7 +41,7 @@ function exportTable(columns: QTableProps["columns"], rows: any[], excludeFromEx } //Escape double quotes (" -> "") and new lines in the content -function wrapCsvValue(val: string, formatFn: any | null = null, row: any = null) { +function wrapCsvValue(val: string, formatFn: any = null, row: any = null) { let formatted = formatFn !== null && formatFn !== undefined ? formatFn(val, row) : val formatted = formatted === undefined || formatted === null ? "" : String(formatted) diff --git a/VueApp/src/composables/RequireLogin.ts b/VueApp/src/composables/RequireLogin.ts index b5d203572..069f050aa 100644 --- a/VueApp/src/composables/RequireLogin.ts +++ b/VueApp/src/composables/RequireLogin.ts @@ -84,7 +84,7 @@ function useRequireLogin(to: RouteLocationNormalized) { loadPermissions: boolean | null = null, permissionPrefix: string | null = null, ): Promise { - const baseUrl = inject("apiURL") as string + const baseUrl = inject("apiURL")! const userStore = useUserStore() const route = useRoute() const router = useRouter() @@ -167,7 +167,7 @@ function handleSendBackToRedirect(route: ReturnType, router: Re params[key] = val } } - router.push({ path: redirectPath, query: params ?? null }) + void router.push({ path: redirectPath, query: params ?? null }) } export { getLoginUrl, useRequireLogin } diff --git a/VueApp/src/composables/ViperFetch.ts b/VueApp/src/composables/ViperFetch.ts index 187ba205e..34888227f 100644 --- a/VueApp/src/composables/ViperFetch.ts +++ b/VueApp/src/composables/ViperFetch.ts @@ -143,7 +143,7 @@ async function fetchWrapper(url: string, options: any = {}) { } return r.pagination ? { result: intialResult, pagination: r.pagination } : intialResult }) - .catch((error) => { + .catch((error: unknown) => { if (error instanceof ValidationError) { // Extract structured errors, falling back to message let validationErrors: string[] = [] @@ -158,7 +158,8 @@ async function fetchWrapper(url: string, options: any = {}) { errorHandler.handleAuthError(error?.message, error.status) errors = [error?.message || "Authentication error"] } else { - errorHandler.handleError(error) + // String() matches what handleError's join() did with a non-string value. + errorHandler.handleError(String(error)) errors = errorHandler.errors.value } }) diff --git a/VueApp/src/composables/use-route-focus.ts b/VueApp/src/composables/use-route-focus.ts index 3607ac9bd..509974ad2 100644 --- a/VueApp/src/composables/use-route-focus.ts +++ b/VueApp/src/composables/use-route-focus.ts @@ -20,7 +20,7 @@ export function useRouteFocus(router: Router) { if (to.path === from.path) { return } - nextTick(() => { + void nextTick(() => { const main = document.querySelector("#main-content") || document.querySelector("main") if (main instanceof HTMLElement) { // Set tabindex temporarily so the element can receive focus diff --git a/package-lock.json b/package-lock.json index dc5e458d1..93d8c346c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,21 +8,21 @@ "name": "viper2", "version": "2.0.0", "devDependencies": { - "@double-great/stylelint-a11y": "^3.4.15", + "@double-great/stylelint-a11y": "^3.5.0", "@eslint/js": "^10.0.0", "concurrently": "^10.0.4", "cross-env": "^10.0.0", - "eslint": "^10.5.0", + "eslint": "^10.8.0", "eslint-plugin-html": "^8.1.4", "eslint-plugin-security": "^4.0.1", - "fallow": "^2.102.0", + "fallow": "^3.6.0", "husky": "^9.1.7", - "jscpd": "^5.0.10", - "oxfmt": "^0.56.0", - "oxlint": "^1.71.0", - "oxlint-tsgolint": "^0.23.0", + "jscpd": "^5.0.12", + "oxfmt": "^0.60.0", + "oxlint": "^1.75.0", + "oxlint-tsgolint": "^7.0.2001", "postcss-html": "^1.8.0", - "stylelint": "^17.13.0", + "stylelint": "^17.14.1", "stylelint-config-standard": "^40.0.0", "yauzl": "^3.4.0" }, @@ -31,13 +31,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -63,13 +63,13 @@ } }, "node_modules/@cacheable/memory": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.9.tgz", - "integrity": "sha512-HdMx6DoGywB30vacDbBsITbIX4pgFqj1zsrV58jZBUw3klzkNoXhj7qOqAgledhxG7YZI5rBSJg7Zp8/VG0DuA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/utils": "^2.4.1", + "@cacheable/utils": "^2.5.0", "@keyv/bigmap": "^1.3.1", "hookified": "^1.15.1", "keyv": "^5.6.0" @@ -103,9 +103,9 @@ } }, "node_modules/@cacheable/utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.4.1.tgz", - "integrity": "sha512-eiFgzCbIneyMlLOmNG4g9xzF7Hv3Mga4LjxjcSC/ues6VYq2+gUbQI8JqNuw/ZM8tJIeIaBGpswAsqV2V7ApgA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", "dev": true, "license": "MIT", "dependencies": { @@ -171,9 +171,9 @@ } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.5.tgz", - "integrity": "sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.7.tgz", + "integrity": "sha512-fQ+05118eQS1cofO3aJpB5efgpBZMvIzwr/sbC8kDLVA5XLG8q1kJV5yzrUAI1f7lvhPnm8fgIjzFB8/O/5Dig==", "dev": true, "funding": [ { @@ -286,16 +286,16 @@ } }, "node_modules/@double-great/stylelint-a11y": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@double-great/stylelint-a11y/-/stylelint-a11y-3.4.15.tgz", - "integrity": "sha512-yMpE5UpdXt4ezKv7fxf69k61ycOrJ7xa+Wt6p1XuV8r1y2PKWyVGp1qxFcc4BMEpptOA0XhWPhKHrpbP3+tmuw==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@double-great/stylelint-a11y/-/stylelint-a11y-3.5.0.tgz", + "integrity": "sha512-OWjpx3bNABE1Ttq541uuR++/RvbwlclMPxsedsw6XoDe4dCqxRJRhZ0pg4aRGlk8w/2RpOeMilK4NEwcQc457w==", "dev": true, "license": "MIT", "dependencies": { - "postcss": "^8.5.15" + "postcss": "^8.5.16" }, "engines": { - "node": ">=18.12.0" + "node": ">=22.0.0" }, "peerDependencies": { "stylelint": ">=16.0.0" @@ -366,9 +366,9 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", - "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", + "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -437,9 +437,9 @@ } }, "node_modules/@fallow-cli/darwin-arm64": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/darwin-arm64/-/darwin-arm64-2.102.0.tgz", - "integrity": "sha512-B8wzfzJgoX6h5Gv2xQ9ZidO5Jb8/PWdssAxYbWs1pb5oJHZ6S5PLwXuUdINmNSIaRGQwTk4DC9/tIMFHFvd9uw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/darwin-arm64/-/darwin-arm64-3.6.0.tgz", + "integrity": "sha512-DnOEQQD7QnMs8mjasPkgzh9jpTbpoUb0jJE1nkV9ZL+x2DkFWSMKYuJ9rdgWdWx7OLKmwgtPMgW1wsRKG0ICLw==", "cpu": [ "arm64" ], @@ -451,9 +451,9 @@ ] }, "node_modules/@fallow-cli/darwin-x64": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/darwin-x64/-/darwin-x64-2.102.0.tgz", - "integrity": "sha512-aLbTWWzQnleKdi56obAPXMJm7YA3qAnkIX9T3eocRHiagYqp8nsf4cslM0rZKvu2WwK34NaBm8x886gl4cl+zg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/darwin-x64/-/darwin-x64-3.6.0.tgz", + "integrity": "sha512-5Gq8fuaFLZ86v2I5B2/L44Nty36AKdCkW48r2cziRtw54xS1uTpi2MYrmNS+as8gu1q4fb7Ei2mwAIz4F/nNtQ==", "cpu": [ "x64" ], @@ -465,9 +465,9 @@ ] }, "node_modules/@fallow-cli/linux-arm64-gnu": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/linux-arm64-gnu/-/linux-arm64-gnu-2.102.0.tgz", - "integrity": "sha512-8nYeOSLSewqcKH/KUcKZaCq5QII5VTRX62l60B6UM1iKe/0jcmlQ2mOtx4rkHpeq3LL5emvT/ph4NNgGmWKSBg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/linux-arm64-gnu/-/linux-arm64-gnu-3.6.0.tgz", + "integrity": "sha512-AP8DdPxX4yLeC2BQh8rBNv466BswuY8s0zQHihcL5RAsc+C6NiAJR3XAMRHl2BOaIlxWeptPAUpcGLeCs4Or1Q==", "cpu": [ "arm64" ], @@ -479,9 +479,9 @@ ] }, "node_modules/@fallow-cli/linux-arm64-musl": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/linux-arm64-musl/-/linux-arm64-musl-2.102.0.tgz", - "integrity": "sha512-2Zi33PXzZxD7HU5sPVwyElZGP7zyEdGo4hK0ewy6gMYgQ9BDfLnFhgaSSOzN1J4paIhYtBmVsLmqakyDKy22Jw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/linux-arm64-musl/-/linux-arm64-musl-3.6.0.tgz", + "integrity": "sha512-Q9ecwQOECRwtFzuPwNmsxha2V/UsP/Y4vRKEogdgydawywzIHkM2t85C9D1YIK+VNl/bpQtLApLsndxxkpC1xQ==", "cpu": [ "arm64" ], @@ -493,9 +493,9 @@ ] }, "node_modules/@fallow-cli/linux-x64-gnu": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/linux-x64-gnu/-/linux-x64-gnu-2.102.0.tgz", - "integrity": "sha512-7Hys4X6hKuR/lqUaGXwezRzDrwXwu9KfahUy85WTuiG1to+ZbzDCqdbZ04LtnI8kK8ufrPDcq+ZXdyt5ksOJHA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/linux-x64-gnu/-/linux-x64-gnu-3.6.0.tgz", + "integrity": "sha512-ckRpZ0svhBGK67Vsg3E+SCDIJQsQ73ArGLfmma9PLz3ZxPoaw028dk8roQv9eShyZeirWTRyX3DppVh1Q4F7ag==", "cpu": [ "x64" ], @@ -507,9 +507,9 @@ ] }, "node_modules/@fallow-cli/linux-x64-musl": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/linux-x64-musl/-/linux-x64-musl-2.102.0.tgz", - "integrity": "sha512-RuDY1jOEPgJOuHBgEpHVl6J7Xf2QLFklnNy6zO1nw8R1fLgWUAAKlFirn1Y93pb9bXzqpn5Gre3YlhgIZ3+LBA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/linux-x64-musl/-/linux-x64-musl-3.6.0.tgz", + "integrity": "sha512-Saz6+KfzorXxujc2WTsKDxr+pOpm3h/sYqe8buAPG/fYfPGeu+YvQem7TzKlf4uB2TKWHl7V51dP7gehGFwF7g==", "cpu": [ "x64" ], @@ -521,9 +521,9 @@ ] }, "node_modules/@fallow-cli/win32-arm64-msvc": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/win32-arm64-msvc/-/win32-arm64-msvc-2.102.0.tgz", - "integrity": "sha512-wsvHjLzWFvsYmCqnQLm1doSEHb9Z038+sFp1RzMcffPUBC5tqS3vCr8J8nolcLlPk7o3QWHQMXAqb1xSJe+doA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/win32-arm64-msvc/-/win32-arm64-msvc-3.6.0.tgz", + "integrity": "sha512-kcM1lgxU4tMcl48nP60srxvYHR5utvFycTpDPbM4PrSrtPJOWLghJwXpjsJWlLJkBEaUhAp7LzBQHFTvEFpM0g==", "cpu": [ "arm64" ], @@ -535,9 +535,9 @@ ] }, "node_modules/@fallow-cli/win32-x64-msvc": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/@fallow-cli/win32-x64-msvc/-/win32-x64-msvc-2.102.0.tgz", - "integrity": "sha512-rH1hd0PD0mm6pCxh1pw5jubpJsvV6f5rjixMoD5AZLzWa6NPJBpPPuzruLGtH/9CYy8B0y7zPrGGTKRO2PCGzg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@fallow-cli/win32-x64-msvc/-/win32-x64-msvc-3.6.0.tgz", + "integrity": "sha512-piMKRxPWev6T4hUFlUJ2dD2sMm5Wc62jm4El/yY2SAmHiwychGcyzYsWh4qQg5r8zPWIkE8wIfXlWXsLKtU7nw==", "cpu": [ "x64" ], @@ -646,9 +646,9 @@ } }, "node_modules/@oxfmt/binding-android-arm-eabi": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.56.0.tgz", - "integrity": "sha512-CSCxi7ovYojgfdPOdUb9T508HKeAdDIKeRGg7x8IZwVJrWz9gVgX7MbUnFqtQAE4QvoNo07mj2JlwnOzJw4qqA==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.60.0.tgz", + "integrity": "sha512-1q4q4Jc8FlOMVojEisyFAVyl8h1yawNv6phjgmhGVEDeyeOdsSnSr9x0+D4mOnEKvpO5L4mxKZ/DP9X6U3A/Mw==", "cpu": [ "arm" ], @@ -663,9 +663,9 @@ } }, "node_modules/@oxfmt/binding-android-arm64": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.56.0.tgz", - "integrity": "sha512-HYJFnd+PkDwf6S9ZPGzXXtjNqvRWFnnhdbWaouh4mi/SxU8wmDuzlMn3xo/wDTGnr4Q1VA7ZzOaE/D4biW0W6A==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.60.0.tgz", + "integrity": "sha512-tD41I6nCt9k8SQXft0CSjjU9jg6SwG7uMu7PxodSEHXl+GDW0868oy6tTtoJkyUze8YKFgTpz/k5LuPUnFiGLw==", "cpu": [ "arm64" ], @@ -680,9 +680,9 @@ } }, "node_modules/@oxfmt/binding-darwin-arm64": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.56.0.tgz", - "integrity": "sha512-sftR/bEOr+t1gs+evwsHi/Xbq2FAPA2uU3VMr8n6ZU9PoK/IMSfnfu7+OEe/uy1+knhrFl4Wvy7Vkm3uo9mJ7g==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.60.0.tgz", + "integrity": "sha512-TTpzPug96Zxdyb46KvTyIUQDdsqbumXh2TKG9C23PCT0kF7JkW56Z/quPuG9rqOFKQIi1gpRNZ7DX18LwxXPnw==", "cpu": [ "arm64" ], @@ -697,9 +697,9 @@ } }, "node_modules/@oxfmt/binding-darwin-x64": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.56.0.tgz", - "integrity": "sha512-z66SdjLqa3MUPKvTp3Mbb5nSjKSbnYxJGeB+Wx987s8T5hPcIRiBMfnJ6zcPgYtQn3x5xjvdzNVkXrSeYH6ZFg==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.60.0.tgz", + "integrity": "sha512-CnOoWgQ7L+JL/YQaRJ+NyATciSfcftncm7y3kqyte1cGtFEGnStaCd1TAyrinkfQ7nRBfHrTs1/vTwUJr3WF2Q==", "cpu": [ "x64" ], @@ -714,9 +714,9 @@ } }, "node_modules/@oxfmt/binding-freebsd-x64": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.56.0.tgz", - "integrity": "sha512-t2tkrV1vtZyaItSQ71dTi2ZVKZEI39b/LqLT12V5KMfIeXK6N32TUC1jhOXKVQmhECq9j2ZXMQV3JeT1kh9Vmg==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.60.0.tgz", + "integrity": "sha512-ychJo7S3hZxdO6eDZ9zM6F2lM9fpJS3EKS5CAUSWyprdLYxTu4gbaUKV/VBPTcMJwQa2Bpo+643y3OJ537pihA==", "cpu": [ "x64" ], @@ -731,9 +731,9 @@ } }, "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.56.0.tgz", - "integrity": "sha512-+gCy+Tp3RHeXQ9y/QrS76lXIpZkbziTyp6hIgjB2MssCwfMph3vG/GEfkhO34Rai1vhYIaUkvv8UT1BcDorJPw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.60.0.tgz", + "integrity": "sha512-36IH5o55T2Fx7E0feDttt+mifxN6yk9pWv4KfhAIsP0dFnUq27331OwbpOsZdoXF9soOLWm7mQUz5+UUmyec4g==", "cpu": [ "arm" ], @@ -748,9 +748,9 @@ } }, "node_modules/@oxfmt/binding-linux-arm-musleabihf": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.56.0.tgz", - "integrity": "sha512-0kKkVvQ2I+FJ2sxQyUu1zJ0yWP5kcWse/yVFnGQSFCXMwSSkfEaUGu0dW774O7nyy3jrcBGap7OSc8dZmU/CdA==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.60.0.tgz", + "integrity": "sha512-G1Ve7lAa6sFBolVI2LWHfEAqy0YKh4vnioH8uYO9kAEdgM7mR40IksIx9/Zk4+vbYew/sGa4J9Q4tZ3n9gXDHA==", "cpu": [ "arm" ], @@ -765,9 +765,9 @@ } }, "node_modules/@oxfmt/binding-linux-arm64-gnu": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.56.0.tgz", - "integrity": "sha512-npkA2siMbyWRh+wEhi1aTAx4RirukGcGNt8V4Ch86pG+xU9aurqS1MZOnKYMu03ISwat3rB6zkQx51SsB9obNw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.60.0.tgz", + "integrity": "sha512-LTQdRBf6uzj/h7Xk6lKzbGD2hrF/fK4YI9LIN1c0509tPUn8wRa3mCmrFQpEWJPLYGFrLFFMTYW1Ljj6VqW2Hw==", "cpu": [ "arm64" ], @@ -785,9 +785,9 @@ } }, "node_modules/@oxfmt/binding-linux-arm64-musl": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.56.0.tgz", - "integrity": "sha512-UekqOjGkV4/MkqreCV9SPIB2jlR3/HbXrmhV1rVXJZ9wfDXMyCMriLtq3tHqLY4PkbVWNtfcm1kMojJ26KLSJw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.60.0.tgz", + "integrity": "sha512-2JMo3XPxMPx3hiqddSZYyaH+fKJm6cz0u8n1naYjP/CdOQOZW34i8lKBUfmbWiuFvd6KoYXLmhAyBuvojsYS7Q==", "cpu": [ "arm64" ], @@ -805,9 +805,9 @@ } }, "node_modules/@oxfmt/binding-linux-ppc64-gnu": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.56.0.tgz", - "integrity": "sha512-XSzveSpeZMD5XJpew5lRFVtNnT04xd3rJxENXmk7wkZzN9oWzv2aFJyoNDhOtoz69BYaS/fg4SYl+CfEZRpB0Q==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.60.0.tgz", + "integrity": "sha512-L3C+nBD13lr306tr/PjM3RMll+BVqgFrIgUyoeHuai5oueJrRLgO3j+GO5/Cbhtkf5PSlHYTI1JY7iqBd1qa6A==", "cpu": [ "ppc64" ], @@ -825,9 +825,9 @@ } }, "node_modules/@oxfmt/binding-linux-riscv64-gnu": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.56.0.tgz", - "integrity": "sha512-EkQ0nJa7k7HDDIVuPF7WY+k4k+bzdclLYtyIXNt7/OqVghfNiMym6YGppFBgx1XRIHW6QylxBz5OogumPjPJbQ==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.60.0.tgz", + "integrity": "sha512-M4MsmvqlxFiPtSRGyBYQSZxchEf463AOyd+Dh4/9xDpjWBsRtDUTDMFN5EdHinjVK1/eDJQ8MLpcYjpYayaCnA==", "cpu": [ "riscv64" ], @@ -845,9 +845,9 @@ } }, "node_modules/@oxfmt/binding-linux-riscv64-musl": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.56.0.tgz", - "integrity": "sha512-dyjAGW8jKRge0ik6U/dgvQG0nVpA3iBlRskQTz5qJLvQWIrySxX5jpqzPetLBNIIZ231KA82fDdi1nLTk8ENCw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.60.0.tgz", + "integrity": "sha512-OH+9UskYuxRB+GxqdGkVN8f5UpwhqG8YscNo1wl8+KJ62cd7wZdGga6iGLJIf8kibF1WBwvlfDUx3cez/VXwFg==", "cpu": [ "riscv64" ], @@ -865,9 +865,9 @@ } }, "node_modules/@oxfmt/binding-linux-s390x-gnu": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.56.0.tgz", - "integrity": "sha512-60ZGH3LtfqlW8X6vcLdSFY4lvCQYINurttYBKaALnHCDVAUCYJ1LsUgS6p1XOzVlzEDx3yNUZvDF1Lvt59zoZw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.60.0.tgz", + "integrity": "sha512-y7AAFutt9wFWBFOAn6+BHaV39usZmcr3YYH2385f+NHgPNpIF9HpqKp0jgUxPaUOCyG3oaX5VhJduL1Nw164rw==", "cpu": [ "s390x" ], @@ -885,9 +885,9 @@ } }, "node_modules/@oxfmt/binding-linux-x64-gnu": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.56.0.tgz", - "integrity": "sha512-u1suj1tgJHK4ZqB7buCtdbNef2n8+d0lXTPJwLHNmtyK6p+DTpsaoDvmqhQrA56fgKYv4LuRxNtL8YooebKOew==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.60.0.tgz", + "integrity": "sha512-yKZ9+CXAI+1RO5nH/4Z/9M6DAsfOzd5bw/gtWk81KB4mpalMaRRSXfouc5/tHxazDmBek55HNPepNYBgaCew0Q==", "cpu": [ "x64" ], @@ -905,9 +905,9 @@ } }, "node_modules/@oxfmt/binding-linux-x64-musl": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.56.0.tgz", - "integrity": "sha512-aYGLvlQHt80y+qKEtfJY/Nm27G0125Lv+qyh9SJ4Cjc6lXnXjD+ndfhqQnbV24POpMi7rNRi0jvx/0d70FRpCQ==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.60.0.tgz", + "integrity": "sha512-bCUGaF6hJOYnQzLJdHLZbvGsOd5oSvGAyJhPAKum2uyLYUuXmP8vqg690DWi2hqcnIoYpqSqCrjzE5aiUAgwQg==", "cpu": [ "x64" ], @@ -925,9 +925,9 @@ } }, "node_modules/@oxfmt/binding-openharmony-arm64": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.56.0.tgz", - "integrity": "sha512-H/re/gO+7ysVc+kywHNuzY3C33EN9sQcZhg0kp1ZwOZl7y998ZE5mhnBiuGR/nYI0pqLL5xQfrHVUOJ/cIJsCA==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.60.0.tgz", + "integrity": "sha512-GrUeZOvzP30ExxfCuQiyofuUGI+OmvAgFwOO5w5p9mGPlxcyuqI+6Sy9fAKFFfLQrqKYWFgc5sYA2Unj/29nPg==", "cpu": [ "arm64" ], @@ -942,9 +942,9 @@ } }, "node_modules/@oxfmt/binding-win32-arm64-msvc": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.56.0.tgz", - "integrity": "sha512-6qLNXfXmtAs8jXDvYMkxk6Wec5SUJoew+ZX1uOZmqaR7ks0EJFbAohuOCELDyJMWyVlxotVG8Xf8m74Bfq0O2w==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.60.0.tgz", + "integrity": "sha512-WD4Q954kUl2TDJV/6q7UnE2rlKk047kXLJsr4bJ2mXRaAqNXcmV3nwKUsGCc3mz/jYDBnXtJEaBErJEybK8iQQ==", "cpu": [ "arm64" ], @@ -959,9 +959,9 @@ } }, "node_modules/@oxfmt/binding-win32-ia32-msvc": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.56.0.tgz", - "integrity": "sha512-UXEXuKphAe15bsob4AswNMArCw38XSmUIs3wk1s6e6MX9OWGW/IRWU95s1hZDiVg09STy1jHgyN2qkqbu1FT0w==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.60.0.tgz", + "integrity": "sha512-HqDekjr8JXzVDUP1YthDZ1Y3CBEcuZT4WX3B+1kaxj8CvZA8Y2YhcEsXqoSop3tVsgjACxjnFQFDkBo0r/jq1Q==", "cpu": [ "ia32" ], @@ -976,9 +976,9 @@ } }, "node_modules/@oxfmt/binding-win32-x64-msvc": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.56.0.tgz", - "integrity": "sha512-HPyNDjky+NIOuaMvHZflR+kst3YWdUOH2JUQYkf99grqZ5mEBTQM6h9iGy501Z8Xt5xMScrwHOuVCOlqDrktRw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.60.0.tgz", + "integrity": "sha512-tz78yhmGPKboTMHCHSaUqXK8JrmoSejgDcWeqAtg2s07ZGKQ3rH5Jn8NuXPGNG33CDbY2e9NoQWXIVEmKO21Rw==", "cpu": [ "x64" ], @@ -993,9 +993,9 @@ } }, "node_modules/@oxlint-tsgolint/darwin-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-arm64/-/darwin-arm64-0.23.0.tgz", - "integrity": "sha512-gOs9PVr2wEg4ox9z0aJo+RKhhImW86YL5N6yav8BK/rgPsIrwN/igSZ+pbRr723NFvUNKde9fgMhRA6JrXAOZw==", + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-arm64/-/darwin-arm64-7.0.2001.tgz", + "integrity": "sha512-CUJEdbSZ54+Xy9OXqOhWLTKZKV0BBiV7C2i/ygyVmXtkUNXx5YCzN8DpSSshTAKktoL7S+tnQ/ftFG/i7X896w==", "cpu": [ "arm64" ], @@ -1007,9 +1007,9 @@ ] }, "node_modules/@oxlint-tsgolint/darwin-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-x64/-/darwin-x64-0.23.0.tgz", - "integrity": "sha512-kjJ8B+7n4tB9VJdxS5A9GdJt6/bYpzbu4lXp2uO1S3sRmCB5gDEABlGoiePNApRWaW+xqL4b4xgiE727jSLhuA==", + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-x64/-/darwin-x64-7.0.2001.tgz", + "integrity": "sha512-pXfBb5BqONCcgrXQNUZWXgiYmRSWJzd97S8i41VVOh6ut0tyo+cJ5FKFpczDHxiVNfj/3e7c9B4MtztNdpIVCw==", "cpu": [ "x64" ], @@ -1021,9 +1021,9 @@ ] }, "node_modules/@oxlint-tsgolint/linux-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-arm64/-/linux-arm64-0.23.0.tgz", - "integrity": "sha512-6dCZuKNu135seMXilkRk9SpCx6i1XgmiipYGalLij5WVRX6ZYS8c4xI7preN/zv9fCXhsQclTIMDu2Y/cytTjw==", + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-arm64/-/linux-arm64-7.0.2001.tgz", + "integrity": "sha512-roP7zujb/QDPzDwEKsFFpzNHHy91/Y7oX9vQXk78ekyZtcQj1QXDIMH33gjDdHBfRl4K9pZ36xhRgrP4Zr+R8A==", "cpu": [ "arm64" ], @@ -1035,9 +1035,9 @@ ] }, "node_modules/@oxlint-tsgolint/linux-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-x64/-/linux-x64-0.23.0.tgz", - "integrity": "sha512-3bdilnyA7kmSTjK27rvjIjSxL5SIg3wt7vwNiRkouWB83ytssyKnuGvxSYJxgMEmFpSutzaBzcCUM2jDtPGcgA==", + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-x64/-/linux-x64-7.0.2001.tgz", + "integrity": "sha512-UDezNqdECVmngu2TPnjaS1YoAmcTaBoI5lV9vk3VahBxoi+I5r9k3iJTT7qZoYWOXTD/7T7bNcwRgrocR6BscQ==", "cpu": [ "x64" ], @@ -1049,9 +1049,9 @@ ] }, "node_modules/@oxlint-tsgolint/win32-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-arm64/-/win32-arm64-0.23.0.tgz", - "integrity": "sha512-j+OEp44SVYiQ+ZD+uttsX7u6L9SvmbbQ77SO1pSFCcJlsVMeCk8qZsjhKfGKuT/jIA+ipOJMVs/+pqUfObBWNw==", + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-arm64/-/win32-arm64-7.0.2001.tgz", + "integrity": "sha512-uJZhqB6pdXLuN+AD1F5082byyQti/NPmJA77GtcFlmT2HzRelqbNls3SaIqxpjdFgvSBF9g0yOKGBkGFg7kX8Q==", "cpu": [ "arm64" ], @@ -1063,9 +1063,9 @@ ] }, "node_modules/@oxlint-tsgolint/win32-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-x64/-/win32-x64-0.23.0.tgz", - "integrity": "sha512-5MyjFuqf+g8OUPJBSGWHJtmoWnzFJYyOg4To9WMQshZYEWig/vtu7JtJ03VWnzHv9LJkAUeApY0gVCOywFR/iQ==", + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-x64/-/win32-x64-7.0.2001.tgz", + "integrity": "sha512-FkDRm8hx9OwzGQqyWG1tO5QrTLRApff9DzSgpz9QZau37BR8d1VYKOxMLGf6shPZntJFoTwIIJYT68VndYDCog==", "cpu": [ "x64" ], @@ -1077,9 +1077,9 @@ ] }, "node_modules/@oxlint/binding-android-arm-eabi": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.71.0.tgz", - "integrity": "sha512-ImGmd1njEg4FEJH03jhRnveEegtO3czCtfptvaHivKAZQIYATbVFBrrzbaYMYv0oJioTnxZAZVSyV+oL7W8S2g==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.75.0.tgz", + "integrity": "sha512-lutovtFzJqlRaqpZrCqSSGaHZzl9nIxxpjLzhSRLunN6dCLylj0uzlCyQGaQDIys7rrv8kVXiFO+R4Zpn0bX7g==", "cpu": [ "arm" ], @@ -1094,9 +1094,9 @@ } }, "node_modules/@oxlint/binding-android-arm64": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.71.0.tgz", - "integrity": "sha512-4A5BEexBrwY1YFF8Kiq/lp/wQPRG79G3BWIE1FuWaM5MvmpYSd+7ZySVcKkHdwo0UDzdQGddp6pD9mpctMqLnw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.75.0.tgz", + "integrity": "sha512-hXI0hDgHkw4w5nfru72aG7y+2iQJmC4waH/KV6H/hbgA6yAP5jYNx0P9yug15Hs0tWl/+mda3Jjn/2gmDT48tw==", "cpu": [ "arm64" ], @@ -1111,9 +1111,9 @@ } }, "node_modules/@oxlint/binding-darwin-arm64": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.71.0.tgz", - "integrity": "sha512-9wJA9GJulLwS2usU3CEisI/ESDO1n1z9eyTCvApMDrAkbJ1ve0mORgTMjcWWsKxkzkeZ2N/Gpra5IQE7x8tYgQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.75.0.tgz", + "integrity": "sha512-D91BWbK/dMYfCcrghspPIuKs2D9LF4Z/OabVSQjw1AO6PWxArD7teDA48bm0ySFqWDaPVqmQRl5GMWNglTXyrQ==", "cpu": [ "arm64" ], @@ -1128,9 +1128,9 @@ } }, "node_modules/@oxlint/binding-darwin-x64": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.71.0.tgz", - "integrity": "sha512-PlLCjS06V0PeJMAJwzjrExw1sYNW9Gch3JtNlcwwZDXGlTYDuwHNN89zYH8LTXFfgkVtsYvs2nv0FqrzyuFDzg==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.75.0.tgz", + "integrity": "sha512-02mpwzf12BonZ6PT0TuQoomvEh2kVl2WGBIKWezCyToIS+rYkQZ6GXnARBAl9A4Ovm2V+Xe7M4KretyqmmcnJQ==", "cpu": [ "x64" ], @@ -1145,9 +1145,9 @@ } }, "node_modules/@oxlint/binding-freebsd-x64": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.71.0.tgz", - "integrity": "sha512-Lhil7bWre0ncxbUoDoxfS0JzpTz17BRQKW7iwoAUY8GJ66+WwJEfYPCFJ1P0WgVZR5/O/b3Q2pENlHOjeXLOGQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.75.0.tgz", + "integrity": "sha512-qZJgLnDaBsiL5YESx2t/TZ8eXkL9fEkKoXEdzegROhlz9A0lgyGnZ0dAzJrh7LJAHQl2K9RdRueN2s/9N7+odg==", "cpu": [ "x64" ], @@ -1162,9 +1162,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-gnueabihf": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.71.0.tgz", - "integrity": "sha512-Oo9/L58PYD3RC0x05d2upAPLllHytTjHQGsnC06P6Ynn7jKkp5mdImQxXdJ3+FnBaKspNpGogzgVsi6g872LiA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.75.0.tgz", + "integrity": "sha512-7XlaWA5BJD3XpCfrEqjEe6Zseeb14S7QGa304XfwKignRaKQ+eIj775BQ7nIslggWickl4IsPUFqJ+/gAyNHVg==", "cpu": [ "arm" ], @@ -1179,9 +1179,9 @@ } }, "node_modules/@oxlint/binding-linux-arm-musleabihf": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.71.0.tgz", - "integrity": "sha512-mSHfyfgJrEbyIR29ejaeS50BdPk+GoNPlC1dckpDiUZbJAIel68sjSMdOt4WY0/gva+ECC7FNITQkxMJU+vSBw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.75.0.tgz", + "integrity": "sha512-av6Tpv8yrcMMMOadOqENBhlsLRcGFXXwoQ0hzHhsmS9FJ4Wioy8we427GbcMe2XTxmL2e60T67H1Dyr3up+tAA==", "cpu": [ "arm" ], @@ -1196,9 +1196,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-gnu": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.71.0.tgz", - "integrity": "sha512-n9yY4M2tiy3aij4AqtlnspzpfdpeT5JQfK2/w2d8oyp5W0FRwOb1dIeX99nORNcxGr08iD9bH8N5XFz3I2iy8w==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.75.0.tgz", + "integrity": "sha512-WcUhd8fHT5plrA14lANevl+hOl815mVI5t2hU21oFWrZKFXIVV/Sr4rWQV0NzSvzBupbMLNc5ErEA6Ehxh5jMg==", "cpu": [ "arm64" ], @@ -1216,9 +1216,9 @@ } }, "node_modules/@oxlint/binding-linux-arm64-musl": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.71.0.tgz", - "integrity": "sha512-fJZrs5sDZtTaPIOiemRQQmo82Ezy+vOGXemPc4Ok7iVVsYsFa7SlW6Z5XN819VfsqBHRm3NJ3rTdnR8+bJYJdQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.75.0.tgz", + "integrity": "sha512-UWzp5wRHFe/ESO3+eEaxXsTkYTGLYjnTsi/I5neEacXSItQ6WNleapfOAeA4x2b8nyhJ4uQxqvtv9pHv8kWJtQ==", "cpu": [ "arm64" ], @@ -1236,9 +1236,9 @@ } }, "node_modules/@oxlint/binding-linux-ppc64-gnu": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.71.0.tgz", - "integrity": "sha512-cwl7VKGERIy9p+G+AvZdfy/06q0aHXaTt/mMRReC751iuNYJgqKjB7NydXSS30nBT9vtr2tunciOtrR4fD6FUA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.75.0.tgz", + "integrity": "sha512-XEVRwGMLKCUKrvhLAz4F6AIh8MJrQVdSZtAmPpRZt9tGPsUnamPOcl3dS/ZQzJnar/Ymgc//+xho0L60Emzuxg==", "cpu": [ "ppc64" ], @@ -1256,9 +1256,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-gnu": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.71.0.tgz", - "integrity": "sha512-eZ8ieVXvzGi8jr7+ybQGPK2STw3mldfxZlgA2738iflfB/rzA69sE6m5rDRpQaxC7dpm745Enlh1Tod0QAk9Gg==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.75.0.tgz", + "integrity": "sha512-mAG4DUXqfLC8cTjMD2kt3jDmVzFREYtDyeLNdLdsCcBc4Zbl2EMuiFektGBilQwkNjYnMvCqJs55U+Hyb+b+jw==", "cpu": [ "riscv64" ], @@ -1276,9 +1276,9 @@ } }, "node_modules/@oxlint/binding-linux-riscv64-musl": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.71.0.tgz", - "integrity": "sha512-puMDbQYe6+NXwfMusojoA7CXGn2b3utukmd23PQqc1E3XhVCwyZ+FueSMzDYeNgDV2dUfIVXAAKZBcFDeCL6sA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.75.0.tgz", + "integrity": "sha512-95hrAvriAlI+pekSomTFIn0+bawMDlDwTNVmdjsFusTHyL2JWh7TWvRNG/Lkim72uN8OiCcO9wcaC6omLP5E3w==", "cpu": [ "riscv64" ], @@ -1296,9 +1296,9 @@ } }, "node_modules/@oxlint/binding-linux-s390x-gnu": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.71.0.tgz", - "integrity": "sha512-4NJLxBs1ujISCt3L/1FcywLs73PWtJuw+piD6feK2V6h6OS6P7xu9/sWt1DTRLibe6QCzmfZzmM/2HPORoV/Lg==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.75.0.tgz", + "integrity": "sha512-4b6f2+FrtruAESrCqIKcrarzfrSx+wk2QNcp+RT91/Prc+pMQMAfyZ1rG1c3tFQNl8Bc616tx40uNXyxNBRPbQ==", "cpu": [ "s390x" ], @@ -1316,9 +1316,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-gnu": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.71.0.tgz", - "integrity": "sha512-cFDaiR8L3430qp88tfZnvFlt3KotFhR/DlbIL0nHOMMYiG/9Wy4l+6f7t8G8pTa9bd8Lt8+M0y/qjRQ/xcB74g==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.75.0.tgz", + "integrity": "sha512-nshAhrUvXFUWOvqQ2soIw7HFNWvpvEV4o0cYSqPtzLiPF5gKyYTDOOTJ6Rn8g8K/iGvPIrbDA4v8+5MvnjJrrg==", "cpu": [ "x64" ], @@ -1336,9 +1336,9 @@ } }, "node_modules/@oxlint/binding-linux-x64-musl": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.71.0.tgz", - "integrity": "sha512-orfixdt76KlpNly9z0PkWBBNfwjKz+JFVLP/7wnVchlKNU9Dpt9InU/ZggeSej6fC7qwHmHNOGlhLnQXcYoGuA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.75.0.tgz", + "integrity": "sha512-e4jNxLKnxLC6sYBQRxrI2pgIIxnmMtF8U/VwNYcjTT/CLS+spH624cYVnj07bTKwaEWT37/e025isOs6j/0xqA==", "cpu": [ "x64" ], @@ -1356,9 +1356,9 @@ } }, "node_modules/@oxlint/binding-openharmony-arm64": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.71.0.tgz", - "integrity": "sha512-9emQu2lAp6yhPB3XuI+++vR+l/o6JR1X+EpxwcumPdQXBWXEPAsquPGL7l158EqU8SebQMXTUa/S5zN98juyHw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.75.0.tgz", + "integrity": "sha512-hZ2lH+1qLf/DiEP9UWuQTK2JWj/BgvMB4jhIV4SmNU1wfEiYYX4TynQyAZXx0j9X4qRYizAL042SKaV+8ynh4w==", "cpu": [ "arm64" ], @@ -1373,9 +1373,9 @@ } }, "node_modules/@oxlint/binding-win32-arm64-msvc": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.71.0.tgz", - "integrity": "sha512-bd5kI8spYwTm3BILDtGhi73zoup5dw8MlPQNT8YB3BD5UIsjNe3K9/4ctrzQMX4SZMoK5HgzVLkLJzacEXB7fA==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.75.0.tgz", + "integrity": "sha512-Ilj6PNzGDS3bCU0MSJH7Msh0NhH+T/mRp2shwg+q+GHeVlPwP5LEboW96aW+3kVKFk6zYZy1Xi5pZkqZh6X8KQ==", "cpu": [ "arm64" ], @@ -1390,9 +1390,9 @@ } }, "node_modules/@oxlint/binding-win32-ia32-msvc": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.71.0.tgz", - "integrity": "sha512-W4HvOHGzVLHcrmFu+bMrJlho+/yrlX5ZNdJZqGe8MEldkQG+RHYhxxad9P4jvWAYFmIqUA5i9DQ8QsJqSU9GIw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.75.0.tgz", + "integrity": "sha512-QVit2nOEOiPhkmsrksPSkoGCdnZRNkspt8fwoYyP09te1VEbnSj4LAxua4rc8FKTmWkySVe05j8iz9GXYfF1AQ==", "cpu": [ "ia32" ], @@ -1407,9 +1407,9 @@ } }, "node_modules/@oxlint/binding-win32-x64-msvc": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.71.0.tgz", - "integrity": "sha512-D2kyEIPHk/G/wiZLnwTVC/sVst+T/lKldVOjAFpgTIBUAOlry72e5OiapDbDBF4LfJLkN5ypJb/8Eu6yJzkveQ==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.75.0.tgz", + "integrity": "sha512-DSxnNkBUAYARPwJtR12Ig3deWr8w0H997xP6jy33i+e0SyYJw8FKuz4+cZtpmPEhQmvlPJE3X/2vNxDmLkd/rA==", "cpu": [ "x64" ], @@ -1551,16 +1551,16 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/braces": { @@ -1577,14 +1577,14 @@ } }, "node_modules/cacheable": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.5.tgz", - "integrity": "sha512-EQfaKe09tl615iNvq/TBRWTFf1AKJNXYQSsMx0Z3EI0nA+pVsVPS8wJhnRlkbdacKPh1d0qVIhwTc2zsQNFEEg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/memory": "^2.0.8", - "@cacheable/utils": "^2.4.1", + "@cacheable/memory": "^2.2.0", + "@cacheable/utils": "^2.5.0", "hookified": "^1.15.0", "keyv": "^5.6.0", "qified": "^0.10.1" @@ -1745,9 +1745,9 @@ } }, "node_modules/cosmiconfig": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", - "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz", + "integrity": "sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==", "dev": true, "license": "MIT", "dependencies": { @@ -1771,99 +1771,6 @@ } } }, - "node_modules/cpd-darwin-arm64": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cpd-darwin-arm64/-/cpd-darwin-arm64-5.0.10.tgz", - "integrity": "sha512-5udYnaOTVLwZGPIvvxMPsGtW+6t0OOzoJEG566ct1VV83i2KhMtxHoo+3xtMQwzwqW+wmSPCRAac+khRd4qVyA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/cpd-darwin-x64": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cpd-darwin-x64/-/cpd-darwin-x64-5.0.10.tgz", - "integrity": "sha512-0gbyaY0uAVVzzA+iEub45fCWnJvplfQW5NdLXndZ+fM+mkvvhvjdfLvU6P54oc3X/Cw0W+SgkjHYlUG3VWgGZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/cpd-linux-arm64-gnu": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cpd-linux-arm64-gnu/-/cpd-linux-arm64-gnu-5.0.10.tgz", - "integrity": "sha512-x9IfdmUn/5CRfqjTpSlEK+pCpmkWt+IzkCCaWvnZyDe6G+gI6/8bT9MKbDMzU9FvYy2QA62j68TmHcahHXxRtQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/cpd-linux-x64-gnu": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cpd-linux-x64-gnu/-/cpd-linux-x64-gnu-5.0.10.tgz", - "integrity": "sha512-d+JCgfelOY+Pnd2NRnysS1TARd0toh+12rCAOiG5jqN/9ZCB9bdpsbY0YphLMmBX28CPlo4vWXxcfN391vVIyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/cpd-linux-x64-musl": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cpd-linux-x64-musl/-/cpd-linux-x64-musl-5.0.10.tgz", - "integrity": "sha512-kiDIAT3kjGa6OjmQMEJwqea0Zxyj1szYZDFDa8fp9tpT8R7kebvdoH6t3R5mjDKG4DWU0XQb1kxDLOX5MY/sGg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/cpd-windows-x64-msvc": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cpd-windows-x64-msvc/-/cpd-windows-x64-msvc-5.0.10.tgz", - "integrity": "sha512-eXnyqEBpnKcTOMTh58VxqGjLrlSglJwI5dVaCbk7aaE4yKbBjL6vgXFk5kaMnjZfgg4/kEFxI+8UjMoD8xONcw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/cross-env": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", @@ -2105,9 +2012,9 @@ } }, "node_modules/eslint": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.5.0.tgz", - "integrity": "sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==", + "version": "10.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.8.0.tgz", + "integrity": "sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==", "dev": true, "license": "MIT", "workspaces": [ @@ -2117,7 +2024,7 @@ "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.6.0", + "@eslint/config-helpers": "^0.7.0", "@eslint/core": "^1.2.1", "@eslint/plugin-kit": "^0.7.2", "@humanfs/node": "^0.16.6", @@ -2141,7 +2048,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.4", + "minimatch": "^10.2.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -2289,9 +2196,9 @@ } }, "node_modules/fallow": { - "version": "2.102.0", - "resolved": "https://registry.npmjs.org/fallow/-/fallow-2.102.0.tgz", - "integrity": "sha512-bkOT58kPVCB12d2apQjIKBw/qSdsGRPQFrN5ff9Yl5WzXRqlDTbT/MVdMXld4sJD5JQW1ftw2bTxJWCINggh6g==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/fallow/-/fallow-3.6.0.tgz", + "integrity": "sha512-CpoOw4Fs35NgF/Md+OTZE9PrsReQp3mbBEqDDd6HATh1gflXAQfDJOk3M8xA0cnIZIfXXAu5fwojxwTXn9S2MA==", "dev": true, "license": "MIT", "dependencies": { @@ -2303,17 +2210,17 @@ "fallow-mcp": "bin/fallow-mcp" }, "engines": { - "node": ">=16" + "node": ">=22" }, "optionalDependencies": { - "@fallow-cli/darwin-arm64": "2.102.0", - "@fallow-cli/darwin-x64": "2.102.0", - "@fallow-cli/linux-arm64-gnu": "2.102.0", - "@fallow-cli/linux-arm64-musl": "2.102.0", - "@fallow-cli/linux-x64-gnu": "2.102.0", - "@fallow-cli/linux-x64-musl": "2.102.0", - "@fallow-cli/win32-arm64-msvc": "2.102.0", - "@fallow-cli/win32-x64-msvc": "2.102.0" + "@fallow-cli/darwin-arm64": "3.6.0", + "@fallow-cli/darwin-x64": "3.6.0", + "@fallow-cli/linux-arm64-gnu": "3.6.0", + "@fallow-cli/linux-arm64-musl": "3.6.0", + "@fallow-cli/linux-x64-gnu": "3.6.0", + "@fallow-cli/linux-x64-musl": "3.6.0", + "@fallow-cli/win32-arm64-msvc": "3.6.0", + "@fallow-cli/win32-x64-msvc": "3.6.0" } }, "node_modules/fast-deep-equal": { @@ -2368,9 +2275,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", - "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", "dev": true, "funding": [ { @@ -2546,9 +2453,9 @@ } }, "node_modules/globby": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.0.tgz", - "integrity": "sha512-QrJia2qDf5BB/V6HYlDTs0I0lBahyjLzpGQg3KT7FnCdTonAyPy2RtY802m2k4ALx6Dp752f82WsOczEVr3l6Q==", + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.2.tgz", + "integrity": "sha512-NLvV9ubZ6NDsJaOpKPy3cQeJpKi9DcWiyCiFUpJPA0YihRqiE6RWaLUmgNNPr8MgPpLZjnBjSmou7uZBRJv9wA==", "dev": true, "license": "MIT", "dependencies": { @@ -2567,9 +2474,9 @@ } }, "node_modules/globby/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", "dev": true, "license": "MIT", "engines": { @@ -2583,6 +2490,19 @@ "dev": true, "license": "MIT" }, + "node_modules/has-flag": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/hashery": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", @@ -2808,26 +2728,118 @@ } }, "node_modules/jscpd": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/jscpd/-/jscpd-5.0.10.tgz", - "integrity": "sha512-ieidqRmKGasve4k9YUftQRJZ2jxm6EbK6mvHSNL1sFDAnrukX7Qs4Ce+i3tUUqu3Vgd9WOhvanKpdoPG/IuZ+g==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/jscpd/-/jscpd-5.0.12.tgz", + "integrity": "sha512-87dC+akj2mCywlt8p3xnRlDg0B55u4GDbfE9cuwOOeIxbEuWuIoNqGoYi65A0516aJ4EzAjGwBj1Qb/Ahc8WAQ==", "dev": true, "license": "MIT", "bin": { - "cpd": "run-jscpd.js", "jscpd": "run-jscpd.js" }, "engines": { "node": ">=18" }, "optionalDependencies": { - "cpd-darwin-arm64": "5.0.10", - "cpd-darwin-x64": "5.0.10", - "cpd-linux-arm64-gnu": "5.0.10", - "cpd-linux-x64-gnu": "5.0.10", - "cpd-linux-x64-musl": "5.0.10", - "cpd-windows-x64-msvc": "5.0.10" - } + "jscpd-darwin-arm64": "5.0.12", + "jscpd-darwin-x64": "5.0.12", + "jscpd-linux-arm64-gnu": "5.0.12", + "jscpd-linux-x64-gnu": "5.0.12", + "jscpd-linux-x64-musl": "5.0.12", + "jscpd-windows-x64-msvc": "5.0.12" + } + }, + "node_modules/jscpd-darwin-arm64": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/jscpd-darwin-arm64/-/jscpd-darwin-arm64-5.0.12.tgz", + "integrity": "sha512-CQCDYhQY9yOGGeauzkRGYW/QtXurPCjfDkEhUoM/M5UdmpzxfG3i9mnNsaheJ0RdFRf73mL7JaLVRP8U2l5/kA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/jscpd-darwin-x64": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/jscpd-darwin-x64/-/jscpd-darwin-x64-5.0.12.tgz", + "integrity": "sha512-7XNCDfChP9fPkIWLepd0zGnTov7/5mR7rJ5Utc1MdWFdgkN//qz6FAJ1FhQA0E/qjFedy9XTucfUCgLybSBsjw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/jscpd-linux-arm64-gnu": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/jscpd-linux-arm64-gnu/-/jscpd-linux-arm64-gnu-5.0.12.tgz", + "integrity": "sha512-i/usHD0/8twzb2Qo4vFWcnuAD4IDLS6K/mTXwYy1CiJZDw4gmjfH45jtjdKUyoutTAiNs+ZWZgx1gIRljUbFuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/jscpd-linux-x64-gnu": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/jscpd-linux-x64-gnu/-/jscpd-linux-x64-gnu-5.0.12.tgz", + "integrity": "sha512-TqaeSTaGawcqyXSrQvYJFtLRn4aQeHgphGGsq2ZtVAg+lPeuMmh81c3bl0yi2dL3gDX1RGBQKBVul1XQknOuoA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/jscpd-linux-x64-musl": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/jscpd-linux-x64-musl/-/jscpd-linux-x64-musl-5.0.12.tgz", + "integrity": "sha512-WelugY1/rdoo0Y0sqJ2XQOIvyIZTfRe+vP3MJe4XvEUwPF0v+9SQoS34FnfblRhsddVixyNkgl7x/sHid9UMJw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/jscpd-windows-x64-msvc": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/jscpd-windows-x64-msvc/-/jscpd-windows-x64-msvc-5.0.12.tgz", + "integrity": "sha512-01x1klKjvfzI6Of5tI9u72x7TIQZQLLG6kMdsEPJKl/BXbskdknrfCepeTXRBbdFPKs25jfcd0klZ4OdDvww5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, "node_modules/json-buffer": { "version": "3.0.1", @@ -2977,13 +2989,13 @@ } }, "node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.5" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -3054,9 +3066,9 @@ } }, "node_modules/oxfmt": { - "version": "0.56.0", - "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.56.0.tgz", - "integrity": "sha512-9Dv0wV3zKiyvhjD7bRKaInKmHQ1sPx3RGOjQkGFJbbdQ16576yf8qhMSO9Q9cvHcs+1NpBsRTkuDDYFFPTJ6gw==", + "version": "0.60.0", + "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.60.0.tgz", + "integrity": "sha512-fViX6i+gJuZWY+jI/fnR6WRbRj70GZ9RlCd30MygJrHTUNc4DxvKHWw8vBjMjffv3PgU5qWDR0AzmojQByqaZA==", "dev": true, "license": "MIT", "dependencies": { @@ -3072,25 +3084,25 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxfmt/binding-android-arm-eabi": "0.56.0", - "@oxfmt/binding-android-arm64": "0.56.0", - "@oxfmt/binding-darwin-arm64": "0.56.0", - "@oxfmt/binding-darwin-x64": "0.56.0", - "@oxfmt/binding-freebsd-x64": "0.56.0", - "@oxfmt/binding-linux-arm-gnueabihf": "0.56.0", - "@oxfmt/binding-linux-arm-musleabihf": "0.56.0", - "@oxfmt/binding-linux-arm64-gnu": "0.56.0", - "@oxfmt/binding-linux-arm64-musl": "0.56.0", - "@oxfmt/binding-linux-ppc64-gnu": "0.56.0", - "@oxfmt/binding-linux-riscv64-gnu": "0.56.0", - "@oxfmt/binding-linux-riscv64-musl": "0.56.0", - "@oxfmt/binding-linux-s390x-gnu": "0.56.0", - "@oxfmt/binding-linux-x64-gnu": "0.56.0", - "@oxfmt/binding-linux-x64-musl": "0.56.0", - "@oxfmt/binding-openharmony-arm64": "0.56.0", - "@oxfmt/binding-win32-arm64-msvc": "0.56.0", - "@oxfmt/binding-win32-ia32-msvc": "0.56.0", - "@oxfmt/binding-win32-x64-msvc": "0.56.0" + "@oxfmt/binding-android-arm-eabi": "0.60.0", + "@oxfmt/binding-android-arm64": "0.60.0", + "@oxfmt/binding-darwin-arm64": "0.60.0", + "@oxfmt/binding-darwin-x64": "0.60.0", + "@oxfmt/binding-freebsd-x64": "0.60.0", + "@oxfmt/binding-linux-arm-gnueabihf": "0.60.0", + "@oxfmt/binding-linux-arm-musleabihf": "0.60.0", + "@oxfmt/binding-linux-arm64-gnu": "0.60.0", + "@oxfmt/binding-linux-arm64-musl": "0.60.0", + "@oxfmt/binding-linux-ppc64-gnu": "0.60.0", + "@oxfmt/binding-linux-riscv64-gnu": "0.60.0", + "@oxfmt/binding-linux-riscv64-musl": "0.60.0", + "@oxfmt/binding-linux-s390x-gnu": "0.60.0", + "@oxfmt/binding-linux-x64-gnu": "0.60.0", + "@oxfmt/binding-linux-x64-musl": "0.60.0", + "@oxfmt/binding-openharmony-arm64": "0.60.0", + "@oxfmt/binding-win32-arm64-msvc": "0.60.0", + "@oxfmt/binding-win32-ia32-msvc": "0.60.0", + "@oxfmt/binding-win32-x64-msvc": "0.60.0" }, "peerDependencies": { "svelte": "^5.0.0", @@ -3106,9 +3118,9 @@ } }, "node_modules/oxlint": { - "version": "1.71.0", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.71.0.tgz", - "integrity": "sha512-U1m1X+C0vDj7DC1e13IoZULzEcPczE7UOMTs8VlZGHUEIUaSTZKo5qkPsQEfzpgnQ29Pea/w3Xntk62UCecxZw==", + "version": "1.75.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.75.0.tgz", + "integrity": "sha512-m9WzjRcRYA/uqIZDa9tclrieoPJ/ln1QYTKdFx6NUOs8uY5DiHlIwRQoCrHT6OM6O3ww3l2skY5gO7G7ZphE7g==", "dev": true, "license": "MIT", "bin": { @@ -3121,28 +3133,28 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxlint/binding-android-arm-eabi": "1.71.0", - "@oxlint/binding-android-arm64": "1.71.0", - "@oxlint/binding-darwin-arm64": "1.71.0", - "@oxlint/binding-darwin-x64": "1.71.0", - "@oxlint/binding-freebsd-x64": "1.71.0", - "@oxlint/binding-linux-arm-gnueabihf": "1.71.0", - "@oxlint/binding-linux-arm-musleabihf": "1.71.0", - "@oxlint/binding-linux-arm64-gnu": "1.71.0", - "@oxlint/binding-linux-arm64-musl": "1.71.0", - "@oxlint/binding-linux-ppc64-gnu": "1.71.0", - "@oxlint/binding-linux-riscv64-gnu": "1.71.0", - "@oxlint/binding-linux-riscv64-musl": "1.71.0", - "@oxlint/binding-linux-s390x-gnu": "1.71.0", - "@oxlint/binding-linux-x64-gnu": "1.71.0", - "@oxlint/binding-linux-x64-musl": "1.71.0", - "@oxlint/binding-openharmony-arm64": "1.71.0", - "@oxlint/binding-win32-arm64-msvc": "1.71.0", - "@oxlint/binding-win32-ia32-msvc": "1.71.0", - "@oxlint/binding-win32-x64-msvc": "1.71.0" + "@oxlint/binding-android-arm-eabi": "1.75.0", + "@oxlint/binding-android-arm64": "1.75.0", + "@oxlint/binding-darwin-arm64": "1.75.0", + "@oxlint/binding-darwin-x64": "1.75.0", + "@oxlint/binding-freebsd-x64": "1.75.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.75.0", + "@oxlint/binding-linux-arm-musleabihf": "1.75.0", + "@oxlint/binding-linux-arm64-gnu": "1.75.0", + "@oxlint/binding-linux-arm64-musl": "1.75.0", + "@oxlint/binding-linux-ppc64-gnu": "1.75.0", + "@oxlint/binding-linux-riscv64-gnu": "1.75.0", + "@oxlint/binding-linux-riscv64-musl": "1.75.0", + "@oxlint/binding-linux-s390x-gnu": "1.75.0", + "@oxlint/binding-linux-x64-gnu": "1.75.0", + "@oxlint/binding-linux-x64-musl": "1.75.0", + "@oxlint/binding-openharmony-arm64": "1.75.0", + "@oxlint/binding-win32-arm64-msvc": "1.75.0", + "@oxlint/binding-win32-ia32-msvc": "1.75.0", + "@oxlint/binding-win32-x64-msvc": "1.75.0" }, "peerDependencies": { - "oxlint-tsgolint": ">=0.22.1", + "oxlint-tsgolint": ">=7.0.2001", "vite-plus": "*" }, "peerDependenciesMeta": { @@ -3155,21 +3167,21 @@ } }, "node_modules/oxlint-tsgolint": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/oxlint-tsgolint/-/oxlint-tsgolint-0.23.0.tgz", - "integrity": "sha512-3mBv3CoPbh8dFbzfDGIWa2ytZjn2v+3EX4aKRXjIhsoGFzG8GCjfRirz3rwZf1wYbZzsNLTSgpw8VjQuWdp/jA==", + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/oxlint-tsgolint/-/oxlint-tsgolint-7.0.2001.tgz", + "integrity": "sha512-KjK/XLcXr1DSyonKhsuFqJRiuKqcyG9j3LJ8nkOsrLzGvodBPqzHOKauy10asLMDI0sUpvb+1sxlzff3udZvfg==", "dev": true, "license": "MIT", "bin": { "tsgolint": "bin/tsgolint.js" }, "optionalDependencies": { - "@oxlint-tsgolint/darwin-arm64": "0.23.0", - "@oxlint-tsgolint/darwin-x64": "0.23.0", - "@oxlint-tsgolint/linux-arm64": "0.23.0", - "@oxlint-tsgolint/linux-x64": "0.23.0", - "@oxlint-tsgolint/win32-arm64": "0.23.0", - "@oxlint-tsgolint/win32-x64": "0.23.0" + "@oxlint-tsgolint/darwin-arm64": "7.0.2001", + "@oxlint-tsgolint/darwin-x64": "7.0.2001", + "@oxlint-tsgolint/linux-arm64": "7.0.2001", + "@oxlint-tsgolint/linux-x64": "7.0.2001", + "@oxlint-tsgolint/win32-arm64": "7.0.2001", + "@oxlint-tsgolint/win32-x64": "7.0.2001" } }, "node_modules/p-limit": { @@ -3379,9 +3391,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", "dev": true, "license": "MIT", "dependencies": { @@ -3664,9 +3676,9 @@ } }, "node_modules/stylelint": { - "version": "17.13.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.13.0.tgz", - "integrity": "sha512-G1WYzMerp7ihOaIe9VJCHLt12MoAD2QLf1AFerYP37+BCRBUK5UCpq8e/mN+zCIaJPKQcaxhE4WlPmqdiOx/gw==", + "version": "17.14.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.14.1.tgz", + "integrity": "sha512-xVQwyiuxALUBNB2fBe0tmNemg9KqLtdj3T64mioFDar79B2cU8LIyz+3KL6LdiHs9NkeNfwxpKSaIVOY8f112g==", "dev": true, "funding": [ { @@ -3682,21 +3694,21 @@ "dependencies": { "@csstools/css-calc": "^3.2.1", "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-syntax-patches-for-csstree": "^1.1.4", + "@csstools/css-syntax-patches-for-csstree": "^1.1.6", "@csstools/css-tokenizer": "^4.0.0", "@csstools/media-query-list-parser": "^5.0.0", "@csstools/selector-resolve-nested": "^4.0.0", "@csstools/selector-specificity": "^6.0.0", "colord": "^2.9.3", - "cosmiconfig": "^9.0.1", + "cosmiconfig": "^9.0.2", "css-functions-list": "^3.3.3", "css-tree": "^3.2.1", "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^11.1.3", + "file-entry-cache": "^11.1.5", "global-modules": "^2.0.0", - "globby": "^16.2.0", + "globby": "^16.2.1", "globjoin": "^0.1.4", "html-tags": "^5.1.0", "ignore": "^7.0.5", @@ -3706,12 +3718,12 @@ "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", - "postcss": "^8.5.15", + "postcss": "^8.5.16", "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.1.1", + "postcss-selector-parser": "^7.1.4", "postcss-value-parser": "^4.2.0", "string-width": "^8.2.1", - "supports-hyperlinks": "^4.4.0", + "supports-hyperlinks": "^4.5.0", "svg-tags": "^1.0.0", "table": "^6.9.0", "write-file-atomic": "^7.0.1" @@ -3786,23 +3798,23 @@ } }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.3.tgz", - "integrity": "sha512-oMbq0PD6VIiIwMF6LIa7MEwd/l9huKwmqRKXqmrkqIZv8CvRbfowL+L0ryAl8h//HfAS0zS+4SbYoRyAoA6BJA==", + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz", + "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^6.1.22" + "flat-cache": "^6.1.23" } }, "node_modules/stylelint/node_modules/flat-cache": { - "version": "6.1.22", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.22.tgz", - "integrity": "sha512-N2dnzVJIphnNsjHcrxGW7DePckJ6haPrSFqpsBUhHYgwtKGVq4JrBGielEGD2fCVnsGm1zlBVZ8wGhkyuetgug==", + "version": "6.1.23", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz", + "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==", "dev": true, "license": "MIT", "dependencies": { - "cacheable": "^2.3.4", + "cacheable": "^2.5.0", "flatted": "^3.4.2", "hookified": "^1.15.0" } @@ -3891,9 +3903,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.4.0.tgz", - "integrity": "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.5.0.tgz", + "integrity": "sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==", "dev": true, "license": "MIT", "dependencies": { @@ -3907,19 +3919,6 @@ "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", - "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", diff --git a/package.json b/package.json index 8cc4c8e55..c312d3b08 100644 --- a/package.json +++ b/package.json @@ -39,21 +39,21 @@ "verify:build": "node scripts/verify-build.js" }, "devDependencies": { - "@double-great/stylelint-a11y": "^3.4.15", + "@double-great/stylelint-a11y": "^3.5.0", "@eslint/js": "^10.0.0", "concurrently": "^10.0.4", "cross-env": "^10.0.0", - "eslint": "^10.5.0", + "eslint": "^10.8.0", "eslint-plugin-html": "^8.1.4", "eslint-plugin-security": "^4.0.1", - "fallow": "^2.102.0", + "fallow": "^3.6.0", "husky": "^9.1.7", - "jscpd": "^5.0.10", - "oxfmt": "^0.56.0", - "oxlint": "^1.71.0", - "oxlint-tsgolint": "^0.23.0", + "jscpd": "^5.0.12", + "oxfmt": "^0.60.0", + "oxlint": "^1.75.0", + "oxlint-tsgolint": "^7.0.2001", "postcss-html": "^1.8.0", - "stylelint": "^17.13.0", + "stylelint": "^17.14.1", "stylelint-config-standard": "^40.0.0", "yauzl": "^3.4.0" },