@creopse/react 0.0.12 → 0.0.13
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/{index-jw_2nhs3.js → content-CM9eJ2st.js} +326 -6
- package/dist/{index-hI__ihu3.cjs → content-WeAhwlM_.cjs} +320 -0
- package/dist/hooks/index.cjs +7 -372
- package/dist/hooks/index.mjs +7 -372
- package/dist/index.cjs +202 -59
- package/dist/index.mjs +182 -39
- package/package.json +4 -2
- package/types/components/RootContainer/RootContainer.d.ts +1 -8
- package/types/components/RootContainer/index.d.ts +1 -1
- package/types/hooks/content.d.ts +1 -4
- package/types/hooks/setup.d.ts +7 -0
- package/types/index.d.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import React__default, { useState, useEffect, createContext, useRef, useLayoutEffect, useId, useContext, useInsertionEffect, useMemo, useCallback, Children, isValidElement, Fragment, createElement, forwardRef, Component } from "react";
|
|
3
|
-
import { u as useHelper,
|
|
3
|
+
import { u as useHelper, a as useContent, b as useProps, P as PropsContext, R as ResolveSectionsContext, c as cloneDeep, s as slideToId, E as EditorMessageType, d as RouterContext, C as ConfigContext } from "./content-CM9eJ2st.js";
|
|
4
4
|
import "@inertiajs/react";
|
|
5
5
|
import { createPortal } from "react-dom";
|
|
6
6
|
var jsxRuntime = { exports: {} };
|
|
@@ -8069,26 +8069,131 @@ const StickyTop = ({
|
|
|
8069
8069
|
}
|
|
8070
8070
|
);
|
|
8071
8071
|
};
|
|
8072
|
-
const
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8072
|
+
const byteToHex = [];
|
|
8073
|
+
for (let i = 0; i < 256; ++i) {
|
|
8074
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
8075
|
+
}
|
|
8076
|
+
function unsafeStringify(arr, offset = 0) {
|
|
8077
|
+
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
8078
|
+
}
|
|
8079
|
+
let getRandomValues;
|
|
8080
|
+
const rnds8 = new Uint8Array(16);
|
|
8081
|
+
function rng() {
|
|
8082
|
+
if (!getRandomValues) {
|
|
8083
|
+
if (typeof crypto === "undefined" || !crypto.getRandomValues) {
|
|
8084
|
+
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
8085
|
+
}
|
|
8086
|
+
getRandomValues = crypto.getRandomValues.bind(crypto);
|
|
8087
|
+
}
|
|
8088
|
+
return getRandomValues(rnds8);
|
|
8089
|
+
}
|
|
8090
|
+
const randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
8091
|
+
const native = { randomUUID };
|
|
8092
|
+
function _v4(options, buf, offset) {
|
|
8093
|
+
options = options || {};
|
|
8094
|
+
const rnds = options.random ?? options.rng?.() ?? rng();
|
|
8095
|
+
if (rnds.length < 16) {
|
|
8096
|
+
throw new Error("Random bytes length must be >= 16");
|
|
8097
|
+
}
|
|
8098
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
8099
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
8100
|
+
return unsafeStringify(rnds);
|
|
8101
|
+
}
|
|
8102
|
+
function v4(options, buf, offset) {
|
|
8103
|
+
if (native.randomUUID && true && !options) {
|
|
8104
|
+
return native.randomUUID();
|
|
8105
|
+
}
|
|
8106
|
+
return _v4(options);
|
|
8107
|
+
}
|
|
8108
|
+
const useSetup = () => {
|
|
8109
|
+
const getComponents = useCallback(
|
|
8110
|
+
(resolveSections) => {
|
|
8111
|
+
const components = {};
|
|
8112
|
+
if (!resolveSections) {
|
|
8113
|
+
throw new Error("[@creopse/react] resolveSections is required");
|
|
8114
|
+
}
|
|
8115
|
+
const files = resolveSections();
|
|
8116
|
+
for (const [key, value] of Object.entries(files)) {
|
|
8117
|
+
const componentName = key.replace(/^\.\/(.*)\.\w+$/, "$1");
|
|
8118
|
+
const parts = componentName.split("/");
|
|
8119
|
+
const name = parts[parts.length - 1]?.split(".")[0];
|
|
8120
|
+
components[name] = value.default;
|
|
8121
|
+
}
|
|
8122
|
+
return components;
|
|
8123
|
+
},
|
|
8124
|
+
[]
|
|
8125
|
+
);
|
|
8126
|
+
const getSectionsInOrder = useCallback(
|
|
8127
|
+
(props) => {
|
|
8128
|
+
const sections = props.pageData?.sections;
|
|
8129
|
+
const sectionsOrder = props.pageData?.sectionsOrder;
|
|
8130
|
+
const sectionsOrdered = [];
|
|
8131
|
+
if (Array.isArray(sections) && Array.isArray(sectionsOrder)) {
|
|
8132
|
+
for (const section of sectionsOrder) {
|
|
8133
|
+
if (section) {
|
|
8134
|
+
const item = sections.find(
|
|
8135
|
+
(value) => `${value.slug}__${value.pivot?.linkId}` === section
|
|
8136
|
+
);
|
|
8137
|
+
if (item) {
|
|
8138
|
+
sectionsOrdered.push(item);
|
|
8139
|
+
}
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
}
|
|
8143
|
+
return sectionsOrdered.length ? sectionsOrdered : sections || [];
|
|
8144
|
+
},
|
|
8145
|
+
[]
|
|
8146
|
+
);
|
|
8147
|
+
const getFinalPageSections = useCallback(
|
|
8148
|
+
(props) => {
|
|
8149
|
+
const sections = getSectionsInOrder(props);
|
|
8150
|
+
const sectionsDisabled = props.pageData?.sectionsDisabled;
|
|
8151
|
+
return sections.filter((section) => {
|
|
8152
|
+
return !sectionsDisabled?.includes(
|
|
8153
|
+
`${section.slug}__${section.pivot?.linkId}`
|
|
8154
|
+
);
|
|
8155
|
+
});
|
|
8156
|
+
},
|
|
8157
|
+
[getSectionsInOrder]
|
|
8158
|
+
);
|
|
8159
|
+
return {
|
|
8160
|
+
getComponents,
|
|
8161
|
+
getSectionsInOrder,
|
|
8162
|
+
getFinalPageSections
|
|
8163
|
+
};
|
|
8164
|
+
};
|
|
8165
|
+
const RootContainer = () => {
|
|
8166
|
+
const { page } = useContent();
|
|
8167
|
+
const props = useProps();
|
|
8168
|
+
const manager = useContext(PropsContext);
|
|
8169
|
+
const resolveSections = useContext(ResolveSectionsContext);
|
|
8170
|
+
const { getComponents, getFinalPageSections } = useSetup();
|
|
8171
|
+
const [sections, setSections] = useState(
|
|
8172
|
+
() => getFinalPageSections(props)
|
|
8173
|
+
);
|
|
8174
|
+
const [components] = useState(() => getComponents(resolveSections));
|
|
8175
|
+
const [sectionsWrapperKey, setSectionsWrapperKey] = useState(v4());
|
|
8176
|
+
const [sectionKeys, setSectionKeys] = useState({});
|
|
8177
|
+
const sectionsStateRef = useRef({});
|
|
8178
|
+
const pagePropsCopyRef = useRef(cloneDeep(props));
|
|
8077
8179
|
useEffect(() => {
|
|
8078
|
-
const
|
|
8079
|
-
|
|
8180
|
+
const keys = {};
|
|
8181
|
+
sections.forEach((section) => {
|
|
8182
|
+
keys[`${section.slug}__${section.pivot?.linkId}-key`] = v4();
|
|
8183
|
+
});
|
|
8184
|
+
setSectionKeys(keys);
|
|
8185
|
+
}, [sections]);
|
|
8186
|
+
useEffect(() => {
|
|
8187
|
+
const timer = setTimeout(() => {
|
|
8188
|
+
const sectionData = page.props.sectionData;
|
|
8080
8189
|
if (sectionData && sections.find(
|
|
8081
8190
|
(section) => section.slug === sectionData.slug && section.pivot?.linkId === sectionData.pivot?.linkId
|
|
8082
8191
|
)) {
|
|
8083
8192
|
slideToId(`${sectionData.slug}__${sectionData.pivot?.linkId}-container`);
|
|
8084
8193
|
}
|
|
8085
8194
|
}, 1e3);
|
|
8086
|
-
return () => clearTimeout(
|
|
8087
|
-
}, [page, sections]);
|
|
8088
|
-
const sectionsStateRef = useRef({});
|
|
8089
|
-
const sectionsRef = useRef(sections);
|
|
8090
|
-
const pageProps = useProps();
|
|
8091
|
-
console.log(pageProps);
|
|
8195
|
+
return () => clearTimeout(timer);
|
|
8196
|
+
}, [page.props.sectionData, sections]);
|
|
8092
8197
|
useEffect(() => {
|
|
8093
8198
|
const deselectAllSections = () => {
|
|
8094
8199
|
Object.keys(sectionsStateRef.current).forEach((key) => {
|
|
@@ -8111,7 +8216,7 @@ const RootContainer = ({
|
|
|
8111
8216
|
const primaryColor = event.data?.primaryColor ?? "blue";
|
|
8112
8217
|
sessionStorage.setItem("replyOrigin", event.origin);
|
|
8113
8218
|
sessionStorage.setItem("primaryColor", primaryColor);
|
|
8114
|
-
|
|
8219
|
+
sections?.forEach((section) => {
|
|
8115
8220
|
if (section.slug && section.pivot?.linkId) {
|
|
8116
8221
|
const sectionElementId = `${section.slug}__${section.pivot?.linkId}-container`;
|
|
8117
8222
|
const sectionElement = document.getElementById(sectionElementId);
|
|
@@ -8149,7 +8254,7 @@ const RootContainer = ({
|
|
|
8149
8254
|
break;
|
|
8150
8255
|
case EditorMessageType.SELECT_SIDEBAR_SECTION: {
|
|
8151
8256
|
setTimeout(() => {
|
|
8152
|
-
if (
|
|
8257
|
+
if (sections.find(
|
|
8153
8258
|
(section) => section.slug === event.data?.slug && section.pivot?.linkId === event.data?.linkId
|
|
8154
8259
|
)) {
|
|
8155
8260
|
slideToId(`${event.data?.slug}__${event.data?.linkId}-container`);
|
|
@@ -8167,30 +8272,64 @@ const RootContainer = ({
|
|
|
8167
8272
|
break;
|
|
8168
8273
|
}
|
|
8169
8274
|
case EditorMessageType.SEND_BASE_SECTION_SETTINGS:
|
|
8170
|
-
|
|
8171
|
-
|
|
8275
|
+
case EditorMessageType.SEND_SECTION_SETTINGS: {
|
|
8276
|
+
const sectionIndex = pagePropsCopyRef.current.pageData?.sections?.findIndex(
|
|
8277
|
+
(section) => section.slug === event.data?.slug && section.pivot?.linkId === event.data?.linkId
|
|
8278
|
+
);
|
|
8279
|
+
if (typeof sectionIndex !== "number" || sectionIndex === -1) {
|
|
8280
|
+
return;
|
|
8172
8281
|
}
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8282
|
+
if (pagePropsCopyRef.current.pageData?.sections && pagePropsCopyRef.current.pageData?.sections[sectionIndex].pivot?.settings) {
|
|
8283
|
+
pagePropsCopyRef.current.pageData.sections[sectionIndex].pivot.settings = event.data?.settings;
|
|
8284
|
+
manager?.sync(pagePropsCopyRef.current);
|
|
8285
|
+
setSectionKeys((prev) => ({
|
|
8286
|
+
...prev,
|
|
8287
|
+
[`${event.data?.slug}__${event.data?.linkId}-key`]: v4()
|
|
8288
|
+
}));
|
|
8177
8289
|
}
|
|
8178
8290
|
break;
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8291
|
+
}
|
|
8292
|
+
case EditorMessageType.SEND_BASE_SECTION_DATA:
|
|
8293
|
+
case EditorMessageType.SEND_SECTION_DATA: {
|
|
8294
|
+
const sectionIndex = pagePropsCopyRef.current.pageData?.sections?.findIndex(
|
|
8295
|
+
(section) => section.slug === event.data?.slug && section.pivot?.linkId === event.data?.linkId
|
|
8296
|
+
);
|
|
8297
|
+
if (typeof sectionIndex !== "number" || sectionIndex === -1) {
|
|
8298
|
+
return;
|
|
8182
8299
|
}
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8300
|
+
if (pagePropsCopyRef.current.pageData?.sections && pagePropsCopyRef.current.pageData?.sections[sectionIndex].pivot?.data) {
|
|
8301
|
+
pagePropsCopyRef.current.pageData.sections[sectionIndex].pivot.data = event.data?.data;
|
|
8302
|
+
manager?.sync(pagePropsCopyRef.current);
|
|
8303
|
+
setSectionKeys((prev) => ({
|
|
8304
|
+
...prev,
|
|
8305
|
+
[`${event.data?.slug}__${event.data?.linkId}-key`]: v4()
|
|
8306
|
+
}));
|
|
8187
8307
|
}
|
|
8188
8308
|
break;
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8309
|
+
}
|
|
8310
|
+
case EditorMessageType.SEND_PAGE_SECTIONS: {
|
|
8311
|
+
if (!pagePropsCopyRef.current.pageData) return;
|
|
8312
|
+
pagePropsCopyRef.current.pageData.sectionsOrder = event.data?.sectionsOrder;
|
|
8313
|
+
pagePropsCopyRef.current.pageData.sectionsDisabled = event.data?.sectionsDisabled;
|
|
8314
|
+
const currentSections = cloneDeep(
|
|
8315
|
+
pagePropsCopyRef.current.pageData.sections || []
|
|
8316
|
+
);
|
|
8317
|
+
pagePropsCopyRef.current.pageData.sections = event.data?.sectionsList || [];
|
|
8318
|
+
currentSections.forEach((currentSection) => {
|
|
8319
|
+
const sectionIndex = pagePropsCopyRef.current.pageData?.sections?.findIndex(
|
|
8320
|
+
(newSection) => newSection.slug === currentSection?.slug && newSection.pivot?.linkId === currentSection.pivot?.linkId
|
|
8321
|
+
);
|
|
8322
|
+
if (typeof sectionIndex === "number" && sectionIndex > -1 && pagePropsCopyRef.current.pageData?.sections?.[sectionIndex].pivot) {
|
|
8323
|
+
pagePropsCopyRef.current.pageData.sections[sectionIndex].pivot.data = currentSection.pivot?.data;
|
|
8324
|
+
pagePropsCopyRef.current.pageData.sections[sectionIndex].pivot.settings = currentSection.pivot?.settings;
|
|
8325
|
+
}
|
|
8326
|
+
});
|
|
8327
|
+
manager?.sync(pagePropsCopyRef.current);
|
|
8328
|
+
const newProps = manager?.getState().props;
|
|
8329
|
+
setSections(getFinalPageSections(newProps));
|
|
8330
|
+
setSectionsWrapperKey(v4());
|
|
8193
8331
|
break;
|
|
8332
|
+
}
|
|
8194
8333
|
}
|
|
8195
8334
|
};
|
|
8196
8335
|
window.addEventListener("message", handleMessage);
|
|
@@ -8206,15 +8345,19 @@ const RootContainer = ({
|
|
|
8206
8345
|
return () => {
|
|
8207
8346
|
window.removeEventListener("message", handleMessage);
|
|
8208
8347
|
};
|
|
8209
|
-
}, []);
|
|
8210
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8348
|
+
}, [sections, manager, getFinalPageSections]);
|
|
8349
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { all: "unset" }, children: sections.map((section) => {
|
|
8211
8350
|
const Component2 = components[section.name];
|
|
8212
|
-
|
|
8351
|
+
const key = sectionKeys[`${section.slug}__${section.pivot?.linkId}-key`];
|
|
8352
|
+
if (!Component2) {
|
|
8353
|
+
console.warn(`[@creopse/react] Component not found: ${section.name}`);
|
|
8354
|
+
return null;
|
|
8355
|
+
}
|
|
8213
8356
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8214
8357
|
"section",
|
|
8215
8358
|
{
|
|
8216
8359
|
id: `${section.slug}__${section.pivot?.linkId}-container`,
|
|
8217
|
-
|
|
8360
|
+
style: { all: "unset" },
|
|
8218
8361
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8219
8362
|
Component2,
|
|
8220
8363
|
{
|
|
@@ -8232,9 +8375,9 @@ const RootContainer = ({
|
|
|
8232
8375
|
}
|
|
8233
8376
|
)
|
|
8234
8377
|
},
|
|
8235
|
-
|
|
8378
|
+
key
|
|
8236
8379
|
);
|
|
8237
|
-
}) });
|
|
8380
|
+
}) }, sectionsWrapperKey);
|
|
8238
8381
|
};
|
|
8239
8382
|
function CreopseProvider({ children, options }) {
|
|
8240
8383
|
if (!options?.initialProps) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@creopse/react",
|
|
3
3
|
"description": "Creopse React Toolkit",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.13",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Noé Gnanih <noegnanih@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
"@vueuse/core": "^14.1.0",
|
|
48
48
|
"axios": "^1.13.2",
|
|
49
49
|
"framer-motion": "^12.23.9",
|
|
50
|
-
"lodash.clonedeep": "^4.5.0"
|
|
50
|
+
"lodash.clonedeep": "^4.5.0",
|
|
51
|
+
"uuid": "^13.0.0"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@eslint/js": "^9.30.1",
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
"@types/lodash.clonedeep": "^4.5.9",
|
|
57
58
|
"@types/react": "^19.1.8",
|
|
58
59
|
"@types/react-dom": "^19.1.6",
|
|
60
|
+
"@types/uuid": "^11.0.0",
|
|
59
61
|
"@types/validator": "^13.15.10",
|
|
60
62
|
"@vitejs/plugin-react": "^4.6.0",
|
|
61
63
|
"eslint": "^9.30.1",
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { type SectionModel } from '@creopse/utils';
|
|
3
|
-
export interface Props {
|
|
4
|
-
page: any;
|
|
5
|
-
sections: SectionModel[];
|
|
6
|
-
components: Record<string, React.ComponentType<any>>;
|
|
7
|
-
}
|
|
8
|
-
declare const RootContainer: React.FC<Props>;
|
|
1
|
+
declare const RootContainer: () => import("react/jsx-runtime").JSX.Element;
|
|
9
2
|
export default RootContainer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as RootContainer
|
|
1
|
+
export { default as RootContainer } from './RootContainer';
|
package/types/hooks/content.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppInformationKey, ContentModelItemModel, ContentModelModel, MenuItemGroupModel, MenuItemModel, MenuModel, NewsArticleModel, NewsCategoryModel, NewsTagModel, PageModel,
|
|
1
|
+
import type { AppInformationKey, ContentModelItemModel, ContentModelModel, MenuItemGroupModel, MenuItemModel, MenuModel, NewsArticleModel, NewsCategoryModel, NewsTagModel, PageModel, SettingType, SharedProps } from '@creopse/utils';
|
|
2
2
|
/**
|
|
3
3
|
* A hook that provides a set of functions and properties for
|
|
4
4
|
* easily accessing and manipulating page data, content models, menus,
|
|
@@ -32,10 +32,7 @@ export declare const useContent: () => {
|
|
|
32
32
|
getSectionSettingsGroup: (key: string | null | undefined, group: string) => object | any | null;
|
|
33
33
|
getSectionSetting: (key: string | null | undefined, group: string, name: string) => object | any | null;
|
|
34
34
|
getAnySectionData: (sectionSlug: string, pageSlug: string, linkId?: string) => Promise<any>;
|
|
35
|
-
getSectionsInOrder: () => SectionModel[];
|
|
36
|
-
getFinalPageSections: () => SectionModel[];
|
|
37
35
|
getSectionRootData: (key?: string) => any;
|
|
38
|
-
getComponents: () => Record<string, any>;
|
|
39
36
|
getContentModel: (name: string) => ContentModelModel | undefined;
|
|
40
37
|
getContentModelItems: (name: string, filterByIsActive?: boolean) => Promise<ContentModelItemModel[]>;
|
|
41
38
|
getPaginatedContentModelItems: (name: string, pageSize: number, filterByIsActive?: boolean) => Promise<{
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SectionModel } from '@creopse/utils';
|
|
2
|
+
import type { Props } from '../types/plugin';
|
|
3
|
+
export declare const useSetup: () => {
|
|
4
|
+
getComponents: (resolveSections?: () => Record<string, unknown>) => Record<string, any>;
|
|
5
|
+
getSectionsInOrder: <T extends Props = Props>(props: T) => SectionModel[];
|
|
6
|
+
getFinalPageSections: <T extends Props = Props>(props: T) => SectionModel[];
|
|
7
|
+
};
|
package/types/index.d.ts
CHANGED
|
@@ -13,6 +13,6 @@ export { MountedTeleport, type MountedTeleportProps, } from './components/widget
|
|
|
13
13
|
export { ReadMore, type ReadMoreProps } from './components/widgets/ReadMore';
|
|
14
14
|
export { StickyBottom, type StickyBottomProps, } from './components/widgets/StickyBottom';
|
|
15
15
|
export { StickyTop, type StickyTopProps } from './components/widgets/StickyTop';
|
|
16
|
-
export { RootContainer,
|
|
16
|
+
export { RootContainer, } from './components/RootContainer';
|
|
17
17
|
export type { PropsManager };
|
|
18
18
|
export type { PluginOptions };
|