@storyblok/svelte 2.3.7 â 2.3.8
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 +20 -222
- package/dist/storyblok-svelte.js +1 -1
- package/dist/storyblok-svelte.mjs +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -32,17 +32,13 @@
|
|
|
32
32
|
</a>
|
|
33
33
|
</p>
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
## đ Usage
|
|
36
36
|
|
|
37
37
|
`@storyblok/svelte` helps you connect your Svelte project to Storyblok by:
|
|
38
38
|
|
|
39
39
|
- Providing the `getStoryblokApi` function to interact with the Storyblok APIs, using the [storyblok-js-client](https://github.com/storyblok/storyblok-js-client)
|
|
40
40
|
- Enabling real time editing through the [Storyblok Bridge](https://www.storyblok.com/docs/Guides/storyblok-latest-js?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte)
|
|
41
|
-
- Providing the `StoryblokComponent` which allows you to connect your components to the Storyblok Visual Editor
|
|
42
|
-
|
|
43
|
-
## đ Usage
|
|
44
|
-
|
|
45
|
-
> If you are first-time user of the Storyblok, read the [Getting Started](https://www.storyblok.com/tp/add-a-headless-cms-to-svelte-in-5-minutes?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte) guide to get a project ready in less than 5 minutes.
|
|
41
|
+
- Providing the `StoryblokComponent` which allows you to connect your components to the Storyblok Visual Editor
|
|
46
42
|
|
|
47
43
|
### Installation
|
|
48
44
|
|
|
@@ -50,10 +46,11 @@ Install `@storyblok/svelte`
|
|
|
50
46
|
|
|
51
47
|
```bash
|
|
52
48
|
npm install @storyblok/svelte
|
|
53
|
-
# yarn add @storyblok/svelte
|
|
54
49
|
```
|
|
55
50
|
|
|
56
|
-
|
|
51
|
+
Please note that you have to use npm - unfortunately we are currently not supporting yarn or pnpm for this SDK.
|
|
52
|
+
|
|
53
|
+
Initialize the library in your application by adding the `apiPlugin` and the [access token](https://www.storyblok.com/docs/api/content-delivery/v2?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte) of your Storyblok space:
|
|
57
54
|
|
|
58
55
|
```js
|
|
59
56
|
import App from "./App.svelte";
|
|
@@ -62,232 +59,33 @@ import { storyblokInit, apiPlugin } from "@storyblok/svelte";
|
|
|
62
59
|
storyblokInit({
|
|
63
60
|
accessToken: "<your-token>",
|
|
64
61
|
// bridge: false,
|
|
65
|
-
// apiOptions: { },
|
|
66
62
|
use: [apiPlugin],
|
|
63
|
+
|
|
67
64
|
components: {
|
|
68
65
|
teaser: Teaser,
|
|
69
66
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
Now, all features are enabled for you: the _Api Client_ for interacting with [Storyblok CDN API](https://www.storyblok.com/docs/api/content-delivery/v2?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte), and _Storyblok Bridge_ for [real-time visual editing experience](https://www.storyblok.com/docs/guide/essentials/visual-editor?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte).
|
|
76
|
-
|
|
77
|
-
> 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
|
|
78
|
-
|
|
79
|
-
### From a CDN
|
|
80
|
-
|
|
81
|
-
Install the file from the CDN and access the methods via `window.storyblokSvelte`:
|
|
82
|
-
|
|
83
|
-
```html
|
|
84
|
-
<script src="https://unpkg.com/@storyblok/svelte"></script>
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Getting started
|
|
88
|
-
|
|
89
|
-
### 1. Fetching Content
|
|
90
|
-
|
|
91
|
-
Use the `getStoryblokApi()` gets your stories from the Storyblok CDN API:
|
|
92
|
-
|
|
93
|
-
```html
|
|
94
|
-
<script>
|
|
95
|
-
import { onMount } from "svelte";
|
|
96
|
-
import { getStoryblokApi } from "@storyblok/svelte";
|
|
97
|
-
|
|
98
|
-
onMount(async () => {
|
|
99
|
-
const storyblokApi = getStoryblokApi();
|
|
100
|
-
const { data } = await storyblokApi.get("cdn/stories/home", {
|
|
101
|
-
version: "draft",
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
</script>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
> Note: you can skip using `storyblokApi` if you prefer your own method or function to fetch your data.
|
|
108
|
-
|
|
109
|
-
### 2. Listen to Storyblok Visual Editor events
|
|
110
|
-
|
|
111
|
-
Use `useStoryBridge` to get the updated story every time a change event is triggered from the Visual Editor. You need to pass the story id as first param, and a callback function as second param to update the new story:
|
|
112
|
-
|
|
113
|
-
```html
|
|
114
|
-
<script>
|
|
115
|
-
import { onMount } from "svelte";
|
|
116
|
-
import { getStoryblokApi, useStoryblokBridge } from "@storyblok/svelte";
|
|
117
|
-
|
|
118
|
-
let story = null;
|
|
119
|
-
|
|
120
|
-
onMount(async () => {
|
|
121
|
-
const storyblokApi = getStoryblokApi();
|
|
122
|
-
const { data } = await storyblokApi.get("cdn/stories/home", {
|
|
123
|
-
version: "draft",
|
|
124
|
-
});
|
|
125
|
-
story = data.story;
|
|
126
|
-
useStoryblokBridge(story.id, (newStory) => (story = newStory));
|
|
127
|
-
});
|
|
128
|
-
</script>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
You can pass [Bridge options](https://www.storyblok.com/docs/Guides/storyblok-latest-js?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte) as a third parameter as well:
|
|
132
|
-
|
|
133
|
-
```js
|
|
134
|
-
useStoryblokBridge(story.id, (newStory) => (story = newStory), {
|
|
135
|
-
resolveRelations: ["Article.author"],
|
|
136
|
-
});
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### 3. Link your components to Storyblok Visual Editor
|
|
140
|
-
|
|
141
|
-
In order to link the storyblok components, you have to
|
|
142
|
-
|
|
143
|
-
- Load them in components when calling `storyblokInit`
|
|
144
|
-
|
|
145
|
-
- Use the `storyblokEditable` action on the root element of each component
|
|
146
|
-
|
|
147
|
-
```html
|
|
148
|
-
<div use:storyblokEditable={blok} / >
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
- Use the `StoryblokComponent` to load them by passing the blok property
|
|
152
|
-
|
|
153
|
-
```html
|
|
154
|
-
<StoryblokComponent {blok} />
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
> The `blok` is the actual blok data coming from [Storblok's Content Delivery API](https://www.storyblok.com/docs/api/content-delivery/v2?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte).
|
|
158
|
-
|
|
159
|
-
### Features and API
|
|
160
|
-
|
|
161
|
-
You can **choose the features to use** when you initialize the plugin. In that way, you can improve Web Performance by optimizing your page load and save some bytes.
|
|
162
|
-
|
|
163
|
-
#### Storyblok API
|
|
164
|
-
|
|
165
|
-
You can use an `apiOptions` object. This is passed down to the [storyblok-js-client config object](https://github.com/storyblok/storyblok-js-client#class-storyblok):
|
|
166
|
-
|
|
167
|
-
```js
|
|
168
|
-
storyblokInit({
|
|
169
|
-
accessToken: "<your-token>",
|
|
170
|
-
apiOptions: {
|
|
171
|
-
//storyblok-js-client config object
|
|
172
|
-
cache: { type: "memory" },
|
|
173
|
-
},
|
|
174
|
-
use: [apiPlugin],
|
|
175
|
-
});
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
If you prefer to use your own fetch method, just remove the `apiPlugin` and `storyblok-js-client` won't be added to your application. You can find out more about our [Content Delivery API](https://www.storyblok.com/docs/api/content-delivery?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte) in the documentation.
|
|
179
|
-
|
|
180
|
-
#### Storyblok Bridge
|
|
181
|
-
|
|
182
|
-
You can conditionally load it by using the `bridge` option. Very useful if you want to disable it in production:
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
storyblokInit({
|
|
186
|
-
bridge: process.env.NODE_ENV !== "production",
|
|
187
|
-
});
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Keep in mind you have still access to the raw `window.StoryblokBridge`:
|
|
191
|
-
|
|
192
|
-
```js
|
|
193
|
-
const sbBridge = new window.StoryblokBridge(options);
|
|
194
|
-
|
|
195
|
-
sbBridge.on(["input", "published", "change"], (event) => {
|
|
196
|
-
// ...
|
|
197
|
-
});
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
For background information on the [Storyblok JS Bridge](https://www.storyblok.com/docs/Guides/storyblok-latest-js?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-svelte), please check out documentation.
|
|
201
|
-
|
|
202
|
-
### Rendering Rich Text
|
|
203
|
-
|
|
204
|
-
You can easily render rich text by using the `renderRichText`function that comes with `@storyblok/svelte`and Sveltes `{@html htmlstring}`directive.
|
|
205
|
-
|
|
206
|
-
```html
|
|
207
|
-
<script>
|
|
208
|
-
import { renderRichText } from "@storyblok/svelte";
|
|
209
|
-
|
|
210
|
-
export let blok;
|
|
211
|
-
$: articleHTML = renderRichText(blok.article);
|
|
212
|
-
</script>
|
|
213
|
-
|
|
214
|
-
<div>{@html articleHTML}</div>
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
You can set a **custom Schema and component resolver globally** at init time by using the `richText` init option:
|
|
218
|
-
|
|
219
|
-
```js
|
|
220
|
-
import { RichTextSchema, storyblokInit } from "@storyblok/svelte";
|
|
221
|
-
import cloneDeep from "clone-deep";
|
|
222
|
-
|
|
223
|
-
const mySchema = cloneDeep(RichTextSchema); // you can make a copy of the default RichTextSchema
|
|
224
|
-
// ... and edit the nodes and marks, or add your own.
|
|
225
|
-
// Check the base RichTextSchema source here https://github.com/storyblok/storyblok-js-client/blob/master/source/schema.js
|
|
226
|
-
|
|
227
|
-
storyblokInit({
|
|
228
|
-
accessToken: "<your-token>",
|
|
229
|
-
richText: {
|
|
230
|
-
schema: mySchema,
|
|
231
|
-
resolver: (component, blok) => {
|
|
232
|
-
switch (component) {
|
|
233
|
-
case "my-custom-component":
|
|
234
|
-
return `<div class="my-component-class">${blok.text}</div>`;
|
|
235
|
-
default:
|
|
236
|
-
return "Resolver not defined";
|
|
237
|
-
}
|
|
238
|
-
},
|
|
239
|
-
},
|
|
240
|
-
});
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
You can also set a **custom Schema and component resolver only once** by passing the options as the second parameter to `renderRichText` function:
|
|
244
|
-
|
|
245
|
-
```js
|
|
246
|
-
import { renderRichText } from "@storyblok/svelte";
|
|
247
|
-
|
|
248
|
-
renderRichText(blok.richTextField, {
|
|
249
|
-
schema: mySchema,
|
|
250
|
-
resolver: (component, blok) => {
|
|
251
|
-
switch (component) {
|
|
252
|
-
case "my-custom-component":
|
|
253
|
-
return `<div class="my-component-class">${blok.text}</div>`;
|
|
254
|
-
break;
|
|
255
|
-
default:
|
|
256
|
-
return `Component ${component} not found`;
|
|
67
|
+
// if you are using a space located in US region
|
|
68
|
+
// you have to use apiOptions.region:
|
|
69
|
+
/*
|
|
70
|
+
apiOptions: {
|
|
71
|
+
region: "us" // region code here
|
|
257
72
|
}
|
|
258
|
-
|
|
73
|
+
*/
|
|
259
74
|
});
|
|
260
75
|
```
|
|
261
76
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
This plugin is for Svelte. Thus, it supports the [same browsers as Svelte 3](https://github.com/sveltejs/svelte/issues/558). In short: all modern browsers and IE10+.
|
|
265
|
-
|
|
266
|
-
## Troubleshooting
|
|
267
|
-
|
|
268
|
-
### Working with a Component Library
|
|
269
|
-
|
|
270
|
-
When working with a component library, create an alias pointing '@storyblok/svelte' to './node_modules/@storyblok/svelte'. This will ensure the imported module will use the local version of storyblok. In your `svelte.config.js`, include:
|
|
271
|
-
|
|
272
|
-
```js
|
|
273
|
-
kit: {
|
|
274
|
-
alias: {
|
|
275
|
-
'@storyblok/svelte': './node_modules/@storyblok/svelte'
|
|
276
|
-
},
|
|
277
|
-
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
Any module importing @storyblok/svelte will now get it from the aliased location. For more information and alternatives to this solution, please see [npm link, peerDependencies and webpack](https://penx.medium.com/managing-dependencies-in-a-node-package-so-that-they-are-compatible-with-npm-link-61befa5aaca7).
|
|
77
|
+
Add all your components to the components object in the storyblokInit function. You can load all of them at the same time by adding them to the list.
|
|
281
78
|
|
|
282
|
-
Another option might also be using npm / yarn workspaces.
|
|
283
79
|
|
|
284
|
-
##
|
|
80
|
+
## âšī¸ More Resources
|
|
285
81
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
- [Svelte Documentation](https://svelte.dev/docs)
|
|
82
|
+
Please follow the step by step instructions available in [Ultimate Tutorial Series](https://www.storyblok.com/tp/the-storyblok-sveltekit-ultimate-tutorial). You can find all the different parts on this overview page and take it from here.
|
|
83
|
+
The parts are:
|
|
289
84
|
|
|
290
|
-
|
|
85
|
+
- Part 1: [Add a headless CMS to SvelteKit in 5 minutes](https://www.storyblok.com/tp/add-a-headless-cms-to-svelte-in-5-minutes) - [Source Code](https://github.com/storyblok/sveltekit-ultimate-tutorial-series/tree/part-1-sveltekit-ut)
|
|
86
|
+
- Part 2: [Render Storyblok Stories Dynamically in SvelteKit](https://www.storyblok.com/tp/render-storyblok-stories-dynamically-in-sveltekit) - [Source Code](https://github.com/storyblok/sveltekit-ultimate-tutorial-series/tree/part-2-sveltekit-ut)
|
|
87
|
+
- Part 3: [Create Dynamic Menus in Storyblok and SvelteKit](https://www.storyblok.com/tp/create-dynamic-menus-in-storyblok-and-sveltekit) - [Source Code](https://github.com/storyblok/sveltekit-ultimate-tutorial-series/tree/part-3-sveltekit-ut)
|
|
88
|
+
- Part 4: [Create Custom Components in Storyblok and SvelteKit](https://www.storyblok.com/tp/create-custom-components-in-storyblok-and-sveltekit) - [Source Code](https://github.com/storyblok/sveltekit-ultimate-tutorial-series/tree/part-4-sveltekit-ut)
|
|
291
89
|
|
|
292
90
|
### Support
|
|
293
91
|
|
package/dist/storyblok-svelte.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* (c) 2020-2022 Stobylok Team
|
|
5
5
|
*/function J(r){return typeof r=="number"&&r==r&&r!==1/0&&r!==-1/0}function Y(r,t,e){if(!J(t))throw new TypeError("Expected `limit` to be a finite number");if(!J(e))throw new TypeError("Expected `interval` to be a finite number");var n=[],s=[],o=0,a=function(){o++;var l=setTimeout(function(){o--,n.length>0&&a(),s=s.filter(function(u){return u!==l})},e);s.indexOf(l)<0&&s.push(l);var c=n.shift();c.resolve(r.apply(c.self,c.args))},i=function(){var l=arguments,c=this;return new Promise(function(u,f){n.push({resolve:u,reject:f,args:l,self:c}),o<t&&a()})};return i.abort=function(){s.forEach(clearTimeout),s=[],n.forEach(function(l){l.reject(new throttle.AbortError)}),n.length=0},i}Y.AbortError=function(){Error.call(this,"Throttled function aborted"),this.name="AbortError"};const _t=function(r,t){if(!r)return null;let e={};for(let n in r){let s=r[n];t.indexOf(n)>-1&&s!==null&&(e[n]=s)}return e};var bt={nodes:{horizontal_rule:()=>({singleTag:"hr"}),blockquote:()=>({tag:"blockquote"}),bullet_list:()=>({tag:"ul"}),code_block:r=>({tag:["pre",{tag:"code",attrs:r.attrs}]}),hard_break:()=>({singleTag:"br"}),heading:r=>({tag:`h${r.attrs.level}`}),image:r=>({singleTag:[{tag:"img",attrs:_t(r.attrs,["src","alt","title"])}]}),list_item:()=>({tag:"li"}),ordered_list:()=>({tag:"ol"}),paragraph:()=>({tag:"p"})},marks:{bold:()=>({tag:"b"}),strike:()=>({tag:"strike"}),underline:()=>({tag:"u"}),strong:()=>({tag:"strong"}),code:()=>({tag:"code"}),italic:()=>({tag:"i"}),link(r){const t=d({},r.attrs),{linktype:e="url"}=r.attrs;return e==="email"&&(t.href=`mailto:${t.href}`),t.anchor&&(t.href=`${t.href}#${t.anchor}`,delete t.anchor),{tag:[{tag:"a",attrs:t}]}},styled:r=>({tag:[{tag:"span",attrs:r.attrs}]})}};class vt{constructor(t){t||(t=bt),this.marks=t.marks||[],this.nodes=t.nodes||[]}addNode(t,e){this.nodes[t]=e}addMark(t,e){this.marks[t]=e}render(t={}){if(t.content&&Array.isArray(t.content)){let e="";return t.content.forEach(n=>{e+=this.renderNode(n)}),e}return console.warn("The render method must receive an object with a content field, which is an array"),""}renderNode(t){let e=[];t.marks&&t.marks.forEach(s=>{const o=this.getMatchingMark(s);o&&e.push(this.renderOpeningTag(o.tag))});const n=this.getMatchingNode(t);return n&&n.tag&&e.push(this.renderOpeningTag(n.tag)),t.content?t.content.forEach(s=>{e.push(this.renderNode(s))}):t.text?e.push(function(s){const o={"&":"&","<":"<",">":">",'"':""","'":"'"},a=/[&<>"']/g,i=RegExp(a.source);return s&&i.test(s)?s.replace(a,l=>o[l]):s}(t.text)):n&&n.singleTag?e.push(this.renderTag(n.singleTag," /")):n&&n.html&&e.push(n.html),n&&n.tag&&e.push(this.renderClosingTag(n.tag)),t.marks&&t.marks.slice(0).reverse().forEach(s=>{const o=this.getMatchingMark(s);o&&e.push(this.renderClosingTag(o.tag))}),e.join("")}renderTag(t,e){return t.constructor===String?`<${t}${e}>`:t.map(n=>{if(n.constructor===String)return`<${n}${e}>`;{let s=`<${n.tag}`;if(n.attrs)for(let o in n.attrs){let a=n.attrs[o];a!==null&&(s+=` ${o}="${a}"`)}return`${s}${e}>`}}).join("")}renderOpeningTag(t){return this.renderTag(t,"")}renderClosingTag(t){return t.constructor===String?`</${t}>`:t.slice(0).reverse().map(e=>e.constructor===String?`</${e}>`:`</${e.tag}>`).join("")}getMatchingNode(t){if(typeof this.nodes[t.type]=="function")return this.nodes[t.type](t)}getMatchingMark(t){if(typeof this.marks[t.type]=="function")return this.marks[t.type](t)}}const $t=(r=0,t=r)=>{const e=Math.abs(t-r)||0,n=r<t?1:-1;return((s=0,o)=>[...Array(s)].map(o))(e,(s,o)=>o*n+r)},S=(r,t,e)=>{const n=[];for(const s in r){if(!Object.prototype.hasOwnProperty.call(r,s))continue;const o=r[s],a=e?"":encodeURIComponent(s);let i;i=typeof o=="object"?S(o,t?t+encodeURIComponent("["+a+"]"):a,Array.isArray(o)):(t?t+encodeURIComponent("["+a+"]"):a)+"="+encodeURIComponent(o),n.push(i)}return n.join("&")};let b={},g={};class wt{constructor(t,e){if(!e){let o=t.region?`-${t.region}`:"",a=t.https===!1?"http":"https";e=t.oauthToken===void 0?`${a}://api${o}.storyblok.com/v2`:`${a}://api${o}.storyblok.com/v1`}let n=Object.assign({},t.headers),s=5;t.oauthToken!==void 0&&(n.Authorization=t.oauthToken,s=3),t.rateLimit!==void 0&&(s=t.rateLimit),this.richTextResolver=new vt(t.richTextSchema),typeof t.componentResolver=="function"&&this.setComponentResolver(t.componentResolver),this.maxRetries=t.maxRetries||5,this.throttle=Y(this.throttledRequest,s,1e3),this.accessToken=t.accessToken,this.relations={},this.links={},this.cache=t.cache||{clear:"manual"},this.client=ct.default.create({baseURL:e,timeout:t.timeout||0,headers:n,proxy:t.proxy||!1}),t.responseInterceptor&&this.client.interceptors.response.use(o=>t.responseInterceptor(o)),this.resolveNestedRelations=t.resolveNestedRelations||!0}setComponentResolver(t){this.richTextResolver.addNode("blok",e=>{let n="";return e.attrs.body.forEach(s=>{n+=t(s.component,s)}),{html:n}})}parseParams(t={}){return t.version||(t.version="published"),t.token||(t.token=this.getToken()),t.cv||(t.cv=g[t.token]),Array.isArray(t.resolve_relations)&&(t.resolve_relations=t.resolve_relations.join(",")),t}factoryParamOptions(t,e={}){return((n="")=>n.indexOf("/cdn/")>-1)(t)?this.parseParams(e):e}makeRequest(t,e,n,s){const o=this.factoryParamOptions(t,((a={},i=25,l=1)=>E(d({},a),{per_page:i,page:l}))(e,n,s));return this.cacheResponse(t,o)}get(t,e){let n=`/${t}`;const s=this.factoryParamOptions(n,e);return this.cacheResponse(n,s)}async getAll(t,e={},n){const s=e.per_page||25,o=`/${t}`,a=o.split("/");n=n||a[a.length-1];const i=await this.makeRequest(o,e,s,1),l=i.total?Math.ceil(i.total/s):1;return((c=[],u)=>c.map(u).reduce((f,R)=>[...f,...R],[]))([i,...await(async(c=[],u)=>Promise.all(c.map(u)))($t(1,l),async c=>this.makeRequest(o,e,s,c+1))],c=>Object.values(c.data[n]))}post(t,e){let n=`/${t}`;return this.throttle("post",n,e)}put(t,e){let n=`/${t}`;return this.throttle("put",n,e)}delete(t,e){let n=`/${t}`;return this.throttle("delete",n,e)}getStories(t){return this.get("cdn/stories",t)}getStory(t,e){return this.get(`cdn/stories/${t}`,e)}setToken(t){this.accessToken=t}getToken(){return this.accessToken}_cleanCopy(t){return JSON.parse(JSON.stringify(t))}_insertLinks(t,e){const n=t[e];n&&n.fieldtype=="multilink"&&n.linktype=="story"&&typeof n.id=="string"&&this.links[n.id]?n.story=this._cleanCopy(this.links[n.id]):n&&n.linktype==="story"&&typeof n.uuid=="string"&&this.links[n.uuid]&&(n.story=this._cleanCopy(this.links[n.uuid]))}_insertRelations(t,e,n){if(n.indexOf(t.component+"."+e)>-1){if(typeof t[e]=="string")this.relations[t[e]]&&(t[e]=this._cleanCopy(this.relations[t[e]]));else if(t[e].constructor===Array){let s=[];t[e].forEach(o=>{this.relations[o]&&s.push(this._cleanCopy(this.relations[o]))}),t[e]=s}}}_insertAssetsRelations(t,e){e.forEach(n=>{t.id===n.id&&(t.original=n,t.original.filename=t.filename,t.original.filename=t.original.filename.includes("https://s3.amazonaws.com/")?t.original.filename:t.original.filename.replace("https://","https://s3.amazonaws.com/"),delete t.original.s3_filename)})}iterateTree(t,e){let n=s=>{if(s!=null){if(s.constructor===Array)for(let o=0;o<s.length;o++)n(s[o]);else if(s.constructor===Object){if(s._stopResolving)return;for(let o in s)s.component&&s._uid||s.type==="link"?(this._insertRelations(s,o,e),this._insertLinks(s,o)):"id"in s&&s.fieldtype==="asset"&&this._insertAssetsRelations(s,e),n(s[o])}}};n(t.content)}async resolveLinks(t,e){let n=[];if(t.link_uuids){const s=t.link_uuids.length;let o=[];const a=50;for(let i=0;i<s;i+=a){const l=Math.min(s,i+a);o.push(t.link_uuids.slice(i,l))}for(let i=0;i<o.length;i++)(await this.getStories({per_page:a,language:e.language,version:e.version,by_uuids:o[i].join(",")})).data.stories.forEach(l=>{n.push(l)})}else n=t.links;n.forEach(s=>{this.links[s.uuid]=E(d({},s),{_stopResolving:!0})})}async resolveRelations(t,e){let n=[];if(t.rel_uuids){const s=t.rel_uuids.length;let o=[];const a=50;for(let i=0;i<s;i+=a){const l=Math.min(s,i+a);o.push(t.rel_uuids.slice(i,l))}for(let i=0;i<o.length;i++)(await this.getStories({per_page:a,language:e.language,version:e.version,by_uuids:o[i].join(",")})).data.stories.forEach(l=>{n.push(l)})}else n=t.rels;n.forEach(s=>{this.relations[s.uuid]=E(d({},s),{_stopResolving:!0})})}async resolveStories(t,e){let n=[];if(e.resolve_relations!==void 0&&e.resolve_relations.length>0&&(t.rels||t.rel_uuids)&&(n=e.resolve_relations.split(","),await this.resolveRelations(t,e)),["1","story","url"].indexOf(e.resolve_links)>-1&&(t.links||t.link_uuids)&&await this.resolveLinks(t,e),this.resolveNestedRelations)for(const s in this.relations)this.iterateTree(this.relations[s],n);t.story?this.iterateTree(t.story,n):t.stories.forEach(s=>{this.iterateTree(s,n)})}resolveAssetsRelations(t){const{assets:e,stories:n,story:s}=t;if(n)for(const o of n)this.iterateTree(o,e);else{if(!s)return t;this.iterateTree(s,e)}}cacheResponse(t,e,n){return n===void 0&&(n=0),new Promise(async(s,o)=>{let a=S({url:t,params:e}),i=this.cacheProvider();if(this.cache.clear==="auto"&&e.version==="draft"&&await this.flushCache(),e.version==="published"&&t!="/cdn/spaces/me"){const c=await i.get(a);if(c)return s(c)}try{let c=await this.throttle("get",t,{params:e,paramsSerializer:f=>S(f)}),u={data:c.data,headers:c.headers};if(u.data.assets&&u.data.assets.length&&this.resolveAssetsRelations(u.data),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}),c.status!=200)return o(c);(u.data.story||u.data.stories)&&await this.resolveStories(u.data,e),e.version==="published"&&t!="/cdn/spaces/me"&&i.set(a,u),u.data.cv&&(e.version=="draft"&&g[e.token]!=u.data.cv&&this.flushCache(),g[e.token]=u.data.cv),s(u)}catch(c){if(c.response&&c.response.status===429&&(n+=1)<this.maxRetries)return console.log(`Hit rate limit. Retrying in ${n} seconds.`),await(l=1e3*n,new Promise(u=>setTimeout(u,l))),this.cacheResponse(t,e,n).then(s).catch(o);o(c)}var l})}throttledRequest(t,e,n){return this.client[t](e,n)}cacheVersions(){return g}cacheVersion(){return g[this.accessToken]}setCacheVersion(t){this.accessToken&&(g[this.accessToken]=t)}cacheProvider(){return this.cache.type==="memory"?{get:t=>b[t],getAll:()=>b,set(t,e){b[t]=e},flush(){b={}}}:{get(){},getAll(){},set(){},flush(){}}}async flushCache(){return await this.cacheProvider().flush(),this}}const Tt=(r={})=>{const{apiOptions:t}=r;if(!t.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 wt(t)}};var Rt=r=>{if(typeof r!="object"||typeof r._editable>"u")return{};const t=JSON.parse(r._editable.replace(/^<!--#storyblok#/,"").replace(/-->$/,""));return{"data-blok-c":JSON.stringify(t),"data-blok-uid":t.id+"-"+t.uid}};let x;const Et="https://app.storyblok.com/f/storyblok-v2-latest.js",St=(r,t,e={})=>{if(!(typeof window>"u")){if(typeof window.storyblokRegisterEvent>"u"){console.error("Storyblok Bridge is disabled. Please enable it to use it. Read https://github.com/storyblok/storyblok-js");return}if(!r){console.warn("Story ID is not defined. Please provide a valid ID.");return}window.storyblokRegisterEvent(()=>{new window.StoryblokBridge(e).on(["input","published","change"],s=>{s.action==="input"&&s.story.id===r?t(s.story):(s.action==="change"||s.action==="published")&&s.storyId===r&&window.location.reload()})})}},xt=(r={})=>{const{bridge:t,accessToken:e,use:n=[],apiOptions:s={},richText:o={}}=r;s.accessToken=s.accessToken||e;const a={bridge:t,apiOptions:s};let i={};return n.forEach(l=>{i=d(d({},i),l(a))}),t!==!1&>(Et),x=new V(o.schema),o.resolver&&F(x,o.resolver),i},F=(r,t)=>{r.addNode("blok",e=>{let n="";return e.attrs.body.forEach(s=>{n+=t(s.component,s)}),{html:n}})},Ot=(r,t,e)=>{let n=e||x;if(!n){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return r===""?"":r?(t&&(n=new V(t.schema),t.resolver&&F(n,t.resolver)),n.render(r)):(console.warn(`${r} is not a valid Richtext object. This might be because the value of the richtext field is empty.
|
|
6
6
|
|
|
7
|
-
For more info about the richtext object check https://github.com/storyblok/storyblok-js#rendering-rich-text`),"")};function O(){}function j(r,t){for(const e in t)r[e]=t[e];return r}function K(r){return r()}function G(){return Object.create(null)}function y(r){r.forEach(K)}function Q(r){return typeof r=="function"}function jt(r,t){return r!=r?t==t:r!==t||r&&typeof r=="object"||typeof r=="function"}function Pt(r){return Object.keys(r).length===0}function At(r){const t={};for(const e in r)e[0]!=="$"&&(t[e]=r[e]);return t}function W(r,t){const e={};t=new Set(t);for(const n in r)!t.has(n)&&n[0]!=="$"&&(e[n]=r[n]);return e}function Ct(r,t,e){r.insertBefore(t,e||null)}function X(r){r.parentNode.removeChild(r)}function Mt(r){return document.createTextNode(r)}function Nt(){return Mt("")}function It(r){return Array.from(r.childNodes)}function Z(r,t){return new r(t)}let P;function k(r){P=r}const _=[],tt=[],v=[],et=[],Lt=Promise.resolve();let A=!1;function qt(){A||(A=!0,Lt.then(rt))}function C(r){v.push(r)}const M=new Set;let $=0;function rt(){const r=P;do{for(;$<_.length;){const t=_[$];$++,k(t),Bt(t.$$)}for(k(null),_.length=0,$=0;tt.length;)tt.pop()();for(let t=0;t<v.length;t+=1){const e=v[t];M.has(e)||(M.add(e),e())}v.length=0}while(_.length);for(;et.length;)et.pop()();A=!1,M.clear(),k(r)}function Bt(r){if(r.fragment!==null){r.update(),y(r.before_update);const t=r.dirty;r.dirty=[-1],r.fragment&&r.fragment.p(r.ctx,t),r.after_update.forEach(C)}}const w=new Set;let p;function Dt(){p={r:0,c:[],p}}function zt(){p.r||y(p.c),p=p.p}function N(r,t){r&&r.i&&(w.delete(r),r.i(t))}function nt(r,t,e,n){if(r&&r.o){if(w.has(r))return;w.add(r),p.c.push(()=>{w.delete(r),n&&(e&&r.d(1),n())}),r.o(t)}else n&&n()}function Ut(r,t){const e={},n={},s={$$scope:1};let o=r.length;for(;o--;){const a=r[o],i=t[o];if(i){for(const l in a)l in i||(n[l]=1);for(const l in i)s[l]||(e[l]=i[l],s[l]=1);r[o]=i}else for(const l in a)s[l]=1}for(const a in n)a in e||(e[a]=void 0);return e}function Ht(r){return typeof r=="object"&&r!==null?r:{}}function st(r){r&&r.c()}function I(r,t,e,n){const{fragment:s,after_update:o}=r.$$;s&&s.m(t,e),n||C(()=>{const a=r.$$.on_mount.map(K).filter(Q);r.$$.on_destroy?r.$$.on_destroy.push(...a):y(a),r.$$.on_mount=[]}),o.forEach(C)}function L(r,t){const e=r.$$;e.fragment!==null&&(y(e.on_destroy),e.fragment&&e.fragment.d(t),e.on_destroy=e.fragment=null,e.ctx=[])}function Vt(r,t){r.$$.dirty[0]===-1&&(_.push(r),qt(),r.$$.dirty.fill(0)),r.$$.dirty[t/31|0]|=1<<t%31}function Jt(r,t,e,n,s,o,a,i=[-1]){const l=P;k(r);const c=r.$$={fragment:null,ctx:[],props:o,update:O,not_equal:s,bound:G(),on_mount:[],on_destroy:[],on_disconnect:[],before_update:[],after_update:[],context:new Map(t.context||(l?l.$$.context:[])),callbacks:G(),dirty:i,skip_bound:!1,root:t.target||l.$$.root};a&&a(c.root);let u=!1;if(c.ctx=e?e(r,t.props||{},(f,R,...at)=>{const lt=at.length?at[0]:R;return c.ctx&&s(c.ctx[f],c.ctx[f]=lt)&&(!c.skip_bound&&c.bound[f]&&c.bound[f](lt),u&&Vt(r,f)),R}):[],c.update(),u=!0,y(c.before_update),c.fragment=n?n(c.ctx):!1,t.target){if(t.hydrate){const f=It(t.target);c.fragment&&c.fragment.l(f),f.forEach(X)}else c.fragment&&c.fragment.c();t.intro&&N(r.$$.fragment),I(r,t.target,t.anchor,t.customElement),rt()}k(l)}class Yt{$destroy(){L(this,1),this.$destroy=O}$on(t,e){if(!Q(e))return O;const n=this.$$.callbacks[t]||(this.$$.callbacks[t]=[]);return n.push(e),()=>{const s=n.indexOf(e);s!==-1&&n.splice(s,1)}}$set(t){this.$$set&&!Pt(t)&&(this.$$.skip_bound=!0,this.$$set(t),this.$$.skip_bound=!1)}}function Ft(r){let t,e,n;const s=[{blok:r[0]},r[2]];var o=r[1];function a(i){let l={};for(let c=0;c<s.length;c+=1)l=j(l,s[c]);return{props:l}}return o&&(t=Z(o,a())),{c(){t&&st(t.$$.fragment),e=Nt()},m(i,l){t&&I(t,i,l),Ct(i,e,l),n=!0},p(i,[l]){const c=l&5?Ut(s,[l&1&&{blok:i[0]},l&4&&Ht(i[2])]):{};if(o!==(o=i[1])){if(t){Dt();const u=t;nt(u.$$.fragment,1,0,()=>{L(u,1)}),zt()}o?(t=Z(o,a()),st(t.$$.fragment),N(t.$$.fragment,1),I(t,e.parentNode,e)):t=null}else o&&t.$set(c)},i(i){n||(t&&N(t.$$.fragment,i),n=!0)},o(i){t&&nt(t.$$.fragment,i),n=!1},d(i){i&&X(e),t&&L(t,i)}}}function Kt(r,t,e){const n=["blok"];let s=W(t,n),o,{blok:a}=t;return a?o=it(a.component):console.error("Please provide a 'blok' property to the StoryblokComponent"),r.$$set=i=>{t=j(j({},t),At(i)),e(2,s=W(t,n)),"blok"in i&&e(0,a=i.blok)},[a,o,s]}class Gt extends Yt{constructor(t){super(),Jt(this,t,Kt,Ft,jt,{blok:0})}}const Qt=(r,t)=>{const e=n=>{const s=Rt(n);s["data-blok-c"]&&(r.setAttribute("data-blok-c",s["data-blok-c"]),r.setAttribute("data-blok-uid",s["data-blok-uid"]),r.classList.add("storyblok__outline"))};return e(t),{update(n){e(n)}}};let q=null;const ot=()=>(q||console.log("You can't use getStoryblokApi if you're not loading apiPlugin."),q);let T=null;const Wt=r=>{const{storyblokApi:t}=xt(r);q=t,T=r.components||{}},it=r=>{let t=null;return t=typeof T=="function"?T()[r]:T[r],t||console.error(`You didn't load the ${r} component. Please load it in storyblokInit. For example:
|
|
7
|
+
For more info about the richtext object check https://github.com/storyblok/storyblok-js#rendering-rich-text`),"")};function O(){}function j(r,t){for(const e in t)r[e]=t[e];return r}function K(r){return r()}function G(){return Object.create(null)}function y(r){r.forEach(K)}function Q(r){return typeof r=="function"}function jt(r,t){return r!=r?t==t:r!==t||r&&typeof r=="object"||typeof r=="function"}function Pt(r){return Object.keys(r).length===0}function At(r){const t={};for(const e in r)e[0]!=="$"&&(t[e]=r[e]);return t}function W(r,t){const e={};t=new Set(t);for(const n in r)!t.has(n)&&n[0]!=="$"&&(e[n]=r[n]);return e}function Ct(r,t,e){r.insertBefore(t,e||null)}function X(r){r.parentNode&&r.parentNode.removeChild(r)}function Mt(r){return document.createTextNode(r)}function Nt(){return Mt("")}function It(r){return Array.from(r.childNodes)}function Z(r,t){return new r(t)}let P;function k(r){P=r}const _=[],tt=[],v=[],et=[],Lt=Promise.resolve();let A=!1;function qt(){A||(A=!0,Lt.then(rt))}function C(r){v.push(r)}const M=new Set;let $=0;function rt(){const r=P;do{for(;$<_.length;){const t=_[$];$++,k(t),Bt(t.$$)}for(k(null),_.length=0,$=0;tt.length;)tt.pop()();for(let t=0;t<v.length;t+=1){const e=v[t];M.has(e)||(M.add(e),e())}v.length=0}while(_.length);for(;et.length;)et.pop()();A=!1,M.clear(),k(r)}function Bt(r){if(r.fragment!==null){r.update(),y(r.before_update);const t=r.dirty;r.dirty=[-1],r.fragment&&r.fragment.p(r.ctx,t),r.after_update.forEach(C)}}const w=new Set;let p;function Dt(){p={r:0,c:[],p}}function zt(){p.r||y(p.c),p=p.p}function N(r,t){r&&r.i&&(w.delete(r),r.i(t))}function nt(r,t,e,n){if(r&&r.o){if(w.has(r))return;w.add(r),p.c.push(()=>{w.delete(r),n&&(e&&r.d(1),n())}),r.o(t)}else n&&n()}function Ut(r,t){const e={},n={},s={$$scope:1};let o=r.length;for(;o--;){const a=r[o],i=t[o];if(i){for(const l in a)l in i||(n[l]=1);for(const l in i)s[l]||(e[l]=i[l],s[l]=1);r[o]=i}else for(const l in a)s[l]=1}for(const a in n)a in e||(e[a]=void 0);return e}function Ht(r){return typeof r=="object"&&r!==null?r:{}}function st(r){r&&r.c()}function I(r,t,e,n){const{fragment:s,after_update:o}=r.$$;s&&s.m(t,e),n||C(()=>{const a=r.$$.on_mount.map(K).filter(Q);r.$$.on_destroy?r.$$.on_destroy.push(...a):y(a),r.$$.on_mount=[]}),o.forEach(C)}function L(r,t){const e=r.$$;e.fragment!==null&&(y(e.on_destroy),e.fragment&&e.fragment.d(t),e.on_destroy=e.fragment=null,e.ctx=[])}function Vt(r,t){r.$$.dirty[0]===-1&&(_.push(r),qt(),r.$$.dirty.fill(0)),r.$$.dirty[t/31|0]|=1<<t%31}function Jt(r,t,e,n,s,o,a,i=[-1]){const l=P;k(r);const c=r.$$={fragment:null,ctx:[],props:o,update:O,not_equal:s,bound:G(),on_mount:[],on_destroy:[],on_disconnect:[],before_update:[],after_update:[],context:new Map(t.context||(l?l.$$.context:[])),callbacks:G(),dirty:i,skip_bound:!1,root:t.target||l.$$.root};a&&a(c.root);let u=!1;if(c.ctx=e?e(r,t.props||{},(f,R,...at)=>{const lt=at.length?at[0]:R;return c.ctx&&s(c.ctx[f],c.ctx[f]=lt)&&(!c.skip_bound&&c.bound[f]&&c.bound[f](lt),u&&Vt(r,f)),R}):[],c.update(),u=!0,y(c.before_update),c.fragment=n?n(c.ctx):!1,t.target){if(t.hydrate){const f=It(t.target);c.fragment&&c.fragment.l(f),f.forEach(X)}else c.fragment&&c.fragment.c();t.intro&&N(r.$$.fragment),I(r,t.target,t.anchor,t.customElement),rt()}k(l)}class Yt{$destroy(){L(this,1),this.$destroy=O}$on(t,e){if(!Q(e))return O;const n=this.$$.callbacks[t]||(this.$$.callbacks[t]=[]);return n.push(e),()=>{const s=n.indexOf(e);s!==-1&&n.splice(s,1)}}$set(t){this.$$set&&!Pt(t)&&(this.$$.skip_bound=!0,this.$$set(t),this.$$.skip_bound=!1)}}function Ft(r){let t,e,n;const s=[{blok:r[0]},r[2]];var o=r[1];function a(i){let l={};for(let c=0;c<s.length;c+=1)l=j(l,s[c]);return{props:l}}return o&&(t=Z(o,a())),{c(){t&&st(t.$$.fragment),e=Nt()},m(i,l){t&&I(t,i,l),Ct(i,e,l),n=!0},p(i,[l]){const c=l&5?Ut(s,[l&1&&{blok:i[0]},l&4&&Ht(i[2])]):{};if(o!==(o=i[1])){if(t){Dt();const u=t;nt(u.$$.fragment,1,0,()=>{L(u,1)}),zt()}o?(t=Z(o,a()),st(t.$$.fragment),N(t.$$.fragment,1),I(t,e.parentNode,e)):t=null}else o&&t.$set(c)},i(i){n||(t&&N(t.$$.fragment,i),n=!0)},o(i){t&&nt(t.$$.fragment,i),n=!1},d(i){i&&X(e),t&&L(t,i)}}}function Kt(r,t,e){const n=["blok"];let s=W(t,n),o,{blok:a}=t;return a?o=it(a.component):console.error("Please provide a 'blok' property to the StoryblokComponent"),r.$$set=i=>{t=j(j({},t),At(i)),e(2,s=W(t,n)),"blok"in i&&e(0,a=i.blok)},[a,o,s]}class Gt extends Yt{constructor(t){super(),Jt(this,t,Kt,Ft,jt,{blok:0})}}const Qt=(r,t)=>{const e=n=>{const s=Rt(n);s["data-blok-c"]&&(r.setAttribute("data-blok-c",s["data-blok-c"]),r.setAttribute("data-blok-uid",s["data-blok-uid"]),r.classList.add("storyblok__outline"))};return e(t),{update(n){e(n)}}};let q=null;const ot=()=>(q||console.log("You can't use getStoryblokApi if you're not loading apiPlugin."),q);let T=null;const Wt=r=>{const{storyblokApi:t}=xt(r);q=t,T=r.components||{}},it=r=>{let t=null;return t=typeof T=="function"?T()[r]:T[r],t||console.error(`You didn't load the ${r} component. Please load it in storyblokInit. For example:
|
|
8
8
|
storyblokInit({
|
|
9
9
|
accessToken: "<your-token>",
|
|
10
10
|
components: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyblok/svelte",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.8",
|
|
4
4
|
"description": "Storyblok SDK to connect Storyblok with Svelte",
|
|
5
5
|
"main": "./dist/storyblok-svelte.js",
|
|
6
6
|
"module": "./dist/storyblok-svelte.mjs",
|
|
@@ -31,17 +31,17 @@
|
|
|
31
31
|
"@storyblok/js": "^1.8.6"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@babel/core": "^7.
|
|
34
|
+
"@babel/core": "^7.20.5",
|
|
35
35
|
"@cypress/vite-dev-server": "^2.2.3",
|
|
36
36
|
"@tsconfig/svelte": "^3.0.0",
|
|
37
37
|
"babel-jest": "^28.1.3",
|
|
38
38
|
"cypress": "^9.6.0",
|
|
39
39
|
"cypress-svelte-unit-test": "^3.3.4",
|
|
40
40
|
"eslint-plugin-cypress": "^2.12.1",
|
|
41
|
-
"eslint-plugin-jest": "^27.
|
|
41
|
+
"eslint-plugin-jest": "^27.1.7",
|
|
42
42
|
"jest": "^29.2.1",
|
|
43
|
-
"svelte-preprocess": "^
|
|
44
|
-
"typescript": "^4.
|
|
43
|
+
"svelte-preprocess": "^5.0.0",
|
|
44
|
+
"typescript": "^4.9.4",
|
|
45
45
|
"vite": "^3.1.8"
|
|
46
46
|
},
|
|
47
47
|
"eslintConfig": {
|