cms-renderer 0.6.5 → 0.6.7

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.
@@ -1,3 +1,75 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // lib/cms-api.ts
12
+ var cms_api_exports = {};
13
+ __export(cms_api_exports, {
14
+ getCmsClient: () => getCmsClient
15
+ });
16
+ import { createTRPCClient, httpBatchLink } from "@trpc/client";
17
+ import superjson from "superjson";
18
+ function getCmsApiUrl(cmsUrl) {
19
+ return new URL("/api/trpc", cmsUrl).toString();
20
+ }
21
+ function createFetchWithApiKey(apiKey, websiteId) {
22
+ return async (url, options) => {
23
+ let finalUrl = url;
24
+ const urlObj = new URL(url.toString());
25
+ if (apiKey) {
26
+ urlObj.searchParams.set("api_key", apiKey);
27
+ }
28
+ if (websiteId) {
29
+ urlObj.searchParams.set("website_id", websiteId);
30
+ }
31
+ if (apiKey || websiteId) {
32
+ finalUrl = urlObj.toString();
33
+ }
34
+ const response = await fetch(finalUrl, options);
35
+ return response;
36
+ };
37
+ }
38
+ function createCmsClient(options) {
39
+ const url = getCmsApiUrl(options.cmsUrl);
40
+ return createTRPCClient({
41
+ links: [
42
+ httpBatchLink({
43
+ url,
44
+ transformer: superjson,
45
+ fetch: createFetchWithApiKey(options.apiKey, options.websiteId)
46
+ })
47
+ ]
48
+ });
49
+ }
50
+ function getClientCacheKey(options) {
51
+ return `${options.cmsUrl}|${options.apiKey ?? ""}|${options.websiteId ?? ""}`;
52
+ }
53
+ function getCmsClient(options) {
54
+ const cacheKey = getClientCacheKey(options);
55
+ let client = clientCache.get(cacheKey);
56
+ if (!client) {
57
+ client = createCmsClient(options);
58
+ clientCache.set(cacheKey, client);
59
+ }
60
+ return client;
61
+ }
62
+ var clientCache;
63
+ var init_cms_api = __esm({
64
+ "lib/cms-api.ts"() {
65
+ "use strict";
66
+ clientCache = /* @__PURE__ */ new Map();
67
+ }
68
+ });
69
+
70
+ // lib/renderer.tsx
71
+ import { notFound } from "next/navigation";
72
+
1
73
  // ../../packages/cms-schema/src/blocks/article.ts
2
74
  function normalizeArticleContent(payload) {
3
75
  if (!payload || typeof payload !== "object") {
@@ -238,8 +310,70 @@ function isValidBlockSchemaName(name) {
238
310
  return BLOCK_SCHEMA_NAMES.includes(name);
239
311
  }
240
312
 
241
- // lib/renderer.tsx
242
- import { notFound } from "next/navigation";
313
+ // ../../packages/cms-schema/src/routing/normalize-path.ts
314
+ function normalizePath(path) {
315
+ if (!path || path === "/") {
316
+ return "/";
317
+ }
318
+ let normalized = path.trim();
319
+ if (!normalized) {
320
+ return "/";
321
+ }
322
+ if (normalized === "/") {
323
+ return "/";
324
+ }
325
+ let end = normalized.length;
326
+ while (end > 1 && normalized.charCodeAt(end - 1) === 47) {
327
+ end--;
328
+ }
329
+ if (end < normalized.length) {
330
+ normalized = normalized.slice(0, end);
331
+ }
332
+ if (!normalized.startsWith("/")) {
333
+ normalized = `/${normalized}`;
334
+ }
335
+ const segments = normalized.split("/").filter((s) => s.length > 0);
336
+ if (segments.length === 0) {
337
+ return "/";
338
+ }
339
+ return `/${segments.join("/")}`;
340
+ }
341
+
342
+ // ../../packages/cms-schema/src/routing/path-validation.ts
343
+ import { z as z8 } from "zod";
344
+ var pathRegex = /^\/[\p{L}\p{N}\-_{}/:]*$/u;
345
+ var placeholderSegmentRegex = /^(:[a-zA-Z0-9_]+|\{[a-zA-Z0-9_]+\})$/;
346
+ function hasValidPlaceholderStructure(path) {
347
+ if (path === "/") {
348
+ return true;
349
+ }
350
+ const segments = path.split("/").filter(Boolean);
351
+ return segments.every((segment) => {
352
+ const hasPlaceholderSyntax = segment.includes(":") || segment.includes("{") || segment.includes("}");
353
+ if (!hasPlaceholderSyntax) {
354
+ return true;
355
+ }
356
+ return placeholderSegmentRegex.test(segment);
357
+ });
358
+ }
359
+ var pathSchema = z8.string().min(1, "Path is required").regex(
360
+ pathRegex,
361
+ "Path must start with / and contain only letters, numbers, hyphens, underscores, slashes, colons, and braces"
362
+ ).refine(
363
+ hasValidPlaceholderStructure,
364
+ "Path placeholders must be in the form :name or {name} with non-empty names"
365
+ );
366
+
367
+ // ../../packages/cms-schema/src/documents/schemas/language.ts
368
+ import { z as z9 } from "zod";
369
+ var LanguageSchema = z9.object({
370
+ /** 2-letter ISO 639-1 language code */
371
+ code: z9.string().length(2, "Language code must be 2 characters"),
372
+ /** English name of the language */
373
+ name: z9.string().min(1, "Language name required"),
374
+ /** Name in the language itself (optional but recommended) */
375
+ nativeName: z9.string().optional()
376
+ });
243
377
 
244
378
  // lib/block-renderer.tsx
245
379
  import React from "react";
@@ -424,46 +558,8 @@ function BlockRenderer({
424
558
  return /* @__PURE__ */ jsx(ClientEditableBlock, { blockId: block.id, blockType: block.type, contentEntries, children: component });
425
559
  }
426
560
 
427
- // lib/cms-api.ts
428
- import { createTRPCClient, httpBatchLink } from "@trpc/client";
429
- import superjson from "superjson";
430
- function getCmsApiUrl(cmsUrl) {
431
- return new URL("/api/trpc", cmsUrl).toString();
432
- }
433
- function createFetchWithApiKey(apiKey, websiteId) {
434
- return async (url, options) => {
435
- let finalUrl = url;
436
- const urlObj = new URL(url.toString());
437
- if (apiKey) {
438
- urlObj.searchParams.set("api_key", apiKey);
439
- }
440
- if (websiteId) {
441
- urlObj.searchParams.set("website_id", websiteId);
442
- }
443
- if (apiKey || websiteId) {
444
- finalUrl = urlObj.toString();
445
- }
446
- const response = await fetch(finalUrl, options);
447
- return response;
448
- };
449
- }
450
- function createCmsClient(options) {
451
- const url = getCmsApiUrl(options.cmsUrl);
452
- return createTRPCClient({
453
- links: [
454
- httpBatchLink({
455
- url,
456
- transformer: superjson,
457
- fetch: createFetchWithApiKey(options.apiKey, options.websiteId)
458
- })
459
- ]
460
- });
461
- }
462
- function getCmsClient(options) {
463
- return createCmsClient(options);
464
- }
465
-
466
- // lib/renderer.tsx
561
+ // lib/parametric-route.tsx
562
+ init_cms_api();
467
563
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
468
564
  function getWebsiteId(providedWebsiteId) {
469
565
  const websiteId = providedWebsiteId ?? process.env.NEXT_PUBLIC_WEBSITE_ID ?? process.env.WEBSITE_ID ?? process.env.CMS_WEBSITE_ID;
@@ -480,7 +576,7 @@ function getWebsiteId(providedWebsiteId) {
480
576
  }
481
577
  return websiteId;
482
578
  }
483
- async function ParametricRoutePage({
579
+ async function renderParametricRoute({
484
580
  params,
485
581
  searchParams,
486
582
  registry,
@@ -507,7 +603,7 @@ async function ParametricRoutePage({
507
603
  const rawPath = `/${slug.join("/")}`;
508
604
  const path = normalizePath(rawPath);
509
605
  if (/\.[a-zA-Z0-9]+$/.test(path)) {
510
- notFound();
606
+ return { status: "not_found" };
511
607
  }
512
608
  const client = getCmsClient({ apiKey, cmsUrl });
513
609
  try {
@@ -516,23 +612,18 @@ async function ParametricRoutePage({
516
612
  path
517
613
  });
518
614
  if (route.state !== "Live") {
519
- notFound();
615
+ return { status: "not_found" };
520
616
  }
521
- const blockPromises = route.block_ids.map(async (blockId) => {
522
- try {
523
- const result = await client.block.getById.query({ websiteId, id: blockId });
524
- return result.block;
525
- } catch (error) {
526
- console.error(`Failed to fetch block ${blockId}:`, error);
527
- return null;
528
- }
617
+ const blockResultsPromise = client.block.getByIds.query({ websiteId, ids: route.block_ids }).catch((error) => {
618
+ console.error("Failed to fetch blocks:", error);
619
+ return [];
529
620
  });
530
621
  const generatedBlocksPromise = aiPreviewIndex !== null ? client.block.getGeneratedByBlockIds.query({ websiteId, blockIds: route.block_ids }).catch((error) => {
531
622
  console.error("Failed to fetch generated blocks:", error);
532
623
  return { generatedBlocks: {} };
533
624
  }) : Promise.resolve({ generatedBlocks: {} });
534
625
  const [blockResults, { generatedBlocks }] = await Promise.all([
535
- Promise.all(blockPromises),
626
+ blockResultsPromise,
536
627
  generatedBlocksPromise
537
628
  ]);
538
629
  const blocks = [];
@@ -585,29 +676,44 @@ async function ParametricRoutePage({
585
676
  }
586
677
  ])
587
678
  ) : void 0;
588
- return /* @__PURE__ */ jsxs2("main", { children: [
589
- editMode && /* @__PURE__ */ jsx2(CmsEditableInit, {}),
590
- blocks.map((block) => /* @__PURE__ */ jsx2(
591
- BlockRenderer,
592
- {
593
- block,
594
- registry: registry ?? {},
595
- disableEditable: !editMode,
596
- routeParams,
597
- path
598
- },
599
- block.id
600
- ))
601
- ] });
679
+ return {
680
+ status: "ok",
681
+ node: /* @__PURE__ */ jsxs2("main", { children: [
682
+ editMode && /* @__PURE__ */ jsx2(CmsEditableInit, {}),
683
+ blocks.map((block) => /* @__PURE__ */ jsx2(
684
+ BlockRenderer,
685
+ {
686
+ block,
687
+ registry: registry ?? {},
688
+ disableEditable: !editMode,
689
+ routeParams,
690
+ path
691
+ },
692
+ block.id
693
+ ))
694
+ ] })
695
+ };
602
696
  } catch (error) {
603
697
  console.error(`Route fetch error for path: ${path}`, error);
604
698
  const errorCode = error instanceof Error && "data" in error ? error.data?.code : error instanceof Error && "code" in error ? error.code : void 0;
605
699
  if (errorCode === "NOT_FOUND" || errorCode === "P0002" || errorCode === "BAD_REQUEST") {
606
- notFound();
700
+ return { status: "not_found" };
607
701
  }
608
- throw error;
702
+ return { status: "error", error };
609
703
  }
610
704
  }
705
+
706
+ // lib/renderer.tsx
707
+ async function ParametricRoutePage(props) {
708
+ const result = await renderParametricRoute(props);
709
+ if (result.status === "not_found") {
710
+ notFound();
711
+ }
712
+ if (result.status === "error") {
713
+ throw result.error;
714
+ }
715
+ return result.node;
716
+ }
611
717
  async function generateMetadata({
612
718
  params,
613
719
  apiKey,
@@ -618,7 +724,8 @@ async function generateMetadata({
618
724
  const { slug } = await params;
619
725
  const rawPath = `/${slug.join("/")}`;
620
726
  const path = normalizePath(rawPath);
621
- const client = getCmsClient({ apiKey, cmsUrl });
727
+ const { getCmsClient: getCmsClient2 } = await Promise.resolve().then(() => (init_cms_api(), cms_api_exports));
728
+ const client = getCmsClient2({ apiKey, cmsUrl });
622
729
  try {
623
730
  const { route } = await client.route.getByPath.query({ websiteId, path });
624
731
  return {
@@ -632,21 +739,8 @@ async function generateMetadata({
632
739
  };
633
740
  }
634
741
  }
635
- function normalizePath(path) {
636
- if (!path || path === "/") {
637
- return "/";
638
- }
639
- let normalized = path.trim();
640
- normalized = normalized.replace(/\/+$/, "");
641
- if (!normalized.startsWith("/")) {
642
- normalized = `/${normalized}`;
643
- }
644
- normalized = normalized.replace(/\/+/g, "/");
645
- return normalized;
646
- }
647
742
  export {
648
743
  ParametricRoutePage as default,
649
- generateMetadata,
650
- normalizePath
744
+ generateMetadata
651
745
  };
652
746
  //# sourceMappingURL=renderer.js.map