cms-renderer 0.3.7 → 0.4.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/lib/block-renderer.d.ts +8 -1
- package/dist/lib/block-renderer.js +35 -4
- package/dist/lib/block-renderer.js.map +1 -1
- package/dist/lib/custom-schemas.d.ts +4 -19
- package/dist/lib/custom-schemas.js +189 -206
- package/dist/lib/custom-schemas.js.map +1 -1
- package/dist/lib/markdown-utils.d.ts +10 -9
- package/dist/lib/markdown-utils.js +1 -1
- package/dist/lib/markdown-utils.js.map +1 -1
- package/dist/lib/proxy.js +16 -10
- package/dist/lib/proxy.js.map +1 -1
- package/dist/lib/renderer.js +41 -6
- package/dist/lib/renderer.js.map +1 -1
- package/package.json +7 -4
|
@@ -24,17 +24,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
mod
|
|
25
25
|
));
|
|
26
26
|
|
|
27
|
-
// ../../node_modules/ret/dist/types/tokens.js
|
|
27
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/tokens.js
|
|
28
28
|
var require_tokens = __commonJS({
|
|
29
|
-
"../../node_modules/ret/dist/types/tokens.js"(exports) {
|
|
29
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/tokens.js"(exports) {
|
|
30
30
|
"use strict";
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
// ../../node_modules/ret/dist/types/types.js
|
|
35
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/types.js
|
|
36
36
|
var require_types = __commonJS({
|
|
37
|
-
"../../node_modules/ret/dist/types/types.js"(exports) {
|
|
37
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/types.js"(exports) {
|
|
38
38
|
"use strict";
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
exports.types = void 0;
|
|
@@ -52,17 +52,17 @@ var require_types = __commonJS({
|
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
// ../../node_modules/ret/dist/types/set-lookup.js
|
|
55
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/set-lookup.js
|
|
56
56
|
var require_set_lookup = __commonJS({
|
|
57
|
-
"../../node_modules/ret/dist/types/set-lookup.js"(exports) {
|
|
57
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/set-lookup.js"(exports) {
|
|
58
58
|
"use strict";
|
|
59
59
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
// ../../node_modules/ret/dist/types/index.js
|
|
63
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/index.js
|
|
64
64
|
var require_types2 = __commonJS({
|
|
65
|
-
"../../node_modules/ret/dist/types/index.js"(exports) {
|
|
65
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/types/index.js"(exports) {
|
|
66
66
|
"use strict";
|
|
67
67
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
68
68
|
if (k2 === void 0) k2 = k;
|
|
@@ -83,9 +83,9 @@ var require_types2 = __commonJS({
|
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
// ../../node_modules/ret/dist/sets.js
|
|
86
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/sets.js
|
|
87
87
|
var require_sets = __commonJS({
|
|
88
|
-
"../../node_modules/ret/dist/sets.js"(exports) {
|
|
88
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/sets.js"(exports) {
|
|
89
89
|
"use strict";
|
|
90
90
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
91
91
|
exports.anyChar = exports.notWhitespace = exports.whitespace = exports.notInts = exports.ints = exports.notWords = exports.words = void 0;
|
|
@@ -130,9 +130,9 @@ var require_sets = __commonJS({
|
|
|
130
130
|
}
|
|
131
131
|
});
|
|
132
132
|
|
|
133
|
-
// ../../node_modules/ret/dist/util.js
|
|
133
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/util.js
|
|
134
134
|
var require_util = __commonJS({
|
|
135
|
-
"../../node_modules/ret/dist/util.js"(exports) {
|
|
135
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/util.js"(exports) {
|
|
136
136
|
"use strict";
|
|
137
137
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
138
138
|
if (k2 === void 0) k2 = k;
|
|
@@ -201,9 +201,9 @@ var require_util = __commonJS({
|
|
|
201
201
|
}
|
|
202
202
|
});
|
|
203
203
|
|
|
204
|
-
// ../../node_modules/ret/dist/tokenizer.js
|
|
204
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/tokenizer.js
|
|
205
205
|
var require_tokenizer = __commonJS({
|
|
206
|
-
"../../node_modules/ret/dist/tokenizer.js"(exports) {
|
|
206
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/tokenizer.js"(exports) {
|
|
207
207
|
"use strict";
|
|
208
208
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
209
209
|
if (k2 === void 0) k2 = k;
|
|
@@ -502,9 +502,9 @@ var require_tokenizer = __commonJS({
|
|
|
502
502
|
}
|
|
503
503
|
});
|
|
504
504
|
|
|
505
|
-
// ../../node_modules/ret/dist/sets-lookup.js
|
|
505
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/sets-lookup.js
|
|
506
506
|
var require_sets_lookup = __commonJS({
|
|
507
|
-
"../../node_modules/ret/dist/sets-lookup.js"(exports) {
|
|
507
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/sets-lookup.js"(exports) {
|
|
508
508
|
"use strict";
|
|
509
509
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
510
510
|
if (k2 === void 0) k2 = k;
|
|
@@ -557,9 +557,9 @@ var require_sets_lookup = __commonJS({
|
|
|
557
557
|
}
|
|
558
558
|
});
|
|
559
559
|
|
|
560
|
-
// ../../node_modules/ret/dist/write-set-tokens.js
|
|
560
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/write-set-tokens.js
|
|
561
561
|
var require_write_set_tokens = __commonJS({
|
|
562
|
-
"../../node_modules/ret/dist/write-set-tokens.js"(exports) {
|
|
562
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/write-set-tokens.js"(exports) {
|
|
563
563
|
"use strict";
|
|
564
564
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
565
565
|
if (k2 === void 0) k2 = k;
|
|
@@ -643,9 +643,9 @@ var require_write_set_tokens = __commonJS({
|
|
|
643
643
|
}
|
|
644
644
|
});
|
|
645
645
|
|
|
646
|
-
// ../../node_modules/ret/dist/reconstruct.js
|
|
646
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/reconstruct.js
|
|
647
647
|
var require_reconstruct = __commonJS({
|
|
648
|
-
"../../node_modules/ret/dist/reconstruct.js"(exports) {
|
|
648
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/reconstruct.js"(exports) {
|
|
649
649
|
"use strict";
|
|
650
650
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
651
651
|
exports.reconstruct = void 0;
|
|
@@ -710,9 +710,9 @@ var require_reconstruct = __commonJS({
|
|
|
710
710
|
}
|
|
711
711
|
});
|
|
712
712
|
|
|
713
|
-
// ../../node_modules/ret/dist/index.js
|
|
713
|
+
// ../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/index.js
|
|
714
714
|
var require_dist = __commonJS({
|
|
715
|
-
"../../node_modules/ret/dist/index.js"(exports, module) {
|
|
715
|
+
"../../node_modules/.bun/ret@0.5.0/node_modules/ret/dist/index.js"(exports, module) {
|
|
716
716
|
"use strict";
|
|
717
717
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
718
718
|
if (k2 === void 0) k2 = k;
|
|
@@ -744,9 +744,9 @@ var require_dist = __commonJS({
|
|
|
744
744
|
}
|
|
745
745
|
});
|
|
746
746
|
|
|
747
|
-
// ../../node_modules/safe-regex2/index.js
|
|
747
|
+
// ../../node_modules/.bun/safe-regex2@5.0.0/node_modules/safe-regex2/index.js
|
|
748
748
|
var require_safe_regex2 = __commonJS({
|
|
749
|
-
"../../node_modules/safe-regex2/index.js"(exports, module) {
|
|
749
|
+
"../../node_modules/.bun/safe-regex2@5.0.0/node_modules/safe-regex2/index.js"(exports, module) {
|
|
750
750
|
"use strict";
|
|
751
751
|
var parse = require_dist();
|
|
752
752
|
var types = parse.types;
|
|
@@ -799,173 +799,6 @@ var require_safe_regex2 = __commonJS({
|
|
|
799
799
|
import { mkdir, writeFile } from "fs/promises";
|
|
800
800
|
import { dirname } from "path";
|
|
801
801
|
|
|
802
|
-
// ../../packages/cms-schema/src/documents/generate-zod-code.ts
|
|
803
|
-
function generateZodSchemaCode(schemaName, fields) {
|
|
804
|
-
const lines = [];
|
|
805
|
-
lines.push(`import { z } from 'zod';`);
|
|
806
|
-
lines.push("");
|
|
807
|
-
const hasImageField = fields.some((f) => f.type === "image");
|
|
808
|
-
if (hasImageField) {
|
|
809
|
-
appendImageReferenceSchema(lines);
|
|
810
|
-
lines.push("");
|
|
811
|
-
}
|
|
812
|
-
appendSchemaBody(lines, schemaName, fields);
|
|
813
|
-
return lines.join("\n");
|
|
814
|
-
}
|
|
815
|
-
function generateCombinedZodSchemaCode(schemas) {
|
|
816
|
-
const lines = [];
|
|
817
|
-
lines.push("/* eslint-disable */");
|
|
818
|
-
lines.push("/* prettier-ignore */");
|
|
819
|
-
lines.push("/* biome-ignore format: auto-generated */");
|
|
820
|
-
lines.push("// This file is auto-generated by cms-renderer. Do not edit manually.");
|
|
821
|
-
lines.push("");
|
|
822
|
-
lines.push(`import { z } from 'zod';`);
|
|
823
|
-
lines.push("");
|
|
824
|
-
const hasImageField = schemas.some((s) => s.fields.some((f) => f.type === "image"));
|
|
825
|
-
if (hasImageField) {
|
|
826
|
-
appendImageReferenceSchema(lines);
|
|
827
|
-
lines.push("");
|
|
828
|
-
}
|
|
829
|
-
for (const [i, schema] of schemas.entries()) {
|
|
830
|
-
if (i > 0) lines.push("");
|
|
831
|
-
appendSchemaBody(lines, schema.name, schema.fields);
|
|
832
|
-
}
|
|
833
|
-
return lines.join("\n");
|
|
834
|
-
}
|
|
835
|
-
function appendSchemaBody(lines, schemaName, fields) {
|
|
836
|
-
const varName = `${toCamelCase(schemaName)}Schema`;
|
|
837
|
-
lines.push(`export const ${varName} = z.object({`);
|
|
838
|
-
for (const field of fields) {
|
|
839
|
-
const fieldCode = generateFieldCode(field);
|
|
840
|
-
if (field.description) {
|
|
841
|
-
lines.push(` /** ${field.description} */`);
|
|
842
|
-
}
|
|
843
|
-
lines.push(` ${field.name}: ${fieldCode},`);
|
|
844
|
-
}
|
|
845
|
-
lines.push("});");
|
|
846
|
-
lines.push("");
|
|
847
|
-
lines.push(`export type ${toPascalCase(schemaName)} = z.infer<typeof ${varName}>;`);
|
|
848
|
-
lines.push("");
|
|
849
|
-
}
|
|
850
|
-
function appendImageReferenceSchema(lines) {
|
|
851
|
-
lines.push("const ImageReferenceSchema = z.object({");
|
|
852
|
-
lines.push(" alt: z.string().min(1, 'Alt text is required for accessibility'),");
|
|
853
|
-
lines.push(" caption: z.string().max(500).optional(),");
|
|
854
|
-
lines.push(" attribution: z.string().max(255).optional(),");
|
|
855
|
-
lines.push(" _asset: z.object({");
|
|
856
|
-
lines.push(" id: z.string().uuid(),");
|
|
857
|
-
lines.push(" }),");
|
|
858
|
-
lines.push("});");
|
|
859
|
-
}
|
|
860
|
-
function generateFieldCode(field) {
|
|
861
|
-
let code = generateBaseTypeCode(field.type, field.constraints);
|
|
862
|
-
if (!field.required) {
|
|
863
|
-
code += ".optional()";
|
|
864
|
-
}
|
|
865
|
-
return code;
|
|
866
|
-
}
|
|
867
|
-
function generateBaseTypeCode(type, constraints) {
|
|
868
|
-
switch (type) {
|
|
869
|
-
case "string":
|
|
870
|
-
return applyStringConstraintCode("z.string()", constraints);
|
|
871
|
-
case "number":
|
|
872
|
-
return applyNumberConstraintCode("z.number()", constraints);
|
|
873
|
-
case "boolean":
|
|
874
|
-
return "z.boolean()";
|
|
875
|
-
case "image":
|
|
876
|
-
return "ImageReferenceSchema";
|
|
877
|
-
case "date":
|
|
878
|
-
return "z.string().date('Invalid date format. Expected YYYY-MM-DD')";
|
|
879
|
-
case "datetime":
|
|
880
|
-
return "z.string().datetime({ offset: true, message: 'Invalid datetime format. Expected ISO 8601' })";
|
|
881
|
-
case "url":
|
|
882
|
-
return applyStringConstraintCode("z.string().url('Invalid URL format')", constraints);
|
|
883
|
-
case "email":
|
|
884
|
-
return applyStringConstraintCode("z.string().email('Invalid email format')", constraints);
|
|
885
|
-
case "enum": {
|
|
886
|
-
const values = constraints?.enumValues;
|
|
887
|
-
if (!values || values.length === 0) {
|
|
888
|
-
return "z.enum([''])";
|
|
889
|
-
}
|
|
890
|
-
const formatted = values.map((v) => `'${escapeString(v)}'`).join(", ");
|
|
891
|
-
return `z.enum([${formatted}])`;
|
|
892
|
-
}
|
|
893
|
-
case "reference":
|
|
894
|
-
return "z.record(z.string(), z.unknown())";
|
|
895
|
-
case "array": {
|
|
896
|
-
const itemType = constraints?.arrayItemType ?? "string";
|
|
897
|
-
const itemCode = generatePrimitiveCode(itemType);
|
|
898
|
-
return applyArrayConstraintCode(`z.array(${itemCode})`, constraints);
|
|
899
|
-
}
|
|
900
|
-
default:
|
|
901
|
-
return "z.unknown()";
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
function generatePrimitiveCode(type) {
|
|
905
|
-
switch (type) {
|
|
906
|
-
case "string":
|
|
907
|
-
return "z.string()";
|
|
908
|
-
case "number":
|
|
909
|
-
return "z.number()";
|
|
910
|
-
case "boolean":
|
|
911
|
-
return "z.boolean()";
|
|
912
|
-
default:
|
|
913
|
-
return "z.unknown()";
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
function applyStringConstraintCode(base, constraints) {
|
|
917
|
-
if (!constraints) return base;
|
|
918
|
-
let code = base;
|
|
919
|
-
if (constraints.minLength !== void 0) {
|
|
920
|
-
code += `.min(${constraints.minLength}, 'Must be at least ${constraints.minLength} characters')`;
|
|
921
|
-
}
|
|
922
|
-
if (constraints.maxLength !== void 0) {
|
|
923
|
-
code += `.max(${constraints.maxLength}, 'Must be at most ${constraints.maxLength} characters')`;
|
|
924
|
-
}
|
|
925
|
-
if (constraints.pattern) {
|
|
926
|
-
code += `.regex(/${escapeRegex(constraints.pattern)}/, 'Invalid format')`;
|
|
927
|
-
}
|
|
928
|
-
return code;
|
|
929
|
-
}
|
|
930
|
-
function applyNumberConstraintCode(base, constraints) {
|
|
931
|
-
if (!constraints) return base;
|
|
932
|
-
let code = base;
|
|
933
|
-
if (constraints.integer) {
|
|
934
|
-
code += `.int('Must be an integer')`;
|
|
935
|
-
}
|
|
936
|
-
if (constraints.min !== void 0) {
|
|
937
|
-
code += `.min(${constraints.min}, 'Must be at least ${constraints.min}')`;
|
|
938
|
-
}
|
|
939
|
-
if (constraints.max !== void 0) {
|
|
940
|
-
code += `.max(${constraints.max}, 'Must be at most ${constraints.max}')`;
|
|
941
|
-
}
|
|
942
|
-
return code;
|
|
943
|
-
}
|
|
944
|
-
function applyArrayConstraintCode(base, constraints) {
|
|
945
|
-
if (!constraints) return base;
|
|
946
|
-
let code = base;
|
|
947
|
-
if (constraints.minItems !== void 0) {
|
|
948
|
-
code += `.min(${constraints.minItems}, 'Must have at least ${constraints.minItems} items')`;
|
|
949
|
-
}
|
|
950
|
-
if (constraints.maxItems !== void 0) {
|
|
951
|
-
code += `.max(${constraints.maxItems}, 'Must have at most ${constraints.maxItems} items')`;
|
|
952
|
-
}
|
|
953
|
-
return code;
|
|
954
|
-
}
|
|
955
|
-
function escapeString(str) {
|
|
956
|
-
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
957
|
-
}
|
|
958
|
-
function escapeRegex(pattern) {
|
|
959
|
-
return pattern.replace(/\//g, "\\/");
|
|
960
|
-
}
|
|
961
|
-
function toCamelCase(str) {
|
|
962
|
-
return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
963
|
-
}
|
|
964
|
-
function toPascalCase(str) {
|
|
965
|
-
const camel = toCamelCase(str);
|
|
966
|
-
return camel.charAt(0).toUpperCase() + camel.slice(1);
|
|
967
|
-
}
|
|
968
|
-
|
|
969
802
|
// ../../packages/cms-schema/src/documents/registry.ts
|
|
970
803
|
import { z } from "zod";
|
|
971
804
|
var schemaNameValidator = z.string().min(1, "Schema name must be a non-empty string").refine((name) => name.trim().length > 0, "Schema name must not be only whitespace");
|
|
@@ -1168,7 +1001,7 @@ function createBaseSchema(type, constraints) {
|
|
|
1168
1001
|
return z6.record(z6.string(), z6.unknown());
|
|
1169
1002
|
case "array": {
|
|
1170
1003
|
const itemType = constraints?.arrayItemType ?? "string";
|
|
1171
|
-
const itemSchema = createPrimitiveSchema(itemType);
|
|
1004
|
+
const itemSchema = itemType === "reference" ? z6.record(z6.string(), z6.unknown()) : createPrimitiveSchema(itemType);
|
|
1172
1005
|
return applyArrayConstraints(z6.array(itemSchema), constraints);
|
|
1173
1006
|
}
|
|
1174
1007
|
default:
|
|
@@ -1183,6 +1016,8 @@ function createPrimitiveSchema(type) {
|
|
|
1183
1016
|
return z6.number();
|
|
1184
1017
|
case "boolean":
|
|
1185
1018
|
return z6.boolean();
|
|
1019
|
+
default:
|
|
1020
|
+
throw new Error(`Unsupported array item type: ${type}`);
|
|
1186
1021
|
}
|
|
1187
1022
|
}
|
|
1188
1023
|
function applyStringConstraints(schema, constraints) {
|
|
@@ -1281,6 +1116,51 @@ import hash from "object-hash";
|
|
|
1281
1116
|
// ../../packages/cms-schema/src/documents/validations/country.ts
|
|
1282
1117
|
import { TRPCError } from "@trpc/server";
|
|
1283
1118
|
|
|
1119
|
+
// ../../packages/cms-schema/src/documents/parse-field-definitions-json.ts
|
|
1120
|
+
import { z as z8 } from "zod";
|
|
1121
|
+
var SNAKE_CASE = /^[a-z][a-z0-9_]*$/;
|
|
1122
|
+
var fieldConstraintsSchema = z8.object({
|
|
1123
|
+
minLength: z8.number().int().min(0).optional(),
|
|
1124
|
+
maxLength: z8.number().int().min(0).optional(),
|
|
1125
|
+
pattern: z8.string().max(500).optional(),
|
|
1126
|
+
min: z8.number().optional(),
|
|
1127
|
+
max: z8.number().optional(),
|
|
1128
|
+
integer: z8.boolean().optional(),
|
|
1129
|
+
enumValues: z8.array(z8.string()).optional(),
|
|
1130
|
+
arrayItemType: z8.enum(["string", "number", "boolean", "reference"]).optional(),
|
|
1131
|
+
minItems: z8.number().int().min(0).optional(),
|
|
1132
|
+
maxItems: z8.number().int().min(0).optional(),
|
|
1133
|
+
refSchema: z8.string().regex(SNAKE_CASE, "refSchema must be snake_case").optional()
|
|
1134
|
+
});
|
|
1135
|
+
var fieldDefinitionSchema = z8.object({
|
|
1136
|
+
name: z8.string().regex(SNAKE_CASE, "must be snake_case (lowercase letters, digits, underscores only)"),
|
|
1137
|
+
type: z8.enum([
|
|
1138
|
+
"string",
|
|
1139
|
+
"number",
|
|
1140
|
+
"boolean",
|
|
1141
|
+
"date",
|
|
1142
|
+
"datetime",
|
|
1143
|
+
"url",
|
|
1144
|
+
"email",
|
|
1145
|
+
"enum",
|
|
1146
|
+
"reference",
|
|
1147
|
+
"array",
|
|
1148
|
+
"image"
|
|
1149
|
+
]),
|
|
1150
|
+
displayName: z8.string().optional(),
|
|
1151
|
+
description: z8.string().optional(),
|
|
1152
|
+
required: z8.boolean(),
|
|
1153
|
+
constraints: fieldConstraintsSchema.optional()
|
|
1154
|
+
});
|
|
1155
|
+
var fieldArraySchema = z8.array(fieldDefinitionSchema).min(1, "Schema must have at least one field");
|
|
1156
|
+
var multiSchemaFieldDefSchema = z8.record(
|
|
1157
|
+
z8.string().regex(SNAKE_CASE, "schema name must be snake_case"),
|
|
1158
|
+
fieldArraySchema
|
|
1159
|
+
);
|
|
1160
|
+
|
|
1161
|
+
// lib/custom-schemas.ts
|
|
1162
|
+
import escapeStringRegexp from "escape-string-regexp";
|
|
1163
|
+
|
|
1284
1164
|
// lib/cms-api.ts
|
|
1285
1165
|
import { createTRPCClient, httpBatchLink } from "@trpc/client";
|
|
1286
1166
|
import superjson from "superjson";
|
|
@@ -1326,7 +1206,7 @@ async function fetchAllCustomSchemaFields(options) {
|
|
|
1326
1206
|
const client = getCmsClient(options);
|
|
1327
1207
|
const summaries = await client.customSchema.list.query({
|
|
1328
1208
|
websiteId,
|
|
1329
|
-
|
|
1209
|
+
includePresets: false
|
|
1330
1210
|
});
|
|
1331
1211
|
const schemas = await Promise.all(
|
|
1332
1212
|
summaries.map(async (summary) => {
|
|
@@ -1369,24 +1249,127 @@ function buildZodSchemas(schemas) {
|
|
|
1369
1249
|
}
|
|
1370
1250
|
return result;
|
|
1371
1251
|
}
|
|
1372
|
-
function
|
|
1373
|
-
const
|
|
1374
|
-
|
|
1375
|
-
|
|
1252
|
+
async function saveZodSchemaCode(schemas, outputPath) {
|
|
1253
|
+
const code = generateCombinedZodSchemaCode(
|
|
1254
|
+
schemas.map((s) => ({ name: s.name, fields: s.fields }))
|
|
1255
|
+
);
|
|
1256
|
+
await mkdir(dirname(outputPath), { recursive: true });
|
|
1257
|
+
await writeFile(outputPath, code, "utf-8");
|
|
1258
|
+
}
|
|
1259
|
+
function generateCombinedZodSchemaCode(schemas) {
|
|
1260
|
+
const lines = [];
|
|
1261
|
+
lines.push("/* eslint-disable */");
|
|
1262
|
+
lines.push("/* prettier-ignore */");
|
|
1263
|
+
lines.push("/* biome-ignore format: auto-generated */");
|
|
1264
|
+
lines.push("// This file is auto-generated by cms-renderer. Do not edit manually.");
|
|
1265
|
+
lines.push("");
|
|
1266
|
+
lines.push(`import { z } from 'zod';`);
|
|
1267
|
+
lines.push("");
|
|
1268
|
+
const hasImageField = schemas.some((s) => s.fields.some((f) => f.type === "image"));
|
|
1269
|
+
if (hasImageField) {
|
|
1270
|
+
lines.push("const ImageReferenceSchema = z.object({");
|
|
1271
|
+
lines.push(" alt: z.string().min(1, 'Alt text is required for accessibility'),");
|
|
1272
|
+
lines.push(" caption: z.string().max(500).optional(),");
|
|
1273
|
+
lines.push(" attribution: z.string().max(255).optional(),");
|
|
1274
|
+
lines.push(" _asset: z.object({");
|
|
1275
|
+
lines.push(" id: z.string().uuid(),");
|
|
1276
|
+
lines.push(" }),");
|
|
1277
|
+
lines.push("});");
|
|
1278
|
+
lines.push("");
|
|
1376
1279
|
}
|
|
1377
|
-
|
|
1280
|
+
for (const [i, schema] of schemas.entries()) {
|
|
1281
|
+
if (i > 0) lines.push("");
|
|
1282
|
+
const varName = `${toCamelCase(schema.name)}Schema`;
|
|
1283
|
+
lines.push(`export const ${varName} = z.object({`);
|
|
1284
|
+
for (const field of schema.fields) {
|
|
1285
|
+
if (field.description) lines.push(` /** ${field.description} */`);
|
|
1286
|
+
lines.push(` ${field.name}: ${generateFieldCode(field)},`);
|
|
1287
|
+
}
|
|
1288
|
+
lines.push("});");
|
|
1289
|
+
lines.push("");
|
|
1290
|
+
lines.push(`export type ${toPascalCase(schema.name)} = z.infer<typeof ${varName}>;`);
|
|
1291
|
+
lines.push("");
|
|
1292
|
+
}
|
|
1293
|
+
return lines.join("\n");
|
|
1378
1294
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1295
|
+
function generateFieldCode(field) {
|
|
1296
|
+
let code = generateBaseTypeCode(field.type, field.constraints);
|
|
1297
|
+
if (!field.required) code += ".optional()";
|
|
1298
|
+
return code;
|
|
1299
|
+
}
|
|
1300
|
+
function generateBaseTypeCode(type, constraints) {
|
|
1301
|
+
switch (type) {
|
|
1302
|
+
case "string":
|
|
1303
|
+
return applyStringConstraintCode("z.string()", constraints);
|
|
1304
|
+
case "number":
|
|
1305
|
+
return applyNumberConstraintCode("z.number()", constraints);
|
|
1306
|
+
case "boolean":
|
|
1307
|
+
return "z.boolean()";
|
|
1308
|
+
case "image":
|
|
1309
|
+
return "ImageReferenceSchema";
|
|
1310
|
+
case "date":
|
|
1311
|
+
return "z.string().date('Invalid date format. Expected YYYY-MM-DD')";
|
|
1312
|
+
case "datetime":
|
|
1313
|
+
return "z.string().datetime({ offset: true, message: 'Invalid datetime format. Expected ISO 8601' })";
|
|
1314
|
+
case "url":
|
|
1315
|
+
return applyStringConstraintCode("z.string().url('Invalid URL format')", constraints);
|
|
1316
|
+
case "email":
|
|
1317
|
+
return applyStringConstraintCode("z.string().email('Invalid email format')", constraints);
|
|
1318
|
+
case "enum": {
|
|
1319
|
+
const values = constraints?.enumValues;
|
|
1320
|
+
if (!values || values.length === 0) return "z.enum([''])";
|
|
1321
|
+
const formatted = values.map((v) => `'${v.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`).join(", ");
|
|
1322
|
+
return `z.enum([${formatted}])`;
|
|
1323
|
+
}
|
|
1324
|
+
case "reference":
|
|
1325
|
+
return "z.record(z.string(), z.unknown())";
|
|
1326
|
+
case "array": {
|
|
1327
|
+
const itemType = constraints?.arrayItemType ?? "string";
|
|
1328
|
+
const itemCode = itemType === "number" ? "z.number()" : itemType === "boolean" ? "z.boolean()" : itemType === "reference" ? "z.record(z.string(), z.unknown())" : "z.string()";
|
|
1329
|
+
return applyArrayConstraintCode(`z.array(${itemCode})`, constraints);
|
|
1330
|
+
}
|
|
1331
|
+
default:
|
|
1332
|
+
return "z.unknown()";
|
|
1383
1333
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1334
|
+
}
|
|
1335
|
+
function applyStringConstraintCode(base, constraints) {
|
|
1336
|
+
if (!constraints) return base;
|
|
1337
|
+
let code = base;
|
|
1338
|
+
if (constraints.minLength !== void 0)
|
|
1339
|
+
code += `.min(${constraints.minLength}, 'Must be at least ${constraints.minLength} characters')`;
|
|
1340
|
+
if (constraints.maxLength !== void 0)
|
|
1341
|
+
code += `.max(${constraints.maxLength}, 'Must be at most ${constraints.maxLength} characters')`;
|
|
1342
|
+
if (constraints.pattern)
|
|
1343
|
+
code += `.regex(/${escapeStringRegexp(constraints.pattern)}/, 'Invalid format')`;
|
|
1344
|
+
return code;
|
|
1345
|
+
}
|
|
1346
|
+
function applyNumberConstraintCode(base, constraints) {
|
|
1347
|
+
if (!constraints) return base;
|
|
1348
|
+
let code = base;
|
|
1349
|
+
if (constraints.integer) code += `.int('Must be an integer')`;
|
|
1350
|
+
if (constraints.min !== void 0)
|
|
1351
|
+
code += `.min(${constraints.min}, 'Must be at least ${constraints.min}')`;
|
|
1352
|
+
if (constraints.max !== void 0)
|
|
1353
|
+
code += `.max(${constraints.max}, 'Must be at most ${constraints.max}')`;
|
|
1354
|
+
return code;
|
|
1355
|
+
}
|
|
1356
|
+
function applyArrayConstraintCode(base, constraints) {
|
|
1357
|
+
if (!constraints) return base;
|
|
1358
|
+
let code = base;
|
|
1359
|
+
if (constraints.minItems !== void 0)
|
|
1360
|
+
code += `.min(${constraints.minItems}, 'Must have at least ${constraints.minItems} items')`;
|
|
1361
|
+
if (constraints.maxItems !== void 0)
|
|
1362
|
+
code += `.max(${constraints.maxItems}, 'Must have at most ${constraints.maxItems} items')`;
|
|
1363
|
+
return code;
|
|
1364
|
+
}
|
|
1365
|
+
function toCamelCase(str) {
|
|
1366
|
+
return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
1367
|
+
}
|
|
1368
|
+
function toPascalCase(str) {
|
|
1369
|
+
const camel = toCamelCase(str);
|
|
1370
|
+
return camel.charAt(0).toUpperCase() + camel.slice(1);
|
|
1387
1371
|
}
|
|
1388
1372
|
export {
|
|
1389
|
-
buildZodSchemaCode,
|
|
1390
1373
|
buildZodSchemas,
|
|
1391
1374
|
fetchAllCustomSchemaFields,
|
|
1392
1375
|
fetchCustomSchemaFields,
|