@storyblok/astro 4.0.5 → 4.1.0-next.1
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/storyblok-astro.js +15 -17
- package/dist/storyblok-astro.mjs +935 -331
- package/dist/types/components/FallbackComponent.d.ts +1 -2
- package/dist/types/components/RichTextRenderer.d.ts +1 -2
- package/dist/types/components/StoryblokComponent.d.ts +1 -2
- package/dist/types/index.d.ts +8 -5
- package/dist/types/live-preview/handleStoryblokMessage.d.ts +1 -0
- package/dist/types/live-preview/middleware.d.ts +1 -0
- package/dist/types/types.d.ts +1 -1
- package/dist/types/utils/generateFinalBridgeObject.d.ts +3 -0
- package/dist/types/utils/parseAstCode.d.ts +1 -0
- package/dist/types/vite-plugins/vite-plugin-storyblok-bridge.d.ts +2 -0
- package/dist/types/vite-plugins/vite-plugin-storyblok-components.d.ts +1 -2
- package/dist/types/vite-plugins/vite-plugin-storyblok-init.d.ts +2 -3
- package/dist/types/vite-plugins/vite-plugin-storyblok-options.d.ts +1 -2
- package/live-preview/handleStoryblokMessage.ts +57 -0
- package/live-preview/middleware.ts +11 -0
- package/package.json +13 -4
- package/utils/generateFinalBridgeObject.ts +32 -0
- package/utils/parseAstCode.ts +41 -0
- package/vite-plugins/vite-plugin-storyblok-bridge.ts +69 -0
- package/vite-plugins/vite-plugin-storyblok-components.ts +124 -0
- package/vite-plugins/vite-plugin-storyblok-init.ts +33 -0
- package/vite-plugins/vite-plugin-storyblok-options.ts +20 -0
package/dist/types/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export {
|
|
1
|
+
import type { AstroIntegration, AstroGlobal } from "astro";
|
|
2
|
+
import type { ISbConfig, ISbRichtext, ISbStoriesParams, ISbStoryData, SbRichTextOptions, StoryblokBridgeConfigV2, StoryblokClient } from "./types";
|
|
3
|
+
export { storyblokEditable, loadStoryblokBridge, RichTextResolver, RichTextSchema, } from "@storyblok/js";
|
|
4
|
+
export { handleStoryblokMessage } from "./live-preview/handleStoryblokMessage";
|
|
5
5
|
export declare function useStoryblokApi(): StoryblokClient;
|
|
6
|
+
export declare function useStoryblok(slug: string, apiOptions: ISbStoriesParams, bridgeOptions: StoryblokBridgeConfigV2, Astro: AstroGlobal): Promise<ISbStoryData<import("@storyblok/js").StoryblokComponentType<string> & {
|
|
7
|
+
[index: string]: any;
|
|
8
|
+
}>>;
|
|
6
9
|
export declare function renderRichText(data?: ISbRichtext, options?: SbRichTextOptions): string;
|
|
7
10
|
export type IntegrationOptions = {
|
|
8
11
|
/**
|
|
@@ -49,4 +52,4 @@ export type IntegrationOptions = {
|
|
|
49
52
|
customFallbackComponent?: string;
|
|
50
53
|
};
|
|
51
54
|
export default function storyblokIntegration(options: IntegrationOptions): AstroIntegration;
|
|
52
|
-
export * from
|
|
55
|
+
export * from "./types";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleStoryblokMessage(event: any): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const onRequest: import("astro").MiddlewareHandler;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseAstRawCode(astCode: any): any;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import type { ISbConfig } from "../types";
|
|
2
|
+
import type { Plugin } from "vite";
|
|
4
3
|
export declare function vitePluginStoryblokInit(accessToken: string, useCustomApi: boolean, apiOptions: ISbConfig): Plugin;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export async function handleStoryblokMessage(event) {
|
|
2
|
+
const { action, story } = event || {};
|
|
3
|
+
//in the case of input event
|
|
4
|
+
if (action === "input" && story) {
|
|
5
|
+
const currentBody = document.body;
|
|
6
|
+
|
|
7
|
+
const newBody = await getNewHTMLBody(story);
|
|
8
|
+
if (newBody.outerHTML === currentBody.outerHTML) return;
|
|
9
|
+
|
|
10
|
+
//Get current focused element in storyblok
|
|
11
|
+
const focusedElem = document.querySelector('[data-blok-focused="true"]');
|
|
12
|
+
updateDOMWithNewBody(currentBody, newBody, focusedElem);
|
|
13
|
+
} else if (["published", "change"].includes(event?.data?.action)) {
|
|
14
|
+
location.reload();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function updateDOMWithNewBody(currentBody, newBody, focusedElem) {
|
|
18
|
+
if (focusedElem) {
|
|
19
|
+
//Get the [data-blok-uid] of the focused element in storyblok
|
|
20
|
+
const focusedElementID = focusedElem.getAttribute("data-blok-uid");
|
|
21
|
+
//Now find the same element by above [data-blok-uid] in our new virtual HTML page
|
|
22
|
+
const newDomFocusElem = newBody.querySelector(
|
|
23
|
+
`[data-blok-uid="${focusedElementID}"]`
|
|
24
|
+
);
|
|
25
|
+
if (newDomFocusElem) {
|
|
26
|
+
// Add the [data-blok-focused] attribute to the above element
|
|
27
|
+
newDomFocusElem.setAttribute("data-blok-focused", "true");
|
|
28
|
+
console.log("Doing partial replace");
|
|
29
|
+
focusedElem.replaceWith(newDomFocusElem);
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
//We can make this part even better
|
|
33
|
+
// const allStoryblokElem =
|
|
34
|
+
// document.querySelectorAll('[data-blok-uid]')
|
|
35
|
+
// console.log({ allStoryblokElem })
|
|
36
|
+
|
|
37
|
+
console.log("Doing full replace");
|
|
38
|
+
currentBody.replaceWith(newBody);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function getNewHTMLBody(story) {
|
|
43
|
+
const result = await fetch(location.href, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
body: JSON.stringify({
|
|
46
|
+
...story,
|
|
47
|
+
is_storyblok_preview: true,
|
|
48
|
+
}),
|
|
49
|
+
headers: {
|
|
50
|
+
"Content-Type": "application/json",
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
const html = await result.text();
|
|
54
|
+
const parser = new DOMParser();
|
|
55
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
56
|
+
return doc.body;
|
|
57
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineMiddleware } from "astro/middleware";
|
|
2
|
+
|
|
3
|
+
export const onRequest = defineMiddleware(async ({ locals, request }, next) => {
|
|
4
|
+
if (request["method"] === "POST") {
|
|
5
|
+
const requestBody = await request.json();
|
|
6
|
+
if (requestBody && requestBody["is_storyblok_preview"]) {
|
|
7
|
+
locals["_storyblok_preview_data"] = requestBody;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return next();
|
|
11
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyblok/astro",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.1.0-next.1",
|
|
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",
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
"dist",
|
|
9
9
|
"components",
|
|
10
10
|
"dev-toolbar",
|
|
11
|
-
"live-preview"
|
|
11
|
+
"live-preview",
|
|
12
|
+
"utils",
|
|
13
|
+
"vite-plugins"
|
|
12
14
|
],
|
|
13
15
|
"exports": {
|
|
14
16
|
".": {
|
|
@@ -35,6 +37,11 @@
|
|
|
35
37
|
"types": "./dev-toolbar/toolbarApp.ts",
|
|
36
38
|
"import": "./dev-toolbar/toolbarApp.ts",
|
|
37
39
|
"require": "./dev-toolbar/toolbarApp.ts"
|
|
40
|
+
},
|
|
41
|
+
"./middleware.ts": {
|
|
42
|
+
"types": "./live-preview/middleware.ts",
|
|
43
|
+
"import": "./live-preview/middleware.ts",
|
|
44
|
+
"require": "./live-preview/middleware.ts"
|
|
38
45
|
}
|
|
39
46
|
},
|
|
40
47
|
"types": "./dist/types/index.d.ts",
|
|
@@ -51,11 +58,13 @@
|
|
|
51
58
|
},
|
|
52
59
|
"dependencies": {
|
|
53
60
|
"@storyblok/js": "^3.0.8",
|
|
54
|
-
"camelcase": "^8.0.0"
|
|
61
|
+
"camelcase": "^8.0.0",
|
|
62
|
+
"lodash.mergewith": "^4.6.2"
|
|
55
63
|
},
|
|
56
64
|
"devDependencies": {
|
|
57
65
|
"@cypress/vite-dev-server": "^5.0.7",
|
|
58
66
|
"@rollup/plugin-dynamic-import-vars": "^2.1.2",
|
|
67
|
+
"@types/lodash.mergewith": "^4.6.9",
|
|
59
68
|
"@types/node": "20.12.7",
|
|
60
69
|
"astro": "^4.6.3",
|
|
61
70
|
"cypress": "^13.8.0",
|
|
@@ -63,7 +72,7 @@
|
|
|
63
72
|
"start-server-and-test": "^2.0.3",
|
|
64
73
|
"typescript": "5.4.5",
|
|
65
74
|
"vite": "^5.2.10",
|
|
66
|
-
"vite-plugin-dts": "^3.
|
|
75
|
+
"vite-plugin-dts": "^3.7.3"
|
|
67
76
|
},
|
|
68
77
|
"peerDependencies": {
|
|
69
78
|
"astro": "^3.0.0 || ^4.0.0"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function generateFinalBridgeObject(rawCode: any) {
|
|
2
|
+
let mergedOptions = {
|
|
3
|
+
resolveRelations: [],
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
function addToResolveRelations(
|
|
7
|
+
resolveRelations: string[] | string | undefined
|
|
8
|
+
) {
|
|
9
|
+
if (resolveRelations) {
|
|
10
|
+
if (Array.isArray(resolveRelations)) {
|
|
11
|
+
mergedOptions.resolveRelations.push(...resolveRelations);
|
|
12
|
+
} else {
|
|
13
|
+
mergedOptions.resolveRelations.push(resolveRelations);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
for (const item of rawCode) {
|
|
19
|
+
if (item.options) {
|
|
20
|
+
const { apiOptions, bridgeOptions } = item.options;
|
|
21
|
+
addToResolveRelations(apiOptions?.resolve_relations);
|
|
22
|
+
if (bridgeOptions) {
|
|
23
|
+
const { resolveRelations, ...rest } = bridgeOptions;
|
|
24
|
+
addToResolveRelations(resolveRelations);
|
|
25
|
+
Object.assign(mergedOptions, rest);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
mergedOptions.resolveRelations = [...new Set(mergedOptions.resolveRelations)];
|
|
30
|
+
|
|
31
|
+
return mergedOptions;
|
|
32
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import mergeWith from "lodash.mergewith";
|
|
2
|
+
|
|
3
|
+
export function parseAstRawCode(astCode) {
|
|
4
|
+
let obj;
|
|
5
|
+
function customizer(_, srcValue) {
|
|
6
|
+
if (
|
|
7
|
+
srcValue?.type === "AwaitExpression" &&
|
|
8
|
+
srcValue?.argument?.callee?.name === "useStoryblok"
|
|
9
|
+
) {
|
|
10
|
+
const props = srcValue?.argument?.arguments;
|
|
11
|
+
if (props[1]?.type === "ObjectExpression") {
|
|
12
|
+
obj = {
|
|
13
|
+
...obj,
|
|
14
|
+
apiOptions: getAstPropToObj(props[1]?.properties),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (props[2]?.type === "ObjectExpression") {
|
|
18
|
+
obj = {
|
|
19
|
+
...obj,
|
|
20
|
+
bridgeOptions: getAstPropToObj(props[2]?.properties),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
mergeWith({}, astCode, customizer);
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getAstPropToObj(properties) {
|
|
31
|
+
return properties.reduce((options, { key, value }) => {
|
|
32
|
+
const { type } = value;
|
|
33
|
+
options[key.name] =
|
|
34
|
+
type === "Literal"
|
|
35
|
+
? value.value
|
|
36
|
+
: type === "ArrayExpression"
|
|
37
|
+
? value.elements.map((v) => v.value)
|
|
38
|
+
: value.value;
|
|
39
|
+
return options;
|
|
40
|
+
}, {});
|
|
41
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import { parseAstRawCode } from "../utils/parseAstCode";
|
|
3
|
+
import { generateFinalBridgeObject } from "../utils/generateFinalBridgeObject";
|
|
4
|
+
let previousRawCode = [];
|
|
5
|
+
|
|
6
|
+
export function vitePluginStoryblokBridge(): Plugin {
|
|
7
|
+
let rawCode = [];
|
|
8
|
+
const virtualModuleId = "virtual:storyblok-bridge";
|
|
9
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
10
|
+
let _server = null;
|
|
11
|
+
let restartTimeout = null;
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
name: "vite-plugin-storyblok-bridge",
|
|
15
|
+
async resolveId(id: string) {
|
|
16
|
+
if (id === virtualModuleId) {
|
|
17
|
+
return resolvedVirtualModuleId;
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
async transform(code, id) {
|
|
21
|
+
if (id.includes("node_modules") && !id.includes("/pages/")) return;
|
|
22
|
+
if (!code.includes("useStoryblok")) return;
|
|
23
|
+
const moduleInfo = this.getModuleInfo(id);
|
|
24
|
+
if (!moduleInfo.meta?.astro) return;
|
|
25
|
+
const [, ...routeArray] = id.split("src/pages/");
|
|
26
|
+
const url = routeArray.join("/").replace(".astro", "");
|
|
27
|
+
const options = parseAstRawCode(this.parse(code));
|
|
28
|
+
if (previousRawCode.length) {
|
|
29
|
+
rawCode = previousRawCode.filter((i) => i.url !== url);
|
|
30
|
+
}
|
|
31
|
+
rawCode.push({
|
|
32
|
+
url,
|
|
33
|
+
options,
|
|
34
|
+
});
|
|
35
|
+
if (!_server) return;
|
|
36
|
+
if (restartTimeout) {
|
|
37
|
+
clearTimeout(restartTimeout);
|
|
38
|
+
}
|
|
39
|
+
restartTimeout = setTimeout(() => {
|
|
40
|
+
if (alreadyHaveThisUrl(previousRawCode, rawCode)) return;
|
|
41
|
+
if (previousRawCode.length !== 0) {
|
|
42
|
+
_server.restart();
|
|
43
|
+
console.info("Updating bridge options...");
|
|
44
|
+
}
|
|
45
|
+
previousRawCode = [...rawCode];
|
|
46
|
+
}, 1000);
|
|
47
|
+
},
|
|
48
|
+
async load(id: string) {
|
|
49
|
+
if (id === resolvedVirtualModuleId) {
|
|
50
|
+
return `export const bridgeOptions = ${JSON.stringify(generateFinalBridgeObject(rawCode))}`;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
configureServer(server) {
|
|
54
|
+
_server = server;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface ParsedCodeObj {
|
|
60
|
+
url: string;
|
|
61
|
+
options: any;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function alreadyHaveThisUrl(a: ParsedCodeObj[] = [], b: ParsedCodeObj[] = []) {
|
|
65
|
+
return b.every(({ url, options }) => {
|
|
66
|
+
const aCopy = a.find((e) => e?.url === url);
|
|
67
|
+
return aCopy && JSON.stringify(options) === JSON.stringify(aCopy.options);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Vite plugin by Tony Sull (https://github.com/tony-sull)
|
|
3
|
+
*/
|
|
4
|
+
import camelcase from "camelcase";
|
|
5
|
+
import type { Plugin } from "vite";
|
|
6
|
+
|
|
7
|
+
export function vitePluginStoryblokComponents(
|
|
8
|
+
componentsDir: string,
|
|
9
|
+
components?: object,
|
|
10
|
+
enableFallbackComponent?: boolean,
|
|
11
|
+
customFallbackComponent?: string
|
|
12
|
+
): Plugin {
|
|
13
|
+
const virtualModuleId = "virtual:storyblok-components";
|
|
14
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
name: "vite-plugin-storyblok-components",
|
|
18
|
+
async resolveId(id: string) {
|
|
19
|
+
if (id === virtualModuleId) {
|
|
20
|
+
return resolvedVirtualModuleId;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
async load(id: string) {
|
|
24
|
+
if (id === resolvedVirtualModuleId) {
|
|
25
|
+
/**
|
|
26
|
+
* Handle registered components
|
|
27
|
+
*/
|
|
28
|
+
const imports: string[] = [];
|
|
29
|
+
const excludedKeys: string[] = [];
|
|
30
|
+
for await (const [key, value] of Object.entries(components)) {
|
|
31
|
+
const resolvedId = await this.resolve(
|
|
32
|
+
"/" + componentsDir + "/" + value + ".astro"
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* if the component cannot be resolved
|
|
37
|
+
*/
|
|
38
|
+
if (!resolvedId) {
|
|
39
|
+
if (enableFallbackComponent) {
|
|
40
|
+
/**
|
|
41
|
+
* if showFallbackComponent is enabled, the current component key needs to be excluded from the imports
|
|
42
|
+
* otherwise the attempted import would result in an error
|
|
43
|
+
*/
|
|
44
|
+
excludedKeys.push(key);
|
|
45
|
+
} else {
|
|
46
|
+
/**
|
|
47
|
+
* if it is not enabled, throw a specific error here
|
|
48
|
+
*/
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Component could not be found for blok "${key}"! Does "${
|
|
51
|
+
"/" + componentsDir + "/" + value
|
|
52
|
+
}.astro" exist?`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
/**
|
|
57
|
+
* if the component can be resolved, add it to the imports array
|
|
58
|
+
* important: convert blok names to camel case for valid import names
|
|
59
|
+
* StoryblokComponent.astro needs to do the same when resolving components!
|
|
60
|
+
*/
|
|
61
|
+
imports.push(`import ${camelcase(key)} from "${resolvedId.id}"`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Handle custom fallback component
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
let fallbackComponentKey: string = "";
|
|
70
|
+
|
|
71
|
+
if (enableFallbackComponent) {
|
|
72
|
+
fallbackComponentKey = ",FallbackComponent";
|
|
73
|
+
if (customFallbackComponent) {
|
|
74
|
+
/**
|
|
75
|
+
* resolve custom FallbackComponent defined in astro.config.mjs
|
|
76
|
+
*/
|
|
77
|
+
const fallbackComponentResolvedId = await this.resolve(
|
|
78
|
+
"/" + componentsDir + "/" + customFallbackComponent + ".astro"
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
if (!fallbackComponentResolvedId) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Custom fallback component could not be found. Does "${
|
|
84
|
+
"/" + componentsDir + "/" + customFallbackComponent
|
|
85
|
+
}.astro" exist?`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
imports.push(
|
|
90
|
+
`import FallbackComponent from "${fallbackComponentResolvedId.id}"`
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
/**
|
|
94
|
+
* import default FallbackComponent bundled with @storyblok/astro
|
|
95
|
+
*/
|
|
96
|
+
imports.push(
|
|
97
|
+
`import FallbackComponent from '@storyblok/astro/FallbackComponent.astro'`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!Object.values(components).length) {
|
|
103
|
+
/**
|
|
104
|
+
* If no components are registered in astro.config.mjs, either export just the fallback component (default or custom),
|
|
105
|
+
* or throw an error.
|
|
106
|
+
*/
|
|
107
|
+
if (enableFallbackComponent) {
|
|
108
|
+
return `${
|
|
109
|
+
imports[0]
|
|
110
|
+
}; export default {${fallbackComponentKey.replace(",", "")}}`;
|
|
111
|
+
}
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Currently, no Storyblok components are registered in astro.config.mjs.\nPlease register your components or enable the fallback component.\nDetailed information can be found here: https://github.com/storyblok/storyblok-astro`
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
return `${imports.join(";")};export default {${Object.keys(components)
|
|
117
|
+
.filter((key) => !excludedKeys.includes(key))
|
|
118
|
+
.map((key) => camelcase(key))
|
|
119
|
+
.join(",")}${fallbackComponentKey}}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ISbConfig } from "../types";
|
|
2
|
+
import type { Plugin } from "vite";
|
|
3
|
+
|
|
4
|
+
export function vitePluginStoryblokInit(
|
|
5
|
+
accessToken: string,
|
|
6
|
+
useCustomApi: boolean,
|
|
7
|
+
apiOptions: ISbConfig
|
|
8
|
+
): Plugin {
|
|
9
|
+
const virtualModuleId = "virtual:storyblok-init";
|
|
10
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
name: "vite-plugin-storyblok-init",
|
|
14
|
+
async resolveId(id: string) {
|
|
15
|
+
if (id === virtualModuleId) {
|
|
16
|
+
return resolvedVirtualModuleId;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
async load(id: string) {
|
|
20
|
+
if (id === resolvedVirtualModuleId) {
|
|
21
|
+
return `
|
|
22
|
+
import { storyblokInit, apiPlugin } from "@storyblok/js";
|
|
23
|
+
const { storyblokApi } = storyblokInit({
|
|
24
|
+
accessToken: "${accessToken}",
|
|
25
|
+
use: ${useCustomApi ? "[]" : "[apiPlugin]"},
|
|
26
|
+
apiOptions: ${JSON.stringify(apiOptions)},
|
|
27
|
+
});
|
|
28
|
+
export const storyblokApiInstance = storyblokApi;
|
|
29
|
+
`;
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
export function vitePluginStoryblokOptions(options: object): Plugin {
|
|
4
|
+
const virtualModuleId = `virtual:storyblok-options`;
|
|
5
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
name: "vite-plugin-storyblok-options",
|
|
9
|
+
async resolveId(id: string) {
|
|
10
|
+
if (id === virtualModuleId) {
|
|
11
|
+
return resolvedVirtualModuleId;
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
async load(id: string) {
|
|
15
|
+
if (id === resolvedVirtualModuleId) {
|
|
16
|
+
return `export default ${JSON.stringify(options)}`;
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|