@fayz-ai/storefront 0.83.1 → 0.84.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CheckoutPage-DDY4WLFJ.js +12 -0
- package/dist/CheckoutPage-DDY4WLFJ.js.map +1 -0
- package/dist/MyPurchasesPage-IHCB5QRR.js +11 -0
- package/dist/MyPurchasesPage-IHCB5QRR.js.map +1 -0
- package/dist/OrderConfirmationPage-SAKAGOCC.js +10 -0
- package/dist/OrderConfirmationPage-SAKAGOCC.js.map +1 -0
- package/dist/app/createStorefrontApp.d.ts.map +1 -1
- package/dist/chunk-45R7CIEA.js +234 -0
- package/dist/chunk-45R7CIEA.js.map +1 -0
- package/dist/chunk-BKO2AQ3Q.js +329 -0
- package/dist/chunk-BKO2AQ3Q.js.map +1 -0
- package/dist/chunk-CV6RYJIC.js +454 -0
- package/dist/chunk-CV6RYJIC.js.map +1 -0
- package/dist/chunk-D5C5U2SG.js +267 -0
- package/dist/chunk-D5C5U2SG.js.map +1 -0
- package/dist/chunk-DRMDBXMT.js +2123 -0
- package/dist/chunk-DRMDBXMT.js.map +1 -0
- package/dist/chunk-DVQHKNNX.js +29 -0
- package/dist/chunk-DVQHKNNX.js.map +1 -0
- package/dist/chunk-FCPOPWG3.js +31 -0
- package/dist/chunk-FCPOPWG3.js.map +1 -0
- package/dist/chunk-GQ3TCJVX.js +216 -0
- package/dist/chunk-GQ3TCJVX.js.map +1 -0
- package/dist/{chunk-7N5HKQBM.js → chunk-GVZ2SAOI.js} +5 -552
- package/dist/chunk-GVZ2SAOI.js.map +1 -0
- package/dist/{chunk-G2R6OJQA.js → chunk-H6IOPA3J.js} +5 -4
- package/dist/chunk-H6IOPA3J.js.map +1 -0
- package/dist/{chunk-OV6DVQMB.js → chunk-HRLF5NYO.js} +1202 -6512
- package/dist/chunk-HRLF5NYO.js.map +1 -0
- package/dist/chunk-K27LYMSF.js +435 -0
- package/dist/chunk-K27LYMSF.js.map +1 -0
- package/dist/chunk-MFAU3AWK.js +817 -0
- package/dist/chunk-MFAU3AWK.js.map +1 -0
- package/dist/chunk-OHWX6BEY.js +436 -0
- package/dist/chunk-OHWX6BEY.js.map +1 -0
- package/dist/chunk-PATS4DIF.js +484 -0
- package/dist/chunk-PATS4DIF.js.map +1 -0
- package/dist/chunk-WDQFNHYO.js +41 -0
- package/dist/chunk-WDQFNHYO.js.map +1 -0
- package/dist/chunk-WPWNYBNG.js +68 -0
- package/dist/chunk-WPWNYBNG.js.map +1 -0
- package/dist/chunk-WXXYJZE6.js +99 -0
- package/dist/chunk-WXXYJZE6.js.map +1 -0
- package/dist/components/delivery/StoreCover.d.ts +3 -1
- package/dist/components/delivery/StoreCover.d.ts.map +1 -1
- package/dist/extend/slots.d.ts +48 -0
- package/dist/extend/slots.d.ts.map +1 -1
- package/dist/host.js +4 -2
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -6
- package/dist/index.js.map +1 -1
- package/dist/render.js +11 -3
- package/dist/render.js.map +1 -1
- package/dist/tanstack.js +10 -2
- package/dist/tanstack.js.map +1 -1
- package/dist/views/MenuPage.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-7N5HKQBM.js.map +0 -1
- package/dist/chunk-G2R6OJQA.js.map +0 -1
- package/dist/chunk-OV6DVQMB.js.map +0 -1
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import React2, { createContext, useContext, useEffect, useSyncExternalStore, useRef
|
|
2
|
-
import { staticRouterAdapter,
|
|
3
|
-
import { getShopProvider } from '@fayz-ai/shop/runtime';
|
|
4
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
-
import { imageVariantUrl } from '@fayz-ai/shop';
|
|
1
|
+
import React2, { createContext, useContext, useEffect, useSyncExternalStore, useRef } from 'react';
|
|
2
|
+
import { staticRouterAdapter, defaultRouterAdapter } from '@fayz-ai/core';
|
|
6
3
|
|
|
7
4
|
// src/locales/messages.ts
|
|
8
5
|
var ptBR = {
|
|
@@ -634,551 +631,7 @@ function withStaticRenderPass(pass, render) {
|
|
|
634
631
|
active = previous;
|
|
635
632
|
}
|
|
636
633
|
}
|
|
637
|
-
function resolveDataParams(need, context) {
|
|
638
|
-
const out = {};
|
|
639
|
-
for (const [name, value] of Object.entries(need.params ?? {})) {
|
|
640
|
-
let resolved = value;
|
|
641
|
-
if (isLoaderParamRef(value)) resolved = context.params[value.$param];
|
|
642
|
-
else if (isLoaderPropRef(value)) resolved = context.props[value.$prop];
|
|
643
|
-
if (resolved !== void 0) out[name] = resolved;
|
|
644
|
-
}
|
|
645
|
-
return out;
|
|
646
|
-
}
|
|
647
|
-
function needsForNode(node) {
|
|
648
|
-
const meta = getBlockMeta(node.type);
|
|
649
|
-
return { ...meta?.data, ...node.data };
|
|
650
|
-
}
|
|
651
|
-
function collectDataNeeds(nodes, routeParams = {}) {
|
|
652
|
-
const found = /* @__PURE__ */ new Map();
|
|
653
|
-
const visit = (node) => {
|
|
654
|
-
const meta = getBlockMeta(node.type);
|
|
655
|
-
const needs = needsForNode(node);
|
|
656
|
-
if (Object.keys(needs).length > 0) {
|
|
657
|
-
const props = { ...defaultPropsFromSettings(meta?.settings), ...node.props };
|
|
658
|
-
for (const need of Object.values(needs)) {
|
|
659
|
-
if (!need || typeof need.loader !== "string" || !need.loader) continue;
|
|
660
|
-
const params = resolveDataParams(need, { params: routeParams, props });
|
|
661
|
-
const key = dataNeedKey(need.loader, params);
|
|
662
|
-
if (!found.has(key)) found.set(key, { key, loader: need.loader, params });
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
for (const child of node.children ?? []) visit(child);
|
|
666
|
-
};
|
|
667
|
-
for (const node of nodes) visit(node);
|
|
668
|
-
return [...found.values()];
|
|
669
|
-
}
|
|
670
|
-
async function resolvePageDataNeed(need) {
|
|
671
|
-
try {
|
|
672
|
-
const impl = resolveLoader(need.loader);
|
|
673
|
-
const data = await impl(need.params, { shop: getShopProvider() });
|
|
674
|
-
return { status: "ready", data };
|
|
675
|
-
} catch (err) {
|
|
676
|
-
const message = errorMessage(err);
|
|
677
|
-
console.error(`[storefront] loader "${need.loader}" failed:`, err);
|
|
678
|
-
return { status: "error", error: message };
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
async function resolvePageData(needs) {
|
|
682
|
-
const settled = await Promise.all(
|
|
683
|
-
needs.map(async (need) => [need.key, await resolvePageDataNeed(need)])
|
|
684
|
-
);
|
|
685
|
-
return Object.fromEntries(settled);
|
|
686
|
-
}
|
|
687
|
-
var PageDataContext = createContext(null);
|
|
688
|
-
function PageDataScope({ nodes, params, initial, children }) {
|
|
689
|
-
const parent = useContext(PageDataContext);
|
|
690
|
-
const routeParams = useMemo(() => params ?? parent?.params ?? {}, [params, parent]);
|
|
691
|
-
const needs = useMemo(() => collectDataNeeds(nodes, routeParams), [nodes, routeParams]);
|
|
692
|
-
const own = useMemo(
|
|
693
|
-
() => needs.filter((need) => !parent || !(need.key in parent.entries)),
|
|
694
|
-
[needs, parent]
|
|
695
|
-
);
|
|
696
|
-
const staticPass = currentStaticRenderPass();
|
|
697
|
-
if (staticPass) {
|
|
698
|
-
staticPass.tree(nodes);
|
|
699
|
-
staticPass.needs(own);
|
|
700
|
-
}
|
|
701
|
-
const [entries, setEntries] = useState(() => ({
|
|
702
|
-
// Everything handed in is published, not only the needs THIS scope
|
|
703
|
-
// collected. That is what lets a host framework resolve a page's data in
|
|
704
|
-
// its own loader and wrap the shell in a seeding scope: the page's own
|
|
705
|
-
// scope then finds those keys already answered on its parent and fetches
|
|
706
|
-
// nothing. Without it, seeding only works when the seeding scope happens to
|
|
707
|
-
// render the same block tree.
|
|
708
|
-
...initial,
|
|
709
|
-
...Object.fromEntries(
|
|
710
|
-
own.map((need) => [
|
|
711
|
-
need.key,
|
|
712
|
-
initial?.[need.key] ?? staticPass?.entries[need.key] ?? { status: "loading" }
|
|
713
|
-
])
|
|
714
|
-
)
|
|
715
|
-
}));
|
|
716
|
-
const signature = own.map((need) => need.key).join("\n");
|
|
717
|
-
useEffect(() => {
|
|
718
|
-
const pending = own.filter((need) => initial?.[need.key]?.status !== "ready");
|
|
719
|
-
if (pending.length === 0) return;
|
|
720
|
-
let cancelled = false;
|
|
721
|
-
setEntries((prev) => {
|
|
722
|
-
const next = { ...prev };
|
|
723
|
-
for (const need of pending) {
|
|
724
|
-
if (next[need.key]?.status !== "ready") next[need.key] = { status: "loading" };
|
|
725
|
-
}
|
|
726
|
-
return next;
|
|
727
|
-
});
|
|
728
|
-
for (const need of pending) {
|
|
729
|
-
void resolvePageDataNeed(need).then((entry) => {
|
|
730
|
-
if (!cancelled) setEntries((prev) => ({ ...prev, [need.key]: entry }));
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
return () => {
|
|
734
|
-
cancelled = true;
|
|
735
|
-
};
|
|
736
|
-
}, [signature]);
|
|
737
|
-
const value = useMemo(
|
|
738
|
-
() => ({ entries: { ...parent?.entries, ...entries, ...initial }, params: routeParams }),
|
|
739
|
-
[parent, entries, initial, routeParams]
|
|
740
|
-
);
|
|
741
|
-
return /* @__PURE__ */ jsx(PageDataContext.Provider, { value, children });
|
|
742
|
-
}
|
|
743
|
-
function useLoader(loader, params) {
|
|
744
|
-
const scope = useContext(PageDataContext);
|
|
745
|
-
const key = params === null ? null : dataNeedKey(loader, params);
|
|
746
|
-
const [nonce, setNonce] = useState(0);
|
|
747
|
-
const scoped = nonce === 0 && key !== null && scope ? scope.entries[key] : void 0;
|
|
748
|
-
const [local, setLocal] = useState(null);
|
|
749
|
-
const staticPass = currentStaticRenderPass();
|
|
750
|
-
const staticEntry = staticPass && key !== null && scoped === void 0 ? staticPass.entries[key] : void 0;
|
|
751
|
-
if (staticPass && key !== null && scoped === void 0 && staticEntry === void 0) {
|
|
752
|
-
staticPass.needs([{ key, loader, params }]);
|
|
753
|
-
}
|
|
754
|
-
const paramsKey = params === null ? null : JSON.stringify(params);
|
|
755
|
-
useEffect(() => {
|
|
756
|
-
if (key === null || scoped !== void 0) return;
|
|
757
|
-
let cancelled = false;
|
|
758
|
-
setLocal({ key, entry: { status: "loading" } });
|
|
759
|
-
void resolvePageDataNeed({ loader, params }).then((entry2) => {
|
|
760
|
-
if (!cancelled) setLocal({ key, entry: entry2 });
|
|
761
|
-
});
|
|
762
|
-
return () => {
|
|
763
|
-
cancelled = true;
|
|
764
|
-
};
|
|
765
|
-
}, [loader, paramsKey, nonce, scoped !== void 0]);
|
|
766
|
-
const entry = scoped ?? staticEntry ?? (local && local.key === key ? local.entry : key !== null ? { status: "loading" } : null);
|
|
767
|
-
return {
|
|
768
|
-
status: entry?.status ?? "idle",
|
|
769
|
-
data: entry?.status === "ready" ? entry.data : null,
|
|
770
|
-
error: entry?.status === "error" ? entry.error ?? "unknown error" : null,
|
|
771
|
-
reload: () => setNonce((n) => n + 1)
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
function useBlockData(node, name, fallback) {
|
|
775
|
-
const scope = useContext(PageDataContext);
|
|
776
|
-
let loader = fallback.loader;
|
|
777
|
-
let params = fallback.params;
|
|
778
|
-
if (node) {
|
|
779
|
-
const need = needsForNode(node)[name];
|
|
780
|
-
if (need && typeof need.loader === "string" && need.loader) {
|
|
781
|
-
const meta = getBlockMeta(node.type);
|
|
782
|
-
loader = need.loader;
|
|
783
|
-
params = resolveDataParams(need, {
|
|
784
|
-
params: scope?.params ?? {},
|
|
785
|
-
props: { ...defaultPropsFromSettings(meta?.settings), ...node.props }
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
const result = useLoader(loader, params);
|
|
790
|
-
return { ...result, loader };
|
|
791
|
-
}
|
|
792
|
-
function BlockDataError({ loader, message }) {
|
|
793
|
-
if (getBlockErrorVisibility() === "silent") return null;
|
|
794
|
-
return /* @__PURE__ */ jsxs(
|
|
795
|
-
"div",
|
|
796
|
-
{
|
|
797
|
-
"data-block-error": `loader:${loader}`,
|
|
798
|
-
style: {
|
|
799
|
-
border: "1px dashed #dc2626",
|
|
800
|
-
color: "#b91c1c",
|
|
801
|
-
padding: "8px 12px",
|
|
802
|
-
font: "12px ui-monospace, monospace",
|
|
803
|
-
borderRadius: 6
|
|
804
|
-
},
|
|
805
|
-
children: [
|
|
806
|
-
`Data for this block failed (loader "${loader}")`,
|
|
807
|
-
message ? /* @__PURE__ */ jsx("div", { style: { opacity: 0.8, marginTop: 4 }, children: message }) : null
|
|
808
|
-
]
|
|
809
|
-
}
|
|
810
|
-
);
|
|
811
|
-
}
|
|
812
|
-
function mergePageTheme(base, overlay) {
|
|
813
|
-
if (!base && !overlay) return void 0;
|
|
814
|
-
if (!overlay) return base;
|
|
815
|
-
const name = overlay.name ?? (base ? `${base.name}-page` : "page");
|
|
816
|
-
const font = base?.font ? { ...base.font, ...overlay.font } : overlay.font;
|
|
817
|
-
return {
|
|
818
|
-
...base,
|
|
819
|
-
...overlay,
|
|
820
|
-
name,
|
|
821
|
-
colors: { ...base?.colors, ...overlay.colors },
|
|
822
|
-
font,
|
|
823
|
-
tokens: { ...base?.tokens, ...overlay.tokens },
|
|
824
|
-
header: { ...base?.header, ...overlay.header },
|
|
825
|
-
productCard: { ...base?.productCard, ...overlay.productCard }
|
|
826
|
-
};
|
|
827
|
-
}
|
|
828
|
-
function pageThemeSelector(slug) {
|
|
829
|
-
return `[data-page="${slug}"]`;
|
|
830
|
-
}
|
|
831
|
-
function routePathParams(path) {
|
|
832
|
-
return path.split("/").filter((segment) => segment.startsWith(":")).map((segment) => segment.slice(1));
|
|
833
|
-
}
|
|
834
|
-
function contentPagePath(slug, page) {
|
|
835
|
-
return page.path ?? `/${slug}`;
|
|
836
|
-
}
|
|
837
|
-
function matchContentPage(pages, path) {
|
|
838
|
-
for (const [slug, page] of Object.entries(pages?.content ?? {})) {
|
|
839
|
-
const params = matchPath(contentPagePath(slug, page), path);
|
|
840
|
-
if (params) return { slug, page, params };
|
|
841
|
-
}
|
|
842
|
-
return null;
|
|
843
|
-
}
|
|
844
|
-
var CATALOG_BODY_BLOCK = "catalogBody";
|
|
845
|
-
var PRODUCT_BODY_BLOCK = "productBody";
|
|
846
|
-
var BODY_BLOCK_BY_KIND = {
|
|
847
|
-
catalog: CATALOG_BODY_BLOCK,
|
|
848
|
-
product: PRODUCT_BODY_BLOCK
|
|
849
|
-
};
|
|
850
|
-
var BLOCK_STRUCTURAL_KEYS = /* @__PURE__ */ new Set([
|
|
851
|
-
"type",
|
|
852
|
-
"id",
|
|
853
|
-
"props",
|
|
854
|
-
"children",
|
|
855
|
-
"data"
|
|
856
|
-
]);
|
|
857
|
-
var STRUCTURAL_KEYS = BLOCK_STRUCTURAL_KEYS;
|
|
858
|
-
function isNestedBlockRef(entry) {
|
|
859
|
-
return isNestedRef(entry);
|
|
860
|
-
}
|
|
861
|
-
function isNestedRef(entry) {
|
|
862
|
-
const record = entry;
|
|
863
|
-
if ("props" in record) return true;
|
|
864
|
-
return Object.keys(record).every((key) => STRUCTURAL_KEYS.has(key));
|
|
865
|
-
}
|
|
866
|
-
function blockInstanceId(entry, index) {
|
|
867
|
-
const record = entry;
|
|
868
|
-
if (record && typeof record.id === "string" && record.id) return record.id;
|
|
869
|
-
return `${String(record?.type)}-${index}`;
|
|
870
|
-
}
|
|
871
|
-
function toBlockNode(entry, index) {
|
|
872
|
-
const record = entry;
|
|
873
|
-
const type = String(record.type);
|
|
874
|
-
const id = blockInstanceId(entry, index);
|
|
875
|
-
const data = record.data;
|
|
876
|
-
if (isNestedRef(entry)) {
|
|
877
|
-
const children = record.children ?? [];
|
|
878
|
-
return {
|
|
879
|
-
type,
|
|
880
|
-
id,
|
|
881
|
-
props: record.props ?? {},
|
|
882
|
-
...children.length ? { children: children.map((child, i) => toBlockNode(child, i)) } : {},
|
|
883
|
-
...data ? { data } : {}
|
|
884
|
-
};
|
|
885
|
-
}
|
|
886
|
-
const props = {};
|
|
887
|
-
for (const [key, value] of Object.entries(record)) {
|
|
888
|
-
if (!STRUCTURAL_KEYS.has(key)) props[key] = value;
|
|
889
|
-
}
|
|
890
|
-
return { type, id, props, ...data ? { data } : {} };
|
|
891
|
-
}
|
|
892
|
-
function toBlockNodes(blocks) {
|
|
893
|
-
return blocks.map(toBlockNode);
|
|
894
|
-
}
|
|
895
|
-
function defaultPageBlocks(kind) {
|
|
896
|
-
const body = BODY_BLOCK_BY_KIND[kind];
|
|
897
|
-
return body ? [{ type: body, id: body, props: {} }] : [];
|
|
898
|
-
}
|
|
899
|
-
function checkPageBlocks(kind, nodes) {
|
|
900
|
-
const found = [];
|
|
901
|
-
const seenIds = /* @__PURE__ */ new Set();
|
|
902
|
-
const expectedBody = BODY_BLOCK_BY_KIND[kind];
|
|
903
|
-
let hasBody = false;
|
|
904
|
-
for (const node of nodes) {
|
|
905
|
-
if (node.type === expectedBody) hasBody = true;
|
|
906
|
-
if (node.id) {
|
|
907
|
-
if (seenIds.has(node.id)) {
|
|
908
|
-
found.push({
|
|
909
|
-
level: "warning",
|
|
910
|
-
rule: "duplicate-block-id",
|
|
911
|
-
detail: `two blocks on the ${kind} page share the id "${node.id}" \u2014 an editor or a generated diff cannot tell them apart`
|
|
912
|
-
});
|
|
913
|
-
}
|
|
914
|
-
seenIds.add(node.id);
|
|
915
|
-
}
|
|
916
|
-
const meta = getBlockMeta(node.type);
|
|
917
|
-
if (!meta) {
|
|
918
|
-
found.push({
|
|
919
|
-
level: "error",
|
|
920
|
-
rule: "unknown-block",
|
|
921
|
-
detail: `the ${kind} page references block "${node.type}", which is not registered \u2014 register it before the storefront mounts`
|
|
922
|
-
});
|
|
923
|
-
continue;
|
|
924
|
-
}
|
|
925
|
-
if (!isBlockEnabledOn({ enabledOn: meta.enabledOn ?? [] }, kind)) {
|
|
926
|
-
found.push({
|
|
927
|
-
level: "warning",
|
|
928
|
-
rule: "block-not-enabled-on-page",
|
|
929
|
-
detail: `block "${node.type}" declares enabledOn [${(meta.enabledOn ?? []).join(", ")}] and is placed on the ${kind} page`
|
|
930
|
-
});
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
if (expectedBody && !hasBody) {
|
|
934
|
-
found.push({
|
|
935
|
-
level: "warning",
|
|
936
|
-
rule: "missing-page-body",
|
|
937
|
-
detail: `the ${kind} page tree omits "${expectedBody}", so the page renders no ${kind === "product" ? "product detail" : "product list"} \u2014 add it back unless the replacement is deliberate`
|
|
938
|
-
});
|
|
939
|
-
}
|
|
940
|
-
for (const violation of checkBlockConstraints(nodes)) {
|
|
941
|
-
found.push({
|
|
942
|
-
level: "error",
|
|
943
|
-
rule: violation.rule,
|
|
944
|
-
detail: `${kind} page ${violation.path}: ${violation.detail}`
|
|
945
|
-
});
|
|
946
|
-
}
|
|
947
|
-
for (const finding of checkBlockContext(nodes)) {
|
|
948
|
-
found.push({
|
|
949
|
-
level: "warning",
|
|
950
|
-
rule: "context-not-provided",
|
|
951
|
-
detail: `block "${finding.type}" at ${kind} page ${finding.path} uses context [${finding.missing.join(", ")}] that no ancestor provides`
|
|
952
|
-
});
|
|
953
|
-
}
|
|
954
|
-
return found;
|
|
955
|
-
}
|
|
956
|
-
function absolute(ctx, path = ctx.path) {
|
|
957
|
-
const origin = (ctx.origin ?? currentStaticRenderPass()?.origin ?? seoOrigin()).replace(/\/$/, "");
|
|
958
|
-
if (!origin) return void 0;
|
|
959
|
-
return `${origin}${path.startsWith("/") ? path : `/${path}`}`;
|
|
960
|
-
}
|
|
961
|
-
function primaryImageUrl(product) {
|
|
962
|
-
return (product.images?.find((i) => i.isPrimary) ?? product.images?.[0])?.url;
|
|
963
|
-
}
|
|
964
|
-
function shareImageUrl(product, ctx) {
|
|
965
|
-
const url = primaryImageUrl(product);
|
|
966
|
-
if (!url) return void 0;
|
|
967
|
-
return ctx.config.imageLoading.transform === "supabase" ? imageVariantUrl(url, { width: 1200, quality: 82 }) : url;
|
|
968
|
-
}
|
|
969
|
-
function productJsonLd(product, ctx) {
|
|
970
|
-
const url = absolute(ctx);
|
|
971
|
-
const image = shareImageUrl(product, ctx);
|
|
972
|
-
return {
|
|
973
|
-
"@context": "https://schema.org",
|
|
974
|
-
"@type": "Product",
|
|
975
|
-
name: product.name,
|
|
976
|
-
...product.description ? { description: product.description } : {},
|
|
977
|
-
...product.sku ? { sku: product.sku } : {},
|
|
978
|
-
...image ? { image: [image] } : {},
|
|
979
|
-
offers: {
|
|
980
|
-
"@type": "Offer",
|
|
981
|
-
...url ? { url } : {},
|
|
982
|
-
price: product.price,
|
|
983
|
-
priceCurrency: product.currency ?? ctx.config.currency,
|
|
984
|
-
availability: (product.inventoryCount ?? 0) > 0 ? "https://schema.org/InStock" : "https://schema.org/OutOfStock"
|
|
985
|
-
}
|
|
986
|
-
};
|
|
987
|
-
}
|
|
988
|
-
function productSeo(product, ctx) {
|
|
989
|
-
const url = absolute(ctx);
|
|
990
|
-
const home = absolute(ctx, "/");
|
|
991
|
-
const catalog = absolute(ctx, ctx.config.catalogPath);
|
|
992
|
-
return {
|
|
993
|
-
title: `${product.name} \u2014 ${ctx.config.name}`,
|
|
994
|
-
description: product.description?.slice(0, 160),
|
|
995
|
-
canonical: url,
|
|
996
|
-
image: shareImageUrl(product, ctx),
|
|
997
|
-
type: "product",
|
|
998
|
-
jsonLd: [
|
|
999
|
-
productJsonLd(product, ctx),
|
|
1000
|
-
...home && catalog && url ? [
|
|
1001
|
-
breadcrumbJsonLd([
|
|
1002
|
-
{ name: ctx.config.name, url: home },
|
|
1003
|
-
{ name: "Loja", url: catalog },
|
|
1004
|
-
{ name: product.name, url }
|
|
1005
|
-
])
|
|
1006
|
-
] : []
|
|
1007
|
-
]
|
|
1008
|
-
};
|
|
1009
|
-
}
|
|
1010
|
-
function pageSeo(ctx, input) {
|
|
1011
|
-
return { ...input, canonical: absolute(ctx), type: "website" };
|
|
1012
|
-
}
|
|
1013
|
-
function menuSections(products, categories) {
|
|
1014
|
-
const byCategory = /* @__PURE__ */ new Map();
|
|
1015
|
-
const loose = [];
|
|
1016
|
-
for (const p of products) {
|
|
1017
|
-
const key = p.categoryId ?? p.categoryName ?? "";
|
|
1018
|
-
if (!key) {
|
|
1019
|
-
loose.push(p);
|
|
1020
|
-
continue;
|
|
1021
|
-
}
|
|
1022
|
-
byCategory.set(key, [...byCategory.get(key) ?? [], p]);
|
|
1023
|
-
}
|
|
1024
|
-
const sections = categories.map((c) => ({ name: c.name, description: c.description, products: byCategory.get(c.id) ?? byCategory.get(c.name) ?? [] })).filter((s) => s.products.length > 0);
|
|
1025
|
-
if (loose.length) sections.push({ name: "Outros", description: null, products: loose });
|
|
1026
|
-
if (!sections.length && products.length) return [{ name: "Card\xE1pio", description: null, products }];
|
|
1027
|
-
return sections;
|
|
1028
|
-
}
|
|
1029
|
-
function menuJsonLd(input, ctx) {
|
|
1030
|
-
const url = absolute(ctx);
|
|
1031
|
-
const home = absolute(ctx, "/");
|
|
1032
|
-
const b = input.business ?? {};
|
|
1033
|
-
const currency = ctx.config.currency;
|
|
1034
|
-
const address = b.address ? {
|
|
1035
|
-
"@type": "PostalAddress",
|
|
1036
|
-
...b.address.streetAddress ? { streetAddress: b.address.streetAddress } : {},
|
|
1037
|
-
...b.address.locality ? { addressLocality: b.address.locality } : {},
|
|
1038
|
-
...b.address.region ? { addressRegion: b.address.region } : {},
|
|
1039
|
-
...b.address.postalCode ? { postalCode: b.address.postalCode } : {},
|
|
1040
|
-
addressCountry: b.address.country ?? "BR"
|
|
1041
|
-
} : void 0;
|
|
1042
|
-
return {
|
|
1043
|
-
"@context": "https://schema.org",
|
|
1044
|
-
"@type": b.type ?? "Restaurant",
|
|
1045
|
-
...home ? { "@id": `${home.replace(/\/$/, "")}/#business` } : {},
|
|
1046
|
-
name: ctx.config.name,
|
|
1047
|
-
...home ? { url: home } : {},
|
|
1048
|
-
...b.description ? { description: b.description } : {},
|
|
1049
|
-
...b.image ? { image: [b.image] } : {},
|
|
1050
|
-
...b.logo ? { logo: b.logo } : {},
|
|
1051
|
-
...b.telephone ? { telephone: b.telephone } : {},
|
|
1052
|
-
...b.email ? { email: b.email } : {},
|
|
1053
|
-
...b.servesCuisine ? { servesCuisine: b.servesCuisine } : {},
|
|
1054
|
-
...b.priceRange ? { priceRange: b.priceRange } : {},
|
|
1055
|
-
...address ? { address } : {},
|
|
1056
|
-
...b.areaServed?.length ? { areaServed: b.areaServed.map((name) => ({ "@type": "Place", name })) } : {},
|
|
1057
|
-
...b.openingHours?.length ? { openingHours: b.openingHours } : {},
|
|
1058
|
-
...b.sameAs?.length ? { sameAs: b.sameAs } : {},
|
|
1059
|
-
...url ? { hasMenu: url } : {},
|
|
1060
|
-
...url ? {
|
|
1061
|
-
potentialAction: {
|
|
1062
|
-
"@type": "OrderAction",
|
|
1063
|
-
target: { "@type": "EntryPoint", urlTemplate: url, actionPlatform: ["https://schema.org/DesktopWebPlatform", "https://schema.org/MobileWebPlatform"] },
|
|
1064
|
-
deliveryMethod: "http://purl.org/goodrelations/v1#DeliveryModeOwnFleet"
|
|
1065
|
-
}
|
|
1066
|
-
} : {},
|
|
1067
|
-
menu: {
|
|
1068
|
-
"@type": "Menu",
|
|
1069
|
-
name: `Card\xE1pio \u2014 ${ctx.config.name}`,
|
|
1070
|
-
...url ? { url } : {},
|
|
1071
|
-
inLanguage: "pt-BR",
|
|
1072
|
-
hasMenuSection: menuSections(input.products, input.categories).map((section) => ({
|
|
1073
|
-
"@type": "MenuSection",
|
|
1074
|
-
name: section.name,
|
|
1075
|
-
...section.description ? { description: section.description } : {},
|
|
1076
|
-
hasMenuItem: section.products.map((p) => {
|
|
1077
|
-
const image = shareImageUrl(p, ctx);
|
|
1078
|
-
const itemUrl = absolute(ctx, `/product/${p.slug}`);
|
|
1079
|
-
return {
|
|
1080
|
-
"@type": "MenuItem",
|
|
1081
|
-
name: p.name,
|
|
1082
|
-
...p.description ? { description: p.description.slice(0, 300) } : {},
|
|
1083
|
-
...image ? { image } : {},
|
|
1084
|
-
...itemUrl ? { url: itemUrl } : {},
|
|
1085
|
-
offers: {
|
|
1086
|
-
"@type": "Offer",
|
|
1087
|
-
price: p.price,
|
|
1088
|
-
priceCurrency: p.currency ?? currency,
|
|
1089
|
-
availability: (p.inventoryCount ?? 0) > 0 ? "https://schema.org/InStock" : "https://schema.org/OutOfStock"
|
|
1090
|
-
}
|
|
1091
|
-
};
|
|
1092
|
-
})
|
|
1093
|
-
}))
|
|
1094
|
-
}
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
|
-
function menuSeo(input, ctx) {
|
|
1098
|
-
const url = absolute(ctx);
|
|
1099
|
-
const home = absolute(ctx, "/");
|
|
1100
|
-
const names = input.products.slice(0, 4).map((p) => p.name).join(", ");
|
|
1101
|
-
return {
|
|
1102
|
-
title: input.title ?? `Delivery ${ctx.config.name} \u2014 pe\xE7a online`,
|
|
1103
|
-
description: (input.description ?? (names ? `Pe\xE7a online: ${names} e mais. Card\xE1pio completo com pre\xE7os.` : void 0))?.slice(0, 160),
|
|
1104
|
-
canonical: url,
|
|
1105
|
-
image: input.business?.image,
|
|
1106
|
-
type: "website",
|
|
1107
|
-
jsonLd: [
|
|
1108
|
-
menuJsonLd(input, ctx),
|
|
1109
|
-
...home && url ? [breadcrumbJsonLd([{ name: ctx.config.name, url: home }, { name: "Delivery", url }])] : []
|
|
1110
|
-
]
|
|
1111
|
-
};
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
// src/app/serving.ts
|
|
1115
|
-
function resolveStorefrontRoute(config, rawPath) {
|
|
1116
|
-
const resolved = ensureResolved(config);
|
|
1117
|
-
const path = rawPath.split("?")[0] || "/";
|
|
1118
|
-
for (const route of resolved.routes ?? []) {
|
|
1119
|
-
const params = matchPath(route.path, path);
|
|
1120
|
-
if (params) return { kind: "custom", route, params };
|
|
1121
|
-
}
|
|
1122
|
-
const product = matchPath("/product/:slug", path);
|
|
1123
|
-
if (product?.slug) return { kind: "product", params: product };
|
|
1124
|
-
const order = matchPath("/order/:id", path);
|
|
1125
|
-
if (order?.id) return { kind: "order", params: order };
|
|
1126
|
-
if (matchPath("/checkout", path)) return { kind: "checkout" };
|
|
1127
|
-
if (matchPath("/account", path)) return { kind: "account" };
|
|
1128
|
-
if (matchPath("/catalog", path)) return { kind: "catalog" };
|
|
1129
|
-
if (resolved.delivery && matchPath(resolved.delivery.menuPath, path)) return { kind: "menu" };
|
|
1130
|
-
if (resolved.search.mode === "overlay" && matchPath(resolved.search.resultsPath, path)) {
|
|
1131
|
-
return { kind: "searchResults" };
|
|
1132
|
-
}
|
|
1133
|
-
if (matchPath("/privacy", path)) return { kind: "policy", policy: "privacy" };
|
|
1134
|
-
if (matchPath("/terms", path)) return { kind: "policy", policy: "terms" };
|
|
1135
|
-
if (matchPath("/refunds", path)) return { kind: "policy", policy: "returns" };
|
|
1136
|
-
const content = matchContentPage(resolved.pages, path);
|
|
1137
|
-
if (content) return { kind: "content", slug: content.slug, params: content.params };
|
|
1138
|
-
if (path === "/" || path === "") return { kind: "home" };
|
|
1139
|
-
return { kind: "notFound" };
|
|
1140
|
-
}
|
|
1141
|
-
function isKnownPath(config, path) {
|
|
1142
|
-
return resolveStorefrontRoute(config, path).kind !== "notFound";
|
|
1143
|
-
}
|
|
1144
|
-
var STATIC_PATTERNS = ["/", "/catalog", "/privacy", "/terms", "/refunds"];
|
|
1145
|
-
function ensureResolved(config) {
|
|
1146
|
-
return "features" in config && "pages" in config ? config : resolveConfig(config);
|
|
1147
|
-
}
|
|
1148
|
-
function isPublicPath(config, path) {
|
|
1149
|
-
const match = resolveStorefrontRoute(config, path);
|
|
1150
|
-
switch (match.kind) {
|
|
1151
|
-
case "checkout":
|
|
1152
|
-
case "account":
|
|
1153
|
-
case "order":
|
|
1154
|
-
return false;
|
|
1155
|
-
case "custom":
|
|
1156
|
-
return match.route.kind !== "checkout" && match.route.kind !== "account" && match.route.chrome !== "focused";
|
|
1157
|
-
default:
|
|
1158
|
-
return true;
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
async function storefrontPaths(input) {
|
|
1162
|
-
const resolved = ensureResolved(input.config);
|
|
1163
|
-
const paths = [...STATIC_PATTERNS];
|
|
1164
|
-
if (resolved.delivery) paths.push(resolved.delivery.menuPath);
|
|
1165
|
-
for (const route of resolved.routes ?? []) {
|
|
1166
|
-
if (!route.path.includes(":")) paths.push(route.path);
|
|
1167
|
-
}
|
|
1168
|
-
const products = await input.provider.listProducts({ status: "active" });
|
|
1169
|
-
for (const product of products) paths.push(`/product/${product.slug}`);
|
|
1170
|
-
const unique = Array.from(new Set(paths));
|
|
1171
|
-
return input.includePrivate ? unique : unique.filter((p) => isPublicPath(resolved, p));
|
|
1172
|
-
}
|
|
1173
|
-
var MENU_DATA_NEEDS = {
|
|
1174
|
-
products: { loader: "products.list", params: {} },
|
|
1175
|
-
categories: { loader: "categories.list", params: {} },
|
|
1176
|
-
featured: { loader: "products.featured", params: {} }
|
|
1177
|
-
};
|
|
1178
|
-
function menuDataNeeds() {
|
|
1179
|
-
return Object.values(MENU_DATA_NEEDS).map(({ loader, params }) => ({ key: dataNeedKey(loader, params), loader, params }));
|
|
1180
|
-
}
|
|
1181
634
|
|
|
1182
|
-
export {
|
|
1183
|
-
//# sourceMappingURL=chunk-
|
|
1184
|
-
//# sourceMappingURL=chunk-
|
|
635
|
+
export { Link, MESSAGES, StorefrontConfigProvider, StorefrontRouterProvider, currentStaticRenderPass, getStorefrontComponents, matchPath, navigateTo, normalizeLanguage, resolveConfig, shellRouterAdapter, translate, useHashPath, useNavigate, useRoutePath, useRouterAdapter, useScrollToTopOnNavigate, useStorefrontConfig, useStorefrontConfigOptional, withStaticRenderPass };
|
|
636
|
+
//# sourceMappingURL=chunk-GVZ2SAOI.js.map
|
|
637
|
+
//# sourceMappingURL=chunk-GVZ2SAOI.js.map
|