cms-renderer 0.4.0 → 0.4.1

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
@@ -26,7 +26,7 @@ The website app fetches structured page data via tRPC and renders blocks using t
26
26
  bun install
27
27
 
28
28
  # Start the website dev server
29
- cd apps/website
29
+ cd apps/renderer
30
30
  bun run dev
31
31
  ```
32
32
 
@@ -51,7 +51,7 @@ Visit [http://localhost:3001/demo](http://localhost:3001/demo) to see the comple
51
51
  auteur/
52
52
  ├── apps/
53
53
  │ ├── cms/ # Content authoring (Lexical editor)
54
- │ └── website/ # This app - renders CMS content
54
+ │ └── renderer/ # This app - renders CMS content
55
55
  └── packages/
56
56
  ├── cms-schema/ # Shared Zod schemas
57
57
  └── markdown-wasm/ # WASM markdown renderer
@@ -62,7 +62,7 @@ The website consumes schemas from `@repo/cms-schema` and uses `@repo/markdown-wa
62
62
  ### Key Directories
63
63
 
64
64
  ```
65
- apps/website/
65
+ apps/renderer/
66
66
  ├── app/ # Next.js App Router pages
67
67
  │ ├── [slug]/ # Dynamic page routes
68
68
  │ │ ├── page.tsx # Server Component fetches via tRPC
@@ -8,6 +8,7 @@ interface SchemaConfigOptions extends Partial<CmsConfig> {
8
8
  interface SchemaQuery {
9
9
  fetchAll: <T = Record<string, unknown>>() => Promise<T[]>;
10
10
  fetchSingle: <T = Record<string, unknown>>() => Promise<T | null>;
11
+ fetchSingleById: <T = Record<string, unknown>>(id: string) => Promise<T | null>;
11
12
  }
12
13
  interface SchemaClient {
13
14
  name: (schemaName: string) => SchemaQuery;
@@ -29,6 +29,18 @@ function createSchemaQuery(cmsUrl, schemaName, fetchOptions = {}, websiteId, _ap
29
29
  }
30
30
  const data = await response.json();
31
31
  return Array.isArray(data) ? data[0] ?? null : data;
32
+ },
33
+ async fetchSingleById(id) {
34
+ const url = new URL(baseUrlString);
35
+ url.searchParams.set("id", id);
36
+ const response = await fetch(url.toString(), fetchOptions);
37
+ if (!response.ok) {
38
+ throw new Error(
39
+ `Failed to fetch schema "${schemaName}" by id "${id}": ${response.statusText}`
40
+ );
41
+ }
42
+ const data = await response.json();
43
+ return Array.isArray(data) ? data[0] ?? null : data;
32
44
  }
33
45
  };
34
46
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../lib/schema.ts"],"sourcesContent":["// Fetch schema from the CMS for a headless setup\n// This should look like this\n//\n// import { schema, configureSchema } from \"@profound/cms\";\n//\n// // Option 1: Use default config (reads from CMS_API_URL env var)\n// const footerData = schema.name(\"footer\").fetchAll();\n//\n// // Option 2: Configure with custom CMS URL and fetch options\n// const customSchema = configureSchema({\n// cmsUrl: \"https://my-cms.example.com/api\",\n// fetchOptions: { headers: { Authorization: \"Bearer token\" } },\n// });\n// const footerData = customSchema.name(\"footer\").fetchAll();\n//\n// console.log(footerData); # [{ logo: \"<cloudflare_signed_img_url>\", \"Footer_text\": \"Profound\" }]\n\nimport type { CmsConfig } from './cms-api';\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\ninterface SchemaConfigOptions extends Partial<CmsConfig> {\n fetchOptions?: RequestInit;\n}\n\ninterface SchemaQuery {\n fetchAll: <T = Record<string, unknown>>() => Promise<T[]>;\n fetchSingle: <T = Record<string, unknown>>() => Promise<T | null>;\n}\n\ninterface SchemaClient {\n name: (schemaName: string) => SchemaQuery;\n}\n\nfunction createSchemaQuery(\n cmsUrl: string,\n schemaName: string,\n fetchOptions: RequestInit = {},\n websiteId?: string,\n _apiKey?: string\n): SchemaQuery {\n const baseUrl = new URL(`/api/schemas/${schemaName}`, `${cmsUrl}`);\n if (websiteId) {\n baseUrl.searchParams.set('websiteId', websiteId);\n }\n\n const baseUrlString = baseUrl.toString();\n\n return {\n async fetchAll<T = Record<string, unknown>>(): Promise<T[]> {\n const response = await fetch(baseUrlString, fetchOptions);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch schema \"${schemaName}\": ${response.statusText}`);\n }\n\n return response.json();\n },\n\n async fetchSingle<T = Record<string, unknown>>(): Promise<T | null> {\n const url = new URL(baseUrlString);\n url.searchParams.set('limit', '1');\n const response = await fetch(url.toString(), fetchOptions);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch schema \"${schemaName}\": ${response.statusText}`);\n }\n\n const data = await response.json();\n return Array.isArray(data) ? (data[0] ?? null) : data;\n },\n };\n}\n\nexport function configureSchema(config: SchemaConfigOptions = {}): SchemaClient {\n const cmsUrl = config.cmsUrl ?? requireEnv('NEXT_PUBLIC_CMS_API_URL');\n const fetchOptions = applyApiKey(config.fetchOptions || {}, config.apiKey);\n const websiteId = config.websiteId;\n\n return {\n name: (schemaName: string): SchemaQuery =>\n createSchemaQuery(cmsUrl, schemaName, fetchOptions, websiteId, config.apiKey),\n };\n}\n\nexport const schema: SchemaClient = configureSchema();\n\nfunction applyApiKey(fetchOptions: RequestInit, apiKey?: string): RequestInit {\n if (!apiKey) {\n return fetchOptions;\n }\n\n const headers = new Headers(fetchOptions.headers);\n if (!headers.has('x-api-key')) {\n headers.set('x-api-key', apiKey);\n }\n\n return {\n ...fetchOptions,\n headers,\n };\n}\n"],"mappings":";AAmBA,SAAS,WAAW,MAAsB;AACxC,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0CAA0C,IAAI,EAAE;AAAA,EAClE;AACA,SAAO;AACT;AAeA,SAAS,kBACP,QACA,YACA,eAA4B,CAAC,GAC7B,WACA,SACa;AACb,QAAM,UAAU,IAAI,IAAI,gBAAgB,UAAU,IAAI,GAAG,MAAM,EAAE;AACjE,MAAI,WAAW;AACb,YAAQ,aAAa,IAAI,aAAa,SAAS;AAAA,EACjD;AAEA,QAAM,gBAAgB,QAAQ,SAAS;AAEvC,SAAO;AAAA,IACL,MAAM,WAAsD;AAC1D,YAAM,WAAW,MAAM,MAAM,eAAe,YAAY;AAExD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,2BAA2B,UAAU,MAAM,SAAS,UAAU,EAAE;AAAA,MAClF;AAEA,aAAO,SAAS,KAAK;AAAA,IACvB;AAAA,IAEA,MAAM,cAA8D;AAClE,YAAM,MAAM,IAAI,IAAI,aAAa;AACjC,UAAI,aAAa,IAAI,SAAS,GAAG;AACjC,YAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG,YAAY;AAEzD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,2BAA2B,UAAU,MAAM,SAAS,UAAU,EAAE;AAAA,MAClF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,MAAM,QAAQ,IAAI,IAAK,KAAK,CAAC,KAAK,OAAQ;AAAA,IACnD;AAAA,EACF;AACF;AAEO,SAAS,gBAAgB,SAA8B,CAAC,GAAiB;AAC9E,QAAM,SAAS,OAAO,UAAU,WAAW,yBAAyB;AACpE,QAAM,eAAe,YAAY,OAAO,gBAAgB,CAAC,GAAG,OAAO,MAAM;AACzE,QAAM,YAAY,OAAO;AAEzB,SAAO;AAAA,IACL,MAAM,CAAC,eACL,kBAAkB,QAAQ,YAAY,cAAc,WAAW,OAAO,MAAM;AAAA,EAChF;AACF;AAEO,IAAM,SAAuB,gBAAgB;AAEpD,SAAS,YAAY,cAA2B,QAA8B;AAC5E,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,IAAI,QAAQ,aAAa,OAAO;AAChD,MAAI,CAAC,QAAQ,IAAI,WAAW,GAAG;AAC7B,YAAQ,IAAI,aAAa,MAAM;AAAA,EACjC;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../lib/schema.ts"],"sourcesContent":["// Fetch schema from the CMS for a headless setup\n// This should look like this\n//\n// import { schema, configureSchema } from \"@profound/cms\";\n//\n// // Option 1: Use default config (reads from CMS_API_URL env var)\n// const footerData = schema.name(\"footer\").fetchAll();\n//\n// // Option 2: Configure with custom CMS URL and fetch options\n// const customSchema = configureSchema({\n// cmsUrl: \"https://my-cms.example.com/api\",\n// fetchOptions: { headers: { Authorization: \"Bearer token\" } },\n// });\n// const footerData = customSchema.name(\"footer\").fetchAll();\n//\n// console.log(footerData); # [{ logo: \"<cloudflare_signed_img_url>\", \"Footer_text\": \"Profound\" }]\n\nimport type { CmsConfig } from './cms-api';\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\ninterface SchemaConfigOptions extends Partial<CmsConfig> {\n fetchOptions?: RequestInit;\n}\n\ninterface SchemaQuery {\n fetchAll: <T = Record<string, unknown>>() => Promise<T[]>;\n fetchSingle: <T = Record<string, unknown>>() => Promise<T | null>;\n fetchSingleById: <T = Record<string, unknown>>(id: string) => Promise<T | null>;\n}\n\ninterface SchemaClient {\n name: (schemaName: string) => SchemaQuery;\n}\n\nfunction createSchemaQuery(\n cmsUrl: string,\n schemaName: string,\n fetchOptions: RequestInit = {},\n websiteId?: string,\n _apiKey?: string\n): SchemaQuery {\n const baseUrl = new URL(`/api/schemas/${schemaName}`, `${cmsUrl}`);\n if (websiteId) {\n baseUrl.searchParams.set('websiteId', websiteId);\n }\n\n const baseUrlString = baseUrl.toString();\n\n return {\n async fetchAll<T = Record<string, unknown>>(): Promise<T[]> {\n const response = await fetch(baseUrlString, fetchOptions);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch schema \"${schemaName}\": ${response.statusText}`);\n }\n\n return response.json();\n },\n\n async fetchSingle<T = Record<string, unknown>>(): Promise<T | null> {\n const url = new URL(baseUrlString);\n url.searchParams.set('limit', '1');\n const response = await fetch(url.toString(), fetchOptions);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch schema \"${schemaName}\": ${response.statusText}`);\n }\n\n const data = await response.json();\n return Array.isArray(data) ? (data[0] ?? null) : data;\n },\n\n async fetchSingleById<T = Record<string, unknown>>(id: string): Promise<T | null> {\n const url = new URL(baseUrlString);\n url.searchParams.set('id', id);\n const response = await fetch(url.toString(), fetchOptions);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch schema \"${schemaName}\" by id \"${id}\": ${response.statusText}`\n );\n }\n\n const data = await response.json();\n return Array.isArray(data) ? (data[0] ?? null) : data;\n },\n };\n}\n\nexport function configureSchema(config: SchemaConfigOptions = {}): SchemaClient {\n const cmsUrl = config.cmsUrl ?? requireEnv('NEXT_PUBLIC_CMS_API_URL');\n const fetchOptions = applyApiKey(config.fetchOptions || {}, config.apiKey);\n const websiteId = config.websiteId;\n\n return {\n name: (schemaName: string): SchemaQuery =>\n createSchemaQuery(cmsUrl, schemaName, fetchOptions, websiteId, config.apiKey),\n };\n}\n\nexport const schema: SchemaClient = configureSchema();\n\nfunction applyApiKey(fetchOptions: RequestInit, apiKey?: string): RequestInit {\n if (!apiKey) {\n return fetchOptions;\n }\n\n const headers = new Headers(fetchOptions.headers);\n if (!headers.has('x-api-key')) {\n headers.set('x-api-key', apiKey);\n }\n\n return {\n ...fetchOptions,\n headers,\n };\n}\n"],"mappings":";AAmBA,SAAS,WAAW,MAAsB;AACxC,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0CAA0C,IAAI,EAAE;AAAA,EAClE;AACA,SAAO;AACT;AAgBA,SAAS,kBACP,QACA,YACA,eAA4B,CAAC,GAC7B,WACA,SACa;AACb,QAAM,UAAU,IAAI,IAAI,gBAAgB,UAAU,IAAI,GAAG,MAAM,EAAE;AACjE,MAAI,WAAW;AACb,YAAQ,aAAa,IAAI,aAAa,SAAS;AAAA,EACjD;AAEA,QAAM,gBAAgB,QAAQ,SAAS;AAEvC,SAAO;AAAA,IACL,MAAM,WAAsD;AAC1D,YAAM,WAAW,MAAM,MAAM,eAAe,YAAY;AAExD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,2BAA2B,UAAU,MAAM,SAAS,UAAU,EAAE;AAAA,MAClF;AAEA,aAAO,SAAS,KAAK;AAAA,IACvB;AAAA,IAEA,MAAM,cAA8D;AAClE,YAAM,MAAM,IAAI,IAAI,aAAa;AACjC,UAAI,aAAa,IAAI,SAAS,GAAG;AACjC,YAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG,YAAY;AAEzD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,2BAA2B,UAAU,MAAM,SAAS,UAAU,EAAE;AAAA,MAClF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,MAAM,QAAQ,IAAI,IAAK,KAAK,CAAC,KAAK,OAAQ;AAAA,IACnD;AAAA,IAEA,MAAM,gBAA6C,IAA+B;AAChF,YAAM,MAAM,IAAI,IAAI,aAAa;AACjC,UAAI,aAAa,IAAI,MAAM,EAAE;AAC7B,YAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG,YAAY;AAEzD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI;AAAA,UACR,2BAA2B,UAAU,YAAY,EAAE,MAAM,SAAS,UAAU;AAAA,QAC9E;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,MAAM,QAAQ,IAAI,IAAK,KAAK,CAAC,KAAK,OAAQ;AAAA,IACnD;AAAA,EACF;AACF;AAEO,SAAS,gBAAgB,SAA8B,CAAC,GAAiB;AAC9E,QAAM,SAAS,OAAO,UAAU,WAAW,yBAAyB;AACpE,QAAM,eAAe,YAAY,OAAO,gBAAgB,CAAC,GAAG,OAAO,MAAM;AACzE,QAAM,YAAY,OAAO;AAEzB,SAAO;AAAA,IACL,MAAM,CAAC,eACL,kBAAkB,QAAQ,YAAY,cAAc,WAAW,OAAO,MAAM;AAAA,EAChF;AACF;AAEO,IAAM,SAAuB,gBAAgB;AAEpD,SAAS,YAAY,cAA2B,QAA8B;AAC5E,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,IAAI,QAAQ,aAAa,OAAO;AAChD,MAAI,CAAC,QAAQ,IAAI,WAAW,GAAG;AAC7B,YAAQ,IAAI,aAAa,MAAM;AAAA,EACjC;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cms-renderer",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {