Skip to content

Commit 9f595aa

Browse files
committed
scrub string values, lint, cleanup
1 parent e1d12c4 commit 9f595aa

39 files changed

Lines changed: 283 additions & 200 deletions

apps/dashboard/e2e/global-setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default async function globalSetup(_config: FullConfig) {
1111

1212
const resolver = createConnectorResolver({
1313
sources: { stripe: sourceStripe },
14-
destinations: { postgres: destinationPostgres, 'google_sheets': destinationGoogleSheets },
14+
destinations: { postgres: destinationPostgres, google_sheets: destinationGoogleSheets },
1515
})
1616

1717
const app = createApp(resolver)

apps/engine/src/__tests__/stripe-to-postgres.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,9 @@ describe('engine read → write', () => {
187187

188188
for (const r of records) {
189189
expect(r.stream).toBe(targetStream)
190-
expect((r as any).data).toBeDefined()
191-
expect((r as any).data.id).toBeDefined()
190+
const data = (r as Record<string, unknown>).data as Record<string, unknown>
191+
expect(data).toBeDefined()
192+
expect(data.id).toBeDefined()
192193
}
193194
})
194195

apps/engine/src/api/app.test.ts

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
22
import type { ConnectorResolver, Message, SourceStateMessage } from '../lib/index.js'
33
import { sourceTest, destinationTest, collectFirst } from '../lib/index.js'
44
import { createApp } from './app.js'
5+
import { z } from 'zod'
6+
7+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8+
type Json = Record<string, any>
59

610
// ---------------------------------------------------------------------------
711
// Helpers
@@ -33,7 +37,7 @@ beforeAll(async () => {
3337
'test',
3438
{
3539
connector: sourceTest,
36-
configSchema: {} as any,
40+
configSchema: z.object({}),
3741
rawConfigJsonSchema: srcConfigSchema,
3842
},
3943
],
@@ -44,7 +48,7 @@ beforeAll(async () => {
4448
'test',
4549
{
4650
connector: destinationTest,
47-
configSchema: {} as any,
51+
configSchema: z.object({}),
4852
rawConfigJsonSchema: destConfigSchema,
4953
},
5054
],
@@ -131,7 +135,7 @@ describe('GET /openapi.json', () => {
131135
it('has typed connector schemas in components (auto-generated from Zod)', async () => {
132136
const app = await createApp(resolver)
133137
const res = await app.request('/openapi.json')
134-
const spec = (await res.json()) as any
138+
const spec = (await res.json()) as Json
135139
const schemaNames = Object.keys(spec.components?.schemas ?? {})
136140

137141
expect(schemaNames).toContain('SourceTestConfig')
@@ -150,7 +154,7 @@ describe('GET /openapi.json', () => {
150154
it('defines NDJSON message schemas with discriminated unions', async () => {
151155
const app = await createApp(resolver)
152156
const res = await app.request('/openapi.json')
153-
const spec = (await res.json()) as any
157+
const spec = (await res.json()) as Json
154158
const schemas = spec.components.schemas
155159

156160
// Individual message types — zod-openapi uses const for z.literal() in OpenAPI 3.1
@@ -187,18 +191,18 @@ describe('GET /openapi.json', () => {
187191
it('ControlMessage source_config/destination_config reference typed connector schemas', async () => {
188192
const app = await createApp(resolver)
189193
const res = await app.request('/openapi.json')
190-
const spec = (await res.json()) as any
194+
const spec = (await res.json()) as Json
191195
const control = spec.components.schemas.ControlMessage.properties.control
192196

193197
const sourceVariant = control.oneOf.find(
194-
(v: any) => v.properties?.control_type?.const === 'source_config'
198+
(v: Json) => v.properties?.control_type?.const === 'source_config'
195199
)
196200
expect(sourceVariant.properties.source_config.$ref).toBe(
197201
'#/components/schemas/SourceTestConfig'
198202
)
199203

200204
const destVariant = control.oneOf.find(
201-
(v: any) => v.properties?.control_type?.const === 'destination_config'
205+
(v: Json) => v.properties?.control_type?.const === 'destination_config'
202206
)
203207
expect(destVariant.properties.destination_config.$ref).toBe(
204208
'#/components/schemas/DestinationTestConfig'
@@ -208,7 +212,7 @@ describe('GET /openapi.json', () => {
208212
it('/setup spec documents 200 response (not 204)', async () => {
209213
const app = await createApp(resolver)
210214
const res = await app.request('/openapi.json')
211-
const spec = (await res.json()) as any
215+
const spec = (await res.json()) as Json
212216
const setupOp = spec.paths['/pipeline_setup']?.post
213217
expect(setupOp).toBeDefined()
214218
expect(setupOp.responses['200']).toBeDefined()
@@ -218,7 +222,7 @@ describe('GET /openapi.json', () => {
218222
it('/write spec documents a required NDJSON request body', async () => {
219223
const app = await createApp(resolver)
220224
const res = await app.request('/openapi.json')
221-
const spec = (await res.json()) as any
225+
const spec = (await res.json()) as Json
222226
const writeOp = spec.paths['/pipeline_write']?.post
223227
expect(writeOp).toBeDefined()
224228
const body = writeOp.requestBody
@@ -232,7 +236,7 @@ describe('GET /openapi.json', () => {
232236
it('/read and /sync spec documents an optional NDJSON request body', async () => {
233237
const app = await createApp(resolver)
234238
const res = await app.request('/openapi.json')
235-
const spec = (await res.json()) as any
239+
const spec = (await res.json()) as Json
236240

237241
for (const path of ['/pipeline_read', '/pipeline_sync'] as const) {
238242
const op = spec.paths[path]?.post
@@ -247,13 +251,13 @@ describe('GET /openapi.json', () => {
247251
it('documents the X-Pipeline header on sync routes', async () => {
248252
const app = await createApp(resolver)
249253
const res = await app.request('/openapi.json')
250-
const spec = (await res.json()) as any
254+
const spec = (await res.json()) as Json
251255

252256
// /check is a POST with X-Pipeline header
253257
const checkOp = spec.paths['/pipeline_check']?.post
254258
expect(checkOp).toBeDefined()
255259
const headerParam = checkOp.parameters?.find(
256-
(p: any) => p.in === 'header' && p.name === 'x-pipeline'
260+
(p: Json) => p.in === 'header' && p.name === 'x-pipeline'
257261
)
258262
expect(headerParam).toBeDefined()
259263
})
@@ -264,9 +268,9 @@ describe('GET /meta/sources', () => {
264268
const app = await createApp(resolver)
265269
const res = await app.request('/meta/sources')
266270
expect(res.status).toBe(200)
267-
const body = (await res.json()) as any
271+
const body = (await res.json()) as Json
268272
expect(Array.isArray(body.items)).toBe(true)
269-
expect(body.items.find((c: any) => c.type === 'test')?.config_schema).toBeDefined()
273+
expect(body.items.find((c: Json) => c.type === 'test')?.config_schema).toBeDefined()
270274
})
271275
})
272276

@@ -275,7 +279,7 @@ describe('GET /meta/sources/:type', () => {
275279
const app = await createApp(resolver)
276280
const res = await app.request('/meta/sources/test')
277281
expect(res.status).toBe(200)
278-
const body = (await res.json()) as any
282+
const body = (await res.json()) as Json
279283
expect(body.config_schema).toBeDefined()
280284
})
281285

@@ -291,9 +295,9 @@ describe('GET /meta/destinations', () => {
291295
const app = await createApp(resolver)
292296
const res = await app.request('/meta/destinations')
293297
expect(res.status).toBe(200)
294-
const body = (await res.json()) as any
298+
const body = (await res.json()) as Json
295299
expect(Array.isArray(body.items)).toBe(true)
296-
expect(body.items.find((c: any) => c.type === 'test')?.config_schema).toBeDefined()
300+
expect(body.items.find((c: Json) => c.type === 'test')?.config_schema).toBeDefined()
297301
})
298302
})
299303

@@ -302,7 +306,7 @@ describe('GET /meta/destinations/:type', () => {
302306
const app = await createApp(resolver)
303307
const res = await app.request('/meta/destinations/test')
304308
expect(res.status).toBe(200)
305-
const body = (await res.json()) as any
309+
const body = (await res.json()) as Json
306310
expect(body.config_schema).toBeDefined()
307311
})
308312

@@ -372,7 +376,7 @@ describe('POST /check', () => {
372376
const events = await readNdjson<Record<string, unknown>>(res)
373377
const statuses = events.filter((e) => e.type === 'connection_status')
374378
expect(statuses).toHaveLength(2)
375-
expect(statuses.every((s: any) => s.connection_status.status === 'succeeded')).toBe(true)
379+
expect(statuses.every((s: Json) => s.connection_status.status === 'succeeded')).toBe(true)
376380
})
377381
})
378382

@@ -436,7 +440,7 @@ describe('POST /read', () => {
436440
'test',
437441
{
438442
connector: sourceTest,
439-
configSchema: {} as any,
443+
configSchema: z.object({}),
440444
rawConfigJsonSchema: srcConfigSchema,
441445
rawInputJsonSchema: inputSchema,
442446
},
@@ -448,7 +452,7 @@ describe('POST /read', () => {
448452
'test',
449453
{
450454
connector: destinationTest,
451-
configSchema: {} as any,
455+
configSchema: z.object({}),
452456
rawConfigJsonSchema: destConfigSchema,
453457
},
454458
],
@@ -459,7 +463,7 @@ describe('POST /read', () => {
459463

460464
it('spec uses SourceInputMessage schema for /read and /sync request body when source has input schema', async () => {
461465
const res = await inputApp.request('/openapi.json')
462-
const spec = (await res.json()) as any
466+
const spec = (await res.json()) as Json
463467

464468
for (const path of ['/pipeline_read', '/pipeline_sync'] as const) {
465469
const body = spec.paths[path]?.post?.requestBody
@@ -794,8 +798,8 @@ describe('POST /source_discover', () => {
794798
const events = await readNdjson<Record<string, unknown>>(res)
795799
const catalogs = events.filter((e) => e.type === 'catalog')
796800
expect(catalogs).toHaveLength(1)
797-
const catalog = (catalogs[0] as any).catalog
798-
const streamNames = catalog.streams.map((s: any) => s.name)
801+
const catalog = (catalogs[0] as Json).catalog
802+
const streamNames = catalog.streams.map((s: Json) => s.name)
799803
expect(streamNames).toContain('customers')
800804
expect(streamNames).toContain('products')
801805
})
@@ -824,7 +828,7 @@ describe('POST /source_discover', () => {
824828
const events = await readNdjson<Record<string, unknown>>(res)
825829
const traces = events.filter((e) => e.type === 'trace')
826830
expect(traces).toHaveLength(1)
827-
const trace = (traces[0] as any).trace
831+
const trace = (traces[0] as Json).trace
828832
expect(trace.trace_type).toBe('error')
829833
expect(trace.error.failure_type).toBe('system_error')
830834
expect(trace.error.message).toContain('network unreachable')

apps/engine/src/api/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const port = Number(process.env.PORT || 3001)
1313
async function main() {
1414
const resolver = await createConnectorResolver({
1515
sources: { stripe: source },
16-
destinations: { postgres: pgDestination, 'google_sheets': sheetsDestination },
16+
destinations: { postgres: pgDestination, google_sheets: sheetsDestination },
1717
})
1818
const app = await createApp(resolver)
1919

apps/engine/src/lib/createSchemas.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,25 @@ export function createConnectorSchemas(resolver: ConnectorResolver) {
7373
return { name, config, variant: z.object({ type: z.literal(name), [name]: config }) }
7474
})
7575

76-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7776
const SourceConfig =
7877
sources.length > 0
7978
? z
80-
.discriminatedUnion('type', sources.map((s) => s.variant) as [any, any, ...any[]])
79+
.discriminatedUnion(
80+
'type',
81+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
82+
sources.map((s) => s.variant) as [any, any, ...any[]]
83+
)
8184
.meta({ id: connectorUnionId('Source') })
8285
: z.object({ type: z.string() }).catchall(z.unknown())
8386

84-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8587
const DestinationConfig =
8688
destinations.length > 0
8789
? z
88-
.discriminatedUnion('type', destinations.map((d) => d.variant) as [any, any, ...any[]])
90+
.discriminatedUnion(
91+
'type',
92+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
93+
destinations.map((d) => d.variant) as [any, any, ...any[]]
94+
)
8995
.meta({ id: connectorUnionId('Destination') })
9096
: z.object({ type: z.string() }).catchall(z.unknown())
9197

apps/engine/src/lib/default-connectors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ export const defaultConnectors: RegisteredConnectors = {
88
sources: { stripe: sourceStripe },
99
destinations: {
1010
postgres: destinationPostgres,
11-
'google_sheets': destinationGoogleSheets,
11+
google_sheets: destinationGoogleSheets,
1212
},
1313
}

apps/engine/src/lib/exec.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { resolveBin } from './resolver.js'
33
import { createSourceFromExec } from './source-exec.js'
44
import { createDestinationFromExec } from './destination-exec.js'
55
import { collectFirst } from '@stripe/sync-protocol'
6-
import type { Message } from '@stripe/sync-protocol'
76

87
// These tests use real connector binaries (built by `pnpm build`).
98

apps/engine/src/lib/pipeline.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ describe('enforceCatalog()', () => {
6464
]
6565
const result = await drain(enforceCatalog(catalog([{ name: 'customers' }]))(toAsync(msgs)))
6666
expect(result).toHaveLength(1)
67-
expect((result[0] as any).record.data).toEqual({ id: 'cus_1', name: 'Alice' })
67+
expect((result[0] as { record: { data: unknown } }).record.data).toEqual({
68+
id: 'cus_1',
69+
name: 'Alice',
70+
})
6871
})
6972

7073
it('filters record fields to json_schema.properties when present', async () => {
@@ -92,7 +95,10 @@ describe('enforceCatalog()', () => {
9295
)(toAsync(msgs))
9396
)
9497
expect(result).toHaveLength(1)
95-
expect((result[0] as any).record.data).toEqual({ id: 'sub_1', status: 'active' })
98+
expect((result[0] as { record: { data: unknown } }).record.data).toEqual({
99+
id: 'sub_1',
100+
status: 'active',
101+
})
96102
})
97103

98104
it('drops unknown internal fields that are not present in the catalog schema', async () => {
@@ -126,7 +132,7 @@ describe('enforceCatalog()', () => {
126132
)(toAsync(msgs))
127133
)
128134
expect(result).toHaveLength(1)
129-
expect((result[0] as any).record.data).toEqual({
135+
expect((result[0] as { record: { data: unknown } }).record.data).toEqual({
130136
id: 'sub_1',
131137
status: 'active',
132138
})
@@ -145,7 +151,7 @@ describe('enforceCatalog()', () => {
145151
]
146152
const result = await drain(enforceCatalog(catalog([{ name: 'subscriptions' }]))(toAsync(msgs)))
147153
expect(result).toHaveLength(1)
148-
expect((result[0] as any).record.data).toEqual({
154+
expect((result[0] as { record: { data: unknown } }).record.data).toEqual({
149155
id: 'sub_1',
150156
status: 'active',
151157
customer: 'cus_1',

apps/engine/src/lib/remote-engine.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { sourceTest, destinationTest, collectFirst } from './index.js'
66
import { createApp } from '../api/app.js'
77
import { createRemoteEngine } from './remote-engine.js'
88
import type { PipelineConfig, SourceStateMessage } from '@stripe/sync-protocol'
9+
import { z } from 'zod'
910

1011
// ---------------------------------------------------------------------------
1112
// Server setup
@@ -54,7 +55,7 @@ beforeAll(async () => {
5455
'test',
5556
{
5657
connector: sourceTest,
57-
configSchema: {} as any,
58+
configSchema: z.object({}),
5859
rawConfigJsonSchema: srcConfigSchema,
5960
},
6061
],
@@ -65,7 +66,7 @@ beforeAll(async () => {
6566
'test',
6667
{
6768
connector: destinationTest,
68-
configSchema: {} as any,
69+
configSchema: z.object({}),
6970
rawConfigJsonSchema: destConfigSchema,
7071
},
7172
],

apps/engine/src/lib/resolver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { existsSync, readFileSync } from 'node:fs'
22
import { dirname, join } from 'node:path'
33
import { z } from 'zod'
4-
import type { Source, Destination, ConnectorSpecification } from '@stripe/sync-protocol'
4+
import type { Source, Destination } from '@stripe/sync-protocol'
55
import { collectFirst } from '@stripe/sync-protocol'
66
import { createSourceFromExec } from './source-exec.js'
77
import { createDestinationFromExec } from './destination-exec.js'

0 commit comments

Comments
 (0)