Skip to content

Commit 8ee9750

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(oci-functions): normalize native block optional parameters
1 parent 5eb58c4 commit 8ee9750

2 files changed

Lines changed: 55 additions & 1 deletion

File tree

‎apps/sim/blocks/blocks/oci_functions.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,13 @@ export const OciFunctionsBlock: BlockConfig<OciFunctionsResponse> = {
611611
? undefined
612612
: params.ociRegion
613613
for (const key of OPERATION_PARAMS[selected]) {
614-
result[key] = params[key] === '' && key !== 'payload' ? undefined : params[key]
614+
result[key] =
615+
(params[key] === '' && key !== 'payload') ||
616+
(params[key] === null &&
617+
(selected === 'list_applications' || selected === 'list_functions') &&
618+
['displayName', 'id', 'lifecycleState', 'page', 'sortBy', 'sortOrder'].includes(key))
619+
? undefined
620+
: params[key]
615621
}
616622
if (
617623
'configuration' in result &&

‎apps/sim/lib/internal/oci-functions/execute-tool.test.ts‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ vi.mock('@/app/api/files/authorization', () => ({ assertToolFileAccess: vi.fn()
2323
import { OciClientError } from '@/lib/internal/oci/errors'
2424
import { executeOciFunctionsTool } from '@/lib/internal/oci-functions/execute-tool'
2525
import type { InternalToolOperationCall } from '@/lib/internal/tool-operations/types'
26+
import { OciFunctionsBlock } from '@/blocks/blocks/oci_functions'
27+
import { ociFunctionsListApplicationsTool } from '@/tools/oci_functions/list_applications'
2628

2729
function request(overrides: Partial<InternalToolOperationCall> = {}): InternalToolOperationCall {
2830
return {
@@ -58,6 +60,52 @@ beforeEach(() => {
5860
})
5961

6062
describe('OCI Functions credential execution boundary', () => {
63+
it.each([null, '', undefined, 'application-name'])(
64+
'normalizes optional list filters through the native merge (%s)',
65+
async (displayName) => {
66+
mocks.request.mockResolvedValue({
67+
status: 200,
68+
headers: {},
69+
body: new TextEncoder().encode('[]'),
70+
})
71+
const raw = {
72+
operation: 'list_applications',
73+
oauthCredential: 'supplied-pointer',
74+
compartmentId: 'compartment',
75+
displayName,
76+
page: null,
77+
sortBy: null,
78+
sortOrder: null,
79+
lifecycleState: null,
80+
id: null,
81+
}
82+
const params = { ...raw, ...OciFunctionsBlock.tools.config?.params?.(raw) }
83+
const result = await executeOciFunctionsTool(
84+
request({
85+
toolId: ociFunctionsListApplicationsTool.id,
86+
input: ociFunctionsListApplicationsTool.operation.input(params),
87+
})
88+
)
89+
expect(result.status).toBe(200)
90+
expect(mocks.request.mock.lastCall?.[0].queryPairs).toEqual([
91+
['compartmentId', 'compartment'],
92+
['limit', '10'],
93+
...(displayName ? [['displayName', displayName]] : []),
94+
])
95+
}
96+
)
97+
98+
it.each([null, false, 0])('preserves meaningful invocation JSON payload %s', (payload) => {
99+
const raw = { operation: 'invoke', payloadType: 'json', payload, dryRun: false }
100+
const params = { ...raw, ...OciFunctionsBlock.tools.config?.params?.(raw) }
101+
expect(params.payload).toBe(payload)
102+
expect(params.dryRun).toBe(false)
103+
})
104+
105+
it('preserves an empty text invocation payload', () => {
106+
const raw = { operation: 'invoke', payloadType: 'text', payload: '' }
107+
expect({ ...raw, ...OciFunctionsBlock.tools.config?.params?.(raw) }.payload).toBe('')
108+
})
61109
it('authorizes the supplied pointer but passes only the resolved ID and trusted context into the foundation', async () => {
62110
const result = await executeOciFunctionsTool(
63111
request({

0 commit comments

Comments
 (0)