@djangocfg/nextjs 2.1.225 → 2.1.226

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -14,7 +14,7 @@ var require_package = __commonJS({
14
14
  "package.json"(exports, module) {
15
15
  module.exports = {
16
16
  name: "@djangocfg/nextjs",
17
- version: "2.1.225",
17
+ version: "2.1.226",
18
18
  description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
19
19
  keywords: [
20
20
  "nextjs",
@@ -58,21 +58,6 @@ var require_package = __commonJS({
58
58
  import: "./dist/health/index.mjs",
59
59
  default: "./dist/health/index.mjs"
60
60
  },
61
- "./og-image": {
62
- types: "./dist/og-image/index.d.mts",
63
- import: "./dist/og-image/index.mjs",
64
- default: "./dist/og-image/index.mjs"
65
- },
66
- "./og-image/utils": {
67
- types: "./dist/og-image/utils/index.d.mts",
68
- import: "./dist/og-image/utils/index.mjs",
69
- default: "./dist/og-image/utils/index.mjs"
70
- },
71
- "./og-image/components": {
72
- types: "./dist/og-image/components/index.d.mts",
73
- import: "./dist/og-image/components/index.mjs",
74
- default: "./dist/og-image/components/index.mjs"
75
- },
76
61
  "./navigation": {
77
62
  types: "./dist/navigation/index.d.mts",
78
63
  import: "./dist/navigation/index.mjs",
@@ -103,6 +88,11 @@ var require_package = __commonJS({
103
88
  import: "./dist/pwa/worker/index.mjs",
104
89
  default: "./dist/pwa/worker/index.mjs"
105
90
  },
91
+ "./og-image": {
92
+ types: "./dist/og-image/index.d.mts",
93
+ import: "./dist/og-image/index.mjs",
94
+ default: "./dist/og-image/index.mjs"
95
+ },
106
96
  "./monitor": {
107
97
  types: "./dist/monitor/index.d.mts",
108
98
  import: "./dist/monitor/index.mjs",
@@ -201,7 +191,6 @@ var require_package = __commonJS({
201
191
  "@types/react-dom": "^19.1.0",
202
192
  "@types/semver": "^7.7.1",
203
193
  "@types/webpack": "^5.28.5",
204
- "@vercel/og": "^0.8.5",
205
194
  eslint: "^9.37.0",
206
195
  "lucide-react": "^0.545.0",
207
196
  tsup: "^8.0.1",
@@ -397,835 +386,6 @@ function createHealthHandler(config = {}) {
397
386
  };
398
387
  }
399
388
 
400
- // src/og-image/route.tsx
401
- import { ImageResponse } from "next/og";
402
- import { NextRequest } from "next/server";
403
-
404
- // src/og-image/components/DefaultTemplate.tsx
405
- import { jsx, jsxs } from "react/jsx-runtime";
406
- function DefaultTemplate({
407
- title,
408
- description,
409
- siteName,
410
- logo,
411
- // Visibility flags
412
- showLogo = true,
413
- showSiteName = true,
414
- // Background customization
415
- backgroundType = "gradient",
416
- gradientStart = "#667eea",
417
- gradientEnd = "#764ba2",
418
- backgroundColor = "#ffffff",
419
- // Typography - Title
420
- titleSize,
421
- titleWeight = 800,
422
- titleColor = "white",
423
- // Typography - Description
424
- descriptionSize = 32,
425
- descriptionColor = "rgba(255, 255, 255, 0.85)",
426
- // Typography - Site Name
427
- siteNameSize = 28,
428
- siteNameColor = "rgba(255, 255, 255, 0.95)",
429
- // Layout
430
- padding = 80,
431
- logoSize = 48,
432
- // Dev mode
433
- devMode = false
434
- }) {
435
- const calculatedTitleSize = titleSize || (title.length > 60 ? 56 : 72);
436
- const backgroundStyle = backgroundType === "gradient" ? `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)` : backgroundColor;
437
- const gridOverlay = devMode ? /* @__PURE__ */ jsx(
438
- "div",
439
- {
440
- style: {
441
- position: "absolute",
442
- top: 0,
443
- left: 0,
444
- right: 0,
445
- bottom: 0,
446
- backgroundImage: `
447
- linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
448
- linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px)
449
- `,
450
- backgroundSize: "20px 20px",
451
- pointerEvents: "none",
452
- zIndex: 10
453
- }
454
- }
455
- ) : null;
456
- return /* @__PURE__ */ jsxs(
457
- "div",
458
- {
459
- style: {
460
- height: "100%",
461
- width: "100%",
462
- display: "flex",
463
- flexDirection: "column",
464
- alignItems: "flex-start",
465
- justifyContent: "space-between",
466
- background: backgroundStyle,
467
- padding: `${padding}px`,
468
- fontFamily: "system-ui, -apple-system, sans-serif",
469
- position: "relative"
470
- },
471
- children: [
472
- gridOverlay,
473
- (showLogo && logo || showSiteName && siteName) && /* @__PURE__ */ jsxs(
474
- "div",
475
- {
476
- style: {
477
- display: "flex",
478
- alignItems: "center",
479
- gap: "16px"
480
- },
481
- children: [
482
- showLogo && logo && // eslint-disable-next-line @next/next/no-img-element
483
- /* @__PURE__ */ jsx(
484
- "img",
485
- {
486
- src: logo,
487
- alt: "Logo",
488
- width: logoSize,
489
- height: logoSize,
490
- style: {
491
- borderRadius: "8px"
492
- }
493
- }
494
- ),
495
- showSiteName && siteName && /* @__PURE__ */ jsx(
496
- "div",
497
- {
498
- style: {
499
- fontSize: siteNameSize,
500
- fontWeight: 600,
501
- color: siteNameColor,
502
- letterSpacing: "-0.02em"
503
- },
504
- children: siteName
505
- }
506
- )
507
- ]
508
- }
509
- ),
510
- /* @__PURE__ */ jsxs(
511
- "div",
512
- {
513
- style: {
514
- display: "flex",
515
- flexDirection: "column",
516
- gap: "24px",
517
- flex: 1,
518
- justifyContent: "center"
519
- },
520
- children: [
521
- /* @__PURE__ */ jsx(
522
- "div",
523
- {
524
- style: {
525
- fontSize: calculatedTitleSize,
526
- fontWeight: titleWeight,
527
- color: titleColor,
528
- lineHeight: 1.1,
529
- letterSpacing: "-0.03em",
530
- textShadow: backgroundType === "gradient" ? "0 2px 20px rgba(0, 0, 0, 0.2)" : "none",
531
- maxWidth: "100%",
532
- wordWrap: "break-word"
533
- },
534
- children: title
535
- }
536
- ),
537
- description && /* @__PURE__ */ jsx(
538
- "div",
539
- {
540
- style: {
541
- fontSize: descriptionSize,
542
- fontWeight: 400,
543
- color: descriptionColor,
544
- lineHeight: 1.5,
545
- letterSpacing: "-0.01em",
546
- maxWidth: "90%",
547
- display: "-webkit-box",
548
- WebkitLineClamp: 2,
549
- WebkitBoxOrient: "vertical",
550
- overflow: "hidden"
551
- },
552
- children: description
553
- }
554
- )
555
- ]
556
- }
557
- ),
558
- /* @__PURE__ */ jsx(
559
- "div",
560
- {
561
- style: {
562
- display: "flex",
563
- width: "100%",
564
- height: "4px",
565
- background: backgroundType === "gradient" ? `linear-gradient(90deg, ${gradientStart} 0%, ${gradientEnd} 100%)` : gradientStart,
566
- borderRadius: "2px"
567
- }
568
- }
569
- )
570
- ]
571
- }
572
- );
573
- }
574
- function LightTemplate({
575
- title,
576
- description,
577
- siteName,
578
- logo,
579
- // Visibility flags
580
- showLogo = true,
581
- showSiteName = true,
582
- // Background customization (defaults to light theme)
583
- backgroundType = "solid",
584
- gradientStart = "#667eea",
585
- gradientEnd = "#764ba2",
586
- backgroundColor = "#ffffff",
587
- // Typography - Title
588
- titleSize,
589
- titleWeight = 800,
590
- titleColor = "#111",
591
- // Typography - Description
592
- descriptionSize = 32,
593
- descriptionColor = "#666",
594
- // Typography - Site Name
595
- siteNameSize = 28,
596
- siteNameColor = "#111",
597
- // Layout
598
- padding = 80,
599
- logoSize = 48,
600
- // Dev mode
601
- devMode = false
602
- }) {
603
- const calculatedTitleSize = titleSize || (title.length > 60 ? 56 : 72);
604
- const backgroundStyle = backgroundType === "gradient" ? `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)` : backgroundColor;
605
- const gridOverlay = devMode ? /* @__PURE__ */ jsx(
606
- "div",
607
- {
608
- style: {
609
- position: "absolute",
610
- top: 0,
611
- left: 0,
612
- right: 0,
613
- bottom: 0,
614
- backgroundImage: `
615
- linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
616
- linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px)
617
- `,
618
- backgroundSize: "20px 20px",
619
- pointerEvents: "none",
620
- zIndex: 10
621
- }
622
- }
623
- ) : null;
624
- return /* @__PURE__ */ jsxs(
625
- "div",
626
- {
627
- style: {
628
- height: "100%",
629
- width: "100%",
630
- display: "flex",
631
- flexDirection: "column",
632
- alignItems: "flex-start",
633
- justifyContent: "space-between",
634
- background: backgroundStyle,
635
- padding: `${padding}px`,
636
- fontFamily: "system-ui, -apple-system, sans-serif",
637
- position: "relative"
638
- },
639
- children: [
640
- gridOverlay,
641
- (showLogo && logo || showSiteName && siteName) && /* @__PURE__ */ jsxs(
642
- "div",
643
- {
644
- style: {
645
- display: "flex",
646
- alignItems: "center",
647
- gap: "16px"
648
- },
649
- children: [
650
- showLogo && logo && // eslint-disable-next-line @next/next/no-img-element
651
- /* @__PURE__ */ jsx(
652
- "img",
653
- {
654
- src: logo,
655
- alt: "Logo",
656
- width: logoSize,
657
- height: logoSize,
658
- style: {
659
- borderRadius: "8px"
660
- }
661
- }
662
- ),
663
- showSiteName && siteName && /* @__PURE__ */ jsx(
664
- "div",
665
- {
666
- style: {
667
- fontSize: siteNameSize,
668
- fontWeight: 600,
669
- color: siteNameColor,
670
- letterSpacing: "-0.02em"
671
- },
672
- children: siteName
673
- }
674
- )
675
- ]
676
- }
677
- ),
678
- /* @__PURE__ */ jsxs(
679
- "div",
680
- {
681
- style: {
682
- display: "flex",
683
- flexDirection: "column",
684
- gap: "24px",
685
- flex: 1,
686
- justifyContent: "center"
687
- },
688
- children: [
689
- /* @__PURE__ */ jsx(
690
- "div",
691
- {
692
- style: {
693
- fontSize: calculatedTitleSize,
694
- fontWeight: titleWeight,
695
- color: titleColor,
696
- lineHeight: 1.1,
697
- letterSpacing: "-0.03em",
698
- maxWidth: "100%",
699
- wordWrap: "break-word"
700
- },
701
- children: title
702
- }
703
- ),
704
- description && /* @__PURE__ */ jsx(
705
- "div",
706
- {
707
- style: {
708
- fontSize: descriptionSize,
709
- fontWeight: 400,
710
- color: descriptionColor,
711
- lineHeight: 1.5,
712
- letterSpacing: "-0.01em",
713
- maxWidth: "90%"
714
- },
715
- children: description
716
- }
717
- )
718
- ]
719
- }
720
- ),
721
- /* @__PURE__ */ jsx(
722
- "div",
723
- {
724
- style: {
725
- display: "flex",
726
- width: "100%",
727
- height: "4px",
728
- background: backgroundType === "gradient" ? `linear-gradient(90deg, ${gradientStart} 0%, ${gradientEnd} 100%)` : gradientStart,
729
- borderRadius: "2px"
730
- }
731
- }
732
- )
733
- ]
734
- }
735
- );
736
- }
737
-
738
- // src/og-image/utils/fonts.ts
739
- async function loadGoogleFont(font, text, weight = 700) {
740
- let url = `https://fonts.googleapis.com/css2?family=${font}:wght@${weight}`;
741
- if (text) {
742
- url += `&text=${encodeURIComponent(text)}`;
743
- }
744
- try {
745
- const css = await fetch(url, {
746
- headers: {
747
- // Required to get TTF format instead of WOFF2
748
- "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
749
- }
750
- }).then((res) => res.text());
751
- const resource = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/);
752
- if (!resource || !resource[1]) {
753
- throw new Error(`Failed to parse font URL from CSS for font: ${font}`);
754
- }
755
- const response = await fetch(resource[1]);
756
- if (response.status !== 200) {
757
- throw new Error(`Failed to fetch font data: HTTP ${response.status}`);
758
- }
759
- return await response.arrayBuffer();
760
- } catch (error) {
761
- console.error(`Error loading Google Font "${font}":`, error);
762
- throw new Error(`Failed to load font "${font}": ${error instanceof Error ? error.message : "Unknown error"}`);
763
- }
764
- }
765
- async function loadGoogleFonts(fonts) {
766
- const fontConfigs = await Promise.all(
767
- fonts.map(async ({ family, weight = 700, style = "normal", text }) => {
768
- const data = await loadGoogleFont(family, text, weight);
769
- return {
770
- name: family,
771
- weight,
772
- style,
773
- data
774
- };
775
- })
776
- );
777
- return fontConfigs;
778
- }
779
- function createFontLoader() {
780
- const cache = /* @__PURE__ */ new Map();
781
- return {
782
- /**
783
- * Load a font with caching
784
- */
785
- async load(family, weight = 700, text) {
786
- const cacheKey = `${family}-${weight}-${text || "all"}`;
787
- if (!cache.has(cacheKey)) {
788
- cache.set(cacheKey, loadGoogleFont(family, text, weight));
789
- }
790
- return cache.get(cacheKey);
791
- },
792
- /**
793
- * Clear the cache
794
- */
795
- clear() {
796
- cache.clear();
797
- },
798
- /**
799
- * Get cache size
800
- */
801
- size() {
802
- return cache.size;
803
- }
804
- };
805
- }
806
-
807
- // src/og-image/utils/url.ts
808
- var DEFAULT_OG_IMAGE_BASE_URL = "https://djangocfg.com/api/og";
809
- function encodeBase64(str) {
810
- if (typeof Buffer !== "undefined") {
811
- return Buffer.from(str, "utf-8").toString("base64");
812
- }
813
- return btoa(unescape(encodeURIComponent(str)));
814
- }
815
- function decodeBase64(str) {
816
- if (typeof Buffer !== "undefined") {
817
- return Buffer.from(str, "base64").toString("utf-8");
818
- }
819
- try {
820
- const binaryString = atob(str);
821
- return decodeURIComponent(
822
- binaryString.split("").map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)).join("")
823
- );
824
- } catch (error) {
825
- return decodeURIComponent(escape(atob(str)));
826
- }
827
- }
828
- function generateOgImageUrl(params, options = {}) {
829
- const {
830
- baseUrl = DEFAULT_OG_IMAGE_BASE_URL,
831
- useBase64 = true
832
- } = options;
833
- if (useBase64) {
834
- const cleanParams = {};
835
- Object.entries(params).forEach(([key, value]) => {
836
- if (value !== void 0 && value !== null && value !== "") {
837
- cleanParams[key] = value;
838
- }
839
- });
840
- const jsonString = JSON.stringify(cleanParams);
841
- const base64Data = encodeBase64(jsonString);
842
- return `${baseUrl}/${base64Data}/`;
843
- } else {
844
- const searchParams = new URLSearchParams();
845
- Object.entries(params).forEach(([key, value]) => {
846
- if (value !== void 0 && value !== null && value !== "") {
847
- searchParams.append(key, String(value));
848
- }
849
- });
850
- const query = searchParams.toString();
851
- return query ? `${baseUrl}?${query}` : baseUrl;
852
- }
853
- }
854
- function getAbsoluteOgImageUrl(relativePath, siteUrl) {
855
- if (relativePath.startsWith("http://") || relativePath.startsWith("https://")) {
856
- return relativePath;
857
- }
858
- const cleanSiteUrl = siteUrl.replace(/\/$/, "");
859
- const cleanPath = relativePath.startsWith("/") ? relativePath : `/${relativePath}`;
860
- return `${cleanSiteUrl}${cleanPath}`;
861
- }
862
- function createOgImageUrlBuilder(defaults = {}, options = {}) {
863
- return (params) => {
864
- return generateOgImageUrl(
865
- { ...defaults, ...params },
866
- options
867
- );
868
- };
869
- }
870
- function parseOgImageUrl(url) {
871
- try {
872
- const urlObj = new URL(url, "http://dummy.com");
873
- const params = {};
874
- urlObj.searchParams.forEach((value, key) => {
875
- params[key] = value;
876
- });
877
- return params;
878
- } catch {
879
- return {};
880
- }
881
- }
882
- function parseOgImageData(searchParams) {
883
- try {
884
- let params;
885
- if (searchParams instanceof URLSearchParams) {
886
- params = {};
887
- for (const [key, value] of searchParams.entries()) {
888
- params[key] = value;
889
- }
890
- } else {
891
- params = searchParams;
892
- }
893
- if (process.env.NODE_ENV === "development") {
894
- console.log("[parseOgImageData] Input params keys:", Object.keys(params));
895
- console.log("[parseOgImageData] Input params:", params);
896
- }
897
- const dataParam = params.data;
898
- if (dataParam && typeof dataParam === "string" && dataParam.trim() !== "") {
899
- if (process.env.NODE_ENV === "development") {
900
- console.log("[parseOgImageData] Found data param, length:", dataParam.length);
901
- }
902
- try {
903
- const decoded = decodeBase64(dataParam);
904
- if (process.env.NODE_ENV === "development") {
905
- console.log("[parseOgImageData] Decoded string:", decoded.substring(0, 100));
906
- }
907
- const parsed = JSON.parse(decoded);
908
- if (process.env.NODE_ENV === "development") {
909
- console.log("[parseOgImageData] Parsed JSON:", parsed);
910
- }
911
- const result2 = {};
912
- for (const [key, value] of Object.entries(parsed)) {
913
- if (value !== void 0 && value !== null) {
914
- result2[key] = String(value);
915
- }
916
- }
917
- if (process.env.NODE_ENV === "development") {
918
- console.log("[parseOgImageData] Result:", result2);
919
- }
920
- return result2;
921
- } catch (decodeError) {
922
- console.error("[parseOgImageData] Error decoding/parsing data param:", decodeError);
923
- if (decodeError instanceof Error) {
924
- console.error("[parseOgImageData] Error message:", decodeError.message);
925
- }
926
- }
927
- } else {
928
- if (process.env.NODE_ENV === "development") {
929
- console.log("[parseOgImageData] No data param found or empty");
930
- }
931
- }
932
- const result = {};
933
- for (const [key, value] of Object.entries(params)) {
934
- if (key !== "data" && value !== void 0 && value !== null) {
935
- result[key] = Array.isArray(value) ? value[0] : String(value);
936
- }
937
- }
938
- if (process.env.NODE_ENV === "development") {
939
- console.log("[parseOgImageData] Fallback result:", result);
940
- }
941
- return result;
942
- } catch (error) {
943
- console.error("[parseOgImageData] Unexpected error:", error);
944
- return {};
945
- }
946
- }
947
-
948
- // src/og-image/utils/metadata.ts
949
- function extractTitle(metadata) {
950
- if (typeof metadata.title === "string") {
951
- return metadata.title;
952
- }
953
- if (metadata.title) {
954
- if ("default" in metadata.title) {
955
- return metadata.title.default;
956
- }
957
- if ("absolute" in metadata.title) {
958
- return metadata.title.absolute;
959
- }
960
- }
961
- return "";
962
- }
963
- function extractDescription(metadata) {
964
- if (typeof metadata.description === "string") {
965
- return metadata.description;
966
- }
967
- return "";
968
- }
969
- function getSiteUrl() {
970
- if (typeof process !== "undefined" && process.env.NEXT_PUBLIC_SITE_URL) {
971
- return process.env.NEXT_PUBLIC_SITE_URL;
972
- }
973
- return "";
974
- }
975
- function generateAppMetadata(metadata, ogImageParams, options = {}) {
976
- const {
977
- ogImageBaseUrl = "https://djangocfg.com/api/og",
978
- siteUrl: providedSiteUrl,
979
- defaultParams = {},
980
- useBase64 = true,
981
- favicon,
982
- appleIcon
983
- } = options;
984
- const siteUrl = providedSiteUrl && providedSiteUrl !== "undefined" ? providedSiteUrl : getSiteUrl();
985
- const extractedTitle = extractTitle(metadata);
986
- const extractedDescription = extractDescription(metadata);
987
- const finalOgImageParams = {
988
- ...defaultParams,
989
- title: ogImageParams?.title || extractedTitle || defaultParams.title || "",
990
- description: ogImageParams?.description || extractedDescription || defaultParams.description || "",
991
- ...ogImageParams
992
- };
993
- const imageAlt = finalOgImageParams.title || finalOgImageParams.siteName;
994
- const relativeOgImageUrl = generateOgImageUrl(
995
- finalOgImageParams,
996
- { baseUrl: ogImageBaseUrl, useBase64 }
997
- );
998
- const ogImageUrl = siteUrl ? getAbsoluteOgImageUrl(relativeOgImageUrl, siteUrl) : relativeOgImageUrl;
999
- const existingOgImages = metadata.openGraph?.images ? Array.isArray(metadata.openGraph.images) ? metadata.openGraph.images : [metadata.openGraph.images] : [];
1000
- const existingTwitterImages = metadata.twitter?.images ? Array.isArray(metadata.twitter.images) ? metadata.twitter.images : [metadata.twitter.images] : [];
1001
- const finalMetadata = {
1002
- ...metadata,
1003
- openGraph: {
1004
- ...metadata.openGraph,
1005
- images: [
1006
- ...existingOgImages,
1007
- {
1008
- url: ogImageUrl,
1009
- width: 1200,
1010
- height: 630,
1011
- alt: imageAlt
1012
- }
1013
- ]
1014
- },
1015
- twitter: {
1016
- ...metadata.twitter,
1017
- card: "summary_large_image",
1018
- images: [
1019
- ...existingTwitterImages,
1020
- {
1021
- url: ogImageUrl,
1022
- alt: imageAlt
1023
- }
1024
- ]
1025
- }
1026
- };
1027
- if (!finalMetadata.metadataBase && siteUrl) {
1028
- if (siteUrl.startsWith("http://") || siteUrl.startsWith("https://")) {
1029
- try {
1030
- finalMetadata.metadataBase = new URL(siteUrl);
1031
- } catch (e) {
1032
- }
1033
- }
1034
- }
1035
- if (favicon || appleIcon) {
1036
- const existingIcons = metadata.icons && typeof metadata.icons === "object" && !Array.isArray(metadata.icons) ? metadata.icons : {};
1037
- finalMetadata.icons = {
1038
- ...existingIcons,
1039
- ...favicon && { icon: favicon },
1040
- ...appleIcon && { apple: appleIcon }
1041
- };
1042
- }
1043
- return finalMetadata;
1044
- }
1045
- function createAppMetadataGenerator(options) {
1046
- return (metadata, ogImageParams) => {
1047
- return generateAppMetadata(metadata, ogImageParams, options);
1048
- };
1049
- }
1050
-
1051
- // src/og-image/route.tsx
1052
- import { jsx as jsx2 } from "react/jsx-runtime";
1053
- function createOgImageHandler(config) {
1054
- const {
1055
- template: Template = DefaultTemplate,
1056
- defaultProps = {},
1057
- fonts: fontConfig = [],
1058
- size = { width: 1200, height: 630 },
1059
- debug = false
1060
- } = config;
1061
- async function GET(req) {
1062
- let searchParams = new URLSearchParams();
1063
- if (req.nextUrl?.searchParams && req.nextUrl.searchParams.size > 0) {
1064
- searchParams = req.nextUrl.searchParams;
1065
- } else if (req.nextUrl?.search && req.nextUrl.search.length > 1) {
1066
- searchParams = new URLSearchParams(req.nextUrl.search);
1067
- } else {
1068
- try {
1069
- const url = new URL(req.url);
1070
- if (url.searchParams.size > 0) {
1071
- searchParams = url.searchParams;
1072
- }
1073
- } catch (error) {
1074
- }
1075
- if (searchParams.size === 0 && req.url) {
1076
- const queryIndex = req.url.indexOf("?");
1077
- if (queryIndex !== -1) {
1078
- const queryString = req.url.substring(queryIndex + 1);
1079
- searchParams = new URLSearchParams(queryString);
1080
- }
1081
- }
1082
- if (searchParams.size === 0) {
1083
- const customParams = req.headers.get("x-og-search-params");
1084
- if (customParams) {
1085
- searchParams = new URLSearchParams(customParams);
1086
- }
1087
- }
1088
- }
1089
- let title = defaultProps.title || "Untitled";
1090
- let subtitle = defaultProps.subtitle || "";
1091
- let description = defaultProps.description || subtitle;
1092
- const dataParam = searchParams.get("data");
1093
- let decodedParams = {};
1094
- if (dataParam) {
1095
- try {
1096
- const paramsObj = { data: dataParam };
1097
- for (const [key, value] of searchParams.entries()) {
1098
- if (key !== "data") {
1099
- paramsObj[key] = value;
1100
- }
1101
- }
1102
- decodedParams = parseOgImageData(paramsObj);
1103
- if (decodedParams.title && typeof decodedParams.title === "string" && decodedParams.title.trim() !== "") {
1104
- title = decodedParams.title.trim();
1105
- }
1106
- if (decodedParams.subtitle && typeof decodedParams.subtitle === "string" && decodedParams.subtitle.trim() !== "") {
1107
- subtitle = decodedParams.subtitle.trim();
1108
- }
1109
- if (decodedParams.description && typeof decodedParams.description === "string" && decodedParams.description.trim() !== "") {
1110
- description = decodedParams.description.trim();
1111
- }
1112
- } catch (error) {
1113
- }
1114
- }
1115
- if (!title || title === "Untitled") {
1116
- const titleParam = searchParams.get("title");
1117
- if (titleParam) {
1118
- title = titleParam;
1119
- }
1120
- }
1121
- if (!subtitle) {
1122
- const subtitleParam = searchParams.get("subtitle");
1123
- if (subtitleParam) {
1124
- subtitle = subtitleParam;
1125
- }
1126
- }
1127
- if (!description || description === subtitle) {
1128
- const descParam = searchParams.get("description");
1129
- if (descParam) {
1130
- description = descParam;
1131
- }
1132
- }
1133
- let fonts = [];
1134
- if (fontConfig.length > 0) {
1135
- fonts = await loadGoogleFonts(fontConfig);
1136
- }
1137
- const parseValue = (value, type = "string") => {
1138
- if (value === void 0 || value === null || value === "") {
1139
- return void 0;
1140
- }
1141
- if (type === "number") {
1142
- const num = Number(value);
1143
- return isNaN(num) ? void 0 : num;
1144
- }
1145
- if (type === "boolean") {
1146
- if (typeof value === "boolean") return value;
1147
- if (typeof value === "string") {
1148
- return value.toLowerCase() === "true" || value === "1";
1149
- }
1150
- return Boolean(value);
1151
- }
1152
- return String(value);
1153
- };
1154
- const templateProps = {
1155
- ...defaultProps,
1156
- // Content
1157
- title,
1158
- subtitle,
1159
- description,
1160
- // Override with decoded params if present
1161
- siteName: decodedParams.siteName || defaultProps.siteName,
1162
- logo: decodedParams.logo || defaultProps.logo,
1163
- // Background
1164
- backgroundType: decodedParams.backgroundType || defaultProps.backgroundType,
1165
- gradientStart: decodedParams.gradientStart || defaultProps.gradientStart,
1166
- gradientEnd: decodedParams.gradientEnd || defaultProps.gradientEnd,
1167
- backgroundColor: decodedParams.backgroundColor || defaultProps.backgroundColor,
1168
- // Typography - Title
1169
- titleSize: parseValue(decodedParams.titleSize, "number") ?? defaultProps.titleSize,
1170
- titleWeight: parseValue(decodedParams.titleWeight, "number") ?? defaultProps.titleWeight,
1171
- titleColor: decodedParams.titleColor || defaultProps.titleColor,
1172
- // Typography - Description
1173
- descriptionSize: parseValue(decodedParams.descriptionSize, "number") ?? defaultProps.descriptionSize,
1174
- descriptionColor: decodedParams.descriptionColor || defaultProps.descriptionColor,
1175
- // Typography - Site Name
1176
- siteNameSize: parseValue(decodedParams.siteNameSize, "number") ?? defaultProps.siteNameSize,
1177
- siteNameColor: decodedParams.siteNameColor || defaultProps.siteNameColor,
1178
- // Layout
1179
- padding: parseValue(decodedParams.padding, "number") ?? defaultProps.padding,
1180
- logoSize: parseValue(decodedParams.logoSize, "number") ?? defaultProps.logoSize,
1181
- // Visibility flags
1182
- showLogo: parseValue(decodedParams.showLogo, "boolean") ?? defaultProps.showLogo,
1183
- showSiteName: parseValue(decodedParams.showSiteName, "boolean") ?? defaultProps.showSiteName
1184
- };
1185
- return new ImageResponse(
1186
- /* @__PURE__ */ jsx2(Template, { ...templateProps }),
1187
- {
1188
- width: size.width,
1189
- height: size.height,
1190
- fonts,
1191
- debug: debug || process.env.NODE_ENV === "development"
1192
- }
1193
- );
1194
- }
1195
- return {
1196
- GET,
1197
- runtime: "edge"
1198
- };
1199
- }
1200
- function createOgImageDynamicRoute(config) {
1201
- const handler = createOgImageHandler(config);
1202
- const isStaticBuild2 = typeof process !== "undefined" && process.env.NEXT_PUBLIC_STATIC_BUILD === "true";
1203
- async function GET(request, context) {
1204
- if (isStaticBuild2) {
1205
- return new Response("OG Image generation is not available in static export mode", {
1206
- status: 404,
1207
- headers: { "Content-Type": "text/plain" }
1208
- });
1209
- }
1210
- const params = await context.params;
1211
- const dataParam = params.data;
1212
- const url = new URL(request.url);
1213
- url.searchParams.set("data", dataParam);
1214
- const modifiedRequest = new NextRequest(url.toString(), {
1215
- method: request.method,
1216
- headers: request.headers
1217
- });
1218
- return handler.GET(modifiedRequest);
1219
- }
1220
- async function generateStaticParams() {
1221
- return [];
1222
- }
1223
- return {
1224
- GET,
1225
- generateStaticParams
1226
- };
1227
- }
1228
-
1229
389
  // src/navigation/utils.ts
1230
390
  function defineRoute(path, metadata) {
1231
391
  return {
@@ -1395,7 +555,7 @@ function getBasePath(isDefaultCfgAdmin) {
1395
555
  function getApiUrl() {
1396
556
  return isStaticBuild ? "" : process.env.NEXT_PUBLIC_API_URL || "";
1397
557
  }
1398
- function getSiteUrl2() {
558
+ function getSiteUrl() {
1399
559
  return isStaticBuild ? "" : process.env.NEXT_PUBLIC_SITE_URL || "";
1400
560
  }
1401
561
 
@@ -2374,7 +1534,7 @@ function deepMerge(target, source) {
2374
1534
  function createBaseNextConfig(options = {}) {
2375
1535
  const basePath = getBasePath(options.isDefaultCfgAdmin);
2376
1536
  const apiUrl = getApiUrl();
2377
- const siteUrl = getSiteUrl2();
1537
+ const siteUrl = getSiteUrl();
2378
1538
  const baseConfig = {
2379
1539
  reactStrictMode: true,
2380
1540
  trailingSlash: true,
@@ -2654,10 +1814,8 @@ export {
2654
1814
  DEFAULT_TRANSPILE_PACKAGES,
2655
1815
  DJANGOCFG_PACKAGES,
2656
1816
  DJANGO_CFG_BANNER,
2657
- DefaultTemplate,
2658
1817
  DevStartupPlugin,
2659
1818
  DjangoCfgDocsClient,
2660
- LightTemplate,
2661
1819
  MCP_API_URL,
2662
1820
  MCP_BASE_URL,
2663
1821
  MCP_SERVER_URL,
@@ -2672,26 +1830,16 @@ export {
2672
1830
  checkForUpdate,
2673
1831
  checkForUpdates,
2674
1832
  checkPackages,
2675
- createAppMetadataGenerator,
2676
1833
  createBaseNextConfig,
2677
- createFontLoader,
2678
1834
  createHealthHandler,
2679
- createOgImageDynamicRoute,
2680
- createOgImageHandler,
2681
- createOgImageUrlBuilder,
2682
1835
  createSitemapHandler,
2683
- decodeBase64,
2684
1836
  deepMerge,
2685
1837
  defineRoute,
2686
1838
  detectPackageManager,
2687
- encodeBase64,
2688
1839
  fetchLatestVersion2 as fetchLatestVersion,
2689
1840
  findRoute,
2690
1841
  findRouteByPattern,
2691
- generateAppMetadata,
2692
- generateOgImageUrl,
2693
1842
  generateSitemapXml,
2694
- getAbsoluteOgImageUrl,
2695
1843
  getApiUrl,
2696
1844
  getBasePath,
2697
1845
  getCurrentVersion,
@@ -2703,7 +1851,7 @@ export {
2703
1851
  getOutdatedPackages,
2704
1852
  getPackagesForContext,
2705
1853
  getPageTitle,
2706
- getSiteUrl2 as getSiteUrl,
1854
+ getSiteUrl,
2707
1855
  getUnauthenticatedRedirect,
2708
1856
  getUpdateCommand,
2709
1857
  groupRoutesByNavGroups,
@@ -2716,11 +1864,7 @@ export {
2716
1864
  isPackageInstalled,
2717
1865
  isProduction,
2718
1866
  isStaticBuild,
2719
- loadGoogleFont,
2720
- loadGoogleFonts,
2721
1867
  normalizeUrl,
2722
- parseOgImageData,
2723
- parseOgImageUrl,
2724
1868
  printVersionInfo,
2725
1869
  redirectToAuth,
2726
1870
  resetDevStartupState,