refactor: move from biome to oxlint/oxformat (#311)
* chore: install and configure oxlint
* chore: fix liniting issues
* chore: install and configure oxfmt
* ci: add oxlint action instead of biome
* chore: pr feedbacks
* Revert "chore: pr feedbacks"
This reverts commit 525dcd8d9f.
This commit is contained in:
parent
7f71767ce7
commit
1391d6fe5e
40 changed files with 294 additions and 146 deletions
7
.github/workflows/checks.yml
vendored
7
.github/workflows/checks.yml
vendored
|
|
@ -25,9 +25,10 @@ jobs:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
uses: "./.github/actions/install-dependencies"
|
uses: "./.github/actions/install-dependencies"
|
||||||
|
|
||||||
- name: Run lint
|
- uses: oxc-project/oxlint-action@latest
|
||||||
shell: bash
|
with:
|
||||||
run: bun run lint:ci
|
config: .oxlintrc.json
|
||||||
|
deny-warnings: true
|
||||||
|
|
||||||
- name: Run type checks
|
- name: Run type checks
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
|
||||||
5
.oxfmtrc.json
Normal file
5
.oxfmtrc.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
||||||
|
"printWidth": 120,
|
||||||
|
"useTabs": true
|
||||||
|
}
|
||||||
150
.oxlintrc.json
Normal file
150
.oxlintrc.json
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
{
|
||||||
|
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||||
|
"plugins": ["unicorn", "typescript", "oxc"],
|
||||||
|
"categories": {},
|
||||||
|
"rules": {
|
||||||
|
"constructor-super": "warn",
|
||||||
|
"for-direction": "warn",
|
||||||
|
"no-async-promise-executor": "warn",
|
||||||
|
"no-caller": "warn",
|
||||||
|
"no-class-assign": "warn",
|
||||||
|
"no-compare-neg-zero": "warn",
|
||||||
|
"no-cond-assign": "warn",
|
||||||
|
"no-const-assign": "warn",
|
||||||
|
"no-constant-binary-expression": "warn",
|
||||||
|
"no-constant-condition": "warn",
|
||||||
|
"no-control-regex": "warn",
|
||||||
|
"no-debugger": "warn",
|
||||||
|
"no-delete-var": "warn",
|
||||||
|
"no-dupe-class-members": "warn",
|
||||||
|
"no-dupe-else-if": "warn",
|
||||||
|
"no-dupe-keys": "warn",
|
||||||
|
"no-duplicate-case": "warn",
|
||||||
|
"no-empty-character-class": "warn",
|
||||||
|
"no-empty-pattern": "warn",
|
||||||
|
"no-empty-static-block": "warn",
|
||||||
|
"no-eval": "warn",
|
||||||
|
"no-ex-assign": "warn",
|
||||||
|
"no-extra-boolean-cast": "warn",
|
||||||
|
"no-func-assign": "warn",
|
||||||
|
"no-global-assign": "warn",
|
||||||
|
"no-import-assign": "warn",
|
||||||
|
"no-invalid-regexp": "warn",
|
||||||
|
"no-irregular-whitespace": "warn",
|
||||||
|
"no-loss-of-precision": "warn",
|
||||||
|
"no-new-native-nonconstructor": "warn",
|
||||||
|
"no-nonoctal-decimal-escape": "warn",
|
||||||
|
"no-obj-calls": "warn",
|
||||||
|
"no-self-assign": "warn",
|
||||||
|
"no-setter-return": "warn",
|
||||||
|
"no-shadow-restricted-names": "warn",
|
||||||
|
"no-sparse-arrays": "warn",
|
||||||
|
"no-this-before-super": "warn",
|
||||||
|
"no-unassigned-vars": "warn",
|
||||||
|
"no-unsafe-finally": "warn",
|
||||||
|
"no-unsafe-negation": "warn",
|
||||||
|
"no-unsafe-optional-chaining": "warn",
|
||||||
|
"no-unused-expressions": "warn",
|
||||||
|
"no-unused-labels": "warn",
|
||||||
|
"no-unused-private-class-members": "warn",
|
||||||
|
"no-unused-vars": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"caughtErrorsIgnorePattern": "^_",
|
||||||
|
"argsIgnorePattern": "^_"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-useless-backreference": "warn",
|
||||||
|
"no-useless-catch": "warn",
|
||||||
|
"no-useless-escape": "warn",
|
||||||
|
"no-useless-rename": "warn",
|
||||||
|
"no-with": "warn",
|
||||||
|
"require-yield": "warn",
|
||||||
|
"use-isnan": "warn",
|
||||||
|
"valid-typeof": "warn",
|
||||||
|
"oxc/bad-array-method-on-arguments": "warn",
|
||||||
|
"oxc/bad-char-at-comparison": "warn",
|
||||||
|
"oxc/bad-comparison-sequence": "warn",
|
||||||
|
"oxc/bad-min-max-func": "warn",
|
||||||
|
"oxc/bad-object-literal-comparison": "warn",
|
||||||
|
"oxc/bad-replace-all-arg": "warn",
|
||||||
|
"oxc/const-comparisons": "warn",
|
||||||
|
"oxc/double-comparisons": "warn",
|
||||||
|
"oxc/erasing-op": "warn",
|
||||||
|
"oxc/missing-throw": "warn",
|
||||||
|
"oxc/number-arg-out-of-range": "warn",
|
||||||
|
"oxc/only-used-in-recursion": "warn",
|
||||||
|
"oxc/uninvoked-array-callback": "warn",
|
||||||
|
"typescript/await-thenable": "warn",
|
||||||
|
"typescript/no-array-delete": "warn",
|
||||||
|
"typescript/no-base-to-string": "warn",
|
||||||
|
"typescript/no-duplicate-enum-values": "warn",
|
||||||
|
"typescript/no-duplicate-type-constituents": "warn",
|
||||||
|
"typescript/no-extra-non-null-assertion": "warn",
|
||||||
|
"typescript/no-floating-promises": "warn",
|
||||||
|
"typescript/no-for-in-array": "warn",
|
||||||
|
"typescript/no-implied-eval": "warn",
|
||||||
|
"typescript/no-meaningless-void-operator": "warn",
|
||||||
|
"typescript/no-misused-new": "warn",
|
||||||
|
"typescript/no-misused-spread": "warn",
|
||||||
|
"typescript/no-non-null-asserted-optional-chain": "warn",
|
||||||
|
"typescript/no-redundant-type-constituents": "warn",
|
||||||
|
"typescript/no-this-alias": "warn",
|
||||||
|
"typescript/no-unnecessary-parameter-property-assignment": "warn",
|
||||||
|
"typescript/no-unsafe-declaration-merging": "warn",
|
||||||
|
"typescript/no-unsafe-unary-minus": "warn",
|
||||||
|
"typescript/no-useless-empty-export": "warn",
|
||||||
|
"typescript/no-wrapper-object-types": "warn",
|
||||||
|
"typescript/prefer-as-const": "warn",
|
||||||
|
"typescript/require-array-sort-compare": "warn",
|
||||||
|
"typescript/restrict-template-expressions": "warn",
|
||||||
|
"typescript/triple-slash-reference": "warn",
|
||||||
|
"typescript/unbound-method": "warn",
|
||||||
|
"unicorn/no-await-in-promise-methods": "warn",
|
||||||
|
"unicorn/no-empty-file": "warn",
|
||||||
|
"unicorn/no-invalid-fetch-options": "warn",
|
||||||
|
"unicorn/no-invalid-remove-event-listener": "warn",
|
||||||
|
"unicorn/no-new-array": "warn",
|
||||||
|
"unicorn/no-single-promise-in-promise-methods": "warn",
|
||||||
|
"unicorn/no-thenable": "warn",
|
||||||
|
"unicorn/no-unnecessary-await": "warn",
|
||||||
|
"unicorn/no-useless-fallback-in-spread": "warn",
|
||||||
|
"unicorn/no-useless-length-check": "warn",
|
||||||
|
"unicorn/no-useless-spread": "warn",
|
||||||
|
"unicorn/prefer-set-size": "warn",
|
||||||
|
"unicorn/prefer-string-starts-ends-with": "warn"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"jsx-a11y": {
|
||||||
|
"polymorphicPropName": null,
|
||||||
|
"components": {},
|
||||||
|
"attributes": {}
|
||||||
|
},
|
||||||
|
"next": {
|
||||||
|
"rootDir": []
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"formComponents": [],
|
||||||
|
"linkComponents": [],
|
||||||
|
"version": null
|
||||||
|
},
|
||||||
|
"jsdoc": {
|
||||||
|
"ignorePrivate": false,
|
||||||
|
"ignoreInternal": false,
|
||||||
|
"ignoreReplacesDocs": true,
|
||||||
|
"overrideReplacesDocs": true,
|
||||||
|
"augmentsExtendsReplacesDocs": false,
|
||||||
|
"implementsReplacesDocs": false,
|
||||||
|
"exemptDestructuredRootsFromChecks": false,
|
||||||
|
"tagNamePreference": {}
|
||||||
|
},
|
||||||
|
"vitest": {
|
||||||
|
"typecheck": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"builtin": true
|
||||||
|
},
|
||||||
|
"globals": {},
|
||||||
|
"ignorePatterns": ["**/api-client/**"]
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ export const DirectoryBrowser = ({ onSelectPath, selectedPath }: Props) => {
|
||||||
return await queryClient.ensureQueryData(browseFilesystemOptions({ query: { path } }));
|
return await queryClient.ensureQueryData(browseFilesystemOptions({ query: { path } }));
|
||||||
},
|
},
|
||||||
prefetchFolder: (path) => {
|
prefetchFolder: (path) => {
|
||||||
queryClient.prefetchQuery(browseFilesystemOptions({ query: { path } }));
|
void queryClient.prefetchQuery(browseFilesystemOptions({ query: { path } }));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ export default function Layout({ loaderData }: Route.ComponentProps) {
|
||||||
const logout = useMutation({
|
const logout = useMutation({
|
||||||
...logoutMutation(),
|
...logoutMutation(),
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
navigate("/login", { replace: true });
|
void navigate("/login", { replace: true });
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ export function RestoreForm({ snapshot, repository, snapshotId, returnPath }: Re
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
prefetchFolder: (path) => {
|
prefetchFolder: (path) => {
|
||||||
queryClient.prefetchQuery(
|
void queryClient.prefetchQuery(
|
||||||
listSnapshotFilesOptions({
|
listSnapshotFilesOptions({
|
||||||
path: { id: repository.id, snapshotId },
|
path: { id: repository.id, snapshotId },
|
||||||
query: { path },
|
query: { path },
|
||||||
|
|
@ -102,7 +102,7 @@ export function RestoreForm({ snapshot, repository, snapshotId, returnPath }: Re
|
||||||
toast.success("Restore completed", {
|
toast.success("Restore completed", {
|
||||||
description: `Successfully restored ${data.filesRestored} file(s). ${data.filesSkipped} file(s) skipped.`,
|
description: `Successfully restored ${data.filesRestored} file(s). ${data.filesSkipped} file(s) skipped.`,
|
||||||
});
|
});
|
||||||
navigate(returnPath);
|
void navigate(returnPath);
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Restore failed", { description: error.message || "Failed to restore snapshot" });
|
toast.error("Restore failed", { description: error.message || "Failed to restore snapshot" });
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export const SnapshotsTable = ({ snapshots, repositoryId, backups }: Props) => {
|
||||||
const deleteSnapshots = useMutation({
|
const deleteSnapshots = useMutation({
|
||||||
...deleteSnapshotsMutation(),
|
...deleteSnapshotsMutation(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ["listSnapshots"] });
|
void queryClient.invalidateQueries({ queryKey: ["listSnapshots"] });
|
||||||
setShowBulkDeleteConfirm(false);
|
setShowBulkDeleteConfirm(false);
|
||||||
setSelectedIds(new Set());
|
setSelectedIds(new Set());
|
||||||
},
|
},
|
||||||
|
|
@ -62,7 +62,7 @@ export const SnapshotsTable = ({ snapshots, repositoryId, backups }: Props) => {
|
||||||
setShowReTagDialog(false);
|
setShowReTagDialog(false);
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: ["listSnapshots"] });
|
void queryClient.invalidateQueries({ queryKey: ["listSnapshots"] });
|
||||||
setShowReTagDialog(false);
|
setShowReTagDialog(false);
|
||||||
setSelectedIds(new Set());
|
setSelectedIds(new Set());
|
||||||
setTargetScheduleId("");
|
setTargetScheduleId("");
|
||||||
|
|
@ -70,7 +70,7 @@ export const SnapshotsTable = ({ snapshots, repositoryId, backups }: Props) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleRowClick = (snapshotId: string) => {
|
const handleRowClick = (snapshotId: string) => {
|
||||||
navigate(`/repositories/${repositoryId}/${snapshotId}`);
|
void navigate(`/repositories/${repositoryId}/${snapshotId}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleSelectAll = () => {
|
const toggleSelectAll = () => {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ export const VolumeFileBrowser = ({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
prefetchFolder: (path) => {
|
prefetchFolder: (path) => {
|
||||||
queryClient.prefetchQuery(
|
void queryClient.prefetchQuery(
|
||||||
listFilesOptions({
|
listFilesOptions({
|
||||||
path: { name: volumeName },
|
path: { name: volumeName },
|
||||||
query: { path },
|
query: { path },
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,8 @@ export function useServerEvents() {
|
||||||
const data = JSON.parse(e.data) as BackupEvent;
|
const data = JSON.parse(e.data) as BackupEvent;
|
||||||
console.log("[SSE] Backup completed:", data);
|
console.log("[SSE] Backup completed:", data);
|
||||||
|
|
||||||
queryClient.invalidateQueries();
|
void queryClient.invalidateQueries();
|
||||||
queryClient.refetchQueries();
|
void queryClient.refetchQueries();
|
||||||
|
|
||||||
handlersRef.current.get("backup:completed")?.forEach((handler) => {
|
handlersRef.current.get("backup:completed")?.forEach((handler) => {
|
||||||
handler(data);
|
handler(data);
|
||||||
|
|
@ -117,7 +117,7 @@ export function useServerEvents() {
|
||||||
const data = JSON.parse(e.data) as VolumeEvent;
|
const data = JSON.parse(e.data) as VolumeEvent;
|
||||||
console.log("[SSE] Volume updated:", data);
|
console.log("[SSE] Volume updated:", data);
|
||||||
|
|
||||||
queryClient.invalidateQueries();
|
void queryClient.invalidateQueries();
|
||||||
|
|
||||||
handlersRef.current.get("volume:updated")?.forEach((handler) => {
|
handlersRef.current.get("volume:updated")?.forEach((handler) => {
|
||||||
handler(data);
|
handler(data);
|
||||||
|
|
@ -128,7 +128,7 @@ export function useServerEvents() {
|
||||||
const data = JSON.parse(e.data) as VolumeEvent;
|
const data = JSON.parse(e.data) as VolumeEvent;
|
||||||
console.log("[SSE] Volume status updated:", data);
|
console.log("[SSE] Volume status updated:", data);
|
||||||
|
|
||||||
queryClient.invalidateQueries();
|
void queryClient.invalidateQueries();
|
||||||
|
|
||||||
handlersRef.current.get("volume:updated")?.forEach((handler) => {
|
handlersRef.current.get("volume:updated")?.forEach((handler) => {
|
||||||
handler(data);
|
handler(data);
|
||||||
|
|
@ -149,7 +149,7 @@ export function useServerEvents() {
|
||||||
console.log("[SSE] Mirror copy completed:", data);
|
console.log("[SSE] Mirror copy completed:", data);
|
||||||
|
|
||||||
// Invalidate queries to refresh mirror status in the UI
|
// Invalidate queries to refresh mirror status in the UI
|
||||||
queryClient.invalidateQueries();
|
void queryClient.invalidateQueries();
|
||||||
|
|
||||||
handlersRef.current.get("mirror:completed")?.forEach((handler) => {
|
handlersRef.current.get("mirror:completed")?.forEach((handler) => {
|
||||||
handler(data);
|
handler(data);
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ export default function DownloadRecoveryKeyPage() {
|
||||||
window.URL.revokeObjectURL(url);
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
toast.success("Recovery key downloaded successfully!");
|
toast.success("Recovery key downloaded successfully!");
|
||||||
navigate("/volumes", { replace: true });
|
void navigate("/volumes", { replace: true });
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to download recovery key", { description: error.message });
|
toast.error("Failed to download recovery key", { description: error.message });
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,9 @@ export default function LoginPage() {
|
||||||
...loginMutation(),
|
...loginMutation(),
|
||||||
onSuccess: async (data) => {
|
onSuccess: async (data) => {
|
||||||
if (data.user && !data.user.hasDownloadedResticPassword) {
|
if (data.user && !data.user.hasDownloadedResticPassword) {
|
||||||
navigate("/download-recovery-key");
|
void navigate("/download-recovery-key");
|
||||||
} else {
|
} else {
|
||||||
navigate("/volumes");
|
void navigate("/volumes");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export default function OnboardingPage() {
|
||||||
...registerMutation(),
|
...registerMutation(),
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
toast.success("Admin user created successfully!");
|
toast.success("Admin user created successfully!");
|
||||||
navigate("/download-recovery-key");
|
void navigate("/download-recovery-key");
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
|
||||||
|
|
@ -728,7 +728,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
|
||||||
.filter(([key, value]) => key.startsWith("keep") && Boolean(value))
|
.filter(([key, value]) => key.startsWith("keep") && Boolean(value))
|
||||||
.map(([key, value]) => {
|
.map(([key, value]) => {
|
||||||
const label = key.replace("keep", "").toLowerCase();
|
const label = key.replace("keep", "").toLowerCase();
|
||||||
return `${value} ${label}`;
|
return `${value.toString()} ${label}`;
|
||||||
})
|
})
|
||||||
.join(", ") || "-"}
|
.join(", ") || "-"}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export const SnapshotFileBrowser = (props: Props) => {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
prefetchFolder: (path) => {
|
prefetchFolder: (path) => {
|
||||||
queryClient.prefetchQuery(
|
void queryClient.prefetchQuery(
|
||||||
listSnapshotFilesOptions({
|
listSnapshotFilesOptions({
|
||||||
path: { id: repositoryId, snapshotId: snapshot.short_id },
|
path: { id: repositoryId, snapshotId: snapshot.short_id },
|
||||||
query: { path },
|
query: { path },
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ export default function ScheduleDetailsPage({ params, loaderData }: Route.Compon
|
||||||
...deleteBackupScheduleMutation(),
|
...deleteBackupScheduleMutation(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Backup schedule deleted successfully");
|
toast.success("Backup schedule deleted successfully");
|
||||||
navigate("/backups");
|
void navigate("/backups");
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to delete backup schedule", { description: parseError(error)?.message });
|
toast.error("Failed to delete backup schedule", { description: parseError(error)?.message });
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ export default function CreateBackup({ loaderData }: Route.ComponentProps) {
|
||||||
...createBackupScheduleMutation(),
|
...createBackupScheduleMutation(),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast.success("Backup job created successfully");
|
toast.success("Backup job created successfully");
|
||||||
navigate(`/backups/${data.id}`);
|
void navigate(`/backups/${data.id}`);
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to create backup job", {
|
toast.error("Failed to create backup job", {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export default function CreateNotification() {
|
||||||
...createNotificationDestinationMutation(),
|
...createNotificationDestinationMutation(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Notification destination created successfully");
|
toast.success("Notification destination created successfully");
|
||||||
navigate(`/notifications`);
|
void navigate(`/notifications`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import { getNotificationDestination } from "~/client/api-client/sdk.gen";
|
||||||
import type { Route } from "./+types/notification-details";
|
import type { Route } from "./+types/notification-details";
|
||||||
import { cn } from "~/client/lib/utils";
|
import { cn } from "~/client/lib/utils";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "~/client/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "~/client/components/ui/card";
|
||||||
import { Bell, Save, TestTube2, Trash2, X } from "lucide-react";
|
import { Bell, Save, TestTube2, Trash2 } from "lucide-react";
|
||||||
import { Alert, AlertDescription } from "~/client/components/ui/alert";
|
import { Alert, AlertDescription } from "~/client/components/ui/alert";
|
||||||
import { CreateNotificationForm, type NotificationFormValues } from "../components/create-notification-form";
|
import { CreateNotificationForm, type NotificationFormValues } from "../components/create-notification-form";
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ export default function NotificationDetailsPage({ loaderData }: Route.ComponentP
|
||||||
...deleteNotificationDestinationMutation(),
|
...deleteNotificationDestinationMutation(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Notification destination deleted successfully");
|
toast.success("Notification destination deleted successfully");
|
||||||
navigate("/notifications");
|
void navigate("/notifications");
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to delete notification destination", {
|
toast.error("Failed to delete notification destination", {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export default function CreateRepository() {
|
||||||
...createRepositoryMutation(),
|
...createRepositoryMutation(),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast.success("Repository created successfully");
|
toast.success("Repository created successfully");
|
||||||
navigate(`/repositories/${data.repository.shortId}`);
|
void navigate(`/repositories/${data.repository.shortId}`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,14 +67,14 @@ export default function RepositoryDetailsPage({ loaderData }: Route.ComponentPro
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
queryClient.prefetchQuery(listSnapshotsOptions({ path: { id: data.id } }));
|
void queryClient.prefetchQuery(listSnapshotsOptions({ path: { id: data.id } }));
|
||||||
}, [queryClient, data.id]);
|
}, [queryClient, data.id]);
|
||||||
|
|
||||||
const deleteRepo = useMutation({
|
const deleteRepo = useMutation({
|
||||||
...deleteRepositoryMutation(),
|
...deleteRepositoryMutation(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Repository deleted successfully");
|
toast.success("Repository deleted successfully");
|
||||||
navigate("/repositories");
|
void navigate("/repositories");
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to delete repository", {
|
toast.error("Failed to delete repository", {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ export default function Settings({ loaderData }: Route.ComponentProps) {
|
||||||
const logout = useMutation({
|
const logout = useMutation({
|
||||||
...logoutMutation(),
|
...logoutMutation(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
navigate("/login", { replace: true });
|
void navigate("/login", { replace: true });
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export default function CreateVolume() {
|
||||||
...createVolumeMutation(),
|
...createVolumeMutation(),
|
||||||
onSuccess: (data) => {
|
onSuccess: (data) => {
|
||||||
toast.success("Volume created successfully");
|
toast.success("Volume created successfully");
|
||||||
navigate(`/volumes/${data.name}`);
|
void navigate(`/volumes/${data.name}`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ export default function VolumeDetails({ loaderData }: Route.ComponentProps) {
|
||||||
...deleteVolumeMutation(),
|
...deleteVolumeMutation(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Volume deleted successfully");
|
toast.success("Volume deleted successfully");
|
||||||
navigate("/volumes");
|
void navigate("/volumes");
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to delete volume", {
|
toast.error("Failed to delete volume", {
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export const VolumeInfoTabContent = ({ volume, statfs }: Props) => {
|
||||||
setPendingValues(null);
|
setPendingValues(null);
|
||||||
|
|
||||||
if (data.name !== volume.name) {
|
if (data.name !== volume.name) {
|
||||||
navigate(`/volumes/${data.name}`);
|
void navigate(`/volumes/${data.name}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ export const links: Route.LinksFunction = () => [
|
||||||
const queryClient = new QueryClient({
|
const queryClient = new QueryClient({
|
||||||
mutationCache: new MutationCache({
|
mutationCache: new MutationCache({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries();
|
void queryClient.invalidateQueries();
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error("Mutation error:", error);
|
console.error("Mutation error:", error);
|
||||||
queryClient.invalidateQueries();
|
void queryClient.invalidateQueries();
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ class SchedulerClass {
|
||||||
|
|
||||||
async stop() {
|
async stop() {
|
||||||
for (const task of this.tasks) {
|
for (const task of this.tasks) {
|
||||||
task.stop();
|
await task.stop();
|
||||||
}
|
}
|
||||||
this.tasks = [];
|
this.tasks = [];
|
||||||
logger.info("Scheduler stopped");
|
logger.info("Scheduler stopped");
|
||||||
|
|
@ -42,7 +42,7 @@ class SchedulerClass {
|
||||||
|
|
||||||
async clear() {
|
async clear() {
|
||||||
for (const task of this.tasks) {
|
for (const task of this.tasks) {
|
||||||
task.destroy();
|
await task.destroy();
|
||||||
}
|
}
|
||||||
this.tasks = [];
|
this.tasks = [];
|
||||||
logger.info("Scheduler cleared all tasks");
|
logger.info("Scheduler cleared all tasks");
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,7 @@ runDbMigrations();
|
||||||
await retagSnapshots();
|
await retagSnapshots();
|
||||||
await validateRequiredMigrations(REQUIRED_MIGRATIONS);
|
await validateRequiredMigrations(REQUIRED_MIGRATIONS);
|
||||||
|
|
||||||
startup();
|
await startup();
|
||||||
|
|
||||||
logger.info(`Server is running at http://localhost:${config.port}`);
|
|
||||||
|
|
||||||
export type AppType = typeof app;
|
export type AppType = typeof app;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { authService } from "../modules/auth/auth.service";
|
||||||
|
|
||||||
export class CleanupSessionsJob extends Job {
|
export class CleanupSessionsJob extends Job {
|
||||||
async run() {
|
async run() {
|
||||||
authService.cleanupExpiredSessions();
|
await authService.cleanupExpiredSessions();
|
||||||
|
|
||||||
return { done: true, timestamp: new Date() };
|
return { done: true, timestamp: new Date() };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ describe("execute backup", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// act
|
// act
|
||||||
backupsService.executeBackup(schedule.id);
|
void backupsService.executeBackup(schedule.id);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||||
await backupsService.executeBackup(schedule.id);
|
await backupsService.executeBackup(schedule.id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const calculateNextRun = (cronExpression: string): number => {
|
||||||
|
|
||||||
return interval.next().getTime();
|
return interval.next().getTime();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Failed to parse cron expression "${cronExpression}": ${error}`);
|
logger.error(`Failed to parse cron expression "${cronExpression}": ${toMessage(error)}`);
|
||||||
const fallback = new Date();
|
const fallback = new Date();
|
||||||
fallback.setMinutes(fallback.getMinutes() + 1);
|
fallback.setMinutes(fallback.getMinutes() + 1);
|
||||||
return fallback.getTime();
|
return fallback.getTime();
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ export const eventsController = new Hono().use(requireAuth).get("/", (c) => {
|
||||||
event: "connected",
|
event: "connected",
|
||||||
});
|
});
|
||||||
|
|
||||||
const onBackupStarted = (data: { scheduleId: number; volumeName: string; repositoryName: string }) => {
|
const onBackupStarted = async (data: { scheduleId: number; volumeName: string; repositoryName: string }) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "backup:started",
|
event: "backup:started",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onBackupProgress = (data: {
|
const onBackupProgress = async (data: {
|
||||||
scheduleId: number;
|
scheduleId: number;
|
||||||
volumeName: string;
|
volumeName: string;
|
||||||
repositoryName: string;
|
repositoryName: string;
|
||||||
|
|
@ -32,60 +32,60 @@ export const eventsController = new Hono().use(requireAuth).get("/", (c) => {
|
||||||
bytes_done: number;
|
bytes_done: number;
|
||||||
current_files: string[];
|
current_files: string[];
|
||||||
}) => {
|
}) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "backup:progress",
|
event: "backup:progress",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onBackupCompleted = (data: {
|
const onBackupCompleted = async (data: {
|
||||||
scheduleId: number;
|
scheduleId: number;
|
||||||
volumeName: string;
|
volumeName: string;
|
||||||
repositoryName: string;
|
repositoryName: string;
|
||||||
status: "success" | "error" | "stopped" | "warning";
|
status: "success" | "error" | "stopped" | "warning";
|
||||||
}) => {
|
}) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "backup:completed",
|
event: "backup:completed",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVolumeMounted = (data: { volumeName: string }) => {
|
const onVolumeMounted = async (data: { volumeName: string }) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "volume:mounted",
|
event: "volume:mounted",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVolumeUnmounted = (data: { volumeName: string }) => {
|
const onVolumeUnmounted = async (data: { volumeName: string }) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "volume:unmounted",
|
event: "volume:unmounted",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVolumeUpdated = (data: { volumeName: string }) => {
|
const onVolumeUpdated = async (data: { volumeName: string }) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "volume:updated",
|
event: "volume:updated",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMirrorStarted = (data: { scheduleId: number; repositoryId: string; repositoryName: string }) => {
|
const onMirrorStarted = async (data: { scheduleId: number; repositoryId: string; repositoryName: string }) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "mirror:started",
|
event: "mirror:started",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMirrorCompleted = (data: {
|
const onMirrorCompleted = async (data: {
|
||||||
scheduleId: number;
|
scheduleId: number;
|
||||||
repositoryId: string;
|
repositoryId: string;
|
||||||
repositoryName: string;
|
repositoryName: string;
|
||||||
status: "success" | "error";
|
status: "success" | "error";
|
||||||
error?: string;
|
error?: string;
|
||||||
}) => {
|
}) => {
|
||||||
stream.writeSSE({
|
await stream.writeSSE({
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
event: "mirror:completed",
|
event: "mirror:completed",
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { sanitizeSensitiveData } from "./sanitize";
|
||||||
|
|
||||||
const { printf, combine, colorize } = format;
|
const { printf, combine, colorize } = format;
|
||||||
|
|
||||||
const printConsole = printf((info) => `${info.level} > ${info.message}`);
|
const printConsole = printf((info) => `${info.level} > ${String(info.message)}`);
|
||||||
const consoleFormat = combine(colorize(), printConsole);
|
const consoleFormat = combine(colorize(), printConsole);
|
||||||
|
|
||||||
const getDefaultLevel = () => {
|
const getDefaultLevel = () => {
|
||||||
|
|
@ -27,7 +27,7 @@ const log = (level: "info" | "warn" | "error" | "debug", messages: unknown[]) =>
|
||||||
return sanitizeSensitiveData(JSON.stringify(m, null, 2));
|
return sanitizeSensitiveData(JSON.stringify(m, null, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sanitizeSensitiveData(String(m));
|
return sanitizeSensitiveData(String(JSON.stringify(m)));
|
||||||
});
|
});
|
||||||
|
|
||||||
winstonLogger.log(level, stringMessages.join(" "));
|
winstonLogger.log(level, stringMessages.join(" "));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { $ } from "bun";
|
import { $ } from "bun";
|
||||||
import { logger } from "./logger";
|
import { logger } from "./logger";
|
||||||
|
import { toMessage } from "./errors";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all configured rclone remotes
|
* List all configured rclone remotes
|
||||||
|
|
@ -9,7 +10,7 @@ export async function listRcloneRemotes(): Promise<string[]> {
|
||||||
const result = await $`rclone listremotes`.nothrow();
|
const result = await $`rclone listremotes`.nothrow();
|
||||||
|
|
||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
logger.error(`Failed to list rclone remotes: ${result.stderr}`);
|
logger.error(`Failed to list rclone remotes: ${result.stderr.toString()}`);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +37,7 @@ export async function getRcloneRemoteInfo(
|
||||||
const result = await $`rclone config show ${remote}`.quiet();
|
const result = await $`rclone config show ${remote}`.quiet();
|
||||||
|
|
||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
logger.error(`Failed to get info for remote ${remote}: ${result.stderr}`);
|
logger.error(`Failed to get info for remote ${remote}: ${result.stderr.toString()}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +71,7 @@ export async function getRcloneRemoteInfo(
|
||||||
|
|
||||||
return { type, config };
|
return { type, config };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error getting remote info for ${remote}: ${error}`);
|
logger.error(`Error getting remote info for ${remote}: ${toMessage(error)}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -358,8 +358,8 @@ const backup = async (
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
finally: async () => {
|
finally: async () => {
|
||||||
includeFile && (await fs.unlink(includeFile).catch(() => {}));
|
if (includeFile) await fs.unlink(includeFile).catch(() => {});
|
||||||
excludeFile && (await fs.unlink(excludeFile).catch(() => {}));
|
if (excludeFile) await fs.unlink(excludeFile).catch(() => {});
|
||||||
await cleanupTemporaryKeys(env);
|
await cleanupTemporaryKeys(env);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -393,7 +393,7 @@ const backup = async (
|
||||||
const result = backupOutputSchema(summaryLine);
|
const result = backupOutputSchema(summaryLine);
|
||||||
|
|
||||||
if (result instanceof type.errors) {
|
if (result instanceof type.errors) {
|
||||||
logger.error(`Restic backup output validation failed: ${result}`);
|
logger.error(`Restic backup output validation failed: ${result.summary}`);
|
||||||
return { result: null, exitCode: res.exitCode };
|
return { result: null, exitCode: res.exitCode };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -484,7 +484,7 @@ const restore = async (
|
||||||
const result = restoreOutputSchema(resSummary);
|
const result = restoreOutputSchema(resSummary);
|
||||||
|
|
||||||
if (result instanceof type.errors) {
|
if (result instanceof type.errors) {
|
||||||
logger.warn(`Restic restore output validation failed: ${result}`);
|
logger.warn(`Restic restore output validation failed: ${result.summary}`);
|
||||||
logger.info(`Restic restore completed for snapshot ${snapshotId} to target ${target}`);
|
logger.info(`Restic restore completed for snapshot ${snapshotId} to target ${target}`);
|
||||||
return {
|
return {
|
||||||
message_type: "summary" as const,
|
message_type: "summary" as const,
|
||||||
|
|
@ -529,8 +529,8 @@ const snapshots = async (config: RepositoryConfig, options: { tags?: string[] }
|
||||||
const result = snapshotInfoSchema.array()(JSON.parse(res.stdout));
|
const result = snapshotInfoSchema.array()(JSON.parse(res.stdout));
|
||||||
|
|
||||||
if (result instanceof type.errors) {
|
if (result instanceof type.errors) {
|
||||||
logger.error(`Restic snapshots output validation failed: ${result}`);
|
logger.error(`Restic snapshots output validation failed: ${result.summary}`);
|
||||||
throw new Error(`Restic snapshots output validation failed: ${result}`);
|
throw new Error(`Restic snapshots output validation failed: ${result.summary}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -712,8 +712,8 @@ const ls = async (config: RepositoryConfig, snapshotId: string, path?: string) =
|
||||||
const snapshot = lsSnapshotInfoSchema(snapshotLine);
|
const snapshot = lsSnapshotInfoSchema(snapshotLine);
|
||||||
|
|
||||||
if (snapshot instanceof type.errors) {
|
if (snapshot instanceof type.errors) {
|
||||||
logger.error(`Restic ls snapshot info validation failed: ${snapshot}`);
|
logger.error(`Restic ls snapshot info validation failed: ${snapshot.summary}`);
|
||||||
throw new Error(`Restic ls snapshot info validation failed: ${snapshot}`);
|
throw new Error(`Restic ls snapshot info validation failed: ${snapshot.summary}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodes: Array<typeof lsNodeSchema.infer> = [];
|
const nodes: Array<typeof lsNodeSchema.infer> = [];
|
||||||
|
|
@ -722,7 +722,7 @@ const ls = async (config: RepositoryConfig, snapshotId: string, path?: string) =
|
||||||
const nodeValidation = lsNodeSchema(nodeLine);
|
const nodeValidation = lsNodeSchema(nodeLine);
|
||||||
|
|
||||||
if (nodeValidation instanceof type.errors) {
|
if (nodeValidation instanceof type.errors) {
|
||||||
logger.warn(`Skipping invalid node: ${nodeValidation}`);
|
logger.warn(`Skipping invalid node: ${nodeValidation.summary}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import path from "node:path";
|
||||||
import { cwd } from "node:process";
|
import { cwd } from "node:process";
|
||||||
import { db } from "~/server/db/db";
|
import { db } from "~/server/db/db";
|
||||||
|
|
||||||
mock.module("~/server/utils/logger", () => ({
|
void mock.module("~/server/utils/logger", () => ({
|
||||||
logger: {
|
logger: {
|
||||||
debug: () => {},
|
debug: () => {},
|
||||||
info: () => {},
|
info: () => {},
|
||||||
|
|
|
||||||
43
biome.json
43
biome.json
|
|
@ -1,43 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
|
||||||
"vcs": {
|
|
||||||
"enabled": true,
|
|
||||||
"clientKind": "git",
|
|
||||||
"defaultBranch": "origin/main",
|
|
||||||
"useIgnoreFile": true
|
|
||||||
},
|
|
||||||
"files": {
|
|
||||||
"includes": ["**/*.{ts,tsx,json}", "!**/api-client", "!**/components/ui"],
|
|
||||||
"ignoreUnknown": false
|
|
||||||
},
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"indentStyle": "tab",
|
|
||||||
"lineWidth": 120,
|
|
||||||
"lineEnding": "lf"
|
|
||||||
},
|
|
||||||
"linter": {
|
|
||||||
"enabled": true,
|
|
||||||
"rules": {
|
|
||||||
"recommended": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"javascript": {
|
|
||||||
"formatter": {
|
|
||||||
"quoteStyle": "double"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"assist": {
|
|
||||||
"enabled": true,
|
|
||||||
"actions": {
|
|
||||||
"source": {
|
|
||||||
"organizeImports": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"css": {
|
|
||||||
"parser": {
|
|
||||||
"tailwindDirectives": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
74
bun.lock
74
bun.lock
|
|
@ -64,7 +64,6 @@
|
||||||
"yaml": "^2.8.2",
|
"yaml": "^2.8.2",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.3.8",
|
|
||||||
"@faker-js/faker": "^10.1.0",
|
"@faker-js/faker": "^10.1.0",
|
||||||
"@happy-dom/global-registrator": "^20.0.11",
|
"@happy-dom/global-registrator": "^20.0.11",
|
||||||
"@hey-api/openapi-ts": "^0.88.0",
|
"@hey-api/openapi-ts": "^0.88.0",
|
||||||
|
|
@ -82,6 +81,9 @@
|
||||||
"dotenv-cli": "^11.0.0",
|
"dotenv-cli": "^11.0.0",
|
||||||
"drizzle-kit": "^0.31.7",
|
"drizzle-kit": "^0.31.7",
|
||||||
"lightningcss": "^1.30.2",
|
"lightningcss": "^1.30.2",
|
||||||
|
"oxfmt": "^0.22.0",
|
||||||
|
"oxlint": "^1.36.0",
|
||||||
|
"oxlint-tsgolint": "^0.10.1",
|
||||||
"tailwindcss": "^4.1.17",
|
"tailwindcss": "^4.1.17",
|
||||||
"tinyglobby": "^0.2.15",
|
"tinyglobby": "^0.2.15",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
|
|
@ -158,24 +160,6 @@
|
||||||
|
|
||||||
"@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
|
"@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
|
||||||
|
|
||||||
"@biomejs/biome": ["@biomejs/biome@2.3.10", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.3.10", "@biomejs/cli-darwin-x64": "2.3.10", "@biomejs/cli-linux-arm64": "2.3.10", "@biomejs/cli-linux-arm64-musl": "2.3.10", "@biomejs/cli-linux-x64": "2.3.10", "@biomejs/cli-linux-x64-musl": "2.3.10", "@biomejs/cli-win32-arm64": "2.3.10", "@biomejs/cli-win32-x64": "2.3.10" }, "bin": { "biome": "bin/biome" } }, "sha512-/uWSUd1MHX2fjqNLHNL6zLYWBbrJeG412/8H7ESuK8ewoRoMPUgHDebqKrPTx/5n6f17Xzqc9hdg3MEqA5hXnQ=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.3.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-M6xUjtCVnNGFfK7HMNKa593nb7fwNm43fq1Mt71kpLpb+4mE7odO8W/oWVDyBVO4ackhresy1ZYO7OJcVo/B7w=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.3.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-Vae7+V6t/Avr8tVbFNjnFSTKZogZHFYl7MMH62P/J1kZtr0tyRQ9Fe0onjqjS2Ek9lmNLmZc/VR5uSekh+p1fg=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.3.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-hhPw2V3/EpHKsileVOFynuWiKRgFEV48cLe0eA+G2wO4SzlwEhLEB9LhlSrVeu2mtSn205W283LkX7Fh48CaxA=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.3.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-B9DszIHkuKtOH2IFeeVkQmSMVUjss9KtHaNXquYYWCjH8IstNgXgx5B0aSBQNr6mn4RcKKRQZXn9Zu1rM3O0/A=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.3.10", "", { "os": "linux", "cpu": "x64" }, "sha512-wwAkWD1MR95u+J4LkWP74/vGz+tRrIQvr8kfMMJY8KOQ8+HMVleREOcPYsQX82S7uueco60L58Wc6M1I9WA9Dw=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.3.10", "", { "os": "linux", "cpu": "x64" }, "sha512-QTfHZQh62SDFdYc2nfmZFuTm5yYb4eO1zwfB+90YxUumRCR171tS1GoTX5OD0wrv4UsziMPmrePMtkTnNyYG3g=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.3.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-o7lYc9n+CfRbHvkjPhm8s9FgbKdYZu5HCcGVMItLjz93EhgJ8AM44W+QckDqLA9MKDNFrR8nPbO4b73VC5kGGQ=="],
|
|
||||||
|
|
||||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.3.10", "", { "os": "win32", "cpu": "x64" }, "sha512-pHEFgq7dUEsKnqG9mx9bXihxGI49X+ar+UBrEIj3Wqj3UCZp1rNgV+OoyjFgcXsjCWpuEAF4VJdkZr3TrWdCbQ=="],
|
|
||||||
|
|
||||||
"@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
|
"@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
|
||||||
|
|
||||||
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.8", "", { "dependencies": { "@so-ric/colorspace": "^1.1.6", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q=="],
|
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.8", "", { "dependencies": { "@so-ric/colorspace": "^1.1.6", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q=="],
|
||||||
|
|
@ -320,6 +304,50 @@
|
||||||
|
|
||||||
"@mjackson/node-fetch-server": ["@mjackson/node-fetch-server@0.2.0", "", {}, "sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng=="],
|
"@mjackson/node-fetch-server": ["@mjackson/node-fetch-server@0.2.0", "", {}, "sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng=="],
|
||||||
|
|
||||||
|
"@oxfmt/darwin-arm64": ["@oxfmt/darwin-arm64@0.22.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dhz2m2uLrHT3MwM+LAdvr97EojJZTwaZ6BuMTRftJzqa9dHYDG/MtSBuDD2DpGpZ0SM2iVwni2wCzCYGKTojbA=="],
|
||||||
|
|
||||||
|
"@oxfmt/darwin-x64": ["@oxfmt/darwin-x64@0.22.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-VykUbibvqSOG5YIFUMpHtZVrY1YKDl9Il2SvFemUfR5Ac1t1BFZOnazYe98jtZGFY4sEdEORs0ImBARnyMX/hw=="],
|
||||||
|
|
||||||
|
"@oxfmt/linux-arm64-gnu": ["@oxfmt/linux-arm64-gnu@0.22.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-y0MBha/K34TztYAZUn6KQE9xLPLNHqRpOdzRp96fhkbrQTeEXo+jF+8+aV8VnqjG0y7p+IQN4ATxNSstSPO9sA=="],
|
||||||
|
|
||||||
|
"@oxfmt/linux-arm64-musl": ["@oxfmt/linux-arm64-musl@0.22.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-8a0p2UEmavB+moQ7ID17i+dE7N2xng6lPU8vrrNnnwKde0YpGHdW6hmuH4mS+rrltvs0fjyGRSvCnD2Qm9IAcA=="],
|
||||||
|
|
||||||
|
"@oxfmt/linux-x64-gnu": ["@oxfmt/linux-x64-gnu@0.22.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ZA1lS6MLvtGfD9AaDylCSTTiOWVQs1eIl9uqsGYs+Zr8p0mI7QRIRA6juWk9FXn1hHfmYBdBgWu2GdIW0YFCFA=="],
|
||||||
|
|
||||||
|
"@oxfmt/linux-x64-musl": ["@oxfmt/linux-x64-musl@0.22.0", "", { "os": "linux", "cpu": "x64" }, "sha512-J5zFB8T5yk6Jx63rdKuXfcPqR1cAp12nO5/NJfGITH00AML2Yj9JM4dRnmssJomYHKa8dNSr40l6OdxRZN88CQ=="],
|
||||||
|
|
||||||
|
"@oxfmt/win32-arm64": ["@oxfmt/win32-arm64@0.22.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-XYxyIiOf3HqlfETLFKqCHYL88mhw+Ka25vDVgmlcghbJv9BPoVzquZW7P4i0T3D5GWp4LHhZHmMo8BuK8PP5BA=="],
|
||||||
|
|
||||||
|
"@oxfmt/win32-x64": ["@oxfmt/win32-x64@0.22.0", "", { "os": "win32", "cpu": "x64" }, "sha512-/shfU+wwlXcKP2NkZt+kYCSVom2EEu8MwbENlYCak6LtPPrN5xAQhHuOSFByjDzTBApdQugch0j0ZB/4Wyaljg=="],
|
||||||
|
|
||||||
|
"@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.10.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KGC4++BeEqrIcmDHiJt/e6/860PWJmUJjjp0mE+smpBmRXMjmOFFjrPmN+ZyCyVgf1WdmhPkQXsRSPeTR+2omw=="],
|
||||||
|
|
||||||
|
"@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.10.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-tvmrDgj3Q0tdc+zMWfCVLVq8EQDEUqasm1zaWgSMYIszpID6qdgqbT+OpWWXV9fLZgtvrkoXGwxkHAUJzdVZXQ=="],
|
||||||
|
|
||||||
|
"@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.10.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-7kD28z6/ykGx8WetKTPRZt30pd+ziassxg/8cM24lhjUI+hNXyRHVtHes73dh9D6glJKno+1ut+3amUdZBZcpQ=="],
|
||||||
|
|
||||||
|
"@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.10.1", "", { "os": "linux", "cpu": "x64" }, "sha512-NmJmiqdzYUTHIxteSTyX6IFFgnIsOAjRWXfrS6Jbo5xlB3g39WHniSF3asB/khLJNtwSg4InUS34NprYM7zrEw=="],
|
||||||
|
|
||||||
|
"@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.10.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-3KrT80vl3nXUkjuJI/z8dF6xWsKx0t9Tz4ZQHgQw3fYw+CoihBRWGklrdlmCz+EGfMyVaQLqBV9PZckhSqLe2A=="],
|
||||||
|
|
||||||
|
"@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.10.1", "", { "os": "win32", "cpu": "x64" }, "sha512-hW1fSJZVxG51sLdGq1sQjOzb1tsQ23z/BquJfUwL7CqBobxr7TJvGmoINL+9KryOJt0jCoaiMfWe4yoYw5XfIA=="],
|
||||||
|
|
||||||
|
"@oxlint/darwin-arm64": ["@oxlint/darwin-arm64@1.36.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MJkj82GH+nhvWKJhSIM6KlZ8tyGKdogSQXtNdpIyP02r/tTayFJQaAEWayG2Jhsn93kske+nimg5MYFhwO/rlg=="],
|
||||||
|
|
||||||
|
"@oxlint/darwin-x64": ["@oxlint/darwin-x64@1.36.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-VvEhfkqj/99dCTqOcfkyFXOSbx4lIy5u2m2GHbK4WCMDySokOcMTNRHGw8fH/WgQ5cDrDMSTYIGQTmnBGi9tiQ=="],
|
||||||
|
|
||||||
|
"@oxlint/linux-arm64-gnu": ["@oxlint/linux-arm64-gnu@1.36.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EMx92X5q+hHc3olTuj/kgkx9+yP0p/AVs4yvHbUfzZhBekXNpUWxWvg4hIKmQWn+Ee2j4o80/0ACGO0hDYJ9mg=="],
|
||||||
|
|
||||||
|
"@oxlint/linux-arm64-musl": ["@oxlint/linux-arm64-musl@1.36.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-7YCxtrPIctVYLqWrWkk8pahdCxch6PtsaucfMLC7TOlDt4nODhnQd4yzEscKqJ8Gjrw1bF4g+Ngob1gB+Qr9Fw=="],
|
||||||
|
|
||||||
|
"@oxlint/linux-x64-gnu": ["@oxlint/linux-x64-gnu@1.36.0", "", { "os": "linux", "cpu": "x64" }, "sha512-lnaJVlx5r3NWmoOMesfQXJSf78jHTn8Z+sdAf795Kgteo72+qGC1Uax2SToCJVN2J8PNG3oRV5bLriiCNR2i6Q=="],
|
||||||
|
|
||||||
|
"@oxlint/linux-x64-musl": ["@oxlint/linux-x64-musl@1.36.0", "", { "os": "linux", "cpu": "x64" }, "sha512-AhuEU2Qdl66lSfTGu/Htirq8r/8q2YnZoG3yEXLMQWnPMn7efy8spD/N1NA7kH0Hll+cdfwgQkQqC2G4MS2lPQ=="],
|
||||||
|
|
||||||
|
"@oxlint/win32-arm64": ["@oxlint/win32-arm64@1.36.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-GlWCBjUJY2QgvBFuNRkiRJu7K/djLmM0UQKfZV8IN+UXbP/JbjZHWKRdd4LXlQmzoz7M5Hd6p+ElCej8/90FCg=="],
|
||||||
|
|
||||||
|
"@oxlint/win32-x64": ["@oxlint/win32-x64@1.36.0", "", { "os": "win32", "cpu": "x64" }, "sha512-J+Vc00Utcf8p77lZPruQgb0QnQXuKnFogN88kCnOqs2a83I+vTBB8ILr0+L9sTwVRvIDMSC0pLdeQH4svWGFZg=="],
|
||||||
|
|
||||||
"@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
|
"@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
|
||||||
|
|
||||||
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
|
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
|
||||||
|
|
@ -1112,6 +1140,12 @@
|
||||||
|
|
||||||
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
|
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
|
||||||
|
|
||||||
|
"oxfmt": ["oxfmt@0.22.0", "", { "dependencies": { "tinypool": "2.0.0" }, "optionalDependencies": { "@oxfmt/darwin-arm64": "0.22.0", "@oxfmt/darwin-x64": "0.22.0", "@oxfmt/linux-arm64-gnu": "0.22.0", "@oxfmt/linux-arm64-musl": "0.22.0", "@oxfmt/linux-x64-gnu": "0.22.0", "@oxfmt/linux-x64-musl": "0.22.0", "@oxfmt/win32-arm64": "0.22.0", "@oxfmt/win32-x64": "0.22.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-Z7JM5yv4KaDz5kT21MxRAvtYo5Eu9Ti/XY1JYShSOlaH859XSn4UaS3wlZKyz4Mpbo8ISkxhU75UY5yp+OQUyA=="],
|
||||||
|
|
||||||
|
"oxlint": ["oxlint@1.36.0", "", { "optionalDependencies": { "@oxlint/darwin-arm64": "1.36.0", "@oxlint/darwin-x64": "1.36.0", "@oxlint/linux-arm64-gnu": "1.36.0", "@oxlint/linux-arm64-musl": "1.36.0", "@oxlint/linux-x64-gnu": "1.36.0", "@oxlint/linux-x64-musl": "1.36.0", "@oxlint/win32-arm64": "1.36.0", "@oxlint/win32-x64": "1.36.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.10.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxc_language_server": "bin/oxc_language_server", "oxlint": "bin/oxlint" } }, "sha512-IicUdXfXgI8OKrDPnoSjvBfeEF8PkKtm+CoLlg4LYe4ypc8U+T4r7730XYshdBGZdelg+JRw8GtCb2w/KaaZvw=="],
|
||||||
|
|
||||||
|
"oxlint-tsgolint": ["oxlint-tsgolint@0.10.1", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.10.1", "@oxlint-tsgolint/darwin-x64": "0.10.1", "@oxlint-tsgolint/linux-arm64": "0.10.1", "@oxlint-tsgolint/linux-x64": "0.10.1", "@oxlint-tsgolint/win32-arm64": "0.10.1", "@oxlint-tsgolint/win32-x64": "0.10.1" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-EEHNdo5cW2w1xwYdBQ7d3IXDqWAtMkfVFrh+9gQ4kYbYJwygY4QXSh1eH80/xVipZdVKujAwBgg/nNNHk56kxQ=="],
|
||||||
|
|
||||||
"p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
|
"p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
|
||||||
|
|
||||||
"parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="],
|
"parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="],
|
||||||
|
|
@ -1286,6 +1320,8 @@
|
||||||
|
|
||||||
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
||||||
|
|
||||||
|
"tinypool": ["tinypool@2.0.0", "", {}, "sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg=="],
|
||||||
|
|
||||||
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
||||||
|
|
||||||
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@
|
||||||
"prefix": ""
|
"prefix": ""
|
||||||
},
|
},
|
||||||
"aliases": {
|
"aliases": {
|
||||||
"components": "~/components",
|
"components": "~/client/components",
|
||||||
"utils": "~/lib/utils",
|
"utils": "~/client/lib/utils",
|
||||||
"ui": "~/components/ui",
|
"ui": "~/client/components/ui",
|
||||||
"lib": "~/lib",
|
"lib": "~/client/lib",
|
||||||
"hooks": "~/hooks"
|
"hooks": "~/client/hooks"
|
||||||
},
|
},
|
||||||
"iconLibrary": "lucide"
|
"iconLibrary": "lucide"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,13 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "bun@1.3.5",
|
"packageManager": "bun@1.3.5",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"lint": "oxlint --type-aware",
|
||||||
"build": "react-router build",
|
"build": "react-router build",
|
||||||
"dev": "bunx --bun vite",
|
"dev": "bunx --bun vite",
|
||||||
"start": "bun ./dist/server/index.js",
|
"start": "bun ./dist/server/index.js",
|
||||||
"cli:dev": "bun run app/server/cli/main.ts",
|
"cli:dev": "bun run app/server/cli/main.ts",
|
||||||
"cli": "ZEROBYTE_CLI=1 bun ./dist/server/index.js",
|
"cli": "ZEROBYTE_CLI=1 bun ./dist/server/index.js",
|
||||||
"tsc": "react-router typegen && tsc",
|
"tsc": "react-router typegen && tsc",
|
||||||
"lint": "biome check .",
|
|
||||||
"lint:ci": "biome ci . --changed --error-on-warnings --no-errors-on-unmatched",
|
|
||||||
"start:dev": "docker compose down && docker compose up --build zerobyte-dev",
|
"start:dev": "docker compose down && docker compose up --build zerobyte-dev",
|
||||||
"start:prod": "docker compose down && docker compose up --build zerobyte-prod",
|
"start:prod": "docker compose down && docker compose up --build zerobyte-prod",
|
||||||
"gen:api-client": "openapi-ts",
|
"gen:api-client": "openapi-ts",
|
||||||
|
|
@ -84,7 +83,6 @@
|
||||||
"yaml": "^2.8.2"
|
"yaml": "^2.8.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.3.8",
|
|
||||||
"@faker-js/faker": "^10.1.0",
|
"@faker-js/faker": "^10.1.0",
|
||||||
"@happy-dom/global-registrator": "^20.0.11",
|
"@happy-dom/global-registrator": "^20.0.11",
|
||||||
"@hey-api/openapi-ts": "^0.88.0",
|
"@hey-api/openapi-ts": "^0.88.0",
|
||||||
|
|
@ -102,6 +100,9 @@
|
||||||
"dotenv-cli": "^11.0.0",
|
"dotenv-cli": "^11.0.0",
|
||||||
"drizzle-kit": "^0.31.7",
|
"drizzle-kit": "^0.31.7",
|
||||||
"lightningcss": "^1.30.2",
|
"lightningcss": "^1.30.2",
|
||||||
|
"oxfmt": "^0.22.0",
|
||||||
|
"oxlint": "^1.36.0",
|
||||||
|
"oxlint-tsgolint": "^0.10.1",
|
||||||
"tailwindcss": "^4.1.17",
|
"tailwindcss": "^4.1.17",
|
||||||
"tinyglobby": "^0.2.15",
|
"tinyglobby": "^0.2.15",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"rootDirs": [".", "./.react-router/types"],
|
"rootDirs": [".", "./.react-router/types"],
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
"paths": {
|
||||||
"~/*": ["./app/*"]
|
"~/*": ["./app/*"]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue