gavaengine 0.1.0 → 1.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/auth/index.d.ts +42 -0
- package/dist/auth/index.js +12 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/{chunk-KCQJHXZP.js → chunk-ICIFEKSX.js} +2 -2
- package/dist/chunk-IK24OCFW.js +534 -0
- package/dist/chunk-IK24OCFW.js.map +1 -0
- package/dist/{chunk-CE7E5MAB.js → chunk-KQHQOMGL.js} +6 -7
- package/dist/{chunk-CE7E5MAB.js.map → chunk-KQHQOMGL.js.map} +1 -1
- package/dist/chunk-QO42DDRU.js +113 -0
- package/dist/chunk-QO42DDRU.js.map +1 -0
- package/dist/cli/index.js +0 -1
- package/dist/components/index.js +2 -2
- package/dist/handlers/index.d.ts +33 -3
- package/dist/handlers/index.js +385 -128
- package/dist/handlers/index.js.map +1 -1
- package/dist/i18n/index.d.ts +114 -0
- package/dist/i18n/index.js +249 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/{index-CIX0MBHm.d.ts → index-Ng6yRSAA.d.ts} +117 -2
- package/dist/index.d.ts +19 -5
- package/dist/index.js +69 -39
- package/dist/index.js.map +1 -1
- package/dist/providers/index.d.ts +2 -1
- package/dist/providers/index.js +2 -2
- package/dist/types-d8-k_4dN.d.ts +19 -0
- package/package.json +12 -1
- package/dist/chunk-GGD7I4JO.js +0 -253
- package/dist/chunk-GGD7I4JO.js.map +0 -1
- /package/dist/{chunk-KCQJHXZP.js.map → chunk-ICIFEKSX.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../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"],"sourcesContent":["export interface GavaEngineConfig {\n branding: {\n name: string;\n logo?: string;\n splashWords: 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 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\nconst DEFAULT_CONFIG: GavaEngineConfig = {\n branding: {\n name: \"GavaEngine\",\n splashWords: [\"Powerful\", \"Flexible\", \"Modular\", \"Secure\", \"Customizable\"],\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 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: {\n articles: \"Articoli\",\n newArticle: \"Nuovo articolo\",\n media: \"Media\",\n users: \"Utenti\",\n statistics: \"Statistiche\",\n settings: \"Impostazioni\",\n revisions: \"Cronologia\",\n publish: \"Pubblica\",\n unpublish: \"Ritira\",\n saveDraft: \"Salva bozza\",\n delete: \"Elimina\",\n edit: \"Modifica\",\n search: \"Cerca\",\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 draft: \"Bozza\",\n published: \"Pubblicato\",\n all: \"Tutti\",\n drafts: \"Bozze\",\n saving: \"Salvando...\",\n saved: \"Salvato\",\n saveError: \"Errore nel salvataggio\",\n noArticles: \"Nessun articolo.\",\n noArticlesSearch: \"Nessun articolo trovato.\",\n noMedia: \"Nessun file caricato.\",\n noMediaSearch: \"Nessun file trovato.\",\n noRevisions: \"Nessuna revisione salvata.\",\n loading: \"Caricamento...\",\n confirm: \"Conferma\",\n cancel: \"Annulla\",\n apply: \"Applica\",\n change: \"Cambia\",\n logout: \"Esci\",\n viewArticle: \"Vedi articolo pubblicato\",\n preview: \"Anteprima\",\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 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 coverImageLabel: \"Immagine di copertina\",\n coverImageHint: \"Scegli dalla libreria o carica un nuovo file\",\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 searchArticles: \"Cerca articoli...\",\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 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 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 saveChanges: \"Salva modifiche\",\n updated: \"Aggiornato\",\n status: \"Stato\",\n title: \"Titolo\",\n untitled: \"Senza titolo\",\n },\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 return deepMerge(DEFAULT_CONFIG, overrides);\n}\n\nexport { DEFAULT_CONFIG };\n","import type { GavaEngineConfig } from \"../config.js\";\n\nexport function createRevisionHandlers(prisma: any, config: GavaEngineConfig) {\n const throttleMs = config.editor.revisionThrottleMinutes * 60 * 1000;\n\n return {\n async getRevisions(articleId: string) {\n return prisma.articleRevision.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.article.findUnique({\n where: { id: articleId },\n });\n if (!article) throw new Error(\"Article not found\");\n\n const revision = await prisma.articleRevision.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.articleRevision.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.article.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.article.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.articleRevision.findFirst({\n where: { articleId, createdAt: { gte: threshold } },\n orderBy: { createdAt: \"desc\" },\n });\n\n if (recent && !note) return;\n\n await prisma.articleRevision.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\n return {\n async getArticles() {\n return prisma.article.findMany({\n orderBy: { updatedAt: \"desc\" },\n });\n },\n\n async getArticleById(id: string) {\n return prisma.article.findUnique({\n where: { id },\n });\n },\n\n async createArticle(authorName: string) {\n const article = await prisma.article.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.article.findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await revisionHandlers.createRevisionSnapshot(id, userId);\n\n await prisma.article.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.article.findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await prisma.article.delete({ where: { id } });\n return { success: true };\n },\n\n async publishArticle(userId: string, id: string) {\n const article = await prisma.article.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.article.update({\n where: { id },\n data: {\n status: \"pubblicato\",\n publishedAt: new Date(),\n },\n });\n\n return { success: true };\n },\n\n async unpublishArticle(id: string) {\n const article = await prisma.article.findUnique({ where: { id } });\n if (!article) throw new Error(\"Article not found\");\n\n await prisma.article.update({\n where: { id },\n data: {\n status: \"bozza\",\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 return {\n async getUsers() {\n return prisma.user.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.user.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.user.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.user.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.user.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.user.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.user.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 return {\n async getMedia(search?: string) {\n return prisma.media.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.media.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.article.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.media.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 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.media.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) {\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.user.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"],"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"],"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\";\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 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"],"mappings":"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","names":["bcrypt"]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
interface GELocale {
|
|
2
|
+
content: {
|
|
3
|
+
articles: string;
|
|
4
|
+
newArticle: string;
|
|
5
|
+
titlePlaceholder: string;
|
|
6
|
+
excerptPlaceholder: string;
|
|
7
|
+
slugPlaceholder: string;
|
|
8
|
+
authorPlaceholder: string;
|
|
9
|
+
category: string;
|
|
10
|
+
selectCategory: string;
|
|
11
|
+
excerpt: string;
|
|
12
|
+
author: string;
|
|
13
|
+
slugUrl: string;
|
|
14
|
+
noArticles: string;
|
|
15
|
+
noArticlesSearch: string;
|
|
16
|
+
searchArticles: string;
|
|
17
|
+
coverImageLabel: string;
|
|
18
|
+
coverImageHint: string;
|
|
19
|
+
viewArticle: string;
|
|
20
|
+
untitled: string;
|
|
21
|
+
};
|
|
22
|
+
editor: {
|
|
23
|
+
publish: string;
|
|
24
|
+
unpublish: string;
|
|
25
|
+
saveDraft: string;
|
|
26
|
+
revisions: string;
|
|
27
|
+
saving: string;
|
|
28
|
+
saved: string;
|
|
29
|
+
saveError: string;
|
|
30
|
+
noRevisions: string;
|
|
31
|
+
restore: string;
|
|
32
|
+
restoreConfirm: string;
|
|
33
|
+
beforeRestore: string;
|
|
34
|
+
publishedNote: string;
|
|
35
|
+
preview: string;
|
|
36
|
+
placeholder: string;
|
|
37
|
+
};
|
|
38
|
+
media: {
|
|
39
|
+
media: string;
|
|
40
|
+
noMedia: string;
|
|
41
|
+
noMediaSearch: string;
|
|
42
|
+
chooseFile: string;
|
|
43
|
+
dragHint: string;
|
|
44
|
+
uploadHint: string;
|
|
45
|
+
mediaLibrary: string;
|
|
46
|
+
uploadNew: string;
|
|
47
|
+
searchFiles: string;
|
|
48
|
+
selectImage: string;
|
|
49
|
+
noImages: string;
|
|
50
|
+
noImagesSearch: string;
|
|
51
|
+
copyUrl: string;
|
|
52
|
+
editImage: string;
|
|
53
|
+
restoreOriginal: string;
|
|
54
|
+
freeAspect: string;
|
|
55
|
+
};
|
|
56
|
+
users: {
|
|
57
|
+
users: string;
|
|
58
|
+
name: string;
|
|
59
|
+
email: string;
|
|
60
|
+
password: string;
|
|
61
|
+
passwordEditHint: string;
|
|
62
|
+
role: string;
|
|
63
|
+
createdAt: string;
|
|
64
|
+
actions: string;
|
|
65
|
+
createUser: string;
|
|
66
|
+
unauthorized: string;
|
|
67
|
+
notAuthenticated: string;
|
|
68
|
+
allFieldsRequired: string;
|
|
69
|
+
passwordMinLength: string;
|
|
70
|
+
emailExists: string;
|
|
71
|
+
invalidRole: string;
|
|
72
|
+
cannotDeleteSelf: string;
|
|
73
|
+
};
|
|
74
|
+
common: {
|
|
75
|
+
statistics: string;
|
|
76
|
+
settings: string;
|
|
77
|
+
delete: string;
|
|
78
|
+
edit: string;
|
|
79
|
+
search: string;
|
|
80
|
+
draft: string;
|
|
81
|
+
published: string;
|
|
82
|
+
all: string;
|
|
83
|
+
drafts: string;
|
|
84
|
+
loading: string;
|
|
85
|
+
confirm: string;
|
|
86
|
+
cancel: string;
|
|
87
|
+
apply: string;
|
|
88
|
+
change: string;
|
|
89
|
+
logout: string;
|
|
90
|
+
saveChanges: string;
|
|
91
|
+
updated: string;
|
|
92
|
+
status: string;
|
|
93
|
+
title: string;
|
|
94
|
+
deleteConfirm: (title: string) => string;
|
|
95
|
+
unpublishConfirm: (title: string) => string;
|
|
96
|
+
deleteUserConfirm: (name: string) => string;
|
|
97
|
+
totalArticles: (count: number) => string;
|
|
98
|
+
totalFiles: (count: number) => string;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
declare const it: GELocale;
|
|
103
|
+
|
|
104
|
+
declare const en: GELocale;
|
|
105
|
+
|
|
106
|
+
declare function loadLocale(locale: string): GELocale;
|
|
107
|
+
declare function defineLocale(locale: GELocale): GELocale;
|
|
108
|
+
declare function mergeLocales(base: GELocale, overrides: DeepPartial<GELocale>): GELocale;
|
|
109
|
+
declare function registerLocale(key: string, locale: GELocale): void;
|
|
110
|
+
type DeepPartial<T> = {
|
|
111
|
+
[P in keyof T]?: T[P] extends (...args: any[]) => any ? T[P] : T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export { type GELocale, defineLocale, en, it, loadLocale, mergeLocales, registerLocale };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
// src/i18n/it.ts
|
|
2
|
+
var it = {
|
|
3
|
+
content: {
|
|
4
|
+
articles: "Articoli",
|
|
5
|
+
newArticle: "Nuovo articolo",
|
|
6
|
+
titlePlaceholder: "Titolo dell'articolo",
|
|
7
|
+
excerptPlaceholder: "Breve descrizione dell'articolo...",
|
|
8
|
+
slugPlaceholder: "slug-articolo",
|
|
9
|
+
authorPlaceholder: "Nome dell'autore",
|
|
10
|
+
category: "Categoria",
|
|
11
|
+
selectCategory: "Seleziona categoria",
|
|
12
|
+
excerpt: "Estratto",
|
|
13
|
+
author: "Autore",
|
|
14
|
+
slugUrl: "Slug URL",
|
|
15
|
+
noArticles: "Nessun articolo.",
|
|
16
|
+
noArticlesSearch: "Nessun articolo trovato.",
|
|
17
|
+
searchArticles: "Cerca articoli...",
|
|
18
|
+
coverImageLabel: "Immagine di copertina",
|
|
19
|
+
coverImageHint: "Scegli dalla libreria o carica un nuovo file",
|
|
20
|
+
viewArticle: "Vedi articolo pubblicato",
|
|
21
|
+
untitled: "Senza titolo"
|
|
22
|
+
},
|
|
23
|
+
editor: {
|
|
24
|
+
publish: "Pubblica",
|
|
25
|
+
unpublish: "Ritira",
|
|
26
|
+
saveDraft: "Salva bozza",
|
|
27
|
+
revisions: "Cronologia",
|
|
28
|
+
saving: "Salvando...",
|
|
29
|
+
saved: "Salvato",
|
|
30
|
+
saveError: "Errore nel salvataggio",
|
|
31
|
+
noRevisions: "Nessuna revisione salvata.",
|
|
32
|
+
restore: "Ripristina",
|
|
33
|
+
restoreConfirm: "Ripristinare questa revisione? Lo stato attuale verr\xE0 salvato prima del ripristino.",
|
|
34
|
+
beforeRestore: "Prima del ripristino",
|
|
35
|
+
publishedNote: "Pubblicato",
|
|
36
|
+
preview: "Anteprima",
|
|
37
|
+
placeholder: "Inizia a scrivere il tuo articolo..."
|
|
38
|
+
},
|
|
39
|
+
media: {
|
|
40
|
+
media: "Media",
|
|
41
|
+
noMedia: "Nessun file caricato.",
|
|
42
|
+
noMediaSearch: "Nessun file trovato.",
|
|
43
|
+
chooseFile: "Scegli file",
|
|
44
|
+
dragHint: "Trascina un'immagine qui oppure",
|
|
45
|
+
uploadHint: "JPEG, PNG, WebP, GIF (max 5MB)",
|
|
46
|
+
mediaLibrary: "Libreria media",
|
|
47
|
+
uploadNew: "Carica nuovo",
|
|
48
|
+
searchFiles: "Cerca file...",
|
|
49
|
+
selectImage: "Seleziona immagine",
|
|
50
|
+
noImages: "Nessuna immagine nella libreria.",
|
|
51
|
+
noImagesSearch: "Nessuna immagine trovata.",
|
|
52
|
+
copyUrl: "Copia URL",
|
|
53
|
+
editImage: "Modifica immagine",
|
|
54
|
+
restoreOriginal: "Ripristina originale",
|
|
55
|
+
freeAspect: "Libero"
|
|
56
|
+
},
|
|
57
|
+
users: {
|
|
58
|
+
users: "Utenti",
|
|
59
|
+
name: "Nome",
|
|
60
|
+
email: "Email",
|
|
61
|
+
password: "Password",
|
|
62
|
+
passwordEditHint: " (lascia vuoto per non modificarla)",
|
|
63
|
+
role: "Ruolo",
|
|
64
|
+
createdAt: "Creato il",
|
|
65
|
+
actions: "Azioni",
|
|
66
|
+
createUser: "Crea utente",
|
|
67
|
+
unauthorized: "Non autorizzato",
|
|
68
|
+
notAuthenticated: "Non autenticato",
|
|
69
|
+
allFieldsRequired: "Tutti i campi sono obbligatori.",
|
|
70
|
+
passwordMinLength: "La password deve avere almeno 6 caratteri.",
|
|
71
|
+
emailExists: "Esiste gi\xE0 un utente con questa email.",
|
|
72
|
+
invalidRole: "Ruolo non valido.",
|
|
73
|
+
cannotDeleteSelf: "Non puoi eliminare il tuo stesso account."
|
|
74
|
+
},
|
|
75
|
+
common: {
|
|
76
|
+
statistics: "Statistiche",
|
|
77
|
+
settings: "Impostazioni",
|
|
78
|
+
delete: "Elimina",
|
|
79
|
+
edit: "Modifica",
|
|
80
|
+
search: "Cerca",
|
|
81
|
+
draft: "Bozza",
|
|
82
|
+
published: "Pubblicato",
|
|
83
|
+
all: "Tutti",
|
|
84
|
+
drafts: "Bozze",
|
|
85
|
+
loading: "Caricamento...",
|
|
86
|
+
confirm: "Conferma",
|
|
87
|
+
cancel: "Annulla",
|
|
88
|
+
apply: "Applica",
|
|
89
|
+
change: "Cambia",
|
|
90
|
+
logout: "Esci",
|
|
91
|
+
saveChanges: "Salva modifiche",
|
|
92
|
+
updated: "Aggiornato",
|
|
93
|
+
status: "Stato",
|
|
94
|
+
title: "Titolo",
|
|
95
|
+
deleteConfirm: (title) => `Eliminare "${title || "Senza titolo"}"?`,
|
|
96
|
+
unpublishConfirm: (title) => `Ritirare "${title || "Senza titolo"}"? L'articolo torner\xE0 in bozza.`,
|
|
97
|
+
deleteUserConfirm: (name) => `Sei sicuro di voler eliminare l'utente "${name}"?`,
|
|
98
|
+
totalArticles: (count) => `${count} articol${count === 1 ? "o" : "i"} totali`,
|
|
99
|
+
totalFiles: (count) => `${count} file caricati`
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// src/i18n/en.ts
|
|
104
|
+
var en = {
|
|
105
|
+
content: {
|
|
106
|
+
articles: "Articles",
|
|
107
|
+
newArticle: "New article",
|
|
108
|
+
titlePlaceholder: "Article title",
|
|
109
|
+
excerptPlaceholder: "Brief description of the article...",
|
|
110
|
+
slugPlaceholder: "article-slug",
|
|
111
|
+
authorPlaceholder: "Author name",
|
|
112
|
+
category: "Category",
|
|
113
|
+
selectCategory: "Select category",
|
|
114
|
+
excerpt: "Excerpt",
|
|
115
|
+
author: "Author",
|
|
116
|
+
slugUrl: "URL Slug",
|
|
117
|
+
noArticles: "No articles.",
|
|
118
|
+
noArticlesSearch: "No articles found.",
|
|
119
|
+
searchArticles: "Search articles...",
|
|
120
|
+
coverImageLabel: "Cover image",
|
|
121
|
+
coverImageHint: "Choose from library or upload a new file",
|
|
122
|
+
viewArticle: "View published article",
|
|
123
|
+
untitled: "Untitled"
|
|
124
|
+
},
|
|
125
|
+
editor: {
|
|
126
|
+
publish: "Publish",
|
|
127
|
+
unpublish: "Unpublish",
|
|
128
|
+
saveDraft: "Save draft",
|
|
129
|
+
revisions: "History",
|
|
130
|
+
saving: "Saving...",
|
|
131
|
+
saved: "Saved",
|
|
132
|
+
saveError: "Error saving",
|
|
133
|
+
noRevisions: "No revisions saved.",
|
|
134
|
+
restore: "Restore",
|
|
135
|
+
restoreConfirm: "Restore this revision? The current state will be saved before restoring.",
|
|
136
|
+
beforeRestore: "Before restore",
|
|
137
|
+
publishedNote: "Published",
|
|
138
|
+
preview: "Preview",
|
|
139
|
+
placeholder: "Start writing your article..."
|
|
140
|
+
},
|
|
141
|
+
media: {
|
|
142
|
+
media: "Media",
|
|
143
|
+
noMedia: "No files uploaded.",
|
|
144
|
+
noMediaSearch: "No files found.",
|
|
145
|
+
chooseFile: "Choose file",
|
|
146
|
+
dragHint: "Drag an image here or",
|
|
147
|
+
uploadHint: "JPEG, PNG, WebP, GIF (max 5MB)",
|
|
148
|
+
mediaLibrary: "Media library",
|
|
149
|
+
uploadNew: "Upload new",
|
|
150
|
+
searchFiles: "Search files...",
|
|
151
|
+
selectImage: "Select image",
|
|
152
|
+
noImages: "No images in library.",
|
|
153
|
+
noImagesSearch: "No images found.",
|
|
154
|
+
copyUrl: "Copy URL",
|
|
155
|
+
editImage: "Edit image",
|
|
156
|
+
restoreOriginal: "Restore original",
|
|
157
|
+
freeAspect: "Free"
|
|
158
|
+
},
|
|
159
|
+
users: {
|
|
160
|
+
users: "Users",
|
|
161
|
+
name: "Name",
|
|
162
|
+
email: "Email",
|
|
163
|
+
password: "Password",
|
|
164
|
+
passwordEditHint: " (leave blank to keep current)",
|
|
165
|
+
role: "Role",
|
|
166
|
+
createdAt: "Created at",
|
|
167
|
+
actions: "Actions",
|
|
168
|
+
createUser: "Create user",
|
|
169
|
+
unauthorized: "Unauthorized",
|
|
170
|
+
notAuthenticated: "Not authenticated",
|
|
171
|
+
allFieldsRequired: "All fields are required.",
|
|
172
|
+
passwordMinLength: "Password must be at least 6 characters.",
|
|
173
|
+
emailExists: "A user with this email already exists.",
|
|
174
|
+
invalidRole: "Invalid role.",
|
|
175
|
+
cannotDeleteSelf: "You cannot delete your own account."
|
|
176
|
+
},
|
|
177
|
+
common: {
|
|
178
|
+
statistics: "Statistics",
|
|
179
|
+
settings: "Settings",
|
|
180
|
+
delete: "Delete",
|
|
181
|
+
edit: "Edit",
|
|
182
|
+
search: "Search",
|
|
183
|
+
draft: "Draft",
|
|
184
|
+
published: "Published",
|
|
185
|
+
all: "All",
|
|
186
|
+
drafts: "Drafts",
|
|
187
|
+
loading: "Loading...",
|
|
188
|
+
confirm: "Confirm",
|
|
189
|
+
cancel: "Cancel",
|
|
190
|
+
apply: "Apply",
|
|
191
|
+
change: "Change",
|
|
192
|
+
logout: "Logout",
|
|
193
|
+
saveChanges: "Save changes",
|
|
194
|
+
updated: "Updated",
|
|
195
|
+
status: "Status",
|
|
196
|
+
title: "Title",
|
|
197
|
+
deleteConfirm: (title) => `Delete "${title || "Untitled"}"?`,
|
|
198
|
+
unpublishConfirm: (title) => `Unpublish "${title || "Untitled"}"? The article will go back to draft.`,
|
|
199
|
+
deleteUserConfirm: (name) => `Are you sure you want to delete user "${name}"?`,
|
|
200
|
+
totalArticles: (count) => `${count} total article${count === 1 ? "" : "s"}`,
|
|
201
|
+
totalFiles: (count) => `${count} uploaded file${count === 1 ? "" : "s"}`
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/i18n/index.ts
|
|
206
|
+
var builtinLocales = { it, en };
|
|
207
|
+
function loadLocale(locale) {
|
|
208
|
+
const found = builtinLocales[locale];
|
|
209
|
+
if (!found) {
|
|
210
|
+
throw new Error(
|
|
211
|
+
`Locale "${locale}" not found. Available: ${Object.keys(builtinLocales).join(", ")}`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
return found;
|
|
215
|
+
}
|
|
216
|
+
function defineLocale(locale) {
|
|
217
|
+
return locale;
|
|
218
|
+
}
|
|
219
|
+
function mergeLocales(base, overrides) {
|
|
220
|
+
return deepMergeLocale(base, overrides);
|
|
221
|
+
}
|
|
222
|
+
function registerLocale(key, locale) {
|
|
223
|
+
builtinLocales[key] = locale;
|
|
224
|
+
}
|
|
225
|
+
function deepMergeLocale(target, source) {
|
|
226
|
+
const result = { ...target };
|
|
227
|
+
for (const key of Object.keys(source)) {
|
|
228
|
+
const sourceVal = source[key];
|
|
229
|
+
const targetVal = target[key];
|
|
230
|
+
if (sourceVal && typeof sourceVal === "object" && !Array.isArray(sourceVal) && typeof targetVal === "object" && !Array.isArray(targetVal) && typeof sourceVal !== "function") {
|
|
231
|
+
result[key] = deepMergeLocale(
|
|
232
|
+
targetVal,
|
|
233
|
+
sourceVal
|
|
234
|
+
);
|
|
235
|
+
} else if (sourceVal !== void 0) {
|
|
236
|
+
result[key] = sourceVal;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
}
|
|
241
|
+
export {
|
|
242
|
+
defineLocale,
|
|
243
|
+
en,
|
|
244
|
+
it,
|
|
245
|
+
loadLocale,
|
|
246
|
+
mergeLocales,
|
|
247
|
+
registerLocale
|
|
248
|
+
};
|
|
249
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/i18n/it.ts","../../src/i18n/en.ts","../../src/i18n/index.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"],"mappings":"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","names":[]}
|