Skip to content

Commit 873ee10

Browse files
committed
remove hard coded v2 & runtime mapping
1 parent 180d96d commit 873ee10

9 files changed

Lines changed: 28 additions & 64 deletions

File tree

apps/supabase/src/edge-functions/stripe-backfill-worker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const safeSchema = schemaName.replace(/"/g, '""')
2525
const stripeKey = Deno.env.get('STRIPE_SECRET_KEY')!
2626
const pool = new pg.Pool({ connectionString: dbUrl, max: 2 })
2727
const resolved = await resolveOpenApiSpec({ apiVersion: '2020-08-27' })
28-
const registry = buildResourceRegistry(resolved.spec, stripeKey)
28+
const registry = buildResourceRegistry(resolved.spec, stripeKey, resolved.apiVersion)
2929

3030
/** Find the resource config whose tableName matches the given stream name. */
3131
function findConfigByTableName(stream: string) {

apps/supabase/src/edge-functions/stripe-webhook.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Deno.serve(async (req) => {
3737
}
3838

3939
const resolved = await resolveOpenApiSpec({ apiVersion: '2020-08-27' })
40-
const registry = buildResourceRegistry(resolved.spec, stripeKey)
40+
const registry = buildResourceRegistry(resolved.spec, stripeKey, resolved.apiVersion)
4141
const catalog = catalogFromRegistry(registry)
4242

4343
try {

apps/supabase/src/edge-functions/stripe-worker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ const safeSchema = schemaName.replace(/"/g, '""')
2424
const stripeKey = Deno.env.get('STRIPE_SECRET_KEY')!
2525
const pool = new pg.Pool({ connectionString: dbUrl, max: 2 })
2626
const resolved = await resolveOpenApiSpec({ apiVersion: '2020-08-27' })
27-
const registry = buildResourceRegistry(resolved.spec, stripeKey)
27+
const registry = buildResourceRegistry(resolved.spec, stripeKey, resolved.apiVersion)
2828

29-
Deno.serve(async (req) => {
29+
Deno.serve(async (req) => {
3030
// Auth: validate Bearer token against vault worker secret
3131
const authHeader = req.headers.get('Authorization')
3232
if (!authHeader?.startsWith('Bearer ')) {

packages/openapi/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
export type * from './types.js'
22
export { SpecParser, OPENAPI_RESOURCE_TABLE_ALIASES } from './specParser.js'
33
export { OPENAPI_COMPATIBILITY_COLUMNS } from './runtimeMappings.js'
4+
45
export { resolveOpenApiSpec } from './specFetchHelper.js'
56
export {
67
discoverListEndpoints,
78
discoverNestedEndpoints,
89
isV2Path,
910
buildListFn,
1011
buildRetrieveFn,
12+
resolveTableName,
1113
} from './listFnResolver.js'
1214
export type {
1315
ListEndpoint,
@@ -17,4 +19,3 @@ export type {
1719
ListParams,
1820
} from './listFnResolver.js'
1921
export { parsedTableToJsonSchema } from './jsonSchemaConverter.js'
20-
export { RUNTIME_REQUIRED_TABLES } from './runtimeMappings.js'

packages/openapi/listFnResolver.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export type NestedEndpoint = {
3333
supportsPagination: boolean
3434
}
3535

36-
function resolveTableName(resourceId: string, aliases: Record<string, string>): string {
36+
export function resolveTableName(resourceId: string, aliases: Record<string, string>): string {
3737
const alias = aliases[resourceId]
3838
if (alias) return alias
3939
const normalized = resourceId.toLowerCase().replace(/[.]/g, '_')
@@ -206,7 +206,6 @@ export function isV2Path(apiPath: string): boolean {
206206
// ---------------------------------------------------------------------------
207207

208208
const STRIPE_API_BASE = 'https://api.stripe.com'
209-
const V2_STRIPE_VERSION = '2026-02-25.clover'
210209

211210
function authHeaders(apiKey: string): Record<string, string> {
212211
return { Authorization: `Bearer ${apiKey}` }
@@ -216,16 +215,17 @@ function authHeaders(apiKey: string): Record<string, string> {
216215
* Build a callable list function that hits the Stripe HTTP API directly.
217216
* Supports both v1 (has_more pagination) and v2 (next_page_url pagination).
218217
*/
219-
export function buildListFn(apiKey: string, apiPath: string): ListFn {
218+
export function buildListFn(apiKey: string, apiPath: string, apiVersion?: string): ListFn {
220219
if (isV2Path(apiPath)) {
221220
return async (params) => {
222221
const qs = new URLSearchParams()
223222
qs.set('limit', String(Math.min(params.limit ?? 20, 20)))
224223
if (params.starting_after) qs.set('page', params.starting_after)
225224

226-
const response = await fetch(`${STRIPE_API_BASE}${apiPath}?${qs}`, {
227-
headers: { ...authHeaders(apiKey), 'Stripe-Version': V2_STRIPE_VERSION },
228-
})
225+
const headers = authHeaders(apiKey)
226+
if (apiVersion) headers['Stripe-Version'] = apiVersion
227+
228+
const response = await fetch(`${STRIPE_API_BASE}${apiPath}?${qs}`, { headers })
229229
const body = (await response.json()) as {
230230
data: unknown[]
231231
next_page_url?: string | null
@@ -257,12 +257,13 @@ export function buildListFn(apiKey: string, apiPath: string): ListFn {
257257
/**
258258
* Build a callable retrieve function that hits the Stripe HTTP API directly.
259259
*/
260-
export function buildRetrieveFn(apiKey: string, apiPath: string): RetrieveFn {
260+
export function buildRetrieveFn(apiKey: string, apiPath: string, apiVersion?: string): RetrieveFn {
261261
if (isV2Path(apiPath)) {
262262
return async (id) => {
263-
const response = await fetch(`${STRIPE_API_BASE}${apiPath}/${id}`, {
264-
headers: { ...authHeaders(apiKey), 'Stripe-Version': V2_STRIPE_VERSION },
265-
})
263+
const headers = authHeaders(apiKey)
264+
if (apiVersion) headers['Stripe-Version'] = apiVersion
265+
266+
const response = await fetch(`${STRIPE_API_BASE}${apiPath}/${id}`, { headers })
266267
return await response.json()
267268
}
268269
}

packages/openapi/runtimeMappings.ts

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,5 @@
11
import type { ParsedColumn } from './types'
22

3-
/**
4-
* Table names that must exist for runtime sync and webhook processing.
5-
* Includes all default sync objects plus child tables.
6-
*/
7-
export const RUNTIME_REQUIRED_TABLES: ReadonlyArray<string> = [
8-
'products',
9-
'coupons',
10-
'prices',
11-
'plans',
12-
'customers',
13-
'subscriptions',
14-
'subscription_schedules',
15-
'invoices',
16-
'charges',
17-
'setup_intents',
18-
'payment_methods',
19-
'payment_intents',
20-
'tax_ids',
21-
'credit_notes',
22-
'disputes',
23-
'early_fraud_warnings',
24-
'refunds',
25-
'checkout_sessions',
26-
'subscription_items',
27-
'checkout_session_line_items',
28-
'features',
29-
]
30-
313
/**
324
* Overrides for x-resourceId values whose table name cannot be inferred by the
335
* default pluralisation / dot-to-underscore rule in SpecParser.resolveTableName.

packages/openapi/specParser.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ import type {
77
ParsedOpenApiSpec,
88
ScalarType,
99
} from './types'
10-
import {
11-
RUNTIME_REQUIRED_TABLES,
12-
OPENAPI_COMPATIBILITY_COLUMNS,
13-
OPENAPI_RESOURCE_TABLE_ALIASES,
14-
} from './runtimeMappings'
10+
import { OPENAPI_COMPATIBILITY_COLUMNS, OPENAPI_RESOURCE_TABLE_ALIASES } from './runtimeMappings'
1511

1612
const SCHEMA_REF_PREFIX = '#/components/schemas/'
1713

@@ -23,7 +19,7 @@ const RESERVED_COLUMNS = new Set([
2319
'_account_id',
2420
])
2521

26-
export { RUNTIME_REQUIRED_TABLES, OPENAPI_RESOURCE_TABLE_ALIASES }
22+
export { OPENAPI_RESOURCE_TABLE_ALIASES }
2723

2824
type ColumnAccumulator = {
2925
type: ScalarType

packages/source-stripe/src/index.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ import Stripe from 'stripe'
88
import { z } from 'zod'
99
import { buildResourceRegistry } from './resourceRegistry.js'
1010
import { catalogFromRegistry, catalogFromOpenApi } from './catalog.js'
11-
import { resolveOpenApiSpec } from './openapi/specFetchHelper.js'
12-
import {
13-
SpecParser,
14-
RUNTIME_REQUIRED_TABLES,
15-
OPENAPI_RESOURCE_TABLE_ALIASES,
16-
} from './openapi/specParser.js'
11+
import { resolveOpenApiSpec, SpecParser, OPENAPI_RESOURCE_TABLE_ALIASES } from '@stripe/openapi'
1712
import { processStripeEvent } from './process-event.js'
1813
import { processWebhookInput, createInputQueue, startWebhookServer } from './src-webhook.js'
1914
import { listApiBackfill } from './src-list-api.js'
@@ -122,12 +117,11 @@ const source = {
122117
const resolved = await resolveOpenApiSpec({
123118
apiVersion: config.api_version ?? '2020-08-27',
124119
})
125-
const registry = buildResourceRegistry(resolved.spec, config.api_key)
120+
const registry = buildResourceRegistry(resolved.spec, config.api_key, resolved.apiVersion)
126121
try {
127122
const parser = new SpecParser()
128123
const parsed = parser.parse(resolved.spec, {
129124
resourceAliases: OPENAPI_RESOURCE_TABLE_ALIASES,
130-
allowedTables: [...RUNTIME_REQUIRED_TABLES],
131125
})
132126
return catalogFromOpenApi(parsed.tables, registry)
133127
} catch {
@@ -178,7 +172,7 @@ const source = {
178172
const resolved = await resolveOpenApiSpec({
179173
apiVersion: config.api_version ?? '2020-08-27',
180174
})
181-
const registry = buildResourceRegistry(resolved.spec, config.api_key)
175+
const registry = buildResourceRegistry(resolved.spec, config.api_key, resolved.apiVersion)
182176
const streamNames = new Set(catalog.streams.map((s) => s.stream.name))
183177

184178
// Event-driven mode: iterate over incoming webhook inputs

packages/source-stripe/src/resourceRegistry.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
isV2Path,
77
buildListFn,
88
buildRetrieveFn,
9-
RUNTIME_REQUIRED_TABLES as OPENAPI_RUNTIME_REQUIRED_TABLES,
9+
resolveTableName,
10+
OPENAPI_RESOURCE_TABLE_ALIASES,
1011
} from '@stripe/openapi'
1112

1213
/**
@@ -52,8 +53,6 @@ export const REVALIDATE_ENTITIES = [
5253
] as const
5354
export type RevalidateEntityName = (typeof REVALIDATE_ENTITIES)[number]
5455

55-
export const RUNTIME_REQUIRED_TABLES: ReadonlyArray<string> = OPENAPI_RUNTIME_REQUIRED_TABLES
56-
5756
export const RESOURCE_TABLE_NAME_MAP: Record<string, string> = Object.fromEntries(
5857
DEFAULT_SYNC_OBJECTS.map((t) => [t, t])
5958
)
@@ -64,7 +63,8 @@ export const RESOURCE_TABLE_NAME_MAP: Record<string, string> = Object.fromEntrie
6463
*/
6564
export function buildResourceRegistry(
6665
spec: OpenApiSpec,
67-
apiKey: string
66+
apiKey: string,
67+
apiVersion?: string
6868
): Record<string, ResourceConfig> {
6969
const endpoints = discoverListEndpoints(spec)
7070
const nestedEndpoints = discoverNestedEndpoints(spec, endpoints)
@@ -91,8 +91,8 @@ export function buildResourceRegistry(
9191
supportsLimit: endpoint.supportsLimit,
9292
sync: true,
9393
dependencies: [],
94-
listFn: buildListFn(apiKey, endpoint.apiPath),
95-
retrieveFn: buildRetrieveFn(apiKey, endpoint.apiPath),
94+
listFn: buildListFn(apiKey, endpoint.apiPath, apiVersion),
95+
retrieveFn: buildRetrieveFn(apiKey, endpoint.apiPath, apiVersion),
9696
nestedResources: children.length > 0 ? children : undefined,
9797
}
9898
registry[tableName] = config

0 commit comments

Comments
 (0)