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 CHANGED
@@ -6,7 +6,7 @@ It provides:
6
6
 
7
7
  - A catch-all route component that fetches CMS routes and blocks from the CMS API and renders them with your React component registry
8
8
  - A proxy helper for mounting the CMS admin and API behind your app
9
- - Schema-fetching utilities for headless document access
9
+ - Component-fetching utilities for headless document access
10
10
  - Docs-oriented markdown rendering and styles
11
11
  - Type exports for block registries and route params
12
12
 
@@ -27,8 +27,8 @@ Main entry points:
27
27
  - `cms-renderer/lib/renderer` for catch-all route rendering
28
28
  - `cms-renderer/lib/types` for block and route types
29
29
  - `cms-renderer/lib/proxy` for proxying CMS admin and API traffic
30
- - `cms-renderer/lib/schema` for headless schema-based reads
31
- - `cms-renderer/lib/custom-schemas` for fetching custom schema metadata and generating Zod code
30
+ - `cms-renderer/lib/schema` for headless component-based reads
31
+ - `cms-renderer/lib/custom-schemas` for fetching custom component metadata and generating Zod code
32
32
  - `cms-renderer/lib/docs-markdown` and `cms-renderer/styles/docs-markdown.css` for docs markdown rendering
33
33
  - `cms-renderer/lib/refresher` for client-side refresh on CMS updates
34
34
 
@@ -147,7 +147,7 @@ NEXT_PUBLIC_CMS_API_URL=https://cms.example.com
147
147
 
148
148
  Use `CMS_API_KEY` when your CMS requires authenticated access.
149
149
 
150
- `NEXT_PUBLIC_CMS_API_URL` is only used by the default `schema` export from `cms-renderer/lib/schema`. If you call `configureSchema(...)` directly, pass `cmsUrl` explicitly instead.
150
+ The default `schema` / `component` exports from `cms-renderer/lib/schema` read `NEXT_PUBLIC_CMS_API_URL` on **first use** (lazy), not when the module loads — so importing only `configureSchema` never touches that env. If you call `configureSchema(...)` directly, pass `cmsUrl` explicitly instead.
151
151
 
152
152
  If no website ID is available, `ParametricRoutePage` throws at runtime.
153
153
 
@@ -181,9 +181,9 @@ The proxy helper:
181
181
  - Rewrites cookies for the current deployment host
182
182
  - Proxies admin-originated static asset requests
183
183
 
184
- ## Headless Schema Access
184
+ ## Headless Component Access
185
185
 
186
- Use `configureSchema` or the default `schema` export when you want published documents for a custom schema outside the block renderer.
186
+ Use `configureSchema` or the default `component` export when you want published documents for a custom component outside the block renderer.
187
187
 
188
188
  ```ts
189
189
  import { configureSchema } from 'cms-renderer/lib/schema';
@@ -206,11 +206,11 @@ Available methods:
206
206
  - `fetchSingleById(id)`
207
207
  - `translation(language)`
208
208
 
209
- If you use the default `schema` export, it reads `NEXT_PUBLIC_CMS_API_URL` from the environment. If your app already has a CMS base URL under a different variable name, prefer `configureSchema(...)` and pass `cmsUrl` explicitly.
209
+ If you use the default `component` export, it reads `NEXT_PUBLIC_CMS_API_URL` from the environment on first access. If you call `configureSchema(...)` directly, pass the CMS origin/base URL as `cmsUrl`.
210
210
 
211
- ## Custom Schema Code Generation
211
+ ## Custom Component Code Generation
212
212
 
213
- Use `cms-renderer/lib/custom-schemas` to fetch custom schema metadata and generate typed Zod schema code for your app.
213
+ Use `cms-renderer/lib/custom-schemas` to fetch custom component metadata and generate typed Zod component code for your app. The helper names in this module still use `Schema` for compatibility.
214
214
 
215
215
  ```ts
216
216
  import {
@@ -218,13 +218,13 @@ import {
218
218
  saveZodSchemaCode,
219
219
  } from 'cms-renderer/lib/custom-schemas';
220
220
 
221
- const schemas = await fetchAllCustomSchemaFields({
221
+ const components = await fetchAllCustomSchemaFields({
222
222
  cmsUrl: process.env.NEXT_PUBLIC_CMS_URL!,
223
223
  apiKey: process.env.CMS_API_KEY,
224
224
  websiteId: process.env.NEXT_PUBLIC_WEBSITE_ID!,
225
225
  });
226
226
 
227
- await saveZodSchemaCode(schemas, 'generated/cms-schemas.ts');
227
+ await saveZodSchemaCode(components, 'generated/cms-schemas.ts');
228
228
  ```
229
229
 
230
230
  Also exported:
@@ -21,6 +21,7 @@ interface CmsConfig {
21
21
  }
22
22
  /**
23
23
  * Get a CMS client for the specified CMS URL.
24
+ * Uses a singleton cache to avoid recreating clients with identical configuration.
24
25
  */
25
26
  declare function getCmsClient(options: CmsConfig): CmsClient;
26
27
 
@@ -33,8 +33,18 @@ function createCmsClient(options) {
33
33
  ]
34
34
  });
35
35
  }
36
+ var clientCache = /* @__PURE__ */ new Map();
37
+ function getClientCacheKey(options) {
38
+ return `${options.cmsUrl}|${options.apiKey ?? ""}|${options.websiteId ?? ""}`;
39
+ }
36
40
  function getCmsClient(options) {
37
- return createCmsClient(options);
41
+ const cacheKey = getClientCacheKey(options);
42
+ let client = clientCache.get(cacheKey);
43
+ if (!client) {
44
+ client = createCmsClient(options);
45
+ clientCache.set(cacheKey, client);
46
+ }
47
+ return client;
38
48
  }
39
49
  export {
40
50
  getCmsClient
@@ -1 +1 @@
1
- {"version":3,"sources":["../../lib/cms-api.ts"],"sourcesContent":["/**\n * CMS API Client\n *\n * Creates an HTTP-based tRPC client for calling the CMS API.\n * Used in Server Components to fetch routes and blocks from the CMS.\n */\n\nimport type { AppRouter } from '@repo/cms-schema/trpc';\nimport { type CreateTRPCClient, createTRPCClient, httpBatchLink } from '@trpc/client';\nimport superjson from 'superjson';\n\n/** Type alias for the CMS API client */\ntype CmsClient = CreateTRPCClient<AppRouter>;\n\n/**\n * Get the CMS API URL from the provided base URL.\n */\nfunction getCmsApiUrl(cmsUrl: string): string {\n return new URL('/api/trpc', cmsUrl).toString();\n}\n\n/** Unified configuration for all CMS API access */\nexport interface CmsConfig {\n /** CMS API base URL (e.g., 'http://localhost:3000') */\n cmsUrl: string;\n /** API key for authentication */\n apiKey?: string;\n /** Website ID to scope API requests */\n websiteId?: string;\n}\n\n/**\n * Create a custom fetch function that appends API key as query parameter.\n */\nfunction createFetchWithApiKey(apiKey?: string, websiteId?: string) {\n return async (url: URL | RequestInfo, options?: RequestInit): Promise<Response> => {\n let finalUrl = url;\n\n const urlObj = new URL(url.toString());\n if (apiKey) {\n urlObj.searchParams.set('api_key', apiKey);\n }\n if (websiteId) {\n urlObj.searchParams.set('website_id', websiteId);\n }\n if (apiKey || websiteId) {\n finalUrl = urlObj.toString();\n }\n\n const response = await fetch(finalUrl, options);\n\n return response;\n };\n}\n\n/**\n * Create a tRPC client for the CMS API.\n */\nfunction createCmsClient(options: CmsConfig): CmsClient {\n const url = getCmsApiUrl(options.cmsUrl);\n\n return createTRPCClient<AppRouter>({\n links: [\n httpBatchLink({\n url,\n transformer: superjson,\n fetch: createFetchWithApiKey(options.apiKey, options.websiteId),\n }),\n ],\n });\n}\n\n/**\n * Get a CMS client for the specified CMS URL.\n */\nexport function getCmsClient(options: CmsConfig): CmsClient {\n return createCmsClient(options);\n}\n"],"mappings":";AAQA,SAAgC,kBAAkB,qBAAqB;AACvE,OAAO,eAAe;AAQtB,SAAS,aAAa,QAAwB;AAC5C,SAAO,IAAI,IAAI,aAAa,MAAM,EAAE,SAAS;AAC/C;AAeA,SAAS,sBAAsB,QAAiB,WAAoB;AAClE,SAAO,OAAO,KAAwB,YAA6C;AACjF,QAAI,WAAW;AAEf,UAAM,SAAS,IAAI,IAAI,IAAI,SAAS,CAAC;AACrC,QAAI,QAAQ;AACV,aAAO,aAAa,IAAI,WAAW,MAAM;AAAA,IAC3C;AACA,QAAI,WAAW;AACb,aAAO,aAAa,IAAI,cAAc,SAAS;AAAA,IACjD;AACA,QAAI,UAAU,WAAW;AACvB,iBAAW,OAAO,SAAS;AAAA,IAC7B;AAEA,UAAM,WAAW,MAAM,MAAM,UAAU,OAAO;AAE9C,WAAO;AAAA,EACT;AACF;AAKA,SAAS,gBAAgB,SAA+B;AACtD,QAAM,MAAM,aAAa,QAAQ,MAAM;AAEvC,SAAO,iBAA4B;AAAA,IACjC,OAAO;AAAA,MACL,cAAc;AAAA,QACZ;AAAA,QACA,aAAa;AAAA,QACb,OAAO,sBAAsB,QAAQ,QAAQ,QAAQ,SAAS;AAAA,MAChE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;AAKO,SAAS,aAAa,SAA+B;AAC1D,SAAO,gBAAgB,OAAO;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../lib/cms-api.ts"],"sourcesContent":["/**\n * CMS API Client\n *\n * Creates an HTTP-based tRPC client for calling the CMS API.\n * Used in Server Components to fetch routes and blocks from the CMS.\n */\n\nimport type { AppRouter } from '@repo/cms-schema/trpc';\nimport { type CreateTRPCClient, createTRPCClient, httpBatchLink } from '@trpc/client';\nimport superjson from 'superjson';\n\n/** Type alias for the CMS API client */\ntype CmsClient = CreateTRPCClient<AppRouter>;\n\n/**\n * Get the CMS API URL from the provided base URL.\n */\nfunction getCmsApiUrl(cmsUrl: string): string {\n return new URL('/api/trpc', cmsUrl).toString();\n}\n\n/** Unified configuration for all CMS API access */\nexport interface CmsConfig {\n /** CMS API base URL (e.g., 'http://localhost:3000') */\n cmsUrl: string;\n /** API key for authentication */\n apiKey?: string;\n /** Website ID to scope API requests */\n websiteId?: string;\n}\n\n/**\n * Create a custom fetch function that appends API key as query parameter.\n */\nfunction createFetchWithApiKey(apiKey?: string, websiteId?: string) {\n return async (url: URL | RequestInfo, options?: RequestInit): Promise<Response> => {\n let finalUrl = url;\n\n const urlObj = new URL(url.toString());\n if (apiKey) {\n urlObj.searchParams.set('api_key', apiKey);\n }\n if (websiteId) {\n urlObj.searchParams.set('website_id', websiteId);\n }\n if (apiKey || websiteId) {\n finalUrl = urlObj.toString();\n }\n\n const response = await fetch(finalUrl, options);\n\n return response;\n };\n}\n\n/**\n * Create a tRPC client for the CMS API.\n */\nfunction createCmsClient(options: CmsConfig): CmsClient {\n const url = getCmsApiUrl(options.cmsUrl);\n\n return createTRPCClient<AppRouter>({\n links: [\n httpBatchLink({\n url,\n transformer: superjson,\n fetch: createFetchWithApiKey(options.apiKey, options.websiteId),\n }),\n ],\n });\n}\n\nconst clientCache = new Map<string, CmsClient>();\n\nfunction getClientCacheKey(options: CmsConfig): string {\n return `${options.cmsUrl}|${options.apiKey ?? ''}|${options.websiteId ?? ''}`;\n}\n\n/**\n * Get a CMS client for the specified CMS URL.\n * Uses a singleton cache to avoid recreating clients with identical configuration.\n */\nexport function getCmsClient(options: CmsConfig): CmsClient {\n const cacheKey = getClientCacheKey(options);\n\n let client = clientCache.get(cacheKey);\n if (!client) {\n client = createCmsClient(options);\n clientCache.set(cacheKey, client);\n }\n\n return client;\n}\n"],"mappings":";AAQA,SAAgC,kBAAkB,qBAAqB;AACvE,OAAO,eAAe;AAQtB,SAAS,aAAa,QAAwB;AAC5C,SAAO,IAAI,IAAI,aAAa,MAAM,EAAE,SAAS;AAC/C;AAeA,SAAS,sBAAsB,QAAiB,WAAoB;AAClE,SAAO,OAAO,KAAwB,YAA6C;AACjF,QAAI,WAAW;AAEf,UAAM,SAAS,IAAI,IAAI,IAAI,SAAS,CAAC;AACrC,QAAI,QAAQ;AACV,aAAO,aAAa,IAAI,WAAW,MAAM;AAAA,IAC3C;AACA,QAAI,WAAW;AACb,aAAO,aAAa,IAAI,cAAc,SAAS;AAAA,IACjD;AACA,QAAI,UAAU,WAAW;AACvB,iBAAW,OAAO,SAAS;AAAA,IAC7B;AAEA,UAAM,WAAW,MAAM,MAAM,UAAU,OAAO;AAE9C,WAAO;AAAA,EACT;AACF;AAKA,SAAS,gBAAgB,SAA+B;AACtD,QAAM,MAAM,aAAa,QAAQ,MAAM;AAEvC,SAAO,iBAA4B;AAAA,IACjC,OAAO;AAAA,MACL,cAAc;AAAA,QACZ;AAAA,QACA,aAAa;AAAA,QACb,OAAO,sBAAsB,QAAQ,QAAQ,QAAQ,SAAS;AAAA,MAChE,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACH;AAEA,IAAM,cAAc,oBAAI,IAAuB;AAE/C,SAAS,kBAAkB,SAA4B;AACrD,SAAO,GAAG,QAAQ,MAAM,IAAI,QAAQ,UAAU,EAAE,IAAI,QAAQ,aAAa,EAAE;AAC7E;AAMO,SAAS,aAAa,SAA+B;AAC1D,QAAM,WAAW,kBAAkB,OAAO;AAE1C,MAAI,SAAS,YAAY,IAAI,QAAQ;AACrC,MAAI,CAAC,QAAQ;AACX,aAAS,gBAAgB,OAAO;AAChC,gBAAY,IAAI,UAAU,MAAM;AAAA,EAClC;AAEA,SAAO;AACT;","names":[]}
@@ -988,6 +988,8 @@ var RehydrationError = class extends Error {
988
988
  this.fieldType = fieldType;
989
989
  this.name = "RehydrationError";
990
990
  }
991
+ fieldName;
992
+ fieldType;
991
993
  };
992
994
  function rehydrateField(field) {
993
995
  try {
@@ -1016,6 +1018,8 @@ function createBaseSchema(type, constraints) {
1016
1018
  return z7.boolean();
1017
1019
  case "image":
1018
1020
  return ImageReferenceSchema;
1021
+ case "icon":
1022
+ return z7.string().max(50);
1019
1023
  case "date":
1020
1024
  return z7.iso.date("Invalid date format. Expected YYYY-MM-DD");
1021
1025
  case "datetime":
@@ -1183,7 +1187,8 @@ var fieldDefinitionSchema = z9.object({
1183
1187
  "enum",
1184
1188
  "reference",
1185
1189
  "array",
1186
- "image"
1190
+ "image",
1191
+ "icon"
1187
1192
  ]),
1188
1193
  displayName: z9.string().optional(),
1189
1194
  description: z9.string().optional(),
@@ -1234,8 +1239,18 @@ function createCmsClient(options) {
1234
1239
  ]
1235
1240
  });
1236
1241
  }
1242
+ var clientCache = /* @__PURE__ */ new Map();
1243
+ function getClientCacheKey(options) {
1244
+ return `${options.cmsUrl}|${options.apiKey ?? ""}|${options.websiteId ?? ""}`;
1245
+ }
1237
1246
  function getCmsClient(options) {
1238
- return createCmsClient(options);
1247
+ const cacheKey = getClientCacheKey(options);
1248
+ let client = clientCache.get(cacheKey);
1249
+ if (!client) {
1250
+ client = createCmsClient(options);
1251
+ clientCache.set(cacheKey, client);
1252
+ }
1253
+ return client;
1239
1254
  }
1240
1255
 
1241
1256
  // lib/custom-schemas.ts