@preprio/toolkit 0.1.0-beta.5 → 0.2.0-beta.2
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 +99 -14
- package/dist/astro/index.cjs +37 -15
- package/dist/astro/index.d.cts +38 -8
- package/dist/astro/index.d.ts +38 -8
- package/dist/astro/index.js +37 -15
- package/dist/{chunk-NLQIRN5O.js → chunk-6OOGNVJ4.js} +83 -41
- package/dist/index.cjs +102 -55
- package/dist/index.d.cts +59 -16
- package/dist/index.d.ts +59 -16
- package/dist/index.js +22 -16
- package/dist/nextjs/components.cjs +87 -42
- package/dist/nextjs/components.d.cts +3 -3
- package/dist/nextjs/components.d.ts +3 -3
- package/dist/nextjs/components.js +8 -4
- package/dist/nextjs/image-loader.cjs +17 -94
- package/dist/nextjs/image-loader.d.cts +8 -4
- package/dist/nextjs/image-loader.d.ts +8 -4
- package/dist/nextjs/image-loader.js +17 -94
- package/dist/nextjs/index.cjs +37 -15
- package/dist/nextjs/index.d.cts +46 -16
- package/dist/nextjs/index.d.ts +46 -16
- package/dist/nextjs/index.js +37 -15
- package/dist/nuxt/index.cjs +37 -15
- package/dist/nuxt/index.d.cts +62 -32
- package/dist/nuxt/index.d.ts +62 -32
- package/dist/nuxt/index.js +37 -15
- package/dist/{pixel-DVSJQC0K.d.cts → pixel-763p7m6A.d.cts} +64 -1
- package/dist/{pixel-DVSJQC0K.d.ts → pixel-763p7m6A.d.ts} +64 -1
- package/dist/sveltekit/index.cjs +37 -15
- package/dist/sveltekit/index.d.cts +62 -32
- package/dist/sveltekit/index.d.ts +62 -32
- package/dist/sveltekit/index.js +37 -15
- package/package.json +1 -1
- package/src/astro/PreprToolbar.astro +16 -10
- package/src/nuxt/PreprToolbar.vue +10 -8
- package/src/sveltekit/PreprToolbar.svelte +11 -4
package/dist/nuxt/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(nuxt_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(nuxt_exports);
|
|
36
36
|
|
|
37
37
|
// src/version.ts
|
|
38
|
-
var VERSION = "0.
|
|
38
|
+
var VERSION = "0.2.0-beta.2";
|
|
39
39
|
|
|
40
40
|
// src/core/constants.ts
|
|
41
41
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -48,6 +48,24 @@ var PARAM_VARIANT = "prepr_preview_ab";
|
|
|
48
48
|
var PARAM_HIDE_BAR = "prepr_hide_bar";
|
|
49
49
|
var ONE_YEAR_SECONDS = 60 * 60 * 24 * 365;
|
|
50
50
|
|
|
51
|
+
// src/core/features.ts
|
|
52
|
+
function isEnabled(config) {
|
|
53
|
+
if (typeof config === "boolean") return config;
|
|
54
|
+
return config?.enabled ?? true;
|
|
55
|
+
}
|
|
56
|
+
function resolveFeatures(features) {
|
|
57
|
+
return {
|
|
58
|
+
segments: isEnabled(features?.segments),
|
|
59
|
+
abTesting: isEnabled(features?.abTesting),
|
|
60
|
+
editMode: isEnabled(features?.editMode)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
var ALL_FEATURES_ENABLED = Object.freeze({
|
|
64
|
+
segments: true,
|
|
65
|
+
abTesting: true,
|
|
66
|
+
editMode: true
|
|
67
|
+
});
|
|
68
|
+
|
|
51
69
|
// src/core/middleware.ts
|
|
52
70
|
var UTM_PARAMS = [
|
|
53
71
|
"utm_source",
|
|
@@ -131,7 +149,8 @@ function processPreprRequest(request, opts) {
|
|
|
131
149
|
if (!opts?.preview) {
|
|
132
150
|
return { requestHeaders, responseCookies };
|
|
133
151
|
}
|
|
134
|
-
const
|
|
152
|
+
const features = resolveFeatures(opts?.features);
|
|
153
|
+
const hasPreviewParams = features.segments && searchParams.has(PARAM_SEGMENT) || features.abTesting && searchParams.has(PARAM_VARIANT);
|
|
135
154
|
if (!hasPreviewParams) {
|
|
136
155
|
const previewModeCookie = requestCookies.get(COOKIE_PREVIEW_MODE);
|
|
137
156
|
const previewModeEnabled = previewModeCookie !== "false";
|
|
@@ -151,16 +170,16 @@ function processPreprRequest(request, opts) {
|
|
|
151
170
|
});
|
|
152
171
|
}
|
|
153
172
|
if (!isLivePreview) {
|
|
154
|
-
const segmentCookie = requestCookies.get(COOKIE_SEGMENT);
|
|
173
|
+
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
155
174
|
if (segmentCookie) {
|
|
156
175
|
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
157
176
|
}
|
|
158
|
-
const abCookie = requestCookies.get(COOKIE_VARIANT);
|
|
177
|
+
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
159
178
|
if (abCookie) {
|
|
160
179
|
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
161
180
|
}
|
|
162
181
|
}
|
|
163
|
-
const previewAb = searchParams.get(PARAM_VARIANT);
|
|
182
|
+
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
164
183
|
if (previewAb !== null) {
|
|
165
184
|
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
166
185
|
if (!isLivePreview) {
|
|
@@ -173,7 +192,7 @@ function processPreprRequest(request, opts) {
|
|
|
173
192
|
});
|
|
174
193
|
}
|
|
175
194
|
}
|
|
176
|
-
const previewSegment = searchParams.get(PARAM_SEGMENT);
|
|
195
|
+
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
177
196
|
if (previewSegment !== null) {
|
|
178
197
|
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
179
198
|
if (!isLivePreview) {
|
|
@@ -352,16 +371,19 @@ async function getPreprEnvironmentSegments(token) {
|
|
|
352
371
|
);
|
|
353
372
|
}
|
|
354
373
|
}
|
|
355
|
-
async function getToolbarPropsFromHeaders(headers, token) {
|
|
374
|
+
async function getToolbarPropsFromHeaders(headers, token, features) {
|
|
375
|
+
const resolved = resolveFeatures(features);
|
|
356
376
|
let segments = [];
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
377
|
+
if (resolved.segments) {
|
|
378
|
+
try {
|
|
379
|
+
segments = await getPreprEnvironmentSegments(token);
|
|
380
|
+
} catch {
|
|
381
|
+
segments = [];
|
|
382
|
+
}
|
|
361
383
|
}
|
|
362
384
|
return {
|
|
363
|
-
activeSegment: getActiveSegmentFromHeaders(headers),
|
|
364
|
-
activeVariant: getActiveVariantFromHeaders(headers),
|
|
385
|
+
activeSegment: resolved.segments ? getActiveSegmentFromHeaders(headers) : null,
|
|
386
|
+
activeVariant: resolved.abTesting ? getActiveVariantFromHeaders(headers) : null,
|
|
365
387
|
segments,
|
|
366
388
|
data: segments
|
|
367
389
|
};
|
|
@@ -380,8 +402,8 @@ function getActiveVariant(headers) {
|
|
|
380
402
|
function getPreprHeaders(headers) {
|
|
381
403
|
return getPreprHeadersFromHeaders(headers);
|
|
382
404
|
}
|
|
383
|
-
async function getToolbarProps(headers, token) {
|
|
384
|
-
return getToolbarPropsFromHeaders(headers, token);
|
|
405
|
+
async function getToolbarProps(headers, token, features) {
|
|
406
|
+
return getToolbarPropsFromHeaders(headers, token, features);
|
|
385
407
|
}
|
|
386
408
|
// Annotate the CommonJS export names for ESM import in node:
|
|
387
409
|
0 && (module.exports = {
|
package/dist/nuxt/index.d.cts
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
|
+
interface PreprSegment {
|
|
2
|
+
readonly _id: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Per-feature config. `false` is shorthand for `{ enabled: false }`; the object
|
|
7
|
+
* form leaves room for per-feature options later without a breaking change.
|
|
8
|
+
*/
|
|
9
|
+
type PreprFeatureConfig = boolean | {
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** Toolkit features a consumer can turn off. Omitted keys stay enabled. */
|
|
13
|
+
interface PreprFeatures {
|
|
14
|
+
/** Segment picker, `Prepr-Segments` header and its cookie/query param. */
|
|
15
|
+
segments?: PreprFeatureConfig;
|
|
16
|
+
/** A/B variant switch, `Prepr-ABtesting` header and its cookie/query param. */
|
|
17
|
+
abTesting?: PreprFeatureConfig;
|
|
18
|
+
/**
|
|
19
|
+
* The site's own click-to-edit: the toolbar's Edit mode control, the stega
|
|
20
|
+
* tooltip/overlay and the close-edit pill.
|
|
21
|
+
*
|
|
22
|
+
* NOT a security control, and NOT the Prepr editor's live preview. When the
|
|
23
|
+
* site is framed by the editor, `prepr:initVE` still activates edit mode —
|
|
24
|
+
* that is the CMS operating inside its own iframe, not an affordance offered
|
|
25
|
+
* to visitors. See iframe-bridge.ts.
|
|
26
|
+
*/
|
|
27
|
+
editMode?: PreprFeatureConfig;
|
|
28
|
+
}
|
|
29
|
+
interface PreprToolbarProps {
|
|
30
|
+
readonly activeSegment: string | null;
|
|
31
|
+
readonly activeVariant: string | null;
|
|
32
|
+
/** Available segments to personalize on. */
|
|
33
|
+
readonly segments?: readonly PreprSegment[];
|
|
34
|
+
/** @deprecated Alias for `segments`. */
|
|
35
|
+
readonly data?: readonly PreprSegment[];
|
|
36
|
+
}
|
|
37
|
+
type PreprVariant = 'A' | 'B';
|
|
38
|
+
interface PreprHeaders {
|
|
39
|
+
readonly 'prepr-customer-id'?: string;
|
|
40
|
+
readonly 'Prepr-Segments'?: string;
|
|
41
|
+
readonly 'Prepr-ABtesting'?: PreprVariant;
|
|
42
|
+
readonly 'Prepr-Preview-Bar'?: 'true';
|
|
43
|
+
readonly 'Prepr-Context-utm_source'?: string;
|
|
44
|
+
readonly 'Prepr-Context-utm_medium'?: string;
|
|
45
|
+
readonly 'Prepr-Context-utm_term'?: string;
|
|
46
|
+
readonly 'Prepr-Context-utm_content'?: string;
|
|
47
|
+
readonly 'Prepr-Context-utm_campaign'?: string;
|
|
48
|
+
readonly 'Prepr-Context-initial_referral'?: string;
|
|
49
|
+
readonly 'Prepr-Visitor-IP'?: string;
|
|
50
|
+
readonly 'Prepr-Hubspot-Id'?: string;
|
|
51
|
+
readonly 'Prepr-Customer-Id-Created'?: 'true';
|
|
52
|
+
readonly 'Prepr-User-Agent'?: string;
|
|
53
|
+
}
|
|
54
|
+
type PreprErrorCode = 'INVALID_TOKEN' | 'MISSING_TOKEN' | 'HTTP_ERROR' | 'FETCH_ERROR' | 'INVALID_RESPONSE' | 'CONTEXT_ERROR';
|
|
55
|
+
|
|
1
56
|
interface PreprMiddlewareOptions {
|
|
2
57
|
/** Enable preview-mode headers (segment/AB overrides, preview bar). */
|
|
3
58
|
preview?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Disable features app-wide. Pass the same object you give the toolbar: a
|
|
61
|
+
* disabled feature injects no header and persists no cookie, whatever the
|
|
62
|
+
* request carries.
|
|
63
|
+
*/
|
|
64
|
+
features?: PreprFeatures;
|
|
4
65
|
/** Override the version reported in Prepr-Package (mainly for tests). */
|
|
5
66
|
version?: string;
|
|
6
67
|
}
|
|
@@ -52,37 +113,6 @@ declare function handlePreprRequest(event: H3EventLike, options?: PreprMiddlewar
|
|
|
52
113
|
*/
|
|
53
114
|
declare function getPreprHeadersFromEvent(event: Pick<H3EventLike, 'context'>): Headers;
|
|
54
115
|
|
|
55
|
-
interface PreprSegment {
|
|
56
|
-
readonly _id: string;
|
|
57
|
-
readonly name: string;
|
|
58
|
-
}
|
|
59
|
-
interface PreprToolbarProps {
|
|
60
|
-
readonly activeSegment: string | null;
|
|
61
|
-
readonly activeVariant: string | null;
|
|
62
|
-
/** Available segments to personalize on. */
|
|
63
|
-
readonly segments?: readonly PreprSegment[];
|
|
64
|
-
/** @deprecated Alias for `segments`. */
|
|
65
|
-
readonly data?: readonly PreprSegment[];
|
|
66
|
-
}
|
|
67
|
-
type PreprVariant = 'A' | 'B';
|
|
68
|
-
interface PreprHeaders {
|
|
69
|
-
readonly 'prepr-customer-id'?: string;
|
|
70
|
-
readonly 'Prepr-Segments'?: string;
|
|
71
|
-
readonly 'Prepr-ABtesting'?: PreprVariant;
|
|
72
|
-
readonly 'Prepr-Preview-Bar'?: 'true';
|
|
73
|
-
readonly 'Prepr-Context-utm_source'?: string;
|
|
74
|
-
readonly 'Prepr-Context-utm_medium'?: string;
|
|
75
|
-
readonly 'Prepr-Context-utm_term'?: string;
|
|
76
|
-
readonly 'Prepr-Context-utm_content'?: string;
|
|
77
|
-
readonly 'Prepr-Context-utm_campaign'?: string;
|
|
78
|
-
readonly 'Prepr-Context-initial_referral'?: string;
|
|
79
|
-
readonly 'Prepr-Visitor-IP'?: string;
|
|
80
|
-
readonly 'Prepr-Hubspot-Id'?: string;
|
|
81
|
-
readonly 'Prepr-Customer-Id-Created'?: 'true';
|
|
82
|
-
readonly 'Prepr-User-Agent'?: string;
|
|
83
|
-
}
|
|
84
|
-
type PreprErrorCode = 'INVALID_TOKEN' | 'MISSING_TOKEN' | 'HTTP_ERROR' | 'FETCH_ERROR' | 'INVALID_RESPONSE' | 'CONTEXT_ERROR';
|
|
85
|
-
|
|
86
116
|
/** Returns the Prepr Customer ID from the request headers. */
|
|
87
117
|
declare function getPreprUUID(headers: Headers): string | null;
|
|
88
118
|
/** Returns the active segment from the request headers. */
|
|
@@ -96,7 +126,7 @@ declare function getPreprHeaders(headers: Headers): PreprHeaders;
|
|
|
96
126
|
* Prepr GraphQL token. Ungated — gate on preview mode yourself (e.g.
|
|
97
127
|
* `import.meta.dev`).
|
|
98
128
|
*/
|
|
99
|
-
declare function getToolbarProps(headers: Headers, token: string): Promise<PreprToolbarProps>;
|
|
129
|
+
declare function getToolbarProps(headers: Headers, token: string, features?: PreprFeatures): Promise<PreprToolbarProps>;
|
|
100
130
|
|
|
101
131
|
/** Error thrown by the token helpers and the segments fetch. */
|
|
102
132
|
declare class PreprError extends Error {
|
package/dist/nuxt/index.d.ts
CHANGED
|
@@ -1,6 +1,67 @@
|
|
|
1
|
+
interface PreprSegment {
|
|
2
|
+
readonly _id: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Per-feature config. `false` is shorthand for `{ enabled: false }`; the object
|
|
7
|
+
* form leaves room for per-feature options later without a breaking change.
|
|
8
|
+
*/
|
|
9
|
+
type PreprFeatureConfig = boolean | {
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** Toolkit features a consumer can turn off. Omitted keys stay enabled. */
|
|
13
|
+
interface PreprFeatures {
|
|
14
|
+
/** Segment picker, `Prepr-Segments` header and its cookie/query param. */
|
|
15
|
+
segments?: PreprFeatureConfig;
|
|
16
|
+
/** A/B variant switch, `Prepr-ABtesting` header and its cookie/query param. */
|
|
17
|
+
abTesting?: PreprFeatureConfig;
|
|
18
|
+
/**
|
|
19
|
+
* The site's own click-to-edit: the toolbar's Edit mode control, the stega
|
|
20
|
+
* tooltip/overlay and the close-edit pill.
|
|
21
|
+
*
|
|
22
|
+
* NOT a security control, and NOT the Prepr editor's live preview. When the
|
|
23
|
+
* site is framed by the editor, `prepr:initVE` still activates edit mode —
|
|
24
|
+
* that is the CMS operating inside its own iframe, not an affordance offered
|
|
25
|
+
* to visitors. See iframe-bridge.ts.
|
|
26
|
+
*/
|
|
27
|
+
editMode?: PreprFeatureConfig;
|
|
28
|
+
}
|
|
29
|
+
interface PreprToolbarProps {
|
|
30
|
+
readonly activeSegment: string | null;
|
|
31
|
+
readonly activeVariant: string | null;
|
|
32
|
+
/** Available segments to personalize on. */
|
|
33
|
+
readonly segments?: readonly PreprSegment[];
|
|
34
|
+
/** @deprecated Alias for `segments`. */
|
|
35
|
+
readonly data?: readonly PreprSegment[];
|
|
36
|
+
}
|
|
37
|
+
type PreprVariant = 'A' | 'B';
|
|
38
|
+
interface PreprHeaders {
|
|
39
|
+
readonly 'prepr-customer-id'?: string;
|
|
40
|
+
readonly 'Prepr-Segments'?: string;
|
|
41
|
+
readonly 'Prepr-ABtesting'?: PreprVariant;
|
|
42
|
+
readonly 'Prepr-Preview-Bar'?: 'true';
|
|
43
|
+
readonly 'Prepr-Context-utm_source'?: string;
|
|
44
|
+
readonly 'Prepr-Context-utm_medium'?: string;
|
|
45
|
+
readonly 'Prepr-Context-utm_term'?: string;
|
|
46
|
+
readonly 'Prepr-Context-utm_content'?: string;
|
|
47
|
+
readonly 'Prepr-Context-utm_campaign'?: string;
|
|
48
|
+
readonly 'Prepr-Context-initial_referral'?: string;
|
|
49
|
+
readonly 'Prepr-Visitor-IP'?: string;
|
|
50
|
+
readonly 'Prepr-Hubspot-Id'?: string;
|
|
51
|
+
readonly 'Prepr-Customer-Id-Created'?: 'true';
|
|
52
|
+
readonly 'Prepr-User-Agent'?: string;
|
|
53
|
+
}
|
|
54
|
+
type PreprErrorCode = 'INVALID_TOKEN' | 'MISSING_TOKEN' | 'HTTP_ERROR' | 'FETCH_ERROR' | 'INVALID_RESPONSE' | 'CONTEXT_ERROR';
|
|
55
|
+
|
|
1
56
|
interface PreprMiddlewareOptions {
|
|
2
57
|
/** Enable preview-mode headers (segment/AB overrides, preview bar). */
|
|
3
58
|
preview?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Disable features app-wide. Pass the same object you give the toolbar: a
|
|
61
|
+
* disabled feature injects no header and persists no cookie, whatever the
|
|
62
|
+
* request carries.
|
|
63
|
+
*/
|
|
64
|
+
features?: PreprFeatures;
|
|
4
65
|
/** Override the version reported in Prepr-Package (mainly for tests). */
|
|
5
66
|
version?: string;
|
|
6
67
|
}
|
|
@@ -52,37 +113,6 @@ declare function handlePreprRequest(event: H3EventLike, options?: PreprMiddlewar
|
|
|
52
113
|
*/
|
|
53
114
|
declare function getPreprHeadersFromEvent(event: Pick<H3EventLike, 'context'>): Headers;
|
|
54
115
|
|
|
55
|
-
interface PreprSegment {
|
|
56
|
-
readonly _id: string;
|
|
57
|
-
readonly name: string;
|
|
58
|
-
}
|
|
59
|
-
interface PreprToolbarProps {
|
|
60
|
-
readonly activeSegment: string | null;
|
|
61
|
-
readonly activeVariant: string | null;
|
|
62
|
-
/** Available segments to personalize on. */
|
|
63
|
-
readonly segments?: readonly PreprSegment[];
|
|
64
|
-
/** @deprecated Alias for `segments`. */
|
|
65
|
-
readonly data?: readonly PreprSegment[];
|
|
66
|
-
}
|
|
67
|
-
type PreprVariant = 'A' | 'B';
|
|
68
|
-
interface PreprHeaders {
|
|
69
|
-
readonly 'prepr-customer-id'?: string;
|
|
70
|
-
readonly 'Prepr-Segments'?: string;
|
|
71
|
-
readonly 'Prepr-ABtesting'?: PreprVariant;
|
|
72
|
-
readonly 'Prepr-Preview-Bar'?: 'true';
|
|
73
|
-
readonly 'Prepr-Context-utm_source'?: string;
|
|
74
|
-
readonly 'Prepr-Context-utm_medium'?: string;
|
|
75
|
-
readonly 'Prepr-Context-utm_term'?: string;
|
|
76
|
-
readonly 'Prepr-Context-utm_content'?: string;
|
|
77
|
-
readonly 'Prepr-Context-utm_campaign'?: string;
|
|
78
|
-
readonly 'Prepr-Context-initial_referral'?: string;
|
|
79
|
-
readonly 'Prepr-Visitor-IP'?: string;
|
|
80
|
-
readonly 'Prepr-Hubspot-Id'?: string;
|
|
81
|
-
readonly 'Prepr-Customer-Id-Created'?: 'true';
|
|
82
|
-
readonly 'Prepr-User-Agent'?: string;
|
|
83
|
-
}
|
|
84
|
-
type PreprErrorCode = 'INVALID_TOKEN' | 'MISSING_TOKEN' | 'HTTP_ERROR' | 'FETCH_ERROR' | 'INVALID_RESPONSE' | 'CONTEXT_ERROR';
|
|
85
|
-
|
|
86
116
|
/** Returns the Prepr Customer ID from the request headers. */
|
|
87
117
|
declare function getPreprUUID(headers: Headers): string | null;
|
|
88
118
|
/** Returns the active segment from the request headers. */
|
|
@@ -96,7 +126,7 @@ declare function getPreprHeaders(headers: Headers): PreprHeaders;
|
|
|
96
126
|
* Prepr GraphQL token. Ungated — gate on preview mode yourself (e.g.
|
|
97
127
|
* `import.meta.dev`).
|
|
98
128
|
*/
|
|
99
|
-
declare function getToolbarProps(headers: Headers, token: string): Promise<PreprToolbarProps>;
|
|
129
|
+
declare function getToolbarProps(headers: Headers, token: string, features?: PreprFeatures): Promise<PreprToolbarProps>;
|
|
100
130
|
|
|
101
131
|
/** Error thrown by the token helpers and the segments fetch. */
|
|
102
132
|
declare class PreprError extends Error {
|
package/dist/nuxt/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var VERSION = "0.
|
|
2
|
+
var VERSION = "0.2.0-beta.2";
|
|
3
3
|
|
|
4
4
|
// src/core/constants.ts
|
|
5
5
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -12,6 +12,24 @@ var PARAM_VARIANT = "prepr_preview_ab";
|
|
|
12
12
|
var PARAM_HIDE_BAR = "prepr_hide_bar";
|
|
13
13
|
var ONE_YEAR_SECONDS = 60 * 60 * 24 * 365;
|
|
14
14
|
|
|
15
|
+
// src/core/features.ts
|
|
16
|
+
function isEnabled(config) {
|
|
17
|
+
if (typeof config === "boolean") return config;
|
|
18
|
+
return config?.enabled ?? true;
|
|
19
|
+
}
|
|
20
|
+
function resolveFeatures(features) {
|
|
21
|
+
return {
|
|
22
|
+
segments: isEnabled(features?.segments),
|
|
23
|
+
abTesting: isEnabled(features?.abTesting),
|
|
24
|
+
editMode: isEnabled(features?.editMode)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
var ALL_FEATURES_ENABLED = Object.freeze({
|
|
28
|
+
segments: true,
|
|
29
|
+
abTesting: true,
|
|
30
|
+
editMode: true
|
|
31
|
+
});
|
|
32
|
+
|
|
15
33
|
// src/core/middleware.ts
|
|
16
34
|
var UTM_PARAMS = [
|
|
17
35
|
"utm_source",
|
|
@@ -95,7 +113,8 @@ function processPreprRequest(request, opts) {
|
|
|
95
113
|
if (!opts?.preview) {
|
|
96
114
|
return { requestHeaders, responseCookies };
|
|
97
115
|
}
|
|
98
|
-
const
|
|
116
|
+
const features = resolveFeatures(opts?.features);
|
|
117
|
+
const hasPreviewParams = features.segments && searchParams.has(PARAM_SEGMENT) || features.abTesting && searchParams.has(PARAM_VARIANT);
|
|
99
118
|
if (!hasPreviewParams) {
|
|
100
119
|
const previewModeCookie = requestCookies.get(COOKIE_PREVIEW_MODE);
|
|
101
120
|
const previewModeEnabled = previewModeCookie !== "false";
|
|
@@ -115,16 +134,16 @@ function processPreprRequest(request, opts) {
|
|
|
115
134
|
});
|
|
116
135
|
}
|
|
117
136
|
if (!isLivePreview) {
|
|
118
|
-
const segmentCookie = requestCookies.get(COOKIE_SEGMENT);
|
|
137
|
+
const segmentCookie = features.segments ? requestCookies.get(COOKIE_SEGMENT) : void 0;
|
|
119
138
|
if (segmentCookie) {
|
|
120
139
|
requestHeaders.set("Prepr-Segments", segmentCookie);
|
|
121
140
|
}
|
|
122
|
-
const abCookie = requestCookies.get(COOKIE_VARIANT);
|
|
141
|
+
const abCookie = features.abTesting ? requestCookies.get(COOKIE_VARIANT) : void 0;
|
|
123
142
|
if (abCookie) {
|
|
124
143
|
requestHeaders.set("Prepr-ABtesting", abCookie);
|
|
125
144
|
}
|
|
126
145
|
}
|
|
127
|
-
const previewAb = searchParams.get(PARAM_VARIANT);
|
|
146
|
+
const previewAb = features.abTesting ? searchParams.get(PARAM_VARIANT) : null;
|
|
128
147
|
if (previewAb !== null) {
|
|
129
148
|
requestHeaders.set("Prepr-ABtesting", previewAb);
|
|
130
149
|
if (!isLivePreview) {
|
|
@@ -137,7 +156,7 @@ function processPreprRequest(request, opts) {
|
|
|
137
156
|
});
|
|
138
157
|
}
|
|
139
158
|
}
|
|
140
|
-
const previewSegment = searchParams.get(PARAM_SEGMENT);
|
|
159
|
+
const previewSegment = features.segments ? searchParams.get(PARAM_SEGMENT) : null;
|
|
141
160
|
if (previewSegment !== null) {
|
|
142
161
|
requestHeaders.set("Prepr-Segments", previewSegment);
|
|
143
162
|
if (!isLivePreview) {
|
|
@@ -316,16 +335,19 @@ async function getPreprEnvironmentSegments(token) {
|
|
|
316
335
|
);
|
|
317
336
|
}
|
|
318
337
|
}
|
|
319
|
-
async function getToolbarPropsFromHeaders(headers, token) {
|
|
338
|
+
async function getToolbarPropsFromHeaders(headers, token, features) {
|
|
339
|
+
const resolved = resolveFeatures(features);
|
|
320
340
|
let segments = [];
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
341
|
+
if (resolved.segments) {
|
|
342
|
+
try {
|
|
343
|
+
segments = await getPreprEnvironmentSegments(token);
|
|
344
|
+
} catch {
|
|
345
|
+
segments = [];
|
|
346
|
+
}
|
|
325
347
|
}
|
|
326
348
|
return {
|
|
327
|
-
activeSegment: getActiveSegmentFromHeaders(headers),
|
|
328
|
-
activeVariant: getActiveVariantFromHeaders(headers),
|
|
349
|
+
activeSegment: resolved.segments ? getActiveSegmentFromHeaders(headers) : null,
|
|
350
|
+
activeVariant: resolved.abTesting ? getActiveVariantFromHeaders(headers) : null,
|
|
329
351
|
segments,
|
|
330
352
|
data: segments
|
|
331
353
|
};
|
|
@@ -344,8 +366,8 @@ function getActiveVariant(headers) {
|
|
|
344
366
|
function getPreprHeaders(headers) {
|
|
345
367
|
return getPreprHeadersFromHeaders(headers);
|
|
346
368
|
}
|
|
347
|
-
async function getToolbarProps(headers, token) {
|
|
348
|
-
return getToolbarPropsFromHeaders(headers, token);
|
|
369
|
+
async function getToolbarProps(headers, token, features) {
|
|
370
|
+
return getToolbarPropsFromHeaders(headers, token, features);
|
|
349
371
|
}
|
|
350
372
|
export {
|
|
351
373
|
PREPR_CONTEXT_KEY,
|
|
@@ -9,9 +9,65 @@ interface PreprSegment {
|
|
|
9
9
|
readonly _id: string;
|
|
10
10
|
readonly name: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Per-feature config. `false` is shorthand for `{ enabled: false }`; the object
|
|
14
|
+
* form leaves room for per-feature options later without a breaking change.
|
|
15
|
+
*/
|
|
16
|
+
type PreprFeatureConfig = boolean | {
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/** Toolkit features a consumer can turn off. Omitted keys stay enabled. */
|
|
20
|
+
interface PreprFeatures {
|
|
21
|
+
/** Segment picker, `Prepr-Segments` header and its cookie/query param. */
|
|
22
|
+
segments?: PreprFeatureConfig;
|
|
23
|
+
/** A/B variant switch, `Prepr-ABtesting` header and its cookie/query param. */
|
|
24
|
+
abTesting?: PreprFeatureConfig;
|
|
25
|
+
/**
|
|
26
|
+
* The site's own click-to-edit: the toolbar's Edit mode control, the stega
|
|
27
|
+
* tooltip/overlay and the close-edit pill.
|
|
28
|
+
*
|
|
29
|
+
* NOT a security control, and NOT the Prepr editor's live preview. When the
|
|
30
|
+
* site is framed by the editor, `prepr:initVE` still activates edit mode —
|
|
31
|
+
* that is the CMS operating inside its own iframe, not an affordance offered
|
|
32
|
+
* to visitors. See iframe-bridge.ts.
|
|
33
|
+
*/
|
|
34
|
+
editMode?: PreprFeatureConfig;
|
|
35
|
+
}
|
|
36
|
+
/** `PreprFeatures` with every key resolved to a boolean. */
|
|
37
|
+
interface ResolvedPreprFeatures {
|
|
38
|
+
readonly segments: boolean;
|
|
39
|
+
readonly abTesting: boolean;
|
|
40
|
+
readonly editMode: boolean;
|
|
41
|
+
}
|
|
12
42
|
interface PreprToolbarOptions {
|
|
13
43
|
debug?: boolean;
|
|
14
44
|
locale?: Locale;
|
|
45
|
+
/** Disable features app-wide. Pass the same object to the middleware. */
|
|
46
|
+
features?: PreprFeatures;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Options for the preview runtime. Two independent axes: `features` decides
|
|
50
|
+
* *what runs*, `ui` decides *whether the toolbar is visible*.
|
|
51
|
+
*/
|
|
52
|
+
interface PreprPreviewOptions extends PreprToolbarOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Mount the visible `<prepr-toolbar>` element. Default `true`.
|
|
55
|
+
*
|
|
56
|
+
* `false` keeps every non-visual side effect wired — click-to-edit, the
|
|
57
|
+
* editor bridge, scroll restore, cookies and headers — with no chrome of its
|
|
58
|
+
* own. That is how a site gets live editing, or editor scroll restore, while
|
|
59
|
+
* rendering its own UI instead of the bar.
|
|
60
|
+
*
|
|
61
|
+
* Already implied inside the editor's iframe (the CMS owns the chrome there)
|
|
62
|
+
* and by `?prepr_hide_bar=true`, so this option is for consumers who want a
|
|
63
|
+
* headless preview by their own choice.
|
|
64
|
+
*/
|
|
65
|
+
ui?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Replace the `*.prepr.io` editor-origin wildcard with an exact list.
|
|
68
|
+
* Intended for self-hosted editors; when set, the wildcard no longer applies.
|
|
69
|
+
*/
|
|
70
|
+
allowedEditorOrigins?: string[];
|
|
15
71
|
}
|
|
16
72
|
interface PreprToolbarProps {
|
|
17
73
|
readonly activeSegment: string | null;
|
|
@@ -21,6 +77,13 @@ interface PreprToolbarProps {
|
|
|
21
77
|
/** @deprecated Alias for `segments`. */
|
|
22
78
|
readonly data?: readonly PreprSegment[];
|
|
23
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Prop type for the framework `<PreprToolbar>` components: the toolbar data
|
|
82
|
+
* plus the options bag core `createPreprPreview` accepts.
|
|
83
|
+
*/
|
|
84
|
+
interface PreprToolbarComponentProps extends PreprToolbarProps {
|
|
85
|
+
options?: PreprPreviewOptions;
|
|
86
|
+
}
|
|
24
87
|
type PreprHeaderName = 'prepr-customer-id' | 'Prepr-Segments' | 'Prepr-ABtesting' | 'Prepr-User-Agent';
|
|
25
88
|
type PreprVariant = 'A' | 'B';
|
|
26
89
|
type PreprEnvironment = 'preview' | 'production';
|
|
@@ -91,4 +154,4 @@ declare function trackEvent(name: string, data?: string | Record<string, unknown
|
|
|
91
154
|
/** Loader-independent like `trackEvent`; warns once if no pixel is installed. */
|
|
92
155
|
declare function setTrackingParam(key: string, value: string): void;
|
|
93
156
|
|
|
94
|
-
export { type Locale as L, type
|
|
157
|
+
export { type Locale as L, type PreprFeatures as P, type ResolvedPreprFeatures as R, type PreprSegment as a, type PreprVariant as b, type PreprToolbarProps as c, type PreprPreviewOptions as d, type PreprErrorCode as e, type PreprHeaders as f, type PreprEnvironment as g, type PreprEventType as h, type PreprFeatureConfig as i, type PreprHeaderName as j, type PreprPixelConfig as k, type PreprToolbarComponentProps as l, type PreprToolbarOptions as m, loadTrackingPixel as n, setTrackingParam as s, trackEvent as t };
|
|
@@ -9,9 +9,65 @@ interface PreprSegment {
|
|
|
9
9
|
readonly _id: string;
|
|
10
10
|
readonly name: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Per-feature config. `false` is shorthand for `{ enabled: false }`; the object
|
|
14
|
+
* form leaves room for per-feature options later without a breaking change.
|
|
15
|
+
*/
|
|
16
|
+
type PreprFeatureConfig = boolean | {
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/** Toolkit features a consumer can turn off. Omitted keys stay enabled. */
|
|
20
|
+
interface PreprFeatures {
|
|
21
|
+
/** Segment picker, `Prepr-Segments` header and its cookie/query param. */
|
|
22
|
+
segments?: PreprFeatureConfig;
|
|
23
|
+
/** A/B variant switch, `Prepr-ABtesting` header and its cookie/query param. */
|
|
24
|
+
abTesting?: PreprFeatureConfig;
|
|
25
|
+
/**
|
|
26
|
+
* The site's own click-to-edit: the toolbar's Edit mode control, the stega
|
|
27
|
+
* tooltip/overlay and the close-edit pill.
|
|
28
|
+
*
|
|
29
|
+
* NOT a security control, and NOT the Prepr editor's live preview. When the
|
|
30
|
+
* site is framed by the editor, `prepr:initVE` still activates edit mode —
|
|
31
|
+
* that is the CMS operating inside its own iframe, not an affordance offered
|
|
32
|
+
* to visitors. See iframe-bridge.ts.
|
|
33
|
+
*/
|
|
34
|
+
editMode?: PreprFeatureConfig;
|
|
35
|
+
}
|
|
36
|
+
/** `PreprFeatures` with every key resolved to a boolean. */
|
|
37
|
+
interface ResolvedPreprFeatures {
|
|
38
|
+
readonly segments: boolean;
|
|
39
|
+
readonly abTesting: boolean;
|
|
40
|
+
readonly editMode: boolean;
|
|
41
|
+
}
|
|
12
42
|
interface PreprToolbarOptions {
|
|
13
43
|
debug?: boolean;
|
|
14
44
|
locale?: Locale;
|
|
45
|
+
/** Disable features app-wide. Pass the same object to the middleware. */
|
|
46
|
+
features?: PreprFeatures;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Options for the preview runtime. Two independent axes: `features` decides
|
|
50
|
+
* *what runs*, `ui` decides *whether the toolbar is visible*.
|
|
51
|
+
*/
|
|
52
|
+
interface PreprPreviewOptions extends PreprToolbarOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Mount the visible `<prepr-toolbar>` element. Default `true`.
|
|
55
|
+
*
|
|
56
|
+
* `false` keeps every non-visual side effect wired — click-to-edit, the
|
|
57
|
+
* editor bridge, scroll restore, cookies and headers — with no chrome of its
|
|
58
|
+
* own. That is how a site gets live editing, or editor scroll restore, while
|
|
59
|
+
* rendering its own UI instead of the bar.
|
|
60
|
+
*
|
|
61
|
+
* Already implied inside the editor's iframe (the CMS owns the chrome there)
|
|
62
|
+
* and by `?prepr_hide_bar=true`, so this option is for consumers who want a
|
|
63
|
+
* headless preview by their own choice.
|
|
64
|
+
*/
|
|
65
|
+
ui?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Replace the `*.prepr.io` editor-origin wildcard with an exact list.
|
|
68
|
+
* Intended for self-hosted editors; when set, the wildcard no longer applies.
|
|
69
|
+
*/
|
|
70
|
+
allowedEditorOrigins?: string[];
|
|
15
71
|
}
|
|
16
72
|
interface PreprToolbarProps {
|
|
17
73
|
readonly activeSegment: string | null;
|
|
@@ -21,6 +77,13 @@ interface PreprToolbarProps {
|
|
|
21
77
|
/** @deprecated Alias for `segments`. */
|
|
22
78
|
readonly data?: readonly PreprSegment[];
|
|
23
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Prop type for the framework `<PreprToolbar>` components: the toolbar data
|
|
82
|
+
* plus the options bag core `createPreprPreview` accepts.
|
|
83
|
+
*/
|
|
84
|
+
interface PreprToolbarComponentProps extends PreprToolbarProps {
|
|
85
|
+
options?: PreprPreviewOptions;
|
|
86
|
+
}
|
|
24
87
|
type PreprHeaderName = 'prepr-customer-id' | 'Prepr-Segments' | 'Prepr-ABtesting' | 'Prepr-User-Agent';
|
|
25
88
|
type PreprVariant = 'A' | 'B';
|
|
26
89
|
type PreprEnvironment = 'preview' | 'production';
|
|
@@ -91,4 +154,4 @@ declare function trackEvent(name: string, data?: string | Record<string, unknown
|
|
|
91
154
|
/** Loader-independent like `trackEvent`; warns once if no pixel is installed. */
|
|
92
155
|
declare function setTrackingParam(key: string, value: string): void;
|
|
93
156
|
|
|
94
|
-
export { type Locale as L, type
|
|
157
|
+
export { type Locale as L, type PreprFeatures as P, type ResolvedPreprFeatures as R, type PreprSegment as a, type PreprVariant as b, type PreprToolbarProps as c, type PreprPreviewOptions as d, type PreprErrorCode as e, type PreprHeaders as f, type PreprEnvironment as g, type PreprEventType as h, type PreprFeatureConfig as i, type PreprHeaderName as j, type PreprPixelConfig as k, type PreprToolbarComponentProps as l, type PreprToolbarOptions as m, loadTrackingPixel as n, setTrackingParam as s, trackEvent as t };
|