mirror of
https://github.com/kennethnym/aris.git
synced 2026-03-20 09:01:19 +00:00
Compare commits
3 Commits
feat/sourc
...
refactor/r
| Author | SHA1 | Date | |
|---|---|---|---|
|
963bf073d1
|
|||
| c0b3db0e11 | |||
|
ca4a337dcd
|
@@ -13,8 +13,6 @@
|
|||||||
"@aris/source-location": "workspace:*",
|
"@aris/source-location": "workspace:*",
|
||||||
"@aris/source-tfl": "workspace:*",
|
"@aris/source-tfl": "workspace:*",
|
||||||
"@aris/source-weatherkit": "workspace:*",
|
"@aris/source-weatherkit": "workspace:*",
|
||||||
"@hono/trpc-server": "^0.3",
|
|
||||||
"@trpc/server": "^11",
|
|
||||||
"arktype": "^2.1.29",
|
"arktype": "^2.1.29",
|
||||||
"better-auth": "^1",
|
"better-auth": "^1",
|
||||||
"hono": "^4",
|
"hono": "^4",
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
import type { Context, Next } from "hono"
|
import type { Context, Next } from "hono"
|
||||||
|
|
||||||
|
import type { AuthSession, AuthUser } from "./session.ts"
|
||||||
|
|
||||||
import { auth } from "./index.ts"
|
import { auth } from "./index.ts"
|
||||||
|
|
||||||
type SessionUser = typeof auth.$Infer.Session.user
|
|
||||||
type Session = typeof auth.$Infer.Session.session
|
|
||||||
|
|
||||||
export interface SessionVariables {
|
export interface SessionVariables {
|
||||||
user: SessionUser | null
|
user: AuthUser | null
|
||||||
session: Session | null
|
session: AuthSession | null
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "hono" {
|
||||||
|
interface ContextVariableMap extends SessionVariables {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +51,7 @@ export async function requireSession(c: Context, next: Next): Promise<Response |
|
|||||||
*/
|
*/
|
||||||
export async function getSessionFromHeaders(
|
export async function getSessionFromHeaders(
|
||||||
headers: Headers,
|
headers: Headers,
|
||||||
): Promise<{ user: SessionUser; session: Session } | null> {
|
): Promise<{ user: AuthUser; session: AuthSession } | null> {
|
||||||
const session = await auth.api.getSession({ headers })
|
const session = await auth.api.getSession({ headers })
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|||||||
4
apps/aris-backend/src/auth/session.ts
Normal file
4
apps/aris-backend/src/auth/session.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import type { auth } from "./index.ts"
|
||||||
|
|
||||||
|
export type AuthUser = typeof auth.$Infer.Session.user
|
||||||
|
export type AuthSession = typeof auth.$Infer.Session.session
|
||||||
56
apps/aris-backend/src/location/http.ts
Normal file
56
apps/aris-backend/src/location/http.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import type { Context, Hono } from "hono"
|
||||||
|
|
||||||
|
import { type } from "arktype"
|
||||||
|
import { createMiddleware } from "hono/factory"
|
||||||
|
|
||||||
|
import type { UserSessionManager } from "../session/index.ts"
|
||||||
|
|
||||||
|
import { requireSession } from "../auth/session-middleware.ts"
|
||||||
|
|
||||||
|
type Env = { Variables: { sessionManager: UserSessionManager } }
|
||||||
|
|
||||||
|
const locationInput = type({
|
||||||
|
lat: "number",
|
||||||
|
lng: "number",
|
||||||
|
accuracy: "number",
|
||||||
|
timestamp: "string.date.iso",
|
||||||
|
})
|
||||||
|
|
||||||
|
export function registerLocationHttpHandlers(
|
||||||
|
app: Hono,
|
||||||
|
{ sessionManager }: { sessionManager: UserSessionManager },
|
||||||
|
) {
|
||||||
|
const inject = createMiddleware<Env>(async (c, next) => {
|
||||||
|
c.set("sessionManager", sessionManager)
|
||||||
|
await next()
|
||||||
|
})
|
||||||
|
|
||||||
|
app.post("/api/location", inject, requireSession, handleUpdateLocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleUpdateLocation(c: Context<Env>) {
|
||||||
|
let body: unknown
|
||||||
|
try {
|
||||||
|
body = await c.req.json()
|
||||||
|
} catch {
|
||||||
|
return c.json({ error: "Invalid JSON" }, 400)
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = locationInput(body)
|
||||||
|
|
||||||
|
if (result instanceof type.errors) {
|
||||||
|
return c.json({ error: result.summary }, 400)
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = c.get("user")!
|
||||||
|
const sessionManager = c.get("sessionManager")
|
||||||
|
const session = sessionManager.getOrCreate(user.id)
|
||||||
|
await session.engine.executeAction("aris.location", "update-location", {
|
||||||
|
lat: result.lat,
|
||||||
|
lng: result.lng,
|
||||||
|
accuracy: result.accuracy,
|
||||||
|
timestamp: new Date(result.timestamp),
|
||||||
|
})
|
||||||
|
|
||||||
|
return c.body(null, 204)
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { type } from "arktype"
|
|
||||||
|
|
||||||
import type { UserSessionManager } from "../session/index.ts"
|
|
||||||
import type { TRPC } from "../trpc/router.ts"
|
|
||||||
|
|
||||||
const locationInput = type({
|
|
||||||
lat: "number",
|
|
||||||
lng: "number",
|
|
||||||
accuracy: "number",
|
|
||||||
timestamp: "Date",
|
|
||||||
})
|
|
||||||
|
|
||||||
export function createLocationRouter(
|
|
||||||
t: TRPC,
|
|
||||||
{ sessionManager }: { sessionManager: UserSessionManager },
|
|
||||||
) {
|
|
||||||
return t.router({
|
|
||||||
update: t.procedure.input(locationInput).mutation(async ({ input, ctx }) => {
|
|
||||||
const session = sessionManager.getOrCreate(ctx.user.id)
|
|
||||||
await session.engine.executeAction("aris.location", "update-location", {
|
|
||||||
lat: input.lat,
|
|
||||||
lng: input.lng,
|
|
||||||
accuracy: input.accuracy,
|
|
||||||
timestamp: input.timestamp,
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
import { LocationSource } from "@aris/source-location"
|
import { LocationSource } from "@aris/source-location"
|
||||||
import { trpcServer } from "@hono/trpc-server"
|
|
||||||
import { Hono } from "hono"
|
import { Hono } from "hono"
|
||||||
|
|
||||||
import { registerAuthHandlers } from "./auth/http.ts"
|
import { registerAuthHandlers } from "./auth/http.ts"
|
||||||
|
import { registerLocationHttpHandlers } from "./location/http.ts"
|
||||||
import { UserSessionManager } from "./session/index.ts"
|
import { UserSessionManager } from "./session/index.ts"
|
||||||
import { WeatherSourceProvider } from "./weather/provider.ts"
|
import { WeatherSourceProvider } from "./weather/provider.ts"
|
||||||
import { createContext } from "./trpc/context.ts"
|
|
||||||
import { createTRPCRouter } from "./trpc/router.ts"
|
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
const sessionManager = new UserSessionManager([
|
const sessionManager = new UserSessionManager([
|
||||||
@@ -21,21 +19,12 @@ function main() {
|
|||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
|
||||||
const trpcRouter = createTRPCRouter({ sessionManager })
|
|
||||||
|
|
||||||
const app = new Hono()
|
const app = new Hono()
|
||||||
|
|
||||||
app.get("/health", (c) => c.json({ status: "ok" }))
|
app.get("/health", (c) => c.json({ status: "ok" }))
|
||||||
|
|
||||||
registerAuthHandlers(app)
|
registerAuthHandlers(app)
|
||||||
|
registerLocationHttpHandlers(app, { sessionManager })
|
||||||
app.use(
|
|
||||||
"/trpc/*",
|
|
||||||
trpcServer({
|
|
||||||
router: trpcRouter,
|
|
||||||
createContext,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
import type { WeatherKitClient, WeatherKitResponse } from "@aris/source-weatherkit"
|
||||||
|
|
||||||
import { LocationSource } from "@aris/source-location"
|
import { LocationSource } from "@aris/source-location"
|
||||||
import { describe, expect, mock, test } from "bun:test"
|
import { describe, expect, mock, test } from "bun:test"
|
||||||
|
|
||||||
import { WeatherSourceProvider } from "../weather/provider.ts"
|
import { WeatherSourceProvider } from "../weather/provider.ts"
|
||||||
import { UserSessionManager } from "./user-session-manager.ts"
|
import { UserSessionManager } from "./user-session-manager.ts"
|
||||||
|
|
||||||
import type { WeatherKitClient, WeatherKitResponse } from "@aris/source-weatherkit"
|
|
||||||
|
|
||||||
const mockWeatherClient: WeatherKitClient = {
|
const mockWeatherClient: WeatherKitClient = {
|
||||||
fetch: async () => ({}) as WeatherKitResponse,
|
fetch: async () => ({}) as WeatherKitResponse,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { FeedSourceProviderInput } from "./feed-source-provider.ts"
|
import type { FeedSourceProviderInput } from "./feed-source-provider.ts"
|
||||||
|
|
||||||
import { UserSession } from "./user-session.ts"
|
import { UserSession } from "./user-session.ts"
|
||||||
|
|
||||||
export class UserSessionManager {
|
export class UserSessionManager {
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
import type { FetchCreateContextFnOptions } from "@trpc/server/adapters/fetch"
|
|
||||||
|
|
||||||
import { auth } from "../auth/index.ts"
|
|
||||||
|
|
||||||
export async function createContext(opts: FetchCreateContextFnOptions) {
|
|
||||||
const session = await auth.api.getSession({ headers: opts.req.headers })
|
|
||||||
|
|
||||||
return {
|
|
||||||
user: session?.user ?? null,
|
|
||||||
session: session?.session ?? null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Context = Awaited<ReturnType<typeof createContext>>
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import { initTRPC, TRPCError } from "@trpc/server"
|
|
||||||
|
|
||||||
import type { UserSessionManager } from "../session/index.ts"
|
|
||||||
import type { Context } from "./context.ts"
|
|
||||||
|
|
||||||
import { createLocationRouter } from "../location/router.ts"
|
|
||||||
|
|
||||||
export type TRPC = ReturnType<typeof createTRPC>
|
|
||||||
|
|
||||||
export interface TRPCRouterDeps {
|
|
||||||
sessionManager: UserSessionManager
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createTRPCRouter({ sessionManager }: TRPCRouterDeps) {
|
|
||||||
const t = createTRPC()
|
|
||||||
|
|
||||||
return t.router({
|
|
||||||
location: createLocationRouter(t, { sessionManager }),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TRPCRouter = ReturnType<typeof createTRPCRouter>
|
|
||||||
|
|
||||||
function createTRPC() {
|
|
||||||
const t = initTRPC.context<Context>().create()
|
|
||||||
|
|
||||||
const isAuthed = t.middleware(({ ctx, next }) => {
|
|
||||||
if (!ctx.user || !ctx.session) {
|
|
||||||
throw new TRPCError({ code: "UNAUTHORIZED" })
|
|
||||||
}
|
|
||||||
return next({
|
|
||||||
ctx: {
|
|
||||||
user: ctx.user,
|
|
||||||
session: ctx.session,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
router: t.router,
|
|
||||||
procedure: t.procedure.use(isAuthed),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -46,97 +46,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
"expo-font"
|
||||||
"expo-font",
|
|
||||||
{
|
|
||||||
"android": {
|
|
||||||
"fonts": [
|
|
||||||
{
|
|
||||||
"fontFamily": "Inter",
|
|
||||||
"fontDefinitions": [
|
|
||||||
{ "path": "./assets/fonts/Inter_100Thin.ttf", "weight": 100 },
|
|
||||||
{ "path": "./assets/fonts/Inter_100Thin_Italic.ttf", "weight": 100, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_200ExtraLight.ttf", "weight": 200 },
|
|
||||||
{ "path": "./assets/fonts/Inter_200ExtraLight_Italic.ttf", "weight": 200, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_300Light.ttf", "weight": 300 },
|
|
||||||
{ "path": "./assets/fonts/Inter_300Light_Italic.ttf", "weight": 300, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_400Regular.ttf", "weight": 400 },
|
|
||||||
{ "path": "./assets/fonts/Inter_400Regular_Italic.ttf", "weight": 400, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_500Medium.ttf", "weight": 500 },
|
|
||||||
{ "path": "./assets/fonts/Inter_500Medium_Italic.ttf", "weight": 500, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_600SemiBold.ttf", "weight": 600 },
|
|
||||||
{ "path": "./assets/fonts/Inter_600SemiBold_Italic.ttf", "weight": 600, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_700Bold.ttf", "weight": 700 },
|
|
||||||
{ "path": "./assets/fonts/Inter_700Bold_Italic.ttf", "weight": 700, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_800ExtraBold.ttf", "weight": 800 },
|
|
||||||
{ "path": "./assets/fonts/Inter_800ExtraBold_Italic.ttf", "weight": 800, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/Inter_900Black.ttf", "weight": 900 },
|
|
||||||
{ "path": "./assets/fonts/Inter_900Black_Italic.ttf", "weight": 900, "style": "italic" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fontFamily": "Source Serif 4",
|
|
||||||
"fontDefinitions": [
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_200ExtraLight.ttf", "weight": 200 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_200ExtraLight_Italic.ttf", "weight": 200, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_300Light.ttf", "weight": 300 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_300Light_Italic.ttf", "weight": 300, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_400Regular.ttf", "weight": 400 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_400Regular_Italic.ttf", "weight": 400, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_500Medium.ttf", "weight": 500 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_500Medium_Italic.ttf", "weight": 500, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_600SemiBold.ttf", "weight": 600 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_600SemiBold_Italic.ttf", "weight": 600, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_700Bold.ttf", "weight": 700 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_700Bold_Italic.ttf", "weight": 700, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_800ExtraBold.ttf", "weight": 800 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_800ExtraBold_Italic.ttf", "weight": 800, "style": "italic" },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_900Black.ttf", "weight": 900 },
|
|
||||||
{ "path": "./assets/fonts/SourceSerif4_900Black_Italic.ttf", "weight": 900, "style": "italic" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ios": {
|
|
||||||
"fonts": [
|
|
||||||
"./assets/fonts/Inter_100Thin.ttf",
|
|
||||||
"./assets/fonts/Inter_100Thin_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_200ExtraLight.ttf",
|
|
||||||
"./assets/fonts/Inter_200ExtraLight_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_300Light.ttf",
|
|
||||||
"./assets/fonts/Inter_300Light_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_400Regular.ttf",
|
|
||||||
"./assets/fonts/Inter_400Regular_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_500Medium.ttf",
|
|
||||||
"./assets/fonts/Inter_500Medium_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_600SemiBold.ttf",
|
|
||||||
"./assets/fonts/Inter_600SemiBold_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_700Bold.ttf",
|
|
||||||
"./assets/fonts/Inter_700Bold_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_800ExtraBold.ttf",
|
|
||||||
"./assets/fonts/Inter_800ExtraBold_Italic.ttf",
|
|
||||||
"./assets/fonts/Inter_900Black.ttf",
|
|
||||||
"./assets/fonts/Inter_900Black_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_200ExtraLight.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_200ExtraLight_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_300Light.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_300Light_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_400Regular.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_400Regular_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_500Medium.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_500Medium_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_600SemiBold.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_600SemiBold_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_700Bold.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_700Bold_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_800ExtraBold.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_800ExtraBold_Italic.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_900Black.ttf",
|
|
||||||
"./assets/fonts/SourceSerif4_900Black_Italic.ttf"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
"experiments": {
|
"experiments": {
|
||||||
"typedRoutes": true,
|
"typedRoutes": true,
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -8,12 +8,6 @@
|
|||||||
"developmentClient": true,
|
"developmentClient": true,
|
||||||
"distribution": "internal"
|
"distribution": "internal"
|
||||||
},
|
},
|
||||||
"development-simulator": {
|
|
||||||
"extends": "development",
|
|
||||||
"ios": {
|
|
||||||
"simulator": "true"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"preview": {
|
"preview": {
|
||||||
"distribution": "internal"
|
"distribution": "internal"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,12 +11,10 @@
|
|||||||
"web": "expo start --web",
|
"web": "expo start --web",
|
||||||
"lint": "expo lint",
|
"lint": "expo lint",
|
||||||
"build:ios": "eas build --profile development --platform ios --non-interactive",
|
"build:ios": "eas build --profile development --platform ios --non-interactive",
|
||||||
"build:ios-simulator": "eas build --profile development-simulator --platform ios --non-interactive",
|
|
||||||
"debugger": "bun run scripts/open-debugger.ts"
|
"debugger": "bun run scripts/open-debugger.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo-google-fonts/inter": "^0.4.2",
|
"@expo-google-fonts/inter": "^0.4.2",
|
||||||
"@expo-google-fonts/source-serif-4": "^0.4.1",
|
|
||||||
"@expo/vector-icons": "^15.0.3",
|
"@expo/vector-icons": "^15.0.3",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.0",
|
"@react-navigation/bottom-tabs": "^7.4.0",
|
||||||
"@react-navigation/elements": "^2.6.3",
|
"@react-navigation/elements": "^2.6.3",
|
||||||
|
|||||||
9
bun.lock
9
bun.lock
@@ -21,8 +21,6 @@
|
|||||||
"@aris/source-location": "workspace:*",
|
"@aris/source-location": "workspace:*",
|
||||||
"@aris/source-tfl": "workspace:*",
|
"@aris/source-tfl": "workspace:*",
|
||||||
"@aris/source-weatherkit": "workspace:*",
|
"@aris/source-weatherkit": "workspace:*",
|
||||||
"@hono/trpc-server": "^0.3",
|
|
||||||
"@trpc/server": "^11",
|
|
||||||
"arktype": "^2.1.29",
|
"arktype": "^2.1.29",
|
||||||
"better-auth": "^1",
|
"better-auth": "^1",
|
||||||
"hono": "^4",
|
"hono": "^4",
|
||||||
@@ -37,7 +35,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo-google-fonts/inter": "^0.4.2",
|
"@expo-google-fonts/inter": "^0.4.2",
|
||||||
"@expo-google-fonts/source-serif-4": "^0.4.1",
|
|
||||||
"@expo/vector-icons": "^15.0.3",
|
"@expo/vector-icons": "^15.0.3",
|
||||||
"@react-navigation/bottom-tabs": "^7.4.0",
|
"@react-navigation/bottom-tabs": "^7.4.0",
|
||||||
"@react-navigation/elements": "^2.6.3",
|
"@react-navigation/elements": "^2.6.3",
|
||||||
@@ -386,8 +383,6 @@
|
|||||||
|
|
||||||
"@expo-google-fonts/inter": ["@expo-google-fonts/inter@0.4.2", "", {}, "sha512-syfiImMaDmq7cFi0of+waE2M4uSCyd16zgyWxdPOY7fN2VBmSLKEzkfbZgeOjJq61kSqPBNNtXjggiQiSD6gMQ=="],
|
"@expo-google-fonts/inter": ["@expo-google-fonts/inter@0.4.2", "", {}, "sha512-syfiImMaDmq7cFi0of+waE2M4uSCyd16zgyWxdPOY7fN2VBmSLKEzkfbZgeOjJq61kSqPBNNtXjggiQiSD6gMQ=="],
|
||||||
|
|
||||||
"@expo-google-fonts/source-serif-4": ["@expo-google-fonts/source-serif-4@0.4.1", "", {}, "sha512-Ej4UXDjW1kwYPHG8YLq6fK1bqnJGb3K35J3S5atSL0ScKFAFLKvndxoTWeCls7mybtlS9x99hzwDeXCBkiI3rA=="],
|
|
||||||
|
|
||||||
"@expo/apple-utils": ["@expo/apple-utils@2.1.13", "", { "bin": { "apple-utils": "bin.js" } }, "sha512-nt3efiJhAWTHl9ikKYrHEuv3dhqCdicsHFRE9LmvtcVsPhXl9bAsm0gbACoLPr7ClP8664H/S6SdVJOD/tw0jg=="],
|
"@expo/apple-utils": ["@expo/apple-utils@2.1.13", "", { "bin": { "apple-utils": "bin.js" } }, "sha512-nt3efiJhAWTHl9ikKYrHEuv3dhqCdicsHFRE9LmvtcVsPhXl9bAsm0gbACoLPr7ClP8664H/S6SdVJOD/tw0jg=="],
|
||||||
|
|
||||||
"@expo/bunyan": ["@expo/bunyan@4.0.1", "", { "dependencies": { "uuid": "^8.0.0" } }, "sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg=="],
|
"@expo/bunyan": ["@expo/bunyan@4.0.1", "", { "dependencies": { "uuid": "^8.0.0" } }, "sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg=="],
|
||||||
@@ -468,8 +463,6 @@
|
|||||||
|
|
||||||
"@hapi/topo": ["@hapi/topo@5.1.0", "", { "dependencies": { "@hapi/hoek": "^9.0.0" } }, "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg=="],
|
"@hapi/topo": ["@hapi/topo@5.1.0", "", { "dependencies": { "@hapi/hoek": "^9.0.0" } }, "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg=="],
|
||||||
|
|
||||||
"@hono/trpc-server": ["@hono/trpc-server@0.3.4", "", { "peerDependencies": { "@trpc/server": "^10.10.0 || >11.0.0-rc", "hono": ">=4.*" } }, "sha512-xFOPjUPnII70FgicDzOJy1ufIoBTu8eF578zGiDOrYOrYN8CJe140s9buzuPkX+SwJRYK8LjEBHywqZtxdm8aA=="],
|
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
||||||
@@ -686,8 +679,6 @@
|
|||||||
|
|
||||||
"@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
|
"@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
|
||||||
|
|
||||||
"@trpc/server": ["@trpc/server@11.10.0", "", { "peerDependencies": { "typescript": ">=5.7.2" } }, "sha512-zZjTrR6He61e5TiT7e/bQqab/jRcXBZM8Fg78Yoo8uh5pz60dzzbYuONNUCOkafv5ppXVMms4NHYfNZgzw50vg=="],
|
|
||||||
|
|
||||||
"@tsconfig/node10": ["@tsconfig/node10@1.0.12", "", {}, "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ=="],
|
"@tsconfig/node10": ["@tsconfig/node10@1.0.12", "", {}, "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ=="],
|
||||||
|
|
||||||
"@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
|
"@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
|
||||||
|
|||||||
Reference in New Issue
Block a user