Skip to content

Commit 2b139e4

Browse files
authored
v0.8.36: sim search, provenance improvements
2 parents 4b3a9df + b26365c commit 2b139e4

79 files changed

Lines changed: 29463 additions & 1308 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/publish-sim-cli.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ on:
55
branches: [main, staging, dev]
66
paths:
77
- 'packages/sim-cli/**'
8+
# The build bundles its workspace dependencies, so a change there
9+
# changes what ships.
10+
- 'packages/utils/**'
11+
# A change to how the package is built or published has to republish it.
12+
- '.github/workflows/publish-sim-cli.yml'
813

914
permissions:
1015
contents: read

.github/workflows/test-build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ jobs:
9393
lib/auth/oauth-provider-lifecycle.postgres.test.ts
9494
app/api/auth/oauth2/token/route.postgres.test.ts
9595
lib/auth/sim-auth-adapter.test.ts
96+
lib/auth/sim-auth-adapter.postgres.test.ts
9697
ee/scim/lib/managed-membership.postgres.test.ts
9798
lib/auth/sso/application/admit-sso-user.postgres.test.ts
9899

apps/sim/app/(landing)/components/shared/zip-icon/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

apps/sim/app/(landing)/components/shared/zip-icon/zip-icon.tsx

Lines changed: 0 additions & 28 deletions
This file was deleted.

apps/sim/app/(landing)/files/components/files-hero-loop.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import { useState } from 'react'
55
import { cn } from '@sim/emcn'
66
import { ArrowUpDown, File, ListFilter, Plus, Search } from '@sim/emcn/icons'
77
import { AgentIcon } from '@/components/icons'
8-
import { CsvIcon, DocxIcon, PdfIcon } from '@/components/icons/document-icons'
8+
import { CsvIcon, DocxIcon, PdfIcon, ZipIcon } from '@/components/icons/document-icons'
99
import { HeroLoopShell } from '@/app/(landing)/components/shared/hero-loop-shell'
1010
import { PLATFORM_LOOP_RESET_FADE_MS } from '@/app/(landing)/components/shared/platform-loop-constants'
11-
import { ZipIcon } from '@/app/(landing)/components/shared/zip-icon'
1211
import { useMotionSafeCycle } from '@/app/(landing)/hooks/use-motion-safe-cycle'
1312

1413
/** Sidebar content for the files hero - a file-heavy team's workspace. */

apps/sim/app/api/table/row-secret-provenance.test.ts

Lines changed: 0 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
*/
44
import { createMockRequest } from '@sim/testing'
55
import { describe, expect, it } from 'vitest'
6-
import { AuthType } from '@/lib/auth/hybrid'
76
import {
87
PRIVATE_SECRET_PROVENANCE_BUNDLE_V1,
98
PRIVATE_SECRET_PROVENANCE_FIELD,
@@ -13,29 +12,16 @@ import {
1312
RESOLVED_SECRET_PROVENANCE_METADATA_V1,
1413
} from '@/lib/execution/private-tool-metadata'
1514
import { TableRowProvenanceError } from '@/lib/table/application/row-secret-provenance'
16-
import { rowDataNameToId } from '@/lib/table/column-keys'
1715
import { tableRowSecretProvenanceSelectionKey } from '@/lib/table/secret-provenance-selection'
18-
import type { RowData } from '@/lib/table/types'
1916
import {
20-
createTableWriteProvenanceTargets,
2117
finalizeTableRowsProvenance,
2218
negotiateTableRowsProvenance,
2319
readTableRowProvenanceEnvelope,
24-
resolveTableWriteSecretProvenance,
2520
} from '@/app/api/table/row-secret-provenance'
2621

2722
const USER_ID = 'user-1'
2823
const WORKSPACE_ID = 'ws-1'
2924

30-
/** Mirrors the internal-JWT wire translator: names → ids, unknown names dropped. */
31-
const ID_BY_NAME = new Map([
32-
['email', 'col_email'],
33-
['company', 'col_company'],
34-
])
35-
36-
const translateNames = (data: RowData): RowData => rowDataNameToId(data, ID_BY_NAME)
37-
const translateIdentity = (data: RowData): RowData => data
38-
3925
function traceProvenance() {
4026
return {
4127
version: 1,
@@ -59,221 +45,6 @@ function bundleRequest(selectionKeys: string[]) {
5945
return { request, payload }
6046
}
6147

62-
describe('createTableWriteProvenanceTargets', () => {
63-
it('maps column names to their storage ids', () => {
64-
const targets = createTableWriteProvenanceTargets([{ email: 'a@b.c' }], translateNames)
65-
66-
expect(targets).toEqual([
67-
{
68-
selectionKey: tableRowSecretProvenanceSelectionKey(0, 'email'),
69-
rowKey: '0',
70-
columnId: 'col_email',
71-
},
72-
])
73-
})
74-
75-
it('returns a null column id for a column the wire translator drops', () => {
76-
const targets = createTableWriteProvenanceTargets(
77-
[{ email: 'a@b.c', notAColumn: 'x' }],
78-
translateNames
79-
)
80-
81-
expect(targets).toHaveLength(2)
82-
expect(targets[0].columnId).toBe('col_email')
83-
expect(targets[1]).toEqual({
84-
selectionKey: tableRowSecretProvenanceSelectionKey(0, 'notAColumn'),
85-
rowKey: '0',
86-
columnId: null,
87-
})
88-
})
89-
90-
it('keeps one target per submitted column so bundle selections stay paired', () => {
91-
const targets = createTableWriteProvenanceTargets(
92-
[{ notAColumn: 'x', alsoNotAColumn: 'y' }],
93-
translateNames
94-
)
95-
96-
expect(targets.map((target) => target.columnId)).toEqual([null, null])
97-
})
98-
99-
it('passes column ids through for identity (session) translation', () => {
100-
const targets = createTableWriteProvenanceTargets([{ col_email: 'a@b.c' }], translateIdentity)
101-
102-
expect(targets[0].columnId).toBe('col_email')
103-
})
104-
105-
it('keys targets by row index across multiple rows', () => {
106-
const targets = createTableWriteProvenanceTargets(
107-
[{ email: 'a@b.c' }, { company: 'Acme' }],
108-
translateNames
109-
)
110-
111-
expect(targets.map((target) => target.rowKey)).toEqual(['0', '1'])
112-
expect(targets[1].selectionKey).toBe(tableRowSecretProvenanceSelectionKey(1, 'company'))
113-
})
114-
})
115-
116-
describe('resolveTableWriteSecretProvenance', () => {
117-
it('records no provenance for a dropped column on an unsupported session write', () => {
118-
const rows = [{ email: 'a@b.c', notAColumn: 'x' }]
119-
const result = resolveTableWriteSecretProvenance({
120-
request: createMockRequest('POST', { rows }),
121-
payload: { rows },
122-
authType: AuthType.SESSION,
123-
userId: USER_ID,
124-
workspaceId: WORKSPACE_ID,
125-
targets: createTableWriteProvenanceTargets(rows, translateNames),
126-
rowKeys: ['0'],
127-
})
128-
129-
expect(result.success).toBe(true)
130-
if (!result.success) return
131-
expect(Object.keys(result.provenanceByRowKey?.['0'].columns ?? {})).toEqual(['col_email'])
132-
})
133-
134-
it('accepts a complete bundle that covers a dropped column', () => {
135-
const rows = [{ email: 'a@b.c', notAColumn: 'x' }]
136-
const { request, payload } = bundleRequest([
137-
tableRowSecretProvenanceSelectionKey(0, 'email'),
138-
tableRowSecretProvenanceSelectionKey(0, 'notAColumn'),
139-
])
140-
141-
const result = resolveTableWriteSecretProvenance({
142-
request,
143-
payload,
144-
authType: AuthType.INTERNAL_JWT,
145-
userId: USER_ID,
146-
workspaceId: WORKSPACE_ID,
147-
targets: createTableWriteProvenanceTargets(rows, translateNames),
148-
rowKeys: ['0'],
149-
})
150-
151-
expect(result.success).toBe(true)
152-
if (!result.success) return
153-
expect(Object.keys(result.provenanceByRowKey?.['0'].columns ?? {})).toEqual(['col_email'])
154-
})
155-
156-
it('stores provenance for a fully translatable bundle', () => {
157-
const rows = [{ email: 'a@b.c', company: 'Acme' }]
158-
const { request, payload } = bundleRequest([
159-
tableRowSecretProvenanceSelectionKey(0, 'email'),
160-
tableRowSecretProvenanceSelectionKey(0, 'company'),
161-
])
162-
163-
const result = resolveTableWriteSecretProvenance({
164-
request,
165-
payload,
166-
authType: AuthType.INTERNAL_JWT,
167-
userId: USER_ID,
168-
workspaceId: WORKSPACE_ID,
169-
targets: createTableWriteProvenanceTargets(rows, translateNames),
170-
rowKeys: ['0'],
171-
})
172-
173-
expect(result.success).toBe(true)
174-
if (!result.success) return
175-
expect(Object.keys(result.provenanceByRowKey?.['0'].columns ?? {}).sort()).toEqual([
176-
'col_company',
177-
'col_email',
178-
])
179-
})
180-
181-
it('rejects a bundle whose selection matches no submitted column', () => {
182-
const rows = [{ email: 'a@b.c' }]
183-
const { request, payload } = bundleRequest([tableRowSecretProvenanceSelectionKey(0, 'company')])
184-
185-
const result = resolveTableWriteSecretProvenance({
186-
request,
187-
payload,
188-
authType: AuthType.INTERNAL_JWT,
189-
userId: USER_ID,
190-
workspaceId: WORKSPACE_ID,
191-
targets: createTableWriteProvenanceTargets(rows, translateNames),
192-
rowKeys: ['0'],
193-
})
194-
195-
expect(result.success).toBe(false)
196-
})
197-
198-
it('accepts a different source user in the authorized destination workspace', () => {
199-
const rows = [{ email: 'a@b.c' }]
200-
const payload = {
201-
[PRIVATE_SECRET_PROVENANCE_FIELD]: {
202-
version: 1,
203-
complete: true,
204-
selections: [
205-
{
206-
key: tableRowSecretProvenanceSelectionKey(0, 'email'),
207-
provenance: {
208-
...traceProvenance(),
209-
scope: { userId: 'someone-else', workspaceId: WORKSPACE_ID },
210-
},
211-
},
212-
],
213-
},
214-
}
215-
216-
const result = resolveTableWriteSecretProvenance({
217-
request: createMockRequest('POST', payload, {
218-
[PRIVATE_SECRET_PROVENANCE_HEADER]: PRIVATE_SECRET_PROVENANCE_BUNDLE_V1,
219-
}),
220-
payload,
221-
authType: AuthType.INTERNAL_JWT,
222-
userId: USER_ID,
223-
workspaceId: WORKSPACE_ID,
224-
targets: createTableWriteProvenanceTargets(rows, translateNames),
225-
rowKeys: ['0'],
226-
})
227-
228-
expect(result.success).toBe(true)
229-
if (!result.success) return
230-
expect(result.provenanceByRowKey?.['0'].columns.col_email).toMatchObject({
231-
scope: { userId: 'someone-else', workspaceId: WORKSPACE_ID },
232-
})
233-
})
234-
235-
it('rejects a bundle whose selection comes from another workspace', () => {
236-
const rows = [{ email: 'a@b.c' }]
237-
const payload = {
238-
[PRIVATE_SECRET_PROVENANCE_FIELD]: {
239-
version: 1,
240-
complete: true,
241-
selections: [
242-
{
243-
key: tableRowSecretProvenanceSelectionKey(0, 'email'),
244-
provenance: {
245-
...traceProvenance(),
246-
scope: { userId: USER_ID, workspaceId: 'another-workspace' },
247-
},
248-
},
249-
],
250-
},
251-
}
252-
253-
const result = resolveTableWriteSecretProvenance({
254-
request: createMockRequest('POST', payload, {
255-
[PRIVATE_SECRET_PROVENANCE_HEADER]: PRIVATE_SECRET_PROVENANCE_BUNDLE_V1,
256-
}),
257-
payload,
258-
authType: AuthType.INTERNAL_JWT,
259-
userId: USER_ID,
260-
workspaceId: WORKSPACE_ID,
261-
targets: createTableWriteProvenanceTargets(rows, translateNames),
262-
rowKeys: ['0'],
263-
})
264-
265-
expect(result.success).toBe(false)
266-
})
267-
})
268-
269-
/**
270-
* The transport half of the envelope, used by the migrated single-row routes.
271-
*
272-
* These are the only cover these helpers have: the route tests assert `mapInput`
273-
* and `present`, so each helper could be replaced by a constant without a route
274-
* test noticing — and a constant `readTableRowProvenanceEnvelope` would silently
275-
* downgrade every executor write from a stamped bundle to untracked.
276-
*/
27748
describe('readTableRowProvenanceEnvelope', () => {
27849
it('reports no envelope when the caller sent none', () => {
27950
const request = createMockRequest('PATCH', { data: {} })

0 commit comments

Comments
 (0)