Compare commits

...

1 Commits

789 changed files with 2542 additions and 3138 deletions

View File

@@ -39,18 +39,8 @@ export function SocialLoginButtons({
setIsGithubLoading(true) setIsGithubLoading(true)
try { try {
await client.signIn.social({ provider: 'github', callbackURL }) await client.signIn.social({ provider: 'github', callbackURL })
} catch (err: any) { } catch (_err: unknown) {
let errorMessage = 'Failed to sign in with GitHub' // Error handling is done silently - user will see the OAuth error page if needed
if (err.message?.includes('account exists')) {
errorMessage = 'An account with this email already exists. Please sign in instead.'
} else if (err.message?.includes('cancelled')) {
errorMessage = 'GitHub sign in was cancelled. Please try again.'
} else if (err.message?.includes('network')) {
errorMessage = 'Network error. Please check your connection and try again.'
} else if (err.message?.includes('rate limit')) {
errorMessage = 'Too many attempts. Please try again later.'
}
} finally { } finally {
setIsGithubLoading(false) setIsGithubLoading(false)
} }
@@ -62,18 +52,8 @@ export function SocialLoginButtons({
setIsGoogleLoading(true) setIsGoogleLoading(true)
try { try {
await client.signIn.social({ provider: 'google', callbackURL }) await client.signIn.social({ provider: 'google', callbackURL })
} catch (err: any) { } catch (_err: unknown) {
let errorMessage = 'Failed to sign in with Google' // Error handling is done silently - user will see the OAuth error page if needed
if (err.message?.includes('account exists')) {
errorMessage = 'An account with this email already exists. Please sign in instead.'
} else if (err.message?.includes('cancelled')) {
errorMessage = 'Google sign in was cancelled. Please try again.'
} else if (err.message?.includes('network')) {
errorMessage = 'Network error. Please check your connection and try again.'
} else if (err.message?.includes('rate limit')) {
errorMessage = 'Too many attempts. Please try again later.'
}
} finally { } finally {
setIsGoogleLoading(false) setIsGoogleLoading(false)
} }

View File

@@ -158,7 +158,7 @@ export default function LoginPage({
return () => { return () => {
window.removeEventListener('keydown', handleKeyDown) window.removeEventListener('keydown', handleKeyDown)
} }
}, [forgotPasswordEmail, forgotPasswordOpen]) }, [forgotPasswordOpen])
const handleEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newEmail = e.target.value const newEmail = e.target.value

View File

@@ -3,7 +3,7 @@
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import Link from 'next/link' import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation' import { useSearchParams } from 'next/navigation'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input' import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label' import { Label } from '@/components/ui/label'
@@ -52,7 +52,6 @@ const validateCallbackUrl = (url: string): boolean => {
} }
export default function SSOForm() { export default function SSOForm() {
const router = useRouter()
const searchParams = useSearchParams() const searchParams = useSearchParams()
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const [email, setEmail] = useState('') const [email, setEmail] = useState('')

View File

@@ -196,7 +196,7 @@ export function useVerification({
return () => clearTimeout(timeoutId) return () => clearTimeout(timeoutId)
} }
}, [otp, email, isLoading, isVerified]) }, [otp, email, isLoading, isVerified, verifyCode])
useEffect(() => { useEffect(() => {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
@@ -220,7 +220,7 @@ export function useVerification({
handleRedirect() handleRedirect()
} }
} }
}, [isEmailVerificationEnabled, router, isInviteFlow, redirectUrl]) }, [isEmailVerificationEnabled, router, isInviteFlow, redirectUrl, refetchSession])
return { return {
otp, otp,

View File

@@ -118,7 +118,7 @@ export function DotPattern({
<stop offset='100%' stopColor='currentColor' stopOpacity='0' /> <stop offset='100%' stopColor='currentColor' stopOpacity='0' />
</radialGradient> </radialGradient>
</defs> </defs>
{dots.map((dot, index) => ( {dots.map((dot, _index) => (
<circle <circle
key={`${dot.x}-${dot.y}`} key={`${dot.x}-${dot.y}`}
cx={dot.x} cx={dot.x}

View File

@@ -106,9 +106,8 @@ export function LandingFlow({
proOptions={{ hideAttribution: true }} proOptions={{ hideAttribution: true }}
fitView={false} fitView={false}
defaultViewport={{ x: 0, y: 0, zoom: 1 }} defaultViewport={{ x: 0, y: 0, zoom: 1 }}
onInit={(instance) => { onInit={() => {
setRfReady(true) setRfReady(true)
// Expose limited viewport API for outer timeline to pan smoothly
viewportApiRef.current = { viewportApiRef.current = {
panTo: (x: number, y: number, options?: { duration?: number }) => { panTo: (x: number, y: number, options?: { duration?: number }) => {
setViewport({ x, y, zoom: 1 }, { duration: options?.duration ?? 0 }) setViewport({ x, y, zoom: 1 }, { duration: options?.duration ?? 0 })

View File

@@ -140,7 +140,7 @@ export default function Hero() {
*/ */
const [rfNodes, setRfNodes] = React.useState<Node[]>([]) const [rfNodes, setRfNodes] = React.useState<Node[]>([])
const [rfEdges, setRfEdges] = React.useState<Edge[]>([]) const [rfEdges, setRfEdges] = React.useState<Edge[]>([])
const [groupBox, setGroupBox] = React.useState<LandingGroupData | null>(null) const [groupBox] = React.useState<LandingGroupData | null>(null)
const [worldWidth, setWorldWidth] = React.useState<number>(1000) const [worldWidth, setWorldWidth] = React.useState<number>(1000)
const viewportApiRef = React.useRef<LandingViewportApi | null>(null) const viewportApiRef = React.useRef<LandingViewportApi | null>(null)

View File

@@ -149,7 +149,7 @@ export function extractAgentContent(executeResult: {
if (typeof executeResult.output === 'object' && executeResult.output !== null) { if (typeof executeResult.output === 'object' && executeResult.output !== null) {
const keys = Object.keys(executeResult.output) const keys = Object.keys(executeResult.output)
// Skip empty objects or objects with only undefined values // Skip empty objects or objects with only undefined values
if (keys.length > 0 && keys.some((k) => executeResult.output![k] !== undefined)) { if (keys.length > 0 && keys.some((k) => executeResult.output?.[k] !== undefined)) {
return JSON.stringify(executeResult.output) return JSON.stringify(executeResult.output)
} }
} }

View File

@@ -19,7 +19,7 @@ interface GoogleIdToken {
/** /**
* Get all OAuth connections for the current user * Get all OAuth connections for the current user
*/ */
export async function GET(request: NextRequest) { export async function GET(_request: NextRequest) {
const requestId = generateRequestId() const requestId = generateRequestId()
try { try {

View File

@@ -177,7 +177,6 @@ describe('OAuth Token API Routes', () => {
const { POST } = await import('@/app/api/auth/oauth/token/route') const { POST } = await import('@/app/api/auth/oauth/token/route')
const response = await POST(req) const response = await POST(req)
const data = await response.json()
expect(response.status).toBe(403) expect(response.status).toBe(403)
}) })

View File

@@ -1,4 +1,4 @@
import crypto from 'crypto' import crypto from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth' import { getSession } from '@/lib/auth'

View File

@@ -8,7 +8,7 @@ const logger = createLogger('TrelloAuthorize')
export const dynamic = 'force-dynamic' export const dynamic = 'force-dynamic'
export async function GET(request: NextRequest) { export async function GET(_request: NextRequest) {
try { try {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {

View File

@@ -3,7 +3,7 @@ import { getBaseUrl } from '@/lib/core/utils/urls'
export const dynamic = 'force-dynamic' export const dynamic = 'force-dynamic'
export async function GET(request: NextRequest) { export async function GET(_request: NextRequest) {
const baseUrl = getBaseUrl() const baseUrl = getBaseUrl()
return new NextResponse( return new NextResponse(

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { db } from '@sim/db' import { db } from '@sim/db'
import { chat, verification } from '@sim/db/schema' import { chat, verification } from '@sim/db/schema'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { db } from '@sim/db' import { db } from '@sim/db'
import { chat, workflow } from '@sim/db/schema' import { chat, workflow } from '@sim/db/schema'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'

View File

@@ -42,7 +42,7 @@ const chatSchema = z.object({
.default([]), .default([]),
}) })
export async function GET(request: NextRequest) { export async function GET(_request: NextRequest) {
try { try {
const session = await getSession() const session = await getSession()

View File

@@ -61,7 +61,7 @@ export async function POST(req: NextRequest) {
{ success: true, key: { id: data?.id || 'new', apiKey: data.apiKey } }, { success: true, key: { id: data?.id || 'new', apiKey: data.apiKey } },
{ status: 201 } { status: 201 }
) )
} catch (error) { } catch (_error) {
return NextResponse.json({ error: 'Failed to generate copilot API key' }, { status: 500 }) return NextResponse.json({ error: 'Failed to generate copilot API key' }, { status: 500 })
} }
} }

View File

@@ -3,7 +3,7 @@ import { getSession } from '@/lib/auth'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/copilot/constants' import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/copilot/constants'
import { env } from '@/lib/core/config/env' import { env } from '@/lib/core/config/env'
export async function GET(request: NextRequest) { export async function GET(_request: NextRequest) {
try { try {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {
@@ -49,7 +49,7 @@ export async function GET(request: NextRequest) {
}) })
return NextResponse.json({ keys }, { status: 200 }) return NextResponse.json({ keys }, { status: 200 })
} catch (error) { } catch (_error) {
return NextResponse.json({ error: 'Failed to get keys' }, { status: 500 }) return NextResponse.json({ error: 'Failed to get keys' }, { status: 500 })
} }
} }
@@ -89,7 +89,7 @@ export async function DELETE(request: NextRequest) {
} }
return NextResponse.json({ success: true }, { status: 200 }) return NextResponse.json({ success: true }, { status: 200 })
} catch (error) { } catch (_error) {
return NextResponse.json({ error: 'Failed to delete key' }, { status: 500 }) return NextResponse.json({ error: 'Failed to delete key' }, { status: 500 })
} }
} }

View File

@@ -494,20 +494,6 @@ export async function POST(req: NextRequest) {
// If streaming is requested, forward the stream and update chat later // If streaming is requested, forward the stream and update chat later
if (stream && simAgentResponse.body) { if (stream && simAgentResponse.body) {
// Create user message to save
const userMessage = {
id: userMessageIdToUse, // Consistent ID used for request and persistence
role: 'user',
content: message,
timestamp: new Date().toISOString(),
...(fileAttachments && fileAttachments.length > 0 && { fileAttachments }),
...(Array.isArray(contexts) && contexts.length > 0 && { contexts }),
...(Array.isArray(contexts) &&
contexts.length > 0 && {
contentBlocks: [{ type: 'contexts', contexts: contexts as any, timestamp: Date.now() }],
}),
}
// Create a pass-through stream that captures the response // Create a pass-through stream that captures the response
const transformedStream = new ReadableStream({ const transformedStream = new ReadableStream({
async start(controller) { async start(controller) {
@@ -515,14 +501,11 @@ export async function POST(req: NextRequest) {
let assistantContent = '' let assistantContent = ''
const toolCalls: any[] = [] const toolCalls: any[] = []
let buffer = '' let buffer = ''
const isFirstDone = true
let responseIdFromStart: string | undefined
let responseIdFromDone: string | undefined let responseIdFromDone: string | undefined
// Track tool call progress to identify a safe done event // Track tool call progress to identify a safe done event
const announcedToolCallIds = new Set<string>() const announcedToolCallIds = new Set<string>()
const startedToolExecutionIds = new Set<string>() const startedToolExecutionIds = new Set<string>()
const completedToolExecutionIds = new Set<string>() const completedToolExecutionIds = new Set<string>()
let lastDoneResponseId: string | undefined
let lastSafeDoneResponseId: string | undefined let lastSafeDoneResponseId: string | undefined
// Send chatId as first event // Send chatId as first event
@@ -564,9 +547,15 @@ export async function POST(req: NextRequest) {
} }
// Forward the sim agent stream and capture assistant response // Forward the sim agent stream and capture assistant response
const reader = simAgentResponse.body!.getReader() const reader = simAgentResponse.body?.getReader()
const decoder = new TextDecoder() const decoder = new TextDecoder()
if (!reader) {
logger.error(`[${tracker.requestId}] Failed to get reader from response body`)
controller.close()
return
}
try { try {
while (true) { while (true) {
const { done, value } = await reader.read() const { done, value } = await reader.read()
@@ -647,15 +636,11 @@ export async function POST(req: NextRequest) {
break break
case 'start': case 'start':
if (event.data?.responseId) {
responseIdFromStart = event.data.responseId
}
break break
case 'done': case 'done':
if (event.data?.responseId) { if (event.data?.responseId) {
responseIdFromDone = event.data.responseId responseIdFromDone = event.data.responseId
lastDoneResponseId = responseIdFromDone
// Mark this done as safe only if no tool call is currently in progress or pending // Mark this done as safe only if no tool call is currently in progress or pending
const announced = announcedToolCallIds.size const announced = announcedToolCallIds.size
@@ -690,7 +675,7 @@ export async function POST(req: NextRequest) {
`data: ${JSON.stringify({ type: 'content', data: formatted })}\n\n` `data: ${JSON.stringify({ type: 'content', data: formatted })}\n\n`
) )
) )
} catch (enqueueErr) { } catch (_enqueueErr) {
reader.cancel() reader.cancel()
break break
} }
@@ -699,7 +684,7 @@ export async function POST(req: NextRequest) {
controller.enqueue( controller.enqueue(
encoder.encode(`data: ${JSON.stringify({ type: 'done' })}\n\n`) encoder.encode(`data: ${JSON.stringify({ type: 'done' })}\n\n`)
) )
} catch (enqueueErr) { } catch (_enqueueErr) {
reader.cancel() reader.cancel()
break break
} }
@@ -709,7 +694,7 @@ export async function POST(req: NextRequest) {
// Forward original event to client // Forward original event to client
try { try {
controller.enqueue(encoder.encode(`data: ${jsonStr}\n\n`)) controller.enqueue(encoder.encode(`data: ${jsonStr}\n\n`))
} catch (enqueueErr) { } catch (_enqueueErr) {
reader.cancel() reader.cancel()
break break
} }
@@ -767,17 +752,17 @@ export async function POST(req: NextRequest) {
controller.enqueue( controller.enqueue(
encoder.encode(`data: ${JSON.stringify({ type: 'done' })}\n\n`) encoder.encode(`data: ${JSON.stringify({ type: 'done' })}\n\n`)
) )
} catch (enqueueErr) { } catch (_enqueueErr) {
reader.cancel() reader.cancel()
} }
} else { } else {
try { try {
controller.enqueue(encoder.encode(`data: ${jsonStr}\n\n`)) controller.enqueue(encoder.encode(`data: ${jsonStr}\n\n`))
} catch (enqueueErr) { } catch (_enqueueErr) {
reader.cancel() reader.cancel()
} }
} }
} catch (e) { } catch (_e) {
logger.warn(`[${tracker.requestId}] Failed to parse final buffer: "${buffer}"`) logger.warn(`[${tracker.requestId}] Failed to parse final buffer: "${buffer}"`)
} }
} }

View File

@@ -113,7 +113,7 @@ export async function POST(request: NextRequest) {
) )
} }
const result = await stateResponse.json() const _result = await stateResponse.json()
logger.info( logger.info(
`[${tracker.requestId}] Successfully reverted workflow ${checkpoint.workflowId} to checkpoint ${checkpointId}` `[${tracker.requestId}] Successfully reverted workflow ${checkpoint.workflowId} to checkpoint ${checkpointId}`
) )

View File

@@ -63,7 +63,7 @@ export async function POST(req: NextRequest) {
let parsedWorkflowState let parsedWorkflowState
try { try {
parsedWorkflowState = JSON.parse(workflowState) parsedWorkflowState = JSON.parse(workflowState)
} catch (error) { } catch (_error) {
return createBadRequestResponse('Invalid workflow state JSON') return createBadRequestResponse('Invalid workflow state JSON')
} }

View File

@@ -121,8 +121,6 @@ export async function POST(req: NextRequest) {
return createBadRequestResponse('Failed to update tool call status or tool call not found') return createBadRequestResponse('Failed to update tool call status or tool call not found')
} }
const duration = tracker.getDuration()
return NextResponse.json({ return NextResponse.json({
success: true, success: true,
message: message || `Tool call ${toolCallId} has been ${status.toLowerCase()}`, message: message || `Tool call ${toolCallId} has been ${status.toLowerCase()}`,

View File

@@ -111,7 +111,7 @@ export async function POST(req: NextRequest) {
* GET /api/copilot/feedback * GET /api/copilot/feedback
* Get all feedback records (for analytics) * Get all feedback records (for analytics)
*/ */
export async function GET(req: NextRequest) { export async function GET(_req: NextRequest) {
const tracker = createRequestTracker() const tracker = createRequestTracker()
try { try {

View File

@@ -5,7 +5,6 @@ import {
authenticateCopilotRequestSessionOnly, authenticateCopilotRequestSessionOnly,
createBadRequestResponse, createBadRequestResponse,
createInternalServerErrorResponse, createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse, createUnauthorizedResponse,
} from '@/lib/copilot/request-helpers' } from '@/lib/copilot/request-helpers'
import { env } from '@/lib/core/config/env' import { env } from '@/lib/core/config/env'
@@ -19,7 +18,6 @@ const BodySchema = z.object({
}) })
export async function POST(req: NextRequest) { export async function POST(req: NextRequest) {
const tracker = createRequestTracker()
try { try {
const { userId, isAuthenticated } = await authenticateCopilotRequestSessionOnly() const { userId, isAuthenticated } = await authenticateCopilotRequestSessionOnly()
if (!isAuthenticated || !userId) { if (!isAuthenticated || !userId) {
@@ -62,7 +60,7 @@ export async function POST(req: NextRequest) {
} }
return NextResponse.json({ success: true }) return NextResponse.json({ success: true })
} catch (error) { } catch (_error) {
return createInternalServerErrorResponse('Failed to forward copilot stats') return createInternalServerErrorResponse('Failed to forward copilot stats')
} }
} }

View File

@@ -34,7 +34,7 @@ const DEFAULT_ENABLED_MODELS: Record<CopilotModelId, boolean> = {
} }
// GET - Fetch user's enabled models // GET - Fetch user's enabled models
export async function GET(request: NextRequest) { export async function GET(_request: NextRequest) {
try { try {
const session = await getSession() const session = await getSession()

View File

@@ -46,7 +46,7 @@ async function hasPermission(userId: string, profile: any): Promise<boolean> {
} }
// GET /api/creators/[id] - Get a specific creator profile // GET /api/creators/[id] - Get a specific creator profile
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { id } = await params const { id } = await params
@@ -137,7 +137,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
// DELETE /api/creators/[id] - Delete a creator profile // DELETE /api/creators/[id] - Delete a creator profile
export async function DELETE( export async function DELETE(
request: NextRequest, _request: NextRequest,
{ params }: { params: Promise<{ id: string }> } { params }: { params: Promise<{ id: string }> }
) { ) {
const requestId = generateRequestId() const requestId = generateRequestId()

View File

@@ -12,7 +12,7 @@ const logger = createLogger('CreatorVerificationAPI')
export const revalidate = 0 export const revalidate = 0
// POST /api/creators/[id]/verify - Verify a creator (super users only) // POST /api/creators/[id]/verify - Verify a creator (super users only)
export async function POST(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function POST(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { id } = await params const { id } = await params
@@ -62,7 +62,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
// DELETE /api/creators/[id]/verify - Unverify a creator (super users only) // DELETE /api/creators/[id]/verify - Unverify a creator (super users only)
export async function DELETE( export async function DELETE(
request: NextRequest, _request: NextRequest,
{ params }: { params: Promise<{ id: string }> } { params }: { params: Promise<{ id: string }> }
) { ) {
const requestId = generateRequestId() const requestId = generateRequestId()

View File

@@ -30,8 +30,6 @@ const CreateCreatorProfileSchema = z.object({
// GET /api/creators - Get creator profiles for current user // GET /api/creators - Get creator profiles for current user
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { searchParams } = new URL(request.url)
const userId = searchParams.get('userId')
try { try {
const session = await getSession() const session = await getSession()

View File

@@ -37,7 +37,7 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
} }
export async function POST( export async function POST(
req: NextRequest, _req: NextRequest,
{ params }: { params: Promise<{ id: string; invitationId: string }> } { params }: { params: Promise<{ id: string; invitationId: string }> }
) { ) {
const session = await getSession() const session = await getSession()

View File

@@ -41,7 +41,7 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
return { set, role: membership.role } return { set, role: membership.role }
} }
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {

View File

@@ -33,7 +33,7 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
return { set, role: membership.role } return { set, role: membership.role }
} }
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {

View File

@@ -43,7 +43,7 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
return { set, role: membership.role } return { set, role: membership.role }
} }
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {
@@ -141,7 +141,7 @@ export async function PUT(req: NextRequest, { params }: { params: Promise<{ id:
} }
} }
export async function DELETE(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function DELETE(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {

View File

@@ -13,7 +13,7 @@ import { syncAllWebhooksForCredentialSet } from '@/lib/webhooks/utils.server'
const logger = createLogger('CredentialSetInviteToken') const logger = createLogger('CredentialSetInviteToken')
export async function GET(req: NextRequest, { params }: { params: Promise<{ token: string }> }) { export async function GET(_req: NextRequest, { params }: { params: Promise<{ token: string }> }) {
const { token } = await params const { token } = await params
const [invitation] = await db const [invitation] = await db
@@ -61,7 +61,7 @@ export async function GET(req: NextRequest, { params }: { params: Promise<{ toke
}) })
} }
export async function POST(req: NextRequest, { params }: { params: Promise<{ token: string }> }) { export async function POST(_req: NextRequest, { params }: { params: Promise<{ token: string }> }) {
const { token } = await params const { token } = await params
const session = await getSession() const session = await getSession()

View File

@@ -72,7 +72,7 @@ export async function POST(req: NextRequest) {
} }
} }
export async function GET(request: Request) { export async function GET(_request: Request) {
const requestId = generateRequestId() const requestId = generateRequestId()
try { try {

View File

@@ -162,7 +162,7 @@ async function verifyWorkspaceFileAccess(
cloudKey: string, cloudKey: string,
userId: string, userId: string,
customConfig?: StorageConfig, customConfig?: StorageConfig,
isLocal?: boolean _isLocal?: boolean
): Promise<boolean> { ): Promise<boolean> {
try { try {
// Priority 1: Check database (most reliable, works for both local and cloud) // Priority 1: Check database (most reliable, works for both local and cloud)
@@ -228,7 +228,7 @@ async function verifyWorkspaceFileAccess(
async function verifyExecutionFileAccess( async function verifyExecutionFileAccess(
cloudKey: string, cloudKey: string,
userId: string, userId: string,
customConfig?: StorageConfig _customConfig?: StorageConfig
): Promise<boolean> { ): Promise<boolean> {
const parts = cloudKey.split('/') const parts = cloudKey.split('/')
@@ -493,7 +493,7 @@ async function verifyRegularFileAccess(
cloudKey: string, cloudKey: string,
userId: string, userId: string,
customConfig?: StorageConfig, customConfig?: StorageConfig,
isLocal?: boolean _isLocal?: boolean
): Promise<boolean> { ): Promise<boolean> {
try { try {
// Priority 1: Check if this might be a workspace file (check database) // Priority 1: Check if this might be a workspace file (check database)

View File

@@ -1,4 +1,4 @@
import path from 'path' import path from 'node:path'
/** /**
* Tests for file parse API route * Tests for file parse API route
* *

View File

@@ -1,7 +1,7 @@
import { Buffer } from 'buffer' import { Buffer } from 'node:buffer'
import { createHash } from 'crypto' import { createHash } from 'node:crypto'
import fsPromises, { readFile } from 'fs/promises' import fsPromises, { readFile } from 'node:fs/promises'
import path from 'path' import path from 'node:path'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import binaryExtensionsList from 'binary-extensions' import binaryExtensionsList from 'binary-extensions'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
@@ -899,7 +899,7 @@ Please use a PDF viewer for best results.`
* Create error message for PDF parsing failure and make it more readable * Create error message for PDF parsing failure and make it more readable
*/ */
function createPdfFailureMessage( function createPdfFailureMessage(
pageCount: number, _pageCount: number,
size: number, size: number,
path: string, path: string,
error: string error: string

View File

@@ -131,7 +131,7 @@ describe('File Serve API Route', () => {
expect(disposition).toContain('filename=') expect(disposition).toContain('filename=')
expect(disposition).toContain('test-file.txt') expect(disposition).toContain('test-file.txt')
const fs = await import('fs/promises') const fs = await import('node:fs/promises')
expect(fs.readFile).toHaveBeenCalled() expect(fs.readFile).toHaveBeenCalled()
}) })
@@ -196,7 +196,7 @@ describe('File Serve API Route', () => {
expect(response.status).toBe(200) expect(response.status).toBe(200)
const fs = await import('fs/promises') const fs = await import('node:fs/promises')
expect(fs.readFile).toHaveBeenCalledWith('/test/uploads/nested/path/file.txt') expect(fs.readFile).toHaveBeenCalledWith('/test/uploads/nested/path/file.txt')
}) })

View File

@@ -1,4 +1,4 @@
import { readFile } from 'fs/promises' import { readFile } from 'node:fs/promises'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import type { NextRequest } from 'next/server' import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server' import { NextResponse } from 'next/server'

View File

@@ -1,5 +1,5 @@
import { existsSync } from 'fs' import { existsSync } from 'node:fs'
import { join, resolve, sep } from 'path' import { join, resolve, sep } from 'node:path'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { NextResponse } from 'next/server' import { NextResponse } from 'next/server'
import { UPLOAD_DIR } from '@/lib/uploads/config' import { UPLOAD_DIR } from '@/lib/uploads/config'
@@ -119,7 +119,7 @@ export function extractFilename(path: string): string {
return filename return filename
} }
function sanitizeFilename(filename: string): string { function _sanitizeFilename(filename: string): string {
if (!filename || typeof filename !== 'string') { if (!filename || typeof filename !== 'string') {
throw new Error('Invalid filename provided') throw new Error('Invalid filename provided')
} }

View File

@@ -321,7 +321,7 @@ describe('Individual Folder API Route', () => {
await PUT(req, { params }) await PUT(req, { params })
expect(capturedUpdates).not.toBeNull() expect(capturedUpdates).not.toBeNull()
expect(capturedUpdates!.name).toBe('Folder With Spaces') expect(capturedUpdates?.name).toBe('Folder With Spaces')
}) })
it('should handle database errors gracefully', async () => { it('should handle database errors gracefully', async () => {

View File

@@ -106,7 +106,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
// DELETE - Delete a folder and all its contents // DELETE - Delete a folder and all its contents
export async function DELETE( export async function DELETE(
request: NextRequest, _request: NextRequest,
{ params }: { params: Promise<{ id: string }> } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {

View File

@@ -551,7 +551,7 @@ describe('Folders API Route', () => {
await POST(req) await POST(req)
expect(capturedValues).not.toBeNull() expect(capturedValues).not.toBeNull()
expect(capturedValues!.name).toBe('Test Folder With Spaces') expect(capturedValues?.name).toBe('Test Folder With Spaces')
}) })
it('should use default color when not provided', async () => { it('should use default color when not provided', async () => {
@@ -591,7 +591,7 @@ describe('Folders API Route', () => {
await POST(req) await POST(req)
expect(capturedValues).not.toBeNull() expect(capturedValues).not.toBeNull()
expect(capturedValues!.color).toBe('#6B7280') expect(capturedValues?.color).toBe('#6B7280')
}) })
}) })
}) })

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { db } from '@sim/db' import { db } from '@sim/db'
import { form, workflow, workflowBlocks } from '@sim/db/schema' import { form, workflow, workflowBlocks } from '@sim/db/schema'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
@@ -235,28 +235,11 @@ export async function POST(
// For forms, we don't stream back - we wait for completion and return success // For forms, we don't stream back - we wait for completion and return success
// Consume the stream to wait for completion // Consume the stream to wait for completion
const reader = stream.getReader() const reader = stream.getReader()
let lastOutput: any = null
try { try {
while (true) { while (true) {
const { done, value } = await reader.read() const { done } = await reader.read()
if (done) break if (done) break
// Parse SSE data if present
const text = new TextDecoder().decode(value)
const lines = text.split('\n')
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6))
if (data.type === 'complete' || data.output) {
lastOutput = data.output || data
}
} catch {
// Ignore parse errors
}
}
}
} }
} finally { } finally {
reader.releaseLock() reader.releaseLock()

View File

@@ -62,7 +62,7 @@ const updateFormSchema = z.object({
isActive: z.boolean().optional(), isActive: z.boolean().optional(),
}) })
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
try { try {
const session = await getSession() const session = await getSession()
@@ -201,7 +201,7 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
} }
export async function DELETE( export async function DELETE(
request: NextRequest, _request: NextRequest,
{ params }: { params: Promise<{ id: string }> } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {

View File

@@ -64,7 +64,7 @@ const formSchema = z.object({
showBranding: z.boolean().optional().default(true), showBranding: z.boolean().optional().default(true),
}) })
export async function GET(request: NextRequest) { export async function GET(_request: NextRequest) {
try { try {
const session = await getSession() const session = await getSession()

View File

@@ -63,7 +63,7 @@ describe('Form API Utils', () => {
it.concurrent('should validate tokens with password hash', async () => { it.concurrent('should validate tokens with password hash', async () => {
const { validateAuthToken } = await import('@/lib/core/security/deployment') const { validateAuthToken } = await import('@/lib/core/security/deployment')
const crypto = await import('crypto') const crypto = await import('node:crypto')
const formId = 'test-form-id' const formId = 'test-form-id'
const encryptedPassword = 'encrypted-password-value' const encryptedPassword = 'encrypted-password-value'

View File

@@ -292,7 +292,7 @@ function formatE2BError(
*/ */
function createUserFriendlyErrorMessage( function createUserFriendlyErrorMessage(
enhanced: EnhancedError, enhanced: EnhancedError,
requestId: string, _requestId: string,
userCode?: string userCode?: string
): string { ): string {
let errorMessage = enhanced.message let errorMessage = enhanced.message

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
@@ -14,7 +14,7 @@ const UpdateChunkSchema = z.object({
}) })
export async function GET( export async function GET(
req: NextRequest, _req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> } { params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> }
) { ) {
const requestId = randomUUID().slice(0, 8) const requestId = randomUUID().slice(0, 8)
@@ -134,7 +134,7 @@ export async function PUT(
} }
export async function DELETE( export async function DELETE(
req: NextRequest, _req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> } { params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> }
) { ) {
const requestId = randomUUID().slice(0, 8) const requestId = randomUUID().slice(0, 8)

View File

@@ -47,7 +47,7 @@ const UpdateDocumentSchema = z.object({
}) })
export async function GET( export async function GET(
req: NextRequest, _req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string }> } { params }: { params: Promise<{ id: string; documentId: string }> }
) { ) {
const requestId = generateRequestId() const requestId = generateRequestId()
@@ -123,8 +123,6 @@ export async function PUT(
try { try {
const validatedData = UpdateDocumentSchema.parse(body) const validatedData = UpdateDocumentSchema.parse(body)
const updateData: any = {}
if (validatedData.markFailedDueToTimeout) { if (validatedData.markFailedDueToTimeout) {
const doc = accessCheck.document const doc = accessCheck.document
@@ -220,7 +218,7 @@ export async function PUT(
} }
export async function DELETE( export async function DELETE(
req: NextRequest, _req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string }> } { params }: { params: Promise<{ id: string; documentId: string }> }
) { ) {
const requestId = generateRequestId() const requestId = generateRequestId()

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
@@ -31,7 +31,7 @@ const BulkTagDefinitionsSchema = z.object({
// GET /api/knowledge/[id]/documents/[documentId]/tag-definitions - Get tag definitions for a document // GET /api/knowledge/[id]/documents/[documentId]/tag-definitions - Get tag definitions for a document
export async function GET( export async function GET(
req: NextRequest, _req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string }> } { params }: { params: Promise<{ id: string; documentId: string }> }
) { ) {
const requestId = randomUUID().slice(0, 8) const requestId = randomUUID().slice(0, 8)

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth' import { getSession } from '@/lib/auth'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth' import { getSession } from '@/lib/auth'
@@ -11,7 +11,7 @@ const logger = createLogger('TagDefinitionAPI')
// DELETE /api/knowledge/[id]/tag-definitions/[tagId] - Delete a tag definition // DELETE /api/knowledge/[id]/tag-definitions/[tagId] - Delete a tag definition
export async function DELETE( export async function DELETE(
req: NextRequest, _req: NextRequest,
{ params }: { params: Promise<{ id: string; tagId: string }> } { params }: { params: Promise<{ id: string; tagId: string }> }
) { ) {
const requestId = randomUUID().slice(0, 8) const requestId = randomUUID().slice(0, 8)

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth' import { getSession } from '@/lib/auth'
@@ -10,7 +10,7 @@ export const dynamic = 'force-dynamic'
const logger = createLogger('TagUsageAPI') const logger = createLogger('TagUsageAPI')
// GET /api/knowledge/[id]/tag-usage - Get usage statistics for all tag definitions // GET /api/knowledge/[id]/tag-usage - Get usage statistics for all tag definitions
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8) const requestId = randomUUID().slice(0, 8)
const { id: knowledgeBaseId } = await params const { id: knowledgeBaseId } = await params

View File

@@ -269,7 +269,7 @@ function getStructuredTagFilters(filters: StructuredFilter[], embeddingTable: an
if (!filtersBySlot.has(slot)) { if (!filtersBySlot.has(slot)) {
filtersBySlot.set(slot, []) filtersBySlot.set(slot, [])
} }
filtersBySlot.get(slot)!.push(filter) filtersBySlot.get(slot)?.push(filter)
} }
// Build conditions: OR within same slot, AND across different slots // Build conditions: OR within same slot, AND across different slots

View File

@@ -63,7 +63,7 @@ async function getServer(serverId: string) {
return server return server
} }
export async function GET(request: NextRequest, { params }: { params: Promise<RouteParams> }) { export async function GET(_request: NextRequest, { params }: { params: Promise<RouteParams> }) {
const { serverId } = await params const { serverId } = await params
try { try {

View File

@@ -140,7 +140,7 @@ async function syncToolSchemasToWorkflows(
} }
export const POST = withMcpAuth<{ id: string }>('read')( export const POST = withMcpAuth<{ id: string }>('read')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => { async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
const { id: serverId } = await params const { id: serverId } = await params
try { try {

View File

@@ -19,7 +19,7 @@ export const dynamic = 'force-dynamic'
* GET - List all registered MCP servers for the workspace * GET - List all registered MCP servers for the workspace
*/ */
export const GET = withMcpAuth('read')( export const GET = withMcpAuth('read')(
async (request: NextRequest, { userId, workspaceId, requestId }) => { async (_request: NextRequest, { userId, workspaceId, requestId }) => {
try { try {
logger.info(`[${requestId}] Listing MCP servers for workspace ${workspaceId}`) logger.info(`[${requestId}] Listing MCP servers for workspace ${workspaceId}`)

View File

@@ -12,7 +12,7 @@ const logger = createLogger('McpStoredToolsAPI')
export const dynamic = 'force-dynamic' export const dynamic = 'force-dynamic'
export const GET = withMcpAuth('read')( export const GET = withMcpAuth('read')(
async (request: NextRequest, { userId, workspaceId, requestId }) => { async (_request: NextRequest, { userId, workspaceId, requestId }) => {
try { try {
logger.info(`[${requestId}] Fetching stored MCP tools for workspace ${workspaceId}`) logger.info(`[${requestId}] Fetching stored MCP tools for workspace ${workspaceId}`)

View File

@@ -18,7 +18,7 @@ interface RouteParams {
* GET - Get a specific workflow MCP server with its tools * GET - Get a specific workflow MCP server with its tools
*/ */
export const GET = withMcpAuth<RouteParams>('read')( export const GET = withMcpAuth<RouteParams>('read')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => { async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
try { try {
const { id: serverId } = await params const { id: serverId } = await params
@@ -127,7 +127,7 @@ export const PATCH = withMcpAuth<RouteParams>('write')(
* DELETE - Delete a workflow MCP server and all its tools * DELETE - Delete a workflow MCP server and all its tools
*/ */
export const DELETE = withMcpAuth<RouteParams>('admin')( export const DELETE = withMcpAuth<RouteParams>('admin')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => { async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
try { try {
const { id: serverId } = await params const { id: serverId } = await params

View File

@@ -20,7 +20,7 @@ interface RouteParams {
* GET - Get a specific tool * GET - Get a specific tool
*/ */
export const GET = withMcpAuth<RouteParams>('read')( export const GET = withMcpAuth<RouteParams>('read')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => { async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
try { try {
const { id: serverId, toolId } = await params const { id: serverId, toolId } = await params
@@ -131,7 +131,7 @@ export const PATCH = withMcpAuth<RouteParams>('write')(
* DELETE - Remove a tool from an MCP server * DELETE - Remove a tool from an MCP server
*/ */
export const DELETE = withMcpAuth<RouteParams>('write')( export const DELETE = withMcpAuth<RouteParams>('write')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => { async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
try { try {
const { id: serverId, toolId } = await params const { id: serverId, toolId } = await params

View File

@@ -20,7 +20,7 @@ interface RouteParams {
* GET - List all tools for a workflow MCP server * GET - List all tools for a workflow MCP server
*/ */
export const GET = withMcpAuth<RouteParams>('read')( export const GET = withMcpAuth<RouteParams>('read')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => { async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
try { try {
const { id: serverId } = await params const { id: serverId } = await params

View File

@@ -16,7 +16,7 @@ export const dynamic = 'force-dynamic'
* GET - List all workflow MCP servers for the workspace * GET - List all workflow MCP servers for the workspace
*/ */
export const GET = withMcpAuth('read')( export const GET = withMcpAuth('read')(
async (request: NextRequest, { userId, workspaceId, requestId }) => { async (_request: NextRequest, { userId, workspaceId, requestId }) => {
try { try {
logger.info(`[${requestId}] Listing workflow MCP servers for workspace ${workspaceId}`) logger.info(`[${requestId}] Listing workflow MCP servers for workspace ${workspaceId}`)

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { db } from '@sim/db' import { db } from '@sim/db'
import { import {
invitation, invitation,

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { db } from '@sim/db' import { db } from '@sim/db'
import { import {
invitation, invitation,
@@ -42,7 +42,7 @@ interface WorkspaceInvitation {
* GET /api/organizations/[id]/invitations * GET /api/organizations/[id]/invitations
* Get all pending invitations for an organization * Get all pending invitations for an organization
*/ */
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
try { try {
const session = await getSession() const session = await getSession()

View File

@@ -239,7 +239,7 @@ export async function PUT(
* Remove member from organization * Remove member from organization
*/ */
export async function DELETE( export async function DELETE(
request: NextRequest, _request: NextRequest,
{ params }: { params: Promise<{ id: string; memberId: string }> } { params }: { params: Promise<{ id: string; memberId: string }> }
) { ) {
try { try {

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { db } from '@sim/db' import { db } from '@sim/db'
import { invitation, member, organization, user, userStats } from '@sim/db/schema' import { invitation, member, organization, user, userStats } from '@sim/db/schema'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'

View File

@@ -32,7 +32,7 @@ async function getPermissionGroupWithAccess(groupId: string, userId: string) {
return { group, role: membership.role } return { group, role: membership.role }
} }
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {

View File

@@ -70,7 +70,7 @@ async function getPermissionGroupWithAccess(groupId: string, userId: string) {
return { group, role: membership.role } return { group, role: membership.role }
} }
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {
@@ -195,7 +195,7 @@ export async function PUT(req: NextRequest, { params }: { params: Promise<{ id:
} }
} }
export async function DELETE(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function DELETE(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const session = await getSession() const session = await getSession()
if (!session?.user?.id) { if (!session?.user?.id) {

View File

@@ -5,7 +5,7 @@ export async function GET() {
try { try {
const allModels = Object.keys(getBaseModelProviders()) const allModels = Object.keys(getBaseModelProviders())
return NextResponse.json({ models: allModels }) return NextResponse.json({ models: allModels })
} catch (error) { } catch (_error) {
return NextResponse.json({ models: [], error: 'Failed to fetch models' }, { status: 500 }) return NextResponse.json({ models: [], error: 'Failed to fetch models' }, { status: 500 })
} }
} }

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { generateRequestId } from '@/lib/core/utils/request' import { generateRequestId } from '@/lib/core/utils/request'

View File

@@ -14,7 +14,7 @@ export const revalidate = 0
/** /**
* POST /api/templates/[id]/approve - Approve a template (super users only) * POST /api/templates/[id]/approve - Approve a template (super users only)
*/ */
export async function POST(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function POST(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { id } = await params const { id } = await params

View File

@@ -14,7 +14,7 @@ export const revalidate = 0
/** /**
* POST /api/templates/[id]/reject - Reject a template (super users only) * POST /api/templates/[id]/reject - Reject a template (super users only)
*/ */
export async function POST(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function POST(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { id } = await params const { id } = await params

View File

@@ -16,7 +16,7 @@ const logger = createLogger('TemplateByIdAPI')
export const revalidate = 0 export const revalidate = 0
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { id } = await params const { id } = await params
@@ -234,7 +234,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
// DELETE /api/templates/[id] - Delete a template // DELETE /api/templates/[id] - Delete a template
export async function DELETE( export async function DELETE(
request: NextRequest, _request: NextRequest,
{ params }: { params: Promise<{ id: string }> } { params }: { params: Promise<{ id: string }> }
) { ) {
const requestId = generateRequestId() const requestId = generateRequestId()

View File

@@ -13,7 +13,7 @@ export const dynamic = 'force-dynamic'
export const revalidate = 0 export const revalidate = 0
// GET /api/templates/[id]/star - Check if user has starred this template // GET /api/templates/[id]/star - Check if user has starred this template
export async function GET(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function GET(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { id } = await params const { id } = await params
@@ -47,7 +47,7 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
} }
// POST /api/templates/[id]/star - Add a star to the template // POST /api/templates/[id]/star - Add a star to the template
export async function POST(request: NextRequest, { params }: { params: Promise<{ id: string }> }) { export async function POST(_request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = generateRequestId() const requestId = generateRequestId()
const { id } = await params const { id } = await params
@@ -120,7 +120,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
// DELETE /api/templates/[id]/star - Remove a star from the template // DELETE /api/templates/[id]/star - Remove a star from the template
export async function DELETE( export async function DELETE(
request: NextRequest, _request: NextRequest,
{ params }: { params: Promise<{ id: string }> } { params }: { params: Promise<{ id: string }> }
) { ) {
const requestId = generateRequestId() const requestId = generateRequestId()

View File

@@ -136,7 +136,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
} }
// Use a transaction for template updates and deployment version // Use a transaction for template updates and deployment version
const result = await db.transaction(async (tx) => { const _result = await db.transaction(async (tx) => {
// Prepare template update data // Prepare template update data
const updateData: any = { const updateData: any = {
views: sql`${templates.views} + 1`, views: sql`${templates.views} + 1`,

View File

@@ -20,7 +20,6 @@ export async function GET(request: NextRequest) {
const requestId = generateRequestId() const requestId = generateRequestId()
try { try {
const url = new URL(request.url)
const hasApiKey = !!request.headers.get('x-api-key') const hasApiKey = !!request.headers.get('x-api-key')
// Check internal API key authentication // Check internal API key authentication
@@ -126,7 +125,7 @@ export async function GET(request: NextRequest) {
} }
// Add a helpful OPTIONS handler for CORS preflight // Add a helpful OPTIONS handler for CORS preflight
export async function OPTIONS(request: NextRequest) { export async function OPTIONS(_request: NextRequest) {
const requestId = generateRequestId() const requestId = generateRequestId()
logger.info(`[${requestId}] OPTIONS request received for /api/templates/approved/sanitized`) logger.info(`[${requestId}] OPTIONS request received for /api/templates/approved/sanitized`)

View File

@@ -9,7 +9,7 @@ import type {
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
import { createA2AClient, extractTextContent, isTerminalState } from '@/lib/a2a/utils' import { createA2AClient, isTerminalState } from '@/lib/a2a/utils'
import { checkHybridAuth } from '@/lib/auth/hybrid' import { checkHybridAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request' import { generateRequestId } from '@/lib/core/utils/request'
@@ -50,14 +50,12 @@ export async function POST(request: NextRequest) {
let taskId = validatedData.taskId let taskId = validatedData.taskId
let contextId: string | undefined let contextId: string | undefined
let state: TaskState = 'working' let state: TaskState = 'working'
let content = ''
let artifacts: Artifact[] = [] let artifacts: Artifact[] = []
let history: Message[] = [] let history: Message[] = []
for await (const event of stream) { for await (const event of stream) {
if (event.kind === 'message') { if (event.kind === 'message') {
const msg = event as Message const msg = event as Message
content = extractTextContent(msg)
taskId = msg.taskId || taskId taskId = msg.taskId || taskId
contextId = msg.contextId || contextId contextId = msg.contextId || contextId
state = 'completed' state = 'completed'
@@ -68,10 +66,6 @@ export async function POST(request: NextRequest) {
state = task.status.state state = task.status.state
artifacts = task.artifacts || [] artifacts = task.artifacts || []
history = task.history || [] history = task.history || []
const lastAgentMessage = history.filter((m) => m.role === 'agent').pop()
if (lastAgentMessage) {
content = extractTextContent(lastAgentMessage)
}
} else if ('status' in event) { } else if ('status' in event) {
const statusEvent = event as TaskStatusUpdateEvent const statusEvent = event as TaskStatusUpdateEvent
state = statusEvent.status.state state = statusEvent.status.state

View File

@@ -82,7 +82,7 @@ describe('Custom Tools API Routes', () => {
mockSelect.mockReturnValue({ from: mockFrom }) mockSelect.mockReturnValue({ from: mockFrom })
mockFrom.mockReturnValue({ where: mockWhere }) mockFrom.mockReturnValue({ where: mockWhere })
mockWhere.mockImplementation((condition) => { mockWhere.mockImplementation((_condition) => {
const queryBuilder = { const queryBuilder = {
orderBy: mockOrderBy, orderBy: mockOrderBy,
limit: mockLimit, limit: mockLimit,
@@ -90,7 +90,7 @@ describe('Custom Tools API Routes', () => {
resolve(sampleTools) resolve(sampleTools)
return queryBuilder return queryBuilder
}, },
catch: (reject: (error: Error) => void) => queryBuilder, catch: (_reject: (error: Error) => void) => queryBuilder,
} }
return queryBuilder return queryBuilder
}) })
@@ -101,7 +101,7 @@ describe('Custom Tools API Routes', () => {
resolve(sampleTools) resolve(sampleTools)
return queryBuilder return queryBuilder
}, },
catch: (reject: (error: Error) => void) => queryBuilder, catch: (_reject: (error: Error) => void) => queryBuilder,
} }
return queryBuilder return queryBuilder
}) })
@@ -131,12 +131,12 @@ describe('Custom Tools API Routes', () => {
resolve(sampleTools) resolve(sampleTools)
return queryBuilder return queryBuilder
}, },
catch: (reject: (error: Error) => void) => queryBuilder, catch: (_reject: (error: Error) => void) => queryBuilder,
} }
return queryBuilder return queryBuilder
}) })
const txMockWhere = vi.fn().mockImplementation((condition) => { const txMockWhere = vi.fn().mockImplementation((_condition) => {
const queryBuilder = { const queryBuilder = {
orderBy: txMockOrderBy, orderBy: txMockOrderBy,
limit: mockLimit, limit: mockLimit,
@@ -144,7 +144,7 @@ describe('Custom Tools API Routes', () => {
resolve(sampleTools) resolve(sampleTools)
return queryBuilder return queryBuilder
}, },
catch: (reject: (error: Error) => void) => queryBuilder, catch: (_reject: (error: Error) => void) => queryBuilder,
} }
return queryBuilder return queryBuilder
}) })
@@ -274,14 +274,14 @@ describe('Custom Tools API Routes', () => {
mockLimit.mockResolvedValueOnce([{ workspaceId: 'workspace-123' }]) mockLimit.mockResolvedValueOnce([{ workspaceId: 'workspace-123' }])
mockWhere.mockImplementationOnce((condition) => { mockWhere.mockImplementationOnce((_condition) => {
const queryBuilder = { const queryBuilder = {
limit: mockLimit, limit: mockLimit,
then: (resolve: (value: typeof sampleTools) => void) => { then: (resolve: (value: typeof sampleTools) => void) => {
resolve(sampleTools) resolve(sampleTools)
return queryBuilder return queryBuilder
}, },
catch: (reject: (error: Error) => void) => queryBuilder, catch: (_reject: (error: Error) => void) => queryBuilder,
} }
return queryBuilder return queryBuilder
}) })

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,7 +1,6 @@
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { NextResponse } from 'next/server' import { NextResponse } from 'next/server'
import { authorizeCredentialUse } from '@/lib/auth/credential-access' import { authorizeCredentialUse } from '@/lib/auth/credential-access'
import { generateRequestId } from '@/lib/core/utils/request'
import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic' export const dynamic = 'force-dynamic'
@@ -20,7 +19,6 @@ export async function POST(request: Request) {
} }
try { try {
const requestId = generateRequestId()
const authz = await authorizeCredentialUse(request as any, { const authz = await authorizeCredentialUse(request as any, {
credentialId: credential, credentialId: credential,
workflowId, workflowId,

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { db } from '@sim/db' import { db } from '@sim/db'
import { account } from '@sim/db/schema' import { account } from '@sim/db/schema'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'

View File

@@ -1,9 +1,13 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid' import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, sanitizeCollectionName, validateFilter } from '../utils' import {
createMongoDBConnection,
sanitizeCollectionName,
validateFilter,
} from '@/app/api/tools/mongodb/utils'
const logger = createLogger('MongoDBDeleteAPI') const logger = createLogger('MongoDBDeleteAPI')
@@ -69,7 +73,7 @@ export async function POST(request: NextRequest) {
let filterDoc let filterDoc
try { try {
filterDoc = JSON.parse(params.filter) filterDoc = JSON.parse(params.filter)
} catch (error) { } catch (_error) {
logger.warn(`[${requestId}] Invalid filter JSON: ${params.filter}`) logger.warn(`[${requestId}] Invalid filter JSON: ${params.filter}`)
return NextResponse.json({ error: 'Invalid JSON format in filter' }, { status: 400 }) return NextResponse.json({ error: 'Invalid JSON format in filter' }, { status: 400 })
} }

View File

@@ -1,9 +1,13 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid' import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, sanitizeCollectionName, validatePipeline } from '../utils' import {
createMongoDBConnection,
sanitizeCollectionName,
validatePipeline,
} from '@/app/api/tools/mongodb/utils'
const logger = createLogger('MongoDBExecuteAPI') const logger = createLogger('MongoDBExecuteAPI')

View File

@@ -1,9 +1,9 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid' import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, sanitizeCollectionName } from '../utils' import { createMongoDBConnection, sanitizeCollectionName } from '@/app/api/tools/mongodb/utils'
const logger = createLogger('MongoDBInsertAPI') const logger = createLogger('MongoDBInsertAPI')

View File

@@ -1,9 +1,9 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid' import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, executeIntrospect } from '../utils' import { createMongoDBConnection, executeIntrospect } from '@/app/api/tools/mongodb/utils'
const logger = createLogger('MongoDBIntrospectAPI') const logger = createLogger('MongoDBIntrospectAPI')

View File

@@ -1,9 +1,13 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid' import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, sanitizeCollectionName, validateFilter } from '../utils' import {
createMongoDBConnection,
sanitizeCollectionName,
validateFilter,
} from '@/app/api/tools/mongodb/utils'
const logger = createLogger('MongoDBQueryAPI') const logger = createLogger('MongoDBQueryAPI')
@@ -83,7 +87,7 @@ export async function POST(request: NextRequest) {
if (params.sort?.trim()) { if (params.sort?.trim()) {
try { try {
sortCriteria = JSON.parse(params.sort) sortCriteria = JSON.parse(params.sort)
} catch (error) { } catch (_error) {
logger.warn(`[${requestId}] Invalid sort JSON: ${params.sort}`) logger.warn(`[${requestId}] Invalid sort JSON: ${params.sort}`)
return NextResponse.json({ error: 'Invalid JSON format in sort criteria' }, { status: 400 }) return NextResponse.json({ error: 'Invalid JSON format in sort criteria' }, { status: 400 })
} }

View File

@@ -1,9 +1,13 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid' import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, sanitizeCollectionName, validateFilter } from '../utils' import {
createMongoDBConnection,
sanitizeCollectionName,
validateFilter,
} from '@/app/api/tools/mongodb/utils'
const logger = createLogger('MongoDBUpdateAPI') const logger = createLogger('MongoDBUpdateAPI')
@@ -90,7 +94,7 @@ export async function POST(request: NextRequest) {
try { try {
filterDoc = JSON.parse(params.filter) filterDoc = JSON.parse(params.filter)
updateDoc = JSON.parse(params.update) updateDoc = JSON.parse(params.update)
} catch (error) { } catch (_error) {
logger.warn(`[${requestId}] Invalid JSON in filter or update`) logger.warn(`[${requestId}] Invalid JSON in filter or update`)
return NextResponse.json( return NextResponse.json(
{ error: 'Invalid JSON format in filter or update' }, { error: 'Invalid JSON format in filter or update' },

View File

@@ -72,7 +72,7 @@ export function validateFilter(filter: string): { isValid: boolean; error?: stri
} }
return { isValid: true } return { isValid: true }
} catch (error) { } catch (_error) {
return { return {
isValid: false, isValid: false,
error: 'Invalid JSON format in filter', error: 'Invalid JSON format in filter',
@@ -113,7 +113,7 @@ export function validatePipeline(pipeline: string): { isValid: boolean; error?:
} }
return { isValid: true } return { isValid: true }
} catch (error) { } catch (_error) {
return { return {
isValid: false, isValid: false,
error: 'Invalid JSON format in pipeline', error: 'Invalid JSON format in pipeline',

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'
@@ -29,7 +29,7 @@ const UpdateSchema = z.object({
throw new Error('Data must be a JSON object') throw new Error('Data must be a JSON object')
} }
return parsed return parsed
} catch (e) { } catch (_e) {
throw new Error('Invalid JSON format in data field') throw new Error('Invalid JSON format in data field')
} }
}), }),

View File

@@ -271,7 +271,7 @@ export async function executeIntrospect(
unique: row.NON_UNIQUE === 0, unique: row.NON_UNIQUE === 0,
}) })
} }
indexMap.get(indexName)!.columns.push(row.COLUMN_NAME) indexMap.get(indexName)?.columns.push(row.COLUMN_NAME)
} }
const indexes = Array.from(indexMap.values()) const indexes = Array.from(indexMap.values())

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto' import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger' import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server' import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod' import { z } from 'zod'

Some files were not shown because too many files have changed in this diff Show More