@amplifyup/sdk 0.1.60 → 0.1.62
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 +11 -6
- package/dist/AmplifyRenderer-BQ8-H2H4.d.ts +74 -0
- package/dist/AmplifyRenderer-W7eqltSj.d.mts +74 -0
- package/dist/AmplifyRenderer.d.mts +4 -40
- package/dist/AmplifyRenderer.d.ts +4 -40
- package/dist/AmplifyRenderer.js +257 -30
- package/dist/AmplifyRenderer.js.map +1 -1
- package/dist/AmplifyRenderer.mjs +258 -31
- package/dist/AmplifyRenderer.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +98 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{query-BqApXxQi.d.ts → query-3AXnQgzO.d.ts} +1 -0
- package/dist/{query-DaJlqU-Z.d.mts → query-DIZjc7st.d.mts} +1 -0
- package/dist/react.d.mts +34 -36
- package/dist/react.d.ts +34 -36
- package/dist/react.js +1480 -1314
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1460 -1297
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +97 -2
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +97 -2
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,21 +65,26 @@ export default function Page() {
|
|
|
65
65
|
|
|
66
66
|
```tsx
|
|
67
67
|
import { Field, Slot } from '@amplifyup/sdk/react';
|
|
68
|
+
import type { Fields } from '@amplifyup/sdk/react';
|
|
68
69
|
|
|
69
|
-
export function Hero({
|
|
70
|
+
export function Hero({ fields }: { fields: Fields<{ heading: string }> }) {
|
|
70
71
|
return (
|
|
71
72
|
<section>
|
|
72
73
|
<h1>
|
|
73
|
-
<Field
|
|
74
|
+
<Field field={fields.heading} />
|
|
74
75
|
</h1>
|
|
75
76
|
</section>
|
|
76
77
|
);
|
|
77
78
|
}
|
|
78
79
|
```
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
AmplifyUp passes `fields` on the component props. Use
|
|
82
|
+
`<Field field={fields.heading} />` to show and edit, or
|
|
83
|
+
`{fields.heading.value}` to render the text. You do not pass `name` unless
|
|
84
|
+
you computed the value yourself. An empty field renders nothing on the live
|
|
85
|
+
site; in Composer it stays clickable. Default copy belongs in your component
|
|
86
|
+
(`{fields.heading.value ?? 'Welcome'}`). Connect content in Composer, then
|
|
87
|
+
**Deploy** so the live site can serve the page.
|
|
83
88
|
|
|
84
89
|
## Content sources
|
|
85
90
|
|
|
@@ -138,7 +143,7 @@ const hits = await queryContent({
|
|
|
138
143
|
});
|
|
139
144
|
```
|
|
140
145
|
|
|
141
|
-
Only entities published with that route can be queried, and visitors only see published content. Also available from `@amplifyup/sdk/server`. See the [runtime queries guide](../../docs/sdk-site-setup.md#8-runtime-content-queries).
|
|
146
|
+
Only entities published with that route can be queried, and visitors only see published content. Results are plain rows, not `fields` objects — they are not canvas-editable. Also available from `@amplifyup/sdk/server`. See the [runtime queries guide](../../docs/sdk-site-setup.md#8-runtime-content-queries).
|
|
142
147
|
|
|
143
148
|
## Track events
|
|
144
149
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { P as PageConfig } from './types-Db_eLrfU.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Field envelopes — same shape in published, draft, and Composer edit.
|
|
8
|
+
* `{ value, name }` where `name` is the full dot path (`hero.image`).
|
|
9
|
+
* Produced once at the Edge resolve boundary (`fetchEdgeResolve`).
|
|
10
|
+
*/
|
|
11
|
+
declare const FIELDS_BRAND: unique symbol;
|
|
12
|
+
type ImageValue = {
|
|
13
|
+
url: string;
|
|
14
|
+
alt?: string;
|
|
15
|
+
width?: number;
|
|
16
|
+
height?: number;
|
|
17
|
+
};
|
|
18
|
+
type Field<T> = {
|
|
19
|
+
value: T;
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
type IsPlainObject<T> = T extends object ? T extends readonly unknown[] ? false : T extends ImageValue ? false : true : false;
|
|
23
|
+
type Fields<T> = {
|
|
24
|
+
readonly [FIELDS_BRAND]: true;
|
|
25
|
+
} & {
|
|
26
|
+
[K in keyof T]-?: NonNullable<T[K]> extends ImageValue ? Field<T[K] | null> : IsPlainObject<NonNullable<T[K]>> extends true ? Fields<NonNullable<T[K]>> : Field<T[K]>;
|
|
27
|
+
};
|
|
28
|
+
/** Props passed into site components. Raw CMS bags are not assignable. */
|
|
29
|
+
type LayoutComponentProps<T extends Record<string, unknown> = Record<string, unknown>> = {
|
|
30
|
+
fields: Fields<T>;
|
|
31
|
+
};
|
|
32
|
+
declare function isBrandedFields(value: unknown): value is Fields<Record<string, unknown>>;
|
|
33
|
+
declare function isFieldEnvelope(value: unknown): value is Field<unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Wrap a props bag as envelopes. Already-enveloped bags are returned as-is.
|
|
36
|
+
* Nested plain objects become nested bags; portable images stay a leaf.
|
|
37
|
+
*/
|
|
38
|
+
declare function toFieldEnvelopes<T extends Record<string, unknown>>(source: T | null | undefined, prefix?: string): Fields<T>;
|
|
39
|
+
|
|
40
|
+
interface AmplifyRendererProps {
|
|
41
|
+
/**
|
|
42
|
+
* Component renderer function that maps componentId to React component
|
|
43
|
+
* This is site-specific and must be provided by the developer
|
|
44
|
+
*/
|
|
45
|
+
renderComponent: (componentId: string, props: LayoutComponentProps, slots?: Record<string, ReactNode>, context?: {
|
|
46
|
+
layoutNodeId: string;
|
|
47
|
+
}) => ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Optional page config for server-side rendering (SSR/SSG)
|
|
50
|
+
* If provided, the component will use this instead of fetching client-side
|
|
51
|
+
*/
|
|
52
|
+
pageConfig?: PageConfig;
|
|
53
|
+
/**
|
|
54
|
+
* Optional loading component
|
|
55
|
+
*/
|
|
56
|
+
loadingComponent?: ReactNode;
|
|
57
|
+
/**
|
|
58
|
+
* Optional error component
|
|
59
|
+
*/
|
|
60
|
+
errorComponent?: (error: string) => ReactNode;
|
|
61
|
+
/**
|
|
62
|
+
* Optional empty state component (when no content is configured)
|
|
63
|
+
*/
|
|
64
|
+
emptyComponent?: ReactNode;
|
|
65
|
+
/**
|
|
66
|
+
* Force Composer page-slot wrapper (avoids SSR miss when window isn't available yet).
|
|
67
|
+
* When true, root components stay under [data-slot-source="page"] so hierarchy can climb to Page.
|
|
68
|
+
*/
|
|
69
|
+
composerPreview?: boolean;
|
|
70
|
+
}
|
|
71
|
+
declare function AmplifyRendererInner({ renderComponent, pageConfig: serverPageConfig, loadingComponent, errorComponent, emptyComponent, composerPreview, }: AmplifyRendererProps): react_jsx_runtime.JSX.Element | null;
|
|
72
|
+
declare const AmplifyRenderer: React.MemoExoticComponent<typeof AmplifyRendererInner>;
|
|
73
|
+
|
|
74
|
+
export { AmplifyRenderer as A, type Field as F, type ImageValue as I, type LayoutComponentProps as L, isBrandedFields as a, type Fields as b, isFieldEnvelope as i, toFieldEnvelopes as t };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import { P as PageConfig } from './types-Db_eLrfU.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Field envelopes — same shape in published, draft, and Composer edit.
|
|
8
|
+
* `{ value, name }` where `name` is the full dot path (`hero.image`).
|
|
9
|
+
* Produced once at the Edge resolve boundary (`fetchEdgeResolve`).
|
|
10
|
+
*/
|
|
11
|
+
declare const FIELDS_BRAND: unique symbol;
|
|
12
|
+
type ImageValue = {
|
|
13
|
+
url: string;
|
|
14
|
+
alt?: string;
|
|
15
|
+
width?: number;
|
|
16
|
+
height?: number;
|
|
17
|
+
};
|
|
18
|
+
type Field<T> = {
|
|
19
|
+
value: T;
|
|
20
|
+
name: string;
|
|
21
|
+
};
|
|
22
|
+
type IsPlainObject<T> = T extends object ? T extends readonly unknown[] ? false : T extends ImageValue ? false : true : false;
|
|
23
|
+
type Fields<T> = {
|
|
24
|
+
readonly [FIELDS_BRAND]: true;
|
|
25
|
+
} & {
|
|
26
|
+
[K in keyof T]-?: NonNullable<T[K]> extends ImageValue ? Field<T[K] | null> : IsPlainObject<NonNullable<T[K]>> extends true ? Fields<NonNullable<T[K]>> : Field<T[K]>;
|
|
27
|
+
};
|
|
28
|
+
/** Props passed into site components. Raw CMS bags are not assignable. */
|
|
29
|
+
type LayoutComponentProps<T extends Record<string, unknown> = Record<string, unknown>> = {
|
|
30
|
+
fields: Fields<T>;
|
|
31
|
+
};
|
|
32
|
+
declare function isBrandedFields(value: unknown): value is Fields<Record<string, unknown>>;
|
|
33
|
+
declare function isFieldEnvelope(value: unknown): value is Field<unknown>;
|
|
34
|
+
/**
|
|
35
|
+
* Wrap a props bag as envelopes. Already-enveloped bags are returned as-is.
|
|
36
|
+
* Nested plain objects become nested bags; portable images stay a leaf.
|
|
37
|
+
*/
|
|
38
|
+
declare function toFieldEnvelopes<T extends Record<string, unknown>>(source: T | null | undefined, prefix?: string): Fields<T>;
|
|
39
|
+
|
|
40
|
+
interface AmplifyRendererProps {
|
|
41
|
+
/**
|
|
42
|
+
* Component renderer function that maps componentId to React component
|
|
43
|
+
* This is site-specific and must be provided by the developer
|
|
44
|
+
*/
|
|
45
|
+
renderComponent: (componentId: string, props: LayoutComponentProps, slots?: Record<string, ReactNode>, context?: {
|
|
46
|
+
layoutNodeId: string;
|
|
47
|
+
}) => ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Optional page config for server-side rendering (SSR/SSG)
|
|
50
|
+
* If provided, the component will use this instead of fetching client-side
|
|
51
|
+
*/
|
|
52
|
+
pageConfig?: PageConfig;
|
|
53
|
+
/**
|
|
54
|
+
* Optional loading component
|
|
55
|
+
*/
|
|
56
|
+
loadingComponent?: ReactNode;
|
|
57
|
+
/**
|
|
58
|
+
* Optional error component
|
|
59
|
+
*/
|
|
60
|
+
errorComponent?: (error: string) => ReactNode;
|
|
61
|
+
/**
|
|
62
|
+
* Optional empty state component (when no content is configured)
|
|
63
|
+
*/
|
|
64
|
+
emptyComponent?: ReactNode;
|
|
65
|
+
/**
|
|
66
|
+
* Force Composer page-slot wrapper (avoids SSR miss when window isn't available yet).
|
|
67
|
+
* When true, root components stay under [data-slot-source="page"] so hierarchy can climb to Page.
|
|
68
|
+
*/
|
|
69
|
+
composerPreview?: boolean;
|
|
70
|
+
}
|
|
71
|
+
declare function AmplifyRendererInner({ renderComponent, pageConfig: serverPageConfig, loadingComponent, errorComponent, emptyComponent, composerPreview, }: AmplifyRendererProps): react_jsx_runtime.JSX.Element | null;
|
|
72
|
+
declare const AmplifyRenderer: React.MemoExoticComponent<typeof AmplifyRendererInner>;
|
|
73
|
+
|
|
74
|
+
export { AmplifyRenderer as A, type Field as F, type ImageValue as I, type LayoutComponentProps as L, isBrandedFields as a, type Fields as b, isFieldEnvelope as i, toFieldEnvelopes as t };
|
|
@@ -1,40 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
interface AmplifyRendererProps {
|
|
7
|
-
/**
|
|
8
|
-
* Component renderer function that maps componentId to React component
|
|
9
|
-
* This is site-specific and must be provided by the developer
|
|
10
|
-
*/
|
|
11
|
-
renderComponent: (componentId: string, props: Record<string, any>, slots?: Record<string, ReactNode>, context?: {
|
|
12
|
-
layoutNodeId: string;
|
|
13
|
-
}) => ReactNode;
|
|
14
|
-
/**
|
|
15
|
-
* Optional page config for server-side rendering (SSR/SSG)
|
|
16
|
-
* If provided, the component will use this instead of fetching client-side
|
|
17
|
-
*/
|
|
18
|
-
pageConfig?: PageConfig;
|
|
19
|
-
/**
|
|
20
|
-
* Optional loading component
|
|
21
|
-
*/
|
|
22
|
-
loadingComponent?: ReactNode;
|
|
23
|
-
/**
|
|
24
|
-
* Optional error component
|
|
25
|
-
*/
|
|
26
|
-
errorComponent?: (error: string) => ReactNode;
|
|
27
|
-
/**
|
|
28
|
-
* Optional empty state component (when no content is configured)
|
|
29
|
-
*/
|
|
30
|
-
emptyComponent?: ReactNode;
|
|
31
|
-
/**
|
|
32
|
-
* Force Composer page-slot wrapper (avoids SSR miss when window isn't available yet).
|
|
33
|
-
* When true, root components stay under [data-slot-source="page"] so hierarchy can climb to Page.
|
|
34
|
-
*/
|
|
35
|
-
composerPreview?: boolean;
|
|
36
|
-
}
|
|
37
|
-
declare function AmplifyRendererInner({ renderComponent, pageConfig: serverPageConfig, loadingComponent, errorComponent, emptyComponent, composerPreview, }: AmplifyRendererProps): react_jsx_runtime.JSX.Element | null;
|
|
38
|
-
declare const AmplifyRenderer: React.MemoExoticComponent<typeof AmplifyRendererInner>;
|
|
39
|
-
|
|
40
|
-
export { AmplifyRenderer };
|
|
1
|
+
import 'react';
|
|
2
|
+
import 'react/jsx-runtime';
|
|
3
|
+
export { A as AmplifyRenderer } from './AmplifyRenderer-W7eqltSj.mjs';
|
|
4
|
+
import './types-Db_eLrfU.mjs';
|
|
@@ -1,40 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
interface AmplifyRendererProps {
|
|
7
|
-
/**
|
|
8
|
-
* Component renderer function that maps componentId to React component
|
|
9
|
-
* This is site-specific and must be provided by the developer
|
|
10
|
-
*/
|
|
11
|
-
renderComponent: (componentId: string, props: Record<string, any>, slots?: Record<string, ReactNode>, context?: {
|
|
12
|
-
layoutNodeId: string;
|
|
13
|
-
}) => ReactNode;
|
|
14
|
-
/**
|
|
15
|
-
* Optional page config for server-side rendering (SSR/SSG)
|
|
16
|
-
* If provided, the component will use this instead of fetching client-side
|
|
17
|
-
*/
|
|
18
|
-
pageConfig?: PageConfig;
|
|
19
|
-
/**
|
|
20
|
-
* Optional loading component
|
|
21
|
-
*/
|
|
22
|
-
loadingComponent?: ReactNode;
|
|
23
|
-
/**
|
|
24
|
-
* Optional error component
|
|
25
|
-
*/
|
|
26
|
-
errorComponent?: (error: string) => ReactNode;
|
|
27
|
-
/**
|
|
28
|
-
* Optional empty state component (when no content is configured)
|
|
29
|
-
*/
|
|
30
|
-
emptyComponent?: ReactNode;
|
|
31
|
-
/**
|
|
32
|
-
* Force Composer page-slot wrapper (avoids SSR miss when window isn't available yet).
|
|
33
|
-
* When true, root components stay under [data-slot-source="page"] so hierarchy can climb to Page.
|
|
34
|
-
*/
|
|
35
|
-
composerPreview?: boolean;
|
|
36
|
-
}
|
|
37
|
-
declare function AmplifyRendererInner({ renderComponent, pageConfig: serverPageConfig, loadingComponent, errorComponent, emptyComponent, composerPreview, }: AmplifyRendererProps): react_jsx_runtime.JSX.Element | null;
|
|
38
|
-
declare const AmplifyRenderer: React.MemoExoticComponent<typeof AmplifyRendererInner>;
|
|
39
|
-
|
|
40
|
-
export { AmplifyRenderer };
|
|
1
|
+
import 'react';
|
|
2
|
+
import 'react/jsx-runtime';
|
|
3
|
+
export { A as AmplifyRenderer } from './AmplifyRenderer-BQ8-H2H4.js';
|
|
4
|
+
import './types-Db_eLrfU.js';
|
package/dist/AmplifyRenderer.js
CHANGED
|
@@ -407,6 +407,106 @@ function isComposerPreview() {
|
|
|
407
407
|
return false;
|
|
408
408
|
}
|
|
409
409
|
|
|
410
|
+
// src/field-envelope.ts
|
|
411
|
+
var FIELDS_BRAND = Symbol("amplifyup.fields");
|
|
412
|
+
function isBrandedFields(value) {
|
|
413
|
+
return !!value && typeof value === "object" && FIELDS_BRAND in value;
|
|
414
|
+
}
|
|
415
|
+
function brandFields(bag) {
|
|
416
|
+
if (isBrandedFields(bag)) return bag;
|
|
417
|
+
Object.defineProperty(bag, FIELDS_BRAND, {
|
|
418
|
+
value: true,
|
|
419
|
+
enumerable: false,
|
|
420
|
+
configurable: false
|
|
421
|
+
});
|
|
422
|
+
return bag;
|
|
423
|
+
}
|
|
424
|
+
function isFieldEnvelope(value) {
|
|
425
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
426
|
+
const rec = value;
|
|
427
|
+
return typeof rec.name === "string" && "value" in rec && !("url" in rec);
|
|
428
|
+
}
|
|
429
|
+
function isPortableImageShape(value) {
|
|
430
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
431
|
+
return "url" in value;
|
|
432
|
+
}
|
|
433
|
+
function joinPath(prefix, key) {
|
|
434
|
+
return prefix ? `${prefix}.${key}` : key;
|
|
435
|
+
}
|
|
436
|
+
function emptyValue(raw) {
|
|
437
|
+
if (raw === void 0) return null;
|
|
438
|
+
return raw;
|
|
439
|
+
}
|
|
440
|
+
function toFieldEnvelopes(source, prefix = "") {
|
|
441
|
+
const input = source && typeof source === "object" && !Array.isArray(source) ? source : {};
|
|
442
|
+
if (isBrandedFields(input)) {
|
|
443
|
+
return input;
|
|
444
|
+
}
|
|
445
|
+
const out = {};
|
|
446
|
+
for (const [key, raw] of Object.entries(input)) {
|
|
447
|
+
const path = joinPath(prefix, key);
|
|
448
|
+
if (isFieldEnvelope(raw)) {
|
|
449
|
+
out[key] = { value: raw.value ?? null, name: raw.name || path };
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && !isPortableImageShape(raw) && !raw.$$typeof) {
|
|
453
|
+
out[key] = toFieldEnvelopes(raw, path);
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
out[key] = { value: emptyValue(raw), name: path };
|
|
457
|
+
}
|
|
458
|
+
return brandFields(out);
|
|
459
|
+
}
|
|
460
|
+
function attachFieldEnvelopes(props) {
|
|
461
|
+
const raw = props && typeof props === "object" ? { ...props } : {};
|
|
462
|
+
if (isBrandedFields(raw.fields)) return raw;
|
|
463
|
+
const { fields: existing, ...content } = raw;
|
|
464
|
+
const source = existing && typeof existing === "object" && !isFieldEnvelope(existing) ? existing : content;
|
|
465
|
+
return { ...raw, fields: toFieldEnvelopes(source) };
|
|
466
|
+
}
|
|
467
|
+
function walkLayoutNodes(nodes) {
|
|
468
|
+
if (!Array.isArray(nodes)) return;
|
|
469
|
+
for (const node of nodes) {
|
|
470
|
+
if (!node || typeof node !== "object") continue;
|
|
471
|
+
const rec = node;
|
|
472
|
+
rec.props = attachFieldEnvelopes(rec.props);
|
|
473
|
+
for (const slot of rec.slots || []) {
|
|
474
|
+
walkLayoutNodes(slot.children);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
function envelopePageConfig(page) {
|
|
479
|
+
if (!page || typeof page !== "object") return page ?? null;
|
|
480
|
+
const tree = page.layoutTree;
|
|
481
|
+
if (Array.isArray(tree)) walkLayoutNodes(tree);
|
|
482
|
+
return page;
|
|
483
|
+
}
|
|
484
|
+
function collectFieldPatches(props) {
|
|
485
|
+
const out = [];
|
|
486
|
+
const walk = (obj, prefix) => {
|
|
487
|
+
for (const [key, raw] of Object.entries(obj)) {
|
|
488
|
+
if (key === "fields" && raw && typeof raw === "object" && !Array.isArray(raw) && !isFieldEnvelope(raw)) {
|
|
489
|
+
walk(raw, prefix);
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
const path = joinPath(prefix, key);
|
|
493
|
+
if (isFieldEnvelope(raw)) {
|
|
494
|
+
out.push({ name: raw.name || path, value: raw.value });
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && !isPortableImageShape(raw) && !raw.$$typeof) {
|
|
498
|
+
walk(raw, path);
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
out.push({ name: path, value: emptyValue(raw) });
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
if (props && typeof props === "object" && !Array.isArray(props)) {
|
|
505
|
+
walk(props, "");
|
|
506
|
+
}
|
|
507
|
+
return out;
|
|
508
|
+
}
|
|
509
|
+
|
|
410
510
|
// src/page-context.ts
|
|
411
511
|
var defaultLog = {
|
|
412
512
|
warn: (...args) => {
|
|
@@ -555,7 +655,70 @@ function mergeEventContext(properties, attached) {
|
|
|
555
655
|
...attached.pageRoute ? { pageRoute: attached.pageRoute } : {}
|
|
556
656
|
};
|
|
557
657
|
}
|
|
658
|
+
var PAGE_RESOURCE_MARKER = "__amplifyupPageResource";
|
|
659
|
+
function isPageResourceSentinel(value) {
|
|
660
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && typeof value[PAGE_RESOURCE_MARKER] === "string";
|
|
661
|
+
}
|
|
662
|
+
function getByDotPath(source, path) {
|
|
663
|
+
if (!path) return source;
|
|
664
|
+
const parts = path.split(".").filter(Boolean);
|
|
665
|
+
let cur = source;
|
|
666
|
+
for (const part of parts) {
|
|
667
|
+
if (cur == null || typeof cur !== "object" || Array.isArray(cur)) {
|
|
668
|
+
return void 0;
|
|
669
|
+
}
|
|
670
|
+
cur = cur[part];
|
|
671
|
+
}
|
|
672
|
+
return cur;
|
|
673
|
+
}
|
|
674
|
+
function hydratePageResourceValue(value, fields) {
|
|
675
|
+
if (!isPageResourceSentinel(value)) return value;
|
|
676
|
+
if (!fields) return null;
|
|
677
|
+
if (value.path) return getByDotPath(fields, value.path) ?? null;
|
|
678
|
+
return fields;
|
|
679
|
+
}
|
|
680
|
+
function hydrateFieldsBag(bag, fields) {
|
|
681
|
+
const out = {};
|
|
682
|
+
for (const [key, val] of Object.entries(bag)) {
|
|
683
|
+
if (val && typeof val === "object" && !Array.isArray(val) && typeof val.name === "string" && "value" in val && !("url" in val)) {
|
|
684
|
+
const env = val;
|
|
685
|
+
out[key] = {
|
|
686
|
+
name: env.name,
|
|
687
|
+
value: isPageResourceSentinel(env.value) ? hydratePageResourceValue(env.value, fields) : env.value
|
|
688
|
+
};
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
if (val && typeof val === "object" && !Array.isArray(val) && !("url" in val)) {
|
|
692
|
+
out[key] = hydrateFieldsBag(val, fields);
|
|
693
|
+
continue;
|
|
694
|
+
}
|
|
695
|
+
out[key] = isPageResourceSentinel(val) ? hydratePageResourceValue(val, fields) : val;
|
|
696
|
+
}
|
|
697
|
+
return out;
|
|
698
|
+
}
|
|
699
|
+
function hydratePageResourceProps(props, fields) {
|
|
700
|
+
const source = props && typeof props === "object" ? props : {};
|
|
701
|
+
const out = { ...source };
|
|
702
|
+
if (out.fields && typeof out.fields === "object" && !Array.isArray(out.fields)) {
|
|
703
|
+
const next = hydrateFieldsBag(out.fields, fields);
|
|
704
|
+
out.fields = isBrandedFields(out.fields) ? brandFields(next) : next;
|
|
705
|
+
}
|
|
706
|
+
for (const [key, val] of Object.entries(out)) {
|
|
707
|
+
if (key === "fields") continue;
|
|
708
|
+
if (isPageResourceSentinel(val)) {
|
|
709
|
+
out[key] = hydratePageResourceValue(val, fields);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
return out;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// src/page-resource-runtime.ts
|
|
716
|
+
var pageResourceFields = null;
|
|
558
717
|
function setPageResourceFields(fields) {
|
|
718
|
+
pageResourceFields = fields && typeof fields === "object" ? fields : null;
|
|
719
|
+
}
|
|
720
|
+
function getPageResourceFields() {
|
|
721
|
+
return pageResourceFields;
|
|
559
722
|
}
|
|
560
723
|
|
|
561
724
|
// src/debug.ts
|
|
@@ -1238,6 +1401,7 @@ var AmplifyUpSDK = class {
|
|
|
1238
1401
|
this.resolvedPageData,
|
|
1239
1402
|
this.resolvedPageRoute
|
|
1240
1403
|
);
|
|
1404
|
+
setPageResourceFields(null);
|
|
1241
1405
|
return;
|
|
1242
1406
|
}
|
|
1243
1407
|
this.attachedPageContext = applyPageContext(this.pendingPageContext, {
|
|
@@ -1666,7 +1830,7 @@ Available Console Commands:
|
|
|
1666
1830
|
this.refreshEventTracking();
|
|
1667
1831
|
}, 800);
|
|
1668
1832
|
}
|
|
1669
|
-
return pageConfig;
|
|
1833
|
+
return envelopePageConfig(pageConfig);
|
|
1670
1834
|
}
|
|
1671
1835
|
/**
|
|
1672
1836
|
* Set up view-level event tracking based on configuration
|
|
@@ -3039,31 +3203,66 @@ function getSDK(adapter) {
|
|
|
3039
3203
|
var trackContentView = (contentId, contentType, properties) => getSDK().trackContentView(contentId, contentType, properties);
|
|
3040
3204
|
var refreshEventTracking = () => getSDK().refreshEventTracking();
|
|
3041
3205
|
getSDK();
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3206
|
+
|
|
3207
|
+
// src/composer-store.ts
|
|
3208
|
+
var ComposerFieldStore = class {
|
|
3209
|
+
constructor() {
|
|
3210
|
+
this.values = /* @__PURE__ */ new Map();
|
|
3211
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
3212
|
+
}
|
|
3213
|
+
get(name) {
|
|
3214
|
+
return this.values.has(name) ? this.values.get(name) : void 0;
|
|
3215
|
+
}
|
|
3216
|
+
set(name, value) {
|
|
3217
|
+
if (!name) return;
|
|
3218
|
+
this.values.set(name, value);
|
|
3219
|
+
const set = this.listeners.get(name);
|
|
3220
|
+
if (!set) return;
|
|
3221
|
+
for (const fn of set) fn();
|
|
3222
|
+
}
|
|
3223
|
+
subscribe(name, fn) {
|
|
3224
|
+
if (!name) return () => {
|
|
3052
3225
|
};
|
|
3226
|
+
let set = this.listeners.get(name);
|
|
3227
|
+
if (!set) {
|
|
3228
|
+
set = /* @__PURE__ */ new Set();
|
|
3229
|
+
this.listeners.set(name, set);
|
|
3230
|
+
}
|
|
3231
|
+
set.add(fn);
|
|
3232
|
+
return () => {
|
|
3233
|
+
set.delete(fn);
|
|
3234
|
+
if (set.size === 0) this.listeners.delete(name);
|
|
3235
|
+
};
|
|
3236
|
+
}
|
|
3237
|
+
};
|
|
3238
|
+
var ComposerStoreContext = react.createContext(null);
|
|
3239
|
+
function matchesNode(eventNodeId, layoutNodeId) {
|
|
3240
|
+
if (eventNodeId && layoutNodeId && String(eventNodeId) !== String(layoutNodeId)) {
|
|
3241
|
+
return false;
|
|
3242
|
+
}
|
|
3243
|
+
return true;
|
|
3244
|
+
}
|
|
3245
|
+
function ComposerProvider({
|
|
3246
|
+
layoutNodeId,
|
|
3247
|
+
children
|
|
3248
|
+
}) {
|
|
3249
|
+
const storeRef = react.useRef(null);
|
|
3250
|
+
if (!storeRef.current) storeRef.current = new ComposerFieldStore();
|
|
3251
|
+
const store = storeRef.current;
|
|
3252
|
+
react.useEffect(() => {
|
|
3053
3253
|
const applyField = (fieldName, value, nodeId) => {
|
|
3054
3254
|
if (!fieldName || typeof fieldName !== "string") return;
|
|
3055
|
-
if (!matchesNode(nodeId)) return;
|
|
3056
|
-
|
|
3255
|
+
if (!matchesNode(nodeId, layoutNodeId)) return;
|
|
3256
|
+
store.set(fieldName, value);
|
|
3057
3257
|
};
|
|
3058
3258
|
const applyProps = (nextProps, nodeId) => {
|
|
3059
3259
|
if (!nextProps || typeof nextProps !== "object" || Array.isArray(nextProps)) {
|
|
3060
3260
|
return;
|
|
3061
3261
|
}
|
|
3062
|
-
if (!matchesNode(nodeId)) return;
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
}));
|
|
3262
|
+
if (!matchesNode(nodeId, layoutNodeId)) return;
|
|
3263
|
+
for (const patch of collectFieldPatches(nextProps)) {
|
|
3264
|
+
store.set(patch.name, patch.value);
|
|
3265
|
+
}
|
|
3067
3266
|
};
|
|
3068
3267
|
const onPatch = (event) => {
|
|
3069
3268
|
const detail = event.detail || {};
|
|
@@ -3089,9 +3288,19 @@ function useLiveComposerProps(layoutNodeId, props) {
|
|
|
3089
3288
|
window.removeEventListener("amplifyup:props-patch", onPropsPatch);
|
|
3090
3289
|
window.removeEventListener("message", onMessage);
|
|
3091
3290
|
};
|
|
3092
|
-
}, [layoutNodeId]);
|
|
3093
|
-
return
|
|
3291
|
+
}, [layoutNodeId, store]);
|
|
3292
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ComposerStoreContext.Provider, { value: store, children });
|
|
3094
3293
|
}
|
|
3294
|
+
function MaybeComposerProvider({
|
|
3295
|
+
enabled,
|
|
3296
|
+
layoutNodeId,
|
|
3297
|
+
children
|
|
3298
|
+
}) {
|
|
3299
|
+
const content = react.useMemo(() => children, [children]);
|
|
3300
|
+
if (!enabled) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: content });
|
|
3301
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ComposerProvider, { layoutNodeId, children });
|
|
3302
|
+
}
|
|
3303
|
+
react.createContext(null);
|
|
3095
3304
|
var usePathname = null;
|
|
3096
3305
|
if (typeof window !== "undefined") {
|
|
3097
3306
|
try {
|
|
@@ -3111,9 +3320,19 @@ function useAmplifyUp() {
|
|
|
3111
3320
|
return context;
|
|
3112
3321
|
}
|
|
3113
3322
|
function nodeRenderProps(node) {
|
|
3323
|
+
const settings = node.settings || {};
|
|
3324
|
+
const hydrated = hydratePageResourceProps(
|
|
3325
|
+
node.props || {},
|
|
3326
|
+
getPageResourceFields()
|
|
3327
|
+
);
|
|
3328
|
+
const fields = hydrated.fields;
|
|
3329
|
+
const branded = isBrandedFields(fields) ? fields : brandFields(
|
|
3330
|
+
fields && typeof fields === "object" ? fields : {}
|
|
3331
|
+
);
|
|
3114
3332
|
return {
|
|
3115
|
-
...
|
|
3116
|
-
...
|
|
3333
|
+
...settings,
|
|
3334
|
+
...hydrated,
|
|
3335
|
+
fields: branded
|
|
3117
3336
|
};
|
|
3118
3337
|
}
|
|
3119
3338
|
var ComponentRenderBoundary = class extends react.Component {
|
|
@@ -3163,17 +3382,24 @@ var ComponentRenderBoundary = class extends react.Component {
|
|
|
3163
3382
|
return this.props.children;
|
|
3164
3383
|
}
|
|
3165
3384
|
};
|
|
3166
|
-
function
|
|
3385
|
+
function NodeWithFields({
|
|
3167
3386
|
nodeId,
|
|
3168
3387
|
componentId,
|
|
3169
3388
|
props,
|
|
3170
3389
|
slots,
|
|
3171
|
-
renderComponent
|
|
3390
|
+
renderComponent,
|
|
3391
|
+
composerPreview
|
|
3172
3392
|
}) {
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3393
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3394
|
+
MaybeComposerProvider,
|
|
3395
|
+
{
|
|
3396
|
+
enabled: !!(composerPreview || isComposerPreview()),
|
|
3397
|
+
layoutNodeId: nodeId,
|
|
3398
|
+
children: renderComponent(componentId, props, slots, {
|
|
3399
|
+
layoutNodeId: nodeId
|
|
3400
|
+
})
|
|
3401
|
+
}
|
|
3402
|
+
);
|
|
3177
3403
|
}
|
|
3178
3404
|
function AmplifyRendererInner({
|
|
3179
3405
|
renderComponent,
|
|
@@ -3529,13 +3755,14 @@ function AmplifyRendererInner({
|
|
|
3529
3755
|
componentId: node.componentId,
|
|
3530
3756
|
nodeId: node.id,
|
|
3531
3757
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3532
|
-
|
|
3758
|
+
NodeWithFields,
|
|
3533
3759
|
{
|
|
3534
3760
|
nodeId: node.id,
|
|
3535
3761
|
componentId: node.componentId,
|
|
3536
3762
|
props: nodeRenderProps(node),
|
|
3537
3763
|
slots: slotsToPass,
|
|
3538
|
-
renderComponent
|
|
3764
|
+
renderComponent,
|
|
3765
|
+
composerPreview
|
|
3539
3766
|
}
|
|
3540
3767
|
)
|
|
3541
3768
|
}
|