@reblu/site-client 5.12.0 → 5.14.0
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/CHANGELOG.md +12 -0
- package/README.md +49 -0
- package/dist/index.cjs +88 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -20
- package/dist/index.d.ts +25 -20
- package/dist/index.js +88 -16
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _reblu_site_contracts from '@reblu/site-contracts';
|
|
2
|
-
import {
|
|
2
|
+
import { AcademyCourseListQuery, PaginationMeta, PageType, PagesListSort, ShopSort, TrustBadgeType, ContactFormInput } from '@reblu/site-contracts';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Cache adapter — the seam that severs the SDK from any framework's caching
|
|
@@ -91,28 +91,21 @@ interface ShopProductsParams {
|
|
|
91
91
|
/**
|
|
92
92
|
* Query params for `academy.courses` (REB-507), grounded on
|
|
93
93
|
* `GET /api/site/academy/courses` — see `parseCourseListParams` in base-api.
|
|
94
|
+
* Since REB-547 this IS the documented query contract (`AcademyCourseListQuery`,
|
|
95
|
+
* the same keys the OpenAPI document lists), so the SDK cannot drift from it.
|
|
94
96
|
*
|
|
95
97
|
* Server-side clamping the caller should know about: `limit` is clamped to 1..50
|
|
96
98
|
* and `page` to >= 1, so an out-of-range value is silently corrected rather than
|
|
97
|
-
* rejected. `q`/`
|
|
98
|
-
*
|
|
99
|
-
* `
|
|
100
|
-
*
|
|
99
|
+
* rejected. `q`/`category` are truncated (200/120 chars).
|
|
100
|
+
* - `category`: a `CourseCategory` slug. Only ACTIVE categories ever match.
|
|
101
|
+
* - `instructor`: a user id from `academy.instructors()`. A value that is not a
|
|
102
|
+
* uuid matches no course.
|
|
103
|
+
* - `priceMin`/`priceMax`: inclusive, in integer cents.
|
|
104
|
+
* - `free: true` means "price is 0" and OVERRIDES any priceMin/priceMax range.
|
|
105
|
+
* - `sort` is a union because an unrecognized key is ignored server-side — typing
|
|
106
|
+
* it makes a typo a compile error instead of a silent fall-back to default order.
|
|
101
107
|
*/
|
|
102
|
-
|
|
103
|
-
page?: number;
|
|
104
|
-
limit?: number;
|
|
105
|
-
q?: string;
|
|
106
|
-
sort?: AcademyCourseSort;
|
|
107
|
-
/** A `CourseCategory` slug. Only ACTIVE categories ever match. */
|
|
108
|
-
category?: string;
|
|
109
|
-
/** A user id — `Course.instructorIds` is a denormalized user-uuid array. */
|
|
110
|
-
instructor?: string;
|
|
111
|
-
/** Restrict to free courses (priceCents = 0); overrides priceMin/priceMax. */
|
|
112
|
-
free?: boolean;
|
|
113
|
-
priceMin?: number;
|
|
114
|
-
priceMax?: number;
|
|
115
|
-
}
|
|
108
|
+
type AcademyCourseListParams = AcademyCourseListQuery;
|
|
116
109
|
/**
|
|
117
110
|
* Body of `academy.enrollmentRequest`, grounded on
|
|
118
111
|
* `POST /api/site/academy/enrollment-requests`.
|
|
@@ -146,6 +139,10 @@ interface AcademyEnrollmentRequestResult {
|
|
|
146
139
|
message: string;
|
|
147
140
|
}
|
|
148
141
|
|
|
142
|
+
/** Memo store of one server request, keyed by read identity (REB-1214). */
|
|
143
|
+
type RequestScope = () => Map<string, Promise<unknown>> | undefined;
|
|
144
|
+
/** Upper bound for a `Retry-After` wait before the single retry (REB-1214). */
|
|
145
|
+
declare const RETRY_AFTER_CAP_MS = 2000;
|
|
149
146
|
/**
|
|
150
147
|
* Header carrying the visitor IP from a SITE server to base-api (REB-1005).
|
|
151
148
|
* base-api keys its per-visitor limit on public writes on it, and trusts it
|
|
@@ -385,6 +382,13 @@ interface RebluClientConfig {
|
|
|
385
382
|
* a Stripe CLI mock host) — never to widen production trust.
|
|
386
383
|
*/
|
|
387
384
|
checkoutRedirectHosts?: string[];
|
|
385
|
+
/**
|
|
386
|
+
* REB-1214 — memo store of the current server request, so identical GET
|
|
387
|
+
* reads within it are fetched once. In Next.js pass `rebluRequestScope`
|
|
388
|
+
* from `@reblu/site-next` (React `cache()`); see the README. Without it,
|
|
389
|
+
* identical GETs share one fetch only while in flight.
|
|
390
|
+
*/
|
|
391
|
+
requestScope?: RequestScope;
|
|
388
392
|
}
|
|
389
393
|
/**
|
|
390
394
|
* Build a Reblu SITE API client. Each domain is a small namespace of bound
|
|
@@ -440,6 +444,7 @@ declare function createRebluClient(config: RebluClientConfig): {
|
|
|
440
444
|
courses: (params?: AcademyCourseListParams, cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCourseSummary>>;
|
|
441
445
|
bySlug: (slug: string, cache?: RebluCachePolicy) => Promise<_reblu_site_contracts.AcademyCourseDetail>;
|
|
442
446
|
lessonPreview: (courseSlug: string, lessonSlug: string) => Promise<_reblu_site_contracts.AcademyLessonPreview>;
|
|
447
|
+
instructors: (cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyInstructorPublic>>;
|
|
443
448
|
categories: (cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCategoryPublic>>;
|
|
444
449
|
enrollmentRequest: (body: AcademyEnrollmentRequestInput, options?: RebluMutationOptions) => Promise<AcademyEnrollmentRequestResult>;
|
|
445
450
|
};
|
|
@@ -456,4 +461,4 @@ declare function createRebluClient(config: RebluClientConfig): {
|
|
|
456
461
|
/** The assembled client returned by {@link createRebluClient}. */
|
|
457
462
|
type RebluClient = ReturnType<typeof createRebluClient>;
|
|
458
463
|
|
|
459
|
-
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, type ContactFormMetadata, type ContactFormMetadataOptions, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageLocation, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type RebluMutationOptions, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, buildContactFormMetadata, createRebluClient, currentPagePath, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
|
464
|
+
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, type ContactFormMetadata, type ContactFormMetadataOptions, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageLocation, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, RETRY_AFTER_CAP_MS, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type RebluMutationOptions, type RequestScope, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, buildContactFormMetadata, createRebluClient, currentPagePath, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _reblu_site_contracts from '@reblu/site-contracts';
|
|
2
|
-
import {
|
|
2
|
+
import { AcademyCourseListQuery, PaginationMeta, PageType, PagesListSort, ShopSort, TrustBadgeType, ContactFormInput } from '@reblu/site-contracts';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Cache adapter — the seam that severs the SDK from any framework's caching
|
|
@@ -91,28 +91,21 @@ interface ShopProductsParams {
|
|
|
91
91
|
/**
|
|
92
92
|
* Query params for `academy.courses` (REB-507), grounded on
|
|
93
93
|
* `GET /api/site/academy/courses` — see `parseCourseListParams` in base-api.
|
|
94
|
+
* Since REB-547 this IS the documented query contract (`AcademyCourseListQuery`,
|
|
95
|
+
* the same keys the OpenAPI document lists), so the SDK cannot drift from it.
|
|
94
96
|
*
|
|
95
97
|
* Server-side clamping the caller should know about: `limit` is clamped to 1..50
|
|
96
98
|
* and `page` to >= 1, so an out-of-range value is silently corrected rather than
|
|
97
|
-
* rejected. `q`/`
|
|
98
|
-
*
|
|
99
|
-
* `
|
|
100
|
-
*
|
|
99
|
+
* rejected. `q`/`category` are truncated (200/120 chars).
|
|
100
|
+
* - `category`: a `CourseCategory` slug. Only ACTIVE categories ever match.
|
|
101
|
+
* - `instructor`: a user id from `academy.instructors()`. A value that is not a
|
|
102
|
+
* uuid matches no course.
|
|
103
|
+
* - `priceMin`/`priceMax`: inclusive, in integer cents.
|
|
104
|
+
* - `free: true` means "price is 0" and OVERRIDES any priceMin/priceMax range.
|
|
105
|
+
* - `sort` is a union because an unrecognized key is ignored server-side — typing
|
|
106
|
+
* it makes a typo a compile error instead of a silent fall-back to default order.
|
|
101
107
|
*/
|
|
102
|
-
|
|
103
|
-
page?: number;
|
|
104
|
-
limit?: number;
|
|
105
|
-
q?: string;
|
|
106
|
-
sort?: AcademyCourseSort;
|
|
107
|
-
/** A `CourseCategory` slug. Only ACTIVE categories ever match. */
|
|
108
|
-
category?: string;
|
|
109
|
-
/** A user id — `Course.instructorIds` is a denormalized user-uuid array. */
|
|
110
|
-
instructor?: string;
|
|
111
|
-
/** Restrict to free courses (priceCents = 0); overrides priceMin/priceMax. */
|
|
112
|
-
free?: boolean;
|
|
113
|
-
priceMin?: number;
|
|
114
|
-
priceMax?: number;
|
|
115
|
-
}
|
|
108
|
+
type AcademyCourseListParams = AcademyCourseListQuery;
|
|
116
109
|
/**
|
|
117
110
|
* Body of `academy.enrollmentRequest`, grounded on
|
|
118
111
|
* `POST /api/site/academy/enrollment-requests`.
|
|
@@ -146,6 +139,10 @@ interface AcademyEnrollmentRequestResult {
|
|
|
146
139
|
message: string;
|
|
147
140
|
}
|
|
148
141
|
|
|
142
|
+
/** Memo store of one server request, keyed by read identity (REB-1214). */
|
|
143
|
+
type RequestScope = () => Map<string, Promise<unknown>> | undefined;
|
|
144
|
+
/** Upper bound for a `Retry-After` wait before the single retry (REB-1214). */
|
|
145
|
+
declare const RETRY_AFTER_CAP_MS = 2000;
|
|
149
146
|
/**
|
|
150
147
|
* Header carrying the visitor IP from a SITE server to base-api (REB-1005).
|
|
151
148
|
* base-api keys its per-visitor limit on public writes on it, and trusts it
|
|
@@ -385,6 +382,13 @@ interface RebluClientConfig {
|
|
|
385
382
|
* a Stripe CLI mock host) — never to widen production trust.
|
|
386
383
|
*/
|
|
387
384
|
checkoutRedirectHosts?: string[];
|
|
385
|
+
/**
|
|
386
|
+
* REB-1214 — memo store of the current server request, so identical GET
|
|
387
|
+
* reads within it are fetched once. In Next.js pass `rebluRequestScope`
|
|
388
|
+
* from `@reblu/site-next` (React `cache()`); see the README. Without it,
|
|
389
|
+
* identical GETs share one fetch only while in flight.
|
|
390
|
+
*/
|
|
391
|
+
requestScope?: RequestScope;
|
|
388
392
|
}
|
|
389
393
|
/**
|
|
390
394
|
* Build a Reblu SITE API client. Each domain is a small namespace of bound
|
|
@@ -440,6 +444,7 @@ declare function createRebluClient(config: RebluClientConfig): {
|
|
|
440
444
|
courses: (params?: AcademyCourseListParams, cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCourseSummary>>;
|
|
441
445
|
bySlug: (slug: string, cache?: RebluCachePolicy) => Promise<_reblu_site_contracts.AcademyCourseDetail>;
|
|
442
446
|
lessonPreview: (courseSlug: string, lessonSlug: string) => Promise<_reblu_site_contracts.AcademyLessonPreview>;
|
|
447
|
+
instructors: (cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyInstructorPublic>>;
|
|
443
448
|
categories: (cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCategoryPublic>>;
|
|
444
449
|
enrollmentRequest: (body: AcademyEnrollmentRequestInput, options?: RebluMutationOptions) => Promise<AcademyEnrollmentRequestResult>;
|
|
445
450
|
};
|
|
@@ -456,4 +461,4 @@ declare function createRebluClient(config: RebluClientConfig): {
|
|
|
456
461
|
/** The assembled client returned by {@link createRebluClient}. */
|
|
457
462
|
type RebluClient = ReturnType<typeof createRebluClient>;
|
|
458
463
|
|
|
459
|
-
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, type ContactFormMetadata, type ContactFormMetadataOptions, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageLocation, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type RebluMutationOptions, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, buildContactFormMetadata, createRebluClient, currentPagePath, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
|
464
|
+
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, type ContactFormMetadata, type ContactFormMetadataOptions, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageLocation, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, RETRY_AFTER_CAP_MS, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type RebluMutationOptions, type RequestScope, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, buildContactFormMetadata, createRebluClient, currentPagePath, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
package/dist/index.js
CHANGED
|
@@ -131,25 +131,87 @@ function apiErrorRawBody(error) {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
// src/client.ts
|
|
134
|
+
var RETRY_AFTER_CAP_MS = 2e3;
|
|
135
|
+
var DEFAULT_RETRY_DELAY_MS = 250;
|
|
136
|
+
var RETRYABLE_READ_STATUSES = /* @__PURE__ */ new Set([429, 503]);
|
|
137
|
+
function retryDelayMs(header) {
|
|
138
|
+
if (header !== null && header.trim() !== "") {
|
|
139
|
+
const value = header.trim();
|
|
140
|
+
const seconds = /^\d+$/.test(value) ? Number(value) * 1e3 : NaN;
|
|
141
|
+
const ms = Number.isFinite(seconds) ? seconds : Date.parse(value) - Date.now();
|
|
142
|
+
if (Number.isFinite(ms)) return Math.min(Math.max(0, ms), RETRY_AFTER_CAP_MS);
|
|
143
|
+
}
|
|
144
|
+
return DEFAULT_RETRY_DELAY_MS;
|
|
145
|
+
}
|
|
146
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
134
147
|
async function request(ctx, path, opts) {
|
|
135
|
-
const
|
|
148
|
+
const method = opts.method ?? "GET";
|
|
149
|
+
const init = {
|
|
150
|
+
method,
|
|
151
|
+
body: opts.body,
|
|
152
|
+
headers: {
|
|
153
|
+
"X-Reblu-Api-Key": ctx.apiKey,
|
|
154
|
+
"X-Reblu-Api-Version": ctx.apiVersion,
|
|
155
|
+
"Content-Type": "application/json",
|
|
156
|
+
...opts.headers
|
|
157
|
+
},
|
|
158
|
+
...ctx.cache.resolveRequestInit(opts.cachePolicy ?? {})
|
|
159
|
+
};
|
|
160
|
+
if (method !== "GET" || opts.body !== void 0) {
|
|
161
|
+
return attempt(ctx, path, init);
|
|
162
|
+
}
|
|
163
|
+
const key = JSON.stringify([ctx.baseUrl + path, init]);
|
|
164
|
+
const scope = ctx.requestScope?.();
|
|
165
|
+
const store = scope ?? ctx.inFlight;
|
|
166
|
+
const existing = store?.get(key);
|
|
167
|
+
if (existing) return existing;
|
|
168
|
+
const pending = readWithRetry(ctx, path, init);
|
|
169
|
+
if (store) {
|
|
170
|
+
store.set(key, pending);
|
|
171
|
+
pending.then(
|
|
172
|
+
() => {
|
|
173
|
+
if (!scope) store.delete(key);
|
|
174
|
+
},
|
|
175
|
+
() => {
|
|
176
|
+
if (store.get(key) === pending) store.delete(key);
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
return pending;
|
|
181
|
+
}
|
|
182
|
+
async function readWithRetry(ctx, path, init) {
|
|
183
|
+
try {
|
|
184
|
+
return await attempt(ctx, path, init);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
if (!(error instanceof RetryableReadError)) throw error;
|
|
187
|
+
await sleep(retryDelayMs(error.retryAfter));
|
|
188
|
+
try {
|
|
189
|
+
return await attempt(ctx, path, init);
|
|
190
|
+
} catch (retryError) {
|
|
191
|
+
throw retryError instanceof RetryableReadError ? retryError.apiError : retryError;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
var RetryableReadError = class extends Error {
|
|
196
|
+
constructor(apiError, retryAfter) {
|
|
197
|
+
super(apiError.message);
|
|
198
|
+
this.apiError = apiError;
|
|
199
|
+
this.retryAfter = retryAfter;
|
|
200
|
+
}
|
|
201
|
+
apiError;
|
|
202
|
+
retryAfter;
|
|
203
|
+
};
|
|
204
|
+
async function attempt(ctx, path, init) {
|
|
136
205
|
const controller = new AbortController();
|
|
137
206
|
const timer = setTimeout(() => controller.abort(), ctx.timeoutMs);
|
|
138
207
|
try {
|
|
139
|
-
const res = await ctx.fetch(
|
|
140
|
-
method: opts.method ?? "GET",
|
|
141
|
-
body: opts.body,
|
|
142
|
-
signal: controller.signal,
|
|
143
|
-
headers: {
|
|
144
|
-
"X-Reblu-Api-Key": ctx.apiKey,
|
|
145
|
-
"X-Reblu-Api-Version": ctx.apiVersion,
|
|
146
|
-
"Content-Type": "application/json",
|
|
147
|
-
...opts.headers
|
|
148
|
-
},
|
|
149
|
-
...ctx.cache.resolveRequestInit(opts.cachePolicy ?? {})
|
|
150
|
-
});
|
|
208
|
+
const res = await ctx.fetch(ctx.baseUrl + path, { ...init, signal: controller.signal });
|
|
151
209
|
if (!res.ok) {
|
|
152
|
-
|
|
210
|
+
const error = new ApiError(res.status, path, await res.text());
|
|
211
|
+
if (init.method === "GET" && RETRYABLE_READ_STATUSES.has(res.status)) {
|
|
212
|
+
throw new RetryableReadError(error, res.headers.get("retry-after"));
|
|
213
|
+
}
|
|
214
|
+
throw error;
|
|
153
215
|
}
|
|
154
216
|
return await res.json();
|
|
155
217
|
} finally {
|
|
@@ -220,6 +282,14 @@ function makeAcademyNamespace(ctx) {
|
|
|
220
282
|
`/api/site/academy/courses/${encodeURIComponent(courseSlug)}/lessons/${encodeURIComponent(lessonSlug)}`,
|
|
221
283
|
{ cachePolicy: { revalidate: false } }
|
|
222
284
|
),
|
|
285
|
+
/**
|
|
286
|
+
* Instructors of published courses, sorted by name, backing the catalog
|
|
287
|
+
* instructor filter (REB-547). Pass an `id` as `courses({ instructor })`.
|
|
288
|
+
* Not paginated.
|
|
289
|
+
*/
|
|
290
|
+
instructors: (cache) => requestList(ctx, "/api/site/academy/instructors", {
|
|
291
|
+
cachePolicy: cache
|
|
292
|
+
}),
|
|
223
293
|
/** Active course categories backing the catalog filter. Not paginated. */
|
|
224
294
|
categories: (cache) => requestList(ctx, "/api/site/academy/categories", {
|
|
225
295
|
cachePolicy: cache
|
|
@@ -529,7 +599,9 @@ function createRebluClient(config) {
|
|
|
529
599
|
cache: config.cache ?? new PlainCacheAdapter(),
|
|
530
600
|
timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
531
601
|
fetch: boundFetch,
|
|
532
|
-
checkoutRedirectHosts: config.checkoutRedirectHosts ?? DEFAULT_CHECKOUT_REDIRECT_HOSTS
|
|
602
|
+
checkoutRedirectHosts: config.checkoutRedirectHosts ?? DEFAULT_CHECKOUT_REDIRECT_HOSTS,
|
|
603
|
+
requestScope: config.requestScope,
|
|
604
|
+
inFlight: /* @__PURE__ */ new Map()
|
|
533
605
|
};
|
|
534
606
|
return {
|
|
535
607
|
config: makeConfigNamespace(ctx),
|
|
@@ -547,6 +619,6 @@ function createRebluClient(config) {
|
|
|
547
619
|
};
|
|
548
620
|
}
|
|
549
621
|
|
|
550
|
-
export { AmbiguousPageSlugError, ApiError, DEFAULT_CHECKOUT_REDIRECT_HOSTS, PlainCacheAdapter, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, buildContactFormMetadata, createRebluClient, currentPagePath, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
|
622
|
+
export { AmbiguousPageSlugError, ApiError, DEFAULT_CHECKOUT_REDIRECT_HOSTS, PlainCacheAdapter, RETRY_AFTER_CAP_MS, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, buildContactFormMetadata, createRebluClient, currentPagePath, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
|
551
623
|
//# sourceMappingURL=index.js.map
|
|
552
624
|
//# sourceMappingURL=index.js.map
|