@preprio/toolkit 0.1.0-beta.4 → 0.1.0-beta.5
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/LICENSE +202 -0
- package/README.md +5 -1
- package/dist/astro/index.cjs +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/{chunk-3FOY6KL4.js → chunk-NLQIRN5O.js} +49 -13
- package/dist/index.cjs +50 -14
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/json-script.cjs +32 -0
- package/dist/json-script.d.cts +17 -0
- package/dist/json-script.d.ts +17 -0
- package/dist/json-script.js +7 -0
- package/dist/nextjs/components.cjs +49 -13
- package/dist/nextjs/components.js +1 -1
- package/dist/nextjs/index.cjs +1 -1
- package/dist/nextjs/index.js +1 -1
- package/dist/nuxt/index.cjs +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/package.json +52 -14
- package/src/astro/PreprToolbar.astro +2 -1
- package/src/astro/PreprTrackingPixel.astro +3 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright 2026 Prepr B.V.
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -647,9 +647,13 @@ validatePreprToken(process.env.PREPR_GRAPHQL_URL!); // throws PreprError if inva
|
|
|
647
647
|
|
|
648
648
|
Extracts the access token from a Prepr GraphQL URL — the value `PreprTrackingPixel` needs as its `id`.
|
|
649
649
|
|
|
650
|
+
Returns the token as a `string`. It never returns `null` — a URL that is malformed, not on `graphql.prepr.io`, or missing a token segment throws a `PreprError` with code `INVALID_TOKEN`.
|
|
651
|
+
|
|
650
652
|
```typescript
|
|
651
653
|
const token = extractAccessToken('https://graphql.prepr.io/abc123');
|
|
652
|
-
// 'abc123'
|
|
654
|
+
// 'abc123'
|
|
655
|
+
|
|
656
|
+
extractAccessToken('not-a-url'); // throws PreprError(INVALID_TOKEN)
|
|
653
657
|
```
|
|
654
658
|
|
|
655
659
|
### Components
|
package/dist/astro/index.cjs
CHANGED
package/dist/astro/index.js
CHANGED
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
import { vercelStegaClean, vercelStegaDecode } from "@vercel/stega";
|
|
3
3
|
|
|
4
4
|
// src/core/utils.ts
|
|
5
|
-
|
|
5
|
+
var trustedParentOrigin = null;
|
|
6
|
+
function setTrustedParentOrigin(origin) {
|
|
7
|
+
trustedParentOrigin = origin;
|
|
8
|
+
}
|
|
9
|
+
function sendPreprEvent(event, data, options) {
|
|
6
10
|
if (typeof window !== "undefined") {
|
|
7
11
|
const message = {
|
|
8
12
|
name: "prepr_preview_bar",
|
|
@@ -13,7 +17,11 @@ function sendPreprEvent(event, data) {
|
|
|
13
17
|
new CustomEvent("prepr_preview_bar", { detail: message })
|
|
14
18
|
);
|
|
15
19
|
if (window.parent && window.parent !== window) {
|
|
16
|
-
|
|
20
|
+
if (trustedParentOrigin) {
|
|
21
|
+
window.parent.postMessage(message, trustedParentOrigin);
|
|
22
|
+
} else if (options?.allowUntrustedTarget) {
|
|
23
|
+
window.parent.postMessage(message, "*");
|
|
24
|
+
}
|
|
17
25
|
}
|
|
18
26
|
}
|
|
19
27
|
}
|
|
@@ -1825,7 +1833,23 @@ function t2(key, locale, vars) {
|
|
|
1825
1833
|
}
|
|
1826
1834
|
|
|
1827
1835
|
// src/core/iframe-bridge.ts
|
|
1828
|
-
|
|
1836
|
+
var EDITOR_BASE_DOMAIN = "prepr.io";
|
|
1837
|
+
function isAllowedEditorOrigin(origin, allowed) {
|
|
1838
|
+
if (allowed) return allowed.includes(origin);
|
|
1839
|
+
let url;
|
|
1840
|
+
try {
|
|
1841
|
+
url = new URL(origin);
|
|
1842
|
+
} catch {
|
|
1843
|
+
return false;
|
|
1844
|
+
}
|
|
1845
|
+
if (url.protocol !== "https:" || url.port !== "") return false;
|
|
1846
|
+
const suffix = `.${EDITOR_BASE_DOMAIN}`;
|
|
1847
|
+
if (!url.hostname.endsWith(suffix)) return false;
|
|
1848
|
+
const label = url.hostname.slice(0, -suffix.length);
|
|
1849
|
+
return label.length > 0 && !label.includes(".");
|
|
1850
|
+
}
|
|
1851
|
+
function createIframeBridge(store, options = {}) {
|
|
1852
|
+
const allowedOrigins = options.allowedEditorOrigins;
|
|
1829
1853
|
let parentOrigin = null;
|
|
1830
1854
|
const onKeyDown = (event) => {
|
|
1831
1855
|
const key = event.key.toLowerCase();
|
|
@@ -1835,14 +1859,16 @@ function createIframeBridge(store) {
|
|
|
1835
1859
|
const onMessage = (evt) => {
|
|
1836
1860
|
const data = evt?.data;
|
|
1837
1861
|
if (data?.event === "prepr:initVE" && !parentOrigin) {
|
|
1862
|
+
if (!isAllowedEditorOrigin(evt.origin, allowedOrigins)) return;
|
|
1838
1863
|
parentOrigin = evt.origin;
|
|
1864
|
+
setTrustedParentOrigin(parentOrigin);
|
|
1839
1865
|
if (data.scrollPosition != null) {
|
|
1840
1866
|
const top = data.scrollPosition;
|
|
1841
1867
|
setTimeout(() => window.scrollTo(0, top), 1);
|
|
1842
1868
|
}
|
|
1843
1869
|
store.set({ previewMode: true, editMode: data.editMode ?? true });
|
|
1844
1870
|
}
|
|
1845
|
-
if (evt.origin !== parentOrigin) return;
|
|
1871
|
+
if (!parentOrigin || evt.origin !== parentOrigin) return;
|
|
1846
1872
|
if (data?.event === "prepr:getScrollPosition") {
|
|
1847
1873
|
const currentScrollY = window.scrollY || document.documentElement.scrollTop;
|
|
1848
1874
|
sendPreprEvent("getScrollPosition", { value: currentScrollY });
|
|
@@ -1850,13 +1876,15 @@ function createIframeBridge(store) {
|
|
|
1850
1876
|
};
|
|
1851
1877
|
return {
|
|
1852
1878
|
start() {
|
|
1853
|
-
sendPreprEvent("loaded");
|
|
1879
|
+
sendPreprEvent("loaded", void 0, { allowUntrustedTarget: true });
|
|
1854
1880
|
window.addEventListener("keydown", onKeyDown);
|
|
1855
1881
|
window.addEventListener("message", onMessage);
|
|
1856
1882
|
},
|
|
1857
1883
|
stop() {
|
|
1858
1884
|
window.removeEventListener("keydown", onKeyDown);
|
|
1859
1885
|
window.removeEventListener("message", onMessage);
|
|
1886
|
+
parentOrigin = null;
|
|
1887
|
+
setTrustedParentOrigin(null);
|
|
1860
1888
|
}
|
|
1861
1889
|
};
|
|
1862
1890
|
}
|
|
@@ -1871,25 +1899,28 @@ function cookieOpts() {
|
|
|
1871
1899
|
}
|
|
1872
1900
|
function createChangeHandler(deps) {
|
|
1873
1901
|
const { store, stega, syncAutoClean } = deps;
|
|
1874
|
-
function
|
|
1902
|
+
function updateParams(patch) {
|
|
1875
1903
|
const [path, existing] = splitPath(deps.currentPath());
|
|
1876
1904
|
const params = new URLSearchParams(existing);
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1905
|
+
for (const [name, value] of Object.entries(patch)) {
|
|
1906
|
+
if (value === null) {
|
|
1907
|
+
params.delete(name);
|
|
1908
|
+
} else {
|
|
1909
|
+
params.set(name, value);
|
|
1910
|
+
}
|
|
1881
1911
|
}
|
|
1882
1912
|
const query = params.toString();
|
|
1883
1913
|
deps.navigate(query ? `${path}?${query}` : path);
|
|
1884
1914
|
}
|
|
1885
1915
|
return function handleChange(before, after) {
|
|
1916
|
+
const paramPatch = {};
|
|
1886
1917
|
if (before.selectedSegment !== after.selectedSegment) {
|
|
1887
1918
|
if (after.selectedSegment === null) {
|
|
1888
1919
|
removeCookie(COOKIE_SEGMENT, "/", crossSiteCookieOptions());
|
|
1889
1920
|
} else {
|
|
1890
1921
|
setCookie(COOKIE_SEGMENT, after.selectedSegment, cookieOpts());
|
|
1891
1922
|
}
|
|
1892
|
-
|
|
1923
|
+
paramPatch[PARAM_SEGMENT] = after.selectedSegment;
|
|
1893
1924
|
sendPreprEvent("segment_changed", {
|
|
1894
1925
|
segment: after.selectedSegment ?? void 0
|
|
1895
1926
|
});
|
|
@@ -1900,11 +1931,14 @@ function createChangeHandler(deps) {
|
|
|
1900
1931
|
} else {
|
|
1901
1932
|
setCookie(COOKIE_VARIANT, after.selectedVariant, cookieOpts());
|
|
1902
1933
|
}
|
|
1903
|
-
|
|
1934
|
+
paramPatch[PARAM_VARIANT] = after.selectedVariant;
|
|
1904
1935
|
sendPreprEvent("variant_changed", {
|
|
1905
1936
|
variant: after.selectedVariant ?? void 0
|
|
1906
1937
|
});
|
|
1907
1938
|
}
|
|
1939
|
+
if (Object.keys(paramPatch).length > 0) {
|
|
1940
|
+
updateParams(paramPatch);
|
|
1941
|
+
}
|
|
1908
1942
|
if (before.editMode !== after.editMode) {
|
|
1909
1943
|
if (after.editMode) {
|
|
1910
1944
|
stega.start();
|
|
@@ -2052,7 +2086,9 @@ function createPreprToolbar(opts) {
|
|
|
2052
2086
|
});
|
|
2053
2087
|
syncAutoClean(store.get().previewMode);
|
|
2054
2088
|
const bridge = createIframeBridge(store);
|
|
2055
|
-
sendPreprEvent("getScrollPosition", { value: 0 }
|
|
2089
|
+
sendPreprEvent("getScrollPosition", { value: 0 }, {
|
|
2090
|
+
allowUntrustedTarget: true
|
|
2091
|
+
});
|
|
2056
2092
|
if (isIframe) {
|
|
2057
2093
|
bridge.start();
|
|
2058
2094
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -43,7 +43,7 @@ __export(src_exports, {
|
|
|
43
43
|
module.exports = __toCommonJS(src_exports);
|
|
44
44
|
|
|
45
45
|
// src/version.ts
|
|
46
|
-
var VERSION = "0.1.0-beta.
|
|
46
|
+
var VERSION = "0.1.0-beta.5";
|
|
47
47
|
|
|
48
48
|
// src/core/constants.ts
|
|
49
49
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
|
@@ -188,7 +188,11 @@ function t(key, locale, vars) {
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
// src/core/utils.ts
|
|
191
|
-
|
|
191
|
+
var trustedParentOrigin = null;
|
|
192
|
+
function setTrustedParentOrigin(origin) {
|
|
193
|
+
trustedParentOrigin = origin;
|
|
194
|
+
}
|
|
195
|
+
function sendPreprEvent(event, data, options) {
|
|
192
196
|
if (typeof window !== "undefined") {
|
|
193
197
|
const message = {
|
|
194
198
|
name: "prepr_preview_bar",
|
|
@@ -199,7 +203,11 @@ function sendPreprEvent(event, data) {
|
|
|
199
203
|
new CustomEvent("prepr_preview_bar", { detail: message })
|
|
200
204
|
);
|
|
201
205
|
if (window.parent && window.parent !== window) {
|
|
202
|
-
|
|
206
|
+
if (trustedParentOrigin) {
|
|
207
|
+
window.parent.postMessage(message, trustedParentOrigin);
|
|
208
|
+
} else if (options?.allowUntrustedTarget) {
|
|
209
|
+
window.parent.postMessage(message, "*");
|
|
210
|
+
}
|
|
203
211
|
}
|
|
204
212
|
}
|
|
205
213
|
}
|
|
@@ -285,7 +293,23 @@ function createElementCache(query, ttl = 1e3) {
|
|
|
285
293
|
}
|
|
286
294
|
|
|
287
295
|
// src/core/iframe-bridge.ts
|
|
288
|
-
|
|
296
|
+
var EDITOR_BASE_DOMAIN = "prepr.io";
|
|
297
|
+
function isAllowedEditorOrigin(origin, allowed) {
|
|
298
|
+
if (allowed) return allowed.includes(origin);
|
|
299
|
+
let url;
|
|
300
|
+
try {
|
|
301
|
+
url = new URL(origin);
|
|
302
|
+
} catch {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
if (url.protocol !== "https:" || url.port !== "") return false;
|
|
306
|
+
const suffix = `.${EDITOR_BASE_DOMAIN}`;
|
|
307
|
+
if (!url.hostname.endsWith(suffix)) return false;
|
|
308
|
+
const label = url.hostname.slice(0, -suffix.length);
|
|
309
|
+
return label.length > 0 && !label.includes(".");
|
|
310
|
+
}
|
|
311
|
+
function createIframeBridge(store, options = {}) {
|
|
312
|
+
const allowedOrigins = options.allowedEditorOrigins;
|
|
289
313
|
let parentOrigin = null;
|
|
290
314
|
const onKeyDown = (event) => {
|
|
291
315
|
const key = event.key.toLowerCase();
|
|
@@ -295,14 +319,16 @@ function createIframeBridge(store) {
|
|
|
295
319
|
const onMessage = (evt) => {
|
|
296
320
|
const data = evt?.data;
|
|
297
321
|
if (data?.event === "prepr:initVE" && !parentOrigin) {
|
|
322
|
+
if (!isAllowedEditorOrigin(evt.origin, allowedOrigins)) return;
|
|
298
323
|
parentOrigin = evt.origin;
|
|
324
|
+
setTrustedParentOrigin(parentOrigin);
|
|
299
325
|
if (data.scrollPosition != null) {
|
|
300
326
|
const top = data.scrollPosition;
|
|
301
327
|
setTimeout(() => window.scrollTo(0, top), 1);
|
|
302
328
|
}
|
|
303
329
|
store.set({ previewMode: true, editMode: data.editMode ?? true });
|
|
304
330
|
}
|
|
305
|
-
if (evt.origin !== parentOrigin) return;
|
|
331
|
+
if (!parentOrigin || evt.origin !== parentOrigin) return;
|
|
306
332
|
if (data?.event === "prepr:getScrollPosition") {
|
|
307
333
|
const currentScrollY = window.scrollY || document.documentElement.scrollTop;
|
|
308
334
|
sendPreprEvent("getScrollPosition", { value: currentScrollY });
|
|
@@ -310,13 +336,15 @@ function createIframeBridge(store) {
|
|
|
310
336
|
};
|
|
311
337
|
return {
|
|
312
338
|
start() {
|
|
313
|
-
sendPreprEvent("loaded");
|
|
339
|
+
sendPreprEvent("loaded", void 0, { allowUntrustedTarget: true });
|
|
314
340
|
window.addEventListener("keydown", onKeyDown);
|
|
315
341
|
window.addEventListener("message", onMessage);
|
|
316
342
|
},
|
|
317
343
|
stop() {
|
|
318
344
|
window.removeEventListener("keydown", onKeyDown);
|
|
319
345
|
window.removeEventListener("message", onMessage);
|
|
346
|
+
parentOrigin = null;
|
|
347
|
+
setTrustedParentOrigin(null);
|
|
320
348
|
}
|
|
321
349
|
};
|
|
322
350
|
}
|
|
@@ -960,25 +988,28 @@ function cookieOpts() {
|
|
|
960
988
|
}
|
|
961
989
|
function createChangeHandler(deps) {
|
|
962
990
|
const { store, stega, syncAutoClean } = deps;
|
|
963
|
-
function
|
|
991
|
+
function updateParams(patch) {
|
|
964
992
|
const [path, existing] = splitPath(deps.currentPath());
|
|
965
993
|
const params = new URLSearchParams(existing);
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
994
|
+
for (const [name, value] of Object.entries(patch)) {
|
|
995
|
+
if (value === null) {
|
|
996
|
+
params.delete(name);
|
|
997
|
+
} else {
|
|
998
|
+
params.set(name, value);
|
|
999
|
+
}
|
|
970
1000
|
}
|
|
971
1001
|
const query = params.toString();
|
|
972
1002
|
deps.navigate(query ? `${path}?${query}` : path);
|
|
973
1003
|
}
|
|
974
1004
|
return function handleChange(before, after) {
|
|
1005
|
+
const paramPatch = {};
|
|
975
1006
|
if (before.selectedSegment !== after.selectedSegment) {
|
|
976
1007
|
if (after.selectedSegment === null) {
|
|
977
1008
|
removeCookie(COOKIE_SEGMENT, "/", crossSiteCookieOptions());
|
|
978
1009
|
} else {
|
|
979
1010
|
setCookie(COOKIE_SEGMENT, after.selectedSegment, cookieOpts());
|
|
980
1011
|
}
|
|
981
|
-
|
|
1012
|
+
paramPatch[PARAM_SEGMENT] = after.selectedSegment;
|
|
982
1013
|
sendPreprEvent("segment_changed", {
|
|
983
1014
|
segment: after.selectedSegment ?? void 0
|
|
984
1015
|
});
|
|
@@ -989,11 +1020,14 @@ function createChangeHandler(deps) {
|
|
|
989
1020
|
} else {
|
|
990
1021
|
setCookie(COOKIE_VARIANT, after.selectedVariant, cookieOpts());
|
|
991
1022
|
}
|
|
992
|
-
|
|
1023
|
+
paramPatch[PARAM_VARIANT] = after.selectedVariant;
|
|
993
1024
|
sendPreprEvent("variant_changed", {
|
|
994
1025
|
variant: after.selectedVariant ?? void 0
|
|
995
1026
|
});
|
|
996
1027
|
}
|
|
1028
|
+
if (Object.keys(paramPatch).length > 0) {
|
|
1029
|
+
updateParams(paramPatch);
|
|
1030
|
+
}
|
|
997
1031
|
if (before.editMode !== after.editMode) {
|
|
998
1032
|
if (after.editMode) {
|
|
999
1033
|
stega.start();
|
|
@@ -2099,7 +2133,9 @@ function createPreprToolbar(opts) {
|
|
|
2099
2133
|
});
|
|
2100
2134
|
syncAutoClean(store.get().previewMode);
|
|
2101
2135
|
const bridge = createIframeBridge(store);
|
|
2102
|
-
sendPreprEvent("getScrollPosition", { value: 0 }
|
|
2136
|
+
sendPreprEvent("getScrollPosition", { value: 0 }, {
|
|
2137
|
+
allowUntrustedTarget: true
|
|
2138
|
+
});
|
|
2103
2139
|
if (isIframe) {
|
|
2104
2140
|
bridge.start();
|
|
2105
2141
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ export { f as PreprEnvironment, g as PreprEventType, h as PreprHeaderName, i as
|
|
|
5
5
|
* Package version; must match package.json. Lives in its own leaf module so
|
|
6
6
|
* core can import it without cycling through the barrel.
|
|
7
7
|
*/
|
|
8
|
-
declare const VERSION = "0.1.0-beta.
|
|
8
|
+
declare const VERSION = "0.1.0-beta.5";
|
|
9
9
|
|
|
10
10
|
interface ToolbarState {
|
|
11
11
|
locale: Locale;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { f as PreprEnvironment, g as PreprEventType, h as PreprHeaderName, i as
|
|
|
5
5
|
* Package version; must match package.json. Lives in its own leaf module so
|
|
6
6
|
* core can import it without cycling through the barrel.
|
|
7
7
|
*/
|
|
8
|
-
declare const VERSION = "0.1.0-beta.
|
|
8
|
+
declare const VERSION = "0.1.0-beta.5";
|
|
9
9
|
|
|
10
10
|
interface ToolbarState {
|
|
11
11
|
locale: Locale;
|
package/dist/index.js
CHANGED
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
setTrackingParam,
|
|
17
17
|
stegaClean,
|
|
18
18
|
trackEvent
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-NLQIRN5O.js";
|
|
20
20
|
|
|
21
21
|
// src/version.ts
|
|
22
|
-
var VERSION = "0.1.0-beta.
|
|
22
|
+
var VERSION = "0.1.0-beta.5";
|
|
23
23
|
|
|
24
24
|
// src/core/server.ts
|
|
25
25
|
var PreprError = class extends Error {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/core/json-script.ts
|
|
21
|
+
var json_script_exports = {};
|
|
22
|
+
__export(json_script_exports, {
|
|
23
|
+
serializeForScriptTag: () => serializeForScriptTag
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(json_script_exports);
|
|
26
|
+
function serializeForScriptTag(value) {
|
|
27
|
+
return JSON.stringify(value ?? null).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
28
|
+
}
|
|
29
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
30
|
+
0 && (module.exports = {
|
|
31
|
+
serializeForScriptTag
|
|
32
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a value for embedding inside `<script type="application/json">`.
|
|
3
|
+
*
|
|
4
|
+
* `JSON.stringify` does not escape `<`, `>` or `&`, so a string value
|
|
5
|
+
* containing `</script>` would close the tag early and let the remainder parse
|
|
6
|
+
* as HTML — stored XSS whenever any part of the payload is author-controlled
|
|
7
|
+
* (CMS segment names reach these components verbatim).
|
|
8
|
+
*
|
|
9
|
+
* Escaping `<` and `>` as `\uXXXX` keeps the output valid JSON that parses back
|
|
10
|
+
* to the identical value, while making an early tag close impossible. `&` is
|
|
11
|
+
* escaped too so the payload is also safe inside HTML-escaping contexts, and
|
|
12
|
+
* U+2028/U+2029 because they are literal line terminators in JS source but
|
|
13
|
+
* legal unescaped inside a JSON string.
|
|
14
|
+
*/
|
|
15
|
+
declare function serializeForScriptTag(value: unknown): string;
|
|
16
|
+
|
|
17
|
+
export { serializeForScriptTag };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a value for embedding inside `<script type="application/json">`.
|
|
3
|
+
*
|
|
4
|
+
* `JSON.stringify` does not escape `<`, `>` or `&`, so a string value
|
|
5
|
+
* containing `</script>` would close the tag early and let the remainder parse
|
|
6
|
+
* as HTML — stored XSS whenever any part of the payload is author-controlled
|
|
7
|
+
* (CMS segment names reach these components verbatim).
|
|
8
|
+
*
|
|
9
|
+
* Escaping `<` and `>` as `\uXXXX` keeps the output valid JSON that parses back
|
|
10
|
+
* to the identical value, while making an early tag close impossible. `&` is
|
|
11
|
+
* escaped too so the payload is also safe inside HTML-escaping contexts, and
|
|
12
|
+
* U+2028/U+2029 because they are literal line terminators in JS source but
|
|
13
|
+
* legal unescaped inside a JSON string.
|
|
14
|
+
*/
|
|
15
|
+
declare function serializeForScriptTag(value: unknown): string;
|
|
16
|
+
|
|
17
|
+
export { serializeForScriptTag };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// src/core/json-script.ts
|
|
2
|
+
function serializeForScriptTag(value) {
|
|
3
|
+
return JSON.stringify(value ?? null).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
4
|
+
}
|
|
5
|
+
export {
|
|
6
|
+
serializeForScriptTag
|
|
7
|
+
};
|
|
@@ -169,7 +169,11 @@ function t(key, locale, vars) {
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
// src/core/utils.ts
|
|
172
|
-
|
|
172
|
+
var trustedParentOrigin = null;
|
|
173
|
+
function setTrustedParentOrigin(origin) {
|
|
174
|
+
trustedParentOrigin = origin;
|
|
175
|
+
}
|
|
176
|
+
function sendPreprEvent(event, data, options) {
|
|
173
177
|
if (typeof window !== "undefined") {
|
|
174
178
|
const message = {
|
|
175
179
|
name: "prepr_preview_bar",
|
|
@@ -180,7 +184,11 @@ function sendPreprEvent(event, data) {
|
|
|
180
184
|
new CustomEvent("prepr_preview_bar", { detail: message })
|
|
181
185
|
);
|
|
182
186
|
if (window.parent && window.parent !== window) {
|
|
183
|
-
|
|
187
|
+
if (trustedParentOrigin) {
|
|
188
|
+
window.parent.postMessage(message, trustedParentOrigin);
|
|
189
|
+
} else if (options?.allowUntrustedTarget) {
|
|
190
|
+
window.parent.postMessage(message, "*");
|
|
191
|
+
}
|
|
184
192
|
}
|
|
185
193
|
}
|
|
186
194
|
}
|
|
@@ -266,7 +274,23 @@ function createElementCache(query, ttl = 1e3) {
|
|
|
266
274
|
}
|
|
267
275
|
|
|
268
276
|
// src/core/iframe-bridge.ts
|
|
269
|
-
|
|
277
|
+
var EDITOR_BASE_DOMAIN = "prepr.io";
|
|
278
|
+
function isAllowedEditorOrigin(origin, allowed) {
|
|
279
|
+
if (allowed) return allowed.includes(origin);
|
|
280
|
+
let url;
|
|
281
|
+
try {
|
|
282
|
+
url = new URL(origin);
|
|
283
|
+
} catch {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
if (url.protocol !== "https:" || url.port !== "") return false;
|
|
287
|
+
const suffix = `.${EDITOR_BASE_DOMAIN}`;
|
|
288
|
+
if (!url.hostname.endsWith(suffix)) return false;
|
|
289
|
+
const label = url.hostname.slice(0, -suffix.length);
|
|
290
|
+
return label.length > 0 && !label.includes(".");
|
|
291
|
+
}
|
|
292
|
+
function createIframeBridge(store, options = {}) {
|
|
293
|
+
const allowedOrigins = options.allowedEditorOrigins;
|
|
270
294
|
let parentOrigin = null;
|
|
271
295
|
const onKeyDown = (event) => {
|
|
272
296
|
const key = event.key.toLowerCase();
|
|
@@ -276,14 +300,16 @@ function createIframeBridge(store) {
|
|
|
276
300
|
const onMessage = (evt) => {
|
|
277
301
|
const data = evt?.data;
|
|
278
302
|
if (data?.event === "prepr:initVE" && !parentOrigin) {
|
|
303
|
+
if (!isAllowedEditorOrigin(evt.origin, allowedOrigins)) return;
|
|
279
304
|
parentOrigin = evt.origin;
|
|
305
|
+
setTrustedParentOrigin(parentOrigin);
|
|
280
306
|
if (data.scrollPosition != null) {
|
|
281
307
|
const top = data.scrollPosition;
|
|
282
308
|
setTimeout(() => window.scrollTo(0, top), 1);
|
|
283
309
|
}
|
|
284
310
|
store.set({ previewMode: true, editMode: data.editMode ?? true });
|
|
285
311
|
}
|
|
286
|
-
if (evt.origin !== parentOrigin) return;
|
|
312
|
+
if (!parentOrigin || evt.origin !== parentOrigin) return;
|
|
287
313
|
if (data?.event === "prepr:getScrollPosition") {
|
|
288
314
|
const currentScrollY = window.scrollY || document.documentElement.scrollTop;
|
|
289
315
|
sendPreprEvent("getScrollPosition", { value: currentScrollY });
|
|
@@ -291,13 +317,15 @@ function createIframeBridge(store) {
|
|
|
291
317
|
};
|
|
292
318
|
return {
|
|
293
319
|
start() {
|
|
294
|
-
sendPreprEvent("loaded");
|
|
320
|
+
sendPreprEvent("loaded", void 0, { allowUntrustedTarget: true });
|
|
295
321
|
window.addEventListener("keydown", onKeyDown);
|
|
296
322
|
window.addEventListener("message", onMessage);
|
|
297
323
|
},
|
|
298
324
|
stop() {
|
|
299
325
|
window.removeEventListener("keydown", onKeyDown);
|
|
300
326
|
window.removeEventListener("message", onMessage);
|
|
327
|
+
parentOrigin = null;
|
|
328
|
+
setTrustedParentOrigin(null);
|
|
301
329
|
}
|
|
302
330
|
};
|
|
303
331
|
}
|
|
@@ -937,25 +965,28 @@ function cookieOpts() {
|
|
|
937
965
|
}
|
|
938
966
|
function createChangeHandler(deps) {
|
|
939
967
|
const { store, stega, syncAutoClean } = deps;
|
|
940
|
-
function
|
|
968
|
+
function updateParams(patch) {
|
|
941
969
|
const [path, existing] = splitPath(deps.currentPath());
|
|
942
970
|
const params = new URLSearchParams(existing);
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
971
|
+
for (const [name, value] of Object.entries(patch)) {
|
|
972
|
+
if (value === null) {
|
|
973
|
+
params.delete(name);
|
|
974
|
+
} else {
|
|
975
|
+
params.set(name, value);
|
|
976
|
+
}
|
|
947
977
|
}
|
|
948
978
|
const query = params.toString();
|
|
949
979
|
deps.navigate(query ? `${path}?${query}` : path);
|
|
950
980
|
}
|
|
951
981
|
return function handleChange(before, after) {
|
|
982
|
+
const paramPatch = {};
|
|
952
983
|
if (before.selectedSegment !== after.selectedSegment) {
|
|
953
984
|
if (after.selectedSegment === null) {
|
|
954
985
|
removeCookie(COOKIE_SEGMENT, "/", crossSiteCookieOptions());
|
|
955
986
|
} else {
|
|
956
987
|
setCookie(COOKIE_SEGMENT, after.selectedSegment, cookieOpts());
|
|
957
988
|
}
|
|
958
|
-
|
|
989
|
+
paramPatch[PARAM_SEGMENT] = after.selectedSegment;
|
|
959
990
|
sendPreprEvent("segment_changed", {
|
|
960
991
|
segment: after.selectedSegment ?? void 0
|
|
961
992
|
});
|
|
@@ -966,11 +997,14 @@ function createChangeHandler(deps) {
|
|
|
966
997
|
} else {
|
|
967
998
|
setCookie(COOKIE_VARIANT, after.selectedVariant, cookieOpts());
|
|
968
999
|
}
|
|
969
|
-
|
|
1000
|
+
paramPatch[PARAM_VARIANT] = after.selectedVariant;
|
|
970
1001
|
sendPreprEvent("variant_changed", {
|
|
971
1002
|
variant: after.selectedVariant ?? void 0
|
|
972
1003
|
});
|
|
973
1004
|
}
|
|
1005
|
+
if (Object.keys(paramPatch).length > 0) {
|
|
1006
|
+
updateParams(paramPatch);
|
|
1007
|
+
}
|
|
974
1008
|
if (before.editMode !== after.editMode) {
|
|
975
1009
|
if (after.editMode) {
|
|
976
1010
|
stega.start();
|
|
@@ -2076,7 +2110,9 @@ function createPreprToolbar(opts) {
|
|
|
2076
2110
|
});
|
|
2077
2111
|
syncAutoClean(store.get().previewMode);
|
|
2078
2112
|
const bridge = createIframeBridge(store);
|
|
2079
|
-
sendPreprEvent("getScrollPosition", { value: 0 }
|
|
2113
|
+
sendPreprEvent("getScrollPosition", { value: 0 }, {
|
|
2114
|
+
allowUntrustedTarget: true
|
|
2115
|
+
});
|
|
2080
2116
|
if (isIframe) {
|
|
2081
2117
|
bridge.start();
|
|
2082
2118
|
}
|
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.1.0-beta.
|
|
41
|
+
var VERSION = "0.1.0-beta.5";
|
|
42
42
|
|
|
43
43
|
// src/core/constants.ts
|
|
44
44
|
var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
|
package/dist/nextjs/index.js
CHANGED
package/dist/nuxt/index.cjs
CHANGED
package/dist/nuxt/index.js
CHANGED
package/dist/sveltekit/index.cjs
CHANGED
package/dist/sveltekit/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@preprio/toolkit",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.5",
|
|
4
4
|
"description": "Prepr personalization, A/B testing and preview toolkit for Next.js, Nuxt, Astro, SvelteKit and Express",
|
|
5
|
-
"license": "
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Prepr B.V. (https://prepr.io)",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"prepr",
|
|
9
|
+
"cms",
|
|
10
|
+
"headless-cms",
|
|
11
|
+
"personalization",
|
|
12
|
+
"ab-testing",
|
|
13
|
+
"preview",
|
|
14
|
+
"visual-editing",
|
|
15
|
+
"nextjs",
|
|
16
|
+
"nuxt",
|
|
17
|
+
"astro",
|
|
18
|
+
"sveltekit"
|
|
19
|
+
],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18.17"
|
|
25
|
+
},
|
|
6
26
|
"repository": {
|
|
7
27
|
"type": "git",
|
|
8
28
|
"url": "git+https://github.com/preprio/prepr-toolkit.git",
|
|
@@ -23,6 +43,16 @@
|
|
|
23
43
|
"import": "./dist/nextjs/index.js",
|
|
24
44
|
"require": "./dist/nextjs/index.cjs"
|
|
25
45
|
},
|
|
46
|
+
"./json-script": {
|
|
47
|
+
"types": "./dist/json-script.d.ts",
|
|
48
|
+
"import": "./dist/json-script.js",
|
|
49
|
+
"require": "./dist/json-script.cjs"
|
|
50
|
+
},
|
|
51
|
+
"./nextjs/components": {
|
|
52
|
+
"types": "./dist/nextjs/components.d.ts",
|
|
53
|
+
"import": "./dist/nextjs/components.js",
|
|
54
|
+
"require": "./dist/nextjs/components.cjs"
|
|
55
|
+
},
|
|
26
56
|
"./nextjs/image-loader": {
|
|
27
57
|
"types": "./dist/nextjs/image-loader.d.ts",
|
|
28
58
|
"import": "./dist/nextjs/image-loader.js",
|
|
@@ -53,6 +83,16 @@
|
|
|
53
83
|
"src/sveltekit/*.svelte",
|
|
54
84
|
"src/nuxt/*.vue"
|
|
55
85
|
],
|
|
86
|
+
"scripts": {
|
|
87
|
+
"gen:css": "node scripts/compile-css.mjs",
|
|
88
|
+
"prebuild": "rm -rf dist && pnpm gen:css && node scripts/check-version.mjs",
|
|
89
|
+
"pretest": "pnpm gen:css",
|
|
90
|
+
"pretypecheck": "pnpm gen:css",
|
|
91
|
+
"build": "tsup",
|
|
92
|
+
"postbuild": "node scripts/check-exports.mjs",
|
|
93
|
+
"test": "vitest run",
|
|
94
|
+
"typecheck": "tsc --noEmit"
|
|
95
|
+
},
|
|
56
96
|
"dependencies": {
|
|
57
97
|
"@vercel/stega": "^1.1.0",
|
|
58
98
|
"preact": "^10.29.7"
|
|
@@ -60,7 +100,9 @@
|
|
|
60
100
|
"peerDependencies": {
|
|
61
101
|
"next": ">=13",
|
|
62
102
|
"react": ">=17",
|
|
63
|
-
"react-dom": ">=17"
|
|
103
|
+
"react-dom": ">=17",
|
|
104
|
+
"svelte": ">=4",
|
|
105
|
+
"vue": ">=3"
|
|
64
106
|
},
|
|
65
107
|
"peerDependenciesMeta": {
|
|
66
108
|
"next": {
|
|
@@ -71,6 +113,12 @@
|
|
|
71
113
|
},
|
|
72
114
|
"react-dom": {
|
|
73
115
|
"optional": true
|
|
116
|
+
},
|
|
117
|
+
"svelte": {
|
|
118
|
+
"optional": true
|
|
119
|
+
},
|
|
120
|
+
"vue": {
|
|
121
|
+
"optional": true
|
|
74
122
|
}
|
|
75
123
|
},
|
|
76
124
|
"devDependencies": {
|
|
@@ -86,15 +134,5 @@
|
|
|
86
134
|
"tsup": "^8.5.1",
|
|
87
135
|
"typescript": "^5.9.3",
|
|
88
136
|
"vitest": "^4.1.10"
|
|
89
|
-
},
|
|
90
|
-
"scripts": {
|
|
91
|
-
"gen:css": "node scripts/compile-css.mjs",
|
|
92
|
-
"prebuild": "rm -rf dist && pnpm gen:css && node scripts/check-version.mjs",
|
|
93
|
-
"pretest": "pnpm gen:css",
|
|
94
|
-
"pretypecheck": "pnpm gen:css",
|
|
95
|
-
"build": "tsup",
|
|
96
|
-
"postbuild": "node scripts/check-exports.mjs",
|
|
97
|
-
"test": "vitest run",
|
|
98
|
-
"typecheck": "tsc --noEmit"
|
|
99
137
|
}
|
|
100
|
-
}
|
|
138
|
+
}
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* data shape of primitives/arrays.)
|
|
30
30
|
*/
|
|
31
31
|
import type { PreprToolbarProps } from '@preprio/toolkit';
|
|
32
|
+
import { serializeForScriptTag } from '@preprio/toolkit/json-script';
|
|
32
33
|
|
|
33
34
|
type Props = PreprToolbarProps;
|
|
34
35
|
|
|
@@ -40,7 +41,7 @@ const props = { activeSegment, activeVariant, segments: segments ?? data ?? [] }
|
|
|
40
41
|
<script
|
|
41
42
|
type="application/json"
|
|
42
43
|
data-prepr-toolbar-props
|
|
43
|
-
set:html={
|
|
44
|
+
set:html={serializeForScriptTag(props)}
|
|
44
45
|
/>
|
|
45
46
|
|
|
46
47
|
<script>
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* from '@preprio/toolkit'` would fail to resolve in the browser. See
|
|
15
15
|
* `PreprToolbar.astro` for the full explanation.
|
|
16
16
|
*/
|
|
17
|
+
import { serializeForScriptTag } from '@preprio/toolkit/json-script';
|
|
18
|
+
|
|
17
19
|
interface Props {
|
|
18
20
|
id: string;
|
|
19
21
|
config?: {
|
|
@@ -34,7 +36,7 @@ const payload = { id, config };
|
|
|
34
36
|
<script
|
|
35
37
|
type="application/json"
|
|
36
38
|
data-prepr-pixel-props
|
|
37
|
-
set:html={
|
|
39
|
+
set:html={serializeForScriptTag(payload)}
|
|
38
40
|
/>
|
|
39
41
|
|
|
40
42
|
<script>
|