diff --git a/frontends/nextjs/eslint.config.js b/frontends/nextjs/eslint.config.js index 27df08d23..db5a1722c 100644 --- a/frontends/nextjs/eslint.config.js +++ b/frontends/nextjs/eslint.config.js @@ -58,12 +58,16 @@ export default tseslint.config( 'src/lib/**/functions/**/*.ts', 'src/hooks/**/*.ts', 'src/lib/github/**/*.ts', + 'src/lib/dbal-client/**/*.ts', + 'src/lib/dbal/**/*.ts', ], rules: { '@typescript-eslint/no-unsafe-assignment': 'warn', '@typescript-eslint/no-unsafe-member-access': 'warn', '@typescript-eslint/no-unsafe-call': 'warn', '@typescript-eslint/no-unsafe-return': 'warn', + '@typescript-eslint/no-unsafe-argument': 'warn', + '@typescript-eslint/strict-boolean-expressions': 'warn', }, }, ) diff --git a/frontends/nextjs/next.config.ts b/frontends/nextjs/next.config.ts index 6e363425c..feaf91e2b 100644 --- a/frontends/nextjs/next.config.ts +++ b/frontends/nextjs/next.config.ts @@ -78,12 +78,14 @@ const nextConfig: NextConfig = { // Environment variables exposed to browser env: { - NEXT_PUBLIC_DBAL_API_URL: process.env.DBAL_API_URL || 'http://localhost:8080', - NEXT_PUBLIC_DBAL_WS_URL: process.env.DBAL_WS_URL || 'ws://localhost:50051', - NEXT_PUBLIC_DBAL_API_KEY: process.env.DBAL_API_KEY || '', + NEXT_PUBLIC_DBAL_API_URL: process.env.DBAL_API_URL ?? 'http://localhost:8080', + NEXT_PUBLIC_DBAL_WS_URL: process.env.DBAL_WS_URL ?? 'ws://localhost:50051', + NEXT_PUBLIC_DBAL_API_KEY: process.env.DBAL_API_KEY ?? '', }, webpack(config, { isServer }) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access config.resolve.alias = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access ...config.resolve.alias, '@/dbal': path.resolve(__dirname, '../../dbal/development/src'), '@dbal-ui': path.resolve(__dirname, '../../dbal/shared/ui'), @@ -92,7 +94,9 @@ const nextConfig: NextConfig = { // Ignore optional AWS SDK and Node.js modules on client side if (!isServer) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access config.resolve.fallback = { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access ...config.resolve.fallback, '@aws-sdk/client-s3': false, fs: false, @@ -106,6 +110,7 @@ const nextConfig: NextConfig = { } } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return return config }, } diff --git a/frontends/nextjs/src/lib/db/css-classes/crud/delete-css-category.ts b/frontends/nextjs/src/lib/db/css-classes/crud/delete-css-category.ts index b9e2d9fcb..517993ef7 100644 --- a/frontends/nextjs/src/lib/db/css-classes/crud/delete-css-category.ts +++ b/frontends/nextjs/src/lib/db/css-classes/crud/delete-css-category.ts @@ -5,10 +5,9 @@ import { getAdapter } from '../../core/dbal-client' */ export async function deleteCssCategory(categoryName: string): Promise { const adapter = getAdapter() - const existing = await adapter.findFirst('CssCategory', { where: { name: categoryName } }) - if (!existing) { + const existing = await adapter.findFirst('CssCategory', { where: { name: categoryName } }) as { id: string | number } | null + if (existing === null || existing === undefined) { return } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - await adapter.delete('CssCategory', (existing as any).id) + await adapter.delete('CssCategory', existing.id) } diff --git a/frontends/nextjs/src/lib/db/css-classes/crud/set-css-classes.ts b/frontends/nextjs/src/lib/db/css-classes/crud/set-css-classes.ts index 21b617164..36d1f3167 100644 --- a/frontends/nextjs/src/lib/db/css-classes/crud/set-css-classes.ts +++ b/frontends/nextjs/src/lib/db/css-classes/crud/set-css-classes.ts @@ -8,9 +8,8 @@ export async function setCssClasses(classes: CssCategory[]): Promise { const adapter = getAdapter() // Delete all existing const existing = await adapter.list('CssCategory') - // eslint-disable-next-line @typescript-eslint/no-explicit-any - for (const item of existing.data as any[]) { - if (item?.id) { + for (const item of existing.data as Array<{ id?: string | number }>) { + if (item?.id !== null && item?.id !== undefined) { await adapter.delete('CssCategory', item.id) } } diff --git a/frontends/nextjs/src/lib/db/css-classes/crud/update-css-category.ts b/frontends/nextjs/src/lib/db/css-classes/crud/update-css-category.ts index 4cab4680d..c560e77a6 100644 --- a/frontends/nextjs/src/lib/db/css-classes/crud/update-css-category.ts +++ b/frontends/nextjs/src/lib/db/css-classes/crud/update-css-category.ts @@ -6,13 +6,12 @@ import type { CssCategory } from '../types' */ export async function updateCssCategory(categoryName: string, updates: CssCategory): Promise { const adapter = getAdapter() - const existing = await adapter.findFirst('CssCategory', { where: { name: categoryName } }) - if (!existing) { + const existing = await adapter.findFirst('CssCategory', { where: { name: categoryName } }) as { id: string | number } | null + if (existing === null || existing === undefined) { throw new Error(`CssCategory not found: ${categoryName}`) } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - await adapter.update('CssCategory', (existing as any).id, { + await adapter.update('CssCategory', existing.id, { name: updates.name, classes: JSON.stringify(updates.classes), }) diff --git a/frontends/nextjs/src/lib/db/database-admin/clear-database.ts b/frontends/nextjs/src/lib/db/database-admin/clear-database.ts index 88943acb0..3a779dd9c 100644 --- a/frontends/nextjs/src/lib/db/database-admin/clear-database.ts +++ b/frontends/nextjs/src/lib/db/database-admin/clear-database.ts @@ -39,8 +39,8 @@ export async function clearDatabase(): Promise { try { const result = (await adapter.list(entityType)) as { data: DBALDeleteCandidate[] } for (const item of result.data) { - const id = item.id || item.packageId || item.name || item.key || item.username - if (id) { + const id = item.id ?? item.packageId ?? item.name ?? item.key ?? item.username + if (id !== null && id !== undefined) { await adapter.delete(entityType, id) } } diff --git a/frontends/nextjs/src/lib/db/database-admin/export/export-database.ts b/frontends/nextjs/src/lib/db/database-admin/export/export-database.ts index cbc298690..850d1c0ae 100644 --- a/frontends/nextjs/src/lib/db/database-admin/export/export-database.ts +++ b/frontends/nextjs/src/lib/db/database-admin/export/export-database.ts @@ -18,7 +18,7 @@ export async function exportDatabase(): Promise { luaScripts: await getLuaScripts(), pages: await getPages(), schemas: await getSchemas(), - appConfig: (await getAppConfig()) || undefined, + appConfig: (await getAppConfig()) ?? undefined, comments: await getComments(), componentHierarchy: await getComponentHierarchy(), componentConfigs: await getComponentConfigs(), diff --git a/frontends/nextjs/src/lib/db/database-admin/import/import-database.ts b/frontends/nextjs/src/lib/db/database-admin/import/import-database.ts index f05401998..a1ab94082 100644 --- a/frontends/nextjs/src/lib/db/database-admin/import/import-database.ts +++ b/frontends/nextjs/src/lib/db/database-admin/import/import-database.ts @@ -15,15 +15,15 @@ export async function importDatabase(jsonData: string): Promise { try { const data = JSON.parse(jsonData) as Partial - if (data.users) await setUsers(data.users) - if (data.workflows) await setWorkflows(data.workflows) - if (data.luaScripts) await setLuaScripts(data.luaScripts) - if (data.pages) await setPages(data.pages) - if (data.schemas) await setSchemas(data.schemas) - if (data.appConfig) await setAppConfig(data.appConfig) - if (data.comments) await setComments(data.comments) - if (data.componentHierarchy) await setComponentHierarchy(data.componentHierarchy) - if (data.componentConfigs) await setComponentConfigs(data.componentConfigs) + if (data.users !== null && data.users !== undefined) await setUsers(data.users) + if (data.workflows !== null && data.workflows !== undefined) await setWorkflows(data.workflows) + if (data.luaScripts !== null && data.luaScripts !== undefined) await setLuaScripts(data.luaScripts) + if (data.pages !== null && data.pages !== undefined) await setPages(data.pages) + if (data.schemas !== null && data.schemas !== undefined) await setSchemas(data.schemas) + if (data.appConfig !== null && data.appConfig !== undefined) await setAppConfig(data.appConfig) + if (data.comments !== null && data.comments !== undefined) await setComments(data.comments) + if (data.componentHierarchy !== null && data.componentHierarchy !== undefined) await setComponentHierarchy(data.componentHierarchy) + if (data.componentConfigs !== null && data.componentConfigs !== undefined) await setComponentConfigs(data.componentConfigs) } catch { throw new Error('Failed to import database: Invalid JSON') } diff --git a/frontends/nextjs/src/lib/db/database-admin/seed-default-data/app/seed-app-config.ts b/frontends/nextjs/src/lib/db/database-admin/seed-default-data/app/seed-app-config.ts index b20c8b8cf..2bf5ab128 100644 --- a/frontends/nextjs/src/lib/db/database-admin/seed-default-data/app/seed-app-config.ts +++ b/frontends/nextjs/src/lib/db/database-admin/seed-default-data/app/seed-app-config.ts @@ -4,7 +4,7 @@ import { buildDefaultAppConfig } from './default-app-config' export const seedAppConfig = async () => { const appConfig = await getAppConfig() - if (!appConfig) { + if (appConfig === null || appConfig === undefined) { await setAppConfig(buildDefaultAppConfig()) } } diff --git a/frontends/nextjs/src/lib/db/dropdown-configs/crud/get-dropdown-configs.ts b/frontends/nextjs/src/lib/db/dropdown-configs/crud/get-dropdown-configs.ts index a87d29261..54671c712 100644 --- a/frontends/nextjs/src/lib/db/dropdown-configs/crud/get-dropdown-configs.ts +++ b/frontends/nextjs/src/lib/db/dropdown-configs/crud/get-dropdown-configs.ts @@ -7,11 +7,10 @@ import type { DropdownConfig } from '../types' export async function getDropdownConfigs(): Promise { const adapter = getAdapter() const result = await adapter.list('DropdownConfig') - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return (result.data as any[]).map(c => ({ + return (result.data as Array<{ id: string | number; name: string; label: string; options: string | string[] }>).map(c => ({ id: c.id, name: c.name, label: c.label, - options: typeof c.options === 'string' ? JSON.parse(c.options) : c.options, + options: typeof c.options === 'string' ? JSON.parse(c.options) as string[] : c.options, })) } diff --git a/frontends/nextjs/src/lib/db/dropdown-configs/crud/set-dropdown-configs.ts b/frontends/nextjs/src/lib/db/dropdown-configs/crud/set-dropdown-configs.ts index 2a5376c04..f2c20488b 100644 --- a/frontends/nextjs/src/lib/db/dropdown-configs/crud/set-dropdown-configs.ts +++ b/frontends/nextjs/src/lib/db/dropdown-configs/crud/set-dropdown-configs.ts @@ -8,8 +8,7 @@ export async function setDropdownConfigs(configs: DropdownConfig[]): Promise) { await adapter.delete('DropdownConfig', item.id) } // Create new ones