chore: move server functions to db/utils (#951)
This commit is contained in:
parent
a159b77fcf
commit
24cb2ce19b
5 changed files with 22 additions and 105 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import { generateDummyPassword } from './utils';
|
import { generateDummyPassword } from './db/utils';
|
||||||
|
|
||||||
export const isProductionEnvironment = process.env.NODE_ENV === 'production';
|
export const isProductionEnvironment = process.env.NODE_ENV === 'production';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import 'server-only';
|
import 'server-only';
|
||||||
|
|
||||||
import { genSaltSync, hashSync } from 'bcrypt-ts';
|
|
||||||
import {
|
import {
|
||||||
and,
|
and,
|
||||||
asc,
|
asc,
|
||||||
|
|
@ -28,6 +27,7 @@ import {
|
||||||
type Chat,
|
type Chat,
|
||||||
} from './schema';
|
} from './schema';
|
||||||
import type { ArtifactKind } from '@/components/artifact';
|
import type { ArtifactKind } from '@/components/artifact';
|
||||||
|
import { generateHashedPassword } from './utils';
|
||||||
|
|
||||||
// Optionally, if not using email/pass login, you can
|
// Optionally, if not using email/pass login, you can
|
||||||
// use the Drizzle adapter for Auth.js / NextAuth
|
// use the Drizzle adapter for Auth.js / NextAuth
|
||||||
|
|
@ -47,11 +47,10 @@ export async function getUser(email: string): Promise<Array<User>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createUser(email: string, password: string) {
|
export async function createUser(email: string, password: string) {
|
||||||
const salt = genSaltSync(10);
|
const hashedPassword = generateHashedPassword(password);
|
||||||
const hash = hashSync(password, salt);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await db.insert(user).values({ email, password: hash });
|
return await db.insert(user).values({ email, password: hashedPassword });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to create user in database');
|
console.error('Failed to create user in database');
|
||||||
throw error;
|
throw error;
|
||||||
|
|
|
||||||
16
lib/db/utils.ts
Normal file
16
lib/db/utils.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { generateId } from 'ai';
|
||||||
|
import { genSaltSync, hashSync } from 'bcrypt-ts';
|
||||||
|
|
||||||
|
export function generateHashedPassword(password: string) {
|
||||||
|
const salt = genSaltSync(10);
|
||||||
|
const hash = hashSync(password, salt);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateDummyPassword() {
|
||||||
|
const password = generateId(12);
|
||||||
|
const hashedPassword = generateHashedPassword(password);
|
||||||
|
|
||||||
|
return hashedPassword;
|
||||||
|
}
|
||||||
100
lib/utils.ts
100
lib/utils.ts
|
|
@ -1,15 +1,7 @@
|
||||||
import {
|
import type { CoreAssistantMessage, CoreToolMessage, UIMessage } from 'ai';
|
||||||
generateId,
|
|
||||||
type CoreAssistantMessage,
|
|
||||||
type CoreToolMessage,
|
|
||||||
type Message,
|
|
||||||
type UIMessage,
|
|
||||||
} from 'ai';
|
|
||||||
import { type ClassValue, clsx } from 'clsx';
|
import { type ClassValue, clsx } from 'clsx';
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
import type { Document } from '@/lib/db/schema';
|
import type { Document } from '@/lib/db/schema';
|
||||||
import { genSaltSync, hashSync } from 'bcrypt-ts';
|
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
|
|
@ -52,90 +44,9 @@ export function generateUUID(): string {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToolMessageToChat({
|
|
||||||
toolMessage,
|
|
||||||
messages,
|
|
||||||
}: {
|
|
||||||
toolMessage: CoreToolMessage;
|
|
||||||
messages: Array<Message>;
|
|
||||||
}): Array<Message> {
|
|
||||||
return messages.map((message) => {
|
|
||||||
if (message.toolInvocations) {
|
|
||||||
return {
|
|
||||||
...message,
|
|
||||||
toolInvocations: message.toolInvocations.map((toolInvocation) => {
|
|
||||||
const toolResult = toolMessage.content.find(
|
|
||||||
(tool) => tool.toolCallId === toolInvocation.toolCallId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (toolResult) {
|
|
||||||
return {
|
|
||||||
...toolInvocation,
|
|
||||||
state: 'result',
|
|
||||||
result: toolResult.result,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return toolInvocation;
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResponseMessageWithoutId = CoreToolMessage | CoreAssistantMessage;
|
type ResponseMessageWithoutId = CoreToolMessage | CoreAssistantMessage;
|
||||||
type ResponseMessage = ResponseMessageWithoutId & { id: string };
|
type ResponseMessage = ResponseMessageWithoutId & { id: string };
|
||||||
|
|
||||||
export function sanitizeResponseMessages({
|
|
||||||
messages,
|
|
||||||
reasoning,
|
|
||||||
}: {
|
|
||||||
messages: Array<ResponseMessage>;
|
|
||||||
reasoning: string | undefined;
|
|
||||||
}) {
|
|
||||||
const toolResultIds: Array<string> = [];
|
|
||||||
|
|
||||||
for (const message of messages) {
|
|
||||||
if (message.role === 'tool') {
|
|
||||||
for (const content of message.content) {
|
|
||||||
if (content.type === 'tool-result') {
|
|
||||||
toolResultIds.push(content.toolCallId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const messagesBySanitizedContent = messages.map((message) => {
|
|
||||||
if (message.role !== 'assistant') return message;
|
|
||||||
|
|
||||||
if (typeof message.content === 'string') return message;
|
|
||||||
|
|
||||||
const sanitizedContent = message.content.filter((content) =>
|
|
||||||
content.type === 'tool-call'
|
|
||||||
? toolResultIds.includes(content.toolCallId)
|
|
||||||
: content.type === 'text'
|
|
||||||
? content.text.length > 0
|
|
||||||
: true,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (reasoning) {
|
|
||||||
// @ts-expect-error: reasoning message parts in sdk is wip
|
|
||||||
sanitizedContent.push({ type: 'reasoning', reasoning });
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...message,
|
|
||||||
content: sanitizedContent,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return messagesBySanitizedContent.filter(
|
|
||||||
(message) => message.content.length > 0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getMostRecentUserMessage(messages: Array<UIMessage>) {
|
export function getMostRecentUserMessage(messages: Array<UIMessage>) {
|
||||||
const userMessages = messages.filter((message) => message.role === 'user');
|
const userMessages = messages.filter((message) => message.role === 'user');
|
||||||
return userMessages.at(-1);
|
return userMessages.at(-1);
|
||||||
|
|
@ -162,12 +73,3 @@ export function getTrailingMessageId({
|
||||||
|
|
||||||
return trailingMessage.id;
|
return trailingMessage.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateDummyPassword() {
|
|
||||||
const password = generateId(12);
|
|
||||||
|
|
||||||
const salt = genSaltSync(10);
|
|
||||||
const hash = hashSync(password, salt);
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ai-chatbot",
|
"name": "ai-chatbot",
|
||||||
"version": "3.0.5",
|
"version": "3.0.6",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --turbo",
|
"dev": "next dev --turbo",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue