camox 0.23.0 → 0.24.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/core/createApp.d.ts +8 -0
- package/dist/core/createBlock.d.ts +4 -0
- package/dist/core/createBlock.js +21 -20
- package/dist/core/lib/contentType.d.ts +2 -0
- package/dist/core/lib/imageTransform.js +4 -1
- package/dist/features/content/components/AssetCard.js +123 -81
- package/dist/features/preview/CamoxPreview.d.ts +2 -0
- package/dist/features/preview/components/AssetFieldEditor.js +6 -5
- package/dist/features/preview/components/AssetLightbox.js +11 -9
- package/dist/features/preview/components/EditPageModal.js +244 -74
- package/dist/features/preview/components/MultipleAssetFieldEditor.js +44 -42
- package/dist/features/routes/pageRoute.d.ts +2 -0
- package/dist/features/routes/pageRoute.js +5 -4
- package/dist/lib/normalized-data.js +6 -4
- package/dist/lib/queries.js +33 -2
- package/package.json +4 -4
- package/skills/camox-cli/SKILL.md +23 -0
|
@@ -5,19 +5,20 @@ import { blockQueries, layoutQueries, pageMutations, pageQueries, projectQueries
|
|
|
5
5
|
import { formatPathSegment } from "../../../lib/utils.js";
|
|
6
6
|
import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
|
|
7
7
|
import { PageLocationFieldset } from "./PageLocationFieldset.js";
|
|
8
|
+
import { UploadDropZone } from "../../content/components/UploadDropZone.js";
|
|
8
9
|
import { DebouncedFieldEditor } from "./DebouncedFieldEditor.js";
|
|
9
10
|
import { ShikiMarkdown } from "./ShikiMarkdown.js";
|
|
10
11
|
import { c } from "react/compiler-runtime";
|
|
11
12
|
import { Label } from "@camox/ui/label";
|
|
12
13
|
import { toast } from "@camox/ui/toaster";
|
|
13
|
-
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
14
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
14
15
|
import { useNavigate } from "@tanstack/react-router";
|
|
15
16
|
import { useSelector } from "@xstate/store-react";
|
|
16
17
|
import * as React from "react";
|
|
17
18
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
19
|
import { Button } from "@camox/ui/button";
|
|
19
20
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@camox/ui/tooltip";
|
|
20
|
-
import { Globe, Info } from "lucide-react";
|
|
21
|
+
import { Globe, Info, Trash2, Upload } from "lucide-react";
|
|
21
22
|
import { Spinner } from "@camox/ui/spinner";
|
|
22
23
|
import { Alert, AlertDescription, AlertTitle } from "@camox/ui/alert";
|
|
23
24
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@camox/ui/dialog";
|
|
@@ -28,9 +29,9 @@ import { Switch } from "@camox/ui/switch";
|
|
|
28
29
|
//#region src/features/preview/components/EditPageModal.tsx
|
|
29
30
|
const EditPageModal = () => {
|
|
30
31
|
const $ = c(3);
|
|
31
|
-
if ($[0] !== "
|
|
32
|
+
if ($[0] !== "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c") {
|
|
32
33
|
for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
33
|
-
$[0] = "
|
|
34
|
+
$[0] = "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c";
|
|
34
35
|
}
|
|
35
36
|
const editingPageId = useSelector(previewStore, _temp);
|
|
36
37
|
let t0;
|
|
@@ -302,9 +303,9 @@ function truncateText(text, maxLen) {
|
|
|
302
303
|
}
|
|
303
304
|
const SearchEnginePreview = (t0) => {
|
|
304
305
|
const $ = c(17);
|
|
305
|
-
if ($[0] !== "
|
|
306
|
+
if ($[0] !== "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c") {
|
|
306
307
|
for (let $i = 0; $i < 17; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
307
|
-
$[0] = "
|
|
308
|
+
$[0] = "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c";
|
|
308
309
|
}
|
|
309
310
|
const { page, metaTitle, metaDescription } = t0;
|
|
310
311
|
const url = `${typeof window !== "undefined" ? window.location.origin : ""}${page.fullPath}`;
|
|
@@ -386,10 +387,10 @@ const SearchEnginePreview = (t0) => {
|
|
|
386
387
|
return t10;
|
|
387
388
|
};
|
|
388
389
|
const SocialPreviewSection = (t0) => {
|
|
389
|
-
const $ = c(
|
|
390
|
-
if ($[0] !== "
|
|
391
|
-
for (let $i = 0; $i <
|
|
392
|
-
$[0] = "
|
|
390
|
+
const $ = c(60);
|
|
391
|
+
if ($[0] !== "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c") {
|
|
392
|
+
for (let $i = 0; $i < 60; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
393
|
+
$[0] = "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c";
|
|
393
394
|
}
|
|
394
395
|
const { page, metaTitle, metaDescription, layoutId, projectName } = t0;
|
|
395
396
|
const pageMetaTitle = page.metaTitle ?? page.pathSegment;
|
|
@@ -407,102 +408,265 @@ const SocialPreviewSection = (t0) => {
|
|
|
407
408
|
$[4] = projectName;
|
|
408
409
|
$[5] = t1;
|
|
409
410
|
} else t1 = $[5];
|
|
410
|
-
const
|
|
411
|
+
const generatedOgImage = `/og?${t1}`;
|
|
412
|
+
const ogImage = page.customOgImageUrl ?? generatedOgImage;
|
|
411
413
|
const url = `${typeof window !== "undefined" ? window.location.origin : ""}${page.fullPath}`;
|
|
414
|
+
const fileInputRef = React.useRef(null);
|
|
415
|
+
const queryClient = useQueryClient();
|
|
412
416
|
let t2;
|
|
413
417
|
if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
|
|
414
|
-
t2 =
|
|
418
|
+
t2 = pageMutations.uploadCustomOgImage();
|
|
415
419
|
$[6] = t2;
|
|
416
420
|
} else t2 = $[6];
|
|
417
421
|
let t3;
|
|
418
|
-
if ($[7] !==
|
|
419
|
-
t3 =
|
|
422
|
+
if ($[7] !== page.id || $[8] !== queryClient) {
|
|
423
|
+
t3 = {
|
|
424
|
+
...t2,
|
|
425
|
+
onSuccess: () => {
|
|
426
|
+
queryClient.invalidateQueries({ queryKey: pageQueries.getById(page.id).queryKey });
|
|
427
|
+
trackClientEvent("page_custom_og_image_uploaded", { pageId: page.id });
|
|
428
|
+
},
|
|
429
|
+
onError: _temp5
|
|
430
|
+
};
|
|
431
|
+
$[7] = page.id;
|
|
432
|
+
$[8] = queryClient;
|
|
433
|
+
$[9] = t3;
|
|
434
|
+
} else t3 = $[9];
|
|
435
|
+
const uploadCustomOgImage = useMutation(t3);
|
|
436
|
+
let t4;
|
|
437
|
+
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
|
|
438
|
+
t4 = pageMutations.deleteCustomOgImage();
|
|
439
|
+
$[10] = t4;
|
|
440
|
+
} else t4 = $[10];
|
|
441
|
+
let t5;
|
|
442
|
+
if ($[11] !== page.id || $[12] !== queryClient) {
|
|
443
|
+
t5 = {
|
|
444
|
+
...t4,
|
|
445
|
+
onSuccess: () => {
|
|
446
|
+
queryClient.invalidateQueries({ queryKey: pageQueries.getById(page.id).queryKey });
|
|
447
|
+
trackClientEvent("page_custom_og_image_removed", { pageId: page.id });
|
|
448
|
+
},
|
|
449
|
+
onError: _temp6
|
|
450
|
+
};
|
|
451
|
+
$[11] = page.id;
|
|
452
|
+
$[12] = queryClient;
|
|
453
|
+
$[13] = t5;
|
|
454
|
+
} else t5 = $[13];
|
|
455
|
+
const deleteCustomOgImage = useMutation(t5);
|
|
456
|
+
const hasCustomImage = !!page.customOgImageUrl;
|
|
457
|
+
const isBusy = uploadCustomOgImage.isPending || deleteCustomOgImage.isPending;
|
|
458
|
+
let t6;
|
|
459
|
+
if ($[14] !== page.id || $[15] !== uploadCustomOgImage) {
|
|
460
|
+
t6 = (files) => {
|
|
461
|
+
const file = files[0];
|
|
462
|
+
if (file) uploadCustomOgImage.mutate({
|
|
463
|
+
pageId: page.id,
|
|
464
|
+
file
|
|
465
|
+
});
|
|
466
|
+
};
|
|
467
|
+
$[14] = page.id;
|
|
468
|
+
$[15] = uploadCustomOgImage;
|
|
469
|
+
$[16] = t6;
|
|
470
|
+
} else t6 = $[16];
|
|
471
|
+
const handleFiles = t6;
|
|
472
|
+
let t7;
|
|
473
|
+
if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
|
|
474
|
+
t7 = /* @__PURE__ */ jsx(Label, { children: "Social preview" });
|
|
475
|
+
$[17] = t7;
|
|
476
|
+
} else t7 = $[17];
|
|
477
|
+
let t8;
|
|
478
|
+
if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
|
|
479
|
+
t8 = () => fileInputRef.current?.click();
|
|
480
|
+
$[18] = t8;
|
|
481
|
+
} else t8 = $[18];
|
|
482
|
+
let t9;
|
|
483
|
+
if ($[19] !== uploadCustomOgImage.isPending) {
|
|
484
|
+
t9 = uploadCustomOgImage.isPending ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(Upload, { className: "size-3.5" });
|
|
485
|
+
$[19] = uploadCustomOgImage.isPending;
|
|
486
|
+
$[20] = t9;
|
|
487
|
+
} else t9 = $[20];
|
|
488
|
+
const t10 = hasCustomImage ? "Replace custom image" : "Upload custom image";
|
|
489
|
+
let t11;
|
|
490
|
+
if ($[21] !== isBusy || $[22] !== t10 || $[23] !== t9) {
|
|
491
|
+
t11 = /* @__PURE__ */ jsxs(Button, {
|
|
492
|
+
type: "button",
|
|
493
|
+
variant: "secondary",
|
|
494
|
+
size: "sm",
|
|
495
|
+
disabled: isBusy,
|
|
496
|
+
onClick: t8,
|
|
497
|
+
children: [t9, t10]
|
|
498
|
+
});
|
|
499
|
+
$[21] = isBusy;
|
|
500
|
+
$[22] = t10;
|
|
501
|
+
$[23] = t9;
|
|
502
|
+
$[24] = t11;
|
|
503
|
+
} else t11 = $[24];
|
|
504
|
+
let t12;
|
|
505
|
+
if ($[25] !== deleteCustomOgImage || $[26] !== hasCustomImage || $[27] !== isBusy || $[28] !== page.id) {
|
|
506
|
+
t12 = hasCustomImage && /* @__PURE__ */ jsxs(Button, {
|
|
507
|
+
type: "button",
|
|
508
|
+
variant: "ghost",
|
|
509
|
+
disabled: isBusy,
|
|
510
|
+
onClick: () => deleteCustomOgImage.mutate({ pageId: page.id }),
|
|
511
|
+
"aria-label": "Remove custom image",
|
|
512
|
+
children: [
|
|
513
|
+
deleteCustomOgImage.isPending ? /* @__PURE__ */ jsx(Spinner, { className: "text-muted-foreground" }) : /* @__PURE__ */ jsx(Trash2, { className: "text-muted-foreground" }),
|
|
514
|
+
" ",
|
|
515
|
+
"Clear"
|
|
516
|
+
]
|
|
517
|
+
});
|
|
518
|
+
$[25] = deleteCustomOgImage;
|
|
519
|
+
$[26] = hasCustomImage;
|
|
520
|
+
$[27] = isBusy;
|
|
521
|
+
$[28] = page.id;
|
|
522
|
+
$[29] = t12;
|
|
523
|
+
} else t12 = $[29];
|
|
524
|
+
let t13;
|
|
525
|
+
if ($[30] !== handleFiles) {
|
|
526
|
+
t13 = /* @__PURE__ */ jsx("input", {
|
|
527
|
+
type: "file",
|
|
528
|
+
ref: fileInputRef,
|
|
529
|
+
className: "hidden",
|
|
530
|
+
accept: "image/jpeg,image/png,image/gif,image/webp",
|
|
531
|
+
onChange: (e) => {
|
|
532
|
+
if (e.target.files) handleFiles(e.target.files);
|
|
533
|
+
e.target.value = "";
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
$[30] = handleFiles;
|
|
537
|
+
$[31] = t13;
|
|
538
|
+
} else t13 = $[31];
|
|
539
|
+
let t14;
|
|
540
|
+
if ($[32] !== t11 || $[33] !== t12 || $[34] !== t13) {
|
|
541
|
+
t14 = /* @__PURE__ */ jsxs("div", {
|
|
542
|
+
className: "flex items-center gap-2",
|
|
543
|
+
children: [
|
|
544
|
+
t11,
|
|
545
|
+
t12,
|
|
546
|
+
t13
|
|
547
|
+
]
|
|
548
|
+
});
|
|
549
|
+
$[32] = t11;
|
|
550
|
+
$[33] = t12;
|
|
551
|
+
$[34] = t13;
|
|
552
|
+
$[35] = t14;
|
|
553
|
+
} else t14 = $[35];
|
|
554
|
+
const t15 = hasCustomImage ? "Drop image to replace" : "Drop image to upload";
|
|
555
|
+
let t16;
|
|
556
|
+
if ($[36] === Symbol.for("react.memo_cache_sentinel")) {
|
|
557
|
+
t16 = { aspectRatio: "1200 / 630" };
|
|
558
|
+
$[36] = t16;
|
|
559
|
+
} else t16 = $[36];
|
|
560
|
+
let t17;
|
|
561
|
+
if ($[37] !== ogImage) {
|
|
562
|
+
t17 = /* @__PURE__ */ jsx("img", {
|
|
420
563
|
src: ogImage,
|
|
421
564
|
alt: "",
|
|
422
565
|
className: "w-full object-cover",
|
|
423
|
-
style:
|
|
424
|
-
}) : /* @__PURE__ */ jsx("div", {
|
|
425
|
-
className: "bg-muted w-full",
|
|
426
|
-
style: { aspectRatio: "1200 / 630" }
|
|
566
|
+
style: t16
|
|
427
567
|
});
|
|
428
|
-
$[
|
|
429
|
-
$[
|
|
430
|
-
} else
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
568
|
+
$[37] = ogImage;
|
|
569
|
+
$[38] = t17;
|
|
570
|
+
} else t17 = $[38];
|
|
571
|
+
let t18;
|
|
572
|
+
if ($[39] !== handleFiles || $[40] !== t15 || $[41] !== t17) {
|
|
573
|
+
t18 = /* @__PURE__ */ jsx(UploadDropZone, {
|
|
574
|
+
onDrop: handleFiles,
|
|
575
|
+
label: t15,
|
|
576
|
+
className: "block",
|
|
577
|
+
children: t17
|
|
578
|
+
});
|
|
579
|
+
$[39] = handleFiles;
|
|
580
|
+
$[40] = t15;
|
|
581
|
+
$[41] = t17;
|
|
582
|
+
$[42] = t18;
|
|
583
|
+
} else t18 = $[42];
|
|
584
|
+
const t19 = metaTitle || "Untitled";
|
|
585
|
+
let t20;
|
|
586
|
+
if ($[43] !== t19) {
|
|
587
|
+
t20 = /* @__PURE__ */ jsx("p", {
|
|
435
588
|
className: "text-foreground truncate text-sm font-semibold",
|
|
436
|
-
children:
|
|
589
|
+
children: t19
|
|
437
590
|
});
|
|
438
|
-
$[
|
|
439
|
-
$[
|
|
440
|
-
} else
|
|
441
|
-
const
|
|
442
|
-
let
|
|
443
|
-
if ($[
|
|
444
|
-
|
|
591
|
+
$[43] = t19;
|
|
592
|
+
$[44] = t20;
|
|
593
|
+
} else t20 = $[44];
|
|
594
|
+
const t21 = metaDescription || "No description";
|
|
595
|
+
let t22;
|
|
596
|
+
if ($[45] !== t21) {
|
|
597
|
+
t22 = /* @__PURE__ */ jsx("p", {
|
|
445
598
|
className: "text-muted-foreground line-clamp-2 text-xs",
|
|
446
|
-
children:
|
|
599
|
+
children: t21
|
|
447
600
|
});
|
|
448
|
-
$[
|
|
449
|
-
$[
|
|
450
|
-
} else
|
|
451
|
-
let
|
|
452
|
-
if ($[
|
|
453
|
-
|
|
454
|
-
$[
|
|
455
|
-
} else
|
|
456
|
-
let
|
|
457
|
-
if ($[
|
|
458
|
-
|
|
601
|
+
$[45] = t21;
|
|
602
|
+
$[46] = t22;
|
|
603
|
+
} else t22 = $[46];
|
|
604
|
+
let t23;
|
|
605
|
+
if ($[47] === Symbol.for("react.memo_cache_sentinel")) {
|
|
606
|
+
t23 = /* @__PURE__ */ jsx(Globe, { className: "size-3 shrink-0" });
|
|
607
|
+
$[47] = t23;
|
|
608
|
+
} else t23 = $[47];
|
|
609
|
+
let t24;
|
|
610
|
+
if ($[48] !== url) {
|
|
611
|
+
t24 = /* @__PURE__ */ jsx("div", {
|
|
459
612
|
className: "pt-1.5",
|
|
460
613
|
children: /* @__PURE__ */ jsxs("p", {
|
|
461
614
|
className: "text-muted-foreground flex items-center gap-1 text-xs",
|
|
462
|
-
children: [
|
|
615
|
+
children: [t23, /* @__PURE__ */ jsx("span", {
|
|
463
616
|
className: "truncate",
|
|
464
617
|
children: url
|
|
465
618
|
})]
|
|
466
619
|
})
|
|
467
620
|
});
|
|
468
|
-
$[
|
|
469
|
-
$[
|
|
470
|
-
} else
|
|
471
|
-
let
|
|
472
|
-
if ($[
|
|
473
|
-
|
|
621
|
+
$[48] = url;
|
|
622
|
+
$[49] = t24;
|
|
623
|
+
} else t24 = $[49];
|
|
624
|
+
let t25;
|
|
625
|
+
if ($[50] !== t20 || $[51] !== t22 || $[52] !== t24) {
|
|
626
|
+
t25 = /* @__PURE__ */ jsxs("div", {
|
|
474
627
|
className: "space-y-1.5 border-t px-3 py-2.5",
|
|
475
628
|
children: [
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
629
|
+
t20,
|
|
630
|
+
t22,
|
|
631
|
+
t24
|
|
479
632
|
]
|
|
480
633
|
});
|
|
481
|
-
$[
|
|
482
|
-
$[
|
|
483
|
-
$[
|
|
484
|
-
$[
|
|
485
|
-
} else
|
|
486
|
-
let
|
|
487
|
-
if ($[
|
|
488
|
-
|
|
634
|
+
$[50] = t20;
|
|
635
|
+
$[51] = t22;
|
|
636
|
+
$[52] = t24;
|
|
637
|
+
$[53] = t25;
|
|
638
|
+
} else t25 = $[53];
|
|
639
|
+
let t26;
|
|
640
|
+
if ($[54] !== t18 || $[55] !== t25) {
|
|
641
|
+
t26 = /* @__PURE__ */ jsxs("div", {
|
|
642
|
+
className: "border-border max-w-xl overflow-hidden rounded-lg border",
|
|
643
|
+
children: [t18, t25]
|
|
644
|
+
});
|
|
645
|
+
$[54] = t18;
|
|
646
|
+
$[55] = t25;
|
|
647
|
+
$[56] = t26;
|
|
648
|
+
} else t26 = $[56];
|
|
649
|
+
let t27;
|
|
650
|
+
if ($[57] !== t14 || $[58] !== t26) {
|
|
651
|
+
t27 = /* @__PURE__ */ jsxs("div", {
|
|
489
652
|
className: "space-y-2 pt-2",
|
|
490
|
-
children: [
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
653
|
+
children: [
|
|
654
|
+
t7,
|
|
655
|
+
t14,
|
|
656
|
+
t26
|
|
657
|
+
]
|
|
494
658
|
});
|
|
495
|
-
$[
|
|
496
|
-
$[
|
|
497
|
-
$[
|
|
498
|
-
} else
|
|
499
|
-
return
|
|
659
|
+
$[57] = t14;
|
|
660
|
+
$[58] = t26;
|
|
661
|
+
$[59] = t27;
|
|
662
|
+
} else t27 = $[59];
|
|
663
|
+
return t27;
|
|
500
664
|
};
|
|
501
665
|
const PageMarkdownPreview = (t0) => {
|
|
502
666
|
const $ = c(9);
|
|
503
|
-
if ($[0] !== "
|
|
667
|
+
if ($[0] !== "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c") {
|
|
504
668
|
for (let $i = 0; $i < 9; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
505
|
-
$[0] = "
|
|
669
|
+
$[0] = "4cfb98531a98e3bc48da0686012d88a786d8b22d52089109158bebc149d3d37c";
|
|
506
670
|
}
|
|
507
671
|
const { pageId, metaTitle, metaDescription } = t0;
|
|
508
672
|
let t1;
|
|
@@ -549,6 +713,12 @@ const PageMarkdownPreview = (t0) => {
|
|
|
549
713
|
function _temp(state) {
|
|
550
714
|
return state.context.editingPageId;
|
|
551
715
|
}
|
|
716
|
+
function _temp5(error) {
|
|
717
|
+
toast.error(error.message || "Could not upload image");
|
|
718
|
+
}
|
|
719
|
+
function _temp6() {
|
|
720
|
+
toast.error("Could not remove image");
|
|
721
|
+
}
|
|
552
722
|
|
|
553
723
|
//#endregion
|
|
554
724
|
export { EditPageModal };
|
|
@@ -21,10 +21,10 @@ import { CSS } from "@dnd-kit/utilities";
|
|
|
21
21
|
|
|
22
22
|
//#region src/features/preview/components/MultipleAssetFieldEditor.tsx
|
|
23
23
|
const SortableAssetItem = (t0) => {
|
|
24
|
-
const $ = c(
|
|
25
|
-
if ($[0] !== "
|
|
26
|
-
for (let $i = 0; $i <
|
|
27
|
-
$[0] = "
|
|
24
|
+
const $ = c(45);
|
|
25
|
+
if ($[0] !== "3cf038d410d44a905bb67a7755e19d8146b75274d1d91e2ad5f7a0d2580bec80") {
|
|
26
|
+
for (let $i = 0; $i < 45; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
27
|
+
$[0] = "3cf038d410d44a905bb67a7755e19d8146b75274d1d91e2ad5f7a0d2580bec80";
|
|
28
28
|
}
|
|
29
29
|
const { asset, assetType, onRemove, onAssetOpen } = t0;
|
|
30
30
|
const t1 = String(asset._fileId);
|
|
@@ -90,13 +90,14 @@ const SortableAssetItem = (t0) => {
|
|
|
90
90
|
$[17] = t10;
|
|
91
91
|
} else t10 = $[17];
|
|
92
92
|
let t11;
|
|
93
|
-
if ($[18] !== asset.alt || $[19] !== asset.filename || $[20] !== asset.mimeType || $[21] !== asset.
|
|
93
|
+
if ($[18] !== asset.alt || $[19] !== asset.filename || $[20] !== asset.mimeType || $[21] !== asset.size || $[22] !== asset.url || $[23] !== assetType) {
|
|
94
94
|
t11 = assetType === "Image" ? /* @__PURE__ */ jsx("div", {
|
|
95
95
|
className: "border-border h-12 w-12 shrink-0 overflow-hidden rounded border",
|
|
96
96
|
children: /* @__PURE__ */ jsx("img", {
|
|
97
97
|
src: transformImageUrl(asset.url, {
|
|
98
98
|
width: 128,
|
|
99
|
-
mimeType: asset.mimeType
|
|
99
|
+
mimeType: asset.mimeType,
|
|
100
|
+
size: asset.size
|
|
100
101
|
}),
|
|
101
102
|
alt: asset.alt || asset.filename,
|
|
102
103
|
className: "h-full w-full object-cover"
|
|
@@ -108,55 +109,56 @@ const SortableAssetItem = (t0) => {
|
|
|
108
109
|
$[18] = asset.alt;
|
|
109
110
|
$[19] = asset.filename;
|
|
110
111
|
$[20] = asset.mimeType;
|
|
111
|
-
$[21] = asset.
|
|
112
|
-
$[22] =
|
|
113
|
-
$[23] =
|
|
114
|
-
|
|
112
|
+
$[21] = asset.size;
|
|
113
|
+
$[22] = asset.url;
|
|
114
|
+
$[23] = assetType;
|
|
115
|
+
$[24] = t11;
|
|
116
|
+
} else t11 = $[24];
|
|
115
117
|
const t12 = asset.filename || "Untitled";
|
|
116
118
|
let t13;
|
|
117
|
-
if ($[
|
|
119
|
+
if ($[25] !== asset.filename || $[26] !== t12) {
|
|
118
120
|
t13 = /* @__PURE__ */ jsx("p", {
|
|
119
121
|
className: "flex-1 truncate text-left text-sm",
|
|
120
122
|
title: asset.filename,
|
|
121
123
|
children: t12
|
|
122
124
|
});
|
|
123
|
-
$[
|
|
124
|
-
$[
|
|
125
|
-
$[
|
|
126
|
-
} else t13 = $[
|
|
125
|
+
$[25] = asset.filename;
|
|
126
|
+
$[26] = t12;
|
|
127
|
+
$[27] = t13;
|
|
128
|
+
} else t13 = $[27];
|
|
127
129
|
let t14;
|
|
128
|
-
if ($[
|
|
130
|
+
if ($[28] !== t10 || $[29] !== t11 || $[30] !== t13) {
|
|
129
131
|
t14 = /* @__PURE__ */ jsxs("button", {
|
|
130
132
|
type: "button",
|
|
131
133
|
className: "flex min-w-0 flex-1 cursor-zoom-in items-center gap-2",
|
|
132
134
|
onClick: t10,
|
|
133
135
|
children: [t11, t13]
|
|
134
136
|
});
|
|
135
|
-
$[
|
|
136
|
-
$[
|
|
137
|
-
$[
|
|
138
|
-
$[
|
|
139
|
-
} else t14 = $[
|
|
137
|
+
$[28] = t10;
|
|
138
|
+
$[29] = t11;
|
|
139
|
+
$[30] = t13;
|
|
140
|
+
$[31] = t14;
|
|
141
|
+
} else t14 = $[31];
|
|
140
142
|
let t15;
|
|
141
|
-
if ($[
|
|
143
|
+
if ($[32] !== asset._fileId || $[33] !== onRemove) {
|
|
142
144
|
t15 = () => onRemove(asset._fileId);
|
|
143
|
-
$[
|
|
144
|
-
$[
|
|
145
|
-
$[
|
|
146
|
-
} else t15 = $[
|
|
145
|
+
$[32] = asset._fileId;
|
|
146
|
+
$[33] = onRemove;
|
|
147
|
+
$[34] = t15;
|
|
148
|
+
} else t15 = $[34];
|
|
147
149
|
let t16;
|
|
148
|
-
if ($[
|
|
150
|
+
if ($[35] !== asset._fileId || $[36] !== t15) {
|
|
149
151
|
t16 = /* @__PURE__ */ jsx(UnlinkAssetButton, {
|
|
150
152
|
fileId: asset._fileId,
|
|
151
153
|
onUnlink: t15,
|
|
152
154
|
className: "hidden group-focus-within:flex group-hover:flex"
|
|
153
155
|
});
|
|
154
|
-
$[
|
|
155
|
-
$[
|
|
156
|
-
$[
|
|
157
|
-
} else t16 = $[
|
|
156
|
+
$[35] = asset._fileId;
|
|
157
|
+
$[36] = t15;
|
|
158
|
+
$[37] = t16;
|
|
159
|
+
} else t16 = $[37];
|
|
158
160
|
let t17;
|
|
159
|
-
if ($[
|
|
161
|
+
if ($[38] !== setNodeRef || $[39] !== style || $[40] !== t14 || $[41] !== t16 || $[42] !== t7 || $[43] !== t9) {
|
|
160
162
|
t17 = /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("div", {
|
|
161
163
|
ref: setNodeRef,
|
|
162
164
|
style,
|
|
@@ -167,21 +169,21 @@ const SortableAssetItem = (t0) => {
|
|
|
167
169
|
t16
|
|
168
170
|
]
|
|
169
171
|
}) });
|
|
170
|
-
$[
|
|
171
|
-
$[
|
|
172
|
-
$[
|
|
173
|
-
$[
|
|
174
|
-
$[
|
|
175
|
-
$[
|
|
176
|
-
$[
|
|
177
|
-
} else t17 = $[
|
|
172
|
+
$[38] = setNodeRef;
|
|
173
|
+
$[39] = style;
|
|
174
|
+
$[40] = t14;
|
|
175
|
+
$[41] = t16;
|
|
176
|
+
$[42] = t7;
|
|
177
|
+
$[43] = t9;
|
|
178
|
+
$[44] = t17;
|
|
179
|
+
} else t17 = $[44];
|
|
178
180
|
return t17;
|
|
179
181
|
};
|
|
180
182
|
const MultipleAssetFieldEditor = (t0) => {
|
|
181
183
|
const $ = c(12);
|
|
182
|
-
if ($[0] !== "
|
|
184
|
+
if ($[0] !== "3cf038d410d44a905bb67a7755e19d8146b75274d1d91e2ad5f7a0d2580bec80") {
|
|
183
185
|
for (let $i = 0; $i < 12; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
184
|
-
$[0] = "
|
|
186
|
+
$[0] = "3cf038d410d44a905bb67a7755e19d8146b75274d1d91e2ad5f7a0d2580bec80";
|
|
185
187
|
}
|
|
186
188
|
const { fieldName, assetType, currentData, onFieldChange } = t0;
|
|
187
189
|
const isImage = assetType === "Image";
|
|
@@ -33,6 +33,8 @@ declare function createPageLoader(apiUrl: string, projectSlug: string, environme
|
|
|
33
33
|
metaTitle: string | null;
|
|
34
34
|
metaDescription: string | null;
|
|
35
35
|
aiSeoEnabled: boolean | null;
|
|
36
|
+
customOgImageBlobId: string | null;
|
|
37
|
+
customOgImageUrl: string | null;
|
|
36
38
|
createdAt: number;
|
|
37
39
|
updatedAt: number;
|
|
38
40
|
};
|
|
@@ -117,12 +117,13 @@ function createPageHead(camoxApp) {
|
|
|
117
117
|
name: "description",
|
|
118
118
|
content: page.page.metaDescription
|
|
119
119
|
});
|
|
120
|
-
const
|
|
120
|
+
const ogImageParams = new URLSearchParams({
|
|
121
121
|
...page.layout && { layoutId: page.layout.layoutId },
|
|
122
122
|
title: pageMetaTitle,
|
|
123
123
|
...page.page.metaDescription && { description: page.page.metaDescription },
|
|
124
124
|
...page.projectName && { projectName: page.projectName }
|
|
125
|
-
})
|
|
125
|
+
});
|
|
126
|
+
const ogImageUrl = page.page.customOgImageUrl ?? `${origin}/og?${ogImageParams.toString()}`;
|
|
126
127
|
meta.push({
|
|
127
128
|
property: "og:title",
|
|
128
129
|
content: title
|
|
@@ -151,9 +152,9 @@ function createPageHead(camoxApp) {
|
|
|
151
152
|
}
|
|
152
153
|
const PageRouteComponent = () => {
|
|
153
154
|
const $ = c(2);
|
|
154
|
-
if ($[0] !== "
|
|
155
|
+
if ($[0] !== "858ec55c5e5a82d2aa9c37c6b5b7f1c0a2d1cff69ec415b2b53199f5bf1faa69") {
|
|
155
156
|
for (let $i = 0; $i < 2; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
156
|
-
$[0] = "
|
|
157
|
+
$[0] = "858ec55c5e5a82d2aa9c37c6b5b7f1c0a2d1cff69ec415b2b53199f5bf1faa69";
|
|
157
158
|
}
|
|
158
159
|
let t0;
|
|
159
160
|
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
|
@@ -11,9 +11,9 @@ const NormalizedDataContext = React.createContext({
|
|
|
11
11
|
});
|
|
12
12
|
const NormalizedDataProvider = (t0) => {
|
|
13
13
|
const $ = c(13);
|
|
14
|
-
if ($[0] !== "
|
|
14
|
+
if ($[0] !== "c508cbfbcda1ea1312463b6cbebcd66332f3346f51c02c09c35687c430a19469") {
|
|
15
15
|
for (let $i = 0; $i < 13; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
16
|
-
$[0] = "
|
|
16
|
+
$[0] = "c508cbfbcda1ea1312463b6cbebcd66332f3346f51c02c09c35687c430a19469";
|
|
17
17
|
}
|
|
18
18
|
const { files, repeatableItems, children } = t0;
|
|
19
19
|
let t1;
|
|
@@ -74,9 +74,9 @@ function useStableArray(next) {
|
|
|
74
74
|
}
|
|
75
75
|
function usePageBlocks(pageStructure) {
|
|
76
76
|
const $ = c(36);
|
|
77
|
-
if ($[0] !== "
|
|
77
|
+
if ($[0] !== "c508cbfbcda1ea1312463b6cbebcd66332f3346f51c02c09c35687c430a19469") {
|
|
78
78
|
for (let $i = 0; $i < 36; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
79
|
-
$[0] = "
|
|
79
|
+
$[0] = "c508cbfbcda1ea1312463b6cbebcd66332f3346f51c02c09c35687c430a19469";
|
|
80
80
|
}
|
|
81
81
|
const blockIds = pageStructure.page.blockIds;
|
|
82
82
|
const beforeIds = pageStructure.layout?.beforeBlockIds ?? EMPTY_IDS;
|
|
@@ -239,6 +239,7 @@ function resolveFileMarker(marker, filesMap) {
|
|
|
239
239
|
alt: file.alt,
|
|
240
240
|
filename: file.filename,
|
|
241
241
|
mimeType: file.mimeType,
|
|
242
|
+
size: file.size,
|
|
242
243
|
_fileId: marker._fileId
|
|
243
244
|
};
|
|
244
245
|
return {
|
|
@@ -246,6 +247,7 @@ function resolveFileMarker(marker, filesMap) {
|
|
|
246
247
|
alt: "",
|
|
247
248
|
filename: "",
|
|
248
249
|
mimeType: "",
|
|
250
|
+
size: 0,
|
|
249
251
|
_fileId: marker._fileId
|
|
250
252
|
};
|
|
251
253
|
}
|
package/dist/lib/queries.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getAuthCookieHeader } from "./auth.js";
|
|
2
|
+
import { getApiUrl, getEnvironmentName, getOrpc } from "./api-client.js";
|
|
2
3
|
import { queryKeys } from "@camox/api-contract/query-keys";
|
|
3
4
|
|
|
4
5
|
//#region src/lib/queries.ts
|
|
@@ -124,6 +125,12 @@ const repeatableItemMutations = {
|
|
|
124
125
|
updateSettings: () => getOrpc().repeatableItems.updateSettings.mutationOptions(),
|
|
125
126
|
updatePosition: () => getOrpc().repeatableItems.updatePosition.mutationOptions()
|
|
126
127
|
};
|
|
128
|
+
function ogImageHeaders() {
|
|
129
|
+
const headers = { "Better-Auth-Cookie": getAuthCookieHeader() };
|
|
130
|
+
const envName = getEnvironmentName();
|
|
131
|
+
if (envName) headers["x-environment-name"] = envName;
|
|
132
|
+
return headers;
|
|
133
|
+
}
|
|
127
134
|
const pageMutations = {
|
|
128
135
|
create: () => getOrpc().pages.create.mutationOptions(),
|
|
129
136
|
delete: () => getOrpc().pages.delete.mutationOptions(),
|
|
@@ -131,7 +138,31 @@ const pageMutations = {
|
|
|
131
138
|
setLayout: () => getOrpc().pages.setLayout.mutationOptions(),
|
|
132
139
|
setAiSeo: () => getOrpc().pages.setAiSeo.mutationOptions(),
|
|
133
140
|
setMetaTitle: () => getOrpc().pages.setMetaTitle.mutationOptions(),
|
|
134
|
-
setMetaDescription: () => getOrpc().pages.setMetaDescription.mutationOptions()
|
|
141
|
+
setMetaDescription: () => getOrpc().pages.setMetaDescription.mutationOptions(),
|
|
142
|
+
uploadCustomOgImage: () => ({ mutationFn: async ({ pageId, file }) => {
|
|
143
|
+
const formData = new FormData();
|
|
144
|
+
formData.append("file", file);
|
|
145
|
+
const res = await fetch(`${getApiUrl()}/pages/${pageId}/og-image`, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
body: formData,
|
|
148
|
+
headers: ogImageHeaders(),
|
|
149
|
+
credentials: "omit"
|
|
150
|
+
});
|
|
151
|
+
if (!res.ok) {
|
|
152
|
+
const body = await res.json().catch(() => null);
|
|
153
|
+
throw new Error(body?.error ?? `Upload failed: ${res.status}`);
|
|
154
|
+
}
|
|
155
|
+
return res.json();
|
|
156
|
+
} }),
|
|
157
|
+
deleteCustomOgImage: () => ({ mutationFn: async ({ pageId }) => {
|
|
158
|
+
const res = await fetch(`${getApiUrl()}/pages/${pageId}/og-image`, {
|
|
159
|
+
method: "DELETE",
|
|
160
|
+
headers: ogImageHeaders(),
|
|
161
|
+
credentials: "omit"
|
|
162
|
+
});
|
|
163
|
+
if (!res.ok) throw new Error(`Delete failed: ${res.status}`);
|
|
164
|
+
return res.json();
|
|
165
|
+
} })
|
|
135
166
|
};
|
|
136
167
|
const fileMutations = {
|
|
137
168
|
delete: () => getOrpc().files.delete.mutationOptions(),
|