@voltro/cms 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.
@@ -0,0 +1,278 @@
1
+ import { Schema as e } from "effect";
2
+ import { createElement as t } from "react";
3
+ //#region src/fieldSchema.ts
4
+ var n = (e) => ({
5
+ ...e,
6
+ pipe(...t) {
7
+ let r = e;
8
+ for (let e of t) r = e(r);
9
+ return n(r);
10
+ },
11
+ optional() {
12
+ return n({
13
+ ...e,
14
+ isOptional: !0
15
+ });
16
+ }
17
+ }), r = (e) => (t) => ({
18
+ ...t,
19
+ maxLength: e,
20
+ editorHint: t.kind === "string" && e > 120 ? "textarea" : t.editorHint
21
+ }), i = (e) => (t) => ({
22
+ ...t,
23
+ pattern: e.source
24
+ }), a = () => (e) => ({
25
+ ...e,
26
+ unique: !0
27
+ }), o = (e, t) => n({
28
+ kind: e,
29
+ editorHint: t,
30
+ isOptional: !1
31
+ }), s = {
32
+ String: o("string", "text"),
33
+ Number: o("number", "number"),
34
+ Boolean: o("boolean", "boolean"),
35
+ Date: o("date", "date"),
36
+ DateTime: o("datetime", "datetime"),
37
+ maxLength: r,
38
+ pattern: i,
39
+ unique: a,
40
+ Literal: (...e) => n({
41
+ kind: "literal",
42
+ editorHint: "select",
43
+ isOptional: !1,
44
+ literals: e
45
+ }),
46
+ RichText: (e = {}) => n({
47
+ kind: "richText",
48
+ editorHint: "richText",
49
+ isOptional: !1,
50
+ richText: e
51
+ }),
52
+ Media: () => n({
53
+ kind: "media",
54
+ editorHint: "media",
55
+ isOptional: !1
56
+ }),
57
+ Reference: (e) => n({
58
+ kind: "reference",
59
+ editorHint: "reference",
60
+ isOptional: !1,
61
+ referenceType: e
62
+ }),
63
+ Array: (e) => n({
64
+ kind: "array",
65
+ editorHint: "array",
66
+ isOptional: !1,
67
+ element: e
68
+ }),
69
+ Struct: (e) => n({
70
+ kind: "struct",
71
+ editorHint: "struct",
72
+ isOptional: !1,
73
+ struct: e
74
+ })
75
+ }, c = (e, t) => (n) => ({
76
+ ...n,
77
+ derived: {
78
+ source: e,
79
+ transform: t
80
+ }
81
+ }), l = (e) => String(e).toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""), u = e.Struct({
82
+ field: e.String,
83
+ rule: e.String,
84
+ message: e.String
85
+ }), d = class extends e.TaggedError()("ContentValidationFailed", {
86
+ contentType: e.String,
87
+ violations: e.Array(u)
88
+ }) {}, f = class extends e.TaggedError()("ContentNotFound", {
89
+ contentType: e.String,
90
+ id: e.String,
91
+ stage: e.Literal("draft", "published")
92
+ }) {}, p = class extends e.TaggedError()("ContentIdConflict", {
93
+ contentType: e.String,
94
+ id: e.String
95
+ }) {}, m = /* @__PURE__ */ new Set([
96
+ "status",
97
+ "publishAt",
98
+ "tenantId",
99
+ "createdAt",
100
+ "updatedAt",
101
+ "createdBy",
102
+ "updatedBy"
103
+ ]), h = (e, t, n) => ({
104
+ field: e,
105
+ rule: t,
106
+ message: n
107
+ }), g = (e) => typeof e == "object" && !!e && !Array.isArray(e), _ = (e) => e instanceof Date ? !Number.isNaN(e.getTime()) : typeof e == "string" && !Number.isNaN(new Date(e).getTime()), v = /* @__PURE__ */ new Set(["image", "img"]), y = /* @__PURE__ */ new Set(["embed", "iframe"]), b = (e, t, n) => {
108
+ if (typeof e != "object" || !e || n.has(e)) return null;
109
+ if (n.add(e), Array.isArray(e)) {
110
+ for (let r of e) {
111
+ let e = b(r, t, n);
112
+ if (e !== null) return e;
113
+ }
114
+ return null;
115
+ }
116
+ let r = e, i = r.type;
117
+ if (typeof i == "string" && t.has(i)) return i;
118
+ for (let e of Object.values(r)) {
119
+ let r = b(e, t, n);
120
+ if (r !== null) return r;
121
+ }
122
+ return null;
123
+ }, x = (e, t, n) => {
124
+ let r = [], i = t.richText ?? {}, a = /* @__PURE__ */ new Set();
125
+ if (i.allowImages === !1) for (let e of v) a.add(e);
126
+ if (i.allowEmbeds === !1) for (let e of y) a.add(e);
127
+ if (a.size === 0) return r;
128
+ if (typeof n == "string") {
129
+ let t = n.toLowerCase();
130
+ return i.allowImages === !1 && t.includes("<img") && r.push(h(e, "richText", "images are not allowed in this field (allowImages: false)")), i.allowEmbeds === !1 && (t.includes("<iframe") || t.includes("<embed")) && r.push(h(e, "richText", "embeds are not allowed in this field (allowEmbeds: false)")), r;
131
+ }
132
+ let o = b(n, a, /* @__PURE__ */ new WeakSet());
133
+ if (o !== null) {
134
+ let t = v.has(o) ? "images are not allowed in this field (allowImages: false)" : "embeds are not allowed in this field (allowEmbeds: false)";
135
+ r.push(h(e, "richText", `${t} — found a '${o}' node`));
136
+ }
137
+ return r;
138
+ }, S = (e, t, n) => {
139
+ let r = [];
140
+ return t.maxLength !== void 0 && n.length > t.maxLength && r.push(h(e, "maxLength", `exceeds maxLength(${t.maxLength}) — got ${n.length} characters`)), t.pattern !== void 0 && !new RegExp(t.pattern).test(n) && r.push(h(e, "pattern", `does not match pattern /${t.pattern}/`)), r;
141
+ }, C = (e, t, n) => {
142
+ switch (t.kind) {
143
+ case "string":
144
+ case "media":
145
+ case "reference": return typeof n == "string" ? S(e, t, n) : [h(e, "type", `expected a string, got ${typeof n}`)];
146
+ case "number": return typeof n != "number" || !Number.isFinite(n) ? [h(e, "type", "expected a finite number")] : [];
147
+ case "boolean": return typeof n == "boolean" ? [] : [h(e, "type", `expected a boolean, got ${typeof n}`)];
148
+ case "date":
149
+ case "datetime": return _(n) ? [] : [h(e, "type", "expected a Date or a parseable date string")];
150
+ case "literal": {
151
+ let r = t.literals ?? [];
152
+ return typeof n != "string" || !r.includes(n) ? [h(e, "literal", `expected one of: ${r.join(", ")}`)] : [];
153
+ }
154
+ case "richText": {
155
+ if (typeof n != "string" && !g(n) && !Array.isArray(n)) return [h(e, "type", "expected a rich-text document (object) or string")];
156
+ let r = x(e, t, n);
157
+ return typeof n == "string" && r.push(...S(e, t, n)), r;
158
+ }
159
+ case "array": {
160
+ if (!Array.isArray(n)) return [h(e, "type", "expected an array")];
161
+ let r = t.element;
162
+ if (r === void 0) return [];
163
+ let i = [];
164
+ return n.forEach((t, n) => i.push(...C(`${e}[${n}]`, r, t))), i;
165
+ }
166
+ case "struct": {
167
+ if (!g(n)) return [h(e, "type", "expected an object")];
168
+ let r = t.struct ?? {}, i = [];
169
+ for (let [t, a] of Object.entries(r)) {
170
+ let r = n[t];
171
+ if (r == null) {
172
+ a.isOptional || i.push(h(`${e}.${t}`, "required", "missing required field"));
173
+ continue;
174
+ }
175
+ i.push(...C(`${e}.${t}`, a, r));
176
+ }
177
+ for (let t of Object.keys(n)) t in r || i.push(h(`${e}.${t}`, "unknown", "not a declared field of this struct"));
178
+ return i;
179
+ }
180
+ }
181
+ }, w = (e, t) => {
182
+ let n = [];
183
+ for (let [r, i] of Object.entries(e.fields)) {
184
+ let e = t[r];
185
+ if (e == null) {
186
+ i.isOptional || n.push(h(r, "required", "missing required field"));
187
+ continue;
188
+ }
189
+ n.push(...C(r, i, e));
190
+ }
191
+ let r = t.id;
192
+ r !== void 0 && typeof r != "string" && n.push(h("id", "type", "expected a string id"));
193
+ for (let r of Object.keys(t)) r === "id" || r in e.fields || m.has(r) || n.push(h(r, "unknown", `'${r}' is not a declared field of '${e.name}'`));
194
+ return n;
195
+ }, T = (e, t) => {
196
+ let n = w(e, t);
197
+ if (n.length > 0) throw new d({
198
+ contentType: e.name,
199
+ violations: n
200
+ });
201
+ }, E = (e, t) => {
202
+ let n = { ...t };
203
+ for (let t of e.derivedFields) {
204
+ let r = e.fields[t]?.derived;
205
+ r !== void 0 && (n[t] = r.transform(n[r.source], n));
206
+ }
207
+ return n;
208
+ }, D = ({ name: e, field: n, value: r, onChange: i }) => t("input", {
209
+ type: "text",
210
+ name: e,
211
+ ...n.maxLength === void 0 ? {} : { maxLength: n.maxLength },
212
+ value: r == null ? "" : String(r),
213
+ onChange: (e) => i(e.target.value)
214
+ }), O = ({ name: e, field: n, value: r, onChange: i }) => t("textarea", {
215
+ name: e,
216
+ ...n.maxLength === void 0 ? {} : { maxLength: n.maxLength },
217
+ value: r == null ? "" : String(r),
218
+ onChange: (e) => i(e.target.value)
219
+ }), k = ({ name: e, value: n, onChange: r }) => t("input", {
220
+ type: "number",
221
+ name: e,
222
+ value: n == null ? "" : String(n),
223
+ onChange: (e) => r(e.target.value === "" ? null : Number(e.target.value))
224
+ }), A = ({ name: e, value: n, onChange: r }) => t("input", {
225
+ type: "checkbox",
226
+ name: e,
227
+ checked: n === !0,
228
+ onChange: (e) => r(e.target.checked)
229
+ }), j = (e) => ({ name: n, value: r, onChange: i }) => t("input", {
230
+ type: e,
231
+ name: n,
232
+ value: r == null ? "" : String(r),
233
+ onChange: (e) => i(e.target.value)
234
+ }), M = ({ name: e, field: n, value: r, onChange: i }) => t("select", {
235
+ name: e,
236
+ value: r == null ? "" : String(r),
237
+ onChange: (e) => i(e.target.value)
238
+ }, (n.literals ?? []).map((e) => t("option", {
239
+ key: e,
240
+ value: e
241
+ }, e))), N = (e) => ({ name: n, value: r, onChange: i }) => t("textarea", {
242
+ name: n,
243
+ "data-cms-widget": e,
244
+ value: r == null ? "" : typeof r == "string" ? r : JSON.stringify(r),
245
+ onChange: (e) => i(e.target.value)
246
+ }), P = {
247
+ text: D,
248
+ textarea: O,
249
+ number: k,
250
+ boolean: A,
251
+ date: j("date"),
252
+ datetime: j("datetime-local"),
253
+ select: M,
254
+ richText: N("richText"),
255
+ media: N("media"),
256
+ reference: N("reference"),
257
+ array: N("array"),
258
+ struct: N("struct")
259
+ }, F = (e, t) => t?.[e] ?? P[e], I = (e) => {
260
+ let { contentType: n, value: r, onChange: i, widgets: a } = e;
261
+ return t("div", { "data-cms-form": !0 }, ...Object.entries(n.fields).map(([e, n]) => {
262
+ let o = F(n.editorHint, a);
263
+ return t("div", {
264
+ key: e,
265
+ "data-cms-field": e
266
+ }, t("label", { htmlFor: e }, e), o({
267
+ name: e,
268
+ field: n,
269
+ value: r[e],
270
+ onChange: (t) => i({
271
+ ...r,
272
+ [e]: t
273
+ })
274
+ }));
275
+ }));
276
+ };
277
+ //#endregion
278
+ export { T as a, d as c, r as d, i as f, w as i, s as l, a as m, F as n, p as o, l as p, E as r, f as s, I as t, c as u };