@funnelsgrove/runtime 0.7.28 → 0.7.30
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/runtime/funnel-answer-draft.d.ts +11 -0
- package/dist/runtime/funnel-answer-draft.js +82 -0
- package/dist/runtime/offer-set-runtime.d.ts +5 -0
- package/dist/runtime/use-funnel-flow-controller.js +70 -36
- package/dist/services/api.service.d.ts +1 -0
- package/dist/services/api.service.js +3 -2
- package/dist/services/funnel-runtime-config.js +15 -1
- package/dist/services/funnel-sdk.service.d.ts +1 -0
- package/dist/services/funnel-sdk.service.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FunnelUserAnswers } from '../sdk/userAnswers.js';
|
|
2
|
+
type FunnelAnswerDraftScope = {
|
|
3
|
+
funnelId: string | null | undefined;
|
|
4
|
+
funnelVersionId: string | null | undefined;
|
|
5
|
+
userId: string | null | undefined;
|
|
6
|
+
};
|
|
7
|
+
export declare const buildFunnelAnswerDraftStorageKey: (scope: FunnelAnswerDraftScope) => string | null;
|
|
8
|
+
export declare const readFunnelAnswerDraft: (scope: FunnelAnswerDraftScope, nowMs?: number) => FunnelUserAnswers | null;
|
|
9
|
+
export declare const writeFunnelAnswerDraft: (scope: FunnelAnswerDraftScope, answers: FunnelUserAnswers, nowMs?: number) => boolean;
|
|
10
|
+
export declare const clearFunnelAnswerDraft: (scope: FunnelAnswerDraftScope) => void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const ANSWER_DRAFT_VERSION = 1;
|
|
2
|
+
const ANSWER_DRAFT_TTL_MS = 14 * 24 * 60 * 60 * 1000;
|
|
3
|
+
const MAX_ANSWER_DRAFT_BYTES = 65536;
|
|
4
|
+
const asNonEmptyPart = (value) => {
|
|
5
|
+
const normalized = value === null || value === void 0 ? void 0 : value.trim();
|
|
6
|
+
return normalized || null;
|
|
7
|
+
};
|
|
8
|
+
const isRecord = (value) => (Boolean(value) && typeof value === 'object' && !Array.isArray(value));
|
|
9
|
+
export const buildFunnelAnswerDraftStorageKey = (scope) => {
|
|
10
|
+
const funnelId = asNonEmptyPart(scope.funnelId);
|
|
11
|
+
const funnelVersionId = asNonEmptyPart(scope.funnelVersionId);
|
|
12
|
+
const userId = asNonEmptyPart(scope.userId);
|
|
13
|
+
if (!funnelId || !funnelVersionId || !userId) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return `funnel:${funnelId}:${funnelVersionId}:${userId}:answer-draft`;
|
|
17
|
+
};
|
|
18
|
+
export const readFunnelAnswerDraft = (scope, nowMs = Date.now()) => {
|
|
19
|
+
const key = buildFunnelAnswerDraftStorageKey(scope);
|
|
20
|
+
if (!key || typeof window === 'undefined') {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const raw = window.localStorage.getItem(key);
|
|
25
|
+
if (!raw) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const parsed = JSON.parse(raw);
|
|
29
|
+
if (parsed.version !== ANSWER_DRAFT_VERSION
|
|
30
|
+
|| typeof parsed.updatedAt !== 'number'
|
|
31
|
+
|| !Number.isFinite(parsed.updatedAt)
|
|
32
|
+
|| parsed.updatedAt > nowMs
|
|
33
|
+
|| nowMs - parsed.updatedAt > ANSWER_DRAFT_TTL_MS
|
|
34
|
+
|| !isRecord(parsed.answers)) {
|
|
35
|
+
window.localStorage.removeItem(key);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return parsed.answers;
|
|
39
|
+
}
|
|
40
|
+
catch (_a) {
|
|
41
|
+
try {
|
|
42
|
+
window.localStorage.removeItem(key);
|
|
43
|
+
}
|
|
44
|
+
catch (_b) {
|
|
45
|
+
// Storage may be unavailable in privacy-constrained browser contexts.
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
export const writeFunnelAnswerDraft = (scope, answers, nowMs = Date.now()) => {
|
|
51
|
+
const key = buildFunnelAnswerDraftStorageKey(scope);
|
|
52
|
+
if (!key || typeof window === 'undefined' || !isRecord(answers)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const serialized = JSON.stringify({
|
|
57
|
+
version: ANSWER_DRAFT_VERSION,
|
|
58
|
+
updatedAt: nowMs,
|
|
59
|
+
answers,
|
|
60
|
+
});
|
|
61
|
+
if (new TextEncoder().encode(serialized).byteLength > MAX_ANSWER_DRAFT_BYTES) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
window.localStorage.setItem(key, serialized);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch (_a) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
export const clearFunnelAnswerDraft = (scope) => {
|
|
72
|
+
const key = buildFunnelAnswerDraftStorageKey(scope);
|
|
73
|
+
if (!key || typeof window === 'undefined') {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
window.localStorage.removeItem(key);
|
|
78
|
+
}
|
|
79
|
+
catch (_a) {
|
|
80
|
+
// Storage may be unavailable in privacy-constrained browser contexts.
|
|
81
|
+
}
|
|
82
|
+
};
|
|
@@ -56,10 +56,15 @@ export type GeneratedOfferSetDiscount = {
|
|
|
56
56
|
readonly position?: number | null;
|
|
57
57
|
readonly metadata?: Record<string, unknown> | null;
|
|
58
58
|
};
|
|
59
|
+
export type GeneratedOfferSetPaymentProviderModeConfig = {
|
|
60
|
+
readonly provider?: 'stripe' | 'solidgate' | null;
|
|
61
|
+
readonly stripePublishableKey?: string | null;
|
|
62
|
+
};
|
|
59
63
|
export type GeneratedOfferSet = {
|
|
60
64
|
readonly id?: string | null;
|
|
61
65
|
readonly key: string;
|
|
62
66
|
readonly paymentProfileId?: string | null;
|
|
67
|
+
readonly paymentProviderConfigByMode?: Partial<Record<RuntimeMode, GeneratedOfferSetPaymentProviderModeConfig>> | null;
|
|
63
68
|
readonly isActive?: boolean | null;
|
|
64
69
|
readonly metadata?: Record<string, unknown> | null;
|
|
65
70
|
readonly items: readonly GeneratedOfferSetPlanItem[];
|
|
@@ -4,7 +4,7 @@ import { useFunnelRuntimeConfig } from '../components/FunnelRuntimeConfigBoundar
|
|
|
4
4
|
import { writeStepChoice } from '../sdk/userAnswers.js';
|
|
5
5
|
import { apiService } from '../services/api.service.js';
|
|
6
6
|
import { logger } from '../services/logger.js';
|
|
7
|
-
import { FUNNEL_ID, POSTHOG_API_HOST, POSTHOG_PROJECT_API_KEY, PROJECT_ID, } from '../services/runtime-api.config.js';
|
|
7
|
+
import { FUNNEL_ID, FUNNEL_VERSION_ID, POSTHOG_API_HOST, POSTHOG_PROJECT_API_KEY, PROJECT_ID, } from '../services/runtime-api.config.js';
|
|
8
8
|
import { buildHostedStepLocation, dispatchWindowCustomEvent, updateFunnelHistory, } from './browser-helpers.js';
|
|
9
9
|
import { isPreviewStepLockRequested, resolveNextStepFromContext, shouldRunAutoAdvanceTimer, } from './funnel-flow.js';
|
|
10
10
|
import { usePreviewBridge } from './preview-bridge.js';
|
|
@@ -19,6 +19,7 @@ import { isDevelopmentRuntime } from '../config/env.config.js';
|
|
|
19
19
|
import { consumeChoiceCompletionMarker, enforceChoiceBypassGuard, registerInternalChoiceCommit, runAtomicChoiceCommit, } from './use-step-choices.js';
|
|
20
20
|
import { createFunnelStepLifecycleState, finishVisit, startVisit, } from './funnel-step-lifecycle.js';
|
|
21
21
|
import { createEmailCaptureSingleFlight, submitEmailCapture as submitEmailCapturePrimitive, } from './submit-email-capture.js';
|
|
22
|
+
import { clearFunnelAnswerDraft, readFunnelAnswerDraft, writeFunnelAnswerDraft, } from './funnel-answer-draft.js';
|
|
22
23
|
const isTerminalCompletion = (stepMeta, outcome) => {
|
|
23
24
|
var _a;
|
|
24
25
|
return (outcome.type === 'complete'
|
|
@@ -322,14 +323,25 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
322
323
|
}, [initialStepId, resolveFallbackStepId, resolveRuntimeInitialStepId]);
|
|
323
324
|
const isSubscriptionManagementRuntime = ((_g = stepById[safeInitialStepId]) === null || _g === void 0 ? void 0 : _g.kind) === 'manage-subscription';
|
|
324
325
|
const lifecycleEventsSuppressed = isPreviewRuntime || editorModeEnabled || isSubscriptionManagementRuntime;
|
|
326
|
+
const [initialRuntimeIdentity] = useState(() => {
|
|
327
|
+
const urlAttributes = resolveUrlUserAttributes();
|
|
328
|
+
const clientUserId = isSubscriptionManagementRuntime
|
|
329
|
+
? urlAttributes.userId || ''
|
|
330
|
+
: api.getOrCreateClientUserId();
|
|
331
|
+
return { clientUserId, urlAttributes };
|
|
332
|
+
});
|
|
325
333
|
const [activeStepId, setActiveStepId] = useState(safeInitialStepId);
|
|
326
|
-
const [attributes, setAttributes] = useState(() => (Object.assign({}, (
|
|
334
|
+
const [attributes, setAttributes] = useState(() => (Object.assign(Object.assign({}, (isSubscriptionManagementRuntime || isPreviewRuntime
|
|
335
|
+
? {}
|
|
336
|
+
: readFunnelAnswerDraft({
|
|
337
|
+
funnelId: FUNNEL_ID,
|
|
338
|
+
funnelVersionId: FUNNEL_VERSION_ID,
|
|
339
|
+
userId: initialRuntimeIdentity.clientUserId,
|
|
340
|
+
}) || {})), (initialAttributes || {}))));
|
|
327
341
|
const [user, setUser] = useState(() => ({
|
|
328
|
-
id:
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
name: '',
|
|
332
|
-
email: '',
|
|
342
|
+
id: initialRuntimeIdentity.clientUserId,
|
|
343
|
+
name: initialRuntimeIdentity.urlAttributes.name || '',
|
|
344
|
+
email: initialRuntimeIdentity.urlAttributes.email || '',
|
|
333
345
|
attributes: {},
|
|
334
346
|
document: {},
|
|
335
347
|
completedSteps: [],
|
|
@@ -353,6 +365,7 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
353
365
|
const stepLifecycleStateRef = useRef(createFunnelStepLifecycleState());
|
|
354
366
|
const activeVisitTokenRef = useRef(null);
|
|
355
367
|
const emailCaptureSingleFlightRef = useRef(createEmailCaptureSingleFlight());
|
|
368
|
+
const answersCommittedRef = useRef(false);
|
|
356
369
|
const pendingEmailCaptureNavigationRef = useRef(null);
|
|
357
370
|
const appliedInitialStepIdRef = useRef(safeInitialStepId);
|
|
358
371
|
const safeActiveStepId = useMemo(() => { var _a; return (_a = resolveRenderableStepId(activeStepId)) !== null && _a !== void 0 ? _a : safeInitialStepId; }, [activeStepId, resolveRenderableStepId, safeInitialStepId]);
|
|
@@ -474,6 +487,16 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
474
487
|
useEffect(() => {
|
|
475
488
|
attributesRef.current = attributes;
|
|
476
489
|
}, [attributes]);
|
|
490
|
+
useEffect(() => {
|
|
491
|
+
if (isPreviewRuntime || isSubscriptionManagementRuntime || answersCommittedRef.current) {
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
writeFunnelAnswerDraft({
|
|
495
|
+
funnelId: FUNNEL_ID,
|
|
496
|
+
funnelVersionId: FUNNEL_VERSION_ID,
|
|
497
|
+
userId: user.id,
|
|
498
|
+
}, attributes);
|
|
499
|
+
}, [attributes, isPreviewRuntime, isSubscriptionManagementRuntime, user.id]);
|
|
477
500
|
useEffect(() => {
|
|
478
501
|
postHogFeatureFlagsRef.current = postHogFeatureFlags;
|
|
479
502
|
}, [postHogFeatureFlags]);
|
|
@@ -522,12 +545,12 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
522
545
|
setPostHogReady(true);
|
|
523
546
|
return;
|
|
524
547
|
}
|
|
525
|
-
const localUserId =
|
|
548
|
+
const localUserId = initialRuntimeIdentity.clientUserId;
|
|
526
549
|
const bootstrapCandidateUserId = api.getBootstrapCandidateUserId(localUserId);
|
|
527
550
|
const initialAttribution = collectCurrentFunnelAttribution();
|
|
528
551
|
initialAttributionRef.current = initialAttribution;
|
|
529
552
|
setUserBootstrapped(isPreviewRuntime);
|
|
530
|
-
setUser((prev) => (Object.assign(Object.assign({}, prev), { id: localUserId })));
|
|
553
|
+
setUser((prev) => (Object.assign(Object.assign({}, prev), { id: localUserId, name: prev.name || urlUserAttributes.name || '', email: prev.email || urlUserAttributes.email || '' })));
|
|
531
554
|
if (isPreviewRuntime) {
|
|
532
555
|
return;
|
|
533
556
|
}
|
|
@@ -551,8 +574,6 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
551
574
|
const sessionBootstrap = api
|
|
552
575
|
.bootstrapSession({
|
|
553
576
|
userId: bootstrapCandidateUserId || localUserId,
|
|
554
|
-
email: urlUserAttributes.email || undefined,
|
|
555
|
-
name: urlUserAttributes.name || undefined,
|
|
556
577
|
attribution: initialAttribution,
|
|
557
578
|
})
|
|
558
579
|
.then((sessionUser) => {
|
|
@@ -560,8 +581,13 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
560
581
|
const sessionAttributes = Object.keys(sessionUser.attributes || {}).length > 0
|
|
561
582
|
? sessionUser.attributes
|
|
562
583
|
: null;
|
|
563
|
-
|
|
564
|
-
|
|
584
|
+
const sessionDraft = readFunnelAnswerDraft({
|
|
585
|
+
funnelId: FUNNEL_ID,
|
|
586
|
+
funnelVersionId: FUNNEL_VERSION_ID,
|
|
587
|
+
userId: sessionUser.id,
|
|
588
|
+
});
|
|
589
|
+
if (sessionAttributes || sessionDraft) {
|
|
590
|
+
setAttributes((prev) => (Object.assign(Object.assign(Object.assign({}, (sessionAttributes || {})), (sessionDraft || {})), prev)));
|
|
565
591
|
}
|
|
566
592
|
initialAttributionRef.current = resolveFunnelEventAttribution(sessionUser.document, initialAttribution);
|
|
567
593
|
setUser((prev) => (Object.assign(Object.assign({}, prev), { id: sessionUser.id || prev.id, name: sessionUser.name || prev.name, email: sessionUser.email || prev.email, document: sessionUser.document, attributes: sessionAttributes ? Object.assign(Object.assign({}, sessionAttributes), prev.attributes) : prev.attributes })));
|
|
@@ -602,6 +628,7 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
602
628
|
return cancelAttributionFailOpen;
|
|
603
629
|
}, [
|
|
604
630
|
api,
|
|
631
|
+
initialRuntimeIdentity.clientUserId,
|
|
605
632
|
isPreviewRuntime,
|
|
606
633
|
isSubscriptionManagementRuntime,
|
|
607
634
|
sessionReplayEnabled,
|
|
@@ -640,25 +667,9 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
640
667
|
const completionAttributes = Object.assign({}, attributesRef.current);
|
|
641
668
|
dispatchWindowCustomEvent('funnel:step-completed', record);
|
|
642
669
|
setUser((prev) => {
|
|
643
|
-
var _a
|
|
670
|
+
var _a;
|
|
644
671
|
const updatedSteps = [...((_a = prev.completedSteps) !== null && _a !== void 0 ? _a : []), record];
|
|
645
672
|
const updatedUser = Object.assign(Object.assign({}, prev), { attributes: Object.assign(Object.assign({}, prev.attributes), completionAttributes), document: prev.document, completedSteps: updatedSteps });
|
|
646
|
-
if (!isPreviewRuntime) {
|
|
647
|
-
api
|
|
648
|
-
.updateUser({
|
|
649
|
-
id: updatedUser.id,
|
|
650
|
-
name: updatedUser.name,
|
|
651
|
-
email: updatedUser.email,
|
|
652
|
-
attributes: Object.assign(Object.assign({}, updatedUser.attributes), { completedSteps: updatedSteps }),
|
|
653
|
-
document: (_b = updatedUser.document) !== null && _b !== void 0 ? _b : {},
|
|
654
|
-
}, {
|
|
655
|
-
attribution: collectCurrentFunnelAttribution(),
|
|
656
|
-
persistClientIdentity: false,
|
|
657
|
-
})
|
|
658
|
-
.catch((error) => {
|
|
659
|
-
logger.error('Failed to persist step completion:', error);
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
673
|
return updatedUser;
|
|
663
674
|
});
|
|
664
675
|
if (!isPreviewRuntime) {
|
|
@@ -670,7 +681,7 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
670
681
|
logger.error('Failed to track step completion:', error);
|
|
671
682
|
}
|
|
672
683
|
}
|
|
673
|
-
}, [analytics,
|
|
684
|
+
}, [analytics, attributionReady, isPreviewRuntime, lifecycleEventsSuppressed, stepById, stepContractVersion]);
|
|
674
685
|
const emitStepExit = useCallback((intent) => {
|
|
675
686
|
var _a;
|
|
676
687
|
const meta = stepById[intent.visit.stepId];
|
|
@@ -785,11 +796,33 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
785
796
|
pendingEmailCaptureNavigationRef.current = null;
|
|
786
797
|
return true;
|
|
787
798
|
},
|
|
788
|
-
persist: (normalizedEmail) =>
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
799
|
+
persist: async (normalizedEmail) => {
|
|
800
|
+
const result = await api.captureEmail({
|
|
801
|
+
userId: submittedUserId,
|
|
802
|
+
email: normalizedEmail,
|
|
803
|
+
environment: getRuntimeMode(),
|
|
804
|
+
answers: Object.assign({}, attributesRef.current),
|
|
805
|
+
});
|
|
806
|
+
answersCommittedRef.current = true;
|
|
807
|
+
clearFunnelAnswerDraft({
|
|
808
|
+
funnelId: FUNNEL_ID,
|
|
809
|
+
funnelVersionId: FUNNEL_VERSION_ID,
|
|
810
|
+
userId: submittedUserId,
|
|
811
|
+
});
|
|
812
|
+
clearFunnelAnswerDraft({
|
|
813
|
+
funnelId: FUNNEL_ID,
|
|
814
|
+
funnelVersionId: FUNNEL_VERSION_ID,
|
|
815
|
+
userId: initialRuntimeIdentity.clientUserId,
|
|
816
|
+
});
|
|
817
|
+
if (result.canonicalUser) {
|
|
818
|
+
clearFunnelAnswerDraft({
|
|
819
|
+
funnelId: FUNNEL_ID,
|
|
820
|
+
funnelVersionId: FUNNEL_VERSION_ID,
|
|
821
|
+
userId: result.canonicalUser.id,
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
return result;
|
|
825
|
+
},
|
|
793
826
|
applyUser: (capturedUser) => {
|
|
794
827
|
setIsReturningSubscriber(false);
|
|
795
828
|
currentUserIdRef.current = capturedUser.id;
|
|
@@ -855,6 +888,7 @@ export function useFunnelFlowController({ api = apiService, analytics, stepContr
|
|
|
855
888
|
api,
|
|
856
889
|
analytics,
|
|
857
890
|
claimActiveVisit,
|
|
891
|
+
initialRuntimeIdentity.clientUserId,
|
|
858
892
|
isFunnelStepId,
|
|
859
893
|
isPreviewRuntime,
|
|
860
894
|
navigateToStep,
|
|
@@ -253,8 +253,8 @@ class ApiService {
|
|
|
253
253
|
async bootstrapSession(input) {
|
|
254
254
|
var _a, _b, _c;
|
|
255
255
|
const urlUserAttributes = resolveUrlUserAttributes();
|
|
256
|
-
const inputEmail = (input === null || input === void 0 ? void 0 : input.email) ||
|
|
257
|
-
const inputName = (input === null || input === void 0 ? void 0 : input.name) ||
|
|
256
|
+
const inputEmail = (input === null || input === void 0 ? void 0 : input.email) || undefined;
|
|
257
|
+
const inputName = (input === null || input === void 0 ? void 0 : input.name) || undefined;
|
|
258
258
|
const candidateUserId = (input === null || input === void 0 ? void 0 : input.userId) || urlUserAttributes.userId;
|
|
259
259
|
const userId = await this.resolveBootstrapUserId(candidateUserId);
|
|
260
260
|
const publishableKey = getFunnelSdkPublishableKey();
|
|
@@ -344,6 +344,7 @@ class ApiService {
|
|
|
344
344
|
userId,
|
|
345
345
|
email,
|
|
346
346
|
environment: input.environment,
|
|
347
|
+
answers: input.answers,
|
|
347
348
|
});
|
|
348
349
|
const eventId = asString(payload.eventId);
|
|
349
350
|
const responseUser = isRecord(payload.user) ? payload.user : null;
|
|
@@ -149,8 +149,22 @@ const normalizePublishedOfferSets = (config) => {
|
|
|
149
149
|
? { oldPriceLabel: pickString(item, 'oldPriceLabel', 'old_price_label') }
|
|
150
150
|
: {})), { isDefault: (_a = pickBoolean(item, 'isDefault', 'is_default')) !== null && _a !== void 0 ? _a : false, providerMappingsByMode: Object.assign(Object.assign({}, (testMapping ? { test: testMapping } : {})), (liveMapping ? { live: liveMapping } : {})), metadata });
|
|
151
151
|
});
|
|
152
|
-
|
|
152
|
+
const rawPaymentProviderConfigByMode = pick(offerSet, 'paymentProviderConfigByMode', 'payment_provider_config_by_mode');
|
|
153
|
+
const paymentProviderConfigByMode = isRecord(rawPaymentProviderConfigByMode)
|
|
154
|
+
? Object.fromEntries(['test', 'live'].flatMap((mode) => {
|
|
155
|
+
const rawModeConfig = rawPaymentProviderConfigByMode[mode];
|
|
156
|
+
if (!isRecord(rawModeConfig)) {
|
|
157
|
+
return [];
|
|
158
|
+
}
|
|
159
|
+
const provider = parsePaymentProvider(pick(rawModeConfig, 'provider'), `Published runtime offer set "${key}" ${mode} payment provider config`);
|
|
160
|
+
const stripePublishableKey = pickString(rawModeConfig, 'stripePublishableKey', 'stripe_publishable_key');
|
|
161
|
+
return [[mode, Object.assign(Object.assign({}, (provider ? { provider } : {})), (stripePublishableKey ? { stripePublishableKey } : {}))]];
|
|
162
|
+
}))
|
|
163
|
+
: {};
|
|
164
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (pickString(offerSet, 'id') ? { id: pickString(offerSet, 'id') } : {})), { key }), (pickString(offerSet, 'paymentProfileId', 'payment_profile_id')
|
|
153
165
|
? { paymentProfileId: pickString(offerSet, 'paymentProfileId', 'payment_profile_id') }
|
|
166
|
+
: {})), (Object.keys(paymentProviderConfigByMode).length > 0
|
|
167
|
+
? { paymentProviderConfigByMode }
|
|
154
168
|
: {})), { isActive: (_a = pickBoolean(offerSet, 'isActive', 'is_active')) !== null && _a !== void 0 ? _a : true, metadata: isRecord(offerSet.metadata) ? offerSet.metadata : {}, items });
|
|
155
169
|
});
|
|
156
170
|
};
|