cms-renderer 0.0.0 → 0.1.0
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/dist/chunk-G22U6UHQ.js +45 -0
- package/dist/chunk-G22U6UHQ.js.map +1 -0
- package/dist/chunk-HVKFEZBT.js +116 -0
- package/dist/chunk-HVKFEZBT.js.map +1 -0
- package/dist/chunk-RPM73PQZ.js +17 -0
- package/dist/chunk-RPM73PQZ.js.map +1 -0
- package/dist/lib/block-renderer.d.ts +32 -0
- package/dist/lib/block-renderer.js +7 -0
- package/dist/lib/block-renderer.js.map +1 -0
- package/dist/lib/cms-api.d.ts +24 -0
- package/dist/lib/cms-api.js +7 -0
- package/dist/lib/cms-api.js.map +1 -0
- package/dist/lib/data-utils.d.ts +218 -0
- package/dist/lib/data-utils.js +247 -0
- package/dist/lib/data-utils.js.map +1 -0
- package/dist/lib/image/lazy-load.d.ts +75 -0
- package/dist/lib/image/lazy-load.js +83 -0
- package/dist/lib/image/lazy-load.js.map +1 -0
- package/dist/lib/markdown-utils.d.ts +172 -0
- package/dist/lib/markdown-utils.js +137 -0
- package/dist/lib/markdown-utils.js.map +1 -0
- package/dist/lib/renderer.d.ts +36 -0
- package/dist/lib/renderer.js +343 -0
- package/dist/lib/renderer.js.map +1 -0
- package/{lib/result.ts → dist/lib/result.d.ts} +32 -146
- package/dist/lib/result.js +37 -0
- package/dist/lib/result.js.map +1 -0
- package/dist/lib/schema.d.ts +15 -0
- package/dist/lib/schema.js +35 -0
- package/dist/lib/schema.js.map +1 -0
- package/{lib/trpc.ts → dist/lib/trpc.d.ts} +6 -4
- package/dist/lib/trpc.js +7 -0
- package/dist/lib/trpc.js.map +1 -0
- package/dist/lib/types.d.ts +163 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +50 -11
- package/.turbo/turbo-check-types.log +0 -2
- package/lib/__tests__/enrich-block-images.test.ts +0 -394
- package/lib/block-renderer.tsx +0 -60
- package/lib/cms-api.ts +0 -86
- package/lib/data-utils.ts +0 -572
- package/lib/image/lazy-load.ts +0 -209
- package/lib/markdown-utils.ts +0 -368
- package/lib/renderer.tsx +0 -189
- package/lib/schema.ts +0 -74
- package/lib/types.ts +0 -201
- package/next.config.ts +0 -39
- package/postcss.config.mjs +0 -5
- package/tsconfig.json +0 -12
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -19,11 +19,6 @@
|
|
|
19
19
|
* return { data };
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
|
|
23
|
-
// -----------------------------------------------------------------------------
|
|
24
|
-
// Result Type
|
|
25
|
-
// -----------------------------------------------------------------------------
|
|
26
|
-
|
|
27
22
|
/**
|
|
28
23
|
* A discriminated union representing either success or failure.
|
|
29
24
|
*
|
|
@@ -45,12 +40,13 @@
|
|
|
45
40
|
* }
|
|
46
41
|
* ```
|
|
47
42
|
*/
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
type Result<T, E = Error> = {
|
|
44
|
+
ok: true;
|
|
45
|
+
value: T;
|
|
46
|
+
} | {
|
|
47
|
+
ok: false;
|
|
48
|
+
error: E;
|
|
49
|
+
};
|
|
54
50
|
/**
|
|
55
51
|
* Creates a success Result.
|
|
56
52
|
*
|
|
@@ -63,10 +59,7 @@ export type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error:
|
|
|
63
59
|
* // { ok: true, value: 42 }
|
|
64
60
|
* ```
|
|
65
61
|
*/
|
|
66
|
-
|
|
67
|
-
return { ok: true, value };
|
|
68
|
-
}
|
|
69
|
-
|
|
62
|
+
declare function ok<T>(value: T): Result<T, never>;
|
|
70
63
|
/**
|
|
71
64
|
* Creates a failure Result.
|
|
72
65
|
*
|
|
@@ -79,14 +72,7 @@ export function ok<T>(value: T): Result<T, never> {
|
|
|
79
72
|
* // { ok: false, error: Error('Something went wrong') }
|
|
80
73
|
* ```
|
|
81
74
|
*/
|
|
82
|
-
|
|
83
|
-
return { ok: false, error };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// -----------------------------------------------------------------------------
|
|
87
|
-
// Type Guards
|
|
88
|
-
// -----------------------------------------------------------------------------
|
|
89
|
-
|
|
75
|
+
declare function err<E>(error: E): Result<never, E>;
|
|
90
76
|
/**
|
|
91
77
|
* Type guard to check if a Result is successful.
|
|
92
78
|
*
|
|
@@ -102,10 +88,10 @@ export function err<E>(error: E): Result<never, E> {
|
|
|
102
88
|
* }
|
|
103
89
|
* ```
|
|
104
90
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
91
|
+
declare function isOk<T, E>(result: Result<T, E>): result is {
|
|
92
|
+
ok: true;
|
|
93
|
+
value: T;
|
|
94
|
+
};
|
|
109
95
|
/**
|
|
110
96
|
* Type guard to check if a Result is a failure.
|
|
111
97
|
*
|
|
@@ -121,14 +107,10 @@ export function isOk<T, E>(result: Result<T, E>): result is { ok: true; value: T
|
|
|
121
107
|
* }
|
|
122
108
|
* ```
|
|
123
109
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// -----------------------------------------------------------------------------
|
|
129
|
-
// Extractors
|
|
130
|
-
// -----------------------------------------------------------------------------
|
|
131
|
-
|
|
110
|
+
declare function isErr<T, E>(result: Result<T, E>): result is {
|
|
111
|
+
ok: false;
|
|
112
|
+
error: E;
|
|
113
|
+
};
|
|
132
114
|
/**
|
|
133
115
|
* Extracts the value from a Result, throwing if it's an error.
|
|
134
116
|
*
|
|
@@ -145,13 +127,7 @@ export function isErr<T, E>(result: Result<T, E>): result is { ok: false; error:
|
|
|
145
127
|
* const value2 = unwrap(errorResult); // throws Error('fail')
|
|
146
128
|
* ```
|
|
147
129
|
*/
|
|
148
|
-
|
|
149
|
-
if (isOk(result)) {
|
|
150
|
-
return result.value;
|
|
151
|
-
}
|
|
152
|
-
throw result.error;
|
|
153
|
-
}
|
|
154
|
-
|
|
130
|
+
declare function unwrap<T, E>(result: Result<T, E>): T;
|
|
155
131
|
/**
|
|
156
132
|
* Extracts the value from a Result, returning a default on error.
|
|
157
133
|
*
|
|
@@ -168,13 +144,7 @@ export function unwrap<T, E>(result: Result<T, E>): T {
|
|
|
168
144
|
* const value2 = unwrapOr(okResult, 0); // 42
|
|
169
145
|
* ```
|
|
170
146
|
*/
|
|
171
|
-
|
|
172
|
-
if (isOk(result)) {
|
|
173
|
-
return result.value;
|
|
174
|
-
}
|
|
175
|
-
return defaultValue;
|
|
176
|
-
}
|
|
177
|
-
|
|
147
|
+
declare function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T;
|
|
178
148
|
/**
|
|
179
149
|
* Extracts the value from a Result, computing a default on error.
|
|
180
150
|
*
|
|
@@ -191,17 +161,7 @@ export function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {
|
|
|
191
161
|
* });
|
|
192
162
|
* ```
|
|
193
163
|
*/
|
|
194
|
-
|
|
195
|
-
if (isOk(result)) {
|
|
196
|
-
return result.value;
|
|
197
|
-
}
|
|
198
|
-
return fn(result.error);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// -----------------------------------------------------------------------------
|
|
202
|
-
// Transformers
|
|
203
|
-
// -----------------------------------------------------------------------------
|
|
204
|
-
|
|
164
|
+
declare function unwrapOrElse<T, E>(result: Result<T, E>, fn: (error: E) => T): T;
|
|
205
165
|
/**
|
|
206
166
|
* Maps a successful Result's value.
|
|
207
167
|
*
|
|
@@ -218,13 +178,7 @@ export function unwrapOrElse<T, E>(result: Result<T, E>, fn: (error: E) => T): T
|
|
|
218
178
|
* const still = map(errorResult, (n) => n * 2); // err('fail')
|
|
219
179
|
* ```
|
|
220
180
|
*/
|
|
221
|
-
|
|
222
|
-
if (isOk(result)) {
|
|
223
|
-
return ok(fn(result.value));
|
|
224
|
-
}
|
|
225
|
-
return result;
|
|
226
|
-
}
|
|
227
|
-
|
|
181
|
+
declare function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
|
|
228
182
|
/**
|
|
229
183
|
* Maps a failed Result's error.
|
|
230
184
|
*
|
|
@@ -238,13 +192,7 @@ export function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<
|
|
|
238
192
|
* const mapped = mapErr(result, (e) => new Error(e)); // err(Error('not found'))
|
|
239
193
|
* ```
|
|
240
194
|
*/
|
|
241
|
-
|
|
242
|
-
if (isErr(result)) {
|
|
243
|
-
return err(fn(result.error));
|
|
244
|
-
}
|
|
245
|
-
return result;
|
|
246
|
-
}
|
|
247
|
-
|
|
195
|
+
declare function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
|
|
248
196
|
/**
|
|
249
197
|
* Chains Result-returning operations.
|
|
250
198
|
*
|
|
@@ -267,20 +215,7 @@ export function mapErr<T, E, F>(result: Result<T, E>, fn: (error: E) => F): Resu
|
|
|
267
215
|
* const fail = flatMap(parse('abc'), double); // err('not a number')
|
|
268
216
|
* ```
|
|
269
217
|
*/
|
|
270
|
-
|
|
271
|
-
result: Result<T, E>,
|
|
272
|
-
fn: (value: T) => Result<U, E>
|
|
273
|
-
): Result<U, E> {
|
|
274
|
-
if (isOk(result)) {
|
|
275
|
-
return fn(result.value);
|
|
276
|
-
}
|
|
277
|
-
return result;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// -----------------------------------------------------------------------------
|
|
281
|
-
// Async Helpers
|
|
282
|
-
// -----------------------------------------------------------------------------
|
|
283
|
-
|
|
218
|
+
declare function flatMap<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E>;
|
|
284
219
|
/**
|
|
285
220
|
* Wraps a Promise in a Result type.
|
|
286
221
|
*
|
|
@@ -297,15 +232,7 @@ export function flatMap<T, U, E>(
|
|
|
297
232
|
* const response = result.value;
|
|
298
233
|
* ```
|
|
299
234
|
*/
|
|
300
|
-
|
|
301
|
-
try {
|
|
302
|
-
const value = await promise;
|
|
303
|
-
return ok(value);
|
|
304
|
-
} catch (error) {
|
|
305
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
235
|
+
declare function fromPromise<T>(promise: Promise<T>): Promise<Result<T, Error>>;
|
|
309
236
|
/**
|
|
310
237
|
* Wraps a throwing function in a Result type.
|
|
311
238
|
*
|
|
@@ -322,14 +249,7 @@ export async function fromPromise<T>(promise: Promise<T>): Promise<Result<T, Err
|
|
|
322
249
|
* return result.value;
|
|
323
250
|
* ```
|
|
324
251
|
*/
|
|
325
|
-
|
|
326
|
-
try {
|
|
327
|
-
return ok(fn());
|
|
328
|
-
} catch (error) {
|
|
329
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
252
|
+
declare function tryCatch<T>(fn: () => T): Result<T, Error>;
|
|
333
253
|
/**
|
|
334
254
|
* Wraps an async function in a Result type.
|
|
335
255
|
*
|
|
@@ -345,19 +265,7 @@ export function tryCatch<T>(fn: () => T): Result<T, Error> {
|
|
|
345
265
|
* });
|
|
346
266
|
* ```
|
|
347
267
|
*/
|
|
348
|
-
|
|
349
|
-
try {
|
|
350
|
-
const value = await fn();
|
|
351
|
-
return ok(value);
|
|
352
|
-
} catch (error) {
|
|
353
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// -----------------------------------------------------------------------------
|
|
358
|
-
// Tuple Helpers (Go-style)
|
|
359
|
-
// -----------------------------------------------------------------------------
|
|
360
|
-
|
|
268
|
+
declare function tryCatchAsync<T>(fn: () => Promise<T>): Promise<Result<T, Error>>;
|
|
361
269
|
/**
|
|
362
270
|
* Go-style tuple for error handling: [error, value]
|
|
363
271
|
*
|
|
@@ -371,8 +279,7 @@ export async function tryCatchAsync<T>(fn: () => Promise<T>): Promise<Result<T,
|
|
|
371
279
|
* console.log(data);
|
|
372
280
|
* ```
|
|
373
281
|
*/
|
|
374
|
-
|
|
375
|
-
|
|
282
|
+
type GoTuple<T, E = Error> = [E, undefined] | [undefined, T];
|
|
376
283
|
/**
|
|
377
284
|
* Converts a Result to a Go-style tuple.
|
|
378
285
|
*
|
|
@@ -385,13 +292,7 @@ export type GoTuple<T, E = Error> = [E, undefined] | [undefined, T];
|
|
|
385
292
|
* const [err, data] = toTuple(result);
|
|
386
293
|
* ```
|
|
387
294
|
*/
|
|
388
|
-
|
|
389
|
-
if (isOk(result)) {
|
|
390
|
-
return [undefined, result.value];
|
|
391
|
-
}
|
|
392
|
-
return [result.error, undefined];
|
|
393
|
-
}
|
|
394
|
-
|
|
295
|
+
declare function toTuple<T, E>(result: Result<T, E>): GoTuple<T, E>;
|
|
395
296
|
/**
|
|
396
297
|
* Wraps an async function and returns a Go-style tuple.
|
|
397
298
|
*
|
|
@@ -413,16 +314,7 @@ export function toTuple<T, E>(result: Result<T, E>): GoTuple<T, E> {
|
|
|
413
314
|
* return data;
|
|
414
315
|
* ```
|
|
415
316
|
*/
|
|
416
|
-
|
|
417
|
-
try {
|
|
418
|
-
const value = await fn();
|
|
419
|
-
return [undefined, value];
|
|
420
|
-
} catch (error) {
|
|
421
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
422
|
-
return [err, undefined];
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
317
|
+
declare function handle<T>(fn: () => Promise<T>): Promise<GoTuple<T, Error>>;
|
|
426
318
|
/**
|
|
427
319
|
* Wraps a synchronous function and returns a Go-style tuple.
|
|
428
320
|
*
|
|
@@ -439,12 +331,6 @@ export async function handle<T>(fn: () => Promise<T>): Promise<GoTuple<T, Error>
|
|
|
439
331
|
* return parsed;
|
|
440
332
|
* ```
|
|
441
333
|
*/
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
return [undefined, value];
|
|
446
|
-
} catch (error) {
|
|
447
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
448
|
-
return [err, undefined];
|
|
449
|
-
}
|
|
450
|
-
}
|
|
334
|
+
declare function handleSync<T>(fn: () => T): GoTuple<T, Error>;
|
|
335
|
+
|
|
336
|
+
export { type GoTuple, type Result, err, flatMap, fromPromise, handle, handleSync, isErr, isOk, map, mapErr, ok, toTuple, tryCatch, tryCatchAsync, unwrap, unwrapOr, unwrapOrElse };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
err,
|
|
3
|
+
flatMap,
|
|
4
|
+
fromPromise,
|
|
5
|
+
handle,
|
|
6
|
+
handleSync,
|
|
7
|
+
isErr,
|
|
8
|
+
isOk,
|
|
9
|
+
map,
|
|
10
|
+
mapErr,
|
|
11
|
+
ok,
|
|
12
|
+
toTuple,
|
|
13
|
+
tryCatch,
|
|
14
|
+
tryCatchAsync,
|
|
15
|
+
unwrap,
|
|
16
|
+
unwrapOr,
|
|
17
|
+
unwrapOrElse
|
|
18
|
+
} from "../chunk-HVKFEZBT.js";
|
|
19
|
+
export {
|
|
20
|
+
err,
|
|
21
|
+
flatMap,
|
|
22
|
+
fromPromise,
|
|
23
|
+
handle,
|
|
24
|
+
handleSync,
|
|
25
|
+
isErr,
|
|
26
|
+
isOk,
|
|
27
|
+
map,
|
|
28
|
+
mapErr,
|
|
29
|
+
ok,
|
|
30
|
+
toTuple,
|
|
31
|
+
tryCatch,
|
|
32
|
+
tryCatchAsync,
|
|
33
|
+
unwrap,
|
|
34
|
+
unwrapOr,
|
|
35
|
+
unwrapOrElse
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface SchemaConfig {
|
|
2
|
+
apiBase?: string;
|
|
3
|
+
fetchOptions?: RequestInit;
|
|
4
|
+
}
|
|
5
|
+
interface SchemaQuery {
|
|
6
|
+
fetchAll: <T = Record<string, unknown>>() => Promise<T[]>;
|
|
7
|
+
fetchSingle: <T = Record<string, unknown>>() => Promise<T | null>;
|
|
8
|
+
}
|
|
9
|
+
interface SchemaClient {
|
|
10
|
+
name: (schemaName: string) => SchemaQuery;
|
|
11
|
+
}
|
|
12
|
+
declare function configureSchema(config?: SchemaConfig): SchemaClient;
|
|
13
|
+
declare const schema: SchemaClient;
|
|
14
|
+
|
|
15
|
+
export { configureSchema, schema };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// lib/schema.ts
|
|
2
|
+
var DEFAULT_API_BASE = process.env.NEXT_PUBLIC_CMS_API_URL ?? "http://localhost:4000/api";
|
|
3
|
+
function createSchemaQuery(apiBase, schemaName, fetchOptions = {}) {
|
|
4
|
+
const baseUrl = `${apiBase}/schemas/${schemaName}`;
|
|
5
|
+
return {
|
|
6
|
+
async fetchAll() {
|
|
7
|
+
const response = await fetch(baseUrl, fetchOptions);
|
|
8
|
+
if (!response.ok) {
|
|
9
|
+
throw new Error(`Failed to fetch schema "${schemaName}": ${response.statusText}`);
|
|
10
|
+
}
|
|
11
|
+
return response.json();
|
|
12
|
+
},
|
|
13
|
+
async fetchSingle() {
|
|
14
|
+
const response = await fetch(`${baseUrl}?limit=1`, fetchOptions);
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
throw new Error(`Failed to fetch schema "${schemaName}": ${response.statusText}`);
|
|
17
|
+
}
|
|
18
|
+
const data = await response.json();
|
|
19
|
+
return Array.isArray(data) ? data[0] ?? null : data;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function configureSchema(config = {}) {
|
|
24
|
+
const apiBase = config.apiBase || DEFAULT_API_BASE;
|
|
25
|
+
const fetchOptions = config.fetchOptions || {};
|
|
26
|
+
return {
|
|
27
|
+
name: (schemaName) => createSchemaQuery(apiBase, schemaName, fetchOptions)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
var schema = configureSchema();
|
|
31
|
+
export {
|
|
32
|
+
configureSchema,
|
|
33
|
+
schema
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +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 API base and fetch options\n// const customSchema = configureSchema({\n// apiBase: \"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\nconst DEFAULT_API_BASE = process.env.NEXT_PUBLIC_CMS_API_URL ?? 'http://localhost:4000/api';\n\ninterface SchemaConfig {\n apiBase?: string;\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 apiBase: string,\n schemaName: string,\n fetchOptions: RequestInit = {}\n): SchemaQuery {\n const baseUrl = `${apiBase}/schemas/${schemaName}`;\n\n return {\n async fetchAll<T = Record<string, unknown>>(): Promise<T[]> {\n const response = await fetch(baseUrl, 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 response = await fetch(`${baseUrl}?limit=1`, 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: SchemaConfig = {}): SchemaClient {\n const apiBase = config.apiBase || DEFAULT_API_BASE;\n const fetchOptions = config.fetchOptions || {};\n\n return {\n name: (schemaName: string): SchemaQuery => createSchemaQuery(apiBase, schemaName, fetchOptions),\n };\n}\n\nexport const schema: SchemaClient = configureSchema();\n"],"mappings":";AAiBA,IAAM,mBAAmB,QAAQ,IAAI,2BAA2B;AAgBhE,SAAS,kBACP,SACA,YACA,eAA4B,CAAC,GAChB;AACb,QAAM,UAAU,GAAG,OAAO,YAAY,UAAU;AAEhD,SAAO;AAAA,IACL,MAAM,WAAsD;AAC1D,YAAM,WAAW,MAAM,MAAM,SAAS,YAAY;AAElD,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,WAAW,MAAM,MAAM,GAAG,OAAO,YAAY,YAAY;AAE/D,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,SAAuB,CAAC,GAAiB;AACvE,QAAM,UAAU,OAAO,WAAW;AAClC,QAAM,eAAe,OAAO,gBAAgB,CAAC;AAE7C,SAAO;AAAA,IACL,MAAM,CAAC,eAAoC,kBAAkB,SAAS,YAAY,YAAY;AAAA,EAChG;AACF;AAEO,IAAM,SAAuB,gBAAgB;","names":[]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { AppRouter } from '@repo/cms-schema/trpc';
|
|
2
|
+
import { CreateTRPCReact } from '@trpc/react-query';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* tRPC Client Setup
|
|
3
6
|
*
|
|
@@ -5,9 +8,6 @@
|
|
|
5
8
|
* Uses tRPC v11 patterns with TanStack Query v5.
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
|
-
import type { AppRouter } from '@repo/cms-schema/trpc';
|
|
9
|
-
import { type CreateTRPCReact, createTRPCReact } from '@trpc/react-query';
|
|
10
|
-
|
|
11
11
|
/**
|
|
12
12
|
* tRPC React client.
|
|
13
13
|
*
|
|
@@ -25,4 +25,6 @@ import { type CreateTRPCReact, createTRPCReact } from '@trpc/react-query';
|
|
|
25
25
|
* }
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
declare const trpc: CreateTRPCReact<AppRouter, unknown>;
|
|
29
|
+
|
|
30
|
+
export { trpc };
|
package/dist/lib/trpc.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../lib/trpc.ts"],"sourcesContent":["/**\n * tRPC Client Setup\n *\n * Creates the tRPC React hooks for client components.\n * Uses tRPC v11 patterns with TanStack Query v5.\n */\n\nimport type { AppRouter } from '@repo/cms-schema/trpc';\nimport { type CreateTRPCReact, createTRPCReact } from '@trpc/react-query';\n\n/**\n * tRPC React client.\n *\n * Use this in client components to call tRPC procedures.\n *\n * @example\n * ```tsx\n * 'use client';\n * import { trpc } from '@/lib/trpc';\n *\n * function NavigationClient() {\n * const { data, isLoading } = trpc.blocks.getNavigation.useQuery();\n * if (isLoading) return <div>Loading...</div>;\n * return <nav>{data?.links.map(link => ...)}</nav>;\n * }\n * ```\n */\nexport const trpc: CreateTRPCReact<AppRouter, unknown> = createTRPCReact<AppRouter>();\n"],"mappings":";AAQA,SAA+B,uBAAuB;AAmB/C,IAAM,OAA4C,gBAA2B;","names":[]}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import * as _repo_cms_schema_blocks from '@repo/cms-schema/blocks';
|
|
2
|
+
import { ComponentType } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Valid block type strings.
|
|
6
|
+
* Must match the schema_name field in block data from the tRPC API.
|
|
7
|
+
*/
|
|
8
|
+
type BlockType = 'navigation' | 'header' | 'article' | 'hero-block' | 'features-block' | 'cta-block' | 'logo-trust-block';
|
|
9
|
+
/**
|
|
10
|
+
* Navigation link button structure.
|
|
11
|
+
*/
|
|
12
|
+
interface NavigationButton {
|
|
13
|
+
label: string;
|
|
14
|
+
href: string;
|
|
15
|
+
ariaLabel: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Navigation link with type and button.
|
|
19
|
+
*/
|
|
20
|
+
interface NavigationLink {
|
|
21
|
+
button: NavigationButton;
|
|
22
|
+
type: 'Default' | 'Flyout';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Level 3 navigation item (leaf node).
|
|
26
|
+
*/
|
|
27
|
+
interface Level3Link {
|
|
28
|
+
link: NavigationLink;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Level 2 navigation item with optional Level 3 children.
|
|
32
|
+
*/
|
|
33
|
+
interface Level2Link {
|
|
34
|
+
link: NavigationLink;
|
|
35
|
+
children?: Level3Link[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Level 1 navigation item with optional Level 2 children.
|
|
39
|
+
*/
|
|
40
|
+
interface Level1Link {
|
|
41
|
+
link: NavigationLink;
|
|
42
|
+
children?: Level2Link[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Navigation block content.
|
|
46
|
+
*/
|
|
47
|
+
interface NavigationContent {
|
|
48
|
+
logo?: {
|
|
49
|
+
url: string;
|
|
50
|
+
alt: string;
|
|
51
|
+
};
|
|
52
|
+
ariaLabel: string;
|
|
53
|
+
links: Level1Link[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Header block content.
|
|
57
|
+
*/
|
|
58
|
+
interface HeaderContent {
|
|
59
|
+
headline: string;
|
|
60
|
+
subheadline?: string;
|
|
61
|
+
backgroundImage?: {
|
|
62
|
+
url: string;
|
|
63
|
+
alt: string;
|
|
64
|
+
};
|
|
65
|
+
ctaButton?: {
|
|
66
|
+
label: string;
|
|
67
|
+
href: string;
|
|
68
|
+
};
|
|
69
|
+
alignment: 'left' | 'center' | 'right';
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Article block content.
|
|
73
|
+
*/
|
|
74
|
+
interface ArticleContent {
|
|
75
|
+
headline: string;
|
|
76
|
+
author?: string;
|
|
77
|
+
publishedAt?: string;
|
|
78
|
+
body: string;
|
|
79
|
+
tags?: readonly string[] | string[];
|
|
80
|
+
status?: string;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Hero block content (from CMS schema).
|
|
84
|
+
*/
|
|
85
|
+
type HeroBlockContent = _repo_cms_schema_blocks.HeroBlockContent;
|
|
86
|
+
/**
|
|
87
|
+
* Features block content (from CMS schema).
|
|
88
|
+
*/
|
|
89
|
+
type FeaturesBlockContent = _repo_cms_schema_blocks.FeaturesBlockContent;
|
|
90
|
+
/**
|
|
91
|
+
* CTA block content (from CMS schema).
|
|
92
|
+
*/
|
|
93
|
+
type CTABlockContent = _repo_cms_schema_blocks.CTABlockContent;
|
|
94
|
+
/**
|
|
95
|
+
* Logo Trust block content (from CMS schema).
|
|
96
|
+
*/
|
|
97
|
+
type LogoTrustBlockContent = _repo_cms_schema_blocks.LogoTrustBlockContent;
|
|
98
|
+
/**
|
|
99
|
+
* Discriminated union of all block types.
|
|
100
|
+
* Use the `type` field to narrow to specific content types.
|
|
101
|
+
*
|
|
102
|
+
* Each block also carries its stable CMS `id`, which should be used as the
|
|
103
|
+
* React `key` when rendering lists of blocks.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```tsx
|
|
107
|
+
* function renderBlock(block: BlockData) {
|
|
108
|
+
* if (block.type === 'header') {
|
|
109
|
+
* // TypeScript knows block.content is HeaderContent
|
|
110
|
+
* return <h1>{block.content.headline}</h1>;
|
|
111
|
+
* }
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
type BlockData = {
|
|
116
|
+
id: string;
|
|
117
|
+
type: 'navigation';
|
|
118
|
+
content: NavigationContent;
|
|
119
|
+
} | {
|
|
120
|
+
id: string;
|
|
121
|
+
type: 'header';
|
|
122
|
+
content: HeaderContent;
|
|
123
|
+
} | {
|
|
124
|
+
id: string;
|
|
125
|
+
type: 'article';
|
|
126
|
+
content: ArticleContent;
|
|
127
|
+
} | {
|
|
128
|
+
id: string;
|
|
129
|
+
type: 'hero-block';
|
|
130
|
+
content: HeroBlockContent;
|
|
131
|
+
} | {
|
|
132
|
+
id: string;
|
|
133
|
+
type: 'features-block';
|
|
134
|
+
content: FeaturesBlockContent;
|
|
135
|
+
} | {
|
|
136
|
+
id: string;
|
|
137
|
+
type: 'cta-block';
|
|
138
|
+
content: CTABlockContent;
|
|
139
|
+
} | {
|
|
140
|
+
id: string;
|
|
141
|
+
type: 'logo-trust-block';
|
|
142
|
+
content: LogoTrustBlockContent;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Props for a block component.
|
|
146
|
+
* Each block component receives its typed content.
|
|
147
|
+
*/
|
|
148
|
+
interface BlockComponentProps<T> {
|
|
149
|
+
content: T;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* A React component that renders a specific block type.
|
|
153
|
+
*/
|
|
154
|
+
type BlockComponent<T> = ComponentType<BlockComponentProps<T>>;
|
|
155
|
+
/**
|
|
156
|
+
* Registry of block type to component mappings.
|
|
157
|
+
* This is the core of the ComponentMap pattern.
|
|
158
|
+
*/
|
|
159
|
+
type BlockComponentRegistry = {
|
|
160
|
+
[K in BlockType]: BlockComponent<K extends 'navigation' ? NavigationContent : K extends 'header' ? HeaderContent : K extends 'article' ? ArticleContent : K extends 'hero-block' ? HeroBlockContent : K extends 'features-block' ? FeaturesBlockContent : K extends 'cta-block' ? CTABlockContent : K extends 'logo-trust-block' ? LogoTrustBlockContent : never>;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export type { ArticleContent, BlockComponent, BlockComponentProps, BlockComponentRegistry, BlockData, BlockType, CTABlockContent, FeaturesBlockContent, HeaderContent, HeroBlockContent, Level1Link, Level2Link, Level3Link, LogoTrustBlockContent, NavigationButton, NavigationContent, NavigationLink };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|