@storyblok/astro 2.0.16 → 2.2.0

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
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
  <a href="https://www.storyblok.com?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-astro" align="center">
3
- <img src="https://a.storyblok.com/f/88751/1500x500/7974d6bc34/storyblok-astro.png" width="300" height="100" alt="Storyblok + Astro">
3
+ <img src="https://a.storyblok.com/f/88751/1500x500/7974d6bc34/storyblok-astro.png#1" width="300" height="100" alt="Storyblok + Astro">
4
4
  </a>
5
5
  <h1 align="center">@storyblok/astro</h1>
6
6
  <p align="center">Astro integration for the <a href="http://www.storyblok.com?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-astro" target="_blank">Storyblok</a> Headless CMS.</p> <br />
@@ -72,6 +72,9 @@ storyblok({
72
72
  bridge: true,
73
73
  apiOptions: {}, // storyblok-js-client options
74
74
  components: {},
75
+ componentsDir: "src",
76
+ enableFallbackComponent: false,
77
+ customFallbackComponent: "",
75
78
  useCustomApi: false,
76
79
  });
77
80
  ```
@@ -79,17 +82,20 @@ storyblok({
79
82
  > Note: By default, the apiPlugin from `@storyblok/js` is loaded. If you want to use your own method to fetch data from Storyblok, you can disable this behavior by setting `useCustomApi` to `true`, resulting in an optimized final bundle.
80
83
 
81
84
  #### Region parameter
85
+
82
86
  Possible values:
87
+
83
88
  - `eu` (default): For spaces created in the EU
84
89
  - `us`: For spaces created in the US
85
90
  - `cn`: For spaces created in China
86
91
 
87
92
  Full example for a space created in the US:
93
+
88
94
  ```js
89
95
  storyblok({
90
96
  accessToken: "<your-access-token>",
91
97
  apiOptions: {
92
- region: 'us'
98
+ region: "us",
93
99
  },
94
100
  });
95
101
  ```
@@ -119,7 +125,18 @@ components: {
119
125
  > - `src/storyblok/Feature.astro`
120
126
  > - `src/storyblok/Grid.astro`
121
127
  > - `src/storyblok/Teaser.astro`
122
- > You can choose any other folder in the `src` directory for your Astro components.
128
+ >
129
+ > You can choose any other folder in the `src` directory for your Astro components.
130
+
131
+ > Note: If you prefer to use a different folder than `src`, you can specify one using the `componentsDir` option:
132
+ >
133
+ > ```js
134
+ > storyblok({
135
+ > componentsDir: "app",
136
+ > });
137
+ > ```
138
+ >
139
+ > Now, your Storyblok components can be located anywhere in the `app` folder, e.g. `app/storyblok/Page.astro`.
123
140
 
124
141
  For each component, use the `storyblokEditable()` function on its root element, passing the `blok` property that they receive:
125
142
 
@@ -152,6 +169,10 @@ const { blok } = Astro.props
152
169
 
153
170
  > Note: 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-astro).
154
171
 
172
+ #### Using fallback components
173
+
174
+ By default, `@storyblok/astro` throws an error if a component is not implemented. Setting `enableFallbackComponent` to `true` bypasses that behavior, rendering a fallback component in the frontend instead. You can also use a custom fallback component by (for example) setting `customFallbackComponent: "storyblok/MyCustomFallback"`.
175
+
155
176
  #### Using partial hydration
156
177
 
157
178
  If you want to use partial hydration with any of the [frameworks supported by Astro](https://docs.astro.build/en/guides/integrations-guide/#article), follow these steps:
@@ -282,6 +303,7 @@ const renderedRichText = renderRichText(blok.text, {
282
303
  Returns the instance of the `storyblok-js-client`.
283
304
 
284
305
  ## The Storyblok JavaScript SDK Ecosystem
306
+
285
307
  ![A visual representation of the Storyblok JavaScript SDK Ecosystem](https://a.storyblok.com/f/88751/2400x1350/be4a4a4180/sdk-ecosystem.png/m/1200x0)
286
308
 
287
309
  ## Acknowledgements
@@ -291,7 +313,7 @@ A huge thank you goes to the Astro Team. In particular to [Tony Sullivan](https:
291
313
  ## Related Links
292
314
 
293
315
  - **[Live Demo on Stackblitz](https://stackblitz.com/edit/astro-sdk-demo)**
294
- - **[Storyblok CLI](https://github.com/storyblok/storyblok)**: A simple CLI for scaffolding Storyblok projects and fieldtypes.
316
+ - **[Storyblok CLI](https://github.com/storyblok/storyblok)**: A simple CLI for scaffolding Storyblok projects.
295
317
 
296
318
  ## More Resources
297
319
 
@@ -299,7 +321,7 @@ A huge thank you goes to the Astro Team. In particular to [Tony Sullivan](https:
299
321
 
300
322
  - Bugs or Feature Requests? [Submit an issue](/../../issues/new);
301
323
  - Do you have questions about this SDK? Or would you like to join the growing community of `@storyblok/astro` users? [Join the Astro Discord Community](https://discord.com/channels/830184174198718474/1002802280267001858)
302
- - Do you have questions about Storyblok or you need help? [Join the Storyblok Discord Community](https://discord.gg/jKrbAMz).
324
+ - Do you have questions about Storyblok or do you need help? [Join the Storyblok Discord Community](https://discord.gg/jKrbAMz).
303
325
 
304
326
  ### Contributing
305
327
 
@@ -1,7 +1,9 @@
1
1
  ---
2
2
  import components from "virtual:storyblok-components";
3
+ import options from "virtual:storyblok-options";
3
4
  import camelcase from "camelcase";
4
5
  import type { SbBlokData } from "./types";
6
+ import type { AstroComponentFactory } from "astro/dist/runtime/server";
5
7
 
6
8
  interface Props {
7
9
  blok: SbBlokData;
@@ -11,21 +13,25 @@ interface Props {
11
13
  const { blok, ...props } = Astro.props;
12
14
 
13
15
  /**
14
- * convert blok components to camel case to match vite-plugin-storyblok
16
+ * convert blok components to camel case to match vite-plugin-storyblok-components
15
17
  */
16
- const key = camelcase(blok.component);
18
+ let key = camelcase(blok.component);
17
19
 
18
- if (!(key in components)) {
19
- /**
20
- * Component not found! Log an error with details on the blok name that could not be found
21
- * TODO: Add support for a placeholder component as a fallback?
22
- */
23
- throw new Error(
24
- `Component could not be found for blok "${blok.component}"! Is it defined in astro.config.mjs?`
25
- );
26
- }
20
+ const componentFound: boolean = key in components;
21
+
22
+ let Component: AstroComponentFactory;
27
23
 
28
- const Component = components[key];
24
+ if (!componentFound) {
25
+ if (!options.enableFallbackComponent)
26
+ throw new Error(
27
+ `Component could not be found for blok "${blok.component}"! Is it defined in astro.config.mjs?`
28
+ );
29
+ else {
30
+ Component = components["FallbackComponent"];
31
+ }
32
+ } else {
33
+ Component = components[key];
34
+ }
29
35
  ---
30
36
 
31
37
  <Component blok={blok} {...props} />
@@ -1,4 +1,4 @@
1
- (function(c,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(c=typeof globalThis<"u"?globalThis:c||self,f(c.storyblokAstro={}))})(this,function(c){"use strict";function f(r,e,t){const s="virtual:storyblok-init",a="\0"+s;return{name:"vite-plugin-storyblok-init",async resolveId(o){if(o===s)return a},async load(o){if(o===a)return`
1
+ (function(g,p){typeof exports=="object"&&typeof module<"u"?p(exports):typeof define=="function"&&define.amd?define(["exports"],p):(g=typeof globalThis<"u"?globalThis:g||self,p(g.storyblokAstro={}))})(this,function(g){"use strict";function p(r,e,t){const o="virtual:storyblok-init",a="\0"+o;return{name:"vite-plugin-storyblok-init",async resolveId(s){if(s===o)return a},async load(s){if(s===a)return`
2
2
  import { storyblokInit, apiPlugin } from "@storyblok/js";
3
3
  const { storyblokApi } = storyblokInit({
4
4
  accessToken: "${r}",
@@ -6,9 +6,9 @@
6
6
  apiOptions: ${JSON.stringify(t)},
7
7
  });
8
8
  export const storyblokApiInstance = storyblokApi;
9
- `}}}const x=/[\p{Lu}]/u,R=/[\p{Ll}]/u,y=/^[\p{Lu}](?![\p{Lu}])/gu,k=/([\p{Alpha}\p{N}_]|$)/u,p=/[_.\- ]+/,N=new RegExp("^"+p.source),$=new RegExp(p.source+k.source,"gu"),v=new RegExp("\\d+"+k.source,"gu"),L=(r,e,t,s)=>{let a=!1,o=!1,i=!1,u=!1;for(let n=0;n<r.length;n++){const l=r[n];u=n>2?r[n-3]==="-":!0,a&&x.test(l)?(r=r.slice(0,n)+"-"+r.slice(n),a=!1,i=o,o=!0,n++):o&&i&&R.test(l)&&(!u||s)?(r=r.slice(0,n-1)+"-"+r.slice(n-1),i=o,o=!1,a=!0):(a=e(l)===l&&t(l)!==l,i=o,o=t(l)===l&&e(l)!==l)}return r},O=(r,e)=>(y.lastIndex=0,r.replace(y,t=>e(t))),_=(r,e)=>($.lastIndex=0,v.lastIndex=0,r.replace($,(t,s)=>e(s)).replace(v,t=>e(t)));function I(r,e){if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");if(e={pascalCase:!1,preserveConsecutiveUppercase:!1,...e},Array.isArray(r)?r=r.map(o=>o.trim()).filter(o=>o.length).join("-"):r=r.trim(),r.length===0)return"";const t=e.locale===!1?o=>o.toLowerCase():o=>o.toLocaleLowerCase(e.locale),s=e.locale===!1?o=>o.toUpperCase():o=>o.toLocaleUpperCase(e.locale);return r.length===1?p.test(r)?"":e.pascalCase?s(r):t(r):(r!==t(r)&&(r=L(r,t,s,e.preserveConsecutiveUppercase)),r=r.replace(N,""),r=e.preserveConsecutiveUppercase?O(r,t):t(r),e.pascalCase&&(r=s(r.charAt(0))+r.slice(1)),_(r,s))}function z(r){const e="virtual:storyblok-components",t="\0"+e;return{name:"vite-plugin-storyblok-components",async resolveId(s){if(s===e)return t},async load(s){if(s===t){const a=[];for await(const[o,i]of Object.entries(r)){const u=await this.resolve("/src/"+i+".astro");if(!u)throw new Error(`Component could not be found for blok "${o}"! Does "/src/${i}.astro" exist?`);a.push(`import ${I(o)} from "${u.id}"`)}return`${a.join(";")};export default {${Object.keys(r).map(o=>I(o)).join(",")}}`}}}}let T=!1;const w=[],M=r=>new Promise((e,t)=>{if(typeof window>"u"||(window.storyblokRegisterEvent=a=>{if(window.location===window.parent.location){console.warn("You are not in Draft Mode or in the Visual Editor.");return}T?a():w.push(a)},document.getElementById("storyblok-javascript-bridge")))return;const s=document.createElement("script");s.async=!0,s.src=r,s.id="storyblok-javascript-bridge",s.onerror=a=>t(a),s.onload=a=>{w.forEach(o=>o()),T=!0,e(a)},document.getElementsByTagName("head")[0].appendChild(s)});var P=Object.defineProperty,D=(r,e,t)=>e in r?P(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,A=(r,e,t)=>(D(r,typeof e!="symbol"?e+"":e,t),t);const U=function(r,e){const t={};for(const s in r){const a=r[s];e.indexOf(s)>-1&&a!==null&&(t[s]=a)}return t},q=r=>r==="email",B=()=>({singleTag:"hr"}),F=()=>({tag:"blockquote"}),J=()=>({tag:"ul"}),V=r=>({tag:["pre",{tag:"code",attrs:r.attrs}]}),G=()=>({singleTag:"br"}),K=r=>({tag:`h${r.attrs.level}`}),W=r=>({singleTag:[{tag:"img",attrs:U(r.attrs,["src","alt","title"])}]}),Y=()=>({tag:"li"}),H=()=>({tag:"ol"}),Q=()=>({tag:"p"}),X=r=>({tag:[{tag:"span",attrs:{["data-type"]:"emoji",["data-name"]:r.attrs.name,emoji:r.attrs.emoji}}]}),Z=()=>({tag:"b"}),ee=()=>({tag:"strike"}),te=()=>({tag:"u"}),re=()=>({tag:"strong"}),se=()=>({tag:"code"}),oe=()=>({tag:"i"}),ae=r=>{const e={...r.attrs},{linktype:t="url"}=r.attrs;if(q(t)&&(e.href=`mailto:${e.href}`),e.anchor&&(e.href=`${e.href}#${e.anchor}`,delete e.anchor),e.custom){for(const s in e.custom)e[s]=e.custom[s];delete e.custom}return{tag:[{tag:"a",attrs:e}]}},ie=r=>({tag:[{tag:"span",attrs:r.attrs}]}),ne=()=>({tag:"sub"}),le=()=>({tag:"sup"}),ce=r=>({tag:[{tag:"span",attrs:r.attrs}]}),ge=r=>({tag:[{tag:"span",attrs:{style:`background-color:${r.attrs.color};`}}]}),ue=r=>({tag:[{tag:"span",attrs:{style:`background-color:${r.attrs.color}`}}]}),E={nodes:{horizontal_rule:B,blockquote:F,bullet_list:J,code_block:V,hard_break:G,heading:K,image:W,list_item:Y,ordered_list:H,paragraph:Q,emoji:X},marks:{bold:Z,strike:ee,underline:te,strong:re,code:se,italic:oe,link:ae,styled:ie,subscript:ne,superscript:le,anchor:ce,highlight:ge,textStyle:ue}},fe=function(r){const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},t=/[&<>"']/g,s=RegExp(t.source);return r&&s.test(r)?r.replace(t,a=>e[a]):r};class j{constructor(e){A(this,"marks"),A(this,"nodes"),e||(e=E),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(a=>{s+=this.renderNode(a)}),t.optimizeImages?this.optimizeImages(s,t.optimizeImages):s}return console.warn("The render method must receive an object with a content field, which is an array"),""}optimizeImages(e,t){let s=0,a=0,o="",i="";typeof t!="boolean"&&(typeof t.width=="number"&&t.width>0&&(o+=`width="${t.width}" `,s=t.width),typeof t.height=="number"&&t.height>0&&(o+=`height="${t.height}" `,a=t.height),(t.loading==="lazy"||t.loading==="eager")&&(o+=`loading="${t.loading}" `),typeof t.class=="string"&&t.class.length>0&&(o+=`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))),o.length>0&&(e=e.replace(/<img/g,`<img ${o.trim()}`));const u=s>0||a>0||i.length>0?`${s}x${a}${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/${u}`),typeof t!="boolean"&&(t.sizes||t.srcset)&&(e=e.replace(/<img.*?src=["|'](.*?)["|']/g,n=>{var l,C;const d=n.match(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g);if(d&&d.length>0){const h={srcset:(l=t.srcset)==null?void 0:l.map(g=>{if(typeof g=="number")return`//${d}/m/${g}x0${i} ${g}w`;if(typeof g=="object"&&g.length===2){let m=0,S=0;return typeof g[0]=="number"&&(m=g[0]),typeof g[1]=="number"&&(S=g[1]),`//${d}/m/${m}x${S}${i} ${m}w`}}).join(", "),sizes:(C=t.sizes)==null?void 0:C.map(g=>g).join(", ")};let b="";return h.srcset&&(b+=`srcset="${h.srcset}" `),h.sizes&&(b+=`sizes="${h.sizes}" `),n.replace(/<img/g,`<img ${b.trim()}`)}return n})),e}renderNode(e){const t=[];e.marks&&e.marks.forEach(a=>{const o=this.getMatchingMark(a);o&&t.push(this.renderOpeningTag(o.tag))});const s=this.getMatchingNode(e);return s&&s.tag&&t.push(this.renderOpeningTag(s.tag)),e.content?e.content.forEach(a=>{t.push(this.renderNode(a))}):e.text?t.push(fe(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(a=>{const o=this.getMatchingMark(a);o&&t.push(this.renderClosingTag(o.tag))}),t.join("")}renderTag(e,t){return e.constructor===String?`<${e}${t}>`:e.map(s=>{if(s.constructor===String)return`<${s}${t}>`;{let a=`<${s.tag}`;if(s.attrs)for(const o in s.attrs){const i=s.attrs[o];i!==null&&(a+=` ${o}="${i}"`)}return`${a}${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 de=r=>{if(typeof r!="object"||typeof r._editable>"u")return{};const e=JSON.parse(r._editable.replace(/^<!--#storyblok#/,"").replace(/-->$/,""));return{"data-blok-c":JSON.stringify(e),"data-blok-uid":e.id+"-"+e.uid}};let he;const pe="https://app.storyblok.com/f/storyblok-v2-latest.js",be=(r,e)=>{r.addNode("blok",t=>{let s="";return t.attrs.body.forEach(a=>{s+=e(a.component,a)}),{html:s}})},me=(r,e,t)=>{let s=t||he;if(!s){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return r===""?"":r?(e&&(s=new j(e.schema),e.resolver&&be(s,e.resolver)),s.render(r)):(console.warn(`${r} is not a valid Richtext object. This might be because the value of the richtext field is empty.
9
+ `}}}const x=/[\p{Lu}]/u,R=/[\p{Ll}]/u,k=/^[\p{Lu}](?![\p{Lu}])/gu,$=/([\p{Alpha}\p{N}_]|$)/u,b=/[_.\- ]+/,N=new RegExp("^"+b.source),v=new RegExp(b.source+$.source,"gu"),I=new RegExp("\\d+"+$.source,"gu"),O=(r,e,t,o)=>{let a=!1,s=!1,i=!1,f=!1;for(let n=0;n<r.length;n++){const l=r[n];f=n>2?r[n-3]==="-":!0,a&&x.test(l)?(r=r.slice(0,n)+"-"+r.slice(n),a=!1,i=s,s=!0,n++):s&&i&&R.test(l)&&(!f||o)?(r=r.slice(0,n-1)+"-"+r.slice(n-1),i=s,s=!1,a=!0):(a=e(l)===l&&t(l)!==l,i=s,s=t(l)===l&&e(l)!==l)}return r},L=(r,e)=>(k.lastIndex=0,r.replace(k,t=>e(t))),M=(r,e)=>(v.lastIndex=0,I.lastIndex=0,r.replace(v,(t,o)=>e(o)).replace(I,t=>e(t)));function w(r,e){if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");if(e={pascalCase:!1,preserveConsecutiveUppercase:!1,...e},Array.isArray(r)?r=r.map(s=>s.trim()).filter(s=>s.length).join("-"):r=r.trim(),r.length===0)return"";const t=e.locale===!1?s=>s.toLowerCase():s=>s.toLocaleLowerCase(e.locale),o=e.locale===!1?s=>s.toUpperCase():s=>s.toLocaleUpperCase(e.locale);return r.length===1?b.test(r)?"":e.pascalCase?o(r):t(r):(r!==t(r)&&(r=O(r,t,o,e.preserveConsecutiveUppercase)),r=r.replace(N,""),r=e.preserveConsecutiveUppercase?L(r,t):t(r),e.pascalCase&&(r=o(r.charAt(0))+r.slice(1)),M(r,o))}function P(r,e,t,o){const a="virtual:storyblok-components",s="\0"+a;return{name:"vite-plugin-storyblok-components",async resolveId(i){if(i===a)return s},async load(i){if(i===s){const f=[],n=[];for await(const[c,d]of Object.entries(e)){const h=await this.resolve("/"+r+"/"+d+".astro");if(h)f.push(`import ${w(c)} from "${h.id}"`);else if(t)n.push(c);else throw new Error(`Component could not be found for blok "${c}"! Does "${"/"+r+"/"+d}.astro" exist?`)}let l="";if(t)if(l=",FallbackComponent",o){const c=await this.resolve("/"+r+"/"+o+".astro");if(!c)throw new Error(`Custom fallback component could not be found. Does "${"/"+r+"/"+o}.astro" exist?`);f.push(`import FallbackComponent from "${c.id}"`)}else f.push("import FallbackComponent from '@storyblok/astro/FallbackComponent.astro';");return`${f.join(";")};export default {${Object.keys(e).filter(c=>!n.includes(c)).map(c=>w(c)).join(",")}${l}}`}}}}function _(r){const e="virtual:storyblok-options",t="\0"+e;return{name:"vite-plugin-storyblok-options",async resolveId(o){if(o===e)return t},async load(o){if(o===t)return`export default ${JSON.stringify(r)}`}}}let T=!1;const A=[],z=r=>new Promise((e,t)=>{if(typeof window>"u"||(window.storyblokRegisterEvent=a=>{if(window.location===window.parent.location){console.warn("You are not in Draft Mode or in the Visual Editor.");return}T?a():A.push(a)},document.getElementById("storyblok-javascript-bridge")))return;const o=document.createElement("script");o.async=!0,o.src=r,o.id="storyblok-javascript-bridge",o.onerror=a=>t(a),o.onload=a=>{A.forEach(s=>s()),T=!0,e(a)},document.getElementsByTagName("head")[0].appendChild(o)});var D=Object.defineProperty,U=(r,e,t)=>e in r?D(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,C=(r,e,t)=>(U(r,typeof e!="symbol"?e+"":e,t),t);const F=function(r,e){const t={};for(const o in r){const a=r[o];e.indexOf(o)>-1&&a!==null&&(t[o]=a)}return t},q=r=>r==="email",B=()=>({singleTag:"hr"}),J=()=>({tag:"blockquote"}),K=()=>({tag:"ul"}),V=r=>({tag:["pre",{tag:"code",attrs:r.attrs}]}),G=()=>({singleTag:"br"}),W=r=>({tag:`h${r.attrs.level}`}),Y=r=>({singleTag:[{tag:"img",attrs:F(r.attrs,["src","alt","title"])}]}),H=()=>({tag:"li"}),Q=()=>({tag:"ol"}),X=()=>({tag:"p"}),Z=r=>({tag:[{tag:"span",attrs:{["data-type"]:"emoji",["data-name"]:r.attrs.name,emoji:r.attrs.emoji}}]}),ee=()=>({tag:"b"}),te=()=>({tag:"strike"}),re=()=>({tag:"u"}),oe=()=>({tag:"strong"}),se=()=>({tag:"code"}),ae=()=>({tag:"i"}),ie=r=>{const e={...r.attrs},{linktype:t="url"}=r.attrs;if(q(t)&&(e.href=`mailto:${e.href}`),e.anchor&&(e.href=`${e.href}#${e.anchor}`,delete e.anchor),e.custom){for(const o in e.custom)e[o]=e.custom[o];delete e.custom}return{tag:[{tag:"a",attrs:e}]}},ne=r=>({tag:[{tag:"span",attrs:r.attrs}]}),le=()=>({tag:"sub"}),ce=()=>({tag:"sup"}),ge=r=>({tag:[{tag:"span",attrs:r.attrs}]}),ue=r=>({tag:[{tag:"span",attrs:{style:`background-color:${r.attrs.color};`}}]}),fe=r=>({tag:[{tag:"span",attrs:{style:`background-color:${r.attrs.color}`}}]}),E={nodes:{horizontal_rule:B,blockquote:J,bullet_list:K,code_block:V,hard_break:G,heading:W,image:Y,list_item:H,ordered_list:Q,paragraph:X,emoji:Z},marks:{bold:ee,strike:te,underline:re,strong:oe,code:se,italic:ae,link:ie,styled:ne,subscript:le,superscript:ce,anchor:ge,highlight:ue,textStyle:fe}},de=function(r){const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},t=/[&<>"']/g,o=RegExp(t.source);return r&&o.test(r)?r.replace(t,a=>e[a]):r};class j{constructor(e){C(this,"marks"),C(this,"nodes"),e||(e=E),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 o="";return e.content.forEach(a=>{o+=this.renderNode(a)}),t.optimizeImages?this.optimizeImages(o,t.optimizeImages):o}return console.warn("The render method must receive an object with a content field, which is an array"),""}optimizeImages(e,t){let o=0,a=0,s="",i="";typeof t!="boolean"&&(typeof t.width=="number"&&t.width>0&&(s+=`width="${t.width}" `,o=t.width),typeof t.height=="number"&&t.height>0&&(s+=`height="${t.height}" `,a=t.height),(t.loading==="lazy"||t.loading==="eager")&&(s+=`loading="${t.loading}" `),typeof t.class=="string"&&t.class.length>0&&(s+=`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))),s.length>0&&(e=e.replace(/<img/g,`<img ${s.trim()}`));const f=o>0||a>0||i.length>0?`${o}x${a}${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/${f}`),typeof t!="boolean"&&(t.sizes||t.srcset)&&(e=e.replace(/<img.*?src=["|'](.*?)["|']/g,n=>{var l,c;const d=n.match(/a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g);if(d&&d.length>0){const h={srcset:(l=t.srcset)==null?void 0:l.map(u=>{if(typeof u=="number")return`//${d}/m/${u}x0${i} ${u}w`;if(typeof u=="object"&&u.length===2){let y=0,S=0;return typeof u[0]=="number"&&(y=u[0]),typeof u[1]=="number"&&(S=u[1]),`//${d}/m/${y}x${S}${i} ${y}w`}}).join(", "),sizes:(c=t.sizes)==null?void 0:c.map(u=>u).join(", ")};let m="";return h.srcset&&(m+=`srcset="${h.srcset}" `),h.sizes&&(m+=`sizes="${h.sizes}" `),n.replace(/<img/g,`<img ${m.trim()}`)}return n})),e}renderNode(e){const t=[];e.marks&&e.marks.forEach(a=>{const s=this.getMatchingMark(a);s&&t.push(this.renderOpeningTag(s.tag))});const o=this.getMatchingNode(e);return o&&o.tag&&t.push(this.renderOpeningTag(o.tag)),e.content?e.content.forEach(a=>{t.push(this.renderNode(a))}):e.text?t.push(de(e.text)):o&&o.singleTag?t.push(this.renderTag(o.singleTag," /")):o&&o.html?t.push(o.html):e.type==="emoji"&&t.push(this.renderEmoji(e)),o&&o.tag&&t.push(this.renderClosingTag(o.tag)),e.marks&&e.marks.slice(0).reverse().forEach(a=>{const s=this.getMatchingMark(a);s&&t.push(this.renderClosingTag(s.tag))}),t.join("")}renderTag(e,t){return e.constructor===String?`<${e}${t}>`:e.map(o=>{if(o.constructor===String)return`<${o}${t}>`;{let a=`<${o.tag}`;if(o.attrs)for(const s in o.attrs){const i=o.attrs[s];i!==null&&(a+=` ${s}="${i}"`)}return`${a}${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 he=r=>{if(typeof r!="object"||typeof r._editable>"u")return{};const e=JSON.parse(r._editable.replace(/^<!--#storyblok#/,"").replace(/-->$/,""));return{"data-blok-c":JSON.stringify(e),"data-blok-uid":e.id+"-"+e.uid}};let pe;const be="https://app.storyblok.com/f/storyblok-v2-latest.js",me=(r,e)=>{r.addNode("blok",t=>{let o="";return t.attrs.body.forEach(a=>{o+=e(a.component,a)}),{html:o}})},ye=(r,e,t)=>{let o=t||pe;if(!o){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return r===""?"":r?(e&&(o=new j(e.schema),e.resolver&&me(o,e.resolver)),o.render(r)):(console.warn(`${r} is not a valid Richtext object. This might be because the value of the richtext field is empty.
10
10
 
11
- For more info about the richtext object check https://github.com/storyblok/storyblok-js#rendering-rich-text`),"")},ye=()=>M(pe);function ke(){return globalThis.storyblokApiInstance||console.error("storyblokApiInstance has not been initialized correctly"),globalThis.storyblokApiInstance}function $e(r,e){const t=globalThis.storyblokApiInstance.richTextResolver;if(!t){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return me(r,e,t)}function ve(r){const e={useCustomApi:!1,bridge:!0,...r};return{name:"@storyblok/astro",hooks:{"astro:config:setup":({injectScript:t,updateConfig:s})=>{s({vite:{plugins:[f(e.accessToken,e.useCustomApi,e.apiOptions),z(e.components)]}}),t("page-ssr",`
11
+ For more info about the richtext object check https://github.com/storyblok/storyblok-js#rendering-rich-text`),"")},ke=()=>z(be);function $e(){return globalThis.storyblokApiInstance||console.error("storyblokApiInstance has not been initialized correctly"),globalThis.storyblokApiInstance}function ve(r,e){const t=globalThis.storyblokApiInstance.richTextResolver;if(!t){console.error("Please initialize the Storyblok SDK before calling the renderRichText function");return}return ye(r,e,t)}function Ie(r){const e={useCustomApi:!1,bridge:!0,componentsDir:"src",enableFallbackComponent:!1,...r};return{name:"@storyblok/astro",hooks:{"astro:config:setup":({injectScript:t,updateConfig:o})=>{o({vite:{plugins:[p(e.accessToken,e.useCustomApi,e.apiOptions),P(e.componentsDir,e.components,e.enableFallbackComponent,e.customFallbackComponent),_(e)]}}),t("page-ssr",`
12
12
  import { storyblokApiInstance } from "virtual:storyblok-init";
13
13
  globalThis.storyblokApiInstance = storyblokApiInstance;
14
14
  `),e.bridge&&t("page",`
@@ -23,4 +23,4 @@
23
23
  }
24
24
  });
25
25
  });
26
- `)}}}}c.RichTextResolver=j,c.RichTextSchema=E,c.default=ve,c.loadStoryblokBridge=ye,c.renderRichText=$e,c.storyblokEditable=de,c.useStoryblokApi=ke,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
26
+ `)}}}}g.RichTextResolver=j,g.RichTextSchema=E,g.default=Ie,g.loadStoryblokBridge=ke,g.renderRichText=ve,g.storyblokEditable=he,g.useStoryblokApi=$e,Object.defineProperties(g,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
@@ -1,13 +1,13 @@
1
- function A(r, e, t) {
2
- const s = "virtual:storyblok-init", a = "\0" + s;
1
+ function T(r, e, t) {
2
+ const o = "virtual:storyblok-init", a = "\0" + o;
3
3
  return {
4
4
  name: "vite-plugin-storyblok-init",
5
- async resolveId(o) {
6
- if (o === s)
5
+ async resolveId(s) {
6
+ if (s === o)
7
7
  return a;
8
8
  },
9
- async load(o) {
10
- if (o === a)
9
+ async load(s) {
10
+ if (s === a)
11
11
  return `
12
12
  import { storyblokInit, apiPlugin } from "@storyblok/js";
13
13
  const { storyblokApi } = storyblokInit({
@@ -20,14 +20,14 @@ function A(r, e, t) {
20
20
  }
21
21
  };
22
22
  }
23
- const j = /[\p{Lu}]/u, C = /[\p{Ll}]/u, y = /^[\p{Lu}](?![\p{Lu}])/gu, E = /([\p{Alpha}\p{N}_]|$)/u, p = /[_.\- ]+/, x = new RegExp("^" + p.source), k = new RegExp(p.source + E.source, "gu"), $ = new RegExp("\\d+" + E.source, "gu"), S = (r, e, t, s) => {
24
- let a = !1, o = !1, i = !1, g = !1;
25
- for (let n = 0; n < r.length; n++) {
26
- const l = r[n];
27
- g = n > 2 ? r[n - 3] === "-" : !0, a && j.test(l) ? (r = r.slice(0, n) + "-" + r.slice(n), a = !1, i = o, o = !0, n++) : o && i && C.test(l) && (!g || s) ? (r = r.slice(0, n - 1) + "-" + r.slice(n - 1), i = o, o = !1, a = !0) : (a = e(l) === l && t(l) !== l, i = o, o = t(l) === l && e(l) !== l);
23
+ const A = /[\p{Lu}]/u, j = /[\p{Ll}]/u, y = /^[\p{Lu}](?![\p{Lu}])/gu, E = /([\p{Alpha}\p{N}_]|$)/u, b = /[_.\- ]+/, x = new RegExp("^" + b.source), k = new RegExp(b.source + E.source, "gu"), $ = new RegExp("\\d+" + E.source, "gu"), S = (r, e, t, o) => {
24
+ let a = !1, s = !1, l = !1, u = !1;
25
+ for (let i = 0; i < r.length; i++) {
26
+ const n = r[i];
27
+ u = i > 2 ? r[i - 3] === "-" : !0, a && A.test(n) ? (r = r.slice(0, i) + "-" + r.slice(i), a = !1, l = s, s = !0, i++) : s && l && j.test(n) && (!u || o) ? (r = r.slice(0, i - 1) + "-" + r.slice(i - 1), l = s, s = !1, a = !0) : (a = e(n) === n && t(n) !== n, l = s, s = t(n) === n && e(n) !== n);
28
28
  }
29
29
  return r;
30
- }, R = (r, e) => (y.lastIndex = 0, r.replace(y, (t) => e(t))), N = (r, e) => (k.lastIndex = 0, $.lastIndex = 0, r.replace(k, (t, s) => e(s)).replace($, (t) => e(t)));
30
+ }, R = (r, e) => (y.lastIndex = 0, r.replace(y, (t) => e(t))), N = (r, e) => (k.lastIndex = 0, $.lastIndex = 0, r.replace(k, (t, o) => e(o)).replace($, (t) => e(t)));
31
31
  function v(r, e) {
32
32
  if (!(typeof r == "string" || Array.isArray(r)))
33
33
  throw new TypeError("Expected the input to be `string | string[]`");
@@ -35,35 +35,71 @@ function v(r, e) {
35
35
  pascalCase: !1,
36
36
  preserveConsecutiveUppercase: !1,
37
37
  ...e
38
- }, Array.isArray(r) ? r = r.map((o) => o.trim()).filter((o) => o.length).join("-") : r = r.trim(), r.length === 0)
38
+ }, Array.isArray(r) ? r = r.map((s) => s.trim()).filter((s) => s.length).join("-") : r = r.trim(), r.length === 0)
39
39
  return "";
40
- const t = e.locale === !1 ? (o) => o.toLowerCase() : (o) => o.toLocaleLowerCase(e.locale), s = e.locale === !1 ? (o) => o.toUpperCase() : (o) => o.toLocaleUpperCase(e.locale);
41
- return r.length === 1 ? p.test(r) ? "" : e.pascalCase ? s(r) : t(r) : (r !== t(r) && (r = S(r, t, s, e.preserveConsecutiveUppercase)), r = r.replace(x, ""), r = e.preserveConsecutiveUppercase ? R(r, t) : t(r), e.pascalCase && (r = s(r.charAt(0)) + r.slice(1)), N(r, s));
40
+ const t = e.locale === !1 ? (s) => s.toLowerCase() : (s) => s.toLocaleLowerCase(e.locale), o = e.locale === !1 ? (s) => s.toUpperCase() : (s) => s.toLocaleUpperCase(e.locale);
41
+ return r.length === 1 ? b.test(r) ? "" : e.pascalCase ? o(r) : t(r) : (r !== t(r) && (r = S(r, t, o, e.preserveConsecutiveUppercase)), r = r.replace(x, ""), r = e.preserveConsecutiveUppercase ? R(r, t) : t(r), e.pascalCase && (r = o(r.charAt(0)) + r.slice(1)), N(r, o));
42
42
  }
43
- function L(r) {
44
- const e = "virtual:storyblok-components", t = "\0" + e;
43
+ function L(r, e, t, o) {
44
+ const a = "virtual:storyblok-components", s = "\0" + a;
45
45
  return {
46
46
  name: "vite-plugin-storyblok-components",
47
- async resolveId(s) {
48
- if (s === e)
49
- return t;
47
+ async resolveId(l) {
48
+ if (l === a)
49
+ return s;
50
50
  },
51
- async load(s) {
52
- if (s === t) {
53
- const a = [];
54
- for await (const [o, i] of Object.entries(r)) {
55
- const g = await this.resolve("/src/" + i + ".astro");
56
- if (!g)
51
+ async load(l) {
52
+ if (l === s) {
53
+ const u = [], i = [];
54
+ for await (const [c, f] of Object.entries(e)) {
55
+ const d = await this.resolve(
56
+ "/" + r + "/" + f + ".astro"
57
+ );
58
+ if (d)
59
+ u.push(`import ${v(c)} from "${d.id}"`);
60
+ else if (t)
61
+ i.push(c);
62
+ else
57
63
  throw new Error(
58
- `Component could not be found for blok "${o}"! Does "/src/${i}.astro" exist?`
64
+ `Component could not be found for blok "${c}"! Does "${"/" + r + "/" + f}.astro" exist?`
59
65
  );
60
- a.push(`import ${v(o)} from "${g.id}"`);
61
66
  }
62
- return `${a.join(";")};export default {${Object.keys(r).map((o) => v(o)).join(",")}}`;
67
+ let n = "";
68
+ if (t)
69
+ if (n = ",FallbackComponent", o) {
70
+ const c = await this.resolve(
71
+ "/" + r + "/" + o + ".astro"
72
+ );
73
+ if (!c)
74
+ throw new Error(
75
+ `Custom fallback component could not be found. Does "${"/" + r + "/" + o}.astro" exist?`
76
+ );
77
+ u.push(
78
+ `import FallbackComponent from "${c.id}"`
79
+ );
80
+ } else
81
+ u.push(
82
+ "import FallbackComponent from '@storyblok/astro/FallbackComponent.astro';"
83
+ );
84
+ return `${u.join(";")};export default {${Object.keys(e).filter((c) => !i.includes(c)).map((c) => v(c)).join(",")}${n}}`;
63
85
  }
64
86
  }
65
87
  };
66
88
  }
89
+ function O(r) {
90
+ const e = "virtual:storyblok-options", t = "\0" + e;
91
+ return {
92
+ name: "vite-plugin-storyblok-options",
93
+ async resolveId(o) {
94
+ if (o === e)
95
+ return t;
96
+ },
97
+ async load(o) {
98
+ if (o === t)
99
+ return `export default ${JSON.stringify(r)}`;
100
+ }
101
+ };
102
+ }
67
103
  let I = !1;
68
104
  const w = [], z = (r) => new Promise((e, t) => {
69
105
  if (typeof window > "u" || (window.storyblokRegisterEvent = (a) => {
@@ -74,22 +110,22 @@ const w = [], z = (r) => new Promise((e, t) => {
74
110
  I ? a() : w.push(a);
75
111
  }, document.getElementById("storyblok-javascript-bridge")))
76
112
  return;
77
- const s = document.createElement("script");
78
- s.async = !0, s.src = r, s.id = "storyblok-javascript-bridge", s.onerror = (a) => t(a), s.onload = (a) => {
79
- w.forEach((o) => o()), I = !0, e(a);
80
- }, document.getElementsByTagName("head")[0].appendChild(s);
113
+ const o = document.createElement("script");
114
+ o.async = !0, o.src = r, o.id = "storyblok-javascript-bridge", o.onerror = (a) => t(a), o.onload = (a) => {
115
+ w.forEach((s) => s()), I = !0, e(a);
116
+ }, document.getElementsByTagName("head")[0].appendChild(o);
81
117
  });
82
- var O = Object.defineProperty, P = (r, e, t) => e in r ? O(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t, T = (r, e, t) => (P(r, typeof e != "symbol" ? e + "" : e, t), t);
118
+ var M = Object.defineProperty, P = (r, e, t) => e in r ? M(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t, C = (r, e, t) => (P(r, typeof e != "symbol" ? e + "" : e, t), t);
83
119
  const _ = function(r, e) {
84
120
  const t = {};
85
- for (const s in r) {
86
- const a = r[s];
87
- e.indexOf(s) > -1 && a !== null && (t[s] = a);
121
+ for (const o in r) {
122
+ const a = r[o];
123
+ e.indexOf(o) > -1 && a !== null && (t[o] = a);
88
124
  }
89
125
  return t;
90
- }, M = (r) => r === "email", D = () => ({
126
+ }, D = (r) => r === "email", U = () => ({
91
127
  singleTag: "hr"
92
- }), U = () => ({
128
+ }), F = () => ({
93
129
  tag: "blockquote"
94
130
  }), q = () => ({
95
131
  tag: "ul"
@@ -101,9 +137,9 @@ const _ = function(r, e) {
101
137
  attrs: r.attrs
102
138
  }
103
139
  ]
104
- }), F = () => ({
140
+ }), J = () => ({
105
141
  singleTag: "br"
106
- }), J = (r) => ({
142
+ }), K = (r) => ({
107
143
  tag: `h${r.attrs.level}`
108
144
  }), V = (r) => ({
109
145
  singleTag: [
@@ -114,11 +150,11 @@ const _ = function(r, e) {
114
150
  ]
115
151
  }), G = () => ({
116
152
  tag: "li"
117
- }), K = () => ({
118
- tag: "ol"
119
153
  }), W = () => ({
154
+ tag: "ol"
155
+ }), Y = () => ({
120
156
  tag: "p"
121
- }), Y = (r) => ({
157
+ }), H = (r) => ({
122
158
  tag: [
123
159
  {
124
160
  tag: "span",
@@ -129,23 +165,23 @@ const _ = function(r, e) {
129
165
  }
130
166
  }
131
167
  ]
132
- }), H = () => ({
133
- tag: "b"
134
168
  }), Q = () => ({
135
- tag: "strike"
169
+ tag: "b"
136
170
  }), X = () => ({
137
- tag: "u"
171
+ tag: "strike"
138
172
  }), Z = () => ({
139
- tag: "strong"
173
+ tag: "u"
140
174
  }), ee = () => ({
141
- tag: "code"
175
+ tag: "strong"
142
176
  }), te = () => ({
177
+ tag: "code"
178
+ }), re = () => ({
143
179
  tag: "i"
144
- }), re = (r) => {
180
+ }), oe = (r) => {
145
181
  const e = { ...r.attrs }, { linktype: t = "url" } = r.attrs;
146
- if (M(t) && (e.href = `mailto:${e.href}`), e.anchor && (e.href = `${e.href}#${e.anchor}`, delete e.anchor), e.custom) {
147
- for (const s in e.custom)
148
- e[s] = e.custom[s];
182
+ if (D(t) && (e.href = `mailto:${e.href}`), e.anchor && (e.href = `${e.href}#${e.anchor}`, delete e.anchor), e.custom) {
183
+ for (const o in e.custom)
184
+ e[o] = e.custom[o];
149
185
  delete e.custom;
150
186
  }
151
187
  return {
@@ -163,9 +199,9 @@ const _ = function(r, e) {
163
199
  attrs: r.attrs
164
200
  }
165
201
  ]
166
- }), oe = () => ({
167
- tag: "sub"
168
202
  }), ae = () => ({
203
+ tag: "sub"
204
+ }), le = () => ({
169
205
  tag: "sup"
170
206
  }), ie = (r) => ({
171
207
  tag: [
@@ -183,7 +219,7 @@ const _ = function(r, e) {
183
219
  }
184
220
  }
185
221
  ]
186
- }), le = (r) => ({
222
+ }), ce = (r) => ({
187
223
  tag: [
188
224
  {
189
225
  tag: "span",
@@ -192,48 +228,48 @@ const _ = function(r, e) {
192
228
  }
193
229
  }
194
230
  ]
195
- }), ce = {
231
+ }), ge = {
196
232
  nodes: {
197
- horizontal_rule: D,
198
- blockquote: U,
233
+ horizontal_rule: U,
234
+ blockquote: F,
199
235
  bullet_list: q,
200
236
  code_block: B,
201
- hard_break: F,
202
- heading: J,
237
+ hard_break: J,
238
+ heading: K,
203
239
  image: V,
204
240
  list_item: G,
205
- ordered_list: K,
206
- paragraph: W,
207
- emoji: Y
241
+ ordered_list: W,
242
+ paragraph: Y,
243
+ emoji: H
208
244
  },
209
245
  marks: {
210
- bold: H,
211
- strike: Q,
212
- underline: X,
213
- strong: Z,
214
- code: ee,
215
- italic: te,
216
- link: re,
246
+ bold: Q,
247
+ strike: X,
248
+ underline: Z,
249
+ strong: ee,
250
+ code: te,
251
+ italic: re,
252
+ link: oe,
217
253
  styled: se,
218
- subscript: oe,
219
- superscript: ae,
254
+ subscript: ae,
255
+ superscript: le,
220
256
  anchor: ie,
221
257
  highlight: ne,
222
- textStyle: le
258
+ textStyle: ce
223
259
  }
224
- }, ge = function(r) {
260
+ }, ue = function(r) {
225
261
  const e = {
226
262
  "&": "&amp;",
227
263
  "<": "&lt;",
228
264
  ">": "&gt;",
229
265
  '"': "&quot;",
230
266
  "'": "&#39;"
231
- }, t = /[&<>"']/g, s = RegExp(t.source);
232
- return r && s.test(r) ? r.replace(t, (a) => e[a]) : r;
267
+ }, t = /[&<>"']/g, o = RegExp(t.source);
268
+ return r && o.test(r) ? r.replace(t, (a) => e[a]) : r;
233
269
  };
234
- class ue {
270
+ class fe {
235
271
  constructor(e) {
236
- T(this, "marks"), T(this, "nodes"), e || (e = ce), this.marks = e.marks || [], this.nodes = e.nodes || [];
272
+ C(this, "marks"), C(this, "nodes"), e || (e = ge), this.marks = e.marks || [], this.nodes = e.nodes || [];
237
273
  }
238
274
  addNode(e, t) {
239
275
  this.nodes[e] = t;
@@ -243,69 +279,69 @@ class ue {
243
279
  }
244
280
  render(e, t = { optimizeImages: !1 }) {
245
281
  if (e && e.content && Array.isArray(e.content)) {
246
- let s = "";
282
+ let o = "";
247
283
  return e.content.forEach((a) => {
248
- s += this.renderNode(a);
249
- }), t.optimizeImages ? this.optimizeImages(s, t.optimizeImages) : s;
284
+ o += this.renderNode(a);
285
+ }), t.optimizeImages ? this.optimizeImages(o, t.optimizeImages) : o;
250
286
  }
251
287
  return console.warn(
252
288
  "The render method must receive an object with a content field, which is an array"
253
289
  ), "";
254
290
  }
255
291
  optimizeImages(e, t) {
256
- let s = 0, a = 0, o = "", i = "";
257
- typeof t != "boolean" && (typeof t.width == "number" && t.width > 0 && (o += `width="${t.width}" `, s = t.width), typeof t.height == "number" && t.height > 0 && (o += `height="${t.height}" `, a = t.height), (t.loading === "lazy" || t.loading === "eager") && (o += `loading="${t.loading}" `), typeof t.class == "string" && t.class.length > 0 && (o += `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))), o.length > 0 && (e = e.replace(/<img/g, `<img ${o.trim()}`));
258
- const g = s > 0 || a > 0 || i.length > 0 ? `${s}x${a}${i}` : "";
292
+ let o = 0, a = 0, s = "", l = "";
293
+ typeof t != "boolean" && (typeof t.width == "number" && t.width > 0 && (s += `width="${t.width}" `, o = t.width), typeof t.height == "number" && t.height > 0 && (s += `height="${t.height}" `, a = t.height), (t.loading === "lazy" || t.loading === "eager") && (s += `loading="${t.loading}" `), typeof t.class == "string" && t.class.length > 0 && (s += `class="${t.class}" `), t.filters && (typeof t.filters.blur == "number" && t.filters.blur >= 0 && t.filters.blur <= 100 && (l += `:blur(${t.filters.blur})`), typeof t.filters.brightness == "number" && t.filters.brightness >= -100 && t.filters.brightness <= 100 && (l += `:brightness(${t.filters.brightness})`), t.filters.fill && (t.filters.fill.match(/[0-9A-Fa-f]{6}/g) || t.filters.fill === "transparent") && (l += `:fill(${t.filters.fill})`), t.filters.format && ["webp", "png", "jpeg"].includes(t.filters.format) && (l += `:format(${t.filters.format})`), typeof t.filters.grayscale == "boolean" && t.filters.grayscale && (l += ":grayscale()"), typeof t.filters.quality == "number" && t.filters.quality >= 0 && t.filters.quality <= 100 && (l += `:quality(${t.filters.quality})`), t.filters.rotate && [90, 180, 270].includes(t.filters.rotate) && (l += `:rotate(${t.filters.rotate})`), l.length > 0 && (l = "/filters" + l))), s.length > 0 && (e = e.replace(/<img/g, `<img ${s.trim()}`));
294
+ const u = o > 0 || a > 0 || l.length > 0 ? `${o}x${a}${l}` : "";
259
295
  return e = e.replace(
260
296
  /a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g,
261
- `a.storyblok.com/f/$1/$2.$3/m/${g}`
262
- ), typeof t != "boolean" && (t.sizes || t.srcset) && (e = e.replace(/<img.*?src=["|'](.*?)["|']/g, (n) => {
263
- var l, m;
264
- const u = n.match(
297
+ `a.storyblok.com/f/$1/$2.$3/m/${u}`
298
+ ), typeof t != "boolean" && (t.sizes || t.srcset) && (e = e.replace(/<img.*?src=["|'](.*?)["|']/g, (i) => {
299
+ var n, c;
300
+ const f = i.match(
265
301
  /a.storyblok.com\/f\/(\d+)\/([^.]+)\.(gif|jpg|jpeg|png|tif|tiff|bmp)/g
266
302
  );
267
- if (u && u.length > 0) {
268
- const f = {
269
- srcset: (l = t.srcset) == null ? void 0 : l.map((c) => {
270
- if (typeof c == "number")
271
- return `//${u}/m/${c}x0${i} ${c}w`;
272
- if (typeof c == "object" && c.length === 2) {
273
- let h = 0, b = 0;
274
- return typeof c[0] == "number" && (h = c[0]), typeof c[1] == "number" && (b = c[1]), `//${u}/m/${h}x${b}${i} ${h}w`;
303
+ if (f && f.length > 0) {
304
+ const d = {
305
+ srcset: (n = t.srcset) == null ? void 0 : n.map((g) => {
306
+ if (typeof g == "number")
307
+ return `//${f}/m/${g}x0${l} ${g}w`;
308
+ if (typeof g == "object" && g.length === 2) {
309
+ let p = 0, m = 0;
310
+ return typeof g[0] == "number" && (p = g[0]), typeof g[1] == "number" && (m = g[1]), `//${f}/m/${p}x${m}${l} ${p}w`;
275
311
  }
276
312
  }).join(", "),
277
- sizes: (m = t.sizes) == null ? void 0 : m.map((c) => c).join(", ")
313
+ sizes: (c = t.sizes) == null ? void 0 : c.map((g) => g).join(", ")
278
314
  };
279
- let d = "";
280
- return f.srcset && (d += `srcset="${f.srcset}" `), f.sizes && (d += `sizes="${f.sizes}" `), n.replace(/<img/g, `<img ${d.trim()}`);
315
+ let h = "";
316
+ return d.srcset && (h += `srcset="${d.srcset}" `), d.sizes && (h += `sizes="${d.sizes}" `), i.replace(/<img/g, `<img ${h.trim()}`);
281
317
  }
282
- return n;
318
+ return i;
283
319
  })), e;
284
320
  }
285
321
  renderNode(e) {
286
322
  const t = [];
287
323
  e.marks && e.marks.forEach((a) => {
288
- const o = this.getMatchingMark(a);
289
- o && t.push(this.renderOpeningTag(o.tag));
324
+ const s = this.getMatchingMark(a);
325
+ s && t.push(this.renderOpeningTag(s.tag));
290
326
  });
291
- const s = this.getMatchingNode(e);
292
- return s && s.tag && t.push(this.renderOpeningTag(s.tag)), e.content ? e.content.forEach((a) => {
327
+ const o = this.getMatchingNode(e);
328
+ return o && o.tag && t.push(this.renderOpeningTag(o.tag)), e.content ? e.content.forEach((a) => {
293
329
  t.push(this.renderNode(a));
294
- }) : e.text ? t.push(ge(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((a) => {
295
- const o = this.getMatchingMark(a);
296
- o && t.push(this.renderClosingTag(o.tag));
330
+ }) : e.text ? t.push(ue(e.text)) : o && o.singleTag ? t.push(this.renderTag(o.singleTag, " /")) : o && o.html ? t.push(o.html) : e.type === "emoji" && t.push(this.renderEmoji(e)), o && o.tag && t.push(this.renderClosingTag(o.tag)), e.marks && e.marks.slice(0).reverse().forEach((a) => {
331
+ const s = this.getMatchingMark(a);
332
+ s && t.push(this.renderClosingTag(s.tag));
297
333
  }), t.join("");
298
334
  }
299
335
  renderTag(e, t) {
300
- return e.constructor === String ? `<${e}${t}>` : e.map((s) => {
301
- if (s.constructor === String)
302
- return `<${s}${t}>`;
336
+ return e.constructor === String ? `<${e}${t}>` : e.map((o) => {
337
+ if (o.constructor === String)
338
+ return `<${o}${t}>`;
303
339
  {
304
- let a = `<${s.tag}`;
305
- if (s.attrs)
306
- for (const o in s.attrs) {
307
- const i = s.attrs[o];
308
- i !== null && (a += ` ${o}="${i}"`);
340
+ let a = `<${o.tag}`;
341
+ if (o.attrs)
342
+ for (const s in o.attrs) {
343
+ const l = o.attrs[s];
344
+ l !== null && (a += ` ${s}="${l}"`);
309
345
  }
310
346
  return `${a}${t}>`;
311
347
  }
@@ -355,32 +391,32 @@ const me = (r) => {
355
391
  "data-blok-uid": e.id + "-" + e.uid
356
392
  };
357
393
  };
358
- let fe;
359
- const de = "https://app.storyblok.com/f/storyblok-v2-latest.js", he = (r, e) => {
394
+ let de;
395
+ const he = "https://app.storyblok.com/f/storyblok-v2-latest.js", pe = (r, e) => {
360
396
  r.addNode("blok", (t) => {
361
- let s = "";
397
+ let o = "";
362
398
  return t.attrs.body.forEach((a) => {
363
- s += e(a.component, a);
399
+ o += e(a.component, a);
364
400
  }), {
365
- html: s
401
+ html: o
366
402
  };
367
403
  });
368
- }, pe = (r, e, t) => {
369
- let s = t || fe;
370
- if (!s) {
404
+ }, be = (r, e, t) => {
405
+ let o = t || de;
406
+ if (!o) {
371
407
  console.error(
372
408
  "Please initialize the Storyblok SDK before calling the renderRichText function"
373
409
  );
374
410
  return;
375
411
  }
376
- return r === "" ? "" : r ? (e && (s = new ue(e.schema), e.resolver && he(s, e.resolver)), s.render(r)) : (console.warn(`${r} is not a valid Richtext object. This might be because the value of the richtext field is empty.
412
+ return r === "" ? "" : r ? (e && (o = new fe(e.schema), e.resolver && pe(o, e.resolver)), o.render(r)) : (console.warn(`${r} is not a valid Richtext object. This might be because the value of the richtext field is empty.
377
413
 
378
414
  For more info about the richtext object check https://github.com/storyblok/storyblok-js#rendering-rich-text`), "");
379
- }, be = () => z(de);
380
- function ye() {
415
+ }, ye = () => z(he);
416
+ function ke() {
381
417
  return globalThis.storyblokApiInstance || console.error("storyblokApiInstance has not been initialized correctly"), globalThis.storyblokApiInstance;
382
418
  }
383
- function ke(r, e) {
419
+ function $e(r, e) {
384
420
  const t = globalThis.storyblokApiInstance.richTextResolver;
385
421
  if (!t) {
386
422
  console.error(
@@ -388,27 +424,35 @@ function ke(r, e) {
388
424
  );
389
425
  return;
390
426
  }
391
- return pe(r, e, t);
427
+ return be(r, e, t);
392
428
  }
393
- function $e(r) {
429
+ function ve(r) {
394
430
  const e = {
395
431
  useCustomApi: !1,
396
432
  bridge: !0,
433
+ componentsDir: "src",
434
+ enableFallbackComponent: !1,
397
435
  ...r
398
436
  };
399
437
  return {
400
438
  name: "@storyblok/astro",
401
439
  hooks: {
402
- "astro:config:setup": ({ injectScript: t, updateConfig: s }) => {
403
- s({
440
+ "astro:config:setup": ({ injectScript: t, updateConfig: o }) => {
441
+ o({
404
442
  vite: {
405
443
  plugins: [
406
- A(
444
+ T(
407
445
  e.accessToken,
408
446
  e.useCustomApi,
409
447
  e.apiOptions
410
448
  ),
411
- L(e.components)
449
+ L(
450
+ e.componentsDir,
451
+ e.components,
452
+ e.enableFallbackComponent,
453
+ e.customFallbackComponent
454
+ ),
455
+ O(e)
412
456
  ]
413
457
  }
414
458
  }), t(
@@ -438,11 +482,11 @@ function $e(r) {
438
482
  };
439
483
  }
440
484
  export {
441
- ue as RichTextResolver,
442
- ce as RichTextSchema,
443
- $e as default,
444
- be as loadStoryblokBridge,
445
- ke as renderRichText,
485
+ fe as RichTextResolver,
486
+ ge as RichTextSchema,
487
+ ve as default,
488
+ ye as loadStoryblokBridge,
489
+ $e as renderRichText,
446
490
  me as storyblokEditable,
447
- ye as useStoryblokApi
491
+ ke as useStoryblokApi
448
492
  };
@@ -34,6 +34,19 @@ export type IntegrationOptions = {
34
34
  * ```
35
35
  */
36
36
  components?: object;
37
+ /**
38
+ * The directory containing your Astro components are. Defaults to "src".
39
+ */
40
+ componentsDir?: string;
41
+ /**
42
+ * Show a fallback component in your frontend if a component is not registered properly.
43
+ */
44
+ enableFallbackComponent?: boolean;
45
+ /**
46
+ * Provide a path to a custom fallback component, e.g. "storyblok/customFallback".
47
+ * Please note: the path takes into account the `componentsDir` option.
48
+ */
49
+ customFallbackComponent?: string;
37
50
  };
38
51
  export default function storyblokIntegration(options: IntegrationOptions): AstroIntegration;
39
52
  export * from "./types";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storyblok/astro",
3
- "version": "2.0.16",
3
+ "version": "2.2.0",
4
4
  "description": "Official Astro integration for the Storyblok Headless CMS",
5
5
  "main": "./dist/storyblok-astro.js",
6
6
  "module": "./dist/storyblok-astro.mjs",
@@ -13,7 +13,8 @@
13
13
  "import": "./dist/storyblok-astro.mjs",
14
14
  "require": "./dist/storyblok-astro.js"
15
15
  },
16
- "./StoryblokComponent.astro": "./StoryblokComponent.astro"
16
+ "./StoryblokComponent.astro": "./StoryblokComponent.astro",
17
+ "./FallbackComponent.astro": "./FallbackComponent.astro"
17
18
  },
18
19
  "types": "./dist/types/index.d.ts",
19
20
  "scripts": {
@@ -32,16 +33,16 @@
32
33
  "camelcase": "^7.0.1"
33
34
  },
34
35
  "devDependencies": {
35
- "@cypress/vite-dev-server": "^5.0.4",
36
+ "@cypress/vite-dev-server": "^5.0.5",
36
37
  "@rollup/plugin-dynamic-import-vars": "^2.0.3",
37
38
  "@types/node": "18.15.11",
38
- "astro": "2.1.8",
39
+ "astro": "2.3.0",
39
40
  "cypress": "^12.9.0",
40
- "eslint-plugin-cypress": "^2.12.1",
41
+ "eslint-plugin-cypress": "^2.13.2",
41
42
  "start-server-and-test": "^2.0.0",
42
- "typescript": "4.9.5",
43
+ "typescript": "5.0.4",
43
44
  "vite": "^4.2.1",
44
- "vite-plugin-dts": "^2.1.0"
45
+ "vite-plugin-dts": "^2.2.0"
45
46
  },
46
47
  "repository": {
47
48
  "type": "git",