diff --git a/app/components/AttachmentItem.vue b/app/components/AttachmentItem.vue
index 51177f9..ad47598 100644
--- a/app/components/AttachmentItem.vue
+++ b/app/components/AttachmentItem.vue
@@ -6,8 +6,9 @@
diff --git a/app/pages/index.vue b/app/pages/index.vue
index f2bdca6..8c4da15 100644
--- a/app/pages/index.vue
+++ b/app/pages/index.vue
@@ -42,6 +42,7 @@
import { computed, onMounted, ref } from 'vue'
import { useUserStore } from '~/stores/user'
import { useSolarNetwork } from '~/composables/useSolarNetwork'
+import type { SnVersion, SnActivity } from '~/types/api'
import PostEditor from '~/components/PostEditor.vue'
import PostItem from '~/components/PostItem.vue'
@@ -50,17 +51,17 @@ const router = useRouter()
const userStore = useUserStore()
-const version = ref(null)
+const version = ref(null)
async function fetchVersion() {
const api = useSolarNetwork()
const resp = await api('/sphere/version')
- version.value = resp
+ version.value = resp as SnVersion
}
onMounted(() => fetchVersion())
const loading = ref(false)
-const activites = ref([])
+const activites = ref([])
const activitesLast = computed(() => activites.value[Math.max(activites.value.length - 1, 0)])
const activitesHasMore = ref(true)
@@ -74,7 +75,7 @@ async function fetchActivites() {
? '/sphere/activities'
: `/sphere/activities?cursor=${new Date(activitesLast.value.created_at).toISOString()}`,
)
- const data = resp
+ const data = resp as SnActivity[]
activites.value = [...activites.value, ...data]
activitesHasMore.value = data[0]?.type != 'empty'
loading.value = false
diff --git a/app/stores/pub.ts b/app/stores/pub.ts
index 45e7cc9..82278cf 100644
--- a/app/stores/pub.ts
+++ b/app/stores/pub.ts
@@ -1,14 +1,15 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { useSolarNetwork } from '~/composables/useSolarNetwork'
+import type { SnPublisher } from '~/types/api'
export const usePubStore = defineStore('pub', () => {
- const publishers = ref([])
+ const publishers = ref([])
async function fetchPublishers() {
const api = useSolarNetwork()
const resp = await api('/publishers')
- publishers.value = resp as any[]
+ publishers.value = resp as SnPublisher[]
}
return { publishers, fetchPublishers }
diff --git a/app/stores/user.ts b/app/stores/user.ts
index f399293..a63e8fa 100644
--- a/app/stores/user.ts
+++ b/app/stores/user.ts
@@ -1,10 +1,11 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useSolarNetwork } from '~/composables/useSolarNetwork'
+import type { SnAccount } from '~/types/api'
export const useUserStore = defineStore('user', () => {
// State
- const user = ref(null)
+ const user = ref(null)
const isLoading = ref(false)
const error = ref(null)
@@ -20,9 +21,9 @@ export const useUserStore = defineStore('user', () => {
try {
const response = await api('/id/accounts/me')
- user.value = response
- } catch (e: any) {
- error.value = e.message
+ user.value = response as SnAccount
+ } catch (e: unknown) {
+ error.value = e instanceof Error ? e.message : 'An error occurred'
user.value = null // Clear user data on error
} finally {
isLoading.value = false
diff --git a/app/types/api/activity.ts b/app/types/api/activity.ts
new file mode 100644
index 0000000..cf903b2
--- /dev/null
+++ b/app/types/api/activity.ts
@@ -0,0 +1,14 @@
+import type { SnPost } from './post'
+
+// Activity interface (main response structure)
+export interface SnActivity {
+ id: string;
+ type: string;
+ resource_identifier: string;
+ meta: Record;
+ data: SnPost;
+ visibility: number;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
diff --git a/app/types/api/index.ts b/app/types/api/index.ts
new file mode 100644
index 0000000..b403f8d
--- /dev/null
+++ b/app/types/api/index.ts
@@ -0,0 +1,6 @@
+// Re-export all types from separate files for easy importing
+export type { SnFileMeta, SnAttachment, SnPost } from './post'
+export type { SnVerification, SnPublisher } from './publisher'
+export type { SnActivity } from './activity'
+export type { SnVersion } from './version'
+export type { SnAccountLink, SnAccountBadge, SnAccountPerkSubscription, SnAccountProfile, SnAccount } from './user'
diff --git a/app/types/api/post.ts b/app/types/api/post.ts
new file mode 100644
index 0000000..97d6bc0
--- /dev/null
+++ b/app/types/api/post.ts
@@ -0,0 +1,83 @@
+// File metadata interface
+import type { SnPublisher } from './publisher'
+
+export interface SnFileMeta {
+ blur?: string;
+ exif?: Record;
+ xres?: number;
+ yres?: number;
+ bands?: number;
+ ratio?: number;
+ width?: number;
+ coding?: number;
+ format?: number | string;
+ height?: number;
+ xoffset?: number;
+ yoffset?: number;
+ filename?: string | null;
+ orientation?: number;
+ 'vips-loader'?: string;
+ interpretation?: number;
+ 'bits-per-sample'?: number;
+ 'resolution-unit'?: string;
+}
+
+// Attachment interface
+export interface SnAttachment {
+ id: string;
+ name: string;
+ file_meta: SnFileMeta;
+ user_meta: Record | null;
+ sensitive_marks: string[];
+ mime_type: string;
+ hash: string;
+ size: number;
+ has_compression: boolean;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
+
+// Post interface
+export interface SnPost {
+ id: string;
+ title: string;
+ description: string;
+ slug: string | null;
+ edited_at: string | null;
+ published_at: string;
+ visibility: number;
+ content: string;
+ type: number;
+ pin_mode: unknown | null;
+ meta: unknown | null;
+ sensitive_marks: string[];
+ embed_view: unknown | null;
+ views_unique: number;
+ views_total: number;
+ upvotes: number;
+ downvotes: number;
+ awarded_score: number;
+ reactions_count: Record;
+ replies_count: number;
+ reactions_made: Record;
+ replied_gone: boolean;
+ forwarded_gone: boolean;
+ replied_post_id: string | null;
+ replied_post: SnPost | null;
+ forwarded_post_id: string | null;
+ forwarded_post: SnPost | null;
+ realm_id: string | null;
+ realm: unknown | null;
+ attachments: SnAttachment[];
+ publisher_id: string;
+ publisher: SnPublisher;
+ awards: unknown | null;
+ tags: string[];
+ categories: string[];
+ is_truncated: boolean;
+ resource_identifier: string;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
diff --git a/app/types/api/publisher.ts b/app/types/api/publisher.ts
new file mode 100644
index 0000000..8b5f278
--- /dev/null
+++ b/app/types/api/publisher.ts
@@ -0,0 +1,30 @@
+import type { SnAttachment } from './post'
+
+// Verification interface
+export interface SnVerification {
+ type: number;
+ title: string;
+ description: string;
+ verified_by: string;
+}
+
+// Publisher interface
+export interface SnPublisher {
+ id: string;
+ type: number;
+ name: string;
+ nick: string;
+ bio: string;
+ picture_id: string;
+ background_id: string;
+ picture: SnAttachment | null;
+ background: SnAttachment | null;
+ verification: SnVerification | null;
+ account_id: string;
+ realm_id: string | null;
+ account: unknown | null;
+ resource_identifier: string;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
diff --git a/app/types/api/user.ts b/app/types/api/user.ts
new file mode 100644
index 0000000..3b24f57
--- /dev/null
+++ b/app/types/api/user.ts
@@ -0,0 +1,92 @@
+import type { SnAttachment } from './post'
+import type { SnVerification } from './publisher'
+
+// Account link interface
+export interface SnAccountLink {
+ name: string;
+ url: string;
+}
+
+// Account badge interface
+export interface SnAccountBadge {
+ id: string;
+ type: string;
+ label: string | null;
+ caption: string | null;
+ meta: Record;
+ activated_at: string;
+ expired_at: string | null;
+ account_id: string;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
+
+// Account perk subscription interface
+export interface SnAccountPerkSubscription {
+ id: string;
+ identifier: string;
+ begun_at: string;
+ ended_at: string;
+ is_active: boolean;
+ is_available: boolean;
+ is_free_trial: boolean;
+ status: number;
+ base_price: number;
+ final_price: number;
+ renewal_at: string;
+ account_id: string;
+ display_name: string;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
+
+// Account profile interface
+export interface SnAccountProfile {
+ id: string;
+ first_name: string;
+ middle_name: string;
+ last_name: string;
+ bio: string;
+ gender: string;
+ pronouns: string;
+ time_zone: string;
+ location: string;
+ links: SnAccountLink[];
+ birthday: string;
+ last_seen_at: string;
+ verification: SnVerification | null;
+ active_badge: unknown | null;
+ experience: number;
+ level: number;
+ social_credits: number;
+ social_credits_level: number;
+ leveling_progress: number;
+ picture: SnAttachment | null;
+ background: SnAttachment | null;
+ account_id: string;
+ resource_identifier: string;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
+
+// Account interface
+export interface SnAccount {
+ id: string;
+ name: string;
+ nick: string;
+ language: string;
+ region: string;
+ activated_at: string;
+ is_superuser: boolean;
+ automated_id: string | null;
+ profile: SnAccountProfile;
+ contacts: unknown[];
+ badges: SnAccountBadge[];
+ perk_subscription: SnAccountPerkSubscription | null;
+ created_at: string;
+ updated_at: string;
+ deleted_at: string | null;
+}
diff --git a/app/types/api/version.ts b/app/types/api/version.ts
new file mode 100644
index 0000000..f7e5687
--- /dev/null
+++ b/app/types/api/version.ts
@@ -0,0 +1,6 @@
+// Version interface
+export interface SnVersion {
+ version: string;
+ commit: string;
+ updatedAt: string;
+}
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 042ccb5..a252638 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -5,7 +5,8 @@ export default withNuxt(
// Your custom configs here
{
rules: {
- 'vue/multi-word-component-names': 'off'
+ 'vue/multi-word-component-names': 'off',
+ 'vue/no-v-html': 'off'
}
}
)