Compare commits

..

1 Commits

549 changed files with 1215 additions and 2213 deletions

View File

@@ -27,16 +27,16 @@ All API responses include information about your workflow execution limits and u
"limits": {
"workflowExecutionRateLimit": {
"sync": {
"requestsPerMinute": 150, // Sustained rate limit per minute
"maxBurst": 300, // Maximum burst capacity
"remaining": 298, // Current tokens available (up to maxBurst)
"resetAt": "..." // When tokens next refill
"requestsPerMinute": 60, // Sustained rate limit per minute
"maxBurst": 120, // Maximum burst capacity
"remaining": 118, // Current tokens available (up to maxBurst)
"resetAt": "..." // When tokens next refill
},
"async": {
"requestsPerMinute": 1000, // Sustained rate limit per minute
"maxBurst": 2000, // Maximum burst capacity
"remaining": 1998, // Current tokens available
"resetAt": "..." // When tokens next refill
"requestsPerMinute": 200, // Sustained rate limit per minute
"maxBurst": 400, // Maximum burst capacity
"remaining": 398, // Current tokens available
"resetAt": "..." // When tokens next refill
}
},
"usage": {
@@ -107,28 +107,28 @@ Query workflow execution logs with extensive filtering options.
}
],
"nextCursor": "eyJzIjoiMjAyNS0wMS0wMVQxMjozNDo1Ni43ODlaIiwiaWQiOiJsb2dfYWJjMTIzIn0",
"limits": {
"workflowExecutionRateLimit": {
"sync": {
"requestsPerMinute": 150,
"maxBurst": 300,
"remaining": 298,
"resetAt": "2025-01-01T12:35:56.789Z"
},
"async": {
"requestsPerMinute": 1000,
"maxBurst": 2000,
"remaining": 1998,
"resetAt": "2025-01-01T12:35:56.789Z"
}
"limits": {
"workflowExecutionRateLimit": {
"sync": {
"requestsPerMinute": 60,
"maxBurst": 120,
"remaining": 118,
"resetAt": "2025-01-01T12:35:56.789Z"
},
"usage": {
"currentPeriodCost": 1.234,
"limit": 10,
"plan": "pro",
"isExceeded": false
"async": {
"requestsPerMinute": 200,
"maxBurst": 400,
"remaining": 398,
"resetAt": "2025-01-01T12:35:56.789Z"
}
},
"usage": {
"currentPeriodCost": 1.234,
"limit": 10,
"plan": "pro",
"isExceeded": false
}
}
}
```
</Tab>
@@ -188,15 +188,15 @@ Retrieve detailed information about a specific log entry.
"limits": {
"workflowExecutionRateLimit": {
"sync": {
"requestsPerMinute": 150,
"maxBurst": 300,
"remaining": 298,
"requestsPerMinute": 60,
"maxBurst": 120,
"remaining": 118,
"resetAt": "2025-01-01T12:35:56.789Z"
},
"async": {
"requestsPerMinute": 1000,
"maxBurst": 2000,
"remaining": 1998,
"requestsPerMinute": 200,
"maxBurst": 400,
"remaining": 398,
"resetAt": "2025-01-01T12:35:56.789Z"
}
},
@@ -477,10 +477,10 @@ The API uses a **token bucket algorithm** for rate limiting, providing fair usag
| Plan | Requests/Minute | Burst Capacity |
|------|-----------------|----------------|
| Free | 30 | 60 |
| Pro | 100 | 200 |
| Team | 200 | 400 |
| Enterprise | 500 | 1000 |
| Free | 10 | 20 |
| Pro | 30 | 60 |
| Team | 60 | 120 |
| Enterprise | 120 | 240 |
**How it works:**
- Tokens refill at `requestsPerMinute` rate

View File

@@ -170,16 +170,16 @@ curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" htt
"rateLimit": {
"sync": {
"isLimited": false,
"requestsPerMinute": 150,
"maxBurst": 300,
"remaining": 300,
"requestsPerMinute": 25,
"maxBurst": 50,
"remaining": 50,
"resetAt": "2025-09-08T22:51:55.999Z"
},
"async": {
"isLimited": false,
"requestsPerMinute": 1000,
"maxBurst": 2000,
"remaining": 2000,
"requestsPerMinute": 200,
"maxBurst": 400,
"remaining": 400,
"resetAt": "2025-09-08T22:51:56.155Z"
},
"authType": "api"
@@ -206,11 +206,11 @@ curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" htt
Different subscription plans have different usage limits:
| Plan | Monthly Usage Included | Rate Limits (per minute) |
|------|------------------------|-------------------------|
| **Free** | $20 | 50 sync, 200 async |
| **Pro** | $20 (adjustable) | 150 sync, 1,000 async |
| **Team** | $40/seat (pooled, adjustable) | 300 sync, 2,500 async |
| Plan | Monthly Usage Limit | Rate Limits (per minute) |
|------|-------------------|-------------------------|
| **Free** | $20 | 5 sync, 10 async |
| **Pro** | $100 | 10 sync, 50 async |
| **Team** | $500 (pooled) | 50 sync, 100 async |
| **Enterprise** | Custom | Custom |
## Billing Model

View File

@@ -39,18 +39,8 @@ export function SocialLoginButtons({
setIsGithubLoading(true)
try {
await client.signIn.social({ provider: 'github', callbackURL })
} catch (err: any) {
let errorMessage = 'Failed to sign in with GitHub'
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.'
}
} catch (_err: unknown) {
// Error handling is done silently - user will see the OAuth error page if needed
} finally {
setIsGithubLoading(false)
}
@@ -62,18 +52,8 @@ export function SocialLoginButtons({
setIsGoogleLoading(true)
try {
await client.signIn.social({ provider: 'google', callbackURL })
} catch (err: any) {
let errorMessage = 'Failed to sign in with Google'
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.'
}
} catch (_err: unknown) {
// Error handling is done silently - user will see the OAuth error page if needed
} finally {
setIsGoogleLoading(false)
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -149,7 +149,7 @@ export function extractAgentContent(executeResult: {
if (typeof executeResult.output === 'object' && executeResult.output !== null) {
const keys = Object.keys(executeResult.output)
// 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)
}
}

View File

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

View File

@@ -177,7 +177,6 @@ describe('OAuth Token API Routes', () => {
const { POST } = await import('@/app/api/auth/oauth/token/route')
const response = await POST(req)
const data = await response.json()
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 { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
import { db } from '@sim/db'
import { chat, verification } from '@sim/db/schema'
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 { chat, workflow } from '@sim/db/schema'
import { createLogger } from '@sim/logger'

View File

@@ -42,7 +42,7 @@ const chatSchema = z.object({
.default([]),
})
export async function GET(request: NextRequest) {
export async function GET(_request: NextRequest) {
try {
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 } },
{ status: 201 }
)
} catch (error) {
} catch (_error) {
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 { env } from '@/lib/core/config/env'
export async function GET(request: NextRequest) {
export async function GET(_request: NextRequest) {
try {
const session = await getSession()
if (!session?.user?.id) {
@@ -49,7 +49,7 @@ export async function GET(request: NextRequest) {
})
return NextResponse.json({ keys }, { status: 200 })
} catch (error) {
} catch (_error) {
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 })
} catch (error) {
} catch (_error) {
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 (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
const transformedStream = new ReadableStream({
async start(controller) {
@@ -515,14 +501,11 @@ export async function POST(req: NextRequest) {
let assistantContent = ''
const toolCalls: any[] = []
let buffer = ''
const isFirstDone = true
let responseIdFromStart: string | undefined
let responseIdFromDone: string | undefined
// Track tool call progress to identify a safe done event
const announcedToolCallIds = new Set<string>()
const startedToolExecutionIds = new Set<string>()
const completedToolExecutionIds = new Set<string>()
let lastDoneResponseId: string | undefined
let lastSafeDoneResponseId: string | undefined
// Send chatId as first event
@@ -564,9 +547,15 @@ export async function POST(req: NextRequest) {
}
// Forward the sim agent stream and capture assistant response
const reader = simAgentResponse.body!.getReader()
const reader = simAgentResponse.body?.getReader()
const decoder = new TextDecoder()
if (!reader) {
logger.error(`[${tracker.requestId}] Failed to get reader from response body`)
controller.close()
return
}
try {
while (true) {
const { done, value } = await reader.read()
@@ -647,15 +636,11 @@ export async function POST(req: NextRequest) {
break
case 'start':
if (event.data?.responseId) {
responseIdFromStart = event.data.responseId
}
break
case 'done':
if (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
const announced = announcedToolCallIds.size
@@ -690,7 +675,7 @@ export async function POST(req: NextRequest) {
`data: ${JSON.stringify({ type: 'content', data: formatted })}\n\n`
)
)
} catch (enqueueErr) {
} catch (_enqueueErr) {
reader.cancel()
break
}
@@ -699,7 +684,7 @@ export async function POST(req: NextRequest) {
controller.enqueue(
encoder.encode(`data: ${JSON.stringify({ type: 'done' })}\n\n`)
)
} catch (enqueueErr) {
} catch (_enqueueErr) {
reader.cancel()
break
}
@@ -709,7 +694,7 @@ export async function POST(req: NextRequest) {
// Forward original event to client
try {
controller.enqueue(encoder.encode(`data: ${jsonStr}\n\n`))
} catch (enqueueErr) {
} catch (_enqueueErr) {
reader.cancel()
break
}
@@ -767,17 +752,17 @@ export async function POST(req: NextRequest) {
controller.enqueue(
encoder.encode(`data: ${JSON.stringify({ type: 'done' })}\n\n`)
)
} catch (enqueueErr) {
} catch (_enqueueErr) {
reader.cancel()
}
} else {
try {
controller.enqueue(encoder.encode(`data: ${jsonStr}\n\n`))
} catch (enqueueErr) {
} catch (_enqueueErr) {
reader.cancel()
}
}
} catch (e) {
} catch (_e) {
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(
`[${tracker.requestId}] Successfully reverted workflow ${checkpoint.workflowId} to checkpoint ${checkpointId}`
)

View File

@@ -63,7 +63,7 @@ export async function POST(req: NextRequest) {
let parsedWorkflowState
try {
parsedWorkflowState = JSON.parse(workflowState)
} catch (error) {
} catch (_error) {
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')
}
const duration = tracker.getDuration()
return NextResponse.json({
success: true,
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 all feedback records (for analytics)
*/
export async function GET(req: NextRequest) {
export async function GET(_req: NextRequest) {
const tracker = createRequestTracker()
try {

View File

@@ -5,7 +5,6 @@ import {
authenticateCopilotRequestSessionOnly,
createBadRequestResponse,
createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/request-helpers'
import { env } from '@/lib/core/config/env'
@@ -19,7 +18,6 @@ const BodySchema = z.object({
})
export async function POST(req: NextRequest) {
const tracker = createRequestTracker()
try {
const { userId, isAuthenticated } = await authenticateCopilotRequestSessionOnly()
if (!isAuthenticated || !userId) {
@@ -62,7 +60,7 @@ export async function POST(req: NextRequest) {
}
return NextResponse.json({ success: true })
} catch (error) {
} catch (_error) {
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
export async function GET(request: NextRequest) {
export async function GET(_request: NextRequest) {
try {
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
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 { id } = await params
@@ -137,7 +137,7 @@ export async function PUT(request: NextRequest, { params }: { params: Promise<{
// DELETE /api/creators/[id] - Delete a creator profile
export async function DELETE(
request: NextRequest,
_request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const requestId = generateRequestId()

View File

@@ -12,7 +12,7 @@ const logger = createLogger('CreatorVerificationAPI')
export const revalidate = 0
// 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 { 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)
export async function DELETE(
request: NextRequest,
_request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const requestId = generateRequestId()

View File

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

View File

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

View File

@@ -41,7 +41,7 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
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()
if (!session?.user?.id) {

View File

@@ -33,7 +33,7 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
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()
if (!session?.user?.id) {

View File

@@ -43,7 +43,7 @@ async function getCredentialSetWithAccess(credentialSetId: string, userId: strin
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()
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()
if (!session?.user?.id) {

View File

@@ -13,7 +13,7 @@ import { syncAllWebhooksForCredentialSet } from '@/lib/webhooks/utils.server'
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 [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 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()
try {

View File

@@ -162,7 +162,7 @@ async function verifyWorkspaceFileAccess(
cloudKey: string,
userId: string,
customConfig?: StorageConfig,
isLocal?: boolean
_isLocal?: boolean
): Promise<boolean> {
try {
// Priority 1: Check database (most reliable, works for both local and cloud)
@@ -228,7 +228,7 @@ async function verifyWorkspaceFileAccess(
async function verifyExecutionFileAccess(
cloudKey: string,
userId: string,
customConfig?: StorageConfig
_customConfig?: StorageConfig
): Promise<boolean> {
const parts = cloudKey.split('/')
@@ -493,7 +493,7 @@ async function verifyRegularFileAccess(
cloudKey: string,
userId: string,
customConfig?: StorageConfig,
isLocal?: boolean
_isLocal?: boolean
): Promise<boolean> {
try {
// 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
*

View File

@@ -1,7 +1,7 @@
import { Buffer } from 'buffer'
import { createHash } from 'crypto'
import fsPromises, { readFile } from 'fs/promises'
import path from 'path'
import { Buffer } from 'node:buffer'
import { createHash } from 'node:crypto'
import fsPromises, { readFile } from 'node:fs/promises'
import path from 'node:path'
import { createLogger } from '@sim/logger'
import binaryExtensionsList from 'binary-extensions'
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
*/
function createPdfFailureMessage(
pageCount: number,
_pageCount: number,
size: number,
path: string,
error: string

View File

@@ -131,7 +131,7 @@ describe('File Serve API Route', () => {
expect(disposition).toContain('filename=')
expect(disposition).toContain('test-file.txt')
const fs = await import('fs/promises')
const fs = await import('node:fs/promises')
expect(fs.readFile).toHaveBeenCalled()
})
@@ -196,7 +196,7 @@ describe('File Serve API Route', () => {
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')
})

View File

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

View File

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

View File

@@ -321,7 +321,7 @@ describe('Individual Folder API Route', () => {
await PUT(req, { params })
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 () => {

View File

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

View File

@@ -551,7 +551,7 @@ describe('Folders API Route', () => {
await POST(req)
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 () => {
@@ -591,7 +591,7 @@ describe('Folders API Route', () => {
await POST(req)
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 { form, workflow, workflowBlocks } from '@sim/db/schema'
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
// Consume the stream to wait for completion
const reader = stream.getReader()
let lastOutput: any = null
try {
while (true) {
const { done, value } = await reader.read()
const { done } = await reader.read()
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 {
reader.releaseLock()

View File

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

View File

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

View File

@@ -63,7 +63,7 @@ describe('Form API Utils', () => {
it.concurrent('should validate tokens with password hash', async () => {
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 encryptedPassword = 'encrypted-password-value'

View File

@@ -292,7 +292,7 @@ function formatE2BError(
*/
function createUserFriendlyErrorMessage(
enhanced: EnhancedError,
requestId: string,
_requestId: string,
userCode?: string
): string {
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 { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
@@ -14,7 +14,7 @@ const UpdateChunkSchema = z.object({
})
export async function GET(
req: NextRequest,
_req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
@@ -134,7 +134,7 @@ export async function PUT(
}
export async function DELETE(
req: NextRequest,
_req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> }
) {
const requestId = randomUUID().slice(0, 8)

View File

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

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
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
export async function GET(
req: NextRequest,
_req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string }> }
) {
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
@@ -11,7 +11,7 @@ const logger = createLogger('TagDefinitionAPI')
// DELETE /api/knowledge/[id]/tag-definitions/[tagId] - Delete a tag definition
export async function DELETE(
req: NextRequest,
_req: NextRequest,
{ params }: { params: Promise<{ id: string; tagId: string }> }
) {
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
@@ -10,7 +10,7 @@ export const dynamic = 'force-dynamic'
const logger = createLogger('TagUsageAPI')
// 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 { id: knowledgeBaseId } = await params

View File

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

View File

@@ -63,7 +63,7 @@ async function getServer(serverId: string) {
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
try {
@@ -264,7 +264,7 @@ async function handleToolsCall(
method: 'POST',
headers,
body: JSON.stringify({ input: params.arguments || {}, triggerType: 'mcp' }),
signal: AbortSignal.timeout(600000), // 10 minute timeout
signal: AbortSignal.timeout(300000), // 5 minute timeout
})
const executeResult = await response.json()

View File

@@ -140,7 +140,7 @@ async function syncToolSchemasToWorkflows(
}
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
try {

View File

@@ -19,7 +19,7 @@ export const dynamic = 'force-dynamic'
* GET - List all registered MCP servers for the workspace
*/
export const GET = withMcpAuth('read')(
async (request: NextRequest, { userId, workspaceId, requestId }) => {
async (_request: NextRequest, { userId, workspaceId, requestId }) => {
try {
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 GET = withMcpAuth('read')(
async (request: NextRequest, { userId, workspaceId, requestId }) => {
async (_request: NextRequest, { userId, workspaceId, requestId }) => {
try {
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
*/
export const GET = withMcpAuth<RouteParams>('read')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
try {
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
*/
export const DELETE = withMcpAuth<RouteParams>('admin')(
async (request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
async (_request: NextRequest, { userId, workspaceId, requestId }, { params }) => {
try {
const { id: serverId } = await params

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
import { db } from '@sim/db'
import {
invitation,
@@ -42,7 +42,7 @@ interface WorkspaceInvitation {
* GET /api/organizations/[id]/invitations
* 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 {
const session = await getSession()

View File

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

View File

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

View File

@@ -32,7 +32,7 @@ async function getPermissionGroupWithAccess(groupId: string, userId: string) {
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()
if (!session?.user?.id) {

View File

@@ -70,7 +70,7 @@ async function getPermissionGroupWithAccess(groupId: string, userId: string) {
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()
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()
if (!session?.user?.id) {

View File

@@ -5,7 +5,7 @@ export async function GET() {
try {
const allModels = Object.keys(getBaseModelProviders())
return NextResponse.json({ models: allModels })
} catch (error) {
} catch (_error) {
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 { type NextRequest, NextResponse } from 'next/server'
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)
*/
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 { id } = await params

View File

@@ -14,7 +14,7 @@ export const revalidate = 0
/**
* 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 { id } = await params

View File

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

View File

@@ -13,7 +13,7 @@ export const dynamic = 'force-dynamic'
export const revalidate = 0
// 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 { 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
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 { 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
export async function DELETE(
request: NextRequest,
_request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
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
const result = await db.transaction(async (tx) => {
const _result = await db.transaction(async (tx) => {
// Prepare template update data
const updateData: any = {
views: sql`${templates.views} + 1`,

View File

@@ -20,7 +20,6 @@ export async function GET(request: NextRequest) {
const requestId = generateRequestId()
try {
const url = new URL(request.url)
const hasApiKey = !!request.headers.get('x-api-key')
// Check internal API key authentication
@@ -126,7 +125,7 @@ export async function GET(request: NextRequest) {
}
// Add a helpful OPTIONS handler for CORS preflight
export async function OPTIONS(request: NextRequest) {
export async function OPTIONS(_request: NextRequest) {
const requestId = generateRequestId()
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 { type NextRequest, NextResponse } from 'next/server'
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 { generateRequestId } from '@/lib/core/utils/request'
@@ -50,14 +50,12 @@ export async function POST(request: NextRequest) {
let taskId = validatedData.taskId
let contextId: string | undefined
let state: TaskState = 'working'
let content = ''
let artifacts: Artifact[] = []
let history: Message[] = []
for await (const event of stream) {
if (event.kind === 'message') {
const msg = event as Message
content = extractTextContent(msg)
taskId = msg.taskId || taskId
contextId = msg.contextId || contextId
state = 'completed'
@@ -68,10 +66,6 @@ export async function POST(request: NextRequest) {
state = task.status.state
artifacts = task.artifacts || []
history = task.history || []
const lastAgentMessage = history.filter((m) => m.role === 'agent').pop()
if (lastAgentMessage) {
content = extractTextContent(lastAgentMessage)
}
} else if ('status' in event) {
const statusEvent = event as TaskStatusUpdateEvent
state = statusEvent.status.state

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
import { db } from '@sim/db'
import { account } from '@sim/db/schema'
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 { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
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')
@@ -69,7 +73,7 @@ export async function POST(request: NextRequest) {
let filterDoc
try {
filterDoc = JSON.parse(params.filter)
} catch (error) {
} catch (_error) {
logger.warn(`[${requestId}] Invalid filter JSON: ${params.filter}`)
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 { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
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')

View File

@@ -1,9 +1,9 @@
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, sanitizeCollectionName } from '../utils'
import { createMongoDBConnection, sanitizeCollectionName } from '@/app/api/tools/mongodb/utils'
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 { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createMongoDBConnection, executeIntrospect } from '../utils'
import { createMongoDBConnection, executeIntrospect } from '@/app/api/tools/mongodb/utils'
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 { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
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')
@@ -83,7 +87,7 @@ export async function POST(request: NextRequest) {
if (params.sort?.trim()) {
try {
sortCriteria = JSON.parse(params.sort)
} catch (error) {
} catch (_error) {
logger.warn(`[${requestId}] Invalid sort JSON: ${params.sort}`)
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 { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
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')
@@ -90,7 +94,7 @@ export async function POST(request: NextRequest) {
try {
filterDoc = JSON.parse(params.filter)
updateDoc = JSON.parse(params.update)
} catch (error) {
} catch (_error) {
logger.warn(`[${requestId}] Invalid JSON in filter or update`)
return NextResponse.json(
{ 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 }
} catch (error) {
} catch (_error) {
return {
isValid: false,
error: 'Invalid JSON format in filter',
@@ -113,7 +113,7 @@ export function validatePipeline(pipeline: string): { isValid: boolean; error?:
}
return { isValid: true }
} catch (error) {
} catch (_error) {
return {
isValid: false,
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
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 { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
@@ -29,7 +29,7 @@ const UpdateSchema = z.object({
throw new Error('Data must be a JSON object')
}
return parsed
} catch (e) {
} catch (_e) {
throw new Error('Invalid JSON format in data field')
}
}),

View File

@@ -271,7 +271,7 @@ export async function executeIntrospect(
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())

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