@amplifyup/sdk 0.1.34 → 0.1.36

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.
@@ -0,0 +1,157 @@
1
+ import { f as AmplifyUpTarget } from './types-CBoVIFI8.mjs';
2
+
3
+ /**
4
+ * On-request variant selection (tier 3).
5
+ *
6
+ * Decisions happen on AmplifyUp Edge. The client asks after the view has
7
+ * rendered; the Worker returns variant keys only. Profile data never leaves
8
+ * the edge. This helper is the JS wrapper around POST /v1/select — the same
9
+ * wire format is the contract for Flutter / native / .NET clients. No DOM
10
+ * or Next.js assumptions.
11
+ */
12
+
13
+ interface SelectVariantsResult {
14
+ siteId: string;
15
+ view: string;
16
+ variantKeys: Record<string, string>;
17
+ meta?: Record<string, unknown>;
18
+ }
19
+ declare class SelectVariantsError extends Error {
20
+ status: number;
21
+ body: unknown;
22
+ constructor(message: string, status: number, body?: unknown);
23
+ }
24
+ interface FetchEdgeSelectOptions {
25
+ edgeUrl: string;
26
+ trackingId?: string;
27
+ site?: string;
28
+ view: string;
29
+ anonId: string;
30
+ zones?: string[];
31
+ /** Request-local facts the edge cannot observe (app version, screen class). */
32
+ context?: Record<string, unknown>;
33
+ fetch?: typeof fetch;
34
+ signal?: AbortSignal;
35
+ }
36
+ declare function fetchEdgeSelect(options: FetchEdgeSelectOptions): Promise<SelectVariantsResult>;
37
+ interface SelectVariantsOptions {
38
+ trackingId?: string;
39
+ site?: string;
40
+ view: string;
41
+ anonId: string;
42
+ zones?: string[];
43
+ context?: Record<string, unknown>;
44
+ target?: AmplifyUpTarget;
45
+ edgeUrl?: string;
46
+ fetch?: typeof fetch;
47
+ signal?: AbortSignal;
48
+ }
49
+ /**
50
+ * Ask Edge to decide deferred rules for a view. Returns variant keys to pass
51
+ * to `/v1/resolve?variants=`.
52
+ */
53
+ declare function selectVariants(options: SelectVariantsOptions): Promise<SelectVariantsResult>;
54
+
55
+ /**
56
+ * Runtime content queries.
57
+ *
58
+ * Page resolve covers data known at Deploy. Visitor-triggered data — search,
59
+ * load more, pickers — runs here: the browser asks AmplifyUp, AmplifyUp asks
60
+ * the CMS. Only entities published with the page can be queried.
61
+ */
62
+
63
+ type QueryFilterOp = 'eq' | 'neq' | 'in' | 'nin' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'exists';
64
+ interface QueryFilter {
65
+ field: string;
66
+ op: QueryFilterOp;
67
+ value?: unknown;
68
+ }
69
+ interface QuerySort {
70
+ field: string;
71
+ dir: 'asc' | 'desc';
72
+ }
73
+ /**
74
+ * Provider-neutral query. AmplifyUp compiles this for the connected CMS —
75
+ * it never contains CMS query syntax. Same shape Composer saves on a
76
+ * query connection, and the shape returned in `{field}Pagination.spec`.
77
+ */
78
+ interface QuerySpec {
79
+ providerId: string;
80
+ entity: string;
81
+ filter: QueryFilter[];
82
+ sort: QuerySort[];
83
+ limit: number;
84
+ offset: number;
85
+ }
86
+ /** Pagination meta added to list props when a query connection is paginated. */
87
+ interface QueryPagination {
88
+ hasMore: boolean;
89
+ limit: number;
90
+ offset: number;
91
+ nextOffset: number;
92
+ spec: QuerySpec;
93
+ }
94
+ interface QueryResult<T = Record<string, unknown>> {
95
+ results: T[];
96
+ count: number;
97
+ hasMore: boolean;
98
+ limit: number;
99
+ offset: number;
100
+ nextOffset: number;
101
+ /** True when a content source failed and results may be incomplete. */
102
+ degraded?: boolean;
103
+ }
104
+ declare class QueryContentError extends Error {
105
+ status: number;
106
+ body: unknown;
107
+ constructor(message: string, status: number, body?: unknown);
108
+ }
109
+ interface FetchEdgeQueryOptions {
110
+ edgeUrl: string;
111
+ trackingId: string;
112
+ /** Published route the query belongs to (provides sources + entity mapping). */
113
+ route: string;
114
+ spec: QuerySpec;
115
+ siteId?: string | null;
116
+ fetch?: typeof fetch;
117
+ signal?: AbortSignal;
118
+ }
119
+ /**
120
+ * Low-level runtime query against a known Edge URL.
121
+ * Most callers should use `queryContent`, which resolves the URL for them.
122
+ */
123
+ declare function fetchEdgeQuery<T = Record<string, unknown>>(options: FetchEdgeQueryOptions): Promise<QueryResult<T>>;
124
+ interface QueryContentOptions {
125
+ trackingId: string;
126
+ /** Published route the query belongs to, e.g. '/insights'. */
127
+ route: string;
128
+ spec: QuerySpec;
129
+ siteId?: string | null;
130
+ target?: AmplifyUpTarget;
131
+ fetch?: typeof fetch;
132
+ signal?: AbortSignal;
133
+ }
134
+ /**
135
+ * Run a content query at request time (search, load more, pickers).
136
+ *
137
+ * Start from the published spec on a paginated list prop so filters and sort
138
+ * stay owned by Composer:
139
+ *
140
+ * ```ts
141
+ * const next = await queryContent({
142
+ * trackingId,
143
+ * route: '/insights',
144
+ * spec: { ...postsPagination.spec, offset: postsPagination.nextOffset },
145
+ * });
146
+ * ```
147
+ */
148
+ declare function queryContent<T = Record<string, unknown>>(options: QueryContentOptions): Promise<QueryResult<T>>;
149
+ /** Convenience: next page from pagination meta on a list prop. */
150
+ declare function nextPageSpec(pagination: QueryPagination): QuerySpec;
151
+ /**
152
+ * Convenience: same published query, filtered by a visitor's search term.
153
+ * Resets to the first page. Empty terms return the unfiltered spec.
154
+ */
155
+ declare function searchSpec(pagination: QueryPagination, field: string, term: string): QuerySpec;
156
+
157
+ export { type FetchEdgeSelectOptions as F, QueryContentError as Q, SelectVariantsError as S, type SelectVariantsOptions as a, type SelectVariantsResult as b, fetchEdgeQuery as c, searchSpec as d, type QueryContentOptions as e, fetchEdgeSelect as f, type FetchEdgeQueryOptions as g, type QueryResult as h, type QueryPagination as i, type QuerySpec as j, type QueryFilter as k, type QueryFilterOp as l, type QuerySort as m, nextPageSpec as n, queryContent as q, selectVariants as s };
@@ -0,0 +1,157 @@
1
+ import { f as AmplifyUpTarget } from './types-CBoVIFI8.js';
2
+
3
+ /**
4
+ * On-request variant selection (tier 3).
5
+ *
6
+ * Decisions happen on AmplifyUp Edge. The client asks after the view has
7
+ * rendered; the Worker returns variant keys only. Profile data never leaves
8
+ * the edge. This helper is the JS wrapper around POST /v1/select — the same
9
+ * wire format is the contract for Flutter / native / .NET clients. No DOM
10
+ * or Next.js assumptions.
11
+ */
12
+
13
+ interface SelectVariantsResult {
14
+ siteId: string;
15
+ view: string;
16
+ variantKeys: Record<string, string>;
17
+ meta?: Record<string, unknown>;
18
+ }
19
+ declare class SelectVariantsError extends Error {
20
+ status: number;
21
+ body: unknown;
22
+ constructor(message: string, status: number, body?: unknown);
23
+ }
24
+ interface FetchEdgeSelectOptions {
25
+ edgeUrl: string;
26
+ trackingId?: string;
27
+ site?: string;
28
+ view: string;
29
+ anonId: string;
30
+ zones?: string[];
31
+ /** Request-local facts the edge cannot observe (app version, screen class). */
32
+ context?: Record<string, unknown>;
33
+ fetch?: typeof fetch;
34
+ signal?: AbortSignal;
35
+ }
36
+ declare function fetchEdgeSelect(options: FetchEdgeSelectOptions): Promise<SelectVariantsResult>;
37
+ interface SelectVariantsOptions {
38
+ trackingId?: string;
39
+ site?: string;
40
+ view: string;
41
+ anonId: string;
42
+ zones?: string[];
43
+ context?: Record<string, unknown>;
44
+ target?: AmplifyUpTarget;
45
+ edgeUrl?: string;
46
+ fetch?: typeof fetch;
47
+ signal?: AbortSignal;
48
+ }
49
+ /**
50
+ * Ask Edge to decide deferred rules for a view. Returns variant keys to pass
51
+ * to `/v1/resolve?variants=`.
52
+ */
53
+ declare function selectVariants(options: SelectVariantsOptions): Promise<SelectVariantsResult>;
54
+
55
+ /**
56
+ * Runtime content queries.
57
+ *
58
+ * Page resolve covers data known at Deploy. Visitor-triggered data — search,
59
+ * load more, pickers — runs here: the browser asks AmplifyUp, AmplifyUp asks
60
+ * the CMS. Only entities published with the page can be queried.
61
+ */
62
+
63
+ type QueryFilterOp = 'eq' | 'neq' | 'in' | 'nin' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'exists';
64
+ interface QueryFilter {
65
+ field: string;
66
+ op: QueryFilterOp;
67
+ value?: unknown;
68
+ }
69
+ interface QuerySort {
70
+ field: string;
71
+ dir: 'asc' | 'desc';
72
+ }
73
+ /**
74
+ * Provider-neutral query. AmplifyUp compiles this for the connected CMS —
75
+ * it never contains CMS query syntax. Same shape Composer saves on a
76
+ * query connection, and the shape returned in `{field}Pagination.spec`.
77
+ */
78
+ interface QuerySpec {
79
+ providerId: string;
80
+ entity: string;
81
+ filter: QueryFilter[];
82
+ sort: QuerySort[];
83
+ limit: number;
84
+ offset: number;
85
+ }
86
+ /** Pagination meta added to list props when a query connection is paginated. */
87
+ interface QueryPagination {
88
+ hasMore: boolean;
89
+ limit: number;
90
+ offset: number;
91
+ nextOffset: number;
92
+ spec: QuerySpec;
93
+ }
94
+ interface QueryResult<T = Record<string, unknown>> {
95
+ results: T[];
96
+ count: number;
97
+ hasMore: boolean;
98
+ limit: number;
99
+ offset: number;
100
+ nextOffset: number;
101
+ /** True when a content source failed and results may be incomplete. */
102
+ degraded?: boolean;
103
+ }
104
+ declare class QueryContentError extends Error {
105
+ status: number;
106
+ body: unknown;
107
+ constructor(message: string, status: number, body?: unknown);
108
+ }
109
+ interface FetchEdgeQueryOptions {
110
+ edgeUrl: string;
111
+ trackingId: string;
112
+ /** Published route the query belongs to (provides sources + entity mapping). */
113
+ route: string;
114
+ spec: QuerySpec;
115
+ siteId?: string | null;
116
+ fetch?: typeof fetch;
117
+ signal?: AbortSignal;
118
+ }
119
+ /**
120
+ * Low-level runtime query against a known Edge URL.
121
+ * Most callers should use `queryContent`, which resolves the URL for them.
122
+ */
123
+ declare function fetchEdgeQuery<T = Record<string, unknown>>(options: FetchEdgeQueryOptions): Promise<QueryResult<T>>;
124
+ interface QueryContentOptions {
125
+ trackingId: string;
126
+ /** Published route the query belongs to, e.g. '/insights'. */
127
+ route: string;
128
+ spec: QuerySpec;
129
+ siteId?: string | null;
130
+ target?: AmplifyUpTarget;
131
+ fetch?: typeof fetch;
132
+ signal?: AbortSignal;
133
+ }
134
+ /**
135
+ * Run a content query at request time (search, load more, pickers).
136
+ *
137
+ * Start from the published spec on a paginated list prop so filters and sort
138
+ * stay owned by Composer:
139
+ *
140
+ * ```ts
141
+ * const next = await queryContent({
142
+ * trackingId,
143
+ * route: '/insights',
144
+ * spec: { ...postsPagination.spec, offset: postsPagination.nextOffset },
145
+ * });
146
+ * ```
147
+ */
148
+ declare function queryContent<T = Record<string, unknown>>(options: QueryContentOptions): Promise<QueryResult<T>>;
149
+ /** Convenience: next page from pagination meta on a list prop. */
150
+ declare function nextPageSpec(pagination: QueryPagination): QuerySpec;
151
+ /**
152
+ * Convenience: same published query, filtered by a visitor's search term.
153
+ * Resets to the first page. Empty terms return the unfiltered spec.
154
+ */
155
+ declare function searchSpec(pagination: QueryPagination, field: string, term: string): QuerySpec;
156
+
157
+ export { type FetchEdgeSelectOptions as F, QueryContentError as Q, SelectVariantsError as S, type SelectVariantsOptions as a, type SelectVariantsResult as b, fetchEdgeQuery as c, searchSpec as d, type QueryContentOptions as e, fetchEdgeSelect as f, type FetchEdgeQueryOptions as g, type QueryResult as h, type QueryPagination as i, type QuerySpec as j, type QueryFilter as k, type QueryFilterOp as l, type QuerySort as m, nextPageSpec as n, queryContent as q, selectVariants as s };
package/dist/react.d.mts CHANGED
@@ -3,6 +3,7 @@ import React, { ReactNode } from 'react';
3
3
  import { P as PageConfig, b as AmplifyUpConfig, C as ContentSource, A as AmplifyContentMeta } from './types-CBoVIFI8.mjs';
4
4
  export { Z as ZoneConfig } from './types-CBoVIFI8.mjs';
5
5
  export { AmplifyRenderer } from './AmplifyRenderer.mjs';
6
+ export { Q as QueryContentError, e as QueryContentOptions, k as QueryFilter, l as QueryFilterOp, i as QueryPagination, h as QueryResult, m as QuerySort, j as QuerySpec, S as SelectVariantsError, a as SelectVariantsOptions, b as SelectVariantsResult, n as nextPageSpec, q as queryContent, d as searchSpec, s as selectVariants } from './query-6BmINKLR.mjs';
6
7
  export { i as isComposerPreview, a as isPreviewRequest, b as isWorkingContentRequest } from './preview-_vHmzRen.mjs';
7
8
  export { fetchPageConfigServer } from './server.mjs';
8
9
 
package/dist/react.d.ts CHANGED
@@ -3,6 +3,7 @@ import React, { ReactNode } from 'react';
3
3
  import { P as PageConfig, b as AmplifyUpConfig, C as ContentSource, A as AmplifyContentMeta } from './types-CBoVIFI8.js';
4
4
  export { Z as ZoneConfig } from './types-CBoVIFI8.js';
5
5
  export { AmplifyRenderer } from './AmplifyRenderer.js';
6
+ export { Q as QueryContentError, e as QueryContentOptions, k as QueryFilter, l as QueryFilterOp, i as QueryPagination, h as QueryResult, m as QuerySort, j as QuerySpec, S as SelectVariantsError, a as SelectVariantsOptions, b as SelectVariantsResult, n as nextPageSpec, q as queryContent, d as searchSpec, s as selectVariants } from './query-DjIuJ71C.js';
6
7
  export { i as isComposerPreview, a as isPreviewRequest, b as isWorkingContentRequest } from './preview-_vHmzRen.js';
7
8
  export { fetchPageConfigServer } from './server.js';
8
9
 
package/dist/react.js CHANGED
@@ -577,6 +577,145 @@ async function fetchContent(options) {
577
577
  }
578
578
  }
579
579
 
580
+ // src/edge/select.ts
581
+ var SelectVariantsError = class extends Error {
582
+ constructor(message, status, body) {
583
+ super(message);
584
+ this.name = "SelectVariantsError";
585
+ this.status = status;
586
+ this.body = body;
587
+ }
588
+ };
589
+ async function fetchEdgeSelect(options) {
590
+ const base = options.edgeUrl.replace(/\/+$/, "");
591
+ const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);
592
+ if (!options.trackingId && !options.site) {
593
+ throw new SelectVariantsError("trackingId or site is required", 400);
594
+ }
595
+ const res = await fetchFn(`${base}/v1/select`, {
596
+ method: "POST",
597
+ headers: {
598
+ Accept: "application/json",
599
+ "Content-Type": "application/json"
600
+ },
601
+ cache: "no-store",
602
+ signal: options.signal,
603
+ body: JSON.stringify({
604
+ view: normalizeRoute(options.view),
605
+ ...options.trackingId ? { trackingId: options.trackingId } : {},
606
+ ...options.site ? { site: options.site } : {},
607
+ anonId: options.anonId,
608
+ ...options.zones?.length ? { zones: options.zones } : {},
609
+ ...options.context ? { context: options.context } : {}
610
+ })
611
+ });
612
+ const body = await res.json().catch(() => ({}));
613
+ if (!res.ok) {
614
+ throw new SelectVariantsError(
615
+ body.error || `Select failed (${res.status})`,
616
+ res.status,
617
+ body
618
+ );
619
+ }
620
+ return {
621
+ siteId: String(body.siteId || ""),
622
+ view: String(body.view || normalizeRoute(options.view)),
623
+ variantKeys: body.variantKeys && typeof body.variantKeys === "object" ? body.variantKeys : {},
624
+ meta: body.meta
625
+ };
626
+ }
627
+ async function selectVariants(options) {
628
+ const target = resolveAmplifyUpTarget({ configTarget: options.target });
629
+ const { edgeUrl } = resolveAmplifyUpUrls(target);
630
+ return fetchEdgeSelect({
631
+ edgeUrl: options.edgeUrl || edgeUrl,
632
+ trackingId: options.trackingId,
633
+ site: options.site,
634
+ view: options.view,
635
+ anonId: options.anonId,
636
+ zones: options.zones,
637
+ context: options.context,
638
+ fetch: options.fetch,
639
+ signal: options.signal
640
+ });
641
+ }
642
+
643
+ // src/edge/query.ts
644
+ var QueryContentError = class extends Error {
645
+ constructor(message, status, body) {
646
+ super(message);
647
+ this.name = "QueryContentError";
648
+ this.status = status;
649
+ this.body = body;
650
+ }
651
+ };
652
+ async function fetchEdgeQuery(options) {
653
+ const base = options.edgeUrl.replace(/\/+$/, "");
654
+ const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);
655
+ const limit = Math.max(1, Number(options.spec.limit) || 10);
656
+ const offset = Math.max(0, Number(options.spec.offset) || 0);
657
+ const res = await fetchFn(`${base}/v1/query`, {
658
+ method: "POST",
659
+ headers: {
660
+ Accept: "application/json",
661
+ "Content-Type": "application/json"
662
+ },
663
+ cache: "no-store",
664
+ signal: options.signal,
665
+ body: JSON.stringify({
666
+ route: normalizeRoute(options.route),
667
+ trackingId: options.trackingId,
668
+ ...options.siteId ? { site: options.siteId } : {},
669
+ spec: { ...options.spec, limit, offset }
670
+ })
671
+ });
672
+ const body = await res.json().catch(() => ({}));
673
+ if (!res.ok) {
674
+ throw new QueryContentError(
675
+ body.error || `Content query failed (${res.status})`,
676
+ res.status,
677
+ body
678
+ );
679
+ }
680
+ const results = Array.isArray(body.results) ? body.results : [];
681
+ const resolvedLimit = Number(body.limit) || limit;
682
+ const resolvedOffset = Number.isFinite(Number(body.offset)) ? Number(body.offset) : offset;
683
+ return {
684
+ results,
685
+ count: Number(body.count) || results.length,
686
+ hasMore: !!body.hasMore,
687
+ limit: resolvedLimit,
688
+ offset: resolvedOffset,
689
+ nextOffset: Number(body.nextOffset) || resolvedOffset + resolvedLimit,
690
+ degraded: body.degraded
691
+ };
692
+ }
693
+ async function queryContent(options) {
694
+ const target = resolveAmplifyUpTarget({ configTarget: options.target });
695
+ const { edgeUrl } = resolveAmplifyUpUrls(target);
696
+ return fetchEdgeQuery({
697
+ edgeUrl,
698
+ trackingId: options.trackingId,
699
+ route: options.route,
700
+ spec: options.spec,
701
+ siteId: options.siteId,
702
+ fetch: options.fetch,
703
+ signal: options.signal
704
+ });
705
+ }
706
+ function nextPageSpec(pagination) {
707
+ return { ...pagination.spec, offset: pagination.nextOffset };
708
+ }
709
+ function searchSpec(pagination, field, term) {
710
+ const value = String(term || "").trim();
711
+ const base = { ...pagination.spec, offset: 0 };
712
+ if (!value) return base;
713
+ return {
714
+ ...base,
715
+ filter: [...base.filter || [], { field, op: "contains", value }]
716
+ };
717
+ }
718
+
580
719
  // src/index.ts
581
720
  var SESSION_IDLE_GAP_MS = 30 * 60 * 1e3;
582
721
  var DWELL_ACTIVITY_IDLE_MS = 2 * 60 * 1e3;
@@ -4061,14 +4200,31 @@ function AmplifyUpProvider({ children, config }) {
4061
4200
  setLoading(false);
4062
4201
  return;
4063
4202
  }
4203
+ let variantKeys;
4204
+ const anonId = sdk.getInstanceId();
4205
+ if (!preview && anonId) {
4206
+ try {
4207
+ const selected = await selectVariants({
4208
+ trackingId,
4209
+ view: actualRoute,
4210
+ anonId,
4211
+ site: sdk.getSiteId() || void 0,
4212
+ edgeUrl
4213
+ });
4214
+ variantKeys = selected.variantKeys;
4215
+ } catch (err) {
4216
+ console.error("AmplifyUp selectVariants failed; overlay will use visitor id", err);
4217
+ }
4218
+ }
4064
4219
  const result = await fetchContent({
4065
4220
  route: actualRoute,
4066
4221
  trackingId,
4067
- anonId: sdk.getInstanceId(),
4222
+ anonId: variantKeys ? void 0 : anonId,
4068
4223
  siteId: sdk.getSiteId() || null,
4069
4224
  preview,
4070
4225
  orchestratorUrl,
4071
4226
  edgeUrl,
4227
+ variantKeys,
4072
4228
  fetchOrchestratorPage: (route, isPreview) => sdk.fetchPageConfig(route, isPreview)
4073
4229
  });
4074
4230
  if (cancelled) return;
@@ -4123,12 +4279,18 @@ exports.AmplifyUpProvider = AmplifyUpProvider;
4123
4279
  exports.ComponentContextProvider = ComponentContextProvider;
4124
4280
  exports.Field = Field;
4125
4281
  exports.Image = Image;
4282
+ exports.QueryContentError = QueryContentError;
4126
4283
  exports.RichText = RichText;
4284
+ exports.SelectVariantsError = SelectVariantsError;
4127
4285
  exports.Slot = Slot;
4128
4286
  exports.fetchPageConfigServer = fetchPageConfigServer;
4129
4287
  exports.isComposerPreview = isComposerPreview;
4130
4288
  exports.isPreviewRequest = isPreviewRequest;
4131
4289
  exports.isWorkingContentRequest = isWorkingContentRequest;
4290
+ exports.nextPageSpec = nextPageSpec;
4291
+ exports.queryContent = queryContent;
4292
+ exports.searchSpec = searchSpec;
4293
+ exports.selectVariants = selectVariants;
4132
4294
  exports.useAmplifyUp = useAmplifyUp;
4133
4295
  exports.useComponentProps = useComponentProps;
4134
4296
  exports.useLiveComposerProps = useLiveComposerProps;