@feelflow/ffid-sdk 2.6.0 → 2.8.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/dist/{chunk-ZORI5YFR.cjs → chunk-GB5OHEVY.cjs} +533 -1
- package/dist/{chunk-7FEWA2P2.js → chunk-SR4UAQ3C.js} +532 -2
- package/dist/components/index.cjs +11 -7
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +1 -1
- package/dist/{index-p4dJw3qR.d.cts → index-BBAzyBFG.d.cts} +58 -1
- package/dist/{index-p4dJw3qR.d.ts → index-BBAzyBFG.d.ts} +58 -1
- package/dist/index.cjs +34 -22
- package/dist/index.d.cts +126 -3
- package/dist/index.d.ts +126 -3
- package/dist/index.js +6 -3
- package/dist/server/index.cjs +176 -1
- package/dist/server/index.d.cts +98 -0
- package/dist/server/index.d.ts +98 -0
- package/dist/server/index.js +176 -1
- package/package.json +1 -1
package/dist/server/index.cjs
CHANGED
|
@@ -617,7 +617,7 @@ function createMembersMethods(deps) {
|
|
|
617
617
|
}
|
|
618
618
|
|
|
619
619
|
// src/client/version-check.ts
|
|
620
|
-
var SDK_VERSION = "2.
|
|
620
|
+
var SDK_VERSION = "2.8.0";
|
|
621
621
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
622
622
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
623
623
|
function sdkHeaders() {
|
|
@@ -1548,6 +1548,168 @@ function createContractWizardMethods(deps) {
|
|
|
1548
1548
|
};
|
|
1549
1549
|
}
|
|
1550
1550
|
|
|
1551
|
+
// src/newsletter/ffid-newsletter-client.ts
|
|
1552
|
+
var EXT_SUBSCRIBE_ENDPOINT2 = "/api/v1/ext/newsletter/subscribe";
|
|
1553
|
+
var CONFIRM_ENDPOINT = "/api/newsletter/confirm";
|
|
1554
|
+
var UNSUBSCRIBE_ENDPOINT = "/api/newsletter/unsubscribe";
|
|
1555
|
+
function trimOrEmpty(s) {
|
|
1556
|
+
return typeof s === "string" ? s.trim() : "";
|
|
1557
|
+
}
|
|
1558
|
+
async function postPublic(url, init, opts) {
|
|
1559
|
+
let response;
|
|
1560
|
+
try {
|
|
1561
|
+
response = await fetch(url, init);
|
|
1562
|
+
} catch (err) {
|
|
1563
|
+
return {
|
|
1564
|
+
error: opts.createError(
|
|
1565
|
+
"NETWORK_ERROR",
|
|
1566
|
+
err instanceof Error ? err.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
|
|
1567
|
+
)
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
if (!response.ok) {
|
|
1571
|
+
try {
|
|
1572
|
+
const body = await response.json();
|
|
1573
|
+
if (body?.error?.code || body?.error?.message) {
|
|
1574
|
+
return {
|
|
1575
|
+
error: opts.createError(
|
|
1576
|
+
body.error.code ?? "UNKNOWN_ERROR",
|
|
1577
|
+
body.error.message ?? `${opts.fallbackMessage} (status: ${response.status})`
|
|
1578
|
+
)
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
} catch {
|
|
1582
|
+
}
|
|
1583
|
+
return {
|
|
1584
|
+
error: opts.createError(
|
|
1585
|
+
"NETWORK_ERROR",
|
|
1586
|
+
`${opts.fallbackMessage} (status: ${response.status})`
|
|
1587
|
+
)
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
return { data: opts.success };
|
|
1591
|
+
}
|
|
1592
|
+
function createNewsletterMethods(deps) {
|
|
1593
|
+
const { fetchWithAuth, baseUrl, createError } = deps;
|
|
1594
|
+
async function subscribe(params) {
|
|
1595
|
+
const email = trimOrEmpty(params.email);
|
|
1596
|
+
const source = trimOrEmpty(params.source);
|
|
1597
|
+
if (!email) {
|
|
1598
|
+
return { error: createError("VALIDATION_ERROR", "email \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1599
|
+
}
|
|
1600
|
+
if (!source) {
|
|
1601
|
+
return { error: createError("VALIDATION_ERROR", "source \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1602
|
+
}
|
|
1603
|
+
if (!Array.isArray(params.types) || params.types.length === 0) {
|
|
1604
|
+
return {
|
|
1605
|
+
error: createError(
|
|
1606
|
+
"VALIDATION_ERROR",
|
|
1607
|
+
"types \u306B\u306F1\u3064\u4EE5\u4E0A\u306E newsletter \u7A2E\u5225\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
1608
|
+
)
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
return fetchWithAuth(
|
|
1612
|
+
EXT_SUBSCRIBE_ENDPOINT2,
|
|
1613
|
+
{
|
|
1614
|
+
method: "POST",
|
|
1615
|
+
body: JSON.stringify({
|
|
1616
|
+
email,
|
|
1617
|
+
types: params.types,
|
|
1618
|
+
source,
|
|
1619
|
+
locale: params.locale
|
|
1620
|
+
})
|
|
1621
|
+
}
|
|
1622
|
+
);
|
|
1623
|
+
}
|
|
1624
|
+
async function confirm(params) {
|
|
1625
|
+
const token = trimOrEmpty(params.token);
|
|
1626
|
+
if (!token) {
|
|
1627
|
+
return { error: createError("VALIDATION_ERROR", "token \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1628
|
+
}
|
|
1629
|
+
return postPublic(
|
|
1630
|
+
`${baseUrl}${CONFIRM_ENDPOINT}`,
|
|
1631
|
+
{
|
|
1632
|
+
method: "POST",
|
|
1633
|
+
headers: { "Content-Type": "application/json" },
|
|
1634
|
+
body: JSON.stringify({ token })
|
|
1635
|
+
},
|
|
1636
|
+
{
|
|
1637
|
+
success: { ok: true },
|
|
1638
|
+
createError,
|
|
1639
|
+
fallbackMessage: "\u78BA\u8A8D\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u5931\u6557\u3057\u307E\u3057\u305F"
|
|
1640
|
+
}
|
|
1641
|
+
);
|
|
1642
|
+
}
|
|
1643
|
+
async function unsubscribe(params) {
|
|
1644
|
+
const token = trimOrEmpty(params.token);
|
|
1645
|
+
if (!token) {
|
|
1646
|
+
return { error: createError("VALIDATION_ERROR", "token \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1647
|
+
}
|
|
1648
|
+
const url = new URL(`${baseUrl}${UNSUBSCRIBE_ENDPOINT}`);
|
|
1649
|
+
url.searchParams.set("token", token);
|
|
1650
|
+
return postPublic(
|
|
1651
|
+
url.toString(),
|
|
1652
|
+
{ method: "POST" },
|
|
1653
|
+
{
|
|
1654
|
+
success: { ok: true },
|
|
1655
|
+
createError,
|
|
1656
|
+
fallbackMessage: "\u89E3\u9664\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u5931\u6557\u3057\u307E\u3057\u305F"
|
|
1657
|
+
}
|
|
1658
|
+
);
|
|
1659
|
+
}
|
|
1660
|
+
return { subscribe, confirm, unsubscribe };
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
// src/inquiry/ffid-inquiry-client.ts
|
|
1664
|
+
var EXT_INQUIRY_ENDPOINT = "/api/v1/ext/inquiry";
|
|
1665
|
+
function trimOrEmpty2(s) {
|
|
1666
|
+
return typeof s === "string" ? s.trim() : "";
|
|
1667
|
+
}
|
|
1668
|
+
function createInquiryMethods(deps) {
|
|
1669
|
+
const { fetchWithAuth, createError } = deps;
|
|
1670
|
+
async function create(params) {
|
|
1671
|
+
const email = trimOrEmpty2(params.email);
|
|
1672
|
+
const name = trimOrEmpty2(params.name);
|
|
1673
|
+
const message = trimOrEmpty2(params.message);
|
|
1674
|
+
const termsVersion = trimOrEmpty2(params.termsVersion);
|
|
1675
|
+
const privacyVersion = trimOrEmpty2(params.privacyVersion);
|
|
1676
|
+
if (!email) return { error: createError("VALIDATION_ERROR", "email \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1677
|
+
if (!name) return { error: createError("VALIDATION_ERROR", "name \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1678
|
+
if (!message) return { error: createError("VALIDATION_ERROR", "message \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1679
|
+
if (!termsVersion) {
|
|
1680
|
+
return { error: createError("VALIDATION_ERROR", "termsVersion \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1681
|
+
}
|
|
1682
|
+
if (!privacyVersion) {
|
|
1683
|
+
return { error: createError("VALIDATION_ERROR", "privacyVersion \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1684
|
+
}
|
|
1685
|
+
const inquiryFollowupOptIn = params.inquiryFollowupOptIn === true;
|
|
1686
|
+
const generalNewsletterOptIn = params.generalNewsletterOptIn === true;
|
|
1687
|
+
return fetchWithAuth(EXT_INQUIRY_ENDPOINT, {
|
|
1688
|
+
method: "POST",
|
|
1689
|
+
body: JSON.stringify({
|
|
1690
|
+
email,
|
|
1691
|
+
name,
|
|
1692
|
+
message,
|
|
1693
|
+
category: params.category,
|
|
1694
|
+
company: params.company,
|
|
1695
|
+
phone: params.phone,
|
|
1696
|
+
locale: params.locale,
|
|
1697
|
+
termsVersion,
|
|
1698
|
+
privacyVersion,
|
|
1699
|
+
// The ext endpoint still accepts the legacy single-flag field, but
|
|
1700
|
+
// the SDK always submits the 2-layer model. `newsletterOptIn` is
|
|
1701
|
+
// passed as the union of the two new flags only to satisfy the
|
|
1702
|
+
// current schema's required bool — the server preferentially
|
|
1703
|
+
// reads `inquiryFollowupOptIn` / `generalNewsletterOptIn`.
|
|
1704
|
+
newsletterOptIn: inquiryFollowupOptIn || generalNewsletterOptIn,
|
|
1705
|
+
inquiryFollowupOptIn,
|
|
1706
|
+
generalNewsletterOptIn
|
|
1707
|
+
})
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
return { create };
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1551
1713
|
// src/client/ffid-client.ts
|
|
1552
1714
|
var UNAUTHORIZED_STATUS2 = 401;
|
|
1553
1715
|
var SDK_LOG_PREFIX = "[FFID SDK]";
|
|
@@ -1823,6 +1985,15 @@ function createFFIDClient(config) {
|
|
|
1823
1985
|
createError,
|
|
1824
1986
|
errorCodes: FFID_ERROR_CODES
|
|
1825
1987
|
});
|
|
1988
|
+
const newsletter = createNewsletterMethods({
|
|
1989
|
+
fetchWithAuth,
|
|
1990
|
+
baseUrl,
|
|
1991
|
+
createError
|
|
1992
|
+
});
|
|
1993
|
+
const inquiry = createInquiryMethods({
|
|
1994
|
+
fetchWithAuth,
|
|
1995
|
+
createError
|
|
1996
|
+
});
|
|
1826
1997
|
const verifyAccessToken = createVerifyAccessToken({
|
|
1827
1998
|
authMode,
|
|
1828
1999
|
baseUrl,
|
|
@@ -1877,6 +2048,10 @@ function createFFIDClient(config) {
|
|
|
1877
2048
|
confirmPasswordReset,
|
|
1878
2049
|
sendOtp,
|
|
1879
2050
|
verifyOtp,
|
|
2051
|
+
/** Newsletter methods (subscribe / confirm / unsubscribe) */
|
|
2052
|
+
newsletter,
|
|
2053
|
+
/** Inquiry methods (create) */
|
|
2054
|
+
inquiry,
|
|
1880
2055
|
/** Token store (token mode only) */
|
|
1881
2056
|
tokenStore,
|
|
1882
2057
|
/** Resolved auth mode */
|
package/dist/server/index.d.cts
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
export { D as DEFAULT_API_BASE_URL } from '../constants-DvTGHPZn.cjs';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Inquiry types exposed by the FFID SDK.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors the `/api/v1/ext/inquiry` and `/api/contact` endpoints
|
|
7
|
+
* with a single shared shape so that consumers can render one
|
|
8
|
+
* `<FFIDInquiryForm />` and submit through either endpoint.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Categories surfaced by the default form. Consumers are free to
|
|
12
|
+
* pass their own list via `<FFIDInquiryForm categories={...} />`.
|
|
13
|
+
*/
|
|
14
|
+
declare const FFID_INQUIRY_CATEGORIES: readonly ["general", "sales", "support", "partnership", "press", "other"];
|
|
15
|
+
type FFIDInquiryCategory = (typeof FFID_INQUIRY_CATEGORIES)[number];
|
|
16
|
+
/**
|
|
17
|
+
* Parameters for `client.inquiry.create()`. When submitting from a
|
|
18
|
+
* server-side SDK (Service API Key), set `source` to a stable
|
|
19
|
+
* origin string so admins can trace the submission back.
|
|
20
|
+
*/
|
|
21
|
+
interface FFIDInquiryCreateParams {
|
|
22
|
+
email: string;
|
|
23
|
+
name: string;
|
|
24
|
+
message: string;
|
|
25
|
+
category?: FFIDInquiryCategory | (string & {});
|
|
26
|
+
company?: string;
|
|
27
|
+
phone?: string;
|
|
28
|
+
locale?: 'ja' | 'en';
|
|
29
|
+
/** Current terms-of-service version the submitter agreed to. */
|
|
30
|
+
termsVersion: string;
|
|
31
|
+
/** Current privacy-policy version the submitter agreed to. */
|
|
32
|
+
privacyVersion: string;
|
|
33
|
+
/** Opt-in to the post-inquiry follow-up newsletter (Type A). */
|
|
34
|
+
inquiryFollowupOptIn?: boolean;
|
|
35
|
+
/** Opt-in to the general marketing newsletter (Type B). */
|
|
36
|
+
generalNewsletterOptIn?: boolean;
|
|
37
|
+
}
|
|
38
|
+
interface FFIDInquiryCreateResponse {
|
|
39
|
+
ok: true;
|
|
40
|
+
inquiryId: string;
|
|
41
|
+
/** True only when the submitter is already a confirmed newsletter subscriber. */
|
|
42
|
+
newsletterSubscribed: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Newsletter types exposed by the FFID SDK.
|
|
47
|
+
*
|
|
48
|
+
* 2-layer newsletter model (#2078):
|
|
49
|
+
* - `inquiry_followup`: 問い合わせフォローアップ (Type A)
|
|
50
|
+
* - `general`: 定期ニュースレター (Type B)
|
|
51
|
+
*
|
|
52
|
+
* FFID account holders' preferences live in `user_marketing_preferences`;
|
|
53
|
+
* anonymous subscribers live in `newsletter_subscribers` with double
|
|
54
|
+
* opt-in required.
|
|
55
|
+
*/
|
|
56
|
+
declare const FFID_NEWSLETTER_TYPES: readonly ["inquiry_followup", "general"];
|
|
57
|
+
type FFIDNewsletterType = (typeof FFID_NEWSLETTER_TYPES)[number];
|
|
58
|
+
interface FFIDNewsletterSubscribeParams {
|
|
59
|
+
/** Subscriber email address */
|
|
60
|
+
email: string;
|
|
61
|
+
/** One or more newsletter types to opt in to */
|
|
62
|
+
types: FFIDNewsletterType[];
|
|
63
|
+
/** Origin string recorded on the subscriber row (e.g. your service code) */
|
|
64
|
+
source: string;
|
|
65
|
+
/** ISO 639-1 locale (e.g. 'ja', 'en') */
|
|
66
|
+
locale?: string;
|
|
67
|
+
}
|
|
68
|
+
interface FFIDNewsletterSubscribeResponse {
|
|
69
|
+
ok: true;
|
|
70
|
+
/** True when a double opt-in confirmation email was sent */
|
|
71
|
+
requiresConfirmation: boolean;
|
|
72
|
+
/** True when the email matched an existing FFID account; the caller
|
|
73
|
+
* must sign in to update preferences. Preferences are NOT modified. */
|
|
74
|
+
requiresSignIn: boolean;
|
|
75
|
+
}
|
|
76
|
+
interface FFIDNewsletterConfirmParams {
|
|
77
|
+
/** Confirmation token received in the double opt-in email */
|
|
78
|
+
token: string;
|
|
79
|
+
}
|
|
80
|
+
interface FFIDNewsletterConfirmResponse {
|
|
81
|
+
ok: true;
|
|
82
|
+
}
|
|
83
|
+
interface FFIDNewsletterUnsubscribeParams {
|
|
84
|
+
/** Unsubscribe token received in the newsletter footer / List-Unsubscribe header */
|
|
85
|
+
token: string;
|
|
86
|
+
}
|
|
87
|
+
interface FFIDNewsletterUnsubscribeResponse {
|
|
88
|
+
ok: true;
|
|
89
|
+
}
|
|
90
|
+
|
|
3
91
|
/** Cache adapter interface for FFID SDK token verification */
|
|
4
92
|
/**
|
|
5
93
|
* Pluggable cache adapter interface.
|
|
@@ -779,6 +867,16 @@ declare function createFFIDClient(config: FFIDConfig): {
|
|
|
779
867
|
accessToken: string;
|
|
780
868
|
refreshToken: string;
|
|
781
869
|
}) => Promise<FFIDApiResponse<FFIDOtpVerifyResponse>>;
|
|
870
|
+
/** Newsletter methods (subscribe / confirm / unsubscribe) */
|
|
871
|
+
newsletter: {
|
|
872
|
+
subscribe: (params: FFIDNewsletterSubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterSubscribeResponse>>;
|
|
873
|
+
confirm: (params: FFIDNewsletterConfirmParams) => Promise<FFIDApiResponse<FFIDNewsletterConfirmResponse>>;
|
|
874
|
+
unsubscribe: (params: FFIDNewsletterUnsubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterUnsubscribeResponse>>;
|
|
875
|
+
};
|
|
876
|
+
/** Inquiry methods (create) */
|
|
877
|
+
inquiry: {
|
|
878
|
+
create: (params: FFIDInquiryCreateParams) => Promise<FFIDApiResponse<FFIDInquiryCreateResponse>>;
|
|
879
|
+
};
|
|
782
880
|
/** Token store (token mode only) */
|
|
783
881
|
tokenStore: TokenStore;
|
|
784
882
|
/** Resolved auth mode */
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
export { D as DEFAULT_API_BASE_URL } from '../constants-DvTGHPZn.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Inquiry types exposed by the FFID SDK.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors the `/api/v1/ext/inquiry` and `/api/contact` endpoints
|
|
7
|
+
* with a single shared shape so that consumers can render one
|
|
8
|
+
* `<FFIDInquiryForm />` and submit through either endpoint.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Categories surfaced by the default form. Consumers are free to
|
|
12
|
+
* pass their own list via `<FFIDInquiryForm categories={...} />`.
|
|
13
|
+
*/
|
|
14
|
+
declare const FFID_INQUIRY_CATEGORIES: readonly ["general", "sales", "support", "partnership", "press", "other"];
|
|
15
|
+
type FFIDInquiryCategory = (typeof FFID_INQUIRY_CATEGORIES)[number];
|
|
16
|
+
/**
|
|
17
|
+
* Parameters for `client.inquiry.create()`. When submitting from a
|
|
18
|
+
* server-side SDK (Service API Key), set `source` to a stable
|
|
19
|
+
* origin string so admins can trace the submission back.
|
|
20
|
+
*/
|
|
21
|
+
interface FFIDInquiryCreateParams {
|
|
22
|
+
email: string;
|
|
23
|
+
name: string;
|
|
24
|
+
message: string;
|
|
25
|
+
category?: FFIDInquiryCategory | (string & {});
|
|
26
|
+
company?: string;
|
|
27
|
+
phone?: string;
|
|
28
|
+
locale?: 'ja' | 'en';
|
|
29
|
+
/** Current terms-of-service version the submitter agreed to. */
|
|
30
|
+
termsVersion: string;
|
|
31
|
+
/** Current privacy-policy version the submitter agreed to. */
|
|
32
|
+
privacyVersion: string;
|
|
33
|
+
/** Opt-in to the post-inquiry follow-up newsletter (Type A). */
|
|
34
|
+
inquiryFollowupOptIn?: boolean;
|
|
35
|
+
/** Opt-in to the general marketing newsletter (Type B). */
|
|
36
|
+
generalNewsletterOptIn?: boolean;
|
|
37
|
+
}
|
|
38
|
+
interface FFIDInquiryCreateResponse {
|
|
39
|
+
ok: true;
|
|
40
|
+
inquiryId: string;
|
|
41
|
+
/** True only when the submitter is already a confirmed newsletter subscriber. */
|
|
42
|
+
newsletterSubscribed: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Newsletter types exposed by the FFID SDK.
|
|
47
|
+
*
|
|
48
|
+
* 2-layer newsletter model (#2078):
|
|
49
|
+
* - `inquiry_followup`: 問い合わせフォローアップ (Type A)
|
|
50
|
+
* - `general`: 定期ニュースレター (Type B)
|
|
51
|
+
*
|
|
52
|
+
* FFID account holders' preferences live in `user_marketing_preferences`;
|
|
53
|
+
* anonymous subscribers live in `newsletter_subscribers` with double
|
|
54
|
+
* opt-in required.
|
|
55
|
+
*/
|
|
56
|
+
declare const FFID_NEWSLETTER_TYPES: readonly ["inquiry_followup", "general"];
|
|
57
|
+
type FFIDNewsletterType = (typeof FFID_NEWSLETTER_TYPES)[number];
|
|
58
|
+
interface FFIDNewsletterSubscribeParams {
|
|
59
|
+
/** Subscriber email address */
|
|
60
|
+
email: string;
|
|
61
|
+
/** One or more newsletter types to opt in to */
|
|
62
|
+
types: FFIDNewsletterType[];
|
|
63
|
+
/** Origin string recorded on the subscriber row (e.g. your service code) */
|
|
64
|
+
source: string;
|
|
65
|
+
/** ISO 639-1 locale (e.g. 'ja', 'en') */
|
|
66
|
+
locale?: string;
|
|
67
|
+
}
|
|
68
|
+
interface FFIDNewsletterSubscribeResponse {
|
|
69
|
+
ok: true;
|
|
70
|
+
/** True when a double opt-in confirmation email was sent */
|
|
71
|
+
requiresConfirmation: boolean;
|
|
72
|
+
/** True when the email matched an existing FFID account; the caller
|
|
73
|
+
* must sign in to update preferences. Preferences are NOT modified. */
|
|
74
|
+
requiresSignIn: boolean;
|
|
75
|
+
}
|
|
76
|
+
interface FFIDNewsletterConfirmParams {
|
|
77
|
+
/** Confirmation token received in the double opt-in email */
|
|
78
|
+
token: string;
|
|
79
|
+
}
|
|
80
|
+
interface FFIDNewsletterConfirmResponse {
|
|
81
|
+
ok: true;
|
|
82
|
+
}
|
|
83
|
+
interface FFIDNewsletterUnsubscribeParams {
|
|
84
|
+
/** Unsubscribe token received in the newsletter footer / List-Unsubscribe header */
|
|
85
|
+
token: string;
|
|
86
|
+
}
|
|
87
|
+
interface FFIDNewsletterUnsubscribeResponse {
|
|
88
|
+
ok: true;
|
|
89
|
+
}
|
|
90
|
+
|
|
3
91
|
/** Cache adapter interface for FFID SDK token verification */
|
|
4
92
|
/**
|
|
5
93
|
* Pluggable cache adapter interface.
|
|
@@ -779,6 +867,16 @@ declare function createFFIDClient(config: FFIDConfig): {
|
|
|
779
867
|
accessToken: string;
|
|
780
868
|
refreshToken: string;
|
|
781
869
|
}) => Promise<FFIDApiResponse<FFIDOtpVerifyResponse>>;
|
|
870
|
+
/** Newsletter methods (subscribe / confirm / unsubscribe) */
|
|
871
|
+
newsletter: {
|
|
872
|
+
subscribe: (params: FFIDNewsletterSubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterSubscribeResponse>>;
|
|
873
|
+
confirm: (params: FFIDNewsletterConfirmParams) => Promise<FFIDApiResponse<FFIDNewsletterConfirmResponse>>;
|
|
874
|
+
unsubscribe: (params: FFIDNewsletterUnsubscribeParams) => Promise<FFIDApiResponse<FFIDNewsletterUnsubscribeResponse>>;
|
|
875
|
+
};
|
|
876
|
+
/** Inquiry methods (create) */
|
|
877
|
+
inquiry: {
|
|
878
|
+
create: (params: FFIDInquiryCreateParams) => Promise<FFIDApiResponse<FFIDInquiryCreateResponse>>;
|
|
879
|
+
};
|
|
782
880
|
/** Token store (token mode only) */
|
|
783
881
|
tokenStore: TokenStore;
|
|
784
882
|
/** Resolved auth mode */
|
package/dist/server/index.js
CHANGED
|
@@ -616,7 +616,7 @@ function createMembersMethods(deps) {
|
|
|
616
616
|
}
|
|
617
617
|
|
|
618
618
|
// src/client/version-check.ts
|
|
619
|
-
var SDK_VERSION = "2.
|
|
619
|
+
var SDK_VERSION = "2.8.0";
|
|
620
620
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
621
621
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
622
622
|
function sdkHeaders() {
|
|
@@ -1547,6 +1547,168 @@ function createContractWizardMethods(deps) {
|
|
|
1547
1547
|
};
|
|
1548
1548
|
}
|
|
1549
1549
|
|
|
1550
|
+
// src/newsletter/ffid-newsletter-client.ts
|
|
1551
|
+
var EXT_SUBSCRIBE_ENDPOINT2 = "/api/v1/ext/newsletter/subscribe";
|
|
1552
|
+
var CONFIRM_ENDPOINT = "/api/newsletter/confirm";
|
|
1553
|
+
var UNSUBSCRIBE_ENDPOINT = "/api/newsletter/unsubscribe";
|
|
1554
|
+
function trimOrEmpty(s) {
|
|
1555
|
+
return typeof s === "string" ? s.trim() : "";
|
|
1556
|
+
}
|
|
1557
|
+
async function postPublic(url, init, opts) {
|
|
1558
|
+
let response;
|
|
1559
|
+
try {
|
|
1560
|
+
response = await fetch(url, init);
|
|
1561
|
+
} catch (err) {
|
|
1562
|
+
return {
|
|
1563
|
+
error: opts.createError(
|
|
1564
|
+
"NETWORK_ERROR",
|
|
1565
|
+
err instanceof Error ? err.message : "\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
|
|
1566
|
+
)
|
|
1567
|
+
};
|
|
1568
|
+
}
|
|
1569
|
+
if (!response.ok) {
|
|
1570
|
+
try {
|
|
1571
|
+
const body = await response.json();
|
|
1572
|
+
if (body?.error?.code || body?.error?.message) {
|
|
1573
|
+
return {
|
|
1574
|
+
error: opts.createError(
|
|
1575
|
+
body.error.code ?? "UNKNOWN_ERROR",
|
|
1576
|
+
body.error.message ?? `${opts.fallbackMessage} (status: ${response.status})`
|
|
1577
|
+
)
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
} catch {
|
|
1581
|
+
}
|
|
1582
|
+
return {
|
|
1583
|
+
error: opts.createError(
|
|
1584
|
+
"NETWORK_ERROR",
|
|
1585
|
+
`${opts.fallbackMessage} (status: ${response.status})`
|
|
1586
|
+
)
|
|
1587
|
+
};
|
|
1588
|
+
}
|
|
1589
|
+
return { data: opts.success };
|
|
1590
|
+
}
|
|
1591
|
+
function createNewsletterMethods(deps) {
|
|
1592
|
+
const { fetchWithAuth, baseUrl, createError } = deps;
|
|
1593
|
+
async function subscribe(params) {
|
|
1594
|
+
const email = trimOrEmpty(params.email);
|
|
1595
|
+
const source = trimOrEmpty(params.source);
|
|
1596
|
+
if (!email) {
|
|
1597
|
+
return { error: createError("VALIDATION_ERROR", "email \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1598
|
+
}
|
|
1599
|
+
if (!source) {
|
|
1600
|
+
return { error: createError("VALIDATION_ERROR", "source \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1601
|
+
}
|
|
1602
|
+
if (!Array.isArray(params.types) || params.types.length === 0) {
|
|
1603
|
+
return {
|
|
1604
|
+
error: createError(
|
|
1605
|
+
"VALIDATION_ERROR",
|
|
1606
|
+
"types \u306B\u306F1\u3064\u4EE5\u4E0A\u306E newsletter \u7A2E\u5225\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044"
|
|
1607
|
+
)
|
|
1608
|
+
};
|
|
1609
|
+
}
|
|
1610
|
+
return fetchWithAuth(
|
|
1611
|
+
EXT_SUBSCRIBE_ENDPOINT2,
|
|
1612
|
+
{
|
|
1613
|
+
method: "POST",
|
|
1614
|
+
body: JSON.stringify({
|
|
1615
|
+
email,
|
|
1616
|
+
types: params.types,
|
|
1617
|
+
source,
|
|
1618
|
+
locale: params.locale
|
|
1619
|
+
})
|
|
1620
|
+
}
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
async function confirm(params) {
|
|
1624
|
+
const token = trimOrEmpty(params.token);
|
|
1625
|
+
if (!token) {
|
|
1626
|
+
return { error: createError("VALIDATION_ERROR", "token \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1627
|
+
}
|
|
1628
|
+
return postPublic(
|
|
1629
|
+
`${baseUrl}${CONFIRM_ENDPOINT}`,
|
|
1630
|
+
{
|
|
1631
|
+
method: "POST",
|
|
1632
|
+
headers: { "Content-Type": "application/json" },
|
|
1633
|
+
body: JSON.stringify({ token })
|
|
1634
|
+
},
|
|
1635
|
+
{
|
|
1636
|
+
success: { ok: true },
|
|
1637
|
+
createError,
|
|
1638
|
+
fallbackMessage: "\u78BA\u8A8D\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u5931\u6557\u3057\u307E\u3057\u305F"
|
|
1639
|
+
}
|
|
1640
|
+
);
|
|
1641
|
+
}
|
|
1642
|
+
async function unsubscribe(params) {
|
|
1643
|
+
const token = trimOrEmpty(params.token);
|
|
1644
|
+
if (!token) {
|
|
1645
|
+
return { error: createError("VALIDATION_ERROR", "token \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1646
|
+
}
|
|
1647
|
+
const url = new URL(`${baseUrl}${UNSUBSCRIBE_ENDPOINT}`);
|
|
1648
|
+
url.searchParams.set("token", token);
|
|
1649
|
+
return postPublic(
|
|
1650
|
+
url.toString(),
|
|
1651
|
+
{ method: "POST" },
|
|
1652
|
+
{
|
|
1653
|
+
success: { ok: true },
|
|
1654
|
+
createError,
|
|
1655
|
+
fallbackMessage: "\u89E3\u9664\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u5931\u6557\u3057\u307E\u3057\u305F"
|
|
1656
|
+
}
|
|
1657
|
+
);
|
|
1658
|
+
}
|
|
1659
|
+
return { subscribe, confirm, unsubscribe };
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
// src/inquiry/ffid-inquiry-client.ts
|
|
1663
|
+
var EXT_INQUIRY_ENDPOINT = "/api/v1/ext/inquiry";
|
|
1664
|
+
function trimOrEmpty2(s) {
|
|
1665
|
+
return typeof s === "string" ? s.trim() : "";
|
|
1666
|
+
}
|
|
1667
|
+
function createInquiryMethods(deps) {
|
|
1668
|
+
const { fetchWithAuth, createError } = deps;
|
|
1669
|
+
async function create(params) {
|
|
1670
|
+
const email = trimOrEmpty2(params.email);
|
|
1671
|
+
const name = trimOrEmpty2(params.name);
|
|
1672
|
+
const message = trimOrEmpty2(params.message);
|
|
1673
|
+
const termsVersion = trimOrEmpty2(params.termsVersion);
|
|
1674
|
+
const privacyVersion = trimOrEmpty2(params.privacyVersion);
|
|
1675
|
+
if (!email) return { error: createError("VALIDATION_ERROR", "email \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1676
|
+
if (!name) return { error: createError("VALIDATION_ERROR", "name \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1677
|
+
if (!message) return { error: createError("VALIDATION_ERROR", "message \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1678
|
+
if (!termsVersion) {
|
|
1679
|
+
return { error: createError("VALIDATION_ERROR", "termsVersion \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1680
|
+
}
|
|
1681
|
+
if (!privacyVersion) {
|
|
1682
|
+
return { error: createError("VALIDATION_ERROR", "privacyVersion \u306F\u5FC5\u9808\u3067\u3059") };
|
|
1683
|
+
}
|
|
1684
|
+
const inquiryFollowupOptIn = params.inquiryFollowupOptIn === true;
|
|
1685
|
+
const generalNewsletterOptIn = params.generalNewsletterOptIn === true;
|
|
1686
|
+
return fetchWithAuth(EXT_INQUIRY_ENDPOINT, {
|
|
1687
|
+
method: "POST",
|
|
1688
|
+
body: JSON.stringify({
|
|
1689
|
+
email,
|
|
1690
|
+
name,
|
|
1691
|
+
message,
|
|
1692
|
+
category: params.category,
|
|
1693
|
+
company: params.company,
|
|
1694
|
+
phone: params.phone,
|
|
1695
|
+
locale: params.locale,
|
|
1696
|
+
termsVersion,
|
|
1697
|
+
privacyVersion,
|
|
1698
|
+
// The ext endpoint still accepts the legacy single-flag field, but
|
|
1699
|
+
// the SDK always submits the 2-layer model. `newsletterOptIn` is
|
|
1700
|
+
// passed as the union of the two new flags only to satisfy the
|
|
1701
|
+
// current schema's required bool — the server preferentially
|
|
1702
|
+
// reads `inquiryFollowupOptIn` / `generalNewsletterOptIn`.
|
|
1703
|
+
newsletterOptIn: inquiryFollowupOptIn || generalNewsletterOptIn,
|
|
1704
|
+
inquiryFollowupOptIn,
|
|
1705
|
+
generalNewsletterOptIn
|
|
1706
|
+
})
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1709
|
+
return { create };
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1550
1712
|
// src/client/ffid-client.ts
|
|
1551
1713
|
var UNAUTHORIZED_STATUS2 = 401;
|
|
1552
1714
|
var SDK_LOG_PREFIX = "[FFID SDK]";
|
|
@@ -1822,6 +1984,15 @@ function createFFIDClient(config) {
|
|
|
1822
1984
|
createError,
|
|
1823
1985
|
errorCodes: FFID_ERROR_CODES
|
|
1824
1986
|
});
|
|
1987
|
+
const newsletter = createNewsletterMethods({
|
|
1988
|
+
fetchWithAuth,
|
|
1989
|
+
baseUrl,
|
|
1990
|
+
createError
|
|
1991
|
+
});
|
|
1992
|
+
const inquiry = createInquiryMethods({
|
|
1993
|
+
fetchWithAuth,
|
|
1994
|
+
createError
|
|
1995
|
+
});
|
|
1825
1996
|
const verifyAccessToken = createVerifyAccessToken({
|
|
1826
1997
|
authMode,
|
|
1827
1998
|
baseUrl,
|
|
@@ -1876,6 +2047,10 @@ function createFFIDClient(config) {
|
|
|
1876
2047
|
confirmPasswordReset,
|
|
1877
2048
|
sendOtp,
|
|
1878
2049
|
verifyOtp,
|
|
2050
|
+
/** Newsletter methods (subscribe / confirm / unsubscribe) */
|
|
2051
|
+
newsletter,
|
|
2052
|
+
/** Inquiry methods (create) */
|
|
2053
|
+
inquiry,
|
|
1879
2054
|
/** Token store (token mode only) */
|
|
1880
2055
|
tokenStore,
|
|
1881
2056
|
/** Resolved auth mode */
|