@feelflow/ffid-sdk 5.8.0 → 5.10.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/{FFIDCookieLink-CE01gYc4.d.cts → FFIDCookieLink-D1WwE_ZO.d.cts} +5 -0
- package/dist/{FFIDCookieLink-CE01gYc4.d.ts → FFIDCookieLink-D1WwE_ZO.d.ts} +5 -0
- package/dist/{chunk-MRHDPB7H.cjs → chunk-IZSL6DI7.cjs} +17 -4
- package/dist/{chunk-KJ7FUNA6.js → chunk-M4N2PUX6.js} +64 -32
- package/dist/{chunk-Z6COUAR6.js → chunk-OJ3OJTIE.js} +17 -4
- package/dist/{chunk-Q5SZVLNB.cjs → chunk-R5WSZMUL.cjs} +64 -32
- package/dist/components/index.cjs +8 -8
- 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/consent/index.cjs +64 -64
- package/dist/consent/index.d.cts +2 -2
- package/dist/consent/index.d.ts +2 -2
- package/dist/consent/index.js +1 -1
- package/dist/{ffid-client-BhopNmnq.d.cts → ffid-client-DRjzfAaS.d.cts} +16 -3
- package/dist/{ffid-client-DoGYvIll.d.ts → ffid-client-gboJROw0.d.ts} +16 -3
- package/dist/{index-DeegKrLW.d.cts → index-DSvX4q8E.d.cts} +18 -3
- package/dist/{index-DeegKrLW.d.ts → index-DSvX4q8E.d.ts} +18 -3
- package/dist/index.cjs +57 -57
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/server/index.cjs +17 -4
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +17 -4
- package/dist/server/test/index.d.cts +1 -1
- package/dist/server/test/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -898,6 +898,11 @@ declare function useFFIDConsentPreferences(): UseFFIDConsentPreferencesReturn;
|
|
|
898
898
|
* was removed in v5.2.1 (#3289) because it overrode `setIsBannerOpen(false)`
|
|
899
899
|
* for fresh visitors and silently kept the banner mounted on "あとで" click.
|
|
900
900
|
*
|
|
901
|
+
* Consent submissions close the banner OPTIMISTICALLY (#3614): the provider
|
|
902
|
+
* flips `isBannerOpen=false` before the POST settles, so the click feels
|
|
903
|
+
* instant. On a failed POST the provider re-opens the banner with `error`
|
|
904
|
+
* set, which this component renders as the retry surface.
|
|
905
|
+
*
|
|
901
906
|
* Four buttons (spec §6.2):
|
|
902
907
|
* 1. "すべて同意" (Accept all)
|
|
903
908
|
* 2. "同意しない" (Necessary only — `necessary=true` is enforced by ePrivacy
|
|
@@ -898,6 +898,11 @@ declare function useFFIDConsentPreferences(): UseFFIDConsentPreferencesReturn;
|
|
|
898
898
|
* was removed in v5.2.1 (#3289) because it overrode `setIsBannerOpen(false)`
|
|
899
899
|
* for fresh visitors and silently kept the banner mounted on "あとで" click.
|
|
900
900
|
*
|
|
901
|
+
* Consent submissions close the banner OPTIMISTICALLY (#3614): the provider
|
|
902
|
+
* flips `isBannerOpen=false` before the POST settles, so the click feels
|
|
903
|
+
* instant. On a failed POST the provider re-opens the banner with `error`
|
|
904
|
+
* set, which this component renders as the retry surface.
|
|
905
|
+
*
|
|
901
906
|
* Four buttons (spec §6.2):
|
|
902
907
|
* 1. "すべて同意" (Accept all)
|
|
903
908
|
* 2. "同意しない" (Necessary only — `necessary=true` is enforced by ePrivacy
|
|
@@ -111,7 +111,16 @@ var SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES = [
|
|
|
111
111
|
function isSessionEligibleSubscriptionStatus(value) {
|
|
112
112
|
return typeof value === "string" && SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES.includes(value);
|
|
113
113
|
}
|
|
114
|
+
function hasOwnKey(value, key) {
|
|
115
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
116
|
+
}
|
|
114
117
|
function normalizeUserinfo(raw) {
|
|
118
|
+
const hasOrganizationId = hasOwnKey(raw, "organization_id");
|
|
119
|
+
const hasOrganizationName = hasOwnKey(raw, "organization_name");
|
|
120
|
+
const organizationFields = hasOrganizationId ? {
|
|
121
|
+
organizationId: raw.organization_id ?? null,
|
|
122
|
+
organizationName: hasOrganizationName ? raw.organization_name ?? null : null
|
|
123
|
+
} : hasOrganizationName ? { organizationName: raw.organization_name ?? null } : {};
|
|
115
124
|
return {
|
|
116
125
|
sub: raw.sub,
|
|
117
126
|
email: raw.email,
|
|
@@ -121,7 +130,7 @@ function normalizeUserinfo(raw) {
|
|
|
121
130
|
department: raw.department ?? null,
|
|
122
131
|
position: raw.position ?? null,
|
|
123
132
|
phoneNumber: raw.phone_number ?? null,
|
|
124
|
-
|
|
133
|
+
...organizationFields,
|
|
125
134
|
subscription: raw.subscription ? {
|
|
126
135
|
subscriptionId: raw.subscription.subscription_id ?? null,
|
|
127
136
|
status: raw.subscription.status ?? null,
|
|
@@ -130,6 +139,7 @@ function normalizeUserinfo(raw) {
|
|
|
130
139
|
seatModel: raw.subscription.seat_model ?? null,
|
|
131
140
|
memberRole: raw.subscription.member_role ?? null,
|
|
132
141
|
organizationId: raw.subscription.organization_id ?? null,
|
|
142
|
+
organizationName: hasOwnKey(raw.subscription, "organization_name") ? raw.subscription.organization_name ?? null : null,
|
|
133
143
|
hasSeatAssignment: raw.subscription.has_seat_assignment ?? false,
|
|
134
144
|
// #3464: legacy FFID (< this issue) omits the field on the wire.
|
|
135
145
|
// The "unknown" axis is unused — no consumer differentiates "server
|
|
@@ -165,7 +175,8 @@ function mapUserinfoSubscriptionToSession(userinfo, serviceCode) {
|
|
|
165
175
|
cancelAtPeriodEnd: subscription.cancelAtPeriodEnd,
|
|
166
176
|
seatModel: subscription.seatModel ?? void 0,
|
|
167
177
|
memberRole: subscription.memberRole ?? void 0,
|
|
168
|
-
organizationId: subscription.organizationId
|
|
178
|
+
organizationId: subscription.organizationId,
|
|
179
|
+
organizationName: subscription.organizationName ?? void 0
|
|
169
180
|
}
|
|
170
181
|
];
|
|
171
182
|
}
|
|
@@ -374,7 +385,8 @@ function createVerifyAccessToken(deps) {
|
|
|
374
385
|
department: introspectResponse.department ?? null,
|
|
375
386
|
position: introspectResponse.position ?? null,
|
|
376
387
|
phone_number: introspectResponse.phone_number ?? null,
|
|
377
|
-
organization_id: introspectResponse.organization_id ?? null
|
|
388
|
+
organization_id: introspectResponse.organization_id ?? null,
|
|
389
|
+
organization_name: introspectResponse.organization_name ?? null
|
|
378
390
|
};
|
|
379
391
|
const raw = introspectResponse.subscription ? {
|
|
380
392
|
...base,
|
|
@@ -386,6 +398,7 @@ function createVerifyAccessToken(deps) {
|
|
|
386
398
|
seat_model: introspectResponse.subscription.seat_model,
|
|
387
399
|
member_role: introspectResponse.subscription.member_role,
|
|
388
400
|
organization_id: introspectResponse.subscription.organization_id,
|
|
401
|
+
organization_name: introspectResponse.subscription.organization_name ?? null,
|
|
389
402
|
has_seat_assignment: introspectResponse.subscription.has_seat_assignment ?? false
|
|
390
403
|
}
|
|
391
404
|
} : base;
|
|
@@ -856,7 +869,7 @@ function createProfileMethods(deps) {
|
|
|
856
869
|
}
|
|
857
870
|
|
|
858
871
|
// src/client/version-check.ts
|
|
859
|
-
var SDK_VERSION = "5.
|
|
872
|
+
var SDK_VERSION = "5.10.0";
|
|
860
873
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
861
874
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
862
875
|
function sdkHeaders() {
|
|
@@ -798,6 +798,7 @@ function createConsentClient(opts) {
|
|
|
798
798
|
};
|
|
799
799
|
if (reqOpts.body !== void 0) init.body = JSON.stringify(reqOpts.body);
|
|
800
800
|
if (reqOpts.signal) init.signal = reqOpts.signal;
|
|
801
|
+
if (reqOpts.keepalive && !reqOpts.signal) init.keepalive = true;
|
|
801
802
|
let res;
|
|
802
803
|
for (let attempt = 0; attempt <= maxAutoRetry429; attempt++) {
|
|
803
804
|
const fetched = await performFetch(url, init);
|
|
@@ -879,6 +880,10 @@ function createConsentClient(opts) {
|
|
|
879
880
|
source,
|
|
880
881
|
cookie_policy_version: cookiePolicyVersion
|
|
881
882
|
},
|
|
883
|
+
// The banner closes before this POST settles (optimistic close,
|
|
884
|
+
// #3614) — keepalive keeps the audit-trail write alive across a
|
|
885
|
+
// quick page navigation.
|
|
886
|
+
keepalive: true,
|
|
882
887
|
...signal ? { signal } : {}
|
|
883
888
|
},
|
|
884
889
|
(json) => {
|
|
@@ -1215,6 +1220,16 @@ function FFIDAnalyticsProvider({
|
|
|
1215
1220
|
cancelled = true;
|
|
1216
1221
|
};
|
|
1217
1222
|
}, []);
|
|
1223
|
+
useEffect(() => {
|
|
1224
|
+
if (!isBannerOpen || policy !== null) return;
|
|
1225
|
+
let cancelled = false;
|
|
1226
|
+
void clientRef.current.getDocument().then((result) => {
|
|
1227
|
+
if (!cancelled && result.ok) setPolicy(result.value);
|
|
1228
|
+
});
|
|
1229
|
+
return () => {
|
|
1230
|
+
cancelled = true;
|
|
1231
|
+
};
|
|
1232
|
+
}, [isBannerOpen, policy]);
|
|
1218
1233
|
const ensurePolicyVersion = useCallback(async () => {
|
|
1219
1234
|
if (policy) return { ok: true, version: policy.version };
|
|
1220
1235
|
const client = clientRef.current;
|
|
@@ -1229,18 +1244,38 @@ function FFIDAnalyticsProvider({
|
|
|
1229
1244
|
}, [onError, policy]);
|
|
1230
1245
|
const submitFromBanner = useCallback(
|
|
1231
1246
|
async (cats) => {
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1247
|
+
setIsBannerOpen(false);
|
|
1248
|
+
let recordedOk = false;
|
|
1249
|
+
try {
|
|
1250
|
+
const version = await ensurePolicyVersion();
|
|
1251
|
+
if (!version.ok) {
|
|
1252
|
+
setIsBannerOpen(true);
|
|
1253
|
+
return { ok: false, error: version.error };
|
|
1254
|
+
}
|
|
1255
|
+
const client = clientRef.current;
|
|
1256
|
+
const result = await client.submit(cats, "banner", version.version);
|
|
1257
|
+
if (!result.ok && result.error.code === "cookie_consent_policy_outdated") {
|
|
1258
|
+
setPolicy(null);
|
|
1259
|
+
}
|
|
1260
|
+
recordedOk = result.ok;
|
|
1261
|
+
handleResult(result);
|
|
1262
|
+
if (!result.ok) setIsBannerOpen(true);
|
|
1263
|
+
return result;
|
|
1264
|
+
} catch (err) {
|
|
1265
|
+
if (!recordedOk) {
|
|
1266
|
+
const escapeError = err instanceof FFIDConsentError ? err : new FFIDConsentError(
|
|
1267
|
+
"cookie_consent_capture_failed",
|
|
1268
|
+
DEFAULT_CONSENT_ERROR_MESSAGES.cookie_consent_capture_failed,
|
|
1269
|
+
{ cause: err }
|
|
1270
|
+
);
|
|
1271
|
+
setError(escapeError);
|
|
1272
|
+
setIsBannerOpen(true);
|
|
1273
|
+
onError?.(escapeError);
|
|
1274
|
+
}
|
|
1275
|
+
throw err;
|
|
1238
1276
|
}
|
|
1239
|
-
handleResult(result);
|
|
1240
|
-
if (result.ok) setIsBannerOpen(false);
|
|
1241
|
-
return result;
|
|
1242
1277
|
},
|
|
1243
|
-
[ensurePolicyVersion, handleResult]
|
|
1278
|
+
[ensurePolicyVersion, handleResult, onError]
|
|
1244
1279
|
);
|
|
1245
1280
|
const acceptAll = useCallback(
|
|
1246
1281
|
() => submitFromBanner({
|
|
@@ -1486,16 +1521,13 @@ function FFIDCookieBanner({
|
|
|
1486
1521
|
error
|
|
1487
1522
|
} = useFFIDConsent();
|
|
1488
1523
|
const [pendingAction, setPendingAction] = useState(null);
|
|
1489
|
-
const
|
|
1524
|
+
const isOpeningPreferences = pendingAction !== null;
|
|
1490
1525
|
const runBannerSubmit = async (action, submit) => {
|
|
1491
|
-
if (
|
|
1492
|
-
setPendingAction(action);
|
|
1526
|
+
if (isOpeningPreferences) return;
|
|
1493
1527
|
try {
|
|
1494
|
-
|
|
1495
|
-
if (!result.ok) setPendingAction(null);
|
|
1528
|
+
await submit();
|
|
1496
1529
|
} catch (err) {
|
|
1497
1530
|
console.error(`[FFIDCookieBanner] ${action} action failed`, err);
|
|
1498
|
-
setPendingAction(null);
|
|
1499
1531
|
}
|
|
1500
1532
|
};
|
|
1501
1533
|
const handleAcceptAll = () => runBannerSubmit("accept-all", acceptAll);
|
|
@@ -1503,7 +1535,7 @@ function FFIDCookieBanner({
|
|
|
1503
1535
|
await runBannerSubmit("necessary-only", acceptNecessaryOnly);
|
|
1504
1536
|
};
|
|
1505
1537
|
const handleOpenPreferences = async () => {
|
|
1506
|
-
if (
|
|
1538
|
+
if (isOpeningPreferences) return;
|
|
1507
1539
|
setPendingAction("preferences");
|
|
1508
1540
|
try {
|
|
1509
1541
|
await openPreferences();
|
|
@@ -1520,7 +1552,7 @@ function FFIDCookieBanner({
|
|
|
1520
1552
|
role: "dialog",
|
|
1521
1553
|
"aria-modal": "false",
|
|
1522
1554
|
"aria-label": "Cookie \u540C\u610F",
|
|
1523
|
-
"aria-busy":
|
|
1555
|
+
"aria-busy": isOpeningPreferences,
|
|
1524
1556
|
className: className ?? classNames?.root,
|
|
1525
1557
|
style: style ?? DEFAULT_STYLE,
|
|
1526
1558
|
"data-testid": "ffid-cookie-banner",
|
|
@@ -1547,15 +1579,15 @@ function FFIDCookieBanner({
|
|
|
1547
1579
|
className: classNames?.primaryButton,
|
|
1548
1580
|
style: {
|
|
1549
1581
|
...DEFAULT_PRIMARY_STYLE,
|
|
1550
|
-
cursor:
|
|
1582
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_PRIMARY_STYLE.cursor
|
|
1551
1583
|
},
|
|
1552
|
-
disabled:
|
|
1553
|
-
"aria-disabled":
|
|
1584
|
+
disabled: isOpeningPreferences,
|
|
1585
|
+
"aria-disabled": isOpeningPreferences,
|
|
1554
1586
|
onClick: () => {
|
|
1555
1587
|
void handleAcceptAll();
|
|
1556
1588
|
},
|
|
1557
1589
|
"data-testid": "ffid-cookie-banner-accept-all",
|
|
1558
|
-
children:
|
|
1590
|
+
children: acceptAllLabel ?? "\u3059\u3079\u3066\u540C\u610F"
|
|
1559
1591
|
}
|
|
1560
1592
|
),
|
|
1561
1593
|
/* @__PURE__ */ jsx(
|
|
@@ -1565,15 +1597,15 @@ function FFIDCookieBanner({
|
|
|
1565
1597
|
className: classNames?.secondaryButton,
|
|
1566
1598
|
style: {
|
|
1567
1599
|
...DEFAULT_BUTTON_STYLE,
|
|
1568
|
-
cursor:
|
|
1600
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_BUTTON_STYLE.cursor
|
|
1569
1601
|
},
|
|
1570
|
-
disabled:
|
|
1571
|
-
"aria-disabled":
|
|
1602
|
+
disabled: isOpeningPreferences,
|
|
1603
|
+
"aria-disabled": isOpeningPreferences,
|
|
1572
1604
|
onClick: () => {
|
|
1573
1605
|
void handleAcceptNecessaryOnly();
|
|
1574
1606
|
},
|
|
1575
1607
|
"data-testid": "ffid-cookie-banner-necessary-only",
|
|
1576
|
-
children:
|
|
1608
|
+
children: necessaryOnlyLabel ?? "\u540C\u610F\u3057\u306A\u3044"
|
|
1577
1609
|
}
|
|
1578
1610
|
),
|
|
1579
1611
|
/* @__PURE__ */ jsx(
|
|
@@ -1583,10 +1615,10 @@ function FFIDCookieBanner({
|
|
|
1583
1615
|
className: classNames?.linkButton,
|
|
1584
1616
|
style: {
|
|
1585
1617
|
...DEFAULT_BUTTON_STYLE,
|
|
1586
|
-
cursor:
|
|
1618
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_BUTTON_STYLE.cursor
|
|
1587
1619
|
},
|
|
1588
|
-
disabled:
|
|
1589
|
-
"aria-disabled":
|
|
1620
|
+
disabled: isOpeningPreferences,
|
|
1621
|
+
"aria-disabled": isOpeningPreferences,
|
|
1590
1622
|
onClick: () => {
|
|
1591
1623
|
void handleOpenPreferences();
|
|
1592
1624
|
},
|
|
@@ -1601,10 +1633,10 @@ function FFIDCookieBanner({
|
|
|
1601
1633
|
className: classNames?.closeButton,
|
|
1602
1634
|
style: {
|
|
1603
1635
|
...DEFAULT_BUTTON_STYLE,
|
|
1604
|
-
cursor:
|
|
1636
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_BUTTON_STYLE.cursor
|
|
1605
1637
|
},
|
|
1606
|
-
disabled:
|
|
1607
|
-
"aria-disabled":
|
|
1638
|
+
disabled: isOpeningPreferences,
|
|
1639
|
+
"aria-disabled": isOpeningPreferences,
|
|
1608
1640
|
onClick: () => {
|
|
1609
1641
|
closeBanner();
|
|
1610
1642
|
},
|
|
@@ -109,7 +109,16 @@ var SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES = [
|
|
|
109
109
|
function isSessionEligibleSubscriptionStatus(value) {
|
|
110
110
|
return typeof value === "string" && SESSION_ELIGIBLE_SUBSCRIPTION_STATUSES.includes(value);
|
|
111
111
|
}
|
|
112
|
+
function hasOwnKey(value, key) {
|
|
113
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
114
|
+
}
|
|
112
115
|
function normalizeUserinfo(raw) {
|
|
116
|
+
const hasOrganizationId = hasOwnKey(raw, "organization_id");
|
|
117
|
+
const hasOrganizationName = hasOwnKey(raw, "organization_name");
|
|
118
|
+
const organizationFields = hasOrganizationId ? {
|
|
119
|
+
organizationId: raw.organization_id ?? null,
|
|
120
|
+
organizationName: hasOrganizationName ? raw.organization_name ?? null : null
|
|
121
|
+
} : hasOrganizationName ? { organizationName: raw.organization_name ?? null } : {};
|
|
113
122
|
return {
|
|
114
123
|
sub: raw.sub,
|
|
115
124
|
email: raw.email,
|
|
@@ -119,7 +128,7 @@ function normalizeUserinfo(raw) {
|
|
|
119
128
|
department: raw.department ?? null,
|
|
120
129
|
position: raw.position ?? null,
|
|
121
130
|
phoneNumber: raw.phone_number ?? null,
|
|
122
|
-
|
|
131
|
+
...organizationFields,
|
|
123
132
|
subscription: raw.subscription ? {
|
|
124
133
|
subscriptionId: raw.subscription.subscription_id ?? null,
|
|
125
134
|
status: raw.subscription.status ?? null,
|
|
@@ -128,6 +137,7 @@ function normalizeUserinfo(raw) {
|
|
|
128
137
|
seatModel: raw.subscription.seat_model ?? null,
|
|
129
138
|
memberRole: raw.subscription.member_role ?? null,
|
|
130
139
|
organizationId: raw.subscription.organization_id ?? null,
|
|
140
|
+
organizationName: hasOwnKey(raw.subscription, "organization_name") ? raw.subscription.organization_name ?? null : null,
|
|
131
141
|
hasSeatAssignment: raw.subscription.has_seat_assignment ?? false,
|
|
132
142
|
// #3464: legacy FFID (< this issue) omits the field on the wire.
|
|
133
143
|
// The "unknown" axis is unused — no consumer differentiates "server
|
|
@@ -163,7 +173,8 @@ function mapUserinfoSubscriptionToSession(userinfo, serviceCode) {
|
|
|
163
173
|
cancelAtPeriodEnd: subscription.cancelAtPeriodEnd,
|
|
164
174
|
seatModel: subscription.seatModel ?? void 0,
|
|
165
175
|
memberRole: subscription.memberRole ?? void 0,
|
|
166
|
-
organizationId: subscription.organizationId
|
|
176
|
+
organizationId: subscription.organizationId,
|
|
177
|
+
organizationName: subscription.organizationName ?? void 0
|
|
167
178
|
}
|
|
168
179
|
];
|
|
169
180
|
}
|
|
@@ -372,7 +383,8 @@ function createVerifyAccessToken(deps) {
|
|
|
372
383
|
department: introspectResponse.department ?? null,
|
|
373
384
|
position: introspectResponse.position ?? null,
|
|
374
385
|
phone_number: introspectResponse.phone_number ?? null,
|
|
375
|
-
organization_id: introspectResponse.organization_id ?? null
|
|
386
|
+
organization_id: introspectResponse.organization_id ?? null,
|
|
387
|
+
organization_name: introspectResponse.organization_name ?? null
|
|
376
388
|
};
|
|
377
389
|
const raw = introspectResponse.subscription ? {
|
|
378
390
|
...base,
|
|
@@ -384,6 +396,7 @@ function createVerifyAccessToken(deps) {
|
|
|
384
396
|
seat_model: introspectResponse.subscription.seat_model,
|
|
385
397
|
member_role: introspectResponse.subscription.member_role,
|
|
386
398
|
organization_id: introspectResponse.subscription.organization_id,
|
|
399
|
+
organization_name: introspectResponse.subscription.organization_name ?? null,
|
|
387
400
|
has_seat_assignment: introspectResponse.subscription.has_seat_assignment ?? false
|
|
388
401
|
}
|
|
389
402
|
} : base;
|
|
@@ -854,7 +867,7 @@ function createProfileMethods(deps) {
|
|
|
854
867
|
}
|
|
855
868
|
|
|
856
869
|
// src/client/version-check.ts
|
|
857
|
-
var SDK_VERSION = "5.
|
|
870
|
+
var SDK_VERSION = "5.10.0";
|
|
858
871
|
var SDK_USER_AGENT = `FFID-SDK/${SDK_VERSION} (TypeScript)`;
|
|
859
872
|
var SDK_VERSION_HEADER = "X-FFID-SDK-Version";
|
|
860
873
|
function sdkHeaders() {
|
|
@@ -800,6 +800,7 @@ function createConsentClient(opts) {
|
|
|
800
800
|
};
|
|
801
801
|
if (reqOpts.body !== void 0) init.body = JSON.stringify(reqOpts.body);
|
|
802
802
|
if (reqOpts.signal) init.signal = reqOpts.signal;
|
|
803
|
+
if (reqOpts.keepalive && !reqOpts.signal) init.keepalive = true;
|
|
803
804
|
let res;
|
|
804
805
|
for (let attempt = 0; attempt <= maxAutoRetry429; attempt++) {
|
|
805
806
|
const fetched = await performFetch(url, init);
|
|
@@ -881,6 +882,10 @@ function createConsentClient(opts) {
|
|
|
881
882
|
source,
|
|
882
883
|
cookie_policy_version: cookiePolicyVersion
|
|
883
884
|
},
|
|
885
|
+
// The banner closes before this POST settles (optimistic close,
|
|
886
|
+
// #3614) — keepalive keeps the audit-trail write alive across a
|
|
887
|
+
// quick page navigation.
|
|
888
|
+
keepalive: true,
|
|
884
889
|
...signal ? { signal } : {}
|
|
885
890
|
},
|
|
886
891
|
(json) => {
|
|
@@ -1217,6 +1222,16 @@ function FFIDAnalyticsProvider({
|
|
|
1217
1222
|
cancelled = true;
|
|
1218
1223
|
};
|
|
1219
1224
|
}, []);
|
|
1225
|
+
react.useEffect(() => {
|
|
1226
|
+
if (!isBannerOpen || policy !== null) return;
|
|
1227
|
+
let cancelled = false;
|
|
1228
|
+
void clientRef.current.getDocument().then((result) => {
|
|
1229
|
+
if (!cancelled && result.ok) setPolicy(result.value);
|
|
1230
|
+
});
|
|
1231
|
+
return () => {
|
|
1232
|
+
cancelled = true;
|
|
1233
|
+
};
|
|
1234
|
+
}, [isBannerOpen, policy]);
|
|
1220
1235
|
const ensurePolicyVersion = react.useCallback(async () => {
|
|
1221
1236
|
if (policy) return { ok: true, version: policy.version };
|
|
1222
1237
|
const client = clientRef.current;
|
|
@@ -1231,18 +1246,38 @@ function FFIDAnalyticsProvider({
|
|
|
1231
1246
|
}, [onError, policy]);
|
|
1232
1247
|
const submitFromBanner = react.useCallback(
|
|
1233
1248
|
async (cats) => {
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1249
|
+
setIsBannerOpen(false);
|
|
1250
|
+
let recordedOk = false;
|
|
1251
|
+
try {
|
|
1252
|
+
const version = await ensurePolicyVersion();
|
|
1253
|
+
if (!version.ok) {
|
|
1254
|
+
setIsBannerOpen(true);
|
|
1255
|
+
return { ok: false, error: version.error };
|
|
1256
|
+
}
|
|
1257
|
+
const client = clientRef.current;
|
|
1258
|
+
const result = await client.submit(cats, "banner", version.version);
|
|
1259
|
+
if (!result.ok && result.error.code === "cookie_consent_policy_outdated") {
|
|
1260
|
+
setPolicy(null);
|
|
1261
|
+
}
|
|
1262
|
+
recordedOk = result.ok;
|
|
1263
|
+
handleResult(result);
|
|
1264
|
+
if (!result.ok) setIsBannerOpen(true);
|
|
1265
|
+
return result;
|
|
1266
|
+
} catch (err) {
|
|
1267
|
+
if (!recordedOk) {
|
|
1268
|
+
const escapeError = err instanceof FFIDConsentError ? err : new FFIDConsentError(
|
|
1269
|
+
"cookie_consent_capture_failed",
|
|
1270
|
+
DEFAULT_CONSENT_ERROR_MESSAGES.cookie_consent_capture_failed,
|
|
1271
|
+
{ cause: err }
|
|
1272
|
+
);
|
|
1273
|
+
setError(escapeError);
|
|
1274
|
+
setIsBannerOpen(true);
|
|
1275
|
+
onError?.(escapeError);
|
|
1276
|
+
}
|
|
1277
|
+
throw err;
|
|
1240
1278
|
}
|
|
1241
|
-
handleResult(result);
|
|
1242
|
-
if (result.ok) setIsBannerOpen(false);
|
|
1243
|
-
return result;
|
|
1244
1279
|
},
|
|
1245
|
-
[ensurePolicyVersion, handleResult]
|
|
1280
|
+
[ensurePolicyVersion, handleResult, onError]
|
|
1246
1281
|
);
|
|
1247
1282
|
const acceptAll = react.useCallback(
|
|
1248
1283
|
() => submitFromBanner({
|
|
@@ -1488,16 +1523,13 @@ function FFIDCookieBanner({
|
|
|
1488
1523
|
error
|
|
1489
1524
|
} = useFFIDConsent();
|
|
1490
1525
|
const [pendingAction, setPendingAction] = react.useState(null);
|
|
1491
|
-
const
|
|
1526
|
+
const isOpeningPreferences = pendingAction !== null;
|
|
1492
1527
|
const runBannerSubmit = async (action, submit) => {
|
|
1493
|
-
if (
|
|
1494
|
-
setPendingAction(action);
|
|
1528
|
+
if (isOpeningPreferences) return;
|
|
1495
1529
|
try {
|
|
1496
|
-
|
|
1497
|
-
if (!result.ok) setPendingAction(null);
|
|
1530
|
+
await submit();
|
|
1498
1531
|
} catch (err) {
|
|
1499
1532
|
console.error(`[FFIDCookieBanner] ${action} action failed`, err);
|
|
1500
|
-
setPendingAction(null);
|
|
1501
1533
|
}
|
|
1502
1534
|
};
|
|
1503
1535
|
const handleAcceptAll = () => runBannerSubmit("accept-all", acceptAll);
|
|
@@ -1505,7 +1537,7 @@ function FFIDCookieBanner({
|
|
|
1505
1537
|
await runBannerSubmit("necessary-only", acceptNecessaryOnly);
|
|
1506
1538
|
};
|
|
1507
1539
|
const handleOpenPreferences = async () => {
|
|
1508
|
-
if (
|
|
1540
|
+
if (isOpeningPreferences) return;
|
|
1509
1541
|
setPendingAction("preferences");
|
|
1510
1542
|
try {
|
|
1511
1543
|
await openPreferences();
|
|
@@ -1522,7 +1554,7 @@ function FFIDCookieBanner({
|
|
|
1522
1554
|
role: "dialog",
|
|
1523
1555
|
"aria-modal": "false",
|
|
1524
1556
|
"aria-label": "Cookie \u540C\u610F",
|
|
1525
|
-
"aria-busy":
|
|
1557
|
+
"aria-busy": isOpeningPreferences,
|
|
1526
1558
|
className: className ?? classNames?.root,
|
|
1527
1559
|
style: style ?? DEFAULT_STYLE,
|
|
1528
1560
|
"data-testid": "ffid-cookie-banner",
|
|
@@ -1549,15 +1581,15 @@ function FFIDCookieBanner({
|
|
|
1549
1581
|
className: classNames?.primaryButton,
|
|
1550
1582
|
style: {
|
|
1551
1583
|
...DEFAULT_PRIMARY_STYLE,
|
|
1552
|
-
cursor:
|
|
1584
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_PRIMARY_STYLE.cursor
|
|
1553
1585
|
},
|
|
1554
|
-
disabled:
|
|
1555
|
-
"aria-disabled":
|
|
1586
|
+
disabled: isOpeningPreferences,
|
|
1587
|
+
"aria-disabled": isOpeningPreferences,
|
|
1556
1588
|
onClick: () => {
|
|
1557
1589
|
void handleAcceptAll();
|
|
1558
1590
|
},
|
|
1559
1591
|
"data-testid": "ffid-cookie-banner-accept-all",
|
|
1560
|
-
children:
|
|
1592
|
+
children: acceptAllLabel ?? "\u3059\u3079\u3066\u540C\u610F"
|
|
1561
1593
|
}
|
|
1562
1594
|
),
|
|
1563
1595
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1567,15 +1599,15 @@ function FFIDCookieBanner({
|
|
|
1567
1599
|
className: classNames?.secondaryButton,
|
|
1568
1600
|
style: {
|
|
1569
1601
|
...DEFAULT_BUTTON_STYLE,
|
|
1570
|
-
cursor:
|
|
1602
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_BUTTON_STYLE.cursor
|
|
1571
1603
|
},
|
|
1572
|
-
disabled:
|
|
1573
|
-
"aria-disabled":
|
|
1604
|
+
disabled: isOpeningPreferences,
|
|
1605
|
+
"aria-disabled": isOpeningPreferences,
|
|
1574
1606
|
onClick: () => {
|
|
1575
1607
|
void handleAcceptNecessaryOnly();
|
|
1576
1608
|
},
|
|
1577
1609
|
"data-testid": "ffid-cookie-banner-necessary-only",
|
|
1578
|
-
children:
|
|
1610
|
+
children: necessaryOnlyLabel ?? "\u540C\u610F\u3057\u306A\u3044"
|
|
1579
1611
|
}
|
|
1580
1612
|
),
|
|
1581
1613
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1585,10 +1617,10 @@ function FFIDCookieBanner({
|
|
|
1585
1617
|
className: classNames?.linkButton,
|
|
1586
1618
|
style: {
|
|
1587
1619
|
...DEFAULT_BUTTON_STYLE,
|
|
1588
|
-
cursor:
|
|
1620
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_BUTTON_STYLE.cursor
|
|
1589
1621
|
},
|
|
1590
|
-
disabled:
|
|
1591
|
-
"aria-disabled":
|
|
1622
|
+
disabled: isOpeningPreferences,
|
|
1623
|
+
"aria-disabled": isOpeningPreferences,
|
|
1592
1624
|
onClick: () => {
|
|
1593
1625
|
void handleOpenPreferences();
|
|
1594
1626
|
},
|
|
@@ -1603,10 +1635,10 @@ function FFIDCookieBanner({
|
|
|
1603
1635
|
className: classNames?.closeButton,
|
|
1604
1636
|
style: {
|
|
1605
1637
|
...DEFAULT_BUTTON_STYLE,
|
|
1606
|
-
cursor:
|
|
1638
|
+
cursor: isOpeningPreferences ? "wait" : DEFAULT_BUTTON_STYLE.cursor
|
|
1607
1639
|
},
|
|
1608
|
-
disabled:
|
|
1609
|
-
"aria-disabled":
|
|
1640
|
+
disabled: isOpeningPreferences,
|
|
1641
|
+
"aria-disabled": isOpeningPreferences,
|
|
1610
1642
|
onClick: () => {
|
|
1611
1643
|
closeBanner();
|
|
1612
1644
|
},
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkIZSL6DI7_cjs = require('../chunk-IZSL6DI7.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "FFIDAnnouncementBadge", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkIZSL6DI7_cjs.FFIDAnnouncementBadge; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "FFIDAnnouncementList", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkIZSL6DI7_cjs.FFIDAnnouncementList; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "FFIDInquiryForm", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkIZSL6DI7_cjs.FFIDInquiryForm; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "FFIDLoginButton", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkIZSL6DI7_cjs.FFIDLoginButton; }
|
|
22
22
|
});
|
|
23
23
|
Object.defineProperty(exports, "FFIDOrganizationSwitcher", {
|
|
24
24
|
enumerable: true,
|
|
25
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkIZSL6DI7_cjs.FFIDOrganizationSwitcher; }
|
|
26
26
|
});
|
|
27
27
|
Object.defineProperty(exports, "FFIDSubscriptionBadge", {
|
|
28
28
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunkIZSL6DI7_cjs.FFIDSubscriptionBadge; }
|
|
30
30
|
});
|
|
31
31
|
Object.defineProperty(exports, "FFIDUserMenu", {
|
|
32
32
|
enumerable: true,
|
|
33
|
-
get: function () { return
|
|
33
|
+
get: function () { return chunkIZSL6DI7_cjs.FFIDUserMenu; }
|
|
34
34
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-
|
|
1
|
+
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-DSvX4q8E.cjs';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-
|
|
1
|
+
export { M as FFIDAnnouncementBadge, al as FFIDAnnouncementBadgeClassNames, am as FFIDAnnouncementBadgeProps, N as FFIDAnnouncementList, an as FFIDAnnouncementListClassNames, ao as FFIDAnnouncementListProps, V as FFIDInquiryForm, W as FFIDInquiryFormCategoryItem, X as FFIDInquiryFormClassNames, Y as FFIDInquiryFormLegalLayout, Z as FFIDInquiryFormOrganization, _ as FFIDInquiryFormPlaceholderContext, $ as FFIDInquiryFormPrefill, a0 as FFIDInquiryFormProps, a1 as FFIDInquiryFormSubmitData, a2 as FFIDInquiryFormSubmitResult, a4 as FFIDLoginButton, ap as FFIDLoginButtonProps, a7 as FFIDOrganizationSwitcher, aq as FFIDOrganizationSwitcherClassNames, ar as FFIDOrganizationSwitcherProps, ac as FFIDSubscriptionBadge, as as FFIDSubscriptionBadgeClassNames, at as FFIDSubscriptionBadgeProps, ae as FFIDUserMenu, au as FFIDUserMenuClassNames, av as FFIDUserMenuProps } from '../index-DSvX4q8E.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
package/dist/components/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-
|
|
1
|
+
export { FFIDAnnouncementBadge, FFIDAnnouncementList, FFIDInquiryForm, FFIDLoginButton, FFIDOrganizationSwitcher, FFIDSubscriptionBadge, FFIDUserMenu } from '../chunk-OJ3OJTIE.js';
|