Skip to content

Commit 3c680c8

Browse files
committed
feat: improve response types
1 parent a5de2ef commit 3c680c8

File tree

16 files changed

+989
-960
lines changed

16 files changed

+989
-960
lines changed

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const SORT_IMPORT_CUSTOM_GROUP = {
99

1010
export default antfu({
1111
toml: false,
12+
isInEditor: false,
1213
rules: {
1314
"antfu/consistent-list-newline": "off",
1415
"antfu/if-newline": "off",

package.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,27 @@
2020
"@octokit/core": "^6.1.4",
2121
"@tabler/icons-vue": "^3.31.0",
2222
"@vitejs/plugin-vue": "^5.2.1",
23-
"@vueuse/core": "^12.8.2",
24-
"@vueuse/integrations": "^12.8.2",
23+
"@vueuse/core": "^13.0.0",
24+
"@vueuse/integrations": "^13.0.0",
2525
"dayjs": "^1.11.13",
2626
"http-status-codes": "^2.3.0",
2727
"semver": "^7.7.1",
2828
"sortablejs": "^1.15.6",
29-
"vite": "^6.2.0",
29+
"vite": "^6.2.1",
3030
"vite-plugin-pwa": "^0.21.1",
3131
"vue": "^3.5.13",
3232
"vue-dompurify-html": "^5.2.0"
3333
},
3434
"devDependencies": {
35-
"@antfu/eslint-config": "^4.6.0",
35+
"@antfu/eslint-config": "^4.8.1",
3636
"@octokit/types": "^13.8.0",
3737
"@stylistic/stylelint-plugin": "^3.1.2",
38-
"@types/node": "^22.13.9",
38+
"@total-typescript/ts-reset": "^0.6.1",
39+
"@types/mime-types": "^2.1.4",
40+
"@types/node": "^22.13.10",
3941
"@types/semver": "^7.5.8",
40-
"eslint": "^9.21.0",
42+
"eslint": "^9.22.0",
43+
"mime-types": "^2.1.35",
4144
"postcss-html": "^1.8.0",
4245
"postcss-scss": "^4.0.9",
4346
"sass": "^1.85.1",
@@ -51,6 +54,7 @@
5154
"typescript": "^5.8.2",
5255
"vue-router": "^4.5.0",
5356
"vue-tsc": "^2.2.8",
57+
"workbox-build": "^7.3.0",
5458
"workbox-core": "^7.3.0",
5559
"workbox-precaching": "^7.3.0",
5660
"workbox-routing": "^7.3.0",

pnpm-lock.yaml

Lines changed: 883 additions & 876 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/header/import-export.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { IconDownload, IconUpload } from "@tabler/icons-vue";
1616
import dayjs from "dayjs";
1717
import { downloadFile, readFile } from "@/helpers/file";
1818
import { isValidJSON } from "@/helpers/validate";
19-
import { useRepositoriesStore } from "@/store/repositories";
19+
import { isExportedRepository, useRepositoriesStore, type ExportedRepository } from "@/store/repositories";
2020
import IconLoader from "../icon-loader.vue";
2121
2222
defineProps<{ noData: boolean }>();
@@ -28,9 +28,18 @@ const isImporting = ref<boolean>(false);
2828
whenever(files, async ({ 0: payload }) => {
2929
const content = await readFile(payload).then(String);
3030
if (!isValidJSON(content)) throw new Error("Invalid JSON");
31+
32+
const parsedData = JSON.parse(content);
33+
if (!Array.isArray(parsedData)) throw new Error("Invalid import data");
34+
const importData = parsedData.reduce((acc: ExportedRepository[], repo) => {
35+
if (isExportedRepository(repo)) acc.push(repo);
36+
return acc;
37+
}, []);
38+
if (!importData.length) throw new Error("Invalid import data");
39+
3140
try {
3241
isImporting.value = true;
33-
await importRepositories(JSON.parse(content));
42+
await importRepositories(importData);
3443
} finally {
3544
isImporting.value = false;
3645
}

src/components/header/main-header.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
<script setup lang="ts">
2828
import { ref } from "vue";
2929
import { IconActivityHeartbeat, IconProgressAlert } from "@tabler/icons-vue";
30-
import { clearCachedRequests } from "@/service/memoize";
31-
import { fetchRateLimit, rateLimit } from "@/service/octokit";
30+
import { fetchRateLimit, fetchRepositoryFiles, rateLimit } from "@/service/octokit";
3231
import { useEventsStore } from "@/store/events";
3332
import { useLatestVersionsStore } from "@/store/latest-versions";
3433
import { useRepositoriesStore } from "@/store/repositories";
@@ -49,7 +48,7 @@ const isUpdating = ref<boolean>(false);
4948
async function update(): Promise<void> {
5049
try {
5150
isUpdating.value = true;
52-
clearCachedRequests();
51+
fetchRepositoryFiles.clear();
5352
await Promise.all([updateRepositories(), updateLatestVersions(), updateEvents()]);
5453
} finally {
5554
isUpdating.value = false;

src/components/header/user-repos.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,17 @@ import { fetchCurrentUserRepos } from "@/service/octokit";
5959
import { useRepositoriesStore } from "@/store/repositories";
6060
import { useSettingsStore } from "@/store/settings";
6161
import type { Repository } from "@/composable/useRepo";
62-
import type { UserRepositoriesResponse } from "@/types/repo";
62+
import type { UserReposResponse } from "@/types/repo";
63+
64+
type RawRepo = UserReposResponse["data"][number];
6365
6466
defineProps<{ progress: { current: number, total: number } }>();
6567
defineEmits<{ submit: [repos: Repository[]] }>();
6668
6769
const { repositories } = useRepositoriesStore();
6870
const { settings } = useSettingsStore();
6971
70-
const userRepos = ref<UserRepositoriesResponse>([]);
72+
const userRepos = ref<RawRepo[]>([]);
7173
const isLoading = ref(false);
7274
onBeforeMount(async () => {
7375
if (settings.value.authToken) {

src/composable/useRepo.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { computed, type Ref } from "vue";
2-
import type { PackageJson } from "type-fest";
3-
import type { RepositoryResponse } from "@/types/repo";
2+
import type { PackageJson, Simplify } from "type-fest";
3+
import type { RepoResponse } from "@/types/repo";
44

55
interface Integrations {
66
uptimerobotKey?: string
@@ -11,10 +11,10 @@ interface Integrations {
1111
packageManager?: string
1212
}
1313

14-
export interface Repository extends RepositoryResponse {
14+
export type Repository = Simplify<RepoResponse["data"] & {
1515
dependencies: NonNullable<PackageJson.Dependency> | null
1616
integrations: Integrations
17-
}
17+
}>;
1818

1919
export function useRepository(data: Ref<Repository>) {
2020
const hostingName = computed<string | null>(() => {

src/helpers/file.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import mimeType from "mime-types";
2+
13
export function readFile(file: File): Promise<string | ArrayBuffer> {
24
return new Promise((resolve, reject) => {
35
const reader = new FileReader();
@@ -8,16 +10,12 @@ export function readFile(file: File): Promise<string | ArrayBuffer> {
810
});
911
}
1012

11-
export function downloadFile(
12-
data: BlobPart,
13-
fileName: HTMLAnchorElement["download"],
14-
type: BlobPropertyBag["type"] = "text/json"
15-
): void {
16-
const blob = new Blob([data], { type });
17-
const element = window.document.createElement("a");
18-
element.href = window.URL.createObjectURL(blob);
19-
element.download = fileName;
20-
document.body.appendChild(element);
21-
element.click();
22-
document.body.removeChild(element);
13+
export function downloadFile(data: BlobPart, fileName: File["name"], type: File["type"]): void {
14+
const blob = data instanceof Blob ? data : new Blob([data], { type });
15+
const link = window.document.createElement("a");
16+
const fileExtension = mimeType.extension(type);
17+
link.href = window.URL.createObjectURL(blob);
18+
link.download = `${fileName}.${fileExtension}`;
19+
link.click();
20+
link.remove();
2321
}

src/helpers/object.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ export function deepEqual<T extends Record<string, any>>(a: T | null, b: T | nul
2121
}
2222

2323
export function deepCopy<T>(object: T): WritableDeep<T> {
24-
return JSON.parse(JSON.stringify(object));
24+
return JSON.parse(JSON.stringify(object)) as WritableDeep<T>;
2525
}

src/service/memoize.ts

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)