From 3f32a9b14de714590feaa4f2c469743ea157f6ae Mon Sep 17 00:00:00 2001 From: Nopm Date: Sat, 7 Jun 2025 02:32:49 -0300 Subject: [PATCH] fix user json imports --- src/admin/web/manage.ts | 71 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/admin/web/manage.ts b/src/admin/web/manage.ts index aa581ba..1117501 100644 --- a/src/admin/web/manage.ts +++ b/src/admin/web/manage.ts @@ -194,7 +194,76 @@ router.post("/import-users", upload.single("users"), (req, res) => { if (!req.file) throw new HttpError(400, "No file uploaded"); const data = JSON.parse(req.file.buffer.toString()); - const result = z.array(UserPartialSchema).safeParse(data.users); + + // Transform old token count format to new format + const transformedUsers = data.users.map((user: any) => { + if (user.tokenCounts) { + const transformedTokenCounts: any = {}; + for (const [family, value] of Object.entries(user.tokenCounts)) { + if (typeof value === 'number') { + // Old format: just a number (legacy_total) + transformedTokenCounts[family] = { + input: 0, + output: 0, + legacy_total: value + }; + } else if (typeof value === 'object' && value !== null) { + // New format or partially new format + transformedTokenCounts[family] = { + input: (value as any).input || 0, + output: (value as any).output || 0, + legacy_total: (value as any).legacy_total + }; + } + } + user.tokenCounts = transformedTokenCounts; + } + + // Also handle tokenLimits and tokenRefresh the same way + if (user.tokenLimits) { + const transformedTokenLimits: any = {}; + for (const [family, value] of Object.entries(user.tokenLimits)) { + if (typeof value === 'number') { + transformedTokenLimits[family] = { + input: 0, + output: 0, + legacy_total: value + }; + } else if (typeof value === 'object' && value !== null) { + transformedTokenLimits[family] = { + input: (value as any).input || 0, + output: (value as any).output || 0, + legacy_total: (value as any).legacy_total + }; + } + } + user.tokenLimits = transformedTokenLimits; + } + + if (user.tokenRefresh) { + const transformedTokenRefresh: any = {}; + for (const [family, value] of Object.entries(user.tokenRefresh)) { + if (typeof value === 'number') { + transformedTokenRefresh[family] = { + input: 0, + output: 0, + legacy_total: value + }; + } else if (typeof value === 'object' && value !== null) { + transformedTokenRefresh[family] = { + input: (value as any).input || 0, + output: (value as any).output || 0, + legacy_total: (value as any).legacy_total + }; + } + } + user.tokenRefresh = transformedTokenRefresh; + } + + return user; + }); + + const result = z.array(UserPartialSchema).safeParse(transformedUsers); if (!result.success) throw new HttpError(400, result.error.toString()); const upserts = result.data.map((user) => userStore.upsertUser(user));