@fluid-app/portal-sdk 0.1.98 → 0.1.99
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/{MessagingScreen-DA62lyrN.mjs → MessagingScreen-BGr41874.mjs} +1 -0
- package/dist/{ProductsScreen-C0o1gVNw.mjs → ProductsScreen-6J79mnIB.mjs} +2 -2
- package/dist/{ProductsScreen-C0o1gVNw.mjs.map → ProductsScreen-6J79mnIB.mjs.map} +1 -1
- package/dist/{ProductsScreen-CigOdDOU.mjs → ProductsScreen-DCPVyEyQ.mjs} +5 -2
- package/dist/{ProductsScreen-CL16lwsI.cjs → ProductsScreen-DZnKtPBp.cjs} +2 -2
- package/dist/{ProductsScreen-BTrBbxX6.cjs → ProductsScreen-PJ95OcSX.cjs} +2 -2
- package/dist/{ProductsScreen-BTrBbxX6.cjs.map → ProductsScreen-PJ95OcSX.cjs.map} +1 -1
- package/dist/ShareablesScreen-CVT7u2hN.cjs +398 -0
- package/dist/ShareablesScreen-CVT7u2hN.cjs.map +1 -0
- package/dist/ShareablesScreen-Cy7w85IH.mjs +380 -0
- package/dist/ShareablesScreen-Cy7w85IH.mjs.map +1 -0
- package/dist/{ShareablesScreen-DufZz22d.cjs → ShareablesScreen-Dk5EQGMa.cjs} +2 -2
- package/dist/{ShareablesScreen-CSLB0ZXS.mjs → ShareablesScreen-jAj9hmif.mjs} +5 -2
- package/dist/index.cjs +7 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +9 -9
- package/dist/{src-D9jWnRlX.mjs → src-BrwLqPPh.mjs} +90 -269
- package/dist/src-BrwLqPPh.mjs.map +1 -0
- package/dist/{src-C3R03o4d.cjs → src-Dlsw83js.cjs} +95 -268
- package/dist/src-Dlsw83js.cjs.map +1 -0
- package/package.json +12 -12
- package/dist/ShareablesScreen-B9c5Mw5b.mjs +0 -159
- package/dist/ShareablesScreen-B9c5Mw5b.mjs.map +0 -1
- package/dist/ShareablesScreen-Bldl8tta.cjs +0 -177
- package/dist/ShareablesScreen-Bldl8tta.cjs.map +0 -1
- package/dist/src-C3R03o4d.cjs.map +0 -1
- package/dist/src-D9jWnRlX.mjs.map +0 -1
|
@@ -33,6 +33,7 @@ import "./SpacerWidget-B3zkEePP.mjs";
|
|
|
33
33
|
import "./TableWidget-CC4XnRF2.mjs";
|
|
34
34
|
import "./ToDoWidget-qyFLHU_o.mjs";
|
|
35
35
|
import "./VideoWidget-CpUPsOI7.mjs";
|
|
36
|
+
import "./use-fluid-api-CaSYWFuj.mjs";
|
|
36
37
|
import "./dist-NMbUD0qE.mjs";
|
|
37
38
|
import "./es-BCKjXBqj.mjs";
|
|
38
39
|
export { MessagingScreen, messagingScreenPropertySchema };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as useSdkClient } from "./use-account-clients-Dsqx0mKw.mjs";
|
|
2
2
|
import { n as useCurrentUser } from "./use-current-user-BMI-LR9t.mjs";
|
|
3
3
|
import { n as useAppNavigation } from "./AppNavigationContext-Du3Qq0yc.mjs";
|
|
4
|
-
import { a as
|
|
4
|
+
import { a as ShareablesApiProvider, i as ShareablesUIProvider, o as ShareablesCoreProvider, t as ProductsApp } from "./src-BrwLqPPh.mjs";
|
|
5
5
|
import { n as createShareablesApiAdapter } from "./src-DryOJTBW.mjs";
|
|
6
6
|
import { useCallback, useMemo } from "react";
|
|
7
7
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -71,4 +71,4 @@ const productsScreenPropertySchema = {
|
|
|
71
71
|
//#endregion
|
|
72
72
|
export { productsScreenPropertySchema as n, ProductsScreen as t };
|
|
73
73
|
|
|
74
|
-
//# sourceMappingURL=ProductsScreen-
|
|
74
|
+
//# sourceMappingURL=ProductsScreen-6J79mnIB.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsScreen-
|
|
1
|
+
{"version":3,"file":"ProductsScreen-6J79mnIB.mjs","names":[],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n type ShareablesApi,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const shareablesApi = useMemo<ShareablesApi>(\n () => createShareablesApiAdapter(domainClient, { repContext: true }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.log(`[Products] ${opts.type}: ${opts.title}`);\n },\n }),\n [userData, navigate],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider api={shareablesApi}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={userData?.country?.iso}\n companyLogoUrl={userData?.company?.logo_url}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;AA2BA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;CACzC,MAAM,eAAe,cAAc;CACnC,MAAM,EAAE,MAAM,aAAa,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAa,kBAAkB;CAGpD,MAAM,YAAY,cAAc;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,sBAAsB,aACzB,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,aAAa,kBAAkB;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;CAEd,MAAM,aAAa,eACV;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACvC,YAAY;EACb,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,gBAAgB,cACd,2BAA2B,cAAc,EAAE,YAAY,MAAM,CAAC,EACpE,CAAC,aAAa,CACf;CAED,MAAM,WAAW,eACR;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,UAAU;EACV,WAAW,SAAiB;AAC1B,YAAS,KAAK;;EAEhB,YAAY,SAGN;AACJ,WAAQ,IAAI,cAAc,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAExD,GACD,CAAC,UAAU,SAAS,CACrB;AAED,QACE,oBAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,oBAAC,wBAAD;GAAwB,QAAQ;aAC9B,oBAAC,uBAAD;IAAuB,KAAK;cAC1B,oBAAC,sBAAD;KAAsB,QAAQ;eAC5B,oBAAC,aAAD;MACE,aAAa,UAAU,SAAS;MAChC,gBAAgB,UAAU,SAAS;MACxB;MACX,iBAAiB;MACjB,QAAQ;MACR,CAAA;KACmB,CAAA;IACD,CAAA;GACD,CAAA;EACrB,CAAA;;AAIV,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
|
|
@@ -32,11 +32,14 @@ import "./SpacerWidget-B3zkEePP.mjs";
|
|
|
32
32
|
import "./TableWidget-CC4XnRF2.mjs";
|
|
33
33
|
import "./ToDoWidget-qyFLHU_o.mjs";
|
|
34
34
|
import "./VideoWidget-CpUPsOI7.mjs";
|
|
35
|
+
import "./use-account-clients-Dsqx0mKw.mjs";
|
|
35
36
|
import "./ScreenHeaderContext-CrdfLGKk.mjs";
|
|
37
|
+
import "./use-fluid-api-CaSYWFuj.mjs";
|
|
38
|
+
import "./use-current-user-BMI-LR9t.mjs";
|
|
36
39
|
import "./dist-NMbUD0qE.mjs";
|
|
37
40
|
import "./es-BCKjXBqj.mjs";
|
|
38
41
|
import "./dist-oYNtEpKP.mjs";
|
|
39
|
-
import "./src-
|
|
42
|
+
import "./src-BrwLqPPh.mjs";
|
|
40
43
|
import "./sortable.esm-DSrWP4x9.mjs";
|
|
41
|
-
import { n as productsScreenPropertySchema, t as ProductsScreen } from "./ProductsScreen-
|
|
44
|
+
import { n as productsScreenPropertySchema, t as ProductsScreen } from "./ProductsScreen-6J79mnIB.mjs";
|
|
42
45
|
export { ProductsScreen, productsScreenPropertySchema };
|
|
@@ -37,8 +37,8 @@ require("./ScreenHeaderContext-DpVOhFzT.cjs");
|
|
|
37
37
|
require("./dist-DRVtlgQ1.cjs");
|
|
38
38
|
require("./es-DlWO6buB.cjs");
|
|
39
39
|
require("./dist-Ck9MGRmE.cjs");
|
|
40
|
-
require("./src-
|
|
40
|
+
require("./src-Dlsw83js.cjs");
|
|
41
41
|
require("./dist-BSbac3uh.cjs");
|
|
42
|
-
const require_ProductsScreen = require("./ProductsScreen-
|
|
42
|
+
const require_ProductsScreen = require("./ProductsScreen-PJ95OcSX.cjs");
|
|
43
43
|
exports.ProductsScreen = require_ProductsScreen.ProductsScreen;
|
|
44
44
|
exports.productsScreenPropertySchema = require_ProductsScreen.productsScreenPropertySchema;
|
|
@@ -2,7 +2,7 @@ require("./chunk-9hOWP6kD.cjs");
|
|
|
2
2
|
const require_use_account_clients = require("./use-account-clients-CkDfPpCR.cjs");
|
|
3
3
|
const require_use_current_user = require("./use-current-user-LLJ1GtNB.cjs");
|
|
4
4
|
const require_AppNavigationContext = require("./AppNavigationContext-Agp0UkCQ.cjs");
|
|
5
|
-
const require_src = require("./src-
|
|
5
|
+
const require_src = require("./src-Dlsw83js.cjs");
|
|
6
6
|
const require_src$1 = require("./src-CMByt6YP.cjs");
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -83,4 +83,4 @@ Object.defineProperty(exports, "productsScreenPropertySchema", {
|
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
//# sourceMappingURL=ProductsScreen-
|
|
86
|
+
//# sourceMappingURL=ProductsScreen-PJ95OcSX.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductsScreen-
|
|
1
|
+
{"version":3,"file":"ProductsScreen-PJ95OcSX.cjs","names":["useSdkClient","useCurrentUser","useAppNavigation","createShareablesApiAdapter","ShareablesCoreProvider","ShareablesApiProvider","ShareablesUIProvider","ProductsApp"],"sources":["../src/screens/ProductsScreen.tsx"],"sourcesContent":["import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n type ShareablesApi,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ProductsApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\n\ntype ProductsScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\nexport function ProductsScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ProductsScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n\n // Extract product ID from slug: \"products/123\" → \"123\"\n const productId = useMemo(() => {\n const match = currentSlug.match(/^products\\/(.+)/);\n return match?.[1] ?? null;\n }, [currentSlug]);\n\n const handleSelectProduct = useCallback(\n (id: string) => {\n navigate(`products/${id}`);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n navigate(\"products\");\n }, [navigate]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const shareablesApi = useMemo<ShareablesApi>(\n () => createShareablesApiAdapter(domainClient, { repContext: true }),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n basePath: \"\",\n navigate: (path: string) => {\n navigate(path);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.log(`[Products] ${opts.type}: ${opts.title}`);\n },\n }),\n [userData, navigate],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider api={shareablesApi}>\n <ShareablesUIProvider config={uiConfig}>\n <ProductsApp\n countryCode={userData?.country?.iso}\n companyLogoUrl={userData?.company?.logo_url}\n productId={productId}\n onSelectProduct={handleSelectProduct}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const productsScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ProductsScreen\",\n displayName: \"Products Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":";;;;;;;;;AA2BA,SAAgB,eAAe,EAE7B,YACA,WACA,aACA,SACA,cAEA,GAAG,YACsC;CACzC,MAAM,eAAeA,4BAAAA,cAAc;CACnC,MAAM,EAAE,MAAM,aAAaC,yBAAAA,gBAAgB;CAC3C,MAAM,EAAE,aAAa,aAAaC,6BAAAA,kBAAkB;CAGpD,MAAM,aAAA,GAAA,MAAA,eAA0B;AAE9B,SADc,YAAY,MAAM,kBAAkB,GACnC,MAAM;IACpB,CAAC,YAAY,CAAC;CAEjB,MAAM,uBAAA,GAAA,MAAA,cACH,OAAe;AACd,WAAS,YAAY,KAAK;IAE5B,CAAC,SAAS,CACX;CAED,MAAM,cAAA,GAAA,MAAA,mBAA+B;AACnC,WAAS,WAAW;IACnB,CAAC,SAAS,CAAC;CAEd,MAAM,cAAA,GAAA,MAAA,gBACG;EACL,QAAQ;EACR,MAAM,WAAW,EAAE,IAAI,SAAS,IAAI,GAAG;EACvC,YAAY;EACb,GACD,CAAC,cAAc,SAAS,CACzB;CAED,MAAM,iBAAA,GAAA,MAAA,eACEC,cAAAA,2BAA2B,cAAc,EAAE,YAAY,MAAM,CAAC,EACpE,CAAC,aAAa,CACf;CAED,MAAM,YAAA,GAAA,MAAA,gBACG;EACL,MAAM,WACF;GACE,IAAI,SAAS;GACb,SAAS,SAAS,UACd,EAAE,UAAU,SAAS,QAAQ,UAAU,GACvC;GACL,GACD,KAAA;EACJ,UAAU;EACV,WAAW,SAAiB;AAC1B,YAAS,KAAK;;EAEhB,YAAY,SAGN;AACJ,WAAQ,IAAI,cAAc,KAAK,KAAK,IAAI,KAAK,QAAQ;;EAExD,GACD,CAAC,UAAU,SAAS,CACrB;AAED,QACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,GAAI;EAAU,WAAW,UAAU,SAAS,aAAa;YAC5D,iBAAA,GAAA,kBAAA,KAACC,YAAAA,wBAAD;GAAwB,QAAQ;aAC9B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,uBAAD;IAAuB,KAAK;cAC1B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,sBAAD;KAAsB,QAAQ;eAC5B,iBAAA,GAAA,kBAAA,KAACC,YAAAA,aAAD;MACE,aAAa,UAAU,SAAS;MAChC,gBAAgB,UAAU,SAAS;MACxB;MACX,iBAAiB;MACjB,QAAQ;MACR,CAAA;KACmB,CAAA;IACD,CAAA;GACD,CAAA;EACrB,CAAA;;AAIV,MAAa,+BAAqD;CAChE,YAAY;CACZ,aAAa;CACb,YAAY,CAAC;EAAE,IAAI;EAAW,OAAO;EAAW,CAAC;CACjD,QAAQ,EAAE;CACX"}
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
require("./chunk-9hOWP6kD.cjs");
|
|
2
|
+
const require_FluidProvider = require("./FluidProvider-CyzA2g75.cjs");
|
|
3
|
+
const require_use_account_clients = require("./use-account-clients-CkDfPpCR.cjs");
|
|
4
|
+
const require_use_current_user = require("./use-current-user-LLJ1GtNB.cjs");
|
|
5
|
+
const require_AppNavigationContext = require("./AppNavigationContext-Agp0UkCQ.cjs");
|
|
6
|
+
const require_src = require("./src-Dlsw83js.cjs");
|
|
7
|
+
const require_src$1 = require("./src-CMByt6YP.cjs");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
+
let zod = require("zod");
|
|
11
|
+
//#region src/hooks/use-user-type.ts
|
|
12
|
+
/**
|
|
13
|
+
* Convenience hook for user-type checks in the portal SDK.
|
|
14
|
+
*/
|
|
15
|
+
function useUserType() {
|
|
16
|
+
const { user } = require_use_account_clients.useFluidAuth();
|
|
17
|
+
return (0, react.useMemo)(() => {
|
|
18
|
+
const userType = user?.user_type ?? null;
|
|
19
|
+
return {
|
|
20
|
+
userType,
|
|
21
|
+
isCustomer: userType === require_FluidProvider.USER_TYPES.customer,
|
|
22
|
+
isRep: userType === require_FluidProvider.USER_TYPES.rep,
|
|
23
|
+
isAdmin: userType === require_FluidProvider.USER_TYPES.admin || userType === require_FluidProvider.USER_TYPES.root_admin
|
|
24
|
+
};
|
|
25
|
+
}, [user?.user_type]);
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region ../../file-picker/core/src/schemas/dam.ts
|
|
29
|
+
const damVariantSchema = zod.z.object({
|
|
30
|
+
id: zod.z.string(),
|
|
31
|
+
url: zod.z.string().nullable(),
|
|
32
|
+
file_name: zod.z.string(),
|
|
33
|
+
mime_type: zod.z.string(),
|
|
34
|
+
content: zod.z.any().nullable(),
|
|
35
|
+
created_at: zod.z.string(),
|
|
36
|
+
updated_at: zod.z.string(),
|
|
37
|
+
default: zod.z.boolean(),
|
|
38
|
+
is_original: zod.z.boolean(),
|
|
39
|
+
is_text: zod.z.boolean(),
|
|
40
|
+
media_type: zod.z.string(),
|
|
41
|
+
processing_status: zod.z.string(),
|
|
42
|
+
tags: zod.z.array(zod.z.string())
|
|
43
|
+
});
|
|
44
|
+
const damAssetSchema = zod.z.object({
|
|
45
|
+
id: zod.z.number(),
|
|
46
|
+
canonical_path: zod.z.string(),
|
|
47
|
+
category: zod.z.string(),
|
|
48
|
+
code: zod.z.string(),
|
|
49
|
+
company: zod.z.string(),
|
|
50
|
+
created_at: zod.z.string(),
|
|
51
|
+
default_variant_id: zod.z.string(),
|
|
52
|
+
default_variant_url: zod.z.string().optional(),
|
|
53
|
+
description: zod.z.string(),
|
|
54
|
+
name: zod.z.string(),
|
|
55
|
+
updated_at: zod.z.string(),
|
|
56
|
+
variants: zod.z.array(damVariantSchema).optional()
|
|
57
|
+
});
|
|
58
|
+
const damTreeFolderNodeSchema = zod.z.object({
|
|
59
|
+
asset_code: zod.z.union([zod.z.string(), zod.z.record(zod.z.string(), zod.z.unknown())]).optional(),
|
|
60
|
+
name: zod.z.union([zod.z.string(), zod.z.record(zod.z.string(), zod.z.unknown())]).optional(),
|
|
61
|
+
category: zod.z.union([zod.z.string(), zod.z.record(zod.z.string(), zod.z.unknown())]).optional(),
|
|
62
|
+
variants: zod.z.union([zod.z.array(zod.z.unknown()), zod.z.record(zod.z.string(), zod.z.unknown())]).optional()
|
|
63
|
+
}).passthrough();
|
|
64
|
+
const damTreeSchema = zod.z.record(zod.z.string(), zod.z.union([
|
|
65
|
+
zod.z.lazy(() => damTreeSchema),
|
|
66
|
+
damAssetSchema,
|
|
67
|
+
damTreeFolderNodeSchema
|
|
68
|
+
]));
|
|
69
|
+
const damQueryResponseSchema = zod.z.object({
|
|
70
|
+
path: zod.z.string(),
|
|
71
|
+
tree: damTreeSchema,
|
|
72
|
+
meta: zod.z.object({ next_cursor: zod.z.string().optional() }).optional()
|
|
73
|
+
});
|
|
74
|
+
zod.z.object({ asset: zod.z.object({
|
|
75
|
+
file: zod.z.any(),
|
|
76
|
+
name: zod.z.string(),
|
|
77
|
+
description: zod.z.string().optional(),
|
|
78
|
+
tags: zod.z.string().optional()
|
|
79
|
+
}) });
|
|
80
|
+
const damAssetCreateResponseSchema = zod.z.object({
|
|
81
|
+
asset: damAssetSchema,
|
|
82
|
+
meta: zod.z.object({
|
|
83
|
+
request_id: zod.z.string(),
|
|
84
|
+
timestamp: zod.z.string()
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
zod.z.object({
|
|
88
|
+
placeholder_asset: zod.z.object({
|
|
89
|
+
mime_type: zod.z.string(),
|
|
90
|
+
name: zod.z.string().optional(),
|
|
91
|
+
description: zod.z.string().optional()
|
|
92
|
+
}),
|
|
93
|
+
skip_autotagging: zod.z.boolean().optional()
|
|
94
|
+
});
|
|
95
|
+
zod.z.object({
|
|
96
|
+
asset: zod.z.object({
|
|
97
|
+
file: zod.z.any(),
|
|
98
|
+
name: zod.z.string(),
|
|
99
|
+
description: zod.z.string().optional(),
|
|
100
|
+
tags: zod.z.string().optional()
|
|
101
|
+
}).optional(),
|
|
102
|
+
text_asset: zod.z.object({
|
|
103
|
+
file_name: zod.z.string(),
|
|
104
|
+
mime_type: zod.z.string(),
|
|
105
|
+
text: zod.z.string(),
|
|
106
|
+
name: zod.z.string().optional(),
|
|
107
|
+
description: zod.z.string().optional(),
|
|
108
|
+
tags: zod.z.string().optional()
|
|
109
|
+
}).optional(),
|
|
110
|
+
placeholder_asset: zod.z.object({
|
|
111
|
+
mime_type: zod.z.string(),
|
|
112
|
+
name: zod.z.string().optional(),
|
|
113
|
+
description: zod.z.string().optional()
|
|
114
|
+
}).optional(),
|
|
115
|
+
skip_autotagging: zod.z.boolean().optional()
|
|
116
|
+
});
|
|
117
|
+
const damAssetPathCreateResponseSchema = zod.z.object({
|
|
118
|
+
asset: zod.z.object({
|
|
119
|
+
id: zod.z.number(),
|
|
120
|
+
canonical_path: zod.z.string(),
|
|
121
|
+
name: zod.z.string()
|
|
122
|
+
}),
|
|
123
|
+
meta: zod.z.object({
|
|
124
|
+
request_id: zod.z.string(),
|
|
125
|
+
timestamp: zod.z.string()
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region ../../file-picker/api-client/src/client.ts
|
|
130
|
+
function createFilePickerClient(config) {
|
|
131
|
+
return {
|
|
132
|
+
fetchClient: config.fetchClient,
|
|
133
|
+
uploadStrategy: config.uploadStrategy,
|
|
134
|
+
unsplashAccessKey: config.unsplashAccessKey,
|
|
135
|
+
proxyEndpoint: config.proxyEndpoint ?? "/api/proxy-url"
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region ../../file-picker/api-client/src/api/dam-assets.ts
|
|
140
|
+
/**
|
|
141
|
+
* Create a DAM asset. Text files use FormData upload; non-text files
|
|
142
|
+
* delegate to the provided uploadStrategy (e.g. ImageKit).
|
|
143
|
+
* If no uploadStrategy is provided, all files use FormData upload.
|
|
144
|
+
*/
|
|
145
|
+
async function createDamAsset(fetchClient, params, uploadStrategy) {
|
|
146
|
+
const mimeType = require_src.getFileMimeType(params.file);
|
|
147
|
+
if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/xml" || params.file.name.endsWith(".txt") || params.file.name.endsWith(".json") || params.file.name.endsWith(".xml") || params.file.name.endsWith(".csv")) return createDamAssetViaFormData(fetchClient, params);
|
|
148
|
+
if (uploadStrategy) return uploadStrategy.uploadFile(params);
|
|
149
|
+
return createDamAssetViaFormData(fetchClient, params);
|
|
150
|
+
}
|
|
151
|
+
async function createDamAssetViaFormData(fetchClient, params) {
|
|
152
|
+
const formData = new FormData();
|
|
153
|
+
formData.append("asset[file]", params.file);
|
|
154
|
+
formData.append("asset[name]", params.name);
|
|
155
|
+
if (params.description) formData.append("asset[description]", params.description);
|
|
156
|
+
if (params.tags && params.tags.length > 0) formData.append("asset[tags]", params.tags.join(","));
|
|
157
|
+
const response = await fetchClient.requestWithFormData("/dam/assets", formData, { method: "POST" });
|
|
158
|
+
return damAssetCreateResponseSchema.parse(response);
|
|
159
|
+
}
|
|
160
|
+
async function createDamAssetPathForAssets(fetchClient, { asset_paths, code }) {
|
|
161
|
+
const response = await fetchClient.post(`/dam/assets/${code}/asset_paths`, { asset_paths });
|
|
162
|
+
return damAssetPathCreateResponseSchema.parse(response);
|
|
163
|
+
}
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region ../../file-picker/api-client/src/api/dam-query.ts
|
|
166
|
+
async function queryDamAssets(fetchClient, params) {
|
|
167
|
+
const response = await fetchClient.post("/dam/query", params);
|
|
168
|
+
return damQueryResponseSchema.parse(response);
|
|
169
|
+
}
|
|
170
|
+
async function deleteDamAsset(fetchClient, code) {
|
|
171
|
+
return fetchClient.delete(`/dam/assets/${code}`);
|
|
172
|
+
}
|
|
173
|
+
async function discardDamAsset(fetchClient, code) {
|
|
174
|
+
return fetchClient.patch(`/dam/assets/${code}/discard`);
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region ../../file-picker/api-client/src/api/unsplash.ts
|
|
178
|
+
const unsplashImageSchema = zod.z.object({
|
|
179
|
+
id: zod.z.string(),
|
|
180
|
+
urls: zod.z.object({
|
|
181
|
+
raw: zod.z.string(),
|
|
182
|
+
full: zod.z.string(),
|
|
183
|
+
regular: zod.z.string(),
|
|
184
|
+
small: zod.z.string(),
|
|
185
|
+
thumb: zod.z.string()
|
|
186
|
+
}),
|
|
187
|
+
alt_description: zod.z.string().nullable(),
|
|
188
|
+
description: zod.z.string().nullable(),
|
|
189
|
+
user: zod.z.object({
|
|
190
|
+
name: zod.z.string(),
|
|
191
|
+
username: zod.z.string()
|
|
192
|
+
}),
|
|
193
|
+
width: zod.z.number(),
|
|
194
|
+
height: zod.z.number()
|
|
195
|
+
});
|
|
196
|
+
const unsplashSearchResponseSchema = zod.z.object({
|
|
197
|
+
results: zod.z.array(unsplashImageSchema),
|
|
198
|
+
total: zod.z.number(),
|
|
199
|
+
total_pages: zod.z.number()
|
|
200
|
+
});
|
|
201
|
+
/**
|
|
202
|
+
* Search Unsplash for photos matching a query.
|
|
203
|
+
*/
|
|
204
|
+
async function searchUnsplash(query, accessKey, page = 1, perPage = 20) {
|
|
205
|
+
const response = await fetch(`https://api.unsplash.com/search/photos?query=${encodeURIComponent(query)}&page=${page}&per_page=${perPage}&client_id=${accessKey}`);
|
|
206
|
+
if (!response.ok) throw new Error("Failed to search Unsplash");
|
|
207
|
+
return unsplashSearchResponseSchema.parse(await response.json());
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region ../../file-picker/api-client/src/api/url-proxy.ts
|
|
211
|
+
const urlProxyResponseSchema = zod.z.object({
|
|
212
|
+
data: zod.z.string(),
|
|
213
|
+
contentType: zod.z.string(),
|
|
214
|
+
size: zod.z.number()
|
|
215
|
+
});
|
|
216
|
+
/**
|
|
217
|
+
* Proxy a URL fetch through the backend to bypass CORS restrictions.
|
|
218
|
+
* The backend fetches the file and returns it as base64-encoded data.
|
|
219
|
+
*
|
|
220
|
+
* @param url - The URL to fetch
|
|
221
|
+
* @param proxyEndpoint - The proxy endpoint (defaults to "/api/proxy-url")
|
|
222
|
+
*/
|
|
223
|
+
async function proxyUrlFetch(url, proxyEndpoint = "/api/proxy-url") {
|
|
224
|
+
const response = await fetch(proxyEndpoint, {
|
|
225
|
+
method: "POST",
|
|
226
|
+
headers: { "Content-Type": "application/json" },
|
|
227
|
+
body: JSON.stringify({ url })
|
|
228
|
+
});
|
|
229
|
+
if (!response.ok) {
|
|
230
|
+
const errorData = await response.json().catch(() => ({ error: "Failed to proxy URL fetch" }));
|
|
231
|
+
throw new Error(errorData.error || `HTTP ${response.status}`);
|
|
232
|
+
}
|
|
233
|
+
const data = await response.json();
|
|
234
|
+
return urlProxyResponseSchema.parse(data);
|
|
235
|
+
}
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region ../../file-picker/api-client/src/create-file-picker-api.ts
|
|
238
|
+
/**
|
|
239
|
+
* Creates a FilePickerApi-compatible adapter backed by the real API client
|
|
240
|
+
* functions. The returned object satisfies the FilePickerApi interface
|
|
241
|
+
* from @fluid-app/file-picker-core via structural typing.
|
|
242
|
+
*/
|
|
243
|
+
function createFilePickerApi(client) {
|
|
244
|
+
return {
|
|
245
|
+
createDamAsset: (params) => createDamAsset(client.fetchClient, params, client.uploadStrategy),
|
|
246
|
+
queryDamAssets: (params) => queryDamAssets(client.fetchClient, params),
|
|
247
|
+
searchUnsplash: (query, page, perPage) => {
|
|
248
|
+
if (!client.unsplashAccessKey) throw new Error("Unsplash access key not configured");
|
|
249
|
+
return searchUnsplash(query, client.unsplashAccessKey, page, perPage);
|
|
250
|
+
},
|
|
251
|
+
deleteDamAsset: (code) => deleteDamAsset(client.fetchClient, code),
|
|
252
|
+
discardDamAsset: (code) => discardDamAsset(client.fetchClient, code),
|
|
253
|
+
createDamAssetPathForAssets: (params) => createDamAssetPathForAssets(client.fetchClient, params),
|
|
254
|
+
proxyUrlFetch: (url) => proxyUrlFetch(url, client.proxyEndpoint)
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/screens/ShareablesScreen.tsx
|
|
259
|
+
/**
|
|
260
|
+
* Parse the current shareables sub-route from the full slug.
|
|
261
|
+
*
|
|
262
|
+
* System nav slugs are "share/products", "share/media", "share/playlists".
|
|
263
|
+
* Detail pages append an ID: "share/products/123", "share/media/456".
|
|
264
|
+
*
|
|
265
|
+
* "share/products" → screen="products", detailId=null
|
|
266
|
+
* "share/products/123" → screen="products", detailId="123"
|
|
267
|
+
* "share/media/456" → screen="media", detailId="456"
|
|
268
|
+
* "share/playlists" → screen="playlists", detailId=null
|
|
269
|
+
* "share/playlists/789" → screen="playlists", detailId="789"
|
|
270
|
+
* "share/files" → screen="files", detailId=null
|
|
271
|
+
* "share" → screen=null (default to products)
|
|
272
|
+
*/
|
|
273
|
+
function parseShareablesRoute(currentSlug) {
|
|
274
|
+
const slugWithoutPrefix = currentSlug.replace(/^share\/?/, "");
|
|
275
|
+
if (!slugWithoutPrefix) return {
|
|
276
|
+
screen: null,
|
|
277
|
+
detailId: null,
|
|
278
|
+
action: null
|
|
279
|
+
};
|
|
280
|
+
const parts = slugWithoutPrefix.split("/");
|
|
281
|
+
return {
|
|
282
|
+
screen: parts[0] || null,
|
|
283
|
+
detailId: parts[1] || null,
|
|
284
|
+
action: parts[2] || null
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function ShareablesScreen({ background, textColor, accentColor, padding, borderRadius, ...divProps }) {
|
|
288
|
+
const domainClient = require_use_account_clients.useSdkClient();
|
|
289
|
+
const { data: userData } = require_use_current_user.useCurrentUser();
|
|
290
|
+
const { currentSlug, navigate } = require_AppNavigationContext.useAppNavigation();
|
|
291
|
+
const { isCustomer } = useUserType();
|
|
292
|
+
const { screen, detailId, action } = parseShareablesRoute(currentSlug);
|
|
293
|
+
const handleNavigate = (0, react.useCallback)((subScreen, id) => {
|
|
294
|
+
navigate(id ? `share/${subScreen}/${id}` : `share/${subScreen}`);
|
|
295
|
+
}, [navigate]);
|
|
296
|
+
const handleBack = (0, react.useCallback)(() => {
|
|
297
|
+
if (detailId && screen) navigate(`share/${screen}`);
|
|
298
|
+
else navigate("share/products");
|
|
299
|
+
}, [
|
|
300
|
+
navigate,
|
|
301
|
+
detailId,
|
|
302
|
+
screen
|
|
303
|
+
]);
|
|
304
|
+
const coreConfig = (0, react.useMemo)(() => ({
|
|
305
|
+
client: domainClient,
|
|
306
|
+
user: userData ? { id: userData.id } : null,
|
|
307
|
+
repContext: true
|
|
308
|
+
}), [domainClient, userData]);
|
|
309
|
+
const shareablesApi = (0, react.useMemo)(() => require_src$1.createShareablesApiAdapter(domainClient, { repContext: true }), [domainClient]);
|
|
310
|
+
const filePickerApi = (0, react.useMemo)(() => createFilePickerApi(createFilePickerClient({ fetchClient: domainClient })), [domainClient]);
|
|
311
|
+
const uiConfig = (0, react.useMemo)(() => ({
|
|
312
|
+
user: userData ? {
|
|
313
|
+
id: userData.id,
|
|
314
|
+
company: userData.company ? { logo_url: userData.company.logo_url } : null
|
|
315
|
+
} : void 0,
|
|
316
|
+
affiliateId: userData?.affiliate_id ?? null,
|
|
317
|
+
basePath: "",
|
|
318
|
+
navigate: (path) => {
|
|
319
|
+
const cleanPath = path.replace(/^\//, "");
|
|
320
|
+
navigate(cleanPath.startsWith("share/") ? cleanPath : `share/${cleanPath}`);
|
|
321
|
+
},
|
|
322
|
+
showToast: (opts) => {
|
|
323
|
+
console.warn(`[Shareables] ${opts.type}: ${opts.title}`);
|
|
324
|
+
},
|
|
325
|
+
filePickerApi,
|
|
326
|
+
onToggleFavorite: async (params) => {
|
|
327
|
+
const affiliateId = userData?.affiliate_id;
|
|
328
|
+
if (!affiliateId) throw new Error("No affiliate ID");
|
|
329
|
+
return domainClient.post(`/user_companies/${affiliateId}/favorites/toggle.json`, {
|
|
330
|
+
favoriteable_id: params.favoriteableId,
|
|
331
|
+
favoriteable_type: params.favoriteableType
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
onDeletePlaylist: isCustomer ? void 0 : async (playlistId) => {
|
|
335
|
+
const { playlists: playlistsApi } = await Promise.resolve().then(() => require("./src-CMByt6YP.cjs")).then((n) => n.src_exports);
|
|
336
|
+
await playlistsApi.deletePlaylist(domainClient, playlistId);
|
|
337
|
+
},
|
|
338
|
+
readOnly: isCustomer
|
|
339
|
+
}), [
|
|
340
|
+
userData,
|
|
341
|
+
navigate,
|
|
342
|
+
filePickerApi,
|
|
343
|
+
domainClient,
|
|
344
|
+
isCustomer
|
|
345
|
+
]);
|
|
346
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
347
|
+
...divProps,
|
|
348
|
+
className: `h-full ${divProps.className ?? ""}`,
|
|
349
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ShareablesCoreProvider, {
|
|
350
|
+
config: coreConfig,
|
|
351
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ShareablesApiProvider, {
|
|
352
|
+
api: shareablesApi,
|
|
353
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ShareablesUIProvider, {
|
|
354
|
+
config: uiConfig,
|
|
355
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.ShareablesApp, {
|
|
356
|
+
screen,
|
|
357
|
+
detailId,
|
|
358
|
+
action,
|
|
359
|
+
companyLogoUrl: userData?.company?.logo_url,
|
|
360
|
+
countryCode: userData?.country?.iso,
|
|
361
|
+
onNavigate: handleNavigate,
|
|
362
|
+
onBack: handleBack
|
|
363
|
+
})
|
|
364
|
+
})
|
|
365
|
+
})
|
|
366
|
+
})
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
const shareablesScreenPropertySchema = {
|
|
370
|
+
widgetType: "ShareablesScreen",
|
|
371
|
+
displayName: "Shareables Screen",
|
|
372
|
+
tabsConfig: [{
|
|
373
|
+
id: "styling",
|
|
374
|
+
label: "Styling"
|
|
375
|
+
}],
|
|
376
|
+
fields: []
|
|
377
|
+
};
|
|
378
|
+
//#endregion
|
|
379
|
+
Object.defineProperty(exports, "ShareablesScreen", {
|
|
380
|
+
enumerable: true,
|
|
381
|
+
get: function() {
|
|
382
|
+
return ShareablesScreen;
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
Object.defineProperty(exports, "shareablesScreenPropertySchema", {
|
|
386
|
+
enumerable: true,
|
|
387
|
+
get: function() {
|
|
388
|
+
return shareablesScreenPropertySchema;
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
Object.defineProperty(exports, "useUserType", {
|
|
392
|
+
enumerable: true,
|
|
393
|
+
get: function() {
|
|
394
|
+
return useUserType;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
//# sourceMappingURL=ShareablesScreen-CVT7u2hN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareablesScreen-CVT7u2hN.cjs","names":["useFluidAuth","USER_TYPES","z","getFileMimeType","z","z","useSdkClient","useCurrentUser","useAppNavigation","createShareablesApiAdapter","ShareablesCoreProvider","ShareablesApiProvider","ShareablesUIProvider","ShareablesApp"],"sources":["../src/hooks/use-user-type.ts","../../../file-picker/core/src/schemas/dam.ts","../../../file-picker/api-client/src/client.ts","../../../file-picker/api-client/src/api/dam-assets.ts","../../../file-picker/api-client/src/api/dam-query.ts","../../../file-picker/api-client/src/api/unsplash.ts","../../../file-picker/api-client/src/api/url-proxy.ts","../../../file-picker/api-client/src/create-file-picker-api.ts","../src/screens/ShareablesScreen.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { useFluidAuth } from \"./use-fluid-auth\";\nimport { USER_TYPES, type UserType } from \"../auth/types\";\n\nexport interface UseUserTypeResult {\n userType: UserType | null;\n isCustomer: boolean;\n isRep: boolean;\n isAdmin: boolean;\n}\n\n/**\n * Convenience hook for user-type checks in the portal SDK.\n */\nexport function useUserType(): UseUserTypeResult {\n const { user } = useFluidAuth();\n\n return useMemo(() => {\n const userType = user?.user_type ?? null;\n return {\n userType,\n isCustomer: userType === USER_TYPES.customer,\n isRep: userType === USER_TYPES.rep,\n isAdmin:\n userType === USER_TYPES.admin || userType === USER_TYPES.root_admin,\n };\n }, [user?.user_type]);\n}\n","import { z } from \"zod\";\n\ntype DamVariantApi = {\n id: string;\n url: string | null;\n file_name: string;\n mime_type: string;\n content: any;\n created_at: string;\n updated_at: string;\n default: boolean;\n is_original: boolean;\n is_text: boolean;\n media_type: string;\n processing_status: string;\n tags: string[];\n};\n\nexport const damVariantSchema: z.ZodType<DamVariantApi> = z.object({\n id: z.string(),\n url: z.string().nullable(),\n file_name: z.string(),\n mime_type: z.string(),\n content: z.any().nullable(),\n created_at: z.string(),\n updated_at: z.string(),\n default: z.boolean(),\n is_original: z.boolean(),\n is_text: z.boolean(),\n media_type: z.string(),\n processing_status: z.string(),\n tags: z.array(z.string()),\n});\n\ntype DamAssetApi = {\n id: number;\n canonical_path: string;\n category: string;\n code: string;\n company: string;\n created_at: string;\n default_variant_id: string;\n default_variant_url?: string;\n description: string;\n name: string;\n updated_at: string;\n variants?: DamVariantApi[];\n};\n\nexport const damAssetSchema: z.ZodType<DamAssetApi> = z.object({\n id: z.number(),\n canonical_path: z.string(),\n category: z.string(),\n code: z.string(),\n company: z.string(),\n created_at: z.string(),\n default_variant_id: z.string(),\n default_variant_url: z.string().optional(),\n description: z.string(),\n name: z.string(),\n updated_at: z.string(),\n variants: z.array(damVariantSchema).optional(),\n});\n\ntype DamTreeFolderNode = {\n asset_code?: string | Record<string, unknown>;\n name?: string | Record<string, unknown>;\n category?: string | Record<string, unknown>;\n variants?: unknown[] | Record<string, unknown>;\n [key: string]: unknown;\n};\n\nexport const damTreeFolderNodeSchema: z.ZodType<DamTreeFolderNode> = z\n .object({\n asset_code: z\n .union([z.string(), z.record(z.string(), z.unknown())])\n .optional(),\n name: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),\n category: z\n .union([z.string(), z.record(z.string(), z.unknown())])\n .optional(),\n variants: z\n .union([z.array(z.unknown()), z.record(z.string(), z.unknown())])\n .optional(),\n })\n .passthrough();\n\nexport const damTreeSchema: z.ZodType<Record<string, any>> = z.record(\n z.string(),\n z.union([\n z.lazy(() => damTreeSchema),\n damAssetSchema,\n damTreeFolderNodeSchema,\n ]),\n);\n\ntype DamQueryResponse = {\n path: string;\n tree: Record<string, any>;\n meta?: { next_cursor?: string };\n};\n\nexport const damQueryResponseSchema: z.ZodType<DamQueryResponse> = z.object({\n path: z.string(),\n tree: damTreeSchema,\n meta: z\n .object({\n next_cursor: z.string().optional(),\n })\n .optional(),\n});\n\ntype DamAssetCreateRequest = {\n asset: {\n file: any;\n name: string;\n description?: string;\n tags?: string;\n };\n};\n\nexport const damAssetCreateRequestSchema: z.ZodType<DamAssetCreateRequest> =\n z.object({\n asset: z.object({\n file: z.any(),\n name: z.string(),\n description: z.string().optional(),\n tags: z.string().optional(),\n }),\n });\n\ntype DamAssetCreateResponse = {\n asset: DamAssetApi;\n meta: { request_id: string; timestamp: string };\n};\n\nexport const damAssetCreateResponseSchema: z.ZodType<DamAssetCreateResponse> =\n z.object({\n asset: damAssetSchema,\n meta: z.object({\n request_id: z.string(),\n timestamp: z.string(),\n }),\n });\n\n// Schema for creating asset with placeholder (for ImageKit direct upload)\ntype DamAssetCreateWithPlaceholderRequest = {\n placeholder_asset: {\n mime_type: string;\n name?: string;\n description?: string;\n };\n skip_autotagging?: boolean;\n};\n\nexport const damAssetCreateWithPlaceholderRequestSchema: z.ZodType<DamAssetCreateWithPlaceholderRequest> =\n z.object({\n placeholder_asset: z.object({\n mime_type: z.string(),\n name: z.string().optional(),\n description: z.string().optional(),\n }),\n skip_autotagging: z.boolean().optional(),\n });\n\n// Schema for creating asset path without file upload (legacy)\ntype DamAssetPathCreateRequest = {\n asset?: {\n file: any;\n name: string;\n description?: string;\n tags?: string;\n };\n text_asset?: {\n file_name: string;\n mime_type: string;\n text: string;\n name?: string;\n description?: string;\n tags?: string;\n };\n placeholder_asset?: {\n mime_type: string;\n name?: string;\n description?: string;\n };\n skip_autotagging?: boolean;\n};\n\nexport const damAssetPathCreateRequestSchema: z.ZodType<DamAssetPathCreateRequest> =\n z.object({\n asset: z\n .object({\n file: z.any(),\n name: z.string(),\n description: z.string().optional(),\n tags: z.string().optional(),\n })\n .optional(),\n text_asset: z\n .object({\n file_name: z.string(),\n mime_type: z.string(),\n text: z.string(),\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.string().optional(),\n })\n .optional(),\n placeholder_asset: z\n .object({\n mime_type: z.string(),\n name: z.string().optional(),\n description: z.string().optional(),\n })\n .optional(),\n skip_autotagging: z.boolean().optional(),\n });\n\ntype DamAssetPathCreateResponse = {\n asset: { id: number; canonical_path: string; name: string };\n meta: { request_id: string; timestamp: string };\n};\n\nexport const damAssetPathCreateResponseSchema: z.ZodType<DamAssetPathCreateResponse> =\n z.object({\n asset: z.object({\n id: z.number(),\n canonical_path: z.string(),\n name: z.string(),\n }),\n meta: z.object({\n request_id: z.string(),\n timestamp: z.string(),\n }),\n });\n\nexport type { DamVariantApi, DamAssetApi };\nexport type DamTreeApi = z.infer<typeof damTreeSchema>;\nexport type { DamQueryResponse };\nexport type { DamAssetCreateRequest };\nexport type { DamAssetCreateResponse };\nexport type { DamAssetCreateWithPlaceholderRequest };\nexport type { DamAssetPathCreateRequest };\nexport type { DamAssetPathCreateResponse };\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport type { DamAssetCreateResponse } from \"@fluid-app/file-picker-core\";\n\nexport interface DamUploadStrategy {\n uploadFile(params: {\n file: File;\n name: string;\n description?: string;\n tags?: string[];\n onProgress?: (progress: number) => void;\n companyId?: number;\n }): Promise<DamAssetCreateResponse>;\n}\n\nexport interface FilePickerClientConfig {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint?: string; // defaults to \"/api/proxy-url\"\n}\n\nexport interface FilePickerClient {\n fetchClient: FetchClientInstance;\n uploadStrategy?: DamUploadStrategy;\n unsplashAccessKey?: string;\n proxyEndpoint: string;\n}\n\nexport function createFilePickerClient(\n config: FilePickerClientConfig,\n): FilePickerClient {\n return {\n fetchClient: config.fetchClient,\n uploadStrategy: config.uploadStrategy,\n unsplashAccessKey: config.unsplashAccessKey,\n proxyEndpoint: config.proxyEndpoint ?? \"/api/proxy-url\",\n };\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport {\n damAssetCreateResponseSchema,\n damAssetPathCreateResponseSchema,\n getFileMimeType,\n type CreateDamAssetParams,\n type CreateDamAssetPathForAssetsParams,\n type DamAssetCreateResponse,\n type DamAssetCreateWithPlaceholderRequest,\n type DamAssetPathCreateRequest,\n type DamAssetPathCreateResponse,\n} from \"@fluid-app/file-picker-core\";\nimport type { DamUploadStrategy } from \"../client\";\n\nexport type { CreateDamAssetParams };\n\nexport interface CreateDamAssetPathParams {\n name: string;\n description?: string;\n tags?: string[];\n companyId?: number;\n mimeType?: string;\n textContent?: string;\n fileName?: string;\n skipAutotagging?: boolean;\n}\n\n/**\n * Create a DAM asset. Text files use FormData upload; non-text files\n * delegate to the provided uploadStrategy (e.g. ImageKit).\n * If no uploadStrategy is provided, all files use FormData upload.\n */\nexport async function createDamAsset(\n fetchClient: FetchClientInstance,\n params: CreateDamAssetParams,\n uploadStrategy?: DamUploadStrategy,\n): Promise<DamAssetCreateResponse> {\n const mimeType = getFileMimeType(params.file);\n const isTextFile =\n mimeType.startsWith(\"text/\") ||\n mimeType === \"application/json\" ||\n mimeType === \"application/xml\" ||\n params.file.name.endsWith(\".txt\") ||\n params.file.name.endsWith(\".json\") ||\n params.file.name.endsWith(\".xml\") ||\n params.file.name.endsWith(\".csv\");\n\n // For text files, use traditional FormData upload\n if (isTextFile) {\n return createDamAssetViaFormData(fetchClient, params);\n }\n\n // For non-text files, use upload strategy if available\n if (uploadStrategy) {\n return uploadStrategy.uploadFile(params);\n }\n\n // Fallback to FormData upload\n return createDamAssetViaFormData(fetchClient, params);\n}\n\nasync function createDamAssetViaFormData(\n fetchClient: FetchClientInstance,\n params: CreateDamAssetParams,\n): Promise<DamAssetCreateResponse> {\n const formData = new FormData();\n formData.append(\"asset[file]\", params.file);\n formData.append(\"asset[name]\", params.name);\n\n if (params.description) {\n formData.append(\"asset[description]\", params.description);\n }\n\n if (params.tags && params.tags.length > 0) {\n formData.append(\"asset[tags]\", params.tags.join(\",\"));\n }\n\n const response = await fetchClient.requestWithFormData<unknown>(\n \"/dam/assets\",\n formData,\n { method: \"POST\" },\n );\n return damAssetCreateResponseSchema.parse(response);\n}\n\n/**\n * Create DAM asset with placeholder for direct upload strategies\n */\nexport async function createDamAssetWithPlaceholder(\n fetchClient: FetchClientInstance,\n params: CreateDamAssetPathParams,\n): Promise<DamAssetPathCreateResponse> {\n if (!params.mimeType) {\n throw new Error(\"mimeType is required for createDamAssetWithPlaceholder\");\n }\n const requestData: DamAssetCreateWithPlaceholderRequest = {\n placeholder_asset: {\n mime_type: params.mimeType,\n name: params.name,\n description: params.description,\n },\n };\n\n if (params.skipAutotagging !== undefined) {\n requestData.skip_autotagging = params.skipAutotagging;\n }\n\n const response = await fetchClient.post<unknown>(\"/dam/assets\", requestData);\n return damAssetPathCreateResponseSchema.parse(response);\n}\n\n/**\n * Create DAM asset path without file upload (legacy)\n */\nexport async function createDamAssetPath(\n fetchClient: FetchClientInstance,\n params: CreateDamAssetPathParams,\n): Promise<DamAssetPathCreateResponse> {\n const requestData: DamAssetPathCreateRequest = {};\n\n if (params.textContent && params.mimeType && params.fileName) {\n requestData.text_asset = {\n file_name: params.fileName,\n mime_type: params.mimeType,\n text: params.textContent,\n name: params.name,\n description: params.description,\n tags: params.tags?.join(\",\"),\n };\n } else if (params.mimeType) {\n requestData.placeholder_asset = {\n mime_type: params.mimeType,\n name: params.name,\n description: params.description,\n };\n } else {\n requestData.asset = {\n file: null,\n name: params.name,\n description: params.description,\n tags: params.tags?.join(\",\"),\n };\n }\n\n if (params.skipAutotagging !== undefined) {\n requestData.skip_autotagging = params.skipAutotagging;\n }\n\n const response = await fetchClient.post<unknown>(\"/dam/assets\", requestData);\n return damAssetPathCreateResponseSchema.parse(response);\n}\n\nexport type { CreateDamAssetPathForAssetsParams } from \"@fluid-app/file-picker-core\";\n\nexport async function createDamAssetPathForAssets(\n fetchClient: FetchClientInstance,\n { asset_paths, code }: CreateDamAssetPathForAssetsParams,\n): Promise<DamAssetPathCreateResponse> {\n const response = await fetchClient.post<unknown>(\n `/dam/assets/${code}/asset_paths`,\n { asset_paths },\n );\n return damAssetPathCreateResponseSchema.parse(response);\n}\n","import type { FetchClientInstance } from \"@fluid-app/api-client-core\";\nimport {\n damQueryResponseSchema,\n type DamQueryParams,\n type DamQueryResponse,\n} from \"@fluid-app/file-picker-core\";\n\nexport async function queryDamAssets(\n fetchClient: FetchClientInstance,\n params: DamQueryParams,\n): Promise<DamQueryResponse> {\n const response = await fetchClient.post<unknown>(\"/dam/query\", params);\n return damQueryResponseSchema.parse(response);\n}\n\nexport async function deleteDamAsset(\n fetchClient: FetchClientInstance,\n code: string,\n): Promise<unknown> {\n return fetchClient.delete(`/dam/assets/${code}`);\n}\n\nexport async function discardDamAsset(\n fetchClient: FetchClientInstance,\n code: string,\n): Promise<unknown> {\n return fetchClient.patch(`/dam/assets/${code}/discard`);\n}\n","import { z } from \"zod\";\nimport type {\n UnsplashImage,\n UnsplashSearchResponse,\n} from \"@fluid-app/file-picker-core\";\n\nexport type { UnsplashImage, UnsplashSearchResponse };\n\nconst unsplashImageSchema: z.ZodType<UnsplashImage> = z.object({\n id: z.string(),\n urls: z.object({\n raw: z.string(),\n full: z.string(),\n regular: z.string(),\n small: z.string(),\n thumb: z.string(),\n }),\n alt_description: z.string().nullable(),\n description: z.string().nullable(),\n user: z.object({ name: z.string(), username: z.string() }),\n width: z.number(),\n height: z.number(),\n});\n\nconst unsplashSearchResponseSchema: z.ZodType<UnsplashSearchResponse> =\n z.object({\n results: z.array(unsplashImageSchema),\n total: z.number(),\n total_pages: z.number(),\n });\n\n/**\n * Search Unsplash for photos matching a query.\n */\nexport async function searchUnsplash(\n query: string,\n accessKey: string,\n page: number = 1,\n perPage: number = 20,\n): Promise<UnsplashSearchResponse> {\n const response = await fetch(\n `https://api.unsplash.com/search/photos?query=${encodeURIComponent(query)}&page=${page}&per_page=${perPage}&client_id=${accessKey}`,\n );\n\n if (!response.ok) {\n throw new Error(\"Failed to search Unsplash\");\n }\n\n return unsplashSearchResponseSchema.parse(await response.json());\n}\n","import { z } from \"zod\";\nimport type { UrlProxyResponse } from \"@fluid-app/file-picker-core\";\n\nexport type { UrlProxyResponse };\n\nconst urlProxyResponseSchema: z.ZodType<UrlProxyResponse> = z.object({\n data: z.string(),\n contentType: z.string(),\n size: z.number(),\n});\n\n/**\n * Proxy a URL fetch through the backend to bypass CORS restrictions.\n * The backend fetches the file and returns it as base64-encoded data.\n *\n * @param url - The URL to fetch\n * @param proxyEndpoint - The proxy endpoint (defaults to \"/api/proxy-url\")\n */\nexport async function proxyUrlFetch(\n url: string,\n proxyEndpoint: string = \"/api/proxy-url\",\n): Promise<UrlProxyResponse> {\n const response = await fetch(proxyEndpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ url }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({\n error: \"Failed to proxy URL fetch\",\n }));\n throw new Error(\n (errorData as { error?: string }).error || `HTTP ${response.status}`,\n );\n }\n\n const data: unknown = await response.json();\n return urlProxyResponseSchema.parse(data);\n}\n","import type { FilePickerApi } from \"@fluid-app/file-picker-core\";\nimport type { FilePickerClient } from \"./client\";\nimport { createDamAsset, createDamAssetPathForAssets } from \"./api/dam-assets\";\nimport {\n queryDamAssets,\n deleteDamAsset,\n discardDamAsset,\n} from \"./api/dam-query\";\nimport { searchUnsplash } from \"./api/unsplash\";\nimport { proxyUrlFetch } from \"./api/url-proxy\";\n\n/**\n * Creates a FilePickerApi-compatible adapter backed by the real API client\n * functions. The returned object satisfies the FilePickerApi interface\n * from @fluid-app/file-picker-core via structural typing.\n */\nexport function createFilePickerApi(client: FilePickerClient): FilePickerApi {\n return {\n createDamAsset: (params: Parameters<typeof createDamAsset>[1]) =>\n createDamAsset(client.fetchClient, params, client.uploadStrategy),\n queryDamAssets: (params: Parameters<typeof queryDamAssets>[1]) =>\n queryDamAssets(client.fetchClient, params),\n searchUnsplash: (query: string, page?: number, perPage?: number) => {\n if (!client.unsplashAccessKey) {\n throw new Error(\"Unsplash access key not configured\");\n }\n return searchUnsplash(query, client.unsplashAccessKey, page, perPage);\n },\n deleteDamAsset: (code: string) => deleteDamAsset(client.fetchClient, code),\n discardDamAsset: (code: string) =>\n discardDamAsset(client.fetchClient, code),\n createDamAssetPathForAssets: (\n params: Parameters<typeof createDamAssetPathForAssets>[1],\n ) => createDamAssetPathForAssets(client.fetchClient, params),\n proxyUrlFetch: (url: string) => proxyUrlFetch(url, client.proxyEndpoint),\n };\n}\n","import { useCallback, useMemo, type ComponentProps } from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n ColorOptions,\n PaddingOptions,\n} from \"../types\";\nimport type { WidgetPropertySchema } from \"../registries/property-schema-types\";\nimport {\n ShareablesCoreProvider,\n ShareablesApiProvider,\n type ShareablesApi,\n} from \"@fluid-app/shareables-core\";\nimport { ShareablesUIProvider, ShareablesApp } from \"@fluid-app/shareables-ui\";\nimport { createShareablesApiAdapter } from \"@fluid-app/shareables-api-client\";\nimport {\n createFilePickerClient,\n createFilePickerApi,\n} from \"@fluid-app/file-picker-api-client\";\nimport { useCurrentUser } from \"../hooks/use-current-user\";\nimport { useAppNavigation } from \"../shell/AppNavigationContext\";\nimport { useSdkClient } from \"../account/use-account-clients\";\nimport { useUserType } from \"../hooks/use-user-type\";\n\ntype ShareablesScreenProps = ComponentProps<\"div\"> & {\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n};\n\n/**\n * Parse the current shareables sub-route from the full slug.\n *\n * System nav slugs are \"share/products\", \"share/media\", \"share/playlists\".\n * Detail pages append an ID: \"share/products/123\", \"share/media/456\".\n *\n * \"share/products\" → screen=\"products\", detailId=null\n * \"share/products/123\" → screen=\"products\", detailId=\"123\"\n * \"share/media/456\" → screen=\"media\", detailId=\"456\"\n * \"share/playlists\" → screen=\"playlists\", detailId=null\n * \"share/playlists/789\" → screen=\"playlists\", detailId=\"789\"\n * \"share/files\" → screen=\"files\", detailId=null\n * \"share\" → screen=null (default to products)\n */\nfunction parseShareablesRoute(currentSlug: string): {\n screen: string | null;\n detailId: string | null;\n action: string | null;\n} {\n // Strip the \"share\" prefix\n const slugWithoutPrefix = currentSlug.replace(/^share\\/?/, \"\");\n if (!slugWithoutPrefix) {\n return { screen: null, detailId: null, action: null };\n }\n\n const parts = slugWithoutPrefix.split(\"/\");\n const screen = parts[0] || null;\n const detailId = parts[1] || null;\n const action = parts[2] || null;\n return { screen, detailId, action };\n}\n\nexport function ShareablesScreen({\n /* eslint-disable @typescript-eslint/no-unused-vars -- destructured to exclude from divProps spread */\n background,\n textColor,\n accentColor,\n padding,\n borderRadius,\n /* eslint-enable @typescript-eslint/no-unused-vars */\n ...divProps\n}: ShareablesScreenProps): React.JSX.Element {\n const domainClient = useSdkClient();\n const { data: userData } = useCurrentUser();\n const { currentSlug, navigate } = useAppNavigation();\n const { isCustomer } = useUserType();\n\n const { screen, detailId, action } = parseShareablesRoute(currentSlug);\n\n const handleNavigate = useCallback(\n (subScreen: string, id?: string) => {\n const path = id ? `share/${subScreen}/${id}` : `share/${subScreen}`;\n navigate(path);\n },\n [navigate],\n );\n\n const handleBack = useCallback(() => {\n if (detailId && screen) {\n // Navigate back to the listing for the current screen\n navigate(`share/${screen}`);\n } else {\n // Navigate to the default shareables screen\n navigate(\"share/products\");\n }\n }, [navigate, detailId, screen]);\n\n const coreConfig = useMemo(\n () => ({\n client: domainClient,\n user: userData ? { id: userData.id } : null,\n repContext: true,\n }),\n [domainClient, userData],\n );\n\n const shareablesApi = useMemo<ShareablesApi>(\n () => createShareablesApiAdapter(domainClient, { repContext: true }),\n [domainClient],\n );\n\n const filePickerApi = useMemo(\n () =>\n createFilePickerApi(\n createFilePickerClient({ fetchClient: domainClient }),\n ),\n [domainClient],\n );\n\n const uiConfig = useMemo(\n () => ({\n user: userData\n ? {\n id: userData.id,\n company: userData.company\n ? { logo_url: userData.company.logo_url }\n : null,\n }\n : undefined,\n affiliateId:\n (userData as { affiliate_id?: number } | undefined)?.affiliate_id ??\n null,\n basePath: \"\",\n navigate: (path: string) => {\n // Strip leading slash — cards generate paths like \"/share/product/123\"\n const cleanPath = path.replace(/^\\//, \"\");\n // Ensure share/ prefix — screen components pass relative paths like \"media/new\"\n const prefixed = cleanPath.startsWith(\"share/\")\n ? cleanPath\n : `share/${cleanPath}`;\n navigate(prefixed);\n },\n showToast: (opts: {\n title: string;\n type: \"success\" | \"error\" | \"warning\";\n }) => {\n console.warn(`[Shareables] ${opts.type}: ${opts.title}`);\n },\n filePickerApi,\n onToggleFavorite: async (params: {\n favoriteableId: number;\n favoriteableType: string;\n }) => {\n const affiliateId = (userData as { affiliate_id?: number } | undefined)\n ?.affiliate_id;\n if (!affiliateId) throw new Error(\"No affiliate ID\");\n return domainClient.post<{ is_favorited: boolean }>(\n `/user_companies/${affiliateId}/favorites/toggle.json`,\n {\n favoriteable_id: params.favoriteableId,\n favoriteable_type: params.favoriteableType,\n },\n );\n },\n onDeletePlaylist: isCustomer\n ? undefined\n : async (playlistId: number) => {\n const { playlists: playlistsApi } =\n await import(\"@fluid-app/shareables-api-client\");\n await playlistsApi.deletePlaylist(domainClient, playlistId);\n },\n readOnly: isCustomer,\n }),\n [userData, navigate, filePickerApi, domainClient, isCustomer],\n );\n\n return (\n <div {...divProps} className={`h-full ${divProps.className ?? \"\"}`}>\n <ShareablesCoreProvider config={coreConfig}>\n <ShareablesApiProvider api={shareablesApi}>\n <ShareablesUIProvider config={uiConfig}>\n <ShareablesApp\n screen={screen}\n detailId={detailId}\n action={action}\n companyLogoUrl={userData?.company?.logo_url}\n countryCode={userData?.country?.iso}\n onNavigate={handleNavigate}\n onBack={handleBack}\n />\n </ShareablesUIProvider>\n </ShareablesApiProvider>\n </ShareablesCoreProvider>\n </div>\n );\n}\n\nexport const shareablesScreenPropertySchema: WidgetPropertySchema = {\n widgetType: \"ShareablesScreen\",\n displayName: \"Shareables Screen\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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"}
|