diff --git a/package.json b/package.json index d0a3a68f..ce477a1a 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,8 @@ "react-navigation-shared-element": "^3.1.3", "rn-slick-bottom-tabs": "^1.1.1", "styled-components": "^5.3.6", - "yarn": "^1.22.19" + "yarn": "^1.22.19", + "zod": "^3.21.4" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/src/api/HttpClient.ts b/src/api/HttpClient.ts index 8b9a7461..c235a506 100644 --- a/src/api/HttpClient.ts +++ b/src/api/HttpClient.ts @@ -6,10 +6,11 @@ import axios, { AxiosResponse, InternalAxiosRequestConfig, } from "axios" -import { PolimiToken, PoliNetworkToken, Tokens } from "contexts/login" +import { PolimiToken, PoliNetworkToken, Tokens, tokensSchema } from "./schemas" import AsyncStorage from "@react-native-async-storage/async-storage" import { wait } from "utils/functions" import { Alert } from "react-native" +import { z } from "zod" /*Docs used to make this: Singleton: @@ -76,9 +77,14 @@ declare module "axios" { waitingTime?: number //seconds readonly retryCount?: number authType?: AuthType + zodSchema?: z.ZodSchema } } +type InferrableAxiosRequestConfig = AxiosRequestConfig & { + zodSchema?: z.ZodSchema +} + /** * Singleton object which manages requests and retries * to PoliNetwork Server and Polimi Server. @@ -188,6 +194,9 @@ export class HttpClient extends EventEmitter { * does (or will do) something before `.then` is called * */ private _handleResponse = (res: AxiosResponse): AxiosResponse => { + if (res.config.zodSchema) { + res.config.zodSchema.parse(res.data) + } return res } @@ -289,7 +298,9 @@ export class HttpClient extends EventEmitter { throw error } - callPolimi(options: AxiosRequestConfig): CancellableApiRequest { + callPolimi( + options: InferrableAxiosRequestConfig + ): CancellableApiRequest { const controller = new AbortController() const request = this.polimiInstance.request({ ...options, @@ -302,7 +313,7 @@ export class HttpClient extends EventEmitter { } callPoliNetwork( - options: AxiosRequestConfig + options: InferrableAxiosRequestConfig ): CancellableApiRequest { const controller = new AbortController() const request = this.poliNetworkInstance.request({ @@ -315,7 +326,9 @@ export class HttpClient extends EventEmitter { return request } - callGeneral(options: AxiosRequestConfig): CancellableApiRequest { + callGeneral( + options: InferrableAxiosRequestConfig + ): CancellableApiRequest { const controller = new AbortController() const request = this.generalInstance.request({ ...options, @@ -419,8 +432,7 @@ export class HttpClient extends EventEmitter { async loadTokens() { const tokens = await AsyncStorage.getItem("api:tokens") if (tokens) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const parsedTokens: Tokens = JSON.parse(tokens) + const parsedTokens: Tokens = tokensSchema.parse(JSON.parse(tokens)) console.log("Loaded tokens from local storage") this.polimiToken = parsedTokens.polimiToken this.poliNetworkToken = parsedTokens.poliNetworkToken diff --git a/src/api/collections/articles.ts b/src/api/collections/articles.ts index 526a319f..b628bd47 100644 --- a/src/api/collections/articles.ts +++ b/src/api/collections/articles.ts @@ -2,54 +2,7 @@ import { mapAxiosRequest } from "api/mapAxiosRequest" import { ApiCollection } from "api/useApiCall" import { HttpClient, RequestOptions } from "../HttpClient" - -export interface Tags { - tags: Tag[] -} - -export interface Tag { - name: string - image: string - blurhash: string -} - -export interface Articles { - articles: Article[] - start: string | null - end: string | null - tag: string | null - author_id: number | null - title: string | null -} -interface ArticleAuthor { - name?: string - link?: string - image?: string -} - -export interface Article { - id: number - tag_id: string - latitude?: number - longitude?: number - publish_time: string - target_time?: string - hidden_until?: string - content: { - it?: ArticleParams - en?: ArticleParams - } - image?: string - blurhash?: string - author?: ArticleAuthor -} - -interface ArticleParams { - content: string - title: string - subtitle: string - url: string -} +import { articlesSchema, tagsSchema } from "api/schemas" const client = HttpClient.getInstance() @@ -86,7 +39,7 @@ export const articles = { params: { tag: string; limit: number; offset: number }, options?: RequestOptions ) { - const request = client.callPoliNetwork({ + const request = client.callPoliNetwork({ url: "/v1/articles", method: "GET", params: { @@ -96,6 +49,7 @@ export const articles = { tag: params.tag, sort: "date", }, + zodSchema: articlesSchema, ...options, }) return mapAxiosRequest(request, res => res.articles) @@ -109,10 +63,11 @@ export const articles = { * @param options see {@link RequestOptions} */ getLastArticleByTag(params: { tag: string }, options?: RequestOptions) { - const request = client.callPoliNetwork({ + const request = client.callPoliNetwork({ url: "/v1/articles", method: "GET", params: { tag: params.tag, limit: 1, sort: "date", platform: 1 }, + zodSchema: articlesSchema, ...options, }) return mapAxiosRequest(request, res => res.articles[0]) @@ -122,9 +77,10 @@ export const articles = { * Retrieves Tags (news categories) from PoliNetwork server. */ getTags(_params?: Record, options?: RequestOptions) { - const request = client.callPoliNetwork({ + const request = client.callPoliNetwork({ url: "/v1/tags", method: "GET", + zodSchema: tagsSchema, ...options, }) diff --git a/src/api/collections/auth.ts b/src/api/collections/auth.ts index 35fd7876..8e9b8115 100644 --- a/src/api/collections/auth.ts +++ b/src/api/collections/auth.ts @@ -1,7 +1,7 @@ import { mapAxiosRequest } from "api/mapAxiosRequest" import { ApiCollection } from "api/useApiCall" -import { PolimiToken } from "contexts/login" import { HttpClient, RequestOptions } from "../HttpClient" +import { polimiTokenSchema } from "api/schemas" const client = HttpClient.getInstance() @@ -15,13 +15,14 @@ export const auth = { * @returns polimi accessToken and refreshToken */ getPolimiToken(params: { authcode: string }, options?: RequestOptions) { - const request = client.callPolimi({ + const request = client.callPolimi({ url: `/rest/jaf/oauth/token/get/${params.authcode}`, method: "GET", - ...options, headers: { accept: "application/json", }, + zodSchema: polimiTokenSchema, + ...options, }) return mapAxiosRequest(request, res => res) }, diff --git a/src/api/collections/event.ts b/src/api/collections/event.ts index 1ff465db..71828032 100644 --- a/src/api/collections/event.ts +++ b/src/api/collections/event.ts @@ -1,102 +1,7 @@ import { mapAxiosRequest } from "api/mapAxiosRequest" import { ApiCollection } from "api/useApiCall" import { AuthType, HttpClient, RequestOptions } from "../HttpClient" -import { EventType } from "utils/events" - -/* eslint-disable @typescript-eslint/naming-convention */ -export interface Event { - event_id: number - date_start: string - date_end: string - show_agenda: boolean - matricola?: string - title: { - it: string - en: string - } - event_type: { - typeId: EventType - type_dn: { - it: string - en: string - } - } - event_subtype?: string - calendar: { - calendar_id: number - calendar_dn: { - it: string - en: string - } - } - room?: { - room_id: number - acronym_dn: string - classroom_id: number - room_dn: string - } - //used by Timetable to store color - lectureColor?: string -} - -export interface RemoteLink { - url: string - link_description: { - it: string - en: string - } -} - -export interface Lecture { - event_id: number - room_id: number - date_start: string - date_end: string - class_code: number - teaching_description: { - it: string - en: string - } - lecturer: string - lecture_type: string - event_type: { - typeId: number - type_dn: { - it: string - en: string - } - } - calendar: { - calendar_id: number - calendar_dn: { - it: string - en: string - } - } - room: { - room_id: number - campus: string - address: string - floor: string - building: string - type: string - acronym_dn: string - coordinates: { - latitude: number - longitude: number - } - csi_id: string - csi_parent_id: string - classroom_id: number - room_dn: string - } - remote_links: RemoteLink[] -} - -export interface LectureDetails { - lecture: Lecture - personal_event: Event -} +import { eventSchema, lectureDetailsSchema } from "api/schemas" const client = HttpClient.getInstance() @@ -106,11 +11,13 @@ export const events = { options?: RequestOptions ) { const url = "/agenda/api/me/" + params.matricola + "/events" - const request = client.callPolimi({ + const request = client.callPolimi({ url, method: "GET", authType: AuthType.POLIMI, + // eslint-disable-next-line @typescript-eslint/naming-convention params: { start_date: params.startDate, n_events: params.nEvents }, + zodSchema: eventSchema.array(), ...options, }) return mapAxiosRequest(request, response => response) @@ -121,10 +28,11 @@ export const events = { options?: RequestOptions ) { const url = `/agenda/api/me/${params.matricola}/lectures/${params.eventId}` - const request = client.callPolimi({ + const request = client.callPolimi({ url, method: "GET", authType: AuthType.POLIMI, + zodSchema: lectureDetailsSchema, ...options, }) return mapAxiosRequest(request, response => response.lecture) diff --git a/src/api/collections/groups.ts b/src/api/collections/groups.ts index c933d363..c6ff0811 100644 --- a/src/api/collections/groups.ts +++ b/src/api/collections/groups.ts @@ -1,36 +1,8 @@ import { mapAxiosRequest } from "api/mapAxiosRequest" import { ApiCollection } from "api/useApiCall" import { HttpClient, RequestOptions } from "../HttpClient" - -/* eslint-disable @typescript-eslint/naming-convention */ - -export interface GroupOptions { - name?: string - year?: string - degree?: string - type?: string - platform?: string - language?: string - office?: string -} - -export interface Group { - class: string | null - office?: string - id: string - degree?: string - school?: string - id_link: string - language?: string - type?: string - year: string | null //probably I should use | null everywhere? - platform: string - permanentId?: number - LastUpdateInviteLinkTime?: string - linkfunzionante?: string - LinkType?: string - members?: string -} +import { groupSchema } from "api/schemas" +import { z } from "zod" const client = HttpClient.getInstance() @@ -44,12 +16,14 @@ export const groups = { */ getFromGithub(_params?: Record, options?: RequestOptions) { - const request = client.callGeneral<{ - index_data: Group[] - }>({ + const request = client.callGeneral({ url: "https://raw.githubusercontent.com/PoliNetworkOrg/polinetworkWebsiteData/main/groupsGenerated.json", method: "GET", ...options, + zodSchema: z.object({ + // eslint-disable-next-line @typescript-eslint/naming-convention + index_data: groupSchema.array(), + }), }) return mapAxiosRequest(request, response => response.index_data) }, diff --git a/src/api/schemas/articles.ts b/src/api/schemas/articles.ts new file mode 100644 index 00000000..d6ee22ef --- /dev/null +++ b/src/api/schemas/articles.ts @@ -0,0 +1,55 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { z } from "zod" + +export const tagSchema = z.object({ + name: z.string(), + image: z.string(), + blurhash: z.string(), +}) +export type Tag = z.infer + +export const tagsSchema = z.object({ + tags: z.array(tagSchema), +}) +export type Tags = z.infer + +const articleAuthorSchema = z.object({ + name: z.string().optional(), + link: z.string().optional(), + image: z.string().optional(), +}) + +const articlesParamsSchema = z.object({ + content: z.string(), + title: z.string(), + subtitle: z.string(), + url: z.string(), +}) + +export const articleSchema = z.object({ + id: z.number(), + tag_id: z.string(), + latitude: z.number().optional(), + longitude: z.number().optional(), + publish_time: z.string(), + target_time: z.string().optional(), + hidden_until: z.string().optional(), + content: z.object({ + it: articlesParamsSchema, + en: articlesParamsSchema, + }), + image: z.string().optional(), + blurhash: z.string().optional(), + author: articleAuthorSchema.optional(), +}) +export type Article = z.infer + +export const articlesSchema = z.object({ + articles: z.array(articleSchema), + start: z.string().optional(), + end: z.string().optional(), + tag: z.string().optional(), + author_id: z.number().optional(), + title: z.string().optional(), +}) +export type Articles = z.infer diff --git a/src/api/schemas/auth.ts b/src/api/schemas/auth.ts new file mode 100644 index 00000000..f58774fa --- /dev/null +++ b/src/api/schemas/auth.ts @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { z } from "zod" + +export const poliNetworkTokenSchema = z.object({ + access_token: z.string(), + expires_in: z.number(), + ext_expires_in: z.number(), + id_token: z.string(), + refresh_token: z.string(), + scope: z.string(), + token_type: z.string(), +}) +export type PoliNetworkToken = z.infer + +export const polimiTokenSchema = z.object({ + accessToken: z.string(), + expiresIn: z.number(), + refreshToken: z.string(), +}) +export type PolimiToken = z.infer + +export const tokensSchema = z.object({ + polimiToken: polimiTokenSchema, + poliNetworkToken: poliNetworkTokenSchema, +}) +export type Tokens = z.infer diff --git a/src/api/schemas/event.ts b/src/api/schemas/event.ts new file mode 100644 index 00000000..094bdd63 --- /dev/null +++ b/src/api/schemas/event.ts @@ -0,0 +1,80 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { z } from "zod" +import { translatedStringSchema } from "./generals" +import { EventType } from "utils/events" + +const eventTypeSchema = z.object({ + typeId: z.nativeEnum(EventType), + type_dn: translatedStringSchema, +}) + +const calendarTypeSchema = z.object({ + calendar_id: z.number(), + calendar_dn: translatedStringSchema, +}) + +export const eventSchema = z.object({ + event_id: z.number(), + date_start: z.string(), + date_end: z.string(), + show_agenda: z.boolean(), + matricola: z.string().optional(), + title: translatedStringSchema, + event_type: eventTypeSchema, + event_subtype: z.string().optional(), + calendar: calendarTypeSchema, + room: z + .object({ + room_id: z.number(), + acronym_dn: z.string(), + classroom_id: z.number(), + room_dn: z.string(), + }) + .optional(), + lectureColor: z.string().optional(), +}) +export type Event = z.infer + +export const remoteLinkSchema = z.object({ + url: z.string(), + link_description: translatedStringSchema, +}) +export type RemoteLink = z.infer + +export const lectureSchema = z.object({ + event_id: z.number(), + room_id: z.number(), + date_start: z.string(), + date_end: z.string(), + class_code: z.number(), + teaching_description: translatedStringSchema, + lecturer: z.string(), + lecture_type: z.string(), + event_type: eventTypeSchema, + calendar: calendarTypeSchema, + room: z.object({ + room_id: z.number(), + campus: z.string(), + address: z.string(), + floor: z.string(), + building: z.string(), + type: z.string(), + acronym_dn: z.string(), + coordinates: z.object({ + latitude: z.number(), + longitude: z.number(), + }), + csi_id: z.string(), + csi_parent_id: z.string(), + classroom_id: z.number(), + room_dn: z.string(), + }), + remote_links: z.array(remoteLinkSchema), +}) +export type Lecture = z.infer + +export const lectureDetailsSchema = z.object({ + lecture: lectureSchema, + personal_event: eventSchema, +}) +export type LectureDetails = z.infer diff --git a/src/api/schemas/generals.ts b/src/api/schemas/generals.ts new file mode 100644 index 00000000..2a57afc8 --- /dev/null +++ b/src/api/schemas/generals.ts @@ -0,0 +1,7 @@ +import { z } from "zod" + +export const translatedStringSchema = z.object({ + it: z.string(), + en: z.string(), +}) +export type TranslatedString = z.infer diff --git a/src/api/schemas/groups.ts b/src/api/schemas/groups.ts new file mode 100644 index 00000000..3c780c73 --- /dev/null +++ b/src/api/schemas/groups.ts @@ -0,0 +1,32 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { z } from "zod" + +export const groupOptionsSchema = z.object({ + name: z.string().optional(), + year: z.string().optional(), + degree: z.string().optional(), + type: z.string().optional(), + platform: z.string().optional(), + language: z.string().optional(), + office: z.string().optional(), +}) +export type GroupOptions = z.infer + +export const groupSchema = z.object({ + class: z.string().nullable(), + office: z.string().optional(), + id: z.string(), + degree: z.string().optional(), + school: z.string().optional(), + id_link: z.string(), + language: z.string().optional(), + type: z.string().optional(), + year: z.string().nullable(), + platform: z.string(), + permanentId: z.number().optional(), + LastUpdateInviteLinkTime: z.string().optional(), + linkfunzionante: z.string().optional(), + LinkType: z.string().optional(), + members: z.string().optional(), +}) +export type Group = z.infer diff --git a/src/api/schemas/index.ts b/src/api/schemas/index.ts new file mode 100644 index 00000000..2b43b23f --- /dev/null +++ b/src/api/schemas/index.ts @@ -0,0 +1,5 @@ +export * from "./articles" +export * from "./auth" +export * from "./event" +export * from "./generals" +export * from "./groups" diff --git a/src/components/Groups/ModalGroup.tsx b/src/components/Groups/ModalGroup.tsx index 500f8fe7..b77be568 100644 --- a/src/components/Groups/ModalGroup.tsx +++ b/src/components/Groups/ModalGroup.tsx @@ -1,7 +1,7 @@ import { FC } from "react" import { ViewStyle } from "react-native" import { usePalette } from "utils/colors" -import { Group } from "api/collections/groups" +import { Group } from "api/schemas" import { BodyText } from "components/Text" import { Modal } from "components/Modal" import { choosePlatformIcon } from "utils/groups" diff --git a/src/components/Home/News/NewsBottomSheet.tsx b/src/components/Home/News/NewsBottomSheet.tsx index 0d3d9c49..9a809ba2 100644 --- a/src/components/Home/News/NewsBottomSheet.tsx +++ b/src/components/Home/News/NewsBottomSheet.tsx @@ -5,7 +5,7 @@ import BottomSheet, { BottomSheetScrollViewMethods, } from "@gorhom/bottom-sheet" -import { Article } from "api/collections/articles" +import { Article } from "api/schemas" import { NewsPreferencesContext, Preference, diff --git a/src/components/Home/News/NewsManager.tsx b/src/components/Home/News/NewsManager.tsx index 132895f1..c8f55d14 100644 --- a/src/components/Home/News/NewsManager.tsx +++ b/src/components/Home/News/NewsManager.tsx @@ -1,7 +1,7 @@ import { useContext, useEffect, useState } from "react" import { api } from "api" -import { Article, Tag } from "api/collections/articles" +import { Article, Tag } from "api/schemas" import { TagWithData, NewsPreferencesContext, diff --git a/src/components/TimeTable/LectureCard.tsx b/src/components/TimeTable/LectureCard.tsx index e417f1f7..5b2382fd 100644 --- a/src/components/TimeTable/LectureCard.tsx +++ b/src/components/TimeTable/LectureCard.tsx @@ -1,7 +1,7 @@ import { BodyText } from "components/Text" import { FC, useEffect } from "react" import { Pressable, StyleSheet } from "react-native" -import { Event } from "api/collections/event" +import { Event } from "api/schemas" import { usePalette } from "utils/colors" import { ATTACHED_LECTURES_MARGIN, diff --git a/src/components/TimeTable/LectureInfo.tsx b/src/components/TimeTable/LectureInfo.tsx index 53f8e1d8..6a76c28d 100644 --- a/src/components/TimeTable/LectureInfo.tsx +++ b/src/components/TimeTable/LectureInfo.tsx @@ -2,7 +2,7 @@ import { BottomSheetScrollView } from "@gorhom/bottom-sheet" import { BodyText, Title } from "components/Text" import { FC, useContext, useMemo, useState } from "react" import { StyleSheet, View } from "react-native" -import { Event } from "api/collections/event" +import { Event } from "api/schemas" import { usePalette } from "utils/colors" import { TimetableDeducer, diff --git a/src/components/TimeTable/RemoteLinkButton.tsx b/src/components/TimeTable/RemoteLinkButton.tsx index 60230c14..4ed20e4e 100644 --- a/src/components/TimeTable/RemoteLinkButton.tsx +++ b/src/components/TimeTable/RemoteLinkButton.tsx @@ -1,4 +1,4 @@ -import { RemoteLink } from "api/collections/event" +import { RemoteLink } from "api/schemas" import { Icon } from "components/Icon" import { FC } from "react" import { Linking, Pressable } from "react-native" diff --git a/src/components/TimeTable/TimetableRow.tsx b/src/components/TimeTable/TimetableRow.tsx index 94881aa5..6e668dd0 100644 --- a/src/components/TimeTable/TimetableRow.tsx +++ b/src/components/TimeTable/TimetableRow.tsx @@ -1,6 +1,6 @@ import { FC } from "react" import { View } from "react-native" -import { Event } from "api/collections/event" +import { Event } from "api/schemas" import { ValidTableRow } from "utils/timetable" import { LectureCard } from "./LectureCard" import Animated, { diff --git a/src/contexts/login.ts b/src/contexts/login.ts index 029df325..b1fee293 100644 --- a/src/contexts/login.ts +++ b/src/contexts/login.ts @@ -3,27 +3,6 @@ import React from "react" /* eslint-disable @typescript-eslint/naming-convention */ -export interface PoliNetworkToken { - access_token: string - expires_in: number - ext_expires_in: number - id_token: string - refresh_token: string - scope: string - token_type: string -} - -export interface PolimiToken { - accessToken: string - expiresIn: number - refreshToken: string -} - -export interface Tokens { - polimiToken: PolimiToken - poliNetworkToken: PoliNetworkToken -} - export type LoginState = | { loggedIn: false diff --git a/src/contexts/newsPreferences.ts b/src/contexts/newsPreferences.ts index 27407618..10ebed67 100644 --- a/src/contexts/newsPreferences.ts +++ b/src/contexts/newsPreferences.ts @@ -1,5 +1,5 @@ import React from "react" -import { Tag } from "api/collections/articles" +import { Tag } from "api/schemas" export type TagWithData = Tag & { /** The column in which the card has to be inserted */ diff --git a/src/navigation/NavigationTypes.ts b/src/navigation/NavigationTypes.ts index b210d247..5f3f351a 100644 --- a/src/navigation/NavigationTypes.ts +++ b/src/navigation/NavigationTypes.ts @@ -22,7 +22,7 @@ import { useNavigation as nativeUseNav, } from "@react-navigation/native" import { StackScreenProps } from "@react-navigation/stack" -import { Article } from "api/collections/articles" +import { Article } from "api/schemas" import { Occupancies } from "api/collections/rooms" import { BuildingItem, diff --git a/src/pages/Groups.tsx b/src/pages/Groups.tsx index 22eddb40..48b20925 100644 --- a/src/pages/Groups.tsx +++ b/src/pages/Groups.tsx @@ -3,7 +3,7 @@ import { MainStackScreen } from "navigation/NavigationTypes" import { Linking, View } from "react-native" import { FiltersList } from "components/Groups/FiltersList" import { api } from "api" -import { Group } from "api/collections/groups" +import { Group } from "api/schemas" import { applyFilters, choosePlatformIcon, diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index 93f0c054..cf5b10c6 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -6,7 +6,11 @@ import WebView from "react-native-webview" import { usePalette } from "utils/colors" import { api } from "api" import { HttpClient } from "api/HttpClient" -import { PolimiToken, PoliNetworkToken } from "contexts/login" +import { + PolimiToken, + PoliNetworkToken, + poliNetworkTokenSchema, +} from "api/schemas" import { NavBar } from "components/NavBar" // TODO: HANDLE ERRORS, this will break as soon as something goes wrong @@ -132,8 +136,9 @@ export const Login: RootStackScreen<"Login"> = () => { if (url.startsWith(polinetworkTargetUrl)) { try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - setPoliNetworkToken(JSON.parse(data)) + setPoliNetworkToken( + poliNetworkTokenSchema.parse(JSON.parse(data)) + ) setCurrentURL(magicTokenUrl) } catch (e) { console.log("error while parsing!!") diff --git a/src/pages/TimeTable.tsx b/src/pages/TimeTable.tsx index 59dd0ea4..b0a6d358 100644 --- a/src/pages/TimeTable.tsx +++ b/src/pages/TimeTable.tsx @@ -10,7 +10,7 @@ import { Pressable, View } from "react-native" import { TimeLine } from "components/TimeTable/TimeLine" import { WeekLine } from "components/TimeTable/WeekLine" import { ScrollView } from "react-native-gesture-handler" -import { Event } from "api/collections/event" +import { Event } from "api/schemas" import { BodyText } from "components/Text" import { getUsableScreenHeight } from "utils/layout" import BottomSheet from "@gorhom/bottom-sheet" diff --git a/src/pages/news/ArticlesList.tsx b/src/pages/news/ArticlesList.tsx index 8c1b2cd4..fbe24e5b 100644 --- a/src/pages/news/ArticlesList.tsx +++ b/src/pages/news/ArticlesList.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useRef, useContext } from "react" import { View } from "react-native" import { api, RetryType } from "api" -import { Article } from "api/collections/articles" +import { Article } from "api/schemas" import { MainStackScreen, useNavigation } from "navigation/NavigationTypes" import { CardWithGradient } from "components/CardWithGradient" import { capitalize } from "utils/functions" diff --git a/src/utils/articles.ts b/src/utils/articles.ts index 8b37c94e..3a2ad05f 100644 --- a/src/utils/articles.ts +++ b/src/utils/articles.ts @@ -1,4 +1,4 @@ -import { Article } from "api/collections/articles" +import { Article } from "api/schemas" const getArticleLanguage = (article: Article, language: string) => { if (language === "it") { diff --git a/src/utils/carousel.ts b/src/utils/carousel.ts index d5e76dde..3b589548 100644 --- a/src/utils/carousel.ts +++ b/src/utils/carousel.ts @@ -1,5 +1,5 @@ import { i18n } from "../locales/i18n" -import { Event } from "api/collections/event" +import { Event } from "api/schemas" import { EventType } from "./events" export interface CarouselItem { diff --git a/src/utils/groups.ts b/src/utils/groups.ts index a4568140..348681e9 100644 --- a/src/utils/groups.ts +++ b/src/utils/groups.ts @@ -1,4 +1,4 @@ -import { Group } from "api/collections/groups" +import { Group } from "api/schemas" import whatsapp from "assets/groups/whatsapp.svg" import facebook from "assets/groups/facebook.svg" import telegram from "assets/groups/telegram.svg" diff --git a/src/utils/notifications.ts b/src/utils/notifications.ts index 775ce3fa..048c492e 100644 --- a/src/utils/notifications.ts +++ b/src/utils/notifications.ts @@ -5,7 +5,7 @@ import { NotificationsChannels, ValidChannelId, } from "notifications/NotificationTypes" -import { Event } from "api/collections/event" +import { Event } from "api/schemas" import * as Notifications from "expo-notifications" export interface MinutesBeforeOptions { deadline?: number diff --git a/src/utils/timetable.ts b/src/utils/timetable.ts index fd4b1cc8..23b71115 100644 --- a/src/utils/timetable.ts +++ b/src/utils/timetable.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { api } from "api" -import { Event } from "api/collections/event" +import { Event } from "api/schemas" import * as FileSystem from "expo-file-system" import { EventType } from "./events" import { EventEmitter } from "events" diff --git a/yarn.lock b/yarn.lock index c3c7174b..e7bc1cbf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10960,3 +10960,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zod@^3.21.4: + version "3.21.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db" + integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==