Skip to content

Commit 970299f

Browse files
committed
fix(logs): move folder expansion to server-only module to fix client bundle build
1 parent d13d662 commit 970299f

5 files changed

Lines changed: 61 additions & 57 deletions

File tree

apps/sim/app/api/logs/export/route.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@ import { and, desc, eq, sql } from 'drizzle-orm'
55
import { type NextRequest, NextResponse } from 'next/server'
66
import { getSession } from '@/lib/auth'
77
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
8-
import {
9-
buildFilterConditions,
10-
expandFolderIdsWithDescendants,
11-
LogFilterParamsSchema,
12-
} from '@/lib/logs/filters'
8+
import { buildFilterConditions, LogFilterParamsSchema } from '@/lib/logs/filters'
9+
import { expandFolderIdsWithDescendants } from '@/lib/logs/folder-expansion'
1310

1411
const logger = createLogger('LogsExportAPI')
1512

apps/sim/app/api/logs/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import { listLogsContract, type WorkflowLogSummary } from '@/lib/api/contracts/l
3131
import { parseRequest } from '@/lib/api/server'
3232
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
3333
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
34-
import { buildFilterConditions, expandFolderIdsWithDescendants } from '@/lib/logs/filters'
34+
import { buildFilterConditions } from '@/lib/logs/filters'
35+
import { expandFolderIdsWithDescendants } from '@/lib/logs/folder-expansion'
3536

3637
const logger = createLogger('LogsAPI')
3738

apps/sim/app/api/logs/stats/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import { isZodError } from '@/lib/api/server'
1313
import { getSession } from '@/lib/auth'
1414
import { generateRequestId } from '@/lib/core/utils/request'
1515
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
16-
import { buildFilterConditions, expandFolderIdsWithDescendants } from '@/lib/logs/filters'
16+
import { buildFilterConditions } from '@/lib/logs/filters'
17+
import { expandFolderIdsWithDescendants } from '@/lib/logs/folder-expansion'
1718

1819
const logger = createLogger('LogsStatsAPI')
1920

apps/sim/lib/logs/filters.ts

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { db } from '@sim/db'
2-
import { workflow, workflowExecutionLogs, workflowFolder } from '@sim/db/schema'
3-
import { and, eq, gt, gte, inArray, isNull, lt, lte, ne, type SQL, sql } from 'drizzle-orm'
1+
import { workflow, workflowExecutionLogs } from '@sim/db/schema'
2+
import { and, eq, gt, gte, inArray, lt, lte, ne, type SQL, sql } from 'drizzle-orm'
43
import { z } from 'zod'
54
import type { TimeRange } from '@/stores/logs/filters/types'
65

@@ -129,53 +128,6 @@ function buildWorkflowIdsCondition(workflowIds: string): SQL | undefined {
129128
return undefined
130129
}
131130

132-
/**
133-
* Expands a CSV of selected folder IDs to include every descendant folder in the
134-
* workspace, so that filtering by a parent folder also matches workflows that
135-
* live in nested subfolders.
136-
*
137-
* Returns the original CSV when there are no descendants (or when the input is
138-
* empty / undefined). Unknown IDs are preserved so the caller's `inArray` check
139-
* behaves the same as today (matches nothing).
140-
*/
141-
export async function expandFolderIdsWithDescendants(
142-
workspaceId: string,
143-
folderIdsCsv: string | undefined
144-
): Promise<string | undefined> {
145-
if (!folderIdsCsv) return folderIdsCsv
146-
const seedIds = folderIdsCsv.split(',').filter(Boolean)
147-
if (seedIds.length === 0) return folderIdsCsv
148-
149-
const rows = await db
150-
.select({ id: workflowFolder.id, parentId: workflowFolder.parentId })
151-
.from(workflowFolder)
152-
.where(and(eq(workflowFolder.workspaceId, workspaceId), isNull(workflowFolder.archivedAt)))
153-
154-
const childrenByParent = new Map<string, string[]>()
155-
for (const row of rows) {
156-
if (!row.parentId) continue
157-
const list = childrenByParent.get(row.parentId)
158-
if (list) list.push(row.id)
159-
else childrenByParent.set(row.parentId, [row.id])
160-
}
161-
162-
const expanded = new Set<string>(seedIds)
163-
const queue = [...seedIds]
164-
while (queue.length > 0) {
165-
const current = queue.pop() as string
166-
const children = childrenByParent.get(current)
167-
if (!children) continue
168-
for (const childId of children) {
169-
if (!expanded.has(childId)) {
170-
expanded.add(childId)
171-
queue.push(childId)
172-
}
173-
}
174-
}
175-
176-
return Array.from(expanded).join(',')
177-
}
178-
179131
function buildFolderIdsCondition(folderIds: string): SQL | undefined {
180132
const ids = folderIds.split(',').filter(Boolean)
181133
if (ids.length > 0) {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { db } from '@sim/db'
2+
import { workflowFolder } from '@sim/db/schema'
3+
import { and, eq, isNull } from 'drizzle-orm'
4+
5+
/**
6+
* Expands a CSV of selected folder IDs to include every descendant folder in the
7+
* workspace, so that filtering by a parent folder also matches workflows that
8+
* live in nested subfolders.
9+
*
10+
* Returns the original CSV when there are no descendants (or when the input is
11+
* empty / undefined). Unknown IDs are preserved so the caller's `inArray` check
12+
* behaves the same as today (matches nothing).
13+
*
14+
* Server-only: pulls in the database client. Keep separate from `filters.ts`
15+
* (imported by client hooks) to avoid leaking postgres into the browser bundle.
16+
*/
17+
export async function expandFolderIdsWithDescendants(
18+
workspaceId: string,
19+
folderIdsCsv: string | undefined
20+
): Promise<string | undefined> {
21+
if (!folderIdsCsv) return folderIdsCsv
22+
const seedIds = folderIdsCsv.split(',').filter(Boolean)
23+
if (seedIds.length === 0) return folderIdsCsv
24+
25+
const rows = await db
26+
.select({ id: workflowFolder.id, parentId: workflowFolder.parentId })
27+
.from(workflowFolder)
28+
.where(and(eq(workflowFolder.workspaceId, workspaceId), isNull(workflowFolder.archivedAt)))
29+
30+
const childrenByParent = new Map<string, string[]>()
31+
for (const row of rows) {
32+
if (!row.parentId) continue
33+
const list = childrenByParent.get(row.parentId)
34+
if (list) list.push(row.id)
35+
else childrenByParent.set(row.parentId, [row.id])
36+
}
37+
38+
const expanded = new Set<string>(seedIds)
39+
const queue = [...seedIds]
40+
while (queue.length > 0) {
41+
const current = queue.pop() as string
42+
const children = childrenByParent.get(current)
43+
if (!children) continue
44+
for (const childId of children) {
45+
if (!expanded.has(childId)) {
46+
expanded.add(childId)
47+
queue.push(childId)
48+
}
49+
}
50+
}
51+
52+
return Array.from(expanded).join(',')
53+
}

0 commit comments

Comments
 (0)