@storyblok/react 3.0.10 → 3.0.12
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 +96 -19
- package/dist/bridge-loader.mjs +4 -4
- package/dist/index2.mjs +6 -6
- package/dist/storyblok-js.js +2 -2
- package/dist/storyblok-js.mjs +126 -121
- package/dist/types/common/index.d.ts +0 -1
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -30,11 +30,16 @@
|
|
|
30
30
|
</a>
|
|
31
31
|
</p>
|
|
32
32
|
|
|
33
|
-
##
|
|
33
|
+
## Kickstart a new project
|
|
34
|
+
Are you eager to dive into coding? **[Follow these steps to kickstart a new project with Storyblok and React](https://www.storyblok.com/technologies#react?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)**, and get started in just a few minutes!
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
## 5-minute Tutorial
|
|
37
|
+
Are you looking for a hands-on, step-by-step tutorial? The **[React 5-minute Tutorial](https://www.storyblok.com/tp/headless-cms-react?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)** has you covered! It provides comprehensive instructions on how to set up a Storyblok space and connect it to your React project.
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
## Ultimate Tutorial
|
|
40
|
+
Are you looking for a hands-on, step-by-step tutorial? The **[Next.js Ultimate Tutorial](https://www.storyblok.com/tp/nextjs-headless-cms-ultimate-tutorial?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)** has you covered! It provides comprehensive instructions on building a complete, multilingual website using Storyblok and Next.js from start to finish.
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
38
43
|
|
|
39
44
|
Install `@storyblok/react`:
|
|
40
45
|
|
|
@@ -45,7 +50,7 @@ npm install @storyblok/react
|
|
|
45
50
|
|
|
46
51
|
> ⚠️ This SDK uses the Fetch API under the hood. If your environment doesn't support it, you need to install a polyfill like [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch). More info on [storyblok-js-client docs](https://github.com/storyblok/storyblok-js-client#fetch-use-polyfill-if-needed---version-5).
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
### From a CDN
|
|
49
54
|
|
|
50
55
|
Install the file from the CDN:
|
|
51
56
|
|
|
@@ -53,7 +58,7 @@ Install the file from the CDN:
|
|
|
53
58
|
<script src="https://unpkg.com/@storyblok/react"></script>
|
|
54
59
|
```
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
## Initialization
|
|
57
62
|
|
|
58
63
|
Register the plugin on your application and add the [access token](https://www.storyblok.com/docs/api/content-delivery#topics/authentication?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react) of your Storyblok space. You can also add the `apiPlugin` in case that you want to use the Storyblok API Client:
|
|
59
64
|
|
|
@@ -88,7 +93,7 @@ That's it! All the features are enabled for you: the _Api Client_ for interactin
|
|
|
88
93
|
|
|
89
94
|
> You can enable/disable some of these features if you don't need them, so you save some KB. Please read the "Features and API" section
|
|
90
95
|
|
|
91
|
-
|
|
96
|
+
## Region parameter
|
|
92
97
|
|
|
93
98
|
Possible values:
|
|
94
99
|
|
|
@@ -144,13 +149,13 @@ Where `blok` is the actual blok data coming from [Storyblok's Content Delivery A
|
|
|
144
149
|
|
|
145
150
|
> Note: The `storyblokEditable` function works the same way for all the frameworks and components created.
|
|
146
151
|
|
|
147
|
-
|
|
152
|
+
## Getting Started
|
|
148
153
|
|
|
149
154
|
**This SDK provides you the support to work with React and all React Frameworks such as Next.js, Remix etc. Depending upon these different frameworks and versions, the way to use the SDK and the functionalities it provides differ.**
|
|
150
155
|
|
|
151
156
|
Below is the guide and examples on how to use it with different frameworks -
|
|
152
157
|
|
|
153
|
-
|
|
158
|
+
### React
|
|
154
159
|
|
|
155
160
|
The initalization remains the same when you work with React. You can intialze the SDK in the `index.js` file. Please refer to the 'Initialization' section above to read more.
|
|
156
161
|
|
|
@@ -193,6 +198,30 @@ useStoryblok(
|
|
|
193
198
|
**Check out our React Boilerplate [here](https://github.com/storyblok/storyblok-react-boilerplate), or read on how to add Storyblok to React in 5 mins [here](https://www.storyblok.com/tp/headless-cms-react)**
|
|
194
199
|
You can also take a look at the [React Playground](https://github.com/arorachakit/storyblok-react/tree/main/playground) in this repo.
|
|
195
200
|
|
|
201
|
+
### Learn: Next.js 13 and 14 Data Fetching and Caching Behavior
|
|
202
|
+
|
|
203
|
+
When using Next.js 13 or 14 with the App Router, ensure that you include `cache: "no-store"` in your requests when fetching data from Storyblok. This prevents data caching, ensuring that you always receive the most up-to-date content from Storyblok.
|
|
204
|
+
|
|
205
|
+
For more details, refer to the Next.js documentation on [opting out of caching](https://nextjs.org/docs/app/building-your-application/caching#opting-out-1).
|
|
206
|
+
|
|
207
|
+
> Note: In Next.js 15, this will no longer be necessary, as the default caching behavior has been adjusted based on [community feedback](https://nextjs.org/blog/next-15-rc#caching-updates).
|
|
208
|
+
|
|
209
|
+
#### Example
|
|
210
|
+
|
|
211
|
+
Here's how you can fetch data from Storyblok with `cache: "no-store"`:
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
export async function fetchData() {
|
|
215
|
+
let sbParams: ISbStoriesParams = { version: "draft" };
|
|
216
|
+
|
|
217
|
+
const storyblokApi: StoryblokClient = getStoryblokApi();
|
|
218
|
+
|
|
219
|
+
return storyblokApi.get(`cdn/stories/home`, sbParams, {
|
|
220
|
+
cache: "no-store", // This prevents Next.js 13, 14 default caching behaviour
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
196
225
|
## Next.js using App Router - Live Editing support
|
|
197
226
|
|
|
198
227
|
The components in the `app` directory are by default React Server Side Components, which limits the reactivity. You can enable Storyblok Visual Editor's live editing with React Server Components by rendering them inside a wrapper (`StoryblokPovider`) on the client. The SDK allows you to take full advantage of the Live Editing, but the use of Server Side Components is partial, which will be still better than the older Next.js approach performance-wise. The next section explains about how to use complete server side approach.
|
|
@@ -605,27 +634,75 @@ We also recommend using the [Storyblok Rich Text Renderer for React by Claus](ht
|
|
|
605
634
|
|
|
606
635
|
By default, `@storyblok/react` returns an empty `<div>` if a component is not implemented. Setting `enableFallbackComponent` to `true` when calling `storyblokInit` bypasses that behavior, rendering a fallback component in the frontend instead. You can use the default fallback component, or create a custom React fallback component in your project and use it by setting `customFallbackComponent: [YourFallbackComponent]`.
|
|
607
636
|
|
|
637
|
+
## Efficiently Loading Storyblok Components in React
|
|
638
|
+
|
|
639
|
+
When using Storyblok with React, the general approach is to load all the Storyblok components when initializing Storyblok, usually in a layout page to ensure all pages have access to all of them:
|
|
640
|
+
|
|
641
|
+
```javascript
|
|
642
|
+
storyblokInit({
|
|
643
|
+
accessToken,
|
|
644
|
+
use: [apiPlugin],
|
|
645
|
+
components: {
|
|
646
|
+
// all your React components
|
|
647
|
+
},
|
|
648
|
+
});
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
Storyblok's React SDK automatically renders these predefined components based on your page content. While this is convenient, it can lead to larger bundle sizes and slower page speeds, especially for larger sites or when using heavy JavaScript libraries that are only needed on specific pages or a specific component.
|
|
652
|
+
|
|
653
|
+
### Solutions
|
|
654
|
+
|
|
655
|
+
1. **Storyblok's `setComponents` Function**:
|
|
656
|
+
Storyblok SDK provides a function called `setComponents` that allows you to load only the components needed for each route instead of defining all components during initialization. This approach is useful but might not be practical if you use a catch-all route, which is common in many React frameworks.
|
|
657
|
+
|
|
658
|
+
2. **React's `react.lazy`**:
|
|
659
|
+
React offers a built-in solution called `react.lazy` for code splitting. Instead of directly importing components, you can do the following:
|
|
660
|
+
|
|
661
|
+
```javascript
|
|
662
|
+
"use client";
|
|
663
|
+
import { storyblokInit, apiPlugin } from "@storyblok/react/rsc";
|
|
664
|
+
import { lazy } from "react";
|
|
665
|
+
|
|
666
|
+
const lazyComponents = {
|
|
667
|
+
page: lazy(() => import("./components/Page")),
|
|
668
|
+
// other lazy-loaded components
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
storyblokInit({
|
|
672
|
+
accessToken,
|
|
673
|
+
use: [apiPlugin],
|
|
674
|
+
components: lazyComponents,
|
|
675
|
+
});
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
This approach enables automatic code splitting and loads only the necessary JavaScript for each page. However, `react.lazy` has some limitations when used with SSR (Server-Side Rendering).
|
|
679
|
+
|
|
680
|
+
3. **Using `@loadable/component`**:
|
|
681
|
+
For cases where SSR is needed, or in general, you can use the `@loadable/component` library, which offers similar functionality and better SSR support. This library is framework-agnostic and can be used with any React framework. [Loadable Components Documentation](https://loadable-components.com/docs/getting-started/)
|
|
682
|
+
|
|
683
|
+
4. **Next.js Dynamic Import**:
|
|
684
|
+
Next.js has a built-in `dynamic` package that provides dynamic imports for lazy loading. [Next.js Dynamic Import Documentation](https://nextjs.org/docs/advanced-features/dynamic-import)
|
|
685
|
+
|
|
686
|
+
By using these techniques, you can ensure that only the necessary components and dependencies are loaded for each page, improving your site's performance and speed.
|
|
687
|
+
|
|
608
688
|
## The Storyblok JavaScript SDK Ecosystem
|
|
609
689
|
|
|
610
690
|

|
|
611
691
|
|
|
612
|
-
##
|
|
613
|
-
|
|
614
|
-
- **[Storyblok Technology Hub](https://www.storyblok.com/technologies?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)**: Storyblok integrates with every framework so that you are free to choose the best fit for your project. We prepared the technology hub so that you can find selected beginner tutorials, videos, boilerplates, and even cheatsheets all in one place.
|
|
615
|
-
- **[Getting Started](https://www.storyblok.com/docs/guide/getting-started?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)**: Get a project ready in less than 5 minutes.
|
|
616
|
-
- **[Storyblok CLI](https://github.com/storyblok/storyblok)**: A simple CLI for scaffolding Storyblok projects and fieldtypes.
|
|
617
|
-
- **[Storyblok Next.js Technology Hub](https://www.storyblok.com/tc/nextjs)**: Learn how to develop your own Next.js applications that use Storyblok APIs to retrieve and manage content.
|
|
618
|
-
- **[Storyblok React.js example demo](https://stackblitz.com/edit/react-sdk-demo)**: See and try how React SDK works with React.js projects
|
|
619
|
-
- **[Storyblok Next.js example demo](https://stackblitz.com/edit/react-next-sdk-demo)**: See and try how React SDK works with Next.js projects
|
|
692
|
+
## Further Resources
|
|
620
693
|
|
|
621
|
-
|
|
694
|
+
- [Quick Start](https://www.storyblok.com/technologies?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)
|
|
695
|
+
- [API Documentation](https://www.storyblok.com/docs/api?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)
|
|
696
|
+
- [Developer Tutorials](https://www.storyblok.com/tutorials?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)
|
|
697
|
+
- [Developer Guides](https://www.storyblok.com/docs/guide/introduction?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)
|
|
698
|
+
- [FAQs](https://www.storyblok.com/faqs?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react)
|
|
622
699
|
|
|
623
|
-
|
|
700
|
+
## Support
|
|
624
701
|
|
|
625
702
|
- Bugs or Feature Requests? [Submit an issue](/../../issues/new).
|
|
626
703
|
- Do you have questions about Storyblok or you need help? [Join our Discord Community](https://discord.gg/jKrbAMz).
|
|
627
704
|
|
|
628
|
-
|
|
705
|
+
## Contributing
|
|
629
706
|
|
|
630
707
|
Please see our [contributing guidelines](https://github.com/storyblok/.github/blob/master/contributing.md) and our [code of conduct](https://www.storyblok.com/trust-center#code-of-conduct?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react).
|
|
631
708
|
This project use [semantic-release](https://semantic-release.gitbook.io/semantic-release/) for generate new versions by using commit messages and we use the Angular Convention to naming the commits. Check [this question](https://semantic-release.gitbook.io/semantic-release/support/faq#how-can-i-change-the-type-of-commits-that-trigger-a-release) about it in semantic-release FAQ.
|
package/dist/bridge-loader.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import
|
|
2
|
+
import o from "react";
|
|
3
3
|
import { loadStoryblokBridge as r } from "./storyblok-js.mjs";
|
|
4
|
-
const t = async (
|
|
5
|
-
await r(), new window.StoryblokBridge(
|
|
4
|
+
const t = async (e) => {
|
|
5
|
+
await r(), new window.StoryblokBridge(e).on(["published", "change"], () => {
|
|
6
6
|
window.location.reload();
|
|
7
7
|
});
|
|
8
|
-
}, i = ({ options:
|
|
8
|
+
}, i = ({ options: e }) => (t(e), /* @__PURE__ */ o.createElement(o.Fragment, null));
|
|
9
9
|
export {
|
|
10
10
|
i as default
|
|
11
11
|
};
|
package/dist/index2.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { storyblokInit as s } from "./storyblok-js.mjs";
|
|
2
|
-
import { RichTextResolver as
|
|
2
|
+
import { RichTextResolver as g, RichTextSchema as C, apiPlugin as d, loadStoryblokBridge as f, registerStoryblokBridge as S, renderRichText as x, storyblokEditable as F, registerStoryblokBridge as A } from "./storyblok-js.mjs";
|
|
3
3
|
import { default as B } from "./storyblok-component.mjs";
|
|
4
|
-
let
|
|
5
|
-
const b = () => (
|
|
4
|
+
let t = null, e = {}, r = !1, l = null;
|
|
5
|
+
const b = () => (t || console.error(
|
|
6
6
|
"You can't use getStoryblokApi if you're not loading apiPlugin."
|
|
7
|
-
),
|
|
7
|
+
), t), c = (o) => (e = o, e), i = (o) => e[o] ? e[o] : (console.error(`Component ${o} doesn't exist.`), !1), k = () => r, m = () => l, p = (o = {}) => {
|
|
8
8
|
const { storyblokApi: n } = s(o);
|
|
9
|
-
|
|
9
|
+
t = n, e = o.components, r = o.enableFallbackComponent, l = o.customFallbackComponent;
|
|
10
10
|
};
|
|
11
11
|
export {
|
|
12
|
-
|
|
12
|
+
g as RichTextResolver,
|
|
13
13
|
C as RichTextSchema,
|
|
14
14
|
B as StoryblokComponent,
|
|
15
15
|
d as apiPlugin,
|
package/dist/storyblok-js.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let _=!1;const j=[],O=n=>new Promise((e,t)=>{if(typeof window>"u"||(window.storyblokRegisterEvent=r=>{if(window.location===window.parent.location){console.warn("You are not in Draft Mode or in the Visual Editor.");return}_?r():j.push(r)},document.getElementById("storyblok-javascript-bridge")))return;const s=document.createElement("script");s.async=!0,s.src=n,s.id="storyblok-javascript-bridge",s.onerror=r=>t(r),s.onload=r=>{j.forEach(i=>i()),_=!0,e(r)},document.getElementsByTagName("head")[0].appendChild(s)});var A=Object.defineProperty,N=(n,e,t)=>e in n?A(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let _=!1;const j=[],O=n=>new Promise((e,t)=>{if(typeof window>"u"||(window.storyblokRegisterEvent=r=>{if(window.location===window.parent.location){console.warn("You are not in Draft Mode or in the Visual Editor.");return}_?r():j.push(r)},document.getElementById("storyblok-javascript-bridge")))return;const s=document.createElement("script");s.async=!0,s.src=n,s.id="storyblok-javascript-bridge",s.onerror=r=>t(r),s.onload=r=>{j.forEach(i=>i()),_=!0,e(r)},document.getElementsByTagName("head")[0].appendChild(s)});var A=Object.defineProperty,N=(n,e,t)=>e in n?A(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,c=(n,e,t)=>N(n,typeof e!="symbol"?e+"":e,t);function S(n){return!(n!==n||n===1/0||n===-1/0)}function L(n,e,t){if(!S(e))throw new TypeError("Expected `limit` to be a finite number");if(!S(t))throw new TypeError("Expected `interval` to be a finite number");const s=[];let r=[],i=0;const o=function(){i++;const a=setTimeout(function(){i--,s.length>0&&o(),r=r.filter(function(h){return h!==a})},t);r.indexOf(a)<0&&r.push(a);const u=s.shift();u.resolve(n.apply(u.self,u.args))},l=function(...a){const u=this;return new Promise(function(h,p){s.push({resolve:h,reject:p,args:a,self:u}),i<e&&o()})};return l.abort=function(){r.forEach(clearTimeout),r=[],s.forEach(function(a){a.reject(function(){Error.call(this,"Throttled function aborted"),this.name="AbortError"})}),s.length=0},l}class v{constructor(){c(this,"isCDNUrl",(e="")=>e.indexOf("/cdn/")>-1),c(this,"getOptionsPage",(e,t=25,s=1)=>({...e,per_page:t,page:s})),c(this,"delay",e=>new Promise(t=>setTimeout(t,e))),c(this,"arrayFrom",(e=0,t)=>[...Array(e)].map(t)),c(this,"range",(e=0,t=e)=>{const s=Math.abs(t-e)||0,r=e<t?1:-1;return this.arrayFrom(s,(i,o)=>o*r+e)}),c(this,"asyncMap",async(e,t)=>Promise.all(e.map(t))),c(this,"flatMap",(e=[],t)=>e.map(t).reduce((s,r)=>[...s,...r],[])),c(this,"escapeHTML",function(e){const t={"&":"&","<":"<",">":">",'"':""","'":"'"},s=/[&<>"']/g,r=RegExp(s.source);return e&&r.test(e)?e.replace(s,i=>t[i]):e})}stringify(e,t,s){const r=[];for(const i in e){if(!Object.prototype.hasOwnProperty.call(e,i))continue;const o=e[i],l=s?"":encodeURIComponent(i);let a;typeof o=="object"?a=this.stringify(o,t?t+encodeURIComponent("["+l+"]"):l,Array.isArray(o)):a=(t?t+encodeURIComponent("["+l+"]"):l)+"="+encodeURIComponent(o),r.push(a)}return r.join("&")}getRegionURL(e){const t="api.storyblok.com",s="api-us.storyblok.com",r="app.storyblokchina.cn",i="api-ap.storyblok.com",o="api-ca.storyblok.com";switch(e){case"us":return s;case"cn":return r;case"ap":return i;case"ca":return o;default:return t}}}const M=function(n,e){const t={};for(const s in n){const r=n[s];e.indexOf(s)>-1&&r!==null&&(t[s]=r)}return t},z=n=>n==="email",U=()=>({singleTag:"hr"}),H=()=>({tag:"blockquote"}),q=()=>({tag:"ul"}),V=n=>({tag:["pre",{tag:"code",attrs:n.attrs}]}),B=()=>({singleTag:"br"}),D=n=>({tag:`h${n.attrs.level}`}),J=n=>({singleTag:[{tag:"img",attrs:M(n.attrs,["src","alt","title"])}]}),F=()=>({tag:"li"}),Y=()=>({tag:"ol"}),K=()=>({tag:"p"}),W=n=>({tag:[{tag:"span",attrs:{"data-type":"emoji","data-name":n.attrs.name,emoji:n.attrs.emoji}}]}),G=()=>({tag:"b"}),Q=()=>({tag:"s"}),X=()=>({tag:"u"}),Z=()=>({tag:"strong"}),ee=()=>({tag:"code"}),te=()=>({tag:"i"}),se=n=>{if(!n.attrs)return{tag:""};const e=new v().escapeHTML,t={...n.attrs},{linktype:s="url"}=n.attrs;if(delete t.linktype,t.href&&(t.href=e(n.attrs.href||"")),z(s)&&(t.href=`mailto:${t.href}`),t.anchor&&(t.href=`${t.href}#${t.anchor}`,delete t.anchor),t.custom){for(const r in t.custom)t[r]=t.custom[r];delete t.custom}return{tag:[{tag:"a",attrs:t}]}},re=n=>({tag:[{tag:"span",attrs:n.attrs}]}),ie=()=>({tag:"sub"}),oe=()=>({tag:"sup"}),ne=n=>({tag:[{tag:"span",attrs:n.attrs}]}),ae=n=>{var e;return(e=n.attrs)!=null&&e.color?{tag:[{tag:"span",attrs:{style:`background-color:${n.attrs.color};`}}]}:{tag:""}},le=n=>{var e;return(e=n.attrs)!=null&&e.color?{tag:[{tag:"span",attrs:{style:`color:${n.attrs.color}`}}]}:{tag:""}},P={nodes:{horizontal_rule:U,blockquote:H,bullet_list:q,code_block:V,hard_break:B,heading:D,image:J,list_item:F,ordered_list:Y,paragraph:K,emoji:W},marks:{bold:G,strike:Q,underline:X,strong:Z,code:ee,italic:te,link:se,styled:re,subscript:ie,superscript:oe,anchor:ne,highlight:ae,textStyle:le}},ce=function(n){const e={"&":"&","<":"<",">":">",'"':""","'":"'"},t=/[&<>"']/g,s=RegExp(t.source);return n&&s.test(n)?n.replace(t,r=>e[r]):n};class he{constructor(e){c(this,"marks"),c(this,"nodes"),e||(e=P),this.marks=e.marks||[],this.nodes=e.nodes||[]}addNode(e,t){this.nodes[e]=t}addMark(e,t){this.marks[e]=t}render(e,t={optimizeImages:!1}){if(e&&e.content&&Array.isArray(e.content)){let s="";return e.content.forEach(r=>{s+=this.renderNode(r)}),t.optimizeImages?this.optimizeImages(s,t.optimizeImages):s}return console.warn(`The render method must receive an Object with a "content" field.
|
|
2
2
|
The "content" field must be an array of nodes as the type ISbRichtext.
|
|
3
3
|
ISbRichtext:
|
|
4
4
|
content?: ISbRichtext[]
|
|
@@ -21,4 +21,4 @@
|
|
|
21
21
|
}
|
|
22
22
|
],
|
|
23
23
|
type: 'doc'
|
|
24
|
-
}`),""}optimizeImages(e,t){let s=0,r=0,i="",o="";typeof t!="boolean"&&(typeof t.width=="number"&&t.width>0&&(i+=`width="${t.width}" `,s=t.width),typeof t.height=="number"&&t.height>0&&(i+=`height="${t.height}" `,r=t.height),(t.loading==="lazy"||t.loading==="eager")&&(i+=`loading="${t.loading}" `),typeof t.class=="string"&&t.class.length>0&&(i+=`class="${t.class}" `),t.filters&&(typeof t.filters.blur=="number"&&t.filters.blur>=0&&t.filters.blur<=100&&(o+=`:blur(${t.filters.blur})`),typeof t.filters.brightness=="number"&&t.filters.brightness>=-100&&t.filters.brightness<=100&&(o+=`:brightness(${t.filters.brightness})`),t.filters.fill&&(t.filters.fill.match(/[0-9A-Fa-f]{6}/g)||t.filters.fill==="transparent")&&(o+=`:fill(${t.filters.fill})`),t.filters.format&&["webp","png","jpeg"].includes(t.filters.format)&&(o+=`:format(${t.filters.format})`),typeof t.filters.grayscale=="boolean"&&t.filters.grayscale&&(o+=":grayscale()"),typeof t.filters.quality=="number"&&t.filters.quality>=0&&t.filters.quality<=100&&(o+=`:quality(${t.filters.quality})`),t.filters.rotate&&[90,180,270].includes(t.filters.rotate)&&(o+=`:rotate(${t.filters.rotate})`),o.length>0&&(o="/filters"+o))),i.length>0&&(e=e.replace(/<img/g,`<img ${i.trim()}`));const l=s>0||r>0||o.length>0?`${s}x${r}${o}`:"";return e=e.replace(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g,`a.storyblok.com/f/$1/$2.$3/m/${l}`),typeof t!="boolean"&&(t.sizes||t.srcset)&&(e=e.replace(/<img.*?src=["|'](.*?)["|']/g,a=>{var c,u;const p=a.match(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g);if(p&&p.length>0){const d={srcset:(c=t.srcset)==null?void 0:c.map(g=>{if(typeof g=="number")return`//${p}/m/${g}x0${o} ${g}w`;if(typeof g=="object"&&g.length===2){let k=0,T=0;return typeof g[0]=="number"&&(k=g[0]),typeof g[1]=="number"&&(T=g[1]),`//${p}/m/${k}x${T}${o} ${k}w`}}).join(", "),sizes:(u=t.sizes)==null?void 0:u.map(g=>g).join(", ")};let f="";return d.srcset&&(f+=`srcset="${d.srcset}" `),d.sizes&&(f+=`sizes="${d.sizes}" `),a.replace(/<img/g,`<img ${f.trim()}`)}return a})),e}renderNode(e){const t=[];e.marks&&e.marks.forEach(r=>{const i=this.getMatchingMark(r);i&&i.tag!==""&&t.push(this.renderOpeningTag(i.tag))});const s=this.getMatchingNode(e);return s&&s.tag&&t.push(this.renderOpeningTag(s.tag)),e.content?e.content.forEach(r=>{t.push(this.renderNode(r))}):e.text?t.push(ce(e.text)):s&&s.singleTag?t.push(this.renderTag(s.singleTag," /")):s&&s.html?t.push(s.html):e.type==="emoji"&&t.push(this.renderEmoji(e)),s&&s.tag&&t.push(this.renderClosingTag(s.tag)),e.marks&&e.marks.slice(0).reverse().forEach(r=>{const i=this.getMatchingMark(r);i&&i.tag!==""&&t.push(this.renderClosingTag(i.tag))}),t.join("")}renderTag(e,t){return e.constructor===String?`<${e}${t}>`:e.map(s=>{if(s.constructor===String)return`<${s}${t}>`;{let r=`<${s.tag}`;if(s.attrs)for(const i in s.attrs){const o=s.attrs[i];o!==null&&(r+=` ${i}="${o}"`)}return`${r}${t}>`}}).join("")}renderOpeningTag(e){return this.renderTag(e,"")}renderClosingTag(e){return e.constructor===String?`</${e}>`:e.slice(0).reverse().map(t=>t.constructor===String?`</${t}>`:`</${t.tag}>`).join("")}getMatchingNode(e){const t=this.nodes[e.type];if(typeof t=="function")return t(e)}getMatchingMark(e){const t=this.marks[e.type];if(typeof t=="function")return t(e)}renderEmoji(e){if(e.attrs.emoji)return e.attrs.emoji;const t=[{tag:"img",attrs:{src:e.attrs.fallbackImage,draggable:"false",loading:"lazy",align:"absmiddle"}}];return this.renderTag(t," /")}}class he{constructor(e){h(this,"baseURL"),h(this,"timeout"),h(this,"headers"),h(this,"responseInterceptor"),h(this,"fetch"),h(this,"ejectInterceptor"),h(this,"url"),h(this,"parameters"),h(this,"fetchOptions"),this.baseURL=e.baseURL,this.headers=e.headers||new Headers,this.timeout=e!=null&&e.timeout?e.timeout*1e3:0,this.responseInterceptor=e.responseInterceptor,this.fetch=(...t)=>e.fetch?e.fetch(...t):fetch(...t),this.ejectInterceptor=!1,this.url="",this.parameters={},this.fetchOptions={}}get(e,t){return this.url=e,this.parameters=t,this._methodHandler("get")}post(e,t){return this.url=e,this.parameters=t,this._methodHandler("post")}put(e,t){return this.url=e,this.parameters=t,this._methodHandler("put")}delete(e,t){return this.url=e,this.parameters=t,this._methodHandler("delete")}async _responseHandler(e){const t=[],s={data:{},headers:{},status:0,statusText:""};e.status!==204&&await e.json().then(r=>{s.data=r});for(const r of e.headers.entries())t[r[0]]=r[1];return s.headers={...t},s.status=e.status,s.statusText=e.statusText,s}async _methodHandler(e){let t=`${this.baseURL}${this.url}`,s=null;if(e==="get"){const a=new v;t=`${this.baseURL}${this.url}?${a.stringify(this.parameters)}`}else s=JSON.stringify(this.parameters);const r=new URL(t),i=new AbortController,{signal:o}=i;let l;this.timeout&&(l=setTimeout(()=>i.abort(),this.timeout));try{const a=await this.fetch(`${r}`,{method:e,headers:this.headers,body:s,signal:o,...this.fetchOptions});this.timeout&&clearTimeout(l);const c=await this._responseHandler(a);return this.responseInterceptor&&!this.ejectInterceptor?this._statusHandler(this.responseInterceptor(c)):this._statusHandler(c)}catch(a){return{message:a}}}setFetchOptions(e={}){Object.keys(e).length>0&&"method"in e&&delete e.method,this.fetchOptions={...e}}eject(){this.ejectInterceptor=!0}_statusHandler(e){const t=/20[0-6]/g;return new Promise((s,r)=>{if(t.test(`${e.status}`))return s(e);const i={message:e.statusText,status:e.status,response:Array.isArray(e.data)?e.data[0]:e.data.error||e.data.slug};r(i)})}}const x="SB-Agent",w={defaultAgentName:"SB-JS-CLIENT",defaultAgentVersion:"SB-Agent-Version",packageVersion:"6.0.0"};let b={};const m={};class ue{constructor(e,t){h(this,"client"),h(this,"maxRetries"),h(this,"throttle"),h(this,"accessToken"),h(this,"cache"),h(this,"helpers"),h(this,"resolveCounter"),h(this,"relations"),h(this,"links"),h(this,"richTextResolver"),h(this,"resolveNestedRelations"),h(this,"stringifiedStoriesCache");let s=e.endpoint||t;if(!s){const o=new v().getRegionURL,l=e.https===!1?"http":"https";e.oauthToken?s=`${l}://${o(e.region)}/v1`:s=`${l}://${o(e.region)}/v2`}const r=new Headers;if(r.set("Content-Type","application/json"),r.set("Accept","application/json"),e.headers)for(const o in e.headers)r.set(o,e.headers[o]);r.has(x)||(r.set(x,w.defaultAgentName),r.set(w.defaultAgentVersion,w.packageVersion));let i=5;e.oauthToken&&(r.set("Authorization",e.oauthToken),i=3),e.rateLimit&&(i=e.rateLimit),e.richTextSchema?this.richTextResolver=new y(e.richTextSchema):this.richTextResolver=new y,e.componentResolver&&this.setComponentResolver(e.componentResolver),this.maxRetries=e.maxRetries||5,this.throttle=L(this.throttledRequest,i,1e3),this.accessToken=e.accessToken||"",this.relations={},this.links={},this.cache=e.cache||{clear:"manual"},this.helpers=new v,this.resolveCounter=0,this.resolveNestedRelations=e.resolveNestedRelations||!0,this.stringifiedStoriesCache={},this.client=new he({baseURL:s,timeout:e.timeout||0,headers:r,responseInterceptor:e.responseInterceptor,fetch:e.fetch})}setComponentResolver(e){this.richTextResolver.addNode("blok",t=>{let s="";return t.attrs.body&&t.attrs.body.forEach(r=>{s+=e(r.component,r)}),{html:s}})}parseParams(e){return e.token||(e.token=this.getToken()),e.cv||(e.cv=m[e.token]),Array.isArray(e.resolve_relations)&&(e.resolve_relations=e.resolve_relations.join(",")),typeof e.resolve_relations<"u"&&(e.resolve_level=2),e}factoryParamOptions(e,t){return this.helpers.isCDNUrl(e)?this.parseParams(t):t}makeRequest(e,t,s,r){const i=this.factoryParamOptions(e,this.helpers.getOptionsPage(t,s,r));return this.cacheResponse(e,i)}get(e,t,s){t||(t={});const r=`/${e}`,i=this.factoryParamOptions(r,t);return this.client.setFetchOptions(s),this.cacheResponse(r,i)}async getAll(e,t,s,r){const i=(t==null?void 0:t.per_page)||25,o=`/${e}`,l=o.split("/"),a=s||l[l.length-1],c=1,u=await this.makeRequest(o,t,i,c),p=u.total?Math.ceil(u.total/i):1;this.client.setFetchOptions(r);const d=await this.helpers.asyncMap(this.helpers.range(c,p),f=>this.makeRequest(o,t,i,f+1));return this.helpers.flatMap([u,...d],f=>Object.values(f.data[a]))}post(e,t,s){const r=`/${e}`;return this.client.setFetchOptions(s),Promise.resolve(this.throttle("post",r,t))}put(e,t,s){const r=`/${e}`;return this.client.setFetchOptions(s),Promise.resolve(this.throttle("put",r,t))}delete(e,t,s){const r=`/${e}`;return this.client.setFetchOptions(s),Promise.resolve(this.throttle("delete",r,t))}getStories(e,t){return this.client.setFetchOptions(t),this._addResolveLevel(e),this.get("cdn/stories",e)}getStory(e,t,s){return this.client.setFetchOptions(s),this._addResolveLevel(t),this.get(`cdn/stories/${e}`,t)}getToken(){return this.accessToken}ejectInterceptor(){this.client.eject()}_addResolveLevel(e){typeof e.resolve_relations<"u"&&(e.resolve_level=2)}_cleanCopy(e){return JSON.parse(JSON.stringify(e))}_insertLinks(e,t,s){const r=e[t];r&&r.fieldtype=="multilink"&&r.linktype=="story"&&typeof r.id=="string"&&this.links[s][r.id]?r.story=this._cleanCopy(this.links[s][r.id]):r&&r.linktype==="story"&&typeof r.uuid=="string"&&this.links[s][r.uuid]&&(r.story=this._cleanCopy(this.links[s][r.uuid]))}getStoryReference(e,t){return this.relations[e][t]?(this.stringifiedStoriesCache[t]||(this.stringifiedStoriesCache[t]=JSON.stringify(this.relations[e][t])),JSON.parse(this.stringifiedStoriesCache[t])):t}_insertRelations(e,t,s,r){s.indexOf(`${e.component}.${t}`)>-1&&(typeof e[t]=="string"?e[t]=this.getStoryReference(r,e[t]):Array.isArray(e[t])&&(e[t]=e[t].map(i=>this.getStoryReference(r,i)).filter(Boolean)))}iterateTree(e,t,s){const r=i=>{if(i!=null){if(i.constructor===Array)for(let o=0;o<i.length;o++)r(i[o]);else if(i.constructor===Object){if(i._stopResolving)return;for(const o in i)(i.component&&i._uid||i.type==="link")&&(this._insertRelations(i,o,t,s),this._insertLinks(i,o,s)),r(i[o])}}};r(e.content)}async resolveLinks(e,t,s){let r=[];if(e.link_uuids){const i=e.link_uuids.length,o=[],l=50;for(let a=0;a<i;a+=l){const c=Math.min(i,a+l);o.push(e.link_uuids.slice(a,c))}for(let a=0;a<o.length;a++)(await this.getStories({per_page:l,language:t.language,version:t.version,by_uuids:o[a].join(",")})).data.stories.forEach(c=>{r.push(c)})}else r=e.links;r.forEach(i=>{this.links[s][i.uuid]={...i,_stopResolving:!0}})}async resolveRelations(e,t,s){let r=[];if(e.rel_uuids){const i=e.rel_uuids.length,o=[],l=50;for(let a=0;a<i;a+=l){const c=Math.min(i,a+l);o.push(e.rel_uuids.slice(a,c))}for(let a=0;a<o.length;a++)(await this.getStories({per_page:l,language:t.language,version:t.version,by_uuids:o[a].join(","),excluding_fields:t.excluding_fields})).data.stories.forEach(c=>{r.push(c)})}else r=e.rels;r&&r.length>0&&r.forEach(i=>{this.relations[s][i.uuid]={...i,_stopResolving:!0}})}async resolveStories(e,t,s){var r,i;let o=[];if(this.links[s]={},this.relations[s]={},typeof t.resolve_relations<"u"&&t.resolve_relations.length>0&&(typeof t.resolve_relations=="string"&&(o=t.resolve_relations.split(",")),await this.resolveRelations(e,t,s)),t.resolve_links&&["1","story","url","link"].indexOf(t.resolve_links)>-1&&((r=e.links)!=null&&r.length||(i=e.link_uuids)!=null&&i.length)&&await this.resolveLinks(e,t,s),this.resolveNestedRelations)for(const l in this.relations[s])this.iterateTree(this.relations[s][l],o,s);e.story?this.iterateTree(e.story,o,s):e.stories.forEach(l=>{this.iterateTree(l,o,s)}),this.stringifiedStoriesCache={},delete this.links[s],delete this.relations[s]}async cacheResponse(e,t,s){(typeof s>"u"||!s)&&(s=0);const r=this.helpers.stringify({url:e,params:t}),i=this.cacheProvider();if(this.cache.clear==="auto"&&t.version==="draft"&&await this.flushCache(),t.version==="published"&&e!="/cdn/spaces/me"){const o=await i.get(r);if(o)return Promise.resolve(o)}return new Promise(async(o,l)=>{var a;try{const c=await this.throttle("get",e,t);if(c.status!==200)return l(c);let u={data:c.data,headers:c.headers};if((a=c.headers)!=null&&a["per-page"]&&(u=Object.assign({},u,{perPage:c.headers["per-page"]?parseInt(c.headers["per-page"]):0,total:c.headers["per-page"]?parseInt(c.headers.total):0})),u.data.story||u.data.stories){const p=this.resolveCounter=++this.resolveCounter%1e3;await this.resolveStories(u.data,t,`${p}`)}return t.version==="published"&&e!="/cdn/spaces/me"&&await i.set(r,u),u.data.cv&&t.token&&(t.version==="draft"&&m[t.token]!=u.data.cv&&await this.flushCache(),m[t.token]=t.cv?t.cv:u.data.cv),o(u)}catch(c){if(c.response&&c.status===429&&(s=s?s+1:0,s<this.maxRetries))return console.log(`Hit rate limit. Retrying in ${s} seconds.`),await this.helpers.delay(1e3*s),this.cacheResponse(e,t,s).then(o).catch(l);l(c)}})}throttledRequest(e,t,s){return this.client[e](t,s)}cacheVersions(){return m}cacheVersion(){return m[this.accessToken]}setCacheVersion(e){this.accessToken&&(m[this.accessToken]=e)}clearCacheVersion(){this.accessToken&&(m[this.accessToken]=0)}cacheProvider(){switch(this.cache.type){case"memory":return{get(e){return Promise.resolve(b[e])},getAll(){return Promise.resolve(b)},set(e,t){return b[e]=t,Promise.resolve(void 0)},flush(){return b={},Promise.resolve(void 0)}};case"custom":if(this.cache.custom)return this.cache.custom;default:return{get(){return Promise.resolve()},getAll(){return Promise.resolve(void 0)},set(){return Promise.resolve(void 0)},flush(){return Promise.resolve(void 0)}}}}async flushCache(){return await this.cacheProvider().flush(),this.clearCacheVersion(),this}}const pe=(n={})=>{const{apiOptions:e}=n;if(!e.accessToken){console.error("You need to provide an access token to interact with Storyblok API. Read https://www.storyblok.com/docs/api/content-delivery#topics/authentication");return}return{storyblokApi:new ue(e)}},ge=n=>{if(typeof n!="object"||typeof n._editable>"u")return{};try{const e=JSON.parse(n._editable.replace(/^<!--#storyblok#/,"").replace(/-->$/,""));return e?{"data-blok-c":JSON.stringify(e),"data-blok-uid":e.id+"-"+e.uid}:{}}catch{return{}}};let R,$="https://app.storyblok.com/f/storyblok-v2-latest.js";const E=(n,e,t={})=>{var s;const r=!(typeof window>"u")&&typeof window.storyblokRegisterEvent<"u",i=+new URL((s=window.location)==null?void 0:s.href).searchParams.get("_storyblok")===n;if(!(!r||!i)){if(!n){console.warn("Story ID is not defined. Please provide a valid ID.");return}window.storyblokRegisterEvent(()=>{new window.StoryblokBridge(t).on(["input","published","change"],o=>{o.action==="input"&&o.story.id===n?e(o.story):(o.action==="change"||o.action==="published")&&o.storyId===n&&window.location.reload()})})}},de=(n={})=>{var e,t;const{bridge:s,accessToken:r,use:i=[],apiOptions:o={},richText:l={},bridgeUrl:a}=n;o.accessToken=o.accessToken||r;const c={bridge:s,apiOptions:o};let u={};i.forEach(d=>{u={...u,...d(c)}}),a&&($=a);const p=!(typeof window>"u")&&((t=(e=window.location)==null?void 0:e.search)==null?void 0:t.includes("_storyblok_tk"));return s!==!1&&p&&O($),R=new y(l.schema),l.resolver&&I(R,l.resolver),u},I=(n,e)=>{n.addNode("blok",t=>{let s="";return t.attrs.body.forEach(r=>{s+=e(r.component,r)}),{html:s}})},C=n=>!n||!(n!=null&&n.content.some(e=>e.content||e.type==="blok"||e.type==="horizontal_rule")),fe=(n,e,t)=>{let s=t||R;if(!s){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return C(n)?"":(e&&(s=new y(e.schema),e.resolver&&I(s,e.resolver)),s.render(n))},me=()=>O($);exports.RichTextResolver=y;exports.RichTextSchema=P;exports.apiPlugin=pe;exports.isRichTextEmpty=C;exports.loadStoryblokBridge=me;exports.registerStoryblokBridge=E;exports.renderRichText=fe;exports.storyblokEditable=ge;exports.storyblokInit=de;exports.useStoryblokBridge=E;
|
|
24
|
+
}`),""}optimizeImages(e,t){let s=0,r=0,i="",o="";typeof t!="boolean"&&(typeof t.width=="number"&&t.width>0&&(i+=`width="${t.width}" `,s=t.width),typeof t.height=="number"&&t.height>0&&(i+=`height="${t.height}" `,r=t.height),(t.loading==="lazy"||t.loading==="eager")&&(i+=`loading="${t.loading}" `),typeof t.class=="string"&&t.class.length>0&&(i+=`class="${t.class}" `),t.filters&&(typeof t.filters.blur=="number"&&t.filters.blur>=0&&t.filters.blur<=100&&(o+=`:blur(${t.filters.blur})`),typeof t.filters.brightness=="number"&&t.filters.brightness>=-100&&t.filters.brightness<=100&&(o+=`:brightness(${t.filters.brightness})`),t.filters.fill&&(t.filters.fill.match(/[0-9A-Fa-f]{6}/g)||t.filters.fill==="transparent")&&(o+=`:fill(${t.filters.fill})`),t.filters.format&&["webp","png","jpeg"].includes(t.filters.format)&&(o+=`:format(${t.filters.format})`),typeof t.filters.grayscale=="boolean"&&t.filters.grayscale&&(o+=":grayscale()"),typeof t.filters.quality=="number"&&t.filters.quality>=0&&t.filters.quality<=100&&(o+=`:quality(${t.filters.quality})`),t.filters.rotate&&[90,180,270].includes(t.filters.rotate)&&(o+=`:rotate(${t.filters.rotate})`),o.length>0&&(o="/filters"+o))),i.length>0&&(e=e.replace(/<img/g,`<img ${i.trim()}`));const l=s>0||r>0||o.length>0?`${s}x${r}${o}`:"";return e=e.replace(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g,`a.storyblok.com/f/$1/$2.$3/m/${l}`),typeof t!="boolean"&&(t.sizes||t.srcset)&&(e=e.replace(/<img.*?src=["|'](.*?)["|']/g,a=>{var u,h;const p=a.match(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g);if(p&&p.length>0){const g={srcset:(u=t.srcset)==null?void 0:u.map(d=>{if(typeof d=="number")return`//${p}/m/${d}x0${o} ${d}w`;if(typeof d=="object"&&d.length===2){let k=0,T=0;return typeof d[0]=="number"&&(k=d[0]),typeof d[1]=="number"&&(T=d[1]),`//${p}/m/${k}x${T}${o} ${k}w`}}).join(", "),sizes:(h=t.sizes)==null?void 0:h.map(d=>d).join(", ")};let f="";return g.srcset&&(f+=`srcset="${g.srcset}" `),g.sizes&&(f+=`sizes="${g.sizes}" `),a.replace(/<img/g,`<img ${f.trim()}`)}return a})),e}renderNode(e){const t=[];e.marks&&e.marks.forEach(r=>{const i=this.getMatchingMark(r);i&&i.tag!==""&&t.push(this.renderOpeningTag(i.tag))});const s=this.getMatchingNode(e);return s&&s.tag&&t.push(this.renderOpeningTag(s.tag)),e.content?e.content.forEach(r=>{t.push(this.renderNode(r))}):e.text?t.push(ce(e.text)):s&&s.singleTag?t.push(this.renderTag(s.singleTag," /")):s&&s.html?t.push(s.html):e.type==="emoji"&&t.push(this.renderEmoji(e)),s&&s.tag&&t.push(this.renderClosingTag(s.tag)),e.marks&&e.marks.slice(0).reverse().forEach(r=>{const i=this.getMatchingMark(r);i&&i.tag!==""&&t.push(this.renderClosingTag(i.tag))}),t.join("")}renderTag(e,t){return e.constructor===String?`<${e}${t}>`:e.map(s=>{if(s.constructor===String)return`<${s}${t}>`;{let r=`<${s.tag}`;if(s.attrs){for(const i in s.attrs)if(Object.prototype.hasOwnProperty.call(s.attrs,i)){const o=s.attrs[i];o!==null&&(r+=` ${i}="${o}"`)}}return`${r}${t}>`}}).join("")}renderOpeningTag(e){return this.renderTag(e,"")}renderClosingTag(e){return e.constructor===String?`</${e}>`:e.slice(0).reverse().map(t=>t.constructor===String?`</${t}>`:`</${t.tag}>`).join("")}getMatchingNode(e){const t=this.nodes[e.type];if(typeof t=="function")return t(e)}getMatchingMark(e){const t=this.marks[e.type];if(typeof t=="function")return t(e)}renderEmoji(e){if(e.attrs.emoji)return e.attrs.emoji;const t=[{tag:"img",attrs:{src:e.attrs.fallbackImage,draggable:"false",loading:"lazy",align:"absmiddle"}}];return this.renderTag(t," /")}}const y=he;class ue{constructor(e){c(this,"baseURL"),c(this,"timeout"),c(this,"headers"),c(this,"responseInterceptor"),c(this,"fetch"),c(this,"ejectInterceptor"),c(this,"url"),c(this,"parameters"),c(this,"fetchOptions"),this.baseURL=e.baseURL,this.headers=e.headers||new Headers,this.timeout=e!=null&&e.timeout?e.timeout*1e3:0,this.responseInterceptor=e.responseInterceptor,this.fetch=(...t)=>e.fetch?e.fetch(...t):fetch(...t),this.ejectInterceptor=!1,this.url="",this.parameters={},this.fetchOptions={}}get(e,t){return this.url=e,this.parameters=t,this._methodHandler("get")}post(e,t){return this.url=e,this.parameters=t,this._methodHandler("post")}put(e,t){return this.url=e,this.parameters=t,this._methodHandler("put")}delete(e,t){return this.url=e,this.parameters=t,this._methodHandler("delete")}async _responseHandler(e){const t=[],s={data:{},headers:{},status:0,statusText:""};e.status!==204&&await e.json().then(r=>{s.data=r});for(const r of e.headers.entries())t[r[0]]=r[1];return s.headers={...t},s.status=e.status,s.statusText=e.statusText,s}async _methodHandler(e){let t=`${this.baseURL}${this.url}`,s=null;if(e==="get"){const a=new v;t=`${this.baseURL}${this.url}?${a.stringify(this.parameters)}`}else s=JSON.stringify(this.parameters);const r=new URL(t),i=new AbortController,{signal:o}=i;let l;this.timeout&&(l=setTimeout(()=>i.abort(),this.timeout));try{const a=await this.fetch(`${r}`,{method:e,headers:this.headers,body:s,signal:o,...this.fetchOptions});this.timeout&&clearTimeout(l);const u=await this._responseHandler(a);return this.responseInterceptor&&!this.ejectInterceptor?this._statusHandler(this.responseInterceptor(u)):this._statusHandler(u)}catch(a){return{message:a}}}setFetchOptions(e={}){Object.keys(e).length>0&&"method"in e&&delete e.method,this.fetchOptions={...e}}eject(){this.ejectInterceptor=!0}_statusHandler(e){const t=/20[0-6]/g;return new Promise((s,r)=>{if(t.test(`${e.status}`))return s(e);const i={message:e.statusText,status:e.status,response:Array.isArray(e.data)?e.data[0]:e.data.error||e.data.slug};r(i)})}}const pe=ue,x="SB-Agent",w={defaultAgentName:"SB-JS-CLIENT",defaultAgentVersion:"SB-Agent-Version",packageVersion:"6.0.0"};let b={};const m={};class de{constructor(e,t){c(this,"client"),c(this,"maxRetries"),c(this,"retriesDelay"),c(this,"throttle"),c(this,"accessToken"),c(this,"cache"),c(this,"helpers"),c(this,"resolveCounter"),c(this,"relations"),c(this,"links"),c(this,"richTextResolver"),c(this,"resolveNestedRelations"),c(this,"stringifiedStoriesCache");let s=e.endpoint||t;if(!s){const o=new v().getRegionURL,l=e.https===!1?"http":"https";e.oauthToken?s=`${l}://${o(e.region)}/v1`:s=`${l}://${o(e.region)}/v2`}const r=new Headers;r.set("Content-Type","application/json"),r.set("Accept","application/json"),e.headers&&e.headers.entries().toArray().forEach(([o,l])=>{r.set(o,l)}),r.has(x)||(r.set(x,w.defaultAgentName),r.set(w.defaultAgentVersion,w.packageVersion));let i=5;e.oauthToken&&(r.set("Authorization",e.oauthToken),i=3),e.rateLimit&&(i=e.rateLimit),e.richTextSchema?this.richTextResolver=new y(e.richTextSchema):this.richTextResolver=new y,e.componentResolver&&this.setComponentResolver(e.componentResolver),this.maxRetries=e.maxRetries||10,this.retriesDelay=300,this.throttle=L(this.throttledRequest,i,1e3),this.accessToken=e.accessToken||"",this.relations={},this.links={},this.cache=e.cache||{clear:"manual"},this.helpers=new v,this.resolveCounter=0,this.resolveNestedRelations=e.resolveNestedRelations||!0,this.stringifiedStoriesCache={},this.client=new pe({baseURL:s,timeout:e.timeout||0,headers:r,responseInterceptor:e.responseInterceptor,fetch:e.fetch})}setComponentResolver(e){this.richTextResolver.addNode("blok",t=>{let s="";return t.attrs.body&&t.attrs.body.forEach(r=>{s+=e(r.component,r)}),{html:s}})}parseParams(e){return e.token||(e.token=this.getToken()),e.cv||(e.cv=m[e.token]),Array.isArray(e.resolve_relations)&&(e.resolve_relations=e.resolve_relations.join(",")),typeof e.resolve_relations<"u"&&(e.resolve_level=2),e}factoryParamOptions(e,t){return this.helpers.isCDNUrl(e)?this.parseParams(t):t}makeRequest(e,t,s,r,i){const o=this.factoryParamOptions(e,this.helpers.getOptionsPage(t,s,r));return this.cacheResponse(e,o,void 0,i)}get(e,t,s){t||(t={});const r=`/${e}`,i=this.factoryParamOptions(r,t);return this.cacheResponse(r,i,void 0,s)}async getAll(e,t,s,r){const i=(t==null?void 0:t.per_page)||25,o=`/${e}`,l=o.split("/"),a=s||l[l.length-1],u=1,h=await this.makeRequest(o,t,i,u,r),p=h.total?Math.ceil(h.total/i):1,g=await this.helpers.asyncMap(this.helpers.range(u,p),f=>this.makeRequest(o,t,i,f+1,r));return this.helpers.flatMap([h,...g],f=>Object.values(f.data[a]))}post(e,t,s){const r=`/${e}`;return Promise.resolve(this.throttle("post",r,t,s))}put(e,t,s){const r=`/${e}`;return Promise.resolve(this.throttle("put",r,t,s))}delete(e,t,s){const r=`/${e}`;return Promise.resolve(this.throttle("delete",r,t,s))}getStories(e,t){return this._addResolveLevel(e),this.get("cdn/stories",e,t)}getStory(e,t,s){return this._addResolveLevel(t),this.get(`cdn/stories/${e}`,t,s)}getToken(){return this.accessToken}ejectInterceptor(){this.client.eject()}_addResolveLevel(e){typeof e.resolve_relations<"u"&&(e.resolve_level=2)}_cleanCopy(e){return JSON.parse(JSON.stringify(e))}_insertLinks(e,t,s){const r=e[t];r&&r.fieldtype=="multilink"&&r.linktype=="story"&&typeof r.id=="string"&&this.links[s][r.id]?r.story=this._cleanCopy(this.links[s][r.id]):r&&r.linktype==="story"&&typeof r.uuid=="string"&&this.links[s][r.uuid]&&(r.story=this._cleanCopy(this.links[s][r.uuid]))}getStoryReference(e,t){return this.relations[e][t]?(this.stringifiedStoriesCache[t]||(this.stringifiedStoriesCache[t]=JSON.stringify(this.relations[e][t])),JSON.parse(this.stringifiedStoriesCache[t])):t}_insertRelations(e,t,s,r){s.indexOf(`${e.component}.${t}`)>-1&&(typeof e[t]=="string"?e[t]=this.getStoryReference(r,e[t]):Array.isArray(e[t])&&(e[t]=e[t].map(i=>this.getStoryReference(r,i)).filter(Boolean)))}iterateTree(e,t,s){const r=i=>{if(i!=null){if(i.constructor===Array)for(let o=0;o<i.length;o++)r(i[o]);else if(i.constructor===Object){if(i._stopResolving)return;for(const o in i)(i.component&&i._uid||i.type==="link")&&(this._insertRelations(i,o,t,s),this._insertLinks(i,o,s)),r(i[o])}}};r(e.content)}async resolveLinks(e,t,s){let r=[];if(e.link_uuids){const i=e.link_uuids.length,o=[],l=50;for(let a=0;a<i;a+=l){const u=Math.min(i,a+l);o.push(e.link_uuids.slice(a,u))}for(let a=0;a<o.length;a++)(await this.getStories({per_page:l,language:t.language,version:t.version,by_uuids:o[a].join(",")})).data.stories.forEach(u=>{r.push(u)})}else r=e.links;r.forEach(i=>{this.links[s][i.uuid]={...i,_stopResolving:!0}})}async resolveRelations(e,t,s){let r=[];if(e.rel_uuids){const i=e.rel_uuids.length,o=[],l=50;for(let a=0;a<i;a+=l){const u=Math.min(i,a+l);o.push(e.rel_uuids.slice(a,u))}for(let a=0;a<o.length;a++)(await this.getStories({per_page:l,language:t.language,version:t.version,by_uuids:o[a].join(","),excluding_fields:t.excluding_fields})).data.stories.forEach(u=>{r.push(u)})}else r=e.rels;r&&r.length>0&&r.forEach(i=>{this.relations[s][i.uuid]={...i,_stopResolving:!0}})}async resolveStories(e,t,s){var r,i;let o=[];if(this.links[s]={},this.relations[s]={},typeof t.resolve_relations<"u"&&t.resolve_relations.length>0&&(typeof t.resolve_relations=="string"&&(o=t.resolve_relations.split(",")),await this.resolveRelations(e,t,s)),t.resolve_links&&["1","story","url","link"].indexOf(t.resolve_links)>-1&&((r=e.links)!=null&&r.length||(i=e.link_uuids)!=null&&i.length)&&await this.resolveLinks(e,t,s),this.resolveNestedRelations)for(const l in this.relations[s])this.iterateTree(this.relations[s][l],o,s);e.story?this.iterateTree(e.story,o,s):e.stories.forEach(l=>{this.iterateTree(l,o,s)}),this.stringifiedStoriesCache={},delete this.links[s],delete this.relations[s]}async cacheResponse(e,t,s,r){const i=this.helpers.stringify({url:e,params:t}),o=this.cacheProvider();if(this.cache.clear==="auto"&&t.version==="draft"&&await this.flushCache(),t.version==="published"&&e!="/cdn/spaces/me"){const l=await o.get(i);if(l)return Promise.resolve(l)}return new Promise(async(l,a)=>{var u;try{const h=await this.throttle("get",e,t,r);if(h.status!==200)return a(h);let p={data:h.data,headers:h.headers};if((u=h.headers)!=null&&u["per-page"]&&(p=Object.assign({},p,{perPage:h.headers["per-page"]?parseInt(h.headers["per-page"]):0,total:h.headers["per-page"]?parseInt(h.headers.total):0})),p.data.story||p.data.stories){const g=this.resolveCounter=++this.resolveCounter%1e3;await this.resolveStories(p.data,t,`${g}`)}return t.version==="published"&&e!="/cdn/spaces/me"&&await o.set(i,p),p.data.cv&&t.token&&(t.version==="draft"&&m[t.token]!=p.data.cv&&await this.flushCache(),m[t.token]=t.cv?t.cv:p.data.cv),l(p)}catch(h){if(h.response&&h.status===429&&(s=typeof s>"u"?0:s+1,s<this.maxRetries))return console.log(`Hit rate limit. Retrying in ${this.retriesDelay/1e3} seconds.`),await this.helpers.delay(this.retriesDelay),this.cacheResponse(e,t,s).then(l).catch(a);a(h)}})}throttledRequest(e,t,s,r){return this.client.setFetchOptions(r),this.client[e](t,s)}cacheVersions(){return m}cacheVersion(){return m[this.accessToken]}setCacheVersion(e){this.accessToken&&(m[this.accessToken]=e)}clearCacheVersion(){this.accessToken&&(m[this.accessToken]=0)}cacheProvider(){switch(this.cache.type){case"memory":return{get(e){return Promise.resolve(b[e])},getAll(){return Promise.resolve(b)},set(e,t){return b[e]=t,Promise.resolve(void 0)},flush(){return b={},Promise.resolve(void 0)}};case"custom":if(this.cache.custom)return this.cache.custom;default:return{get(){return Promise.resolve()},getAll(){return Promise.resolve(void 0)},set(){return Promise.resolve(void 0)},flush(){return Promise.resolve(void 0)}}}}async flushCache(){return await this.cacheProvider().flush(),this.clearCacheVersion(),this}}const ge=(n={})=>{const{apiOptions:e}=n;if(!e.accessToken){console.error("You need to provide an access token to interact with Storyblok API. Read https://www.storyblok.com/docs/api/content-delivery#topics/authentication");return}return{storyblokApi:new de(e)}},fe=n=>{if(typeof n!="object"||typeof n._editable>"u")return{};try{const e=JSON.parse(n._editable.replace(/^<!--#storyblok#/,"").replace(/-->$/,""));return e?{"data-blok-c":JSON.stringify(e),"data-blok-uid":e.id+"-"+e.uid}:{}}catch{return{}}};let R,$="https://app.storyblok.com/f/storyblok-v2-latest.js";const E=(n,e,t={})=>{var s;const r=!(typeof window>"u")&&typeof window.storyblokRegisterEvent<"u",i=+new URL((s=window.location)==null?void 0:s.href).searchParams.get("_storyblok")===n;if(!(!r||!i)){if(!n){console.warn("Story ID is not defined. Please provide a valid ID.");return}window.storyblokRegisterEvent(()=>{new window.StoryblokBridge(t).on(["input","published","change"],o=>{o.action==="input"&&o.story.id===n?e(o.story):(o.action==="change"||o.action==="published")&&o.storyId===n&&window.location.reload()})})}},me=(n={})=>{var e,t;const{bridge:s,accessToken:r,use:i=[],apiOptions:o={},richText:l={},bridgeUrl:a}=n;o.accessToken=o.accessToken||r;const u={bridge:s,apiOptions:o};let h={};i.forEach(g=>{h={...h,...g(u)}}),a&&($=a);const p=!(typeof window>"u")&&((t=(e=window.location)==null?void 0:e.search)==null?void 0:t.includes("_storyblok_tk"));return s!==!1&&p&&O($),R=new y(l.schema),l.resolver&&I(R,l.resolver),h},I=(n,e)=>{n.addNode("blok",t=>{let s="";return t.attrs.body.forEach(r=>{s+=e(r.component,r)}),{html:s}})},C=n=>!n||!(n!=null&&n.content.some(e=>e.content||e.type==="blok"||e.type==="horizontal_rule")),ye=(n,e,t)=>{let s=t||R;if(!s){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return C(n)?"":(e&&(s=new y(e.schema),e.resolver&&I(s,e.resolver)),s.render(n))},be=()=>O($);exports.RichTextResolver=y;exports.RichTextSchema=P;exports.apiPlugin=ge;exports.isRichTextEmpty=C;exports.loadStoryblokBridge=be;exports.registerStoryblokBridge=E;exports.renderRichText=ye;exports.storyblokEditable=fe;exports.storyblokInit=me;exports.useStoryblokBridge=E;
|
package/dist/storyblok-js.mjs
CHANGED
|
@@ -6,14 +6,13 @@ const j = [], O = (n) => new Promise((e, t) => {
|
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
8
|
_ ? r() : j.push(r);
|
|
9
|
-
}, document.getElementById("storyblok-javascript-bridge")))
|
|
10
|
-
return;
|
|
9
|
+
}, document.getElementById("storyblok-javascript-bridge"))) return;
|
|
11
10
|
const s = document.createElement("script");
|
|
12
11
|
s.async = !0, s.src = n, s.id = "storyblok-javascript-bridge", s.onerror = (r) => t(r), s.onload = (r) => {
|
|
13
12
|
j.forEach((i) => i()), _ = !0, e(r);
|
|
14
13
|
}, document.getElementsByTagName("head")[0].appendChild(s);
|
|
15
14
|
});
|
|
16
|
-
var P = Object.defineProperty, I = (n, e, t) => e in n ? P(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t,
|
|
15
|
+
var P = Object.defineProperty, I = (n, e, t) => e in n ? P(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, c = (n, e, t) => I(n, typeof e != "symbol" ? e + "" : e, t);
|
|
17
16
|
function x(n) {
|
|
18
17
|
return !(n !== n || n === 1 / 0 || n === -1 / 0);
|
|
19
18
|
}
|
|
@@ -27,21 +26,21 @@ function C(n, e, t) {
|
|
|
27
26
|
const o = function() {
|
|
28
27
|
i++;
|
|
29
28
|
const a = setTimeout(function() {
|
|
30
|
-
i--, s.length > 0 && o(), r = r.filter(function(
|
|
31
|
-
return
|
|
29
|
+
i--, s.length > 0 && o(), r = r.filter(function(h) {
|
|
30
|
+
return h !== a;
|
|
32
31
|
});
|
|
33
32
|
}, t);
|
|
34
33
|
r.indexOf(a) < 0 && r.push(a);
|
|
35
|
-
const
|
|
36
|
-
|
|
34
|
+
const u = s.shift();
|
|
35
|
+
u.resolve(n.apply(u.self, u.args));
|
|
37
36
|
}, l = function(...a) {
|
|
38
|
-
const
|
|
39
|
-
return new Promise(function(
|
|
37
|
+
const u = this;
|
|
38
|
+
return new Promise(function(h, p) {
|
|
40
39
|
s.push({
|
|
41
|
-
resolve:
|
|
40
|
+
resolve: h,
|
|
42
41
|
reject: p,
|
|
43
42
|
args: a,
|
|
44
|
-
self:
|
|
43
|
+
self: u
|
|
45
44
|
}), i < e && o();
|
|
46
45
|
});
|
|
47
46
|
};
|
|
@@ -55,14 +54,14 @@ function C(n, e, t) {
|
|
|
55
54
|
}
|
|
56
55
|
class b {
|
|
57
56
|
constructor() {
|
|
58
|
-
|
|
57
|
+
c(this, "isCDNUrl", (e = "") => e.indexOf("/cdn/") > -1), c(this, "getOptionsPage", (e, t = 25, s = 1) => ({
|
|
59
58
|
...e,
|
|
60
59
|
per_page: t,
|
|
61
60
|
page: s
|
|
62
|
-
})),
|
|
61
|
+
})), c(this, "delay", (e) => new Promise((t) => setTimeout(t, e))), c(this, "arrayFrom", (e = 0, t) => [...Array(e)].map(t)), c(this, "range", (e = 0, t = e) => {
|
|
63
62
|
const s = Math.abs(t - e) || 0, r = e < t ? 1 : -1;
|
|
64
63
|
return this.arrayFrom(s, (i, o) => o * r + e);
|
|
65
|
-
}),
|
|
64
|
+
}), c(this, "asyncMap", async (e, t) => Promise.all(e.map(t))), c(this, "flatMap", (e = [], t) => e.map(t).reduce((s, r) => [...s, ...r], [])), c(this, "escapeHTML", function(e) {
|
|
66
65
|
const t = {
|
|
67
66
|
"&": "&",
|
|
68
67
|
"<": "<",
|
|
@@ -141,20 +140,20 @@ const A = function(n, e) {
|
|
|
141
140
|
singleTag: "br"
|
|
142
141
|
}), q = (n) => ({
|
|
143
142
|
tag: `h${n.attrs.level}`
|
|
144
|
-
}),
|
|
143
|
+
}), V = (n) => ({
|
|
145
144
|
singleTag: [
|
|
146
145
|
{
|
|
147
146
|
tag: "img",
|
|
148
147
|
attrs: A(n.attrs, ["src", "alt", "title"])
|
|
149
148
|
}
|
|
150
149
|
]
|
|
151
|
-
}), V = () => ({
|
|
152
|
-
tag: "li"
|
|
153
150
|
}), B = () => ({
|
|
151
|
+
tag: "li"
|
|
152
|
+
}), D = () => ({
|
|
154
153
|
tag: "ol"
|
|
155
154
|
}), J = () => ({
|
|
156
155
|
tag: "p"
|
|
157
|
-
}),
|
|
156
|
+
}), F = (n) => ({
|
|
158
157
|
tag: [
|
|
159
158
|
{
|
|
160
159
|
tag: "span",
|
|
@@ -250,11 +249,11 @@ const A = function(n, e) {
|
|
|
250
249
|
code_block: U,
|
|
251
250
|
hard_break: H,
|
|
252
251
|
heading: q,
|
|
253
|
-
image:
|
|
254
|
-
list_item:
|
|
255
|
-
ordered_list:
|
|
252
|
+
image: V,
|
|
253
|
+
list_item: B,
|
|
254
|
+
ordered_list: D,
|
|
256
255
|
paragraph: J,
|
|
257
|
-
emoji:
|
|
256
|
+
emoji: F
|
|
258
257
|
},
|
|
259
258
|
marks: {
|
|
260
259
|
bold: Y,
|
|
@@ -281,9 +280,9 @@ const A = function(n, e) {
|
|
|
281
280
|
}, t = /[&<>"']/g, s = RegExp(t.source);
|
|
282
281
|
return n && s.test(n) ? n.replace(t, (r) => e[r]) : n;
|
|
283
282
|
};
|
|
284
|
-
class
|
|
283
|
+
class le {
|
|
285
284
|
constructor(e) {
|
|
286
|
-
|
|
285
|
+
c(this, "marks"), c(this, "nodes"), e || (e = ne), this.marks = e.marks || [], this.nodes = e.nodes || [];
|
|
287
286
|
}
|
|
288
287
|
addNode(e, t) {
|
|
289
288
|
this.nodes[e] = t;
|
|
@@ -333,24 +332,24 @@ class v {
|
|
|
333
332
|
/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g,
|
|
334
333
|
`a.storyblok.com/f/$1/$2.$3/m/${l}`
|
|
335
334
|
), typeof t != "boolean" && (t.sizes || t.srcset) && (e = e.replace(/<img.*?src=["|'](.*?)["|']/g, (a) => {
|
|
336
|
-
var
|
|
335
|
+
var u, h;
|
|
337
336
|
const p = a.match(
|
|
338
337
|
/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g
|
|
339
338
|
);
|
|
340
339
|
if (p && p.length > 0) {
|
|
341
|
-
const
|
|
342
|
-
srcset: (
|
|
343
|
-
if (typeof
|
|
344
|
-
return `//${p}/m/${
|
|
345
|
-
if (typeof
|
|
340
|
+
const g = {
|
|
341
|
+
srcset: (u = t.srcset) == null ? void 0 : u.map((d) => {
|
|
342
|
+
if (typeof d == "number")
|
|
343
|
+
return `//${p}/m/${d}x0${o} ${d}w`;
|
|
344
|
+
if (typeof d == "object" && d.length === 2) {
|
|
346
345
|
let k = 0, T = 0;
|
|
347
|
-
return typeof
|
|
346
|
+
return typeof d[0] == "number" && (k = d[0]), typeof d[1] == "number" && (T = d[1]), `//${p}/m/${k}x${T}${o} ${k}w`;
|
|
348
347
|
}
|
|
349
348
|
}).join(", "),
|
|
350
|
-
sizes: (
|
|
349
|
+
sizes: (h = t.sizes) == null ? void 0 : h.map((d) => d).join(", ")
|
|
351
350
|
};
|
|
352
351
|
let f = "";
|
|
353
|
-
return
|
|
352
|
+
return g.srcset && (f += `srcset="${g.srcset}" `), g.sizes && (f += `sizes="${g.sizes}" `), a.replace(/<img/g, `<img ${f.trim()}`);
|
|
354
353
|
}
|
|
355
354
|
return a;
|
|
356
355
|
})), e;
|
|
@@ -375,11 +374,13 @@ class v {
|
|
|
375
374
|
return `<${s}${t}>`;
|
|
376
375
|
{
|
|
377
376
|
let r = `<${s.tag}`;
|
|
378
|
-
if (s.attrs)
|
|
379
|
-
for (const i in s.attrs)
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
377
|
+
if (s.attrs) {
|
|
378
|
+
for (const i in s.attrs)
|
|
379
|
+
if (Object.prototype.hasOwnProperty.call(s.attrs, i)) {
|
|
380
|
+
const o = s.attrs[i];
|
|
381
|
+
o !== null && (r += ` ${i}="${o}"`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
383
384
|
return `${r}${t}>`;
|
|
384
385
|
}
|
|
385
386
|
}).join("");
|
|
@@ -417,9 +418,10 @@ class v {
|
|
|
417
418
|
return this.renderTag(t, " /");
|
|
418
419
|
}
|
|
419
420
|
}
|
|
420
|
-
|
|
421
|
+
const v = le;
|
|
422
|
+
class ce {
|
|
421
423
|
constructor(e) {
|
|
422
|
-
|
|
424
|
+
c(this, "baseURL"), c(this, "timeout"), c(this, "headers"), c(this, "responseInterceptor"), c(this, "fetch"), c(this, "ejectInterceptor"), c(this, "url"), c(this, "parameters"), c(this, "fetchOptions"), this.baseURL = e.baseURL, this.headers = e.headers || new Headers(), this.timeout = e != null && e.timeout ? e.timeout * 1e3 : 0, this.responseInterceptor = e.responseInterceptor, this.fetch = (...t) => e.fetch ? e.fetch(...t) : fetch(...t), this.ejectInterceptor = !1, this.url = "", this.parameters = {}, this.fetchOptions = {};
|
|
423
425
|
}
|
|
424
426
|
/**
|
|
425
427
|
*
|
|
@@ -474,10 +476,10 @@ class le {
|
|
|
474
476
|
...this.fetchOptions
|
|
475
477
|
});
|
|
476
478
|
this.timeout && clearTimeout(l);
|
|
477
|
-
const
|
|
479
|
+
const u = await this._responseHandler(
|
|
478
480
|
a
|
|
479
481
|
);
|
|
480
|
-
return this.responseInterceptor && !this.ejectInterceptor ? this._statusHandler(this.responseInterceptor(
|
|
482
|
+
return this.responseInterceptor && !this.ejectInterceptor ? this._statusHandler(this.responseInterceptor(u)) : this._statusHandler(u);
|
|
481
483
|
} catch (a) {
|
|
482
484
|
return {
|
|
483
485
|
message: a
|
|
@@ -504,36 +506,35 @@ class le {
|
|
|
504
506
|
});
|
|
505
507
|
}
|
|
506
508
|
}
|
|
507
|
-
const S = "SB-Agent", w = {
|
|
509
|
+
const he = ce, S = "SB-Agent", w = {
|
|
508
510
|
defaultAgentName: "SB-JS-CLIENT",
|
|
509
511
|
defaultAgentVersion: "SB-Agent-Version",
|
|
510
512
|
packageVersion: "6.0.0"
|
|
511
513
|
};
|
|
512
514
|
let y = {};
|
|
513
515
|
const m = {};
|
|
514
|
-
class
|
|
516
|
+
class ue {
|
|
515
517
|
/**
|
|
516
518
|
*
|
|
517
519
|
* @param config ISbConfig interface
|
|
518
520
|
* @param endpoint string, optional
|
|
519
521
|
*/
|
|
520
522
|
constructor(e, t) {
|
|
521
|
-
|
|
523
|
+
c(this, "client"), c(this, "maxRetries"), c(this, "retriesDelay"), c(this, "throttle"), c(this, "accessToken"), c(this, "cache"), c(this, "helpers"), c(this, "resolveCounter"), c(this, "relations"), c(this, "links"), c(this, "richTextResolver"), c(this, "resolveNestedRelations"), c(this, "stringifiedStoriesCache");
|
|
522
524
|
let s = e.endpoint || t;
|
|
523
525
|
if (!s) {
|
|
524
526
|
const o = new b().getRegionURL, l = e.https === !1 ? "http" : "https";
|
|
525
527
|
e.oauthToken ? s = `${l}://${o(e.region)}/v1` : s = `${l}://${o(e.region)}/v2`;
|
|
526
528
|
}
|
|
527
529
|
const r = new Headers();
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
r.has(S) || (r.set(S, w.defaultAgentName), r.set(
|
|
530
|
+
r.set("Content-Type", "application/json"), r.set("Accept", "application/json"), e.headers && e.headers.entries().toArray().forEach(([o, l]) => {
|
|
531
|
+
r.set(o, l);
|
|
532
|
+
}), r.has(S) || (r.set(S, w.defaultAgentName), r.set(
|
|
532
533
|
w.defaultAgentVersion,
|
|
533
534
|
w.packageVersion
|
|
534
535
|
));
|
|
535
536
|
let i = 5;
|
|
536
|
-
e.oauthToken && (r.set("Authorization", e.oauthToken), i = 3), e.rateLimit && (i = e.rateLimit), e.richTextSchema ? this.richTextResolver = new v(e.richTextSchema) : this.richTextResolver = new v(), e.componentResolver && this.setComponentResolver(e.componentResolver), this.maxRetries = e.maxRetries ||
|
|
537
|
+
e.oauthToken && (r.set("Authorization", e.oauthToken), i = 3), e.rateLimit && (i = e.rateLimit), e.richTextSchema ? this.richTextResolver = new v(e.richTextSchema) : this.richTextResolver = new v(), e.componentResolver && this.setComponentResolver(e.componentResolver), this.maxRetries = e.maxRetries || 10, this.retriesDelay = 300, this.throttle = C(this.throttledRequest, i, 1e3), this.accessToken = e.accessToken || "", this.relations = {}, this.links = {}, this.cache = e.cache || { clear: "manual" }, this.helpers = new b(), this.resolveCounter = 0, this.resolveNestedRelations = e.resolveNestedRelations || !0, this.stringifiedStoriesCache = {}, this.client = new he({
|
|
537
538
|
baseURL: s,
|
|
538
539
|
timeout: e.timeout || 0,
|
|
539
540
|
headers: r,
|
|
@@ -557,47 +558,51 @@ class ce {
|
|
|
557
558
|
factoryParamOptions(e, t) {
|
|
558
559
|
return this.helpers.isCDNUrl(e) ? this.parseParams(t) : t;
|
|
559
560
|
}
|
|
560
|
-
makeRequest(e, t, s, r) {
|
|
561
|
-
const
|
|
561
|
+
makeRequest(e, t, s, r, i) {
|
|
562
|
+
const o = this.factoryParamOptions(
|
|
562
563
|
e,
|
|
563
564
|
this.helpers.getOptionsPage(t, s, r)
|
|
564
565
|
);
|
|
565
|
-
return this.cacheResponse(e, i);
|
|
566
|
+
return this.cacheResponse(e, o, void 0, i);
|
|
566
567
|
}
|
|
567
568
|
get(e, t, s) {
|
|
568
569
|
t || (t = {});
|
|
569
570
|
const r = `/${e}`, i = this.factoryParamOptions(r, t);
|
|
570
|
-
return this.
|
|
571
|
+
return this.cacheResponse(r, i, void 0, s);
|
|
571
572
|
}
|
|
572
573
|
async getAll(e, t, s, r) {
|
|
573
|
-
const i = (t == null ? void 0 : t.per_page) || 25, o = `/${e}`, l = o.split("/"), a = s || l[l.length - 1],
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
574
|
+
const i = (t == null ? void 0 : t.per_page) || 25, o = `/${e}`, l = o.split("/"), a = s || l[l.length - 1], u = 1, h = await this.makeRequest(
|
|
575
|
+
o,
|
|
576
|
+
t,
|
|
577
|
+
i,
|
|
578
|
+
u,
|
|
579
|
+
r
|
|
580
|
+
), p = h.total ? Math.ceil(h.total / i) : 1, g = await this.helpers.asyncMap(
|
|
581
|
+
this.helpers.range(u, p),
|
|
582
|
+
(f) => this.makeRequest(o, t, i, f + 1, r)
|
|
578
583
|
);
|
|
579
584
|
return this.helpers.flatMap(
|
|
580
|
-
[
|
|
585
|
+
[h, ...g],
|
|
581
586
|
(f) => Object.values(f.data[a])
|
|
582
587
|
);
|
|
583
588
|
}
|
|
584
589
|
post(e, t, s) {
|
|
585
590
|
const r = `/${e}`;
|
|
586
|
-
return
|
|
591
|
+
return Promise.resolve(this.throttle("post", r, t, s));
|
|
587
592
|
}
|
|
588
593
|
put(e, t, s) {
|
|
589
594
|
const r = `/${e}`;
|
|
590
|
-
return
|
|
595
|
+
return Promise.resolve(this.throttle("put", r, t, s));
|
|
591
596
|
}
|
|
592
597
|
delete(e, t, s) {
|
|
593
598
|
const r = `/${e}`;
|
|
594
|
-
return
|
|
599
|
+
return Promise.resolve(this.throttle("delete", r, t, s));
|
|
595
600
|
}
|
|
596
601
|
getStories(e, t) {
|
|
597
|
-
return this.
|
|
602
|
+
return this._addResolveLevel(e), this.get("cdn/stories", e, t);
|
|
598
603
|
}
|
|
599
604
|
getStory(e, t, s) {
|
|
600
|
-
return this.
|
|
605
|
+
return this._addResolveLevel(t), this.get(`cdn/stories/${e}`, t, s);
|
|
601
606
|
}
|
|
602
607
|
getToken() {
|
|
603
608
|
return this.accessToken;
|
|
@@ -659,8 +664,8 @@ class ce {
|
|
|
659
664
|
if (e.link_uuids) {
|
|
660
665
|
const i = e.link_uuids.length, o = [], l = 50;
|
|
661
666
|
for (let a = 0; a < i; a += l) {
|
|
662
|
-
const
|
|
663
|
-
o.push(e.link_uuids.slice(a,
|
|
667
|
+
const u = Math.min(i, a + l);
|
|
668
|
+
o.push(e.link_uuids.slice(a, u));
|
|
664
669
|
}
|
|
665
670
|
for (let a = 0; a < o.length; a++)
|
|
666
671
|
(await this.getStories({
|
|
@@ -669,8 +674,8 @@ class ce {
|
|
|
669
674
|
version: t.version,
|
|
670
675
|
by_uuids: o[a].join(",")
|
|
671
676
|
})).data.stories.forEach(
|
|
672
|
-
(
|
|
673
|
-
r.push(
|
|
677
|
+
(u) => {
|
|
678
|
+
r.push(u);
|
|
674
679
|
}
|
|
675
680
|
);
|
|
676
681
|
} else
|
|
@@ -687,8 +692,8 @@ class ce {
|
|
|
687
692
|
if (e.rel_uuids) {
|
|
688
693
|
const i = e.rel_uuids.length, o = [], l = 50;
|
|
689
694
|
for (let a = 0; a < i; a += l) {
|
|
690
|
-
const
|
|
691
|
-
o.push(e.rel_uuids.slice(a,
|
|
695
|
+
const u = Math.min(i, a + l);
|
|
696
|
+
o.push(e.rel_uuids.slice(a, u));
|
|
692
697
|
}
|
|
693
698
|
for (let a = 0; a < o.length; a++)
|
|
694
699
|
(await this.getStories({
|
|
@@ -697,8 +702,8 @@ class ce {
|
|
|
697
702
|
version: t.version,
|
|
698
703
|
by_uuids: o[a].join(","),
|
|
699
704
|
excluding_fields: t.excluding_fields
|
|
700
|
-
})).data.stories.forEach((
|
|
701
|
-
r.push(
|
|
705
|
+
})).data.stories.forEach((u) => {
|
|
706
|
+
r.push(u);
|
|
702
707
|
});
|
|
703
708
|
} else
|
|
704
709
|
r = e.rels;
|
|
@@ -732,38 +737,39 @@ class ce {
|
|
|
732
737
|
this.iterateTree(l, o, s);
|
|
733
738
|
}), this.stringifiedStoriesCache = {}, delete this.links[s], delete this.relations[s];
|
|
734
739
|
}
|
|
735
|
-
async cacheResponse(e, t, s) {
|
|
736
|
-
(
|
|
737
|
-
const r = this.helpers.stringify({ url: e, params: t }), i = this.cacheProvider();
|
|
740
|
+
async cacheResponse(e, t, s, r) {
|
|
741
|
+
const i = this.helpers.stringify({ url: e, params: t }), o = this.cacheProvider();
|
|
738
742
|
if (this.cache.clear === "auto" && t.version === "draft" && await this.flushCache(), t.version === "published" && e != "/cdn/spaces/me") {
|
|
739
|
-
const
|
|
740
|
-
if (
|
|
741
|
-
return Promise.resolve(
|
|
743
|
+
const l = await o.get(i);
|
|
744
|
+
if (l)
|
|
745
|
+
return Promise.resolve(l);
|
|
742
746
|
}
|
|
743
|
-
return new Promise(async (
|
|
744
|
-
var
|
|
747
|
+
return new Promise(async (l, a) => {
|
|
748
|
+
var u;
|
|
745
749
|
try {
|
|
746
|
-
const
|
|
747
|
-
if (
|
|
748
|
-
return
|
|
749
|
-
let
|
|
750
|
-
if ((
|
|
751
|
-
perPage:
|
|
752
|
-
total:
|
|
753
|
-
})),
|
|
754
|
-
const
|
|
755
|
-
await this.resolveStories(
|
|
750
|
+
const h = await this.throttle("get", e, t, r);
|
|
751
|
+
if (h.status !== 200)
|
|
752
|
+
return a(h);
|
|
753
|
+
let p = { data: h.data, headers: h.headers };
|
|
754
|
+
if ((u = h.headers) != null && u["per-page"] && (p = Object.assign({}, p, {
|
|
755
|
+
perPage: h.headers["per-page"] ? parseInt(h.headers["per-page"]) : 0,
|
|
756
|
+
total: h.headers["per-page"] ? parseInt(h.headers.total) : 0
|
|
757
|
+
})), p.data.story || p.data.stories) {
|
|
758
|
+
const g = this.resolveCounter = ++this.resolveCounter % 1e3;
|
|
759
|
+
await this.resolveStories(p.data, t, `${g}`);
|
|
756
760
|
}
|
|
757
|
-
return t.version === "published" && e != "/cdn/spaces/me" && await
|
|
758
|
-
} catch (
|
|
759
|
-
if (
|
|
760
|
-
return console.log(
|
|
761
|
-
|
|
761
|
+
return t.version === "published" && e != "/cdn/spaces/me" && await o.set(i, p), p.data.cv && t.token && (t.version === "draft" && m[t.token] != p.data.cv && await this.flushCache(), m[t.token] = t.cv ? t.cv : p.data.cv), l(p);
|
|
762
|
+
} catch (h) {
|
|
763
|
+
if (h.response && h.status === 429 && (s = typeof s > "u" ? 0 : s + 1, s < this.maxRetries))
|
|
764
|
+
return console.log(
|
|
765
|
+
`Hit rate limit. Retrying in ${this.retriesDelay / 1e3} seconds.`
|
|
766
|
+
), await this.helpers.delay(this.retriesDelay), this.cacheResponse(e, t, s).then(l).catch(a);
|
|
767
|
+
a(h);
|
|
762
768
|
}
|
|
763
769
|
});
|
|
764
770
|
}
|
|
765
|
-
throttledRequest(e, t, s) {
|
|
766
|
-
return this.client[e](t, s);
|
|
771
|
+
throttledRequest(e, t, s, r) {
|
|
772
|
+
return this.client.setFetchOptions(r), this.client[e](t, s);
|
|
767
773
|
}
|
|
768
774
|
cacheVersions() {
|
|
769
775
|
return m;
|
|
@@ -795,8 +801,7 @@ class ce {
|
|
|
795
801
|
}
|
|
796
802
|
};
|
|
797
803
|
case "custom":
|
|
798
|
-
if (this.cache.custom)
|
|
799
|
-
return this.cache.custom;
|
|
804
|
+
if (this.cache.custom) return this.cache.custom;
|
|
800
805
|
default:
|
|
801
806
|
return {
|
|
802
807
|
get() {
|
|
@@ -818,7 +823,7 @@ class ce {
|
|
|
818
823
|
return await this.cacheProvider().flush(), this.clearCacheVersion(), this;
|
|
819
824
|
}
|
|
820
825
|
}
|
|
821
|
-
const
|
|
826
|
+
const de = (n = {}) => {
|
|
822
827
|
const { apiOptions: e } = n;
|
|
823
828
|
if (!e.accessToken) {
|
|
824
829
|
console.error(
|
|
@@ -826,8 +831,8 @@ const ue = (n = {}) => {
|
|
|
826
831
|
);
|
|
827
832
|
return;
|
|
828
833
|
}
|
|
829
|
-
return { storyblokApi: new
|
|
830
|
-
},
|
|
834
|
+
return { storyblokApi: new ue(e) };
|
|
835
|
+
}, ge = (n) => {
|
|
831
836
|
if (typeof n != "object" || typeof n._editable > "u")
|
|
832
837
|
return {};
|
|
833
838
|
try {
|
|
@@ -843,7 +848,7 @@ const ue = (n = {}) => {
|
|
|
843
848
|
}
|
|
844
849
|
};
|
|
845
850
|
let R, $ = "https://app.storyblok.com/f/storyblok-v2-latest.js";
|
|
846
|
-
const
|
|
851
|
+
const fe = (n, e, t = {}) => {
|
|
847
852
|
var s;
|
|
848
853
|
const r = !(typeof window > "u") && typeof window.storyblokRegisterEvent < "u", i = +new URL((s = window.location) == null ? void 0 : s.href).searchParams.get(
|
|
849
854
|
"_storyblok"
|
|
@@ -859,7 +864,7 @@ const ge = (n, e, t = {}) => {
|
|
|
859
864
|
});
|
|
860
865
|
});
|
|
861
866
|
}
|
|
862
|
-
},
|
|
867
|
+
}, me = (n = {}) => {
|
|
863
868
|
var e, t;
|
|
864
869
|
const {
|
|
865
870
|
bridge: s,
|
|
@@ -870,13 +875,13 @@ const ge = (n, e, t = {}) => {
|
|
|
870
875
|
bridgeUrl: a
|
|
871
876
|
} = n;
|
|
872
877
|
o.accessToken = o.accessToken || r;
|
|
873
|
-
const
|
|
874
|
-
let
|
|
875
|
-
i.forEach((
|
|
876
|
-
|
|
878
|
+
const u = { bridge: s, apiOptions: o };
|
|
879
|
+
let h = {};
|
|
880
|
+
i.forEach((g) => {
|
|
881
|
+
h = { ...h, ...g(u) };
|
|
877
882
|
}), a && ($ = a);
|
|
878
883
|
const p = !(typeof window > "u") && ((t = (e = window.location) == null ? void 0 : e.search) == null ? void 0 : t.includes("_storyblok_tk"));
|
|
879
|
-
return s !== !1 && p && O($), R = new v(l.schema), l.resolver && E(R, l.resolver),
|
|
884
|
+
return s !== !1 && p && O($), R = new v(l.schema), l.resolver && E(R, l.resolver), h;
|
|
880
885
|
}, E = (n, e) => {
|
|
881
886
|
n.addNode("blok", (t) => {
|
|
882
887
|
let s = "";
|
|
@@ -886,7 +891,7 @@ const ge = (n, e, t = {}) => {
|
|
|
886
891
|
html: s
|
|
887
892
|
};
|
|
888
893
|
});
|
|
889
|
-
},
|
|
894
|
+
}, pe = (n) => !n || !(n != null && n.content.some((e) => e.content || e.type === "blok" || e.type === "horizontal_rule")), ye = (n, e, t) => {
|
|
890
895
|
let s = t || R;
|
|
891
896
|
if (!s) {
|
|
892
897
|
console.error(
|
|
@@ -894,17 +899,17 @@ const ge = (n, e, t = {}) => {
|
|
|
894
899
|
);
|
|
895
900
|
return;
|
|
896
901
|
}
|
|
897
|
-
return
|
|
898
|
-
},
|
|
902
|
+
return pe(n) ? "" : (e && (s = new v(e.schema), e.resolver && E(s, e.resolver)), s.render(n));
|
|
903
|
+
}, be = () => O($);
|
|
899
904
|
export {
|
|
900
905
|
v as RichTextResolver,
|
|
901
906
|
ne as RichTextSchema,
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
907
|
+
de as apiPlugin,
|
|
908
|
+
pe as isRichTextEmpty,
|
|
909
|
+
be as loadStoryblokBridge,
|
|
910
|
+
fe as registerStoryblokBridge,
|
|
911
|
+
ye as renderRichText,
|
|
912
|
+
ge as storyblokEditable,
|
|
913
|
+
me as storyblokInit,
|
|
914
|
+
fe as useStoryblokBridge
|
|
910
915
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { SbReactComponentsMap, SbReactSDKOptions, StoryblokClient } from "../types";
|
|
3
2
|
export declare const useStoryblokApi: () => StoryblokClient;
|
|
4
3
|
export declare const setComponents: (newComponentsMap: SbReactComponentsMap) => SbReactComponentsMap;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyblok/react",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.12",
|
|
4
4
|
"description": "SDK to integrate Storyblok into your project using React.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -44,26 +44,26 @@
|
|
|
44
44
|
"prepublishOnly": "npm run build && cp ../README.md ./"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@storyblok/js": "^3.0.
|
|
47
|
+
"@storyblok/js": "^3.0.11"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@babel/core": "^7.
|
|
51
|
-
"@babel/preset-env": "^7.
|
|
52
|
-
"@cypress/react": "^8.0.
|
|
53
|
-
"@cypress/vite-dev-server": "^5.
|
|
54
|
-
"@tsconfig/recommended": "^1.0.
|
|
55
|
-
"@types/react": "18.
|
|
56
|
-
"@vitejs/plugin-react": "^4.
|
|
50
|
+
"@babel/core": "^7.25.2",
|
|
51
|
+
"@babel/preset-env": "^7.25.4",
|
|
52
|
+
"@cypress/react": "^8.0.2",
|
|
53
|
+
"@cypress/vite-dev-server": "^5.1.1",
|
|
54
|
+
"@tsconfig/recommended": "^1.0.7",
|
|
55
|
+
"@types/react": "18.3.4",
|
|
56
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
57
57
|
"babel-jest": "^29.7.0",
|
|
58
|
-
"cypress": "^13.
|
|
59
|
-
"eslint-plugin-cypress": "^
|
|
60
|
-
"eslint-plugin-jest": "^28.
|
|
58
|
+
"cypress": "^13.13.3",
|
|
59
|
+
"eslint-plugin-cypress": "^3.5.0",
|
|
60
|
+
"eslint-plugin-jest": "^28.8.0",
|
|
61
61
|
"jest": "^29.7.0",
|
|
62
|
-
"react": "^18.
|
|
63
|
-
"react-dom": "^18.
|
|
62
|
+
"react": "^18.3.1",
|
|
63
|
+
"react-dom": "^18.3.1",
|
|
64
64
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
65
|
-
"start-server-and-test": "^2.0.
|
|
66
|
-
"vite": "^5.2
|
|
65
|
+
"start-server-and-test": "^2.0.5",
|
|
66
|
+
"vite": "^5.4.2"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"react": "^17.0.0 || ^18.0.0",
|