gavaengine 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DashboardSplashTrigger-CRpueuUi.d.ts → DashboardSplashTrigger-Bz4Z4edN.d.ts} +1 -1
- package/dist/{chunk-4LM22T36.js → chunk-3ZYJ4C6R.js} +4 -3
- package/dist/chunk-3ZYJ4C6R.js.map +1 -0
- package/dist/{chunk-MC3FBYWV.js → chunk-PHT76VW6.js} +26 -2
- package/dist/chunk-PHT76VW6.js.map +1 -0
- package/dist/{chunk-5X5LEDAN.js → chunk-XUWBLDOW.js} +2 -2
- package/dist/components/index.d.ts +5 -22
- package/dist/components/index.js +10 -3
- package/dist/handlers/index.d.ts +56 -0
- package/dist/handlers/index.js.map +1 -1
- package/dist/{index-CCsSC4nF.d.ts → index-ByyETmJM.d.ts} +2 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/providers/index.d.ts +2 -2
- package/dist/providers/index.js +2 -2
- package/dist/{types-X07o_zKf.d.ts → registry-Do5nzO7_.d.ts} +45 -1
- package/package.json +1 -1
- package/dist/chunk-4LM22T36.js.map +0 -1
- package/dist/chunk-MC3FBYWV.js.map +0 -1
- /package/dist/{chunk-5X5LEDAN.js.map → chunk-XUWBLDOW.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import { Editor, NodeViewProps } from '@tiptap/react';
|
|
|
3
3
|
import * as _tiptap_core from '@tiptap/core';
|
|
4
4
|
import { Node } from '@tiptap/core';
|
|
5
5
|
import * as _tiptap_extension_youtube from '@tiptap/extension-youtube';
|
|
6
|
-
import {
|
|
6
|
+
import { m as GEMedia } from './registry-Do5nzO7_.js';
|
|
7
7
|
import { LucideIcon } from 'lucide-react';
|
|
8
8
|
|
|
9
9
|
interface ArticleData {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
ActionsProvider,
|
|
4
|
+
ComponentRegistryProvider,
|
|
4
5
|
ConfigProvider,
|
|
5
6
|
SplashProvider
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PHT76VW6.js";
|
|
7
8
|
|
|
8
9
|
// src/providers/GavaEngineProvider.tsx
|
|
9
10
|
import { useRouter } from "next/navigation";
|
|
@@ -30,7 +31,7 @@ function GavaEngineProvider({
|
|
|
30
31
|
children
|
|
31
32
|
}) {
|
|
32
33
|
const router = useRouter();
|
|
33
|
-
return /* @__PURE__ */ jsx3(SessionProvider, { children: /* @__PURE__ */ jsx3(ThemeProvider, { children: /* @__PURE__ */ jsx3(ConfigProvider, { config, children: /* @__PURE__ */ jsx3(ActionsProvider, { actions, children: /* @__PURE__ */ jsx3(SplashProvider, { navigate: (url) => router.push(url), children }) }) }) }) });
|
|
34
|
+
return /* @__PURE__ */ jsx3(SessionProvider, { children: /* @__PURE__ */ jsx3(ThemeProvider, { children: /* @__PURE__ */ jsx3(ConfigProvider, { config, children: /* @__PURE__ */ jsx3(ActionsProvider, { actions, children: /* @__PURE__ */ jsx3(ComponentRegistryProvider, { overrides: config.components ?? {}, children: /* @__PURE__ */ jsx3(SplashProvider, { navigate: (url) => router.push(url), children }) }) }) }) }) });
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// src/providers/ThemeToggle.tsx
|
|
@@ -64,4 +65,4 @@ export {
|
|
|
64
65
|
GavaEngineProvider,
|
|
65
66
|
ThemeToggle
|
|
66
67
|
};
|
|
67
|
-
//# sourceMappingURL=chunk-
|
|
68
|
+
//# sourceMappingURL=chunk-3ZYJ4C6R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/GavaEngineProvider.tsx","../src/providers/SessionProvider.tsx","../src/providers/ThemeProvider.tsx","../src/providers/ThemeToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport { useRouter } from \"next/navigation\";\nimport { type GavaEngineConfig } from \"../config.js\";\nimport type { GEActions } from \"../types.js\";\nimport { ConfigProvider } from \"./ConfigContext.js\";\nimport { ActionsProvider } from \"./ActionsContext.js\";\nimport { SplashProvider } from \"./SplashContext.js\";\nimport { SessionProvider } from \"./SessionProvider.js\";\nimport { ThemeProvider } from \"./ThemeProvider.js\";\nimport { ComponentRegistryProvider } from \"../components/registry.js\";\n\ninterface GavaEngineProviderProps {\n config: GavaEngineConfig;\n actions: GEActions;\n children: ReactNode;\n}\n\nexport function GavaEngineProvider({\n config,\n actions,\n children,\n}: GavaEngineProviderProps) {\n const router = useRouter();\n\n return (\n <SessionProvider>\n <ThemeProvider>\n <ConfigProvider config={config}>\n <ActionsProvider actions={actions}>\n <ComponentRegistryProvider overrides={config.components ?? {}}>\n <SplashProvider navigate={(url) => router.push(url)}>\n {children}\n </SplashProvider>\n </ComponentRegistryProvider>\n </ActionsProvider>\n </ConfigProvider>\n </ThemeProvider>\n </SessionProvider>\n );\n}\n","\"use client\";\n\nimport { SessionProvider as NextAuthSessionProvider } from \"next-auth/react\";\nimport { type ReactNode } from \"react\";\n\nexport function SessionProvider({ children }: { children: ReactNode }) {\n return <NextAuthSessionProvider>{children}</NextAuthSessionProvider>;\n}\n","\"use client\";\n\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\nimport { type ReactNode } from \"react\";\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n return (\n <NextThemesProvider attribute=\"class\" defaultTheme=\"system\" enableSystem>\n {children}\n </NextThemesProvider>\n );\n}\n","\"use client\";\n\nimport { useTheme } from \"next-themes\";\nimport { useEffect, useState } from \"react\";\nimport { Sun, Moon } from \"lucide-react\";\n\nexport function ThemeToggle() {\n const [mounted, setMounted] = useState(false);\n const { theme, setTheme } = useTheme();\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!mounted) {\n return (\n <button className=\"p-2 rounded-lg bg-card border border-card-border\">\n <div className=\"w-5 h-5\" />\n </button>\n );\n }\n\n return (\n <button\n onClick={() => setTheme(theme === \"dark\" ? \"light\" : \"dark\")}\n className=\"p-2 rounded-lg bg-card border border-card-border hover:bg-card-border transition-colors\"\n aria-label=\"Toggle theme\"\n >\n {theme === \"dark\" ? (\n <Sun className=\"w-5 h-5 text-foreground\" />\n ) : (\n <Moon className=\"w-5 h-5 text-foreground\" />\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;AAGA,SAAS,iBAAiB;;;ACD1B,SAAS,mBAAmB,+BAA+B;AAIlD;AADF,SAAS,gBAAgB,EAAE,SAAS,GAA4B;AACrE,SAAO,oBAAC,2BAAyB,UAAS;AAC5C;;;ACLA,SAAS,iBAAiB,0BAA0B;AAKhD,gBAAAA,YAAA;AAFG,SAAS,cAAc,EAAE,SAAS,GAA4B;AACnE,SACE,gBAAAA,KAAC,sBAAmB,WAAU,SAAQ,cAAa,UAAS,cAAY,MACrE,UACH;AAEJ;;;AFqBc,gBAAAC,YAAA;AAbP,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,SAAS,UAAU;AAEzB,SACE,gBAAAA,KAAC,mBACC,0BAAAA,KAAC,iBACC,0BAAAA,KAAC,kBAAe,QACd,0BAAAA,KAAC,mBAAgB,SACf,0BAAAA,KAAC,6BAA0B,WAAW,OAAO,cAAc,CAAC,GAC1D,0BAAAA,KAAC,kBAAe,UAAU,CAAC,QAAQ,OAAO,KAAK,GAAG,GAC/C,UACH,GACF,GACF,GACF,GACF,GACF;AAEJ;;;AGvCA,SAAS,gBAAgB;AACzB,SAAS,WAAW,gBAAgB;AACpC,SAAS,KAAK,YAAY;AAalB,gBAAAC,YAAA;AAXD,SAAS,cAAc;AAC5B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,EAAE,OAAO,SAAS,IAAI,SAAS;AAErC,YAAU,MAAM;AACd,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,CAAC;AAEL,MAAI,CAAC,SAAS;AACZ,WACE,gBAAAA,KAAC,YAAO,WAAU,oDAChB,0BAAAA,KAAC,SAAI,WAAU,WAAU,GAC3B;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,MAAM,SAAS,UAAU,SAAS,UAAU,MAAM;AAAA,MAC3D,WAAU;AAAA,MACV,cAAW;AAAA,MAEV,oBAAU,SACT,gBAAAA,KAAC,OAAI,WAAU,2BAA0B,IAEzC,gBAAAA,KAAC,QAAK,WAAU,2BAA0B;AAAA;AAAA,EAE9C;AAEJ;","names":["jsx","jsx","jsx"]}
|
|
@@ -514,6 +514,27 @@ function SplashProvider({
|
|
|
514
514
|
return /* @__PURE__ */ jsx3(SplashContext.Provider, { value: { phase, navigateWithSplash, openSplash }, children });
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
+
// src/components/registry.tsx
|
|
518
|
+
import {
|
|
519
|
+
createContext as createContext4,
|
|
520
|
+
useContext as useContext4
|
|
521
|
+
} from "react";
|
|
522
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
523
|
+
var RegistryContext = createContext4({});
|
|
524
|
+
function ComponentRegistryProvider({
|
|
525
|
+
overrides,
|
|
526
|
+
children
|
|
527
|
+
}) {
|
|
528
|
+
return /* @__PURE__ */ jsx4(RegistryContext.Provider, { value: overrides, children });
|
|
529
|
+
}
|
|
530
|
+
function useRegisteredComponent(name, fallback) {
|
|
531
|
+
const registry = useContext4(RegistryContext);
|
|
532
|
+
return registry[name] ?? fallback;
|
|
533
|
+
}
|
|
534
|
+
function useComponentRegistry() {
|
|
535
|
+
return useContext4(RegistryContext);
|
|
536
|
+
}
|
|
537
|
+
|
|
517
538
|
export {
|
|
518
539
|
it,
|
|
519
540
|
en,
|
|
@@ -529,6 +550,9 @@ export {
|
|
|
529
550
|
useGavaActions,
|
|
530
551
|
ActionsProvider,
|
|
531
552
|
useSplash,
|
|
532
|
-
SplashProvider
|
|
553
|
+
SplashProvider,
|
|
554
|
+
ComponentRegistryProvider,
|
|
555
|
+
useRegisteredComponent,
|
|
556
|
+
useComponentRegistry
|
|
533
557
|
};
|
|
534
|
-
//# sourceMappingURL=chunk-
|
|
558
|
+
//# sourceMappingURL=chunk-PHT76VW6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/i18n/it.ts","../src/i18n/en.ts","../src/i18n/index.ts","../src/config.ts","../src/providers/ConfigContext.tsx","../src/providers/ActionsContext.tsx","../src/providers/SplashContext.tsx","../src/components/registry.tsx"],"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","\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport { type GavaEngineConfig, DEFAULT_CONFIG } from \"../config.js\";\n\nconst ConfigContext = createContext<GavaEngineConfig>(DEFAULT_CONFIG);\n\nexport function useGavaConfig() {\n return useContext(ConfigContext);\n}\n\nexport function ConfigProvider({\n config,\n children,\n}: {\n config: GavaEngineConfig;\n children: ReactNode;\n}) {\n return (\n <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>\n );\n}\n","\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport type { GEActions } from \"../types.js\";\n\nconst ActionsContext = createContext<GEActions | null>(null);\n\nexport function useGavaActions(): GEActions {\n const ctx = useContext(ActionsContext);\n if (!ctx) {\n throw new Error(\n \"useGavaActions must be used within a <GavaEngineProvider> with actions provided.\"\n );\n }\n return ctx;\n}\n\nexport function ActionsProvider({\n actions,\n children,\n}: {\n actions: GEActions;\n children: ReactNode;\n}) {\n return (\n <ActionsContext.Provider value={actions}>{children}</ActionsContext.Provider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useState,\n useCallback,\n type ReactNode,\n} from \"react\";\n\ntype Phase = \"idle\" | \"closing\" | \"closed\" | \"opening\";\n\ninterface SplashContextValue {\n phase: Phase;\n navigateWithSplash: (url: string) => void;\n openSplash: () => void;\n}\n\nconst SplashContext = createContext<SplashContextValue>({\n phase: \"idle\",\n navigateWithSplash: () => {},\n openSplash: () => {},\n});\n\nexport function useSplash() {\n return useContext(SplashContext);\n}\n\nexport function SplashProvider({\n children,\n navigate,\n}: {\n children: ReactNode;\n navigate: (url: string) => void;\n}) {\n const [phase, setPhase] = useState<Phase>(\"idle\");\n\n const navigateWithSplash = useCallback(\n (url: string) => {\n if (phase !== \"idle\") return;\n setPhase(\"closing\");\n\n setTimeout(() => {\n setPhase(\"closed\");\n navigate(url);\n }, 700);\n },\n [phase, navigate]\n );\n\n const openSplash = useCallback(() => {\n if (phase !== \"closed\") return;\n requestAnimationFrame(() => {\n setPhase(\"opening\");\n setTimeout(() => setPhase(\"idle\"), 900);\n });\n }, [phase]);\n\n return (\n <SplashContext.Provider value={{ phase, navigateWithSplash, openSplash }}>\n {children}\n </SplashContext.Provider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport type { ContentEditorProps } from \"./content/ContentEditor.js\";\nimport type { ContentListProps } from \"./content/ContentList.js\";\n\nexport interface GEComponentOverrides {\n DashboardNavbar?: ComponentType<any>;\n DashboardLayout?: ComponentType<{ children: ReactNode }>;\n EditorToolbar?: ComponentType<{ editor: any }>;\n ContentEditor?: ComponentType<ContentEditorProps>;\n ContentList?: ComponentType<ContentListProps>;\n MediaGrid?: ComponentType<any>;\n UserTable?: ComponentType<any>;\n LoginPage?: ComponentType<any>;\n StatCard?: ComponentType<any>;\n}\n\nconst RegistryContext = createContext<GEComponentOverrides>({});\n\nexport function ComponentRegistryProvider({\n overrides,\n children,\n}: {\n overrides: GEComponentOverrides;\n children: ReactNode;\n}) {\n return (\n <RegistryContext.Provider value={overrides}>\n {children}\n </RegistryContext.Provider>\n );\n}\n\nexport function useRegisteredComponent<K extends keyof GEComponentOverrides>(\n name: K,\n fallback: NonNullable<GEComponentOverrides[K]>\n): NonNullable<GEComponentOverrides[K]> {\n const registry = useContext(RegistryContext);\n return (registry[name] as NonNullable<GEComponentOverrides[K]>) ?? fallback;\n}\n\nexport function useComponentRegistry(): GEComponentOverrides {\n return useContext(RegistryContext);\n}\n"],"mappings":"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","names":["createContext","useContext","jsx","createContext","useContext","jsx","createContext","useContext","jsx"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
useGavaActions,
|
|
4
4
|
useGavaConfig,
|
|
5
5
|
useSplash
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PHT76VW6.js";
|
|
7
7
|
|
|
8
8
|
// src/components/editor/ArticleEditor.tsx
|
|
9
9
|
import { useState as useState6, useEffect as useEffect4, useCallback as useCallback4, useRef as useRef3 } from "react";
|
|
@@ -3258,4 +3258,4 @@ export {
|
|
|
3258
3258
|
SplashScreen,
|
|
3259
3259
|
DashboardSplashTrigger
|
|
3260
3260
|
};
|
|
3261
|
-
//# sourceMappingURL=chunk-
|
|
3261
|
+
//# sourceMappingURL=chunk-XUWBLDOW.js.map
|
|
@@ -1,30 +1,13 @@
|
|
|
1
|
-
|
|
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';
|
|
2
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import
|
|
5
|
+
import 'react';
|
|
4
6
|
import '@tiptap/react';
|
|
5
7
|
import '@tiptap/core';
|
|
6
8
|
import '@tiptap/extension-youtube';
|
|
7
9
|
import 'lucide-react';
|
|
8
10
|
|
|
9
|
-
interface ContentEditorProps {
|
|
10
|
-
contentType: GEContentType;
|
|
11
|
-
actions: GEContentActions;
|
|
12
|
-
initialData?: Record<string, any>;
|
|
13
|
-
id?: string;
|
|
14
|
-
categories?: string[];
|
|
15
|
-
onSave?: () => void;
|
|
16
|
-
onPublish?: () => void;
|
|
17
|
-
}
|
|
18
|
-
declare function ContentEditor({ contentType, actions, initialData, id, categories, onSave, onPublish, }: ContentEditorProps): react_jsx_runtime.JSX.Element;
|
|
19
|
-
|
|
20
|
-
interface ContentListProps {
|
|
21
|
-
contentType: GEContentType;
|
|
22
|
-
actions: GEContentActions;
|
|
23
|
-
onEdit?: (id: string) => void;
|
|
24
|
-
onCreate?: () => void;
|
|
25
|
-
}
|
|
26
|
-
declare function ContentList({ contentType, actions, onEdit, onCreate, }: ContentListProps): react_jsx_runtime.JSX.Element;
|
|
27
|
-
|
|
28
11
|
interface TextRendererProps {
|
|
29
12
|
field: GEFieldDef;
|
|
30
13
|
value: string;
|
|
@@ -102,4 +85,4 @@ interface CategoryManagerProps {
|
|
|
102
85
|
}
|
|
103
86
|
declare function CategoryManager({ getCategories, createCategory, updateCategory, deleteCategory, }: CategoryManagerProps): react_jsx_runtime.JSX.Element;
|
|
104
87
|
|
|
105
|
-
export { BooleanRenderer, CategoryManager,
|
|
88
|
+
export { BooleanRenderer, CategoryManager, DateRenderer, ImageRenderer, JsonRenderer, NumberRenderer, SelectRenderer, SlugRenderer, TextRenderer };
|
package/dist/components/index.js
CHANGED
|
@@ -31,13 +31,18 @@ import {
|
|
|
31
31
|
UserTable,
|
|
32
32
|
VideoExtension,
|
|
33
33
|
VideoView
|
|
34
|
-
} from "../chunk-
|
|
35
|
-
import
|
|
34
|
+
} from "../chunk-XUWBLDOW.js";
|
|
35
|
+
import {
|
|
36
|
+
ComponentRegistryProvider,
|
|
37
|
+
useComponentRegistry,
|
|
38
|
+
useRegisteredComponent
|
|
39
|
+
} from "../chunk-PHT76VW6.js";
|
|
36
40
|
export {
|
|
37
41
|
ArticleEditor,
|
|
38
42
|
ArticleList,
|
|
39
43
|
BooleanRenderer,
|
|
40
44
|
CategoryManager,
|
|
45
|
+
ComponentRegistryProvider,
|
|
41
46
|
ContentEditor,
|
|
42
47
|
ContentList,
|
|
43
48
|
CoverImageUpload,
|
|
@@ -64,6 +69,8 @@ export {
|
|
|
64
69
|
UserForm,
|
|
65
70
|
UserTable,
|
|
66
71
|
VideoExtension,
|
|
67
|
-
VideoView
|
|
72
|
+
VideoView,
|
|
73
|
+
useComponentRegistry,
|
|
74
|
+
useRegisteredComponent
|
|
68
75
|
};
|
|
69
76
|
//# sourceMappingURL=index.js.map
|
package/dist/handlers/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GEContentType } from '../content/index.js';
|
|
2
|
+
import { ComponentType, ReactNode } from 'react';
|
|
2
3
|
|
|
3
4
|
interface GEUser {
|
|
4
5
|
id: string;
|
|
@@ -18,6 +19,60 @@ interface GEAuthAdapter {
|
|
|
18
19
|
signOut?(): Promise<void>;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
interface GEContentActions {
|
|
23
|
+
getAll(options?: {
|
|
24
|
+
search?: string;
|
|
25
|
+
status?: string;
|
|
26
|
+
}): Promise<any[]>;
|
|
27
|
+
getById(id: string): Promise<any | null>;
|
|
28
|
+
create(data?: Record<string, any>): Promise<string>;
|
|
29
|
+
update(id: string, data: Record<string, any>): Promise<{
|
|
30
|
+
success: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
delete(id: string): Promise<{
|
|
33
|
+
success: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
publish?(id: string): Promise<{
|
|
36
|
+
success: boolean;
|
|
37
|
+
}>;
|
|
38
|
+
unpublish?(id: string): Promise<{
|
|
39
|
+
success: boolean;
|
|
40
|
+
}>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface ContentEditorProps {
|
|
44
|
+
contentType: GEContentType;
|
|
45
|
+
actions: GEContentActions;
|
|
46
|
+
initialData?: Record<string, any>;
|
|
47
|
+
id?: string;
|
|
48
|
+
categories?: string[];
|
|
49
|
+
onSave?: () => void;
|
|
50
|
+
onPublish?: () => void;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface ContentListProps {
|
|
54
|
+
contentType: GEContentType;
|
|
55
|
+
actions: GEContentActions;
|
|
56
|
+
onEdit?: (id: string) => void;
|
|
57
|
+
onCreate?: () => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface GEComponentOverrides {
|
|
61
|
+
DashboardNavbar?: ComponentType<any>;
|
|
62
|
+
DashboardLayout?: ComponentType<{
|
|
63
|
+
children: ReactNode;
|
|
64
|
+
}>;
|
|
65
|
+
EditorToolbar?: ComponentType<{
|
|
66
|
+
editor: any;
|
|
67
|
+
}>;
|
|
68
|
+
ContentEditor?: ComponentType<ContentEditorProps>;
|
|
69
|
+
ContentList?: ComponentType<ContentListProps>;
|
|
70
|
+
MediaGrid?: ComponentType<any>;
|
|
71
|
+
UserTable?: ComponentType<any>;
|
|
72
|
+
LoginPage?: ComponentType<any>;
|
|
73
|
+
StatCard?: ComponentType<any>;
|
|
74
|
+
}
|
|
75
|
+
|
|
21
76
|
interface GavaEngineConfig {
|
|
22
77
|
branding: {
|
|
23
78
|
name: string;
|
|
@@ -44,6 +99,7 @@ interface GavaEngineConfig {
|
|
|
44
99
|
};
|
|
45
100
|
auth?: GEAuthAdapter;
|
|
46
101
|
contentTypes?: GEContentType[];
|
|
102
|
+
components?: GEComponentOverrides;
|
|
47
103
|
categories: string[];
|
|
48
104
|
upload: {
|
|
49
105
|
endpoint: string;
|
|
@@ -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\";\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 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 },\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,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { G as GEAuthAdapter } from './types-d8-k_4dN.js';
|
|
4
|
-
import {
|
|
4
|
+
import { g as GEContentType, e as GEComponentOverrides, h as GEActions } from './registry-Do5nzO7_.js';
|
|
5
5
|
|
|
6
6
|
interface GELocale {
|
|
7
7
|
content: {
|
|
@@ -130,6 +130,7 @@ interface GavaEngineConfig {
|
|
|
130
130
|
};
|
|
131
131
|
auth?: GEAuthAdapter;
|
|
132
132
|
contentTypes?: GEContentType[];
|
|
133
|
+
components?: GEComponentOverrides;
|
|
133
134
|
categories: string[];
|
|
134
135
|
upload: {
|
|
135
136
|
endpoint: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { G as GELocale, a as GavaEngineConfig } from './index-
|
|
2
|
-
export { A as ActionsProvider, C as ConfigProvider, D as DEFAULT_CONFIG, b as GavaEngineProvider, S as SessionProvider, c as SplashProvider, T as ThemeProvider, d as ThemeToggle, e as defineConfig, l as localeToStrings, u as useGavaActions, f as useGavaConfig, g as useSplash } from './index-
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
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-
|
|
1
|
+
import { G as GELocale, a as GavaEngineConfig } from './index-ByyETmJM.js';
|
|
2
|
+
export { A as ActionsProvider, C as ConfigProvider, D as DEFAULT_CONFIG, b as GavaEngineProvider, S as SessionProvider, c as SplashProvider, T as ThemeProvider, d as ThemeToggle, e as defineConfig, l as localeToStrings, u as useGavaActions, f as useGavaConfig, g as useSplash } from './index-ByyETmJM.js';
|
|
3
|
+
import { g as GEContentType } from './registry-Do5nzO7_.js';
|
|
4
|
+
export { C as ComponentRegistryProvider, h as GEActions, i as GEActionsV2, j as GEArticle, e as GEComponentOverrides, k as GEContentActions, G as GEFieldDef, l as GEFieldType, m as GEMedia, n as GERevision, o as GESession, p as GEUser, q as articlesContentType, r as createLegacyActions, s as defineContentType, u as useComponentRegistry, f as useRegisteredComponent } from './registry-Do5nzO7_.js';
|
|
5
|
+
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';
|
|
6
6
|
export { G as GEAuthAdapter, a as GEAuthSession, b as GEAuthUser } from './types-d8-k_4dN.js';
|
|
7
7
|
export { AuthProvider, createNextAuthAdapter, useGavaAuth } from './auth/index.js';
|
|
8
8
|
import 'react/jsx-runtime';
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
SessionProvider,
|
|
5
5
|
ThemeProvider,
|
|
6
6
|
ThemeToggle
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3ZYJ4C6R.js";
|
|
8
8
|
import {
|
|
9
9
|
ArticleEditor,
|
|
10
10
|
ArticleList,
|
|
@@ -26,9 +26,10 @@ import {
|
|
|
26
26
|
UserTable,
|
|
27
27
|
VideoExtension,
|
|
28
28
|
VideoView
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-XUWBLDOW.js";
|
|
30
30
|
import {
|
|
31
31
|
ActionsProvider,
|
|
32
|
+
ComponentRegistryProvider,
|
|
32
33
|
ConfigProvider,
|
|
33
34
|
DEFAULT_CONFIG,
|
|
34
35
|
SplashProvider,
|
|
@@ -40,10 +41,12 @@ import {
|
|
|
40
41
|
localeToStrings,
|
|
41
42
|
mergeLocales,
|
|
42
43
|
registerLocale,
|
|
44
|
+
useComponentRegistry,
|
|
43
45
|
useGavaActions,
|
|
44
46
|
useGavaConfig,
|
|
47
|
+
useRegisteredComponent,
|
|
45
48
|
useSplash
|
|
46
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-PHT76VW6.js";
|
|
47
50
|
import {
|
|
48
51
|
AuthProvider,
|
|
49
52
|
createNextAuthAdapter,
|
|
@@ -693,6 +696,7 @@ export {
|
|
|
693
696
|
ArticleEditor,
|
|
694
697
|
ArticleList,
|
|
695
698
|
AuthProvider,
|
|
699
|
+
ComponentRegistryProvider,
|
|
696
700
|
ConfigProvider,
|
|
697
701
|
CoverImageUpload,
|
|
698
702
|
DEFAULT_CONFIG,
|
|
@@ -740,9 +744,11 @@ export {
|
|
|
740
744
|
localeToStrings,
|
|
741
745
|
mergeLocales,
|
|
742
746
|
registerLocale,
|
|
747
|
+
useComponentRegistry,
|
|
743
748
|
useGavaActions,
|
|
744
749
|
useGavaAuth,
|
|
745
750
|
useGavaConfig,
|
|
751
|
+
useRegisteredComponent,
|
|
746
752
|
useSplash
|
|
747
753
|
};
|
|
748
754
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/content/types.ts","../src/types.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":["export type GEFieldType =\n | \"text\"\n | \"richtext\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"image\"\n | \"select\"\n | \"slug\"\n | \"relationship\"\n | \"json\";\n\nexport interface GEFieldDef {\n name: string;\n type: GEFieldType;\n label: string;\n required?: boolean;\n defaultValue?: any;\n placeholder?: string;\n options?: string[]; // for 'select' type\n generateFrom?: string; // for 'slug' type — field name to auto-generate from\n relationTo?: string; // for 'relationship' type — content type slug\n hidden?: boolean; // hide from editor\n admin?: {\n width?: \"full\" | \"half\";\n position?: \"main\" | \"sidebar\";\n };\n}\n\nexport interface GEContentType {\n slug: string; // 'articles', 'pages', 'events'\n labels: {\n singular: string;\n plural: string;\n };\n fields: GEFieldDef[];\n statuses?: string[]; // ['draft', 'published'] — custom statuses\n defaultStatus?: string;\n publishedStatus?: string;\n features?: {\n revisions?: boolean;\n views?: boolean;\n search?: boolean;\n };\n admin?: {\n listColumns?: string[];\n searchableFields?: string[];\n defaultSort?: {\n field: string;\n direction: \"asc\" | \"desc\";\n };\n };\n}\n\n// Helper to define a content type with full type safety\nexport function defineContentType(contentType: GEContentType): GEContentType {\n return {\n statuses: [\"draft\", \"published\"],\n defaultStatus: \"draft\",\n publishedStatus: \"published\",\n features: {\n revisions: true,\n views: false,\n search: true,\n },\n ...contentType,\n };\n}\n\n// Built-in \"articles\" content type matching the legacy v0.x schema\nexport const articlesContentType: GEContentType = defineContentType({\n slug: \"articles\",\n labels: { singular: \"Article\", plural: \"Articles\" },\n fields: [\n { name: \"title\", type: \"text\", label: \"Title\", placeholder: \"Article title\" },\n { name: \"slug\", type: \"slug\", label: \"Slug\", generateFrom: \"title\", admin: { position: \"sidebar\" } },\n { name: \"excerpt\", type: \"text\", label: \"Excerpt\", placeholder: \"Brief description...\", admin: { position: \"sidebar\" } },\n { name: \"content\", type: \"richtext\", label: \"Content\" },\n { name: \"coverImage\", type: \"image\", label: \"Cover image\", admin: { position: \"sidebar\" } },\n { name: \"category\", type: \"select\", label: \"Category\", admin: { position: \"sidebar\" } },\n { name: \"authorName\", type: \"text\", label: \"Author\", admin: { position: \"sidebar\" } },\n ],\n features: { revisions: true, views: true, search: true },\n admin: {\n listColumns: [\"title\", \"category\", \"status\", \"updatedAt\"],\n searchableFields: [\"title\", \"excerpt\", \"authorName\"],\n defaultSort: { field: \"updatedAt\", direction: \"desc\" },\n },\n});\n","export interface GEArticle {\n id: string;\n title: string;\n slug: string;\n excerpt: string;\n content: string;\n coverImage: string;\n category: string;\n status: string;\n authorName: string;\n viewCount?: number;\n createdAt: Date;\n updatedAt: Date;\n publishedAt: Date | null;\n}\n\nexport interface GEUser {\n id: string;\n name: string;\n email: string;\n role: string;\n createdAt: Date;\n}\n\nexport interface GEMedia {\n id: string;\n filename: string;\n path: string;\n mimeType: string;\n size: number;\n createdAt: Date;\n uploader: { name: string };\n}\n\nexport interface GERevision {\n id: string;\n title: string;\n content: string;\n excerpt: string;\n coverImage: string;\n category: string;\n note: string;\n createdAt: Date;\n editor: { name: string };\n}\n\nexport interface GESession {\n user: {\n id: string;\n name?: string | null;\n email?: string | null;\n role: string;\n };\n}\n\n// v2.0 content-based actions interface\nexport interface GEContentActions {\n getAll(options?: {\n search?: string;\n status?: string;\n }): Promise<any[]>;\n getById(id: string): Promise<any | null>;\n create(data?: Record<string, any>): Promise<string>;\n update(\n id: string,\n data: Record<string, any>\n ): Promise<{ success: boolean }>;\n delete(id: string): Promise<{ success: boolean }>;\n publish?(id: string): Promise<{ success: boolean }>;\n unpublish?(id: string): Promise<{ success: boolean }>;\n}\n\n// v2.0 actions interface with content-based structure\nexport interface GEActionsV2 {\n content: Record<string, GEContentActions>;\n media: {\n getMedia: (search?: string) => Promise<GEMedia[]>;\n deleteMedia: (id: string) => Promise<{ success: boolean }>;\n };\n users: {\n getUsers: () => Promise<GEUser[]>;\n getUserById: (id: string) => Promise<GEUser | null>;\n createUser: (formData: FormData) => Promise<{ error?: string } | void>;\n updateUser: (\n id: string,\n formData: FormData\n ) => Promise<{ error?: string } | void>;\n deleteUser: (id: string) => Promise<{ error?: string } | void>;\n };\n revisions: {\n getRevisions: (contentId: string) => Promise<GERevision[]>;\n restoreRevision: (\n contentId: string,\n revisionId: string\n ) => Promise<{ success: boolean }>;\n };\n uploadUrl: string;\n}\n\n// Legacy v1.x flat actions interface (backward compat)\nexport interface GEActions {\n // Articles\n getArticles: () => Promise<GEArticle[]>;\n getArticleById: (id: string) => Promise<GEArticle | null>;\n createArticle: () => Promise<string>;\n updateArticle: (\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 ) => Promise<{ success: boolean }>;\n deleteArticle: (id: string) => Promise<{ success: boolean }>;\n publishArticle: (id: string) => Promise<{ success: boolean }>;\n unpublishArticle: (id: string) => Promise<{ success: boolean }>;\n\n // Media\n getMedia: (search?: string) => Promise<GEMedia[]>;\n deleteMedia: (id: string) => Promise<{ success: boolean }>;\n uploadUrl: string;\n\n // Revisions\n getRevisions: (articleId: string) => Promise<GERevision[]>;\n restoreRevision: (\n articleId: string,\n revisionId: string\n ) => Promise<{ success: boolean }>;\n\n // Users\n getUsers: () => Promise<GEUser[]>;\n getUserById: (id: string) => Promise<GEUser | null>;\n createUser: (formData: FormData) => Promise<{ error?: string } | void>;\n updateUser: (\n id: string,\n formData: FormData\n ) => Promise<{ error?: string } | void>;\n deleteUser: (id: string) => Promise<{ error?: string } | void>;\n}\n\n/**\n * @deprecated Use GEActionsV2 instead. This helper maps v1.x flat actions to v2.x structure.\n */\nexport function createLegacyActions(v2Actions: GEActionsV2, contentSlug: string = \"articles\"): GEActions {\n const content = v2Actions.content[contentSlug];\n if (!content) {\n throw new Error(`Content type \"${contentSlug}\" not found in actions`);\n }\n\n return {\n getArticles: () => content.getAll(),\n getArticleById: (id) => content.getById(id),\n createArticle: () => content.create(),\n updateArticle: (id, data) => content.update(id, data),\n deleteArticle: (id) => content.delete(id),\n publishArticle: (id) => content.publish?.(id) ?? Promise.resolve({ success: false }),\n unpublishArticle: (id) => content.unpublish?.(id) ?? Promise.resolve({ success: false }),\n getMedia: v2Actions.media.getMedia,\n deleteMedia: v2Actions.media.deleteMedia,\n uploadUrl: v2Actions.uploadUrl,\n getRevisions: v2Actions.revisions.getRevisions,\n restoreRevision: v2Actions.revisions.restoreRevision,\n getUsers: v2Actions.users.getUsers,\n getUserById: v2Actions.users.getUserById,\n createUser: v2Actions.users.createUser,\n updateUser: v2Actions.users.updateUser,\n deleteUser: v2Actions.users.deleteUser,\n };\n}\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/content/types.ts","../src/types.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":["export type GEFieldType =\n | \"text\"\n | \"richtext\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"image\"\n | \"select\"\n | \"slug\"\n | \"relationship\"\n | \"json\";\n\nexport interface GEFieldDef {\n name: string;\n type: GEFieldType;\n label: string;\n required?: boolean;\n defaultValue?: any;\n placeholder?: string;\n options?: string[]; // for 'select' type\n generateFrom?: string; // for 'slug' type — field name to auto-generate from\n relationTo?: string; // for 'relationship' type — content type slug\n hidden?: boolean; // hide from editor\n admin?: {\n width?: \"full\" | \"half\";\n position?: \"main\" | \"sidebar\";\n };\n}\n\nexport interface GEContentType {\n slug: string; // 'articles', 'pages', 'events'\n labels: {\n singular: string;\n plural: string;\n };\n fields: GEFieldDef[];\n statuses?: string[]; // ['draft', 'published'] — custom statuses\n defaultStatus?: string;\n publishedStatus?: string;\n features?: {\n revisions?: boolean;\n views?: boolean;\n search?: boolean;\n };\n admin?: {\n listColumns?: string[];\n searchableFields?: string[];\n defaultSort?: {\n field: string;\n direction: \"asc\" | \"desc\";\n };\n };\n}\n\n// Helper to define a content type with full type safety\nexport function defineContentType(contentType: GEContentType): GEContentType {\n return {\n statuses: [\"draft\", \"published\"],\n defaultStatus: \"draft\",\n publishedStatus: \"published\",\n features: {\n revisions: true,\n views: false,\n search: true,\n },\n ...contentType,\n };\n}\n\n// Built-in \"articles\" content type matching the legacy v0.x schema\nexport const articlesContentType: GEContentType = defineContentType({\n slug: \"articles\",\n labels: { singular: \"Article\", plural: \"Articles\" },\n fields: [\n { name: \"title\", type: \"text\", label: \"Title\", placeholder: \"Article title\" },\n { name: \"slug\", type: \"slug\", label: \"Slug\", generateFrom: \"title\", admin: { position: \"sidebar\" } },\n { name: \"excerpt\", type: \"text\", label: \"Excerpt\", placeholder: \"Brief description...\", admin: { position: \"sidebar\" } },\n { name: \"content\", type: \"richtext\", label: \"Content\" },\n { name: \"coverImage\", type: \"image\", label: \"Cover image\", admin: { position: \"sidebar\" } },\n { name: \"category\", type: \"select\", label: \"Category\", admin: { position: \"sidebar\" } },\n { name: \"authorName\", type: \"text\", label: \"Author\", admin: { position: \"sidebar\" } },\n ],\n features: { revisions: true, views: true, search: true },\n admin: {\n listColumns: [\"title\", \"category\", \"status\", \"updatedAt\"],\n searchableFields: [\"title\", \"excerpt\", \"authorName\"],\n defaultSort: { field: \"updatedAt\", direction: \"desc\" },\n },\n});\n","export interface GEArticle {\n id: string;\n title: string;\n slug: string;\n excerpt: string;\n content: string;\n coverImage: string;\n category: string;\n status: string;\n authorName: string;\n viewCount?: number;\n createdAt: Date;\n updatedAt: Date;\n publishedAt: Date | null;\n}\n\nexport interface GEUser {\n id: string;\n name: string;\n email: string;\n role: string;\n createdAt: Date;\n}\n\nexport interface GEMedia {\n id: string;\n filename: string;\n path: string;\n mimeType: string;\n size: number;\n createdAt: Date;\n uploader: { name: string };\n}\n\nexport interface GERevision {\n id: string;\n title: string;\n content: string;\n excerpt: string;\n coverImage: string;\n category: string;\n note: string;\n createdAt: Date;\n editor: { name: string };\n}\n\nexport interface GESession {\n user: {\n id: string;\n name?: string | null;\n email?: string | null;\n role: string;\n };\n}\n\n// v2.0 content-based actions interface\nexport interface GEContentActions {\n getAll(options?: {\n search?: string;\n status?: string;\n }): Promise<any[]>;\n getById(id: string): Promise<any | null>;\n create(data?: Record<string, any>): Promise<string>;\n update(\n id: string,\n data: Record<string, any>\n ): Promise<{ success: boolean }>;\n delete(id: string): Promise<{ success: boolean }>;\n publish?(id: string): Promise<{ success: boolean }>;\n unpublish?(id: string): Promise<{ success: boolean }>;\n}\n\n// v2.0 actions interface with content-based structure\nexport interface GEActionsV2 {\n content: Record<string, GEContentActions>;\n media: {\n getMedia: (search?: string) => Promise<GEMedia[]>;\n deleteMedia: (id: string) => Promise<{ success: boolean }>;\n };\n users: {\n getUsers: () => Promise<GEUser[]>;\n getUserById: (id: string) => Promise<GEUser | null>;\n createUser: (formData: FormData) => Promise<{ error?: string } | void>;\n updateUser: (\n id: string,\n formData: FormData\n ) => Promise<{ error?: string } | void>;\n deleteUser: (id: string) => Promise<{ error?: string } | void>;\n };\n revisions: {\n getRevisions: (contentId: string) => Promise<GERevision[]>;\n restoreRevision: (\n contentId: string,\n revisionId: string\n ) => Promise<{ success: boolean }>;\n };\n uploadUrl: string;\n}\n\n// Legacy v1.x flat actions interface (backward compat)\nexport interface GEActions {\n // Articles\n getArticles: () => Promise<GEArticle[]>;\n getArticleById: (id: string) => Promise<GEArticle | null>;\n createArticle: () => Promise<string>;\n updateArticle: (\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 ) => Promise<{ success: boolean }>;\n deleteArticle: (id: string) => Promise<{ success: boolean }>;\n publishArticle: (id: string) => Promise<{ success: boolean }>;\n unpublishArticle: (id: string) => Promise<{ success: boolean }>;\n\n // Media\n getMedia: (search?: string) => Promise<GEMedia[]>;\n deleteMedia: (id: string) => Promise<{ success: boolean }>;\n uploadUrl: string;\n\n // Revisions\n getRevisions: (articleId: string) => Promise<GERevision[]>;\n restoreRevision: (\n articleId: string,\n revisionId: string\n ) => Promise<{ success: boolean }>;\n\n // Users\n getUsers: () => Promise<GEUser[]>;\n getUserById: (id: string) => Promise<GEUser | null>;\n createUser: (formData: FormData) => Promise<{ error?: string } | void>;\n updateUser: (\n id: string,\n formData: FormData\n ) => Promise<{ error?: string } | void>;\n deleteUser: (id: string) => Promise<{ error?: string } | void>;\n}\n\n/**\n * @deprecated Use GEActionsV2 instead. This helper maps v1.x flat actions to v2.x structure.\n */\nexport function createLegacyActions(v2Actions: GEActionsV2, contentSlug: string = \"articles\"): GEActions {\n const content = v2Actions.content[contentSlug];\n if (!content) {\n throw new Error(`Content type \"${contentSlug}\" not found in actions`);\n }\n\n return {\n getArticles: () => content.getAll(),\n getArticleById: (id) => content.getById(id),\n createArticle: () => content.create(),\n updateArticle: (id, data) => content.update(id, data),\n deleteArticle: (id) => content.delete(id),\n publishArticle: (id) => content.publish?.(id) ?? Promise.resolve({ success: false }),\n unpublishArticle: (id) => content.unpublish?.(id) ?? Promise.resolve({ success: false }),\n getMedia: v2Actions.media.getMedia,\n deleteMedia: v2Actions.media.deleteMedia,\n uploadUrl: v2Actions.uploadUrl,\n getRevisions: v2Actions.revisions.getRevisions,\n restoreRevision: v2Actions.revisions.restoreRevision,\n getUsers: v2Actions.users.getUsers,\n getUserById: v2Actions.users.getUserById,\n createUser: v2Actions.users.createUser,\n updateUser: v2Actions.users.updateUser,\n deleteUser: v2Actions.users.deleteUser,\n };\n}\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,5 +1,5 @@
|
|
|
1
|
-
export { A as ActionsProvider, C as ConfigProvider, b as GavaEngineProvider, S as SessionProvider, c as SplashProvider, T as ThemeProvider, d as ThemeToggle, u as useGavaActions, f as useGavaConfig, g as useSplash } from '../index-
|
|
1
|
+
export { A as ActionsProvider, C as ConfigProvider, b as GavaEngineProvider, S as SessionProvider, c as SplashProvider, T as ThemeProvider, d as ThemeToggle, u as useGavaActions, f as useGavaConfig, g as useSplash } from '../index-ByyETmJM.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
3
|
import 'react';
|
|
4
4
|
import '../types-d8-k_4dN.js';
|
|
5
|
-
import '../
|
|
5
|
+
import '../registry-Do5nzO7_.js';
|
package/dist/providers/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
SessionProvider,
|
|
5
5
|
ThemeProvider,
|
|
6
6
|
ThemeToggle
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-3ZYJ4C6R.js";
|
|
8
8
|
import {
|
|
9
9
|
ActionsProvider,
|
|
10
10
|
ConfigProvider,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
useGavaActions,
|
|
13
13
|
useGavaConfig,
|
|
14
14
|
useSplash
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-PHT76VW6.js";
|
|
16
16
|
export {
|
|
17
17
|
ActionsProvider,
|
|
18
18
|
ConfigProvider,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ComponentType, ReactNode } from 'react';
|
|
3
|
+
|
|
1
4
|
type GEFieldType = "text" | "richtext" | "number" | "boolean" | "date" | "image" | "select" | "slug" | "relationship" | "json";
|
|
2
5
|
interface GEFieldDef {
|
|
3
6
|
name: string;
|
|
@@ -195,4 +198,45 @@ interface GEActions {
|
|
|
195
198
|
*/
|
|
196
199
|
declare function createLegacyActions(v2Actions: GEActionsV2, contentSlug?: string): GEActions;
|
|
197
200
|
|
|
198
|
-
|
|
201
|
+
interface ContentEditorProps {
|
|
202
|
+
contentType: GEContentType;
|
|
203
|
+
actions: GEContentActions;
|
|
204
|
+
initialData?: Record<string, any>;
|
|
205
|
+
id?: string;
|
|
206
|
+
categories?: string[];
|
|
207
|
+
onSave?: () => void;
|
|
208
|
+
onPublish?: () => void;
|
|
209
|
+
}
|
|
210
|
+
declare function ContentEditor({ contentType, actions, initialData, id, categories, onSave, onPublish, }: ContentEditorProps): react_jsx_runtime.JSX.Element;
|
|
211
|
+
|
|
212
|
+
interface ContentListProps {
|
|
213
|
+
contentType: GEContentType;
|
|
214
|
+
actions: GEContentActions;
|
|
215
|
+
onEdit?: (id: string) => void;
|
|
216
|
+
onCreate?: () => void;
|
|
217
|
+
}
|
|
218
|
+
declare function ContentList({ contentType, actions, onEdit, onCreate, }: ContentListProps): react_jsx_runtime.JSX.Element;
|
|
219
|
+
|
|
220
|
+
interface GEComponentOverrides {
|
|
221
|
+
DashboardNavbar?: ComponentType<any>;
|
|
222
|
+
DashboardLayout?: ComponentType<{
|
|
223
|
+
children: ReactNode;
|
|
224
|
+
}>;
|
|
225
|
+
EditorToolbar?: ComponentType<{
|
|
226
|
+
editor: any;
|
|
227
|
+
}>;
|
|
228
|
+
ContentEditor?: ComponentType<ContentEditorProps>;
|
|
229
|
+
ContentList?: ComponentType<ContentListProps>;
|
|
230
|
+
MediaGrid?: ComponentType<any>;
|
|
231
|
+
UserTable?: ComponentType<any>;
|
|
232
|
+
LoginPage?: ComponentType<any>;
|
|
233
|
+
StatCard?: ComponentType<any>;
|
|
234
|
+
}
|
|
235
|
+
declare function ComponentRegistryProvider({ overrides, children, }: {
|
|
236
|
+
overrides: GEComponentOverrides;
|
|
237
|
+
children: ReactNode;
|
|
238
|
+
}): react_jsx_runtime.JSX.Element;
|
|
239
|
+
declare function useRegisteredComponent<K extends keyof GEComponentOverrides>(name: K, fallback: NonNullable<GEComponentOverrides[K]>): NonNullable<GEComponentOverrides[K]>;
|
|
240
|
+
declare function useComponentRegistry(): GEComponentOverrides;
|
|
241
|
+
|
|
242
|
+
export { ComponentRegistryProvider as C, type GEFieldDef as G, ContentEditor as a, type ContentEditorProps as b, ContentList as c, type ContentListProps as d, type GEComponentOverrides as e, useRegisteredComponent as f, type GEContentType as g, type GEActions as h, type GEActionsV2 as i, type GEArticle as j, type GEContentActions as k, type GEFieldType as l, type GEMedia as m, type GERevision as n, type GESession as o, type GEUser as p, articlesContentType as q, createLegacyActions as r, defineContentType as s, useComponentRegistry as u };
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/providers/GavaEngineProvider.tsx","../src/providers/SessionProvider.tsx","../src/providers/ThemeProvider.tsx","../src/providers/ThemeToggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport { useRouter } from \"next/navigation\";\nimport { type GavaEngineConfig } from \"../config.js\";\nimport type { GEActions } from \"../types.js\";\nimport { ConfigProvider } from \"./ConfigContext.js\";\nimport { ActionsProvider } from \"./ActionsContext.js\";\nimport { SplashProvider } from \"./SplashContext.js\";\nimport { SessionProvider } from \"./SessionProvider.js\";\nimport { ThemeProvider } from \"./ThemeProvider.js\";\n\ninterface GavaEngineProviderProps {\n config: GavaEngineConfig;\n actions: GEActions;\n children: ReactNode;\n}\n\nexport function GavaEngineProvider({\n config,\n actions,\n children,\n}: GavaEngineProviderProps) {\n const router = useRouter();\n\n return (\n <SessionProvider>\n <ThemeProvider>\n <ConfigProvider config={config}>\n <ActionsProvider actions={actions}>\n <SplashProvider navigate={(url) => router.push(url)}>\n {children}\n </SplashProvider>\n </ActionsProvider>\n </ConfigProvider>\n </ThemeProvider>\n </SessionProvider>\n );\n}\n","\"use client\";\n\nimport { SessionProvider as NextAuthSessionProvider } from \"next-auth/react\";\nimport { type ReactNode } from \"react\";\n\nexport function SessionProvider({ children }: { children: ReactNode }) {\n return <NextAuthSessionProvider>{children}</NextAuthSessionProvider>;\n}\n","\"use client\";\n\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\";\nimport { type ReactNode } from \"react\";\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n return (\n <NextThemesProvider attribute=\"class\" defaultTheme=\"system\" enableSystem>\n {children}\n </NextThemesProvider>\n );\n}\n","\"use client\";\n\nimport { useTheme } from \"next-themes\";\nimport { useEffect, useState } from \"react\";\nimport { Sun, Moon } from \"lucide-react\";\n\nexport function ThemeToggle() {\n const [mounted, setMounted] = useState(false);\n const { theme, setTheme } = useTheme();\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n if (!mounted) {\n return (\n <button className=\"p-2 rounded-lg bg-card border border-card-border\">\n <div className=\"w-5 h-5\" />\n </button>\n );\n }\n\n return (\n <button\n onClick={() => setTheme(theme === \"dark\" ? \"light\" : \"dark\")}\n className=\"p-2 rounded-lg bg-card border border-card-border hover:bg-card-border transition-colors\"\n aria-label=\"Toggle theme\"\n >\n {theme === \"dark\" ? (\n <Sun className=\"w-5 h-5 text-foreground\" />\n ) : (\n <Moon className=\"w-5 h-5 text-foreground\" />\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;AAGA,SAAS,iBAAiB;;;ACD1B,SAAS,mBAAmB,+BAA+B;AAIlD;AADF,SAAS,gBAAgB,EAAE,SAAS,GAA4B;AACrE,SAAO,oBAAC,2BAAyB,UAAS;AAC5C;;;ACLA,SAAS,iBAAiB,0BAA0B;AAKhD,gBAAAA,YAAA;AAFG,SAAS,cAAc,EAAE,SAAS,GAA4B;AACnE,SACE,gBAAAA,KAAC,sBAAmB,WAAU,SAAQ,cAAa,UAAS,cAAY,MACrE,UACH;AAEJ;;;AFmBY,gBAAAC,YAAA;AAZL,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,SAAS,UAAU;AAEzB,SACE,gBAAAA,KAAC,mBACC,0BAAAA,KAAC,iBACC,0BAAAA,KAAC,kBAAe,QACd,0BAAAA,KAAC,mBAAgB,SACf,0BAAAA,KAAC,kBAAe,UAAU,CAAC,QAAQ,OAAO,KAAK,GAAG,GAC/C,UACH,GACF,GACF,GACF,GACF;AAEJ;;;AGpCA,SAAS,gBAAgB;AACzB,SAAS,WAAW,gBAAgB;AACpC,SAAS,KAAK,YAAY;AAalB,gBAAAC,YAAA;AAXD,SAAS,cAAc;AAC5B,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,EAAE,OAAO,SAAS,IAAI,SAAS;AAErC,YAAU,MAAM;AACd,eAAW,IAAI;AAAA,EACjB,GAAG,CAAC,CAAC;AAEL,MAAI,CAAC,SAAS;AACZ,WACE,gBAAAA,KAAC,YAAO,WAAU,oDAChB,0BAAAA,KAAC,SAAI,WAAU,WAAU,GAC3B;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,MAAM,SAAS,UAAU,SAAS,UAAU,MAAM;AAAA,MAC3D,WAAU;AAAA,MACV,cAAW;AAAA,MAEV,oBAAU,SACT,gBAAAA,KAAC,OAAI,WAAU,2BAA0B,IAEzC,gBAAAA,KAAC,QAAK,WAAU,2BAA0B;AAAA;AAAA,EAE9C;AAEJ;","names":["jsx","jsx","jsx"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/i18n/it.ts","../src/i18n/en.ts","../src/i18n/index.ts","../src/config.ts","../src/providers/ConfigContext.tsx","../src/providers/ActionsContext.tsx","../src/providers/SplashContext.tsx"],"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\";\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 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","\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport { type GavaEngineConfig, DEFAULT_CONFIG } from \"../config.js\";\n\nconst ConfigContext = createContext<GavaEngineConfig>(DEFAULT_CONFIG);\n\nexport function useGavaConfig() {\n return useContext(ConfigContext);\n}\n\nexport function ConfigProvider({\n config,\n children,\n}: {\n config: GavaEngineConfig;\n children: ReactNode;\n}) {\n return (\n <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>\n );\n}\n","\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport type { GEActions } from \"../types.js\";\n\nconst ActionsContext = createContext<GEActions | null>(null);\n\nexport function useGavaActions(): GEActions {\n const ctx = useContext(ActionsContext);\n if (!ctx) {\n throw new Error(\n \"useGavaActions must be used within a <GavaEngineProvider> with actions provided.\"\n );\n }\n return ctx;\n}\n\nexport function ActionsProvider({\n actions,\n children,\n}: {\n actions: GEActions;\n children: ReactNode;\n}) {\n return (\n <ActionsContext.Provider value={actions}>{children}</ActionsContext.Provider>\n );\n}\n","\"use client\";\n\nimport {\n createContext,\n useContext,\n useState,\n useCallback,\n type ReactNode,\n} from \"react\";\n\ntype Phase = \"idle\" | \"closing\" | \"closed\" | \"opening\";\n\ninterface SplashContextValue {\n phase: Phase;\n navigateWithSplash: (url: string) => void;\n openSplash: () => void;\n}\n\nconst SplashContext = createContext<SplashContextValue>({\n phase: \"idle\",\n navigateWithSplash: () => {},\n openSplash: () => {},\n});\n\nexport function useSplash() {\n return useContext(SplashContext);\n}\n\nexport function SplashProvider({\n children,\n navigate,\n}: {\n children: ReactNode;\n navigate: (url: string) => void;\n}) {\n const [phase, setPhase] = useState<Phase>(\"idle\");\n\n const navigateWithSplash = useCallback(\n (url: string) => {\n if (phase !== \"idle\") return;\n setPhase(\"closing\");\n\n setTimeout(() => {\n setPhase(\"closed\");\n navigate(url);\n }, 700);\n },\n [phase, navigate]\n );\n\n const openSplash = useCallback(() => {\n if (phase !== \"closed\") return;\n requestAnimationFrame(() => {\n setPhase(\"opening\");\n setTimeout(() => setPhase(\"idle\"), 900);\n });\n }, [phase]);\n\n return (\n <SplashContext.Provider value={{ phase, navigateWithSplash, openSplash }}>\n {children}\n </SplashContext.Provider>\n );\n}\n"],"mappings":"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","names":["createContext","useContext","jsx","createContext","useContext","jsx"]}
|
|
File without changes
|