@mints-cloud/cxf-codegen 1.0.2 → 1.0.4

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.
Files changed (41) hide show
  1. package/README.md +40 -1
  2. package/dist/components/ApiCall.d.ts +5 -0
  3. package/dist/components/ApiCall.d.ts.map +1 -1
  4. package/dist/components/ApiCall.js +18 -3
  5. package/dist/components/JsonLdSchemas.d.ts +104 -0
  6. package/dist/components/JsonLdSchemas.d.ts.map +1 -0
  7. package/dist/components/JsonLdSchemas.js +380 -0
  8. package/dist/components/MetadataOverrides.d.ts +84 -0
  9. package/dist/components/MetadataOverrides.d.ts.map +1 -0
  10. package/dist/components/MetadataOverrides.js +270 -0
  11. package/dist/index.d.ts +3 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +14 -1
  14. package/dist/lib/api-call-hooks.d.ts +2 -1
  15. package/dist/lib/api-call-hooks.d.ts.map +1 -1
  16. package/dist/lib/api-call-hooks.js +64 -11
  17. package/dist/lib/api-route-helpers.d.ts +1 -0
  18. package/dist/lib/api-route-helpers.d.ts.map +1 -1
  19. package/dist/lib/api-route-helpers.js +13 -0
  20. package/dist/lib/assets-query-params.d.ts +11 -0
  21. package/dist/lib/assets-query-params.d.ts.map +1 -0
  22. package/dist/lib/assets-query-params.js +130 -0
  23. package/dist/lib/cxf-auth.d.ts +7 -3
  24. package/dist/lib/cxf-auth.d.ts.map +1 -1
  25. package/dist/lib/cxf-auth.js +17 -6
  26. package/dist/lib/seo-utils.d.ts +22 -0
  27. package/dist/lib/seo-utils.d.ts.map +1 -0
  28. package/dist/lib/seo-utils.js +228 -0
  29. package/dist/lib/server-props.d.ts.map +1 -1
  30. package/dist/lib/server-props.js +46 -4
  31. package/dist/pages/api/assets.d.ts.map +1 -1
  32. package/dist/pages/api/assets.js +27 -1
  33. package/dist/pages/api/cxf.d.ts +5 -0
  34. package/dist/pages/api/cxf.d.ts.map +1 -1
  35. package/dist/pages/api/cxf.js +37 -4
  36. package/dist/pages/app.d.ts +4 -1
  37. package/dist/pages/app.d.ts.map +1 -1
  38. package/dist/pages/app.js +11 -6
  39. package/dist/register.d.ts.map +1 -1
  40. package/dist/register.js +193 -2
  41. package/package.json +13 -1
package/README.md CHANGED
@@ -17,14 +17,53 @@ Your project needs thin wrapper files that import from this library. The `create
17
17
  ```tsx
18
18
  import '@/styles/globals.css'
19
19
  import '@mints-cloud/cxf-codegen/register';
20
+ import type { AppProps } from 'next/app';
20
21
  import CxfApp from '@mints-cloud/cxf-codegen/pages/app';
21
22
  import projectcss from '../components/plasmic/<your-project>/plasmic.module.css';
22
23
 
23
- export default function App(props) {
24
+ export default function App(props: AppProps) {
24
25
  return <CxfApp {...props} tokenClass={projectcss.plasmic_tokens} />;
25
26
  }
26
27
  ```
27
28
 
29
+ ### Configure assets query params from variants
30
+
31
+ Configure this in `pages/_app.tsx` by passing dynamic asset query params to `CxfApp`.
32
+ These params are synced to a cookie and automatically appended by `pages/api/assets/[...path].ts` proxy requests.
33
+ Your `pages/api/assets/[...path].ts` file should stay a thin wrapper:
34
+
35
+ ```ts
36
+ export { default } from '@mints-cloud/cxf-codegen/pages/api/assets';
37
+ ```
38
+
39
+ ```tsx
40
+ import '@/styles/globals.css'
41
+ import '@mints-cloud/cxf-codegen/register';
42
+ import type { AppProps } from 'next/app';
43
+ import CxfApp from '@mints-cloud/cxf-codegen/pages/app';
44
+ import projectcss from '../components/plasmic/<your-project>/plasmic.module.css';
45
+ import { useScreenVariants } from '../components/plasmic/<your-project>/PlasmicGlobalVariant__Screen';
46
+
47
+ export default function App(props: AppProps) {
48
+ const screenVariants = useScreenVariants();
49
+ const variation = screenVariants.includes('mobile')
50
+ ? 'mobile'
51
+ : screenVariants.includes('tablet')
52
+ ? 'tablet'
53
+ : undefined;
54
+
55
+ return (
56
+ <CxfApp
57
+ {...props}
58
+ tokenClass={projectcss.plasmic_tokens}
59
+ assetsQueryParams={variation ? { variation } : undefined}
60
+ />
61
+ );
62
+ }
63
+ ```
64
+
65
+ `assetsQueryParams` accepts any query keys/values, so you can map any Plasmic variant naming to any asset param names you need.
66
+
28
67
  ### `pages/api/[...path].ts`
29
68
 
30
69
  ```ts
@@ -12,6 +12,11 @@ export interface ApiCallProps {
12
12
  onSuccess?: (data: any) => void;
13
13
  onError?: (error: string) => void;
14
14
  loadingContent?: React.ReactNode;
15
+ /**
16
+ * In Plasmic Studio canvas, throttle automatic GET refetches to this interval.
17
+ * Defaults to 5 minutes. Runtime pages are unaffected.
18
+ */
19
+ canvasAutoFetchCooldownMs?: number;
15
20
  children?: React.ReactNode;
16
21
  }
17
22
  export declare function ApiCall(props: ApiCallProps): import("react/jsx-runtime").JSX.Element | null;
@@ -1 +1 @@
1
- {"version":3,"file":"ApiCall.d.ts","sourceRoot":"","sources":["../../src/components/ApiCall.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAsBD,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,kDAqD1C;AAED,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"ApiCall.d.ts","sourceRoot":"","sources":["../../src/components/ApiCall.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC;;;OAGG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAgCD,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,kDA0D1C;AAED,eAAe,OAAO,CAAC"}
@@ -38,6 +38,18 @@ const jsx_runtime_1 = require("react/jsx-runtime");
38
38
  const React = __importStar(require("react"));
39
39
  const host_1 = require("@plasmicapp/host");
40
40
  const api_call_hooks_1 = require("../lib/api-call-hooks");
41
+ function parseAutoFetch(value) {
42
+ if (typeof value === "boolean")
43
+ return value;
44
+ if (typeof value === "string") {
45
+ const normalized = value.trim().toLowerCase();
46
+ if (normalized === "true")
47
+ return true;
48
+ if (normalized === "false")
49
+ return false;
50
+ }
51
+ return undefined;
52
+ }
41
53
  function trimSlashes(p) {
42
54
  return String(p || "").replace(/^\/+|\/+$/g, "");
43
55
  }
@@ -57,9 +69,10 @@ function buildEndpointPath(apiType, rawPath) {
57
69
  }
58
70
  }
59
71
  function ApiCall(props) {
60
- const { apiType = "contact", path, method = "GET", params, body, initialData, autoFetch, trigger, onSuccess, onError, loadingContent, children, } = props;
72
+ const { apiType = "contact", path, method = "GET", params, body, initialData, autoFetch, trigger, onSuccess, onError, loadingContent, canvasAutoFetchCooldownMs, children, } = props;
61
73
  const endpointPath = React.useMemo(() => buildEndpointPath(apiType, path), [apiType, path]);
62
- const shouldAutoFetch = autoFetch !== undefined ? autoFetch : method === "GET";
74
+ const explicitAutoFetch = parseAutoFetch(autoFetch);
75
+ const shouldAutoFetch = explicitAutoFetch ?? method === "GET";
63
76
  const { preloaded, hasExactPreload } = (0, api_call_hooks_1.useIsrPrefetch)(endpointPath, params, method, initialData);
64
77
  const { data, error, loading } = (0, api_call_hooks_1.useApiFetch)({
65
78
  endpointPath,
@@ -73,13 +86,15 @@ function ApiCall(props) {
73
86
  onSuccess,
74
87
  onError,
75
88
  unwrapData: true,
89
+ canvasAutoFetchCooldownMs,
76
90
  });
77
91
  // If no children, render nothing (still performs the call + callbacks)
78
92
  if (!children)
79
93
  return null;
80
94
  // If children exist, respect loadingContent for UX
81
- if (loading)
95
+ if (loading) {
82
96
  return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: loadingContent ?? (0, jsx_runtime_1.jsx)("div", { children: "Loading\u2026" }) });
97
+ }
83
98
  const responseData = {
84
99
  data: error ? null : data,
85
100
  error,
@@ -0,0 +1,104 @@
1
+ import type { PageMeta, SiteSettings } from "./MetadataOverrides";
2
+ type MaybeString = string | null | undefined;
3
+ type MaybeStringList = string[] | string | null | undefined;
4
+ type JsonLdPayload = Record<string, unknown> | unknown[];
5
+ interface FaqItem {
6
+ question?: MaybeString;
7
+ answer?: MaybeString;
8
+ }
9
+ interface BlogAuthor {
10
+ name?: MaybeString;
11
+ url?: MaybeString;
12
+ type?: MaybeString;
13
+ }
14
+ interface BlogCoverImage {
15
+ slug?: MaybeString;
16
+ title?: MaybeString;
17
+ alt_text?: MaybeString;
18
+ mime_type?: MaybeString;
19
+ public_path?: MaybeString;
20
+ id?: MaybeString;
21
+ }
22
+ interface BlogVersionDefault {
23
+ lecture_time?: MaybeString;
24
+ cover_image?: BlogCoverImage;
25
+ blurb?: MaybeString;
26
+ body?: MaybeString;
27
+ }
28
+ interface BlogPageMeta {
29
+ page_title?: MaybeString;
30
+ permalink?: MaybeString;
31
+ page_type?: MaybeString;
32
+ }
33
+ interface BlogSeoPerPage {
34
+ page_meta_title?: MaybeString;
35
+ page_meta_description?: MaybeString;
36
+ page_robots_follow?: MaybeString;
37
+ page_robots_indexing?: MaybeString;
38
+ page_canonical_url?: MaybeString;
39
+ keywords?: MaybeStringList;
40
+ }
41
+ interface BlogSocialAndSharing {
42
+ page_open_graph_title?: MaybeString;
43
+ page_open_graph_description?: MaybeString;
44
+ page_open_graph_image?: {
45
+ public_path?: MaybeString;
46
+ alt_text?: MaybeString;
47
+ };
48
+ }
49
+ interface BlogVersion {
50
+ created_at?: MaybeString;
51
+ updated_at?: MaybeString;
52
+ title?: MaybeString;
53
+ slug?: MaybeString;
54
+ default?: BlogVersionDefault;
55
+ page_meta?: BlogPageMeta;
56
+ seo_per_page?: BlogSeoPerPage;
57
+ social_and_sharing?: BlogSocialAndSharing;
58
+ }
59
+ interface MetadataSourceInput {
60
+ siteSettings?: SiteSettings | string | null;
61
+ pageMeta?: PageMeta | string | null;
62
+ }
63
+ interface BlogInfo {
64
+ headline?: MaybeString;
65
+ description?: MaybeString;
66
+ image?: MaybeString;
67
+ datePublished?: MaybeString;
68
+ dateModified?: MaybeString;
69
+ articleSection?: MaybeString;
70
+ articleBody?: MaybeString;
71
+ wordCount?: number | string | null;
72
+ keywords?: MaybeStringList;
73
+ schemaId?: MaybeString;
74
+ id?: MaybeString;
75
+ seo_per_page?: BlogSeoPerPage;
76
+ version?: BlogVersion;
77
+ }
78
+ interface BlogAuthorGroup {
79
+ name?: MaybeString;
80
+ url?: MaybeString;
81
+ type?: MaybeString;
82
+ authors?: BlogAuthor[] | string | null;
83
+ }
84
+ export interface FaqJsonLdProps {
85
+ items?: FaqItem[] | string | null;
86
+ metadataSource?: MetadataSourceInput | string | null;
87
+ schemaId?: MaybeString;
88
+ scriptKey?: MaybeString;
89
+ }
90
+ export interface BlogPostingJsonLdProps {
91
+ blog?: BlogInfo | string | null;
92
+ author?: BlogAuthorGroup | string | null;
93
+ metadataSource?: MetadataSourceInput | string | null;
94
+ scriptKey?: MaybeString;
95
+ }
96
+ export interface CustomJsonLdProps {
97
+ schema?: JsonLdPayload | string | null;
98
+ scriptKey?: MaybeString;
99
+ }
100
+ export declare function FaqJsonLd(props: FaqJsonLdProps): import("react/jsx-runtime").JSX.Element | null;
101
+ export declare function BlogPostingJsonLd(props: BlogPostingJsonLdProps): import("react/jsx-runtime").JSX.Element | null;
102
+ export declare function CustomJsonLd(props: CustomJsonLdProps): import("react/jsx-runtime").JSX.Element | null;
103
+ export {};
104
+ //# sourceMappingURL=JsonLdSchemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonLdSchemas.d.ts","sourceRoot":"","sources":["../../src/components/JsonLdSchemas.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,380 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.FaqJsonLd = FaqJsonLd;
40
+ exports.BlogPostingJsonLd = BlogPostingJsonLd;
41
+ exports.CustomJsonLd = CustomJsonLd;
42
+ const jsx_runtime_1 = require("react/jsx-runtime");
43
+ const React = __importStar(require("react"));
44
+ const head_1 = __importDefault(require("next/head"));
45
+ const seo_utils_1 = require("../lib/seo-utils");
46
+ function resolveMetadataDefaults(metadataSource) {
47
+ const source = (0, seo_utils_1.parseObject)(metadataSource, {
48
+ parseJson: seo_utils_1.tryParseLooseJson
49
+ }) ?? undefined;
50
+ const siteSettings = (0, seo_utils_1.parseObject)(source?.siteSettings, {
51
+ parseJson: seo_utils_1.tryParseLooseJson
52
+ }) ?? undefined;
53
+ const pageMeta = (0, seo_utils_1.parseObject)(source?.pageMeta, {
54
+ parseJson: seo_utils_1.tryParseLooseJson
55
+ }) ?? undefined;
56
+ const canonicalBase = (0, seo_utils_1.pickFirstString)(siteSettings?.seo_defaults?.canonical_base, siteSettings?.domains_and_locales?.primary_domain);
57
+ const url = (0, seo_utils_1.pickFirstString)(pageMeta?.seo_per_page?.page_canonical_url, (0, seo_utils_1.toAbsoluteUrl)(pageMeta?.default?.permalink, canonicalBase), canonicalBase);
58
+ const inLanguage = (0, seo_utils_1.pickFirstString)(siteSettings?.domains_and_locales?.default_locale);
59
+ const canonicalAssetBaseUrl = (0, seo_utils_1.pickFirstString)((0, seo_utils_1.resolveUrlBase)(canonicalBase, url), canonicalBase, url);
60
+ const currentOrigin = (0, seo_utils_1.getCurrentOrigin)();
61
+ const assetBaseUrl = (0, seo_utils_1.pickFirstString)((0, seo_utils_1.resolveUrlBase)(currentOrigin, canonicalAssetBaseUrl), currentOrigin, canonicalAssetBaseUrl);
62
+ return { url, inLanguage, assetBaseUrl };
63
+ }
64
+ function resolveOrganizationId(metadataSource) {
65
+ const source = (0, seo_utils_1.parseObject)(metadataSource, {
66
+ parseJson: seo_utils_1.tryParseLooseJson
67
+ }) ?? undefined;
68
+ const siteSettings = (0, seo_utils_1.parseObject)(source?.siteSettings, {
69
+ parseJson: seo_utils_1.tryParseLooseJson
70
+ }) ?? undefined;
71
+ const pageMeta = (0, seo_utils_1.parseObject)(source?.pageMeta, {
72
+ parseJson: seo_utils_1.tryParseLooseJson
73
+ }) ?? undefined;
74
+ const organizationBase = (0, seo_utils_1.pickFirstString)((0, seo_utils_1.resolveUrlBase)(siteSettings?.seo_defaults?.canonical_base, siteSettings?.domains_and_locales?.primary_domain, pageMeta?.seo_per_page?.page_canonical_url), siteSettings?.seo_defaults?.canonical_base, siteSettings?.domains_and_locales?.primary_domain, pageMeta?.seo_per_page?.page_canonical_url);
75
+ return (0, seo_utils_1.buildOrganizationId)(organizationBase);
76
+ }
77
+ function resolveBlogEntryUrl(blog, metadataDefaults) {
78
+ const canonicalFromBlog = (0, seo_utils_1.cleanString)(blog.version?.seo_per_page?.page_canonical_url ?? blog.seo_per_page?.page_canonical_url);
79
+ if (canonicalFromBlog) {
80
+ return canonicalFromBlog;
81
+ }
82
+ const permalink = (0, seo_utils_1.cleanString)(blog.version?.page_meta?.permalink);
83
+ if (permalink) {
84
+ return (0, seo_utils_1.toAbsoluteUrl)(permalink, metadataDefaults.assetBaseUrl ?? metadataDefaults.url);
85
+ }
86
+ return metadataDefaults.url;
87
+ }
88
+ function toNumber(value) {
89
+ if (typeof value === "number" && Number.isFinite(value)) {
90
+ return value;
91
+ }
92
+ if (typeof value === "string") {
93
+ const trimmed = value.trim();
94
+ if (!trimmed) {
95
+ return undefined;
96
+ }
97
+ const parsed = Number(trimmed);
98
+ if (Number.isFinite(parsed)) {
99
+ return parsed;
100
+ }
101
+ }
102
+ return undefined;
103
+ }
104
+ function decodeHtmlEntities(input) {
105
+ const namedEntities = {
106
+ amp: "&",
107
+ lt: "<",
108
+ gt: ">",
109
+ quot: "\"",
110
+ apos: "'",
111
+ nbsp: " ",
112
+ aacute: "\u00e1",
113
+ eacute: "\u00e9",
114
+ iacute: "\u00ed",
115
+ oacute: "\u00f3",
116
+ uacute: "\u00fa",
117
+ Aacute: "\u00c1",
118
+ Eacute: "\u00c9",
119
+ Iacute: "\u00cd",
120
+ Oacute: "\u00d3",
121
+ Uacute: "\u00da",
122
+ ntilde: "\u00f1",
123
+ Ntilde: "\u00d1",
124
+ uuml: "\u00fc",
125
+ Uuml: "\u00dc"
126
+ };
127
+ return input
128
+ .replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => {
129
+ const code = Number.parseInt(hex, 16);
130
+ return Number.isFinite(code) ? String.fromCodePoint(code) : _;
131
+ })
132
+ .replace(/&#([0-9]+);/g, (_, dec) => {
133
+ const code = Number.parseInt(dec, 10);
134
+ return Number.isFinite(code) ? String.fromCodePoint(code) : _;
135
+ })
136
+ .replace(/&([a-zA-Z][a-zA-Z0-9]+);/g, (entity, name) => namedEntities[name] ?? entity);
137
+ }
138
+ function stripHtmlToText(value) {
139
+ const raw = (0, seo_utils_1.cleanString)(value);
140
+ if (!raw) {
141
+ return undefined;
142
+ }
143
+ const withoutScripts = raw
144
+ .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, " ")
145
+ .replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, " ");
146
+ const withoutTags = withoutScripts.replace(/<[^>]+>/g, " ");
147
+ const decoded = decodeHtmlEntities(withoutTags);
148
+ const normalized = decoded.replace(/\s+/g, " ").trim();
149
+ return normalized || undefined;
150
+ }
151
+ function countWords(value) {
152
+ const text = stripHtmlToText(value) ?? (0, seo_utils_1.cleanString)(value);
153
+ if (!text) {
154
+ return undefined;
155
+ }
156
+ const words = text.split(/\s+/).filter(Boolean);
157
+ return words.length > 0 ? words.length : undefined;
158
+ }
159
+ function uniqStrings(values) {
160
+ return Array.from(new Set(values.map((value) => value.trim()).filter(Boolean)));
161
+ }
162
+ function parseJsonLdPayload(value) {
163
+ if (value == null) {
164
+ return undefined;
165
+ }
166
+ if (typeof value === "object") {
167
+ return value;
168
+ }
169
+ const trimmed = value.trim();
170
+ if (!trimmed) {
171
+ return undefined;
172
+ }
173
+ try {
174
+ const parsed = JSON.parse(trimmed);
175
+ if (parsed && typeof parsed === "object") {
176
+ return parsed;
177
+ }
178
+ }
179
+ catch {
180
+ return undefined;
181
+ }
182
+ return undefined;
183
+ }
184
+ function buildJsonLdKey(prefix, scriptKey, schemaId) {
185
+ const suffix = (0, seo_utils_1.cleanString)(scriptKey) ?? (0, seo_utils_1.cleanString)(schemaId) ?? "default";
186
+ return `jsonld-${prefix}-${suffix}`;
187
+ }
188
+ function JsonLdScript(props) {
189
+ const { payload, headKey } = props;
190
+ const json = React.useMemo(() => (0, seo_utils_1.safeJsonForInlineScript)(payload), [payload]);
191
+ const scriptId = (0, seo_utils_1.toDomId)(headKey);
192
+ React.useEffect(() => {
193
+ const cleanup = () => {
194
+ (0, seo_utils_1.removeDuplicateJsonLdScripts)(scriptId, headKey, json);
195
+ };
196
+ cleanup();
197
+ if (typeof document === "undefined" || typeof MutationObserver === "undefined") {
198
+ return undefined;
199
+ }
200
+ let rafId = null;
201
+ const observer = new MutationObserver(() => {
202
+ if (rafId != null) {
203
+ return;
204
+ }
205
+ rafId = window.requestAnimationFrame(() => {
206
+ rafId = null;
207
+ cleanup();
208
+ });
209
+ });
210
+ observer.observe(document.documentElement, {
211
+ childList: true,
212
+ subtree: true
213
+ });
214
+ return () => {
215
+ observer.disconnect();
216
+ if (rafId != null) {
217
+ window.cancelAnimationFrame(rafId);
218
+ }
219
+ };
220
+ }, [headKey, json, scriptId]);
221
+ return ((0, jsx_runtime_1.jsx)(head_1.default, { children: (0, jsx_runtime_1.jsx)("script", { id: scriptId, type: "application/ld+json", "data-jsonld-key": headKey, dangerouslySetInnerHTML: { __html: json } }, headKey) }));
222
+ }
223
+ function FaqJsonLd(props) {
224
+ const faqItems = React.useMemo(() => (0, seo_utils_1.parseObjectArray)(props.items, { parseJson: seo_utils_1.tryParseLooseJson }), [props.items]);
225
+ const metadataDefaults = React.useMemo(() => resolveMetadataDefaults(props.metadataSource), [props.metadataSource]);
226
+ const inLanguage = metadataDefaults.inLanguage;
227
+ const url = metadataDefaults.url;
228
+ const schemaId = (0, seo_utils_1.cleanString)(props.schemaId) ?? (url ? `${url.replace(/#.*$/, "")}#faq` : undefined);
229
+ const mainEntity = faqItems
230
+ .map((item) => {
231
+ const question = (0, seo_utils_1.cleanString)(item.question);
232
+ const answer = (0, seo_utils_1.cleanString)(item.answer);
233
+ if (!question || !answer) {
234
+ return null;
235
+ }
236
+ return {
237
+ "@type": "Question",
238
+ name: question,
239
+ acceptedAnswer: {
240
+ "@type": "Answer",
241
+ text: answer
242
+ }
243
+ };
244
+ })
245
+ .filter((item) => Boolean(item));
246
+ if (mainEntity.length === 0) {
247
+ return null;
248
+ }
249
+ const schema = {
250
+ "@context": "https://schema.org",
251
+ "@type": "FAQPage",
252
+ mainEntity
253
+ };
254
+ if (schemaId) {
255
+ schema["@id"] = schemaId;
256
+ }
257
+ if (url) {
258
+ schema.url = url;
259
+ }
260
+ if (inLanguage) {
261
+ schema.inLanguage = inLanguage;
262
+ }
263
+ return ((0, jsx_runtime_1.jsx)(JsonLdScript, { payload: schema, headKey: buildJsonLdKey("faq", props.scriptKey, schemaId) }));
264
+ }
265
+ function BlogPostingJsonLd(props) {
266
+ const blog = React.useMemo(() => (0, seo_utils_1.parseObject)(props.blog, { parseJson: seo_utils_1.tryParseLooseJson }) ?? {}, [props.blog]);
267
+ const authorGroup = React.useMemo(() => (0, seo_utils_1.parseObject)(props.author, { parseJson: seo_utils_1.tryParseLooseJson }) ?? {}, [props.author]);
268
+ const metadataDefaults = React.useMemo(() => resolveMetadataDefaults(props.metadataSource), [props.metadataSource]);
269
+ const organizationId = React.useMemo(() => resolveOrganizationId(props.metadataSource), [props.metadataSource]);
270
+ const headline = (0, seo_utils_1.pickFirstString)(blog.version?.social_and_sharing?.page_open_graph_title, blog.version?.seo_per_page?.page_meta_title, blog.seo_per_page?.page_meta_title, blog.version?.page_meta?.page_title, blog.version?.title, blog.headline);
271
+ if (!headline) {
272
+ return null;
273
+ }
274
+ const description = (0, seo_utils_1.pickFirstString)(blog.version?.social_and_sharing?.page_open_graph_description, blog.version?.seo_per_page?.page_meta_description, blog.seo_per_page?.page_meta_description, stripHtmlToText(blog.version?.default?.blurb), stripHtmlToText(blog.version?.default?.body));
275
+ const url = resolveBlogEntryUrl(blog, metadataDefaults);
276
+ const assetBaseUrl = (0, seo_utils_1.pickFirstString)((0, seo_utils_1.resolveUrlBase)(url, metadataDefaults.assetBaseUrl, metadataDefaults.url), metadataDefaults.assetBaseUrl, metadataDefaults.url, url);
277
+ const image = (0, seo_utils_1.toAbsoluteUrl)((0, seo_utils_1.pickFirstString)(blog.version?.social_and_sharing?.page_open_graph_image?.public_path, blog.version?.default?.cover_image?.public_path, blog.image), assetBaseUrl);
278
+ const datePublished = (0, seo_utils_1.pickFirstString)(blog.version?.created_at, blog.datePublished);
279
+ const dateModified = (0, seo_utils_1.pickFirstString)(blog.version?.updated_at, blog.dateModified);
280
+ const inLanguage = metadataDefaults.inLanguage;
281
+ const articleSection = (0, seo_utils_1.pickFirstString)(blog.articleSection, blog.version?.page_meta?.page_type);
282
+ const articleBody = (0, seo_utils_1.pickFirstString)(stripHtmlToText(blog.articleBody), stripHtmlToText(blog.version?.default?.body), (0, seo_utils_1.cleanString)(blog.articleBody), (0, seo_utils_1.cleanString)(blog.version?.default?.body));
283
+ const wordCount = toNumber(blog.wordCount) ?? countWords(articleBody ?? blog.version?.default?.body);
284
+ const blogId = (0, seo_utils_1.cleanString)(blog.id);
285
+ const schemaId = (0, seo_utils_1.cleanString)(blog.schemaId) ??
286
+ (blogId && url ? `${url.replace(/#.*$/, "")}#blog-posting-${blogId}` : undefined);
287
+ const seoKeywords = (0, seo_utils_1.parseStringList)(blog.version?.seo_per_page?.keywords ?? blog.seo_per_page?.keywords);
288
+ const explicitKeywords = (0, seo_utils_1.parseStringList)(blog.keywords);
289
+ const keywords = uniqStrings([...seoKeywords, ...explicitKeywords]);
290
+ const parsedAuthors = (0, seo_utils_1.parseObjectArray)(authorGroup.authors, {
291
+ parseJson: seo_utils_1.tryParseLooseJson
292
+ });
293
+ const fallbackAuthorName = (0, seo_utils_1.cleanString)(authorGroup.name);
294
+ const fallbackAuthorUrl = (0, seo_utils_1.cleanString)(authorGroup.url);
295
+ const fallbackAuthorType = (0, seo_utils_1.cleanString)(authorGroup.type) ?? "Person";
296
+ const authorNodes = parsedAuthors
297
+ .map((author) => {
298
+ const authorName = (0, seo_utils_1.cleanString)(author.name);
299
+ if (!authorName) {
300
+ return null;
301
+ }
302
+ const authorUrl = (0, seo_utils_1.cleanString)(author.url);
303
+ const authorType = (0, seo_utils_1.cleanString)(author.type) ?? "Person";
304
+ return {
305
+ "@type": authorType,
306
+ name: authorName,
307
+ ...(authorUrl ? { url: authorUrl } : {})
308
+ };
309
+ })
310
+ .filter((item) => Boolean(item));
311
+ if (authorNodes.length === 0 && fallbackAuthorName) {
312
+ authorNodes.push({
313
+ "@type": fallbackAuthorType,
314
+ name: fallbackAuthorName,
315
+ ...(fallbackAuthorUrl ? { url: fallbackAuthorUrl } : {})
316
+ });
317
+ }
318
+ const schema = {
319
+ "@context": "https://schema.org",
320
+ "@type": "BlogPosting",
321
+ headline
322
+ };
323
+ if (schemaId) {
324
+ schema["@id"] = schemaId;
325
+ }
326
+ if (description) {
327
+ schema.description = description;
328
+ }
329
+ if (url) {
330
+ schema.url = url;
331
+ schema.mainEntityOfPage = {
332
+ "@type": "WebPage",
333
+ "@id": url
334
+ };
335
+ }
336
+ if (image) {
337
+ schema.image = image;
338
+ }
339
+ if (datePublished) {
340
+ schema.datePublished = datePublished;
341
+ }
342
+ if (dateModified) {
343
+ schema.dateModified = dateModified;
344
+ }
345
+ if (inLanguage) {
346
+ schema.inLanguage = inLanguage;
347
+ }
348
+ if (articleSection) {
349
+ schema.articleSection = articleSection;
350
+ }
351
+ if (articleBody) {
352
+ schema.articleBody = articleBody;
353
+ }
354
+ if (wordCount !== undefined) {
355
+ schema.wordCount = wordCount;
356
+ }
357
+ if (keywords.length > 0) {
358
+ schema.keywords = keywords;
359
+ }
360
+ if (authorNodes.length === 1) {
361
+ schema.author = authorNodes[0];
362
+ }
363
+ else if (authorNodes.length > 1) {
364
+ schema.author = authorNodes;
365
+ }
366
+ if (organizationId) {
367
+ schema.publisher = {
368
+ "@id": organizationId
369
+ };
370
+ }
371
+ return ((0, jsx_runtime_1.jsx)(JsonLdScript, { payload: schema, headKey: buildJsonLdKey("blog", props.scriptKey, schemaId) }));
372
+ }
373
+ function CustomJsonLd(props) {
374
+ const payload = React.useMemo(() => parseJsonLdPayload(props.schema), [props.schema]);
375
+ if (!payload) {
376
+ return null;
377
+ }
378
+ const headKey = buildJsonLdKey("custom", props.scriptKey);
379
+ return (0, jsx_runtime_1.jsx)(JsonLdScript, { payload: payload, headKey: headKey });
380
+ }