@preprio/toolkit 0.2.0-beta.7 → 0.2.0-beta.9
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 +237 -471
- package/dist/astro/index.cjs +20 -6
- package/dist/astro/index.d.cts +1 -1
- package/dist/astro/index.d.ts +1 -1
- package/dist/astro/index.js +20 -6
- package/dist/{chunk-P6VTLWM4.js → chunk-JVUG6S4O.js} +23 -13
- package/dist/index.cjs +39 -18
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -6
- package/dist/nextjs/components.cjs +26 -14
- package/dist/nextjs/components.js +5 -3
- package/dist/nextjs/image-loader.cjs +7 -2
- package/dist/nextjs/image-loader.d.cts +1 -1
- package/dist/nextjs/image-loader.d.ts +1 -1
- package/dist/nextjs/image-loader.js +7 -2
- package/dist/nextjs/index.cjs +31 -9
- package/dist/nextjs/index.d.cts +99 -2
- package/dist/nextjs/index.d.ts +99 -2
- package/dist/nextjs/index.js +31 -9
- package/dist/nuxt/index.cjs +20 -6
- package/dist/nuxt/index.js +20 -6
- package/dist/react/components.cjs +23 -13
- package/dist/react/components.js +23 -13
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/sveltekit/index.cjs +20 -6
- package/dist/sveltekit/index.js +20 -6
- package/package.json +3 -3
package/dist/nextjs/index.cjs
CHANGED
|
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(nextjs_exports);
|
|
|
38
38
|
var import_server = require("next/server");
|
|
39
39
|
|
|
40
40
|
// src/version.ts
|
|
41
|
-
var VERSION = "0.2.0-beta.
|
|
41
|
+
var VERSION = "0.2.0-beta.9";
|
|
42
42
|
|
|
43
43
|
// src/core/constants.ts
|
|
44
44
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -92,7 +92,11 @@ function parseCookies(request) {
|
|
|
92
92
|
const name = part.slice(0, eq).trim();
|
|
93
93
|
const value = part.slice(eq + 1).trim();
|
|
94
94
|
if (!name) continue;
|
|
95
|
-
|
|
95
|
+
try {
|
|
96
|
+
cookies.set(name, decodeURIComponent(value));
|
|
97
|
+
} catch {
|
|
98
|
+
cookies.set(name, value);
|
|
99
|
+
}
|
|
96
100
|
}
|
|
97
101
|
return cookies;
|
|
98
102
|
}
|
|
@@ -131,7 +135,10 @@ function processPreprRequest(request, opts) {
|
|
|
131
135
|
if (userAgent) {
|
|
132
136
|
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
133
137
|
}
|
|
134
|
-
requestHeaders.set(
|
|
138
|
+
requestHeaders.set(
|
|
139
|
+
"Prepr-Package",
|
|
140
|
+
`@preprio/toolkit@${opts?.version ?? VERSION}`
|
|
141
|
+
);
|
|
135
142
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
136
143
|
if (ip) {
|
|
137
144
|
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
@@ -140,7 +147,7 @@ function processPreprRequest(request, opts) {
|
|
|
140
147
|
if (hutkCookie) {
|
|
141
148
|
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
142
149
|
}
|
|
143
|
-
let uid = requestCookies.get(COOKIE_UID);
|
|
150
|
+
let uid = sanitizeHeaderValue(requestCookies.get(COOKIE_UID) ?? "");
|
|
144
151
|
if (!uid) {
|
|
145
152
|
uid = crypto.randomUUID();
|
|
146
153
|
responseCookies.push({
|
|
@@ -224,19 +231,30 @@ function createPreprMiddleware(request, responseOrOptions, maybeOptions) {
|
|
|
224
231
|
} else {
|
|
225
232
|
options = responseOrOptions;
|
|
226
233
|
}
|
|
227
|
-
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
234
|
+
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
235
|
+
request,
|
|
236
|
+
options
|
|
237
|
+
);
|
|
228
238
|
const response = chainedResponse ?? import_server.NextResponse.next({ request: { headers: requestHeaders } });
|
|
229
239
|
if (chainedResponse) {
|
|
240
|
+
const existing = response.headers.get("x-middleware-override-headers");
|
|
241
|
+
const names = new Set(
|
|
242
|
+
existing ? existing.split(",").map((name) => name.trim()).filter(Boolean) : []
|
|
243
|
+
);
|
|
230
244
|
requestHeaders.forEach((value, key) => {
|
|
231
|
-
|
|
245
|
+
names.add(key);
|
|
246
|
+
response.headers.set(`x-middleware-request-${key}`, value);
|
|
232
247
|
});
|
|
248
|
+
response.headers.set("x-middleware-override-headers", [...names].join(","));
|
|
233
249
|
}
|
|
234
250
|
for (const cookie of responseCookies) {
|
|
235
251
|
response.cookies.set(cookie.name, cookie.value, {
|
|
236
252
|
maxAge: cookie.maxAge,
|
|
237
253
|
path: cookie.path,
|
|
238
254
|
// Lower-cased: Next's cookie API expects 'none' | 'lax' | 'strict'.
|
|
239
|
-
...cookie.sameSite ? {
|
|
255
|
+
...cookie.sameSite ? {
|
|
256
|
+
sameSite: cookie.sameSite.toLowerCase()
|
|
257
|
+
} : {},
|
|
240
258
|
...cookie.secure ? { secure: true } : {}
|
|
241
259
|
});
|
|
242
260
|
}
|
|
@@ -296,7 +314,11 @@ function getPreprHeadersFromHeaders(headers2) {
|
|
|
296
314
|
}
|
|
297
315
|
function validatePreprToken(token) {
|
|
298
316
|
if (!token) {
|
|
299
|
-
throw new PreprError(
|
|
317
|
+
throw new PreprError(
|
|
318
|
+
"Token is required",
|
|
319
|
+
"MISSING_TOKEN",
|
|
320
|
+
"validatePreprToken"
|
|
321
|
+
);
|
|
300
322
|
}
|
|
301
323
|
if (!token.startsWith("https://")) {
|
|
302
324
|
throw new PreprError(
|
|
@@ -426,7 +448,7 @@ async function getToolbarProps(token, features) {
|
|
|
426
448
|
}
|
|
427
449
|
|
|
428
450
|
// src/nextjs/index.ts
|
|
429
|
-
var import_components = require("./components");
|
|
451
|
+
var import_components = require("./components.cjs");
|
|
430
452
|
// Annotate the CommonJS export names for ESM import in node:
|
|
431
453
|
0 && (module.exports = {
|
|
432
454
|
PreprError,
|
package/dist/nextjs/index.d.cts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
type Dictionary = Record<string, unknown>;
|
|
4
|
+
declare const dictionaries: {
|
|
5
|
+
en: Dictionary;
|
|
6
|
+
nl: Dictionary;
|
|
7
|
+
};
|
|
8
|
+
type Locale = keyof typeof dictionaries;
|
|
3
9
|
|
|
4
10
|
interface PreprSegment {
|
|
5
11
|
readonly _id: string;
|
|
@@ -29,6 +35,36 @@ interface PreprFeatures {
|
|
|
29
35
|
*/
|
|
30
36
|
editMode?: PreprFeatureConfig;
|
|
31
37
|
}
|
|
38
|
+
interface PreprToolbarOptions {
|
|
39
|
+
debug?: boolean;
|
|
40
|
+
locale?: Locale;
|
|
41
|
+
/** Disable features app-wide. Pass the same object to the middleware. */
|
|
42
|
+
features?: PreprFeatures;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Options for the preview runtime. Two independent axes: `features` decides
|
|
46
|
+
* *what runs*, `ui` decides *whether the toolbar is visible*.
|
|
47
|
+
*/
|
|
48
|
+
interface PreprPreviewOptions extends PreprToolbarOptions {
|
|
49
|
+
/**
|
|
50
|
+
* Mount the visible `<prepr-toolbar>` element. Default `true`.
|
|
51
|
+
*
|
|
52
|
+
* `false` keeps every non-visual side effect wired — click-to-edit, the
|
|
53
|
+
* editor bridge, scroll restore, cookies and headers — with no chrome of its
|
|
54
|
+
* own. That is how a site gets live editing, or editor scroll restore, while
|
|
55
|
+
* rendering its own UI instead of the bar.
|
|
56
|
+
*
|
|
57
|
+
* Already implied inside the editor's iframe (the CMS owns the chrome there)
|
|
58
|
+
* and by `?prepr_hide_bar=true`, so this option is for consumers who want a
|
|
59
|
+
* headless preview by their own choice.
|
|
60
|
+
*/
|
|
61
|
+
ui?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Replace the `*.prepr.io` editor-origin wildcard with an exact list.
|
|
64
|
+
* Intended for self-hosted editors; when set, the wildcard no longer applies.
|
|
65
|
+
*/
|
|
66
|
+
allowedEditorOrigins?: string[];
|
|
67
|
+
}
|
|
32
68
|
interface PreprToolbarProps {
|
|
33
69
|
/**
|
|
34
70
|
* Server-resolved active segment. Optional: omit it with `segments`
|
|
@@ -47,6 +83,13 @@ interface PreprToolbarProps {
|
|
|
47
83
|
/** @deprecated Alias for `segments`. */
|
|
48
84
|
readonly data?: readonly PreprSegment[];
|
|
49
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Prop type for the framework `<PreprToolbar>` components: the toolbar data
|
|
88
|
+
* plus the options bag core `createPreprPreview` accepts.
|
|
89
|
+
*/
|
|
90
|
+
interface PreprToolbarComponentProps extends PreprToolbarProps {
|
|
91
|
+
options?: PreprPreviewOptions;
|
|
92
|
+
}
|
|
50
93
|
type PreprVariant = 'A' | 'B';
|
|
51
94
|
interface PreprHeaders {
|
|
52
95
|
readonly 'prepr-customer-id'?: string;
|
|
@@ -127,4 +170,58 @@ declare function validatePreprToken(token: string): void;
|
|
|
127
170
|
*/
|
|
128
171
|
declare function extractAccessToken(graphqlUrl: string): string;
|
|
129
172
|
|
|
130
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Loader + typed facade for Prepr's CDN tracking pixel, so consumers don't have
|
|
175
|
+
* to paste a `<script>` tag. The pixel itself lives on the CDN; this only sets
|
|
176
|
+
* up the handoff.
|
|
177
|
+
*
|
|
178
|
+
* The CDN script expects a queue stub to already exist when it loads, so the
|
|
179
|
+
* contract must be reproduced exactly:
|
|
180
|
+
* - `window.prepr` pushes `arguments` onto `.queue` until the real script
|
|
181
|
+
* lands and replaces `.process`.
|
|
182
|
+
* - `.t` must be a `Date.now()` timestamp.
|
|
183
|
+
* - The tag is inserted async, `src` cache-busted every 24h via
|
|
184
|
+
* `Math.ceil(Date.now() / cacheTime) * cacheTime`.
|
|
185
|
+
*/
|
|
186
|
+
/** Config accepted by the CDN pixel. */
|
|
187
|
+
interface PreprPixelConfig {
|
|
188
|
+
destinations?: {
|
|
189
|
+
googleTagManager?: boolean;
|
|
190
|
+
};
|
|
191
|
+
variantImpressionThreshold?: number;
|
|
192
|
+
}
|
|
193
|
+
type PreprQueueArgs = unknown[];
|
|
194
|
+
interface PreprQueueFn {
|
|
195
|
+
(...args: PreprQueueArgs): void;
|
|
196
|
+
queue: PreprQueueArgs[];
|
|
197
|
+
t: number;
|
|
198
|
+
process?: (...args: PreprQueueArgs) => void;
|
|
199
|
+
}
|
|
200
|
+
declare global {
|
|
201
|
+
interface Window {
|
|
202
|
+
prepr?: PreprQueueFn;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface PreprTrackingPixelProps {
|
|
207
|
+
/** Prepr tracking/access token. */
|
|
208
|
+
id: string;
|
|
209
|
+
config?: PreprPixelConfig;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Loads Prepr's CDN tracking pixel on mount. Renders nothing.
|
|
213
|
+
*
|
|
214
|
+
* The pixel queues a single `pageload` event when it installs. Client-side
|
|
215
|
+
* route changes emit nothing on their own — call `trackEvent('pageload')` from
|
|
216
|
+
* the router to count them.
|
|
217
|
+
*/
|
|
218
|
+
declare function PreprTrackingPixel({ id, config, }: PreprTrackingPixelProps): null;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Mounts the Prepr toolbar and wires it to the Next.js router so segment/variant
|
|
222
|
+
* switches navigate. Renders nothing — the toolbar UI is a custom element that
|
|
223
|
+
* `createPreprPreview` mounts imperatively.
|
|
224
|
+
*/
|
|
225
|
+
declare function PreprToolbar({ options, ...props }: PreprToolbarComponentProps): null;
|
|
226
|
+
|
|
227
|
+
export { PreprError, type PreprMiddlewareOptions, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, createPreprMiddleware, extractAccessToken, getActiveSegment, getActiveVariant, getPreprHeaders, getPreprUUID, getToolbarProps, validatePreprToken };
|
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
type Dictionary = Record<string, unknown>;
|
|
4
|
+
declare const dictionaries: {
|
|
5
|
+
en: Dictionary;
|
|
6
|
+
nl: Dictionary;
|
|
7
|
+
};
|
|
8
|
+
type Locale = keyof typeof dictionaries;
|
|
3
9
|
|
|
4
10
|
interface PreprSegment {
|
|
5
11
|
readonly _id: string;
|
|
@@ -29,6 +35,36 @@ interface PreprFeatures {
|
|
|
29
35
|
*/
|
|
30
36
|
editMode?: PreprFeatureConfig;
|
|
31
37
|
}
|
|
38
|
+
interface PreprToolbarOptions {
|
|
39
|
+
debug?: boolean;
|
|
40
|
+
locale?: Locale;
|
|
41
|
+
/** Disable features app-wide. Pass the same object to the middleware. */
|
|
42
|
+
features?: PreprFeatures;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Options for the preview runtime. Two independent axes: `features` decides
|
|
46
|
+
* *what runs*, `ui` decides *whether the toolbar is visible*.
|
|
47
|
+
*/
|
|
48
|
+
interface PreprPreviewOptions extends PreprToolbarOptions {
|
|
49
|
+
/**
|
|
50
|
+
* Mount the visible `<prepr-toolbar>` element. Default `true`.
|
|
51
|
+
*
|
|
52
|
+
* `false` keeps every non-visual side effect wired — click-to-edit, the
|
|
53
|
+
* editor bridge, scroll restore, cookies and headers — with no chrome of its
|
|
54
|
+
* own. That is how a site gets live editing, or editor scroll restore, while
|
|
55
|
+
* rendering its own UI instead of the bar.
|
|
56
|
+
*
|
|
57
|
+
* Already implied inside the editor's iframe (the CMS owns the chrome there)
|
|
58
|
+
* and by `?prepr_hide_bar=true`, so this option is for consumers who want a
|
|
59
|
+
* headless preview by their own choice.
|
|
60
|
+
*/
|
|
61
|
+
ui?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Replace the `*.prepr.io` editor-origin wildcard with an exact list.
|
|
64
|
+
* Intended for self-hosted editors; when set, the wildcard no longer applies.
|
|
65
|
+
*/
|
|
66
|
+
allowedEditorOrigins?: string[];
|
|
67
|
+
}
|
|
32
68
|
interface PreprToolbarProps {
|
|
33
69
|
/**
|
|
34
70
|
* Server-resolved active segment. Optional: omit it with `segments`
|
|
@@ -47,6 +83,13 @@ interface PreprToolbarProps {
|
|
|
47
83
|
/** @deprecated Alias for `segments`. */
|
|
48
84
|
readonly data?: readonly PreprSegment[];
|
|
49
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Prop type for the framework `<PreprToolbar>` components: the toolbar data
|
|
88
|
+
* plus the options bag core `createPreprPreview` accepts.
|
|
89
|
+
*/
|
|
90
|
+
interface PreprToolbarComponentProps extends PreprToolbarProps {
|
|
91
|
+
options?: PreprPreviewOptions;
|
|
92
|
+
}
|
|
50
93
|
type PreprVariant = 'A' | 'B';
|
|
51
94
|
interface PreprHeaders {
|
|
52
95
|
readonly 'prepr-customer-id'?: string;
|
|
@@ -127,4 +170,58 @@ declare function validatePreprToken(token: string): void;
|
|
|
127
170
|
*/
|
|
128
171
|
declare function extractAccessToken(graphqlUrl: string): string;
|
|
129
172
|
|
|
130
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Loader + typed facade for Prepr's CDN tracking pixel, so consumers don't have
|
|
175
|
+
* to paste a `<script>` tag. The pixel itself lives on the CDN; this only sets
|
|
176
|
+
* up the handoff.
|
|
177
|
+
*
|
|
178
|
+
* The CDN script expects a queue stub to already exist when it loads, so the
|
|
179
|
+
* contract must be reproduced exactly:
|
|
180
|
+
* - `window.prepr` pushes `arguments` onto `.queue` until the real script
|
|
181
|
+
* lands and replaces `.process`.
|
|
182
|
+
* - `.t` must be a `Date.now()` timestamp.
|
|
183
|
+
* - The tag is inserted async, `src` cache-busted every 24h via
|
|
184
|
+
* `Math.ceil(Date.now() / cacheTime) * cacheTime`.
|
|
185
|
+
*/
|
|
186
|
+
/** Config accepted by the CDN pixel. */
|
|
187
|
+
interface PreprPixelConfig {
|
|
188
|
+
destinations?: {
|
|
189
|
+
googleTagManager?: boolean;
|
|
190
|
+
};
|
|
191
|
+
variantImpressionThreshold?: number;
|
|
192
|
+
}
|
|
193
|
+
type PreprQueueArgs = unknown[];
|
|
194
|
+
interface PreprQueueFn {
|
|
195
|
+
(...args: PreprQueueArgs): void;
|
|
196
|
+
queue: PreprQueueArgs[];
|
|
197
|
+
t: number;
|
|
198
|
+
process?: (...args: PreprQueueArgs) => void;
|
|
199
|
+
}
|
|
200
|
+
declare global {
|
|
201
|
+
interface Window {
|
|
202
|
+
prepr?: PreprQueueFn;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface PreprTrackingPixelProps {
|
|
207
|
+
/** Prepr tracking/access token. */
|
|
208
|
+
id: string;
|
|
209
|
+
config?: PreprPixelConfig;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Loads Prepr's CDN tracking pixel on mount. Renders nothing.
|
|
213
|
+
*
|
|
214
|
+
* The pixel queues a single `pageload` event when it installs. Client-side
|
|
215
|
+
* route changes emit nothing on their own — call `trackEvent('pageload')` from
|
|
216
|
+
* the router to count them.
|
|
217
|
+
*/
|
|
218
|
+
declare function PreprTrackingPixel({ id, config, }: PreprTrackingPixelProps): null;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Mounts the Prepr toolbar and wires it to the Next.js router so segment/variant
|
|
222
|
+
* switches navigate. Renders nothing — the toolbar UI is a custom element that
|
|
223
|
+
* `createPreprPreview` mounts imperatively.
|
|
224
|
+
*/
|
|
225
|
+
declare function PreprToolbar({ options, ...props }: PreprToolbarComponentProps): null;
|
|
226
|
+
|
|
227
|
+
export { PreprError, type PreprMiddlewareOptions, PreprToolbar, PreprTrackingPixel, type PreprTrackingPixelProps, createPreprMiddleware, extractAccessToken, getActiveSegment, getActiveVariant, getPreprHeaders, getPreprUUID, getToolbarProps, validatePreprToken };
|
package/dist/nextjs/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
|
|
4
4
|
// src/version.ts
|
|
5
|
-
var VERSION = "0.2.0-beta.
|
|
5
|
+
var VERSION = "0.2.0-beta.9";
|
|
6
6
|
|
|
7
7
|
// src/core/constants.ts
|
|
8
8
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -56,7 +56,11 @@ function parseCookies(request) {
|
|
|
56
56
|
const name = part.slice(0, eq).trim();
|
|
57
57
|
const value = part.slice(eq + 1).trim();
|
|
58
58
|
if (!name) continue;
|
|
59
|
-
|
|
59
|
+
try {
|
|
60
|
+
cookies.set(name, decodeURIComponent(value));
|
|
61
|
+
} catch {
|
|
62
|
+
cookies.set(name, value);
|
|
63
|
+
}
|
|
60
64
|
}
|
|
61
65
|
return cookies;
|
|
62
66
|
}
|
|
@@ -95,7 +99,10 @@ function processPreprRequest(request, opts) {
|
|
|
95
99
|
if (userAgent) {
|
|
96
100
|
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
97
101
|
}
|
|
98
|
-
requestHeaders.set(
|
|
102
|
+
requestHeaders.set(
|
|
103
|
+
"Prepr-Package",
|
|
104
|
+
`@preprio/toolkit@${opts?.version ?? VERSION}`
|
|
105
|
+
);
|
|
99
106
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
100
107
|
if (ip) {
|
|
101
108
|
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
@@ -104,7 +111,7 @@ function processPreprRequest(request, opts) {
|
|
|
104
111
|
if (hutkCookie) {
|
|
105
112
|
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
106
113
|
}
|
|
107
|
-
let uid = requestCookies.get(COOKIE_UID);
|
|
114
|
+
let uid = sanitizeHeaderValue(requestCookies.get(COOKIE_UID) ?? "");
|
|
108
115
|
if (!uid) {
|
|
109
116
|
uid = crypto.randomUUID();
|
|
110
117
|
responseCookies.push({
|
|
@@ -188,19 +195,30 @@ function createPreprMiddleware(request, responseOrOptions, maybeOptions) {
|
|
|
188
195
|
} else {
|
|
189
196
|
options = responseOrOptions;
|
|
190
197
|
}
|
|
191
|
-
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
198
|
+
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
199
|
+
request,
|
|
200
|
+
options
|
|
201
|
+
);
|
|
192
202
|
const response = chainedResponse ?? NextResponse.next({ request: { headers: requestHeaders } });
|
|
193
203
|
if (chainedResponse) {
|
|
204
|
+
const existing = response.headers.get("x-middleware-override-headers");
|
|
205
|
+
const names = new Set(
|
|
206
|
+
existing ? existing.split(",").map((name) => name.trim()).filter(Boolean) : []
|
|
207
|
+
);
|
|
194
208
|
requestHeaders.forEach((value, key) => {
|
|
195
|
-
|
|
209
|
+
names.add(key);
|
|
210
|
+
response.headers.set(`x-middleware-request-${key}`, value);
|
|
196
211
|
});
|
|
212
|
+
response.headers.set("x-middleware-override-headers", [...names].join(","));
|
|
197
213
|
}
|
|
198
214
|
for (const cookie of responseCookies) {
|
|
199
215
|
response.cookies.set(cookie.name, cookie.value, {
|
|
200
216
|
maxAge: cookie.maxAge,
|
|
201
217
|
path: cookie.path,
|
|
202
218
|
// Lower-cased: Next's cookie API expects 'none' | 'lax' | 'strict'.
|
|
203
|
-
...cookie.sameSite ? {
|
|
219
|
+
...cookie.sameSite ? {
|
|
220
|
+
sameSite: cookie.sameSite.toLowerCase()
|
|
221
|
+
} : {},
|
|
204
222
|
...cookie.secure ? { secure: true } : {}
|
|
205
223
|
});
|
|
206
224
|
}
|
|
@@ -260,7 +278,11 @@ function getPreprHeadersFromHeaders(headers2) {
|
|
|
260
278
|
}
|
|
261
279
|
function validatePreprToken(token) {
|
|
262
280
|
if (!token) {
|
|
263
|
-
throw new PreprError(
|
|
281
|
+
throw new PreprError(
|
|
282
|
+
"Token is required",
|
|
283
|
+
"MISSING_TOKEN",
|
|
284
|
+
"validatePreprToken"
|
|
285
|
+
);
|
|
264
286
|
}
|
|
265
287
|
if (!token.startsWith("https://")) {
|
|
266
288
|
throw new PreprError(
|
|
@@ -393,7 +415,7 @@ async function getToolbarProps(token, features) {
|
|
|
393
415
|
import {
|
|
394
416
|
PreprToolbar,
|
|
395
417
|
PreprTrackingPixel
|
|
396
|
-
} from "./components";
|
|
418
|
+
} from "./components.js";
|
|
397
419
|
export {
|
|
398
420
|
PreprError,
|
|
399
421
|
PreprToolbar,
|
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.2.0-beta.
|
|
38
|
+
var VERSION = "0.2.0-beta.9";
|
|
39
39
|
|
|
40
40
|
// src/core/constants.ts
|
|
41
41
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -103,7 +103,11 @@ function parseCookies(request) {
|
|
|
103
103
|
const name = part.slice(0, eq).trim();
|
|
104
104
|
const value = part.slice(eq + 1).trim();
|
|
105
105
|
if (!name) continue;
|
|
106
|
-
|
|
106
|
+
try {
|
|
107
|
+
cookies.set(name, decodeURIComponent(value));
|
|
108
|
+
} catch {
|
|
109
|
+
cookies.set(name, value);
|
|
110
|
+
}
|
|
107
111
|
}
|
|
108
112
|
return cookies;
|
|
109
113
|
}
|
|
@@ -142,7 +146,10 @@ function processPreprRequest(request, opts) {
|
|
|
142
146
|
if (userAgent) {
|
|
143
147
|
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
144
148
|
}
|
|
145
|
-
requestHeaders.set(
|
|
149
|
+
requestHeaders.set(
|
|
150
|
+
"Prepr-Package",
|
|
151
|
+
`@preprio/toolkit@${opts?.version ?? VERSION}`
|
|
152
|
+
);
|
|
146
153
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
147
154
|
if (ip) {
|
|
148
155
|
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
@@ -151,7 +158,7 @@ function processPreprRequest(request, opts) {
|
|
|
151
158
|
if (hutkCookie) {
|
|
152
159
|
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
153
160
|
}
|
|
154
|
-
let uid = requestCookies.get(COOKIE_UID);
|
|
161
|
+
let uid = sanitizeHeaderValue(requestCookies.get(COOKIE_UID) ?? "");
|
|
155
162
|
if (!uid) {
|
|
156
163
|
uid = crypto.randomUUID();
|
|
157
164
|
responseCookies.push({
|
|
@@ -238,7 +245,10 @@ function handlePreprRequest(event, options) {
|
|
|
238
245
|
request.headers.set(key, value.join(", "));
|
|
239
246
|
}
|
|
240
247
|
}
|
|
241
|
-
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
248
|
+
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
249
|
+
request,
|
|
250
|
+
options
|
|
251
|
+
);
|
|
242
252
|
requestHeaders.forEach((value, key) => {
|
|
243
253
|
req.headers[key.toLowerCase()] = value;
|
|
244
254
|
});
|
|
@@ -302,7 +312,11 @@ function getPreprHeadersFromHeaders(headers) {
|
|
|
302
312
|
}
|
|
303
313
|
function validatePreprToken(token) {
|
|
304
314
|
if (!token) {
|
|
305
|
-
throw new PreprError(
|
|
315
|
+
throw new PreprError(
|
|
316
|
+
"Token is required",
|
|
317
|
+
"MISSING_TOKEN",
|
|
318
|
+
"validatePreprToken"
|
|
319
|
+
);
|
|
306
320
|
}
|
|
307
321
|
if (!token.startsWith("https://")) {
|
|
308
322
|
throw new PreprError(
|
package/dist/nuxt/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var VERSION = "0.2.0-beta.
|
|
2
|
+
var VERSION = "0.2.0-beta.9";
|
|
3
3
|
|
|
4
4
|
// src/core/constants.ts
|
|
5
5
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -67,7 +67,11 @@ function parseCookies(request) {
|
|
|
67
67
|
const name = part.slice(0, eq).trim();
|
|
68
68
|
const value = part.slice(eq + 1).trim();
|
|
69
69
|
if (!name) continue;
|
|
70
|
-
|
|
70
|
+
try {
|
|
71
|
+
cookies.set(name, decodeURIComponent(value));
|
|
72
|
+
} catch {
|
|
73
|
+
cookies.set(name, value);
|
|
74
|
+
}
|
|
71
75
|
}
|
|
72
76
|
return cookies;
|
|
73
77
|
}
|
|
@@ -106,7 +110,10 @@ function processPreprRequest(request, opts) {
|
|
|
106
110
|
if (userAgent) {
|
|
107
111
|
requestHeaders.set("Prepr-User-Agent", sanitizeHeaderValue(userAgent));
|
|
108
112
|
}
|
|
109
|
-
requestHeaders.set(
|
|
113
|
+
requestHeaders.set(
|
|
114
|
+
"Prepr-Package",
|
|
115
|
+
`@preprio/toolkit@${opts?.version ?? VERSION}`
|
|
116
|
+
);
|
|
110
117
|
const ip = request.headers.get("Cf-Connecting-Ip") ?? request.headers.get("x-real-ip");
|
|
111
118
|
if (ip) {
|
|
112
119
|
requestHeaders.set("Prepr-Visitor-IP", sanitizeHeaderValue(ip));
|
|
@@ -115,7 +122,7 @@ function processPreprRequest(request, opts) {
|
|
|
115
122
|
if (hutkCookie) {
|
|
116
123
|
requestHeaders.set("Prepr-Hubspot-Id", sanitizeHeaderValue(hutkCookie));
|
|
117
124
|
}
|
|
118
|
-
let uid = requestCookies.get(COOKIE_UID);
|
|
125
|
+
let uid = sanitizeHeaderValue(requestCookies.get(COOKIE_UID) ?? "");
|
|
119
126
|
if (!uid) {
|
|
120
127
|
uid = crypto.randomUUID();
|
|
121
128
|
responseCookies.push({
|
|
@@ -202,7 +209,10 @@ function handlePreprRequest(event, options) {
|
|
|
202
209
|
request.headers.set(key, value.join(", "));
|
|
203
210
|
}
|
|
204
211
|
}
|
|
205
|
-
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
212
|
+
const { requestHeaders, responseCookies } = processPreprRequest(
|
|
213
|
+
request,
|
|
214
|
+
options
|
|
215
|
+
);
|
|
206
216
|
requestHeaders.forEach((value, key) => {
|
|
207
217
|
req.headers[key.toLowerCase()] = value;
|
|
208
218
|
});
|
|
@@ -266,7 +276,11 @@ function getPreprHeadersFromHeaders(headers) {
|
|
|
266
276
|
}
|
|
267
277
|
function validatePreprToken(token) {
|
|
268
278
|
if (!token) {
|
|
269
|
-
throw new PreprError(
|
|
279
|
+
throw new PreprError(
|
|
280
|
+
"Token is required",
|
|
281
|
+
"MISSING_TOKEN",
|
|
282
|
+
"validatePreprToken"
|
|
283
|
+
);
|
|
270
284
|
}
|
|
271
285
|
if (!token.startsWith("https://")) {
|
|
272
286
|
throw new PreprError(
|
|
@@ -368,9 +368,7 @@ function decodeStega(str) {
|
|
|
368
368
|
const match = str.match(/{"origin.*?}/);
|
|
369
369
|
if (match) {
|
|
370
370
|
try {
|
|
371
|
-
const decodedMatch = (0, import_stega.vercelStegaDecode)(
|
|
372
|
-
match[0]
|
|
373
|
-
);
|
|
371
|
+
const decodedMatch = (0, import_stega.vercelStegaDecode)(match[0]);
|
|
374
372
|
if (decodedMatch?.href) {
|
|
375
373
|
return decodedMatch;
|
|
376
374
|
}
|
|
@@ -898,8 +896,13 @@ function createStegaController(opts) {
|
|
|
898
896
|
overlay.hide();
|
|
899
897
|
}
|
|
900
898
|
}, 16);
|
|
901
|
-
document.addEventListener("mousemove", throttledMouseMove
|
|
902
|
-
|
|
899
|
+
document.addEventListener("mousemove", throttledMouseMove, {
|
|
900
|
+
passive: true
|
|
901
|
+
});
|
|
902
|
+
window.addEventListener("scroll", handleScroll, {
|
|
903
|
+
capture: true,
|
|
904
|
+
passive: true
|
|
905
|
+
});
|
|
903
906
|
initialized = true;
|
|
904
907
|
debug6.log("stega controller started");
|
|
905
908
|
};
|
|
@@ -1042,7 +1045,9 @@ function createChangeHandler(deps) {
|
|
|
1042
1045
|
}
|
|
1043
1046
|
setCookie(COOKIE_PREVIEW_MODE, String(after.previewMode), cookieOpts());
|
|
1044
1047
|
setCookie(COOKIE_TOOLBAR_OPEN, "false", cookieOpts());
|
|
1045
|
-
sendPreprEvent("preview_mode_toggled", {
|
|
1048
|
+
sendPreprEvent("preview_mode_toggled", {
|
|
1049
|
+
previewMode: after.previewMode
|
|
1050
|
+
});
|
|
1046
1051
|
if (!after.isIframe) {
|
|
1047
1052
|
const [path, existing] = splitPath(deps.currentPath());
|
|
1048
1053
|
const params = new URLSearchParams(existing);
|
|
@@ -1363,7 +1368,10 @@ function u2(e2, t3, n2, o2, i2, u3) {
|
|
|
1363
1368
|
}
|
|
1364
1369
|
|
|
1365
1370
|
// src/core/ui/panel.tsx
|
|
1366
|
-
function RawSvg({
|
|
1371
|
+
function RawSvg({
|
|
1372
|
+
svg,
|
|
1373
|
+
className
|
|
1374
|
+
}) {
|
|
1367
1375
|
return /* @__PURE__ */ u2(
|
|
1368
1376
|
"span",
|
|
1369
1377
|
{
|
|
@@ -1934,9 +1942,7 @@ var PreprToolbarElement = class extends HTMLElementBase {
|
|
|
1934
1942
|
) ?? null;
|
|
1935
1943
|
}
|
|
1936
1944
|
optionsList() {
|
|
1937
|
-
return this.shadowRoot?.querySelector(
|
|
1938
|
-
'[data-prepr="options"]'
|
|
1939
|
-
) ?? null;
|
|
1945
|
+
return this.shadowRoot?.querySelector('[data-prepr="options"]') ?? null;
|
|
1940
1946
|
}
|
|
1941
1947
|
onListboxKeydown(event) {
|
|
1942
1948
|
const e2 = event;
|
|
@@ -2156,9 +2162,13 @@ function createPreprPreview(opts = {}) {
|
|
|
2156
2162
|
const bridge = createIframeBridge(store, {
|
|
2157
2163
|
allowedEditorOrigins: options?.allowedEditorOrigins
|
|
2158
2164
|
});
|
|
2159
|
-
sendPreprEvent(
|
|
2160
|
-
|
|
2161
|
-
|
|
2165
|
+
sendPreprEvent(
|
|
2166
|
+
"getScrollPosition",
|
|
2167
|
+
{ value: 0 },
|
|
2168
|
+
{
|
|
2169
|
+
allowUntrustedTarget: true
|
|
2170
|
+
}
|
|
2171
|
+
);
|
|
2162
2172
|
if (isIframe) {
|
|
2163
2173
|
bridge.start();
|
|
2164
2174
|
}
|