Skip to content

Commit 7c247da

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(oracledb): address review feedback
1 parent 7f38877 commit 7c247da

8 files changed

Lines changed: 64 additions & 13 deletions

File tree

apps/docs/components/icons.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9276,7 +9276,7 @@ export function NewRelicIcon(props: SVGProps<SVGSVGElement>) {
92769276
)
92779277
}
92789278

9279-
export function NetSuiteIcon(props: SVGProps<SVGSVGElement>) {
9279+
function OracleOvalMark(props: SVGProps<SVGSVGElement>) {
92809280
return (
92819281
<svg {...props} viewBox='0 0 93.9 59.4' xmlns='http://www.w3.org/2000/svg'>
92829282
<path
@@ -9287,8 +9287,12 @@ export function NetSuiteIcon(props: SVGProps<SVGSVGElement>) {
92879287
)
92889288
}
92899289

9290+
export function NetSuiteIcon(props: SVGProps<SVGSVGElement>) {
9291+
return <OracleOvalMark {...props} />
9292+
}
9293+
92909294
export function OracleDatabaseIcon(props: SVGProps<SVGSVGElement>) {
9291-
return <NetSuiteIcon {...props} />
9295+
return <OracleOvalMark {...props} />
92929296
}
92939297

92949298
export function WizaIcon(props: SVGProps<SVGSVGElement>) {

apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ const AUTH_STEP: Record<AuthType, (name: string) => string> = {
110110
`Connect your ${name} account with one-click OAuth, with no credentials to copy.`,
111111
'api-key': (name) =>
112112
`Paste your ${name} API key to authenticate. You can find it in your ${name} account settings.`,
113-
none: () => 'No authentication is needed, so the block works as soon as you drop it in.',
113+
none: () => 'Configure the block directly; no separate account connection is needed.',
114114
}
115115

116116
/** Human-readable catalog refresh date for the visible last-updated line. */
@@ -503,7 +503,7 @@ export default async function IntegrationPage({ params }: { params: Promise<{ sl
503503
? `${name} connects with one-click OAuth.`
504504
: authType === 'api-key'
505505
? `${name} connects with an API key.`
506-
: `${name} requires no authentication.`}{' '}
506+
: `${name} is configured directly in its workflow block.`}{' '}
507507
Free to start at sim.ai.
508508
</p>
509509

@@ -658,7 +658,7 @@ export default async function IntegrationPage({ params }: { params: Promise<{ sl
658658
? `Open your workspace, drag ${articleFor(name)} ${name} block onto the workflow builder, and connect your account with one-click OAuth.`
659659
: authType === 'api-key'
660660
? `Open your workspace, drag ${articleFor(name)} ${name} block onto the workflow builder, and paste in your ${name} API key.`
661-
: `Open your workspace, drag ${articleFor(name)} ${name} block onto the workflow builder. No authentication is needed.`,
661+
: `Open your workspace, drag ${articleFor(name)} ${name} block onto the workflow builder, and configure its inputs directly. No separate account connection is needed.`,
662662
},
663663
{
664664
step: '03',

apps/sim/components/icons.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9276,7 +9276,7 @@ export function NewRelicIcon(props: SVGProps<SVGSVGElement>) {
92769276
)
92779277
}
92789278

9279-
export function NetSuiteIcon(props: SVGProps<SVGSVGElement>) {
9279+
function OracleOvalMark(props: SVGProps<SVGSVGElement>) {
92809280
return (
92819281
<svg {...props} viewBox='0 0 93.9 59.4' xmlns='http://www.w3.org/2000/svg'>
92829282
<path
@@ -9287,8 +9287,12 @@ export function NetSuiteIcon(props: SVGProps<SVGSVGElement>) {
92879287
)
92889288
}
92899289

9290+
export function NetSuiteIcon(props: SVGProps<SVGSVGElement>) {
9291+
return <OracleOvalMark {...props} />
9292+
}
9293+
92909294
export function OracleDatabaseIcon(props: SVGProps<SVGSVGElement>) {
9291-
return <NetSuiteIcon {...props} />
9295+
return <OracleOvalMark {...props} />
92929296
}
92939297

92949298
export function WizaIcon(props: SVGProps<SVGSVGElement>) {

apps/sim/lib/internal/oracledb/public-contract.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
oracleQueryTool,
1212
oracleUpdateTool,
1313
} from '@/tools/oracledb'
14+
import type { OracleQueryParams } from '@/tools/oracledb/types'
1415

1516
const CONNECTION_FIELDS = [
1617
'host',
@@ -115,6 +116,23 @@ describe('Oracle Database public integration contract', () => {
115116
})
116117
})
117118

119+
it('accepts the defaulted connection fields as optional in the exported contract', () => {
120+
const minimal = {
121+
host: 'db.example.com',
122+
serviceName: 'FREEPDB1',
123+
username: 'application',
124+
password: 'secret',
125+
query: 'SELECT 1 FROM DUAL',
126+
} satisfies OracleQueryParams
127+
128+
expect(oracleQueryTool.operation.input(minimal)).toMatchObject({
129+
port: 1521,
130+
protocol: 'tcp',
131+
connectionType: 'serviceName',
132+
connectionTimeout: 15000,
133+
})
134+
})
135+
118136
it('selects exactly one service identifier and only forwards wallets for TCPS', () => {
119137
const service = buildParams({
120138
...connection,

apps/sim/lib/internal/oracledb/query.test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,27 @@ describe('Oracle SQL validation and builders', () => {
129129
).toThrow('always-true')
130130
})
131131

132-
it('accepts ordinary function, range, and q-quoted predicates', () => {
132+
it('rejects unbound placeholders in structured WHERE clauses', () => {
133+
expect(() => buildOracleUpdate(undefined, 'Users', { active: 0 }, 'id = :b1')).toThrow(
134+
'bind placeholders'
135+
)
136+
expect(() => buildOracleDelete(undefined, 'Users', 'id = :id')).toThrow('bind placeholders')
137+
})
138+
139+
it('accepts ordinary function, range, quoted-colon, and q-quoted predicates', () => {
133140
expect(() =>
134-
buildOracleDelete(undefined, 'Users', "UPPER(name) = UPPER(q'[Ada]') AND id BETWEEN 1 AND 10")
141+
buildOracleDelete(
142+
undefined,
143+
'Users',
144+
"UPPER(name) = UPPER(q'[Ada]') AND note = 'a:b' AND id BETWEEN 1 AND 10"
145+
)
146+
).not.toThrow()
147+
expect(() =>
148+
buildOracleDelete(
149+
undefined,
150+
'Users',
151+
`JSON_OBJECT('id':(id) RETURNING VARCHAR2) = '{"id":42}'`
152+
)
135153
).not.toThrow()
136154
})
137155
})

apps/sim/lib/internal/oracledb/query.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,13 @@ export function validateOracleWhere(where: string): ValidationResult {
328328
if (scan.error) return invalid(scan.error)
329329
if (scan.hasComment) return invalid('WHERE clause cannot contain SQL comments or hints')
330330
if (scan.semicolonIndex !== undefined) return invalid('WHERE clause cannot contain a semicolon')
331+
// Oracle also uses `:` in JSON_OBJECT; a parenthesized value is the documented
332+
// form that keeps client drivers from interpreting the separator as a bind.
333+
if (/:(?!\s*\()/.test(scan.masked)) {
334+
return invalid(
335+
'Structured WHERE clauses cannot contain bind placeholders; use literal predicates or Execute with named binds'
336+
)
337+
}
331338
if (ORACLE_WHERE_MASKED_PATTERNS.some((pattern) => pattern.test(scan.masked))) {
332339
return invalid('WHERE clause contains a disallowed or always-true expression')
333340
}

apps/sim/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "Apache-2.0",
66
"engines": {
77
"bun": ">=1.3.14",
8-
"node": ">=22.19.0"
8+
"node": ">=24.0.0 <25.0.0"
99
},
1010
"scripts": {
1111
"dev": "bun run dev:cache:cap && next dev --port 3000",

apps/sim/tools/oracledb/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export type OracleBinds = Record<string, OracleBindScalar>
88
/** Connection fields accepted by every Oracle Database tool. */
99
export interface OracleConnectionConfig {
1010
host: string
11-
port: number
12-
protocol: OracleProtocol
13-
connectionType: OracleConnectionType
11+
port?: number
12+
protocol?: OracleProtocol
13+
connectionType?: OracleConnectionType
1414
serviceName?: string
1515
sid?: string
1616
username: string

0 commit comments

Comments
 (0)