gavaengine 2.2.0 → 2.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.
Files changed (34) hide show
  1. package/dist/{DashboardSplashTrigger-Bz4Z4edN.d.ts → DashboardSplashTrigger-M23R6617.d.ts} +21 -4
  2. package/dist/auth/index.js +5 -2
  3. package/dist/{chunk-3ZYJ4C6R.js → chunk-AMARPSPH.js} +2 -2
  4. package/dist/chunk-AOSHQP7D.js +12 -0
  5. package/dist/chunk-AOSHQP7D.js.map +1 -0
  6. package/dist/{chunk-QO42DDRU.js → chunk-IU2SMMVV.js} +1 -40
  7. package/dist/chunk-IU2SMMVV.js.map +1 -0
  8. package/dist/chunk-IYUHCOF5.js +44 -0
  9. package/dist/chunk-IYUHCOF5.js.map +1 -0
  10. package/dist/{chunk-PHT76VW6.js → chunk-MANXBV2D.js} +117 -4
  11. package/dist/chunk-MANXBV2D.js.map +1 -0
  12. package/dist/{chunk-XUWBLDOW.js → chunk-PZ5SO7QO.js} +184 -103
  13. package/dist/chunk-PZ5SO7QO.js.map +1 -0
  14. package/dist/cli/index.js +557 -54
  15. package/dist/components/index.d.ts +4 -4
  16. package/dist/components/index.js +7 -3
  17. package/dist/handlers/index.d.ts +60 -0
  18. package/dist/handlers/index.js +116 -3
  19. package/dist/handlers/index.js.map +1 -1
  20. package/dist/i18n/index.d.ts +37 -0
  21. package/dist/i18n/index.js +76 -2
  22. package/dist/i18n/index.js.map +1 -1
  23. package/dist/{index-ByyETmJM.d.ts → index-C4AHVM5-.d.ts} +82 -1
  24. package/dist/index.d.ts +6 -6
  25. package/dist/index.js +11 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/providers/index.d.ts +3 -2
  28. package/dist/providers/index.js +3 -2
  29. package/dist/{registry-Do5nzO7_.d.ts → registry-kAqFTg2C.d.ts} +17 -1
  30. package/package.json +15 -14
  31. package/dist/chunk-PHT76VW6.js.map +0 -1
  32. package/dist/chunk-QO42DDRU.js.map +0 -1
  33. package/dist/chunk-XUWBLDOW.js.map +0 -1
  34. /package/dist/{chunk-3ZYJ4C6R.js.map → chunk-AMARPSPH.js.map} +0 -0
@@ -1,12 +1,12 @@
1
- import { G as GEFieldDef } from '../registry-Do5nzO7_.js';
2
- export { C as ComponentRegistryProvider, a as ContentEditor, b as ContentEditorProps, c as ContentList, d as ContentListProps, e as GEComponentOverrides, u as useComponentRegistry, f as useRegisteredComponent } from '../registry-Do5nzO7_.js';
3
- export { A as ArticleEditor, a as ArticleList, C as CoverImageUpload, D as DashboardNavbar, b as DashboardSplashTrigger, c as DraggableYoutube, d as DraggableYoutubeView, E as EditorToolbar, I as ImageEditModal, M as MediaGrid, e as MediaPickerModal, R as ResizableImage, f as ResizableImageView, g as RevisionPanel, S as SplashScreen, h as StatCard, U as UserForm, i as UserTable, V as VideoExtension, j as VideoView } from '../DashboardSplashTrigger-Bz4Z4edN.js';
1
+ import { G as GEFieldDef } from '../registry-kAqFTg2C.js';
2
+ export { C as ComponentRegistryProvider, a as ContentEditor, b as ContentEditorProps, c as ContentList, d as ContentListProps, e as GEComponentOverrides, u as useComponentRegistry, f as useRegisteredComponent } from '../registry-kAqFTg2C.js';
3
+ export { A as ArticleEditor, a as ArticleList, C as CoverImageUpload, D as DashboardNavbar, b as DashboardNavbarProps, c as DashboardSplashTrigger, d as DraggableYoutube, e as DraggableYoutubeView, E as EditorToolbar, I as ImageEditModal, M as MediaGrid, f as MediaPickerModal, R as ResizableImage, g as ResizableImageView, h as RevisionPanel, S as SplashScreen, i as StatCard, U as UserForm, j as UserTable, V as VideoExtension, k as VideoView, u as useDefaultNavigation } from '../DashboardSplashTrigger-M23R6617.js';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import 'react';
6
+ import 'lucide-react';
6
7
  import '@tiptap/react';
7
8
  import '@tiptap/core';
8
9
  import '@tiptap/extension-youtube';
9
- import 'lucide-react';
10
10
 
11
11
  interface TextRendererProps {
12
12
  field: GEFieldDef;
@@ -30,13 +30,16 @@ import {
30
30
  UserForm,
31
31
  UserTable,
32
32
  VideoExtension,
33
- VideoView
34
- } from "../chunk-XUWBLDOW.js";
33
+ VideoView,
34
+ useDefaultNavigation
35
+ } from "../chunk-PZ5SO7QO.js";
35
36
  import {
36
37
  ComponentRegistryProvider,
37
38
  useComponentRegistry,
38
39
  useRegisteredComponent
39
- } from "../chunk-PHT76VW6.js";
40
+ } from "../chunk-MANXBV2D.js";
41
+ import "../chunk-IU2SMMVV.js";
42
+ import "../chunk-AOSHQP7D.js";
40
43
  export {
41
44
  ArticleEditor,
42
45
  ArticleList,
@@ -71,6 +74,7 @@ export {
71
74
  VideoExtension,
72
75
  VideoView,
73
76
  useComponentRegistry,
77
+ useDefaultNavigation,
74
78
  useRegisteredComponent
75
79
  };
76
80
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,6 @@
1
1
  import { GEContentType } from '../content/index.js';
2
2
  import { ComponentType, ReactNode } from 'react';
3
+ import { LucideIcon } from 'lucide-react';
3
4
 
4
5
  interface GEUser {
5
6
  id: string;
@@ -19,6 +20,21 @@ interface GEAuthAdapter {
19
20
  signOut?(): Promise<void>;
20
21
  }
21
22
 
23
+ interface GENavItem {
24
+ name: string;
25
+ href: string;
26
+ icon: LucideIcon;
27
+ visible?: (role: string) => boolean;
28
+ }
29
+ interface GESplashConfig {
30
+ words?: string[];
31
+ topText?: string;
32
+ bottomText?: string;
33
+ }
34
+ interface GEColorOption {
35
+ label: string;
36
+ value: string;
37
+ }
22
38
  interface GEContentActions {
23
39
  getAll(options?: {
24
40
  search?: string;
@@ -97,6 +113,12 @@ interface GavaEngineConfig {
97
113
  media: string;
98
114
  user: string;
99
115
  };
116
+ navigation?: GENavItem[];
117
+ splash?: GESplashConfig;
118
+ editorToolbar?: {
119
+ textColors?: GEColorOption[];
120
+ highlightColors?: GEColorOption[];
121
+ };
100
122
  auth?: GEAuthAdapter;
101
123
  contentTypes?: GEContentType[];
102
124
  components?: GEComponentOverrides;
@@ -125,6 +147,7 @@ interface GavaEngineConfig {
125
147
  userNew: string;
126
148
  media: string;
127
149
  dashboard: string;
150
+ statistics: string;
128
151
  login: string;
129
152
  home: string;
130
153
  };
@@ -216,6 +239,43 @@ interface GavaEngineConfig {
216
239
  status: string;
217
240
  title: string;
218
241
  untitled: string;
242
+ bold: string;
243
+ italic: string;
244
+ underline: string;
245
+ strikethrough: string;
246
+ superscript: string;
247
+ subscript: string;
248
+ textColor: string;
249
+ highlight: string;
250
+ heading2: string;
251
+ heading3: string;
252
+ bulletList: string;
253
+ numberedList: string;
254
+ quote: string;
255
+ codeBlock: string;
256
+ divider: string;
257
+ alignLeft: string;
258
+ alignCenter: string;
259
+ alignRight: string;
260
+ table: string;
261
+ insertTable: string;
262
+ addRowAbove: string;
263
+ addRowBelow: string;
264
+ addColumnLeft: string;
265
+ addColumnRight: string;
266
+ deleteRow: string;
267
+ deleteColumn: string;
268
+ deleteTable: string;
269
+ link: string;
270
+ image: string;
271
+ youtube: string;
272
+ video: string;
273
+ undo: string;
274
+ redo: string;
275
+ defaultColor: string;
276
+ removeHighlight: string;
277
+ linkPrompt: string;
278
+ youtubePrompt: string;
219
279
  };
220
280
  }
221
281
  declare const DEFAULT_CONFIG: GavaEngineConfig;
@@ -34,7 +34,44 @@ var it = {
34
34
  beforeRestore: "Prima del ripristino",
35
35
  publishedNote: "Pubblicato",
36
36
  preview: "Anteprima",
37
- placeholder: "Inizia a scrivere il tuo articolo..."
37
+ placeholder: "Inizia a scrivere il tuo articolo...",
38
+ bold: "Grassetto",
39
+ italic: "Corsivo",
40
+ underline: "Sottolineato",
41
+ strikethrough: "Barrato",
42
+ superscript: "Apice",
43
+ subscript: "Pedice",
44
+ textColor: "Colore testo",
45
+ highlight: "Evidenzia",
46
+ heading2: "H2",
47
+ heading3: "H3",
48
+ bulletList: "Elenco puntato",
49
+ numberedList: "Elenco numerato",
50
+ quote: "Citazione",
51
+ codeBlock: "Blocco codice",
52
+ divider: "Separatore",
53
+ alignLeft: "Allinea a sinistra",
54
+ alignCenter: "Allinea al centro",
55
+ alignRight: "Allinea a destra",
56
+ table: "Tabella",
57
+ insertTable: "Inserisci tabella 3\xD73",
58
+ addRowAbove: "Aggiungi riga sopra",
59
+ addRowBelow: "Aggiungi riga sotto",
60
+ addColumnLeft: "Aggiungi colonna a sinistra",
61
+ addColumnRight: "Aggiungi colonna a destra",
62
+ deleteRow: "Elimina riga",
63
+ deleteColumn: "Elimina colonna",
64
+ deleteTable: "Elimina tabella",
65
+ link: "Link",
66
+ image: "Immagine",
67
+ youtube: "YouTube",
68
+ video: "Video",
69
+ undo: "Annulla",
70
+ redo: "Ripeti",
71
+ defaultColor: "Predefinito",
72
+ removeHighlight: "Rimuovi",
73
+ linkPrompt: "URL:",
74
+ youtubePrompt: "URL YouTube:"
38
75
  },
39
76
  media: {
40
77
  media: "Media",
@@ -136,7 +173,44 @@ var en = {
136
173
  beforeRestore: "Before restore",
137
174
  publishedNote: "Published",
138
175
  preview: "Preview",
139
- placeholder: "Start writing your article..."
176
+ placeholder: "Start writing your article...",
177
+ bold: "Bold",
178
+ italic: "Italic",
179
+ underline: "Underline",
180
+ strikethrough: "Strikethrough",
181
+ superscript: "Superscript",
182
+ subscript: "Subscript",
183
+ textColor: "Text color",
184
+ highlight: "Highlight",
185
+ heading2: "H2",
186
+ heading3: "H3",
187
+ bulletList: "Bullet list",
188
+ numberedList: "Numbered list",
189
+ quote: "Quote",
190
+ codeBlock: "Code block",
191
+ divider: "Divider",
192
+ alignLeft: "Align left",
193
+ alignCenter: "Align center",
194
+ alignRight: "Align right",
195
+ table: "Table",
196
+ insertTable: "Insert 3\xD73 table",
197
+ addRowAbove: "Add row above",
198
+ addRowBelow: "Add row below",
199
+ addColumnLeft: "Add column left",
200
+ addColumnRight: "Add column right",
201
+ deleteRow: "Delete row",
202
+ deleteColumn: "Delete column",
203
+ deleteTable: "Delete table",
204
+ link: "Link",
205
+ image: "Image",
206
+ youtube: "YouTube",
207
+ video: "Video",
208
+ undo: "Undo",
209
+ redo: "Redo",
210
+ defaultColor: "Default",
211
+ removeHighlight: "Remove",
212
+ linkPrompt: "URL:",
213
+ youtubePrompt: "YouTube URL:"
140
214
  },
141
215
  media: {
142
216
  media: "Media",
@@ -308,7 +382,45 @@ function localeToStrings(locale) {
308
382
  unpublishConfirm: locale.common.unpublishConfirm,
309
383
  deleteUserConfirm: locale.common.deleteUserConfirm,
310
384
  totalArticles: locale.common.totalArticles,
311
- totalFiles: locale.common.totalFiles
385
+ totalFiles: locale.common.totalFiles,
386
+ // Toolbar
387
+ bold: locale.editor.bold,
388
+ italic: locale.editor.italic,
389
+ underline: locale.editor.underline,
390
+ strikethrough: locale.editor.strikethrough,
391
+ superscript: locale.editor.superscript,
392
+ subscript: locale.editor.subscript,
393
+ textColor: locale.editor.textColor,
394
+ highlight: locale.editor.highlight,
395
+ heading2: locale.editor.heading2,
396
+ heading3: locale.editor.heading3,
397
+ bulletList: locale.editor.bulletList,
398
+ numberedList: locale.editor.numberedList,
399
+ quote: locale.editor.quote,
400
+ codeBlock: locale.editor.codeBlock,
401
+ divider: locale.editor.divider,
402
+ alignLeft: locale.editor.alignLeft,
403
+ alignCenter: locale.editor.alignCenter,
404
+ alignRight: locale.editor.alignRight,
405
+ table: locale.editor.table,
406
+ insertTable: locale.editor.insertTable,
407
+ addRowAbove: locale.editor.addRowAbove,
408
+ addRowBelow: locale.editor.addRowBelow,
409
+ addColumnLeft: locale.editor.addColumnLeft,
410
+ addColumnRight: locale.editor.addColumnRight,
411
+ deleteRow: locale.editor.deleteRow,
412
+ deleteColumn: locale.editor.deleteColumn,
413
+ deleteTable: locale.editor.deleteTable,
414
+ link: locale.editor.link,
415
+ image: locale.editor.image,
416
+ youtube: locale.editor.youtube,
417
+ video: locale.editor.video,
418
+ undo: locale.editor.undo,
419
+ redo: locale.editor.redo,
420
+ defaultColor: locale.editor.defaultColor,
421
+ removeHighlight: locale.editor.removeHighlight,
422
+ linkPrompt: locale.editor.linkPrompt,
423
+ youtubePrompt: locale.editor.youtubePrompt
312
424
  };
313
425
  }
314
426
  var DEFAULT_STRINGS = localeToStrings(loadLocale("it"));
@@ -371,6 +483,7 @@ var DEFAULT_CONFIG = {
371
483
  userNew: "/dashboard/utenti/nuovo",
372
484
  media: "/dashboard/media",
373
485
  dashboard: "/dashboard",
486
+ statistics: "/dashboard/statistiche",
374
487
  login: "/login",
375
488
  home: "/"
376
489
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/i18n/it.ts","../../src/i18n/en.ts","../../src/i18n/index.ts","../../src/config.ts","../../src/handlers/revisions.ts","../../src/handlers/articles.ts","../../src/handlers/users.ts","../../src/handlers/media.ts","../../src/handlers/upload.ts","../../src/handlers/auth.ts","../../src/handlers/auth-utils.ts","../../src/handlers/content.ts","../../src/handlers/categories.ts"],"sourcesContent":["import type { GELocale } from \"./types.js\";\n\nexport const it: GELocale = {\n content: {\n articles: \"Articoli\",\n newArticle: \"Nuovo articolo\",\n titlePlaceholder: \"Titolo dell'articolo\",\n excerptPlaceholder: \"Breve descrizione dell'articolo...\",\n slugPlaceholder: \"slug-articolo\",\n authorPlaceholder: \"Nome dell'autore\",\n category: \"Categoria\",\n selectCategory: \"Seleziona categoria\",\n excerpt: \"Estratto\",\n author: \"Autore\",\n slugUrl: \"Slug URL\",\n noArticles: \"Nessun articolo.\",\n noArticlesSearch: \"Nessun articolo trovato.\",\n searchArticles: \"Cerca articoli...\",\n coverImageLabel: \"Immagine di copertina\",\n coverImageHint: \"Scegli dalla libreria o carica un nuovo file\",\n viewArticle: \"Vedi articolo pubblicato\",\n untitled: \"Senza titolo\",\n },\n editor: {\n publish: \"Pubblica\",\n unpublish: \"Ritira\",\n saveDraft: \"Salva bozza\",\n revisions: \"Cronologia\",\n saving: \"Salvando...\",\n saved: \"Salvato\",\n saveError: \"Errore nel salvataggio\",\n noRevisions: \"Nessuna revisione salvata.\",\n restore: \"Ripristina\",\n restoreConfirm:\n \"Ripristinare questa revisione? Lo stato attuale verrà salvato prima del ripristino.\",\n beforeRestore: \"Prima del ripristino\",\n publishedNote: \"Pubblicato\",\n preview: \"Anteprima\",\n placeholder: \"Inizia a scrivere il tuo articolo...\",\n },\n media: {\n media: \"Media\",\n noMedia: \"Nessun file caricato.\",\n noMediaSearch: \"Nessun file trovato.\",\n chooseFile: \"Scegli file\",\n dragHint: \"Trascina un'immagine qui oppure\",\n uploadHint: \"JPEG, PNG, WebP, GIF (max 5MB)\",\n mediaLibrary: \"Libreria media\",\n uploadNew: \"Carica nuovo\",\n searchFiles: \"Cerca file...\",\n selectImage: \"Seleziona immagine\",\n noImages: \"Nessuna immagine nella libreria.\",\n noImagesSearch: \"Nessuna immagine trovata.\",\n copyUrl: \"Copia URL\",\n editImage: \"Modifica immagine\",\n restoreOriginal: \"Ripristina originale\",\n freeAspect: \"Libero\",\n },\n users: {\n users: \"Utenti\",\n name: \"Nome\",\n email: \"Email\",\n password: \"Password\",\n passwordEditHint: \" (lascia vuoto per non modificarla)\",\n role: \"Ruolo\",\n createdAt: \"Creato il\",\n actions: \"Azioni\",\n createUser: \"Crea utente\",\n unauthorized: \"Non autorizzato\",\n notAuthenticated: \"Non autenticato\",\n allFieldsRequired: \"Tutti i campi sono obbligatori.\",\n passwordMinLength: \"La password deve avere almeno 6 caratteri.\",\n emailExists: \"Esiste già un utente con questa email.\",\n invalidRole: \"Ruolo non valido.\",\n cannotDeleteSelf: \"Non puoi eliminare il tuo stesso account.\",\n },\n common: {\n statistics: \"Statistiche\",\n settings: \"Impostazioni\",\n delete: \"Elimina\",\n edit: \"Modifica\",\n search: \"Cerca\",\n draft: \"Bozza\",\n published: \"Pubblicato\",\n all: \"Tutti\",\n drafts: \"Bozze\",\n loading: \"Caricamento...\",\n confirm: \"Conferma\",\n cancel: \"Annulla\",\n apply: \"Applica\",\n change: \"Cambia\",\n logout: \"Esci\",\n saveChanges: \"Salva modifiche\",\n updated: \"Aggiornato\",\n status: \"Stato\",\n title: \"Titolo\",\n deleteConfirm: (title) => `Eliminare \"${title || \"Senza titolo\"}\"?`,\n unpublishConfirm: (title) =>\n `Ritirare \"${title || \"Senza titolo\"}\"? L'articolo tornerà in bozza.`,\n deleteUserConfirm: (name) =>\n `Sei sicuro di voler eliminare l'utente \"${name}\"?`,\n totalArticles: (count) =>\n `${count} articol${count === 1 ? \"o\" : \"i\"} totali`,\n totalFiles: (count) => `${count} file caricati`,\n },\n};\n","import type { GELocale } from \"./types.js\";\n\nexport const en: GELocale = {\n content: {\n articles: \"Articles\",\n newArticle: \"New article\",\n titlePlaceholder: \"Article title\",\n excerptPlaceholder: \"Brief description of the article...\",\n slugPlaceholder: \"article-slug\",\n authorPlaceholder: \"Author name\",\n category: \"Category\",\n selectCategory: \"Select category\",\n excerpt: \"Excerpt\",\n author: \"Author\",\n slugUrl: \"URL Slug\",\n noArticles: \"No articles.\",\n noArticlesSearch: \"No articles found.\",\n searchArticles: \"Search articles...\",\n coverImageLabel: \"Cover image\",\n coverImageHint: \"Choose from library or upload a new file\",\n viewArticle: \"View published article\",\n untitled: \"Untitled\",\n },\n editor: {\n publish: \"Publish\",\n unpublish: \"Unpublish\",\n saveDraft: \"Save draft\",\n revisions: \"History\",\n saving: \"Saving...\",\n saved: \"Saved\",\n saveError: \"Error saving\",\n noRevisions: \"No revisions saved.\",\n restore: \"Restore\",\n restoreConfirm:\n \"Restore this revision? The current state will be saved before restoring.\",\n beforeRestore: \"Before restore\",\n publishedNote: \"Published\",\n preview: \"Preview\",\n placeholder: \"Start writing your article...\",\n },\n media: {\n media: \"Media\",\n noMedia: \"No files uploaded.\",\n noMediaSearch: \"No files found.\",\n chooseFile: \"Choose file\",\n dragHint: \"Drag an image here or\",\n uploadHint: \"JPEG, PNG, WebP, GIF (max 5MB)\",\n mediaLibrary: \"Media library\",\n uploadNew: \"Upload new\",\n searchFiles: \"Search files...\",\n selectImage: \"Select image\",\n noImages: \"No images in library.\",\n noImagesSearch: \"No images found.\",\n copyUrl: \"Copy URL\",\n editImage: \"Edit image\",\n restoreOriginal: \"Restore original\",\n freeAspect: \"Free\",\n },\n users: {\n users: \"Users\",\n name: \"Name\",\n email: \"Email\",\n password: \"Password\",\n passwordEditHint: \" (leave blank to keep current)\",\n role: \"Role\",\n createdAt: \"Created at\",\n actions: \"Actions\",\n createUser: \"Create user\",\n unauthorized: \"Unauthorized\",\n notAuthenticated: \"Not authenticated\",\n allFieldsRequired: \"All fields are required.\",\n passwordMinLength: \"Password must be at least 6 characters.\",\n emailExists: \"A user with this email already exists.\",\n invalidRole: \"Invalid role.\",\n cannotDeleteSelf: \"You cannot delete your own account.\",\n },\n common: {\n statistics: \"Statistics\",\n settings: \"Settings\",\n delete: \"Delete\",\n edit: \"Edit\",\n search: \"Search\",\n draft: \"Draft\",\n published: \"Published\",\n all: \"All\",\n drafts: \"Drafts\",\n loading: \"Loading...\",\n confirm: \"Confirm\",\n cancel: \"Cancel\",\n apply: \"Apply\",\n change: \"Change\",\n logout: \"Logout\",\n saveChanges: \"Save changes\",\n updated: \"Updated\",\n status: \"Status\",\n title: \"Title\",\n deleteConfirm: (title) => `Delete \"${title || \"Untitled\"}\"?`,\n unpublishConfirm: (title) =>\n `Unpublish \"${title || \"Untitled\"}\"? The article will go back to draft.`,\n deleteUserConfirm: (name) =>\n `Are you sure you want to delete user \"${name}\"?`,\n totalArticles: (count) =>\n `${count} total article${count === 1 ? \"\" : \"s\"}`,\n totalFiles: (count) => `${count} uploaded file${count === 1 ? \"\" : \"s\"}`,\n },\n};\n","import type { GELocale } from \"./types.js\";\nimport { it } from \"./it.js\";\nimport { en } from \"./en.js\";\n\nexport type { GELocale } from \"./types.js\";\nexport { it } from \"./it.js\";\nexport { en } from \"./en.js\";\n\nconst builtinLocales: Record<string, GELocale> = { it, en };\n\nexport function loadLocale(locale: string): GELocale {\n const found = builtinLocales[locale];\n if (!found) {\n throw new Error(\n `Locale \"${locale}\" not found. Available: ${Object.keys(builtinLocales).join(\", \")}`\n );\n }\n return found;\n}\n\nexport function defineLocale(locale: GELocale): GELocale {\n return locale;\n}\n\nexport function mergeLocales(\n base: GELocale,\n overrides: DeepPartial<GELocale>\n): GELocale {\n return deepMergeLocale(base, overrides);\n}\n\nexport function registerLocale(key: string, locale: GELocale): void {\n builtinLocales[key] = locale;\n}\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends (...args: any[]) => any\n ? T[P]\n : T[P] extends object\n ? DeepPartial<T[P]>\n : T[P];\n};\n\nfunction deepMergeLocale<T extends Record<string, any>>(\n target: T,\n source: DeepPartial<T>\n): T {\n const result = { ...target };\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal) &&\n typeof sourceVal !== \"function\"\n ) {\n (result as any)[key] = deepMergeLocale(\n targetVal as Record<string, any>,\n sourceVal as Record<string, any>\n );\n } else if (sourceVal !== undefined) {\n (result as any)[key] = sourceVal;\n }\n }\n return result;\n}\n","import { loadLocale } from \"./i18n/index.js\";\nimport type { GELocale } from \"./i18n/types.js\";\nimport type { GEAuthAdapter } from \"./auth/types.js\";\nimport type { GEContentType } from \"./content/types.js\";\nimport type { GEComponentOverrides } from \"./components/registry.js\";\n\nexport interface GavaEngineConfig {\n branding: {\n name: string;\n logo?: string;\n };\n roles: {\n list: string[];\n labels: Record<string, string>;\n canEdit: (role: string) => boolean;\n canPublish: (role: string) => boolean;\n adminRole: string;\n };\n statuses: {\n draft: string;\n published: string;\n };\n locale: string;\n models: {\n article: string;\n articleRevision: string;\n articleView: string;\n media: string;\n user: string;\n };\n auth?: GEAuthAdapter;\n contentTypes?: GEContentType[];\n components?: GEComponentOverrides;\n categories: string[];\n upload: {\n endpoint: string;\n imageTypes: string[];\n videoTypes: string[];\n maxImageSize: number;\n maxVideoSize: number;\n };\n editor: {\n placeholder: string;\n autoSaveDelay: number;\n revisionThrottleMinutes: number;\n headingLevels: number[];\n };\n routes: {\n articles: string;\n articleEdit: (id: string) => string;\n articleNew: string;\n articleView: (slug: string) => string;\n articlePreview: (id: string) => string;\n users: string;\n userEdit: (id: string) => string;\n userNew: string;\n media: string;\n dashboard: string;\n login: string;\n home: string;\n };\n strings: {\n articles: string;\n newArticle: string;\n media: string;\n users: string;\n statistics: string;\n settings: string;\n revisions: string;\n publish: string;\n unpublish: string;\n saveDraft: string;\n delete: string;\n edit: string;\n search: string;\n titlePlaceholder: string;\n excerptPlaceholder: string;\n slugPlaceholder: string;\n authorPlaceholder: string;\n category: string;\n selectCategory: string;\n excerpt: string;\n author: string;\n slugUrl: string;\n draft: string;\n published: string;\n all: string;\n drafts: string;\n saving: string;\n saved: string;\n saveError: string;\n noArticles: string;\n noArticlesSearch: string;\n noMedia: string;\n noMediaSearch: string;\n noRevisions: string;\n loading: string;\n confirm: string;\n cancel: string;\n apply: string;\n change: string;\n logout: string;\n viewArticle: string;\n preview: string;\n restore: string;\n restoreConfirm: string;\n beforeRestore: string;\n publishedNote: string;\n deleteConfirm: (title: string) => string;\n unpublishConfirm: (title: string) => string;\n deleteUserConfirm: (name: string) => string;\n totalArticles: (count: number) => string;\n totalFiles: (count: number) => string;\n coverImageLabel: string;\n coverImageHint: string;\n chooseFile: string;\n dragHint: string;\n uploadHint: string;\n mediaLibrary: string;\n uploadNew: string;\n searchFiles: string;\n searchArticles: string;\n selectImage: string;\n noImages: string;\n noImagesSearch: string;\n copyUrl: string;\n editImage: string;\n restoreOriginal: string;\n freeAspect: string;\n unauthorized: string;\n notAuthenticated: string;\n allFieldsRequired: string;\n passwordMinLength: string;\n emailExists: string;\n invalidRole: string;\n cannotDeleteSelf: string;\n name: string;\n email: string;\n password: string;\n passwordEditHint: string;\n role: string;\n createdAt: string;\n actions: string;\n createUser: string;\n saveChanges: string;\n updated: string;\n status: string;\n title: string;\n untitled: string;\n };\n}\n\nfunction localeToStrings(locale: GELocale): GavaEngineConfig[\"strings\"] {\n return {\n // content\n articles: locale.content.articles,\n newArticle: locale.content.newArticle,\n titlePlaceholder: locale.content.titlePlaceholder,\n excerptPlaceholder: locale.content.excerptPlaceholder,\n slugPlaceholder: locale.content.slugPlaceholder,\n authorPlaceholder: locale.content.authorPlaceholder,\n category: locale.content.category,\n selectCategory: locale.content.selectCategory,\n excerpt: locale.content.excerpt,\n author: locale.content.author,\n slugUrl: locale.content.slugUrl,\n noArticles: locale.content.noArticles,\n noArticlesSearch: locale.content.noArticlesSearch,\n searchArticles: locale.content.searchArticles,\n coverImageLabel: locale.content.coverImageLabel,\n coverImageHint: locale.content.coverImageHint,\n viewArticle: locale.content.viewArticle,\n untitled: locale.content.untitled,\n // editor\n publish: locale.editor.publish,\n unpublish: locale.editor.unpublish,\n saveDraft: locale.editor.saveDraft,\n revisions: locale.editor.revisions,\n saving: locale.editor.saving,\n saved: locale.editor.saved,\n saveError: locale.editor.saveError,\n noRevisions: locale.editor.noRevisions,\n restore: locale.editor.restore,\n restoreConfirm: locale.editor.restoreConfirm,\n beforeRestore: locale.editor.beforeRestore,\n publishedNote: locale.editor.publishedNote,\n preview: locale.editor.preview,\n // media\n media: locale.media.media,\n noMedia: locale.media.noMedia,\n noMediaSearch: locale.media.noMediaSearch,\n chooseFile: locale.media.chooseFile,\n dragHint: locale.media.dragHint,\n uploadHint: locale.media.uploadHint,\n mediaLibrary: locale.media.mediaLibrary,\n uploadNew: locale.media.uploadNew,\n searchFiles: locale.media.searchFiles,\n selectImage: locale.media.selectImage,\n noImages: locale.media.noImages,\n noImagesSearch: locale.media.noImagesSearch,\n copyUrl: locale.media.copyUrl,\n editImage: locale.media.editImage,\n restoreOriginal: locale.media.restoreOriginal,\n freeAspect: locale.media.freeAspect,\n // users\n users: locale.users.users,\n name: locale.users.name,\n email: locale.users.email,\n password: locale.users.password,\n passwordEditHint: locale.users.passwordEditHint,\n role: locale.users.role,\n createdAt: locale.users.createdAt,\n actions: locale.users.actions,\n createUser: locale.users.createUser,\n unauthorized: locale.users.unauthorized,\n notAuthenticated: locale.users.notAuthenticated,\n allFieldsRequired: locale.users.allFieldsRequired,\n passwordMinLength: locale.users.passwordMinLength,\n emailExists: locale.users.emailExists,\n invalidRole: locale.users.invalidRole,\n cannotDeleteSelf: locale.users.cannotDeleteSelf,\n // common\n statistics: locale.common.statistics,\n settings: locale.common.settings,\n delete: locale.common.delete,\n edit: locale.common.edit,\n search: locale.common.search,\n draft: locale.common.draft,\n published: locale.common.published,\n all: locale.common.all,\n drafts: locale.common.drafts,\n loading: locale.common.loading,\n confirm: locale.common.confirm,\n cancel: locale.common.cancel,\n apply: locale.common.apply,\n change: locale.common.change,\n logout: locale.common.logout,\n saveChanges: locale.common.saveChanges,\n updated: locale.common.updated,\n status: locale.common.status,\n title: locale.common.title,\n deleteConfirm: locale.common.deleteConfirm,\n unpublishConfirm: locale.common.unpublishConfirm,\n deleteUserConfirm: locale.common.deleteUserConfirm,\n totalArticles: locale.common.totalArticles,\n totalFiles: locale.common.totalFiles,\n };\n}\n\nconst DEFAULT_STRINGS = localeToStrings(loadLocale(\"it\"));\n\nconst DEFAULT_CONFIG: GavaEngineConfig = {\n branding: {\n name: \"GavaEngine\",\n },\n roles: {\n list: [\"admin\", \"redattore\", \"scrittore\", \"lettore\"],\n labels: {\n admin: \"Amministratore\",\n redattore: \"Redattore\",\n scrittore: \"Scrittore\",\n lettore: \"Lettore\",\n },\n canEdit: (role: string) => role !== \"lettore\",\n canPublish: (role: string) => role === \"admin\" || role === \"redattore\",\n adminRole: \"admin\",\n },\n statuses: {\n draft: \"bozza\",\n published: \"pubblicato\",\n },\n locale: \"it\",\n models: {\n article: \"article\",\n articleRevision: \"articleRevision\",\n articleView: \"articleView\",\n media: \"media\",\n user: \"user\",\n },\n categories: [\n \"Cultura ed Intercultura\",\n \"Fatti ed Eventi\",\n \"Poeti e Prosatori\",\n \"Famiglia, Istituzioni e Territorio\",\n \"Amici del Meucci\",\n ],\n upload: {\n endpoint: \"/api/upload\",\n imageTypes: [\"image/jpeg\", \"image/png\", \"image/webp\", \"image/gif\"],\n videoTypes: [\"video/mp4\", \"video/webm\", \"video/quicktime\"],\n maxImageSize: 5 * 1024 * 1024,\n maxVideoSize: 50 * 1024 * 1024,\n },\n editor: {\n placeholder: \"Inizia a scrivere il tuo articolo...\",\n autoSaveDelay: 2000,\n revisionThrottleMinutes: 5,\n headingLevels: [2, 3],\n },\n routes: {\n articles: \"/dashboard/articoli\",\n articleEdit: (id) => `/dashboard/articoli/${id}`,\n articleNew: \"/dashboard/articoli/nuovo\",\n articleView: (slug) => `/articoli/${slug}`,\n articlePreview: (id) => `/anteprima/${id}`,\n users: \"/dashboard/utenti\",\n userEdit: (id) => `/dashboard/utenti/${id}`,\n userNew: \"/dashboard/utenti/nuovo\",\n media: \"/dashboard/media\",\n dashboard: \"/dashboard\",\n login: \"/login\",\n home: \"/\",\n },\n strings: DEFAULT_STRINGS,\n};\n\nfunction deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal) &&\n typeof sourceVal !== \"function\"\n ) {\n (result as any)[key] = deepMerge(\n targetVal as Record<string, any>,\n sourceVal as Record<string, any>\n );\n } else if (sourceVal !== undefined) {\n (result as any)[key] = sourceVal;\n }\n }\n return result;\n}\n\nexport function defineConfig(\n overrides: Partial<GavaEngineConfig> = {}\n): GavaEngineConfig {\n // If a different locale is specified, load it as base strings\n const locale = overrides.locale ?? DEFAULT_CONFIG.locale;\n const baseStrings = localeToStrings(loadLocale(locale));\n\n // Build config with locale-based strings as default\n const configWithLocale = {\n ...DEFAULT_CONFIG,\n strings: baseStrings,\n };\n\n // Also update editor.placeholder from locale if not overridden\n if (!overrides.editor?.placeholder) {\n const localeData = loadLocale(locale);\n configWithLocale.editor = {\n ...configWithLocale.editor,\n placeholder: localeData.editor.placeholder,\n };\n }\n\n return deepMerge(configWithLocale, overrides);\n}\n\nexport { DEFAULT_CONFIG, localeToStrings };\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createRevisionHandlers(prisma: any, config: GavaEngineConfig) {\n const throttleMs = config.editor.revisionThrottleMinutes * 60 * 1000;\n const articleModel = config.models.article;\n const revisionModel = config.models.articleRevision;\n\n return {\n async getRevisions(articleId: string) {\n return prisma[revisionModel].findMany({\n where: { articleId },\n include: { editor: { select: { name: true } } },\n orderBy: { createdAt: \"desc\" },\n });\n },\n\n async restoreRevision(\n articleId: string,\n revisionId: string,\n editorId: string\n ) {\n const article = await prisma[articleModel].findUnique({\n where: { id: articleId },\n });\n if (!article) throw new Error(\"Article not found\");\n\n const revision = await prisma[revisionModel].findUnique({\n where: { id: revisionId },\n });\n if (!revision || revision.articleId !== articleId) {\n throw new Error(\"Revision not found\");\n }\n\n // Save current state before restoring\n await prisma[revisionModel].create({\n data: {\n articleId,\n title: article.title,\n content: article.content,\n excerpt: article.excerpt,\n coverImage: article.coverImage,\n category: article.category,\n editorId,\n note: config.strings.beforeRestore,\n },\n });\n\n // Restore\n await prisma[articleModel].update({\n where: { id: articleId },\n data: {\n title: revision.title,\n content: revision.content,\n excerpt: revision.excerpt,\n coverImage: revision.coverImage,\n category: revision.category,\n updatedAt: new Date(),\n },\n });\n\n return { success: true };\n },\n\n async createRevisionSnapshot(\n articleId: string,\n editorId: string,\n note: string = \"\"\n ) {\n const article = await prisma[articleModel].findUnique({\n where: { id: articleId },\n });\n if (!article) return;\n\n // Throttle: only create if last revision was > threshold ago\n const threshold = new Date(Date.now() - throttleMs);\n const recent = await prisma[revisionModel].findFirst({\n where: { articleId, createdAt: { gte: threshold } },\n orderBy: { createdAt: \"desc\" },\n });\n\n if (recent && !note) return;\n\n await prisma[revisionModel].create({\n data: {\n articleId,\n title: article.title,\n content: article.content,\n excerpt: article.excerpt,\n coverImage: article.coverImage,\n category: article.category,\n editorId,\n note,\n },\n });\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\nimport { createRevisionHandlers } from \"./revisions.js\";\n\nexport function createArticleHandlers(prisma: any, config: GavaEngineConfig) {\n const revisionHandlers = createRevisionHandlers(prisma, config);\n const articleModel = config.models.article;\n\n return {\n async getArticles() {\n return prisma[articleModel].findMany({\n orderBy: { updatedAt: \"desc\" },\n });\n },\n\n async getArticleById(id: string) {\n return prisma[articleModel].findUnique({\n where: { id },\n });\n },\n\n async createArticle(authorName: string) {\n const article = await prisma[articleModel].create({\n data: {\n authorName,\n },\n });\n return article.id;\n },\n\n async updateArticle(\n userId: string,\n id: string,\n data: {\n title?: string;\n slug?: string;\n excerpt?: string;\n content?: string;\n coverImage?: string;\n category?: string;\n authorName?: string;\n }\n ) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await revisionHandlers.createRevisionSnapshot(id, userId);\n\n await prisma[articleModel].update({\n where: { id },\n data: { ...data, updatedAt: new Date() },\n });\n\n return { success: true };\n },\n\n async deleteArticle(id: string) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await prisma[articleModel].delete({ where: { id } });\n return { success: true };\n },\n\n async publishArticle(userId: string, id: string) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n if (!article.title || !article.slug) {\n throw new Error(\n \"Title and slug are required for publishing\"\n );\n }\n\n await revisionHandlers.createRevisionSnapshot(\n id,\n userId,\n config.strings.publishedNote\n );\n\n await prisma[articleModel].update({\n where: { id },\n data: {\n status: config.statuses.published,\n publishedAt: new Date(),\n },\n });\n\n return { success: true };\n },\n\n async unpublishArticle(id: string) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await prisma[articleModel].update({\n where: { id },\n data: {\n status: config.statuses.draft,\n publishedAt: null,\n },\n });\n\n return { success: true };\n },\n };\n}\n","import bcrypt from \"bcryptjs\";\nimport type { GavaEngineConfig } from \"../config.js\";\n\nexport function createUserHandlers(prisma: any, config: GavaEngineConfig) {\n const userModel = config.models.user;\n\n return {\n async getUsers() {\n return prisma[userModel].findMany({\n select: {\n id: true,\n name: true,\n email: true,\n role: true,\n createdAt: true,\n },\n orderBy: { createdAt: \"desc\" },\n });\n },\n\n async getUserById(id: string) {\n return prisma[userModel].findUnique({\n where: { id },\n select: {\n id: true,\n name: true,\n email: true,\n role: true,\n },\n });\n },\n\n async createUser(formData: FormData) {\n const name = formData.get(\"name\") as string;\n const email = formData.get(\"email\") as string;\n const password = formData.get(\"password\") as string;\n const role = formData.get(\"role\") as string;\n\n if (!name || !email || !password || !role) {\n return { error: config.strings.allFieldsRequired };\n }\n\n if (!config.roles.list.includes(role)) {\n return { error: config.strings.invalidRole };\n }\n\n if (password.length < 6) {\n return { error: config.strings.passwordMinLength };\n }\n\n const existing = await prisma[userModel].findUnique({ where: { email } });\n if (existing) {\n return { error: config.strings.emailExists };\n }\n\n const hashedPassword = await bcrypt.hash(password, 10);\n\n await prisma[userModel].create({\n data: {\n name,\n email,\n password: hashedPassword,\n role,\n },\n });\n\n return { success: true };\n },\n\n async updateUser(id: string, formData: FormData) {\n const name = formData.get(\"name\") as string;\n const email = formData.get(\"email\") as string;\n const password = formData.get(\"password\") as string;\n const role = formData.get(\"role\") as string;\n\n if (!name || !email || !role) {\n return { error: config.strings.allFieldsRequired };\n }\n\n if (!config.roles.list.includes(role)) {\n return { error: config.strings.invalidRole };\n }\n\n const existing = await prisma[userModel].findUnique({ where: { email } });\n if (existing && existing.id !== id) {\n return { error: config.strings.emailExists };\n }\n\n const data: {\n name: string;\n email: string;\n role: string;\n password?: string;\n } = {\n name,\n email,\n role,\n };\n\n if (password && password.length > 0) {\n if (password.length < 6) {\n return { error: config.strings.passwordMinLength };\n }\n data.password = await bcrypt.hash(password, 10);\n }\n\n await prisma[userModel].update({\n where: { id },\n data,\n });\n\n return { success: true };\n },\n\n async deleteUser(currentUserId: string, id: string) {\n if (currentUserId === id) {\n return { error: config.strings.cannotDeleteSelf };\n }\n\n await prisma[userModel].delete({ where: { id } });\n return { success: true };\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createMediaHandlers(prisma: any, config: GavaEngineConfig) {\n const mediaModel = config.models.media;\n const articleModel = config.models.article;\n\n return {\n async getMedia(search?: string) {\n return prisma[mediaModel].findMany({\n where: search ? { filename: { contains: search } } : undefined,\n include: { uploader: { select: { name: true } } },\n orderBy: { createdAt: \"desc\" },\n });\n },\n\n async deleteMedia(\n userId: string,\n userRole: string,\n id: string,\n deleteFileFromDisk?: (path: string) => Promise<void>\n ) {\n const media = await prisma[mediaModel].findUnique({ where: { id } });\n if (!media) throw new Error(\"File not found\");\n\n // Writers can only delete their own media\n if (userRole === \"scrittore\" && media.uploaderId !== userId) {\n throw new Error(\"Unauthorized\");\n }\n\n // Check if image is used in articles\n const usedInArticles = await prisma[articleModel].findMany({\n where: {\n OR: [\n { coverImage: media.path },\n { content: { contains: media.path } },\n ],\n },\n select: { id: true, title: true },\n });\n\n if (usedInArticles.length > 0) {\n const titles = usedInArticles\n .map((a: { title: string }) => a.title || \"Untitled\")\n .join(\", \");\n throw new Error(\n `Cannot delete: image is used in ${usedInArticles.length} article(s) (${titles})`\n );\n }\n\n // Delete file from disk if handler provided\n if (deleteFileFromDisk) {\n try {\n await deleteFileFromDisk(media.path);\n } catch {\n // File may already be missing\n }\n }\n\n await prisma[mediaModel].delete({ where: { id } });\n return { success: true };\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport interface UploadResult {\n url?: string;\n error?: string;\n}\n\nexport interface FileStorage {\n save(filename: string, buffer: Buffer, mimeType: string): Promise<string>;\n}\n\nexport function createUploadHandler(\n prisma: any,\n config: GavaEngineConfig,\n storage: FileStorage\n) {\n const allowedTypes = [\n ...config.upload.imageTypes,\n ...config.upload.videoTypes,\n ];\n\n const mediaModel = config.models.media;\n\n return {\n async handleUpload(\n file: {\n name: string;\n type: string;\n size: number;\n arrayBuffer: () => Promise<ArrayBuffer>;\n },\n uploaderId: string\n ): Promise<UploadResult> {\n if (!allowedTypes.includes(file.type)) {\n return { error: \"Unsupported file type\" };\n }\n\n const isVideo = config.upload.videoTypes.includes(file.type);\n const maxSize = isVideo\n ? config.upload.maxVideoSize\n : config.upload.maxImageSize;\n\n if (file.size > maxSize) {\n return {\n error: `File too large. Max ${isVideo ? config.upload.maxVideoSize / (1024 * 1024) : config.upload.maxImageSize / (1024 * 1024)}MB.`,\n };\n }\n\n const buffer = Buffer.from(await file.arrayBuffer());\n const url = await storage.save(file.name, buffer, file.type);\n\n await prisma[mediaModel].create({\n data: {\n filename: file.name,\n path: url,\n mimeType: file.type,\n size: file.size,\n uploaderId,\n },\n });\n\n return { url };\n },\n };\n}\n","import bcrypt from \"bcryptjs\";\nimport type { GavaEngineConfig } from \"../config.js\";\n\nexport function buildCredentialsProvider(prisma: any, config?: GavaEngineConfig) {\n const userModel = config?.models?.user ?? \"user\";\n\n return {\n credentials: {\n email: {},\n password: {},\n },\n async authorize(credentials: Record<string, unknown>) {\n const email = credentials.email as string;\n const password = credentials.password as string;\n\n if (!email || !password) return null;\n\n const user = await prisma[userModel].findUnique({\n where: { email },\n });\n\n if (!user) return null;\n\n const isValid = await bcrypt.compare(password, user.password);\n if (!isValid) return null;\n\n return {\n id: user.id,\n name: user.name,\n email: user.email,\n role: user.role,\n };\n },\n };\n}\n\nexport function buildAuthCallbacks(config: GavaEngineConfig) {\n return {\n async jwt({\n token,\n user,\n }: {\n token: Record<string, unknown>;\n user?: Record<string, unknown>;\n }) {\n if (user) {\n token.id = user.id as string;\n token.role = user.role as string;\n }\n return token;\n },\n async session({\n session,\n token,\n }: {\n session: Record<string, any>;\n token: Record<string, unknown>;\n }) {\n if (session.user) {\n session.user.id = token.id as string;\n session.user.role = token.role as string;\n }\n return session;\n },\n authorized({\n auth,\n request: { nextUrl },\n }: {\n auth: Record<string, any> | null;\n request: { nextUrl: URL };\n }) {\n const isLoggedIn = !!auth;\n const role = auth?.user?.role;\n const pathname = nextUrl.pathname;\n\n if (pathname === config.routes.login && isLoggedIn) {\n return Response.redirect(new URL(config.routes.articles, nextUrl));\n }\n\n if (pathname.startsWith(config.routes.dashboard)) {\n if (!isLoggedIn) {\n return Response.redirect(new URL(config.routes.login, nextUrl));\n }\n\n if (\n pathname.startsWith(config.routes.users) &&\n role !== config.roles.adminRole\n ) {\n return Response.redirect(\n new URL(config.routes.articles, nextUrl)\n );\n }\n }\n\n return true;\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createAuthUtils(config: GavaEngineConfig) {\n return {\n canEdit(role: string): boolean {\n return config.roles.canEdit(role);\n },\n canPublish(role: string): boolean {\n return config.roles.canPublish(role);\n },\n isAdmin(role: string): boolean {\n return role === config.roles.adminRole;\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\nimport type { GEContentType } from \"../content/types.js\";\n\nexport interface ContentHandlers {\n getAll(options?: {\n search?: string;\n status?: string;\n orderBy?: Record<string, \"asc\" | \"desc\">;\n }): Promise<any[]>;\n getById(id: string): Promise<any | null>;\n create(data?: Record<string, any>): Promise<string>;\n update(id: string, data: Record<string, any>): Promise<{ success: boolean }>;\n delete(id: string): Promise<{ success: boolean }>;\n publish?(userId: string, id: string): Promise<{ success: boolean }>;\n unpublish?(id: string): Promise<{ success: boolean }>;\n}\n\nexport function createContentHandlers(\n prisma: any,\n contentType: GEContentType,\n config: GavaEngineConfig\n): ContentHandlers {\n const modelName = contentType.slug.replace(/s$/, \"\").replace(/(^|\\-)(\\w)/g, (_m, _p1, p2) => p2.toUpperCase());\n // Try to find the Prisma model — fallback to slug\n const model = prisma[modelName] ?? prisma[contentType.slug];\n\n if (!model) {\n throw new Error(\n `Prisma model \"${modelName}\" not found for content type \"${contentType.slug}\"`\n );\n }\n\n const defaultSort = contentType.admin?.defaultSort\n ? { [contentType.admin.defaultSort.field]: contentType.admin.defaultSort.direction }\n : { updatedAt: \"desc\" };\n\n const searchableFields = contentType.admin?.searchableFields ?? [\"title\"];\n\n return {\n async getAll(options) {\n const where: Record<string, any> = {};\n\n if (options?.search) {\n where.OR = searchableFields.map((field) => ({\n [field]: { contains: options.search },\n }));\n }\n\n if (options?.status) {\n where.status = options.status;\n }\n\n return model.findMany({\n where: Object.keys(where).length > 0 ? where : undefined,\n orderBy: options?.orderBy ?? defaultSort,\n });\n },\n\n async getById(id: string) {\n return model.findUnique({ where: { id } });\n },\n\n async create(data?: Record<string, any>) {\n const createData: Record<string, any> = {};\n\n // Set default values from field definitions\n for (const field of contentType.fields) {\n if (field.defaultValue !== undefined) {\n createData[field.name] = field.defaultValue;\n }\n }\n\n // Set default status\n if (contentType.defaultStatus) {\n createData.status = contentType.defaultStatus;\n }\n\n // Merge provided data\n if (data) {\n Object.assign(createData, data);\n }\n\n const record = await model.create({\n data: createData,\n });\n\n return record.id;\n },\n\n async update(id: string, data: Record<string, any>) {\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.update({\n where: { id },\n data: { ...data, updatedAt: new Date() },\n });\n\n return { success: true };\n },\n\n async delete(id: string) {\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.delete({ where: { id } });\n return { success: true };\n },\n\n async publish(userId: string, id: string) {\n if (!contentType.publishedStatus) return { success: false };\n\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.update({\n where: { id },\n data: {\n status: contentType.publishedStatus,\n publishedAt: new Date(),\n },\n });\n\n return { success: true };\n },\n\n async unpublish(id: string) {\n if (!contentType.defaultStatus) return { success: false };\n\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.update({\n where: { id },\n data: {\n status: contentType.defaultStatus,\n publishedAt: null,\n },\n });\n\n return { success: true };\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createCategoryHandlers(prisma: any, config: GavaEngineConfig) {\n const categoryModel = prisma.category;\n\n return {\n async getCategories() {\n if (!categoryModel) {\n // Fallback: return config categories as static list\n return config.categories.map((name, i) => ({\n id: `static-${i}`,\n name,\n slug: name.toLowerCase().replace(/\\s+/g, \"-\"),\n sortOrder: i,\n }));\n }\n\n return categoryModel.findMany({\n orderBy: { sortOrder: \"asc\" },\n });\n },\n\n async createCategory(data: { name: string; slug?: string; sortOrder?: number }) {\n if (!categoryModel) {\n throw new Error(\"Category model not available — categories are static from config\");\n }\n\n const slug =\n data.slug ??\n data.name\n .toLowerCase()\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\");\n\n return categoryModel.create({\n data: {\n name: data.name,\n slug,\n sortOrder: data.sortOrder ?? 0,\n },\n });\n },\n\n async updateCategory(\n id: string,\n data: { name?: string; slug?: string; sortOrder?: number }\n ) {\n if (!categoryModel) {\n throw new Error(\"Category model not available — categories are static from config\");\n }\n\n return categoryModel.update({\n where: { id },\n data,\n });\n },\n\n async deleteCategory(id: string) {\n if (!categoryModel) {\n throw new Error(\"Category model not available — categories are static from config\");\n }\n\n await categoryModel.delete({ where: { id } });\n return { success: true };\n },\n\n async seedCategories() {\n if (!categoryModel) return;\n\n const existing = await categoryModel.count();\n if (existing > 0) return;\n\n for (let i = 0; i < config.categories.length; i++) {\n const name = config.categories[i];\n const slug = name\n .toLowerCase()\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\");\n\n await categoryModel.create({\n data: {\n name,\n slug,\n sortOrder: i,\n },\n });\n }\n },\n };\n}\n"],"mappings":"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","names":["bcrypt"]}
1
+ {"version":3,"sources":["../../src/i18n/it.ts","../../src/i18n/en.ts","../../src/i18n/index.ts","../../src/config.ts","../../src/handlers/revisions.ts","../../src/handlers/articles.ts","../../src/handlers/users.ts","../../src/handlers/media.ts","../../src/handlers/upload.ts","../../src/handlers/auth.ts","../../src/handlers/auth-utils.ts","../../src/handlers/content.ts","../../src/handlers/categories.ts"],"sourcesContent":["import type { GELocale } from \"./types.js\";\n\nexport const it: GELocale = {\n content: {\n articles: \"Articoli\",\n newArticle: \"Nuovo articolo\",\n titlePlaceholder: \"Titolo dell'articolo\",\n excerptPlaceholder: \"Breve descrizione dell'articolo...\",\n slugPlaceholder: \"slug-articolo\",\n authorPlaceholder: \"Nome dell'autore\",\n category: \"Categoria\",\n selectCategory: \"Seleziona categoria\",\n excerpt: \"Estratto\",\n author: \"Autore\",\n slugUrl: \"Slug URL\",\n noArticles: \"Nessun articolo.\",\n noArticlesSearch: \"Nessun articolo trovato.\",\n searchArticles: \"Cerca articoli...\",\n coverImageLabel: \"Immagine di copertina\",\n coverImageHint: \"Scegli dalla libreria o carica un nuovo file\",\n viewArticle: \"Vedi articolo pubblicato\",\n untitled: \"Senza titolo\",\n },\n editor: {\n publish: \"Pubblica\",\n unpublish: \"Ritira\",\n saveDraft: \"Salva bozza\",\n revisions: \"Cronologia\",\n saving: \"Salvando...\",\n saved: \"Salvato\",\n saveError: \"Errore nel salvataggio\",\n noRevisions: \"Nessuna revisione salvata.\",\n restore: \"Ripristina\",\n restoreConfirm:\n \"Ripristinare questa revisione? Lo stato attuale verrà salvato prima del ripristino.\",\n beforeRestore: \"Prima del ripristino\",\n publishedNote: \"Pubblicato\",\n preview: \"Anteprima\",\n placeholder: \"Inizia a scrivere il tuo articolo...\",\n bold: \"Grassetto\",\n italic: \"Corsivo\",\n underline: \"Sottolineato\",\n strikethrough: \"Barrato\",\n superscript: \"Apice\",\n subscript: \"Pedice\",\n textColor: \"Colore testo\",\n highlight: \"Evidenzia\",\n heading2: \"H2\",\n heading3: \"H3\",\n bulletList: \"Elenco puntato\",\n numberedList: \"Elenco numerato\",\n quote: \"Citazione\",\n codeBlock: \"Blocco codice\",\n divider: \"Separatore\",\n alignLeft: \"Allinea a sinistra\",\n alignCenter: \"Allinea al centro\",\n alignRight: \"Allinea a destra\",\n table: \"Tabella\",\n insertTable: \"Inserisci tabella 3×3\",\n addRowAbove: \"Aggiungi riga sopra\",\n addRowBelow: \"Aggiungi riga sotto\",\n addColumnLeft: \"Aggiungi colonna a sinistra\",\n addColumnRight: \"Aggiungi colonna a destra\",\n deleteRow: \"Elimina riga\",\n deleteColumn: \"Elimina colonna\",\n deleteTable: \"Elimina tabella\",\n link: \"Link\",\n image: \"Immagine\",\n youtube: \"YouTube\",\n video: \"Video\",\n undo: \"Annulla\",\n redo: \"Ripeti\",\n defaultColor: \"Predefinito\",\n removeHighlight: \"Rimuovi\",\n linkPrompt: \"URL:\",\n youtubePrompt: \"URL YouTube:\",\n },\n media: {\n media: \"Media\",\n noMedia: \"Nessun file caricato.\",\n noMediaSearch: \"Nessun file trovato.\",\n chooseFile: \"Scegli file\",\n dragHint: \"Trascina un'immagine qui oppure\",\n uploadHint: \"JPEG, PNG, WebP, GIF (max 5MB)\",\n mediaLibrary: \"Libreria media\",\n uploadNew: \"Carica nuovo\",\n searchFiles: \"Cerca file...\",\n selectImage: \"Seleziona immagine\",\n noImages: \"Nessuna immagine nella libreria.\",\n noImagesSearch: \"Nessuna immagine trovata.\",\n copyUrl: \"Copia URL\",\n editImage: \"Modifica immagine\",\n restoreOriginal: \"Ripristina originale\",\n freeAspect: \"Libero\",\n },\n users: {\n users: \"Utenti\",\n name: \"Nome\",\n email: \"Email\",\n password: \"Password\",\n passwordEditHint: \" (lascia vuoto per non modificarla)\",\n role: \"Ruolo\",\n createdAt: \"Creato il\",\n actions: \"Azioni\",\n createUser: \"Crea utente\",\n unauthorized: \"Non autorizzato\",\n notAuthenticated: \"Non autenticato\",\n allFieldsRequired: \"Tutti i campi sono obbligatori.\",\n passwordMinLength: \"La password deve avere almeno 6 caratteri.\",\n emailExists: \"Esiste già un utente con questa email.\",\n invalidRole: \"Ruolo non valido.\",\n cannotDeleteSelf: \"Non puoi eliminare il tuo stesso account.\",\n },\n common: {\n statistics: \"Statistiche\",\n settings: \"Impostazioni\",\n delete: \"Elimina\",\n edit: \"Modifica\",\n search: \"Cerca\",\n draft: \"Bozza\",\n published: \"Pubblicato\",\n all: \"Tutti\",\n drafts: \"Bozze\",\n loading: \"Caricamento...\",\n confirm: \"Conferma\",\n cancel: \"Annulla\",\n apply: \"Applica\",\n change: \"Cambia\",\n logout: \"Esci\",\n saveChanges: \"Salva modifiche\",\n updated: \"Aggiornato\",\n status: \"Stato\",\n title: \"Titolo\",\n deleteConfirm: (title) => `Eliminare \"${title || \"Senza titolo\"}\"?`,\n unpublishConfirm: (title) =>\n `Ritirare \"${title || \"Senza titolo\"}\"? L'articolo tornerà in bozza.`,\n deleteUserConfirm: (name) =>\n `Sei sicuro di voler eliminare l'utente \"${name}\"?`,\n totalArticles: (count) =>\n `${count} articol${count === 1 ? \"o\" : \"i\"} totali`,\n totalFiles: (count) => `${count} file caricati`,\n },\n};\n","import type { GELocale } from \"./types.js\";\n\nexport const en: GELocale = {\n content: {\n articles: \"Articles\",\n newArticle: \"New article\",\n titlePlaceholder: \"Article title\",\n excerptPlaceholder: \"Brief description of the article...\",\n slugPlaceholder: \"article-slug\",\n authorPlaceholder: \"Author name\",\n category: \"Category\",\n selectCategory: \"Select category\",\n excerpt: \"Excerpt\",\n author: \"Author\",\n slugUrl: \"URL Slug\",\n noArticles: \"No articles.\",\n noArticlesSearch: \"No articles found.\",\n searchArticles: \"Search articles...\",\n coverImageLabel: \"Cover image\",\n coverImageHint: \"Choose from library or upload a new file\",\n viewArticle: \"View published article\",\n untitled: \"Untitled\",\n },\n editor: {\n publish: \"Publish\",\n unpublish: \"Unpublish\",\n saveDraft: \"Save draft\",\n revisions: \"History\",\n saving: \"Saving...\",\n saved: \"Saved\",\n saveError: \"Error saving\",\n noRevisions: \"No revisions saved.\",\n restore: \"Restore\",\n restoreConfirm:\n \"Restore this revision? The current state will be saved before restoring.\",\n beforeRestore: \"Before restore\",\n publishedNote: \"Published\",\n preview: \"Preview\",\n placeholder: \"Start writing your article...\",\n bold: \"Bold\",\n italic: \"Italic\",\n underline: \"Underline\",\n strikethrough: \"Strikethrough\",\n superscript: \"Superscript\",\n subscript: \"Subscript\",\n textColor: \"Text color\",\n highlight: \"Highlight\",\n heading2: \"H2\",\n heading3: \"H3\",\n bulletList: \"Bullet list\",\n numberedList: \"Numbered list\",\n quote: \"Quote\",\n codeBlock: \"Code block\",\n divider: \"Divider\",\n alignLeft: \"Align left\",\n alignCenter: \"Align center\",\n alignRight: \"Align right\",\n table: \"Table\",\n insertTable: \"Insert 3×3 table\",\n addRowAbove: \"Add row above\",\n addRowBelow: \"Add row below\",\n addColumnLeft: \"Add column left\",\n addColumnRight: \"Add column right\",\n deleteRow: \"Delete row\",\n deleteColumn: \"Delete column\",\n deleteTable: \"Delete table\",\n link: \"Link\",\n image: \"Image\",\n youtube: \"YouTube\",\n video: \"Video\",\n undo: \"Undo\",\n redo: \"Redo\",\n defaultColor: \"Default\",\n removeHighlight: \"Remove\",\n linkPrompt: \"URL:\",\n youtubePrompt: \"YouTube URL:\",\n },\n media: {\n media: \"Media\",\n noMedia: \"No files uploaded.\",\n noMediaSearch: \"No files found.\",\n chooseFile: \"Choose file\",\n dragHint: \"Drag an image here or\",\n uploadHint: \"JPEG, PNG, WebP, GIF (max 5MB)\",\n mediaLibrary: \"Media library\",\n uploadNew: \"Upload new\",\n searchFiles: \"Search files...\",\n selectImage: \"Select image\",\n noImages: \"No images in library.\",\n noImagesSearch: \"No images found.\",\n copyUrl: \"Copy URL\",\n editImage: \"Edit image\",\n restoreOriginal: \"Restore original\",\n freeAspect: \"Free\",\n },\n users: {\n users: \"Users\",\n name: \"Name\",\n email: \"Email\",\n password: \"Password\",\n passwordEditHint: \" (leave blank to keep current)\",\n role: \"Role\",\n createdAt: \"Created at\",\n actions: \"Actions\",\n createUser: \"Create user\",\n unauthorized: \"Unauthorized\",\n notAuthenticated: \"Not authenticated\",\n allFieldsRequired: \"All fields are required.\",\n passwordMinLength: \"Password must be at least 6 characters.\",\n emailExists: \"A user with this email already exists.\",\n invalidRole: \"Invalid role.\",\n cannotDeleteSelf: \"You cannot delete your own account.\",\n },\n common: {\n statistics: \"Statistics\",\n settings: \"Settings\",\n delete: \"Delete\",\n edit: \"Edit\",\n search: \"Search\",\n draft: \"Draft\",\n published: \"Published\",\n all: \"All\",\n drafts: \"Drafts\",\n loading: \"Loading...\",\n confirm: \"Confirm\",\n cancel: \"Cancel\",\n apply: \"Apply\",\n change: \"Change\",\n logout: \"Logout\",\n saveChanges: \"Save changes\",\n updated: \"Updated\",\n status: \"Status\",\n title: \"Title\",\n deleteConfirm: (title) => `Delete \"${title || \"Untitled\"}\"?`,\n unpublishConfirm: (title) =>\n `Unpublish \"${title || \"Untitled\"}\"? The article will go back to draft.`,\n deleteUserConfirm: (name) =>\n `Are you sure you want to delete user \"${name}\"?`,\n totalArticles: (count) =>\n `${count} total article${count === 1 ? \"\" : \"s\"}`,\n totalFiles: (count) => `${count} uploaded file${count === 1 ? \"\" : \"s\"}`,\n },\n};\n","import type { GELocale } from \"./types.js\";\nimport { it } from \"./it.js\";\nimport { en } from \"./en.js\";\n\nexport type { GELocale } from \"./types.js\";\nexport { it } from \"./it.js\";\nexport { en } from \"./en.js\";\n\nconst builtinLocales: Record<string, GELocale> = { it, en };\n\nexport function loadLocale(locale: string): GELocale {\n const found = builtinLocales[locale];\n if (!found) {\n throw new Error(\n `Locale \"${locale}\" not found. Available: ${Object.keys(builtinLocales).join(\", \")}`\n );\n }\n return found;\n}\n\nexport function defineLocale(locale: GELocale): GELocale {\n return locale;\n}\n\nexport function mergeLocales(\n base: GELocale,\n overrides: DeepPartial<GELocale>\n): GELocale {\n return deepMergeLocale(base, overrides);\n}\n\nexport function registerLocale(key: string, locale: GELocale): void {\n builtinLocales[key] = locale;\n}\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends (...args: any[]) => any\n ? T[P]\n : T[P] extends object\n ? DeepPartial<T[P]>\n : T[P];\n};\n\nfunction deepMergeLocale<T extends Record<string, any>>(\n target: T,\n source: DeepPartial<T>\n): T {\n const result = { ...target };\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal) &&\n typeof sourceVal !== \"function\"\n ) {\n (result as any)[key] = deepMergeLocale(\n targetVal as Record<string, any>,\n sourceVal as Record<string, any>\n );\n } else if (sourceVal !== undefined) {\n (result as any)[key] = sourceVal;\n }\n }\n return result;\n}\n","import { loadLocale } from \"./i18n/index.js\";\nimport type { GELocale } from \"./i18n/types.js\";\nimport type { GEAuthAdapter } from \"./auth/types.js\";\nimport type { GEContentType } from \"./content/types.js\";\nimport type { GEComponentOverrides } from \"./components/registry.js\";\nimport type { GENavItem, GESplashConfig, GEColorOption } from \"./types.js\";\n\nexport interface GavaEngineConfig {\n branding: {\n name: string;\n logo?: string;\n };\n roles: {\n list: string[];\n labels: Record<string, string>;\n canEdit: (role: string) => boolean;\n canPublish: (role: string) => boolean;\n adminRole: string;\n };\n statuses: {\n draft: string;\n published: string;\n };\n locale: string;\n models: {\n article: string;\n articleRevision: string;\n articleView: string;\n media: string;\n user: string;\n };\n navigation?: GENavItem[];\n splash?: GESplashConfig;\n editorToolbar?: {\n textColors?: GEColorOption[];\n highlightColors?: GEColorOption[];\n };\n auth?: GEAuthAdapter;\n contentTypes?: GEContentType[];\n components?: GEComponentOverrides;\n categories: string[];\n upload: {\n endpoint: string;\n imageTypes: string[];\n videoTypes: string[];\n maxImageSize: number;\n maxVideoSize: number;\n };\n editor: {\n placeholder: string;\n autoSaveDelay: number;\n revisionThrottleMinutes: number;\n headingLevels: number[];\n };\n routes: {\n articles: string;\n articleEdit: (id: string) => string;\n articleNew: string;\n articleView: (slug: string) => string;\n articlePreview: (id: string) => string;\n users: string;\n userEdit: (id: string) => string;\n userNew: string;\n media: string;\n dashboard: string;\n statistics: string;\n login: string;\n home: string;\n };\n strings: {\n articles: string;\n newArticle: string;\n media: string;\n users: string;\n statistics: string;\n settings: string;\n revisions: string;\n publish: string;\n unpublish: string;\n saveDraft: string;\n delete: string;\n edit: string;\n search: string;\n titlePlaceholder: string;\n excerptPlaceholder: string;\n slugPlaceholder: string;\n authorPlaceholder: string;\n category: string;\n selectCategory: string;\n excerpt: string;\n author: string;\n slugUrl: string;\n draft: string;\n published: string;\n all: string;\n drafts: string;\n saving: string;\n saved: string;\n saveError: string;\n noArticles: string;\n noArticlesSearch: string;\n noMedia: string;\n noMediaSearch: string;\n noRevisions: string;\n loading: string;\n confirm: string;\n cancel: string;\n apply: string;\n change: string;\n logout: string;\n viewArticle: string;\n preview: string;\n restore: string;\n restoreConfirm: string;\n beforeRestore: string;\n publishedNote: string;\n deleteConfirm: (title: string) => string;\n unpublishConfirm: (title: string) => string;\n deleteUserConfirm: (name: string) => string;\n totalArticles: (count: number) => string;\n totalFiles: (count: number) => string;\n coverImageLabel: string;\n coverImageHint: string;\n chooseFile: string;\n dragHint: string;\n uploadHint: string;\n mediaLibrary: string;\n uploadNew: string;\n searchFiles: string;\n searchArticles: string;\n selectImage: string;\n noImages: string;\n noImagesSearch: string;\n copyUrl: string;\n editImage: string;\n restoreOriginal: string;\n freeAspect: string;\n unauthorized: string;\n notAuthenticated: string;\n allFieldsRequired: string;\n passwordMinLength: string;\n emailExists: string;\n invalidRole: string;\n cannotDeleteSelf: string;\n name: string;\n email: string;\n password: string;\n passwordEditHint: string;\n role: string;\n createdAt: string;\n actions: string;\n createUser: string;\n saveChanges: string;\n updated: string;\n status: string;\n title: string;\n untitled: string;\n // Toolbar\n bold: string;\n italic: string;\n underline: string;\n strikethrough: string;\n superscript: string;\n subscript: string;\n textColor: string;\n highlight: string;\n heading2: string;\n heading3: string;\n bulletList: string;\n numberedList: string;\n quote: string;\n codeBlock: string;\n divider: string;\n alignLeft: string;\n alignCenter: string;\n alignRight: string;\n table: string;\n insertTable: string;\n addRowAbove: string;\n addRowBelow: string;\n addColumnLeft: string;\n addColumnRight: string;\n deleteRow: string;\n deleteColumn: string;\n deleteTable: string;\n link: string;\n image: string;\n youtube: string;\n video: string;\n undo: string;\n redo: string;\n defaultColor: string;\n removeHighlight: string;\n linkPrompt: string;\n youtubePrompt: string;\n };\n}\n\nfunction localeToStrings(locale: GELocale): GavaEngineConfig[\"strings\"] {\n return {\n // content\n articles: locale.content.articles,\n newArticle: locale.content.newArticle,\n titlePlaceholder: locale.content.titlePlaceholder,\n excerptPlaceholder: locale.content.excerptPlaceholder,\n slugPlaceholder: locale.content.slugPlaceholder,\n authorPlaceholder: locale.content.authorPlaceholder,\n category: locale.content.category,\n selectCategory: locale.content.selectCategory,\n excerpt: locale.content.excerpt,\n author: locale.content.author,\n slugUrl: locale.content.slugUrl,\n noArticles: locale.content.noArticles,\n noArticlesSearch: locale.content.noArticlesSearch,\n searchArticles: locale.content.searchArticles,\n coverImageLabel: locale.content.coverImageLabel,\n coverImageHint: locale.content.coverImageHint,\n viewArticle: locale.content.viewArticle,\n untitled: locale.content.untitled,\n // editor\n publish: locale.editor.publish,\n unpublish: locale.editor.unpublish,\n saveDraft: locale.editor.saveDraft,\n revisions: locale.editor.revisions,\n saving: locale.editor.saving,\n saved: locale.editor.saved,\n saveError: locale.editor.saveError,\n noRevisions: locale.editor.noRevisions,\n restore: locale.editor.restore,\n restoreConfirm: locale.editor.restoreConfirm,\n beforeRestore: locale.editor.beforeRestore,\n publishedNote: locale.editor.publishedNote,\n preview: locale.editor.preview,\n // media\n media: locale.media.media,\n noMedia: locale.media.noMedia,\n noMediaSearch: locale.media.noMediaSearch,\n chooseFile: locale.media.chooseFile,\n dragHint: locale.media.dragHint,\n uploadHint: locale.media.uploadHint,\n mediaLibrary: locale.media.mediaLibrary,\n uploadNew: locale.media.uploadNew,\n searchFiles: locale.media.searchFiles,\n selectImage: locale.media.selectImage,\n noImages: locale.media.noImages,\n noImagesSearch: locale.media.noImagesSearch,\n copyUrl: locale.media.copyUrl,\n editImage: locale.media.editImage,\n restoreOriginal: locale.media.restoreOriginal,\n freeAspect: locale.media.freeAspect,\n // users\n users: locale.users.users,\n name: locale.users.name,\n email: locale.users.email,\n password: locale.users.password,\n passwordEditHint: locale.users.passwordEditHint,\n role: locale.users.role,\n createdAt: locale.users.createdAt,\n actions: locale.users.actions,\n createUser: locale.users.createUser,\n unauthorized: locale.users.unauthorized,\n notAuthenticated: locale.users.notAuthenticated,\n allFieldsRequired: locale.users.allFieldsRequired,\n passwordMinLength: locale.users.passwordMinLength,\n emailExists: locale.users.emailExists,\n invalidRole: locale.users.invalidRole,\n cannotDeleteSelf: locale.users.cannotDeleteSelf,\n // common\n statistics: locale.common.statistics,\n settings: locale.common.settings,\n delete: locale.common.delete,\n edit: locale.common.edit,\n search: locale.common.search,\n draft: locale.common.draft,\n published: locale.common.published,\n all: locale.common.all,\n drafts: locale.common.drafts,\n loading: locale.common.loading,\n confirm: locale.common.confirm,\n cancel: locale.common.cancel,\n apply: locale.common.apply,\n change: locale.common.change,\n logout: locale.common.logout,\n saveChanges: locale.common.saveChanges,\n updated: locale.common.updated,\n status: locale.common.status,\n title: locale.common.title,\n deleteConfirm: locale.common.deleteConfirm,\n unpublishConfirm: locale.common.unpublishConfirm,\n deleteUserConfirm: locale.common.deleteUserConfirm,\n totalArticles: locale.common.totalArticles,\n totalFiles: locale.common.totalFiles,\n // Toolbar\n bold: locale.editor.bold,\n italic: locale.editor.italic,\n underline: locale.editor.underline,\n strikethrough: locale.editor.strikethrough,\n superscript: locale.editor.superscript,\n subscript: locale.editor.subscript,\n textColor: locale.editor.textColor,\n highlight: locale.editor.highlight,\n heading2: locale.editor.heading2,\n heading3: locale.editor.heading3,\n bulletList: locale.editor.bulletList,\n numberedList: locale.editor.numberedList,\n quote: locale.editor.quote,\n codeBlock: locale.editor.codeBlock,\n divider: locale.editor.divider,\n alignLeft: locale.editor.alignLeft,\n alignCenter: locale.editor.alignCenter,\n alignRight: locale.editor.alignRight,\n table: locale.editor.table,\n insertTable: locale.editor.insertTable,\n addRowAbove: locale.editor.addRowAbove,\n addRowBelow: locale.editor.addRowBelow,\n addColumnLeft: locale.editor.addColumnLeft,\n addColumnRight: locale.editor.addColumnRight,\n deleteRow: locale.editor.deleteRow,\n deleteColumn: locale.editor.deleteColumn,\n deleteTable: locale.editor.deleteTable,\n link: locale.editor.link,\n image: locale.editor.image,\n youtube: locale.editor.youtube,\n video: locale.editor.video,\n undo: locale.editor.undo,\n redo: locale.editor.redo,\n defaultColor: locale.editor.defaultColor,\n removeHighlight: locale.editor.removeHighlight,\n linkPrompt: locale.editor.linkPrompt,\n youtubePrompt: locale.editor.youtubePrompt,\n };\n}\n\nconst DEFAULT_STRINGS = localeToStrings(loadLocale(\"it\"));\n\nconst DEFAULT_CONFIG: GavaEngineConfig = {\n branding: {\n name: \"GavaEngine\",\n },\n roles: {\n list: [\"admin\", \"redattore\", \"scrittore\", \"lettore\"],\n labels: {\n admin: \"Amministratore\",\n redattore: \"Redattore\",\n scrittore: \"Scrittore\",\n lettore: \"Lettore\",\n },\n canEdit: (role: string) => role !== \"lettore\",\n canPublish: (role: string) => role === \"admin\" || role === \"redattore\",\n adminRole: \"admin\",\n },\n statuses: {\n draft: \"bozza\",\n published: \"pubblicato\",\n },\n locale: \"it\",\n models: {\n article: \"article\",\n articleRevision: \"articleRevision\",\n articleView: \"articleView\",\n media: \"media\",\n user: \"user\",\n },\n categories: [\n \"Cultura ed Intercultura\",\n \"Fatti ed Eventi\",\n \"Poeti e Prosatori\",\n \"Famiglia, Istituzioni e Territorio\",\n \"Amici del Meucci\",\n ],\n upload: {\n endpoint: \"/api/upload\",\n imageTypes: [\"image/jpeg\", \"image/png\", \"image/webp\", \"image/gif\"],\n videoTypes: [\"video/mp4\", \"video/webm\", \"video/quicktime\"],\n maxImageSize: 5 * 1024 * 1024,\n maxVideoSize: 50 * 1024 * 1024,\n },\n editor: {\n placeholder: \"Inizia a scrivere il tuo articolo...\",\n autoSaveDelay: 2000,\n revisionThrottleMinutes: 5,\n headingLevels: [2, 3],\n },\n routes: {\n articles: \"/dashboard/articoli\",\n articleEdit: (id) => `/dashboard/articoli/${id}`,\n articleNew: \"/dashboard/articoli/nuovo\",\n articleView: (slug) => `/articoli/${slug}`,\n articlePreview: (id) => `/anteprima/${id}`,\n users: \"/dashboard/utenti\",\n userEdit: (id) => `/dashboard/utenti/${id}`,\n userNew: \"/dashboard/utenti/nuovo\",\n media: \"/dashboard/media\",\n dashboard: \"/dashboard\",\n statistics: \"/dashboard/statistiche\",\n login: \"/login\",\n home: \"/\",\n },\n strings: DEFAULT_STRINGS,\n};\n\nfunction deepMerge<T extends Record<string, any>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target };\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal) &&\n typeof sourceVal !== \"function\"\n ) {\n (result as any)[key] = deepMerge(\n targetVal as Record<string, any>,\n sourceVal as Record<string, any>\n );\n } else if (sourceVal !== undefined) {\n (result as any)[key] = sourceVal;\n }\n }\n return result;\n}\n\nexport function defineConfig(\n overrides: Partial<GavaEngineConfig> = {}\n): GavaEngineConfig {\n // If a different locale is specified, load it as base strings\n const locale = overrides.locale ?? DEFAULT_CONFIG.locale;\n const baseStrings = localeToStrings(loadLocale(locale));\n\n // Build config with locale-based strings as default\n const configWithLocale = {\n ...DEFAULT_CONFIG,\n strings: baseStrings,\n };\n\n // Also update editor.placeholder from locale if not overridden\n if (!overrides.editor?.placeholder) {\n const localeData = loadLocale(locale);\n configWithLocale.editor = {\n ...configWithLocale.editor,\n placeholder: localeData.editor.placeholder,\n };\n }\n\n return deepMerge(configWithLocale, overrides);\n}\n\nexport { DEFAULT_CONFIG, localeToStrings };\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createRevisionHandlers(prisma: any, config: GavaEngineConfig) {\n const throttleMs = config.editor.revisionThrottleMinutes * 60 * 1000;\n const articleModel = config.models.article;\n const revisionModel = config.models.articleRevision;\n\n return {\n async getRevisions(articleId: string) {\n return prisma[revisionModel].findMany({\n where: { articleId },\n include: { editor: { select: { name: true } } },\n orderBy: { createdAt: \"desc\" },\n });\n },\n\n async restoreRevision(\n articleId: string,\n revisionId: string,\n editorId: string\n ) {\n const article = await prisma[articleModel].findUnique({\n where: { id: articleId },\n });\n if (!article) throw new Error(\"Article not found\");\n\n const revision = await prisma[revisionModel].findUnique({\n where: { id: revisionId },\n });\n if (!revision || revision.articleId !== articleId) {\n throw new Error(\"Revision not found\");\n }\n\n // Save current state before restoring\n await prisma[revisionModel].create({\n data: {\n articleId,\n title: article.title,\n content: article.content,\n excerpt: article.excerpt,\n coverImage: article.coverImage,\n category: article.category,\n editorId,\n note: config.strings.beforeRestore,\n },\n });\n\n // Restore\n await prisma[articleModel].update({\n where: { id: articleId },\n data: {\n title: revision.title,\n content: revision.content,\n excerpt: revision.excerpt,\n coverImage: revision.coverImage,\n category: revision.category,\n updatedAt: new Date(),\n },\n });\n\n return { success: true };\n },\n\n async createRevisionSnapshot(\n articleId: string,\n editorId: string,\n note: string = \"\"\n ) {\n const article = await prisma[articleModel].findUnique({\n where: { id: articleId },\n });\n if (!article) return;\n\n // Throttle: only create if last revision was > threshold ago\n const threshold = new Date(Date.now() - throttleMs);\n const recent = await prisma[revisionModel].findFirst({\n where: { articleId, createdAt: { gte: threshold } },\n orderBy: { createdAt: \"desc\" },\n });\n\n if (recent && !note) return;\n\n await prisma[revisionModel].create({\n data: {\n articleId,\n title: article.title,\n content: article.content,\n excerpt: article.excerpt,\n coverImage: article.coverImage,\n category: article.category,\n editorId,\n note,\n },\n });\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\nimport { createRevisionHandlers } from \"./revisions.js\";\n\nexport function createArticleHandlers(prisma: any, config: GavaEngineConfig) {\n const revisionHandlers = createRevisionHandlers(prisma, config);\n const articleModel = config.models.article;\n\n return {\n async getArticles() {\n return prisma[articleModel].findMany({\n orderBy: { updatedAt: \"desc\" },\n });\n },\n\n async getArticleById(id: string) {\n return prisma[articleModel].findUnique({\n where: { id },\n });\n },\n\n async createArticle(authorName: string) {\n const article = await prisma[articleModel].create({\n data: {\n authorName,\n },\n });\n return article.id;\n },\n\n async updateArticle(\n userId: string,\n id: string,\n data: {\n title?: string;\n slug?: string;\n excerpt?: string;\n content?: string;\n coverImage?: string;\n category?: string;\n authorName?: string;\n }\n ) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await revisionHandlers.createRevisionSnapshot(id, userId);\n\n await prisma[articleModel].update({\n where: { id },\n data: { ...data, updatedAt: new Date() },\n });\n\n return { success: true };\n },\n\n async deleteArticle(id: string) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await prisma[articleModel].delete({ where: { id } });\n return { success: true };\n },\n\n async publishArticle(userId: string, id: string) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n if (!article.title || !article.slug) {\n throw new Error(\n \"Title and slug are required for publishing\"\n );\n }\n\n await revisionHandlers.createRevisionSnapshot(\n id,\n userId,\n config.strings.publishedNote\n );\n\n await prisma[articleModel].update({\n where: { id },\n data: {\n status: config.statuses.published,\n publishedAt: new Date(),\n },\n });\n\n return { success: true };\n },\n\n async unpublishArticle(id: string) {\n const article = await prisma[articleModel].findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await prisma[articleModel].update({\n where: { id },\n data: {\n status: config.statuses.draft,\n publishedAt: null,\n },\n });\n\n return { success: true };\n },\n };\n}\n","import bcrypt from \"bcryptjs\";\nimport type { GavaEngineConfig } from \"../config.js\";\n\nexport function createUserHandlers(prisma: any, config: GavaEngineConfig) {\n const userModel = config.models.user;\n\n return {\n async getUsers() {\n return prisma[userModel].findMany({\n select: {\n id: true,\n name: true,\n email: true,\n role: true,\n createdAt: true,\n },\n orderBy: { createdAt: \"desc\" },\n });\n },\n\n async getUserById(id: string) {\n return prisma[userModel].findUnique({\n where: { id },\n select: {\n id: true,\n name: true,\n email: true,\n role: true,\n },\n });\n },\n\n async createUser(formData: FormData) {\n const name = formData.get(\"name\") as string;\n const email = formData.get(\"email\") as string;\n const password = formData.get(\"password\") as string;\n const role = formData.get(\"role\") as string;\n\n if (!name || !email || !password || !role) {\n return { error: config.strings.allFieldsRequired };\n }\n\n if (!config.roles.list.includes(role)) {\n return { error: config.strings.invalidRole };\n }\n\n if (password.length < 6) {\n return { error: config.strings.passwordMinLength };\n }\n\n const existing = await prisma[userModel].findUnique({ where: { email } });\n if (existing) {\n return { error: config.strings.emailExists };\n }\n\n const hashedPassword = await bcrypt.hash(password, 10);\n\n await prisma[userModel].create({\n data: {\n name,\n email,\n password: hashedPassword,\n role,\n },\n });\n\n return { success: true };\n },\n\n async updateUser(id: string, formData: FormData) {\n const name = formData.get(\"name\") as string;\n const email = formData.get(\"email\") as string;\n const password = formData.get(\"password\") as string;\n const role = formData.get(\"role\") as string;\n\n if (!name || !email || !role) {\n return { error: config.strings.allFieldsRequired };\n }\n\n if (!config.roles.list.includes(role)) {\n return { error: config.strings.invalidRole };\n }\n\n const existing = await prisma[userModel].findUnique({ where: { email } });\n if (existing && existing.id !== id) {\n return { error: config.strings.emailExists };\n }\n\n const data: {\n name: string;\n email: string;\n role: string;\n password?: string;\n } = {\n name,\n email,\n role,\n };\n\n if (password && password.length > 0) {\n if (password.length < 6) {\n return { error: config.strings.passwordMinLength };\n }\n data.password = await bcrypt.hash(password, 10);\n }\n\n await prisma[userModel].update({\n where: { id },\n data,\n });\n\n return { success: true };\n },\n\n async deleteUser(currentUserId: string, id: string) {\n if (currentUserId === id) {\n return { error: config.strings.cannotDeleteSelf };\n }\n\n await prisma[userModel].delete({ where: { id } });\n return { success: true };\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createMediaHandlers(prisma: any, config: GavaEngineConfig) {\n const mediaModel = config.models.media;\n const articleModel = config.models.article;\n\n return {\n async getMedia(search?: string) {\n return prisma[mediaModel].findMany({\n where: search ? { filename: { contains: search } } : undefined,\n include: { uploader: { select: { name: true } } },\n orderBy: { createdAt: \"desc\" },\n });\n },\n\n async deleteMedia(\n userId: string,\n userRole: string,\n id: string,\n deleteFileFromDisk?: (path: string) => Promise<void>\n ) {\n const media = await prisma[mediaModel].findUnique({ where: { id } });\n if (!media) throw new Error(\"File not found\");\n\n // Writers can only delete their own media\n if (userRole === \"scrittore\" && media.uploaderId !== userId) {\n throw new Error(\"Unauthorized\");\n }\n\n // Check if image is used in articles\n const usedInArticles = await prisma[articleModel].findMany({\n where: {\n OR: [\n { coverImage: media.path },\n { content: { contains: media.path } },\n ],\n },\n select: { id: true, title: true },\n });\n\n if (usedInArticles.length > 0) {\n const titles = usedInArticles\n .map((a: { title: string }) => a.title || \"Untitled\")\n .join(\", \");\n throw new Error(\n `Cannot delete: image is used in ${usedInArticles.length} article(s) (${titles})`\n );\n }\n\n // Delete file from disk if handler provided\n if (deleteFileFromDisk) {\n try {\n await deleteFileFromDisk(media.path);\n } catch {\n // File may already be missing\n }\n }\n\n await prisma[mediaModel].delete({ where: { id } });\n return { success: true };\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport interface UploadResult {\n url?: string;\n error?: string;\n}\n\nexport interface FileStorage {\n save(filename: string, buffer: Buffer, mimeType: string): Promise<string>;\n}\n\nexport function createUploadHandler(\n prisma: any,\n config: GavaEngineConfig,\n storage: FileStorage\n) {\n const allowedTypes = [\n ...config.upload.imageTypes,\n ...config.upload.videoTypes,\n ];\n\n const mediaModel = config.models.media;\n\n return {\n async handleUpload(\n file: {\n name: string;\n type: string;\n size: number;\n arrayBuffer: () => Promise<ArrayBuffer>;\n },\n uploaderId: string\n ): Promise<UploadResult> {\n if (!allowedTypes.includes(file.type)) {\n return { error: \"Unsupported file type\" };\n }\n\n const isVideo = config.upload.videoTypes.includes(file.type);\n const maxSize = isVideo\n ? config.upload.maxVideoSize\n : config.upload.maxImageSize;\n\n if (file.size > maxSize) {\n return {\n error: `File too large. Max ${isVideo ? config.upload.maxVideoSize / (1024 * 1024) : config.upload.maxImageSize / (1024 * 1024)}MB.`,\n };\n }\n\n const buffer = Buffer.from(await file.arrayBuffer());\n const url = await storage.save(file.name, buffer, file.type);\n\n await prisma[mediaModel].create({\n data: {\n filename: file.name,\n path: url,\n mimeType: file.type,\n size: file.size,\n uploaderId,\n },\n });\n\n return { url };\n },\n };\n}\n","import bcrypt from \"bcryptjs\";\nimport type { GavaEngineConfig } from \"../config.js\";\n\nexport function buildCredentialsProvider(prisma: any, config?: GavaEngineConfig) {\n const userModel = config?.models?.user ?? \"user\";\n\n return {\n credentials: {\n email: {},\n password: {},\n },\n async authorize(credentials: Record<string, unknown>) {\n const email = credentials.email as string;\n const password = credentials.password as string;\n\n if (!email || !password) return null;\n\n const user = await prisma[userModel].findUnique({\n where: { email },\n });\n\n if (!user) return null;\n\n const isValid = await bcrypt.compare(password, user.password);\n if (!isValid) return null;\n\n return {\n id: user.id,\n name: user.name,\n email: user.email,\n role: user.role,\n };\n },\n };\n}\n\nexport function buildAuthCallbacks(config: GavaEngineConfig) {\n return {\n async jwt({\n token,\n user,\n }: {\n token: Record<string, unknown>;\n user?: Record<string, unknown>;\n }) {\n if (user) {\n token.id = user.id as string;\n token.role = user.role as string;\n }\n return token;\n },\n async session({\n session,\n token,\n }: {\n session: Record<string, any>;\n token: Record<string, unknown>;\n }) {\n if (session.user) {\n session.user.id = token.id as string;\n session.user.role = token.role as string;\n }\n return session;\n },\n authorized({\n auth,\n request: { nextUrl },\n }: {\n auth: Record<string, any> | null;\n request: { nextUrl: URL };\n }) {\n const isLoggedIn = !!auth;\n const role = auth?.user?.role;\n const pathname = nextUrl.pathname;\n\n if (pathname === config.routes.login && isLoggedIn) {\n return Response.redirect(new URL(config.routes.articles, nextUrl));\n }\n\n if (pathname.startsWith(config.routes.dashboard)) {\n if (!isLoggedIn) {\n return Response.redirect(new URL(config.routes.login, nextUrl));\n }\n\n if (\n pathname.startsWith(config.routes.users) &&\n role !== config.roles.adminRole\n ) {\n return Response.redirect(\n new URL(config.routes.articles, nextUrl)\n );\n }\n }\n\n return true;\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createAuthUtils(config: GavaEngineConfig) {\n return {\n canEdit(role: string): boolean {\n return config.roles.canEdit(role);\n },\n canPublish(role: string): boolean {\n return config.roles.canPublish(role);\n },\n isAdmin(role: string): boolean {\n return role === config.roles.adminRole;\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\nimport type { GEContentType } from \"../content/types.js\";\n\nexport interface ContentHandlers {\n getAll(options?: {\n search?: string;\n status?: string;\n orderBy?: Record<string, \"asc\" | \"desc\">;\n }): Promise<any[]>;\n getById(id: string): Promise<any | null>;\n create(data?: Record<string, any>): Promise<string>;\n update(id: string, data: Record<string, any>): Promise<{ success: boolean }>;\n delete(id: string): Promise<{ success: boolean }>;\n publish?(userId: string, id: string): Promise<{ success: boolean }>;\n unpublish?(id: string): Promise<{ success: boolean }>;\n}\n\nexport function createContentHandlers(\n prisma: any,\n contentType: GEContentType,\n config: GavaEngineConfig\n): ContentHandlers {\n const modelName = contentType.slug.replace(/s$/, \"\").replace(/(^|\\-)(\\w)/g, (_m, _p1, p2) => p2.toUpperCase());\n // Try to find the Prisma model — fallback to slug\n const model = prisma[modelName] ?? prisma[contentType.slug];\n\n if (!model) {\n throw new Error(\n `Prisma model \"${modelName}\" not found for content type \"${contentType.slug}\"`\n );\n }\n\n const defaultSort = contentType.admin?.defaultSort\n ? { [contentType.admin.defaultSort.field]: contentType.admin.defaultSort.direction }\n : { updatedAt: \"desc\" };\n\n const searchableFields = contentType.admin?.searchableFields ?? [\"title\"];\n\n return {\n async getAll(options) {\n const where: Record<string, any> = {};\n\n if (options?.search) {\n where.OR = searchableFields.map((field) => ({\n [field]: { contains: options.search },\n }));\n }\n\n if (options?.status) {\n where.status = options.status;\n }\n\n return model.findMany({\n where: Object.keys(where).length > 0 ? where : undefined,\n orderBy: options?.orderBy ?? defaultSort,\n });\n },\n\n async getById(id: string) {\n return model.findUnique({ where: { id } });\n },\n\n async create(data?: Record<string, any>) {\n const createData: Record<string, any> = {};\n\n // Set default values from field definitions\n for (const field of contentType.fields) {\n if (field.defaultValue !== undefined) {\n createData[field.name] = field.defaultValue;\n }\n }\n\n // Set default status\n if (contentType.defaultStatus) {\n createData.status = contentType.defaultStatus;\n }\n\n // Merge provided data\n if (data) {\n Object.assign(createData, data);\n }\n\n const record = await model.create({\n data: createData,\n });\n\n return record.id;\n },\n\n async update(id: string, data: Record<string, any>) {\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.update({\n where: { id },\n data: { ...data, updatedAt: new Date() },\n });\n\n return { success: true };\n },\n\n async delete(id: string) {\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.delete({ where: { id } });\n return { success: true };\n },\n\n async publish(userId: string, id: string) {\n if (!contentType.publishedStatus) return { success: false };\n\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.update({\n where: { id },\n data: {\n status: contentType.publishedStatus,\n publishedAt: new Date(),\n },\n });\n\n return { success: true };\n },\n\n async unpublish(id: string) {\n if (!contentType.defaultStatus) return { success: false };\n\n const record = await model.findUnique({ where: { id } });\n if (!record) throw new Error(`${contentType.labels.singular} not found`);\n\n await model.update({\n where: { id },\n data: {\n status: contentType.defaultStatus,\n publishedAt: null,\n },\n });\n\n return { success: true };\n },\n };\n}\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createCategoryHandlers(prisma: any, config: GavaEngineConfig) {\n const categoryModel = prisma.category;\n\n return {\n async getCategories() {\n if (!categoryModel) {\n // Fallback: return config categories as static list\n return config.categories.map((name, i) => ({\n id: `static-${i}`,\n name,\n slug: name.toLowerCase().replace(/\\s+/g, \"-\"),\n sortOrder: i,\n }));\n }\n\n return categoryModel.findMany({\n orderBy: { sortOrder: \"asc\" },\n });\n },\n\n async createCategory(data: { name: string; slug?: string; sortOrder?: number }) {\n if (!categoryModel) {\n throw new Error(\"Category model not available — categories are static from config\");\n }\n\n const slug =\n data.slug ??\n data.name\n .toLowerCase()\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\");\n\n return categoryModel.create({\n data: {\n name: data.name,\n slug,\n sortOrder: data.sortOrder ?? 0,\n },\n });\n },\n\n async updateCategory(\n id: string,\n data: { name?: string; slug?: string; sortOrder?: number }\n ) {\n if (!categoryModel) {\n throw new Error(\"Category model not available — categories are static from config\");\n }\n\n return categoryModel.update({\n where: { id },\n data,\n });\n },\n\n async deleteCategory(id: string) {\n if (!categoryModel) {\n throw new Error(\"Category model not available — categories are static from config\");\n }\n\n await categoryModel.delete({ where: { id } });\n return { success: true };\n },\n\n async seedCategories() {\n if (!categoryModel) return;\n\n const existing = await categoryModel.count();\n if (existing > 0) return;\n\n for (let i = 0; i < config.categories.length; i++) {\n const name = config.categories[i];\n const slug = name\n .toLowerCase()\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^a-z0-9\\s-]/g, \"\")\n .replace(/\\s+/g, \"-\");\n\n await categoryModel.create({\n data: {\n name,\n slug,\n sortOrder: i,\n },\n });\n }\n },\n };\n}\n"],"mappings":"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","names":["bcrypt"]}