@oktis-works/admin 0.1.5 → 0.1.8

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.
Files changed (47) hide show
  1. package/dist/client/_astro/{BaseLayout.COf3Eran.css → BaseLayout.BPkaFsmK.css} +1 -1
  2. package/dist/client/_astro/ContentEditor.C9TSxsGW.js +1 -0
  3. package/dist/client/_astro/ContentList.e1datweV.js +1 -0
  4. package/dist/client/_astro/DashboardHome.CqnldWlv.js +1 -0
  5. package/dist/client/_astro/DashboardLayout.astro_astro_type_script_index_0_lang.sNve10RH.js +1 -0
  6. package/dist/client/_astro/GeneralSettings.D-ALN9_r.js +1 -0
  7. package/dist/client/_astro/MediaLibrary.NQ1lF95i.js +1 -0
  8. package/dist/client/_astro/PostTypesManager.CdMx_Nxn.js +1 -0
  9. package/dist/client/_astro/TaxonomiesManager.BU7A02Ay.js +1 -0
  10. package/dist/client/_astro/UserCreateForm.BvDn97aZ.js +1 -0
  11. package/dist/client/_astro/UsersManager.CFBCKO-t.js +1 -0
  12. package/dist/client/_astro/api.DCaprPaL.js +1 -0
  13. package/dist/client/_astro/client.BY0Z100j.js +1 -0
  14. package/dist/client/_astro/dist.B3u752Tx.js +1 -0
  15. package/dist/client/_astro/extensions.PfWqwyUU.js +1 -0
  16. package/dist/client/_astro/{login.astro_astro_type_script_index_0_lang.BLhqPWk8.js → login.astro_astro_type_script_index_0_lang.BZaUVRCc.js} +1 -1
  17. package/dist/client/_astro/{web.BRlgYXBp.js → web.D_vCtCLj.js} +1 -1
  18. package/dist/server/chunks/{BaseLayout_Mvr1_6Ng.mjs → BaseLayout_C41_wW4F.mjs} +19 -2
  19. package/dist/server/chunks/{edit_D14rRl_p.mjs → ContentEditor_CrO12IkK.mjs} +535 -48
  20. package/dist/server/chunks/DashboardLayout_h9iqOf7E.mjs +524 -0
  21. package/dist/server/chunks/MediaLibrary_Ctc5H6Od.mjs +309 -0
  22. package/dist/server/chunks/_slug__FVgVdi48.mjs +30 -0
  23. package/dist/server/chunks/api_C1VC3OiH.mjs +286 -0
  24. package/dist/server/chunks/edit_Dau0tASP.mjs +30 -0
  25. package/dist/server/chunks/general_DOXmhv-h.mjs +180 -0
  26. package/dist/server/chunks/index_B26K6w42.mjs +316 -0
  27. package/dist/server/chunks/index_BYBvZsat.mjs +23 -0
  28. package/dist/server/chunks/index_D9OGVvPs.mjs +275 -0
  29. package/dist/server/chunks/index_Owj31XBA.mjs +133 -0
  30. package/dist/server/chunks/index_oZK1qJym.mjs +30 -0
  31. package/dist/server/chunks/{login_B7vbWIed.mjs → login_BH67N4b1.mjs} +2 -19
  32. package/dist/server/chunks/new_2mb-n_fU.mjs +86 -0
  33. package/dist/server/chunks/new_BhA9pTES.mjs +30 -0
  34. package/dist/server/chunks/{post-types_BtNyF2Iv.mjs → post-types_B4rrV0WI.mjs} +2 -2
  35. package/dist/server/chunks/{taxonomies_DSgstawN.mjs → taxonomies_Bdxv94jK.mjs} +2 -2
  36. package/dist/server/chunks/upload_RgdwSWbY.mjs +31 -0
  37. package/dist/server/entry.mjs +291 -15
  38. package/package.json +5 -5
  39. package/dist/client/_astro/ContentEditor.COyD6bGV.js +0 -1
  40. package/dist/client/_astro/PostTypesManager.APvO7Cs9.js +0 -1
  41. package/dist/client/_astro/TaxonomiesManager.CVFdfaUR.js +0 -1
  42. package/dist/client/_astro/api.DSP61PKM.js +0 -1
  43. package/dist/client/_astro/client.D7G9q8lk.js +0 -1
  44. package/dist/server/chunks/DashboardLayout_CP5ag-_P.mjs +0 -17
  45. package/dist/server/chunks/api_Cy8sbUHf.mjs +0 -153
  46. package/dist/server/chunks/index_BgbHlcwr.mjs +0 -23
  47. package/dist/server/chunks/index_c3b5hMDp.mjs +0 -22
@@ -1,22 +1,515 @@
1
- import { r as __exportAll } from "./rolldown-runtime_BMI-E3GI.mjs";
2
- import { d as maybeRenderHead, i as renderComponent, u as renderTemplate } from "./server_CnzC2Y0K.mjs";
3
- import { t as createComponent$1 } from "./compiler_CYjwXhLT.mjs";
4
- import { t as $$DashboardLayout } from "./DashboardLayout_CP5ag-_P.mjs";
5
- import { t as apiClient } from "./api_Cy8sbUHf.mjs";
6
- import { t as require_semver } from "./semver_WbqCUY_o.mjs";
1
+ import { a as For2, d as createMemo$1, f as createSignal$1, l as Show2 } from "./DashboardLayout_h9iqOf7E.mjs";
2
+ import { t as apiClient } from "./api_C1VC3OiH.mjs";
7
3
  import { createComponent, escape, memo, ssr, ssrAttribute, ssrHydrationKey } from "solid-js/web";
8
- import { For, For as For$1, Show, Show as Show$1, createMemo, createMemo as createMemo$1, createSignal, createSignal as createSignal$1, onMount } from "solid-js";
9
- //#region src/lib/validation.ts
10
- function validateFieldClient(_field, _value) {
11
- return {
12
- valid: true,
13
- errors: []
14
- };
4
+ import { For, Show, createMemo, createSignal, onMount } from "solid-js";
5
+ //#region ../../packages/validation/dist/client-validate.js
6
+ function isEmptyValue(value) {
7
+ if (value === null || value === void 0) return true;
8
+ if (typeof value === "string") return value.trim() === "";
9
+ if (Array.isArray(value)) return value.length === 0;
10
+ return false;
11
+ }
12
+ function checkRequired(value, required, field, errors) {
13
+ if (!required) return true;
14
+ if (isEmptyValue(value)) {
15
+ errors.push({
16
+ field,
17
+ code: "REQUIRED",
18
+ message: `${field} é obrigatório`
19
+ });
20
+ return false;
21
+ }
22
+ return true;
23
+ }
24
+ function validateTextLike(value, config, field, errors) {
25
+ if (isEmptyValue(value)) return;
26
+ const str = String(value);
27
+ const characterLimit = config["characterLimit"];
28
+ if (characterLimit !== void 0 && str.length > characterLimit) errors.push({
29
+ field,
30
+ code: "CHARACTER_LIMIT",
31
+ message: `${field} excede o limite de ${characterLimit} caracteres`
32
+ });
33
+ }
34
+ function validateEmail(value, field, errors) {
35
+ if (isEmptyValue(value)) return;
36
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(value))) errors.push({
37
+ field,
38
+ code: "INVALID_EMAIL",
39
+ message: `${field} não é um e-mail válido`
40
+ });
41
+ }
42
+ function validateUrl(value, field, errors) {
43
+ if (isEmptyValue(value)) return;
44
+ try {
45
+ const parsed = new URL(String(value));
46
+ if (!["http:", "https:"].includes(parsed.protocol)) throw new Error("protocol");
47
+ } catch {
48
+ errors.push({
49
+ field,
50
+ code: "INVALID_URL",
51
+ message: `${field} não é uma URL válida (http/https)`
52
+ });
53
+ }
15
54
  }
55
+ function validateNumber(value, config, field, errors) {
56
+ if (isEmptyValue(value)) return;
57
+ const num = Number(value);
58
+ if (Number.isNaN(num)) {
59
+ errors.push({
60
+ field,
61
+ code: "NOT_A_NUMBER",
62
+ message: `${field} deve ser um número`
63
+ });
64
+ return;
65
+ }
66
+ const minValue = config["minValue"];
67
+ const maxValue = config["maxValue"];
68
+ const step = config["step"];
69
+ if (minValue !== void 0 && num < minValue) errors.push({
70
+ field,
71
+ code: "MIN_VALUE",
72
+ message: `${field} deve ser maior ou igual a ${minValue}`
73
+ });
74
+ if (maxValue !== void 0 && num > maxValue) errors.push({
75
+ field,
76
+ code: "MAX_VALUE",
77
+ message: `${field} deve ser menor ou igual a ${maxValue}`
78
+ });
79
+ if (step !== void 0 && step > 0) {
80
+ const base = minValue ?? 0;
81
+ if (Math.abs((num - base) / step - Math.round((num - base) / step)) > 1e-9) errors.push({
82
+ field,
83
+ code: "STEP_MISMATCH",
84
+ message: `${field} deve seguir o incremento de ${step}`
85
+ });
86
+ }
87
+ }
88
+ function getValidChoiceValues(config) {
89
+ const choices = config["choices"] ?? [];
90
+ return new Set(choices.map((c) => String(c.value)));
91
+ }
92
+ function checkClosedSet(value, valid, allowCustom, field, errors) {
93
+ if (allowCustom) return;
94
+ if (!valid.has(String(value))) errors.push({
95
+ field,
96
+ code: "INVALID_CHOICE",
97
+ message: `${field} contém um valor fora das opções permitidas`
98
+ });
99
+ }
100
+ function checkSelectionCount(values, config, field, errors) {
101
+ const min = config["minSelections"];
102
+ const max = config["maxSelections"];
103
+ if (min !== void 0 && values.length < min) errors.push({
104
+ field,
105
+ code: "MIN_SELECTIONS",
106
+ message: `${field} requer no mínimo ${min} seleção(ões)`
107
+ });
108
+ if (max !== void 0 && values.length > max) errors.push({
109
+ field,
110
+ code: "MAX_SELECTIONS",
111
+ message: `${field} permite no máximo ${max} seleção(ões)`
112
+ });
113
+ }
114
+ function validateSelect(value, config, field, errors) {
115
+ if (isEmptyValue(value)) return;
116
+ const multiple = Boolean(config["multiple"]);
117
+ const allowCustom = Boolean(config["allowCustom"] ?? false);
118
+ const valid = getValidChoiceValues(config);
119
+ if (multiple) {
120
+ if (!Array.isArray(value)) {
121
+ errors.push({
122
+ field,
123
+ code: "NOT_ARRAY",
124
+ message: `${field} deve ser uma lista`
125
+ });
126
+ return;
127
+ }
128
+ if (!allowCustom) for (const item of value) checkClosedSet(item, valid, false, field, errors);
129
+ checkSelectionCount(value, config, field, errors);
130
+ return;
131
+ }
132
+ checkClosedSet(value, valid, allowCustom, field, errors);
133
+ if (Array.isArray(value)) errors.push({
134
+ field,
135
+ code: "SINGLE_ONLY",
136
+ message: `${field} aceita apenas um valor`
137
+ });
138
+ }
139
+ function validateCheckbox(value, config, field, errors) {
140
+ if (isEmptyValue(value)) return;
141
+ if (!Array.isArray(value)) {
142
+ errors.push({
143
+ field,
144
+ code: "NOT_ARRAY",
145
+ message: `${field} deve ser uma lista de valores`
146
+ });
147
+ return;
148
+ }
149
+ const valid = getValidChoiceValues(config);
150
+ for (const item of value) checkClosedSet(item, valid, true, field, errors);
151
+ checkSelectionCount(value, config, field, errors);
152
+ }
153
+ function validateRadio(value, config, field, errors) {
154
+ if (isEmptyValue(value)) return;
155
+ checkClosedSet(value, getValidChoiceValues(config), Boolean(config["allowCustom"]), field, errors);
156
+ }
157
+ function validateTrueFalse(value, field, errors) {
158
+ if (value === null || value === void 0) return;
159
+ if (!(typeof value === "boolean" || value === 0 || value === 1 || value === "0" || value === "1")) errors.push({
160
+ field,
161
+ code: "NOT_BOOLEAN",
162
+ message: `${field} deve ser verdadeiro ou falso`
163
+ });
164
+ }
165
+ function validateMediaItem(item, config, field, errors) {
166
+ if (typeof item !== "object" || item === null || Array.isArray(item)) {
167
+ errors.push({
168
+ field,
169
+ code: "INVALID_MEDIA",
170
+ message: `${field} deve referenciar uma mídia válida`
171
+ });
172
+ return;
173
+ }
174
+ const media = item;
175
+ const mimeTypes = config["mimeTypes"] ?? [];
176
+ if (mimeTypes.length > 0 && media.mimeType) {
177
+ if (!mimeTypes.map((m) => m.toLowerCase()).includes(media.mimeType.toLowerCase())) errors.push({
178
+ field,
179
+ code: "INVALID_MIME",
180
+ message: `${field} não aceita arquivos do tipo ${media.mimeType}`
181
+ });
182
+ }
183
+ const maxSize = config["maxSize"];
184
+ const minSize = config["minSize"];
185
+ if (media.size !== void 0) {
186
+ if (maxSize !== void 0 && media.size > maxSize) errors.push({
187
+ field,
188
+ code: "FILE_TOO_LARGE",
189
+ message: `${field} excede o tamanho máximo de ${Math.round(maxSize / 1024)}KB`
190
+ });
191
+ if (minSize !== void 0 && media.size < minSize) errors.push({
192
+ field,
193
+ code: "FILE_TOO_SMALL",
194
+ message: `${field} está abaixo do tamanho mínimo de ${Math.round(minSize / 1024)}KB`
195
+ });
196
+ }
197
+ if (media.width !== void 0 && media.height !== void 0) {
198
+ const minWidth = config["minWidth"];
199
+ const maxWidth = config["maxWidth"];
200
+ const minHeight = config["minHeight"];
201
+ const maxHeight = config["maxHeight"];
202
+ if (minWidth !== void 0 && media.width < minWidth) errors.push({
203
+ field,
204
+ code: "MIN_WIDTH",
205
+ message: `${field} requer largura mínima de ${minWidth}px`
206
+ });
207
+ if (maxWidth !== void 0 && media.width > maxWidth) errors.push({
208
+ field,
209
+ code: "MAX_WIDTH",
210
+ message: `${field} permite largura máxima de ${maxWidth}px`
211
+ });
212
+ if (minHeight !== void 0 && media.height < minHeight) errors.push({
213
+ field,
214
+ code: "MIN_HEIGHT",
215
+ message: `${field} requer altura mínima de ${minHeight}px`
216
+ });
217
+ if (maxHeight !== void 0 && media.height > maxHeight) errors.push({
218
+ field,
219
+ code: "MAX_HEIGHT",
220
+ message: `${field} permite altura máxima de ${maxHeight}px`
221
+ });
222
+ }
223
+ }
224
+ function validateImage(value, config, field, errors) {
225
+ if (isEmptyValue(value)) return;
226
+ validateMediaItem(value, config, field, errors);
227
+ }
228
+ function validateFile(value, config, field, errors) {
229
+ if (isEmptyValue(value)) return;
230
+ validateMediaItem(value, config, field, errors);
231
+ }
232
+ function validateGallery(value, config, field, errors) {
233
+ if (value === null || value === void 0) return;
234
+ if (!Array.isArray(value)) {
235
+ errors.push({
236
+ field,
237
+ code: "NOT_ARRAY",
238
+ message: `${field} deve ser uma lista de imagens`
239
+ });
240
+ return;
241
+ }
242
+ const hasLimits = config["minSelections"] !== void 0 || config["maxSelections"] !== void 0;
243
+ if (value.length === 0 && !hasLimits) return;
244
+ const minSelections = config["minSelections"];
245
+ const maxSelections = config["maxSelections"];
246
+ if (minSelections !== void 0 && value.length < minSelections) errors.push({
247
+ field,
248
+ code: "MIN_SELECTIONS",
249
+ message: `${field} requer no mínimo ${minSelections} imagem(ns)`
250
+ });
251
+ if (maxSelections !== void 0 && value.length > maxSelections) errors.push({
252
+ field,
253
+ code: "MAX_SELECTIONS",
254
+ message: `${field} permite no máximo ${maxSelections} imagem(ns)`
255
+ });
256
+ for (const item of value) validateMediaItem(item, config, field, errors);
257
+ }
258
+ function validateRelationshipIds(value, config, field, errors) {
259
+ if (isEmptyValue(value)) return;
260
+ const multiple = config["multiple"] !== false;
261
+ const minSelections = config["minSelections"];
262
+ const maxSelections = config["maxSelections"];
263
+ const ids = Array.isArray(value) ? value : [value];
264
+ for (const id of ids) if (typeof id !== "string" && typeof id !== "number") {
265
+ errors.push({
266
+ field,
267
+ code: "INVALID_ID",
268
+ message: `${field} contém um identificador inválido`
269
+ });
270
+ return;
271
+ }
272
+ if (multiple) {
273
+ if (maxSelections !== void 0 && ids.length > maxSelections) errors.push({
274
+ field,
275
+ code: "MAX_SELECTIONS",
276
+ message: `${field} permite no máximo ${maxSelections} seleção(ões)`
277
+ });
278
+ if (minSelections !== void 0 && ids.length < minSelections) errors.push({
279
+ field,
280
+ code: "MIN_SELECTIONS",
281
+ message: `${field} requer no mínimo ${minSelections} seleção(ões)`
282
+ });
283
+ } else if (ids.length > 1) errors.push({
284
+ field,
285
+ code: "SINGLE_ONLY",
286
+ message: `${field} aceita apenas um valor`
287
+ });
288
+ }
289
+ function validateLink(value, field, errors) {
290
+ if (isEmptyValue(value)) return;
291
+ if (typeof value !== "object" || value === null) {
292
+ errors.push({
293
+ field,
294
+ code: "INVALID_LINK",
295
+ message: `${field} deve ser um objeto de link`
296
+ });
297
+ return;
298
+ }
299
+ const link = value;
300
+ if (!link.url || typeof link.url !== "string") {
301
+ errors.push({
302
+ field,
303
+ code: "LINK_URL_REQUIRED",
304
+ message: `${field} requer uma URL`
305
+ });
306
+ return;
307
+ }
308
+ try {
309
+ const parsed = new URL(link.url);
310
+ if (![
311
+ "http:",
312
+ "https:",
313
+ "mailto:",
314
+ "tel:"
315
+ ].includes(parsed.protocol) && !link.url.startsWith("#") && !link.url.startsWith("/")) throw new Error("protocol");
316
+ } catch {
317
+ if (!link.url.startsWith("#") && !link.url.startsWith("/") && !link.url.startsWith("?")) errors.push({
318
+ field,
319
+ code: "INVALID_URL",
320
+ message: `${field} contém uma URL inválida`
321
+ });
322
+ }
323
+ if (link.target !== void 0 && !["_self", "_blank"].includes(String(link.target))) errors.push({
324
+ field,
325
+ code: "INVALID_TARGET",
326
+ message: `${field} aceita apenas _self ou _blank`
327
+ });
328
+ }
329
+ function validateGoogleMap(value, field, errors) {
330
+ if (isEmptyValue(value)) return;
331
+ if (typeof value !== "object" || value === null) {
332
+ errors.push({
333
+ field,
334
+ code: "INVALID_MAP",
335
+ message: `${field} deve conter endereço e coordenadas`
336
+ });
337
+ return;
338
+ }
339
+ const map = value;
340
+ if (isEmptyValue(map.address)) errors.push({
341
+ field,
342
+ code: "ADDRESS_REQUIRED",
343
+ message: `${field} requer um endereço`
344
+ });
345
+ const lat = Number(map.lat);
346
+ const lng = Number(map.lng);
347
+ if (!Number.isFinite(lat) || lat < -90 || lat > 90) errors.push({
348
+ field,
349
+ code: "INVALID_LATITUDE",
350
+ message: `${field} contém latitude inválida (-90 a 90)`
351
+ });
352
+ if (!Number.isFinite(lng) || lng < -180 || lng > 180) errors.push({
353
+ field,
354
+ code: "INVALID_LONGITUDE",
355
+ message: `${field} contém longitude inválida (-180 a 180)`
356
+ });
357
+ }
358
+ var HEX_PATTERN = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
359
+ function validateColorPicker(value, config, field, errors) {
360
+ if (isEmptyValue(value)) return;
361
+ const color = String(value);
362
+ const isRgba = color.startsWith("rgba(");
363
+ if (isRgba && !config["enableOpacity"]) {
364
+ errors.push({
365
+ field,
366
+ code: "OPACITY_DISABLED",
367
+ message: `${field} não permite transparência`
368
+ });
369
+ return;
370
+ }
371
+ if (!isRgba && !HEX_PATTERN.test(color)) {
372
+ errors.push({
373
+ field,
374
+ code: "INVALID_COLOR",
375
+ message: `${field} deve ser uma cor em formato hexadecimal válido`
376
+ });
377
+ return;
378
+ }
379
+ const palette = config["palette"] ?? [];
380
+ if (palette.length > 0) {
381
+ if (!palette.map((e) => e.toLowerCase()).includes(color.toLowerCase())) errors.push({
382
+ field,
383
+ code: "NOT_IN_PALETTE",
384
+ message: `${field} deve usar uma cor da paleta definida`
385
+ });
386
+ }
387
+ }
388
+ /**
389
+ * Valida um único campo no cliente e retorna a primeira mensagem de erro
390
+ * ou null quando válido. Não considera lógica condicional.
391
+ */
392
+ function validateFieldClient(field, value) {
393
+ if (field.type === "clone" || field.type === "repeater" || field.type === "group" || field.type === "flexible_content") return null;
394
+ const config = field.config ?? {};
395
+ const errors = [];
396
+ checkRequired(value, field.required, field.label, errors);
397
+ switch (field.type) {
398
+ case "text":
399
+ case "textarea":
400
+ case "password":
401
+ validateTextLike(value, config, field.label, errors);
402
+ break;
403
+ case "email":
404
+ validateEmail(value, field.label, errors);
405
+ break;
406
+ case "url":
407
+ case "oembed":
408
+ validateUrl(value, field.label, errors);
409
+ break;
410
+ case "number":
411
+ case "range":
412
+ validateNumber(value, config, field.label, errors);
413
+ break;
414
+ case "wysiwyg":
415
+ validateTextLike(value, config, field.label, errors);
416
+ break;
417
+ case "select":
418
+ validateSelect(value, config, field.label, errors);
419
+ break;
420
+ case "checkbox":
421
+ validateCheckbox(value, config, field.label, errors);
422
+ break;
423
+ case "radio":
424
+ validateRadio(value, config, field.label, errors);
425
+ break;
426
+ case "true_false":
427
+ validateTrueFalse(value, field.label, errors);
428
+ break;
429
+ case "image":
430
+ validateImage(value, config, field.label, errors);
431
+ break;
432
+ case "file":
433
+ validateFile(value, config, field.label, errors);
434
+ break;
435
+ case "gallery":
436
+ validateGallery(value, config, field.label, errors);
437
+ break;
438
+ case "link":
439
+ validateLink(value, field.label, errors);
440
+ break;
441
+ case "page_link":
442
+ case "post_object":
443
+ case "relationship":
444
+ case "taxonomy":
445
+ case "user":
446
+ validateRelationshipIds(value, config, field.label, errors);
447
+ break;
448
+ case "google_map":
449
+ validateGoogleMap(value, field.label, errors);
450
+ break;
451
+ case "color_picker": validateColorPicker(value, config, field.label, errors);
452
+ }
453
+ return errors[0]?.message ?? null;
454
+ }
455
+ //#endregion
456
+ //#region ../../packages/validation/dist/clone.js
457
+ /**
458
+ * Expande campos do tipo `clone` nas definições alvo.
459
+ *
460
+ * - `display: 'seamless'` (default): os campos referenciados entram
461
+ * diretamente na lista, com os mesmos nomes (valores "inline").
462
+ * - `display: 'group'`: os campos viram subcampos de um pseudo-group com o
463
+ * nome do clone, e os nomes internos recebem o prefixo `{clone}_`
464
+ * (valores aninhados em data[clone.name]).
465
+ *
466
+ * Referências inexistentes são ignoradas; clones de clones não são
467
+ * resolvidos recursivamente (profundidade 1, como o modo básico do ACF).
468
+ */
16
469
  function expandCloneFields(fields) {
17
- return fields;
470
+ const byName = /* @__PURE__ */ new Map();
471
+ for (const field of fields) byName.set(field.name, field);
472
+ const result = [];
473
+ const emittedNames = /* @__PURE__ */ new Set();
474
+ const emit = (field) => {
475
+ if (emittedNames.has(field.name)) return;
476
+ emittedNames.add(field.name);
477
+ result.push(field);
478
+ };
479
+ for (const field of fields) {
480
+ if (field.type !== "clone") {
481
+ emit(field);
482
+ continue;
483
+ }
484
+ const config = field.config ?? {};
485
+ const display = config["display"] ?? "seamless";
486
+ const targets = config["clone"] ?? [];
487
+ const resolved = [];
488
+ for (const targetName of targets) {
489
+ const target = byName.get(targetName);
490
+ if (!target || target.type === "clone") continue;
491
+ resolved.push(target);
492
+ }
493
+ if (resolved.length === 0) continue;
494
+ if (display === "group") {
495
+ emit({
496
+ ...field,
497
+ type: "group",
498
+ name: field.name,
499
+ label: field.label,
500
+ required: false,
501
+ conditionalLogic: void 0,
502
+ subFields: resolved.map((target) => ({
503
+ ...target,
504
+ name: `${field.name}_${target.name}`
505
+ }))
506
+ });
507
+ continue;
508
+ }
509
+ for (const target of resolved) emit(target);
510
+ }
511
+ return result;
18
512
  }
19
- require_semver();
20
513
  //#endregion
21
514
  //#region src/components/content/RelationshipPicker.tsx
22
515
  var _tmpl$$3 = [
@@ -62,36 +555,36 @@ function RelationshipPicker(props) {
62
555
  if (Array.isArray(value)) return value.map(String);
63
556
  return value ? [String(value)] : [];
64
557
  });
65
- return ssr(_tmpl$5$3, ssrHydrationKey(), escape(createComponent(Show$1, {
558
+ return ssr(_tmpl$5$3, ssrHydrationKey(), escape(createComponent(Show2, {
66
559
  get when() {
67
560
  return selected().length > 0 || selectedIds().length > 0;
68
561
  },
69
562
  get children() {
70
- return ssr(_tmpl$$3, ssrHydrationKey(), escape(createComponent(For$1, {
563
+ return ssr(_tmpl$$3, ssrHydrationKey(), escape(createComponent(For2, {
71
564
  get each() {
72
565
  return selected();
73
566
  },
74
567
  children: (entry) => ssr(_tmpl$6$2, ssrHydrationKey(), escape(entry.title))
75
568
  })));
76
569
  }
77
- })), ssrAttribute("placeholder", escape(props.placeholder ?? "Buscar conteúdo...", true), false) + ssrAttribute("value", escape(query(), true), false), escape(createComponent(Show$1, {
570
+ })), ssrAttribute("placeholder", escape(props.placeholder ?? "Buscar conteúdo...", true), false) + ssrAttribute("value", escape(query(), true), false), escape(createComponent(Show2, {
78
571
  get when() {
79
572
  return memo(() => !!open())() && (loading() || results().length > 0);
80
573
  },
81
574
  get children() {
82
- return ssr(_tmpl$4$3, ssrHydrationKey(), escape(createComponent(Show$1, {
575
+ return ssr(_tmpl$4$3, ssrHydrationKey(), escape(createComponent(Show2, {
83
576
  get when() {
84
577
  return loading();
85
578
  },
86
579
  get children() {
87
580
  return ssr(_tmpl$2$3, ssrHydrationKey());
88
581
  }
89
- })), escape(createComponent(For$1, {
582
+ })), escape(createComponent(For2, {
90
583
  get each() {
91
584
  return results();
92
585
  },
93
586
  children: (option) => ssr(_tmpl$7$2, ssrHydrationKey(), escape(option.title), escape(option.type))
94
- })), escape(createComponent(Show$1, {
587
+ })), escape(createComponent(Show2, {
95
588
  get when() {
96
589
  return memo(() => !!!loading())() && results().length === 0;
97
590
  },
@@ -321,10 +814,10 @@ function FieldRenderer(props) {
321
814
  }
322
815
  })), escape(createComponent(Show, {
323
816
  get when() {
324
- return memo(() => !!validationError())() && !validationError()?.valid;
817
+ return validationError();
325
818
  },
326
819
  get children() {
327
- return ssr(_tmpl$3$2, ssrHydrationKey(), escape(validationError()?.errors.join(", ")));
820
+ return ssr(_tmpl$3$2, ssrHydrationKey(), escape(validationError()));
328
821
  }
329
822
  })));
330
823
  }
@@ -710,6 +1203,24 @@ function ContentEditor() {
710
1203
  } catch (err) {
711
1204
  setErrors([err instanceof Error ? err.message : String(err)]);
712
1205
  }
1206
+ const editId = new URLSearchParams(window.location.search).get("id");
1207
+ if (editId) try {
1208
+ const existing = await apiClient.getContentById(editId);
1209
+ const rawRow = existing;
1210
+ setDraft({
1211
+ id: existing.id,
1212
+ type: existing.type,
1213
+ title: existing.title,
1214
+ slug: existing.slug,
1215
+ excerpt: existing.excerpt,
1216
+ featuredImageId: rawRow["featuredImageId"] ?? rawRow["featured_image_id"],
1217
+ status: existing.status,
1218
+ layout: existing.layout
1219
+ });
1220
+ setData(existing.body ?? {});
1221
+ } catch (err) {
1222
+ setErrors([err instanceof Error ? err.message : String(err)]);
1223
+ }
713
1224
  await loadGroups(draft().type);
714
1225
  });
715
1226
  const availableLayouts = () => {
@@ -818,28 +1329,4 @@ function ContentEditor() {
818
1329
  })), ssrAttribute("disabled", saving(), true));
819
1330
  }
820
1331
  //#endregion
821
- //#region src/pages/content/edit.astro
822
- var edit_exports = /* @__PURE__ */ __exportAll({
823
- default: () => $$Edit,
824
- file: () => $$file,
825
- url: () => $$url
826
- });
827
- var $$Edit = createComponent$1(($$result, $$props, $$slots) => {
828
- return renderTemplate`${renderComponent($$result, "DashboardLayout", $$DashboardLayout, {
829
- "title": "Editor de Conteúdo",
830
- "data-astro-cid-4zhgedtj": true
831
- }, { "default": ($$result) => renderTemplate`${maybeRenderHead($$result)}<div class="editor-page" data-astro-cid-4zhgedtj>${renderComponent($$result, "ContentEditor", ContentEditor, {
832
- "client:load": true,
833
- "data-astro-cid-4zhgedtj": true,
834
- "client:component-hydration": "load",
835
- "client:component-path": "/home/runner/work/cms/cms/apps/admin/src/components/content/ContentEditor.tsx",
836
- "client:component-export": "ContentEditor"
837
- })}</div>` })}`;
838
- }, "/home/runner/work/cms/cms/apps/admin/src/pages/content/edit.astro", void 0);
839
- var $$file = "/home/runner/work/cms/cms/apps/admin/src/pages/content/edit.astro";
840
- var $$url = "/content/edit";
841
- //#endregion
842
- //#region \0virtual:astro:page:src/pages/content/edit@_@astro
843
- var page = () => edit_exports;
844
- //#endregion
845
- export { page };
1332
+ export { ContentEditor as t };