@storyblok/vue 7.1.17 → 7.1.18

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 CHANGED
@@ -30,12 +30,14 @@
30
30
  </a>
31
31
  </p>
32
32
 
33
- **Note**: This plugin is for Vue 3. [Check out the docs for Vue 2 version](https://github.com/storyblok/storyblok-vue-2).
33
+ > **Note**
34
+ > This plugin is for Vue 3. [Check out the docs for Vue 2 version](https://github.com/storyblok/storyblok-vue-2).
34
35
 
35
36
  ## 🚀 Usage
36
37
 
37
38
  Check out the **[Live Demo](https://stackblitz.com/edit/vue-sdk-demo?file=src/main.js&terminal=dev)** on Stackblitz!
38
39
 
40
+ > **Important**
39
41
  > If you are first-time user of the Storyblok, read the [Getting Started](https://www.storyblok.com/docs/guide/getting-started?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-vue) guide to get a project ready in less than 5 minutes.
40
42
 
41
43
  ### Installation
@@ -47,7 +49,8 @@ npm install @storyblok/vue
47
49
  # yarn add @storyblok/vue
48
50
  ```
49
51
 
50
- > ⚠️ 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).
52
+ > **Warning**
53
+ > 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).
51
54
 
52
55
  Register the plugin on your application (usually in `main.js`), add the `apiPlugin` 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-vue) of your Storyblok space:
53
56
 
@@ -66,6 +69,7 @@ app.use(StoryblokVue, {
66
69
 
67
70
  That's it! All the features are enabled for you: the _Api Client_ for interacting with [Storyblok CDN API](https://www.storyblok.com/docs/api/content-delivery#topics/introduction?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-vue), 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-vue).
68
71
 
72
+ > **Note**
69
73
  > 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.
70
74
 
71
75
  #### From a CDN
@@ -103,7 +107,8 @@ app.component("Teaser", Teaser);
103
107
 
104
108
  The simplest way is by using the `useStoryblok` one-liner composable. Where you need to pass as first parameter the `slug`, while the second and third parameters, `apiOptions` and `bridgeOptions` respectively, are optional:
105
109
 
106
- > `resolveRelations` and `resolveLinks` from `bridgeOptions` can be excluded if you're already defining them as `resolve_relations` and `resolve_links` in `apiOptions`, we will add them by default. But you will always be able to overwrite them.
110
+ > **Note**
111
+ > The `resolveRelations` and `resolveLinks` from `bridgeOptions` can be excluded if you're already defining them as `resolve_relations` and `resolve_links` in `apiOptions`, we will add them by default. But you will always be able to overwrite them.
107
112
 
108
113
  ```html
109
114
  <script setup>
@@ -209,7 +214,8 @@ Inject `storyblokApi` when using Composition API:
209
214
  </script>
210
215
  ```
211
216
 
212
- > Note: you can skip using `apiPlugin` if you prefer your own method or function to fetch your data.
217
+ > **Note**
218
+ > You can skip using `apiPlugin` if you prefer your own method or function to fetch your data.
213
219
 
214
220
  ##### 2. Listen to Storyblok Visual Editor events
215
221
 
@@ -346,7 +352,8 @@ app.use(StoryblokVue, {
346
352
  });
347
353
  ```
348
354
 
349
- > Note: For spaces created in the United States or China, the `region` parameter **must** be specified.
355
+ > **Important**
356
+ > For spaces created in the United States or China, the `region` parameter **must** be specified.
350
357
 
351
358
  #### Storyblok Bridge
352
359
 
@@ -21,5 +21,5 @@
21
21
  }
22
22
  ],
23
23
  type: 'doc'
24
- }`),""}optimizeImages(e,t){let s=0,r=0,n="",i="";typeof t!="boolean"&&(typeof t.width=="number"&&t.width>0&&(n+=`width="${t.width}" `,s=t.width),typeof t.height=="number"&&t.height>0&&(n+=`height="${t.height}" `,r=t.height),(t.loading==="lazy"||t.loading==="eager")&&(n+=`loading="${t.loading}" `),typeof t.class=="string"&&t.class.length>0&&(n+=`class="${t.class}" `),t.filters&&(typeof t.filters.blur=="number"&&t.filters.blur>=0&&t.filters.blur<=100&&(i+=`:blur(${t.filters.blur})`),typeof t.filters.brightness=="number"&&t.filters.brightness>=-100&&t.filters.brightness<=100&&(i+=`:brightness(${t.filters.brightness})`),t.filters.fill&&(t.filters.fill.match(/[0-9A-Fa-f]{6}/g)||t.filters.fill==="transparent")&&(i+=`:fill(${t.filters.fill})`),t.filters.format&&["webp","png","jpeg"].includes(t.filters.format)&&(i+=`:format(${t.filters.format})`),typeof t.filters.grayscale=="boolean"&&t.filters.grayscale&&(i+=":grayscale()"),typeof t.filters.quality=="number"&&t.filters.quality>=0&&t.filters.quality<=100&&(i+=`:quality(${t.filters.quality})`),t.filters.rotate&&[90,180,270].includes(t.filters.rotate)&&(i+=`:rotate(${t.filters.rotate})`),i.length>0&&(i="/filters"+i))),n.length>0&&(e=e.replace(/<img/g,`<img ${n.trim()}`));const c=s>0||r>0||i.length>0?`${s}x${r}${i}`:"";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/${c}`),typeof t!="boolean"&&(t.sizes||t.srcset)&&(e=e.replace(/<img.*?src=["|'](.*?)["|']/g,a=>{var l,u;const g=a.match(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g);if(g&&g.length>0){const m={srcset:(l=t.srcset)==null?void 0:l.map(f=>{if(typeof f=="number")return`//${g}/m/${f}x0${i} ${f}w`;if(typeof f=="object"&&f.length===2){let _=0,O=0;return typeof f[0]=="number"&&(_=f[0]),typeof f[1]=="number"&&(O=f[1]),`//${g}/m/${_}x${O}${i} ${_}w`}}).join(", "),sizes:(u=t.sizes)==null?void 0:u.map(f=>f).join(", ")};let R="";return m.srcset&&(R+=`srcset="${m.srcset}" `),m.sizes&&(R+=`sizes="${m.sizes}" `),a.replace(/<img/g,`<img ${R.trim()}`)}return a})),e}renderNode(e){const t=[];e.marks&&e.marks.forEach(r=>{const n=this.getMatchingMark(r);n&&n.tag!==""&&t.push(this.renderOpeningTag(n.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(pe(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 n=this.getMatchingMark(r);n&&n.tag!==""&&t.push(this.renderClosingTag(n.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 n in s.attrs){const i=s.attrs[n];i!==null&&(r+=` ${n}="${i}"`)}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 de{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"),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={}}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),n=new AbortController,{signal:i}=n;let c;this.timeout&&(c=setTimeout(()=>n.abort(),this.timeout));try{const a=await this.fetch(`${r}`,{method:e,headers:this.headers,body:s,signal:i});this.timeout&&clearTimeout(c);const l=await this._responseHandler(a);return this.responseInterceptor&&!this.ejectInterceptor?this._statusHandler(this.responseInterceptor(l)):this._statusHandler(l)}catch(a){return{message:a}}}eject(){this.ejectInterceptor=!0}_statusHandler(e){const t=/20[0-6]/g;return new Promise(s=>{if(t.test(`${e.status}`))return s(e);const r={message:e.statusText,status:e.status,response:Array.isArray(e.data)?e.data[0]:e.data.error||e.data.slug};throw new Error(JSON.stringify(r))})}}const I="SB-Agent",$={defaultAgentName:"SB-JS-CLIENT",defaultAgentVersion:"SB-Agent-Version",packageVersion:"5.14.2"};let w={};const y={};class ge{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");let s=e.endpoint||t;if(!s){const i=new v().getRegionURL,c=e.https===!1?"http":"https";e.oauthToken?s=`${c}://${i(e.region)}/v1`:s=`${c}://${i(e.region)}/v2`}const r=new Headers;if(r.set("Content-Type","application/json"),r.set("Accept","application/json"),e.headers)for(const i in e.headers)r.set(i,e.headers[i]);r.has(I)||(r.set(I,$.defaultAgentName),r.set($.defaultAgentVersion,$.packageVersion));let n=5;e.oauthToken&&(r.set("Authorization",e.oauthToken),n=3),e.rateLimit&&(n=e.rateLimit),e.richTextSchema?this.richTextResolver=new b(e.richTextSchema):this.richTextResolver=new b,e.componentResolver&&this.setComponentResolver(e.componentResolver),this.maxRetries=e.maxRetries||5,this.throttle=H(this.throttledRequest,n,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.client=new de({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.version||(e.version="published"),e.token||(e.token=this.getToken()),e.cv||(e.cv=y[e.token]),Array.isArray(e.resolve_relations)&&(e.resolve_relations=e.resolve_relations.join(",")),e}factoryParamOptions(e,t){return this.helpers.isCDNUrl(e)?this.parseParams(t):t}makeRequest(e,t,s,r){const n=this.factoryParamOptions(e,this.helpers.getOptionsPage(t,s,r));return this.cacheResponse(e,n)}get(e,t){t||(t={});const s=`/${e}`,r=this.factoryParamOptions(s,t);return this.cacheResponse(s,r)}async getAll(e,t,s){const r=(t==null?void 0:t.per_page)||25,n=`/${e}`,i=n.split("/"),c=s||i[i.length-1],a=1,l=await this.makeRequest(n,t,r,a),u=l.total?Math.ceil(l.total/r):1,g=await this.helpers.asyncMap(this.helpers.range(a,u),m=>this.makeRequest(n,t,r,m+1));return this.helpers.flatMap([l,...g],m=>Object.values(m.data[c]))}post(e,t){const s=`/${e}`;return Promise.resolve(this.throttle("post",s,t))}put(e,t){const s=`/${e}`;return Promise.resolve(this.throttle("put",s,t))}delete(e,t){const s=`/${e}`;return Promise.resolve(this.throttle("delete",s,t))}getStories(e){return this.get("cdn/stories",e)}getStory(e,t){return this.get(`cdn/stories/${e}`,t)}getToken(){return this.accessToken}ejectInterceptor(){this.client.eject()}_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]))}_insertRelations(e,t,s,r){if(s.indexOf(`${e.component}.${t}`)>-1){if(typeof e[t]=="string")this.relations[r][e[t]]&&(e[t]=this._cleanCopy(this.relations[r][e[t]]));else if(e[t]&&e[t].constructor===Array){const n=[];e[t].forEach(i=>{this.relations[r][i]&&n.push(this._cleanCopy(this.relations[r][i]))}),e[t]=n}}}iterateTree(e,t,s){const r=n=>{if(n!=null){if(n.constructor===Array)for(let i=0;i<n.length;i++)r(n[i]);else if(n.constructor===Object){if(n._stopResolving)return;for(const i in n)(n.component&&n._uid||n.type==="link")&&(this._insertRelations(n,i,t,s),this._insertLinks(n,i,s)),r(n[i])}}};r(e.content)}async resolveLinks(e,t,s){let r=[];if(e.link_uuids){const n=e.link_uuids.length,i=[],c=50;for(let a=0;a<n;a+=c){const l=Math.min(n,a+c);i.push(e.link_uuids.slice(a,l))}for(let a=0;a<i.length;a++)(await this.getStories({per_page:c,language:t.language,version:t.version,by_uuids:i[a].join(",")})).data.stories.forEach(l=>{r.push(l)})}else r=e.links;r.forEach(n=>{this.links[s][n.uuid]={...n,_stopResolving:!0}})}async resolveRelations(e,t,s){let r=[];if(e.rel_uuids){const n=e.rel_uuids.length,i=[],c=50;for(let a=0;a<n;a+=c){const l=Math.min(n,a+c);i.push(e.rel_uuids.slice(a,l))}for(let a=0;a<i.length;a++)(await this.getStories({per_page:c,language:t.language,version:t.version,by_uuids:i[a].join(",")})).data.stories.forEach(l=>{r.push(l)})}else r=e.rels;r&&r.length>0&&r.forEach(n=>{this.relations[s][n.uuid]={...n,_stopResolving:!0}})}async resolveStories(e,t,s){var r,n;let i=[];if(this.links[s]={},this.relations[s]={},typeof t.resolve_relations<"u"&&t.resolve_relations.length>0&&(typeof t.resolve_relations=="string"&&(i=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||(n=e.link_uuids)!=null&&n.length)&&await this.resolveLinks(e,t,s),this.resolveNestedRelations)for(const c in this.relations[s])this.iterateTree(this.relations[s][c],i,s);e.story?this.iterateTree(e.story,i,s):e.stories.forEach(c=>{this.iterateTree(c,i,s)}),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}),n=this.cacheProvider();if(this.cache.clear==="auto"&&t.version==="draft"&&await this.flushCache(),t.version==="published"&&e!="/cdn/spaces/me"){const i=await n.get(r);if(i)return Promise.resolve(i)}return new Promise(async(i,c)=>{var a;try{const l=await this.throttle("get",e,t);if(l.status!==200)return c(l);let u={data:l.data,headers:l.headers};if((a=l.headers)!=null&&a["per-page"]&&(u=Object.assign({},u,{perPage:l.headers["per-page"]?parseInt(l.headers["per-page"]):0,total:l.headers["per-page"]?parseInt(l.headers.total):0})),u.data.story||u.data.stories){const g=this.resolveCounter=++this.resolveCounter%1e3;await this.resolveStories(u.data,t,`${g}`)}return t.version==="published"&&e!="/cdn/spaces/me"&&await n.set(r,u),u.data.cv&&t.token&&(t.version=="draft"&&y[t.token]!=u.data.cv&&await this.flushCache(),y[t.token]=u.data.cv),i(u)}catch(l){if(l.response&&l.response.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(i).catch(c);c(l.message)}})}throttledRequest(e,t,s){return this.client[e](t,s)}cacheVersions(){return y}cacheVersion(){return y[this.accessToken]}setCacheVersion(e){this.accessToken&&(y[this.accessToken]=e)}cacheProvider(){switch(this.cache.type){case"memory":return{get(e){return Promise.resolve(w[e])},getAll(){return Promise.resolve(w)},set(e,t){return w[e]=t,Promise.resolve(void 0)},flush(){return w={},Promise.resolve(void 0)}};case"custom":if(this.cache.custom)return this.cache.custom;default:return{get(){return Promise.resolve(void 0)},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}}const fe=(o={})=>{const{apiOptions:e}=o;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 ge(e)}},me=o=>{if(typeof o!="object"||typeof o._editable>"u")return{};const e=JSON.parse(o._editable.replace(/^<!--#storyblok#/,"").replace(/-->$/,""));return{"data-blok-c":JSON.stringify(e),"data-blok-uid":e.id+"-"+e.uid}};let T;const ye="https://app.storyblok.com/f/storyblok-v2-latest.js",x=(o,e,t={})=>{var s;const r=!(typeof window>"u")&&typeof window.storyblokRegisterEvent<"u",n=+new URL((s=window.location)==null?void 0:s.href).searchParams.get("_storyblok")===o;if(!(!r||!n)){if(!o){console.warn("Story ID is not defined. Please provide a valid ID.");return}window.storyblokRegisterEvent(()=>{new window.StoryblokBridge(t).on(["input","published","change"],i=>{i.action==="input"&&i.story.id===o?e(i.story):(i.action==="change"||i.action==="published")&&i.storyId===o&&window.location.reload()})})}},be=(o={})=>{var e,t;const{bridge:s,accessToken:r,use:n=[],apiOptions:i={},richText:c={}}=o;i.accessToken=i.accessToken||r;const a={bridge:s,apiOptions:i};let l={};n.forEach(g=>{l={...l,...g(a)}});const u=!(typeof window>"u")&&((t=(e=window.location)==null?void 0:e.search)==null?void 0:t.includes("_storyblok_tk"));return s!==!1&&u&&M(ye),T=new b(c.schema),c.resolver&&A(T,c.resolver),l},A=(o,e)=>{o.addNode("blok",t=>{let s="";return t.attrs.body.forEach(r=>{s+=e(r.component,r)}),{html:s}})},ke=o=>!o||!(o!=null&&o.content.some(e=>e.content||e.type==="blok"||e.type==="horizontal_rule")),ve=(o,e,t)=>{let s=t||T;if(!s){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return ke(o)?"":(e&&(s=new b(e.schema),e.resolver&&A(s,e.resolver)),s.render(o))},C=d.defineComponent({__name:"StoryblokComponent",props:{blok:{}},setup(o){return(e,t)=>(d.openBlock(),d.createBlock(d.resolveDynamicComponent(e.blok.component),d.normalizeProps(d.guardReactiveProps({...e.$props,...e.$attrs})),null,16))}}),we={beforeMount(o,e){if(e.value){const t=me(e.value);o.setAttribute("data-blok-c",t["data-blok-c"]),o.setAttribute("data-blok-uid",t["data-blok-uid"]),o.classList.add("storyblok__outline")}}},N=o=>{console.error(`You can't use ${o} if you're not loading apiPlugin. Please provide it on StoryblokVue initialization.
24
+ }`),""}optimizeImages(e,t){let s=0,r=0,n="",i="";typeof t!="boolean"&&(typeof t.width=="number"&&t.width>0&&(n+=`width="${t.width}" `,s=t.width),typeof t.height=="number"&&t.height>0&&(n+=`height="${t.height}" `,r=t.height),(t.loading==="lazy"||t.loading==="eager")&&(n+=`loading="${t.loading}" `),typeof t.class=="string"&&t.class.length>0&&(n+=`class="${t.class}" `),t.filters&&(typeof t.filters.blur=="number"&&t.filters.blur>=0&&t.filters.blur<=100&&(i+=`:blur(${t.filters.blur})`),typeof t.filters.brightness=="number"&&t.filters.brightness>=-100&&t.filters.brightness<=100&&(i+=`:brightness(${t.filters.brightness})`),t.filters.fill&&(t.filters.fill.match(/[0-9A-Fa-f]{6}/g)||t.filters.fill==="transparent")&&(i+=`:fill(${t.filters.fill})`),t.filters.format&&["webp","png","jpeg"].includes(t.filters.format)&&(i+=`:format(${t.filters.format})`),typeof t.filters.grayscale=="boolean"&&t.filters.grayscale&&(i+=":grayscale()"),typeof t.filters.quality=="number"&&t.filters.quality>=0&&t.filters.quality<=100&&(i+=`:quality(${t.filters.quality})`),t.filters.rotate&&[90,180,270].includes(t.filters.rotate)&&(i+=`:rotate(${t.filters.rotate})`),i.length>0&&(i="/filters"+i))),n.length>0&&(e=e.replace(/<img/g,`<img ${n.trim()}`));const c=s>0||r>0||i.length>0?`${s}x${r}${i}`:"";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/${c}`),typeof t!="boolean"&&(t.sizes||t.srcset)&&(e=e.replace(/<img.*?src=["|'](.*?)["|']/g,a=>{var l,u;const g=a.match(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g);if(g&&g.length>0){const m={srcset:(l=t.srcset)==null?void 0:l.map(f=>{if(typeof f=="number")return`//${g}/m/${f}x0${i} ${f}w`;if(typeof f=="object"&&f.length===2){let _=0,O=0;return typeof f[0]=="number"&&(_=f[0]),typeof f[1]=="number"&&(O=f[1]),`//${g}/m/${_}x${O}${i} ${_}w`}}).join(", "),sizes:(u=t.sizes)==null?void 0:u.map(f=>f).join(", ")};let R="";return m.srcset&&(R+=`srcset="${m.srcset}" `),m.sizes&&(R+=`sizes="${m.sizes}" `),a.replace(/<img/g,`<img ${R.trim()}`)}return a})),e}renderNode(e){const t=[];e.marks&&e.marks.forEach(r=>{const n=this.getMatchingMark(r);n&&n.tag!==""&&t.push(this.renderOpeningTag(n.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(pe(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 n=this.getMatchingMark(r);n&&n.tag!==""&&t.push(this.renderClosingTag(n.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 n in s.attrs){const i=s.attrs[n];i!==null&&(r+=` ${n}="${i}"`)}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 de{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"),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={}}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),n=new AbortController,{signal:i}=n;let c;this.timeout&&(c=setTimeout(()=>n.abort(),this.timeout));try{const a=await this.fetch(`${r}`,{method:e,headers:this.headers,body:s,signal:i});this.timeout&&clearTimeout(c);const l=await this._responseHandler(a);return this.responseInterceptor&&!this.ejectInterceptor?this._statusHandler(this.responseInterceptor(l)):this._statusHandler(l)}catch(a){return{message:a}}}eject(){this.ejectInterceptor=!0}_statusHandler(e){const t=/20[0-6]/g;return new Promise(s=>{if(t.test(`${e.status}`))return s(e);const r={message:e.statusText,status:e.status,response:Array.isArray(e.data)?e.data[0]:e.data.error||e.data.slug};throw new Error(JSON.stringify(r))})}}const I="SB-Agent",$={defaultAgentName:"SB-JS-CLIENT",defaultAgentVersion:"SB-Agent-Version",packageVersion:"5.14.2"};let w={};const y={};class ge{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");let s=e.endpoint||t;if(!s){const i=new v().getRegionURL,c=e.https===!1?"http":"https";e.oauthToken?s=`${c}://${i(e.region)}/v1`:s=`${c}://${i(e.region)}/v2`}const r=new Headers;if(r.set("Content-Type","application/json"),r.set("Accept","application/json"),e.headers)for(const i in e.headers)r.set(i,e.headers[i]);r.has(I)||(r.set(I,$.defaultAgentName),r.set($.defaultAgentVersion,$.packageVersion));let n=5;e.oauthToken&&(r.set("Authorization",e.oauthToken),n=3),e.rateLimit&&(n=e.rateLimit),e.richTextSchema?this.richTextResolver=new b(e.richTextSchema):this.richTextResolver=new b,e.componentResolver&&this.setComponentResolver(e.componentResolver),this.maxRetries=e.maxRetries||5,this.throttle=H(this.throttledRequest,n,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.client=new de({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.version||(e.version="published"),e.token||(e.token=this.getToken()),e.cv||(e.cv=y[e.token]),Array.isArray(e.resolve_relations)&&(e.resolve_relations=e.resolve_relations.join(",")),e}factoryParamOptions(e,t){return this.helpers.isCDNUrl(e)?this.parseParams(t):t}makeRequest(e,t,s,r){const n=this.factoryParamOptions(e,this.helpers.getOptionsPage(t,s,r));return this.cacheResponse(e,n)}get(e,t){t||(t={});const s=`/${e}`,r=this.factoryParamOptions(s,t);return this.cacheResponse(s,r)}async getAll(e,t,s){const r=(t==null?void 0:t.per_page)||25,n=`/${e}`,i=n.split("/"),c=s||i[i.length-1],a=1,l=await this.makeRequest(n,t,r,a),u=l.total?Math.ceil(l.total/r):1,g=await this.helpers.asyncMap(this.helpers.range(a,u),m=>this.makeRequest(n,t,r,m+1));return this.helpers.flatMap([l,...g],m=>Object.values(m.data[c]))}post(e,t){const s=`/${e}`;return Promise.resolve(this.throttle("post",s,t))}put(e,t){const s=`/${e}`;return Promise.resolve(this.throttle("put",s,t))}delete(e,t){const s=`/${e}`;return Promise.resolve(this.throttle("delete",s,t))}getStories(e){return this.get("cdn/stories",e)}getStory(e,t){return this.get(`cdn/stories/${e}`,t)}getToken(){return this.accessToken}ejectInterceptor(){this.client.eject()}_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]))}_insertRelations(e,t,s,r){if(s.indexOf(`${e.component}.${t}`)>-1){if(typeof e[t]=="string")this.relations[r][e[t]]&&(e[t]=this._cleanCopy(this.relations[r][e[t]]));else if(e[t]&&e[t].constructor===Array){const n=[];e[t].forEach(i=>{this.relations[r][i]&&n.push(this._cleanCopy(this.relations[r][i]))}),e[t]=n}}}iterateTree(e,t,s){const r=n=>{if(n!=null){if(n.constructor===Array)for(let i=0;i<n.length;i++)r(n[i]);else if(n.constructor===Object){if(n._stopResolving)return;for(const i in n)(n.component&&n._uid||n.type==="link")&&(this._insertRelations(n,i,t,s),this._insertLinks(n,i,s)),r(n[i])}}};r(e.content)}async resolveLinks(e,t,s){let r=[];if(e.link_uuids){const n=e.link_uuids.length,i=[],c=50;for(let a=0;a<n;a+=c){const l=Math.min(n,a+c);i.push(e.link_uuids.slice(a,l))}for(let a=0;a<i.length;a++)(await this.getStories({per_page:c,language:t.language,version:t.version,by_uuids:i[a].join(",")})).data.stories.forEach(l=>{r.push(l)})}else r=e.links;r.forEach(n=>{this.links[s][n.uuid]={...n,_stopResolving:!0}})}async resolveRelations(e,t,s){let r=[];if(e.rel_uuids){const n=e.rel_uuids.length,i=[],c=50;for(let a=0;a<n;a+=c){const l=Math.min(n,a+c);i.push(e.rel_uuids.slice(a,l))}for(let a=0;a<i.length;a++)(await this.getStories({per_page:c,language:t.language,version:t.version,by_uuids:i[a].join(",")})).data.stories.forEach(l=>{r.push(l)})}else r=e.rels;r&&r.length>0&&r.forEach(n=>{this.relations[s][n.uuid]={...n,_stopResolving:!0}})}async resolveStories(e,t,s){var r,n;let i=[];if(this.links[s]={},this.relations[s]={},typeof t.resolve_relations<"u"&&t.resolve_relations.length>0&&(typeof t.resolve_relations=="string"&&(i=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||(n=e.link_uuids)!=null&&n.length)&&await this.resolveLinks(e,t,s),this.resolveNestedRelations)for(const c in this.relations[s])this.iterateTree(this.relations[s][c],i,s);e.story?this.iterateTree(e.story,i,s):e.stories.forEach(c=>{this.iterateTree(c,i,s)}),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}),n=this.cacheProvider();if(this.cache.clear==="auto"&&t.version==="draft"&&await this.flushCache(),t.version==="published"&&e!="/cdn/spaces/me"){const i=await n.get(r);if(i)return Promise.resolve(i)}return new Promise(async(i,c)=>{var a;try{const l=await this.throttle("get",e,t);if(l.status!==200)return c(l);let u={data:l.data,headers:l.headers};if((a=l.headers)!=null&&a["per-page"]&&(u=Object.assign({},u,{perPage:l.headers["per-page"]?parseInt(l.headers["per-page"]):0,total:l.headers["per-page"]?parseInt(l.headers.total):0})),u.data.story||u.data.stories){const g=this.resolveCounter=++this.resolveCounter%1e3;await this.resolveStories(u.data,t,`${g}`)}return t.version==="published"&&e!="/cdn/spaces/me"&&await n.set(r,u),u.data.cv&&t.token&&(t.version=="draft"&&y[t.token]!=u.data.cv&&await this.flushCache(),y[t.token]=u.data.cv),i(u)}catch(l){if(l.response&&l.response.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(i).catch(c);c(l.message)}})}throttledRequest(e,t,s){return this.client[e](t,s)}cacheVersions(){return y}cacheVersion(){return y[this.accessToken]}setCacheVersion(e){this.accessToken&&(y[this.accessToken]=e)}cacheProvider(){switch(this.cache.type){case"memory":return{get(e){return Promise.resolve(w[e])},getAll(){return Promise.resolve(w)},set(e,t){return w[e]=t,Promise.resolve(void 0)},flush(){return w={},Promise.resolve(void 0)}};case"custom":if(this.cache.custom)return this.cache.custom;default:return{get(){return Promise.resolve(void 0)},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}}const fe=(o={})=>{const{apiOptions:e}=o;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 ge(e)}},me=o=>{if(typeof o!="object"||typeof o._editable>"u")return{};const e=JSON.parse(o._editable.replace(/^<!--#storyblok#/,"").replace(/-->$/,""));return e?{"data-blok-c":JSON.stringify(e),"data-blok-uid":e.id+"-"+e.uid}:{}};let T;const ye="https://app.storyblok.com/f/storyblok-v2-latest.js",x=(o,e,t={})=>{var s;const r=!(typeof window>"u")&&typeof window.storyblokRegisterEvent<"u",n=+new URL((s=window.location)==null?void 0:s.href).searchParams.get("_storyblok")===o;if(!(!r||!n)){if(!o){console.warn("Story ID is not defined. Please provide a valid ID.");return}window.storyblokRegisterEvent(()=>{new window.StoryblokBridge(t).on(["input","published","change"],i=>{i.action==="input"&&i.story.id===o?e(i.story):(i.action==="change"||i.action==="published")&&i.storyId===o&&window.location.reload()})})}},be=(o={})=>{var e,t;const{bridge:s,accessToken:r,use:n=[],apiOptions:i={},richText:c={}}=o;i.accessToken=i.accessToken||r;const a={bridge:s,apiOptions:i};let l={};n.forEach(g=>{l={...l,...g(a)}});const u=!(typeof window>"u")&&((t=(e=window.location)==null?void 0:e.search)==null?void 0:t.includes("_storyblok_tk"));return s!==!1&&u&&M(ye),T=new b(c.schema),c.resolver&&A(T,c.resolver),l},A=(o,e)=>{o.addNode("blok",t=>{let s="";return t.attrs.body.forEach(r=>{s+=e(r.component,r)}),{html:s}})},ke=o=>!o||!(o!=null&&o.content.some(e=>e.content||e.type==="blok"||e.type==="horizontal_rule")),ve=(o,e,t)=>{let s=t||T;if(!s){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return ke(o)?"":(e&&(s=new b(e.schema),e.resolver&&A(s,e.resolver)),s.render(o))},C=d.defineComponent({__name:"StoryblokComponent",props:{blok:{}},setup(o){return(e,t)=>(d.openBlock(),d.createBlock(d.resolveDynamicComponent(e.blok.component),d.normalizeProps(d.guardReactiveProps({...e.$props,...e.$attrs})),null,16))}}),we={beforeMount(o,e){if(e.value){const t=me(e.value);o.setAttribute("data-blok-c",t["data-blok-c"]),o.setAttribute("data-blok-uid",t["data-blok-uid"]),o.classList.add("storyblok__outline")}}},N=o=>{console.error(`You can't use ${o} if you're not loading apiPlugin. Please provide it on StoryblokVue initialization.
25
25
  `)};let k=null;const $e=()=>(k||N("useStoryblokApi"),k),Te=async(o,e={},t={})=>{const s=d.ref(null);if(t.resolveRelations=t.resolveRelations??e.resolve_relations,t.resolveLinks=t.resolveLinks??e.resolve_links,d.onMounted(()=>{s.value&&s.value.id&&x(s.value.id,r=>s.value=r,t)}),k){const{data:r}=await k.get(`cdn/stories/${o}`,e);s.value=r.story}else N("useStoryblok");return s},Re={install(o,e={}){o.directive("editable",we),o.component("StoryblokComponent",C);const{storyblokApi:t}=be(e);k=t}};p.RichTextResolver=b,p.RichTextSchema=E,p.StoryblokComponent=C,p.StoryblokVue=Re,p.apiPlugin=fe,p.renderRichText=ve,p.useStoryblok=Te,p.useStoryblokApi=$e,p.useStoryblokBridge=x,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
@@ -802,10 +802,10 @@ const Se = (o = {}) => {
802
802
  const e = JSON.parse(
803
803
  o._editable.replace(/^<!--#storyblok#/, "").replace(/-->$/, "")
804
804
  );
805
- return {
805
+ return e ? {
806
806
  "data-blok-c": JSON.stringify(e),
807
807
  "data-blok-uid": e.id + "-" + e.uid
808
- };
808
+ } : {};
809
809
  };
810
810
  let R;
811
811
  const ve = "https://app.storyblok.com/f/storyblok-v2-latest.js", we = (o, e, t = {}) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storyblok/vue",
3
- "version": "7.1.17",
3
+ "version": "7.1.18",
4
4
  "description": "Storyblok directive for get editable elements.",
5
5
  "main": "./dist/storyblok-vue.js",
6
6
  "module": "./dist/storyblok-vue.mjs",
@@ -25,10 +25,10 @@
25
25
  "prepublishOnly": "npm run build && cp ../README.md ./"
26
26
  },
27
27
  "dependencies": {
28
- "@storyblok/js": "^2.2.11"
28
+ "@storyblok/js": "^2.2.12"
29
29
  },
30
30
  "devDependencies": {
31
- "@babel/core": "^7.22.10",
31
+ "@babel/core": "^7.22.11",
32
32
  "@cypress/vite-dev-server": "^5.0.5",
33
33
  "@cypress/vue": "^5.0.5",
34
34
  "@vitejs/plugin-vue": "^4.3.3",