@reblu/site-client 5.8.0 → 5.10.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 +53 -1
- package/dist/index.cjs +72 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -28
- package/dist/index.d.ts +55 -28
- package/dist/index.js +71 -14
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
import * as _reblu_site_contracts from '@reblu/site-contracts';
|
|
2
2
|
import { AcademyCourseSort, PaginationMeta, PageType, PagesListSort, ShopSort, TrustBadgeType } from '@reblu/site-contracts';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Cache adapter — the seam that severs the SDK from any framework's caching
|
|
6
|
+
* model (design doc D4 / §3.2). The client owns *when* to cache (a per-call
|
|
7
|
+
* `RebluCachePolicy`); the adapter owns *how* (the framework-specific
|
|
8
|
+
* `RequestInit` fields). `@reblu/site-client` ships the framework-agnostic
|
|
9
|
+
* `PlainCacheAdapter`; `@reblu/site-next` (REB-418) supplies a `NextCacheAdapter`
|
|
10
|
+
* that returns `{ next: { revalidate } }`.
|
|
11
|
+
*/
|
|
12
|
+
interface RebluCachePolicy {
|
|
13
|
+
/**
|
|
14
|
+
* Seconds to revalidate. `undefined` → use the adapter's default; `0`/`false`
|
|
15
|
+
* → never cache (always fetch fresh).
|
|
16
|
+
*/
|
|
17
|
+
revalidate?: number | false;
|
|
18
|
+
}
|
|
19
|
+
interface RebluCacheAdapter {
|
|
20
|
+
/** Map a per-call cache policy to framework-specific `fetch` `RequestInit` fields. */
|
|
21
|
+
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Default adapter — plain `fetch` cache semantics that work in Node, edge,
|
|
25
|
+
* browser and tests. No `next`, no `server-only`.
|
|
26
|
+
*/
|
|
27
|
+
declare class PlainCacheAdapter implements RebluCacheAdapter {
|
|
28
|
+
private readonly defaultRevalidate;
|
|
29
|
+
constructor(defaultRevalidate?: number | false);
|
|
30
|
+
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
31
|
+
}
|
|
32
|
+
|
|
4
33
|
/**
|
|
5
34
|
* The shape every list method returns. Unlike demo-site's old bare-array return,
|
|
6
35
|
* the SDK surfaces `meta` so pagination is never silently dropped (design doc
|
|
@@ -118,33 +147,31 @@ interface AcademyEnrollmentRequestResult {
|
|
|
118
147
|
}
|
|
119
148
|
|
|
120
149
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* `RequestInit` fields). `@reblu/site-client` ships the framework-agnostic
|
|
125
|
-
* `PlainCacheAdapter`; `@reblu/site-next` (REB-418) supplies a `NextCacheAdapter`
|
|
126
|
-
* that returns `{ next: { revalidate } }`.
|
|
150
|
+
* Header carrying the visitor IP from a SITE server to base-api (REB-1005).
|
|
151
|
+
* base-api keys its per-visitor limit on public writes on it, and trusts it
|
|
152
|
+
* only behind a valid API key.
|
|
127
153
|
*/
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Seconds to revalidate. `undefined` → use the adapter's default; `0`/`false`
|
|
131
|
-
* → never cache (always fetch fresh).
|
|
132
|
-
*/
|
|
133
|
-
revalidate?: number | false;
|
|
134
|
-
}
|
|
135
|
-
interface RebluCacheAdapter {
|
|
136
|
-
/** Map a per-call cache policy to framework-specific `fetch` `RequestInit` fields. */
|
|
137
|
-
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
138
|
-
}
|
|
154
|
+
declare const VISITOR_IP_HEADER = "x-reblu-visitor-ip";
|
|
139
155
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
156
|
+
* Per-call options for a write (REB-1005).
|
|
157
|
+
*
|
|
158
|
+
* - `visitorIp` — the visitor's IP when a SITE calls the SDK server-side, sent
|
|
159
|
+
* as `x-reblu-visitor-ip`. Do NOT rely on forwarding `x-forwarded-for`: on
|
|
160
|
+
* Vercel the SITE→base-api hop gets it overwritten with the SITE function's
|
|
161
|
+
* egress IP. Read it from the INCOMING request with
|
|
162
|
+
* {@link visitorIpFromHeaders}.
|
|
163
|
+
* - `headers` — other extra headers (e.g. `user-agent`). They can never set
|
|
164
|
+
* `x-reblu-visitor-ip` nor replace `X-Reblu-Api-Key`, `X-Reblu-Api-Version`
|
|
165
|
+
* or `Content-Type`.
|
|
142
166
|
*/
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
167
|
+
interface RebluMutationOptions {
|
|
168
|
+
visitorIp?: string;
|
|
169
|
+
headers?: Record<string, string>;
|
|
147
170
|
}
|
|
171
|
+
/** The visitor IP of an incoming request: first `x-forwarded-for` entry, else `x-real-ip`. */
|
|
172
|
+
declare function visitorIpFromHeaders(headers: {
|
|
173
|
+
get(name: string): string | null;
|
|
174
|
+
}): string | undefined;
|
|
148
175
|
|
|
149
176
|
/**
|
|
150
177
|
* The `details` shape `/api/site/contact-form` and `/api/site/leads` attach on a
|
|
@@ -364,26 +391,26 @@ declare function createRebluClient(config: RebluClientConfig): {
|
|
|
364
391
|
checkout: (body: _reblu_site_contracts.ShopCheckoutInput) => Promise<_reblu_site_contracts.ShopCheckoutSession>;
|
|
365
392
|
validateCart: (body: _reblu_site_contracts.ShopValidateCartInput) => Promise<_reblu_site_contracts.ShopCartValidation>;
|
|
366
393
|
applyDiscount: (body: _reblu_site_contracts.ShopApplyDiscountInput) => Promise<_reblu_site_contracts.ShopDiscountApplication>;
|
|
367
|
-
checkEmail: (body: _reblu_site_contracts.ShopCheckEmailInput) => Promise<_reblu_site_contracts.ShopEmailCheck>;
|
|
394
|
+
checkEmail: (body: _reblu_site_contracts.ShopCheckEmailInput, options?: RebluMutationOptions) => Promise<_reblu_site_contracts.ShopEmailCheck>;
|
|
368
395
|
order: (sessionId: string, cache?: RebluCachePolicy) => Promise<_reblu_site_contracts.ShopOrder>;
|
|
369
396
|
};
|
|
370
397
|
academy: {
|
|
371
398
|
courses: (params?: AcademyCourseListParams, cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCourseSummary>>;
|
|
372
399
|
bySlug: (slug: string, cache?: RebluCachePolicy) => Promise<_reblu_site_contracts.AcademyCourseDetail>;
|
|
373
400
|
categories: (cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCategoryPublic>>;
|
|
374
|
-
enrollmentRequest: (body: AcademyEnrollmentRequestInput) => Promise<AcademyEnrollmentRequestResult>;
|
|
401
|
+
enrollmentRequest: (body: AcademyEnrollmentRequestInput, options?: RebluMutationOptions) => Promise<AcademyEnrollmentRequestResult>;
|
|
375
402
|
};
|
|
376
403
|
contactForm: {
|
|
377
|
-
submit: (body: _reblu_site_contracts.ContactFormInput) => Promise<_reblu_site_contracts.ContactFormSubmission>;
|
|
404
|
+
submit: (body: _reblu_site_contracts.ContactFormInput, options?: RebluMutationOptions) => Promise<_reblu_site_contracts.ContactFormSubmission>;
|
|
378
405
|
};
|
|
379
406
|
leads: {
|
|
380
407
|
create: (body: _reblu_site_contracts.LeadInput) => Promise<_reblu_site_contracts.LeadSubmission>;
|
|
381
408
|
};
|
|
382
409
|
dataRequests: {
|
|
383
|
-
submit: (body: _reblu_site_contracts.DataRequestInput) => Promise<_reblu_site_contracts.DataRequestSubmission>;
|
|
410
|
+
submit: (body: _reblu_site_contracts.DataRequestInput, options?: RebluMutationOptions) => Promise<_reblu_site_contracts.DataRequestSubmission>;
|
|
384
411
|
};
|
|
385
412
|
};
|
|
386
413
|
/** The assembled client returned by {@link createRebluClient}. */
|
|
387
414
|
type RebluClient = ReturnType<typeof createRebluClient>;
|
|
388
415
|
|
|
389
|
-
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, createRebluClient, isSafeCheckoutRedirectUrl };
|
|
416
|
+
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type RebluMutationOptions, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, createRebluClient, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
import * as _reblu_site_contracts from '@reblu/site-contracts';
|
|
2
2
|
import { AcademyCourseSort, PaginationMeta, PageType, PagesListSort, ShopSort, TrustBadgeType } from '@reblu/site-contracts';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Cache adapter — the seam that severs the SDK from any framework's caching
|
|
6
|
+
* model (design doc D4 / §3.2). The client owns *when* to cache (a per-call
|
|
7
|
+
* `RebluCachePolicy`); the adapter owns *how* (the framework-specific
|
|
8
|
+
* `RequestInit` fields). `@reblu/site-client` ships the framework-agnostic
|
|
9
|
+
* `PlainCacheAdapter`; `@reblu/site-next` (REB-418) supplies a `NextCacheAdapter`
|
|
10
|
+
* that returns `{ next: { revalidate } }`.
|
|
11
|
+
*/
|
|
12
|
+
interface RebluCachePolicy {
|
|
13
|
+
/**
|
|
14
|
+
* Seconds to revalidate. `undefined` → use the adapter's default; `0`/`false`
|
|
15
|
+
* → never cache (always fetch fresh).
|
|
16
|
+
*/
|
|
17
|
+
revalidate?: number | false;
|
|
18
|
+
}
|
|
19
|
+
interface RebluCacheAdapter {
|
|
20
|
+
/** Map a per-call cache policy to framework-specific `fetch` `RequestInit` fields. */
|
|
21
|
+
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Default adapter — plain `fetch` cache semantics that work in Node, edge,
|
|
25
|
+
* browser and tests. No `next`, no `server-only`.
|
|
26
|
+
*/
|
|
27
|
+
declare class PlainCacheAdapter implements RebluCacheAdapter {
|
|
28
|
+
private readonly defaultRevalidate;
|
|
29
|
+
constructor(defaultRevalidate?: number | false);
|
|
30
|
+
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
31
|
+
}
|
|
32
|
+
|
|
4
33
|
/**
|
|
5
34
|
* The shape every list method returns. Unlike demo-site's old bare-array return,
|
|
6
35
|
* the SDK surfaces `meta` so pagination is never silently dropped (design doc
|
|
@@ -118,33 +147,31 @@ interface AcademyEnrollmentRequestResult {
|
|
|
118
147
|
}
|
|
119
148
|
|
|
120
149
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* `RequestInit` fields). `@reblu/site-client` ships the framework-agnostic
|
|
125
|
-
* `PlainCacheAdapter`; `@reblu/site-next` (REB-418) supplies a `NextCacheAdapter`
|
|
126
|
-
* that returns `{ next: { revalidate } }`.
|
|
150
|
+
* Header carrying the visitor IP from a SITE server to base-api (REB-1005).
|
|
151
|
+
* base-api keys its per-visitor limit on public writes on it, and trusts it
|
|
152
|
+
* only behind a valid API key.
|
|
127
153
|
*/
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Seconds to revalidate. `undefined` → use the adapter's default; `0`/`false`
|
|
131
|
-
* → never cache (always fetch fresh).
|
|
132
|
-
*/
|
|
133
|
-
revalidate?: number | false;
|
|
134
|
-
}
|
|
135
|
-
interface RebluCacheAdapter {
|
|
136
|
-
/** Map a per-call cache policy to framework-specific `fetch` `RequestInit` fields. */
|
|
137
|
-
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
138
|
-
}
|
|
154
|
+
declare const VISITOR_IP_HEADER = "x-reblu-visitor-ip";
|
|
139
155
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
156
|
+
* Per-call options for a write (REB-1005).
|
|
157
|
+
*
|
|
158
|
+
* - `visitorIp` — the visitor's IP when a SITE calls the SDK server-side, sent
|
|
159
|
+
* as `x-reblu-visitor-ip`. Do NOT rely on forwarding `x-forwarded-for`: on
|
|
160
|
+
* Vercel the SITE→base-api hop gets it overwritten with the SITE function's
|
|
161
|
+
* egress IP. Read it from the INCOMING request with
|
|
162
|
+
* {@link visitorIpFromHeaders}.
|
|
163
|
+
* - `headers` — other extra headers (e.g. `user-agent`). They can never set
|
|
164
|
+
* `x-reblu-visitor-ip` nor replace `X-Reblu-Api-Key`, `X-Reblu-Api-Version`
|
|
165
|
+
* or `Content-Type`.
|
|
142
166
|
*/
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
resolveRequestInit(policy: RebluCachePolicy): RequestInit;
|
|
167
|
+
interface RebluMutationOptions {
|
|
168
|
+
visitorIp?: string;
|
|
169
|
+
headers?: Record<string, string>;
|
|
147
170
|
}
|
|
171
|
+
/** The visitor IP of an incoming request: first `x-forwarded-for` entry, else `x-real-ip`. */
|
|
172
|
+
declare function visitorIpFromHeaders(headers: {
|
|
173
|
+
get(name: string): string | null;
|
|
174
|
+
}): string | undefined;
|
|
148
175
|
|
|
149
176
|
/**
|
|
150
177
|
* The `details` shape `/api/site/contact-form` and `/api/site/leads` attach on a
|
|
@@ -364,26 +391,26 @@ declare function createRebluClient(config: RebluClientConfig): {
|
|
|
364
391
|
checkout: (body: _reblu_site_contracts.ShopCheckoutInput) => Promise<_reblu_site_contracts.ShopCheckoutSession>;
|
|
365
392
|
validateCart: (body: _reblu_site_contracts.ShopValidateCartInput) => Promise<_reblu_site_contracts.ShopCartValidation>;
|
|
366
393
|
applyDiscount: (body: _reblu_site_contracts.ShopApplyDiscountInput) => Promise<_reblu_site_contracts.ShopDiscountApplication>;
|
|
367
|
-
checkEmail: (body: _reblu_site_contracts.ShopCheckEmailInput) => Promise<_reblu_site_contracts.ShopEmailCheck>;
|
|
394
|
+
checkEmail: (body: _reblu_site_contracts.ShopCheckEmailInput, options?: RebluMutationOptions) => Promise<_reblu_site_contracts.ShopEmailCheck>;
|
|
368
395
|
order: (sessionId: string, cache?: RebluCachePolicy) => Promise<_reblu_site_contracts.ShopOrder>;
|
|
369
396
|
};
|
|
370
397
|
academy: {
|
|
371
398
|
courses: (params?: AcademyCourseListParams, cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCourseSummary>>;
|
|
372
399
|
bySlug: (slug: string, cache?: RebluCachePolicy) => Promise<_reblu_site_contracts.AcademyCourseDetail>;
|
|
373
400
|
categories: (cache?: RebluCachePolicy) => Promise<ListResult<_reblu_site_contracts.AcademyCategoryPublic>>;
|
|
374
|
-
enrollmentRequest: (body: AcademyEnrollmentRequestInput) => Promise<AcademyEnrollmentRequestResult>;
|
|
401
|
+
enrollmentRequest: (body: AcademyEnrollmentRequestInput, options?: RebluMutationOptions) => Promise<AcademyEnrollmentRequestResult>;
|
|
375
402
|
};
|
|
376
403
|
contactForm: {
|
|
377
|
-
submit: (body: _reblu_site_contracts.ContactFormInput) => Promise<_reblu_site_contracts.ContactFormSubmission>;
|
|
404
|
+
submit: (body: _reblu_site_contracts.ContactFormInput, options?: RebluMutationOptions) => Promise<_reblu_site_contracts.ContactFormSubmission>;
|
|
378
405
|
};
|
|
379
406
|
leads: {
|
|
380
407
|
create: (body: _reblu_site_contracts.LeadInput) => Promise<_reblu_site_contracts.LeadSubmission>;
|
|
381
408
|
};
|
|
382
409
|
dataRequests: {
|
|
383
|
-
submit: (body: _reblu_site_contracts.DataRequestInput) => Promise<_reblu_site_contracts.DataRequestSubmission>;
|
|
410
|
+
submit: (body: _reblu_site_contracts.DataRequestInput, options?: RebluMutationOptions) => Promise<_reblu_site_contracts.DataRequestSubmission>;
|
|
384
411
|
};
|
|
385
412
|
};
|
|
386
413
|
/** The assembled client returned by {@link createRebluClient}. */
|
|
387
414
|
type RebluClient = ReturnType<typeof createRebluClient>;
|
|
388
415
|
|
|
389
|
-
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, createRebluClient, isSafeCheckoutRedirectUrl };
|
|
416
|
+
export { type AcademyCourseListParams, type AcademyEnrollmentRequestInput, type AcademyEnrollmentRequestResult, AmbiguousPageSlugError, ApiError, type ApiErrorBody, type ApiErrorDetails, type BlogListParams, DEFAULT_CHECKOUT_REDIRECT_HOSTS, type FeaturedPagesOptions, type ListResult, type PageBySlugOptions, type PageSlugCandidate, type PagesListParams, PlainCacheAdapter, type RebluCacheAdapter, type RebluCachePolicy, type RebluClient, type RebluClientConfig, type RebluMutationOptions, type ShopProductsParams, type TrustBadgeListParams, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, createRebluClient, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
package/dist/index.js
CHANGED
|
@@ -164,11 +164,33 @@ async function requestList(ctx, path, opts) {
|
|
|
164
164
|
const body = await request(ctx, path, opts);
|
|
165
165
|
return { data: body.data, meta: body.meta };
|
|
166
166
|
}
|
|
167
|
-
|
|
167
|
+
var VISITOR_IP_HEADER = "x-reblu-visitor-ip";
|
|
168
|
+
function visitorIpFromHeaders(headers) {
|
|
169
|
+
return headers.get("x-forwarded-for")?.split(",")[0]?.trim() || headers.get("x-real-ip")?.trim() || void 0;
|
|
170
|
+
}
|
|
171
|
+
var RESERVED_HEADERS = /* @__PURE__ */ new Set([
|
|
172
|
+
"x-reblu-api-key",
|
|
173
|
+
"x-reblu-api-version",
|
|
174
|
+
"content-type",
|
|
175
|
+
VISITOR_IP_HEADER
|
|
176
|
+
]);
|
|
177
|
+
function extraHeaders(options) {
|
|
178
|
+
if (!options?.headers && !options?.visitorIp) return void 0;
|
|
179
|
+
const safe = {};
|
|
180
|
+
for (const [name, value] of Object.entries(options.headers ?? {})) {
|
|
181
|
+
if (!RESERVED_HEADERS.has(name.toLowerCase())) safe[name] = value;
|
|
182
|
+
}
|
|
183
|
+
const visitorIp = options.visitorIp?.trim();
|
|
184
|
+
if (visitorIp) safe[VISITOR_IP_HEADER] = visitorIp;
|
|
185
|
+
return safe;
|
|
186
|
+
}
|
|
187
|
+
async function requestMutation(ctx, path, body, options) {
|
|
188
|
+
const headers = extraHeaders(options);
|
|
168
189
|
const envelope = await request(ctx, path, {
|
|
169
190
|
method: "POST",
|
|
170
191
|
body: JSON.stringify(body),
|
|
171
|
-
cachePolicy: { revalidate: false }
|
|
192
|
+
cachePolicy: { revalidate: false },
|
|
193
|
+
...headers ? { headers } : {}
|
|
172
194
|
});
|
|
173
195
|
return envelope.data;
|
|
174
196
|
}
|
|
@@ -197,12 +219,21 @@ function makeAcademyNamespace(ctx) {
|
|
|
197
219
|
* was new (a request row was created) or already known (a sign-in link was
|
|
198
220
|
* sent and NO request row exists). Never present the returned message as
|
|
199
221
|
* confirmation that a request was recorded — it is not one.
|
|
222
|
+
*
|
|
223
|
+
* Server-side, pass `options.visitorIp` (from the incoming request, see
|
|
224
|
+
* `visitorIpFromHeaders`): base-api keys this route's per-IP limit on it
|
|
225
|
+
* and, without it, throttles every visitor of the SITE in one shared
|
|
226
|
+
* tenant-level bucket (REB-1006).
|
|
200
227
|
*/
|
|
201
|
-
enrollmentRequest: (body) =>
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
228
|
+
enrollmentRequest: (body, options) => {
|
|
229
|
+
const headers = extraHeaders(options);
|
|
230
|
+
return request(ctx, "/api/site/academy/enrollment-requests", {
|
|
231
|
+
method: "POST",
|
|
232
|
+
body: JSON.stringify(body),
|
|
233
|
+
cachePolicy: { revalidate: false },
|
|
234
|
+
...headers ? { headers } : {}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
206
237
|
};
|
|
207
238
|
}
|
|
208
239
|
|
|
@@ -242,8 +273,18 @@ function makeConfigNamespace(ctx) {
|
|
|
242
273
|
// src/domains/contact-form.ts
|
|
243
274
|
function makeContactFormNamespace(ctx) {
|
|
244
275
|
return {
|
|
245
|
-
/**
|
|
246
|
-
|
|
276
|
+
/**
|
|
277
|
+
* Submit a contact form. Returns the created lead acknowledgement.
|
|
278
|
+
* Server-side (a Server Action / Route Handler), pass `options.visitorIp`
|
|
279
|
+
* (from the incoming request, see `visitorIpFromHeaders`) so base-api's
|
|
280
|
+
* per-IP limit (REB-1005) applies to the real visitor.
|
|
281
|
+
*/
|
|
282
|
+
submit: (body, options) => requestMutation(
|
|
283
|
+
ctx,
|
|
284
|
+
"/api/site/contact-form",
|
|
285
|
+
body,
|
|
286
|
+
options
|
|
287
|
+
)
|
|
247
288
|
};
|
|
248
289
|
}
|
|
249
290
|
|
|
@@ -257,11 +298,17 @@ function makeCtasNamespace(ctx) {
|
|
|
257
298
|
// src/domains/data-requests.ts
|
|
258
299
|
function makeDataRequestsNamespace(ctx) {
|
|
259
300
|
return {
|
|
260
|
-
/**
|
|
261
|
-
|
|
301
|
+
/**
|
|
302
|
+
* Submit a data-subject request. Returns its acknowledgement with the 72h
|
|
303
|
+
* deadline. Server-side, pass `options.visitorIp` (from the incoming
|
|
304
|
+
* request, see `visitorIpFromHeaders`) so base-api's per-IP limit
|
|
305
|
+
* (REB-1005) sees the real visitor.
|
|
306
|
+
*/
|
|
307
|
+
submit: (body, options) => requestMutation(
|
|
262
308
|
ctx,
|
|
263
309
|
"/api/site/data-requests",
|
|
264
|
-
body
|
|
310
|
+
body,
|
|
311
|
+
options
|
|
265
312
|
)
|
|
266
313
|
};
|
|
267
314
|
}
|
|
@@ -399,8 +446,18 @@ function makeShopNamespace(ctx) {
|
|
|
399
446
|
* branch UI on `exists`; the checkout always offers «Iniciar sesión o
|
|
400
447
|
* continuar como invitado» and the server links the order to an existing
|
|
401
448
|
* account after payment. Removed in the next major.
|
|
449
|
+
*
|
|
450
|
+
* Server-side, pass `options.visitorIp` (from the incoming request, see
|
|
451
|
+
* `visitorIpFromHeaders`): base-api keys this route's per-IP limit on it
|
|
452
|
+
* and, without it, throttles every visitor of the SITE in one shared
|
|
453
|
+
* tenant-level bucket (REB-1006).
|
|
402
454
|
*/
|
|
403
|
-
checkEmail: (body) => requestMutation(
|
|
455
|
+
checkEmail: (body, options) => requestMutation(
|
|
456
|
+
ctx,
|
|
457
|
+
"/api/site/shop/check-email",
|
|
458
|
+
body,
|
|
459
|
+
options
|
|
460
|
+
),
|
|
404
461
|
/**
|
|
405
462
|
* Look up a confirmed (or still-pending) order by its Stripe Checkout
|
|
406
463
|
* session id — the order-confirmation flow (REB-829). `GET`, so it goes
|
|
@@ -459,6 +516,6 @@ function createRebluClient(config) {
|
|
|
459
516
|
};
|
|
460
517
|
}
|
|
461
518
|
|
|
462
|
-
export { AmbiguousPageSlugError, ApiError, DEFAULT_CHECKOUT_REDIRECT_HOSTS, PlainCacheAdapter, UnsafeCheckoutRedirectError, createRebluClient, isSafeCheckoutRedirectUrl };
|
|
519
|
+
export { AmbiguousPageSlugError, ApiError, DEFAULT_CHECKOUT_REDIRECT_HOSTS, PlainCacheAdapter, UnsafeCheckoutRedirectError, VISITOR_IP_HEADER, createRebluClient, isSafeCheckoutRedirectUrl, visitorIpFromHeaders };
|
|
463
520
|
//# sourceMappingURL=index.js.map
|
|
464
521
|
//# sourceMappingURL=index.js.map
|