@storyblok/astro 10.0.1 → 10.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/dist/components/StoryblokRichText.astro +2 -3
- package/dist/components/richtext/RenderLinkGroup.astro +1 -1
- package/dist/components/richtext/RenderNode.astro +12 -6
- package/dist/components/richtext/RenderTextNodeWithMarks.astro +1 -1
- package/dist/index.js +40 -26
- package/dist/utils/richtext-helpers.d.ts +1 -0
- package/dist/vite-plugins/vite-plugin-import-storyblok-components.d.ts +28 -4
- package/package.json +4 -4
|
@@ -6,9 +6,8 @@ interface Props extends SbAstroRichTextRenderContext {
|
|
|
6
6
|
document: SbRichTextInput;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const { document, components, optimizeImage } = Astro.props;
|
|
10
|
-
|
|
9
|
+
const { document, components, optimizeImage, data } = Astro.props;
|
|
11
10
|
const nodes = normalizeNodes(document);
|
|
12
11
|
---
|
|
13
12
|
|
|
14
|
-
<RenderChildren nodes={nodes} options={{ components, optimizeImage }} />
|
|
13
|
+
<RenderChildren nodes={nodes} options={{ components, optimizeImage, data }} />
|
|
@@ -19,16 +19,22 @@ interface Props {
|
|
|
19
19
|
}
|
|
20
20
|
const { node, options } = Astro.props;
|
|
21
21
|
const components = options.components;
|
|
22
|
-
const Custom = components
|
|
22
|
+
const Custom = components ? components[node.type] : undefined;
|
|
23
|
+
|
|
24
|
+
// When passing context to a custom component, exclude that component type
|
|
25
|
+
// to prevent infinite loops if the custom component uses StoryblokRichText internally
|
|
26
|
+
const contextForCustom = Custom
|
|
27
|
+
? { ...options, components: { ...components, [node.type]: undefined } }
|
|
28
|
+
: options;
|
|
23
29
|
---
|
|
24
30
|
|
|
25
31
|
{
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
<Custom {...node} context={options}>
|
|
30
|
-
{node.content && <RenderChildren nodes={node.content} options={options} />}
|
|
32
|
+
isValidAstroComponent(Custom) ? (
|
|
33
|
+
<Custom {...node} context={contextForCustom}>
|
|
34
|
+
{node.type !== 'text' && node.content && <RenderChildren nodes={node.content} options={options} />}
|
|
31
35
|
</Custom>
|
|
36
|
+
) : node.type === 'text' ? (
|
|
37
|
+
<RenderTextNodeWithMarks node={node} marks={node.marks} options={options} />
|
|
32
38
|
) : node.type === 'image' ? (
|
|
33
39
|
<RenderImage node={node} options={options} />
|
|
34
40
|
) : node.type === 'blok' ? (
|
|
@@ -23,7 +23,7 @@ const MarkComponent = mark && components ? components[mark.type] : undefined;
|
|
|
23
23
|
reversedMarks.length === 0 ? (
|
|
24
24
|
node.text
|
|
25
25
|
) : isValidAstroComponent(MarkComponent) ? (
|
|
26
|
-
<MarkComponent {...mark}>
|
|
26
|
+
<MarkComponent {...mark} context={options}>
|
|
27
27
|
<Astro.self node={node} marks={rest} options={options} />
|
|
28
28
|
</MarkComponent>
|
|
29
29
|
) : (
|
package/dist/index.js
CHANGED
|
@@ -113,13 +113,15 @@ function C(e, t, n, r) {
|
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
115
|
function w(e, t, n) {
|
|
116
|
+
let r = `${s(e)}/storyblok/**/*.astro`, i = [...n];
|
|
117
|
+
t && i.push(t);
|
|
118
|
+
let a = i.map((e) => e.importStatement), o = i.map((e) => e.wrapperDefinition), c = i.map((e) => e.registrationCall);
|
|
116
119
|
return `
|
|
117
|
-
// Import utilities and fallback component
|
|
118
120
|
import { toCamelCase } from '@storyblok/astro';
|
|
121
|
+
${a.join("\n ")}
|
|
122
|
+
|
|
123
|
+
const modules = import.meta.glob('${r}', { eager: true });
|
|
119
124
|
|
|
120
|
-
// Dynamically import all Storyblok components using Vite's glob import
|
|
121
|
-
const modules = import.meta.glob('${`${s(e)}/storyblok/**/*.astro`}', { eager: true });
|
|
122
|
-
// Process imported modules into a components object
|
|
123
125
|
const storyblokComponents = {};
|
|
124
126
|
const createComponentLoader = (module) => {
|
|
125
127
|
return async () => module?.default ?? module;
|
|
@@ -131,25 +133,24 @@ function w(e, t, n) {
|
|
|
131
133
|
get: () => createComponentLoader(component),
|
|
132
134
|
});
|
|
133
135
|
};
|
|
136
|
+
|
|
134
137
|
for (const filePath in modules) {
|
|
135
|
-
// Extract component name from file path (remove extension)
|
|
136
138
|
const fileName = filePath.split('/').pop();
|
|
137
|
-
const componentName = toCamelCase(fileName?.replace(
|
|
139
|
+
const componentName = toCamelCase(fileName?.replace(/\\.[^/.]+$/, '') ?? '');
|
|
138
140
|
if (componentName) {
|
|
139
141
|
registerComponent(componentName, modules[filePath]);
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// Export the components object for use in Storyblok initialization
|
|
144
|
+
|
|
145
|
+
${o.join("\n ")}
|
|
146
|
+
|
|
147
|
+
${c.join("\n ")}
|
|
148
|
+
|
|
148
149
|
export { storyblokComponents };
|
|
149
150
|
`.trim();
|
|
150
151
|
}
|
|
151
152
|
async function ee(e, t, n, r) {
|
|
152
|
-
if (!n) return
|
|
153
|
+
if (!n) return null;
|
|
153
154
|
if (!r) return D({
|
|
154
155
|
componentName: "FallbackComponent",
|
|
155
156
|
importPath: "@storyblok/astro/FallbackComponent.astro"
|
|
@@ -181,10 +182,12 @@ function E(e, t) {
|
|
|
181
182
|
return o(`${s(e)}${s(t)}`);
|
|
182
183
|
}
|
|
183
184
|
function D({ componentName: e, importPath: t }) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
let n = `__${e}_component__`, r = `__${e}_wrapper__`;
|
|
186
|
+
return {
|
|
187
|
+
importStatement: `import ${n} from '${t}';`,
|
|
188
|
+
wrapperDefinition: `const ${r} = { get default() { return ${n}; } };`,
|
|
189
|
+
registrationCall: `registerComponent('${e}', ${r});`
|
|
190
|
+
};
|
|
188
191
|
}
|
|
189
192
|
//#endregion
|
|
190
193
|
//#region src/lib/storyblok-integration.ts
|
|
@@ -949,13 +952,22 @@ function dt(e, t) {
|
|
|
949
952
|
return n?.length ? pt(n, t) : "";
|
|
950
953
|
}
|
|
951
954
|
function q(e, t) {
|
|
955
|
+
let n = e.type !== "text" && e.content ? pt(e.content, t) : "", r = t?.renderers?.[e.type];
|
|
956
|
+
if (r) {
|
|
957
|
+
let i = t?.renderers?.[e.type] ? {
|
|
958
|
+
...t,
|
|
959
|
+
renderers: {
|
|
960
|
+
...t.renderers,
|
|
961
|
+
[e.type]: void 0
|
|
962
|
+
}
|
|
963
|
+
} : t;
|
|
964
|
+
return r({
|
|
965
|
+
...e,
|
|
966
|
+
children: n,
|
|
967
|
+
context: i
|
|
968
|
+
});
|
|
969
|
+
}
|
|
952
970
|
if (e.type === "text") return mt(e, e.marks, t);
|
|
953
|
-
let n = e.content ? pt(e.content, t) : "", r = t?.renderers?.[e.type];
|
|
954
|
-
if (r) return r({
|
|
955
|
-
...e,
|
|
956
|
-
children: n,
|
|
957
|
-
context: t
|
|
958
|
-
});
|
|
959
971
|
if (e.type === "blok") return console.warn("\"blok\" nodes require a custom renderer in renderRichText."), "";
|
|
960
972
|
let i = G(e);
|
|
961
973
|
if (!i) return n;
|
|
@@ -1001,7 +1013,8 @@ function ht(e, t, n) {
|
|
|
1001
1013
|
let r = n?.renderers?.[t.type];
|
|
1002
1014
|
if (r) return r({
|
|
1003
1015
|
...t,
|
|
1004
|
-
children: e
|
|
1016
|
+
children: e,
|
|
1017
|
+
context: n
|
|
1005
1018
|
});
|
|
1006
1019
|
let i = G(t);
|
|
1007
1020
|
return i ? `<${i}${J(t.type, t.attrs)}>${e}</${i}>` : e;
|
|
@@ -1015,7 +1028,8 @@ function gt(e, t, n, r, i) {
|
|
|
1015
1028
|
let o = i?.renderers?.[r.type];
|
|
1016
1029
|
if (o) return o({
|
|
1017
1030
|
...r,
|
|
1018
|
-
children: a
|
|
1031
|
+
children: a,
|
|
1032
|
+
context: i
|
|
1019
1033
|
});
|
|
1020
1034
|
let s = G(r);
|
|
1021
1035
|
return s ? `<${s}${J(r.type, r.attrs)}>${a}</${s}>` : a;
|
|
@@ -1611,7 +1625,7 @@ var Ht = class {
|
|
|
1611
1625
|
}
|
|
1612
1626
|
return { storyblokApi: new Ut(t) };
|
|
1613
1627
|
}, Jt = (e) => {
|
|
1614
|
-
if (typeof e != "object" || typeof e._editable
|
|
1628
|
+
if (typeof e != "object" || typeof e._editable != "string") return {};
|
|
1615
1629
|
try {
|
|
1616
1630
|
let t = JSON.parse(e._editable.replace(/^<!--#storyblok#/, "").replace(/-->$/, ""));
|
|
1617
1631
|
return t ? {
|
|
@@ -6,6 +6,7 @@ export type SbAstroRichTextComponentMap = {
|
|
|
6
6
|
export interface SbAstroRichTextRenderContext {
|
|
7
7
|
optimizeImage?: boolean | SbRichTextImageOptions;
|
|
8
8
|
components?: SbAstroRichTextComponentMap;
|
|
9
|
+
data?: unknown;
|
|
9
10
|
}
|
|
10
11
|
export type SbAstroRichTextProps<T extends SbRichTextElement> = SbRichTextElementByType<SbAstroRichTextRenderContext>[T];
|
|
11
12
|
export declare function isValidAstroComponent(component: unknown): component is AstroComponentFactory;
|
|
@@ -1,8 +1,32 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
/**
|
|
3
|
-
* Vite plugin that
|
|
4
|
-
* and merges them with
|
|
5
|
-
*
|
|
6
|
-
* @returns Vite plugin object
|
|
3
|
+
* Vite plugin that auto-imports Storyblok components from a directory
|
|
4
|
+
* and merges them with user-provided component mappings.
|
|
7
5
|
*/
|
|
8
6
|
export declare function vitePluginImportStoryblokComponents(components: Record<string, string>, componentsDir: string, enableFallbackComponent: boolean, customFallbackComponent?: string): Plugin;
|
|
7
|
+
export interface ComponentRegistrationParts {
|
|
8
|
+
importStatement: string;
|
|
9
|
+
wrapperDefinition: string;
|
|
10
|
+
registrationCall: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generates the virtual module code with:
|
|
14
|
+
* - Static imports at the top for proper hoisting
|
|
15
|
+
* - Glob-imported components from storyblok folder
|
|
16
|
+
* - Manual and fallback component registrations
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateModuleCode(componentsDir: string, fallbackRegistration: ComponentRegistrationParts | null, manualRegistrations: ComponentRegistrationParts[]): string;
|
|
19
|
+
interface CreateComponentRegistrationPartsOptions {
|
|
20
|
+
componentName: string;
|
|
21
|
+
importPath: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generates structured registration parts for a component.
|
|
25
|
+
*
|
|
26
|
+
* Uses a getter wrapper to avoid TDZ (Temporal Dead Zone) errors.
|
|
27
|
+
* When Vite bundles modules, direct references to imported components
|
|
28
|
+
* can cause "Cannot access 'X' before initialization" errors.
|
|
29
|
+
* The getter defers access until the component is actually needed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createComponentRegistrationParts({ componentName, importPath, }: CreateComponentRegistrationPartsOptions): ComponentRegistrationParts;
|
|
32
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyblok/astro",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "10.0
|
|
4
|
+
"version": "10.2.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Official Astro integration for the Storyblok Headless CMS",
|
|
7
7
|
"author": "Storyblok",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"camelcase": "^8.0.0",
|
|
53
53
|
"morphdom": "^2.7.8",
|
|
54
|
-
"@storyblok/
|
|
55
|
-
"@storyblok/
|
|
54
|
+
"@storyblok/js": "6.2.0",
|
|
55
|
+
"@storyblok/richtext": "5.2.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@cypress/vite-dev-server": "^6.0.3",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"vite-plugin-dts": "^4.5.3",
|
|
74
74
|
"vite-plugin-static-copy": "^4.1.1",
|
|
75
75
|
"vitest": "^3.1.3",
|
|
76
|
-
"@storyblok/eslint-config": "0.
|
|
76
|
+
"@storyblok/eslint-config": "0.6.0"
|
|
77
77
|
},
|
|
78
78
|
"eslintConfig": {
|
|
79
79
|
"env": {
|