@amplifyup/sdk 0.1.22 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -38
- package/dist/AmplifyRenderer.d.mts +1 -1
- package/dist/AmplifyRenderer.d.ts +1 -1
- package/dist/AmplifyRenderer.js +172 -18
- package/dist/AmplifyRenderer.js.map +1 -1
- package/dist/AmplifyRenderer.mjs +173 -19
- package/dist/AmplifyRenderer.mjs.map +1 -1
- package/dist/index.d.mts +117 -6
- package/dist/index.d.ts +117 -6
- package/dist/index.js +285 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +280 -15
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +24 -3
- package/dist/react.d.ts +24 -3
- package/dist/react.js +476 -47
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +477 -49
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +26 -8
- package/dist/server.d.ts +26 -8
- package/dist/server.js +277 -20
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +277 -21
- package/dist/server.mjs.map +1 -1
- package/dist/{types-Cy5aWQ5c.d.mts → types-BxpG9Gsy.d.mts} +37 -2
- package/dist/{types-Cy5aWQ5c.d.ts → types-BxpG9Gsy.d.ts} +37 -2
- package/package.json +6 -3
package/dist/react.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var marked = require('marked');
|
|
6
7
|
|
|
7
8
|
/* @amplifyup/sdk - https://amplifyup.ai */
|
|
8
9
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -153,17 +154,42 @@ var AWSAdapter = class {
|
|
|
153
154
|
};
|
|
154
155
|
this.sendEvent("/v1/track", eventData);
|
|
155
156
|
}
|
|
156
|
-
identify(
|
|
157
|
+
identify(userIdOrIdentifiers, traits = {}) {
|
|
157
158
|
if (!this.initialized) {
|
|
158
159
|
console.warn("AmplifyUp SDK: Not initialized. Call init() first.");
|
|
159
160
|
return;
|
|
160
161
|
}
|
|
162
|
+
const isMap = userIdOrIdentifiers !== null && typeof userIdOrIdentifiers === "object" && !Array.isArray(userIdOrIdentifiers);
|
|
163
|
+
const identifiers = isMap ? userIdOrIdentifiers : traits.identifiers;
|
|
164
|
+
const userId = isMap ? void 0 : String(userIdOrIdentifiers);
|
|
161
165
|
const eventData = {
|
|
162
166
|
type: "identify",
|
|
163
|
-
userId,
|
|
164
167
|
anonymousId: traits.instanceId,
|
|
165
168
|
traits: {
|
|
166
|
-
...traits
|
|
169
|
+
...traits,
|
|
170
|
+
...identifiers ? { identifiers } : {}
|
|
171
|
+
},
|
|
172
|
+
...identifiers ? { identifiers } : {},
|
|
173
|
+
...userId ? { userId } : {},
|
|
174
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
175
|
+
};
|
|
176
|
+
this.sendEvent("/v1/track", eventData);
|
|
177
|
+
}
|
|
178
|
+
setProfileFields(fields, context = {}) {
|
|
179
|
+
if (!this.initialized) {
|
|
180
|
+
console.warn("AmplifyUp SDK: Not initialized. Call init() first.");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const eventData = {
|
|
184
|
+
type: "set_fields",
|
|
185
|
+
anonymousId: context.instanceId,
|
|
186
|
+
fields,
|
|
187
|
+
traits: {
|
|
188
|
+
instanceId: context.instanceId,
|
|
189
|
+
trackingId: context.trackingId
|
|
190
|
+
},
|
|
191
|
+
properties: {
|
|
192
|
+
trackingId: context.trackingId
|
|
167
193
|
},
|
|
168
194
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
169
195
|
};
|
|
@@ -225,6 +251,7 @@ function clearIds() {
|
|
|
225
251
|
var AWS_DEV_API = "https://api-dev.amplifyup.ai";
|
|
226
252
|
var AWS_PROD_API = "https://api.amplifyup.ai";
|
|
227
253
|
var PROD_ORCHESTRATOR = "https://amplifyup.ai";
|
|
254
|
+
var PROD_EDGE = "https://edge.amplifyup.ai";
|
|
228
255
|
function isAmplifyUpTarget(value) {
|
|
229
256
|
return value === "local" || value === "dev" || value === "production";
|
|
230
257
|
}
|
|
@@ -260,6 +287,10 @@ function localAwsApiUrl() {
|
|
|
260
287
|
const fromEnv = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL : void 0;
|
|
261
288
|
return (fromEnv || AWS_DEV_API).replace(/\/$/, "");
|
|
262
289
|
}
|
|
290
|
+
function localEdgeUrl() {
|
|
291
|
+
const fromEnv = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_EDGE_URL : void 0;
|
|
292
|
+
return (fromEnv || "http://localhost:8787").replace(/\/$/, "");
|
|
293
|
+
}
|
|
263
294
|
function resolveAmplifyUpUrls(target) {
|
|
264
295
|
if (target === "local") {
|
|
265
296
|
const orchestratorUrl2 = localOrchestratorUrl();
|
|
@@ -270,18 +301,22 @@ function resolveAmplifyUpUrls(target) {
|
|
|
270
301
|
orchestratorUrl: orchestratorUrl2,
|
|
271
302
|
// Events + personalize → AWS development stack
|
|
272
303
|
apiGatewayUrl,
|
|
273
|
-
decisionApiUrl: `${apiGatewayUrl}/v1/personalize
|
|
304
|
+
decisionApiUrl: `${apiGatewayUrl}/v1/personalize`,
|
|
305
|
+
edgeUrl: localEdgeUrl()
|
|
274
306
|
};
|
|
275
307
|
}
|
|
276
308
|
const resolvedApi = typeof process !== "undefined" && process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL?.replace(/\/$/, "") || AWS_PROD_API;
|
|
277
309
|
const orchestratorFromEnv = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL : void 0;
|
|
278
310
|
const isLocalOrchestrator = !!orchestratorFromEnv && (orchestratorFromEnv.includes("localhost") || orchestratorFromEnv.includes("127.0.0.1"));
|
|
279
311
|
const orchestratorUrl = isLocalOrchestrator || !orchestratorFromEnv ? PROD_ORCHESTRATOR : orchestratorFromEnv.replace(/\/$/, "");
|
|
312
|
+
const edgeFromEnv = typeof process !== "undefined" ? process.env.NEXT_PUBLIC_EDGE_URL?.replace(/\/$/, "") : void 0;
|
|
313
|
+
const edgeUrl = edgeFromEnv && !edgeFromEnv.includes("localhost") && !edgeFromEnv.includes("127.0.0.1") ? edgeFromEnv : PROD_EDGE;
|
|
280
314
|
return {
|
|
281
315
|
target: "production",
|
|
282
316
|
apiGatewayUrl: resolvedApi,
|
|
283
317
|
orchestratorUrl,
|
|
284
|
-
decisionApiUrl: `${resolvedApi}/v1/personalize
|
|
318
|
+
decisionApiUrl: `${resolvedApi}/v1/personalize`,
|
|
319
|
+
edgeUrl
|
|
285
320
|
};
|
|
286
321
|
}
|
|
287
322
|
|
|
@@ -311,6 +346,177 @@ function isComposerPreview() {
|
|
|
311
346
|
return false;
|
|
312
347
|
}
|
|
313
348
|
|
|
349
|
+
// src/edge/normalizeRoute.ts
|
|
350
|
+
function normalizeRoute(route) {
|
|
351
|
+
let path = String(route || "").trim();
|
|
352
|
+
if (!path) return "/";
|
|
353
|
+
try {
|
|
354
|
+
if (/^https?:\/\//i.test(path)) {
|
|
355
|
+
path = new URL(path).pathname;
|
|
356
|
+
}
|
|
357
|
+
} catch {
|
|
358
|
+
}
|
|
359
|
+
const q = path.indexOf("?");
|
|
360
|
+
if (q >= 0) path = path.slice(0, q);
|
|
361
|
+
const h = path.indexOf("#");
|
|
362
|
+
if (h >= 0) path = path.slice(0, h);
|
|
363
|
+
if (!path.startsWith("/")) path = `/${path}`;
|
|
364
|
+
if (path.length > 1 && path.endsWith("/")) {
|
|
365
|
+
path = path.replace(/\/+$/, "");
|
|
366
|
+
}
|
|
367
|
+
return path || "/";
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// src/edge/resolve.ts
|
|
371
|
+
var EdgeResolveError = class extends Error {
|
|
372
|
+
constructor(message, status, body) {
|
|
373
|
+
super(message);
|
|
374
|
+
this.name = "EdgeResolveError";
|
|
375
|
+
this.status = status;
|
|
376
|
+
this.body = body;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
async function fetchEdgeResolve(options) {
|
|
380
|
+
const base = options.edgeUrl.replace(/\/+$/, "");
|
|
381
|
+
const route = normalizeRoute(options.route);
|
|
382
|
+
const params = new URLSearchParams({
|
|
383
|
+
route,
|
|
384
|
+
trackingId: options.trackingId
|
|
385
|
+
});
|
|
386
|
+
if (options.siteId) params.set("site", options.siteId);
|
|
387
|
+
if (options.anonId) params.set("anonId", options.anonId);
|
|
388
|
+
const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
389
|
+
const res = await fetchFn(`${base}/v1/resolve?${params.toString()}`, {
|
|
390
|
+
method: "GET",
|
|
391
|
+
headers: { Accept: "application/json" }
|
|
392
|
+
});
|
|
393
|
+
const body = await res.json().catch(() => ({}));
|
|
394
|
+
if (!res.ok) {
|
|
395
|
+
throw new EdgeResolveError(
|
|
396
|
+
(body && typeof body === "object" && "error" in body ? String(body.error) : `Edge resolve failed (${res.status})`) || `Edge resolve failed (${res.status})`,
|
|
397
|
+
res.status,
|
|
398
|
+
body
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
return body;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// src/edge/mapResolvedToPageConfig.ts
|
|
405
|
+
function mapResolvedComponent(node) {
|
|
406
|
+
const slots = [];
|
|
407
|
+
if (node.children) {
|
|
408
|
+
for (const [slotId, kids] of Object.entries(node.children)) {
|
|
409
|
+
slots.push({
|
|
410
|
+
slotId,
|
|
411
|
+
children: (kids || []).map(mapResolvedComponent)
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
id: node.instanceId,
|
|
417
|
+
componentId: node.componentId,
|
|
418
|
+
props: { ...node.props || {} },
|
|
419
|
+
...slots.length > 0 ? { slots } : {},
|
|
420
|
+
_contentSource: "edge"
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
function mapResolvedToPageConfig(payload) {
|
|
424
|
+
let layoutTree = [];
|
|
425
|
+
if (payload.tree && payload.tree.length > 0) {
|
|
426
|
+
layoutTree = payload.tree.map(mapResolvedComponent);
|
|
427
|
+
} else {
|
|
428
|
+
const zoneIds = Object.keys(payload.zones || {}).sort();
|
|
429
|
+
for (const zoneId of zoneIds) {
|
|
430
|
+
const roots = payload.zones[zoneId] || [];
|
|
431
|
+
layoutTree.push(...roots.map(mapResolvedComponent));
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
id: `edge:${payload.siteId}:${payload.route}:v${payload.version}`,
|
|
436
|
+
route: payload.route,
|
|
437
|
+
title: "",
|
|
438
|
+
layoutTree,
|
|
439
|
+
meta: {
|
|
440
|
+
// Stash edge meta for diagnostics (not visitor-facing)
|
|
441
|
+
description: payload.meta?.degraded ? "degraded" : void 0
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
function collectDegraded(payload) {
|
|
446
|
+
if (payload.meta?.degraded) return true;
|
|
447
|
+
const walk = (nodes) => nodes.some(
|
|
448
|
+
(n) => !!n.degraded || (n.children ? Object.values(n.children).some((kids) => walk(kids || [])) : false)
|
|
449
|
+
);
|
|
450
|
+
if (payload.tree && walk(payload.tree)) return true;
|
|
451
|
+
return Object.values(payload.zones || {}).some((roots) => walk(roots || []));
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/content/fetchContent.ts
|
|
455
|
+
async function fetchContent(options) {
|
|
456
|
+
const preview = options.preview ?? (typeof window !== "undefined" ? isComposerPreview() : false);
|
|
457
|
+
if (preview) {
|
|
458
|
+
try {
|
|
459
|
+
const page = await options.fetchOrchestratorPage(options.route, true);
|
|
460
|
+
return {
|
|
461
|
+
pageConfig: page,
|
|
462
|
+
source: "orchestrator",
|
|
463
|
+
meta: { source: "orchestrator" },
|
|
464
|
+
error: null
|
|
465
|
+
};
|
|
466
|
+
} catch (err) {
|
|
467
|
+
return {
|
|
468
|
+
pageConfig: null,
|
|
469
|
+
source: "orchestrator",
|
|
470
|
+
meta: { source: "orchestrator" },
|
|
471
|
+
error: err instanceof Error ? err.message : "Failed to load preview"
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
const payload = await fetchEdgeResolve({
|
|
477
|
+
edgeUrl: options.edgeUrl,
|
|
478
|
+
trackingId: options.trackingId,
|
|
479
|
+
route: options.route,
|
|
480
|
+
anonId: options.anonId,
|
|
481
|
+
siteId: options.siteId,
|
|
482
|
+
fetch: options.fetchFn
|
|
483
|
+
});
|
|
484
|
+
const pageConfig = mapResolvedToPageConfig(payload);
|
|
485
|
+
const degraded = collectDegraded(payload);
|
|
486
|
+
return {
|
|
487
|
+
pageConfig,
|
|
488
|
+
source: "edge",
|
|
489
|
+
meta: {
|
|
490
|
+
source: "edge",
|
|
491
|
+
version: payload.version,
|
|
492
|
+
siteId: payload.siteId,
|
|
493
|
+
variantKeys: payload.meta?.variantKeys,
|
|
494
|
+
degraded,
|
|
495
|
+
audienceLookup: payload.meta?.audienceLookup,
|
|
496
|
+
decideLookup: payload.meta?.decideLookup,
|
|
497
|
+
resolvedAt: payload.meta?.resolvedAt
|
|
498
|
+
},
|
|
499
|
+
error: null
|
|
500
|
+
};
|
|
501
|
+
} catch (err) {
|
|
502
|
+
if (err instanceof EdgeResolveError && err.status === 404) {
|
|
503
|
+
return {
|
|
504
|
+
pageConfig: null,
|
|
505
|
+
source: "edge",
|
|
506
|
+
meta: { source: "edge" },
|
|
507
|
+
error: null
|
|
508
|
+
// unpublished → site fallback, not an error banner
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
pageConfig: null,
|
|
513
|
+
source: "edge",
|
|
514
|
+
meta: { source: "edge" },
|
|
515
|
+
error: err instanceof Error ? err.message : "Couldn't load page content."
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
314
520
|
// src/index.ts
|
|
315
521
|
var SESSION_IDLE_GAP_MS = 30 * 60 * 1e3;
|
|
316
522
|
function readPreviewQueryOverrides() {
|
|
@@ -340,6 +546,8 @@ var AmplifyUpSDK = class {
|
|
|
340
546
|
this.apiGatewayUrl = "";
|
|
341
547
|
this.orchestratorUrl = "";
|
|
342
548
|
this.decisionApiUrl = "";
|
|
549
|
+
this.edgeUrl = "";
|
|
550
|
+
this.siteId = "";
|
|
343
551
|
this.target = "local";
|
|
344
552
|
this.initialized = false;
|
|
345
553
|
/** Prevents overlapping init() from React Strict Mode double-mount */
|
|
@@ -496,7 +704,8 @@ var AmplifyUpSDK = class {
|
|
|
496
704
|
isInitialized: () => this.isInitialized(),
|
|
497
705
|
page: (url, properties) => this.page(url, properties),
|
|
498
706
|
track: (eventName, properties) => this.track(eventName, properties),
|
|
499
|
-
identify: (
|
|
707
|
+
identify: (userIdOrIdentifiers, traits) => this.identify(userIdOrIdentifiers, traits),
|
|
708
|
+
setProfileFields: (fields) => this.setProfileFields(fields)
|
|
500
709
|
};
|
|
501
710
|
}
|
|
502
711
|
async performInit(config) {
|
|
@@ -511,6 +720,8 @@ var AmplifyUpSDK = class {
|
|
|
511
720
|
this.apiGatewayUrl = urls.apiGatewayUrl;
|
|
512
721
|
this.orchestratorUrl = urls.orchestratorUrl;
|
|
513
722
|
this.decisionApiUrl = urls.decisionApiUrl;
|
|
723
|
+
this.edgeUrl = urls.edgeUrl;
|
|
724
|
+
this.siteId = config.siteId || "";
|
|
514
725
|
const previewOverrides = readPreviewQueryOverrides();
|
|
515
726
|
if (previewOverrides.orchestratorUrl) {
|
|
516
727
|
this.orchestratorUrl = previewOverrides.orchestratorUrl;
|
|
@@ -519,6 +730,7 @@ var AmplifyUpSDK = class {
|
|
|
519
730
|
this.target = "production";
|
|
520
731
|
this.apiGatewayUrl = prodUrls.apiGatewayUrl;
|
|
521
732
|
this.decisionApiUrl = prodUrls.decisionApiUrl;
|
|
733
|
+
this.edgeUrl = prodUrls.edgeUrl;
|
|
522
734
|
}
|
|
523
735
|
}
|
|
524
736
|
this.config = {
|
|
@@ -526,7 +738,8 @@ var AmplifyUpSDK = class {
|
|
|
526
738
|
debug: config.debug ?? true,
|
|
527
739
|
// Enable debug by default
|
|
528
740
|
target: this.target,
|
|
529
|
-
dev: config.dev
|
|
741
|
+
dev: config.dev,
|
|
742
|
+
...config.siteId ? { siteId: config.siteId } : {}
|
|
530
743
|
};
|
|
531
744
|
try {
|
|
532
745
|
const adapterConfig = {
|
|
@@ -924,12 +1137,17 @@ var AmplifyUpSDK = class {
|
|
|
924
1137
|
});
|
|
925
1138
|
}
|
|
926
1139
|
/**
|
|
927
|
-
* Identify
|
|
1140
|
+
* Identify a visitor.
|
|
1141
|
+
* - identify('user_123') — bare string; server maps via org default type
|
|
1142
|
+
* - identify({ email: '...', crm_id: '...' }) — explicit types
|
|
1143
|
+
* - identify('user_123', traits) — legacy form
|
|
928
1144
|
*/
|
|
929
|
-
identify(
|
|
1145
|
+
identify(userIdOrIdentifiers, traits) {
|
|
930
1146
|
if (this.isPreviewMode()) {
|
|
931
1147
|
if (this.config?.debug) {
|
|
932
|
-
console.log("AmplifyUp SDK: Identify tracking disabled in preview mode", {
|
|
1148
|
+
console.log("AmplifyUp SDK: Identify tracking disabled in preview mode", {
|
|
1149
|
+
userIdOrIdentifiers
|
|
1150
|
+
});
|
|
933
1151
|
}
|
|
934
1152
|
return;
|
|
935
1153
|
}
|
|
@@ -945,10 +1163,45 @@ var AmplifyUpSDK = class {
|
|
|
945
1163
|
trackingId: this.config?.trackingId,
|
|
946
1164
|
...traits
|
|
947
1165
|
};
|
|
948
|
-
this.adapter.identify(
|
|
949
|
-
|
|
1166
|
+
this.adapter.identify(userIdOrIdentifiers, identifyTraits);
|
|
1167
|
+
if (typeof userIdOrIdentifiers === "string") {
|
|
1168
|
+
setUserId(userIdOrIdentifiers);
|
|
1169
|
+
}
|
|
950
1170
|
if (this.config?.debug) {
|
|
951
|
-
console.log("AmplifyUp SDK: User identified", {
|
|
1171
|
+
console.log("AmplifyUp SDK: User identified", {
|
|
1172
|
+
userIdOrIdentifiers,
|
|
1173
|
+
instanceId
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
/**
|
|
1178
|
+
* Set profile fields (partial update). Omitted keys are left alone;
|
|
1179
|
+
* an explicit empty value clears the field.
|
|
1180
|
+
*/
|
|
1181
|
+
setProfileFields(fields) {
|
|
1182
|
+
if (this.isPreviewMode()) {
|
|
1183
|
+
if (this.config?.debug) {
|
|
1184
|
+
console.log("AmplifyUp SDK: setProfileFields disabled in preview mode", {
|
|
1185
|
+
fields
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
if (!this.isInitialized()) {
|
|
1191
|
+
if (this.config?.debug) {
|
|
1192
|
+
console.warn("AmplifyUp SDK: Not initialized. setProfileFields not called.");
|
|
1193
|
+
}
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
const instanceId = getInstanceId();
|
|
1197
|
+
if (typeof this.adapter.setProfileFields === "function") {
|
|
1198
|
+
this.adapter.setProfileFields(fields, {
|
|
1199
|
+
instanceId: instanceId || void 0,
|
|
1200
|
+
trackingId: this.config?.trackingId
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
if (this.config?.debug) {
|
|
1204
|
+
console.log("AmplifyUp SDK: Profile fields set", { fields, instanceId });
|
|
952
1205
|
}
|
|
953
1206
|
}
|
|
954
1207
|
/**
|
|
@@ -1123,6 +1376,18 @@ Available Console Commands:
|
|
|
1123
1376
|
getDecisionApiUrl() {
|
|
1124
1377
|
return this.decisionApiUrl || void 0;
|
|
1125
1378
|
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Get Edge Worker URL (production content resolve)
|
|
1381
|
+
*/
|
|
1382
|
+
getEdgeUrl() {
|
|
1383
|
+
return this.edgeUrl || void 0;
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Optional site id from config (Edge can resolve via trackingId alone).
|
|
1387
|
+
*/
|
|
1388
|
+
getSiteId() {
|
|
1389
|
+
return this.siteId || this.config?.siteId || void 0;
|
|
1390
|
+
}
|
|
1126
1391
|
/**
|
|
1127
1392
|
* Build API URL for fetching page config from the Layout Provider
|
|
1128
1393
|
*/
|
|
@@ -2397,6 +2662,53 @@ function getSDK(adapter) {
|
|
|
2397
2662
|
var trackContentView = (contentId, contentType, properties) => getSDK().trackContentView(contentId, contentType, properties);
|
|
2398
2663
|
var refreshEventTracking = () => getSDK().refreshEventTracking();
|
|
2399
2664
|
getSDK();
|
|
2665
|
+
var ComponentRenderBoundary = class extends react.Component {
|
|
2666
|
+
constructor() {
|
|
2667
|
+
super(...arguments);
|
|
2668
|
+
this.state = { error: null };
|
|
2669
|
+
}
|
|
2670
|
+
static getDerivedStateFromError(error) {
|
|
2671
|
+
return { error };
|
|
2672
|
+
}
|
|
2673
|
+
componentDidCatch(error) {
|
|
2674
|
+
console.error(
|
|
2675
|
+
`[AmplifyRenderer] "${this.props.componentId}" (${this.props.nodeId}) threw while rendering:`,
|
|
2676
|
+
error
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2679
|
+
render() {
|
|
2680
|
+
if (this.state.error) {
|
|
2681
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2682
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2683
|
+
"div",
|
|
2684
|
+
{
|
|
2685
|
+
"data-amplifyup-render-error": "",
|
|
2686
|
+
"data-component-id": this.props.componentId,
|
|
2687
|
+
"data-node-id": this.props.nodeId,
|
|
2688
|
+
style: {
|
|
2689
|
+
margin: "1rem 0",
|
|
2690
|
+
padding: "0.75rem 1rem",
|
|
2691
|
+
border: "1px solid #fca5a5",
|
|
2692
|
+
borderRadius: "0.5rem",
|
|
2693
|
+
background: "#fef2f2",
|
|
2694
|
+
color: "#991b1b",
|
|
2695
|
+
fontSize: "0.875rem"
|
|
2696
|
+
},
|
|
2697
|
+
children: [
|
|
2698
|
+
'Component "',
|
|
2699
|
+
this.props.componentId,
|
|
2700
|
+
'" failed to render:',
|
|
2701
|
+
" ",
|
|
2702
|
+
this.state.error.message
|
|
2703
|
+
]
|
|
2704
|
+
}
|
|
2705
|
+
);
|
|
2706
|
+
}
|
|
2707
|
+
return null;
|
|
2708
|
+
}
|
|
2709
|
+
return this.props.children;
|
|
2710
|
+
}
|
|
2711
|
+
};
|
|
2400
2712
|
function AmplifyRenderer({
|
|
2401
2713
|
renderComponent,
|
|
2402
2714
|
pageConfig: serverPageConfig,
|
|
@@ -2409,6 +2721,7 @@ function AmplifyRenderer({
|
|
|
2409
2721
|
const pageConfig = serverPageConfig || clientHook.pageConfig || null;
|
|
2410
2722
|
const loading = serverPageConfig ? false : clientHook.loading;
|
|
2411
2723
|
const error = serverPageConfig ? null : clientHook.error;
|
|
2724
|
+
const contentSource = clientHook.source;
|
|
2412
2725
|
const [variantCache, setVariantCache] = react.useState({});
|
|
2413
2726
|
react.useEffect(() => {
|
|
2414
2727
|
if (typeof window !== "undefined") {
|
|
@@ -2550,6 +2863,9 @@ function AmplifyRenderer({
|
|
|
2550
2863
|
}, [pageConfig]);
|
|
2551
2864
|
react.useEffect(() => {
|
|
2552
2865
|
if (!pageConfig?.layoutTree || !pageConfig.layoutId) return;
|
|
2866
|
+
const roots = pageConfig.layoutTree;
|
|
2867
|
+
const fromEdge = contentSource === "edge" || roots.some((n) => n._contentSource === "edge");
|
|
2868
|
+
if (fromEdge) return;
|
|
2553
2869
|
const sdk = getSDK();
|
|
2554
2870
|
const instanceId = sdk.getInstanceId();
|
|
2555
2871
|
const decisionApiUrl = sdk.getDecisionApiUrl();
|
|
@@ -2644,7 +2960,7 @@ function AmplifyRenderer({
|
|
|
2644
2960
|
setVariantCache(newCache);
|
|
2645
2961
|
};
|
|
2646
2962
|
fetchVariants();
|
|
2647
|
-
}, [pageConfig?.layoutTree, pageConfig?.layoutId, pageConfig?.route]);
|
|
2963
|
+
}, [pageConfig?.layoutTree, pageConfig?.layoutId, pageConfig?.route, contentSource]);
|
|
2648
2964
|
if (loading) {
|
|
2649
2965
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: loadingComponent || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-screen bg-gray-50", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto px-4 py-16", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse", children: [
|
|
2650
2966
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 bg-gray-200 rounded w-1/4 mb-4" }),
|
|
@@ -2749,11 +3065,20 @@ function AmplifyRenderer({
|
|
|
2749
3065
|
const slotsToPass = Object.keys(slotChildren).length > 0 ? slotChildren : void 0;
|
|
2750
3066
|
console.log(`[AmplifyRenderer] Calling renderComponent for ${node.componentId}`, {
|
|
2751
3067
|
hasSlots: !!slotsToPass,
|
|
2752
|
-
slotKeys: slotsToPass ? Object.keys(slotsToPass) : []
|
|
3068
|
+
slotKeys: slotsToPass ? Object.keys(slotsToPass) : [],
|
|
3069
|
+
propKeys: Object.keys(node.props || {}),
|
|
3070
|
+
props: node.props || {}
|
|
2753
3071
|
});
|
|
2754
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-node-id": node.id, "data-amplifyup-node": "", children:
|
|
2755
|
-
|
|
2756
|
-
|
|
3072
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-node-id": node.id, "data-amplifyup-node": "", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3073
|
+
ComponentRenderBoundary,
|
|
3074
|
+
{
|
|
3075
|
+
componentId: node.componentId,
|
|
3076
|
+
nodeId: node.id,
|
|
3077
|
+
children: renderComponent(node.componentId, node.props || {}, slotsToPass, {
|
|
3078
|
+
layoutNodeId: node.id
|
|
3079
|
+
})
|
|
3080
|
+
}
|
|
3081
|
+
) });
|
|
2757
3082
|
};
|
|
2758
3083
|
const rawTree = pageConfig.layoutTree;
|
|
2759
3084
|
const layoutTree = Array.isArray(rawTree) ? rawTree : rawTree && typeof rawTree === "object" && rawTree.componentId ? [rawTree] : [];
|
|
@@ -2845,28 +3170,38 @@ async function fetchPageConfigServer(route, trackingId, preview = false, options
|
|
|
2845
3170
|
const target = resolveAmplifyUpTarget({
|
|
2846
3171
|
configTarget: options?.target
|
|
2847
3172
|
});
|
|
2848
|
-
const { orchestratorUrl } = resolveAmplifyUpUrls(target);
|
|
2849
|
-
const
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
params.set("preview", "true");
|
|
2855
|
-
}
|
|
2856
|
-
const url = `${orchestratorUrl}/api/layout/provider?${params.toString()}`;
|
|
2857
|
-
try {
|
|
2858
|
-
const res = await fetch(url, {
|
|
2859
|
-
cache: "no-store",
|
|
2860
|
-
headers: { Accept: "application/json" }
|
|
3173
|
+
const { orchestratorUrl, edgeUrl } = resolveAmplifyUpUrls(target);
|
|
3174
|
+
const previewFlag = preview || (options?.searchParams ? isPreviewRequest(options.searchParams) : false);
|
|
3175
|
+
const fetchOrchestratorPage = async (pageRoute, isPreview) => {
|
|
3176
|
+
const params = new URLSearchParams({
|
|
3177
|
+
route: pageRoute,
|
|
3178
|
+
trackingId
|
|
2861
3179
|
});
|
|
2862
|
-
if (
|
|
3180
|
+
if (isPreview) params.set("preview", "true");
|
|
3181
|
+
const url = `${orchestratorUrl}/api/layout/provider?${params.toString()}`;
|
|
3182
|
+
try {
|
|
3183
|
+
const res = await fetch(url, {
|
|
3184
|
+
cache: "no-store",
|
|
3185
|
+
headers: { Accept: "application/json" }
|
|
3186
|
+
});
|
|
3187
|
+
if (!res.ok) return null;
|
|
3188
|
+
const data = await res.json();
|
|
3189
|
+
return data.page || null;
|
|
3190
|
+
} catch {
|
|
2863
3191
|
return null;
|
|
2864
3192
|
}
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
3193
|
+
};
|
|
3194
|
+
const result = await fetchContent({
|
|
3195
|
+
route,
|
|
3196
|
+
trackingId,
|
|
3197
|
+
anonId: options?.anonId,
|
|
3198
|
+
siteId: options?.siteId,
|
|
3199
|
+
preview: previewFlag,
|
|
3200
|
+
orchestratorUrl,
|
|
3201
|
+
edgeUrl,
|
|
3202
|
+
fetchOrchestratorPage
|
|
3203
|
+
});
|
|
3204
|
+
return result.pageConfig;
|
|
2870
3205
|
}
|
|
2871
3206
|
var ComponentContext = react.createContext(null);
|
|
2872
3207
|
function ComponentContextProvider({
|
|
@@ -2989,6 +3324,25 @@ function Slot({
|
|
|
2989
3324
|
}
|
|
2990
3325
|
);
|
|
2991
3326
|
}
|
|
3327
|
+
function formatFieldValue(value) {
|
|
3328
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
3329
|
+
return String(value);
|
|
3330
|
+
}
|
|
3331
|
+
if (Array.isArray(value)) {
|
|
3332
|
+
const parts = value.map((item) => {
|
|
3333
|
+
if (typeof item === "string") return item;
|
|
3334
|
+
if (item && typeof item === "object" && "children" in item && Array.isArray(item.children)) {
|
|
3335
|
+
return item.children.map((c) => typeof c?.text === "string" ? c.text : "").join("");
|
|
3336
|
+
}
|
|
3337
|
+
return "";
|
|
3338
|
+
}).filter(Boolean);
|
|
3339
|
+
if (parts.length > 0) return parts.join(" ");
|
|
3340
|
+
}
|
|
3341
|
+
if (value && typeof value === "object") {
|
|
3342
|
+
return "";
|
|
3343
|
+
}
|
|
3344
|
+
return "";
|
|
3345
|
+
}
|
|
2992
3346
|
function Field({
|
|
2993
3347
|
name,
|
|
2994
3348
|
fallback,
|
|
@@ -3007,7 +3361,51 @@ function Field({
|
|
|
3007
3361
|
if (render) {
|
|
3008
3362
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: render(fieldValue) });
|
|
3009
3363
|
}
|
|
3010
|
-
|
|
3364
|
+
const text = formatFieldValue(fieldValue);
|
|
3365
|
+
if (!text) {
|
|
3366
|
+
return fallback ? /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: fallback }) : null;
|
|
3367
|
+
}
|
|
3368
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: text });
|
|
3369
|
+
}
|
|
3370
|
+
function markdownToHtml(markdown) {
|
|
3371
|
+
try {
|
|
3372
|
+
const result = marked.marked.parse(markdown, { async: false });
|
|
3373
|
+
return typeof result === "string" ? result : "";
|
|
3374
|
+
} catch {
|
|
3375
|
+
return markdown;
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
function RichText({
|
|
3379
|
+
name,
|
|
3380
|
+
fallback,
|
|
3381
|
+
className,
|
|
3382
|
+
as: Tag = "div"
|
|
3383
|
+
}) {
|
|
3384
|
+
const context = react.useContext(ComponentContext);
|
|
3385
|
+
if (!context) {
|
|
3386
|
+
console.warn(`[AmplifyUp SDK] RichText "${name}" used outside ComponentContextProvider`);
|
|
3387
|
+
return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
|
|
3388
|
+
}
|
|
3389
|
+
const fieldValue = context.props?.[name];
|
|
3390
|
+
if (fieldValue === void 0 || fieldValue === null || fieldValue === "") {
|
|
3391
|
+
return fallback ? /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, children: fallback }) : null;
|
|
3392
|
+
}
|
|
3393
|
+
let html = "";
|
|
3394
|
+
if (typeof fieldValue === "string") {
|
|
3395
|
+
const trimmed = fieldValue.trim();
|
|
3396
|
+
if (trimmed.startsWith("<") && trimmed.includes(">")) {
|
|
3397
|
+
html = fieldValue;
|
|
3398
|
+
} else {
|
|
3399
|
+
html = markdownToHtml(fieldValue);
|
|
3400
|
+
}
|
|
3401
|
+
} else {
|
|
3402
|
+
const text = formatFieldValue(fieldValue);
|
|
3403
|
+
html = text ? markdownToHtml(text) : "";
|
|
3404
|
+
}
|
|
3405
|
+
if (!html) {
|
|
3406
|
+
return fallback ? /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, children: fallback }) : null;
|
|
3407
|
+
}
|
|
3408
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, dangerouslySetInnerHTML: { __html: html } });
|
|
3011
3409
|
}
|
|
3012
3410
|
var usePathname = null;
|
|
3013
3411
|
if (typeof window !== "undefined") {
|
|
@@ -3025,6 +3423,8 @@ function AmplifyUpProvider({ children, config }) {
|
|
|
3025
3423
|
const [pageConfig, setPageConfig] = react.useState(null);
|
|
3026
3424
|
const [loading, setLoading] = react.useState(true);
|
|
3027
3425
|
const [error, setError] = react.useState(null);
|
|
3426
|
+
const [source, setSource] = react.useState(null);
|
|
3427
|
+
const [meta, setMeta] = react.useState(null);
|
|
3028
3428
|
const getActualRoute = () => {
|
|
3029
3429
|
if (typeof window === "undefined") return "";
|
|
3030
3430
|
const currentPath = window.location.pathname;
|
|
@@ -3090,10 +3490,10 @@ function AmplifyUpProvider({ children, config }) {
|
|
|
3090
3490
|
return () => {
|
|
3091
3491
|
cancelled = true;
|
|
3092
3492
|
};
|
|
3093
|
-
}, [config.trackingId, config.target, config.debug, config.dev]);
|
|
3493
|
+
}, [config.trackingId, config.target, config.debug, config.dev, config.siteId]);
|
|
3094
3494
|
react.useEffect(() => {
|
|
3095
3495
|
if (!initialized) return;
|
|
3096
|
-
const
|
|
3496
|
+
const load = async () => {
|
|
3097
3497
|
try {
|
|
3098
3498
|
setLoading(true);
|
|
3099
3499
|
setError(null);
|
|
@@ -3104,29 +3504,57 @@ function AmplifyUpProvider({ children, config }) {
|
|
|
3104
3504
|
}
|
|
3105
3505
|
const sdk = getSDK();
|
|
3106
3506
|
sdk.routeChange(actualRoute);
|
|
3107
|
-
const
|
|
3108
|
-
const
|
|
3109
|
-
|
|
3507
|
+
const preview = isComposerPreview();
|
|
3508
|
+
const edgeUrl = sdk.getEdgeUrl();
|
|
3509
|
+
const orchestratorUrl = sdk.getOrchestratorUrl();
|
|
3510
|
+
const trackingId = sdk.getTrackingId();
|
|
3511
|
+
if (!trackingId || !orchestratorUrl || !edgeUrl) {
|
|
3512
|
+
setError("SDK not initialized");
|
|
3513
|
+
setLoading(false);
|
|
3514
|
+
return;
|
|
3515
|
+
}
|
|
3516
|
+
const result = await fetchContent({
|
|
3517
|
+
route: actualRoute,
|
|
3518
|
+
trackingId,
|
|
3519
|
+
anonId: sdk.getInstanceId(),
|
|
3520
|
+
siteId: sdk.getSiteId() || null,
|
|
3521
|
+
preview,
|
|
3522
|
+
orchestratorUrl,
|
|
3523
|
+
edgeUrl,
|
|
3524
|
+
fetchOrchestratorPage: (route, isPreview) => sdk.fetchPageConfig(route, isPreview)
|
|
3525
|
+
});
|
|
3526
|
+
setSource(result.source);
|
|
3527
|
+
setMeta(result.meta);
|
|
3528
|
+
setError(result.error);
|
|
3529
|
+
if (!result.pageConfig) {
|
|
3110
3530
|
setPageConfig({
|
|
3111
3531
|
id: "default",
|
|
3112
3532
|
route: actualRoute,
|
|
3113
3533
|
title: "Page Not Configured",
|
|
3114
|
-
description: "This page has not been
|
|
3534
|
+
description: "This page has not been published yet.",
|
|
3115
3535
|
layoutTree: []
|
|
3116
3536
|
});
|
|
3117
3537
|
} else {
|
|
3118
|
-
setPageConfig(
|
|
3538
|
+
setPageConfig(result.pageConfig);
|
|
3119
3539
|
}
|
|
3120
3540
|
} catch (err) {
|
|
3121
3541
|
console.error("Error fetching page config:", err);
|
|
3122
3542
|
setError(err instanceof Error ? err.message : "Unknown error");
|
|
3543
|
+
setSource(null);
|
|
3544
|
+
setMeta(null);
|
|
3123
3545
|
} finally {
|
|
3124
3546
|
setLoading(false);
|
|
3125
3547
|
}
|
|
3126
3548
|
};
|
|
3127
|
-
|
|
3549
|
+
void load();
|
|
3128
3550
|
}, [pathname, initialized]);
|
|
3129
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3551
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3552
|
+
AmplifyUpContext.Provider,
|
|
3553
|
+
{
|
|
3554
|
+
value: { pageConfig, loading, error, source, meta },
|
|
3555
|
+
children
|
|
3556
|
+
}
|
|
3557
|
+
);
|
|
3130
3558
|
}
|
|
3131
3559
|
function useAmplifyUp() {
|
|
3132
3560
|
const context = react.useContext(AmplifyUpContext);
|
|
@@ -3141,6 +3569,7 @@ exports.AmplifyRenderer = AmplifyRenderer;
|
|
|
3141
3569
|
exports.AmplifyUpProvider = AmplifyUpProvider;
|
|
3142
3570
|
exports.ComponentContextProvider = ComponentContextProvider;
|
|
3143
3571
|
exports.Field = Field;
|
|
3572
|
+
exports.RichText = RichText;
|
|
3144
3573
|
exports.Slot = Slot;
|
|
3145
3574
|
exports.fetchPageConfigServer = fetchPageConfigServer;
|
|
3146
3575
|
exports.isComposerPreview = isComposerPreview;
|