From cab4d03f420e2d829fb849fc4d586975db0cc43d Mon Sep 17 00:00:00 2001 From: Tadjaur Date: Sun, 21 Jul 2024 18:16:34 +0100 Subject: [PATCH 1/2] Save downloaded map in user profile --- .../src/validations/userRoutesValidator.ts | 16 ++++++++++++++++ server/migrations/0003_reflective_mimic.sql | 1 + server/migrations/meta/0003_snapshot.json | 11 +++++++++-- server/migrations/meta/_journal.json | 7 +++++++ server/src/controllers/user/editUser.ts | 3 +++ server/src/db/schema.ts | 14 ++++++++++++++ .../middleware/validators/userRoutesValidator.ts | 16 ++++++++++++++++ 7 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 server/migrations/0003_reflective_mimic.sql diff --git a/packages/validations/src/validations/userRoutesValidator.ts b/packages/validations/src/validations/userRoutesValidator.ts index 37b17e2c4..27e144c51 100644 --- a/packages/validations/src/validations/userRoutesValidator.ts +++ b/packages/validations/src/validations/userRoutesValidator.ts @@ -63,6 +63,22 @@ export const editUser = z.object({ code: z.string().optional(), role: z.enum(['user', 'admin']).optional(), username: z.string().optional(), + offlineMaps: z + .record( + z.string(), + z.object({ + name: z.string(), + styleURL: z.string(), + metadata: z.object({ + shape: z.string(), + }), + bounds: z.array(z.array(z.number())), + minZoom: z.number(), + maxZoom: z.number(), + }), + ) + .optional() + .nullable(), profileImage: z.string().optional().nullable(), preferredWeather: z.string().optional(), preferredWeight: z.string().optional(), diff --git a/server/migrations/0003_reflective_mimic.sql b/server/migrations/0003_reflective_mimic.sql new file mode 100644 index 000000000..1f1757472 --- /dev/null +++ b/server/migrations/0003_reflective_mimic.sql @@ -0,0 +1 @@ +ALTER TABLE user ADD `offline_maps` text; \ No newline at end of file diff --git a/server/migrations/meta/0003_snapshot.json b/server/migrations/meta/0003_snapshot.json index e0d13f1e5..25e45e48e 100644 --- a/server/migrations/meta/0003_snapshot.json +++ b/server/migrations/meta/0003_snapshot.json @@ -1,8 +1,8 @@ { "version": "5", "dialect": "sqlite", - "id": "139ca60e-e238-46a7-b360-e18f0451c9b7", - "prevId": "79e15743-f558-4a68-bdb3-8220ab3aefe5", + "id": "57e2d274-a728-4d09-9aff-74d3b92399fa", + "prevId": "139ca60e-e238-46a7-b360-e18f0451c9b7", "tables": { "conversation": { "name": "conversation", @@ -945,6 +945,13 @@ "notNull": false, "autoincrement": false }, + "offline_maps": { + "name": "offline_maps", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, "role": { "name": "role", "type": "text", diff --git a/server/migrations/meta/_journal.json b/server/migrations/meta/_journal.json index 6b209ab71..9e5b092be 100644 --- a/server/migrations/meta/_journal.json +++ b/server/migrations/meta/_journal.json @@ -22,6 +22,13 @@ "when": 1713116052484, "tag": "0002_numerous_tyger_tiger", "breakpoints": true + }, + { + "idx": 3, + "version": "5", + "when": 1721509132975, + "tag": "0003_reflective_mimic", + "breakpoints": true } ] } \ No newline at end of file diff --git a/server/src/controllers/user/editUser.ts b/server/src/controllers/user/editUser.ts index c03e4a145..b132f035c 100644 --- a/server/src/controllers/user/editUser.ts +++ b/server/src/controllers/user/editUser.ts @@ -55,7 +55,9 @@ export function editUserRoute() { profileImage, preferredWeather, preferredWeight, + offlineMaps, } = opts.input; + console.error('failed to logging'); let { password } = opts.input; const { env }: any = opts.ctx; const JWT_SECRET = env.JWT_SECRET; @@ -74,6 +76,7 @@ export function editUserRoute() { ...(profileImage && { profileImage }), ...(preferredWeather && { preferredWeather }), ...(preferredWeight && { preferredWeight }), + ...(offlineMaps && { offlineMaps }), }; const editedUser = await userClass.update(data); return editedUser; diff --git a/server/src/db/schema.ts b/server/src/db/schema.ts index 3c9e2c081..8de08a859 100644 --- a/server/src/db/schema.ts +++ b/server/src/db/schema.ts @@ -14,6 +14,17 @@ import { import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; import { createId } from '@paralleldrive/cuid2'; +type OfflineMap = { + name: string; + styleURL: string; + bounds: [number[], number[]]; + minZoom: number; + maxZoom: number; + metadata: { + shape: string; + }; +}; + export const user = sqliteTable('user', { id: text('id') .primaryKey() @@ -31,6 +42,9 @@ export const user = sqliteTable('user', { passwordResetTokenExpiration: integer('password_reset_token_expiration', { mode: 'timestamp', }), + offlineMaps: text('offline_maps', { mode: 'json' }).$type< + Record + >(), role: text('role', { enum: ['admin', 'user'] }) .default('user') .$type<'admin' | 'user'>(), diff --git a/server/src/middleware/validators/userRoutesValidator.ts b/server/src/middleware/validators/userRoutesValidator.ts index 9bbee26ec..5dd675c93 100644 --- a/server/src/middleware/validators/userRoutesValidator.ts +++ b/server/src/middleware/validators/userRoutesValidator.ts @@ -37,6 +37,22 @@ export const editUser = z.object({ email: z.string().optional(), code: z.string().optional(), role: z.enum(['user', 'admin']).optional(), + offlineMaps: z + .record( + z.string(), + z.object({ + name: z.string(), + styleURL: z.string(), + metadata: z.object({ + shape: z.string(), + }), + bounds: z.array(z.array(z.number())), + minZoom: z.number(), + maxZoom: z.number(), + }), + ) + .optional() + .nullable(), username: z.string().optional(), profileImage: z.string().optional(), preferredWeather: z.string().optional(), From 5bc73bd072334ea8d0085594dde11ccfb57c4450 Mon Sep 17 00:00:00 2001 From: Tadjaur Date: Sun, 21 Jul 2024 18:20:30 +0100 Subject: [PATCH 2/2] run the lint command --- server/src/controllers/auth/emailExists.ts | 2 +- server/src/controllers/getOsm/getPhotonResults.ts | 4 ++-- server/src/controllers/item/addGlobalItemToPack.ts | 5 +---- server/src/controllers/item/addItemGlobal.ts | 3 +-- server/src/controllers/item/searchItemsByName.ts | 2 +- server/src/controllers/pack/index.ts | 2 +- server/src/controllers/passport/signInGoogle.ts | 2 +- server/src/controllers/user/getMe.ts | 2 +- server/src/controllers/user/sentEmail.ts | 2 +- server/src/db/schema.ts | 4 ++-- server/src/index.ts | 2 +- server/src/integrations/ai/client.ts | 6 +++--- server/src/middleware/checkRole.ts | 2 +- server/src/queue/client.ts | 8 +++----- server/src/queue/index.ts | 4 ++-- server/src/services/item/addItemService.ts | 4 ++-- server/src/services/item/getSimilarItemsService.ts | 5 ++--- server/src/services/pack/getPublicPacksService.ts | 1 - server/src/services/pack/getSimilarPacksService.ts | 5 ++--- server/src/services/user/emailExistsService.ts | 5 ++--- server/src/tests/routes/pack.spec.ts | 2 +- server/src/vector/client.ts | 14 +++++++------- 22 files changed, 38 insertions(+), 48 deletions(-) diff --git a/server/src/controllers/auth/emailExists.ts b/server/src/controllers/auth/emailExists.ts index 5c9ff56a4..054be0905 100644 --- a/server/src/controllers/auth/emailExists.ts +++ b/server/src/controllers/auth/emailExists.ts @@ -11,7 +11,7 @@ export const emailExists = async (c) => { smtpEmail: c.env.STMP_EMAIL, email, }); - console.log('emailExists', emailExists) + console.log('emailExists', emailExists); return c.json({ emailExists }, 200); } catch (error) { return c.json({ error: `Failed to delete user: ${error.message}` }, 404); diff --git a/server/src/controllers/getOsm/getPhotonResults.ts b/server/src/controllers/getOsm/getPhotonResults.ts index 7fb287954..4a05aed92 100644 --- a/server/src/controllers/getOsm/getPhotonResults.ts +++ b/server/src/controllers/getOsm/getPhotonResults.ts @@ -8,9 +8,9 @@ export async function getPhotonResults(ctx: Context) { try { const { searchString } = await ctx.req.query(); const response = await getPhotonResultsService(searchString); - return ctx.json(response.features, 200) + return ctx.json(response.features, 200); } catch (error) { - return ctx.json({error: error.message}, 500) + return ctx.json({ error: error.message }, 500); } } diff --git a/server/src/controllers/item/addGlobalItemToPack.ts b/server/src/controllers/item/addGlobalItemToPack.ts index 989210782..b8a1e17ee 100644 --- a/server/src/controllers/item/addGlobalItemToPack.ts +++ b/server/src/controllers/item/addGlobalItemToPack.ts @@ -9,10 +9,7 @@ export const addGlobalItemToPack = async (c: Context) => { const item = await addGlobalItemToPackService(packId, itemId, ownerId); return c.json({ item }, 200); } catch (error) { - return c.json( - { error: `${error.message}` }, - 500, - ); + return c.json({ error: `${error.message}` }, 500); } }; diff --git a/server/src/controllers/item/addItemGlobal.ts b/server/src/controllers/item/addItemGlobal.ts index 3f288d6bb..753139a1d 100644 --- a/server/src/controllers/item/addItemGlobal.ts +++ b/server/src/controllers/item/addItemGlobal.ts @@ -5,8 +5,7 @@ import * as validator from '@packrat/validations'; export const addItemGlobal = async (c: Context) => { try { - const { name, weight, quantity, unit, type, ownerId } = - await c.req.json(); + const { name, weight, quantity, unit, type, ownerId } = await c.req.json(); const item = await addItemGlobalService( name, diff --git a/server/src/controllers/item/searchItemsByName.ts b/server/src/controllers/item/searchItemsByName.ts index b83998514..d215fbbf0 100644 --- a/server/src/controllers/item/searchItemsByName.ts +++ b/server/src/controllers/item/searchItemsByName.ts @@ -6,7 +6,7 @@ import { type Context } from 'hono'; export const searchItemsByName = async (c: Context) => { try { const { name } = await c.req.query(); - + const items = await searchItemsByNameService(name); return c.json({ items }, 200); } catch (error) { diff --git a/server/src/controllers/pack/index.ts b/server/src/controllers/pack/index.ts index 2d2839dde..283bee58b 100644 --- a/server/src/controllers/pack/index.ts +++ b/server/src/controllers/pack/index.ts @@ -6,4 +6,4 @@ export * from './duplicatePublicPack'; export * from './getPackById'; export * from './getPublicPacks'; export * from './scorePack'; -export * from './getSimilarPacks'; \ No newline at end of file +export * from './getSimilarPacks'; diff --git a/server/src/controllers/passport/signInGoogle.ts b/server/src/controllers/passport/signInGoogle.ts index 89ef917b2..f303712f6 100644 --- a/server/src/controllers/passport/signInGoogle.ts +++ b/server/src/controllers/passport/signInGoogle.ts @@ -17,7 +17,7 @@ export const signInGoogle = async (c: Context) => { if (!decodedToken) { throw new Error('Invalid ID token'); } - console.log('decodedToken', decodedToken) + console.log('decodedToken', decodedToken); const { payload: { email, name, sub: googleId }, } = decodedToken; diff --git a/server/src/controllers/user/getMe.ts b/server/src/controllers/user/getMe.ts index 77f49663d..970ad5cbd 100644 --- a/server/src/controllers/user/getMe.ts +++ b/server/src/controllers/user/getMe.ts @@ -5,7 +5,7 @@ import { protectedProcedure } from '../../trpc'; export const getMe = async (c: Context) => { try { const { user } = await c.req.json(); - console.log('user ', user) + console.log('user ', user); return c.json({ user }, 200); } catch (error) { return c.json({ error: `Failed to get user: ${error.message}` }, 500); diff --git a/server/src/controllers/user/sentEmail.ts b/server/src/controllers/user/sentEmail.ts index 5dc66884f..2ffd0a58d 100644 --- a/server/src/controllers/user/sentEmail.ts +++ b/server/src/controllers/user/sentEmail.ts @@ -8,7 +8,7 @@ import { type Context } from 'hono'; export const sentEmail = async (c: Context) => { try { const { email } = await c.req.json(); - console.log('email ', c.env.SEND_GRID_API_KEY) + console.log('email ', c.env.SEND_GRID_API_KEY); const STMP_EMAIL = c.env.STMP_EMAIL; const SEND_GRID_API_KEY = c.env.SEND_GRID_API_KEY; const JWT_SECRET = c.env.JWT_SECRET; diff --git a/server/src/db/schema.ts b/server/src/db/schema.ts index 8de08a859..4ff7ce3f2 100644 --- a/server/src/db/schema.ts +++ b/server/src/db/schema.ts @@ -14,7 +14,7 @@ import { import { createInsertSchema, createSelectSchema } from 'drizzle-zod'; import { createId } from '@paralleldrive/cuid2'; -type OfflineMap = { +interface OfflineMap { name: string; styleURL: string; bounds: [number[], number[]]; @@ -23,7 +23,7 @@ type OfflineMap = { metadata: { shape: string; }; -}; +} export const user = sqliteTable('user', { id: text('id') diff --git a/server/src/index.ts b/server/src/index.ts index 140931a56..65584dea0 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -7,7 +7,7 @@ import { securityHeaders } from './middleware/securityHeaders'; import { enforceHttps } from './middleware/enforceHttps'; import router from './routes'; import { CORS_METHODS } from './config'; -import { Ai } from '@cloudflare/ai'; +import { type Ai } from '@cloudflare/ai'; import { httpDBContext } from './trpc/httpDBContext'; interface Bindings { diff --git a/server/src/integrations/ai/client.ts b/server/src/integrations/ai/client.ts index 36a19bb8e..0217e8563 100644 --- a/server/src/integrations/ai/client.ts +++ b/server/src/integrations/ai/client.ts @@ -1,9 +1,9 @@ -import { Ai } from "@cloudflare/ai"; +import { Ai } from '@cloudflare/ai'; class AiClient { private static _instance: AiClient | null = null; - private apiKey: string; - private accountId: string; + private readonly apiKey: string; + private readonly accountId: string; private readonly MODEL_NAME: string = '@cf/baai/bge-base-en-v1.5'; private readonly EXECUTE_AI_MODEL_URL: string; diff --git a/server/src/middleware/checkRole.ts b/server/src/middleware/checkRole.ts index 079335140..a0ebcf62e 100644 --- a/server/src/middleware/checkRole.ts +++ b/server/src/middleware/checkRole.ts @@ -35,7 +35,7 @@ const checkRole = (roles: string[]) => { // Proceed to the next middleware or route handler. await next(); } catch (err) { - console.log('error', err) + console.log('error', err); if (err instanceof ZodError) { console.error('Invalid role provided:', err.errors); return c.json({ error: 'Invalid role provided.' }, 400); diff --git a/server/src/queue/client.ts b/server/src/queue/client.ts index 4b0809734..e70339248 100644 --- a/server/src/queue/client.ts +++ b/server/src/queue/client.ts @@ -1,12 +1,10 @@ import PQueue from 'p-queue'; -interface QueueTask { - (): Promise; -} +type QueueTask = () => Promise; export class Queue { private static instance: Queue; - private queue: PQueue; + private readonly queue: PQueue; private constructor(concurrency: number = 1) { this.queue = new PQueue({ concurrency }); @@ -22,4 +20,4 @@ export class Queue { async addTask(task: QueueTask): Promise { return this.queue.add(task); } -} \ No newline at end of file +} diff --git a/server/src/queue/index.ts b/server/src/queue/index.ts index 79f7925d4..6e8944722 100644 --- a/server/src/queue/index.ts +++ b/server/src/queue/index.ts @@ -1,5 +1,5 @@ -import { MessageBatch } from '@cloudflare/workers-types'; -import { Bindings } from '..'; +import { type MessageBatch } from '@cloudflare/workers-types'; +import { type Bindings } from '..'; async function handleEtlQueue(batch: MessageBatch, env: Bindings) { for (const message of batch.messages) { diff --git a/server/src/services/item/addItemService.ts b/server/src/services/item/addItemService.ts index f99c847a6..a6eeaedf7 100644 --- a/server/src/services/item/addItemService.ts +++ b/server/src/services/item/addItemService.ts @@ -27,7 +27,7 @@ export const addItemService = async ( packId: string, type: 'Food' | 'Water' | 'Essentials', ownerId: string, - executionCtx: ExecutionContext + executionCtx: ExecutionContext, ) => { let category: InsertItemCategory | null; if (!categories.includes(type)) { @@ -85,4 +85,4 @@ export const addItemService = async ( ); return item; -}; \ No newline at end of file +}; diff --git a/server/src/services/item/getSimilarItemsService.ts b/server/src/services/item/getSimilarItemsService.ts index b469a0365..5f74b55c1 100644 --- a/server/src/services/item/getSimilarItemsService.ts +++ b/server/src/services/item/getSimilarItemsService.ts @@ -18,7 +18,7 @@ export async function getSimilarItemsService( visibility: PackAndItemVisibilityFilter, ) { const itemObj = new Item(); - let item = await itemObj.findItem({ + const item = await itemObj.findItem({ id, }); @@ -35,8 +35,7 @@ export async function getSimilarItemsService( visibility == PackAndItemVisibilityFilter.ALL ? undefined : { - isPublic: - visibility == PackAndItemVisibilityFilter.PUBLIC ? true : false, + isPublic: visibility == PackAndItemVisibilityFilter.PUBLIC, }, ); diff --git a/server/src/services/pack/getPublicPacksService.ts b/server/src/services/pack/getPublicPacksService.ts index b6a20ca76..0bfeba40a 100644 --- a/server/src/services/pack/getPublicPacksService.ts +++ b/server/src/services/pack/getPublicPacksService.ts @@ -17,7 +17,6 @@ export async function getPublicPacksService(queryBy: string = 'createdAt') { is_public: true, }); - // Apply sorting if necessary packs = await sortFunction({ packs, diff --git a/server/src/services/pack/getSimilarPacksService.ts b/server/src/services/pack/getSimilarPacksService.ts index d48cb7785..62b559b06 100644 --- a/server/src/services/pack/getSimilarPacksService.ts +++ b/server/src/services/pack/getSimilarPacksService.ts @@ -18,7 +18,7 @@ export async function getSimilarPacksService( visibility: PackAndItemVisibilityFilter, ) { const packClass = new Pack(); - let pack = await packClass.findPack({ + const pack = await packClass.findPack({ id, }); @@ -35,8 +35,7 @@ export async function getSimilarPacksService( visibility == PackAndItemVisibilityFilter.ALL ? undefined : { - isPublic: - visibility == PackAndItemVisibilityFilter.PUBLIC ? true : false, + isPublic: visibility == PackAndItemVisibilityFilter.PUBLIC, }, ); diff --git a/server/src/services/user/emailExistsService.ts b/server/src/services/user/emailExistsService.ts index 51a3c3166..f6ee00f2d 100644 --- a/server/src/services/user/emailExistsService.ts +++ b/server/src/services/user/emailExistsService.ts @@ -18,7 +18,7 @@ export async function emailExistsService({ throw new Error(val); } const result1 = await sendEmailNotice({ sendGridApiKey, smtpEmail, email }); - console.log('result1result1', result1) + console.log('result1result1', result1); if (result1.status) { const { newcode } = result1; const result2 = await findUserAndUpdate(email, newcode, 'code'); @@ -27,9 +27,8 @@ export async function emailExistsService({ } } } catch (error) { - console.log('error', error.message) + console.log('error', error.message); throw new Error(error.message); - } } diff --git a/server/src/tests/routes/pack.spec.ts b/server/src/tests/routes/pack.spec.ts index b4863f750..dd7474f00 100644 --- a/server/src/tests/routes/pack.spec.ts +++ b/server/src/tests/routes/pack.spec.ts @@ -9,7 +9,7 @@ import { import { Pack as PackClass } from '../../drizzle/methods/pack'; import { User as UserClass } from '../../drizzle/methods/User'; import type { Pack, User } from '../../db/schema'; -import { ExecutionContext } from 'hono'; +import { type ExecutionContext } from 'hono'; const { mockSyncRecord, mockDeleteVector, mockSearchVector } = vi.hoisted( () => { diff --git a/server/src/vector/client.ts b/server/src/vector/client.ts index b64e8e393..259a339bd 100644 --- a/server/src/vector/client.ts +++ b/server/src/vector/client.ts @@ -3,19 +3,19 @@ import { AiClient } from '../integrations/ai/client'; interface VectorsQueryResponse { result: { count: number; - matches: { id: string; namespace: string; score: number }[]; + matches: Array<{ id: string; namespace: string; score: number }>; }; result_info: string | null; success: boolean; - errors: { code: number; message: string }[]; - messages: { code: number; message: string }[]; + errors: Array<{ code: number; message: string }>; + messages: Array<{ code: number; message: string }>; } class VectorClient { private static _instance: VectorClient | null = null; - private apiKey: string; - private indexName: string; - private accountId: string; + private readonly apiKey: string; + private readonly indexName: string; + private readonly accountId: string; private readonly VECTORIZE_INDEX_URL: string; private constructor(apiKey: string, indexName: string, accountId: string) { @@ -149,7 +149,7 @@ class VectorClient { content: string, namespace: string, topK: number = 3, - filter?: { [key: string]: any }, + filter?: Record, ): Promise { const vector = await AiClient.getEmbedding(content); const url = `${this.VECTORIZE_INDEX_URL}/query`;