From 85f181abeb0960c35f05446636d6151182432f23 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 6 May 2026 22:17:10 -0700 Subject: [PATCH] fix(revenuecat): address PR review feedback - create_purchase: wrap JSON.parse(attributes) with try/catch and clear error - update_subscriber_attributes: drop subscriber output (endpoint returns empty body) and guard JSON.parse on attributes - grant_entitlement: throw when both duration and endTimeMs are provided, matching defer_google_subscription behavior --- apps/sim/tools/revenuecat/create_purchase.ts | 11 ++++++-- .../sim/tools/revenuecat/grant_entitlement.ts | 3 ++ apps/sim/tools/revenuecat/types.ts | 1 - .../update_subscriber_attributes.ts | 28 ++++++++----------- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/apps/sim/tools/revenuecat/create_purchase.ts b/apps/sim/tools/revenuecat/create_purchase.ts index 75b58c1d2a..5794acbc83 100644 --- a/apps/sim/tools/revenuecat/create_purchase.ts +++ b/apps/sim/tools/revenuecat/create_purchase.ts @@ -135,8 +135,15 @@ export const revenuecatCreatePurchaseTool: ToolConfig< body.introductory_price = params.introductoryPrice } if (params.attributes !== undefined && params.attributes !== '') { - body.attributes = - typeof params.attributes === 'string' ? JSON.parse(params.attributes) : params.attributes + if (typeof params.attributes === 'string') { + try { + body.attributes = JSON.parse(params.attributes) + } catch { + throw new Error('attributes must be a valid JSON object') + } + } else { + body.attributes = params.attributes + } } if (params.updatedAtMs !== undefined) body.updated_at_ms = params.updatedAtMs return body diff --git a/apps/sim/tools/revenuecat/grant_entitlement.ts b/apps/sim/tools/revenuecat/grant_entitlement.ts index d17946b7d8..e61d536363 100644 --- a/apps/sim/tools/revenuecat/grant_entitlement.ts +++ b/apps/sim/tools/revenuecat/grant_entitlement.ts @@ -70,6 +70,9 @@ export const revenuecatGrantEntitlementTool: ToolConfig< if (!params.duration && params.endTimeMs === undefined) { throw new Error('Provide either duration or endTimeMs to grant a promotional entitlement') } + if (params.duration && params.endTimeMs !== undefined) { + throw new Error('Provide only one of duration or endTimeMs — they cannot be used together') + } const body: Record = {} if (params.endTimeMs !== undefined) body.end_time_ms = params.endTimeMs else if (params.duration) body.duration = params.duration diff --git a/apps/sim/tools/revenuecat/types.ts b/apps/sim/tools/revenuecat/types.ts index 4376dacaf2..9f3520450d 100644 --- a/apps/sim/tools/revenuecat/types.ts +++ b/apps/sim/tools/revenuecat/types.ts @@ -399,7 +399,6 @@ export interface UpdateSubscriberAttributesResponse extends ToolResponse { output: { updated: boolean app_user_id: string - subscriber: RevenueCatSubscriber } } diff --git a/apps/sim/tools/revenuecat/update_subscriber_attributes.ts b/apps/sim/tools/revenuecat/update_subscriber_attributes.ts index 0603d2b77f..83bb0e7778 100644 --- a/apps/sim/tools/revenuecat/update_subscriber_attributes.ts +++ b/apps/sim/tools/revenuecat/update_subscriber_attributes.ts @@ -2,12 +2,7 @@ import type { UpdateSubscriberAttributesParams, UpdateSubscriberAttributesResponse, } from '@/tools/revenuecat/types' -import { - extractSubscriber, - SUBSCRIBER_OUTPUT, - shapeSubscriber, - throwIfRevenueCatError, -} from '@/tools/revenuecat/types' +import { throwIfRevenueCatError } from '@/tools/revenuecat/types' import type { ToolConfig } from '@/tools/types' export const revenuecatUpdateSubscriberAttributesTool: ToolConfig< @@ -51,22 +46,27 @@ export const revenuecatUpdateSubscriberAttributesTool: ToolConfig< 'Content-Type': 'application/json', }), body: (params) => { - const attributes = - typeof params.attributes === 'string' ? JSON.parse(params.attributes) : params.attributes + let attributes: unknown + if (typeof params.attributes === 'string') { + try { + attributes = JSON.parse(params.attributes) + } catch { + throw new Error('attributes must be a valid JSON object') + } + } else { + attributes = params.attributes + } return { attributes } }, }, transformResponse: async (response, params) => { await throwIfRevenueCatError(response) - const data = await response.json().catch(() => ({})) - const subscriber = shapeSubscriber(extractSubscriber(data)) return { success: true, output: { updated: true, - app_user_id: subscriber.original_app_user_id || (params?.appUserId ?? ''), - subscriber, + app_user_id: params?.appUserId ?? '', }, } }, @@ -80,9 +80,5 @@ export const revenuecatUpdateSubscriberAttributesTool: ToolConfig< type: 'string', description: 'The app user ID of the updated subscriber', }, - subscriber: { - ...SUBSCRIBER_OUTPUT, - description: 'The updated subscriber object after applying the attribute changes', - }, }, }