Compare commits

..

22 Commits

Author SHA1 Message Date
Waleed
e157ce5fbc v0.5.16: MCP fixes, code refactors, jira fixes, new mistral models 2025-12-02 22:02:11 -08:00
Vikhyath Mondreti
7de721e090 fix(logs): logging with error issues for model costs (#2169)
* fix(async-execution): restore async executions

* fix schedules trace span collection'

* fix execution trace spans for schedules + cost tracking when workflow errors
2025-12-02 20:54:17 -08:00
Waleed
3e83fb398c fix(trace-spans): fix input/output token count in trace spans (#2168) 2025-12-02 20:36:16 -08:00
Waleed
a6e3c92c10 fix(jira): fixed incorrect dependsOn for jira project/issue subblcks (#2167) 2025-12-02 20:18:01 -08:00
Vikhyath Mondreti
9670d96eca fix(templates-page): loading issue due to loading extensive workflow block in preview for all listings (#2166)
* fix(templates-page): loading issue due to loading extensive workflow block in preview for all listings

* add more properties
2025-12-02 19:47:48 -08:00
Waleed
eb0d4cbd57 fix(templates): fixed verified creator status displaying & tooltip on templates (#2165) 2025-12-02 19:23:35 -08:00
Waleed
ffd12e1da4 fix(subblocks): update guardrails pii selector component to use emcn (#2164) 2025-12-02 18:36:34 -08:00
Waleed
84c2335a37 feat(i18n): update translations (#2163)
Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>
2025-12-02 16:37:30 -08:00
Waleed
2ab8cec8c3 fix(icons): fix mailgun, restore tts and smtp blocks (#2162)
* fix(icons): fix mailgun

* register smtp block that was missing
2025-12-02 16:21:43 -08:00
Waleed
bf54c88ae4 feat(models): added xai models and updated gemini pricing (#2161) 2025-12-02 14:31:23 -08:00
Waleed
41c068c023 improvement(lib): refactored lib/ to be more aligned with queries and api directory (#2160)
* fix(lib): consolidate into core dir in lib/

* refactored lib/
2025-12-02 14:17:41 -08:00
Waleed
6fda9bd72e feat(models): added latest mistral models (#2159) 2025-12-02 13:46:00 -08:00
Waleed
3b4f227e43 fix(mcp): reuse sessionID for consecutive MCP tool calls, fix dynamic args clearing, fix refreshing tools on save (#2158)
* fix(mcp): reuse sessionID for consecutive MCP tool calls, fix dynamic args clearing, fix refreshing tools on save

* prevent defaults

* fix subblock text area

* added placeholders in tool-inp for mcp dynamic args

* ack PR comments
2025-12-02 12:37:59 -08:00
Vikhyath Mondreti
774e5d585c v0.5.15: add tools, revert subblock prop change 2025-12-01 13:52:12 -08:00
Vikhyath Mondreti
54cc93743f v0.5.14: fix issue with teams, google selectors + cleanup code 2025-12-01 12:39:39 -08:00
Waleed
8c32ad4c0d v0.5.13: polling fixes, generic agent search tool, status page, smtp, sendgrid, linkedin, more tools (#2148)
* feat(tools): added smtp, sendgrid, mailgun, linkedin, fixed permissions in context menu (#2133)

* feat(tools): added twilio sendgrid integration

* feat(tools): added smtp, sendgrid, mailgun, fixed permissions in context menu

* added top level mocks for sporadically failing tests

* incr type safety

* fix(team-plans): track departed member usage so value not lost (#2118)

* fix(team-plans): track departed member usage so value not lost

* reset usage to 0 when they leave team

* prep merge with stagig

* regen migrations

* fix org invite + ws selection'

---------

Co-authored-by: Waleed <walif6@gmail.com>

* feat(i18n): update translations (#2134)

Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>

* feat(creators): add verification for creators (#2135)

* feat(tools): added apify block/tools  (#2136)

* feat(tools): added apify

* cleanup

* feat(i18n): update translations (#2137)

Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>

* feat(env): added more optional env var examples (#2138)

* feat(statuspage): added statuspage, updated list of tools in footer, renamed routes (#2139)

* feat(statuspage): added statuspage, updated list of tools in footer, renamed routes

* ack PR comments

* feat(tools): add generic search tool (#2140)

* feat(i18n): update translations (#2141)

* fix(sdks): bump sdk versions (#2142)

* fix(webhooks): count test webhooks towards usage limit (#2143)

* fix(bill): add requestId to webhook processing (#2144)

* improvement(subflow): remove all associated edges when moving a block into a subflow (#2145)

* improvement(subflow): remove all associated edges when moving a block into a subflow

* ack PR comments

* fix(polling): mark webhook failed on webhook trigger errors (#2146)

* fix(deps): declare core transient deps explicitly (#2147)

* fix(deps): declare core transient deps explicitly

* ack PR comments

---------

Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>
2025-12-01 10:15:36 -08:00
Waleed
1d08796853 v0.5.12: memory optimizations, sentry, incidentio, posthog, zendesk, pylon, intercom, mailchimp, loading optimizations (#2132)
* fix(memory-util): fixed unbounded array of gmail/outlook pollers causing high memory util, added missing db indexes/removed unused ones, auto-disable schedules/webhooks after 10 consecutive failures (#2115)

* fix(memory-util): fixed unbounded array of gmail/outlook pollers causing high memory util, added missing db indexes/removed unused ones, auto-disable schedules/webhooks after 10 consecutive failures

* ack PR comments

* ack

* improvement(teams-plan): seats increase simplification + not triggering checkout session (#2117)

* improvement(teams-plan): seats increase simplification + not triggering checkout session

* cleanup via helper

* feat(tools): added sentry, incidentio, and posthog tools (#2116)

* feat(tools): added sentry, incidentio, and posthog tools

* update docs

* fixed docs to use native fumadocs for llms.txt and copy markdown, fixed tool issues

* cleanup

* enhance error extractor, fixed posthog tools

* docs enhancements, cleanup

* added more incident io ops, remove zustand/shallow in favor of zustand/react/shallow

* fix type errors

* remove unnecessary comments

* added vllm to docs

* feat(i18n): update translations (#2120)

* feat(i18n): update translations

* fix build

---------

Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>

* improvement(workflow-execution): perf improvements to passing workflow state + decrypted env vars (#2119)

* improvement(execution): load workflow state once instead of 2-3 times

* decrypt only in get helper

* remove comments

* remove comments

* feat(models): host google gemini models (#2122)

* feat(models): host google gemini models

* remove unused primary key

* feat(i18n): update translations (#2123)

Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>

* feat(tools): added zendesk, pylon, intercom, & mailchimp (#2126)

* feat(tools): added zendesk, pylon, intercom, & mailchimp

* finish zendesk and pylon

* updated docs

* feat(i18n): update translations (#2129)

* feat(i18n): update translations

* fixed build

---------

Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>

* fix(permissions): add client-side permissions validation to prevent unauthorized actions, upgraded custom tool modal (#2130)

* fix(permissions): add client-side permissions validation to prevent unauthorized actions, upgraded custom tool modal

* fix failing test

* fix test

* cleanup

* fix(custom-tools): add composite index on custom tool names & workspace id (#2131)

---------

Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: waleedlatif1 <waleedlatif1@users.noreply.github.com>
2025-11-28 16:08:06 -08:00
Waleed
ebcd243942 v0.5.11: stt, videogen, vllm, billing fixes, new models 2025-11-25 01:14:12 -08:00
Waleed
b7e814b721 v0.5.10: copilot upgrade, preprocessor, logs search, UI, code hygiene 2025-11-21 12:04:34 -08:00
Waleed
842ef27ed9 v0.5.9: add backwards compatibility for agent messages array 2025-11-20 11:19:42 -08:00
Vikhyath Mondreti
31c34b2ea3 v0.5.8: notifications, billing, ui changes, store loading state machine 2025-11-20 01:32:32 -08:00
Vikhyath Mondreti
8f0ef58056 v0.5.7: combobox selectors, usage indicator, workflow loading race condition, other improvements 2025-11-17 21:25:51 -08:00
731 changed files with 2672 additions and 2535 deletions

View File

@@ -3765,12 +3765,16 @@ export function MailgunIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
fill='currentColor'
version='1.1'
viewBox='0 0 1000 1000'
xmlns='http://www.w3.org/2000/svg'
xmlnsXlink='http://www.w3.org/1999/xlink'
xmlSpace='preserve'
viewBox='0 0 512 512'
>
<path d='M256.5 159.5c-53.5 0-97 43.5-97 97s43.5 97 97 97 97-43.5 97-97-43.5-97-97-97m-151.1 97c0-83.4 67.7-151.1 151.1-151.1s151.1 67.7 151.1 151.1c0 5.8-.5 11-1 16.3-1 14.7 9.4 25.7 24.1 25.7 24.7 0 27.3-32 27.3-42.5 0-111.7-90.2-202-202-202S54 144.3 54 256s90.2 202 202 202c59.3 0 112.3-25.7 149.5-66.1l41.4 34.6C400.3 479 332.1 512 256 512 114.4 512 0 397.1 0 256 0 114.4 114.9 0 256 0c141.6 0 256 114.9 256 256 0 56.7-27.3 102.8-81.3 102.8-24.1 0-38.3-11-46.7-23.1-26.8 43-74 71.3-128.5 71.3-82.4.6-150.1-67.1-150.1-150.5m151.1-44.6c24.7 0 44.6 19.9 44.6 44.1 0 24.7-19.9 44.6-44.6 44.6s-44.6-19.9-44.6-44.6c.6-24.1 20-44.1 44.6-44.1' />
<path
fill='#C12126'
d='M493,305.7c-88.9,0-161,72.1-161,161c0,88.9,72.1,161,161,161c88.9,0,161-72.1,161-161 C654,377.8,582,305.7,493,305.7z M242,466.7c0-138.7,112.4-251,251-251c138.7,0,251.1,112.4,251.1,251c0,9.2-0.5,18.2-1.4,27.1 c-1.9,24.5,16.1,43.2,40.4,43.2c41.3,0,45.7-53.2,45.7-70.3c0-185.4-150.3-335.6-335.6-335.6S157.4,281.4,157.4,466.7 c0,185.4,150.3,335.6,335.6,335.6c98.4,0,187-42.4,248.4-109.9l69,57.9c-77.9,87.1-191.3,142-317.4,142 c-235.1,0-425.7-190.6-425.7-425.7S257.9,41,493,41c235.1,0,425.7,190.6,425.7,425.7c0,94.5-45,171.2-135.4,171.2 c-39.8,0-64-18.2-77.2-38.6C661.9,670.5,583,717.8,493,717.8C354.4,717.8,242,605.4,242,466.7z M493,393.1c40.7,0,73.7,33,73.7,73.7 c0,40.7-33,73.7-73.7,73.7c-40.7,0-73.7-33-73.7-73.7S452.3,393.1,493,393.1z'
/>
</svg>
)
}

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="mailgun"
color="#F06248"
color="#E0E0E0"
/>
{/* MANUAL-CONTENT-START:intro */}

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="mailgun"
color="#F06248"
color="#E0E0E0"
/>
{/* MANUAL-CONTENT-START:intro */}

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="mailgun"
color="#F06248"
color="#E0E0E0"
/>
{/* MANUAL-CONTENT-START:intro */}

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="mailgun"
color="#F06248"
color="#E0E0E0"
/>
{/* MANUAL-CONTENT-START:intro */}

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="mailgun"
color="#F06248"
color="#E0E0E0"
/>
{/* MANUAL-CONTENT-START:intro */}

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="mailgun"
color="#F06248"
color="#E0E0E0"
/>
{/* MANUAL-CONTENT-START:intro */}

View File

@@ -47252,7 +47252,7 @@ checksums:
meta/title: b0301322c66fcbf604c6988c11a8a0b6
meta/description: 54233683a87a944c333d0a27a15f297e
content/0: 1b031fb0c62c46b177aeed5c3d3f8f80
content/1: 0aefa3b41a9d2ecaf2cfafe6818ed5d2
content/1: 64159072101de51ad1e456dc76936fd0
content/2: 3f99340b6a2b22d8f91d8cabd457f4f5
content/3: e64b467b3c7f0ade59c79c0a9a8da002
content/4: a639faec4ba8d6237dd700c4c986f8cd

View File

@@ -1,4 +1,4 @@
import { cn } from '@/lib/utils'
import { cn } from '@/lib/core/utils/cn'
import AuthBackgroundSVG from '@/app/(auth)/components/auth-background-svg'
type AuthBackgroundProps = {

View File

@@ -1,7 +1,7 @@
'use server'
import { env } from '@/lib/env'
import { isProd } from '@/lib/environment'
import { env } from '@/lib/core/config/env'
import { isProd } from '@/lib/core/config/environment'
export async function getOAuthProviderStatus() {
const githubAvailable = !!(env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET)

View File

@@ -3,7 +3,7 @@
import { type ReactNode, useEffect, useState } from 'react'
import { GithubIcon, GoogleIcon } from '@/components/icons'
import { Button } from '@/components/ui/button'
import { client } from '@/lib/auth-client'
import { client } from '@/lib/auth/auth-client'
import { inter } from '@/app/_styles/fonts/inter/inter'
interface SocialLoginButtonsProps {

View File

@@ -2,8 +2,8 @@
import { useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { getEnv, isTruthy } from '@/lib/env'
import { cn } from '@/lib/utils'
import { getEnv, isTruthy } from '@/lib/core/config/env'
import { cn } from '@/lib/core/utils/cn'
interface SSOLoginButtonProps {
callbackURL?: string

View File

@@ -14,12 +14,12 @@ import {
} from '@/components/ui/dialog'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { client } from '@/lib/auth-client'
import { quickValidateEmail } from '@/lib/email/validation'
import { getEnv, isFalsy, isTruthy } from '@/lib/env'
import { client } from '@/lib/auth/auth-client'
import { getEnv, isFalsy, isTruthy } from '@/lib/core/config/env'
import { cn } from '@/lib/core/utils/cn'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { getBaseUrl } from '@/lib/urls/utils'
import { cn } from '@/lib/utils'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { SocialLoginButtons } from '@/app/(auth)/components/social-login-buttons'

View File

@@ -5,7 +5,7 @@ import { ArrowRight, ChevronRight, Eye, EyeOff } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { cn } from '@/lib/utils'
import { cn } from '@/lib/core/utils/cn'
import { inter } from '@/app/_styles/fonts/inter/inter'
interface RequestResetFormProps {

View File

@@ -1,4 +1,4 @@
import { env, isTruthy } from '@/lib/env'
import { env, isTruthy } from '@/lib/core/config/env'
import { getOAuthProviderStatus } from '@/app/(auth)/components/oauth-provider-checker'
import SignupForm from '@/app/(auth)/signup/signup-form'

View File

@@ -7,11 +7,11 @@ import { useRouter, useSearchParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { client, useSession } from '@/lib/auth-client'
import { quickValidateEmail } from '@/lib/email/validation'
import { getEnv, isFalsy, isTruthy } from '@/lib/env'
import { client, useSession } from '@/lib/auth/auth-client'
import { getEnv, isFalsy, isTruthy } from '@/lib/core/config/env'
import { cn } from '@/lib/core/utils/cn'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { SocialLoginButtons } from '@/app/(auth)/components/social-login-buttons'

View File

@@ -1,5 +1,5 @@
import { redirect } from 'next/navigation'
import { getEnv, isTruthy } from '@/lib/env'
import { getEnv, isTruthy } from '@/lib/core/config/env'
import SSOForm from '@/app/(auth)/sso/sso-form'
export const dynamic = 'force-dynamic'

View File

@@ -6,11 +6,11 @@ import { useRouter, useSearchParams } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { client } from '@/lib/auth-client'
import { quickValidateEmail } from '@/lib/email/validation'
import { env, isFalsy } from '@/lib/env'
import { client } from '@/lib/auth/auth-client'
import { env, isFalsy } from '@/lib/core/config/env'
import { cn } from '@/lib/core/utils/cn'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'

View File

@@ -1,5 +1,5 @@
import { hasEmailService } from '@/lib/email/mailer'
import { isEmailVerificationEnabled, isProd } from '@/lib/environment'
import { isEmailVerificationEnabled, isProd } from '@/lib/core/config/environment'
import { hasEmailService } from '@/lib/messaging/email/mailer'
import { VerifyContent } from '@/app/(auth)/verify/verify-content'
export const dynamic = 'force-dynamic'

View File

@@ -2,7 +2,7 @@
import { useEffect, useState } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import { client, useSession } from '@/lib/auth-client'
import { client, useSession } from '@/lib/auth/auth-client'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('useVerification')

View File

@@ -4,7 +4,7 @@ import { Suspense, useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { InputOTP, InputOTPGroup, InputOTPSlot } from '@/components/ui/input-otp'
import { cn } from '@/lib/utils'
import { cn } from '@/lib/core/utils/cn'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { useVerification } from '@/app/(auth)/verify/use-verification'

View File

@@ -13,10 +13,10 @@ import {
SelectValue,
} from '@/components/ui/select'
import { Textarea } from '@/components/ui/textarea'
import { quickValidateEmail } from '@/lib/email/validation'
import { isHosted } from '@/lib/environment'
import { isHosted } from '@/lib/core/config/environment'
import { cn } from '@/lib/core/utils/cn'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Footer from '@/app/(landing)/components/footer/footer'
import Nav from '@/app/(landing)/components/nav/nav'

View File

@@ -1,5 +1,5 @@
import dynamic from 'next/dynamic'
import { cn } from '@/lib/utils'
import { cn } from '@/lib/core/utils/cn'
// Lazy load the SVG to reduce initial bundle size
const BackgroundSVG = dynamic(() => import('./background-svg'), {

View File

@@ -2,7 +2,7 @@
import type React from 'react'
import { useEffect, useId, useRef, useState } from 'react'
import { cn } from '@/lib/utils'
import { cn } from '@/lib/core/utils/cn'
/**
* DotPattern Component Props

View File

@@ -32,7 +32,7 @@ import {
StripeIcon,
SupabaseIcon,
} from '@/components/icons'
import { LandingPromptStorage } from '@/lib/browser-storage'
import { LandingPromptStorage } from '@/lib/core/utils/browser-storage'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import {
CARD_WIDTH,

View File

@@ -12,8 +12,8 @@ import {
Workflow,
} from 'lucide-react'
import { useRouter } from 'next/navigation'
import { cn } from '@/lib/core/utils/cn'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { inter } from '@/app/_styles/fonts/inter/inter'
import {
ENTERPRISE_PLAN_FEATURES,

View File

@@ -1,6 +1,6 @@
'use client'
import { isHosted } from '@/lib/environment'
import { isHosted } from '@/lib/core/config/environment'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Footer from '@/app/(landing)/components/footer/footer'
import Nav from '@/app/(landing)/components/nav/nav'

View File

@@ -7,7 +7,7 @@ import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { GithubIcon } from '@/components/icons'
import { useBrandConfig } from '@/lib/branding/branding'
import { isHosted } from '@/lib/environment'
import { isHosted } from '@/lib/core/config/environment'
import { createLogger } from '@/lib/logs/console/logger'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { getFormattedGitHubStars } from '@/app/(landing)/actions/github'

View File

@@ -2,7 +2,7 @@
import { useEffect } from 'react'
import Link from 'next/link'
import { getEnv } from '@/lib/env'
import { getEnv } from '@/lib/core/config/env'
import { LegalLayout } from '@/app/(landing)/components'
export default function PrivacyPolicy() {

View File

@@ -2,7 +2,7 @@
import { useEffect } from 'react'
import Link from 'next/link'
import { getEnv } from '@/lib/env'
import { getEnv } from '@/lib/core/config/env'
import { LegalLayout } from '@/app/(landing)/components'
export default function TermsOfService() {

View File

@@ -3,7 +3,7 @@
import { useEffect } from 'react'
import posthog from 'posthog-js'
import { PostHogProvider as PHProvider } from 'posthog-js/react'
import { getEnv, isTruthy } from '../../../lib/env'
import { getEnv, isTruthy } from '@/lib/core/config/env'
export function PostHogProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {

View File

@@ -3,7 +3,7 @@
import type React from 'react'
import { createContext, useCallback, useEffect, useMemo, useState } from 'react'
import posthog from 'posthog-js'
import { client } from '@/lib/auth-client'
import { client } from '@/lib/auth/auth-client'
export type AppSession = {
user: {

View File

@@ -305,24 +305,20 @@ export function createMockRequest(
}
export function mockExecutionDependencies() {
vi.mock('@/lib/utils', async () => {
const actual = await vi.importActual('@/lib/utils')
return {
...(actual as any),
decryptSecret: vi.fn().mockImplementation((encrypted: string) => {
const entries = Object.entries(mockEnvironmentVars)
const found = entries.find(([_, val]) => val === encrypted)
const key = found ? found[0] : null
vi.mock('@/lib/core/security/encryption', () => ({
decryptSecret: vi.fn().mockImplementation((encrypted: string) => {
const entries = Object.entries(mockEnvironmentVars)
const found = entries.find(([_, val]) => val === encrypted)
const key = found ? found[0] : null
return Promise.resolve({
decrypted:
key && key in mockDecryptedEnvVars
? mockDecryptedEnvVars[key as keyof typeof mockDecryptedEnvVars]
: 'decrypted-value',
})
}),
}
})
return Promise.resolve({
decrypted:
key && key in mockDecryptedEnvVars
? mockDecryptedEnvVars[key as keyof typeof mockDecryptedEnvVars]
: 'decrypted-value',
})
}),
}))
vi.mock('@/lib/logs/execution/trace-spans/trace-spans', () => ({
buildTraceSpans: vi.fn().mockReturnValue({
@@ -455,7 +451,7 @@ export function mockWorkflowAccessValidation(shouldSucceed = true) {
}
export async function getMockedDependencies() {
const utilsModule = await import('@/lib/utils')
const encryptionModule = await import('@/lib/core/security/encryption')
const traceSpansModule = await import('@/lib/logs/execution/trace-spans/trace-spans')
const workflowUtilsModule = await import('@/lib/workflows/utils')
const executorModule = await import('@/executor')
@@ -463,7 +459,7 @@ export async function getMockedDependencies() {
const dbModule = await import('@sim/db')
return {
decryptSecret: utilsModule.decryptSecret,
decryptSecret: encryptionModule.decryptSecret,
buildTraceSpans: traceSpansModule.buildTraceSpans,
updateWorkflowRunCounts: workflowUtilsModule.updateWorkflowRunCounts,
Executor: executorModule.Executor,
@@ -801,7 +797,7 @@ export function mockFileSystem(
export function mockEncryption(options: { encryptedValue?: string; decryptedValue?: string } = {}) {
const { encryptedValue = 'encrypted-value', decryptedValue = 'decrypted-value' } = options
vi.doMock('@/lib/utils', () => ({
vi.doMock('@/lib/core/security/encryption', () => ({
encryptSecret: vi.fn().mockResolvedValue({ encrypted: encryptedValue }),
decryptSecret: vi.fn().mockResolvedValue({ decrypted: decryptedValue }),
}))

View File

@@ -1,159 +0,0 @@
import { db } from '@sim/db'
import { user, workflow, workflowDeploymentVersion } from '@sim/db/schema'
import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/db-helpers'
import { sanitizeForExport } from '@/lib/workflows/json-sanitizer'
const logger = createLogger('AdminImportWorkflowAPI')
const ImportWorkflowSchema = z.object({
workflowId: z.string().min(1, 'Workflow ID is required'),
targetWorkspaceId: z.string().min(1, 'Target workspace ID is required'),
deploymentVersion: z.number().int().positive().optional(),
})
/**
* POST /api/admin/import-workflow
* Export a workflow from database by ID (superuser only)
*/
export async function POST(request: NextRequest) {
const requestId = generateRequestId()
try {
const session = await getSession()
if (!session?.user?.id) {
logger.warn(`[${requestId}] Unauthorized import attempt`)
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// Check if user is superuser
const currentUser = await db
.select({ isSuperUser: user.isSuperUser })
.from(user)
.where(eq(user.id, session.user.id))
.limit(1)
if (!currentUser[0]?.isSuperUser) {
logger.warn(`[${requestId}] Non-superuser attempted workflow import: ${session.user.id}`)
return NextResponse.json({ error: 'Forbidden - Superuser access required' }, { status: 403 })
}
const body = await request.json()
const validation = ImportWorkflowSchema.safeParse(body)
if (!validation.success) {
return NextResponse.json(
{ error: 'Invalid request', details: validation.error.errors },
{ status: 400 }
)
}
const { workflowId, targetWorkspaceId, deploymentVersion } = validation.data
// Fetch workflow metadata
const [workflowData] = await db
.select()
.from(workflow)
.where(eq(workflow.id, workflowId))
.limit(1)
if (!workflowData) {
return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
}
let workflowState: any
let sourceLabel = 'current state'
if (deploymentVersion !== undefined) {
// Load from deployment version
const [deployedVersion] = await db
.select({ state: workflowDeploymentVersion.state })
.from(workflowDeploymentVersion)
.where(
and(
eq(workflowDeploymentVersion.workflowId, workflowId),
eq(workflowDeploymentVersion.version, deploymentVersion)
)
)
.limit(1)
if (!deployedVersion?.state) {
return NextResponse.json({ error: `Deployment version ${deploymentVersion} not found` }, { status: 404 })
}
const deployedState = deployedVersion.state as any
workflowState = {
blocks: deployedState.blocks || {},
edges: Array.isArray(deployedState.edges) ? deployedState.edges : [],
loops: deployedState.loops || {},
parallels: deployedState.parallels || {},
metadata: {
name: workflowData.name,
description: workflowData.description ?? undefined,
color: workflowData.color ?? undefined,
},
variables: Array.isArray(deployedState.variables) ? deployedState.variables : [],
}
sourceLabel = `deployment v${deploymentVersion}`
} else {
// Load current state from normalized tables
const normalizedData = await loadWorkflowFromNormalizedTables(workflowId)
if (!normalizedData) {
return NextResponse.json({ error: 'Workflow has no data' }, { status: 404 })
}
let workflowVariables: any[] = []
if (workflowData.variables && typeof workflowData.variables === 'object') {
workflowVariables = Object.values(workflowData.variables).map((v: any) => ({
id: v.id,
name: v.name,
type: v.type,
value: v.value,
}))
}
workflowState = {
blocks: normalizedData.blocks || {},
edges: Array.isArray(normalizedData.edges) ? normalizedData.edges : [],
loops: normalizedData.loops || {},
parallels: normalizedData.parallels || {},
metadata: {
name: workflowData.name,
description: workflowData.description ?? undefined,
color: workflowData.color ?? undefined,
},
variables: workflowVariables,
}
}
const exportState = sanitizeForExport(workflowState)
logger.info(`[${requestId}] Exported workflow ${workflowId} (${sourceLabel})`)
return NextResponse.json({
success: true,
workflow: exportState,
metadata: {
originalId: workflowId,
originalName: workflowData.name,
originalDescription: workflowData.description,
targetWorkspaceId,
deploymentVersion: deploymentVersion ?? null,
source: sourceLabel,
},
})
} catch (error) {
logger.error(`[${requestId}] Error importing workflow:`, error)
return NextResponse.json(
{ error: 'Failed to import workflow' },
{ status: 500 }
)
}
}

View File

@@ -1,65 +0,0 @@
import { db } from '@sim/db'
import { user, workflowDeploymentVersion } from '@sim/db/schema'
import { desc, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
const logger = createLogger('AdminWorkflowDeploymentsAPI')
/**
* GET /api/admin/workflow-deployments?workflowId=xxx
* List all deployment versions for a workflow (superuser only)
*/
export async function GET(request: NextRequest) {
const requestId = generateRequestId()
try {
const session = await getSession()
if (!session?.user?.id) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// Check if user is superuser
const currentUser = await db
.select({ isSuperUser: user.isSuperUser })
.from(user)
.where(eq(user.id, session.user.id))
.limit(1)
if (!currentUser[0]?.isSuperUser) {
return NextResponse.json({ error: 'Forbidden - Superuser access required' }, { status: 403 })
}
const { searchParams } = new URL(request.url)
const workflowId = searchParams.get('workflowId')
if (!workflowId) {
return NextResponse.json({ error: 'workflowId query parameter is required' }, { status: 400 })
}
const versions = await db
.select({
id: workflowDeploymentVersion.id,
version: workflowDeploymentVersion.version,
name: workflowDeploymentVersion.name,
isActive: workflowDeploymentVersion.isActive,
createdAt: workflowDeploymentVersion.createdAt,
createdBy: workflowDeploymentVersion.createdBy,
deployedBy: user.name,
})
.from(workflowDeploymentVersion)
.leftJoin(user, eq(workflowDeploymentVersion.createdBy, user.id))
.where(eq(workflowDeploymentVersion.workflowId, workflowId))
.orderBy(desc(workflowDeploymentVersion.version))
logger.info(`[${requestId}] Retrieved ${versions.length} deployments for workflow ${workflowId}`)
return NextResponse.json({ success: true, versions })
} catch (error) {
logger.error(`[${requestId}] Error listing deployments:`, error)
return NextResponse.json({ error: 'Failed to list deployments' }, { status: 500 })
}
}

View File

@@ -3,10 +3,10 @@ import { eq } from 'drizzle-orm'
import { jwtDecode } from 'jwt-decode'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import type { OAuthProvider } from '@/lib/oauth/oauth'
import { evaluateScopeCoverage, parseProvider } from '@/lib/oauth/oauth'
import { generateRequestId } from '@/lib/utils'
const logger = createLogger('OAuthConnectionsAPI')

View File

@@ -5,10 +5,10 @@ import { jwtDecode } from 'jwt-decode'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { evaluateScopeCoverage, parseProvider } from '@/lib/oauth/oauth'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import { generateRequestId } from '@/lib/utils'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
export const dynamic = 'force-dynamic'

View File

@@ -4,8 +4,8 @@ import { and, eq, like, or } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
export const dynamic = 'force-dynamic'

View File

@@ -1,8 +1,8 @@
import { type NextRequest, NextResponse } from 'next/server'
import { authorizeCredentialUse } from '@/lib/auth/credential-access'
import { validateMicrosoftGraphId } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { validateMicrosoftGraphId } from '@/lib/security/input-validation'
import { generateRequestId } from '@/lib/utils'
import { getCredential, refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'

View File

@@ -1,7 +1,7 @@
import { type NextRequest, NextResponse } from 'next/server'
import { authorizeCredentialUse } from '@/lib/auth/credential-access'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { getCredential, refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'

View File

@@ -2,8 +2,8 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { authorizeCredentialUse } from '@/lib/auth/credential-access'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { getCredential, refreshTokenIfNeeded } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'

View File

@@ -3,9 +3,9 @@ import { account } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { validateEnum, validatePathSegment } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { validateEnum, validatePathSegment } from '@/lib/security/input-validation'
import { generateRequestId } from '@/lib/utils'
import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'

View File

@@ -3,8 +3,8 @@ import { account } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'

View File

@@ -1,7 +1,7 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { auth } from '@/lib/auth'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('SSO-Register')

View File

@@ -1,8 +1,8 @@
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { getBaseUrl } from '@/lib/urls/utils'
const logger = createLogger('TrelloAuthorize')

View File

@@ -1,5 +1,5 @@
import { type NextRequest, NextResponse } from 'next/server'
import { getBaseUrl } from '@/lib/urls/utils'
import { getBaseUrl } from '@/lib/core/utils/urls'
export const dynamic = 'force-dynamic'

View File

@@ -1,7 +1,7 @@
import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { createLogger } from '@/lib/logs/console/logger'
import { db } from '@/../../packages/db'
import { account } from '@/../../packages/db/schema'

View File

@@ -4,8 +4,8 @@ import { and, eq, or } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { requireStripeClient } from '@/lib/billing/stripe-client'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { getBaseUrl } from '@/lib/urls/utils'
const logger = createLogger('BillingPortal')

View File

@@ -5,9 +5,9 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkAndBillOverageThreshold } from '@/lib/billing/threshold-billing'
import { checkInternalApiKey } from '@/lib/copilot/utils'
import { isBillingEnabled } from '@/lib/environment'
import { isBillingEnabled } from '@/lib/core/config/environment'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
const logger = createLogger('BillingUpdateCostAPI')

View File

@@ -3,9 +3,9 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import CareersConfirmationEmail from '@/components/emails/careers/careers-confirmation-email'
import CareersSubmissionEmail from '@/components/emails/careers/careers-submission-email'
import { sendEmail } from '@/lib/email/mailer'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { sendEmail } from '@/lib/messaging/email/mailer'
export const dynamic = 'force-dynamic'

View File

@@ -4,10 +4,10 @@ import { eq } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { z } from 'zod'
import { renderOTPEmail } from '@/components/emails/render-email'
import { sendEmail } from '@/lib/email/mailer'
import { getRedisClient, markMessageAsProcessed, releaseLock } from '@/lib/core/config/redis'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { getRedisClient, markMessageAsProcessed, releaseLock } from '@/lib/redis'
import { generateRequestId } from '@/lib/utils'
import { sendEmail } from '@/lib/messaging/email/mailer'
import { addCorsHeaders, setChatAuthCookie } from '@/app/api/chat/utils'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'

View File

@@ -53,17 +53,20 @@ vi.mock('@/lib/logs/execution/logging-session', () => ({
})),
}))
vi.mock('@/lib/workflows/streaming', () => ({
vi.mock('@/lib/workflows/streaming/streaming', () => ({
createStreamingResponse: vi.fn().mockImplementation(async () => createMockStream()),
}))
vi.mock('@/lib/utils', () => ({
vi.mock('@/lib/core/utils/sse', () => ({
SSE_HEADERS: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'X-Accel-Buffering': 'no',
},
}))
vi.mock('@/lib/core/utils/request', () => ({
generateRequestId: vi.fn().mockReturnValue('test-request-id'),
}))
@@ -388,7 +391,7 @@ describe('Chat Identifier API Route', () => {
const params = Promise.resolve({ identifier: 'test-chat' })
const { POST } = await import('@/app/api/chat/[identifier]/route')
const { createStreamingResponse } = await import('@/lib/workflows/streaming')
const { createStreamingResponse } = await import('@/lib/workflows/streaming/streaming')
const response = await POST(req, { params })
@@ -440,7 +443,7 @@ describe('Chat Identifier API Route', () => {
})
it('should handle workflow execution errors gracefully', async () => {
const { createStreamingResponse } = await import('@/lib/workflows/streaming')
const { createStreamingResponse } = await import('@/lib/workflows/streaming/streaming')
const originalStreamingResponse = vi.mocked(createStreamingResponse).getMockImplementation()
vi.mocked(createStreamingResponse).mockImplementationOnce(async () => {
throw new Error('Execution failed')
@@ -492,7 +495,7 @@ describe('Chat Identifier API Route', () => {
const params = Promise.resolve({ identifier: 'test-chat' })
const { POST } = await import('@/app/api/chat/[identifier]/route')
const { createStreamingResponse } = await import('@/lib/workflows/streaming')
const { createStreamingResponse } = await import('@/lib/workflows/streaming/streaming')
await POST(req, { params })
@@ -511,7 +514,7 @@ describe('Chat Identifier API Route', () => {
const params = Promise.resolve({ identifier: 'test-chat' })
const { POST } = await import('@/app/api/chat/[identifier]/route')
const { createStreamingResponse } = await import('@/lib/workflows/streaming')
const { createStreamingResponse } = await import('@/lib/workflows/streaming/streaming')
await POST(req, { params })

View File

@@ -4,11 +4,11 @@ import { chat } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { generateRequestId } from '@/lib/core/utils/request'
import { preprocessExecution } from '@/lib/execution/preprocessing'
import { createLogger } from '@/lib/logs/console/logger'
import { LoggingSession } from '@/lib/logs/execution/logging-session'
import { ChatFiles } from '@/lib/uploads'
import { generateRequestId } from '@/lib/utils'
import {
addCorsHeaders,
setChatAuthCookie,
@@ -182,8 +182,8 @@ export async function POST(
}
}
const { createStreamingResponse } = await import('@/lib/workflows/streaming')
const { SSE_HEADERS } = await import('@/lib/utils')
const { createStreamingResponse } = await import('@/lib/workflows/streaming/streaming')
const { SSE_HEADERS } = await import('@/lib/core/utils/sse')
const { createFilteredResult } = await import('@/app/api/workflows/[id]/execute/route')
const workflowInput: any = { input, conversationId }

View File

@@ -69,15 +69,15 @@ describe('Chat Edit API Route', () => {
}),
}))
vi.doMock('@/lib/utils', () => ({
vi.doMock('@/lib/core/security/encryption', () => ({
encryptSecret: mockEncryptSecret.mockResolvedValue({ encrypted: 'encrypted-password' }),
}))
vi.doMock('@/lib/urls/utils', () => ({
vi.doMock('@/lib/core/utils/urls', () => ({
getEmailDomain: vi.fn().mockReturnValue('localhost:3000'),
}))
vi.doMock('@/lib/environment', () => ({
vi.doMock('@/lib/core/config/environment', () => ({
isDev: true,
}))
@@ -86,7 +86,7 @@ describe('Chat Edit API Route', () => {
}))
mockDeployWorkflow.mockResolvedValue({ success: true, version: 1 })
vi.doMock('@/lib/workflows/db-helpers', () => ({
vi.doMock('@/lib/workflows/persistence/utils', () => ({
deployWorkflow: mockDeployWorkflow,
}))

View File

@@ -4,11 +4,11 @@ import { eq } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { isDev } from '@/lib/environment'
import { isDev } from '@/lib/core/config/environment'
import { encryptSecret } from '@/lib/core/security/encryption'
import { getEmailDomain } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { getEmailDomain } from '@/lib/urls/utils'
import { encryptSecret } from '@/lib/utils'
import { deployWorkflow } from '@/lib/workflows/db-helpers'
import { deployWorkflow } from '@/lib/workflows/persistence/utils'
import { checkChatAccess } from '@/app/api/chat/utils'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'

View File

@@ -66,7 +66,7 @@ describe('Chat API Route', () => {
}),
}))
vi.doMock('@/lib/utils', () => ({
vi.doMock('@/lib/core/security/encryption', () => ({
encryptSecret: mockEncryptSecret.mockResolvedValue({ encrypted: 'encrypted-password' }),
}))
@@ -78,7 +78,7 @@ describe('Chat API Route', () => {
checkWorkflowAccessForChatCreation: mockCheckWorkflowAccessForChatCreation,
}))
vi.doMock('@/lib/workflows/db-helpers', () => ({
vi.doMock('@/lib/workflows/persistence/utils', () => ({
deployWorkflow: mockDeployWorkflow.mockResolvedValue({
success: true,
version: 1,
@@ -249,7 +249,7 @@ describe('Chat API Route', () => {
}),
}))
vi.doMock('@/lib/env', () => ({
vi.doMock('@/lib/core/config/env', () => ({
env: {
NODE_ENV: 'development',
NEXT_PUBLIC_APP_URL: 'http://localhost:3000',
@@ -296,7 +296,7 @@ describe('Chat API Route', () => {
}),
}))
vi.doMock('@/lib/env', () => ({
vi.doMock('@/lib/core/config/env', () => ({
env: {
NODE_ENV: 'development',
NEXT_PUBLIC_APP_URL: 'http://localhost:3000',

View File

@@ -5,11 +5,11 @@ import type { NextRequest } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { isDev } from '@/lib/environment'
import { isDev } from '@/lib/core/config/environment'
import { encryptSecret } from '@/lib/core/security/encryption'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { getBaseUrl } from '@/lib/urls/utils'
import { encryptSecret } from '@/lib/utils'
import { deployWorkflow } from '@/lib/workflows/db-helpers'
import { deployWorkflow } from '@/lib/workflows/persistence/utils'
import { checkWorkflowAccessForChatCreation } from '@/app/api/chat/utils'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'

View File

@@ -5,7 +5,7 @@ import type { NextResponse } from 'next/server'
* @vitest-environment node
*/
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
vi.mock('@sim/db', () => ({
db: {
@@ -36,8 +36,11 @@ vi.mock('@/stores/workflows/server-utils', () => ({
const mockDecryptSecret = vi.fn()
vi.mock('@/lib/utils', () => ({
vi.mock('@/lib/core/security/encryption', () => ({
decryptSecret: mockDecryptSecret,
}))
vi.mock('@/lib/core/utils/request', () => ({
generateRequestId: vi.fn(),
}))
@@ -60,7 +63,7 @@ describe('Chat API Utils', () => {
},
})
vi.doMock('@/lib/environment', () => ({
vi.doMock('@/lib/core/config/environment', () => ({
isDev: true,
isHosted: false,
}))
@@ -229,7 +232,7 @@ describe('Chat API Utils', () => {
it('should validate password for POST requests', async () => {
const { validateChatAuth } = await import('@/app/api/chat/utils')
const { decryptSecret } = await import('@/lib/utils')
const { decryptSecret } = await import('@/lib/core/security/encryption')
const deployment = {
id: 'chat-id',

View File

@@ -2,10 +2,10 @@ import { db } from '@sim/db'
import { chat, workflow } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import type { NextRequest, NextResponse } from 'next/server'
import { isDev } from '@/lib/environment'
import { isDev } from '@/lib/core/config/environment'
import { decryptSecret } from '@/lib/core/security/encryption'
import { createLogger } from '@/lib/logs/console/logger'
import { hasAdminPermission } from '@/lib/permissions/utils'
import { decryptSecret } from '@/lib/utils'
import { hasAdminPermission } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('ChatAuthUtils')

View File

@@ -1,8 +1,8 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { env } from '@/lib/env'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/sim-agent/constants'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/copilot/constants'
import { env } from '@/lib/core/config/env'
const GenerateApiKeySchema = z.object({}).optional()

View File

@@ -1,7 +1,7 @@
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { env } from '@/lib/env'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/sim-agent/constants'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/copilot/constants'
import { env } from '@/lib/core/config/env'
export async function GET(request: NextRequest) {
try {

View File

@@ -97,8 +97,11 @@ describe('Copilot Chat API Route', () => {
mockGetRotatingApiKey.mockReturnValue('test-api-key')
vi.doMock('@/lib/utils', () => ({
vi.doMock('@/lib/core/config/api-keys', () => ({
getRotatingApiKey: mockGetRotatingApiKey,
}))
vi.doMock('@/lib/core/utils/request', () => ({
generateRequestId: vi.fn(() => 'test-request-id'),
}))
@@ -110,7 +113,7 @@ describe('Copilot Chat API Route', () => {
NODE_ENV: 'test',
} as const
vi.doMock('@/lib/env', () => ({
vi.doMock('@/lib/core/config/env', () => ({
env: mockEnvValues,
getEnv: (variable: string) => mockEnvValues[variable as keyof typeof mockEnvValues],
isTruthy: (value: string | boolean | number | undefined) =>

View File

@@ -4,19 +4,19 @@ import { and, desc, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateChatTitle } from '@/lib/copilot/chat-title'
import { getCopilotModel } from '@/lib/copilot/config'
import { SIM_AGENT_API_URL_DEFAULT, SIM_AGENT_VERSION } from '@/lib/copilot/constants'
import {
authenticateCopilotRequestSessionOnly,
createBadRequestResponse,
createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
import { getCopilotModel } from '@/lib/copilot/config'
} from '@/lib/copilot/request-helpers'
import type { CopilotProviderConfig } from '@/lib/copilot/types'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { createLogger } from '@/lib/logs/console/logger'
import { SIM_AGENT_API_URL_DEFAULT, SIM_AGENT_VERSION } from '@/lib/sim-agent/constants'
import { generateChatTitle } from '@/lib/sim-agent/utils'
import { CopilotFiles } from '@/lib/uploads'
import { createFileContent } from '@/lib/uploads/utils/file-utils'

View File

@@ -9,7 +9,7 @@ import {
createNotFoundResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
} from '@/lib/copilot/request-helpers'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotChatUpdateAPI')

View File

@@ -6,7 +6,7 @@ import {
authenticateCopilotRequestSessionOnly,
createInternalServerErrorResponse,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
} from '@/lib/copilot/request-helpers'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotChatsListAPI')

View File

@@ -24,7 +24,7 @@ describe('Copilot Checkpoints Revert API Route', () => {
mockCryptoUuid()
// Mock getBaseUrl to return localhost for tests
vi.doMock('@/lib/urls/utils', () => ({
vi.doMock('@/lib/core/utils/urls', () => ({
getBaseUrl: vi.fn(() => 'http://localhost:3000'),
getBaseDomain: vi.fn(() => 'localhost:3000'),
getEmailDomain: vi.fn(() => 'localhost:3000'),

View File

@@ -9,10 +9,10 @@ import {
createNotFoundResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
} from '@/lib/copilot/request-helpers'
import { validateUUID } from '@/lib/core/security/input-validation'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { validateUUID } from '@/lib/security/input-validation'
import { getBaseUrl } from '@/lib/urls/utils'
const logger = createLogger('CheckpointRevertAPI')

View File

@@ -9,7 +9,7 @@ import {
createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
} from '@/lib/copilot/request-helpers'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('WorkflowCheckpointsAPI')

View File

@@ -28,27 +28,23 @@ describe('Copilot Confirm API Route', () => {
}
mockGetRedisClient.mockReturnValue(mockRedisClient)
mockRedisExists.mockResolvedValue(1) // Tool call exists by default
mockRedisExists.mockResolvedValue(1)
mockRedisSet.mockResolvedValue('OK')
vi.doMock('@/lib/redis', () => ({
vi.doMock('@/lib/core/config/redis', () => ({
getRedisClient: mockGetRedisClient,
}))
// Mock setTimeout to control polling behavior
vi.spyOn(global, 'setTimeout').mockImplementation((callback, _delay) => {
// Immediately call callback to avoid delays
if (typeof callback === 'function') {
setImmediate(callback)
}
return setTimeout(() => {}, 0) as any
})
// Mock Date.now to control timeout behavior
let mockTime = 1640995200000
vi.spyOn(Date, 'now').mockImplementation(() => {
// Increment time rapidly to trigger timeout for non-existent keys
mockTime += 10000 // Add 10 seconds each call
mockTime += 10000
return mockTime
})
})
@@ -82,7 +78,6 @@ describe('Copilot Confirm API Route', () => {
const req = createMockRequest('POST', {
status: 'success',
// Missing toolCallId
})
const { POST } = await import('@/app/api/copilot/confirm/route')
@@ -149,7 +144,6 @@ describe('Copilot Confirm API Route', () => {
status: 'success',
})
// Verify Redis operations were called
expect(mockRedisExists).toHaveBeenCalled()
expect(mockRedisSet).toHaveBeenCalled()
})
@@ -252,7 +246,6 @@ describe('Copilot Confirm API Route', () => {
const authMocks = mockAuth()
authMocks.setAuthenticated()
// Mock Redis client as unavailable
mockGetRedisClient.mockReturnValue(null)
const req = createMockRequest('POST', {
@@ -272,7 +265,6 @@ describe('Copilot Confirm API Route', () => {
const authMocks = mockAuth()
authMocks.setAuthenticated()
// Mock tool call as not existing in Redis
mockRedisExists.mockResolvedValue(0)
const req = createMockRequest('POST', {
@@ -292,7 +284,6 @@ describe('Copilot Confirm API Route', () => {
const authMocks = mockAuth()
authMocks.setAuthenticated()
// Mock Redis operations to throw an error
mockRedisExists.mockRejectedValue(new Error('Redis connection failed'))
const req = createMockRequest('POST', {
@@ -312,7 +303,6 @@ describe('Copilot Confirm API Route', () => {
const authMocks = mockAuth()
authMocks.setAuthenticated()
// Tool call exists but set operation fails
mockRedisExists.mockResolvedValue(1)
mockRedisSet.mockRejectedValue(new Error('Redis set failed'))
@@ -333,7 +323,6 @@ describe('Copilot Confirm API Route', () => {
const authMocks = mockAuth()
authMocks.setAuthenticated()
// Create a request with invalid JSON
const req = new NextRequest('http://localhost:3000/api/copilot/confirm', {
method: 'POST',
body: '{invalid-json',

View File

@@ -7,9 +7,9 @@ import {
createRequestTracker,
createUnauthorizedResponse,
type NotificationStatus,
} from '@/lib/copilot/auth'
} from '@/lib/copilot/request-helpers'
import { getRedisClient } from '@/lib/core/config/redis'
import { createLogger } from '@/lib/logs/console/logger'
import { getRedisClient } from '@/lib/redis'
const logger = createLogger('CopilotConfirmAPI')

View File

@@ -2,10 +2,10 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { getCopilotModel } from '@/lib/copilot/config'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/copilot/constants'
import type { CopilotProviderConfig } from '@/lib/copilot/types'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { createLogger } from '@/lib/logs/console/logger'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/sim-agent/constants'
const logger = createLogger('ContextUsageAPI')

View File

@@ -6,7 +6,7 @@ import {
createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
} from '@/lib/copilot/request-helpers'
import { routeExecution } from '@/lib/copilot/tools/server/router'
import { createLogger } from '@/lib/logs/console/logger'

View File

@@ -8,7 +8,7 @@ import {
createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
} from '@/lib/copilot/request-helpers'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotFeedbackAPI')

View File

@@ -1,14 +1,14 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/copilot/constants'
import {
authenticateCopilotRequestSessionOnly,
createBadRequestResponse,
createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
import { env } from '@/lib/env'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/sim-agent/constants'
} from '@/lib/copilot/request-helpers'
import { env } from '@/lib/core/config/env'
const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT

View File

@@ -1,15 +1,15 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/copilot/constants'
import {
authenticateCopilotRequestSessionOnly,
createBadRequestResponse,
createInternalServerErrorResponse,
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/auth'
import { env } from '@/lib/env'
} from '@/lib/copilot/request-helpers'
import { env } from '@/lib/core/config/env'
import { createLogger } from '@/lib/logs/console/logger'
import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/sim-agent/constants'
const logger = createLogger('CopilotMarkToolCompleteAPI')

View File

@@ -1,6 +1,6 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotTrainingExamplesAPI')

View File

@@ -1,6 +1,6 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { createLogger } from '@/lib/logs/console/logger'
const logger = createLogger('CopilotTrainingAPI')

View File

@@ -4,8 +4,8 @@ import { and, eq, or } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
const logger = createLogger('CreatorProfileByIdAPI')

View File

@@ -3,8 +3,8 @@ import { templateCreators, user } from '@sim/db/schema'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
const logger = createLogger('CreatorVerificationAPI')

View File

@@ -5,8 +5,8 @@ import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import type { CreatorProfileDetails } from '@/app/_types/creator-profile'
const logger = createLogger('CreatorProfilesAPI')

View File

@@ -4,8 +4,9 @@ import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { decryptSecret, encryptSecret } from '@/lib/core/security/encryption'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { decryptSecret, encryptSecret, generateRequestId } from '@/lib/utils'
import type { EnvironmentVariable } from '@/stores/settings/environment/types'
const logger = createLogger('EnvironmentAPI')

View File

@@ -2,7 +2,6 @@ import { db } from '@sim/db'
import { document, workspaceFile } from '@sim/db/schema'
import { eq, like, or } from 'drizzle-orm'
import { createLogger } from '@/lib/logs/console/logger'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import { getFileMetadata } from '@/lib/uploads'
import type { StorageContext } from '@/lib/uploads/config'
import {
@@ -14,6 +13,7 @@ import {
import type { StorageConfig } from '@/lib/uploads/core/storage-client'
import { getFileMetadataByKey } from '@/lib/uploads/server/metadata'
import { inferContextFromKey } from '@/lib/uploads/utils/file-utils'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('FileAuthorization')

View File

@@ -61,7 +61,7 @@ export async function POST(request: NextRequest) {
throw new FileNotFoundError(`File not found: ${key}`)
}
const { getBaseUrl } = await import('@/lib/urls/utils')
const { getBaseUrl } = await import('@/lib/core/utils/urls')
const downloadUrl = `${getBaseUrl()}/api/files/serve/${encodeURIComponent(key)}?context=${storageContext}`
logger.info(`Generated download URL for ${storageContext} file: ${key}`)

View File

@@ -5,10 +5,9 @@ import path from 'path'
import binaryExtensionsList from 'binary-extensions'
import { type NextRequest, NextResponse } from 'next/server'
import { checkHybridAuth } from '@/lib/auth/hybrid'
import { validateExternalUrl } from '@/lib/core/security/input-validation'
import { isSupportedFileType, parseFile } from '@/lib/file-parsers'
import { createLogger } from '@/lib/logs/console/logger'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import { validateExternalUrl } from '@/lib/security/input-validation'
import { isUsingCloudStorage, type StorageContext, StorageService } from '@/lib/uploads'
import { UPLOAD_DIR_SERVER } from '@/lib/uploads/core/setup.server'
import { getFileMetadataByKey } from '@/lib/uploads/server/metadata'
@@ -19,6 +18,7 @@ import {
getViewerUrl,
inferContextFromKey,
} from '@/lib/uploads/utils/file-utils'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
import { verifyFileAccess } from '@/app/api/files/authorization'
import '@/lib/uploads/core/setup.server'

View File

@@ -2,10 +2,10 @@ import { type NextRequest, NextResponse } from 'next/server'
import { createLogger } from '@/lib/logs/console/logger'
import '@/lib/uploads/core/setup.server'
import { getSession } from '@/lib/auth'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import type { StorageContext } from '@/lib/uploads/config'
import { isImageFileType } from '@/lib/uploads/utils/file-utils'
import { validateFileType } from '@/lib/uploads/utils/validation'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
import {
createErrorResponse,
createOptionsResponse,

View File

@@ -4,10 +4,10 @@ import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import { generateRequestId } from '@/lib/utils'
import { duplicateWorkflow } from '@/lib/workflows/duplicate'
import { duplicateWorkflow } from '@/lib/workflows/persistence/duplicate'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('FolderDuplicateAPI')

View File

@@ -113,7 +113,7 @@ describe('Individual Folder API Route', () => {
mockGetUserEntityPermissions.mockResolvedValue('admin')
vi.doMock('@/lib/permissions/utils', () => ({
vi.doMock('@/lib/workspaces/permissions/utils', () => ({
getUserEntityPermissions: mockGetUserEntityPermissions,
}))
})

View File

@@ -5,7 +5,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('FoldersIDAPI')

View File

@@ -83,7 +83,7 @@ describe('Folders API Route', () => {
},
}))
vi.doMock('@/lib/permissions/utils', () => ({
vi.doMock('@/lib/workspaces/permissions/utils', () => ({
getUserEntityPermissions: mockGetUserEntityPermissions,
}))
})

View File

@@ -4,7 +4,7 @@ import { and, asc, desc, eq, isNull } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('FoldersAPI')

View File

@@ -66,7 +66,7 @@ describe('Function Execute API Route', () => {
})
it.concurrent('should block SSRF attacks through secure fetch wrapper', async () => {
const { validateProxyUrl } = await import('@/lib/security/input-validation')
const { validateProxyUrl } = await import('@/lib/core/security/input-validation')
expect(validateProxyUrl('http://169.254.169.254/latest/meta-data/').isValid).toBe(false)
expect(validateProxyUrl('http://127.0.0.1:8080/admin').isValid).toBe(false)
@@ -75,7 +75,7 @@ describe('Function Execute API Route', () => {
})
it.concurrent('should allow legitimate external URLs', async () => {
const { validateProxyUrl } = await import('@/lib/security/input-validation')
const { validateProxyUrl } = await import('@/lib/core/security/input-validation')
expect(validateProxyUrl('https://api.github.com/user').isValid).toBe(true)
expect(validateProxyUrl('https://httpbin.org/get').isValid).toBe(true)
@@ -83,7 +83,7 @@ describe('Function Execute API Route', () => {
})
it.concurrent('should block dangerous protocols', async () => {
const { validateProxyUrl } = await import('@/lib/security/input-validation')
const { validateProxyUrl } = await import('@/lib/core/security/input-validation')
expect(validateProxyUrl('file:///etc/passwd').isValid).toBe(false)
expect(validateProxyUrl('ftp://internal.server/files').isValid).toBe(false)

View File

@@ -1,11 +1,11 @@
import { createContext, Script } from 'vm'
import { type NextRequest, NextResponse } from 'next/server'
import { env, isTruthy } from '@/lib/env'
import { env, isTruthy } from '@/lib/core/config/env'
import { validateProxyUrl } from '@/lib/core/security/input-validation'
import { generateRequestId } from '@/lib/core/utils/request'
import { executeInE2B } from '@/lib/execution/e2b'
import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages'
import { createLogger } from '@/lib/logs/console/logger'
import { validateProxyUrl } from '@/lib/security/input-validation'
import { generateRequestId } from '@/lib/utils'
export const dynamic = 'force-dynamic'
export const runtime = 'nodejs'

View File

@@ -1,10 +1,10 @@
import { type NextRequest, NextResponse } from 'next/server'
import { generateRequestId } from '@/lib/core/utils/request'
import { validateHallucination } from '@/lib/guardrails/validate_hallucination'
import { validateJson } from '@/lib/guardrails/validate_json'
import { validatePII } from '@/lib/guardrails/validate_pii'
import { validateRegex } from '@/lib/guardrails/validate_regex'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
const logger = createLogger('GuardrailsValidateAPI')

View File

@@ -2,12 +2,12 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { renderHelpConfirmationEmail } from '@/components/emails'
import { getSession } from '@/lib/auth'
import { sendEmail } from '@/lib/email/mailer'
import { getFromEmailAddress } from '@/lib/email/utils'
import { env } from '@/lib/env'
import { env } from '@/lib/core/config/env'
import { generateRequestId } from '@/lib/core/utils/request'
import { getEmailDomain } from '@/lib/core/utils/urls'
import { createLogger } from '@/lib/logs/console/logger'
import { getEmailDomain } from '@/lib/urls/utils'
import { generateRequestId } from '@/lib/utils'
import { sendEmail } from '@/lib/messaging/email/mailer'
import { getFromEmailAddress } from '@/lib/messaging/email/utils'
const logger = createLogger('HelpAPI')

View File

@@ -2,8 +2,8 @@ import { runs } from '@trigger.dev/sdk'
import { type NextRequest, NextResponse } from 'next/server'
import { authenticateApiKeyFromHeader, updateApiKeyLastUsed } from '@/lib/api-key/service'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { createErrorResponse } from '@/app/api/workflows/utils'
const logger = createLogger('TaskStatusAPI')

View File

@@ -1,9 +1,9 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { batchChunkOperation, createChunk, queryChunks } from '@/lib/knowledge/chunks/service'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { getUserId } from '@/app/api/auth/oauth/utils'
import { checkDocumentAccess, checkDocumentWriteAccess } from '@/app/api/knowledge/utils'
import { calculateCost } from '@/providers/utils'

View File

@@ -1,6 +1,7 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import {
deleteDocument,
markDocumentAsFailedTimeout,
@@ -8,7 +9,6 @@ import {
updateDocument,
} from '@/lib/knowledge/documents/service'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { checkDocumentAccess, checkDocumentWriteAccess } from '@/app/api/knowledge/utils'
const logger = createLogger('DocumentByIdAPI')

View File

@@ -2,7 +2,7 @@ import { randomUUID } from 'crypto'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { SUPPORTED_FIELD_TYPES } from '@/lib/knowledge/consts'
import { SUPPORTED_FIELD_TYPES } from '@/lib/knowledge/constants'
import {
cleanupUnusedTagDefinitions,
createOrUpdateTagDefinitionsBulk,

View File

@@ -189,7 +189,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
// Track bulk document upload
try {
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
const { trackPlatformEvent } = await import('@/lib/core/telemetry')
trackPlatformEvent('platform.knowledge_base.documents_uploaded', {
'knowledge_base.id': knowledgeBaseId,
'documents.count': createdDocuments.length,
@@ -253,7 +253,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
// Track single document upload
try {
const { trackPlatformEvent } = await import('@/lib/telemetry/tracer')
const { trackPlatformEvent } = await import('@/lib/core/telemetry')
trackPlatformEvent('platform.knowledge_base.documents_uploaded', {
'knowledge_base.id': knowledgeBaseId,
'documents.count': 1,

View File

@@ -1,13 +1,13 @@
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import {
deleteKnowledgeBase,
getKnowledgeBaseById,
updateKnowledgeBase,
} from '@/lib/knowledge/service'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import { checkKnowledgeBaseAccess, checkKnowledgeBaseWriteAccess } from '@/app/api/knowledge/utils'
const logger = createLogger('KnowledgeBaseByIdAPI')

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