@feelflow/ffid-sdk 8.0.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -223,18 +223,16 @@ function mapUserinfoSubscriptionToSession(userinfo, serviceCode) {
223
223
  ];
224
224
  }
225
225
  var JWKS_ENDPOINT = "/.well-known/jwks.json";
226
- var LEGACY_JWT_ISSUER = "https://id.feelflow.net";
227
226
  var JWT_ALGORITHM = "ES256";
228
227
  var JWT_CLOCK_TOLERANCE_SECONDS = 30;
229
- function resolveAcceptedIssuers(baseUrl) {
230
- const deployedOrigin = new URL(baseUrl).origin;
231
- return deployedOrigin === LEGACY_JWT_ISSUER ? [LEGACY_JWT_ISSUER] : [deployedOrigin, LEGACY_JWT_ISSUER];
228
+ function resolveAcceptedIssuer(baseUrl) {
229
+ return new URL(baseUrl).origin;
232
230
  }
233
231
  function createJwtVerifier(deps) {
234
232
  const { baseUrl, serviceCode, logger, createError, errorCodes } = deps;
235
233
  const jwksUrl = new URL(JWKS_ENDPOINT, baseUrl);
236
234
  const jwks = jose.createRemoteJWKSet(jwksUrl);
237
- const acceptedIssuers = resolveAcceptedIssuers(baseUrl);
235
+ const acceptedIssuer = resolveAcceptedIssuer(baseUrl);
238
236
  async function verifyJwt(accessToken) {
239
237
  if (!accessToken || !accessToken.trim()) {
240
238
  return {
@@ -247,7 +245,7 @@ function createJwtVerifier(deps) {
247
245
  try {
248
246
  const { payload } = await jose.jwtVerify(accessToken, jwks, {
249
247
  algorithms: [JWT_ALGORITHM],
250
- issuer: acceptedIssuers,
248
+ issuer: acceptedIssuer,
251
249
  audience: serviceCode,
252
250
  clockTolerance: JWT_CLOCK_TOLERANCE_SECONDS
253
251
  });
@@ -1373,7 +1371,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
1373
1371
  };
1374
1372
 
1375
1373
  // src/client/version-check.ts
1376
- var SDK_VERSION = "8.0.0";
1374
+ var SDK_VERSION = "9.0.0";
1377
1375
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1378
1376
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1379
1377
  function sdkHeaders() {
@@ -1,5 +1,5 @@
1
- import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-BaEmw7jP.cjs';
2
- export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAllowedLogoMimeType, n as FFIDAssignableMemberRole, o as FFIDCacheConfig, p as FFIDCatalogPublication, q as FFIDCatalogPublicationStatus, r as FFIDClient, s as FFIDCompanySizeCode, t as FFIDConfig, u as FFIDIndustryCode, v as FFIDListMembersResponse, w as FFIDListingConsentInput, x as FFIDLogoWallEntry, y as FFIDLogoWallResponse, z as FFIDMemberRole, A as FFIDOrganization, B as FFIDOrganizationLogoUploadResponse, C as FFIDOrganizationMember, D as FFIDOrganizationProfile, E as FFIDOrganizationProfileErrorCode, G as FFIDOrganizationProfileResponse, H as FFIDOtpSendResponse, I as FFIDOtpVerifyResponse, J as FFIDPasswordResetConfirmResponse, K as FFIDPasswordResetResponse, L as FFIDPasswordResetVerifyResponse, M as FFIDProfileCallOptions, N as FFIDProvisionMemberPlan, O as FFIDProvisionMemberPlanStatus, P as FFIDProvisionMemberResult, Q as FFIDProvisionMemberStatus, R as FFIDProvisionOrganizationDryRun, S as FFIDProvisionOrganizationMemberInput, T as FFIDProvisionOrganizationOutcome, U as FFIDProvisionOrganizationParams, V as FFIDProvisionOrganizationResponse, W as FFIDProvisionUserDryRun, X as FFIDProvisionUserOutcome, Y as FFIDProvisionUserParams, Z as FFIDProvisionUserProfileInput, _ as FFIDProvisionUserResponse, $ as FFIDProvisionedOrganization, a0 as FFIDProvisionedUser, a1 as FFIDPublishedPlan, a2 as FFIDRemoveMemberResponse, a3 as FFIDResetSessionResponse, a4 as FFIDSubscription, a5 as FFIDUpdateMemberRoleResponse, a6 as FFIDUpdateUserProfileRequest, a7 as FFIDUploadOrganizationLogoParams, a8 as FFIDUpsertOrganizationProfileParams, a9 as FFIDUpsertOrganizationProfileRequest, aa as FFIDUser, ab as FFIDUserProfile, ac as FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, ad as FFID_CATALOG_ENVIRONMENTS, ae as FFID_CATALOG_PUBLICATION_STATUSES, af as FFID_COMPANY_SIZE_CODES, ag as FFID_INDUSTRY_CODES, ah as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, ai as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, aj as FFID_ORGANIZATION_PROFILE_ERROR_CODES, ak as TokenData, al as TokenStore, am as createFFIDClient, an as createTokenStore } from '../ffid-client-BaEmw7jP.cjs';
1
+ import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-6aLs9Fqc.cjs';
2
+ export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAllowedLogoMimeType, n as FFIDAssignableMemberRole, o as FFIDCacheConfig, p as FFIDCatalogPublication, q as FFIDCatalogPublicationStatus, r as FFIDClient, s as FFIDCompanySizeCode, t as FFIDConfig, u as FFIDIndustryCode, v as FFIDListMembersResponse, w as FFIDListingConsentInput, x as FFIDLogoWallEntry, y as FFIDLogoWallResponse, z as FFIDMemberRole, A as FFIDOrganization, B as FFIDOrganizationLogoUploadResponse, C as FFIDOrganizationMember, D as FFIDOrganizationProfile, E as FFIDOrganizationProfileErrorCode, G as FFIDOrganizationProfileResponse, H as FFIDOtpSendResponse, I as FFIDOtpVerifyResponse, J as FFIDPasswordResetConfirmResponse, K as FFIDPasswordResetResponse, L as FFIDPasswordResetVerifyResponse, M as FFIDProfileCallOptions, N as FFIDProvisionMemberPlan, O as FFIDProvisionMemberPlanStatus, P as FFIDProvisionMemberResult, Q as FFIDProvisionMemberStatus, R as FFIDProvisionOrganizationDryRun, S as FFIDProvisionOrganizationMemberInput, T as FFIDProvisionOrganizationOutcome, U as FFIDProvisionOrganizationParams, V as FFIDProvisionOrganizationResponse, W as FFIDProvisionUserDryRun, X as FFIDProvisionUserOutcome, Y as FFIDProvisionUserParams, Z as FFIDProvisionUserProfileInput, _ as FFIDProvisionUserResponse, $ as FFIDProvisionedOrganization, a0 as FFIDProvisionedUser, a1 as FFIDPublishedPlan, a2 as FFIDRemoveMemberResponse, a3 as FFIDResetSessionResponse, a4 as FFIDSubscription, a5 as FFIDUpdateMemberRoleResponse, a6 as FFIDUpdateUserProfileRequest, a7 as FFIDUploadOrganizationLogoParams, a8 as FFIDUpsertOrganizationProfileParams, a9 as FFIDUpsertOrganizationProfileRequest, aa as FFIDUser, ab as FFIDUserProfile, ac as FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, ad as FFID_CATALOG_ENVIRONMENTS, ae as FFID_CATALOG_PUBLICATION_STATUSES, af as FFID_COMPANY_SIZE_CODES, ag as FFID_INDUSTRY_CODES, ah as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, ai as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, aj as FFID_ORGANIZATION_PROFILE_ERROR_CODES, ak as TokenData, al as TokenStore, am as createFFIDClient, an as createTokenStore } from '../ffid-client-6aLs9Fqc.cjs';
3
3
  export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-Ce2eXQtB.cjs';
4
4
  import { z } from 'zod';
5
5
  import '../types-Cjb9J0rL.cjs';
@@ -1,5 +1,5 @@
1
- import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-5GAPcRIG.js';
2
- export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAllowedLogoMimeType, n as FFIDAssignableMemberRole, o as FFIDCacheConfig, p as FFIDCatalogPublication, q as FFIDCatalogPublicationStatus, r as FFIDClient, s as FFIDCompanySizeCode, t as FFIDConfig, u as FFIDIndustryCode, v as FFIDListMembersResponse, w as FFIDListingConsentInput, x as FFIDLogoWallEntry, y as FFIDLogoWallResponse, z as FFIDMemberRole, A as FFIDOrganization, B as FFIDOrganizationLogoUploadResponse, C as FFIDOrganizationMember, D as FFIDOrganizationProfile, E as FFIDOrganizationProfileErrorCode, G as FFIDOrganizationProfileResponse, H as FFIDOtpSendResponse, I as FFIDOtpVerifyResponse, J as FFIDPasswordResetConfirmResponse, K as FFIDPasswordResetResponse, L as FFIDPasswordResetVerifyResponse, M as FFIDProfileCallOptions, N as FFIDProvisionMemberPlan, O as FFIDProvisionMemberPlanStatus, P as FFIDProvisionMemberResult, Q as FFIDProvisionMemberStatus, R as FFIDProvisionOrganizationDryRun, S as FFIDProvisionOrganizationMemberInput, T as FFIDProvisionOrganizationOutcome, U as FFIDProvisionOrganizationParams, V as FFIDProvisionOrganizationResponse, W as FFIDProvisionUserDryRun, X as FFIDProvisionUserOutcome, Y as FFIDProvisionUserParams, Z as FFIDProvisionUserProfileInput, _ as FFIDProvisionUserResponse, $ as FFIDProvisionedOrganization, a0 as FFIDProvisionedUser, a1 as FFIDPublishedPlan, a2 as FFIDRemoveMemberResponse, a3 as FFIDResetSessionResponse, a4 as FFIDSubscription, a5 as FFIDUpdateMemberRoleResponse, a6 as FFIDUpdateUserProfileRequest, a7 as FFIDUploadOrganizationLogoParams, a8 as FFIDUpsertOrganizationProfileParams, a9 as FFIDUpsertOrganizationProfileRequest, aa as FFIDUser, ab as FFIDUserProfile, ac as FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, ad as FFID_CATALOG_ENVIRONMENTS, ae as FFID_CATALOG_PUBLICATION_STATUSES, af as FFID_COMPANY_SIZE_CODES, ag as FFID_INDUSTRY_CODES, ah as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, ai as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, aj as FFID_ORGANIZATION_PROFILE_ERROR_CODES, ak as TokenData, al as TokenStore, am as createFFIDClient, an as createTokenStore } from '../ffid-client-5GAPcRIG.js';
1
+ import { F as FFIDLogger, a as FFIDError, b as FFIDCacheAdapter, c as FFIDVerifyAccessTokenOptions, d as FFIDApiResponse, e as FFIDOAuthUserInfo, f as FFIDCatalogEnvironment, g as FFIDBillingInterval, h as FFIDTaxBehavior, i as FFIDPublishedCatalog } from '../ffid-client-B0cORHac.js';
2
+ export { j as FFIDAddMemberParams, k as FFIDAddMemberRequest, l as FFIDAddMemberResponse, m as FFIDAllowedLogoMimeType, n as FFIDAssignableMemberRole, o as FFIDCacheConfig, p as FFIDCatalogPublication, q as FFIDCatalogPublicationStatus, r as FFIDClient, s as FFIDCompanySizeCode, t as FFIDConfig, u as FFIDIndustryCode, v as FFIDListMembersResponse, w as FFIDListingConsentInput, x as FFIDLogoWallEntry, y as FFIDLogoWallResponse, z as FFIDMemberRole, A as FFIDOrganization, B as FFIDOrganizationLogoUploadResponse, C as FFIDOrganizationMember, D as FFIDOrganizationProfile, E as FFIDOrganizationProfileErrorCode, G as FFIDOrganizationProfileResponse, H as FFIDOtpSendResponse, I as FFIDOtpVerifyResponse, J as FFIDPasswordResetConfirmResponse, K as FFIDPasswordResetResponse, L as FFIDPasswordResetVerifyResponse, M as FFIDProfileCallOptions, N as FFIDProvisionMemberPlan, O as FFIDProvisionMemberPlanStatus, P as FFIDProvisionMemberResult, Q as FFIDProvisionMemberStatus, R as FFIDProvisionOrganizationDryRun, S as FFIDProvisionOrganizationMemberInput, T as FFIDProvisionOrganizationOutcome, U as FFIDProvisionOrganizationParams, V as FFIDProvisionOrganizationResponse, W as FFIDProvisionUserDryRun, X as FFIDProvisionUserOutcome, Y as FFIDProvisionUserParams, Z as FFIDProvisionUserProfileInput, _ as FFIDProvisionUserResponse, $ as FFIDProvisionedOrganization, a0 as FFIDProvisionedUser, a1 as FFIDPublishedPlan, a2 as FFIDRemoveMemberResponse, a3 as FFIDResetSessionResponse, a4 as FFIDSubscription, a5 as FFIDUpdateMemberRoleResponse, a6 as FFIDUpdateUserProfileRequest, a7 as FFIDUploadOrganizationLogoParams, a8 as FFIDUpsertOrganizationProfileParams, a9 as FFIDUpsertOrganizationProfileRequest, aa as FFIDUser, ab as FFIDUserProfile, ac as FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, ad as FFID_CATALOG_ENVIRONMENTS, ae as FFID_CATALOG_PUBLICATION_STATUSES, af as FFID_COMPANY_SIZE_CODES, ag as FFID_INDUSTRY_CODES, ah as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, ai as FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, aj as FFID_ORGANIZATION_PROFILE_ERROR_CODES, ak as TokenData, al as TokenStore, am as createFFIDClient, an as createTokenStore } from '../ffid-client-B0cORHac.js';
3
3
  export { D as DEFAULT_API_BASE_URL, a as DEFAULT_OAUTH_SCOPES } from '../constants-Ce2eXQtB.js';
4
4
  import { z } from 'zod';
5
5
  import '../types-Cjb9J0rL.js';
@@ -222,18 +222,16 @@ function mapUserinfoSubscriptionToSession(userinfo, serviceCode) {
222
222
  ];
223
223
  }
224
224
  var JWKS_ENDPOINT = "/.well-known/jwks.json";
225
- var LEGACY_JWT_ISSUER = "https://id.feelflow.net";
226
225
  var JWT_ALGORITHM = "ES256";
227
226
  var JWT_CLOCK_TOLERANCE_SECONDS = 30;
228
- function resolveAcceptedIssuers(baseUrl) {
229
- const deployedOrigin = new URL(baseUrl).origin;
230
- return deployedOrigin === LEGACY_JWT_ISSUER ? [LEGACY_JWT_ISSUER] : [deployedOrigin, LEGACY_JWT_ISSUER];
227
+ function resolveAcceptedIssuer(baseUrl) {
228
+ return new URL(baseUrl).origin;
231
229
  }
232
230
  function createJwtVerifier(deps) {
233
231
  const { baseUrl, serviceCode, logger, createError, errorCodes } = deps;
234
232
  const jwksUrl = new URL(JWKS_ENDPOINT, baseUrl);
235
233
  const jwks = createRemoteJWKSet(jwksUrl);
236
- const acceptedIssuers = resolveAcceptedIssuers(baseUrl);
234
+ const acceptedIssuer = resolveAcceptedIssuer(baseUrl);
237
235
  async function verifyJwt(accessToken) {
238
236
  if (!accessToken || !accessToken.trim()) {
239
237
  return {
@@ -246,7 +244,7 @@ function createJwtVerifier(deps) {
246
244
  try {
247
245
  const { payload } = await jwtVerify(accessToken, jwks, {
248
246
  algorithms: [JWT_ALGORITHM],
249
- issuer: acceptedIssuers,
247
+ issuer: acceptedIssuer,
250
248
  audience: serviceCode,
251
249
  clockTolerance: JWT_CLOCK_TOLERANCE_SECONDS
252
250
  });
@@ -1372,7 +1370,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
1372
1370
  };
1373
1371
 
1374
1372
  // src/client/version-check.ts
1375
- var SDK_VERSION = "8.0.0";
1373
+ var SDK_VERSION = "9.0.0";
1376
1374
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1377
1375
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1378
1376
  function sdkHeaders() {
@@ -1,4 +1,4 @@
1
- import { r as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-BaEmw7jP.cjs';
1
+ import { r as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-6aLs9Fqc.cjs';
2
2
  import '../../types-Cjb9J0rL.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { r as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-5GAPcRIG.js';
1
+ import { r as FFIDClient, e as FFIDOAuthUserInfo } from '../../ffid-client-B0cORHac.js';
2
2
  import '../../types-Cjb9J0rL.js';
3
3
 
4
4
  /**
@@ -55,15 +55,46 @@ interface FFIDSubscriptionCreatedPayload {
55
55
  status?: string;
56
56
  effectiveStatus?: EffectiveSubscriptionStatus;
57
57
  gracePeriodEndsAt?: string | null;
58
+ /**
59
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
60
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
61
+ * that event type, so compare this with your own service code to skip events for other
62
+ * services. Absent only when FFID could not resolve it — do not read absence as
63
+ * "not addressed to this service".
64
+ */
65
+ serviceCode?: string;
58
66
  }
67
+ /**
68
+ * `subscription.updated`.
69
+ *
70
+ * 9.0.0 aligned this type with what FFID sends (#6380): `status` is always present, and
71
+ * `subscriptionId` / `organizationId` are absent when the event comes from a Stripe notice
72
+ * whose subscription FFID could not match to its own record (check before use).
73
+ * `previousPlan` was removed — FFID never sent it.
74
+ */
59
75
  interface FFIDSubscriptionUpdatedPayload {
60
- subscriptionId: string;
76
+ /**
77
+ * Subscription status after the change — the raw status string (FFID's or Stripe's), not a
78
+ * closed enum. Use `effectiveStatus` for access decisions.
79
+ */
80
+ status: string;
81
+ /** FFID subscription UUID. Absent when FFID could not match the Stripe subscription */
82
+ subscriptionId?: string;
83
+ /** Stripe subscription id (`sub_...`). Present on events that come from Stripe notices */
84
+ stripeSubscriptionId?: string;
61
85
  organizationId?: string;
86
+ /** Plan code after the change */
62
87
  plan?: string;
63
- previousPlan?: string;
64
- status?: string;
65
88
  effectiveStatus?: EffectiveSubscriptionStatus;
66
89
  gracePeriodEndsAt?: string | null;
90
+ /**
91
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
92
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
93
+ * that event type, so compare this with your own service code to skip events for other
94
+ * services. Absent only when FFID could not resolve it — do not read absence as
95
+ * "not addressed to this service".
96
+ */
97
+ serviceCode?: string;
67
98
  }
68
99
  /**
69
100
  * `subscription.reactivated` (8.0.0): a cancellation reserved until the period end was
@@ -81,7 +112,13 @@ interface FFIDSubscriptionReactivatedPayload {
81
112
  gracePeriodEndsAt?: string | null;
82
113
  stripeSubscriptionId: string;
83
114
  stripeCustomerId: string;
84
- /** Code of the service the subscription belongs to (resolved by FFID when the event is sent) */
115
+ /**
116
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
117
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
118
+ * that event type, so compare this with your own service code to skip events for other
119
+ * services. Absent only when FFID could not resolve it — do not read absence as
120
+ * "not addressed to this service".
121
+ */
85
122
  serviceCode?: string;
86
123
  }
87
124
  /**
@@ -145,6 +182,14 @@ interface FFIDSubscriptionCanceledPayload {
145
182
  effectiveStatus?: EffectiveSubscriptionStatus;
146
183
  /** Always null for cancellation events because no grace window remains. */
147
184
  gracePeriodEndsAt?: string | null;
185
+ /**
186
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
187
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
188
+ * that event type, so compare this with your own service code to skip events for other
189
+ * services. Absent only when FFID could not resolve it — do not read absence as
190
+ * "not addressed to this service".
191
+ */
192
+ serviceCode?: string;
148
193
  }
149
194
  interface FFIDSubscriptionDowngradeScheduledPayload {
150
195
  /** FFID subscription UUID. */
@@ -161,6 +206,14 @@ interface FFIDSubscriptionDowngradeScheduledPayload {
161
206
  scheduledAt: string;
162
207
  /** ISO timestamp when the scheduled downgrade should take effect. */
163
208
  effectiveAt: string;
209
+ /**
210
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
211
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
212
+ * that event type, so compare this with your own service code to skip events for other
213
+ * services. Absent only when FFID could not resolve it — do not read absence as
214
+ * "not addressed to this service".
215
+ */
216
+ serviceCode?: string;
164
217
  }
165
218
  interface FFIDSubscriptionDowngradeAppliedPayload {
166
219
  /** FFID subscription UUID. */
@@ -175,6 +228,14 @@ interface FFIDSubscriptionDowngradeAppliedPayload {
175
228
  billingInterval: string;
176
229
  /** ISO timestamp when FFID applied the pending downgrade. */
177
230
  appliedAt: string;
231
+ /**
232
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
233
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
234
+ * that event type, so compare this with your own service code to skip events for other
235
+ * services. Absent only when FFID could not resolve it — do not read absence as
236
+ * "not addressed to this service".
237
+ */
238
+ serviceCode?: string;
178
239
  }
179
240
  interface FFIDSubscriptionDowngradeCanceledPayload {
180
241
  /** FFID subscription UUID. */
@@ -187,11 +248,45 @@ interface FFIDSubscriptionDowngradeCanceledPayload {
187
248
  currentPlanId: string;
188
249
  /** ISO timestamp when the pending downgrade was canceled. */
189
250
  canceledAt: string;
251
+ /**
252
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
253
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
254
+ * that event type, so compare this with your own service code to skip events for other
255
+ * services. Absent only when FFID could not resolve it — do not read absence as
256
+ * "not addressed to this service".
257
+ */
258
+ serviceCode?: string;
190
259
  }
260
+ /**
261
+ * `subscription.trial_ending` — sent when Stripe announces that a trial is about to end.
262
+ *
263
+ * 9.0.0 aligned this type with what FFID sends (#6380). FFID does not resolve its own
264
+ * subscription UUID for this event; identify the subscription by `stripeSubscriptionId`
265
+ * (and the service by `serviceCode`).
266
+ */
191
267
  interface FFIDSubscriptionTrialEndingPayload {
192
- subscriptionId: string;
193
- organizationId?: string;
268
+ /** Stripe subscription id (`sub_...`) */
269
+ stripeSubscriptionId: string;
270
+ /**
271
+ * Days until the trial ends, rounded **up** at the moment FFID processed Stripe's notice
272
+ * (a trial ending later the same day is `1`). `0` only when the trial had already ended by
273
+ * then. Fixed when the event is created — a redelivered event carries the same value.
274
+ */
275
+ daysRemaining: number;
276
+ /**
277
+ * Trial end date **for display**, in Japanese long form in JST (e.g. `2026年10月3日`) — not
278
+ * an ISO timestamp. `(無効な日時)` when FFID could not read Stripe's timestamp. Use
279
+ * `daysRemaining` for any calculation.
280
+ */
194
281
  trialEndDate: string;
282
+ /**
283
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
284
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
285
+ * that event type, so compare this with your own service code to skip events for other
286
+ * services. Absent only when FFID could not resolve it — do not read absence as
287
+ * "not addressed to this service".
288
+ */
289
+ serviceCode?: string;
195
290
  }
196
291
  interface FFIDSubscriptionPaymentFailedPayload {
197
292
  /**
@@ -249,6 +344,14 @@ interface FFIDSubscriptionPaymentFailedPayload {
249
344
  * "backend has no mapping yet" from "payload shape regression".
250
345
  */
251
346
  correlationUnavailable?: boolean;
347
+ /**
348
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
349
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
350
+ * that event type, so compare this with your own service code to skip events for other
351
+ * services. Absent only when FFID could not resolve it — do not read absence as
352
+ * "not addressed to this service".
353
+ */
354
+ serviceCode?: string;
252
355
  }
253
356
  interface FFIDUserCreatedPayload {
254
357
  userId: string;
@@ -55,15 +55,46 @@ interface FFIDSubscriptionCreatedPayload {
55
55
  status?: string;
56
56
  effectiveStatus?: EffectiveSubscriptionStatus;
57
57
  gracePeriodEndsAt?: string | null;
58
+ /**
59
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
60
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
61
+ * that event type, so compare this with your own service code to skip events for other
62
+ * services. Absent only when FFID could not resolve it — do not read absence as
63
+ * "not addressed to this service".
64
+ */
65
+ serviceCode?: string;
58
66
  }
67
+ /**
68
+ * `subscription.updated`.
69
+ *
70
+ * 9.0.0 aligned this type with what FFID sends (#6380): `status` is always present, and
71
+ * `subscriptionId` / `organizationId` are absent when the event comes from a Stripe notice
72
+ * whose subscription FFID could not match to its own record (check before use).
73
+ * `previousPlan` was removed — FFID never sent it.
74
+ */
59
75
  interface FFIDSubscriptionUpdatedPayload {
60
- subscriptionId: string;
76
+ /**
77
+ * Subscription status after the change — the raw status string (FFID's or Stripe's), not a
78
+ * closed enum. Use `effectiveStatus` for access decisions.
79
+ */
80
+ status: string;
81
+ /** FFID subscription UUID. Absent when FFID could not match the Stripe subscription */
82
+ subscriptionId?: string;
83
+ /** Stripe subscription id (`sub_...`). Present on events that come from Stripe notices */
84
+ stripeSubscriptionId?: string;
61
85
  organizationId?: string;
86
+ /** Plan code after the change */
62
87
  plan?: string;
63
- previousPlan?: string;
64
- status?: string;
65
88
  effectiveStatus?: EffectiveSubscriptionStatus;
66
89
  gracePeriodEndsAt?: string | null;
90
+ /**
91
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
92
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
93
+ * that event type, so compare this with your own service code to skip events for other
94
+ * services. Absent only when FFID could not resolve it — do not read absence as
95
+ * "not addressed to this service".
96
+ */
97
+ serviceCode?: string;
67
98
  }
68
99
  /**
69
100
  * `subscription.reactivated` (8.0.0): a cancellation reserved until the period end was
@@ -81,7 +112,13 @@ interface FFIDSubscriptionReactivatedPayload {
81
112
  gracePeriodEndsAt?: string | null;
82
113
  stripeSubscriptionId: string;
83
114
  stripeCustomerId: string;
84
- /** Code of the service the subscription belongs to (resolved by FFID when the event is sent) */
115
+ /**
116
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
117
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
118
+ * that event type, so compare this with your own service code to skip events for other
119
+ * services. Absent only when FFID could not resolve it — do not read absence as
120
+ * "not addressed to this service".
121
+ */
85
122
  serviceCode?: string;
86
123
  }
87
124
  /**
@@ -145,6 +182,14 @@ interface FFIDSubscriptionCanceledPayload {
145
182
  effectiveStatus?: EffectiveSubscriptionStatus;
146
183
  /** Always null for cancellation events because no grace window remains. */
147
184
  gracePeriodEndsAt?: string | null;
185
+ /**
186
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
187
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
188
+ * that event type, so compare this with your own service code to skip events for other
189
+ * services. Absent only when FFID could not resolve it — do not read absence as
190
+ * "not addressed to this service".
191
+ */
192
+ serviceCode?: string;
148
193
  }
149
194
  interface FFIDSubscriptionDowngradeScheduledPayload {
150
195
  /** FFID subscription UUID. */
@@ -161,6 +206,14 @@ interface FFIDSubscriptionDowngradeScheduledPayload {
161
206
  scheduledAt: string;
162
207
  /** ISO timestamp when the scheduled downgrade should take effect. */
163
208
  effectiveAt: string;
209
+ /**
210
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
211
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
212
+ * that event type, so compare this with your own service code to skip events for other
213
+ * services. Absent only when FFID could not resolve it — do not read absence as
214
+ * "not addressed to this service".
215
+ */
216
+ serviceCode?: string;
164
217
  }
165
218
  interface FFIDSubscriptionDowngradeAppliedPayload {
166
219
  /** FFID subscription UUID. */
@@ -175,6 +228,14 @@ interface FFIDSubscriptionDowngradeAppliedPayload {
175
228
  billingInterval: string;
176
229
  /** ISO timestamp when FFID applied the pending downgrade. */
177
230
  appliedAt: string;
231
+ /**
232
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
233
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
234
+ * that event type, so compare this with your own service code to skip events for other
235
+ * services. Absent only when FFID could not resolve it — do not read absence as
236
+ * "not addressed to this service".
237
+ */
238
+ serviceCode?: string;
178
239
  }
179
240
  interface FFIDSubscriptionDowngradeCanceledPayload {
180
241
  /** FFID subscription UUID. */
@@ -187,11 +248,45 @@ interface FFIDSubscriptionDowngradeCanceledPayload {
187
248
  currentPlanId: string;
188
249
  /** ISO timestamp when the pending downgrade was canceled. */
189
250
  canceledAt: string;
251
+ /**
252
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
253
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
254
+ * that event type, so compare this with your own service code to skip events for other
255
+ * services. Absent only when FFID could not resolve it — do not read absence as
256
+ * "not addressed to this service".
257
+ */
258
+ serviceCode?: string;
190
259
  }
260
+ /**
261
+ * `subscription.trial_ending` — sent when Stripe announces that a trial is about to end.
262
+ *
263
+ * 9.0.0 aligned this type with what FFID sends (#6380). FFID does not resolve its own
264
+ * subscription UUID for this event; identify the subscription by `stripeSubscriptionId`
265
+ * (and the service by `serviceCode`).
266
+ */
191
267
  interface FFIDSubscriptionTrialEndingPayload {
192
- subscriptionId: string;
193
- organizationId?: string;
268
+ /** Stripe subscription id (`sub_...`) */
269
+ stripeSubscriptionId: string;
270
+ /**
271
+ * Days until the trial ends, rounded **up** at the moment FFID processed Stripe's notice
272
+ * (a trial ending later the same day is `1`). `0` only when the trial had already ended by
273
+ * then. Fixed when the event is created — a redelivered event carries the same value.
274
+ */
275
+ daysRemaining: number;
276
+ /**
277
+ * Trial end date **for display**, in Japanese long form in JST (e.g. `2026年10月3日`) — not
278
+ * an ISO timestamp. `(無効な日時)` when FFID could not read Stripe's timestamp. Use
279
+ * `daysRemaining` for any calculation.
280
+ */
194
281
  trialEndDate: string;
282
+ /**
283
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
284
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
285
+ * that event type, so compare this with your own service code to skip events for other
286
+ * services. Absent only when FFID could not resolve it — do not read absence as
287
+ * "not addressed to this service".
288
+ */
289
+ serviceCode?: string;
195
290
  }
196
291
  interface FFIDSubscriptionPaymentFailedPayload {
197
292
  /**
@@ -249,6 +344,14 @@ interface FFIDSubscriptionPaymentFailedPayload {
249
344
  * "backend has no mapping yet" from "payload shape regression".
250
345
  */
251
346
  correlationUnavailable?: boolean;
347
+ /**
348
+ * Code of the service the subscription belongs to (e.g. `chatbot-v2`), resolved by FFID when
349
+ * the event is sent. Every `subscription.*` event is broadcast to all endpoints subscribed to
350
+ * that event type, so compare this with your own service code to skip events for other
351
+ * services. Absent only when FFID could not resolve it — do not read absence as
352
+ * "not addressed to this service".
353
+ */
354
+ serviceCode?: string;
252
355
  }
253
356
  interface FFIDUserCreatedPayload {
254
357
  userId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feelflow/ffid-sdk",
3
- "version": "8.0.0",
3
+ "version": "9.0.0",
4
4
  "description": "FeelFlow ID Platform SDK for React/Next.js applications",
5
5
  "keywords": [
6
6
  "feelflow",