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.
- package/README.md +11 -11
- package/dist/lib/cms-api.d.ts +1 -0
- package/dist/lib/cms-api.js +11 -1
- package/dist/lib/cms-api.js.map +1 -1
- package/dist/lib/custom-schemas.js +17 -2
- package/dist/lib/custom-schemas.js.map +1 -1
- package/dist/lib/docs-markdown.d.ts +1 -0
- package/dist/lib/docs-markdown.js +103 -14
- package/dist/lib/docs-markdown.js.map +1 -1
- package/dist/lib/parametric-route.d.ts +41 -0
- package/dist/lib/parametric-route.js +686 -0
- package/dist/lib/parametric-route.js.map +1 -0
- package/dist/lib/proxy.js +8 -20
- package/dist/lib/proxy.js.map +1 -1
- package/dist/lib/renderer.d.ts +7 -23
- package/dist/lib/renderer.js +179 -85
- package/dist/lib/renderer.js.map +1 -1
- package/dist/lib/schema.d.ts +24 -7
- package/dist/lib/schema.js +62 -8
- package/dist/lib/schema.js.map +1 -1
- package/package.json +8 -1
package/dist/lib/renderer.js
CHANGED
|
@@ -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
|
-
//
|
|
242
|
-
|
|
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/
|
|
428
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
615
|
+
return { status: "not_found" };
|
|
520
616
|
}
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
|
|
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
|
-
|
|
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
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
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
|
-
|
|
700
|
+
return { status: "not_found" };
|
|
607
701
|
}
|
|
608
|
-
|
|
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
|
|
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
|