@feelflow/ffid-sdk 12.1.0 → 12.2.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.
package/README.md CHANGED
@@ -22,6 +22,35 @@ pnpm add @feelflow/ffid-sdk
22
22
 
23
23
  ## 統合ガイド
24
24
 
25
+ ### ニュースレター登録・目的別停止(12.2.0)
26
+
27
+ 登録はサーバー上の `service-key` クライアントで行います。Service API Key を
28
+ ブラウザへ渡さず、公開フォームのCAPTCHAと配信同意をBFFで検証してください。
29
+
30
+ ```ts
31
+ // 一つの登録操作に一つのUUID。応答が失われた再操作では同じキーを保持する。
32
+ const idempotencyKey = crypto.randomUUID()
33
+ const result = await client.newsletter.subscribe({
34
+ email: 'reader@example.com',
35
+ types: ['general'],
36
+ source: 'website-newsletter',
37
+ locale: 'ja',
38
+ }, { idempotencyKey })
39
+
40
+ // tokenはメール内の不透明な値。ログへ出さない。
41
+ await client.newsletter.unsubscribe({ token, type: 'general' })
42
+ ```
43
+
44
+ `requiresConfirmation` は確認メール送信済み、`confirmationEmailPending` は未送信、
45
+ `requiresSignIn` は既存会員の設定案内です。後二つを「登録完了」にしないでください。
46
+ 未送信フラグは自動再送の予約を意味しません。登録内容を変えるときと、確定した結果の
47
+ 後で新しい登録を依頼するときは新しいキーを使います。SDKが自動再送することはありません。
48
+ 独立ニュースレター側の処理中・結果不明なreceiptの回復は、運用上の確認が必要です。
49
+ 配信停止の `type` を省略すると既存の全目的停止を維持します。
50
+ キー付き登録には、独立ownerへ転送する更新済みFFID互換APIが必要です。旧処理モードでは
51
+ 書込み・メール送信前に拒否し、SDKは返却された `requestId` の一致を確認します。
52
+ 互換APIの配備と独立化の切替を確認してから、BFFでキー付き登録を有効にしてください。
53
+
25
54
  サービスを FFID Platform に統合する詳細なガイドは **[Integration Guide](./docs/INTEGRATION_GUIDE.md)** を参照してください。OAuth フロー、フロントエンド/バックエンド実装パターン、セキュリティチェックリスト、アンチパターン集を網羅しています。
26
55
 
27
56
  ### Cookie 同意管理基盤 (v5.0.0+)
@@ -1,5 +1,6 @@
1
1
  import { createContext, useState, useRef, useEffect, useMemo, useCallback, useContext } from 'react';
2
2
  import { createRemoteJWKSet, jwtVerify, errors } from 'jose';
3
+ import { z } from 'zod';
3
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
5
 
5
6
  // src/constants.ts
@@ -1391,7 +1392,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
1391
1392
  };
1392
1393
 
1393
1394
  // src/client/version-check.ts
1394
- var SDK_VERSION = "12.1.0";
1395
+ var SDK_VERSION = "12.2.0";
1395
1396
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1396
1397
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1397
1398
  function sdkHeaders() {
@@ -3478,24 +3479,45 @@ function createContractWizardMethods(deps) {
3478
3479
  };
3479
3480
  }
3480
3481
 
3482
+ // src/newsletter/types.ts
3483
+ var FFID_NEWSLETTER_TYPES = ["inquiry_followup", "general"];
3484
+ var FFID_NEWSLETTER_DISPATCH_MAX_RECIPIENTS = 1e3;
3485
+
3481
3486
  // src/newsletter/ffid-newsletter-client.ts
3482
3487
  var EXT_SUBSCRIBE_ENDPOINT2 = "/api/v1/ext/newsletter/subscribe";
3483
3488
  var CONFIRM_ENDPOINT = "/api/newsletter/confirm";
3484
3489
  var UNSUBSCRIBE_ENDPOINT = "/api/newsletter/unsubscribe";
3485
3490
  var DISPATCH_ENDPOINT = "/api/v1/newsletter/dispatch";
3491
+ var PUBLIC_TOKEN_TIMEOUT_MS = 3e4;
3492
+ var subscribeResponseSchema = z.object({
3493
+ ok: z.literal(true),
3494
+ requiresConfirmation: z.boolean(),
3495
+ requiresSignIn: z.boolean(),
3496
+ confirmationEmailPending: z.boolean(),
3497
+ requestId: z.uuid().optional()
3498
+ }).refine(
3499
+ (value) => [
3500
+ value.requiresConfirmation,
3501
+ value.requiresSignIn,
3502
+ value.confirmationEmailPending
3503
+ ].filter(Boolean).length <= 1
3504
+ );
3486
3505
  function trimOrEmpty(s) {
3487
3506
  return typeof s === "string" ? s.trim() : "";
3488
3507
  }
3489
3508
  async function postPublic(url, init, opts) {
3490
3509
  let response;
3491
3510
  try {
3492
- response = await fetch(url, init);
3493
- } catch (err) {
3511
+ response = await fetch(url, {
3512
+ ...init,
3513
+ credentials: "omit",
3514
+ redirect: "error",
3515
+ cache: "no-store",
3516
+ signal: AbortSignal.timeout(PUBLIC_TOKEN_TIMEOUT_MS)
3517
+ });
3518
+ } catch {
3494
3519
  return {
3495
- error: opts.createError(
3496
- "NETWORK_ERROR",
3497
- err instanceof Error ? err.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
3498
- )
3520
+ error: opts.createError("NETWORK_ERROR", opts.fallbackMessage)
3499
3521
  };
3500
3522
  }
3501
3523
  if (!response.ok) {
@@ -3522,7 +3544,7 @@ async function postPublic(url, init, opts) {
3522
3544
  }
3523
3545
  function createNewsletterMethods(deps) {
3524
3546
  const { fetchWithAuth, baseUrl, createError } = deps;
3525
- async function subscribe(params) {
3547
+ async function subscribe(params, options = {}) {
3526
3548
  const email = trimOrEmpty(params.email);
3527
3549
  const source = trimOrEmpty(params.source);
3528
3550
  if (!email) {
@@ -3539,10 +3561,19 @@ function createNewsletterMethods(deps) {
3539
3561
  )
3540
3562
  };
3541
3563
  }
3542
- return fetchWithAuth(
3564
+ if (options.idempotencyKey !== void 0 && !z.uuid().safeParse(options.idempotencyKey).success) {
3565
+ return {
3566
+ error: createError(
3567
+ "INVALID_IDEMPOTENCY_KEY",
3568
+ "idempotencyKey \u306B\u306F UUID \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
3569
+ )
3570
+ };
3571
+ }
3572
+ const response = await fetchWithAuth(
3543
3573
  EXT_SUBSCRIBE_ENDPOINT2,
3544
3574
  {
3545
3575
  method: "POST",
3576
+ ...options.idempotencyKey ? { headers: { "Idempotency-Key": options.idempotencyKey } } : {},
3546
3577
  body: JSON.stringify({
3547
3578
  email,
3548
3579
  types: params.types,
@@ -3551,6 +3582,23 @@ function createNewsletterMethods(deps) {
3551
3582
  })
3552
3583
  }
3553
3584
  );
3585
+ if (response.error) return response;
3586
+ const parsed = subscribeResponseSchema.safeParse(response.data);
3587
+ if (!parsed.success)
3588
+ return {
3589
+ error: createError(
3590
+ "PARSE_ERROR",
3591
+ "\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u767B\u9332\u306E\u5FDC\u7B54\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"
3592
+ )
3593
+ };
3594
+ if (options.idempotencyKey && parsed.data.requestId !== options.idempotencyKey)
3595
+ return {
3596
+ error: createError(
3597
+ "PARSE_ERROR",
3598
+ "\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u767B\u9332\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u8B58\u5225\u5B50\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"
3599
+ )
3600
+ };
3601
+ return { data: parsed.data };
3554
3602
  }
3555
3603
  async function confirm(params) {
3556
3604
  const token = trimOrEmpty(params.token);
@@ -3578,6 +3626,16 @@ function createNewsletterMethods(deps) {
3578
3626
  }
3579
3627
  const url = new URL(`${baseUrl}${UNSUBSCRIBE_ENDPOINT}`);
3580
3628
  url.searchParams.set("token", token);
3629
+ if (params.type !== void 0) {
3630
+ if (!FFID_NEWSLETTER_TYPES.includes(params.type))
3631
+ return {
3632
+ error: createError(
3633
+ "VALIDATION_ERROR",
3634
+ "\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u306E\u914D\u4FE1\u7A2E\u5225\u304C\u4E0D\u6B63\u3067\u3059"
3635
+ )
3636
+ };
3637
+ url.searchParams.set("type", params.type);
3638
+ }
3581
3639
  return postPublic(
3582
3640
  url.toString(),
3583
3641
  { method: "POST" },
@@ -6868,4 +6926,4 @@ function FFIDInquiryForm({
6868
6926
  );
6869
6927
  }
6870
6928
 
6871
- export { ACCESS_GRANTING_EFFECTIVE_STATUSES, AGENCY_INVITE_COOKIE_MAX_AGE_SEC, AGENCY_INVITE_COOKIE_NAME, AGENCY_INVITE_TOKEN_PARAM, AGENCY_INVITE_TOKEN_REDACTION, BLOCKING_EFFECTIVE_STATUSES, CATALOG_HASH_PATTERN, DEFAULT_API_BASE_URL, DEFAULT_OAUTH_SCOPES, EFFECTIVE_SUBSCRIPTION_STATUSES, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDCatalogHashError, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSDKError, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, FFID_ANNOUNCEMENTS_ERROR_CODES, FFID_CATALOG_ENVIRONMENTS, FFID_CATALOG_PUBLICATION_STATUSES, FFID_COMPANY_SIZE_CODES, FFID_CREDITS_CONSUME_MAX_AMOUNT, FFID_CREDITS_CONSUME_MIN_AMOUNT, FFID_CREDITS_ERROR_CODES, FFID_CREDITS_FEATURE_PATTERN, FFID_CREDITS_HISTORY_DEFAULT_LIMIT, FFID_CREDITS_HISTORY_MAX_LIMIT, FFID_CREDITS_HISTORY_MIN_LIMIT, FFID_CREDITS_IDEMPOTENCY_KEY_PATTERN, FFID_CREDITS_LOW_THRESHOLD_PERCENT, FFID_CREDITS_METADATA_MAX_BYTES, FFID_CREDIT_GRANT_KINDS, FFID_CREDIT_HISTORY_TYPES, FFID_CREDIT_PACK_MAX_QUANTITY, FFID_CREDIT_PACK_MIN_QUANTITY, FFID_ERROR_CODES, FFID_INDUSTRY_CODES, FFID_INQUIRY_ACQUISITION_SOURCES, FFID_INQUIRY_CATEGORIES, FFID_INQUIRY_CATEGORIES_SITE_2026, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, FFID_OAUTH_DENIAL_REASONS, FFID_ORGANIZATION_PROFILE_ERROR_CODES, FFID_SUBSCRIPTION_ERROR_CODES, canonicalizeCatalogValue, captureAgencyInviteToken, cleanupStateStorage, clearAgencyInviteToken, computeEffectiveStatusFromSession, computeFFIDCheckoutCopyHash, computeLegalDisclosureHash, computePaymentConfigurationHash, computePraxisCopyHash, computeScopeHash, computeTaxConfigurationHash, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, getFFIDAuthorizationError, handleRedirectCallback, hasAccessFromUserinfo, hashCanonicalJson, isBlockedFromUserinfo, isFFIDInquiryAcquisitionSource, isFFIDInquiryCategorySite2026, isFFIDOAuthDenialReason, normalizeRedirectUri, readAgencyInviteCookie, readAgencyInviteToken, redactAgencyInviteToken, retrieveCodeVerifier, retrieveState, sha256Hex, storeCodeVerifier, storeState, useFFID, useFFIDAnnouncements, useFFIDContext, useSubscription, validatePublishedCatalog, withSubscription };
6929
+ export { ACCESS_GRANTING_EFFECTIVE_STATUSES, AGENCY_INVITE_COOKIE_MAX_AGE_SEC, AGENCY_INVITE_COOKIE_NAME, AGENCY_INVITE_TOKEN_PARAM, AGENCY_INVITE_TOKEN_REDACTION, BLOCKING_EFFECTIVE_STATUSES, CATALOG_HASH_PATTERN, DEFAULT_API_BASE_URL, DEFAULT_OAUTH_SCOPES, EFFECTIVE_SUBSCRIPTION_STATUSES, FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDCatalogHashError, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDProvider, FFIDSDKError, FFIDSubscriptionBadge, FFIDUserMenu, FFID_ALLOWED_ORGANIZATION_LOGO_MIME_TYPES, FFID_ANNOUNCEMENTS_ERROR_CODES, FFID_CATALOG_ENVIRONMENTS, FFID_CATALOG_PUBLICATION_STATUSES, FFID_COMPANY_SIZE_CODES, FFID_CREDITS_CONSUME_MAX_AMOUNT, FFID_CREDITS_CONSUME_MIN_AMOUNT, FFID_CREDITS_ERROR_CODES, FFID_CREDITS_FEATURE_PATTERN, FFID_CREDITS_HISTORY_DEFAULT_LIMIT, FFID_CREDITS_HISTORY_MAX_LIMIT, FFID_CREDITS_HISTORY_MIN_LIMIT, FFID_CREDITS_IDEMPOTENCY_KEY_PATTERN, FFID_CREDITS_LOW_THRESHOLD_PERCENT, FFID_CREDITS_METADATA_MAX_BYTES, FFID_CREDIT_GRANT_KINDS, FFID_CREDIT_HISTORY_TYPES, FFID_CREDIT_PACK_MAX_QUANTITY, FFID_CREDIT_PACK_MIN_QUANTITY, FFID_ERROR_CODES, FFID_INDUSTRY_CODES, FFID_INQUIRY_ACQUISITION_SOURCES, FFID_INQUIRY_CATEGORIES, FFID_INQUIRY_CATEGORIES_SITE_2026, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES, FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB, FFID_NEWSLETTER_DISPATCH_MAX_RECIPIENTS, FFID_NEWSLETTER_TYPES, FFID_OAUTH_DENIAL_REASONS, FFID_ORGANIZATION_PROFILE_ERROR_CODES, FFID_SUBSCRIPTION_ERROR_CODES, canonicalizeCatalogValue, captureAgencyInviteToken, cleanupStateStorage, clearAgencyInviteToken, computeEffectiveStatusFromSession, computeFFIDCheckoutCopyHash, computeLegalDisclosureHash, computePaymentConfigurationHash, computePraxisCopyHash, computeScopeHash, computeTaxConfigurationHash, createFFIDAnnouncementsClient, createFFIDClient, createTokenStore, generateCodeChallenge, generateCodeVerifier, getFFIDAuthorizationError, handleRedirectCallback, hasAccessFromUserinfo, hashCanonicalJson, isBlockedFromUserinfo, isFFIDInquiryAcquisitionSource, isFFIDInquiryCategorySite2026, isFFIDOAuthDenialReason, normalizeRedirectUri, readAgencyInviteCookie, readAgencyInviteToken, redactAgencyInviteToken, retrieveCodeVerifier, retrieveState, sha256Hex, storeCodeVerifier, storeState, useFFID, useFFIDAnnouncements, useFFIDContext, useSubscription, validatePublishedCatalog, withSubscription };
@@ -2,6 +2,7 @@
2
2
 
3
3
  var react = require('react');
4
4
  var jose = require('jose');
5
+ var zod = require('zod');
5
6
  var jsxRuntime = require('react/jsx-runtime');
6
7
 
7
8
  // src/constants.ts
@@ -1393,7 +1394,7 @@ var FFID_ORGANIZATION_PROFILE_ERROR_CODES = {
1393
1394
  };
1394
1395
 
1395
1396
  // src/client/version-check.ts
1396
- var SDK_VERSION = "12.1.0";
1397
+ var SDK_VERSION = "12.2.0";
1397
1398
  var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
1398
1399
  var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
1399
1400
  function sdkHeaders() {
@@ -3480,24 +3481,45 @@ function createContractWizardMethods(deps) {
3480
3481
  };
3481
3482
  }
3482
3483
 
3484
+ // src/newsletter/types.ts
3485
+ var FFID_NEWSLETTER_TYPES = ["inquiry_followup", "general"];
3486
+ var FFID_NEWSLETTER_DISPATCH_MAX_RECIPIENTS = 1e3;
3487
+
3483
3488
  // src/newsletter/ffid-newsletter-client.ts
3484
3489
  var EXT_SUBSCRIBE_ENDPOINT2 = "/api/v1/ext/newsletter/subscribe";
3485
3490
  var CONFIRM_ENDPOINT = "/api/newsletter/confirm";
3486
3491
  var UNSUBSCRIBE_ENDPOINT = "/api/newsletter/unsubscribe";
3487
3492
  var DISPATCH_ENDPOINT = "/api/v1/newsletter/dispatch";
3493
+ var PUBLIC_TOKEN_TIMEOUT_MS = 3e4;
3494
+ var subscribeResponseSchema = zod.z.object({
3495
+ ok: zod.z.literal(true),
3496
+ requiresConfirmation: zod.z.boolean(),
3497
+ requiresSignIn: zod.z.boolean(),
3498
+ confirmationEmailPending: zod.z.boolean(),
3499
+ requestId: zod.z.uuid().optional()
3500
+ }).refine(
3501
+ (value) => [
3502
+ value.requiresConfirmation,
3503
+ value.requiresSignIn,
3504
+ value.confirmationEmailPending
3505
+ ].filter(Boolean).length <= 1
3506
+ );
3488
3507
  function trimOrEmpty(s) {
3489
3508
  return typeof s === "string" ? s.trim() : "";
3490
3509
  }
3491
3510
  async function postPublic(url, init, opts) {
3492
3511
  let response;
3493
3512
  try {
3494
- response = await fetch(url, init);
3495
- } catch (err) {
3513
+ response = await fetch(url, {
3514
+ ...init,
3515
+ credentials: "omit",
3516
+ redirect: "error",
3517
+ cache: "no-store",
3518
+ signal: AbortSignal.timeout(PUBLIC_TOKEN_TIMEOUT_MS)
3519
+ });
3520
+ } catch {
3496
3521
  return {
3497
- error: opts.createError(
3498
- "NETWORK_ERROR",
3499
- err instanceof Error ? err.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
3500
- )
3522
+ error: opts.createError("NETWORK_ERROR", opts.fallbackMessage)
3501
3523
  };
3502
3524
  }
3503
3525
  if (!response.ok) {
@@ -3524,7 +3546,7 @@ async function postPublic(url, init, opts) {
3524
3546
  }
3525
3547
  function createNewsletterMethods(deps) {
3526
3548
  const { fetchWithAuth, baseUrl, createError } = deps;
3527
- async function subscribe(params) {
3549
+ async function subscribe(params, options = {}) {
3528
3550
  const email = trimOrEmpty(params.email);
3529
3551
  const source = trimOrEmpty(params.source);
3530
3552
  if (!email) {
@@ -3541,10 +3563,19 @@ function createNewsletterMethods(deps) {
3541
3563
  )
3542
3564
  };
3543
3565
  }
3544
- return fetchWithAuth(
3566
+ if (options.idempotencyKey !== void 0 && !zod.z.uuid().safeParse(options.idempotencyKey).success) {
3567
+ return {
3568
+ error: createError(
3569
+ "INVALID_IDEMPOTENCY_KEY",
3570
+ "idempotencyKey \u306B\u306F UUID \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
3571
+ )
3572
+ };
3573
+ }
3574
+ const response = await fetchWithAuth(
3545
3575
  EXT_SUBSCRIBE_ENDPOINT2,
3546
3576
  {
3547
3577
  method: "POST",
3578
+ ...options.idempotencyKey ? { headers: { "Idempotency-Key": options.idempotencyKey } } : {},
3548
3579
  body: JSON.stringify({
3549
3580
  email,
3550
3581
  types: params.types,
@@ -3553,6 +3584,23 @@ function createNewsletterMethods(deps) {
3553
3584
  })
3554
3585
  }
3555
3586
  );
3587
+ if (response.error) return response;
3588
+ const parsed = subscribeResponseSchema.safeParse(response.data);
3589
+ if (!parsed.success)
3590
+ return {
3591
+ error: createError(
3592
+ "PARSE_ERROR",
3593
+ "\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u767B\u9332\u306E\u5FDC\u7B54\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"
3594
+ )
3595
+ };
3596
+ if (options.idempotencyKey && parsed.data.requestId !== options.idempotencyKey)
3597
+ return {
3598
+ error: createError(
3599
+ "PARSE_ERROR",
3600
+ "\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u767B\u9332\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u8B58\u5225\u5B50\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"
3601
+ )
3602
+ };
3603
+ return { data: parsed.data };
3556
3604
  }
3557
3605
  async function confirm(params) {
3558
3606
  const token = trimOrEmpty(params.token);
@@ -3580,6 +3628,16 @@ function createNewsletterMethods(deps) {
3580
3628
  }
3581
3629
  const url = new URL(`${baseUrl}${UNSUBSCRIBE_ENDPOINT}`);
3582
3630
  url.searchParams.set("token", token);
3631
+ if (params.type !== void 0) {
3632
+ if (!FFID_NEWSLETTER_TYPES.includes(params.type))
3633
+ return {
3634
+ error: createError(
3635
+ "VALIDATION_ERROR",
3636
+ "\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u306E\u914D\u4FE1\u7A2E\u5225\u304C\u4E0D\u6B63\u3067\u3059"
3637
+ )
3638
+ };
3639
+ url.searchParams.set("type", params.type);
3640
+ }
3583
3641
  return postPublic(
3584
3642
  url.toString(),
3585
3643
  { method: "POST" },
@@ -6916,6 +6974,8 @@ exports.FFID_INQUIRY_CATEGORIES = FFID_INQUIRY_CATEGORIES;
6916
6974
  exports.FFID_INQUIRY_CATEGORIES_SITE_2026 = FFID_INQUIRY_CATEGORIES_SITE_2026;
6917
6975
  exports.FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES = FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_BYTES;
6918
6976
  exports.FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB = FFID_MAX_ORGANIZATION_LOGO_FILE_SIZE_MB;
6977
+ exports.FFID_NEWSLETTER_DISPATCH_MAX_RECIPIENTS = FFID_NEWSLETTER_DISPATCH_MAX_RECIPIENTS;
6978
+ exports.FFID_NEWSLETTER_TYPES = FFID_NEWSLETTER_TYPES;
6919
6979
  exports.FFID_OAUTH_DENIAL_REASONS = FFID_OAUTH_DENIAL_REASONS;
6920
6980
  exports.FFID_ORGANIZATION_PROFILE_ERROR_CODES = FFID_ORGANIZATION_PROFILE_ERROR_CODES;
6921
6981
  exports.FFID_SUBSCRIPTION_ERROR_CODES = FFID_SUBSCRIPTION_ERROR_CODES;
@@ -1,34 +1,34 @@
1
1
  'use strict';
2
2
 
3
- var chunk62MINYOA_cjs = require('../chunk-62MINYOA.cjs');
3
+ var chunkLT7FQ7BT_cjs = require('../chunk-LT7FQ7BT.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "FFIDAnnouncementBadge", {
8
8
  enumerable: true,
9
- get: function () { return chunk62MINYOA_cjs.FFIDAnnouncementBadge; }
9
+ get: function () { return chunkLT7FQ7BT_cjs.FFIDAnnouncementBadge; }
10
10
  });
11
11
  Object.defineProperty(exports, "FFIDAnnouncementList", {
12
12
  enumerable: true,
13
- get: function () { return chunk62MINYOA_cjs.FFIDAnnouncementList; }
13
+ get: function () { return chunkLT7FQ7BT_cjs.FFIDAnnouncementList; }
14
14
  });
15
15
  Object.defineProperty(exports, "FFIDInquiryForm", {
16
16
  enumerable: true,
17
- get: function () { return chunk62MINYOA_cjs.FFIDInquiryForm; }
17
+ get: function () { return chunkLT7FQ7BT_cjs.FFIDInquiryForm; }
18
18
  });
19
19
  Object.defineProperty(exports, "FFIDLoginButton", {
20
20
  enumerable: true,
21
- get: function () { return chunk62MINYOA_cjs.FFIDLoginButton; }
21
+ get: function () { return chunkLT7FQ7BT_cjs.FFIDLoginButton; }
22
22
  });
23
23
  Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
24
24
  enumerable: true,
25
- get: function () { return chunk62MINYOA_cjs.FFIDOrganizationSwitcher; }
25
+ get: function () { return chunkLT7FQ7BT_cjs.FFIDOrganizationSwitcher; }
26
26
  });
27
27
  Object.defineProperty(exports, "FFIDSubscriptionBadge", {
28
28
  enumerable: true,
29
- get: function () { return chunk62MINYOA_cjs.FFIDSubscriptionBadge; }
29
+ get: function () { return chunkLT7FQ7BT_cjs.FFIDSubscriptionBadge; }
30
30
  });
31
31
  Object.defineProperty(exports, "FFIDUserMenu", {
32
32
  enumerable: true,
33
- get: function () { return chunk62MINYOA_cjs.FFIDUserMenu; }
33
+ get: function () { return chunkLT7FQ7BT_cjs.FFIDUserMenu; }
34
34
  });
@@ -1 +1 @@
1
- export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-3MYUVPLD.js';
1
+ export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-75ISD4I4.js';
@@ -114,7 +114,7 @@ interface FFIDInquiryCreateResponse {
114
114
  * Newsletter types exposed by the FFID SDK.
115
115
  *
116
116
  * 2-layer newsletter model (#2078):
117
- * - `inquiry_followup`: 問い合わせフォローアップ (Type A)
117
+ * - `inquiry_followup`: 資料請求・お問い合わせ後のご案内 (Type A)
118
118
  * - `general`: 定期ニュースレター (Type B)
119
119
  *
120
120
  * FFID account holders' preferences live in `user_marketing_preferences`;
@@ -133,6 +133,12 @@ interface FFIDNewsletterSubscribeParams {
133
133
  /** ISO 639-1 locale (e.g. 'ja', 'en') */
134
134
  locale?: string;
135
135
  }
136
+ interface FFIDNewsletterSubscribeOptions {
137
+ /** UUID for one intentional registration. Reuse unchanged across retries;
138
+ * create a new key when the registration changes or a new request is intended.
139
+ * Transport-only: sent as Idempotency-Key, never added to the consent body. */
140
+ idempotencyKey?: string | undefined;
141
+ }
136
142
  interface FFIDNewsletterSubscribeResponse {
137
143
  ok: true;
138
144
  /** True when a double opt-in confirmation email was sent */
@@ -140,6 +146,11 @@ interface FFIDNewsletterSubscribeResponse {
140
146
  /** True when the email matched an existing FFID account; the caller
141
147
  * must sign in to update preferences. Preferences are NOT modified. */
142
148
  requiresSignIn: boolean;
149
+ /** True when confirmation could not be sent; subscription is still pending.
150
+ * This flag does not promise an automatic resend. */
151
+ confirmationEmailPending: boolean;
152
+ /** Present only when the independent owner acknowledged a durable registration intent. */
153
+ requestId?: string | undefined;
143
154
  }
144
155
  interface FFIDNewsletterConfirmParams {
145
156
  /** Confirmation token received in the double opt-in email */
@@ -151,6 +162,8 @@ interface FFIDNewsletterConfirmResponse {
151
162
  interface FFIDNewsletterUnsubscribeParams {
152
163
  /** Unsubscribe token received in the newsletter footer / List-Unsubscribe header */
153
164
  token: string;
165
+ /** Stop only the selected purpose. Omission preserves legacy all-purpose links. */
166
+ type?: FFIDNewsletterType | undefined;
154
167
  }
155
168
  interface FFIDNewsletterUnsubscribeResponse {
156
169
  ok: true;
@@ -2880,7 +2893,7 @@ declare function createFFIDClient(config: FFIDConfig): {
2880
2893
  }) => Promise<FFIDApiResponse<FFIDOtpVerifyResponse>>;
2881
2894
  /** Newsletter methods (subscribe / confirm / unsubscribe) */
2882
2895
  newsletter: {
2883
- subscribe: (params: FFIDNewsletterSubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterSubscribeResponse>>;
2896
+ subscribe: (params: FFIDNewsletterSubscribeParams, options?: FFIDNewsletterSubscribeOptions) => Promise<FFIDApiResponse<FFIDNewsletterSubscribeResponse>>;
2884
2897
  confirm: (params: FFIDNewsletterConfirmParams) => Promise<FFIDApiResponse<FFIDNewsletterConfirmResponse>>;
2885
2898
  unsubscribe: (params: FFIDNewsletterUnsubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterUnsubscribeResponse>>;
2886
2899
  dispatch: (params: FFIDNewsletterDispatchParams) => Promise<FFIDApiResponse<FFIDNewsletterDispatchResponse>>;
@@ -114,7 +114,7 @@ interface FFIDInquiryCreateResponse {
114
114
  * Newsletter types exposed by the FFID SDK.
115
115
  *
116
116
  * 2-layer newsletter model (#2078):
117
- * - `inquiry_followup`: 問い合わせフォローアップ (Type A)
117
+ * - `inquiry_followup`: 資料請求・お問い合わせ後のご案内 (Type A)
118
118
  * - `general`: 定期ニュースレター (Type B)
119
119
  *
120
120
  * FFID account holders' preferences live in `user_marketing_preferences`;
@@ -133,6 +133,12 @@ interface FFIDNewsletterSubscribeParams {
133
133
  /** ISO 639-1 locale (e.g. 'ja', 'en') */
134
134
  locale?: string;
135
135
  }
136
+ interface FFIDNewsletterSubscribeOptions {
137
+ /** UUID for one intentional registration. Reuse unchanged across retries;
138
+ * create a new key when the registration changes or a new request is intended.
139
+ * Transport-only: sent as Idempotency-Key, never added to the consent body. */
140
+ idempotencyKey?: string | undefined;
141
+ }
136
142
  interface FFIDNewsletterSubscribeResponse {
137
143
  ok: true;
138
144
  /** True when a double opt-in confirmation email was sent */
@@ -140,6 +146,11 @@ interface FFIDNewsletterSubscribeResponse {
140
146
  /** True when the email matched an existing FFID account; the caller
141
147
  * must sign in to update preferences. Preferences are NOT modified. */
142
148
  requiresSignIn: boolean;
149
+ /** True when confirmation could not be sent; subscription is still pending.
150
+ * This flag does not promise an automatic resend. */
151
+ confirmationEmailPending: boolean;
152
+ /** Present only when the independent owner acknowledged a durable registration intent. */
153
+ requestId?: string | undefined;
143
154
  }
144
155
  interface FFIDNewsletterConfirmParams {
145
156
  /** Confirmation token received in the double opt-in email */
@@ -151,6 +162,8 @@ interface FFIDNewsletterConfirmResponse {
151
162
  interface FFIDNewsletterUnsubscribeParams {
152
163
  /** Unsubscribe token received in the newsletter footer / List-Unsubscribe header */
153
164
  token: string;
165
+ /** Stop only the selected purpose. Omission preserves legacy all-purpose links. */
166
+ type?: FFIDNewsletterType | undefined;
154
167
  }
155
168
  interface FFIDNewsletterUnsubscribeResponse {
156
169
  ok: true;
@@ -2880,7 +2893,7 @@ declare function createFFIDClient(config: FFIDConfig): {
2880
2893
  }) => Promise<FFIDApiResponse<FFIDOtpVerifyResponse>>;
2881
2894
  /** Newsletter methods (subscribe / confirm / unsubscribe) */
2882
2895
  newsletter: {
2883
- subscribe: (params: FFIDNewsletterSubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterSubscribeResponse>>;
2896
+ subscribe: (params: FFIDNewsletterSubscribeParams, options?: FFIDNewsletterSubscribeOptions) => Promise<FFIDApiResponse<FFIDNewsletterSubscribeResponse>>;
2884
2897
  confirm: (params: FFIDNewsletterConfirmParams) => Promise<FFIDApiResponse<FFIDNewsletterConfirmResponse>>;
2885
2898
  unsubscribe: (params: FFIDNewsletterUnsubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterUnsubscribeResponse>>;
2886
2899
  dispatch: (params: FFIDNewsletterDispatchParams) => Promise<FFIDApiResponse<FFIDNewsletterDispatchResponse>>;