@funnelsgrove/runtime 0.1.5 → 0.1.7
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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/runtime/funnel-attribution.js +1 -1
- package/dist/runtime/url-user-attributes.d.ts +6 -0
- package/dist/runtime/url-user-attributes.js +30 -5
- package/dist/runtime/use-funnel-flow-controller.js +4 -0
- package/dist/runtime/use-url-user-attributes-sync.d.ts +13 -0
- package/dist/runtime/use-url-user-attributes-sync.js +54 -0
- package/dist/services/api.service.js +15 -50
- package/dist/services/public-env.d.ts +2 -0
- package/dist/services/public-env.js +85 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from './runtime/preview-definition-overrides.js';
|
|
|
17
17
|
export * from './runtime/route-resolver.js';
|
|
18
18
|
export * from './runtime/subscription-handoff.js';
|
|
19
19
|
export * from './runtime/url-user-attributes.js';
|
|
20
|
+
export * from './runtime/use-url-user-attributes-sync.js';
|
|
20
21
|
export * from './services/api.service.js';
|
|
21
22
|
export * from './services/funnel-state.service.js';
|
|
22
23
|
export * from './services/logger.js';
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export * from './runtime/preview-definition-overrides.js';
|
|
|
17
17
|
export * from './runtime/route-resolver.js';
|
|
18
18
|
export * from './runtime/subscription-handoff.js';
|
|
19
19
|
export * from './runtime/url-user-attributes.js';
|
|
20
|
+
export * from './runtime/use-url-user-attributes-sync.js';
|
|
20
21
|
export * from './services/api.service.js';
|
|
21
22
|
export * from './services/funnel-state.service.js';
|
|
22
23
|
export * from './services/logger.js';
|
|
@@ -194,7 +194,7 @@ export const collectCurrentFunnelAttribution = (input = {}) => {
|
|
|
194
194
|
language,
|
|
195
195
|
platform,
|
|
196
196
|
vendor,
|
|
197
|
-
timeZone, deviceType: resolveDeviceType(userAgent), osFamily: resolveOsFamily(userAgent) }, posthogContext)),
|
|
197
|
+
timeZone, capturedAt: new Date().toISOString(), deviceType: resolveDeviceType(userAgent), osFamily: resolveOsFamily(userAgent) }, posthogContext)),
|
|
198
198
|
};
|
|
199
199
|
};
|
|
200
200
|
export const mergeFunnelUserAttribution = (current, incoming) => {
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import type { FunnelUserAnswers } from '../sdk/userAnswers.js';
|
|
2
2
|
export type UrlUserAttributes = {
|
|
3
|
+
userId: string | null;
|
|
3
4
|
email: string | null;
|
|
5
|
+
name: string | null;
|
|
6
|
+
stripeCustomerId: string | null;
|
|
4
7
|
};
|
|
5
8
|
export type UrlUserAttributeUser = {
|
|
6
9
|
email: string;
|
|
10
|
+
name: string;
|
|
7
11
|
attributes?: FunnelUserAnswers;
|
|
8
12
|
document?: Record<string, unknown>;
|
|
9
13
|
};
|
|
10
14
|
export declare function normalizeUrlUserEmail(value: string | null | undefined): string | null;
|
|
15
|
+
export declare function normalizeUrlUserAttribute(value: string | null | undefined): string | null;
|
|
11
16
|
export declare function resolveUrlUserAttributes(search?: string): UrlUserAttributes;
|
|
12
17
|
export declare function hasUrlUserAttributes(urlAttributes: UrlUserAttributes | null | undefined): boolean;
|
|
18
|
+
export declare function hasUrlUserProfileAttributes(urlAttributes: UrlUserAttributes | null | undefined): boolean;
|
|
13
19
|
export declare function applyUrlUserAttributesToUser<TUser extends UrlUserAttributeUser>(input: {
|
|
14
20
|
user: TUser;
|
|
15
21
|
attributes?: FunnelUserAnswers;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
const EMAIL_QUERY_KEY = 'email';
|
|
2
|
+
const USER_ID_QUERY_KEY = 'user_id';
|
|
3
|
+
const STRIPE_CUSTOMER_ID_QUERY_KEY = 'stripe_customer_id';
|
|
4
|
+
const NAME_QUERY_KEYS = ['name', 'fullName', 'full_name'];
|
|
2
5
|
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
3
6
|
export function normalizeUrlUserEmail(value) {
|
|
4
7
|
const email = value === null || value === void 0 ? void 0 : value.trim();
|
|
@@ -7,32 +10,54 @@ export function normalizeUrlUserEmail(value) {
|
|
|
7
10
|
}
|
|
8
11
|
return email;
|
|
9
12
|
}
|
|
13
|
+
export function normalizeUrlUserAttribute(value) {
|
|
14
|
+
const normalized = value === null || value === void 0 ? void 0 : value.trim();
|
|
15
|
+
return normalized || null;
|
|
16
|
+
}
|
|
10
17
|
export function resolveUrlUserAttributes(search) {
|
|
18
|
+
var _a;
|
|
11
19
|
if (typeof window === 'undefined' && typeof search !== 'string') {
|
|
12
20
|
return {
|
|
21
|
+
userId: null,
|
|
13
22
|
email: null,
|
|
23
|
+
name: null,
|
|
24
|
+
stripeCustomerId: null,
|
|
14
25
|
};
|
|
15
26
|
}
|
|
16
27
|
try {
|
|
17
28
|
const params = new URLSearchParams(search !== null && search !== void 0 ? search : window.location.search);
|
|
29
|
+
const name = (_a = NAME_QUERY_KEYS.map((key) => normalizeUrlUserAttribute(params.get(key))).find(Boolean)) !== null && _a !== void 0 ? _a : null;
|
|
18
30
|
return {
|
|
31
|
+
userId: normalizeUrlUserAttribute(params.get(USER_ID_QUERY_KEY)),
|
|
19
32
|
email: normalizeUrlUserEmail(params.get(EMAIL_QUERY_KEY)),
|
|
33
|
+
name,
|
|
34
|
+
stripeCustomerId: normalizeUrlUserAttribute(params.get(STRIPE_CUSTOMER_ID_QUERY_KEY)),
|
|
20
35
|
};
|
|
21
36
|
}
|
|
22
|
-
catch (
|
|
37
|
+
catch (_b) {
|
|
23
38
|
return {
|
|
39
|
+
userId: null,
|
|
24
40
|
email: null,
|
|
41
|
+
name: null,
|
|
42
|
+
stripeCustomerId: null,
|
|
25
43
|
};
|
|
26
44
|
}
|
|
27
45
|
}
|
|
28
46
|
export function hasUrlUserAttributes(urlAttributes) {
|
|
29
|
-
return Boolean(urlAttributes === null || urlAttributes === void 0 ? void 0 : urlAttributes.
|
|
47
|
+
return Boolean((urlAttributes === null || urlAttributes === void 0 ? void 0 : urlAttributes.userId) ||
|
|
48
|
+
(urlAttributes === null || urlAttributes === void 0 ? void 0 : urlAttributes.email) ||
|
|
49
|
+
(urlAttributes === null || urlAttributes === void 0 ? void 0 : urlAttributes.name) ||
|
|
50
|
+
(urlAttributes === null || urlAttributes === void 0 ? void 0 : urlAttributes.stripeCustomerId));
|
|
51
|
+
}
|
|
52
|
+
export function hasUrlUserProfileAttributes(urlAttributes) {
|
|
53
|
+
return Boolean((urlAttributes === null || urlAttributes === void 0 ? void 0 : urlAttributes.email) || (urlAttributes === null || urlAttributes === void 0 ? void 0 : urlAttributes.name));
|
|
30
54
|
}
|
|
31
55
|
export function applyUrlUserAttributesToUser(input) {
|
|
32
|
-
var _a, _b, _c, _d;
|
|
56
|
+
var _a, _b, _c, _d, _e;
|
|
33
57
|
const email = (_a = input.urlAttributes) === null || _a === void 0 ? void 0 : _a.email;
|
|
34
|
-
|
|
58
|
+
const name = (_b = input.urlAttributes) === null || _b === void 0 ? void 0 : _b.name;
|
|
59
|
+
if (!email && !name) {
|
|
35
60
|
return input.user;
|
|
36
61
|
}
|
|
37
|
-
return Object.assign(Object.assign({}, input.user), { email, attributes: Object.assign(Object.assign({}, ((
|
|
62
|
+
return Object.assign(Object.assign({}, input.user), { email: email !== null && email !== void 0 ? email : input.user.email, name: name !== null && name !== void 0 ? name : input.user.name, attributes: Object.assign(Object.assign({}, ((_c = input.attributes) !== null && _c !== void 0 ? _c : {})), ((_d = input.user.attributes) !== null && _d !== void 0 ? _d : {})), document: (_e = input.user.document) !== null && _e !== void 0 ? _e : {} });
|
|
38
63
|
}
|
|
@@ -9,6 +9,7 @@ import { isPreviewStepLockRequested, resolveNextStepFromContext, shouldRunAutoAd
|
|
|
9
9
|
import { usePreviewBridge } from './preview-bridge.js';
|
|
10
10
|
import { resolveExperimentAssignment } from './experiment-assignment.js';
|
|
11
11
|
import { collectCurrentFunnelAttribution } from './funnel-attribution.js';
|
|
12
|
+
import { resolveUrlUserAttributes } from './url-user-attributes.js';
|
|
12
13
|
import { bootstrapPostHog, getPostHog, identifyPostHog, isPostHogReady, resolveExperimentVariant, } from './posthog-flags.js';
|
|
13
14
|
import { isEditorEnabled, useRuntimeMode } from '../services/runtime-mode.service.js';
|
|
14
15
|
import { isPreviewFrameRuntime } from '../services/preview-frame.service.js';
|
|
@@ -244,6 +245,7 @@ export function useFunnelFlowController({ initialStepId, lockToInitialStep = fal
|
|
|
244
245
|
}, [goToStep, resolveNextStepId, safeActiveStepId]);
|
|
245
246
|
useEffect(() => {
|
|
246
247
|
const localUserId = apiService.getOrCreateClientUserId();
|
|
248
|
+
const urlUserAttributes = resolveUrlUserAttributes();
|
|
247
249
|
const bootstrapCandidateUserId = apiService.getBootstrapCandidateUserId(localUserId);
|
|
248
250
|
const initialAttribution = collectCurrentFunnelAttribution();
|
|
249
251
|
setUser((prev) => (Object.assign(Object.assign({}, prev), { id: localUserId })));
|
|
@@ -263,6 +265,8 @@ export function useFunnelFlowController({ initialStepId, lockToInitialStep = fal
|
|
|
263
265
|
const sessionBootstrap = apiService
|
|
264
266
|
.bootstrapSession({
|
|
265
267
|
userId: bootstrapCandidateUserId || localUserId,
|
|
268
|
+
email: urlUserAttributes.email || undefined,
|
|
269
|
+
name: urlUserAttributes.name || undefined,
|
|
266
270
|
attribution: initialAttribution,
|
|
267
271
|
})
|
|
268
272
|
.then((sessionUser) => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FunnelUser } from '../components/FunnelContext.js';
|
|
2
|
+
import type { FunnelUserAnswers } from '../sdk/userAnswers.js';
|
|
3
|
+
import { type FunnelUserAttribution } from './funnel-attribution.js';
|
|
4
|
+
import { type UrlUserAttributes } from './url-user-attributes.js';
|
|
5
|
+
export type UseUrlUserAttributesSyncInput = {
|
|
6
|
+
user: FunnelUser;
|
|
7
|
+
attributes: FunnelUserAnswers;
|
|
8
|
+
setUser: (user: FunnelUser) => void;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
urlAttributes?: UrlUserAttributes | null;
|
|
11
|
+
getAttribution?: () => FunnelUserAttribution;
|
|
12
|
+
};
|
|
13
|
+
export declare function useUrlUserAttributesSync({ user, attributes, setUser, disabled, urlAttributes, getAttribution, }: UseUrlUserAttributesSyncInput): UrlUserAttributes;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
3
|
+
import { apiService } from '../services/api.service.js';
|
|
4
|
+
import { logger } from '../services/logger.js';
|
|
5
|
+
import { collectCurrentFunnelAttribution, } from './funnel-attribution.js';
|
|
6
|
+
import { applyUrlUserAttributesToUser, hasUrlUserProfileAttributes, resolveUrlUserAttributes, } from './url-user-attributes.js';
|
|
7
|
+
export function useUrlUserAttributesSync({ user, attributes, setUser, disabled = false, urlAttributes, getAttribution = collectCurrentFunnelAttribution, }) {
|
|
8
|
+
const resolvedUrlAttributes = useMemo(() => urlAttributes !== null && urlAttributes !== void 0 ? urlAttributes : resolveUrlUserAttributes(), [urlAttributes]);
|
|
9
|
+
const syncedUrlUserAttributesRef = useRef(null);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
if (disabled || !hasUrlUserProfileAttributes(resolvedUrlAttributes)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const nextUser = applyUrlUserAttributesToUser({
|
|
16
|
+
user,
|
|
17
|
+
attributes,
|
|
18
|
+
urlAttributes: resolvedUrlAttributes,
|
|
19
|
+
});
|
|
20
|
+
const currentEmail = user.email.trim();
|
|
21
|
+
const nextEmail = nextUser.email.trim();
|
|
22
|
+
const currentName = user.name.trim();
|
|
23
|
+
const nextName = nextUser.name.trim();
|
|
24
|
+
if (currentEmail !== nextEmail || currentName !== nextName) {
|
|
25
|
+
setUser(nextUser);
|
|
26
|
+
}
|
|
27
|
+
const syncKey = [
|
|
28
|
+
nextUser.id,
|
|
29
|
+
(_a = resolvedUrlAttributes.email) !== null && _a !== void 0 ? _a : '',
|
|
30
|
+
(_b = resolvedUrlAttributes.name) !== null && _b !== void 0 ? _b : '',
|
|
31
|
+
].join(':');
|
|
32
|
+
if (syncedUrlUserAttributesRef.current === syncKey) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
syncedUrlUserAttributesRef.current = syncKey;
|
|
36
|
+
apiService
|
|
37
|
+
.syncUrlUserAttributes({
|
|
38
|
+
user: nextUser,
|
|
39
|
+
attributes,
|
|
40
|
+
urlAttributes: resolvedUrlAttributes,
|
|
41
|
+
attribution: getAttribution(),
|
|
42
|
+
})
|
|
43
|
+
.then((updatedUser) => {
|
|
44
|
+
if (updatedUser) {
|
|
45
|
+
setUser(updatedUser);
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
.catch((error) => {
|
|
49
|
+
syncedUrlUserAttributesRef.current = null;
|
|
50
|
+
logger.error('Failed to persist URL attributes onto funnel user:', error);
|
|
51
|
+
});
|
|
52
|
+
}, [attributes, disabled, getAttribution, resolvedUrlAttributes, setUser, user]);
|
|
53
|
+
return resolvedUrlAttributes;
|
|
54
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { buildMainApiUrl, buildSdkHeaders, FUNNEL_ID, FUNNEL_VERSION_ID, getFunnelSdkPublishableKey, } from './runtime-api.config.js';
|
|
2
2
|
import { mergeFunnelUserAttribution, } from '../runtime/funnel-attribution.js';
|
|
3
|
-
import { applyUrlUserAttributesToUser,
|
|
3
|
+
import { applyUrlUserAttributesToUser, hasUrlUserProfileAttributes, resolveUrlUserAttributes, } from '../runtime/url-user-attributes.js';
|
|
4
4
|
const DEFAULT_USER_ID_STORAGE_KEY = 'funnel:user-id';
|
|
5
|
-
const LOCATION_USER_ID_QUERY_KEYS = ['user_id'];
|
|
6
|
-
const LOCATION_STRIPE_CUSTOMER_ID_QUERY_KEYS = ['stripe_customer_id'];
|
|
7
5
|
const canUseDom = () => {
|
|
8
6
|
return typeof window !== 'undefined';
|
|
9
7
|
};
|
|
@@ -63,42 +61,6 @@ const persistUserId = (value, funnelId = FUNNEL_ID) => {
|
|
|
63
61
|
}
|
|
64
62
|
return normalized;
|
|
65
63
|
};
|
|
66
|
-
const readLocationUserId = () => {
|
|
67
|
-
if (!canUseDom()) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
try {
|
|
71
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
72
|
-
for (const key of LOCATION_USER_ID_QUERY_KEYS) {
|
|
73
|
-
const candidate = normalizeUserId(searchParams.get(key));
|
|
74
|
-
if (candidate) {
|
|
75
|
-
return candidate;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
catch (_a) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
return null;
|
|
83
|
-
};
|
|
84
|
-
const readLocationStripeCustomerId = () => {
|
|
85
|
-
if (!canUseDom()) {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
90
|
-
for (const key of LOCATION_STRIPE_CUSTOMER_ID_QUERY_KEYS) {
|
|
91
|
-
const candidate = asString(searchParams.get(key));
|
|
92
|
-
if (candidate) {
|
|
93
|
-
return candidate;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch (_a) {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
return null;
|
|
101
|
-
};
|
|
102
64
|
const buildSdkEvent = (event) => {
|
|
103
65
|
return {
|
|
104
66
|
eventType: event.eventType,
|
|
@@ -178,7 +140,7 @@ class ApiService {
|
|
|
178
140
|
return persistUserId(generateUserId(), FUNNEL_ID);
|
|
179
141
|
}
|
|
180
142
|
getSubscriptionManagementUserId() {
|
|
181
|
-
const locationUserId =
|
|
143
|
+
const locationUserId = resolveUrlUserAttributes().userId;
|
|
182
144
|
if (locationUserId) {
|
|
183
145
|
return persistUserId(locationUserId, FUNNEL_ID);
|
|
184
146
|
}
|
|
@@ -188,10 +150,10 @@ class ApiService {
|
|
|
188
150
|
return this.getOrCreateClientUserId();
|
|
189
151
|
}
|
|
190
152
|
getSubscriptionManagementStripeCustomerId() {
|
|
191
|
-
return
|
|
153
|
+
return resolveUrlUserAttributes().stripeCustomerId;
|
|
192
154
|
}
|
|
193
155
|
getBootstrapCandidateUserId(fallbackUserId) {
|
|
194
|
-
return
|
|
156
|
+
return resolveUrlUserAttributes().userId || normalizeUserId(fallbackUserId);
|
|
195
157
|
}
|
|
196
158
|
async fetchCurrentUserState(userId) {
|
|
197
159
|
const publishableKey = getFunnelSdkPublishableKey();
|
|
@@ -236,13 +198,16 @@ class ApiService {
|
|
|
236
198
|
}
|
|
237
199
|
async bootstrapSession(input) {
|
|
238
200
|
var _a;
|
|
239
|
-
const
|
|
201
|
+
const urlUserAttributes = resolveUrlUserAttributes();
|
|
202
|
+
const inputEmail = (input === null || input === void 0 ? void 0 : input.email) || urlUserAttributes.email || undefined;
|
|
203
|
+
const inputName = (input === null || input === void 0 ? void 0 : input.name) || urlUserAttributes.name || undefined;
|
|
204
|
+
const userId = await this.resolveBootstrapUserId((input === null || input === void 0 ? void 0 : input.userId) || urlUserAttributes.userId);
|
|
240
205
|
const publishableKey = getFunnelSdkPublishableKey();
|
|
241
206
|
if (!publishableKey) {
|
|
242
207
|
return toAppUser({
|
|
243
208
|
userId,
|
|
244
|
-
fallbackName:
|
|
245
|
-
fallbackEmail:
|
|
209
|
+
fallbackName: inputName,
|
|
210
|
+
fallbackEmail: inputEmail,
|
|
246
211
|
fallbackDocument: withMergedAttributionDocument({}, input === null || input === void 0 ? void 0 : input.attribution),
|
|
247
212
|
});
|
|
248
213
|
}
|
|
@@ -256,8 +221,8 @@ class ApiService {
|
|
|
256
221
|
funnelId: FUNNEL_ID || undefined,
|
|
257
222
|
funnelVersionId: FUNNEL_VERSION_ID || undefined,
|
|
258
223
|
user_id: userId,
|
|
259
|
-
email:
|
|
260
|
-
fullName:
|
|
224
|
+
email: inputEmail,
|
|
225
|
+
fullName: inputName,
|
|
261
226
|
metadata: {
|
|
262
227
|
source: 'funnel-session',
|
|
263
228
|
},
|
|
@@ -275,8 +240,8 @@ class ApiService {
|
|
|
275
240
|
return toAppUser({
|
|
276
241
|
apiUser: payload.user,
|
|
277
242
|
userId: persistedUserId,
|
|
278
|
-
fallbackName:
|
|
279
|
-
fallbackEmail:
|
|
243
|
+
fallbackName: inputName,
|
|
244
|
+
fallbackEmail: inputEmail,
|
|
280
245
|
fallbackDocument: withMergedAttributionDocument({}, input === null || input === void 0 ? void 0 : input.attribution),
|
|
281
246
|
});
|
|
282
247
|
}
|
|
@@ -329,7 +294,7 @@ class ApiService {
|
|
|
329
294
|
}
|
|
330
295
|
async syncUrlUserAttributes(input) {
|
|
331
296
|
var _a;
|
|
332
|
-
if (!
|
|
297
|
+
if (!hasUrlUserProfileAttributes(input.urlAttributes)) {
|
|
333
298
|
return null;
|
|
334
299
|
}
|
|
335
300
|
const nextUser = applyUrlUserAttributesToUser({
|
|
@@ -64,6 +64,8 @@ export declare const RUNTIME_PUBLIC_DEFAULTS: {
|
|
|
64
64
|
export declare const RUNTIME_PREVIEW_PAYMENT_DEFAULTS: {
|
|
65
65
|
readonly funnelSdkPublishableKey: "pk_test_51SopXWPEfkEVo5kh6foOs9zVyKsVSKLhlQw8YsAfMMymRlGH3Qp8U5I7j5bHivmOB232oJiQZi8cEv1wkmV80QGg00vPcI1DZI";
|
|
66
66
|
};
|
|
67
|
+
export type RuntimeStaticExportEnv = Record<string, string | undefined>;
|
|
68
|
+
export declare const resolveNextStaticExportRuntimeEnv: (env: RuntimeStaticExportEnv) => Record<string, string>;
|
|
67
69
|
export declare const isSeedFunnelSdkPublishableKey: (value: string | null | undefined) => boolean;
|
|
68
70
|
export declare const isPreviewPaymentPublishableKey: (value: string | null | undefined) => boolean;
|
|
69
71
|
export declare const resolvePreviewPaymentPublishableKey: (value: string | null | undefined) => string;
|
|
@@ -89,6 +89,91 @@ export const RUNTIME_PUBLIC_DEFAULTS = {
|
|
|
89
89
|
export const RUNTIME_PREVIEW_PAYMENT_DEFAULTS = {
|
|
90
90
|
funnelSdkPublishableKey: DEFAULT_PREVIEW_PAYMENT_PUBLISHABLE_KEY,
|
|
91
91
|
};
|
|
92
|
+
const NEXT_STATIC_EXPORT_RUNTIME_PUBLIC_KEYS = [
|
|
93
|
+
{
|
|
94
|
+
outputKey: 'NEXT_PUBLIC_APP_DEALS_API_BASE_URL',
|
|
95
|
+
inputKeys: ['NEXT_PUBLIC_APP_DEALS_API_BASE_URL'],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
outputKey: 'NEXT_PUBLIC_FUNNEL_PUBLISHABLE_KEY',
|
|
99
|
+
inputKeys: [
|
|
100
|
+
'NEXT_PUBLIC_FUNNEL_PUBLISHABLE_KEY',
|
|
101
|
+
'NEXT_PUBLIC_FUNNEL_SDK_PUBLISHABLE_KEY',
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_ID', inputKeys: ['NEXT_PUBLIC_FUNNEL_ID'] },
|
|
105
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_VERSION_ID', inputKeys: ['NEXT_PUBLIC_FUNNEL_VERSION_ID'] },
|
|
106
|
+
{ outputKey: 'NEXT_PUBLIC_PROJECT_ID', inputKeys: ['NEXT_PUBLIC_PROJECT_ID'] },
|
|
107
|
+
{
|
|
108
|
+
outputKey: 'NEXT_PUBLIC_POSTHOG_PROJECT_API_KEY',
|
|
109
|
+
inputKeys: ['NEXT_PUBLIC_POSTHOG_PROJECT_API_KEY'],
|
|
110
|
+
},
|
|
111
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_SUPPORT_EMAIL', inputKeys: ['NEXT_PUBLIC_FUNNEL_SUPPORT_EMAIL'] },
|
|
112
|
+
{ outputKey: 'NEXT_PUBLIC_IOS_APP_STORE_URL', inputKeys: ['NEXT_PUBLIC_IOS_APP_STORE_URL'] },
|
|
113
|
+
{ outputKey: 'NEXT_PUBLIC_ANDROID_PLAY_STORE_URL', inputKeys: ['NEXT_PUBLIC_ANDROID_PLAY_STORE_URL'] },
|
|
114
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_APP_STORE_ID', inputKeys: ['NEXT_PUBLIC_FUNNEL_APP_STORE_ID'] },
|
|
115
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_GOOGLE_STORE_ID', inputKeys: ['NEXT_PUBLIC_FUNNEL_GOOGLE_STORE_ID'] },
|
|
116
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_TIMEZONE', inputKeys: ['NEXT_PUBLIC_FUNNEL_TIMEZONE'] },
|
|
117
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_FAVICON_URL', inputKeys: ['NEXT_PUBLIC_FUNNEL_FAVICON_URL'] },
|
|
118
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_PAGE_TITLE', inputKeys: ['NEXT_PUBLIC_FUNNEL_PAGE_TITLE'] },
|
|
119
|
+
{
|
|
120
|
+
outputKey: 'NEXT_PUBLIC_FUNNEL_PAGE_DESCRIPTION',
|
|
121
|
+
inputKeys: ['NEXT_PUBLIC_FUNNEL_PAGE_DESCRIPTION'],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
outputKey: 'NEXT_PUBLIC_FUNNEL_PAGE_PREVIEW_IMAGE_URL',
|
|
125
|
+
inputKeys: ['NEXT_PUBLIC_FUNNEL_PAGE_PREVIEW_IMAGE_URL'],
|
|
126
|
+
},
|
|
127
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_COMPANY_NAME', inputKeys: ['NEXT_PUBLIC_FUNNEL_COMPANY_NAME'] },
|
|
128
|
+
{
|
|
129
|
+
outputKey: 'NEXT_PUBLIC_FUNNEL_COMPANY_ADDRESS',
|
|
130
|
+
inputKeys: ['NEXT_PUBLIC_FUNNEL_COMPANY_ADDRESS'],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
outputKey: 'NEXT_PUBLIC_FUNNEL_COMPANY_COUNTRY',
|
|
134
|
+
inputKeys: ['NEXT_PUBLIC_FUNNEL_COMPANY_COUNTRY'],
|
|
135
|
+
},
|
|
136
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_PRIVACY_URL', inputKeys: ['NEXT_PUBLIC_FUNNEL_PRIVACY_URL'] },
|
|
137
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_TERMS_URL', inputKeys: ['NEXT_PUBLIC_FUNNEL_TERMS_URL'] },
|
|
138
|
+
{
|
|
139
|
+
outputKey: 'NEXT_PUBLIC_FUNNEL_UNIVERSAL_LINK',
|
|
140
|
+
inputKeys: ['NEXT_PUBLIC_FUNNEL_UNIVERSAL_LINK'],
|
|
141
|
+
},
|
|
142
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_IOS_DEEP_LINK', inputKeys: ['NEXT_PUBLIC_FUNNEL_IOS_DEEP_LINK'] },
|
|
143
|
+
{
|
|
144
|
+
outputKey: 'NEXT_PUBLIC_FUNNEL_ANDROID_DEEP_LINK',
|
|
145
|
+
inputKeys: ['NEXT_PUBLIC_FUNNEL_ANDROID_DEEP_LINK'],
|
|
146
|
+
},
|
|
147
|
+
{ outputKey: 'NEXT_PUBLIC_FUNNEL_QR_TARGET', inputKeys: ['NEXT_PUBLIC_FUNNEL_QR_TARGET'] },
|
|
148
|
+
{ outputKey: 'NEXT_PUBLIC_META_PIXEL_ENABLED', inputKeys: ['NEXT_PUBLIC_META_PIXEL_ENABLED'] },
|
|
149
|
+
{ outputKey: 'NEXT_PUBLIC_META_PIXEL_ID', inputKeys: ['NEXT_PUBLIC_META_PIXEL_ID'] },
|
|
150
|
+
];
|
|
151
|
+
const readNonEmptyStaticExportEnv = (env, keys) => {
|
|
152
|
+
var _a;
|
|
153
|
+
for (const key of keys) {
|
|
154
|
+
const value = ((_a = env[key]) === null || _a === void 0 ? void 0 : _a.trim()) || '';
|
|
155
|
+
if (value) {
|
|
156
|
+
return value;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
};
|
|
161
|
+
export const resolveNextStaticExportRuntimeEnv = (env) => {
|
|
162
|
+
var _a, _b;
|
|
163
|
+
if (env.NEXT_EXPORT !== '1') {
|
|
164
|
+
return {};
|
|
165
|
+
}
|
|
166
|
+
if ((_a = env.NEXT_PUBLIC_PROJECT_ID) === null || _a === void 0 ? void 0 : _a.trim()) {
|
|
167
|
+
return Object.fromEntries(NEXT_STATIC_EXPORT_RUNTIME_PUBLIC_KEYS.flatMap(({ outputKey, inputKeys }) => {
|
|
168
|
+
const value = readNonEmptyStaticExportEnv(env, inputKeys);
|
|
169
|
+
return value ? [[outputKey, value]] : [];
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
NEXT_PUBLIC_FUNNEL_PUBLISHABLE_KEY: DEFAULT_PREVIEW_PAYMENT_PUBLISHABLE_KEY,
|
|
174
|
+
NEXT_PUBLIC_FUNNEL_ID: ((_b = env.NEXT_PUBLIC_RAG_FUNNEL_ID) === null || _b === void 0 ? void 0 : _b.trim()) || '',
|
|
175
|
+
};
|
|
176
|
+
};
|
|
92
177
|
export const isSeedFunnelSdkPublishableKey = (value) => {
|
|
93
178
|
const normalized = (value === null || value === void 0 ? void 0 : value.trim()) || '';
|
|
94
179
|
return !normalized || normalized === DEFAULT_FUNNEL_SDK_PUBLISHABLE_KEY;
|