@storyblok/astro 7.3.7 → 7.4.0-alpha.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/StoryblokServerData.astro +29 -0
- package/dist/index.d.ts +3 -1
- package/dist/lib/helpers.d.ts +46 -0
- package/dist/lib/sanitizeJSON.d.ts +30 -0
- package/dist/live-preview/middleware.ts +6 -7
- package/dist/public.d.ts +8 -0
- package/dist/storyblok-astro.es.js +935 -608
- package/dist/storyblok-astro.umd.js +13 -13
- package/dist/utils/isEditorRequest.d.ts +41 -0
- package/package.json +5 -3
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* StoryblokServerData Component
|
|
4
|
+
*
|
|
5
|
+
* Pass server-side data to the client that persists across live preview updates.
|
|
6
|
+
* All props passed to this component will be serialized as JSON and available
|
|
7
|
+
* to the client via the extraData parameter in getLiveStory().
|
|
8
|
+
*
|
|
9
|
+
* Data is automatically sanitized to prevent XSS attacks and script injection.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```astro
|
|
13
|
+
* ---
|
|
14
|
+
* import { StoryblokServerData } from '@storyblok/astro';
|
|
15
|
+
* const users = await getUsers();
|
|
16
|
+
* const config = { apiUrl: 'https://api.example.com' };
|
|
17
|
+
* ---
|
|
18
|
+
*
|
|
19
|
+
* <StoryblokServerData users={users} config={config} />
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { sanitizeJSON } from '@storyblok/astro';
|
|
24
|
+
|
|
25
|
+
const props = Astro.props;
|
|
26
|
+
const safeJson = sanitizeJSON(props);
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
<script is:inline id="__STORYBLOK_SERVERDATA__" type="application/json" set:html={safeJson} />
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/// <reference path="./public.d.ts" />
|
|
2
2
|
import { default as storyblokIntegration } from './lib/storyblok-integration';
|
|
3
|
-
export { getLiveStory, useStoryblokApi } from './lib/helpers';
|
|
3
|
+
export { getLiveStory, getPayload, useStoryblokApi } from './lib/helpers';
|
|
4
|
+
export { sanitizeJSON } from './lib/sanitizeJSON';
|
|
4
5
|
export type { IntegrationOptions } from './lib/storyblok-integration';
|
|
5
6
|
export { handleStoryblokMessage } from './live-preview/handleStoryblokMessage';
|
|
6
7
|
export * from './types';
|
|
8
|
+
export { isEditorRequest } from './utils/isEditorRequest';
|
|
7
9
|
export { toCamelCase } from './utils/toCamelCase';
|
|
8
10
|
export { loadStoryblokBridge, renderRichText, richTextResolver, storyblokEditable, } from '@storyblok/js';
|
|
9
11
|
export { storyblokIntegration as storyblok };
|
package/dist/lib/helpers.d.ts
CHANGED
|
@@ -23,6 +23,9 @@ export declare function useStoryblokApi(): StoryblokClient;
|
|
|
23
23
|
* This function is primarily useful when working with the Storyblok Visual Editor
|
|
24
24
|
* and live preview updates in an Astro project.
|
|
25
25
|
*
|
|
26
|
+
* @deprecated Use `getPayload()` instead for better type safety and to access both story and serverData.
|
|
27
|
+
* @see {@link getPayload}
|
|
28
|
+
*
|
|
26
29
|
* @param {Readonly<AstroGlobal>} Astro - The Astro global object.
|
|
27
30
|
* @returns {Promise<ISbStoryData | null>} The Storyblok story data if available,
|
|
28
31
|
* otherwise `null`.
|
|
@@ -36,4 +39,47 @@ export declare function useStoryblokApi(): StoryblokClient;
|
|
|
36
39
|
* ```
|
|
37
40
|
*/
|
|
38
41
|
export declare function getLiveStory(Astro: Readonly<AstroGlobal>): Promise<ISbStoryData | null>;
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves the live Storyblok story and server data from Astro's `locals` during preview mode.
|
|
44
|
+
*
|
|
45
|
+
* This function is primarily useful when working with the Storyblok Visual Editor
|
|
46
|
+
* and live preview updates in an Astro project.
|
|
47
|
+
*
|
|
48
|
+
* @template ServerData - The type of server data, constrained to StoryblokServerData
|
|
49
|
+
* @template Story - The type of story data, constrained to ISbStoryData
|
|
50
|
+
* @param {object} params - The function parameters
|
|
51
|
+
* @param {object} params.locals - The Astro locals object
|
|
52
|
+
* @returns {Promise<{ story?: Story; serverData?: ServerData }>} An object containing the story and serverData if available
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* // Basic usage:
|
|
57
|
+
* const payload = await getPayload({ locals: Astro.locals });
|
|
58
|
+
* const story = payload.story ?? null;
|
|
59
|
+
*
|
|
60
|
+
* // With typed server data:
|
|
61
|
+
* interface ServerData {
|
|
62
|
+
* users?: User[];
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* interface MyStory extends ISbStoryData {
|
|
66
|
+
* content: { myField: string };
|
|
67
|
+
* }
|
|
68
|
+
*
|
|
69
|
+
* const payload = await getPayload<ServerData, MyStory>({ locals: Astro.locals });
|
|
70
|
+
* const story = payload.story ?? null;
|
|
71
|
+
* const users = payload.serverData?.users ?? [];
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function getPayload<ServerData extends object = object, Story extends ISbStoryData = ISbStoryData>({ locals, }: {
|
|
75
|
+
locals: {
|
|
76
|
+
_storyblok_preview_data?: {
|
|
77
|
+
serverData?: ServerData;
|
|
78
|
+
story?: Story;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
}): Promise<{
|
|
82
|
+
story?: Story;
|
|
83
|
+
serverData?: ServerData;
|
|
84
|
+
}>;
|
|
39
85
|
export declare function initStoryblokBridge(config: boolean | StoryblokBridgeConfigV2): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safely serializes data to JSON and escapes characters that could break out of a script tag
|
|
3
|
+
* or execute malicious code when embedded in HTML.
|
|
4
|
+
*
|
|
5
|
+
* This prevents XSS attacks by escaping:
|
|
6
|
+
* - `</script>` tags that could close the script tag early
|
|
7
|
+
* - `<!--` and `-->` HTML comment sequences
|
|
8
|
+
* - Line separator (U+2028) and paragraph separator (U+2029) which are valid JSON but can break JS
|
|
9
|
+
* - Other potentially dangerous Unicode characters
|
|
10
|
+
*
|
|
11
|
+
* @param data - The data to serialize
|
|
12
|
+
* @returns A safe JSON string that can be embedded in HTML
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const safeJSON = sanitizeJSON({
|
|
17
|
+
* message: '</script><script>alert("XSS")</script>'
|
|
18
|
+
* });
|
|
19
|
+
* // Returns escaped version that won't execute
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function sanitizeJSON(data: unknown): string;
|
|
23
|
+
/**
|
|
24
|
+
* Parses JSON that was sanitized with sanitizeJSON()
|
|
25
|
+
* This is just JSON.parse but provided for symmetry and clarity
|
|
26
|
+
*
|
|
27
|
+
* @param json - The sanitized JSON string
|
|
28
|
+
* @returns The parsed data
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseSanitizedJSON<T = unknown>(json: string): T;
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { defineMiddleware } from 'astro/middleware';
|
|
2
|
+
import { isEditorRequest } from '@storyblok/astro';
|
|
2
3
|
|
|
3
4
|
export const onRequest = defineMiddleware(async ({ locals, request }, next) => {
|
|
4
5
|
if (request.method === 'POST') {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
= url.searchParams.has('_storyblok')
|
|
9
|
-
&& url.searchParams.has('_storyblok_c');
|
|
6
|
+
// First do a check if its coming from within storyblok
|
|
7
|
+
const editorRequest
|
|
8
|
+
= isEditorRequest(new URL(request.url));
|
|
10
9
|
|
|
11
|
-
if (
|
|
10
|
+
if (editorRequest) {
|
|
12
11
|
try {
|
|
13
12
|
// Create a copy of the request
|
|
14
13
|
const requestBody = await request.clone().json();
|
|
15
|
-
if (requestBody
|
|
14
|
+
if (requestBody?.story?.is_storyblok_preview) {
|
|
16
15
|
locals._storyblok_preview_data = requestBody;
|
|
17
16
|
}
|
|
18
17
|
}
|
package/dist/public.d.ts
CHANGED
|
@@ -16,6 +16,14 @@ declare module '@storyblok/astro/StoryblokComponent.astro' {
|
|
|
16
16
|
/** Renders a dynamic Storyblok component */
|
|
17
17
|
export default StoryblokComponent;
|
|
18
18
|
}
|
|
19
|
+
declare module '@storyblok/astro/StoryblokServerData.astro' {
|
|
20
|
+
function StoryblokServerData(
|
|
21
|
+
_props: Record<string, unknown>
|
|
22
|
+
): any;
|
|
23
|
+
|
|
24
|
+
/** Renders a dynamic Storyblok component */
|
|
25
|
+
export default StoryblokServerData;
|
|
26
|
+
}
|
|
19
27
|
declare module '@storyblok/astro/client' {
|
|
20
28
|
import type {
|
|
21
29
|
StoryblokClient,
|