@fluid-app/portal-core 0.1.16
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/chunk-CKQMccvm.cjs +28 -0
- package/dist/data-sources/DataAwareWidget.cjs +50 -0
- package/dist/data-sources/DataAwareWidget.cjs.map +1 -0
- package/dist/data-sources/DataAwareWidget.d.cts +24 -0
- package/dist/data-sources/DataAwareWidget.d.cts.map +1 -0
- package/dist/data-sources/DataAwareWidget.d.mts +24 -0
- package/dist/data-sources/DataAwareWidget.d.mts.map +1 -0
- package/dist/data-sources/DataAwareWidget.mjs +48 -0
- package/dist/data-sources/DataAwareWidget.mjs.map +1 -0
- package/dist/data-sources/ErrorState.cjs +20 -0
- package/dist/data-sources/ErrorState.cjs.map +1 -0
- package/dist/data-sources/ErrorState.d.cts +7 -0
- package/dist/data-sources/ErrorState.d.cts.map +1 -0
- package/dist/data-sources/ErrorState.d.mts +7 -0
- package/dist/data-sources/ErrorState.d.mts.map +1 -0
- package/dist/data-sources/ErrorState.mjs +18 -0
- package/dist/data-sources/ErrorState.mjs.map +1 -0
- package/dist/data-sources/context.cjs +24 -0
- package/dist/data-sources/context.cjs.map +1 -0
- package/dist/data-sources/context.d.cts +21 -0
- package/dist/data-sources/context.d.cts.map +1 -0
- package/dist/data-sources/context.d.mts +21 -0
- package/dist/data-sources/context.d.mts.map +1 -0
- package/dist/data-sources/context.mjs +21 -0
- package/dist/data-sources/context.mjs.map +1 -0
- package/dist/data-sources/fetchers/api.cjs +65 -0
- package/dist/data-sources/fetchers/api.cjs.map +1 -0
- package/dist/data-sources/fetchers/api.d.cts +10 -0
- package/dist/data-sources/fetchers/api.d.cts.map +1 -0
- package/dist/data-sources/fetchers/api.d.mts +10 -0
- package/dist/data-sources/fetchers/api.d.mts.map +1 -0
- package/dist/data-sources/fetchers/api.mjs +64 -0
- package/dist/data-sources/fetchers/api.mjs.map +1 -0
- package/dist/data-sources/fetchers/custom.cjs +108 -0
- package/dist/data-sources/fetchers/custom.cjs.map +1 -0
- package/dist/data-sources/fetchers/custom.d.cts +17 -0
- package/dist/data-sources/fetchers/custom.d.cts.map +1 -0
- package/dist/data-sources/fetchers/custom.d.mts +17 -0
- package/dist/data-sources/fetchers/custom.d.mts.map +1 -0
- package/dist/data-sources/fetchers/custom.mjs +107 -0
- package/dist/data-sources/fetchers/custom.mjs.map +1 -0
- package/dist/data-sources/fetchers/static.cjs +161 -0
- package/dist/data-sources/fetchers/static.cjs.map +1 -0
- package/dist/data-sources/fetchers/static.d.cts +40 -0
- package/dist/data-sources/fetchers/static.d.cts.map +1 -0
- package/dist/data-sources/fetchers/static.d.mts +40 -0
- package/dist/data-sources/fetchers/static.d.mts.map +1 -0
- package/dist/data-sources/fetchers/static.mjs +158 -0
- package/dist/data-sources/fetchers/static.mjs.map +1 -0
- package/dist/data-sources/preview-context.cjs +21 -0
- package/dist/data-sources/preview-context.cjs.map +1 -0
- package/dist/data-sources/preview-context.d.cts +13 -0
- package/dist/data-sources/preview-context.d.cts.map +1 -0
- package/dist/data-sources/preview-context.d.mts +13 -0
- package/dist/data-sources/preview-context.d.mts.map +1 -0
- package/dist/data-sources/preview-context.mjs +18 -0
- package/dist/data-sources/preview-context.mjs.map +1 -0
- package/dist/data-sources/registry-context.cjs +53 -0
- package/dist/data-sources/registry-context.cjs.map +1 -0
- package/dist/data-sources/registry-context.d.cts +48 -0
- package/dist/data-sources/registry-context.d.cts.map +1 -0
- package/dist/data-sources/registry-context.d.mts +48 -0
- package/dist/data-sources/registry-context.d.mts.map +1 -0
- package/dist/data-sources/registry-context.mjs +49 -0
- package/dist/data-sources/registry-context.mjs.map +1 -0
- package/dist/data-sources/registry.cjs +31 -0
- package/dist/data-sources/registry.cjs.map +1 -0
- package/dist/data-sources/registry.d.cts +19 -0
- package/dist/data-sources/registry.d.cts.map +1 -0
- package/dist/data-sources/registry.d.mts +19 -0
- package/dist/data-sources/registry.d.mts.map +1 -0
- package/dist/data-sources/registry.mjs +29 -0
- package/dist/data-sources/registry.mjs.map +1 -0
- package/dist/data-sources/transformers.cjs +154 -0
- package/dist/data-sources/transformers.cjs.map +1 -0
- package/dist/data-sources/transformers.d.cts +10 -0
- package/dist/data-sources/transformers.d.cts.map +1 -0
- package/dist/data-sources/transformers.d.mts +10 -0
- package/dist/data-sources/transformers.d.mts.map +1 -0
- package/dist/data-sources/transformers.mjs +153 -0
- package/dist/data-sources/transformers.mjs.map +1 -0
- package/dist/data-sources/types.cjs +0 -0
- package/dist/data-sources/types.d.cts +2 -0
- package/dist/data-sources/types.d.mts +2 -0
- package/dist/data-sources/types.mjs +1 -0
- package/dist/data-sources/use-widget-data.cjs +111 -0
- package/dist/data-sources/use-widget-data.cjs.map +1 -0
- package/dist/data-sources/use-widget-data.d.cts +17 -0
- package/dist/data-sources/use-widget-data.d.cts.map +1 -0
- package/dist/data-sources/use-widget-data.d.mts +17 -0
- package/dist/data-sources/use-widget-data.d.mts.map +1 -0
- package/dist/data-sources/use-widget-data.mjs +109 -0
- package/dist/data-sources/use-widget-data.mjs.map +1 -0
- package/dist/index-B5cTNde-.d.cts +246 -0
- package/dist/index-B5cTNde-.d.cts.map +1 -0
- package/dist/index-Cqt2JzkQ.d.mts +246 -0
- package/dist/index-Cqt2JzkQ.d.mts.map +1 -0
- package/dist/registries/index.cjs +243 -0
- package/dist/registries/index.cjs.map +1 -0
- package/dist/registries/index.d.cts +338 -0
- package/dist/registries/index.d.cts.map +1 -0
- package/dist/registries/index.d.mts +338 -0
- package/dist/registries/index.d.mts.map +1 -0
- package/dist/registries/index.mjs +229 -0
- package/dist/registries/index.mjs.map +1 -0
- package/dist/shell/AppShellLayout.cjs +49 -0
- package/dist/shell/AppShellLayout.cjs.map +1 -0
- package/dist/shell/AppShellLayout.d.cts +39 -0
- package/dist/shell/AppShellLayout.d.cts.map +1 -0
- package/dist/shell/AppShellLayout.d.mts +39 -0
- package/dist/shell/AppShellLayout.d.mts.map +1 -0
- package/dist/shell/AppShellLayout.mjs +46 -0
- package/dist/shell/AppShellLayout.mjs.map +1 -0
- package/dist/shell/ScreenHeader.cjs +44 -0
- package/dist/shell/ScreenHeader.cjs.map +1 -0
- package/dist/shell/ScreenHeader.d.cts +12 -0
- package/dist/shell/ScreenHeader.d.cts.map +1 -0
- package/dist/shell/ScreenHeader.d.mts +12 -0
- package/dist/shell/ScreenHeader.d.mts.map +1 -0
- package/dist/shell/ScreenHeader.mjs +42 -0
- package/dist/shell/ScreenHeader.mjs.map +1 -0
- package/dist/shell/ScreenHeaderContext.cjs +91 -0
- package/dist/shell/ScreenHeaderContext.cjs.map +1 -0
- package/dist/shell/ScreenHeaderContext.d.cts +35 -0
- package/dist/shell/ScreenHeaderContext.d.cts.map +1 -0
- package/dist/shell/ScreenHeaderContext.d.mts +35 -0
- package/dist/shell/ScreenHeaderContext.d.mts.map +1 -0
- package/dist/shell/ScreenHeaderContext.mjs +86 -0
- package/dist/shell/ScreenHeaderContext.mjs.map +1 -0
- package/dist/shell/ThemeModeContext.cjs +70 -0
- package/dist/shell/ThemeModeContext.cjs.map +1 -0
- package/dist/shell/ThemeModeContext.d.cts +33 -0
- package/dist/shell/ThemeModeContext.d.cts.map +1 -0
- package/dist/shell/ThemeModeContext.d.mts +33 -0
- package/dist/shell/ThemeModeContext.d.mts.map +1 -0
- package/dist/shell/ThemeModeContext.mjs +66 -0
- package/dist/shell/ThemeModeContext.mjs.map +1 -0
- package/dist/shell/index.cjs +43 -0
- package/dist/shell/index.d.cts +7 -0
- package/dist/shell/index.d.mts +7 -0
- package/dist/shell/index.mjs +7 -0
- package/dist/shell/sidebar.cjs +390 -0
- package/dist/shell/sidebar.cjs.map +1 -0
- package/dist/shell/sidebar.d.cts +85 -0
- package/dist/shell/sidebar.d.cts.map +1 -0
- package/dist/shell/sidebar.d.mts +85 -0
- package/dist/shell/sidebar.d.mts.map +1 -0
- package/dist/shell/sidebar.mjs +364 -0
- package/dist/shell/sidebar.mjs.map +1 -0
- package/dist/shell/use-mobile.cjs +51 -0
- package/dist/shell/use-mobile.cjs.map +1 -0
- package/dist/shell/use-mobile.d.cts +7 -0
- package/dist/shell/use-mobile.d.cts.map +1 -0
- package/dist/shell/use-mobile.d.mts +7 -0
- package/dist/shell/use-mobile.d.mts.map +1 -0
- package/dist/shell/use-mobile.mjs +47 -0
- package/dist/shell/use-mobile.mjs.map +1 -0
- package/dist/theme/index.cjs +758 -0
- package/dist/theme/index.cjs.map +1 -0
- package/dist/theme/index.d.cts +131 -0
- package/dist/theme/index.d.cts.map +1 -0
- package/dist/theme/index.d.mts +131 -0
- package/dist/theme/index.d.mts.map +1 -0
- package/dist/theme/index.mjs +728 -0
- package/dist/theme/index.mjs.map +1 -0
- package/dist/types/index.cjs +18 -0
- package/dist/types/index.d.cts +4 -0
- package/dist/types/index.d.mts +4 -0
- package/dist/types/index.mjs +2 -0
- package/dist/types-27AHMek-.d.cts +85 -0
- package/dist/types-27AHMek-.d.cts.map +1 -0
- package/dist/types-BXFX9bXp.cjs +303 -0
- package/dist/types-BXFX9bXp.cjs.map +1 -0
- package/dist/types-Bjmd7Fdx.mjs +208 -0
- package/dist/types-Bjmd7Fdx.mjs.map +1 -0
- package/dist/types-C5Zs5V3E.d.mts +155 -0
- package/dist/types-C5Zs5V3E.d.mts.map +1 -0
- package/dist/types-CeCPKvOv.d.mts +85 -0
- package/dist/types-CeCPKvOv.d.mts.map +1 -0
- package/dist/types-DrzvahW8.d.cts +155 -0
- package/dist/types-DrzvahW8.d.cts.map +1 -0
- package/dist/widget-schema-BKZgsNG7.d.mts +119 -0
- package/dist/widget-schema-BKZgsNG7.d.mts.map +1 -0
- package/dist/widget-schema-BSX2fVhW.d.cts +119 -0
- package/dist/widget-schema-BSX2fVhW.d.cts.map +1 -0
- package/dist/widget-utils/index.cjs +130 -0
- package/dist/widget-utils/index.cjs.map +1 -0
- package/dist/widget-utils/index.d.cts +47 -0
- package/dist/widget-utils/index.d.cts.map +1 -0
- package/dist/widget-utils/index.d.mts +47 -0
- package/dist/widget-utils/index.d.mts.map +1 -0
- package/dist/widget-utils/index.mjs +119 -0
- package/dist/widget-utils/index.mjs.map +1 -0
- package/package.json +200 -0
- package/src/styles/globals.css +1 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
Object.defineProperty(exports, "__toESM", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function() {
|
|
26
|
+
return __toESM;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../chunk-CKQMccvm.cjs");
|
|
3
|
+
const require_data_sources_use_widget_data = require("./use-widget-data.cjs");
|
|
4
|
+
const require_data_sources_ErrorState = require("./ErrorState.cjs");
|
|
5
|
+
let react = require("react");
|
|
6
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
|
+
//#region src/data-sources/DataAwareWidget.tsx
|
|
8
|
+
const EMPTY_OBJECT = {};
|
|
9
|
+
/**
|
|
10
|
+
* Wrapper component that resolves data sources before rendering the widget.
|
|
11
|
+
* Merges resolved data with static props.
|
|
12
|
+
*/
|
|
13
|
+
function DataAwareWidgetImpl({ widget, Component, additionalProps, loadingComponent, errorComponent, baseUrl }) {
|
|
14
|
+
const stableAdditionalProps = additionalProps ?? EMPTY_OBJECT;
|
|
15
|
+
const { data, isLoading, error } = require_data_sources_use_widget_data.useWidgetData(widget, { baseUrl });
|
|
16
|
+
const mergedProps = (0, react.useMemo)(() => ({
|
|
17
|
+
...widget.props,
|
|
18
|
+
...data,
|
|
19
|
+
...stableAdditionalProps
|
|
20
|
+
}), [
|
|
21
|
+
widget.props,
|
|
22
|
+
data,
|
|
23
|
+
stableAdditionalProps
|
|
24
|
+
]);
|
|
25
|
+
if (isLoading && widget.dataSource?.loading?.showSkeleton !== false) {
|
|
26
|
+
if (loadingComponent) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: loadingComponent });
|
|
27
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
28
|
+
className: "bg-muted animate-pulse rounded-md",
|
|
29
|
+
style: { minHeight: 100 },
|
|
30
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
31
|
+
className: "sr-only",
|
|
32
|
+
children: "Loading..."
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (error && !data) {
|
|
37
|
+
if (errorComponent) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: errorComponent(error) });
|
|
38
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_data_sources_ErrorState.ErrorState, {});
|
|
39
|
+
}
|
|
40
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Component, { ...mergedProps });
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Memoized wrapper component that resolves data sources before rendering the widget.
|
|
44
|
+
* Prevents re-renders when parent re-renders but props haven't changed.
|
|
45
|
+
*/
|
|
46
|
+
const DataAwareWidget = (0, react.memo)(DataAwareWidgetImpl);
|
|
47
|
+
//#endregion
|
|
48
|
+
exports.DataAwareWidget = DataAwareWidget;
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=DataAwareWidget.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataAwareWidget.cjs","names":["useWidgetData","ErrorState"],"sources":["../../src/data-sources/DataAwareWidget.tsx"],"sourcesContent":["import type React from \"react\";\nimport { memo, useMemo, type ComponentType, type ReactNode } from \"react\";\nimport type { WidgetSchema } from \"../types/widget-schema\";\nimport { useWidgetData } from \"./use-widget-data\";\nimport { ErrorState } from \"./ErrorState\";\n\nexport interface DataAwareWidgetProps {\n widget: WidgetSchema;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Component: ComponentType<any>;\n /** Additional props to pass through (e.g., edit mode callbacks) */\n additionalProps?: Record<string, unknown>;\n /** Custom loading component */\n loadingComponent?: ReactNode;\n /** Custom error component */\n errorComponent?: (error: Error) => ReactNode;\n /** Base URL for API calls (e.g., \"https://api.fluid.app/api\") */\n baseUrl?: string | undefined;\n}\n\n// Empty object constant to avoid creating new references\nconst EMPTY_OBJECT: Record<string, unknown> = {};\n\n/**\n * Wrapper component that resolves data sources before rendering the widget.\n * Merges resolved data with static props.\n */\nfunction DataAwareWidgetImpl({\n widget,\n Component,\n additionalProps,\n loadingComponent,\n errorComponent,\n baseUrl,\n}: DataAwareWidgetProps): React.JSX.Element | null {\n // Use stable empty object if no additionalProps provided\n const stableAdditionalProps = additionalProps ?? EMPTY_OBJECT;\n const { data, isLoading, error } = useWidgetData(widget, { baseUrl });\n\n // Merge static props with resolved data\n // Data takes precedence (allows overriding defaults)\n // Memoized to prevent unnecessary child re-renders\n // Note: Must be called before any early returns to satisfy Rules of Hooks\n const mergedProps = useMemo(\n () => ({\n ...widget.props,\n ...data,\n ...stableAdditionalProps,\n }),\n [widget.props, data, stableAdditionalProps],\n );\n\n // Show loading state\n if (isLoading && widget.dataSource?.loading?.showSkeleton !== false) {\n if (loadingComponent) {\n return <>{loadingComponent}</>;\n }\n // Default skeleton - can be customized\n return (\n <div\n className=\"bg-muted animate-pulse rounded-md\"\n style={{ minHeight: 100 }}\n >\n <span className=\"sr-only\">Loading...</span>\n </div>\n );\n }\n\n // Show error state (if no fallback was applied)\n if (error && !data) {\n if (errorComponent) {\n return <>{errorComponent(error)}</>;\n }\n // Default error display\n return <ErrorState />;\n }\n\n return <Component {...mergedProps} />;\n}\n\n/**\n * Memoized wrapper component that resolves data sources before rendering the widget.\n * Prevents re-renders when parent re-renders but props haven't changed.\n */\nexport const DataAwareWidget: React.NamedExoticComponent<DataAwareWidgetProps> =\n memo(DataAwareWidgetImpl);\n"],"mappings":";;;;;;;AAqBA,MAAM,eAAwC,EAAE;;;;;AAMhD,SAAS,oBAAoB,EAC3B,QACA,WACA,iBACA,kBACA,gBACA,WACiD;CAEjD,MAAM,wBAAwB,mBAAmB;CACjD,MAAM,EAAE,MAAM,WAAW,UAAUA,qCAAAA,cAAc,QAAQ,EAAE,SAAS,CAAC;CAMrE,MAAM,eAAA,GAAA,MAAA,gBACG;EACL,GAAG,OAAO;EACV,GAAG;EACH,GAAG;EACJ,GACD;EAAC,OAAO;EAAO;EAAM;EAAsB,CAC5C;AAGD,KAAI,aAAa,OAAO,YAAY,SAAS,iBAAiB,OAAO;AACnE,MAAI,iBACF,QAAO,iBAAA,GAAA,kBAAA,KAAA,kBAAA,UAAA,EAAA,UAAG,kBAAoB,CAAA;AAGhC,SACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,WAAW,KAAK;aAEzB,iBAAA,GAAA,kBAAA,KAAC,QAAD;IAAM,WAAU;cAAU;IAAiB,CAAA;GACvC,CAAA;;AAKV,KAAI,SAAS,CAAC,MAAM;AAClB,MAAI,eACF,QAAO,iBAAA,GAAA,kBAAA,KAAA,kBAAA,UAAA,EAAA,UAAG,eAAe,MAAM,EAAI,CAAA;AAGrC,SAAO,iBAAA,GAAA,kBAAA,KAACC,gCAAAA,YAAD,EAAc,CAAA;;AAGvB,QAAO,iBAAA,GAAA,kBAAA,KAAC,WAAD,EAAW,GAAI,aAAe,CAAA;;;;;;AAOvC,MAAa,mBAAA,GAAA,MAAA,MACN,oBAAoB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { a as WidgetSchema } from "../widget-schema-BSX2fVhW.cjs";
|
|
2
|
+
import React, { ComponentType, ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/data-sources/DataAwareWidget.d.ts
|
|
5
|
+
interface DataAwareWidgetProps {
|
|
6
|
+
widget: WidgetSchema;
|
|
7
|
+
Component: ComponentType<any>;
|
|
8
|
+
/** Additional props to pass through (e.g., edit mode callbacks) */
|
|
9
|
+
additionalProps?: Record<string, unknown>;
|
|
10
|
+
/** Custom loading component */
|
|
11
|
+
loadingComponent?: ReactNode;
|
|
12
|
+
/** Custom error component */
|
|
13
|
+
errorComponent?: (error: Error) => ReactNode;
|
|
14
|
+
/** Base URL for API calls (e.g., "https://api.fluid.app/api") */
|
|
15
|
+
baseUrl?: string | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Memoized wrapper component that resolves data sources before rendering the widget.
|
|
19
|
+
* Prevents re-renders when parent re-renders but props haven't changed.
|
|
20
|
+
*/
|
|
21
|
+
declare const DataAwareWidget: React.NamedExoticComponent<DataAwareWidgetProps>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { DataAwareWidget, DataAwareWidgetProps };
|
|
24
|
+
//# sourceMappingURL=DataAwareWidget.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataAwareWidget.d.cts","names":[],"sources":["../../src/data-sources/DataAwareWidget.tsx"],"mappings":";;;;UAMiB,oBAAA;EACf,MAAA,EAAQ,YAAA;EAER,SAAA,EAAW,aAAA;;EAEX,eAAA,GAAkB,MAAA;;EAElB,gBAAA,GAAmB,SAAA;;EAEnB,cAAA,IAAkB,KAAA,EAAO,KAAA,KAAU,SAAA;;EAEnC,OAAA;AAAA;;;;;cAmEW,eAAA,EAAiB,KAAA,CAAM,oBAAA,CAAqB,oBAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { a as WidgetSchema } from "../widget-schema-BKZgsNG7.mjs";
|
|
2
|
+
import React, { ComponentType, ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/data-sources/DataAwareWidget.d.ts
|
|
5
|
+
interface DataAwareWidgetProps {
|
|
6
|
+
widget: WidgetSchema;
|
|
7
|
+
Component: ComponentType<any>;
|
|
8
|
+
/** Additional props to pass through (e.g., edit mode callbacks) */
|
|
9
|
+
additionalProps?: Record<string, unknown>;
|
|
10
|
+
/** Custom loading component */
|
|
11
|
+
loadingComponent?: ReactNode;
|
|
12
|
+
/** Custom error component */
|
|
13
|
+
errorComponent?: (error: Error) => ReactNode;
|
|
14
|
+
/** Base URL for API calls (e.g., "https://api.fluid.app/api") */
|
|
15
|
+
baseUrl?: string | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Memoized wrapper component that resolves data sources before rendering the widget.
|
|
19
|
+
* Prevents re-renders when parent re-renders but props haven't changed.
|
|
20
|
+
*/
|
|
21
|
+
declare const DataAwareWidget: React.NamedExoticComponent<DataAwareWidgetProps>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { DataAwareWidget, DataAwareWidgetProps };
|
|
24
|
+
//# sourceMappingURL=DataAwareWidget.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataAwareWidget.d.mts","names":[],"sources":["../../src/data-sources/DataAwareWidget.tsx"],"mappings":";;;;UAMiB,oBAAA;EACf,MAAA,EAAQ,YAAA;EAER,SAAA,EAAW,aAAA;;EAEX,eAAA,GAAkB,MAAA;;EAElB,gBAAA,GAAmB,SAAA;;EAEnB,cAAA,IAAkB,KAAA,EAAO,KAAA,KAAU,SAAA;;EAEnC,OAAA;AAAA;;;;;cAmEW,eAAA,EAAiB,KAAA,CAAM,oBAAA,CAAqB,oBAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useWidgetData } from "./use-widget-data.mjs";
|
|
2
|
+
import { ErrorState } from "./ErrorState.mjs";
|
|
3
|
+
import { memo, useMemo } from "react";
|
|
4
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/data-sources/DataAwareWidget.tsx
|
|
6
|
+
const EMPTY_OBJECT = {};
|
|
7
|
+
/**
|
|
8
|
+
* Wrapper component that resolves data sources before rendering the widget.
|
|
9
|
+
* Merges resolved data with static props.
|
|
10
|
+
*/
|
|
11
|
+
function DataAwareWidgetImpl({ widget, Component, additionalProps, loadingComponent, errorComponent, baseUrl }) {
|
|
12
|
+
const stableAdditionalProps = additionalProps ?? EMPTY_OBJECT;
|
|
13
|
+
const { data, isLoading, error } = useWidgetData(widget, { baseUrl });
|
|
14
|
+
const mergedProps = useMemo(() => ({
|
|
15
|
+
...widget.props,
|
|
16
|
+
...data,
|
|
17
|
+
...stableAdditionalProps
|
|
18
|
+
}), [
|
|
19
|
+
widget.props,
|
|
20
|
+
data,
|
|
21
|
+
stableAdditionalProps
|
|
22
|
+
]);
|
|
23
|
+
if (isLoading && widget.dataSource?.loading?.showSkeleton !== false) {
|
|
24
|
+
if (loadingComponent) return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent });
|
|
25
|
+
return /* @__PURE__ */ jsx("div", {
|
|
26
|
+
className: "bg-muted animate-pulse rounded-md",
|
|
27
|
+
style: { minHeight: 100 },
|
|
28
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
29
|
+
className: "sr-only",
|
|
30
|
+
children: "Loading..."
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (error && !data) {
|
|
35
|
+
if (errorComponent) return /* @__PURE__ */ jsx(Fragment, { children: errorComponent(error) });
|
|
36
|
+
return /* @__PURE__ */ jsx(ErrorState, {});
|
|
37
|
+
}
|
|
38
|
+
return /* @__PURE__ */ jsx(Component, { ...mergedProps });
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Memoized wrapper component that resolves data sources before rendering the widget.
|
|
42
|
+
* Prevents re-renders when parent re-renders but props haven't changed.
|
|
43
|
+
*/
|
|
44
|
+
const DataAwareWidget = memo(DataAwareWidgetImpl);
|
|
45
|
+
//#endregion
|
|
46
|
+
export { DataAwareWidget };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=DataAwareWidget.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DataAwareWidget.mjs","names":[],"sources":["../../src/data-sources/DataAwareWidget.tsx"],"sourcesContent":["import type React from \"react\";\nimport { memo, useMemo, type ComponentType, type ReactNode } from \"react\";\nimport type { WidgetSchema } from \"../types/widget-schema\";\nimport { useWidgetData } from \"./use-widget-data\";\nimport { ErrorState } from \"./ErrorState\";\n\nexport interface DataAwareWidgetProps {\n widget: WidgetSchema;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Component: ComponentType<any>;\n /** Additional props to pass through (e.g., edit mode callbacks) */\n additionalProps?: Record<string, unknown>;\n /** Custom loading component */\n loadingComponent?: ReactNode;\n /** Custom error component */\n errorComponent?: (error: Error) => ReactNode;\n /** Base URL for API calls (e.g., \"https://api.fluid.app/api\") */\n baseUrl?: string | undefined;\n}\n\n// Empty object constant to avoid creating new references\nconst EMPTY_OBJECT: Record<string, unknown> = {};\n\n/**\n * Wrapper component that resolves data sources before rendering the widget.\n * Merges resolved data with static props.\n */\nfunction DataAwareWidgetImpl({\n widget,\n Component,\n additionalProps,\n loadingComponent,\n errorComponent,\n baseUrl,\n}: DataAwareWidgetProps): React.JSX.Element | null {\n // Use stable empty object if no additionalProps provided\n const stableAdditionalProps = additionalProps ?? EMPTY_OBJECT;\n const { data, isLoading, error } = useWidgetData(widget, { baseUrl });\n\n // Merge static props with resolved data\n // Data takes precedence (allows overriding defaults)\n // Memoized to prevent unnecessary child re-renders\n // Note: Must be called before any early returns to satisfy Rules of Hooks\n const mergedProps = useMemo(\n () => ({\n ...widget.props,\n ...data,\n ...stableAdditionalProps,\n }),\n [widget.props, data, stableAdditionalProps],\n );\n\n // Show loading state\n if (isLoading && widget.dataSource?.loading?.showSkeleton !== false) {\n if (loadingComponent) {\n return <>{loadingComponent}</>;\n }\n // Default skeleton - can be customized\n return (\n <div\n className=\"bg-muted animate-pulse rounded-md\"\n style={{ minHeight: 100 }}\n >\n <span className=\"sr-only\">Loading...</span>\n </div>\n );\n }\n\n // Show error state (if no fallback was applied)\n if (error && !data) {\n if (errorComponent) {\n return <>{errorComponent(error)}</>;\n }\n // Default error display\n return <ErrorState />;\n }\n\n return <Component {...mergedProps} />;\n}\n\n/**\n * Memoized wrapper component that resolves data sources before rendering the widget.\n * Prevents re-renders when parent re-renders but props haven't changed.\n */\nexport const DataAwareWidget: React.NamedExoticComponent<DataAwareWidgetProps> =\n memo(DataAwareWidgetImpl);\n"],"mappings":";;;;;AAqBA,MAAM,eAAwC,EAAE;;;;;AAMhD,SAAS,oBAAoB,EAC3B,QACA,WACA,iBACA,kBACA,gBACA,WACiD;CAEjD,MAAM,wBAAwB,mBAAmB;CACjD,MAAM,EAAE,MAAM,WAAW,UAAU,cAAc,QAAQ,EAAE,SAAS,CAAC;CAMrE,MAAM,cAAc,eACX;EACL,GAAG,OAAO;EACV,GAAG;EACH,GAAG;EACJ,GACD;EAAC,OAAO;EAAO;EAAM;EAAsB,CAC5C;AAGD,KAAI,aAAa,OAAO,YAAY,SAAS,iBAAiB,OAAO;AACnE,MAAI,iBACF,QAAO,oBAAA,UAAA,EAAA,UAAG,kBAAoB,CAAA;AAGhC,SACE,oBAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,WAAW,KAAK;aAEzB,oBAAC,QAAD;IAAM,WAAU;cAAU;IAAiB,CAAA;GACvC,CAAA;;AAKV,KAAI,SAAS,CAAC,MAAM;AAClB,MAAI,eACF,QAAO,oBAAA,UAAA,EAAA,UAAG,eAAe,MAAM,EAAI,CAAA;AAGrC,SAAO,oBAAC,YAAD,EAAc,CAAA;;AAGvB,QAAO,oBAAC,WAAD,EAAW,GAAI,aAAe,CAAA;;;;;;AAOvC,MAAa,kBACX,KAAK,oBAAoB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../chunk-CKQMccvm.cjs");
|
|
3
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
4
|
+
//#region src/data-sources/ErrorState.tsx
|
|
5
|
+
function ErrorState() {
|
|
6
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7
|
+
className: "flex min-h-[120px] flex-col items-center justify-center p-6 text-center",
|
|
8
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
9
|
+
className: "text-lg font-semibold",
|
|
10
|
+
children: "Something Went Wrong"
|
|
11
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
12
|
+
className: "text-muted-foreground text-sm",
|
|
13
|
+
children: "Please contact a company admin for help"
|
|
14
|
+
})]
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.ErrorState = ErrorState;
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=ErrorState.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorState.cjs","names":[],"sources":["../../src/data-sources/ErrorState.tsx"],"sourcesContent":["import type React from \"react\";\n\nexport function ErrorState(): React.JSX.Element {\n return (\n <div className=\"flex min-h-[120px] flex-col items-center justify-center p-6 text-center\">\n <p className=\"text-lg font-semibold\">Something Went Wrong</p>\n <p className=\"text-muted-foreground text-sm\">\n Please contact a company admin for help\n </p>\n </div>\n );\n}\n"],"mappings":";;;;AAEA,SAAgB,aAAgC;AAC9C,QACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;EAAK,WAAU;YAAf,CACE,iBAAA,GAAA,kBAAA,KAAC,KAAD;GAAG,WAAU;aAAwB;GAAwB,CAAA,EAC7D,iBAAA,GAAA,kBAAA,KAAC,KAAD;GAAG,WAAU;aAAgC;GAEzC,CAAA,CACA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorState.d.cts","names":[],"sources":["../../src/data-sources/ErrorState.tsx"],"mappings":";;;iBAEgB,UAAA,CAAA,GAAc,KAAA,CAAM,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorState.d.mts","names":[],"sources":["../../src/data-sources/ErrorState.tsx"],"mappings":";;;iBAEgB,UAAA,CAAA,GAAc,KAAA,CAAM,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
//#region src/data-sources/ErrorState.tsx
|
|
3
|
+
function ErrorState() {
|
|
4
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5
|
+
className: "flex min-h-[120px] flex-col items-center justify-center p-6 text-center",
|
|
6
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
7
|
+
className: "text-lg font-semibold",
|
|
8
|
+
children: "Something Went Wrong"
|
|
9
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
10
|
+
className: "text-muted-foreground text-sm",
|
|
11
|
+
children: "Please contact a company admin for help"
|
|
12
|
+
})]
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { ErrorState };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=ErrorState.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorState.mjs","names":[],"sources":["../../src/data-sources/ErrorState.tsx"],"sourcesContent":["import type React from \"react\";\n\nexport function ErrorState(): React.JSX.Element {\n return (\n <div className=\"flex min-h-[120px] flex-col items-center justify-center p-6 text-center\">\n <p className=\"text-lg font-semibold\">Something Went Wrong</p>\n <p className=\"text-muted-foreground text-sm\">\n Please contact a company admin for help\n </p>\n </div>\n );\n}\n"],"mappings":";;AAEA,SAAgB,aAAgC;AAC9C,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,KAAD;GAAG,WAAU;aAAwB;GAAwB,CAAA,EAC7D,oBAAC,KAAD;GAAG,WAAU;aAAgC;GAEzC,CAAA,CACA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../chunk-CKQMccvm.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
//#region src/data-sources/context.tsx
|
|
6
|
+
const DataSourceContext = (0, react.createContext)({});
|
|
7
|
+
function DataSourceProvider({ baseUrl, getApiHeaders, children }) {
|
|
8
|
+
const value = (0, react.useMemo)(() => ({
|
|
9
|
+
baseUrl,
|
|
10
|
+
getApiHeaders
|
|
11
|
+
}), [baseUrl, getApiHeaders]);
|
|
12
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataSourceContext.Provider, {
|
|
13
|
+
value,
|
|
14
|
+
children
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function useDataSourceConfig() {
|
|
18
|
+
return (0, react.useContext)(DataSourceContext);
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.DataSourceProvider = DataSourceProvider;
|
|
22
|
+
exports.useDataSourceConfig = useDataSourceConfig;
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=context.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.cjs","names":[],"sources":["../../src/data-sources/context.tsx"],"sourcesContent":["import type React from \"react\";\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\n\nexport interface DataSourceContextValue {\n baseUrl?: string | undefined;\n getApiHeaders?: (() => Record<string, string>) | undefined;\n}\n\nconst DataSourceContext = createContext<DataSourceContextValue>({});\n\nexport interface DataSourceProviderProps {\n baseUrl?: string | undefined;\n getApiHeaders?: (() => Record<string, string>) | undefined;\n children: ReactNode;\n}\n\nexport function DataSourceProvider({\n baseUrl,\n getApiHeaders,\n children,\n}: DataSourceProviderProps): React.JSX.Element {\n const value = useMemo(\n () => ({ baseUrl, getApiHeaders }),\n [baseUrl, getApiHeaders],\n );\n\n return (\n <DataSourceContext.Provider value={value}>\n {children}\n </DataSourceContext.Provider>\n );\n}\n\nexport function useDataSourceConfig(): DataSourceContextValue {\n return useContext(DataSourceContext);\n}\n"],"mappings":";;;;;AAQA,MAAM,qBAAA,GAAA,MAAA,eAA0D,EAAE,CAAC;AAQnE,SAAgB,mBAAmB,EACjC,SACA,eACA,YAC6C;CAC7C,MAAM,SAAA,GAAA,MAAA,gBACG;EAAE;EAAS;EAAe,GACjC,CAAC,SAAS,cAAc,CACzB;AAED,QACE,iBAAA,GAAA,kBAAA,KAAC,kBAAkB,UAAnB;EAAmC;EAChC;EAC0B,CAAA;;AAIjC,SAAgB,sBAA8C;AAC5D,SAAA,GAAA,MAAA,YAAkB,kBAAkB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/data-sources/context.d.ts
|
|
4
|
+
interface DataSourceContextValue {
|
|
5
|
+
baseUrl?: string | undefined;
|
|
6
|
+
getApiHeaders?: (() => Record<string, string>) | undefined;
|
|
7
|
+
}
|
|
8
|
+
interface DataSourceProviderProps {
|
|
9
|
+
baseUrl?: string | undefined;
|
|
10
|
+
getApiHeaders?: (() => Record<string, string>) | undefined;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
declare function DataSourceProvider({
|
|
14
|
+
baseUrl,
|
|
15
|
+
getApiHeaders,
|
|
16
|
+
children
|
|
17
|
+
}: DataSourceProviderProps): React.JSX.Element;
|
|
18
|
+
declare function useDataSourceConfig(): DataSourceContextValue;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { DataSourceContextValue, DataSourceProvider, DataSourceProviderProps, useDataSourceConfig };
|
|
21
|
+
//# sourceMappingURL=context.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.cts","names":[],"sources":["../../src/data-sources/context.tsx"],"mappings":";;;UAGiB,sBAAA;EACf,OAAA;EACA,aAAA,UAAuB,MAAA;AAAA;AAAA,UAKR,uBAAA;EACf,OAAA;EACA,aAAA,UAAuB,MAAA;EACvB,QAAA,EAAU,SAAA;AAAA;AAAA,iBAGI,kBAAA,CAAA;EACd,OAAA;EACA,aAAA;EACA;AAAA,GACC,uBAAA,GAA0B,KAAA,CAAM,GAAA,CAAI,OAAA;AAAA,iBAavB,mBAAA,CAAA,GAAuB,sBAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/data-sources/context.d.ts
|
|
4
|
+
interface DataSourceContextValue {
|
|
5
|
+
baseUrl?: string | undefined;
|
|
6
|
+
getApiHeaders?: (() => Record<string, string>) | undefined;
|
|
7
|
+
}
|
|
8
|
+
interface DataSourceProviderProps {
|
|
9
|
+
baseUrl?: string | undefined;
|
|
10
|
+
getApiHeaders?: (() => Record<string, string>) | undefined;
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
declare function DataSourceProvider({
|
|
14
|
+
baseUrl,
|
|
15
|
+
getApiHeaders,
|
|
16
|
+
children
|
|
17
|
+
}: DataSourceProviderProps): React.JSX.Element;
|
|
18
|
+
declare function useDataSourceConfig(): DataSourceContextValue;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { DataSourceContextValue, DataSourceProvider, DataSourceProviderProps, useDataSourceConfig };
|
|
21
|
+
//# sourceMappingURL=context.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.mts","names":[],"sources":["../../src/data-sources/context.tsx"],"mappings":";;;UAGiB,sBAAA;EACf,OAAA;EACA,aAAA,UAAuB,MAAA;AAAA;AAAA,UAKR,uBAAA;EACf,OAAA;EACA,aAAA,UAAuB,MAAA;EACvB,QAAA,EAAU,SAAA;AAAA;AAAA,iBAGI,kBAAA,CAAA;EACd,OAAA;EACA,aAAA;EACA;AAAA,GACC,uBAAA,GAA0B,KAAA,CAAM,GAAA,CAAI,OAAA;AAAA,iBAavB,mBAAA,CAAA,GAAuB,sBAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
//#region src/data-sources/context.tsx
|
|
4
|
+
const DataSourceContext = createContext({});
|
|
5
|
+
function DataSourceProvider({ baseUrl, getApiHeaders, children }) {
|
|
6
|
+
const value = useMemo(() => ({
|
|
7
|
+
baseUrl,
|
|
8
|
+
getApiHeaders
|
|
9
|
+
}), [baseUrl, getApiHeaders]);
|
|
10
|
+
return /* @__PURE__ */ jsx(DataSourceContext.Provider, {
|
|
11
|
+
value,
|
|
12
|
+
children
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function useDataSourceConfig() {
|
|
16
|
+
return useContext(DataSourceContext);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { DataSourceProvider, useDataSourceConfig };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=context.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.mjs","names":[],"sources":["../../src/data-sources/context.tsx"],"sourcesContent":["import type React from \"react\";\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\n\nexport interface DataSourceContextValue {\n baseUrl?: string | undefined;\n getApiHeaders?: (() => Record<string, string>) | undefined;\n}\n\nconst DataSourceContext = createContext<DataSourceContextValue>({});\n\nexport interface DataSourceProviderProps {\n baseUrl?: string | undefined;\n getApiHeaders?: (() => Record<string, string>) | undefined;\n children: ReactNode;\n}\n\nexport function DataSourceProvider({\n baseUrl,\n getApiHeaders,\n children,\n}: DataSourceProviderProps): React.JSX.Element {\n const value = useMemo(\n () => ({ baseUrl, getApiHeaders }),\n [baseUrl, getApiHeaders],\n );\n\n return (\n <DataSourceContext.Provider value={value}>\n {children}\n </DataSourceContext.Provider>\n );\n}\n\nexport function useDataSourceConfig(): DataSourceContextValue {\n return useContext(DataSourceContext);\n}\n"],"mappings":";;;AAQA,MAAM,oBAAoB,cAAsC,EAAE,CAAC;AAQnE,SAAgB,mBAAmB,EACjC,SACA,eACA,YAC6C;CAC7C,MAAM,QAAQ,eACL;EAAE;EAAS;EAAe,GACjC,CAAC,SAAS,cAAc,CACzB;AAED,QACE,oBAAC,kBAAkB,UAAnB;EAAmC;EAChC;EAC0B,CAAA;;AAIjC,SAAgB,sBAA8C;AAC5D,QAAO,WAAW,kBAAkB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/data-sources/fetchers/api.ts
|
|
3
|
+
/**
|
|
4
|
+
* Extracts a value from an object using dot notation path
|
|
5
|
+
* e.g., getByPath({ data: { items: [1,2,3] } }, 'data.items') => [1,2,3]
|
|
6
|
+
*/
|
|
7
|
+
function getByPath(obj, path) {
|
|
8
|
+
return path.split(".").reduce((current, key) => {
|
|
9
|
+
if (current && typeof current === "object" && key in current) return current[key];
|
|
10
|
+
}, obj);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Replaces {variable} placeholders in an endpoint path with values from the
|
|
14
|
+
* variables map. E.g., "/reps/{rep_id}/most_shared" with { rep_id: "42" }
|
|
15
|
+
* becomes "/reps/42/most_shared".
|
|
16
|
+
*/
|
|
17
|
+
function interpolateVariables(endpoint, variables) {
|
|
18
|
+
if (!variables) return endpoint;
|
|
19
|
+
const resolved = endpoint.replace(/\{(\w+)\}/g, (match, key) => variables[key] ?? match);
|
|
20
|
+
const unresolved = resolved.match(/\{(\w+)\}/g);
|
|
21
|
+
if (unresolved) console.warn(`[DataSource] Unresolved variable placeholders in endpoint: ${unresolved.join(", ")}. Endpoint: "${endpoint}". Available variables: ${Object.keys(variables).join(", ") || "(none)"}`);
|
|
22
|
+
return resolved;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolves the full URL for an endpoint.
|
|
26
|
+
* - Substitutes {variable} placeholders from context variables
|
|
27
|
+
* - Absolute URLs (starting with http:// or https://) are used as-is
|
|
28
|
+
* - Relative paths are prefixed with the context's baseUrl
|
|
29
|
+
*/
|
|
30
|
+
function resolveEndpointUrl(endpoint, baseUrl, variables) {
|
|
31
|
+
const resolved = interpolateVariables(endpoint, variables);
|
|
32
|
+
if (resolved.startsWith("http://") || resolved.startsWith("https://")) return resolved;
|
|
33
|
+
if (baseUrl) return `${baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl}${resolved.startsWith("/") ? resolved : `/${resolved}`}`;
|
|
34
|
+
return resolved;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Default API fetcher implementation
|
|
38
|
+
*/
|
|
39
|
+
async function apiFetcher(source, context) {
|
|
40
|
+
const { endpoint, method = "GET", headers = {}, body } = source;
|
|
41
|
+
const mergedVariables = {
|
|
42
|
+
...context.variables,
|
|
43
|
+
...source.variables
|
|
44
|
+
};
|
|
45
|
+
const url = resolveEndpointUrl(endpoint, context.baseUrl, mergedVariables);
|
|
46
|
+
const fetchOptions = {
|
|
47
|
+
method,
|
|
48
|
+
headers: {
|
|
49
|
+
"content-type": "application/json",
|
|
50
|
+
...context.getApiHeaders?.(),
|
|
51
|
+
...headers
|
|
52
|
+
},
|
|
53
|
+
signal: context.signal
|
|
54
|
+
};
|
|
55
|
+
if (body && (method === "POST" || method === "PUT")) fetchOptions.body = JSON.stringify(body);
|
|
56
|
+
const response = await fetch(url, fetchOptions);
|
|
57
|
+
if (!response.ok) throw new Error(`API request failed: ${response.status} ${response.statusText}`);
|
|
58
|
+
const data = await response.json();
|
|
59
|
+
if (source.resultPath) return getByPath(data, source.resultPath);
|
|
60
|
+
return data;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
exports.apiFetcher = apiFetcher;
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=api.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.cjs","names":[],"sources":["../../../src/data-sources/fetchers/api.ts"],"sourcesContent":["import type { ApiDataSource, DataSourceContext } from \"../types\";\n\n/**\n * Extracts a value from an object using dot notation path\n * e.g., getByPath({ data: { items: [1,2,3] } }, 'data.items') => [1,2,3]\n */\nfunction getByPath(obj: unknown, path: string): unknown {\n return path.split(\".\").reduce((current, key) => {\n if (current && typeof current === \"object\" && key in current) {\n return (current as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Replaces {variable} placeholders in an endpoint path with values from the\n * variables map. E.g., \"/reps/{rep_id}/most_shared\" with { rep_id: \"42\" }\n * becomes \"/reps/42/most_shared\".\n */\nfunction interpolateVariables(\n endpoint: string,\n variables?: Record<string, string>,\n): string {\n if (!variables) return endpoint;\n const resolved = endpoint.replace(\n /\\{(\\w+)\\}/g,\n (match, key: string) => variables[key] ?? match,\n );\n const unresolved = resolved.match(/\\{(\\w+)\\}/g);\n if (unresolved) {\n console.warn(\n `[DataSource] Unresolved variable placeholders in endpoint: ${unresolved.join(\", \")}. ` +\n `Endpoint: \"${endpoint}\". Available variables: ${Object.keys(variables).join(\", \") || \"(none)\"}`,\n );\n }\n return resolved;\n}\n\n/**\n * Resolves the full URL for an endpoint.\n * - Substitutes {variable} placeholders from context variables\n * - Absolute URLs (starting with http:// or https://) are used as-is\n * - Relative paths are prefixed with the context's baseUrl\n */\nfunction resolveEndpointUrl(\n endpoint: string,\n baseUrl?: string,\n variables?: Record<string, string>,\n): string {\n const resolved = interpolateVariables(endpoint, variables);\n\n // If endpoint is already absolute, use it directly\n if (resolved.startsWith(\"http://\") || resolved.startsWith(\"https://\")) {\n return resolved;\n }\n\n // If we have a baseUrl, prepend it to the relative endpoint\n if (baseUrl) {\n // Ensure proper joining (no double slashes)\n const base = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n const path = resolved.startsWith(\"/\") ? resolved : `/${resolved}`;\n return `${base}${path}`;\n }\n\n // No baseUrl provided, return endpoint as-is (will likely fail for relative paths)\n return resolved;\n}\n\n/**\n * Default API fetcher implementation\n */\nexport async function apiFetcher(\n source: ApiDataSource,\n context: DataSourceContext,\n): Promise<unknown> {\n const { endpoint, method = \"GET\", headers = {}, body } = source;\n\n // Merge context variables with per-source variables (source overrides context)\n const mergedVariables = { ...context.variables, ...source.variables };\n\n // Resolve the full URL, substituting variables and using baseUrl for relative endpoints\n const url = resolveEndpointUrl(endpoint, context.baseUrl, mergedVariables);\n\n const fetchOptions: RequestInit = {\n method,\n headers: {\n \"content-type\": \"application/json\",\n ...context.getApiHeaders?.(),\n ...headers,\n },\n signal: context.signal,\n };\n\n if (body && (method === \"POST\" || method === \"PUT\")) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n throw new Error(\n `API request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n // Extract data at resultPath if specified\n if (source.resultPath) {\n return getByPath(data, source.resultPath);\n }\n\n return data;\n}\n"],"mappings":";;;;;;AAMA,SAAS,UAAU,KAAc,MAAuB;AACtD,QAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,SAAS,QAAQ;AAC9C,MAAI,WAAW,OAAO,YAAY,YAAY,OAAO,QACnD,QAAQ,QAAoC;IAG7C,IAAI;;;;;;;AAQT,SAAS,qBACP,UACA,WACQ;AACR,KAAI,CAAC,UAAW,QAAO;CACvB,MAAM,WAAW,SAAS,QACxB,eACC,OAAO,QAAgB,UAAU,QAAQ,MAC3C;CACD,MAAM,aAAa,SAAS,MAAM,aAAa;AAC/C,KAAI,WACF,SAAQ,KACN,8DAA8D,WAAW,KAAK,KAAK,CAAC,eACpE,SAAS,0BAA0B,OAAO,KAAK,UAAU,CAAC,KAAK,KAAK,IAAI,WACzF;AAEH,QAAO;;;;;;;;AAST,SAAS,mBACP,UACA,SACA,WACQ;CACR,MAAM,WAAW,qBAAqB,UAAU,UAAU;AAG1D,KAAI,SAAS,WAAW,UAAU,IAAI,SAAS,WAAW,WAAW,CACnE,QAAO;AAIT,KAAI,QAIF,QAAO,GAFM,QAAQ,SAAS,IAAI,GAAG,QAAQ,MAAM,GAAG,GAAG,GAAG,UAC/C,SAAS,WAAW,IAAI,GAAG,WAAW,IAAI;AAKzD,QAAO;;;;;AAMT,eAAsB,WACpB,QACA,SACkB;CAClB,MAAM,EAAE,UAAU,SAAS,OAAO,UAAU,EAAE,EAAE,SAAS;CAGzD,MAAM,kBAAkB;EAAE,GAAG,QAAQ;EAAW,GAAG,OAAO;EAAW;CAGrE,MAAM,MAAM,mBAAmB,UAAU,QAAQ,SAAS,gBAAgB;CAE1E,MAAM,eAA4B;EAChC;EACA,SAAS;GACP,gBAAgB;GAChB,GAAG,QAAQ,iBAAiB;GAC5B,GAAG;GACJ;EACD,QAAQ,QAAQ;EACjB;AAED,KAAI,SAAS,WAAW,UAAU,WAAW,OAC3C,cAAa,OAAO,KAAK,UAAU,KAAK;CAG1C,MAAM,WAAW,MAAM,MAAM,KAAK,aAAa;AAE/C,KAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MACR,uBAAuB,SAAS,OAAO,GAAG,SAAS,aACpD;CAGH,MAAM,OAAO,MAAM,SAAS,MAAM;AAGlC,KAAI,OAAO,WACT,QAAO,UAAU,MAAM,OAAO,WAAW;AAG3C,QAAO"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { o as DataSourceContext, t as ApiDataSource } from "../../types-DrzvahW8.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/data-sources/fetchers/api.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Default API fetcher implementation
|
|
6
|
+
*/
|
|
7
|
+
declare function apiFetcher(source: ApiDataSource, context: DataSourceContext): Promise<unknown>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { apiFetcher };
|
|
10
|
+
//# sourceMappingURL=api.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.cts","names":[],"sources":["../../../src/data-sources/fetchers/api.ts"],"mappings":";;;;;AAwEA;iBAAsB,UAAA,CACpB,MAAA,EAAQ,aAAA,EACR,OAAA,EAAS,iBAAA,GACR,OAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { o as DataSourceContext, t as ApiDataSource } from "../../types-C5Zs5V3E.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/data-sources/fetchers/api.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Default API fetcher implementation
|
|
6
|
+
*/
|
|
7
|
+
declare function apiFetcher(source: ApiDataSource, context: DataSourceContext): Promise<unknown>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { apiFetcher };
|
|
10
|
+
//# sourceMappingURL=api.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.mts","names":[],"sources":["../../../src/data-sources/fetchers/api.ts"],"mappings":";;;;;AAwEA;iBAAsB,UAAA,CACpB,MAAA,EAAQ,aAAA,EACR,OAAA,EAAS,iBAAA,GACR,OAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
//#region src/data-sources/fetchers/api.ts
|
|
2
|
+
/**
|
|
3
|
+
* Extracts a value from an object using dot notation path
|
|
4
|
+
* e.g., getByPath({ data: { items: [1,2,3] } }, 'data.items') => [1,2,3]
|
|
5
|
+
*/
|
|
6
|
+
function getByPath(obj, path) {
|
|
7
|
+
return path.split(".").reduce((current, key) => {
|
|
8
|
+
if (current && typeof current === "object" && key in current) return current[key];
|
|
9
|
+
}, obj);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Replaces {variable} placeholders in an endpoint path with values from the
|
|
13
|
+
* variables map. E.g., "/reps/{rep_id}/most_shared" with { rep_id: "42" }
|
|
14
|
+
* becomes "/reps/42/most_shared".
|
|
15
|
+
*/
|
|
16
|
+
function interpolateVariables(endpoint, variables) {
|
|
17
|
+
if (!variables) return endpoint;
|
|
18
|
+
const resolved = endpoint.replace(/\{(\w+)\}/g, (match, key) => variables[key] ?? match);
|
|
19
|
+
const unresolved = resolved.match(/\{(\w+)\}/g);
|
|
20
|
+
if (unresolved) console.warn(`[DataSource] Unresolved variable placeholders in endpoint: ${unresolved.join(", ")}. Endpoint: "${endpoint}". Available variables: ${Object.keys(variables).join(", ") || "(none)"}`);
|
|
21
|
+
return resolved;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolves the full URL for an endpoint.
|
|
25
|
+
* - Substitutes {variable} placeholders from context variables
|
|
26
|
+
* - Absolute URLs (starting with http:// or https://) are used as-is
|
|
27
|
+
* - Relative paths are prefixed with the context's baseUrl
|
|
28
|
+
*/
|
|
29
|
+
function resolveEndpointUrl(endpoint, baseUrl, variables) {
|
|
30
|
+
const resolved = interpolateVariables(endpoint, variables);
|
|
31
|
+
if (resolved.startsWith("http://") || resolved.startsWith("https://")) return resolved;
|
|
32
|
+
if (baseUrl) return `${baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl}${resolved.startsWith("/") ? resolved : `/${resolved}`}`;
|
|
33
|
+
return resolved;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Default API fetcher implementation
|
|
37
|
+
*/
|
|
38
|
+
async function apiFetcher(source, context) {
|
|
39
|
+
const { endpoint, method = "GET", headers = {}, body } = source;
|
|
40
|
+
const mergedVariables = {
|
|
41
|
+
...context.variables,
|
|
42
|
+
...source.variables
|
|
43
|
+
};
|
|
44
|
+
const url = resolveEndpointUrl(endpoint, context.baseUrl, mergedVariables);
|
|
45
|
+
const fetchOptions = {
|
|
46
|
+
method,
|
|
47
|
+
headers: {
|
|
48
|
+
"content-type": "application/json",
|
|
49
|
+
...context.getApiHeaders?.(),
|
|
50
|
+
...headers
|
|
51
|
+
},
|
|
52
|
+
signal: context.signal
|
|
53
|
+
};
|
|
54
|
+
if (body && (method === "POST" || method === "PUT")) fetchOptions.body = JSON.stringify(body);
|
|
55
|
+
const response = await fetch(url, fetchOptions);
|
|
56
|
+
if (!response.ok) throw new Error(`API request failed: ${response.status} ${response.statusText}`);
|
|
57
|
+
const data = await response.json();
|
|
58
|
+
if (source.resultPath) return getByPath(data, source.resultPath);
|
|
59
|
+
return data;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { apiFetcher };
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=api.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.mjs","names":[],"sources":["../../../src/data-sources/fetchers/api.ts"],"sourcesContent":["import type { ApiDataSource, DataSourceContext } from \"../types\";\n\n/**\n * Extracts a value from an object using dot notation path\n * e.g., getByPath({ data: { items: [1,2,3] } }, 'data.items') => [1,2,3]\n */\nfunction getByPath(obj: unknown, path: string): unknown {\n return path.split(\".\").reduce((current, key) => {\n if (current && typeof current === \"object\" && key in current) {\n return (current as Record<string, unknown>)[key];\n }\n return undefined;\n }, obj);\n}\n\n/**\n * Replaces {variable} placeholders in an endpoint path with values from the\n * variables map. E.g., \"/reps/{rep_id}/most_shared\" with { rep_id: \"42\" }\n * becomes \"/reps/42/most_shared\".\n */\nfunction interpolateVariables(\n endpoint: string,\n variables?: Record<string, string>,\n): string {\n if (!variables) return endpoint;\n const resolved = endpoint.replace(\n /\\{(\\w+)\\}/g,\n (match, key: string) => variables[key] ?? match,\n );\n const unresolved = resolved.match(/\\{(\\w+)\\}/g);\n if (unresolved) {\n console.warn(\n `[DataSource] Unresolved variable placeholders in endpoint: ${unresolved.join(\", \")}. ` +\n `Endpoint: \"${endpoint}\". Available variables: ${Object.keys(variables).join(\", \") || \"(none)\"}`,\n );\n }\n return resolved;\n}\n\n/**\n * Resolves the full URL for an endpoint.\n * - Substitutes {variable} placeholders from context variables\n * - Absolute URLs (starting with http:// or https://) are used as-is\n * - Relative paths are prefixed with the context's baseUrl\n */\nfunction resolveEndpointUrl(\n endpoint: string,\n baseUrl?: string,\n variables?: Record<string, string>,\n): string {\n const resolved = interpolateVariables(endpoint, variables);\n\n // If endpoint is already absolute, use it directly\n if (resolved.startsWith(\"http://\") || resolved.startsWith(\"https://\")) {\n return resolved;\n }\n\n // If we have a baseUrl, prepend it to the relative endpoint\n if (baseUrl) {\n // Ensure proper joining (no double slashes)\n const base = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n const path = resolved.startsWith(\"/\") ? resolved : `/${resolved}`;\n return `${base}${path}`;\n }\n\n // No baseUrl provided, return endpoint as-is (will likely fail for relative paths)\n return resolved;\n}\n\n/**\n * Default API fetcher implementation\n */\nexport async function apiFetcher(\n source: ApiDataSource,\n context: DataSourceContext,\n): Promise<unknown> {\n const { endpoint, method = \"GET\", headers = {}, body } = source;\n\n // Merge context variables with per-source variables (source overrides context)\n const mergedVariables = { ...context.variables, ...source.variables };\n\n // Resolve the full URL, substituting variables and using baseUrl for relative endpoints\n const url = resolveEndpointUrl(endpoint, context.baseUrl, mergedVariables);\n\n const fetchOptions: RequestInit = {\n method,\n headers: {\n \"content-type\": \"application/json\",\n ...context.getApiHeaders?.(),\n ...headers,\n },\n signal: context.signal,\n };\n\n if (body && (method === \"POST\" || method === \"PUT\")) {\n fetchOptions.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n throw new Error(\n `API request failed: ${response.status} ${response.statusText}`,\n );\n }\n\n const data = await response.json();\n\n // Extract data at resultPath if specified\n if (source.resultPath) {\n return getByPath(data, source.resultPath);\n }\n\n return data;\n}\n"],"mappings":";;;;;AAMA,SAAS,UAAU,KAAc,MAAuB;AACtD,QAAO,KAAK,MAAM,IAAI,CAAC,QAAQ,SAAS,QAAQ;AAC9C,MAAI,WAAW,OAAO,YAAY,YAAY,OAAO,QACnD,QAAQ,QAAoC;IAG7C,IAAI;;;;;;;AAQT,SAAS,qBACP,UACA,WACQ;AACR,KAAI,CAAC,UAAW,QAAO;CACvB,MAAM,WAAW,SAAS,QACxB,eACC,OAAO,QAAgB,UAAU,QAAQ,MAC3C;CACD,MAAM,aAAa,SAAS,MAAM,aAAa;AAC/C,KAAI,WACF,SAAQ,KACN,8DAA8D,WAAW,KAAK,KAAK,CAAC,eACpE,SAAS,0BAA0B,OAAO,KAAK,UAAU,CAAC,KAAK,KAAK,IAAI,WACzF;AAEH,QAAO;;;;;;;;AAST,SAAS,mBACP,UACA,SACA,WACQ;CACR,MAAM,WAAW,qBAAqB,UAAU,UAAU;AAG1D,KAAI,SAAS,WAAW,UAAU,IAAI,SAAS,WAAW,WAAW,CACnE,QAAO;AAIT,KAAI,QAIF,QAAO,GAFM,QAAQ,SAAS,IAAI,GAAG,QAAQ,MAAM,GAAG,GAAG,GAAG,UAC/C,SAAS,WAAW,IAAI,GAAG,WAAW,IAAI;AAKzD,QAAO;;;;;AAMT,eAAsB,WACpB,QACA,SACkB;CAClB,MAAM,EAAE,UAAU,SAAS,OAAO,UAAU,EAAE,EAAE,SAAS;CAGzD,MAAM,kBAAkB;EAAE,GAAG,QAAQ;EAAW,GAAG,OAAO;EAAW;CAGrE,MAAM,MAAM,mBAAmB,UAAU,QAAQ,SAAS,gBAAgB;CAE1E,MAAM,eAA4B;EAChC;EACA,SAAS;GACP,gBAAgB;GAChB,GAAG,QAAQ,iBAAiB;GAC5B,GAAG;GACJ;EACD,QAAQ,QAAQ;EACjB;AAED,KAAI,SAAS,WAAW,UAAU,WAAW,OAC3C,cAAa,OAAO,KAAK,UAAU,KAAK;CAG1C,MAAM,WAAW,MAAM,MAAM,KAAK,aAAa;AAE/C,KAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MACR,uBAAuB,SAAS,OAAO,GAAG,SAAS,aACpD;CAGH,MAAM,OAAO,MAAM,SAAS,MAAM;AAGlC,KAAI,OAAO,WACT,QAAO,UAAU,MAAM,OAAO,WAAW;AAG3C,QAAO"}
|